[Suggestion] Lua Scripting - Possible Enhancements
Posted: Fri Jul 29, 2016 9:37 am
Preamble
Ok, so after having delved into a bit of modding in PA, I found the Lua API to be somewhat lacking. So, being the investigative sod that I am, I decompiled my copy of the game, and took a look for some, possibly undocumented Lua functions. While I did not find any undocumented ones (props to the wiki for that), I did find that there are a literal f**k-ton of C/C++ methods that heavily resemble already implemented Lua functions.
Just quickly, for those that aren't aware, Lua is pretty much a language designed to be implemented inside of another language, and provides an extensive interface to C/C++ particularly, hence why I'm even bringing C/C++ methods into this
Now, some of you are probably aware that finding nearby objects, entities and other in-game objects can be a real pain, the most often used (and only) function for doing this is [code single]Object.GetNearbyObjects()[/code], which is EXTREMELY in-accurate, and often leads to a lot of code that really shouldn't be necessary. As well as that, as far as I can tell, the only way to add room requirements, nearby objects e.t.c. is to override the corresponding .txt files from the game. This isn't efficient and can be infuriating at times.
I will give a list of all functions found, but am going to focus on a couple that seem like they'd be extremely helpful
PLEASE NOTE, AS THIS IS FROM DISASSEMBLED CODE, IT MAY BE INNACCURATE
World::GetRoom
This function allows one to get the pointer to the room containing a specific object
The syntax appears to be as follows
This means it takes a pointer to a Objectid constant.
It then seems to return a pointer to the room, which as far as I can tell, is an [code single]int[/code]
This would be immensely helpful for campaigns, grants and new rooms, as it'd allow for better context checking
World::GetObject
This function has 2 variants, one that takes 2 [code single]int[/code]'s, presumably x and y coordinates. The other variant takes a [code single]ObjectId[/code] pointer. The x, y variant would presumably return whatever object was present in that coordinate. The other presumably just returns a pointer to the [code single]WorldObject[/code] with the corresponding id. This would be great for sanbox mods, one example is True Sandbox Mod V2, which makes extensive use of the [code single]World::GetNearbyObjects()[/code] function to allow one to instantly create large sections of materials
Syntax is as follows
World::GetObjectsInRoom
This function is pretty much self-explanatory, apart from the fact that it returns a pointer to a [code single]FastList[/code] of the objects found
Please note that I'm really not sure on the arguments for this, it seems to take [code single]ObjectID[/code]'s even though I would of thought it'd take some sort of [code single]Room[/code] object pointer
This would be helpful for grant mods
World::ToggleLockdown and World::ToggleBangup
Self explanatory, but would be useful for modding
Both take no arguments
Entity namespace
Entity::ClearRouting
This would be great to stop Workers from getting stuck in corners for several minutes after placing mod objects
Final Notes
I haven't covered as many functions as I could have, but BBcode is a pain, and I'm sure theres a post size limit. Hope this helps people, and perhaps my suggestions will be implemented
List of Functions (Not all of them, that'd be too many. Full lists attached)
Full Lists
Unfortunately, I cant upload them directly, so heres a link to a gist
https://gist.github.com/MicroTransactionsMatterToo/4337df40304ddaa1078b28d0a2d40272
Ok, so after having delved into a bit of modding in PA, I found the Lua API to be somewhat lacking. So, being the investigative sod that I am, I decompiled my copy of the game, and took a look for some, possibly undocumented Lua functions. While I did not find any undocumented ones (props to the wiki for that), I did find that there are a literal f**k-ton of C/C++ methods that heavily resemble already implemented Lua functions.
Just quickly, for those that aren't aware, Lua is pretty much a language designed to be implemented inside of another language, and provides an extensive interface to C/C++ particularly, hence why I'm even bringing C/C++ methods into this
Now, some of you are probably aware that finding nearby objects, entities and other in-game objects can be a real pain, the most often used (and only) function for doing this is [code single]Object.GetNearbyObjects()[/code], which is EXTREMELY in-accurate, and often leads to a lot of code that really shouldn't be necessary. As well as that, as far as I can tell, the only way to add room requirements, nearby objects e.t.c. is to override the corresponding .txt files from the game. This isn't efficient and can be infuriating at times.
I will give a list of all functions found, but am going to focus on a couple that seem like they'd be extremely helpful
PLEASE NOTE, AS THIS IS FROM DISASSEMBLED CODE, IT MAY BE INNACCURATE
World::GetRoom
This function allows one to get the pointer to the room containing a specific object
The syntax appears to be as follows
Code: Select all
int *example = World::GetRoom(Objectid const&)This means it takes a pointer to a Objectid constant.
It then seems to return a pointer to the room, which as far as I can tell, is an [code single]int[/code]
This would be immensely helpful for campaigns, grants and new rooms, as it'd allow for better context checking
World::GetObject
This function has 2 variants, one that takes 2 [code single]int[/code]'s, presumably x and y coordinates. The other variant takes a [code single]ObjectId[/code] pointer. The x, y variant would presumably return whatever object was present in that coordinate. The other presumably just returns a pointer to the [code single]WorldObject[/code] with the corresponding id. This would be great for sanbox mods, one example is True Sandbox Mod V2, which makes extensive use of the [code single]World::GetNearbyObjects()[/code] function to allow one to instantly create large sections of materials
Syntax is as follows
Code: Select all
int *variant1 = World::GetObject(int, int)
int *variant2 = World::GetObject(ObjectId const&)
// Actual function declarations (I think)
int World::GetObject1(int arg1, int arg2) {};
int World::GetObject2(void * arg) {};World::GetObjectsInRoom
This function is pretty much self-explanatory, apart from the fact that it returns a pointer to a [code single]FastList[/code] of the objects found
Please note that I'm really not sure on the arguments for this, it seems to take [code single]ObjectID[/code]'s even though I would of thought it'd take some sort of [code single]Room[/code] object pointer
This would be helpful for grant mods
Code: Select all
int *example = World::GetObjectsInRoom(ObjectId const&, FastList<ObjectId>&, int);
// Function decl
int World::GetObjectsInRoom(void * arg0, void * arg4, int arg8) {};World::ToggleLockdown and World::ToggleBangup
Self explanatory, but would be useful for modding
Both take no arguments
Entity namespace
Entity::ClearRouting
This would be great to stop Workers from getting stuck in corners for several minutes after placing mod objects
Final Notes
I haven't covered as many functions as I could have, but BBcode is a pain, and I'm sure theres a post size limit. Hope this helps people, and perhaps my suggestions will be implemented
List of Functions (Not all of them, that'd be too many. Full lists attached)
Code: Select all
// App namespace
App::App()
App::App()
App::FinishThreadedUpdate()
App::CloseMap()
App::NewMap(int, bool)
App::Update()
App::UpdateMotdPopup()
App::CanAutoSave()
App::SaveMap(std::string const&, bool, bool)
App::GetSaveExtension()
App::StartThreadedUpdate(float, float)
App::ThreadedUpdate(float, float)
App::UpdateAndRender_SkipCutscene()
App::Render()
App::RenderLoadingScreen(std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, Image*)
App::RenderTimeLapseInfo()
App::RenderTimeLapse()
App::LoadMap(std::string const&, bool, bool)
App::CloseCampaign()
App::LoadMap(TextReader*, std::string const&, bool)
App::RunCampaign(std::string const&)
App::RunCampaignMap(std::string const&, bool)
App::SaveCampaignMap(std::string const&)
App::SaveCampaignProgress()
App::DeleteCampaignProgress(std::string const&)
App::GetCampaignExtension()
App::GetEscapeModeExtension()
App::GetPrisonExtension()
App::GetFullVersionId()
App::CreateOffscreenBuffer()
App::ShutdownOffscreenBuffers()
App::HandleTimeLapse()
App::ResetAssets()
App::ResetLanguage()
App::ResetFonts()
App::ResetInterface()
App::ResetDialogs()
App::ResetSounds()
App::ClearAssets()
App::RemakeAssets()
App::ResetSpriteBank()
App::LoadLanguageStructure(std::string const&)
App::PurchaseLandPlot(int, int, int, int)
App::MakeTemporarySaveFile()
App::LoadTemporarySaveFile()
App::GetThreadedUpdateDeadline()
App::PostThreadedUpdateJob(Runnable*)
App::FinishThreadedUpdate()::maxWaited
App::RenderLoadingScreen(std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, Image*)::s_multiLine
App::RenderLoadingScreen(std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, std::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> > const&, Image*)::s_lastDescription
// Entity namespace
Entity::UpdateExecutionActor(float)
Entity::Entity()
Entity::Entity()
Entity::~Entity()
Entity::YieldJob()
Entity::~Entity()
Entity::~Entity()
Entity::Create()
Entity::Initialise()
Entity::AiSetsTarget(float, float, float, float, float)
Entity::GoToRoom(ObjectId const&, float, float)
Entity::ClearRouting()
Entity::PlotRouteToDestination()
Entity::WalkTowardsDestination(float, float, Vector2 const&)
Entity::CalculateActualMoveSpeed(float, float)
Entity::CheckValidMovement(Vector2 const&, bool)
Entity::PushFromOtherEntities(float)
Entity::IsDead()
Entity::DetermineRoutingFlags()
Entity::IsIncapacitated()
Entity::SearchForIdleWander()
Entity::EvadeDanger(float)
Entity::UpdateCarrying(float)
Entity::NotifyLoadedInto(ObjectId const&)
Entity::NotifyCarried(ObjectId const&)
Entity::NotifyLockdown()
Entity::Follow(ObjectId const&)
Entity::GetPreferredZone() const
Entity::LookupAttackWeapon()
Entity::UpdateAttacking_RangedWeapon(float, WorldObject*)
Entity::ShootTarget(WorldObject*)
Entity::ShootWeapon(Vector2)
Entity::DropEquipment(bool, bool, bool)
Entity::UpdateReloading(float)
Entity::UpdateAttacking(float, WorldObject*)
Entity::ThrowHit()
Entity::HitTarget(WorldObject*)
Entity::UpdateTeaching(float)
Entity::Update_Resting(float)
Entity::HangOutInRoom(int, float, float)
Entity::UpdateVisitDoctor(float)
Entity::Update(float)
Entity::IsCarryingSomething()
Entity::Drop(bool)
Entity::UpdateLeaving(float)
Entity::Update_EnergyLevel(float)
Entity::InExclusionNoRenderZone()
Entity::RenderStatBar(float, float, float, float, std::string const&, float, bool)
Entity::RenderEffects()
Entity::RenderRoute()
Entity::IsHostage()
Entity::PlotRouteToRoomType(int)
Entity::HasRoute()
Entity::PlayerSetsTarget(float, float, ObjectId const&)
Entity::IsAITargetSet()
Entity::ClearAITarget()
Entity::HasDestination()
Entity::Damage(float, WorldObject*)
Entity::IsEquipped()
Entity::HitByTazer(WorldObject*)
Entity::AttackedBy(Entity*)
Entity::FailJob(int, bool)
Entity::IntimidatedBy(Entity*)
Entity::Destroy()
Entity::NotifyHostage(Entity*)
Entity::IsEquipmentVisible()
Entity::Pickup(ObjectId const&)
Entity::SearchForJob()
Entity::SearchForJobAsync()
Entity::SearchForJobNow()
Entity::PerformJob(float)
Entity::SearchForStation()
Entity::HangAroundAtStation(float)
Entity::UpdateAvatarControl(float)
Entity::AttendReformProgram(float)
Entity::Write(Directory*)
Entity::Read(Directory*)
// Prisoner Namespace
Prisoner::Prisoner()
Prisoner::Prisoner()
Prisoner::~Prisoner()
Prisoner::~Prisoner()
Prisoner::~Prisoner()
Prisoner::Initialise()
Prisoner::InitialiseTimeOfLastMisconduct()
Prisoner::AteRecently()
Prisoner::IsUnconsciousWhenSick()
Prisoner::AutoRecoverWhenSick()
Prisoner::IsOnWorkLockdown()
Prisoner::EnsureInCell(float)
Prisoner::IsSleeping()
Prisoner::HasObjectInCell(int)
Prisoner::GetRequiredRoom()
Prisoner::GetBabyState()
Prisoner::DetermineAssignedCanteen()
Prisoner::IsOnPermanentLockdown()
Prisoner::Update_DoNothing(float)
Prisoner::IsLockedDown()
Prisoner::Update_EscapeFollowingLeader(float)
Prisoner::StartMisbehaving(int)
Prisoner::Update_Misbehaving(float)
Prisoner::IsMisbehaving()
Prisoner::Update_Misbehaving_Destroying(float)
Prisoner::EquipItemFromContraband(int)
Prisoner::Update_Misbehaving_Escaping(float)
Prisoner::Update_Misbehaving_ArmouryRaid(float)
Prisoner::Update_Misbehaving_SecurityRoomRaid(float)
Prisoner::Update_Misbehaving_SnitchRaid(float)
Prisoner::IsAssassinationTarget()
Prisoner::EquipGroupFromContraband(int)
Prisoner::Update_Misbehaving_Rioting(float)
Prisoner::SearchForFoe(bool)
Prisoner::NotifyContraband(ObjectId const&)
Prisoner::Update_Misbehaving_Spoiling(float)
Prisoner::CountNearbyEntities(int&, int&)
Prisoner::Update_Misbehaving_Fighting(float)
Prisoner::StopMisbehaving()
Prisoner::Update_Misbehaving_HostageTaking(float)
Prisoner::IsFighting()
Prisoner::ResetTimeWithoutIncident()
Prisoner::GetDaysWithoutIncident()
Prisoner::GetAppropriateCellQuality()
Prisoner::HasBaby()
Prisoner::ConsiderCopyingMisbehavior(Prisoner*)
Prisoner::DetermineMaxEscapeDoors()
Prisoner::IsReleased()
Prisoner::IsWorking()
Prisoner::BroadcastSnitch()
Prisoner::ConsiderSnitchAttack(Prisoner*)
Prisoner::BeginSnitchAttack(Prisoner*)
Prisoner::Update_AttackGangTerritory(float)
Prisoner::Update_DefendGangEviction(float)
Prisoner::Update(float)
Prisoner::MisconductImminent()
Prisoner::Unshackle()
Prisoner::GrabContraband(float)
Prisoner::OpenMail(ObjectId const&)
Prisoner::DetermineTableDirection(WorldPosition const&)
Prisoner::DetermineJitter()
Prisoner::AddictionAmount(bool, bool)
Prisoner::DetermineParoleAttackChance()
Prisoner::IsArmed()
Prisoner::RenderEffects()
Prisoner::RenderStats()
Prisoner::PlayerSetsTarget(float, float, ObjectId const&)
Prisoner::GetMisconductType(std::string const&)
Prisoner::IntimidatedBy(Entity*)
Prisoner::AttackedBy(Entity*)
Prisoner::CallForGangHelp()
Prisoner::NotifyBeginBangup()
Prisoner::Destroy()
Prisoner::QuickEatMeal(WorldObject*)
Prisoner::BuyGoods(int)
Prisoner::PayGang(int, float)
Prisoner::GetCell()
Prisoner::GetCellSize()
Prisoner::Read(Directory*)
Prisoner::Write(Directory*)
Prisoner::GetUniformColour(int)
Prisoner::GetCategoryType(std::string const&)
Prisoner::RegisterScriptSyntax(lua_State*, std::string const&, std::string const&)
Prisoner::GetHoursSinceLastVisit()
Prisoner::ResetLastVisitTime()
// World namespace
World::GetRoom(ObjectId const&)
World::NotifyScratched(int, int, bool, bool, bool)
World::World()
World::World()
World::~World()
World::~World()
World::SetGameOver()
World::NotifyRoomScratched()
World::ClearScratched()
World::ScratchAll(bool)
World::ScratchedCellIterator::Next(int*, int*)
World::GetScratchedCellIterator()
World::Initialise(int, int)
World::GenerateIndoorOutdoorMap()
World::LoadWorldScripts()
World::GenerateNewWorld()
World::GenerateLandscape(int, int, int, int)
World::GetRoadPosition(int&, int&)
World::AddObject(WorldObject*)
World::LookupObject(int, int, int)
World::RemoveObject(ObjectId const&)
World::GetObjectsInZone(int, int, int, int, FastList<ObjectId>&, int)
World::GetObject(int, int)
World::GetObject(ObjectId const&)
World::GetDoor(int, int)
World::ThreadedUpdate(float)
World::Update(float)
World::GetRoomByType(int, bool)
World::GetObjects(int, FastList<ObjectId>&)
World::UpdateChefDistribution()
World::GetRooms(int, FastList<ObjectId>&)
World::CountObjectsInRoom(ObjectId, int)
World::CreateRoom()
World::RemoveRoom(ObjectId const&)
World::GetAccessibleRooms(int, WorldObject*, FastList<Room*>&)
World::GetAccessibleRoomRandom(int, WorldObject*)
World::GetAccessibleRoom(int, WorldObject*)
World::GetRoomsWithProperty(int, FastList<ObjectId>&)
World::NotifyLightsGroundScratched(int, int)
World::NotifyCellIndoorChanged(int, int)
World::RegisterScriptSyntax(lua_State*, std::string const&, std::string const&)
World::AssignPrisonerToCell(ObjectId const&, ObjectId const&)
World::ConsiderCellUpgrade(ObjectId const&)
World::GetNearestObject(int, int, int)
World::GetObjectByType(int)
World::GetObjectsInRoom(ObjectId const&, FastList<ObjectId>&, int)
World::CountObjectsInRoom(ObjectId, int*)
World::GetNearbyObjects(int, int, float, FastList<ObjectId>&, int, bool)
World::GetNeighbourObjects(ObjectId const&, FastList<ObjectId>&, bool)
World::GetEmptyNeighbourCells(ObjectId const&, FastList<WorldPosition>&, bool, bool, ObjectId const&)
World::GetEmptyNearbyCells(int, int, int, FastList<WorldPosition>&, bool)
World::IsCellEmpty(int, int, bool)
World::GetRoomSecurityLevel(ObjectId const&)
World::NeighboursHaveSameMaterial(int, int)
World::IsBuildingEdge(int, int, bool)
World::IsRoomEdge(int, int)
World::IsCellBlocked(int, int, Entity*)
World::HasAdjacentIndoorCell(int, int)
World::GetObjectsNextToRoom(ObjectId const&, FastList<ObjectId>&, int)
World::GetObjectsInSector(int, FastList<ObjectId>&, int)
World::GetObjectsWithProperty(int, int, int, FastList<ObjectId>&)
World::CountObjectsWithProperty(int, int, int)
World::ConsiderStackingObject(ObjectId const&, ObjectId const&)
World::ConsiderStackingObject(ObjectId const&)
World::LookupObject(ObjectId const&, int)
World::LookupObject(std::string const&)
World::LookupRoom(std::string const&)
World::CountAttackers(ObjectId const&)
World::CountPrisonerTypes(int*)
World::CountCellsInEachZone(int*, int&)
World::DeathRowSpace()
World::ToggleLockdown()
World::ToggleBangup()
World::WriteCells(Directory*)
World::ReadCells(Directory*)
World::WriteMods(Directory*)
World::ReadMods(Directory*)
World::Write(Directory*)
World::Read(Directory*)
World::ResizedSavedWorld(Directory*, int, int, int, int)
World::GetLandPlotCost(int, int)
World::GetPrisonersDueParole(FastList<ObjectId>&)
World::GetDeathRowPrisoners(FastList<ObjectId>&)
World::LuaGetter(lua_State*)
World::LuaSetter(lua_State*)
World::GetIndoorOutdoorTexture()
World::Update(float)::s_nextRoomIndex
World::GetNearbyObjects(int, int, float, FastList<ObjectId>&, int, bool)::maxNearbyFound
// WorldObject namespace
WorldObject::WorldObject()
WorldObject::WorldObject()
WorldObject::Create()
WorldObject::Initialise()
WorldObject::IsScripted(int)
WorldObject::SetupScriptSystem()
WorldObject::AttachScript(std::string)
WorldObject::RemoveScript()
WorldObject::RegisterScriptSyntax(lua_State*, std::string const&, std::string const&)
WorldObject::ScriptComponentInput(DialogComponent*)
WorldObject::DetermineNearestWalls()
WorldObject::GetBounds(float&, float&, float&, float&)
WorldObject::ApplyVelocity(Vector2 const&, bool)
WorldObject::~WorldObject()
WorldObject::IsLoaded()
WorldObject::IsUtility(int)
WorldObject::~WorldObject()
WorldObject::~WorldObject()
WorldObject::Update(float)
WorldObject::IsBeingCarried()
WorldObject::IsEntity(int)
WorldObject::HasProperty(int)
WorldObject::UpdateAppliedVelocity(float)
WorldObject::ProvideHeat(float)
WorldObject::IsElectrical(int)
WorldObject::InExclusionNoRenderZone()
WorldObject::NotifyUsedAsNeedProvider(std::string const&)
WorldObject::AlwaysRenderPreEffects()
WorldObject::RenderPreEffects()
WorldObject::RenderEffects()
WorldObject::RenderPreSprite(VertexArray*, Vector2 const&, Vector2 const&, Vector2 const&)
WorldObject::RenderPostSprite(VertexArray*, Vector2 const&, Vector2 const&, Vector2 const&)
WorldObject::Damage(float, WorldObject*)
WorldObject::IsBroken()
WorldObject::Destroy()
WorldObject::Create(int)
WorldObject::IsAdministrator(int)
WorldObject::IsWired(int)
WorldObject::IsDoor(int)
WorldObject::IsProcessor(int)
WorldObject::GetTypeId(std::string const&)
WorldObject::NumObjectsExtended()
WorldObject::HasProperty(int, int)
WorldObject::IsMaterial(int)
WorldObject::IsStaff(int)
WorldObject::GetsTired(int)
WorldObject::NotifyCarried(ObjectId const&)
WorldObject::EnsureNotInWall()
WorldObject::NotifyDropped()
WorldObject::NotifyInstalled()
WorldObject::Clone(WorldObject*)
WorldObject::IsCarrying(ObjectId const&)
WorldObject::GetSectorZone(int)
WorldObject::LoadObjectInto(ObjectId const&, int)
WorldObject::NotifyObjectUnloaded(ObjectId const&)
WorldObject::NotifyLoadedInto(ObjectId const&)
WorldObject::NotifyUnloaded()
WorldObject::GetSlotPosition(int, Vector2&, Vector2&)
WorldObject::IsInsideDeliveryTruck()
WorldObject::GetInteractionPoint(ReformProgram*, int)
WorldObject::Read(Directory*)
WorldObject::Write(Directory*)Full Lists
Unfortunately, I cant upload them directly, so heres a link to a gist
https://gist.github.com/MicroTransactionsMatterToo/4337df40304ddaa1078b28d0a2d40272