From 35b4482cd714fa1126496d3319daace8bf9f416d Mon Sep 17 00:00:00 2001 From: CzaroMain Date: Fri, 17 Nov 2023 10:27:51 +0100 Subject: [PATCH] POB Rework - Major performance optimization to health manipulation - Earhart randomization should now never trigger after a server crash - Flattening of Dock_Call hook method - Minor cleanup of unused variables in CoreModule - /base setshield now only accepts valid numeric input --- Plugins/Public/base_plugin/CoreModule.cpp | 19 ++- Plugins/Public/base_plugin/Jumper.cpp | 2 +- Plugins/Public/base_plugin/Main.cpp | 126 +++++++++--------- Plugins/Public/base_plugin/Main.h | 9 +- Plugins/Public/base_plugin/PlayerBase.cpp | 16 ++- Plugins/Public/base_plugin/PlayerCommands.cpp | 19 ++- 6 files changed, 114 insertions(+), 77 deletions(-) diff --git a/Plugins/Public/base_plugin/CoreModule.cpp b/Plugins/Public/base_plugin/CoreModule.cpp index 42d0978a2..1aeb0ec41 100644 --- a/Plugins/Public/base_plugin/CoreModule.cpp +++ b/Plugins/Public/base_plugin/CoreModule.cpp @@ -132,6 +132,8 @@ void CoreModule::Spawn() pub::SpaceObj::SetRelativeHealth(space_obj, base->base_health / base->max_base_health); + base->baseCSolar = (CSolar*)CObject::Find(space_obj, CObject::CSOLAR_OBJECT); + if (shield_reinforcement_threshold_map.count(base->base_level)) base->base_shield_reinforcement_threshold = shield_reinforcement_threshold_map[base->base_level]; else @@ -262,8 +264,11 @@ bool CoreModule::Timer(uint time) uint number_of_crew = base->HasMarketItem(set_base_crew_type); bool isCrewSufficient = number_of_crew >= (base->base_level * 200); - pub::SpaceObj::GetHealth(space_obj, base->base_health, base->max_base_health); + if (wasDamagedSinceLastUpdate) + { + base->base_health = base->baseCSolar->get_hit_pts(); + } if (!dont_rust && ((time % set_damage_tick_time) == 0)) { float no_crew_penalty = isCrewSufficient ? 1.0f : no_crew_damage_multiplier; @@ -289,7 +294,11 @@ bool CoreModule::Timer(uint time) base->base_health = 0; } - pub::SpaceObj::SetRelativeHealth(space_obj, base->base_health / base->max_base_health); + if (wasDamagedSinceLastUpdate) + { + wasDamagedSinceLastUpdate = false; + base->baseCSolar->set_hit_pts(base->base_health); + } // Humans use commodity_oxygen, commodity_water. Consume these for // the crew or kill 10 crew off and repeat this every 12 hours. @@ -386,6 +395,12 @@ float CoreModule::SpaceObjDamaged(uint space_obj, uint attacking_space_obj, floa base->shield_strength_multiplier += shield_reinforcement_increment; } + if (!wasDamagedSinceLastUpdate) + { + base->baseCSolar->set_hit_pts(base->base_health); + wasDamagedSinceLastUpdate = true; + } + base->base_health -= damageTaken; return curr_hitpoints - damageTaken; } diff --git a/Plugins/Public/base_plugin/Jumper.cpp b/Plugins/Public/base_plugin/Jumper.cpp index 7d365d278..45b555ed1 100644 --- a/Plugins/Public/base_plugin/Jumper.cpp +++ b/Plugins/Public/base_plugin/Jumper.cpp @@ -390,5 +390,5 @@ void HyperJump::LoadHyperspaceHubConfig(const string& configPath) } } - WritePrivateProfileString("Timer", "lastRandomization", itos((int)currTime).c_str(), cfg_filehyperspaceHubTimer.c_str()); + WritePrivateProfileString("Timer", "lastRandomization", itos((int)(currTime - (currTime % randomizationCooldown))).c_str(), cfg_filehyperspaceHubTimer.c_str()); } \ No newline at end of file diff --git a/Plugins/Public/base_plugin/Main.cpp b/Plugins/Public/base_plugin/Main.cpp index 561cf0782..6bac5bbba 100644 --- a/Plugins/Public/base_plugin/Main.cpp +++ b/Plugins/Public/base_plugin/Main.cpp @@ -1586,79 +1586,89 @@ int __cdecl Dock_Call(unsigned int const &iShip, unsigned int const &base, int& { returncode = DEFAULT_RETURNCODE; - uint client = HkGetClientIDByShip(iShip); //AP::ClearClientInfo(client); - if (client && (response == PROCEED_DOCK || response == DOCK) && iCancel != -1) + if (!((response == PROCEED_DOCK || response == DOCK) && iCancel != -1)) + { + return 0; + } + PlayerBase* pbase = GetPlayerBase(base); + if (!pbase) + { + return 0; + } + + uint client = HkGetClientIDByShip(iShip); + + if (!client) + { + return 0; + } + + if (mapArchs[pbase->basetype].isjump == 1) { - PlayerBase* pbase = GetPlayerBase(base); - if (pbase) + //check if we have an ID restriction + if (mapArchs[pbase->basetype].idrestriction == 1) { - if (mapArchs[pbase->basetype].isjump == 1) + bool foundid = false; + for (list::iterator item = Players[client].equipDescList.equip.begin(); item != Players[client].equipDescList.equip.end(); item++) { - //check if we have an ID restriction - if (mapArchs[pbase->basetype].idrestriction == 1) + if (item->bMounted && mapArchs[pbase->basetype].allowedids.count(item->iArchID)) { - bool foundid = false; - for (list::iterator item = Players[client].equipDescList.equip.begin(); item != Players[client].equipDescList.equip.end(); item++) - { - if (item->bMounted && mapArchs[pbase->basetype].allowedids.count(item->iArchID)) - { - foundid = true; - break; - } - } - if (foundid == false) - { - PrintUserCmdText(client, L"ERR Unable to dock with this ID."); - iCancel = -1; - response = ACCESS_DENIED; - return 0; - } - } - - //check if we have a shipclass restriction - if (mapArchs[pbase->basetype].shipclassrestriction == 1) - { - bool foundclass = false; - // get the player ship class - Archetype::Ship* TheShipArch = Archetype::GetShip(Players[client].iShipArchetype); - uint shipclass = TheShipArch->iShipClass; - - if(!mapArchs[pbase->basetype].allowedshipclasses.count(shipclass)) - { - PrintUserCmdText(client, L"ERR Unable to dock with a vessel of this type."); - iCancel = -1; - response = ACCESS_DENIED; - return 0; - } + foundid = true; + break; } - - SendJumpObjOverride(client, base, pbase->destSystem); - - return 0; } - - // Shield is up, docking is not possible. - if (pbase->shield_timeout) + if (foundid == false) { - PrintUserCmdText(client, L"Docking failed because base shield is active"); + PrintUserCmdText(client, L"ERR Unable to dock with this ID."); iCancel = -1; response = ACCESS_DENIED; return 0; } + } - if (!IsDockingAllowed(pbase, client)) + //check if we have a shipclass restriction + if (mapArchs[pbase->basetype].shipclassrestriction == 1) + { + bool foundclass = false; + // get the player ship class + Archetype::Ship* TheShipArch = Archetype::GetShip(Players[client].iShipArchetype); + uint shipclass = TheShipArch->iShipClass; + + if(!mapArchs[pbase->basetype].allowedshipclasses.count(shipclass)) { - PrintUserCmdText(client, L"Docking at this base is restricted"); + PrintUserCmdText(client, L"ERR Unable to dock with a vessel of this type."); iCancel = -1; response = ACCESS_DENIED; return 0; } - - SendBaseStatus(client, pbase); } + + SendJumpObjOverride(client, base, pbase->destSystem); + + return 0; + } + + // Shield is up, docking is not possible. + if (pbase->shield_timeout) + { + PrintUserCmdText(client, L"Docking failed because base shield is active"); + iCancel = -1; + response = ACCESS_DENIED; + return 0; + } + + if (!IsDockingAllowed(pbase, client)) + { + PrintUserCmdText(client, L"Docking at this base is restricted"); + iCancel = -1; + response = ACCESS_DENIED; + return 0; } + + SendBaseStatus(client, pbase); + return 0; } @@ -2363,7 +2373,6 @@ void __stdcall HkCb_AddDmgEntry(DamageList *dmg, unsigned short sID, float& newH } } // This call is for us, skip all plugins. - iDmgToSpaceID = 0; newHealth = damagedModule->SpaceObjDamaged(iDmgToSpaceID, dmg->get_inflictor_id(), curr, newHealth); if (newHealth == curr) { @@ -2372,17 +2381,6 @@ void __stdcall HkCb_AddDmgEntry(DamageList *dmg, unsigned short sID, float& newH } returncode = SKIPPLUGINS; - - if (newHealth <= 0 && sID == 1) - { - uint iType; - pub::SpaceObj::GetType(iDmgToSpaceID, iType); - uint iClientIDKiller = HkGetClientIDByShip(dmg->get_inflictor_id()); - if (set_plugin_debug) - ConPrint(L"HkCb_AddDmgEntry[2]: iType is %u, iClientIDKiller is %u\n", iType, iClientIDKiller); - if (iClientIDKiller && iType & (OBJ_DOCKING_RING | OBJ_STATION | OBJ_WEAPONS_PLATFORM)) - BaseDestroyed(iDmgToSpaceID, iClientIDKiller); - } } #define IS_CMD(a) !args.compare(L##a) diff --git a/Plugins/Public/base_plugin/Main.h b/Plugins/Public/base_plugin/Main.h index 9e8cfef79..fba67445e 100644 --- a/Plugins/Public/base_plugin/Main.h +++ b/Plugins/Public/base_plugin/Main.h @@ -145,11 +145,7 @@ class CoreModule : public Module // If true, do not take damage bool dont_rust; - // The list of goods and usage of goods per minute for the autosys effect - map mapAutosysGood; - - // The list of goods and usage of goods per minute for the autosys effect - map mapHumansysGood; + bool wasDamagedSinceLastUpdate; CoreModule(PlayerBase* the_base); ~CoreModule(); @@ -163,7 +159,6 @@ class CoreModule : public Module float SpaceObjDamaged(uint space_obj, uint attacking_space_obj, float curr_hitpoints, float new_hitpoints); bool SpaceObjDestroyed(uint space_obj, bool moveFile = true, bool broadcastDeath = true); void SetReputation(int player_rep, float attitude); - float FindWearNTearModifier(float currHpPercentage); void EnableShieldFuse(bool shieldState); void RepairDamage(float max_base_health); @@ -320,6 +315,8 @@ class PlayerBase // The base nickname string nickname; + CSolar* baseCSolar; + // The base affiliation uint affiliation; diff --git a/Plugins/Public/base_plugin/PlayerBase.cpp b/Plugins/Public/base_plugin/PlayerBase.cpp index 4894faebc..65ee43536 100644 --- a/Plugins/Public/base_plugin/PlayerBase.cpp +++ b/Plugins/Public/base_plugin/PlayerBase.cpp @@ -2,7 +2,7 @@ PlayerBase::PlayerBase(uint client, const wstring &password, const wstring &the_basename) : basename(the_basename), - base(0), money(0), base_health(0), + base(0), money(0), base_health(0), baseCSolar(nullptr), base_level(1), defense_mode(0), proxy_base(0), affiliation(0), siege_mode(false), shield_timeout(0), isShieldOn(false), isFreshlyBuilt(true), shield_strength_multiplier(base_shield_strength), damage_taken_since_last_threshold(0) @@ -36,7 +36,7 @@ PlayerBase::PlayerBase(uint client, const wstring &password, const wstring &the_ } PlayerBase::PlayerBase(const string &the_path) - : path(the_path), base(0), money(0), + : path(the_path), base(0), money(0), baseCSolar(nullptr), base_health(0), base_level(0), defense_mode(0), proxy_base(0), affiliation(0), siege_mode(false), shield_timeout(0), isShieldOn(false), isFreshlyBuilt(false), shield_strength_multiplier(base_shield_strength), damage_taken_since_last_threshold(0) @@ -102,12 +102,20 @@ void PlayerBase::CheckVulnerabilityWindow(uint currTime) base_shield_reinforcement_threshold = FLT_MAX; } } + if (baseCSolar && base_health <= max_base_health) + { + baseCSolar->set_hit_pts(base_health); + } vulnerableWindowStatus = true; } else if (!single_vulnerability_window && IsVulnerabilityWindowActive(vulnerabilityWindow2, timeOfDay)) { if (!vulnerableWindowStatus) { + if (baseCSolar && base_health <= max_base_health) + { + baseCSolar->set_hit_pts(base_health); + } vulnerableWindowStatus = true; siege_mode = true; SyncReputationForBase(); @@ -115,6 +123,10 @@ void PlayerBase::CheckVulnerabilityWindow(uint currTime) } else if (vulnerableWindowStatus) { + if (baseCSolar && base_health <= max_base_health) + { + baseCSolar->set_hit_pts(base_health); + } vulnerableWindowStatus = false; siege_mode = false; SyncReputationForBase(); diff --git a/Plugins/Public/base_plugin/PlayerCommands.cpp b/Plugins/Public/base_plugin/PlayerCommands.cpp index 4a0771543..9985f4ff7 100644 --- a/Plugins/Public/base_plugin/PlayerCommands.cpp +++ b/Plugins/Public/base_plugin/PlayerCommands.cpp @@ -2474,6 +2474,22 @@ namespace PlayerCommands int param1 = ToInt(param1Str); int param2 = ToInt(param2Str); + + if (stows(itos(param1)) != param1Str + || (!single_vulnerability_window && stows(itos(param2)) != param2Str)) + { + PrintUserCmdText(client, L"ERR Provided parameter is not a number!"); + if (single_vulnerability_window) + { + PrintUserCmdText(client, L"Example input: /base setshield 15"); + } + else + { + PrintUserCmdText(client, L"Example input: /base setshield 15 23"); + } + return; + } + if (param1 < 0 || param1 > 23 || (!single_vulnerability_window && (param2 < 0 || param2 > 23))) { @@ -2482,8 +2498,7 @@ namespace PlayerCommands } int vulnerabilityWindowOneStart = param1 * 60; // minutes - int vulnerabilityWindowOneEnd = (vulnerabilityWindowOneStart + vulnerability_window_length) % (60 * 24); // - + int vulnerabilityWindowOneEnd = (vulnerabilityWindowOneStart + vulnerability_window_length) % (60 * 24); int vulnerabilityWindowTwoStart = param2 * 60; int vulnerabilityWindowTwoEnd = (vulnerabilityWindowTwoStart + vulnerability_window_length) % (60 * 24);