From 14367532a3ccfd8d6623503607d9203ad70035d1 Mon Sep 17 00:00:00 2001 From: Aknor Jaden Date: Tue, 10 Apr 2012 08:50:19 -0400 Subject: [PATCH] Finished my merge of Module Manager work on incursion into crucible. Tested build on windows vista 32-bit, logged in, undocked, warped, jumped, docked. All seems fine so far. Let me know if there are any new problems. I also reversed, AGAIN, the z-axis calculations in the DestinyManager::AttempDockOperation() and increased the minimum dock perimeter to 1500m from 500m. This seems to allow you to insta-dock when warping to 0m on a station. --- include/eve-server/EVEServerPCH.h | 5 + include/eve-server/ship/ModuleManager.h | 352 ++++---- .../eve-server/ship/Modules/ActiveModules.h | 134 +-- include/eve-server/ship/Modules/ModuleDB.h | 75 +- include/eve-server/ship/Modules/ModuleDefs.h | 173 +++- .../eve-server/ship/Modules/ModuleEffects.h | 442 +++------- .../eve-server/ship/Modules/ModuleFactory.h | 132 +-- include/eve-server/ship/Modules/Modules.h | 120 ++- .../eve-server/ship/Modules/PassiveModules.h | 55 +- include/eve-server/ship/Modules/RigModule.h | 26 +- .../ship/Modules/SubSystemModules.h | 23 +- .../ActiveModuleProcessingComponent.h | 52 +- .../ModifyShipAttributesComponent.h | 118 +-- include/eve-server/ship/Ship.h | 53 +- .../eve-server/ship/ShipOperatorInterface.h | 15 +- .../eve-server/ship/dgmtypeattributeinfo.h | 25 + src/eve-server/CMakeLists.txt | 17 +- src/eve-server/ship/DestinyManager.cpp | 15 +- src/eve-server/ship/ModuleManager.cpp | 813 +++++++++++------- src/eve-server/ship/Ship.cpp | 129 +-- src/eve-server/ship/ShipOperatorInterface.cpp | 15 + 21 files changed, 1311 insertions(+), 1478 deletions(-) diff --git a/include/eve-server/EVEServerPCH.h b/include/eve-server/EVEServerPCH.h index 0432c580..14630d2c 100644 --- a/include/eve-server/EVEServerPCH.h +++ b/include/eve-server/EVEServerPCH.h @@ -232,6 +232,7 @@ // item stuff #include "inventory/AttributeEnum.h" #include "inventory/AttributeMgr.h" +#include "inventory/EffectsEnum.h" #include "inventory/EVEAttributeMgr.h" #include "inventory/InvBrokerService.h" #include "inventory/Inventory.h" @@ -314,6 +315,7 @@ #include "ship/Modules/components/ActiveModuleProcessingComponent.h" #include "ship/Modules/components/ModifyShipAttributesComponent.h" + #include "ship/Modules/ModuleDB.h" #include "ship/Modules/ModuleFactory.h" #include "ship/Modules/Modules.h" @@ -323,6 +325,9 @@ #include "ship/Modules/PassiveModules.h" #include "ship/Modules/RigModule.h" #include "ship/Modules/SubSystemModules.h" + +#include "ship/Modules/propulsion_modules/Afterburner.h" + #include "ship/ModuleManager.h" #include "ship/BeyonceService.h" #include "ship/DestinyManager.h" diff --git a/include/eve-server/ship/ModuleManager.h b/include/eve-server/ship/ModuleManager.h index c6e41aa7..724cd3de 100644 --- a/include/eve-server/ship/ModuleManager.h +++ b/include/eve-server/ship/ModuleManager.h @@ -31,6 +31,7 @@ class InventoryItem; class GenericModule; class SystemEntity; class Client; +class ModuleManager; #include "ship/Modules/Modules.h" #include "ship/Modules/ModuleDefs.h" @@ -41,98 +42,106 @@ class Client; class ModuleContainer { public: - ModuleContainer(uint32 lowSlots, uint32 medSlots, uint32 highSlots, uint32 rigSlots, uint32 subSystemSlots); - ~ModuleContainer(); - - void AddModule(uint32 flag, GenericModule * mod); - void RemoveModule(EVEItemFlags flag); - void RemoveModule(uint32 itemID); - GenericModule * GetModule(EVEItemFlags flag); - GenericModule * GetModule(uint32 itemID); - - int NumberOfSameType(uint32 typeID); - - //batch processes handlers - void Process(); - void OfflineAll(); - void OnlineAll(); - void DeactivateAll(); - void UnloadAll(); - - //useful accessors - bool isHighPower(uint32 itemID); - bool isMediumPower(uint32 itemID); - bool isLowPower(uint32 itemID); - bool isRig(uint32 itemID); - bool isSubSystem(uint32 itemID); + ModuleContainer(uint32 lowSlots, uint32 medSlots, uint32 highSlots, uint32 rigSlots, uint32 subSystemSlots, + uint32 turretSlots, uint32 launcherSlots, ModuleManager * myManager); + ~ModuleContainer(); + + void AddModule(uint32 flag, GenericModule * mod); + void RemoveModule(EVEItemFlags flag); + void RemoveModule(uint32 itemID); + GenericModule * GetModule(EVEItemFlags flag); + GenericModule * GetModule(uint32 itemID); + + int NumberOfSameType(uint32 typeID); + + //batch processes handlers + void Process(); + void OfflineAll(); + void OnlineAll(); + void DeactivateAll(); + void UnloadAll(); + + //useful accessors + bool isHighPower(uint32 itemID); + bool isMediumPower(uint32 itemID); + bool isLowPower(uint32 itemID); + bool isRig(uint32 itemID); + bool isSubSystem(uint32 itemID); + + uint32 GetFittedTurretCount() { return m_TotalTurretsFitted; } + uint32 GetFittedLauncherCount() { return m_TotalLaunchersFitted; } + uint32 GetFittedModuleCountByGroup(uint32 groupID); + + void SaveModules(); private: - //internal enums - enum processType - { - typeOnlineAll, - typeOfflineAll, - typeDeactivateAll, - typeUnloadAll, - typeProcessAll - }; - - enum slotType - { - highSlot, - mediumSlot, - lowSlot, - rigSlot, - subSystemSlot - }; - - void _removeModule(EVEItemFlags flag); - - void _process(processType p); - void _processEx(processType p, slotType t); - - void _addHighSlotModule(uint32 flag, GenericModule * mod); - void _addMediumSlotModule(uint32 flag, GenericModule * mod); - void _addLowSlotModule(uint32 flag, GenericModule * mod); - void _addRigModule(uint32 flag, GenericModule * mod); - void _addSubSystemModule(uint32 flag, GenericModule * mod); - - GenericModule * _getHighSlotModule(uint32 flag); - GenericModule * _getMediumSlotModule(uint32 flag); - GenericModule * _getLowSlotModule(uint32 flag); - GenericModule * _getRigModule(uint32 flag); - GenericModule * _getSubSystemModule(uint32 flag); - - void _removeHighSlotModule(uint32 flag); - void _removeMediumSlotModule(uint32 flag); - void _removeLowSlotModule(uint32 flag); - void _removeRigSlotModule(uint32 flag); - void _removeSubSystemModule(uint32 flag); - - EVEItemSlotType _checkBounds(uint32 flag); - - bool _isLowSlot(uint32 flag); - bool _isMediumSlot(uint32 flag); - bool _isHighSlot(uint32 flag); - bool _isRigSlot(uint32 flag); - bool _isSubSystemSlot(uint32 flag); - - void _initializeModuleContainers(); - - //we own these - GenericModule ** m_HighSlotModules; - GenericModule ** m_MediumSlotModules; - GenericModule ** m_LowSlotModules; - GenericModule ** m_RigModules; - GenericModule ** m_SubSystemModules; - - uint32 m_LowSlots; - uint32 m_MediumSlots; - uint32 m_HighSlots; - uint32 m_RigSlots; - uint32 m_SubSystemSlots; - + //internal enums + enum processType + { + typeOnlineAll, + typeOfflineAll, + typeDeactivateAll, + typeUnloadAll, + typeProcessAll + }; + + enum slotType + { + highSlot, + mediumSlot, + lowSlot, + rigSlot, + subSystemSlot + }; + + void _removeModule(EVEItemFlags flag, GenericModule * mod); + + void _process(processType p); + void _processEx(processType p, slotType t); + + GenericModule * _getHighSlotModule(uint32 flag); + GenericModule * _getMediumSlotModule(uint32 flag); + GenericModule * _getLowSlotModule(uint32 flag); + GenericModule * _getRigModule(uint32 flag); + GenericModule * _getSubSystemModule(uint32 flag); + + void _removeHighSlotModule(uint32 flag); + void _removeMediumSlotModule(uint32 flag); + void _removeLowSlotModule(uint32 flag); + void _removeRigSlotModule(uint32 flag); + void _removeSubSystemModule(uint32 flag); + + EVEItemSlotType _checkBounds(uint32 flag); + + bool _isLowSlot(uint32 flag); + bool _isMediumSlot(uint32 flag); + bool _isHighSlot(uint32 flag); + bool _isRigSlot(uint32 flag); + bool _isSubSystemSlot(uint32 flag); + + void _initializeModuleContainers(); + + //we own these + GenericModule ** m_HighSlotModules; + GenericModule ** m_MediumSlotModules; + GenericModule ** m_LowSlotModules; + GenericModule ** m_RigModules; + GenericModule ** m_SubSystemModules; + + uint32 m_LowSlots; + uint32 m_MediumSlots; + uint32 m_HighSlots; + uint32 m_RigSlots; + uint32 m_SubSystemSlots; + uint32 m_TurretSlots; + uint32 m_LauncherSlots; + + uint32 m_TotalTurretsFitted; + uint32 m_TotalLaunchersFitted; + std::map m_ModulesFittedByGroupID; + + ModuleManager * m_MyManager; // we do not own this }; #pragma endregion @@ -146,25 +155,25 @@ class SubEffect { public: - SubEffect(uint32 attrID, EVECalculationType type, EvilNumber val, uint32 targetItemID = 0) - : m_AttrID( attrID ), m_TargetItemID( targetItemID ), m_CalcType( type ), m_Val( val ) - { + SubEffect(uint32 attrID, EVECalculationType type, EvilNumber val, uint32 targetItemID = 0) + : m_AttrID( attrID ), m_TargetItemID( targetItemID ), m_CalcType( type ), m_Val( val ) + { - } + } - ~SubEffect() { } + ~SubEffect() { } - //gets - uint32 AttributeID() { return m_AttrID; } - uint32 TargetItemID() { return m_TargetItemID; } - EVECalculationType CalculationType() { return m_CalcType; } - EvilNumber AppliedValue() { return m_Val; } + //gets + uint32 AttributeID() { return m_AttrID; } + uint32 TargetItemID() { return m_TargetItemID; } + EVECalculationType CalculationType() { return m_CalcType; } + EvilNumber AppliedValue() { return m_Val; } private: - uint32 m_AttrID; - uint32 m_TargetItemID; - EVECalculationType m_CalcType; - EvilNumber m_Val; + uint32 m_AttrID; + uint32 m_TargetItemID; + EVECalculationType m_CalcType; + EvilNumber m_Val; }; @@ -173,42 +182,42 @@ class SubEffect class Effect { public: - Effect() - : m_Count( 0 ) - { + Effect() + : m_Count( 0 ) + { - } + } - ~Effect() - { + ~Effect() + { for (int i = 0; i <= m_Count; i++) { delete m_SubEffects[i]; } - } + } - void AddEffect(uint32 attributeID, EVECalculationType type, EvilNumber val, uint32 targetItemID = 0) - { - SubEffect * s = new SubEffect(attributeID, type, val, targetItemID); - if( m_Count + 1 < MAX_EFFECT_COUNT ) - { - m_SubEffects[m_Count] = s; - m_Count++; - } - } + void AddEffect(uint32 attributeID, EVECalculationType type, EvilNumber val, uint32 targetItemID = 0) + { + SubEffect * s = new SubEffect(attributeID, type, val, targetItemID); + if( m_Count + 1 < MAX_EFFECT_COUNT ) + { + m_SubEffects[m_Count] = s; + m_Count++; + } + } - bool hasEffect() { return (m_Count > 0); } + bool hasEffect() { return (m_Count > 0); } - SubEffect * next() - { - m_Count--; - return m_SubEffects[m_Count]; + SubEffect * next() + { + m_Count--; + return m_SubEffects[m_Count]; - } + } private: - SubEffect * m_SubEffects[MAX_EFFECT_COUNT]; - int m_Count; + SubEffect * m_SubEffects[MAX_EFFECT_COUNT]; + int m_Count; }; @@ -220,57 +229,62 @@ class Effect class ModuleManager { public: - ModuleManager(Ship *const ship); - ~ModuleManager(); - - void InstallRig(InventoryItemRef item); - void UninstallRig(uint32 itemID); - void InstallSubSystem(InventoryItemRef item); - void SwapSubSystem(InventoryItemRef item); - void FitModule(InventoryItemRef item); - void UnfitModule(uint32 itemID); - void Online(uint32 itemID); - void OnlineAll(); - void Offline(uint32 itemID); - void OfflineAll(); - int32 Activate(uint32 itemID, std::string effectName, uint32 targetID, uint32 repeat); - void Deactivate(uint32 itemID, std::string effecetName); - void DeactivateAllModules(); - void Overload(uint32 itemID); - void DeOverload(uint32 itemID); - void DamageModule(uint32 itemID, EvilNumber val); - void RepairModule(uint32 itemID); - void ReplaceCharges(); - void UnloadAllModules(); - void CharacterLeavingShip(); - void CharacterBoardingShip(); - void ShipWarping(); - void ShipJumping(); - void Process(); - void ProcessExternalEffect(Effect * e); - std::vector GetStackedItems(uint32 typeID, ModulePowerLevel level); //should only be used by components + ModuleManager(Ship *const ship); + ~ModuleManager(); + + bool IsSlotOccupied(uint32 flag); + + bool InstallRig(InventoryItemRef item, EVEItemFlags flag); + void UninstallRig(uint32 itemID); + bool InstallSubSystem(InventoryItemRef item, EVEItemFlags flag); + bool SwapSubSystem(InventoryItemRef item, EVEItemFlags flag); + bool FitModule(InventoryItemRef item, EVEItemFlags flag); + void UnfitModule(uint32 itemID); + void Online(uint32 itemID); + void OnlineAll(); + void Offline(uint32 itemID); + void OfflineAll(); + int32 Activate(uint32 itemID, std::string effectName, uint32 targetID, uint32 repeat); + void Deactivate(uint32 itemID, std::string effectName); + void DeactivateAllModules(); + void Overload(uint32 itemID); + void DeOverload(uint32 itemID); + void DamageModule(uint32 itemID, EvilNumber val); + void RepairModule(uint32 itemID); + void ReplaceCharges(); + void UnloadAllModules(); + void CharacterLeavingShip(); + void CharacterBoardingShip(); + void ShipWarping(); + void ShipJumping(); + void Process(); + void ProcessExternalEffect(Effect * e); + std::vector GetStackedItems(uint32 typeID, ModulePowerLevel level); //should only be used by components + + GenericModule * GetModule(EVEItemFlags flag) { return m_Modules->GetModule(flag); } + GenericModule * GetModule(uint32 itemID) { return m_Modules->GetModule(itemID); } + + void SaveModules(); private: - void _fitModule(InventoryItemRef item); - - void _processExternalEffect(SubEffect * e); - - ModuleCommand _translateEffectName(std::string s); + bool _fitModule(InventoryItemRef item, EVEItemFlags flag); + void _processExternalEffect(SubEffect * e); - void _SendInfoMessage(const char* fmt, ...); - void _SendErrorMessage(const char* fmt, ...); + ModuleCommand _translateEffectName(std::string s); - //access to the ship that owns us. We do not own this - Ship * m_Ship; - //access to destiny. We do not own this - DestinyManager * m_Destiny; + void _SendInfoMessage(const char* fmt, ...); + void _SendErrorMessage(const char* fmt, ...); - //modules storage, we own this - ModuleContainer * m_Modules; + //access to the ship that owns us. We do not own this + Ship * m_Ship; + //access to destiny. We do not own this + DestinyManager * m_Destiny; + //modules storage, we own this + ModuleContainer * m_Modules; }; #pragma endregion diff --git a/include/eve-server/ship/Modules/ActiveModules.h b/include/eve-server/ship/Modules/ActiveModules.h index 3200dd05..e34d8e8b 100644 --- a/include/eve-server/ship/Modules/ActiveModules.h +++ b/include/eve-server/ship/Modules/ActiveModules.h @@ -33,120 +33,38 @@ class ActiveModule : public GenericModule { public: - ActiveModule(InventoryItemRef item, ShipRef ship) + ActiveModule(InventoryItemRef item, ShipRef ship); + ~ActiveModule(); + + void Process(); + void Offline(); + void Online(); + void Activate(uint32 targetID); + void Deactivate(); + + //access functions + ModulePowerLevel GetModulePowerLevel() { return isHighPower() ? HIGH_POWER : ( isMediumPower() ? MEDIUM_POWER : LOW_POWER); } + + bool isHighPower() { return m_Effects->isHighSlot(); } + bool isMediumPower() { return m_Effects->isMediumSlot(); } + bool isLowPower() { return m_Effects->isLowSlot(); } + bool isRig() { return false; } + bool isSubSystem() { return false; } + bool requiresTarget() { - m_Item = item; - m_Ship = ship; - m_Effects = new ModuleEffects(m_Item->typeID()); - m_ShipAttrComp = new ModifyShipAttributesComponent(this, ship); + if( m_Effects->HasDefaultEffect() ) + return m_Effects->GetDefaultEffect()->GetIsAssistance() || m_Effects->GetDefaultEffect()->GetIsOffensive(); + else + return false; } - virtual ~ActiveModule() - { - //delete members - delete m_Effects; - delete m_ShipAttrComp; - - //null ptrs - m_Effects = NULL; - m_ShipAttrComp = NULL; - } - - void Process() - { - - } - - void Offline() - { - - } - - void Online() - { - - } - - void Activate(uint32 targetID) - { - - } - - void Deactivate() - { - - } - - //access functions - ModulePowerLevel GetModulePowerLevel() { return isHighPower() ? HIGH_POWER : ( isMediumPower() ? MEDIUM_POWER : LOW_POWER); } - - bool isHighPower() { return m_Effects->isHighSlot(); } - bool isMediumPower() { return m_Effects->isMediumSlot(); } - bool isLowPower() { return m_Effects->isLowSlot(); } - bool isRig() { return false; } - bool isSubSystem() { return false; } - bool requiresTarget() { return m_Effects->GetIsAssistance() || m_Effects->GetIsOffensive(); } - protected: - ModifyShipAttributesComponent * m_ShipAttrComp; - uint32 targetID; //passed to us by activate + ModifyShipAttributesComponent * m_ShipAttrComp; + uint32 targetID; //passed to us by activate - //inheritance crap - ActiveModule() { } + //inheritance crap + ActiveModule() {} }; -class Afterburner : public ActiveModule -{ -public: - - Afterburner( InventoryItemRef item, ShipRef ship ) - { - m_Item = item; - m_Ship = ship; - m_Effects = new ModuleEffects(m_Item->typeID()); - m_ShipAttrComp = new ModifyShipAttributesComponent(this, ship); - } - - ~Afterburner() - { - - } - - - - void Load() - { - - } - - void Unload() - { - - } - - void Repair() - { - - } - - void Overload() - { - - } - - void DeOverload() - { - - } - - void DestroyRig() - { - - } - - - -}; - #endif \ No newline at end of file diff --git a/include/eve-server/ship/Modules/ModuleDB.h b/include/eve-server/ship/Modules/ModuleDB.h index a807f573..0758f028 100644 --- a/include/eve-server/ship/Modules/ModuleDB.h +++ b/include/eve-server/ship/Modules/ModuleDB.h @@ -23,87 +23,22 @@ Author: Luck */ - - - #ifndef MODULE_DB_H #define MODULE_DB_H #include "ServiceDB.h" + //yes, a moduleDB class. This will not be fun class ModuleDB : public ServiceDB { public: - static void GetDgmEffects(uint32 effectID, DBQueryResult &res) - { - if(sDatabase.RunQuery(res, - " SELECT " - " effectName, " - " effectCategory, " - " preExpression, " - " postExpression, " - " description, " - " guid, " - " graphicID, " - " isOffensive, " - " isAssistance, " - " durationAttributeID, " - " trackingSpeedAttributeID, " - " dischargeAttributeID, " - " rangeAttributeID, " - " falloffAttributeID, " - " disallowAutoRepeat, " - " published, " - " displayName, " - " isWarpSafe, " - " rangeChance, " - " electronicChance, " - " propulsionChance, " - " distribution, " - " sfxName, " - " npcUsageChanceAttributeID, " - " npcActivationChanceAttributeID, " - " fittingUsageChanceAttributeID " - " FROM dgmEffects " - " WHERE effectID = '%u' ", - effectID)) - { - _log(DATABASE__ERROR, "Error in query: %s", res.error.c_str()); - } - } - - static void GetDgmEffectsInfo(uint32 effectID, DBQueryResult &res) - { - if(sDatabase.RunQuery(res, - " SELECT " - " targetAttributeID, " - " sourceAttributeID, " - " calculationTypeID, " - " reverseCalculationTypeID " - " FROM dgmEffectsInfo " - " WHERE effectID = '%u' ", - effectID)) - { - _log(DATABASE__ERROR, "Error in query: %s", res.error.c_str()); - } - } - - static void GetDgmTypeEffectsInformation(uint32 typeID, DBQueryResult &res) - { - if(sDatabase.RunQuery(res, - " SELECT " - " effectID, " - " isDefault " - " FROM dgmTypeEffects " - " WHERE typeID = '%u' ", - typeID)) - { - _log(DATABASE__ERROR, "Error in query: %s", res.error.c_str()); - } + static void GetDgmEffects(uint32 effectID, DBQueryResult &res); + static void GetDgmEffectsInfo(uint32 effectID, DBQueryResult &res); + static void GetDgmEffectsActions(uint32 effectID, DBQueryResult &res); + static void GetDgmTypeEffectsInformation(uint32 typeID, DBQueryResult &res); - } }; diff --git a/include/eve-server/ship/Modules/ModuleDefs.h b/include/eve-server/ship/Modules/ModuleDefs.h index 5e67ebe2..532eb856 100644 --- a/include/eve-server/ship/Modules/ModuleDefs.h +++ b/include/eve-server/ship/Modules/ModuleDefs.h @@ -32,101 +32,180 @@ //this is to avoid include complications and multiple dependancies etc.. enum ModuleCommand { - CMD_ERROR, - ONLINE, - OFFLINE, - ACTIVATE, - DEACTIVATE, - OVERLOAD, //idk if this is used yet - or what it's called :) - DEOVERLOAD //idk if this is used + CMD_ERROR, + ONLINE, + OFFLINE, + ACTIVATE, + DEACTIVATE, + OVERLOAD, //idk if this is used yet - or what it's called :) + DEOVERLOAD, //idk if this is used + LOAD_CHARGE, + RELOAD_CHARGE, + UNLOAD_CHARGE +}; + +enum ModuleStates +{ + MOD_UNFITTED, + MOD_OFFLINE, + MOD_ONLINE, + MOD_ACTIVATED, + MOD_DEACTIVATING, + MOD_OVERLOADED +}; + +enum ChargeStates +{ + MOD_UNLOADED, + MOD_LOADED, + MOD_LOADING, + MOD_RELOADING +}; + +// These are the module states where an effect will, ahem, take 'effect': +// *** use these values to decode the 'effectAppliedInState' field of the 'dgmEffectsInfo' database table +enum ModuleEffectTriggers +{ + EFFECT_ONLINE, // means the effect takes effect on the target (see below) upon entering the ONLINE state + EFFECT_ACTIVE, // used only for ACTIVE modules operating in non-Overloaded mode + EFFECT_OVERLOAD // used only for ACTIVE modules operating in Overloaded mode +}; + +// These are the targets to which module effects are applied when activated: +// *** use these values to decode the 'effectAppliedTo' field of the 'dgmEffectsInfo' database table +enum ModuleEffectTargets +{ + SELF, // means the target of the effect is the module's own attribute(s) + SHIP, // means the target of the effect is the attribute(s) of the ship to which the module is fitted + TARGET // means the target of the effect is the attribute(s) of the current target of the ship to which the module is fitted +}; + +// These are the methods by which module effects are applied to the designated target: +// *** use these values to decode the 'effectApplicationType' field of the 'dgmEffectsInfo' database table +enum ModuleApplicationTypes +{ + EFFECT_ONLINE_MAINTAIN, // applied by PASSIVE or ACTIVE modules where an effect is maintained; means the effect takes effect on the + // target (see below) upon entering the ONLINE state, then reversed when going out of ONLINE state + EFFECT_ACTIVE_MAINTAIN, // applied by ACTIVE modules where an effect is maintained; means the effect takes effect on the + // target (see below) upon entering the ACTIVATE state, then reversed when going out of ACTIVATE state + EFFECT_ACTIVE_CONSUME // applied by ACTIVE modules where an effect is applied cumulatively on each cycle; means the effect takes +}; // effect on the target (see below) one extra time when in ACTIVATE state after each CYCLE duration expires + +// These are the methods by which module effects are applied to the designated target: +// *** use these values to decode the 'stackingPenaltyApplied' field of the 'dgmEffectsInfo' database table +enum ModuleStackingPenaltyState +{ + NO_PENALTY, + PENALTY }; //this may or may not be redundant...idk enum ModulePowerLevel { - HIGH_POWER, - MEDIUM_POWER, - LOW_POWER, - RIG, - SUBSYSTEM + HIGH_POWER, + MEDIUM_POWER, + LOW_POWER, + RIG, + SUBSYSTEM }; //calculation types +// *** use these values to decode the 'calculationTypeID' and the 'reverseCalculationTypeID' fields of the 'dgmEffectsInfo' database table enum EVECalculationType { - ADD, - SUBTRACT, - DIVIDE, - MULTIPLY, - ADD_PERCENT, - SUBTRACT_PERCENT, - ADD_AS_PERCENT, - SUBTRACT_AS_PERCENT - //more will show up, im sure + NONE, + AUTO, + ADD, + SUBTRACT, + DIVIDE, + MULTIPLY, + ADD_PERCENT, + REV_ADD_PERCENT, + SUBTRACT_PERCENT, + REV_SUBTRACT_PERCENT, + ADD_AS_PERCENT, + SUBTRACT_AS_PERCENT + //more will show up, im sure }; //TODO - check mem usage static EvilNumber Add(EvilNumber &val1, EvilNumber &val2) { - return val1 + val2; + return val1 + val2; } static EvilNumber Subtract(EvilNumber &val1, EvilNumber &val2) { - return val1 - val2; + return val1 - val2; } static EvilNumber Divide(EvilNumber &val1, EvilNumber &val2) { - return ( val1 / val2 ); + return ( val1 / val2 ); } static EvilNumber Multiply(EvilNumber &val1, EvilNumber &val2) { - return val1 * val2; + return val1 * val2; } static EvilNumber AddPercent(EvilNumber &val1, EvilNumber &val2) { - return val1 + ( val1 * val2 ); + return val1 + ( val1 * val2 ); } -static EvilNumber AddAsPercent(EvilNumber &val1, EvilNumber &val2) +static EvilNumber ReverseAddPercent(EvilNumber &val1, EvilNumber &val2) { - EvilNumber val3 = 100; - return val1 + ( val1 * val2 / val3 ); + EvilNumber val3 = 1; + return val1 / (val3 + val2); } static EvilNumber SubtractPercent(EvilNumber &val1, EvilNumber &val2) { - return val1 - ( val1 * val2 ); + return val1 - ( val1 * val2 ); } -static EvilNumber SubtractAsPercent(EvilNumber &val1, EvilNumber &val2) +static EvilNumber ReverseSubtractPercent(EvilNumber &val1, EvilNumber &val2) { EvilNumber val3 = 1; - EvilNumber val4 = 100; + return val1 / ( val3 - val2 ); +} + +static EvilNumber AddAsPercent(EvilNumber &val1, EvilNumber &val2) +{ + EvilNumber val3 = 100; + return val1 + ( val1 * (val2 / val3) ); +} + +static EvilNumber SubtractAsPercent(EvilNumber &val1, EvilNumber &val2) +{ + EvilNumber val3 = 1; + EvilNumber val4 = 100; - return val1 / ( val3 + ( val2 / val4 )); + return val1 / ( val3 + ( val2 / val4 )); } static EvilNumber CalculateNewAttributeValue(EvilNumber attrVal, EvilNumber attrMod, EVECalculationType type) { - switch(type) - { - case ADD : return Add(attrVal, attrMod); - case SUBTRACT : return Subtract(attrVal, attrMod); - case DIVIDE : return Divide(attrVal, attrMod); - case MULTIPLY : return Multiply(attrVal, attrMod); - case ADD_PERCENT : return AddPercent(attrVal, attrMod); - case ADD_AS_PERCENT : return AddAsPercent(attrVal, attrMod); - case SUBTRACT_PERCENT : return SubtractPercent(attrVal, attrMod); - case SUBTRACT_AS_PERCENT : return SubtractAsPercent(attrVal, attrMod); - } - - sLog.Error("CalculateNewAttributeValue", "Unknown EveCalculationType used"); - assert(false); + switch(type) + { + case NONE : return attrVal; + case AUTO : return attrVal; // AUTO NOT SUPPORTED AT THIS TIME !!! + case ADD : return Add(attrVal, attrMod); + case SUBTRACT : return Subtract(attrVal, attrMod); + case DIVIDE : return Divide(attrVal, attrMod); + case MULTIPLY : return Multiply(attrVal, attrMod); + case ADD_PERCENT : return AddPercent(attrVal, attrMod); + case REV_ADD_PERCENT : return ReverseAddPercent(attrVal, attrMod); + case SUBTRACT_PERCENT : return SubtractPercent(attrVal, attrMod); + case REV_SUBTRACT_PERCENT : return ReverseSubtractPercent(attrVal, attrMod); + case ADD_AS_PERCENT : return AddAsPercent(attrVal, attrMod); + case SUBTRACT_AS_PERCENT : return SubtractAsPercent(attrVal, attrMod); + } + + sLog.Error("CalculateNewAttributeValue", "Unknown EveCalculationType used"); + assert(false); return NULL; } diff --git a/include/eve-server/ship/Modules/ModuleEffects.h b/include/eve-server/ship/Modules/ModuleEffects.h index b61841f0..0ff8ad86 100644 --- a/include/eve-server/ship/Modules/ModuleEffects.h +++ b/include/eve-server/ship/Modules/ModuleEffects.h @@ -26,347 +26,139 @@ #ifndef MODULE_EFFECTS_H #define MODULE_EFFECTS_H -//class contained by all modules that is populated on construction of the module -//this will contain all information about the effects of the module - #include "ModuleDB.h" -class ModuleEffects +class MEffect { public: - ModuleEffects(uint32 typeID) : m_TypeID( typeID ), m_Cached( false ) - { - _populate(typeID); - } - - ~ModuleEffects() - { - //delete arrays - delete[] m_Effects; - delete[] m_EffectIDs; - - //null ptrs - m_EffectIDs = NULL; - m_Effects = NULL; - } - - //useful accessors - probably a better way to do this, but at least it's fast - bool isHighSlot() - { - if( m_Cached ) - return m_HighPower; - else - { - for(uint32 i = 0; i < m_EffectCount; i++) - { - if( m_EffectIDs[i] == effectHiPower ) - { - m_HighPower = true; - m_MediumPower = false; - m_LowPower = false; - m_Cached = true; //cache the result - return true; - } - } - } - - return false; - } - - bool isMediumSlot() - { - if( m_Cached ) - return m_MediumPower; - else - { - for(uint32 i = 0; i < m_EffectCount; i++) - { - if( m_EffectIDs[i] == effectMedPower ) - { - m_HighPower = false; - m_MediumPower = true; - m_LowPower = false; - m_Cached = true; //cache the result - return true; - } - } - } - - return false; - } - - bool isLowSlot() - { - if( m_Cached ) - return m_LowPower; - else - { - for(uint32 i = 0; i < m_EffectCount; i++) - { - if( m_EffectIDs[i] == effectLoPower ) - { - m_HighPower = false; - m_MediumPower = false; - m_LowPower = true; - m_Cached = true; //cache the result - return true; - } - } - } - - return false; - } - - //this will need to be reworked to implement a singleton architecture...i'll do it later -luck - - //this class uses a system to set the "active effect" that you want to get information about - //returns false if the effect specified is not found - bool SetActiveEffect(uint32 effectID) - { - //iterate through the effects to find the one we want - for(uint32 i = 0; i < m_EffectCount; i++) - { - if(m_EffectIDs[i] == effectID) - { - m_SelectedEffect = i; - return true; - } - - } - - return false; - } - - bool SetDefaultEffectAsActive() - { - //iterate through the effects to find the one we want - if(m_DefaultEffect != 0) - { - m_SelectedEffect = m_DefaultEffect; - return true; - } - - return false; - } - - //accessors for selected effect - uint32 GetEffectID() { return m_Effects[m_SelectedEffect].m_EffectID; } - std::string GetEffectName() { return m_Effects[m_SelectedEffect].m_EffectName; } - uint32 GetEffectCategory() { return m_Effects[m_SelectedEffect].m_EffectCategory; } - uint32 GetPreExpression() { return m_Effects[m_SelectedEffect].m_PreExpression; } - uint32 GetPostExpression() { return m_Effects[m_SelectedEffect].m_PostExpression; } - std::string GetDescription() { return m_Effects[m_SelectedEffect].m_Description; } - std::string GetGuid() { return m_Effects[m_SelectedEffect].m_Guid; } - uint32 GetIconID() { return m_Effects[m_SelectedEffect].m_IconID; } - bool GetIsOffensive() { return m_Effects[m_SelectedEffect].m_IsOffensive == 1; } - bool GetIsAssistance() { return m_Effects[m_SelectedEffect].m_IsAssistance == 1; } - uint32 GetDurationAttributeID() { return m_Effects[m_SelectedEffect].m_DurationAttributeID; } - uint32 GetTrackingSpeedAttributeID() { return m_Effects[m_SelectedEffect].m_TrackingSpeedAttributeID; } - uint32 GetDischargeAttributeID() { return m_Effects[m_SelectedEffect].m_DischargeAttributeID; } - uint32 GetRangeAttributeID() { return m_Effects[m_SelectedEffect].m_RangeAttributeID; } - uint32 GetFalloffAttributeID() { return m_Effects[m_SelectedEffect].m_FalloffAttributeID; } - bool GetDisallowAutoRepeat() { return m_Effects[m_SelectedEffect].m_DisallowAutoRepeat == 1; } - bool GetIsPublished() { return m_Effects[m_SelectedEffect].m_Published == 1; } - std::string GetDisplayName() { return m_Effects[m_SelectedEffect].m_DisplayName; } - bool GetIsWarpSafe() { return m_Effects[m_SelectedEffect].m_IsWarpSafe == 1; } - bool GetRangeChance() { return m_Effects[m_SelectedEffect].m_RangeChance == 1; } - bool GetPropulsionChance() { return m_Effects[m_SelectedEffect].m_PropulsionChance == 1; } - bool GetElectronicChance() { return m_Effects[m_SelectedEffect].m_ElectronicChance == 1; } - uint32 GetDistribution() { return m_Effects[m_SelectedEffect].m_Distribution; } - std::string GetSfxName() { return m_Effects[m_SelectedEffect].m_DisplayName; } - uint32 GetNpcUsageChanceAttributeID() { return m_Effects[m_SelectedEffect].m_NpcUsageChanceAttributeID; } - uint32 GetNpcActivationChanceAttributeID() { return m_Effects[m_SelectedEffect].m_NpcActivationChanceAttributeID; } - uint32 GetFittingUsageChanceAttributeID() { return m_Effects[m_SelectedEffect].m_FittingUsageChanceAttributeID; } - - //accessors for the effects targetAttributeID, sourceAttributeID and calculation type - uint32 GetSizeOfAttributeList() { return m_Effects[m_SelectedEffect].m_numOfIDs; } - uint32 GetTargetAttributeID(uint32 count) { return m_Effects[m_SelectedEffect].m_TargetAttributeIDs[count]; } - uint32 GetSourceAttributeID(uint32 count) { return m_Effects[m_SelectedEffect].m_SourceAttributeIDs[count]; } - EVECalculationType GetCalculationType(uint32 count) { return (EVECalculationType)m_Effects[m_SelectedEffect].m_CalculationTypeID[count];} - EVECalculationType GetReverseCalculationType(uint32 count) { return (EVECalculationType)m_Effects[m_SelectedEffect].m_ReverseCalculationTypeID[count];} + MEffect(uint32 effectID); + ~MEffect(); + + //accessors for selected effect + uint32 GetEffectID() { return (m_EffectID == 0) ? 0 : m_EffectID; } + std::string GetEffectName() { return (m_EffectID == 0) ? std::string("") : m_EffectName; } + uint32 GetEffectCategory() { return (m_EffectID == 0) ? 0 : m_EffectCategory; } + uint32 GetPreExpression() { return (m_EffectID == 0) ? 0 : m_PreExpression; } + uint32 GetPostExpression() { return (m_EffectID == 0) ? 0 : m_PostExpression; } + std::string GetDescription() { return (m_EffectID == 0) ? std::string("") : m_Description; } + std::string GetGuid() { return (m_EffectID == 0) ? std::string("") : m_Guid; } + uint32 GetIconID() { return (m_EffectID == 0) ? 0 : m_IconID; } + bool GetIsOffensive() { return (m_EffectID == 0) ? false : m_IsOffensive == 1; } + bool GetIsAssistance() { return (m_EffectID == 0) ? false : m_IsAssistance == 1; } + uint32 GetDurationAttributeID() { return (m_EffectID == 0) ? 0 : m_DurationAttributeID; } + uint32 GetTrackingSpeedAttributeID() { return (m_EffectID == 0) ? 0 : m_TrackingSpeedAttributeID; } + uint32 GetDischargeAttributeID() { return (m_EffectID == 0) ? 0 : m_DischargeAttributeID; } + uint32 GetRangeAttributeID() { return (m_EffectID == 0) ? 0 : m_RangeAttributeID; } + uint32 GetFalloffAttributeID() { return (m_EffectID == 0) ? 0 : m_FalloffAttributeID; } + bool GetDisallowAutoRepeat() { return (m_EffectID == 0) ? false : m_DisallowAutoRepeat == 1; } + bool GetIsPublished() { return (m_EffectID == 0) ? false : m_Published == 1; } + std::string GetDisplayName() { return (m_EffectID == 0) ? std::string("") : m_DisplayName; } + bool GetIsWarpSafe() { return (m_EffectID == 0) ? false : m_IsWarpSafe == 1; } + bool GetRangeChance() { return (m_EffectID == 0) ? false : m_RangeChance == 1; } + bool GetPropulsionChance() { return (m_EffectID == 0) ? false : m_PropulsionChance == 1; } + bool GetElectronicChance() { return (m_EffectID == 0) ? false : m_ElectronicChance == 1; } + uint32 GetDistribution() { return (m_EffectID == 0) ? 0 : m_Distribution; } + std::string GetSfxName() { return (m_EffectID == 0) ? std::string("") : m_DisplayName; } + uint32 GetNpcUsageChanceAttributeID() { return (m_EffectID == 0) ? 0 : m_NpcUsageChanceAttributeID; } + uint32 GetNpcActivationChanceAttributeID() { return (m_EffectID == 0) ? 0 : m_NpcActivationChanceAttributeID; } + uint32 GetFittingUsageChanceAttributeID() { return (m_EffectID == 0) ? 0 : m_FittingUsageChanceAttributeID; } + + //accessors for the effects targetAttributeID, sourceAttributeID and calculation type: + uint32 GetSizeOfAttributeList() { return (m_EffectID == 0) ? 0 : m_numOfIDs; } + uint32 GetTargetAttributeID(uint32 index) { return (m_EffectID == 0) ? 0 : m_TargetAttributeIDs[index]; } + uint32 GetSourceAttributeID(uint32 index) { return (m_EffectID == 0) ? 0 : m_SourceAttributeIDs[index]; } + EVECalculationType GetCalculationType(uint32 index) { return (m_EffectID == 0) ? (EVECalculationType)0 : (EVECalculationType)m_CalculationTypeIDs[index];} + EVECalculationType GetReverseCalculationType(uint32 index) { return (m_EffectID == 0) ? (EVECalculationType)0 : (EVECalculationType)m_ReverseCalculationTypeIDs[index];} + + uint32 GetModuleStateWhenEffectApplied(uint32 index) { return (m_EffectID == 0) ? 0 : m_EffectAppliedWhenID; } + uint32 GetTargetTypeToWhichEffectApplied(uint32 index) { return (m_EffectID == 0) ? 0 : m_EffectAppliedTargetID; } + uint32 GetEffectApplicationType(uint32 index) { return (m_EffectID == 0) ? 0 : m_EffectApplicationTypeID; } + uint32 GetStackingPenaltyApplied(uint32 index) { return (m_EffectID == 0) ? 0 : m_StackingPenaltyAppliedID; } + uint32 GetNullifyOnlineEffectEnable(uint32 index) { return (m_EffectID == 0) ? 0 : m_NullifyOnlineEffectEnable; } + uint32 GetNullifiedOnlineEffectID(uint32 index) { return (m_EffectID == 0) ? 0 : m_NullifiedOnlineEffectID; } private: + void _Populate(uint32 effectID); + + int m_EffectID; + std::string m_EffectName; + int m_EffectCategory; + int m_PreExpression; + int m_PostExpression; + std::string m_Description; + std::string m_Guid; + int m_IconID; + int m_IsOffensive; + int m_IsAssistance; + int m_DurationAttributeID; + int m_TrackingSpeedAttributeID; + int m_DischargeAttributeID; + int m_RangeAttributeID; + int m_FalloffAttributeID; + int m_DisallowAutoRepeat; + int m_Published; + std::string m_DisplayName; + int m_IsWarpSafe; + int m_RangeChance; + int m_ElectronicChance; + int m_PropulsionChance; + int m_Distribution; + std::string m_SfxName; + int m_NpcUsageChanceAttributeID; + int m_NpcActivationChanceAttributeID; + int m_FittingUsageChanceAttributeID; + + int m_numOfIDs; + int * m_TargetAttributeIDs; + int * m_SourceAttributeIDs; + int * m_CalculationTypeIDs; + int * m_ReverseCalculationTypeIDs; + int m_EffectAppliedWhenID; + int m_EffectAppliedTargetID; + int m_EffectApplicationTypeID; + int m_StackingPenaltyAppliedID; + int m_NullifyOnlineEffectEnable; + int m_NullifiedOnlineEffectID; +}; - class MEffect - { - public: - MEffect() { /* nothing to do */ } - - ~MEffect() { /* nothing to do */ } - - void Populate(uint32 effectID) - { - DBQueryResult *res = new DBQueryResult(); - ModuleDB::GetDgmEffects(effectID, *res); - - DBResultRow row1; - if( !res->GetRow(row1) ) - sLog.Error("MEffect","Could not populate effect information for effectID: %u", effectID); - else - { - //get all the data from the query - m_EffectID = effectID; - m_EffectName = row1.GetText(0); - m_EffectCategory = row1.GetInt(1); - m_PreExpression = row1.GetInt(2); - m_PostExpression = row1.GetInt(3); - if( !row1.IsNull(4) ) - m_Description = row1.GetText(4); - if( !row1.IsNull(5) ) - m_Guid = row1.GetText(5); - if( !row1.IsNull(6) ) - m_IconID = row1.GetInt(6); - m_IsOffensive = row1.GetInt(7); - m_IsAssistance = row1.GetInt(8); - if( !row1.IsNull(9) ) - m_DurationAttributeID = row1.GetInt(9); - if( !row1.IsNull(10) ) - m_TrackingSpeedAttributeID = row1.GetInt(10); - if( !row1.IsNull(11) ) - m_DischargeAttributeID = row1.GetInt(11); - if( !row1.IsNull(12) ) - m_RangeAttributeID = row1.GetInt(12); - if( !row1.IsNull(13) ) - m_FalloffAttributeID = row1.GetInt(13); - if( !row1.IsNull(14) ) - m_DisallowAutoRepeat = row1.GetInt(14); - m_Published = row1.GetInt(15); - if( !row1.IsNull(16) ) - m_DisplayName = row1.GetText(16); - m_IsWarpSafe = row1.GetInt(17); - m_RangeChance = row1.GetInt(18); - m_ElectronicChance = row1.GetInt(19); - m_PropulsionChance = row1.GetInt(20); - if( !row1.IsNull(21) ) - m_Distribution = row1.GetInt(21); - if( !row1.IsNull(22) ) - m_SfxName = row1.GetText(22); - if( !row1.IsNull(23) ) - m_NpcUsageChanceAttributeID = row1.GetInt(23); - if( !row1.IsNull(24) ) - m_NpcActivationChanceAttributeID = row1.GetInt(24); - if( !row1.IsNull(25) ) - m_FittingUsageChanceAttributeID = row1.GetInt(25); - } - - //next get the info from the dgmEffectsInfo table - ModuleDB::GetDgmEffectsInfo(effectID, *res); - - DBResultRow row2; - - //initialize the new tables - m_TargetAttributeIDs = new int[res->GetRowCount()]; - m_SourceAttributeIDs = new int[res->GetRowCount()]; - m_CalculationTypeID = new int[res->GetRowCount()]; - m_ReverseCalculationTypeID = new int[res->GetRowCount()]; - - //counter - int count = 0; - - while( res->GetRow(row2) ) - { - m_TargetAttributeIDs[count] = row2.GetInt(1); - m_SourceAttributeIDs[count] = row2.GetInt(2); - m_CalculationTypeID[count] = row2.GetInt(3); - m_ReverseCalculationTypeID[count] = row2.GetInt(4); - count++; - } - - m_numOfIDs = count; - - delete res; - res = NULL; - - } - - int * m_TargetAttributeIDs; - int * m_SourceAttributeIDs; - int * m_CalculationTypeID; - int * m_ReverseCalculationTypeID; - int m_numOfIDs; - - int m_EffectID; - std::string m_EffectName; - int m_EffectCategory; - int m_PreExpression; - int m_PostExpression; - std::string m_Description; - std::string m_Guid; - int m_IconID; - int m_IsOffensive; - int m_IsAssistance; - int m_DurationAttributeID; - int m_TrackingSpeedAttributeID; - int m_DischargeAttributeID; - int m_RangeAttributeID; - int m_FalloffAttributeID; - int m_DisallowAutoRepeat; - int m_Published; - std::string m_DisplayName; - int m_IsWarpSafe; - int m_RangeChance; - int m_ElectronicChance; - int m_PropulsionChance; - int m_Distribution; - std::string m_SfxName; - int m_NpcUsageChanceAttributeID; - int m_NpcActivationChanceAttributeID; - int m_FittingUsageChanceAttributeID; - - }; - - void _populate(uint32 typeID) - { - //first get all of the effects associated with the typeID - DBQueryResult *res = new DBQueryResult(); - ModuleDB::GetDgmTypeEffectsInformation(typeID, *res); - - //initialize our container to the correct size - m_Effects = new MEffect[res->GetRowCount()]; - m_EffectIDs = new int[res->GetRowCount()]; - - //counter - int i = 0; - - //go through and populate each effect - DBResultRow row; - while( res->GetRow(row) ) - { - //add new stuff to the arrays - m_EffectIDs[i] = row.GetInt(0); - m_Effects[i] = *new MEffect(); - - //check if this is the default effect - if( row.GetInt(1) ) - m_DefaultEffect = i; +//class contained by all modules that is populated on construction of the module +//this will contain all information about the effects of the module +class ModuleEffects +{ +public: + ModuleEffects(uint32 typeID); + ~ModuleEffects(); - //populate the new MEffect - m_Effects[i].Populate(row.GetInt(0)); + //this will need to be reworked to implement a singleton architecture...i'll do it later -luck - i++; //increment - } + //useful accessors - probably a better way to do this, but at least it's fast + bool isHighSlot(); + bool isMediumSlot(); + bool isLowSlot(); + bool HasEffect(uint32 effectID); + bool HasDefaultEffect() { return ( (m_defaultEffect != NULL) ? true : false ); } + MEffect * GetDefaultEffect() { return m_defaultEffect; } + MEffect * GetEffect(uint32 effectID); - m_EffectCount = i; + std::map::const_iterator GetOnlineEffectsConstIterator() { return m_OnlineEffects.begin(); } + std::map::const_iterator GetActiveEffectsConstIterator() { return m_ActiveEffects.begin(); } + std::map::const_iterator GetOverloadEffectsConstIterator() { return m_OverloadEffects.begin(); } - //cleanup - delete res; - res = NULL; +private: - } + void _populate(uint32 typeID); - //data members - int m_TypeID; - int *m_EffectIDs; - MEffect * m_Effects; - int m_DefaultEffect; + //data members + std::map m_OnlineEffects; + std::map m_ActiveEffects; + std::map m_OverloadEffects; + MEffect * m_defaultEffect; - //internal counters - uint32 m_EffectCount; - uint32 m_SelectedEffect; + uint32 m_typeID; - //cached stuff - bool m_HighPower, m_MediumPower, m_LowPower, m_Cached; + //cached stuff + bool m_HighPower, m_MediumPower, m_LowPower, m_Cached; }; diff --git a/include/eve-server/ship/Modules/ModuleFactory.h b/include/eve-server/ship/Modules/ModuleFactory.h index da0f8a9f..2d7d3ee4 100644 --- a/include/eve-server/ship/Modules/ModuleFactory.h +++ b/include/eve-server/ship/Modules/ModuleFactory.h @@ -32,32 +32,33 @@ #include "PassiveModules.h" #include "RigModule.h" #include "SubSystemModules.h" +#include "ship/Modules/propulsion_modules/Afterburner.h" //how you should access the modules static GenericModule* ModuleFactory(InventoryItemRef item, ShipRef ship) { - if( item->categoryID() != EVEDB::invCategories::Module ) - { - sLog.Error("ModuleFactory","Cannot create module from non module type item"); - assert(false); - } - else - { - switch(item->groupID()) - { + if( item->categoryID() != EVEDB::invCategories::Module ) + { + sLog.Error("ModuleFactory","Cannot create module from non module type item"); + assert(false); + } + else + { + switch(item->groupID()) + { // Armor Modules Subgroup: - case EVEDB::invGroups::Damage_Control: return NULL; // Active + case EVEDB::invGroups::Damage_Control: return (new ActiveModule(item, ship)); break; // Active case EVEDB::invGroups::Armor_Repair_Unit: return NULL; // Active case EVEDB::invGroups::Hull_Repair_Unit: return NULL; // Active - case EVEDB::invGroups::Reinforced_Bulkheads: return NULL; // Passive - case EVEDB::invGroups::Armor_Coating: return NULL; // Passive + case EVEDB::invGroups::Reinforced_Bulkheads: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Armor_Coating: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Armor_Repair_Projector: return NULL; // Active - case EVEDB::invGroups::Armor_Plating_Energized: return NULL; // Active - case EVEDB::invGroups::Armor_Hardener: return NULL; // Active - case EVEDB::invGroups::Armor_Reinforcer: new PassiveModule(item, ship); break; + case EVEDB::invGroups::Armor_Plating_Energized: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Armor_Hardener: return (new ActiveModule(item, ship)); break; // Active + case EVEDB::invGroups::Armor_Reinforcer: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Remote_Hull_Repairer: return NULL; // Active - case EVEDB::invGroups::Expanded_Cargohold: return NULL; // Passive + case EVEDB::invGroups::Expanded_Cargohold: return (new PassiveModule(item, ship)); break; // Electronics Modules Subgroup: case EVEDB::invGroups::Cargo_Scanner: return NULL; // Active @@ -65,25 +66,25 @@ static GenericModule* ModuleFactory(InventoryItemRef item, ShipRef ship) case EVEDB::invGroups::Survey_Scanner: return NULL; // Active case EVEDB::invGroups::Cloaking_Device: return NULL; // Active case EVEDB::invGroups::Target_Painter: return NULL; // Active - case EVEDB::invGroups::Drone_Control_Unit: return NULL; // Passive + case EVEDB::invGroups::Drone_Control_Unit: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::System_Scanner: return NULL; // Active case EVEDB::invGroups::Scan_Probe_Launcher: return NULL; // Active - case EVEDB::invGroups::Drone_Navigation_Computer: return NULL; // Passive - case EVEDB::invGroups::Drone_Tracking_Modules: return NULL; // Passive - case EVEDB::invGroups::Drone_Control_Range_Module: return NULL; // Passive + case EVEDB::invGroups::Drone_Navigation_Computer: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Drone_Tracking_Modules: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Drone_Control_Range_Module: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Tractor_Beam: return NULL; // Active // Engineering Modules Subgroup: - case EVEDB::invGroups::Capacitor_Recharger: return NULL; // Passive - case EVEDB::invGroups::Capacitor_Battery: return NULL; // Passive + case EVEDB::invGroups::Capacitor_Recharger: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Capacitor_Battery: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Energy_Transfer_Array: return NULL; // Active case EVEDB::invGroups::Capacitor_Booster: return NULL; // Active - case EVEDB::invGroups::Auxiliary_Power_Core: new PassiveModule(item, ship); break; - case EVEDB::invGroups::Power_Diagnostic_System: return NULL; // Passive - case EVEDB::invGroups::Capacitor_Power_Relay: return NULL; // Passive - case EVEDB::invGroups::Capacitor_Flux_Coil: return NULL; // Passive - case EVEDB::invGroups::Reactor_Control_Unit: return NULL; // Passive - case EVEDB::invGroups::Shield_Flux_Coil: return NULL; // Passive + case EVEDB::invGroups::Auxiliary_Power_Core: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Power_Diagnostic_System: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Capacitor_Power_Relay: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Capacitor_Flux_Coil: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Reactor_Control_Unit: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Shield_Flux_Coil: return (new PassiveModule(item, ship)); break; // EWAR Modules Subgroup: case EVEDB::invGroups::Warp_Scrambler: return NULL; // Active @@ -93,18 +94,18 @@ static GenericModule* ModuleFactory(InventoryItemRef item, ShipRef ship) case EVEDB::invGroups::Automated_Targeting_System: return NULL; // Active case EVEDB::invGroups::ECM: return NULL; // Active case EVEDB::invGroups::ECCM: return NULL; // Active - case EVEDB::invGroups::Sensor_Backup_Array: return NULL; // Active + case EVEDB::invGroups::Sensor_Backup_Array: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Remote_Sensor_Damper: return NULL; // Active case EVEDB::invGroups::Tracking_Link: return NULL; // Active - case EVEDB::invGroups::Signal_Amplifier: return NULL; // Active - case EVEDB::invGroups::Tracking_Enhancer: return NULL; // Active + case EVEDB::invGroups::Signal_Amplifier: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Tracking_Enhancer: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Sensor_Booster: return NULL; // Active case EVEDB::invGroups::Tracking_Computer: return NULL; // Active - case EVEDB::invGroups::CPU_Enhancer: return NULL; // Passive + case EVEDB::invGroups::CPU_Enhancer: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Projected_ECCM: return NULL; // Active case EVEDB::invGroups::Remote_Sensor_Booster: return NULL; // Active case EVEDB::invGroups::Tracking_Disruptor: return NULL; // Active - case EVEDB::invGroups::ECM_Stabilizer: return NULL; // Active + case EVEDB::invGroups::ECM_Stabilizer: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Remote_ECM_Burst: return NULL; // Active // Gang Assist Modules Subgroup: @@ -113,44 +114,44 @@ static GenericModule* ModuleFactory(InventoryItemRef item, ShipRef ship) case EVEDB::invGroups::Data_Miners: return NULL; // Active case EVEDB::invGroups::Jump_Portal_Generator: return NULL; // Active case EVEDB::invGroups::Cynosural_Field: return NULL; // Active - case EVEDB::invGroups::Clone_Vat_Bay: return NULL; // Passive + case EVEDB::invGroups::Clone_Vat_Bay: return (new PassiveModule(item, ship)); break; // Mining Modules Subgroup: case EVEDB::invGroups::Mining_Laser: return NULL; // Active case EVEDB::invGroups::Strip_Miner: return NULL; // Active case EVEDB::invGroups::Frequency_Mining_Laser: return NULL; // Active - case EVEDB::invGroups::Mining_Upgrade: return NULL; // Passive + case EVEDB::invGroups::Mining_Upgrade: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Gas_Cloud_Harvester: return NULL; // Active // Propulsion Modules Subgroup: - case EVEDB::invGroups::Afterburner: return new Afterburner(item, ship); break; - case EVEDB::invGroups::Warp_Core_Stabilizer: return NULL; // Passive - case EVEDB::invGroups::Inertial_Stabilizer: return NULL; // Passive - case EVEDB::invGroups::Nanofiber_Internal_Structure: return NULL; // Passive - case EVEDB::invGroups::Overdrive_Injector_System: return NULL; // Passive + case EVEDB::invGroups::Afterburner: return (new Afterburner(item, ship)); break; + case EVEDB::invGroups::Warp_Core_Stabilizer: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Inertial_Stabilizer: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Nanofiber_Internal_Structure: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Overdrive_Injector_System: return (new PassiveModule(item, ship)); break; // Shield Modules Subgroup: - case EVEDB::invGroups::Shield_Extender: return NULL; // Passive - case EVEDB::invGroups::Shield_Recharger: return NULL; // Active + case EVEDB::invGroups::Shield_Extender: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Shield_Recharger: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Shield_Booster: return NULL; // Active case EVEDB::invGroups::Shield_Transporter: return NULL; // Active - case EVEDB::invGroups::Shield_Power_Relay: return NULL; // Passive + case EVEDB::invGroups::Shield_Power_Relay: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Shield_Hardener: return NULL; // Active - case EVEDB::invGroups::Shield_Amplifier: return NULL; // Active - case EVEDB::invGroups::Shield_Boost_Amplifier: return NULL; // Active + case EVEDB::invGroups::Shield_Amplifier: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Shield_Boost_Amplifier: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Shield_Disruptor: return NULL; // Active // Weapon Modules Subgroup: - case EVEDB::invGroups::Energy_Weapon: return NULL; // Active + case EVEDB::invGroups::Energy_Weapon: return (new ActiveModule(item, ship)); break; // Active case EVEDB::invGroups::Projectile_Weapon: return NULL; // Active - case EVEDB::invGroups::Gyrostabilizer: return NULL; // Passive + case EVEDB::invGroups::Gyrostabilizer: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Energy_Vampire: return NULL; // Active case EVEDB::invGroups::Energy_Destabilizer: return NULL; // Active case EVEDB::invGroups::Smart_Bomb: return NULL; // Active case EVEDB::invGroups::Hybrid_Weapon: return NULL; // Active - case EVEDB::invGroups::Heat_Sink: return NULL; // Passive - case EVEDB::invGroups::Magnetic_Field_Stabilizer: return NULL; // Passive - case EVEDB::invGroups::Ballistic_Control_system: new PassiveModule(item, ship); break; + case EVEDB::invGroups::Heat_Sink: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Magnetic_Field_Stabilizer: return (new PassiveModule(item, ship)); break; + case EVEDB::invGroups::Ballistic_Control_system: return (new PassiveModule(item, ship)); break; case EVEDB::invGroups::Missile_Launcher_Snowball: return NULL; // Active case EVEDB::invGroups::Missile_Launcher_Cruise: return NULL; // Active case EVEDB::invGroups::Missile_Launcher_Rocket: return NULL; // Active @@ -162,7 +163,7 @@ static GenericModule* ModuleFactory(InventoryItemRef item, ShipRef ship) case EVEDB::invGroups::Missile_Launcher_Citadel: return NULL; // Active case EVEDB::invGroups::Super_Weapon: return NULL; // Active case EVEDB::invGroups::Interdiction_Sphere_Launcher: return NULL; // Active - case EVEDB::invGroups::Missile_Launcher_Heavy_Assault: return NULL; // Active + case EVEDB::invGroups::Missile_Launcher_Heavy_Assault: return (new ActiveModule(item, ship)); break; // Active case EVEDB::invGroups::Missile_Launcher_Bomb: return NULL; // Active case EVEDB::invGroups::Warp_Disrupt_Field_Generator: return NULL; // Active @@ -197,19 +198,19 @@ static GenericModule* ModuleFactory(InventoryItemRef item, ShipRef ship) /* Rigs */ /************************************/ - case EVEDB::invGroups::Rig_Armor: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Shield: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Energy_Weapon: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Hybrid_Weapon: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Projectile_Weapon: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Drones: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Launcher: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Electronics: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Energy_Grid: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Astronautic: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Electronics_Superiority: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Mining: return new RigModule(item, ship); - case EVEDB::invGroups::Rig_Security_Transponder: return new RigModule(item, ship); + case EVEDB::invGroups::Rig_Armor: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Shield: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Energy_Weapon: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Hybrid_Weapon: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Projectile_Weapon: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Drones: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Launcher: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Electronics: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Energy_Grid: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Astronautic: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Electronics_Superiority: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Mining: return (new RigModule(item, ship)); break; + case EVEDB::invGroups::Rig_Security_Transponder: return (new RigModule(item, ship)); break; /************************************/ @@ -227,6 +228,9 @@ static GenericModule* ModuleFactory(InventoryItemRef item, ShipRef ship) } } + // THIS IS A MAJOR PROBLEM IF CODE EXECUTION MAKES IT TO THIS POINT, + // IT WILL CRASH THE SERVER IF NULL IS RETURNED: + sLog.Error( "ModuleFactory::ModuleFactory()", "CRITICAL! NO Module Group was found for item '%s' (itemID = %u)", item->itemName().c_str(), item->itemID() ); return NULL; } diff --git a/include/eve-server/ship/Modules/Modules.h b/include/eve-server/ship/Modules/Modules.h index 3bdc5f92..87e8a325 100644 --- a/include/eve-server/ship/Modules/Modules.h +++ b/include/eve-server/ship/Modules/Modules.h @@ -29,6 +29,7 @@ #include "ship/Modules/ModuleDefs.h" #include "ship/Modules/ModuleEffects.h" +#include "inventory/EffectsEnum.h" //generic module base class - possibly should inherit from RefPtr... @@ -36,58 +37,93 @@ class GenericModule { public: - GenericModule() { } - virtual ~GenericModule() + GenericModule() { - //warn user - yes be obnoxious - sLog.Error("GenericModule","MEMORY LEAK!"); + m_Module_State = MOD_UNFITTED; + m_Charge_State = MOD_UNLOADED; + } + virtual ~GenericModule() + { + // ALL DERIVED CLASSES SHOULD OVERRIDE THIS + // //warn user - yes be obnoxious + // sLog.Error("GenericModule","MEMORY LEAK!"); + + // //force the users to override the inherited destructor + // assert(false); //crash if they don't + } + + virtual void Process() { /* Do nothing here */ } + virtual void Offline() { /* Do nothing here */ } + virtual void Online() { /* Do nothing here */ } + virtual void Activate(uint32 targetID) { /* Do nothing here */ } + virtual void Deactivate() { /* Do nothing here */ } + virtual void Load(InventoryItemRef charge) { /* Do nothing here */ } + virtual void Unload() { /* Do nothing here */ } + virtual void Overload() { /* Do nothing here */ } + virtual void DeOverload() { /* Do nothing here */ } + virtual void DestroyRig() { /* Do nothing here */ } + + + virtual void Repair() { m_Item->ResetAttribute(AttrHp, true); } + virtual void Repair(EvilNumber amount) { m_Item->SetAttribute(AttrHp, m_Item->GetAttribute(AttrHp) + amount); } + + virtual void SetAttribute(uint32 attrID, EvilNumber val) { m_Item->SetAttribute(attrID, val); } + virtual EvilNumber GetAttribute(uint32 attrID) { return m_Item->GetAttribute(attrID); } + + //access functions + InventoryItemRef getItem() { return m_Item; } + virtual uint32 itemID() { return m_Item->itemID(); } + virtual EVEItemFlags flag() { return m_Item->flag(); } + virtual uint32 typeID() { return m_Item->typeID(); } + virtual bool isOnline() { return (m_Item->GetAttribute(AttrIsOnline) == 1); } + virtual bool isHighPower() { return m_Effects->isHighSlot(); } + virtual bool isMediumPower() { return m_Effects->isMediumSlot(); } + virtual bool isLowPower() { return m_Effects->isLowSlot(); } + + virtual bool isTurretFitted() + { + // Try to make the effect called 'turretFitted' active, if it exists, to test for module being a turret: + if( m_Effects->HasEffect(EveEffectEnum::Effect_turretFitted) ) + return true; + else + return false; + } - //force the users to override the inherited destructor - assert(false); //crash if they don't + virtual bool isLauncherFitted() + { + // Try to make the effect called 'launcherFitted' active, if it exists, to test for module being a launcher: + if( m_Effects->HasEffect(EveEffectEnum::Effect_launcherFitted) ) + return true; + else + return false; } - virtual void Process() { /* Do nothing here */ } - virtual void Offline() { /* Do nothing here */ } - virtual void Online() { /* Do nothing here */ } - virtual void Activate(uint32 targetID) { /* Do nothing here */ } - virtual void Deactivate() { /* Do nothing here */ } - virtual void Load(InventoryItemRef charge) { /* Do nothing here */ } - virtual void Unload() { /* Do nothing here */ } - virtual void Overload() { /* Do nothing here */ } - virtual void DeOverload() { /* Do nothing here */ } - virtual void DestroyRig() { /* Do nothing here */ } - - - virtual void Repair() { m_Item->ResetAttribute(AttrHp, true); } - virtual void Repair(EvilNumber amount) { m_Item->SetAttribute(AttrHp, m_Item->GetAttribute(AttrHp) + amount); } - - virtual void SetAttribute(uint32 attrID, EvilNumber val) { m_Item->SetAttribute(attrID, val); } - virtual EvilNumber GetAttribute(uint32 attrID) { return m_Item->GetAttribute(attrID); } - - //access functions - virtual uint32 itemID() { return m_Item->itemID(); } - virtual EVEItemFlags flag() { return m_Item->flag(); } - virtual uint32 typeID() { return m_Item->typeID(); } - virtual bool isOnline() { return (m_Item->GetAttribute(AttrIsOnline) == 1); } - virtual bool isHighPower() { return m_Effects->isHighSlot(); } - virtual bool isMediumPower() { return m_Effects->isMediumSlot(); } - virtual bool isLowPower() { return m_Effects->isLowSlot(); } - - virtual bool isRig() + virtual bool isMaxGroupFitLimited() { - uint32 i = m_Item->categoryID(); - return ( (i >= 773 && i <= 782) || (i == 786) || (i == 787) || (i == 896) || (i == 904) ); //need to use enums, but the enum system is a huge mess + if( m_Item->HasAttribute(EveAttrEnum::AttrMaxGroupFitted) ) + return true; + else + return false; } - virtual bool isSubSystem() { return (m_Item->categoryID() == EVEDB::invCategories::Subsystem); } + virtual bool isRig() + { + uint32 i = m_Item->categoryID(); + return ( (i >= 773 && i <= 782) || (i == 786) || (i == 787) || (i == 896) || (i == 904) ); //need to use enums, but the enum system is a huge mess + } + + virtual bool isSubSystem() { return (m_Item->categoryID() == EVEDB::invCategories::Subsystem); } - //override for rigs and subsystems - virtual ModulePowerLevel GetModulePowerLevel() { return isHighPower() ? HIGH_POWER : ( isMediumPower() ? MEDIUM_POWER : LOW_POWER); } + //override for rigs and subsystems + virtual ModulePowerLevel GetModulePowerLevel() { return isHighPower() ? HIGH_POWER : ( isMediumPower() ? MEDIUM_POWER : LOW_POWER); } protected: - InventoryItemRef m_Item; - ShipRef m_Ship; - ModuleEffects * m_Effects; + InventoryItemRef m_Item; + ShipRef m_Ship; + ModuleEffects * m_Effects; + + ModuleStates m_Module_State; + ChargeStates m_Charge_State; }; diff --git a/include/eve-server/ship/Modules/PassiveModules.h b/include/eve-server/ship/Modules/PassiveModules.h index 470c03fa..8096942c 100644 --- a/include/eve-server/ship/Modules/PassiveModules.h +++ b/include/eve-server/ship/Modules/PassiveModules.h @@ -32,58 +32,17 @@ class PassiveModule : public GenericModule { public: - PassiveModule(InventoryItemRef item, ShipRef ship) - { - m_Item = item; - m_Ship = ship; - m_Effects = new ModuleEffects(m_Item->typeID()); - m_ShipAttrComp = new ModifyShipAttributesComponent(this, ship); - } - - ~PassiveModule() - { - //delete members - delete m_Effects; - delete m_ShipAttrComp; - - //null ptrs - m_Effects = NULL; - m_ShipAttrComp = NULL; - } - - void Offline() - { - //remove item attributes - m_Effects->SetDefaultEffectAsActive(); - for(uint32 i = 0; i < m_Effects->GetSizeOfAttributeList(); i++) - { - m_ShipAttrComp->ModifyShipAttribute(m_Effects->GetTargetAttributeID(i), m_Effects->GetSourceAttributeID(i), m_Effects->GetReverseCalculationType(i)); - } - - //change item state - m_Item->PutOffline(); - } - - void Online() - { - //add item attributes - m_Effects->SetDefaultEffectAsActive(); - for(uint32 i = 0; i < m_Effects->GetSizeOfAttributeList(); i++) - { - m_ShipAttrComp->ModifyShipAttribute(m_Effects->GetTargetAttributeID(i), m_Effects->GetSourceAttributeID(i), m_Effects->GetCalculationType(i)); - } - - //change item state - m_Item->PutOnline(); - } - + PassiveModule(InventoryItemRef item, ShipRef ship); + ~PassiveModule(); + void Offline(); + void Online(); protected: - ModifyShipAttributesComponent * m_ShipAttrComp; + ModifyShipAttributesComponent * m_ShipAttrComp; - //inheritance crap - PassiveModule() { } + //inheritance crap + PassiveModule() { } }; diff --git a/include/eve-server/ship/Modules/RigModule.h b/include/eve-server/ship/Modules/RigModule.h index a3b0dda2..988ece8e 100644 --- a/include/eve-server/ship/Modules/RigModule.h +++ b/include/eve-server/ship/Modules/RigModule.h @@ -26,31 +26,15 @@ #ifndef RIG_MODULE_H #define RIG_MODULE_H + class RigModule : public PassiveModule { public: + + RigModule(InventoryItemRef item, ShipRef ship); + ~RigModule(); - RigModule(InventoryItemRef item, ShipRef ship) - { - m_Item = item; - m_Ship = ship; - m_Effects = new ModuleEffects(m_Item->typeID()); - m_ShipAttrComp = new ModifyShipAttributesComponent(this, ship); - } - - ~RigModule() - { - //delete members - delete m_Effects; - delete m_ShipAttrComp; - - //null ptrs - m_Effects = NULL; - m_ShipAttrComp = NULL; - } - - //not much to do here... hopefully there won't be - virtual ModulePowerLevel GetModulePowerLevel() { return RIG; } + ModulePowerLevel GetModulePowerLevel(); }; diff --git a/include/eve-server/ship/Modules/SubSystemModules.h b/include/eve-server/ship/Modules/SubSystemModules.h index a443a398..d8df7ebf 100644 --- a/include/eve-server/ship/Modules/SubSystemModules.h +++ b/include/eve-server/ship/Modules/SubSystemModules.h @@ -30,27 +30,10 @@ class SubSystemModule : public PassiveModule { public: - SubSystemModule(InventoryItemRef item, ShipRef ship) - { - m_Item = item; - m_Ship = ship; - m_Effects = new ModuleEffects(m_Item->typeID()); - m_ShipAttrComp = new ModifyShipAttributesComponent(this, ship); - } + SubSystemModule(InventoryItemRef item, ShipRef ship); + ~SubSystemModule(); - ~SubSystemModule() - { - //delete members - delete m_Effects; - delete m_ShipAttrComp; - - //null ptrs - m_Effects = NULL; - m_ShipAttrComp = NULL; - } - - //not much to do here... hopefully there won't be - virtual ModulePowerLevel GetModulePowerLevel() { return SUBSYSTEM; } + ModulePowerLevel GetModulePowerLevel(); }; #endif \ No newline at end of file diff --git a/include/eve-server/ship/Modules/components/ActiveModuleProcessingComponent.h b/include/eve-server/ship/Modules/components/ActiveModuleProcessingComponent.h index 0c84dafa..fc8030c0 100644 --- a/include/eve-server/ship/Modules/components/ActiveModuleProcessingComponent.h +++ b/include/eve-server/ship/Modules/components/ActiveModuleProcessingComponent.h @@ -33,54 +33,24 @@ class ActiveModuleProcessingComponent { public: - ActiveModuleProcessingComponent(GenericModule * mod, ShipRef ship, ModifyShipAttributesComponent * shipAttrMod) - : m_Stop( false ), m_Mod( mod ), m_Ship( ship ), m_ShipAttrModComp( shipAttrMod ) - { + ActiveModuleProcessingComponent(GenericModule * mod, ShipRef ship, ModifyShipAttributesComponent * shipAttrMod); + ~ActiveModuleProcessingComponent(); - } + void DeactivateCycle(); - ~ActiveModuleProcessingComponent() - { - //nothing to do yet - } + bool ShouldProcessActiveCycle(); - void DeactivateCycle() - { - m_Stop = true; - } - - //timing and verification function - bool ShouldProcessActiveCycle() - { - //first check time for cycle timer - - //next check that we have enough capacitor avaiable - - //finally check if we have been told to deactivate - - } - - void ProcessActiveCycle() - { - //check for stop signal - if(m_Stop) - return; - - //else consume capacitor - - - //then check if we are targeting another ship or not - } + void ProcessActiveCycle(); private: - //internal storage and record keeping - bool m_Stop; + //internal storage and record keeping + bool m_Stop; - //internal access to owner - GenericModule *m_Mod; - ShipRef m_Ship; - ModifyShipAttributesComponent * m_ShipAttrModComp; + //internal access to owner + GenericModule *m_Mod; + ShipRef m_Ship; + ModifyShipAttributesComponent * m_ShipAttrModComp; }; diff --git a/include/eve-server/ship/Modules/components/ModifyShipAttributesComponent.h b/include/eve-server/ship/Modules/components/ModifyShipAttributesComponent.h index 50239dd1..65223d39 100644 --- a/include/eve-server/ship/Modules/components/ModifyShipAttributesComponent.h +++ b/include/eve-server/ship/Modules/components/ModifyShipAttributesComponent.h @@ -33,121 +33,27 @@ class ModifyShipAttributesComponent { public: - ModifyShipAttributesComponent(GenericModule * mod, ShipRef ship) - : m_Mod( mod ), m_Ship( ship ) - { + ModifyShipAttributesComponent(GenericModule * mod, ShipRef ship); + ~ModifyShipAttributesComponent(); - } + void ModifyShipAttribute(uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type); - ~ModifyShipAttributesComponent() - { - //nothing to do yet - } + void ModifyTargetShipAttribute(uint32 targetItemID, uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type ); - //modify our ship - void ModifyShipAttribute(uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type) - { - _modifyShipAttributes(m_Ship, targetAttrID, sourceAttrID, type); - } +private: - //modify target ship - void ModifyTargetShipAttribute(uint32 targetItemID, uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type ) - { - //find the ship - ShipRef target = m_Ship->GetItemFactory()->GetShip(targetItemID); + void _modifyShipAttributes(ShipRef ship, uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type); - //check if we found the ship - if( target == 0) - { - sLog.Error("ModifyShipAttributesComponent","Failed to find target ship %u", targetItemID); - return; - } + EvilNumber _calculateNewValue(uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type, std::vector mods); - //modify the attributes properly - _modifyShipAttributes(target, targetAttrID, sourceAttrID, type); + EvilNumber _calculateNewAttributeValue( EvilNumber sourceAttr, EvilNumber targetAttr, EVECalculationType type, int stackNumber ); - } + std::vector _sortModules(uint32 sortAttrID, std::vector mods); -private: - // implements a rudimentary but working stacking penalty. Currently only penalizes for stacking same item, - // but should penalize for modifying the same attribute, with some exceptions. These exceptions are why - // it has not been implemented fully, as more data is needed and this is just a proof of concept. - // No module code will have to be changed to implement the fully functional stacking penalty - void _modifyShipAttributes(ShipRef ship, uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type) - { - //first we must reset the attribute in order to properly recalculate the attribute - ship->ResetAttribute(targetAttrID, false); - - //recalculate the attribute for the ship with the new modifier - ship->SetAttribute(targetAttrID, _calculateNewValue(targetAttrID, sourceAttrID, type, m_Ship->GetStackedItems(m_Mod->typeID(), m_Mod->GetModulePowerLevel()))); - } - - EvilNumber _calculateNewValue(uint32 targetAttrID, uint32 sourceAttrID, EVECalculationType type, std::vector mods) - { - //based on http://wiki.eve-id.net/Stacking - //EVEDev had a mistake in their formula, however I have corrected it and verified my results in excel - - //note - we must have already been put online to be on the list. This is just a check for people - //who may have implemented their Online function incorrectly - if( !(m_Mod->isOnline()) ) - mods.push_back(m_Mod); - - std::vector sortedMods = _sortModules(targetAttrID, mods); - - EvilNumber finalVal; - EvilNumber startVal = m_Ship->GetAttribute(targetAttrID); //start value - - //iterate through all the modules, largest first - for(uint32 i = 0; i < mods.size(); i++) - { - finalVal = _calculateNewAttributeValue(mods[i]->GetAttribute(sourceAttrID), startVal, type, i ); - startVal = finalVal; //set the starting value as the calculated value - } - - - return finalVal; - } - - //calculate the new value including the stacking penalty - EvilNumber _calculateNewAttributeValue( EvilNumber sourceAttr, EvilNumber targetAttr, EVECalculationType type, int stackNumber ) - { - EvilNumber effectiveness = exp(-pow((double)(stackNumber - 1),2)/7.1289); //should be correct, but should be checked - return CalculateNewAttributeValue(targetAttr, sourceAttr * effectiveness, type); - } - - //sorts a vector of modules in descending order by arbitrary attribute. That is array[0] > array[1] - std::vector _sortModules(uint32 sortAttrID, std::vector mods) - { - - //begin basic bubble sort - this needs to be checked thoroughly for bugs - bool done = false; - - while(!done) //check if sorted - { - done = true; //assume sorted - - for( int i = 0; i != mods.size() + 1; i++) //iterate though list - { - if( mods[i]->GetAttribute(sortAttrID) > mods[i+1]->GetAttribute(sortAttrID) ) //check if each pair is sorted - { - //it's not, so flip the values - GenericModule * tmp = mods[i]; - mods[i] = mods[i+1]; - mods[i] = tmp; - - done = false; //we weren't sorted, so now go back and check if we are - } - } - } - - return mods; //return sorted list - } - - - //internal access to owner - GenericModule *m_Mod; - ShipRef m_Ship; + //internal access to owner + GenericModule *m_Mod; + ShipRef m_Ship; }; diff --git a/include/eve-server/ship/Ship.h b/include/eve-server/ship/Ship.h index 9d988e27..18b964e5 100644 --- a/include/eve-server/ship/Ship.h +++ b/include/eve-server/ship/Ship.h @@ -42,16 +42,16 @@ class ShipOperatorInterface; */ class ShipTypeData { public: - ShipTypeData( - uint32 _weaponTypeID = 0, - uint32 _miningTypeID = 0, - uint32 _skillTypeID = 0 - ); - - // Content: - uint32 mWeaponTypeID; - uint32 mMiningTypeID; - uint32 mSkillTypeID; + ShipTypeData( + uint32 _weaponTypeID = 0, + uint32 _miningTypeID = 0, + uint32 _skillTypeID = 0 + ); + + // Content: + uint32 mWeaponTypeID; + uint32 mMiningTypeID; + uint32 mSkillTypeID; }; /** @@ -220,22 +220,25 @@ class Ship */ void SaveShip(); - /* begin new module manager interface */ - void AddItem( EVEItemFlags flag, InventoryItemRef item); - void RemoveItem( InventoryItemRef item, uint32 inventoryID, EVEItemFlags flag ); - void UpdateModules(); - void UnloadModule(uint32 itemID); - void UnloadAllModules(); - void RepairModules(); - int32 Activate(int32 itemID, std::string effectName, int32 targetID, int32 repeat); - void Deactivate(int32 itemID, std::string effectName); - void ReplaceCharges(EVEItemFlags flag, InventoryItemRef newCharge); - void RemoveRig(InventoryItemRef item, uint32 inventoryID); - void Process(); - void DeactivateAllModules(); - void OnlineAll(); + /* begin new module manager interface */ + uint32 FindAvailableModuleSlot( InventoryItemRef item ); + EvilNumber GetMaxTurrentHardpoints() { return GetAttribute(AttrTurretSlotsLeft); } + EvilNumber GetMaxLauncherHardpoints() { return GetAttribute(AttrLauncherSlotsLeft); } + void AddItem( EVEItemFlags flag, InventoryItemRef item); + void RemoveItem( InventoryItemRef item, uint32 inventoryID, EVEItemFlags flag ); + void UpdateModules(); + void UnloadModule(uint32 itemID); + void UnloadAllModules(); + void RepairModules(); + int32 Activate(int32 itemID, std::string effectName, int32 targetID, int32 repeat); + void Deactivate(int32 itemID, std::string effectName); + void ReplaceCharges(EVEItemFlags flag, InventoryItemRef newCharge); + void RemoveRig(InventoryItemRef item, uint32 inventoryID); + void Process(); + void DeactivateAllModules(); + void OnlineAll(); ShipOperatorInterface * GetOperator() { return m_pOperator; } - std::vector GetStackedItems(uint32 typeID, ModulePowerLevel level); + std::vector GetStackedItems(uint32 typeID, ModulePowerLevel level); protected: Ship( diff --git a/include/eve-server/ship/ShipOperatorInterface.h b/include/eve-server/ship/ShipOperatorInterface.h index 140194a5..6b8f0a66 100644 --- a/include/eve-server/ship/ShipOperatorInterface.h +++ b/include/eve-server/ship/ShipOperatorInterface.h @@ -60,13 +60,14 @@ class ShipOperatorInterface // Pass Through calls to Operator object: // CLIENT Object calls: - void SendNotifyMsg( const char* fmt, va_list args ); - void SendErrorMsg( const char* fmt, va_list args ); - const char *GetName() const; - ShipRef GetShip() const; - CharacterRef GetChar() const; - uint32 GetLocationID() const; - void MoveItem(uint32 itemID, uint32 location, EVEItemFlags flag); + void SendNotifyMsg( const char* fmt, va_list args ); + void SendErrorMsg( const char* fmt, va_list args ); + const char *GetName() const; + ShipRef GetShip() const; + CharacterRef GetChar() const; + DestinyManager * GetDestiny(); + uint32 GetLocationID() const; + void MoveItem(uint32 itemID, uint32 location, EVEItemFlags flag); // NPC Object calls: // none diff --git a/include/eve-server/ship/dgmtypeattributeinfo.h b/include/eve-server/ship/dgmtypeattributeinfo.h index ab044a56..6cd8accc 100644 --- a/include/eve-server/ship/dgmtypeattributeinfo.h +++ b/include/eve-server/ship/dgmtypeattributeinfo.h @@ -1,3 +1,28 @@ +/* + ------------------------------------------------------------------------------------ + LICENSE: + ------------------------------------------------------------------------------------ + This file is part of EVEmu: EVE Online Server Emulator + Copyright 2006 - 2011 The EVEmu Team + For the latest information visit http://evemu.org + ------------------------------------------------------------------------------------ + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA, or go to + http://www.gnu.org/copyleft/lesser.txt. + ------------------------------------------------------------------------------------ + Author: Captnoord +*/ + #ifndef dgmtypeattributeinfo_h__ #define dgmtypeattributeinfo_h__ diff --git a/src/eve-server/CMakeLists.txt b/src/eve-server/CMakeLists.txt index 112bde7e..8c0cb1c9 100644 --- a/src/eve-server/CMakeLists.txt +++ b/src/eve-server/CMakeLists.txt @@ -241,6 +241,7 @@ SET( infogathering_SOURCE SET( inventory_INCLUDE "${TARGET_INCLUDE_DIR}/inventory/AttributeEnum.h" "${TARGET_INCLUDE_DIR}/inventory/AttributeMgr.h" + "${TARGET_INCLUDE_DIR}/inventory/EffectsEnum.h" "${TARGET_INCLUDE_DIR}/inventory/EVEAttributeMgr.h" "${TARGET_INCLUDE_DIR}/inventory/EVEAttributes.h" "${TARGET_INCLUDE_DIR}/inventory/InvBrokerService.h" @@ -399,9 +400,18 @@ SET( shipmodules_INCLUDE "${TARGET_INCLUDE_DIR}/ship/Modules/Modules.h" "${TARGET_INCLUDE_DIR}/ship/Modules/PassiveModules.h" "${TARGET_INCLUDE_DIR}/ship/Modules/RigModule.h" - "${TARGET_INCLUDE_DIR}/ship/Modules/SubSystemModules.h" ) + "${TARGET_INCLUDE_DIR}/ship/Modules/SubSystemModules.h" + "${TARGET_INCLUDE_DIR}/ship/Modules/propulsion_modules/Afterburner.h" + ) SET( shipmodules_SOURCE - ) + "${TARGET_SOURCE_DIR}/ship/Modules/ActiveModules.cpp" + "${TARGET_SOURCE_DIR}/ship/Modules/ModuleDB.cpp" + "${TARGET_SOURCE_DIR}/ship/Modules/ModuleEffects.cpp" + "${TARGET_SOURCE_DIR}/ship/Modules/PassiveModules.cpp" + "${TARGET_SOURCE_DIR}/ship/Modules/RigModule.cpp" + "${TARGET_SOURCE_DIR}/ship/Modules/SubSystemModules.cpp" + "${TARGET_SOURCE_DIR}/ship/Modules/propulsion_modules/Afterburner.cpp" + ) #"${TARGET_SOURCE_DIR}/ship/Modules/.cpp" #"${TARGET_SOURCE_DIR}/ship/Modules/.cpp" ) @@ -409,7 +419,8 @@ SET( shipmodulecomponents_INCLUDE "${TARGET_INCLUDE_DIR}/ship/Modules/components/ActiveModuleProcessingComponent.h" "${TARGET_INCLUDE_DIR}/ship/Modules/components/ModifyShipAttributesComponent.h" ) SET( shipmodulecomponents_SOURCE - ) + "${TARGET_SOURCE_DIR}/ship/Modules/components/ActiveModuleProcessingComponent.cpp" + "${TARGET_SOURCE_DIR}/ship/Modules/components/ModifyShipAttributesComponent.cpp" ) #"${TARGET_SOURCE_DIR}/ship/Modules/.cpp" #"${TARGET_SOURCE_DIR}/ship/Modules/.cpp" ) diff --git a/src/eve-server/ship/DestinyManager.cpp b/src/eve-server/ship/DestinyManager.cpp index f5e6deea..f766c49d 100644 --- a/src/eve-server/ship/DestinyManager.cpp +++ b/src/eve-server/ship/DestinyManager.cpp @@ -1153,18 +1153,15 @@ PyResult DestinyManager::AttemptDockOperation() // Calculate 1000m out from docking bay along dock orientation vector away from station: stationOrigin.x += stationDockPoint.x; stationOrigin.y += stationDockPoint.y; - stationOrigin.z -= stationDockPoint.z; + stationOrigin.z += stationDockPoint.z; stationOrigin.x += 1000 * stationDockOrientation.x; stationOrigin.y += 1000 * stationDockOrientation.y; - stationOrigin.z += (-1) * (1000 * stationDockOrientation.z); - //stationDockPoint.x += 1000 * stationDockOrientation.x; - //stationDockPoint.y += 1000 * stationDockOrientation.y; - //stationDockPoint.z += 1000 * stationDockOrientation.z; + stationOrigin.z += 1000 * stationDockOrientation.z; OnDockingAccepted da; - da.end_x = stationOrigin.x; //stationDockPoint.x; - da.end_y = stationOrigin.y; //stationDockPoint.y; - da.end_z = stationOrigin.z; //stationDockPoint.z; + da.end_x = stationOrigin.x; + da.end_y = stationOrigin.y; + da.end_z = stationOrigin.z; da.start_x = position.x; da.start_y = position.y; da.start_z = position.z; @@ -1181,7 +1178,7 @@ PyResult DestinyManager::AttemptDockOperation() // Verify range to station is within docking perimeter of 500 meters: // (there is something WRONG with this as it will become true even when the client says ship is still about 14km from station) - if( (rangeToStation - station->GetRadius()) > 500 ) + if( (rangeToStation - station->GetRadius()) > 1500 ) { // WARNING: DO NOT uncomment the following line as it for some reason causes HEAP corruption to occur on auto-docking //who->SetPendingDockOperation( true ); // Set client object into state that a Docking operation is pending diff --git a/src/eve-server/ship/ModuleManager.cpp b/src/eve-server/ship/ModuleManager.cpp index 6ef643b9..c41fd66e 100644 --- a/src/eve-server/ship/ModuleManager.cpp +++ b/src/eve-server/ship/ModuleManager.cpp @@ -28,15 +28,23 @@ //ModuleContainer class definitions #pragma region ModuleContainerClass -ModuleContainer::ModuleContainer(uint32 lowSlots, uint32 medSlots, uint32 highSlots, uint32 rigSlots, uint32 subSystemSlots) +ModuleContainer::ModuleContainer(uint32 lowSlots, uint32 medSlots, uint32 highSlots, uint32 rigSlots, uint32 subSystemSlots, + uint32 turretSlots, uint32 launcherSlots, ModuleManager * myManager) { - m_LowSlots = lowSlots; - m_MediumSlots = medSlots; - m_HighSlots = highSlots; - m_RigSlots = rigSlots; - m_SubSystemSlots = subSystemSlots; + m_LowSlots = lowSlots; + m_MediumSlots = medSlots; + m_HighSlots = highSlots; + m_RigSlots = rigSlots; + m_SubSystemSlots = subSystemSlots; + m_TurretSlots = turretSlots; + m_LauncherSlots = launcherSlots; - _initializeModuleContainers(); + _initializeModuleContainers(); + + m_TotalTurretsFitted = 0; + m_TotalLaunchersFitted = 0; + + m_MyManager = myManager; } ModuleContainer::~ModuleContainer() @@ -74,24 +82,46 @@ ModuleContainer::~ModuleContainer() void ModuleContainer::AddModule(uint32 flag, GenericModule * mod) { - switch(_checkBounds(flag)) - { - case NaT: sLog.Error("AddModule","Out of bounds"); break; - case slotTypeSubSystem: _addSubSystemModule(flag, mod); break; - case slotTypeRig: _addRigModule(flag, mod); break; - case slotTypeLowPower: _addLowSlotModule(flag, mod); break; - case slotTypeMedPower: _addMediumSlotModule(flag, mod); break; - case slotTypeHiPower: _addHighSlotModule(flag, mod); break; - } - - + switch(_checkBounds(flag)) + { + case NaT: + sLog.Error("ModuleContainer::AddModule()","Flag Out of bounds"); + break; + case slotTypeSubSystem: + m_SubSystemModules[flag - flagSubSystem0] = mod; + break; + case slotTypeRig: + m_RigModules[flag - flagRigSlot0] = mod; + break; + case slotTypeLowPower: + m_LowSlotModules[flag - flagLowSlot0] = mod; + break; + case slotTypeMedPower: + m_MediumSlotModules[flag - flagMedSlot0] = mod; + break; + case slotTypeHiPower: + m_HighSlotModules[flag - flagHiSlot0] = mod; + break; + } + + // Maintain Turret and Launcher Fitted module counts: + if( mod->isTurretFitted() ) + m_TotalTurretsFitted++; + if( mod->isLauncherFitted() ) + m_TotalLaunchersFitted++; + + // Maintain the Modules Fitted By Group counter for this module group: + if( m_ModulesFittedByGroupID.find(mod->getItem()->groupID()) != m_ModulesFittedByGroupID.end() ) + m_ModulesFittedByGroupID.find(mod->getItem()->groupID())->second += 1; + else + m_ModulesFittedByGroupID.insert(std::pair(mod->getItem()->groupID(), 1)); } void ModuleContainer::RemoveModule(EVEItemFlags flag) { GenericModule * mod = GetModule(flag); - _removeModule(mod->flag()); + _removeModule(mod->flag(), mod); //delete the module delete mod; @@ -102,7 +132,7 @@ void ModuleContainer::RemoveModule(uint32 itemID) { GenericModule * mod = GetModule(itemID); - _removeModule(mod->flag()); + _removeModule(mod->flag(), mod); //delete the module delete mod; @@ -111,69 +141,73 @@ void ModuleContainer::RemoveModule(uint32 itemID) GenericModule * ModuleContainer::GetModule(EVEItemFlags flag) { - switch(_checkBounds(flag)) - { - case NaT: sLog.Error("AddModule","Out of bounds"); break; - case slotTypeSubSystem: return _getSubSystemModule(flag); break; - case slotTypeRig: return _getRigModule(flag); break; - case slotTypeLowPower: return _getLowSlotModule(flag); break; - case slotTypeMedPower: return _getMediumSlotModule(flag); break; - case slotTypeHiPower: return _getHighSlotModule(flag); break; - } - - return NULL; + switch(_checkBounds(flag)) + { + case NaT: + sLog.Error("ModuleContainer::AddModule()","Flag Out of bounds"); + break; + case slotTypeSubSystem: + return m_SubSystemModules[flag - flagSubSystem0]; + break; + case slotTypeRig: + return m_RigModules[flag - flagRigSlot0]; + break; + case slotTypeLowPower: + return m_LowSlotModules[flag - flagLowSlot0]; + break; + case slotTypeMedPower: + return m_MediumSlotModules[flag - flagMedSlot0]; + break; + case slotTypeHiPower: + return m_HighSlotModules[flag - flagHiSlot0]; + break; + } + + return NULL; } GenericModule * ModuleContainer::GetModule(uint32 itemID) { - //iterate through the list and see if we have it - uint8 r; - for(r = 0; r < MAX_HIGH_SLOT_COUNT; r++) - { - if(m_HighSlotModules[r]->itemID() == itemID) - return m_HighSlotModules[r]; - } - - for(r = 0; r < MAX_MEDIUM_SLOT_COUNT; r++) - { - if(m_MediumSlotModules[r]->itemID() == itemID) - return m_MediumSlotModules[r]; - } - - for(r = 0; r < MAX_LOW_SLOT_COUNT; r++) - { - if(m_LowSlotModules[r]->itemID() == itemID) - return m_LowSlotModules[r]; - } - - for(r = 0; r < MAX_ASSEMBLY_COUNT; r++) - { - if(m_SubSystemModules[r]->itemID() == itemID) - return m_SubSystemModules[r]; - } - - for(r = 0; r < MAX_RIG_COUNT; r++) - { - if(m_RigModules[r]->itemID() == itemID) - return m_RigModules[r]; - } - - sLog.Warning("ModuleContainer","Search for itemID: %u yielded no results", itemID); - - return NULL; //we don't -} - -void ModuleContainer::_removeModule(EVEItemFlags flag) -{ - switch(_checkBounds(flag)) - { - case NaT: sLog.Error("AddModule","Out of bounds"); break; - case slotTypeSubSystem: _removeSubSystemModule(flag); break; - case slotTypeRig: _removeRigSlotModule(flag); break; - case slotTypeLowPower: _removeLowSlotModule(flag); break; - case slotTypeMedPower: _removeMediumSlotModule(flag); break; - case slotTypeHiPower: _removeHighSlotModule(flag); break; - } + //iterate through the list and see if we have it + uint8 r; + for(r = 0; r < MAX_HIGH_SLOT_COUNT; r++) + { + if( !(m_HighSlotModules[r] == NULL) ) + if(m_HighSlotModules[r]->itemID() == itemID) + return m_HighSlotModules[r]; + } + + for(r = 0; r < MAX_MEDIUM_SLOT_COUNT; r++) + { + if( !(m_MediumSlotModules[r] == NULL) ) + if(m_MediumSlotModules[r]->itemID() == itemID) + return m_MediumSlotModules[r]; + } + + for(r = 0; r < MAX_LOW_SLOT_COUNT; r++) + { + if( !(m_LowSlotModules[r] == NULL) ) + if(m_LowSlotModules[r]->itemID() == itemID) + return m_LowSlotModules[r]; + } + + for(r = 0; r < MAX_ASSEMBLY_COUNT; r++) + { + if( !(m_SubSystemModules[r] == NULL) ) + if(m_SubSystemModules[r]->itemID() == itemID) + return m_SubSystemModules[r]; + } + + for(r = 0; r < MAX_RIG_COUNT; r++) + { + if( !(m_RigModules[r] == NULL) ) + if(m_RigModules[r]->itemID() == itemID) + return m_RigModules[r]; + } + + sLog.Warning("ModuleContainer::GetModule()","Search for itemID: %u yielded no results", itemID); + + return NULL; //we don't } @@ -237,176 +271,190 @@ bool ModuleContainer::isSubSystem(uint32 itemID) return mod->isSubSystem(); } -void ModuleContainer::_process(processType p) +uint32 ModuleContainer::GetFittedModuleCountByGroup(uint32 groupID) { - //high slots - _processEx(p, highSlot); - - //med slots - _processEx(p, mediumSlot); - - //low slots - _processEx(p, lowSlot); + uint32 moduleCountByGroup = 0; + if( m_ModulesFittedByGroupID.find(groupID) == m_ModulesFittedByGroupID.end() ) + return 0; + else + return m_ModulesFittedByGroupID.find(groupID)->second; } -void ModuleContainer::_processEx(processType p, slotType t) +void ModuleContainer::SaveModules() { - uint8 r, COUNT; + uint8 r; + for(r = 0; r < MAX_HIGH_SLOT_COUNT; r++) + { + if( !(m_HighSlotModules[r] == NULL) ) + m_HighSlotModules[r]->getItem()->SaveItem(); + } - GenericModule **cur; + for(r = 0; r < MAX_MEDIUM_SLOT_COUNT; r++) + { + if( !(m_MediumSlotModules[r] == NULL) ) + m_MediumSlotModules[r]->getItem()->SaveItem(); + } - switch(t) - { - case highSlot: - COUNT = MAX_HIGH_SLOT_COUNT; - cur = m_HighSlotModules; - break; - case mediumSlot: - COUNT = MAX_MEDIUM_SLOT_COUNT; - cur = m_MediumSlotModules; - break; - case lowSlot: - COUNT = MAX_LOW_SLOT_COUNT; - cur = m_LowSlotModules; - break; - case rigSlot: - COUNT = MAX_RIG_COUNT; - cur = m_RigModules; - break; - case subSystemSlot: - COUNT = MAX_ASSEMBLY_COUNT; - cur = m_SubSystemModules; - break; - } + for(r = 0; r < MAX_LOW_SLOT_COUNT; r++) + { + if( !(m_LowSlotModules[r] == NULL) ) + m_LowSlotModules[r]->getItem()->SaveItem(); + } - switch(p) - { - case typeOnlineAll: - for(r = 0; r < COUNT; r++, cur++) - { - if(*cur == NULL) - continue; + for(r = 0; r < MAX_ASSEMBLY_COUNT; r++) + { + if( !(m_SubSystemModules[r] == NULL) ) + m_SubSystemModules[r]->getItem()->SaveItem(); + } - (*cur)->Online(); - } - break; + for(r = 0; r < MAX_RIG_COUNT; r++) + { + if( !(m_RigModules[r] == NULL) ) + m_RigModules[r]->getItem()->SaveItem(); + } - case typeOfflineAll: - for(r = 0; r < COUNT; r++, cur++) - { - if(cur == NULL) - continue; +} - (*cur)->Offline(); - } +void ModuleContainer::_removeModule(EVEItemFlags flag, GenericModule * mod) +{ + switch(_checkBounds(flag)) + { + case NaT: + sLog.Error("ModuleContainer::_removeModule()","Flag Out of bounds"); + break; + case slotTypeSubSystem: + m_SubSystemModules[flag-flagSubSystem0] = NULL; break; - - case typeDeactivateAll: - for(r = 0; r < COUNT; r++, cur++) - { - if(*cur == NULL) - continue; - - (*cur)->Deactivate(); - } + case slotTypeRig: + m_RigModules[flag-flagRigSlot0] = NULL; break; - - case typeUnloadAll: - for(r = 0; r < COUNT; r++, cur++) - { - if(*cur == NULL) - continue; - - (*cur)->Unload(); - } + case slotTypeLowPower: + m_LowSlotModules[flag-flagLowSlot0] = NULL; break; - - case typeProcessAll: - for(r = 0; r < COUNT; r++, cur++) - { - if(*cur == NULL) - continue; - - (*cur)->Process(); - } + case slotTypeMedPower: + m_MediumSlotModules[flag-flagMedSlot0] = NULL; break; - } -} - - -void ModuleContainer::_addSubSystemModule(uint32 flag, GenericModule * mod) -{ - m_SubSystemModules[flag - flagSubSystem0] = mod; -} - -void ModuleContainer::_addRigModule(uint32 flag, GenericModule * mod) -{ - m_RigModules[flag - flagRigSlot0] = mod; -} - -void ModuleContainer::_addLowSlotModule(uint32 flag, GenericModule * mod) -{ - m_LowSlotModules[flag - flagLowSlot0] = mod; -} - -void ModuleContainer::_addMediumSlotModule(uint32 flag, GenericModule * mod) -{ - m_MediumSlotModules[flag - flagMedSlot0] = mod; -} - -void ModuleContainer::_addHighSlotModule(uint32 flag, GenericModule * mod) -{ - m_HighSlotModules[flag - flagHiSlot0] = mod; -} + case slotTypeHiPower: + m_HighSlotModules[flag-flagHiSlot0] = NULL; + break; + } -GenericModule * ModuleContainer::_getSubSystemModule(uint32 flag) -{ - return m_SubSystemModules[flag - flagSubSystem0]; -} + // Maintain Turret and Launcher Fitted module counts: + if( mod->isTurretFitted() ) + m_TotalTurretsFitted--; + if( mod->isLauncherFitted() ) + m_TotalLaunchersFitted--; -GenericModule * ModuleContainer::_getRigModule(uint32 flag) -{ - return m_RigModules[flag - flagRigSlot0]; + // Maintain the Modules Fitted By Group counter for this module group: + if( m_ModulesFittedByGroupID.find(mod->getItem()->groupID()) != m_ModulesFittedByGroupID.end() ) + { + uint32 moduleCount = 0; + if( (moduleCount = m_ModulesFittedByGroupID.find(mod->getItem()->groupID())->second) > 1) + // We still have more than one module of this group fitted, so just reduce number fitted by 1: + m_ModulesFittedByGroupID.find(mod->getItem()->groupID())->second -= 1; + else + // This was the last module of this group fitted, so remove the entry from the map: + m_ModulesFittedByGroupID.erase(mod->getItem()->groupID()); + } + else + sLog.Error( "ModuleContainer::_removeModule()", "Removing Module from ship fit when it had NO entry in m_ModulesFittedByGroup !" ); } -GenericModule * ModuleContainer::_getLowSlotModule(uint32 flag) +void ModuleContainer::_process(processType p) { - return m_LowSlotModules[flag - flagLowSlot0]; -} + //high slots + _processEx(p, highSlot); -GenericModule * ModuleContainer::_getMediumSlotModule(uint32 flag) -{ - return m_MediumSlotModules[flag - flagMedSlot0]; -} + //med slots + _processEx(p, mediumSlot); -GenericModule * ModuleContainer::_getHighSlotModule(uint32 flag) -{ - return m_HighSlotModules[flag - flagHiSlot0]; + //low slots + _processEx(p, lowSlot); } -void ModuleContainer::_removeSubSystemModule(uint32 flag) -{ - m_SubSystemModules[flag-flagSubSystem0] = NULL; -} - -void ModuleContainer::_removeRigSlotModule(uint32 flag) -{ - m_RigModules[flag-flagRigSlot0] = NULL; -} - -void ModuleContainer::_removeLowSlotModule(uint32 flag) +void ModuleContainer::_processEx(processType p, slotType t) { - m_LowSlotModules[flag-flagLowSlot0] = NULL; -} + uint8 r, COUNT; + + GenericModule **cur; + + switch(t) + { + case highSlot: + COUNT = MAX_HIGH_SLOT_COUNT; + cur = m_HighSlotModules; + break; + case mediumSlot: + COUNT = MAX_MEDIUM_SLOT_COUNT; + cur = m_MediumSlotModules; + break; + case lowSlot: + COUNT = MAX_LOW_SLOT_COUNT; + cur = m_LowSlotModules; + break; + case rigSlot: + COUNT = MAX_RIG_COUNT; + cur = m_RigModules; + break; + case subSystemSlot: + COUNT = MAX_ASSEMBLY_COUNT; + cur = m_SubSystemModules; + break; + } + + switch(p) + { + case typeOnlineAll: + for(r = 0; r < COUNT; r++, cur++) + { + if(*cur == NULL) + continue; + + (*cur)->Online(); + } + break; + + case typeOfflineAll: + for(r = 0; r < COUNT; r++, cur++) + { + if(cur == NULL) + continue; + + (*cur)->Offline(); + } + break; + + case typeDeactivateAll: + for(r = 0; r < COUNT; r++, cur++) + { + if(*cur == NULL) + continue; + + (*cur)->Deactivate(); + } + break; + + case typeUnloadAll: + for(r = 0; r < COUNT; r++, cur++) + { + if(*cur == NULL) + continue; + + (*cur)->Unload(); + } + break; + + case typeProcessAll: + for(r = 0; r < COUNT; r++, cur++) + { + if(*cur == NULL) + continue; -void ModuleContainer::_removeMediumSlotModule(uint32 flag) -{ - m_MediumSlotModules[flag-flagMedSlot0] = NULL; -} + (*cur)->Process(); + } -void ModuleContainer::_removeHighSlotModule(uint32 flag) -{ - m_HighSlotModules[flag-flagHiSlot0] = NULL; + break; + } } //TODO - make this better -Luck @@ -434,65 +482,65 @@ EVEItemSlotType ModuleContainer::_checkBounds(uint32 flag) bool ModuleContainer::_isLowSlot(uint32 flag) { - if( flag >= flagLowSlot0 && flag <= flagLowSlot7 ) - { - if( (flag - flagLowSlot0) < m_LowSlots ) - return true; - else - sLog.Error("_isLowSlot", "this shouldn't happen"); - } + if( flag >= flagLowSlot0 && flag <= flagLowSlot7 ) + { + if( (flag - flagLowSlot0) < m_LowSlots ) + return true; + else + sLog.Error("ModuleContainer::_isLowSlot()", "this shouldn't happen"); + } return false; } bool ModuleContainer::_isMediumSlot(uint32 flag) { - if( flag >= flagMedSlot0 && flag <= flagMedSlot7 ) - { - if( (flag - flagMedSlot0) < m_MediumSlots ) - return true; - else - sLog.Error("_isMediumSlot", "this shouldn't happen"); - } + if( flag >= flagMedSlot0 && flag <= flagMedSlot7 ) + { + if( (flag - flagMedSlot0) < m_MediumSlots ) + return true; + else + sLog.Error("ModuleContainer::_isMediumSlot()", "this shouldn't happen"); + } return false; } bool ModuleContainer::_isHighSlot(uint32 flag) { - if( flag >= flagHiSlot0 && flag <= flagHiSlot7 ) - { - if( (flag - flagHiSlot0) < m_HighSlots ) - return true; - else - sLog.Error("_isHighSlot", "this shouldn't happen"); - } + if( flag >= flagHiSlot0 && flag <= flagHiSlot7 ) + { + if( (flag - flagHiSlot0) < m_HighSlots ) + return true; + else + sLog.Error("ModuleContainer::_isHighSlot()", "this shouldn't happen"); + } return false; } bool ModuleContainer::_isRigSlot(uint32 flag) { - if( flag >= flagRigSlot0 && flag <= flagRigSlot7 ) - { - if( (flag - flagRigSlot0) < m_RigSlots ) - return true; - else - sLog.Error("_isRigSlot", "this shouldn't happen"); - } + if( flag >= flagRigSlot0 && flag <= flagRigSlot7 ) + { + if( (flag - flagRigSlot0) < m_RigSlots ) + return true; + else + sLog.Error("ModuleContainer::_isRigSlot()", "this shouldn't happen"); + } return false; } bool ModuleContainer::_isSubSystemSlot(uint32 flag) { - if( flag >= flagSubSystem0 && flag <= flagSubSystem7 ) - { - if( (flag - flagSubSystem0) < m_SubSystemSlots ) - return true; - else - sLog.Error("_isSubSystemSlot", "this shouldn't happen"); - } + if( flag >= flagSubSystem0 && flag <= flagSubSystem7 ) + { + if( (flag - flagSubSystem0) < m_SubSystemSlots ) + return true; + else + sLog.Error("ModuleContainer::_isSubSystemSlot()", "this shouldn't happen"); + } return false; } @@ -523,26 +571,82 @@ void ModuleContainer::_initializeModuleContainers() } #pragma endregion +/////////////////////////// END MODULECONTAINER ////////////////////////////////// + //ModuleManager class definitions #pragma region ModuleManagerClass ModuleManager::ModuleManager(Ship *const ship) { + // Create ModuleContainer object and initialize with sizes for all slot banks for this ship: + m_Modules = new ModuleContainer((uint32)ship->GetAttribute(AttrLowSlots).get_int(), + (uint32)ship->GetAttribute(AttrMedSlots).get_int(), + (uint32)ship->GetAttribute(AttrHiSlots).get_int(), + (uint32)ship->GetAttribute(AttrRigSlots).get_int(), + (uint32)ship->GetAttribute(AttrSubSystemSlot).get_int(), + (uint32)ship->GetAttribute(AttrTurretSlotsLeft).get_int(), + (uint32)ship->GetAttribute(AttrLauncherSlotsLeft).get_int(), + this); + + // Store reference to the Ship object to which the ModuleManager belongs: + m_Ship = ship; + + // Load modules, rigs and subsystems from Ship's inventory into ModuleContainer: + uint32 flagIndex; + for(flagIndex=flagLowSlot0; flagIndex<=flagLowSlot7; flagIndex++) + { + InventoryItemRef itemRef; + m_Ship->FindSingleByFlag( (EVEItemFlags)flagIndex, itemRef ); + if( !(itemRef == NULL) ) + _fitModule( itemRef, (EVEItemFlags)flagIndex ); + } - m_Modules = new ModuleContainer((uint32)ship->GetAttribute(AttrLowSlots).get_int(), - (uint32)ship->GetAttribute(AttrMedSlots).get_int(), - (uint32)ship->GetAttribute(AttrHiSlots).get_int(), - (uint32)ship->GetAttribute(AttrRigSlots).get_int(), - (uint32)ship->GetAttribute(AttrSubSystemSlot).get_int()); + for(flagIndex=flagMedSlot0; flagIndex<=flagMedSlot7; flagIndex++) + { + InventoryItemRef itemRef; + m_Ship->FindSingleByFlag( (EVEItemFlags)flagIndex, itemRef ); + if( !(itemRef == NULL) ) + _fitModule( itemRef, (EVEItemFlags)flagIndex ); + } - m_Ship = ship; + for(flagIndex=flagHiSlot0; flagIndex<=flagHiSlot7; flagIndex++) + { + InventoryItemRef itemRef; + m_Ship->FindSingleByFlag( (EVEItemFlags)flagIndex, itemRef ); + if( !(itemRef == NULL) ) + _fitModule( itemRef, (EVEItemFlags)flagIndex ); + } + + for(flagIndex=flagRigSlot0; flagIndex<=flagRigSlot7; flagIndex++) + { + InventoryItemRef itemRef; + m_Ship->FindSingleByFlag( (EVEItemFlags)flagIndex, itemRef ); + if( !(itemRef == NULL) ) + _fitModule( itemRef, (EVEItemFlags)flagIndex ); + } + + for(flagIndex=flagSubSystem0; flagIndex<=flagSubSystem7; flagIndex++) + { + InventoryItemRef itemRef; + m_Ship->FindSingleByFlag( (EVEItemFlags)flagIndex, itemRef ); + if( !(itemRef == NULL) ) + _fitModule( itemRef, (EVEItemFlags)flagIndex ); + } } ModuleManager::~ModuleManager() { - //module cleanup is handled in the ModuleContainer destructor - delete m_Modules; - m_Modules = NULL; + //module cleanup is handled in the ModuleContainer destructor + delete m_Modules; + m_Modules = NULL; +} + +bool ModuleManager::IsSlotOccupied(uint32 flag) +{ + if( this->m_Modules->GetModule(EVEItemFlags(flag)) == NULL ) + return false; + else + return true; } void ModuleManager::_SendInfoMessage(const char *fmt, ...) @@ -572,12 +676,17 @@ void ModuleManager::_SendErrorMessage(const char *fmt, ...) } } -void ModuleManager::InstallRig(InventoryItemRef item) +bool ModuleManager::InstallRig(InventoryItemRef item, EVEItemFlags flag) { - if(item->groupID() >= 773 && item->groupID() <= 786 && item->groupID() != 783) - _fitModule(item); - else - sLog.Debug("ModuleManager","%s tried to fit item %u, which is not a rig", m_Ship->GetOperator()->GetName(), item->itemID()); + if(item->groupID() >= 773 && item->groupID() <= 786 && item->groupID() != 783) + { + _fitModule(item,flag); + return true; + } + else + sLog.Debug("ModuleManager","%s tried to fit item %u, which is not a rig", m_Ship->GetOperator()->GetName(), item->itemID()); + + return false; } void ModuleManager::UninstallRig(uint32 itemID) @@ -587,20 +696,35 @@ void ModuleManager::UninstallRig(uint32 itemID) mod->DestroyRig(); } -void ModuleManager::SwapSubSystem(InventoryItemRef item) +bool ModuleManager::SwapSubSystem(InventoryItemRef item, EVEItemFlags flag) { - if(item->groupID() >= 954 && item->groupID() <= 958) - _fitModule(item); - else - sLog.Debug("ModuleManager","%s tried to fit item %u, which is not a subsystem", m_Ship->GetOperator()->GetName(), item->itemID()); + if(item->groupID() >= 954 && item->groupID() <= 958) + { + _fitModule(item,flag); + return true; + } + else + sLog.Debug("ModuleManager","%s tried to fit item %u, which is not a subsystem", m_Ship->GetOperator()->GetName(), item->itemID()); + + return false; } -void ModuleManager::FitModule(InventoryItemRef item) +bool ModuleManager::FitModule(InventoryItemRef item, EVEItemFlags flag) { - if(item->categoryID() == EVEDB::invCategories::Module) - _fitModule(item); - else - sLog.Debug("ModuleManager","%s tried to fit item %u, which is not a module", m_Ship->GetOperator()->GetName(), item->itemID()); + if(item->categoryID() == EVEDB::invCategories::Module) + { + // Attempt to fit the module + if( _fitModule(item, flag) ) + { + // Now that module is successfully fitted, attempt to put it Online: + Online(item->itemID()); + return true; + } + } + else + sLog.Debug("ModuleManager","%s tried to fit item %u, which is not a module", m_Ship->GetOperator()->GetName(), item->itemID()); + + return false; } void ModuleManager::UnfitModule(uint32 itemID) @@ -613,11 +737,55 @@ void ModuleManager::UnfitModule(uint32 itemID) } } -void ModuleManager::_fitModule(InventoryItemRef item) +bool ModuleManager::_fitModule(InventoryItemRef item, EVEItemFlags flag) { - GenericModule * mod = ModuleFactory(item, m_Ship->GetOperator()->GetShip()); + bool verifyFailed = false; + GenericModule * mod = ModuleFactory(item, ShipRef(m_Ship)); + + // Check for max turret modules allowed: + if( mod->isTurretFitted() && (m_Modules->GetFittedTurretCount() == m_Ship->GetMaxTurrentHardpoints().get_int()) ) + { + //std::map args; + //args["typename"] = new PyString(item->itemName().c_str()); + //args["portion"] = new PyInt(item->type().portionSize()); + + throw PyException( MakeUserError( "NotEnoughTurretSlots" ) ); + verifyFailed = true; + } + // Check for max launcher modules allowed: + if( mod->isLauncherFitted() && (m_Modules->GetFittedLauncherCount() == m_Ship->GetMaxLauncherHardpoints().get_int()) ) + { + //std::map args; + //args["typename"] = new PyString(item->itemName().c_str()); + //args["portion"] = new PyInt(item->type().portionSize()); + + throw PyException( MakeUserError( "NotEnoughLauncherSlots" ) ); + verifyFailed = true; + } + // Check for max modules of group allowed: + else if( mod->isMaxGroupFitLimited() && (m_Modules->GetFittedModuleCountByGroup(item->groupID()) == mod->getItem()->GetAttribute(AttrMaxGroupFitted).get_int()) ) + { + //std::map args; + //args["typename"] = new PyString(item->itemName().c_str()); + //args["portion"] = new PyInt(item->type().portionSize()); + + throw PyException( MakeUserError( "CantFitTooManyByGroup" ) ); + verifyFailed = true; + } + else + { + // Fit Module now that all checks have passed: + //m_Modules->AddModule(mod->flag(), mod); + m_Modules->AddModule(flag, mod); + } - m_Modules->AddModule(mod->flag(), mod); + if( verifyFailed ) + { + delete mod; + return false; + } + else + return true; } void ModuleManager::Online(uint32 itemID) @@ -646,31 +814,33 @@ void ModuleManager::OfflineAll() int32 ModuleManager::Activate(uint32 itemID, std::string effectName, uint32 targetID, uint32 repeat) { - sLog.Debug("Activate","Needs to be implemented"); - return 1; - GenericModule * mod = m_Modules->GetModule(itemID); - if( mod != NULL ) - { - ModuleCommand cmd = _translateEffectName(effectName); - // mod->getItem()->PutOnline(); - if(cmd == ONLINE) - mod->Online(); // this currently fails since m_selectedEffect and m_defaultEffect in the ModuleEffect class are undefined - //there needs to be more cases here i just don't know what they're called yet - } + //sLog.Debug("Activate","Needs to be implemented"); + //return 1; + + GenericModule * mod = m_Modules->GetModule(itemID); + if( mod != NULL ) + { + ModuleCommand cmd = _translateEffectName(effectName); + mod->getItem()->PutOnline(); + //if(cmd == ONLINE) + // mod->Online(); // this currently fails since m_selectedEffect and m_defaultEffect in the ModuleEffect class are undefined + //there needs to be more cases here i just don't know what they're called yet + } return 1; } void ModuleManager::Deactivate(uint32 itemID, std::string effectName) { - GenericModule * mod = m_Modules->GetModule(itemID); - if( mod != NULL ) - { - ModuleCommand cmd = _translateEffectName(effectName); - if(cmd == OFFLINE) - mod->Offline(); - //there needs to be more cases here i just don't know what they're called yet - } + GenericModule * mod = m_Modules->GetModule(itemID); + if( mod != NULL ) + { + ModuleCommand cmd = _translateEffectName(effectName); + mod->getItem()->PutOffline(); + //if(cmd == OFFLINE) + // mod->Offline(); // this currently fails since m_selectedEffect and m_defaultEffect in the ModuleEffect class are undefined + //there needs to be more cases here i just don't know what they're called yet + } } void ModuleManager::DeactivateAllModules() @@ -814,7 +984,12 @@ std::vector ModuleManager::GetStackedItems(uint32 typeID, Modul break; } - return mods; + return mods; +} + +void ModuleManager::SaveModules() +{ + m_Modules->SaveModules(); } void ModuleManager::_processExternalEffect(SubEffect * s) @@ -842,20 +1017,20 @@ void ModuleManager::_processExternalEffect(SubEffect * s) ModuleCommand ModuleManager::_translateEffectName(std::string s) { - //slow but it's better to do it once then many times as it gets passed around in modules or w/e - //all modules should expect a ModuleCommand instead of a string - - //slightly faster version for when I know what things are really called - //might as well use, but will definately not be right - - switch(s[0]) - { - case 'A': return ACTIVATE; - case 'D': return s[2] == 'a' ? DEACTIVATE : DEOVERLOAD; - case 'O': return s[1] == 'n' ? ONLINE : (s[1] == 'f' ? OFFLINE : OVERLOAD); //compound booleans ftw - } - - return CMD_ERROR; + //slow but it's better to do it once then many times as it gets passed around in modules or w/e + //all modules should expect a ModuleCommand instead of a string + + //slightly faster version for when I know what things are really called + //might as well use, but will definately not be right + + switch(s[0]) + { + case 'a': return ACTIVATE; + case 'd': return s[2] == 'a' ? DEACTIVATE : DEOVERLOAD; + case 'o': return s[1] == 'n' ? ONLINE : (s[1] == 'f' ? OFFLINE : OVERLOAD); //compound booleans ftw + } + + return CMD_ERROR; } #pragma endregion \ No newline at end of file diff --git a/src/eve-server/ship/Ship.cpp b/src/eve-server/ship/Ship.cpp index 54361c74..c56f95cc 100644 --- a/src/eve-server/ship/Ship.cpp +++ b/src/eve-server/ship/Ship.cpp @@ -138,9 +138,12 @@ ShipRef Ship::Spawn(ItemFactory &factory, ItemData &data) { // Warp Speed Multiplier if( !(sShipRef.get()->HasAttribute(AttrWarpSpeedMultiplier)) ) sShipRef.get()->SetAttribute(AttrWarpSpeedMultiplier, 1.0f); - - //Save Ship To Database. - sShipRef->SaveShip(); + // CPU Load of the ship (new ships have zero load with no modules fitted, of course): + if( !(sShipRef.get()->HasAttribute(AttrCpuLoad)) ) + sShipRef.get()->SetAttribute(AttrCpuLoad, 0); + // Power Load of the ship (new ships have zero load with no modules fitted, of course): + if( !(sShipRef.get()->HasAttribute(AttrPowerLoad)) ) + sShipRef.get()->SetAttribute(AttrPowerLoad, 0); return sShipRef; } @@ -170,8 +173,11 @@ bool Ship::_Load() bool loadSuccess = InventoryItem::_Load(); // Attributes are loaded here! // TODO: MOVE THIS TO Ship::Load() or some other place AFTER InventoryItem::mAttributeMap has been loaded - //allocate the module manager - m_ModuleManager = new ModuleManager(this); + // allocate the module manager, only the first time: + if( m_ModuleManager == NULL ) + m_ModuleManager = new ModuleManager(this); + + // check for module manager load success if( m_ModuleManager == NULL ) loadSuccess = false; @@ -225,45 +231,47 @@ void Ship::ValidateAddItem(EVEItemFlags flag, InventoryItemRef item) throw PyException( MakeCustomError( "%s has no corporate hangars.", item->itemName().c_str() ) ); } else if( flag == flagCargoHold ) - { - //get all items in cargohold - EvilNumber capacityUsed(0); - std::vector items; - m_pOperator->GetShip()->FindByFlag(flag, items); // Operator assumed to be Client * - for(uint32 i = 0; i < items.size(); i++){ - capacityUsed += items[i]->GetAttribute(AttrVolume); - } - if( capacityUsed + item->GetAttribute(AttrVolume) > m_pOperator->GetShip()->GetAttribute(AttrCapacity) ) // Operator assumed to be Client * - throw PyException( MakeCustomError( "Not enough cargo space!") ); - } - else if( flag > flagLowSlot0 && flag < flagHiSlot7 ) - { + { + //get all items in cargohold + EvilNumber capacityUsed(0); + std::vector items; + m_pOperator->GetShip()->FindByFlag(flag, items); // Operator assumed to be Client * + for(uint32 i = 0; i < items.size(); i++){ + capacityUsed += items[i]->GetAttribute(AttrVolume); + } + if( capacityUsed + item->GetAttribute(AttrVolume) > m_pOperator->GetShip()->GetAttribute(AttrCapacity) ) // Operator assumed to be Client * + throw PyException( MakeCustomError( "Not enough cargo space!") ); + } + else if( (flag >= flagLowSlot0) && (flag <= flagHiSlot7) ) + { if( m_pOperator->IsClient() ) - if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * - throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); - if(!ValidateItemSpecifics(item)) - throw PyException( MakeCustomError( "Your ship cannot equip this module" ) ); - if(item->categoryID() == EVEDB::invCategories::Charge) { - InventoryItemRef module; - m_pOperator->GetShip()->FindSingleByFlag(flag, module); // Operator assumed to be Client * - if(module->GetAttribute(AttrChargeSize) != item->GetAttribute(AttrChargeSize) ) - throw PyException( MakeCustomError( "The charge is not the correct size for this module." ) ); - if(module->GetAttribute(AttrChargeGroup1) != item->groupID()) - throw PyException( MakeCustomError( "Incorrect charge type for this module.") ); - } - } - else if( flag > flagRigSlot0 && flag < flagRigSlot7 ) - { + if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * + throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); + if(!ValidateItemSpecifics(item)) + throw PyException( MakeCustomError( "Your ship cannot equip this module" ) ); + if( m_ModuleManager->IsSlotOccupied(flag) ) + throw PyException( MakeUserError( "SlotAlreadyOccupied" ) ); + if(item->categoryID() == EVEDB::invCategories::Charge) { + InventoryItemRef module; + m_pOperator->GetShip()->FindSingleByFlag(flag, module); // Operator assumed to be Client * + if(module->GetAttribute(AttrChargeSize) != item->GetAttribute(AttrChargeSize) ) + throw PyException( MakeCustomError( "The charge is not the correct size for this module." ) ); + if(module->GetAttribute(AttrChargeGroup1) != item->groupID()) + throw PyException( MakeCustomError( "Incorrect charge type for this module.") ); + } + } + else if( (flag >= flagRigSlot0) && (flag <= flagRigSlot7) ) + { if( m_pOperator->IsClient() ) - if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * - throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); - if(m_pOperator->GetShip()->GetAttribute(AttrRigSize) != item->GetAttribute(AttrRigSize)) // Operator assumed to be Client * - throw PyException( MakeCustomError( "Your ship cannot fit this size module" ) ); - if( m_pOperator->GetShip()->GetAttribute(AttrUpgradeLoad) + item->GetAttribute(AttrUpgradeCost) > m_pOperator->GetShip()->GetAttribute(AttrUpgradeCapacity) ) // Operator assumed to be Client * - throw PyException( MakeCustomError( "Your ship cannot handle the extra calibration" ) ); - } - else if( flag > flagSubSystem0 && flag < flagSubSystem7 ) - { + if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * + throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); + if(m_pOperator->GetShip()->GetAttribute(AttrRigSize) != item->GetAttribute(AttrRigSize)) // Operator assumed to be Client * + throw PyException( MakeCustomError( "Your ship cannot fit this size module" ) ); + if( m_pOperator->GetShip()->GetAttribute(AttrUpgradeLoad) + item->GetAttribute(AttrUpgradeCost) > m_pOperator->GetShip()->GetAttribute(AttrUpgradeCapacity) ) // Operator assumed to be Client * + throw PyException( MakeCustomError( "Your ship cannot handle the extra calibration" ) ); + } + else if( (flag >= flagSubSystem0) && (flag <= flagSubSystem7) ) + { if( m_pOperator->IsClient() ) if(!Skill::FitModuleSkillCheck(item, character)) // SKIP THIS SKILL CHECK if Operator is NOT Client * throw PyException( MakeCustomError( "You do not have the required skills to fit this \n%s", item->itemName().c_str() ) ); @@ -462,8 +470,9 @@ bool Ship::ValidateBoardShip(ShipRef ship, CharacterRef character) void Ship::SaveShip() { sLog.Debug( "Ship::SaveShip()", "Saving all 'entity' info and attribute info to DB for ship %s (%u)...", itemName().c_str(), itemID() ); - SaveItem(); - SaveAttributes(); + + SaveItem(); // Save all attributes and item info + m_ModuleManager->SaveModules(); // Save all attributes and item info for all modules fitted to this ship } bool Ship::ValidateItemSpecifics(InventoryItemRef equip) { @@ -517,19 +526,31 @@ bool Ship::ValidateItemSpecifics(InventoryItemRef equip) { } /* Begin new Module Manager Interface */ - -void Ship::AddItem(EVEItemFlags flag, InventoryItemRef item) +uint32 Ship::FindAvailableModuleSlot( InventoryItemRef item ) { + // TODO: + // 1) get slot bank (low, med, high, rig, subsystem) from dgmTypeEffects using item->itemID() + // 2) query this ship's ModuleManager to determine if there are any free slots in that bank, + // it should return a slot flag number for the next available slot starting at the lowest number + // for that bank + // 3) return that slot flag number - ValidateAddItem( flag, item ); - - //it's a new module, make sure it's state starts at offline so that it is added correctly - if( item->categoryID() != EVEDB::invCategories::Charge ) - item->PutOffline(); - - item->Move(m_pOperator->GetLocationID(), flag); //TODO - check this + return flagAutoFit; +} - m_ModuleManager->FitModule(item); +void Ship::AddItem(EVEItemFlags flag, InventoryItemRef item) +{ + + ValidateAddItem( flag, item ); + + //it's a new module, make sure it's state starts at offline so that it is added correctly + if( item->categoryID() != EVEDB::invCategories::Charge ) + item->PutOffline(); + + // TODO: Somehow, if this returns FALSE, the item->Move() above has to be "undone"... can we do the move AFTER attempting to fit? + // what if we pass the flag into FitModule().... then if it returns true, the item->Move() can be called + if( m_ModuleManager->FitModule(item, flag) ) + item->Move(m_pOperator->GetLocationID(), flag); //TODO - check this } void Ship::RemoveItem(InventoryItemRef item, uint32 inventoryID, EVEItemFlags flag) diff --git a/src/eve-server/ship/ShipOperatorInterface.cpp b/src/eve-server/ship/ShipOperatorInterface.cpp index 180a3ae3..96d3aa8e 100644 --- a/src/eve-server/ship/ShipOperatorInterface.cpp +++ b/src/eve-server/ship/ShipOperatorInterface.cpp @@ -116,6 +116,21 @@ CharacterRef ShipOperatorInterface::GetChar() const return ret; } +DestinyManager * ShipOperatorInterface::GetDestiny() +{ + if( m_pClient != NULL ) + return m_pClient->Destiny(); +// else if( m_pNPC != NULL ) +// return m_pNPC->Destiny(); + + sLog.Error( "ShipOperatorInterface::GetDestiny()", "ERROR: All Operator types should be accounted for" ); + assert(false); + + // Hack to get rid of warning, code execution should never reach this point + DestinyManager * ret = NULL; + return ret; +} + uint32 ShipOperatorInterface::GetLocationID() const { if( m_pClient != NULL )