diff --git a/src/action.cpp b/src/action.cpp index 0c3097a895d..1319a1906d6 100644 --- a/src/action.cpp +++ b/src/action.cpp @@ -227,7 +227,7 @@ static bool actionInsideMinRange(DROID *psDroid, BASE_OBJECT *psObj, WEAPON_STAT if (!psStats) { - psStats = getWeaponStats(psDroid, 0); + psStats = psDroid->getWeaponStats(0); } /* if I am a multi-turret droid */ @@ -605,7 +605,7 @@ static bool actionRemoveDroidsFromBuildPos(unsigned player, Vector2i pos, uint16 { Vector2i dest = world_coord(b.map + Vector2i(x, y)) + Vector2i(TILE_UNITS, TILE_UNITS) / 2; unsigned dist = iHypot(droid->pos.xy() - dest); - if (dist < bestDist && !fpathBlockingTile(map_coord(dest.x), map_coord(dest.y), getPropulsionStats(droid)->propulsionType)) + if (dist < bestDist && !fpathBlockingTile(map_coord(dest.x), map_coord(dest.y), droid->getPropulsionStats()->propulsionType)) { bestDest = dest; bestDist = dist; @@ -634,7 +634,7 @@ void actionSanity(DROID *psDroid) // clear the target if it has died for (int i = 0; i < MAX_WEAPONS; i++) { - bDirect = proj_Direct(getWeaponStats(psDroid, i)); + bDirect = proj_Direct(psDroid->getWeaponStats(i)); if (psDroid->psActionTarget[i] && (avoidOverkill ? aiObjectIsProbablyDoomed(psDroid->psActionTarget[i], bDirect) : psDroid->psActionTarget[i]->died)) { syncDebugObject(psDroid->psActionTarget[i], '-'); @@ -681,7 +681,7 @@ void actionUpdateDroid(DROID *psDroid) CHECK_DROID(psDroid); - PROPULSION_STATS *psPropStats = getPropulsionStats(psDroid); + PROPULSION_STATS *psPropStats = psDroid->getPropulsionStats(); ASSERT_OR_RETURN(, psPropStats != nullptr, "Invalid propulsion stats pointer"); bool secHoldActive = secondaryGetState(psDroid, DSO_HALTTYPE) == DSS_HALT_HOLD; @@ -738,7 +738,7 @@ void actionUpdateDroid(DROID *psDroid) { BASE_OBJECT *psTemp = nullptr; - WEAPON_STATS *const psWeapStats = getWeaponStats(psDroid, i); + WEAPON_STATS *const psWeapStats = psDroid->getWeaponStats(i); if (psDroid->asWeaps[i].nStat > 0 && psWeapStats->rotate && IS_TIME_TO_CHECK_FOR_NEW_TARGET(psDroid) @@ -838,7 +838,7 @@ void actionUpdateDroid(DROID *psDroid) BASE_OBJECT *psTemp = nullptr; //I moved psWeapStats flag update there - WEAPON_STATS *const psWeapStats = getWeaponStats(psDroid, i); + WEAPON_STATS *const psWeapStats = psDroid->getWeaponStats(i); if (!psDroid->isVtol() && psDroid->asWeaps[i].nStat > 0 && psWeapStats->rotate @@ -876,7 +876,7 @@ void actionUpdateDroid(DROID *psDroid) bHasTarget = false; for (unsigned i = 0; i < psDroid->numWeaps; ++i) { - bDirect = proj_Direct(getWeaponStats(psDroid, i)); + bDirect = proj_Direct(psDroid->getWeaponStats(i)); blockingWall = nullptr; // Does this weapon have a target? if (psDroid->psActionTarget[i] != nullptr) @@ -1071,7 +1071,7 @@ void actionUpdateDroid(DROID *psDroid) && actionVisibleTarget(psDroid, psActionTarget, i) && actionInRange(psDroid, psActionTarget, i)) { - WEAPON_STATS *const psWeapStats = getWeaponStats(psDroid, i); + WEAPON_STATS *const psWeapStats = psDroid->getWeaponStats(i); WEAPON_EFFECT weapEffect = psWeapStats->weaponEffect; blockingWall = visGetBlockingWall(psDroid, psActionTarget); @@ -1226,7 +1226,7 @@ void actionUpdateDroid(DROID *psDroid) && validTarget(psDroid, psDroid->psActionTarget[0], i)) { //I moved psWeapStats flag update there - psWeapStats = getWeaponStats(psDroid, i); + psWeapStats = psDroid->getWeaponStats(i); if (actionVisibleTarget(psDroid, psDroid->psActionTarget[0], i)) { if (actionInRange(psDroid, psDroid->psActionTarget[0], i)) @@ -1325,7 +1325,7 @@ void actionUpdateDroid(DROID *psDroid) && actionVisibleTarget(psDroid, psDroid->psActionTarget[0], i)) { bool chaseBloke = false; - WEAPON_STATS *const psWeapStats = getWeaponStats(psDroid, i); + WEAPON_STATS *const psWeapStats = psDroid->getWeaponStats(i); const bool actionIsInRange = actionInRange(psDroid, psDroid->psActionTarget[0], i); if (psWeapStats->rotate) { @@ -1403,7 +1403,7 @@ void actionUpdateDroid(DROID *psDroid) /* Stopped moving but haven't reached the target - possibly move again */ //'hack' to make the droid to check the primary turrent instead of all - WEAPON_STATS *const psWeapStats = getWeaponStats(psDroid, 0); + WEAPON_STATS *const psWeapStats = psDroid->getWeaponStats(0); if (order->type == DORDER_ATTACKTARGET && secHoldActive) { @@ -1969,7 +1969,7 @@ void actionUpdateDroid(DROID *psDroid) { Vector2i diff = (psDroid->pos - order->psObj->pos).xy(); //Consider .shortRange here - int rangeSq = getWeaponStats(psDroid, 0)->upgrade[psDroid->player].maxRange / 2; // move close to sensor + int rangeSq = psDroid->getWeaponStats(0)->upgrade[psDroid->player].maxRange / 2; // move close to sensor rangeSq = rangeSq * rangeSq; if (dot(diff, diff) < rangeSq) { @@ -2063,7 +2063,7 @@ void actionUpdateDroid(DROID *psDroid) { BASE_OBJECT *psTemp = nullptr; - WEAPON_STATS *const psWeapStats = getWeaponStats(psDroid, i); + WEAPON_STATS *const psWeapStats = psDroid->getWeaponStats(i); if (psDroid->asWeaps[i].nStat > 0 && psWeapStats->rotate && secondaryGetState(psDroid, DSO_ATTACK_LEVEL) == DSS_ALEV_ALWAYS && IS_TIME_TO_CHECK_FOR_NEW_TARGET(psDroid) @@ -2231,7 +2231,7 @@ static void actionDroidBase(DROID *psDroid, DROID_ACTION_DATA *psAction) { ASSERT_OR_RETURN(, psAction->psObj == nullptr || !psAction->psObj->died, "Droid dead"); - WEAPON_STATS *psWeapStats = getWeaponStats(psDroid, 0); + WEAPON_STATS *psWeapStats = psDroid->getWeaponStats(0); Vector2i pos(0, 0); CHECK_DROID(psDroid); diff --git a/src/ai.cpp b/src/ai.cpp index 9e1a775de0e..745ed3d1a07 100644 --- a/src/ai.cpp +++ b/src/ai.cpp @@ -94,7 +94,7 @@ static int aiDroidRange(DROID *psDroid, int weapon_slot) } else { - WEAPON_STATS *psWStats = getWeaponStats(psDroid, weapon_slot); + WEAPON_STATS *psWStats = psDroid->getWeaponStats(weapon_slot); longRange = proj_GetLongRange(*psWStats, psDroid->player); } @@ -110,7 +110,7 @@ static bool aiStructHasRange(STRUCTURE *psStruct, BASE_OBJECT *psTarget, int wea return false; } - WEAPON_STATS *psWStats = &asWeaponStats[psStruct->asWeaps[weapon_slot].nStat]; + WEAPON_STATS *psWStats = psStruct->getWeaponStats(weapon_slot); int longRange = proj_GetLongRange(*psWStats, psStruct->player); return objPosDiffSq(psStruct, psTarget) < longRange * longRange && lineOfFire(psStruct, psTarget, weapon_slot, true); @@ -197,7 +197,7 @@ static BASE_OBJECT *aiSearchSensorTargets(BASE_OBJECT *psObj, int weapon_slot, W { continue; } - const auto sensorType = getSensorStats(psDroid)->type; + const auto sensorType = psDroid->getSensorStats()->type; // Artillery should not fire at objects observed by VTOL CB/Strike sensors. if (sensorType == VTOL_CB_SENSOR || sensorType == VTOL_INTERCEPT_SENSOR || @@ -293,7 +293,7 @@ static SDWORD targetAttackWeight(BASE_OBJECT *psTarget, BASE_OBJECT *psAttacker, { psAttackerDroid = (DROID *)psAttacker; - attackerWeapon = getWeaponStats(psAttackerDroid, weapon_slot); + attackerWeapon = psAttackerDroid->getWeaponStats(weapon_slot); //check if this droid is assigned to a commander bCmdAttached = hasCommander(psAttackerDroid); @@ -335,7 +335,7 @@ static SDWORD targetAttackWeight(BASE_OBJECT *psTarget, BASE_OBJECT *psAttacker, } else if (psAttacker->type == OBJ_STRUCTURE) { - attackerWeapon = (WEAPON_STATS *)(&asWeaponStats[((STRUCTURE *)psAttacker)->asWeaps[weapon_slot].nStat]); + attackerWeapon = ((STRUCTURE*)psAttacker)->getWeaponStats(weapon_slot); } else /* feature */ { @@ -420,8 +420,8 @@ static SDWORD targetAttackWeight(BASE_OBJECT *psTarget, BASE_OBJECT *psAttacker, } /* Now calculate the overall weight */ - attackWeight = asWeaponModifier[weaponEffect][getPropulsionStats(targetDroid)->propulsionType] // Our weapon's effect against target - + asWeaponModifierBody[weaponEffect][getBodyStats(targetDroid)->size] + attackWeight = asWeaponModifier[weaponEffect][targetDroid->getPropulsionStats()->propulsionType] // Our weapon's effect against target + + asWeaponModifierBody[weaponEffect][targetDroid->getBodyStats()->size] + WEIGHT_DIST_TILE_DROID * objSensorRange(psAttacker) / TILE_UNITS - WEIGHT_DIST_TILE_DROID * dist / TILE_UNITS // farther droids are less attractive + WEIGHT_HEALTH_DROID * damageRatio / 100 // we prefer damaged droids @@ -583,7 +583,7 @@ int aiBestNearestTarget(DROID *psDroid, BASE_OBJECT **ppsObj, int weapon_slot, i ++numDroidNearestTargetChecksThisFrame; // Check if we have a CB target to begin with - WEAPON_STATS* psWStats = getWeaponStats(psDroid, weapon_slot); + WEAPON_STATS* psWStats = psDroid->getWeaponStats(weapon_slot); if (!proj_Direct(psWStats)) { bestTarget = aiSearchSensorTargets((BASE_OBJECT *)psDroid, weapon_slot, psWStats, &tmpOrigin); @@ -887,7 +887,7 @@ bool aiChooseTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget, int weapon_slot ASSERT_OR_RETURN(false, psObj->asWeaps[weapon_slot].nStat > 0, "Invalid weapon turret"); - WEAPON_STATS *psWStats = &asWeaponStats[psObj->asWeaps[weapon_slot].nStat]; + WEAPON_STATS *psWStats = ((const STRUCTURE*)psObj)->getWeaponStats(weapon_slot); int longRange = proj_GetLongRange(*psWStats, psObj->player); // see if there is a target from the command droids @@ -1267,7 +1267,7 @@ bool validTarget(BASE_OBJECT const *psObject, BASE_OBJECT const *psTarget, int w switch (psTarget->type) { case OBJ_DROID: - if (asPropulsionTypes[getPropulsionStats((const DROID*)psTarget)->propulsionType].travel == AIR) + if (asPropulsionTypes[((const DROID*)psTarget)->getPropulsionStats()->propulsionType].travel == AIR) { if (((const DROID *)psTarget)->sMove.Status != MOVEINACTIVE) { @@ -1302,7 +1302,7 @@ bool validTarget(BASE_OBJECT const *psObject, BASE_OBJECT const *psTarget, int w // Can't attack without a weapon if (((const DROID *)psObject)->numWeaps != 0 && ((const DROID *)psObject)->asWeaps[weapon_slot].nStat != 0) { - surfaceToAir = getWeaponStats((const DROID*)psObject, weapon_slot)->surfaceToAir; + surfaceToAir = ((const DROID*)psObject)->getWeaponStats(weapon_slot)->surfaceToAir; if (((surfaceToAir & SHOOT_IN_AIR) && bTargetInAir) || ((surfaceToAir & SHOOT_ON_GROUND) && !bTargetInAir)) { return true; @@ -1317,7 +1317,7 @@ bool validTarget(BASE_OBJECT const *psObject, BASE_OBJECT const *psTarget, int w // Can't attack without a weapon if (((const STRUCTURE *)psObject)->numWeaps != 0 && ((const STRUCTURE *)psObject)->asWeaps[weapon_slot].nStat != 0) { - surfaceToAir = asWeaponStats[((const STRUCTURE *)psObject)->asWeaps[weapon_slot].nStat].surfaceToAir; + surfaceToAir = ((const STRUCTURE*)psObject)->getWeaponStats(weapon_slot)->surfaceToAir; } else { diff --git a/src/basedef.h b/src/basedef.h index 3b68e477dbd..8abca0384d0 100644 --- a/src/basedef.h +++ b/src/basedef.h @@ -84,11 +84,15 @@ enum OBJECT_FLAG OBJECT_FLAG_COUNT }; +struct WEAPON_STATS; + struct BASE_OBJECT : public SIMPLE_OBJECT { BASE_OBJECT(OBJECT_TYPE type, uint32_t id, unsigned player); ~BASE_OBJECT(); + WEAPON_STATS* getWeaponStats(int weaponSlot) const; + SCREEN_DISP_DATA sDisplay; ///< screen coordinate details UBYTE group = 0; ///< Which group selection is the droid currently in? UBYTE selected; ///< Whether the object is selected (might want this elsewhere) diff --git a/src/baseobject.cpp b/src/baseobject.cpp index 89c5ef1b120..bd400b2e184 100644 --- a/src/baseobject.cpp +++ b/src/baseobject.cpp @@ -117,6 +117,12 @@ BASE_OBJECT::~BASE_OBJECT() visRemoveVisibility(this); } + +WEAPON_STATS* BASE_OBJECT::getWeaponStats(int weaponSlot) const +{ + return &asWeaponStats[asWeaps[weaponSlot].nStat]; +} + // Query visibility for display purposes (i.e. for `selectedPlayer`) // *DO NOT USE TO QUERY VISIBILITY FOR CALCULATIONS INVOLVING GAME / SIMULATION STATE* UBYTE BASE_OBJECT::visibleForLocalDisplay() const diff --git a/src/bucket3d.cpp b/src/bucket3d.cpp index 571dc9aa425..d437c83fd15 100644 --- a/src/bucket3d.cpp +++ b/src/bucket3d.cpp @@ -197,7 +197,7 @@ static SDWORD bucketCalculateZ(RENDER_TYPE objectType, void *pObject, const glm: position.z = -(psSimpObj->pos.y); position.y = psSimpObj->pos.z; - psBStats = getBodyStats(psDroid); + psBStats = psDroid->getBodyStats(); droidSize = psBStats->pIMD->radius; z = pie_RotateProjectWithPerspective(&position, perspectiveViewMatrix, &pixel) - (droidSize * 2); diff --git a/src/cmddroid.cpp b/src/cmddroid.cpp index 102b2a753f6..66a7c748d63 100644 --- a/src/cmddroid.cpp +++ b/src/cmddroid.cpp @@ -180,7 +180,7 @@ SDWORD cmdDroidGetIndex(const DROID *psCommander) /** This function returns the maximum group size of the command droid.*/ unsigned int cmdDroidMaxGroup(const DROID *psCommander) { - const BRAIN_STATS *psStats = getBrainStats(psCommander); + const BRAIN_STATS *psStats = psCommander->getBrainStats(); return getDroidLevel(psCommander) * psStats->upgrade[psCommander->player].maxDroidsMult + psStats->upgrade[psCommander->player].maxDroids; } diff --git a/src/combat.cpp b/src/combat.cpp index 829b95d697c..fe329f678f3 100644 --- a/src/combat.cpp +++ b/src/combat.cpp @@ -376,7 +376,7 @@ int objArmour(const BASE_OBJECT *psObj, WEAPON_CLASS weaponClass) int armour = 0; if (psObj->type == OBJ_DROID) { - armour = bodyArmour(*getBodyStats((const DROID*)psObj), psObj->player, weaponClass); + armour = bodyArmour(*((const DROID*)psObj)->getBodyStats(), psObj->player, weaponClass); } else if (psObj->type == OBJ_STRUCTURE && weaponClass == WC_KINETIC && ((const STRUCTURE *)psObj)->status != SS_BEING_BUILT) { diff --git a/src/component.cpp b/src/component.cpp index 50fa8af32e3..1cd1ae553d2 100644 --- a/src/component.cpp +++ b/src/component.cpp @@ -444,7 +444,7 @@ static bool displayCompObj(DROID *psDroid, bool bButton, const glm::mat4& modelM } /* get propulsion stats */ - psPropStats = getPropulsionStats(psDroid); + psPropStats = psDroid->getPropulsionStats(); ASSERT_OR_RETURN(didDrawSomething, psPropStats != nullptr, "invalid propulsion stats pointer"); //set pieflag for button object or ingame object @@ -531,7 +531,7 @@ static bool displayCompObj(DROID *psDroid, bool bButton, const glm::mat4& modelM } /* Render animation effects based on movement or lack thereof, if any */ - const auto* bodyStats = getBodyStats(psDroid); + const auto* bodyStats = psDroid->getBodyStats(); psMoveAnim = bodyStats->ppMoveIMDList[psDroid->asBits[COMP_PROPULSION]]; psStillAnim = bodyStats->ppStillIMDList[psDroid->asBits[COMP_PROPULSION]]; if (!bButton && psMoveAnim && psDroid->sMove.Status != MOVEINACTIVE) diff --git a/src/component.h b/src/component.h index fee30e9376b..6280187759b 100644 --- a/src/component.h +++ b/src/component.h @@ -83,32 +83,32 @@ void drawMuzzleFlash(WEAPON sWeap, iIMDShape *weaponImd, iIMDShape *flashImd, PI #define PART_IMD(STATS,DROID,COMPONENT,PLAYER) (STATS[DROID->asBits[COMPONENT]].pIMD) /* Get the chassis imd */ -#define BODY_IMD(DROID,PLAYER) (getBodyStats(DROID)->pIMD) +#define BODY_IMD(DROID,PLAYER) (DROID->getBodyStats()->pIMD) /* Get the brain imd - NOTE: Unused!*/ -#define BRAIN_IMD(DROID,PLAYER) (getBrainStats(DROID)->pIMD) +#define BRAIN_IMD(DROID,PLAYER) (DROID->getBrainStats()->pIMD) /* Get the weapon imd */ -#define WEAPON_IMD(DROID,WEAPON_NUM) (getWeaponStats(DROID, WEAPON_NUM)->pIMD) +#define WEAPON_IMD(DROID,WEAPON_NUM) (DROID->getWeaponStats(WEAPON_NUM)->pIMD) /* Get the propulsion imd THIS IS A LITTLE MORE COMPLICATED NOW!*/ //#define PROPULSION_IMD(DROID,PLAYER) (asPropulsionStats[DROID->asBits[COMP_PROPULSION]].pIMD[PLAYER]) /* Get the sensor imd */ -#define SENSOR_IMD(DROID,PLAYER) (getSensorStats(DROID)->pIMD) +#define SENSOR_IMD(DROID,PLAYER) (DROID->getSensorStats()->pIMD) /* Get an ECM imd!?! */ -#define ECM_IMD(DROID,PLAYER) (getECMStats(DROID)->pIMD) +#define ECM_IMD(DROID,PLAYER) (DROID->getECMStats()->pIMD) /* Get an Repair imd!?! */ -#define REPAIR_IMD(DROID,PLAYER) (getRepairStats(DROID)->pIMD) +#define REPAIR_IMD(DROID,PLAYER) (DROID->getRepairStats()->pIMD) /* Get a construct imd */ -#define CONSTRUCT_IMD(DROID,PLAYER) (getConstructStats(DROID)->pIMD) +#define CONSTRUCT_IMD(DROID,PLAYER) (DROID->getConstructStats()->pIMD) /* Get a weapon mount imd*/ -#define WEAPON_MOUNT_IMD(DROID,WEAPON_NUM) (getWeaponStats(DROID, WEAPON_NUM)->pMountGraphic) +#define WEAPON_MOUNT_IMD(DROID,WEAPON_NUM) (DROID->getWeaponStats(WEAPON_NUM)->pMountGraphic) /* Get a sensor mount imd*/ -#define SENSOR_MOUNT_IMD(DROID,PLAYER) (getSensorStats(DROID)->pMountGraphic) +#define SENSOR_MOUNT_IMD(DROID,PLAYER) (DROID->getSensorStats()->pMountGraphic) /* Get a construct mount imd*/ -#define CONSTRUCT_MOUNT_IMD(DROID,PLAYER) (getConstructStats(DROID)->pMountGraphic) +#define CONSTRUCT_MOUNT_IMD(DROID,PLAYER) (DROID->getConstructStats()->pMountGraphic) /* Get a ecm mount imd*/ -#define ECM_MOUNT_IMD(DROID,PLAYER) (getECMStats(DROID)->pMountGraphic) +#define ECM_MOUNT_IMD(DROID,PLAYER) (DROID->getECMStats()->pMountGraphic) /* Get a repair mount imd*/ -#define REPAIR_MOUNT_IMD(DROID,PLAYER) (getRepairStats(DROID)->pMountGraphic) +#define REPAIR_MOUNT_IMD(DROID,PLAYER) (DROID->getRepairStats()->pMountGraphic) /* Get a muzzle flash pie*/ -#define MUZZLE_FLASH_PIE(DROID,WEAPON_NUM) (getWeaponStats(DROID, WEAPON_NUM)->pMuzzleGraphic) +#define MUZZLE_FLASH_PIE(DROID,WEAPON_NUM) (DROID->getWeaponStats(WEAPON_NUM)->pMuzzleGraphic) #endif // __INCLUDED_SRC_COMPONENT_H__ diff --git a/src/design.cpp b/src/design.cpp index eb117b3b741..be86018b987 100644 --- a/src/design.cpp +++ b/src/design.cpp @@ -1202,7 +1202,7 @@ static void intSetDesignMode(DES_COMPMODE newCompMode, bool forceRefresh) widgSetButtonState(psWScreen, IDDES_SYSTEMFORM, WBUT_LOCK); widgSetButtonState(psWScreen, IDDES_SYSTEMBUTTON, WBUT_CLICKLOCK); widgReveal(psWScreen, IDDES_SYSTEMFORM); - intSetSystemForm((COMPONENT_STATS *)(&asWeaponStats[sCurrDesign.asWeaps[0]])); // in case previous was a different slot + intSetSystemForm(sCurrDesign.getWeaponStats(0)); // in case previous was a different slot break; case IDES_BODY: compList = intAddComponentForm(); @@ -1217,7 +1217,7 @@ static void intSetDesignMode(DES_COMPMODE newCompMode, bool forceRefresh) widgSetButtonState(psWScreen, IDDES_PROPFORM, WBUT_LOCK); widgSetButtonState(psWScreen, IDDES_PROPBUTTON, WBUT_CLICKLOCK); widgReveal(psWScreen, IDDES_PROPFORM); - intSetPropulsionForm(&asPropulsionStats[sCurrDesign.asParts[COMP_PROPULSION]]); + intSetPropulsionForm(sCurrDesign.getPropulsionStats()); break; case IDES_TURRET_A: compList = intAddComponentForm(); @@ -1227,7 +1227,7 @@ static void intSetDesignMode(DES_COMPMODE newCompMode, bool forceRefresh) widgSetButtonState(psWScreen, IDDES_SYSTEMFORM, WBUT_LOCK); widgSetButtonState(psWScreen, IDDES_WPABUTTON, WBUT_CLICKLOCK); widgReveal(psWScreen, IDDES_SYSTEMFORM); - intSetSystemForm((COMPONENT_STATS *)(&asWeaponStats[sCurrDesign.asWeaps[1]])); // in case previous was a different slot + intSetSystemForm(sCurrDesign.getWeaponStats(1)); // in case previous was a different slot // Stop the button flashing intSetButtonFlash(IDDES_WPABUTTON, false); break; @@ -1239,7 +1239,7 @@ static void intSetDesignMode(DES_COMPMODE newCompMode, bool forceRefresh) widgSetButtonState(psWScreen, IDDES_SYSTEMFORM, WBUT_LOCK); widgSetButtonState(psWScreen, IDDES_WPBBUTTON, WBUT_CLICKLOCK); widgReveal(psWScreen, IDDES_SYSTEMFORM); - intSetSystemForm((COMPONENT_STATS *)(&asWeaponStats[sCurrDesign.asWeaps[2]])); // in case previous was a different slot + intSetSystemForm(sCurrDesign.getWeaponStats(2)); // in case previous was a different slot // Stop the button flashing intSetButtonFlash(IDDES_WPBBUTTON, false); break; @@ -1413,10 +1413,10 @@ static void intSetDesignStats(DROID_TEMPLATE *psTemplate) intSetSystemForm(psStats); /* Set the body stats */ - intSetBodyStats(&asBodyStats[psTemplate->asParts[COMP_BODY]]); + intSetBodyStats(psTemplate->getBodyStats()); /* Set the propulsion stats */ - intSetPropulsionForm(&asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]]); + intSetPropulsionForm(psTemplate->getPropulsionStats()); /* Set the name in the edit box */ intSetEditBoxTextFromTemplate(psTemplate); @@ -2030,14 +2030,14 @@ static bool intAddComponentButtons(ListTabWidget *compList, ComponentIterator co //check if the current Template propulsion has been set if (sCurrDesign.asParts[COMP_PROPULSION]) { - PROPULSION_STATS *psPropStats = &asPropulsionStats[sCurrDesign.asParts[COMP_PROPULSION]]; + PROPULSION_STATS *psPropStats = sCurrDesign.getPropulsionStats(); ASSERT_OR_RETURN(false, psPropStats != nullptr, "invalid propulsion stats pointer"); bVTOL |= asPropulsionTypes[psPropStats->propulsionType].travel == AIR; } if (sCurrDesign.asParts[COMP_BODY]) { - bodysize = asBodyStats[sCurrDesign.asParts[COMP_BODY]].size; + bodysize = sCurrDesign.getBodyStats()->size; } } @@ -2552,7 +2552,7 @@ static void setTemplateStat(DROID_TEMPLATE *psTemplate, COMPONENT_STATS *psStats } case COMP_PROPULSION: { auto stats = (PROPULSION_STATS *)psStats; - auto oldStats = &asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]]; + auto oldStats = psTemplate->getPropulsionStats(); if ((stats->propulsionType == PROPULSION_TYPE_LIFT) != (oldStats->propulsionType == PROPULSION_TYPE_LIFT)) { clearTurret(); @@ -2701,7 +2701,7 @@ static uint32_t calculatePropulsionWeight(COMPONENT_STATS &propulsionStats) return 0; } - return propulsionStats.weight *asBodyStats[sCurrDesign.asParts[COMP_BODY]].weight / 100; + return propulsionStats.weight * sCurrDesign.getBodyStats()->weight / 100; } /* Set the shadow bar graphs for the Propulsion stats */ @@ -2805,13 +2805,13 @@ bool intValidTemplate(DROID_TEMPLATE *psTempl, const char *newName, bool complai ASSERT_OR_RETURN(false, psTempl->asParts[COMP_CONSTRUCT] < asConstructStats.size(), "Invalid range referenced for numConstructStats, %d > %zu", psTempl->asParts[COMP_CONSTRUCT], asConstructStats.size()); code_part level = complain ? LOG_ERROR : LOG_NEVER; - int bodysize = asBodyStats[psTempl->asParts[COMP_BODY]].size; + int bodysize = psTempl->getBodyStats()->size; // set the weapon for a command droid if (psTempl->asParts[COMP_BRAIN] != 0) { psTempl->numWeaps = 1; - psTempl->asWeaps[0] = asBrainStats[psTempl->asParts[COMP_BRAIN]].psWeaponStat - asWeaponStats.data(); + psTempl->asWeaps[0] = psTempl->getBrainStats()->psWeaponStat - asWeaponStats.data(); } /* Check all the components have been set */ @@ -2844,7 +2844,7 @@ bool intValidTemplate(DROID_TEMPLATE *psTempl, const char *newName, bool complai { ASSERT_OR_RETURN(false, psTempl->asWeaps[i] < asWeaponStats.size(), "Invalid range referenced for numWeaponStats, %d > %zu", psTempl->asWeaps[i], asWeaponStats.size()); - int weaponSize = asWeaponStats[psTempl->asWeaps[i]].weaponSize; + int weaponSize = psTempl->getWeaponStats(i)->weaponSize; if ((weaponSize == WEAPON_SIZE_LIGHT && bodysize != SIZE_LIGHT) || (weaponSize == WEAPON_SIZE_HEAVY && bodysize == SIZE_LIGHT) @@ -2854,7 +2854,7 @@ bool intValidTemplate(DROID_TEMPLATE *psTempl, const char *newName, bool complai return false; } if (checkTemplateIsVtol(psTempl) - && asWeaponStats[psTempl->asWeaps[i]].vtolAttackRuns <= 0) + && psTempl->getWeaponStats(i)->vtolAttackRuns <= 0) { debug(level, "VTOL with non-VTOL turret, not possible"); return false; @@ -2862,7 +2862,7 @@ bool intValidTemplate(DROID_TEMPLATE *psTempl, const char *newName, bool complai } // Check number of weapon slots - if ((unsigned)psTempl->numWeaps > asBodyStats[psTempl->asParts[COMP_BODY]].weaponSlots) + if ((unsigned)psTempl->numWeaps > psTempl->getBodyStats()->weaponSlots) { debug(level, "Too many weapon turrets"); return false; @@ -3140,7 +3140,7 @@ void intProcessDesign(UDWORD id) case IDES_TURRET: setTemplateStat(&sCurrDesign, apsComponentList[id - IDDES_COMPSTART]); //Watermelon:weaponslots >= 2 - if (asBodyStats[sCurrDesign.asParts[COMP_BODY]].weaponSlots >= 2) + if (sCurrDesign.getBodyStats()->weaponSlots >= 2) { /* reveal turret_a button if hidden */ widgReveal(psWScreen, IDDES_WPABUTTON); @@ -3156,7 +3156,7 @@ void intProcessDesign(UDWORD id) case IDES_TURRET_A: setTemplateStat(&sCurrDesign, apsComponentList[id - IDDES_COMPSTART]); //Watermelon:weaponSlots > 2 - if (asBodyStats[sCurrDesign.asParts[COMP_BODY]].weaponSlots > 2) + if (sCurrDesign.getBodyStats()->weaponSlots > 2) { /* reveal turret_b button if hidden */ widgReveal(psWScreen, IDDES_WPBBUTTON); @@ -3186,7 +3186,7 @@ void intProcessDesign(UDWORD id) intSetBodyStats((BODY_STATS *)apsComponentList[id - IDDES_COMPSTART]); int numWeaps = sCurrDesign.asParts[COMP_BRAIN] != 0? 0 : sCurrDesign.numWeaps; - int maxWeaps = asBodyStats[sCurrDesign.asParts[COMP_BODY]].weaponSlots; + int maxWeaps = sCurrDesign.getBodyStats()->weaponSlots; widgGetFromID(psWScreen, IDDES_WPABUTTON)->show(maxWeaps > 1 && numWeaps >= 1); widgGetFromID(psWScreen, IDDES_WPBBUTTON)->show(maxWeaps > 2 && numWeaps >= 2); widgSetButtonState(psWScreen, IDDES_WPABUTTON, maxWeaps > 1 && numWeaps == 1? WBUT_FLASH : 0); @@ -3230,7 +3230,7 @@ void intProcessDesign(UDWORD id) desCompID = id; /* Update the propulsion stats as the droid weight will have changed */ - intSetPropulsionStats(&asPropulsionStats[sCurrDesign.asParts[COMP_PROPULSION]]); + intSetPropulsionStats(sCurrDesign.getPropulsionStats()); /*Update the Power bar stats as the power to build will have changed */ intSetDesignPower(&sCurrDesign); @@ -3270,7 +3270,7 @@ void intProcessDesign(UDWORD id) desCompID = id; // Update the propulsion stats as the droid weight will have changed - intSetPropulsionStats(&asPropulsionStats[sCurrDesign.asParts[COMP_PROPULSION]]); + intSetPropulsionStats(sCurrDesign.getPropulsionStats()); // Update the Power bar stats as the power to build will have changed intSetDesignPower(&sCurrDesign); @@ -3569,7 +3569,7 @@ void intProcessDesign(UDWORD id) case IDES_SYSTEM: case IDES_TURRET: - if (asBodyStats[sCurrDesign.asParts[COMP_BODY]].weaponSlots > 1 && + if (sCurrDesign.getBodyStats()->weaponSlots > 1 && sCurrDesign.numWeaps == 1 && sCurrDesign.asParts[COMP_BRAIN] == 0) { debug(LOG_GUI, "intProcessDesign: First weapon selected, doing next."); @@ -3582,7 +3582,7 @@ void intProcessDesign(UDWORD id) } break; case IDES_TURRET_A: - if (asBodyStats[sCurrDesign.asParts[COMP_BODY]].weaponSlots > 2) + if (sCurrDesign.getBodyStats()->weaponSlots > 2) { debug(LOG_GUI, "intProcessDesign: Second weapon selected, doing next."); intSetDesignMode(IDES_TURRET_B); @@ -3847,8 +3847,8 @@ void runTemplateShadowStats(UDWORD id) if (psTempl && psTempl != &sCurrDesign) { /* Now set the bar graphs for the stats */ - intSetBodyShadowStats(&asBodyStats[psTempl->asParts[COMP_BODY]]); - intSetPropulsionShadowStats(&asPropulsionStats[psTempl->asParts[COMP_PROPULSION]]); + intSetBodyShadowStats(psTempl->getBodyStats()); + intSetPropulsionShadowStats(psTempl->getPropulsionStats()); //only set the system shadow bar if the same type of droid COMPONENT_STATS *psStats = nullptr; DROID_TYPE templType = droidTemplateType(psTempl); @@ -3932,7 +3932,7 @@ to check the weapon is 'allowed'. Check if VTOL, the weapon is direct fire. Also check numVTOLattackRuns for the weapon is not zero - return true if valid weapon*/ static bool intCheckValidWeaponForProp(DROID_TEMPLATE *psTemplate) { - if (asPropulsionTypes[asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]].propulsionType].travel != AIR) + if (asPropulsionTypes[psTemplate->getPropulsionStats()->propulsionType].travel != AIR) { if (psTemplate->numWeaps == 0 && (psTemplate->asParts[COMP_SENSOR] || @@ -3950,7 +3950,7 @@ static bool intCheckValidWeaponForProp(DROID_TEMPLATE *psTemplate) //checks if the template has PROPULSION_TYPE_LIFT propulsion attached - returns true if it does bool checkTemplateIsVtol(const DROID_TEMPLATE *psTemplate) { - return asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]].propulsionType == PROPULSION_TYPE_LIFT; + return psTemplate->getPropulsionStats()->propulsionType == PROPULSION_TYPE_LIFT; } void updateStoreButton(bool isStored) diff --git a/src/display.cpp b/src/display.cpp index 5ea1f21b57d..94392b09f20 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -944,7 +944,7 @@ void processMouseClickInput() else if (arnMPointers[item][selection] == CURSOR_NOTPOSSIBLE && ObjUnderMouse && (ObjUnderMouse->player == selectedPlayer) && ObjUnderMouse->type == OBJ_STRUCTURE && ((STRUCTURE *)ObjUnderMouse)->asWeaps[0].nStat && - (asWeaponStats[((STRUCTURE *)ObjUnderMouse)->asWeaps[0].nStat].weaponSubClass == WSC_LAS_SAT)) + (((STRUCTURE*)ObjUnderMouse)->getWeaponStats(0)->weaponSubClass == WSC_LAS_SAT)) { wzSetCursor(CURSOR_SELECT); // Special casing for LasSat } @@ -990,7 +990,7 @@ void processMouseClickInput() } else if (ObjUnderMouse && (ObjUnderMouse->player == selectedPlayer) && ((ObjUnderMouse->type == OBJ_STRUCTURE && ((STRUCTURE *)ObjUnderMouse)->asWeaps[0].nStat - && (asWeaponStats[((STRUCTURE *)ObjUnderMouse)->asWeaps[0].nStat].weaponSubClass == WSC_LAS_SAT)) + && (((STRUCTURE*)ObjUnderMouse)->getWeaponStats(0)->weaponSubClass == WSC_LAS_SAT)) || ObjUnderMouse->type == OBJ_DROID)) { wzSetCursor(CURSOR_SELECT); // Special casing for LasSat or own unit @@ -1722,7 +1722,7 @@ static void dealWithLMBDroid(DROID *psDroid, SELECTION_TYPE selection) if ((psCurr->droidType == DROID_WEAPON) && (psCurr->selected) && (psCurr->asWeaps[0].nStat > 0) && - ((!proj_Direct(getWeaponStats(psCurr, 0))) || + ((!proj_Direct(psCurr->getWeaponStats(0))) || psCurr->isVtol()) && droidSensorDroidWeapon((BASE_OBJECT *)psDroid, psCurr)) { @@ -2608,7 +2608,7 @@ static SELECTION_TYPE establishSelection(UDWORD _selectedPlayer) switch (psDominant->droidType) { case DROID_WEAPON: - if (proj_Direct(getWeaponStats(psDominant, 0))) + if (proj_Direct(psDominant->getWeaponStats(0))) { selectionClass = SC_DROID_DIRECT; } diff --git a/src/display3d.cpp b/src/display3d.cpp index 4bfd4169149..e1e52ccad76 100644 --- a/src/display3d.cpp +++ b/src/display3d.cpp @@ -1771,7 +1771,7 @@ bool clipDroidOnScreen(DROID *psDroid, const glm::mat4 &perspectiveViewModelMatr { /* Get its absolute dimensions */ // NOTE: This only takes into account body, but is "good enough" - const BODY_STATS *psBStats = getBodyStats(psDroid); + const BODY_STATS *psBStats = psDroid->getBodyStats(); const iIMDShape * pIMD = (psBStats != nullptr) ? psBStats->pIMD->displayModel() : nullptr; return clipShapeOnScreen(pIMD, perspectiveViewModelMatrix, overdrawScreenPoints); @@ -3751,7 +3751,7 @@ static void drawDroidCmndNo(DROID *psDroid) void calcScreenCoords(DROID *psDroid, const glm::mat4 &perspectiveViewMatrix) { /* Get it's absolute dimensions */ - const BODY_STATS *psBStats = getBodyStats(psDroid); + const BODY_STATS *psBStats = psDroid->getBodyStats(); Vector3i origin; Vector2i center(0, 0); int wsRadius = 22; // World space radius, 22 = magic minimum @@ -4412,7 +4412,7 @@ static void addConstructionLine(DROID *psDroid, STRUCTURE *psStructure, const gl auto deltaPlayer = Vector3f(0,0,0); auto pt0 = Vector3f(psDroid->pos.x, psDroid->pos.z + 24, -psDroid->pos.y) + deltaPlayer; - int constructPoints = constructorPoints(*getConstructStats(psDroid), psDroid->player); + int constructPoints = constructorPoints(*psDroid->getConstructStats(), psDroid->player); int amount = 800 * constructPoints * (graphicsTime - psDroid->actionStarted) / GAME_TICKS_PER_SEC; Vector3i each; diff --git a/src/droid.cpp b/src/droid.cpp index 1b5e1d7c1f0..970cf33b9ce 100644 --- a/src/droid.cpp +++ b/src/droid.cpp @@ -247,7 +247,7 @@ void addDroidDeathAnimationEffect(DROID *psDroid) { iIMDShape *strImd = psShapeBody->objanimpie[ANIM_EVENT_DYING]->displayModel(); /* get propulsion stats */ - PROPULSION_STATS *psPropStats = getPropulsionStats(psDroid); + PROPULSION_STATS *psPropStats = psDroid->getPropulsionStats(); if (psPropStats && psPropStats->propulsionType == PROPULSION_TYPE_PROPELLOR) { // FIXME: change when adding submarines to the game @@ -1120,7 +1120,7 @@ bool droidUpdateBuild(DROID *psDroid) return false; } - unsigned constructPoints = constructorPoints(*getConstructStats(psDroid), psDroid->player); + unsigned constructPoints = constructorPoints(*psDroid->getConstructStats(), psDroid->player); unsigned pointsToAdd = constructPoints * (gameTime - psDroid->actionStarted) / GAME_TICKS_PER_SEC; @@ -1143,7 +1143,7 @@ bool droidUpdateDemolishing(DROID *psDroid) STRUCTURE *psStruct = (STRUCTURE *)psDroid->order.psObj; ASSERT_OR_RETURN(false, psStruct->type == OBJ_STRUCTURE, "target is not a structure"); - int constructRate = 5 * constructorPoints(*getConstructStats(psDroid), psDroid->player); + int constructRate = 5 * constructorPoints(*psDroid->getConstructStats(), psDroid->player); int pointsToAdd = gameTimeAdjustedAverage(constructRate); structureDemolish(psStruct, psDroid, pointsToAdd); @@ -1254,7 +1254,7 @@ bool droidUpdateRepair(DROID *psDroid) STRUCTURE *psStruct = (STRUCTURE *)psDroid->psActionTarget[0]; ASSERT_OR_RETURN(false, psStruct->type == OBJ_STRUCTURE, "target is not a structure"); - int iRepairRate = constructorPoints(*getConstructStats(psDroid), psDroid->player); + int iRepairRate = constructorPoints(*psDroid->getConstructStats(), psDroid->player); /* add points to structure */ structureRepair(psStruct, psDroid, iRepairRate); @@ -1276,7 +1276,7 @@ static bool droidUpdateDroidRepairBase(DROID *psRepairDroid, DROID *psDroidToRep { CHECK_DROID(psRepairDroid); - const auto* repairStats = getRepairStats(psRepairDroid); + const auto* repairStats = psRepairDroid->getRepairStats(); int iRepairRateNumerator = repairPoints(*repairStats, psRepairDroid->player); int iRepairRateDenominator = 1; @@ -1358,11 +1358,11 @@ DROID_TYPE droidTemplateType(const DROID_TEMPLATE *psTemplate) { type = DROID_COMMAND; } - else if (asSensorStats[psTemplate->asParts[COMP_SENSOR]].location == LOC_TURRET) + else if (psTemplate->getSensorStats()->location == LOC_TURRET) { type = DROID_SENSOR; } - else if (asECMStats[psTemplate->asParts[COMP_ECM]].location == LOC_TURRET) + else if (psTemplate->getECMStats()->location == LOC_TURRET) { type = DROID_ECM; } @@ -1370,7 +1370,7 @@ DROID_TYPE droidTemplateType(const DROID_TEMPLATE *psTemplate) { type = DROID_CONSTRUCT; } - else if (asRepairStats[psTemplate->asParts[COMP_REPAIRUNIT]].location == LOC_TURRET) + else if (psTemplate->getRepairStats()->location == LOC_TURRET) { type = DROID_REPAIR; } @@ -1525,24 +1525,24 @@ static UDWORD calcDroidBaseBody(DROID *psDroid) /* Calculate the base speed of a droid from it's template */ UDWORD calcDroidBaseSpeed(const DROID_TEMPLATE *psTemplate, UDWORD weight, UBYTE player) { - unsigned speed = asPropulsionTypes[asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]].propulsionType].powerRatioMult * - bodyPower(asBodyStats[psTemplate->asParts[COMP_BODY]], player) / MAX(1, weight); + unsigned speed = asPropulsionTypes[psTemplate->getPropulsionStats()->propulsionType].powerRatioMult * + bodyPower(*psTemplate->getBodyStats(), player) / MAX(1, weight); // reduce the speed of medium/heavy VTOLs - if (asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]].propulsionType == PROPULSION_TYPE_LIFT) + if (psTemplate->getPropulsionStats()->propulsionType == PROPULSION_TYPE_LIFT) { - if (asBodyStats[psTemplate->asParts[COMP_BODY]].size == SIZE_HEAVY) + if (psTemplate->getBodyStats()->size == SIZE_HEAVY) { speed /= 4; } - else if (asBodyStats[psTemplate->asParts[COMP_BODY]].size == SIZE_MEDIUM) + else if (psTemplate->getBodyStats()->size == SIZE_MEDIUM) { speed = speed * 3 / 4; } } // applies the engine output bonus if output > weight - if (asBodyStats[psTemplate->asParts[COMP_BODY]].base.power > weight) + if (psTemplate->getBodyStats()->base.power > weight) { speed = speed * 3 / 2; } @@ -1783,13 +1783,13 @@ void droidSetBits(const DROID_TEMPLATE *pTemplate, DROID *psDroid) if (inc < pTemplate->numWeaps) { psDroid->asWeaps[inc].nStat = pTemplate->asWeaps[inc]; - psDroid->asWeaps[inc].ammo = getWeaponStats(psDroid, inc)->upgrade[psDroid->player].numRounds; + psDroid->asWeaps[inc].ammo = psDroid->getWeaponStats(inc)->upgrade[psDroid->player].numRounds; } psDroid->asWeaps[inc].usedAmmo = 0; } memcpy(psDroid->asBits, pTemplate->asParts, sizeof(psDroid->asBits)); - switch (getPropulsionStats(psDroid)->propulsionType) // getPropulsionStats(psDroid) only defined after psDroid->asBits[COMP_PROPULSION] is set. + switch (psDroid->getPropulsionStats()->propulsionType) // getPropulsionStats(psDroid) only defined after psDroid->asBits[COMP_PROPULSION] is set. { case PROPULSION_TYPE_LIFT: psDroid->blockedBits = AIR_BLOCKED; @@ -2253,7 +2253,7 @@ UDWORD getDroidEffectiveLevel(const DROID *psDroid) const char *getDroidLevelName(const DROID *psDroid) { - const BRAIN_STATS *psStats = getBrainStats(psDroid); + const BRAIN_STATS *psStats = psDroid->getBrainStats(); return PE_("rank", psStats->rankNames[getDroidLevel(psDroid)].c_str()); } @@ -2467,7 +2467,7 @@ static bool ThreatInRange(SDWORD player, SDWORD range, SDWORD rangeX, SDWORD ran } //if VTOLs are excluded, skip them - if (!bVTOLs && ((getPropulsionStats(psDroid)->propulsionType == PROPULSION_TYPE_LIFT) || psDroid->isTransporter())) + if (!bVTOLs && ((psDroid->getPropulsionStats()->propulsionType == PROPULSION_TYPE_LIFT) || psDroid->isTransporter())) { continue; } @@ -2693,7 +2693,7 @@ bool electronicDroid(const DROID *psDroid) CHECK_DROID(psDroid); //use slot 0 for now - if (psDroid->numWeaps > 0 && getWeaponStats(psDroid, 0)->weaponSubClass == WSC_ELECTRONIC) + if (psDroid->numWeaps > 0 && psDroid->getWeaponStats(0)->weaponSubClass == WSC_ELECTRONIC) { return true; } @@ -2777,14 +2777,14 @@ bool isTransporter(DROID_TEMPLATE const *psTemplate) //access functions for vtols bool DROID::isVtol() const { - return getPropulsionStats(this)->propulsionType == PROPULSION_TYPE_LIFT + return getPropulsionStats()->propulsionType == PROPULSION_TYPE_LIFT && !isTransporter(); } /* returns true if the droid has lift propulsion and is moving */ bool DROID::isFlying() const { - return getPropulsionStats(this)->propulsionType == PROPULSION_TYPE_LIFT + return getPropulsionStats()->propulsionType == PROPULSION_TYPE_LIFT && (sMove.Status != MOVEINACTIVE || isTransporter()); } @@ -2804,7 +2804,7 @@ bool vtolEmpty(const DROID *psDroid) for (int i = 0; i < psDroid->numWeaps; i++) { - if (getWeaponStats(psDroid, i)->vtolAttackRuns > 0 && + if (psDroid->getWeaponStats(i)->vtolAttackRuns > 0 && psDroid->asWeaps[i].usedAmmo < getNumAttackRuns(psDroid, i)) { return false; @@ -2830,7 +2830,7 @@ bool vtolFull(const DROID *psDroid) for (int i = 0; i < psDroid->numWeaps; i++) { - if (getWeaponStats(psDroid, i)->vtolAttackRuns > 0 && + if (psDroid->getWeaponStats(i)->vtolAttackRuns > 0 && psDroid->asWeaps[i].usedAmmo > 0) { return false; @@ -2959,7 +2959,7 @@ bool allVtolsRearmed(const DROID *psDroid) UWORD getNumAttackRuns(const DROID *psDroid, int weapon_slot) { ASSERT_OR_RETURN(0, psDroid->isVtol(), "not a VTOL Droid"); - const auto* weaponStats = getWeaponStats(psDroid, weapon_slot); + const auto* weaponStats = psDroid->getWeaponStats(weapon_slot); // if weapon is a salvo weapon, then number of shots that can be fired = vtolAttackRuns * numRounds if (weaponStats->upgrade[psDroid->player].reloadTime) { @@ -2999,7 +2999,7 @@ bool vtolHappy(const DROID *psDroid) //check full complement of ammo for (int i = 0; i < psDroid->numWeaps; ++i) { - if (getWeaponStats(psDroid, i)->vtolAttackRuns > 0 + if (psDroid->getWeaponStats(i)->vtolAttackRuns > 0 && psDroid->asWeaps[i].usedAmmo != 0) { return false; @@ -3016,7 +3016,7 @@ void updateVtolAttackRun(DROID *psDroid, int weapon_slot) { if (psDroid->numWeaps > 0) { - if (getWeaponStats(psDroid, weapon_slot)->vtolAttackRuns > 0) + if (psDroid->getWeaponStats(weapon_slot)->vtolAttackRuns > 0) { ++psDroid->asWeaps[weapon_slot].usedAmmo; if (psDroid->asWeaps[weapon_slot].usedAmmo == getNumAttackRuns(psDroid, weapon_slot)) @@ -3116,7 +3116,7 @@ bool droidSensorDroidWeapon(const BASE_OBJECT *psObj, const DROID *psDroid) } // Check indirect weapon droid with standard/CB/radar detector sensor - if (!proj_Direct(getWeaponStats(psDroid, 0))) + if (!proj_Direct(psDroid->getWeaponStats(0))) { if ((psStats->type == STANDARD_SENSOR || psStats->type == INDIRECT_CB_SENSOR || psStats->type == SUPER_SENSOR /*|| psStats->type == RADAR_DETECTOR_SENSOR*/) && !(psObj->type == OBJ_DROID && ((const DROID*)psObj)->droidType == DROID_COMMAND)) @@ -3135,7 +3135,7 @@ bool cbSensorDroid(const DROID *psDroid) { return false; } - const auto sensorType = getSensorStats(psDroid)->type; + const auto sensorType = psDroid->getSensorStats()->type; if (sensorType == VTOL_CB_SENSOR || sensorType == INDIRECT_CB_SENSOR) { @@ -3152,7 +3152,7 @@ bool standardSensorDroid(const DROID *psDroid) { return false; } - const auto sensorType = getSensorStats(psDroid)->type; + const auto sensorType = psDroid->getSensorStats()->type; if (sensorType == VTOL_INTERCEPT_SENSOR || sensorType == STANDARD_SENSOR || sensorType == SUPER_SENSOR) @@ -3278,21 +3278,21 @@ DROID *giftSingleDroid(DROID *psD, UDWORD to, bool electronic, Vector2i pos) adjustDroidCount(psD, 1); // the new player may have different default sensor/ecm/repair components - if (getSensorStats(psD)->location == LOC_DEFAULT) + if (psD->getSensorStats()->location == LOC_DEFAULT) { if (psD->asBits[COMP_SENSOR] != aDefaultSensor[psD->player]) { psD->asBits[COMP_SENSOR] = aDefaultSensor[psD->player]; } } - if (getECMStats(psD)->location == LOC_DEFAULT) + if (psD->getECMStats()->location == LOC_DEFAULT) { if (psD->asBits[COMP_ECM] != aDefaultECM[psD->player]) { psD->asBits[COMP_ECM] = aDefaultECM[psD->player]; } } - if (getRepairStats(psD)->location == LOC_DEFAULT) + if (psD->getRepairStats()->location == LOC_DEFAULT) { if (psD->asBits[COMP_REPAIRUNIT] != aDefaultRepair[psD->player]) { @@ -3361,7 +3361,7 @@ DROID *giftSingleDroid(DROID *psD, UDWORD to, bool electronic, Vector2i pos) int16_t DROID::droidResistance() const { CHECK_DROID(this); - const BODY_STATS *psStats = &asBodyStats[asBits[COMP_BODY]]; + const BODY_STATS *psStats = getBodyStats(); int res = experience / (65536 / MAX(1, psStats->upgrade[player].resistance)); // ensure resistance is a base minimum res = MAX(res, psStats->upgrade[player].resistance); @@ -3379,7 +3379,7 @@ bool checkValidWeaponForProp(const DROID_TEMPLATE *psTemplate) PROPULSION_STATS *psPropStats; //check propulsion stat for vtol - psPropStats = &asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]]; + psPropStats = psTemplate->getPropulsionStats(); ASSERT_OR_RETURN(false, psPropStats != nullptr, "invalid propulsion stats pointer"); @@ -3392,8 +3392,8 @@ bool checkValidWeaponForProp(const DROID_TEMPLATE *psTemplate) if (asPropulsionTypes[psPropStats->propulsionType].travel == AIR) { //check weapon stat for indirect - if (!proj_Direct(&asWeaponStats[psTemplate->asWeaps[0]]) - || !asWeaponStats[psTemplate->asWeaps[0]].vtolAttackRuns) + if (!proj_Direct(psTemplate->getWeaponStats(0)) + || !psTemplate->getWeaponStats(0)->vtolAttackRuns) { return false; } @@ -3401,7 +3401,7 @@ bool checkValidWeaponForProp(const DROID_TEMPLATE *psTemplate) else { // VTOL weapons do not go on non-AIR units. - if (asWeaponStats[psTemplate->asWeaps[0]].vtolAttackRuns) + if (psTemplate->getWeaponStats(0)->vtolAttackRuns) { return false; } @@ -3409,7 +3409,7 @@ bool checkValidWeaponForProp(const DROID_TEMPLATE *psTemplate) //also checks that there is no other system component if (psTemplate->asParts[COMP_BRAIN] != 0 - && asWeaponStats[psTemplate->asWeaps[0]].weaponSubClass != WSC_COMMAND) + && psTemplate->getWeaponStats(0)->weaponSubClass != WSC_COMMAND) { assert(false); return false; @@ -3547,7 +3547,7 @@ void checkDroid(const DROID *droid, const char *const location, const char *func int droidSqDist(const DROID *psDroid, const BASE_OBJECT *psObj) { - PROPULSION_STATS *psPropStats = getPropulsionStats(psDroid); + PROPULSION_STATS *psPropStats = psDroid->getPropulsionStats(); if (!fpathCheck(psDroid->pos, psObj->pos, psPropStats->propulsionType)) { @@ -3555,3 +3555,38 @@ int droidSqDist(const DROID *psDroid, const BASE_OBJECT *psObj) } return objPosDiffSq(psDroid->pos, psObj->pos); } + +BODY_STATS* DROID::getBodyStats() const +{ + return &asBodyStats[asBits[COMP_BODY]]; +} + +BRAIN_STATS* DROID::getBrainStats() const +{ + return &asBrainStats[asBits[COMP_BRAIN]]; +} + +PROPULSION_STATS* DROID::getPropulsionStats() const +{ + return &asPropulsionStats[asBits[COMP_PROPULSION]]; +} + +SENSOR_STATS* DROID::getSensorStats() const +{ + return &asSensorStats[asBits[COMP_SENSOR]]; +} + +ECM_STATS* DROID::getECMStats() const +{ + return &asECMStats[asBits[COMP_ECM]]; +} + +REPAIR_STATS* DROID::getRepairStats() const +{ + return &asRepairStats[asBits[COMP_REPAIRUNIT]]; +} + +CONSTRUCT_STATS* DROID::getConstructStats() const +{ + return &asConstructStats[asBits[COMP_CONSTRUCT]]; +} diff --git a/src/droid.h b/src/droid.h index 480544d286c..1f1156dd63a 100644 --- a/src/droid.h +++ b/src/droid.h @@ -303,49 +303,6 @@ static inline int droidSensorRange(const DROID *psDroid) return objSensorRange((const BASE_OBJECT *)psDroid); } -/* - * Component stat helper functions - */ -static inline BODY_STATS *getBodyStats(const DROID *psDroid) -{ - return &asBodyStats[psDroid->asBits[COMP_BODY]]; -} - -static inline BRAIN_STATS *getBrainStats(const DROID *psDroid) -{ - return &asBrainStats[psDroid->asBits[COMP_BRAIN]]; -} - -static inline PROPULSION_STATS *getPropulsionStats(const DROID *psDroid) -{ - return &asPropulsionStats[psDroid->asBits[COMP_PROPULSION]]; -} - -static inline SENSOR_STATS *getSensorStats(const DROID *psDroid) -{ - return &asSensorStats[psDroid->asBits[COMP_SENSOR]]; -} - -static inline ECM_STATS *getECMStats(const DROID *psDroid) -{ - return &asECMStats[psDroid->asBits[COMP_ECM]]; -} - -static inline REPAIR_STATS *getRepairStats(const DROID *psDroid) -{ - return &asRepairStats[psDroid->asBits[COMP_REPAIRUNIT]]; -} - -static inline CONSTRUCT_STATS *getConstructStats(const DROID *psDroid) -{ - return &asConstructStats[psDroid->asBits[COMP_CONSTRUCT]]; -} - -static inline WEAPON_STATS *getWeaponStats(const DROID *psDroid, int weapon_slot) -{ - return &asWeaponStats[psDroid->asWeaps[weapon_slot].nStat]; -} - static inline Rotation getInterpolatedWeaponRotation(const DROID *psDroid, int weaponSlot, uint32_t time) { return interpolateRot(psDroid->asWeaps[weaponSlot].prevRot, psDroid->asWeaps[weaponSlot].rot, psDroid->prevSpacetime.time, psDroid->time, time); diff --git a/src/droiddef.h b/src/droiddef.h index a4df0a90059..439ba258e88 100644 --- a/src/droiddef.h +++ b/src/droiddef.h @@ -57,6 +57,15 @@ struct DROID_TEMPLATE : public BASE_STATS { DROID_TEMPLATE(); + BODY_STATS* getBodyStats() const; + BRAIN_STATS* getBrainStats() const; + PROPULSION_STATS* getPropulsionStats() const; + SENSOR_STATS* getSensorStats() const; + ECM_STATS* getECMStats() const; + REPAIR_STATS* getRepairStats() const; + CONSTRUCT_STATS* getConstructStats() const; + WEAPON_STATS* getWeaponStats(int weaponSlot) const; + /*! * The droid components. * @@ -112,6 +121,15 @@ struct DROID : public BASE_OBJECT // true if a vtol droid currently returning to be rearmed bool isVtolRearming() const; + // Helper functions to get various droid stats. + BODY_STATS* getBodyStats() const; + BRAIN_STATS* getBrainStats() const; + PROPULSION_STATS* getPropulsionStats() const; + SENSOR_STATS* getSensorStats() const; + ECM_STATS* getECMStats() const; + REPAIR_STATS* getRepairStats() const; + CONSTRUCT_STATS* getConstructStats() const; + /// UTF-8 name of the droid. This is generated from the droid template /// WARNING: This *can* be changed by the game player after creation & can be translated, do NOT rely on this being the same for everyone! char aName[MAX_STR_LENGTH]; diff --git a/src/fpath.cpp b/src/fpath.cpp index a33f4bea350..213420b55f8 100644 --- a/src/fpath.cpp +++ b/src/fpath.cpp @@ -251,7 +251,7 @@ bool fpathBaseBlockingTile(SDWORD x, SDWORD y, PROPULSION_TYPE propulsion, int m bool fpathDroidBlockingTile(DROID *psDroid, int x, int y, FPATH_MOVETYPE moveType) { - return fpathBaseBlockingTile(x, y, getPropulsionStats(psDroid)->propulsionType, psDroid->player, moveType); + return fpathBaseBlockingTile(x, y, psDroid->getPropulsionStats()->propulsionType, psDroid->player, moveType); } // Check if the map tile at a location blocks a droid @@ -414,7 +414,7 @@ static FPATH_RETVAL fpathRoute(MOVE_CONTROL *psMove, unsigned id, int startX, in FPATH_RETVAL fpathDroidRoute(DROID *psDroid, SDWORD tX, SDWORD tY, FPATH_MOVETYPE moveType) { bool acceptNearest; - PROPULSION_STATS *psPropStats = getPropulsionStats(psDroid); + PROPULSION_STATS *psPropStats = psDroid->getPropulsionStats(); // override for AI to blast our way through stuff if (!isHumanPlayer(psDroid->player) && moveType == FMT_MOVE) @@ -429,7 +429,7 @@ FPATH_RETVAL fpathDroidRoute(DROID *psDroid, SDWORD tX, SDWORD tY, FPATH_MOVETYP Position startPos = psDroid->pos; Position endPos = Position(tX, tY, 0); StructureBounds dstStructure = getStructureBounds(worldTile(endPos.xy())->psObject); - const auto droidPropulsionType = getPropulsionStats(psDroid)->propulsionType; + const auto droidPropulsionType = psDroid->getPropulsionStats()->propulsionType; startPos = findNonblockingPosition(startPos, droidPropulsionType, psDroid->player, moveType); if (!dstStructure.valid()) // If there's a structure over the destination, ignore it, otherwise pathfind from somewhere around the obstruction. { diff --git a/src/game.cpp b/src/game.cpp index 6628a334728..f6e97f97c34 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -5872,16 +5872,16 @@ static nlohmann::json writeDroid(const DROID *psCurr, bool onMission, int &count droidObj["droidType"] = psCurr->droidType; droidObj["weapons"] = psCurr->numWeaps; nlohmann::json partsObj = nlohmann::json::object(); - partsObj["body"] = getBodyStats(psCurr)->id; - partsObj["propulsion"] = getPropulsionStats(psCurr)->id; - partsObj["brain"] = getBrainStats(psCurr)->id; - partsObj["repair"] = getRepairStats(psCurr)->id; - partsObj["ecm"] = getECMStats(psCurr)->id; - partsObj["sensor"] = getSensorStats(psCurr)->id; - partsObj["construct"] = getConstructStats(psCurr)->id; + partsObj["body"] = psCurr->getBodyStats()->id; + partsObj["propulsion"] = psCurr->getPropulsionStats()->id; + partsObj["brain"] = psCurr->getBrainStats()->id; + partsObj["repair"] = psCurr->getRepairStats()->id; + partsObj["ecm"] = psCurr->getECMStats()->id; + partsObj["sensor"] = psCurr->getSensorStats()->id; + partsObj["construct"] = psCurr->getConstructStats()->id; for (int j = 0; j < psCurr->numWeaps; j++) { - partsObj["weapon/" + WzString::number(j + 1).toStdString()] = getWeaponStats(psCurr, j)->id; + partsObj["weapon/" + WzString::number(j + 1).toStdString()] = psCurr->getWeaponStats(j)->id; } droidObj["parts"] = partsObj; droidObj["moveStatus"] = psCurr->sMove.Status; @@ -6557,7 +6557,7 @@ bool writeStructFile(const char *pFileName) ini.setValue("weapons", psCurr->numWeaps); for (unsigned j = 0; j < psCurr->numWeaps; j++) { - ini.setValue("parts/weapon/" + WzString::number(j + 1), asWeaponStats[psCurr->asWeaps[j].nStat].id); + ini.setValue("parts/weapon/" + WzString::number(j + 1), psCurr->getWeaponStats(j)->id); if (psCurr->asWeaps[j].nStat > 0) { ini.setValue("ammo/" + WzString::number(j), psCurr->asWeaps[j].ammo); diff --git a/src/keybind.cpp b/src/keybind.cpp index fc5e4ad2735..afc4e6a29b3 100644 --- a/src/keybind.cpp +++ b/src/keybind.cpp @@ -1528,7 +1528,7 @@ void kf_Reload() { if (isLasSat(psCurr->pStructureType) && psCurr->selected) { - unsigned int firePause = weaponFirePause(asWeaponStats[psCurr->asWeaps[0].nStat], psCurr->player); + unsigned int firePause = weaponFirePause(*psCurr->getWeaponStats(0), psCurr->player); psCurr->asWeaps[0].lastFired -= firePause; CONPRINTF("%s", _("Selected buildings instantly recharged!")); diff --git a/src/loop.cpp b/src/loop.cpp index c53f651aaaa..8b50b544dc7 100644 --- a/src/loop.cpp +++ b/src/loop.cpp @@ -465,7 +465,7 @@ void countUpdate(bool synch) setSatUplinkExists(true, i); } //don't wait for the Las Sat to be built - can't build another if one is partially built - if (asWeaponStats[psCBuilding->asWeaps[0].nStat].weaponSubClass == WSC_LAS_SAT) + if (psCBuilding->getWeaponStats(0)->weaponSubClass == WSC_LAS_SAT) { setLasSatExists(true, i); } @@ -477,7 +477,7 @@ void countUpdate(bool synch) setSatUplinkExists(true, i); } //don't wait for the Las Sat to be built - can't build another if one is partially built - if (asWeaponStats[psCBuilding->asWeaps[0].nStat].weaponSubClass == WSC_LAS_SAT) + if (psCBuilding->getWeaponStats(0)->weaponSubClass == WSC_LAS_SAT) { setLasSatExists(true, i); } diff --git a/src/map.cpp b/src/map.cpp index 4ef31120c35..f573ea3ba93 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2093,7 +2093,7 @@ static void threatUpdate(int player) } for (weapon = 0; weapon < psDroid->numWeaps; weapon++) { - mode |= getWeaponStats(psDroid, weapon)->surfaceToAir; + mode |= psDroid->getWeaponStats(weapon)->surfaceToAir; } if (psDroid->droidType == DROID_SENSOR) // special treatment for sensor turrets, no multiweapon support { @@ -2111,7 +2111,7 @@ static void threatUpdate(int player) for (weapon = 0; weapon < psStruct->numWeaps; weapon++) { - mode |= asWeaponStats[psStruct->asWeaps[weapon].nStat].surfaceToAir; + mode |= psStruct->getWeaponStats(weapon)->surfaceToAir; } if (psStruct->pStructureType->pSensor && psStruct->pStructureType->pSensor->location == LOC_TURRET) // special treatment for sensor turrets { diff --git a/src/mapgrid.cpp b/src/mapgrid.cpp index 21fea2acc5b..7cbf73f5cfe 100644 --- a/src/mapgrid.cpp +++ b/src/mapgrid.cpp @@ -215,7 +215,7 @@ struct ConditionDroidCandidateForRepair if (obj->type != OBJ_DROID) return false; const DROID *psDroid = (const DROID*) obj; const bool isOwnOrAlly = psDroid->player == player || aiCheckAlliances(psDroid->player, player); - const bool isVTOL = getPropulsionStats(psDroid)->propulsionType == PROPULSION_TYPE_LIFT; + const bool isVTOL = psDroid->getPropulsionStats()->propulsionType == PROPULSION_TYPE_LIFT; // either it's a ground unit, or it's a VTOL on ground const bool isOnGround = (!isVTOL) || (isVTOL && (psDroid->sMove.Status == MOVEINACTIVE && psDroid->sMove.iVertSpeed == 0)); // Note: no check for droidIsDamaged(psDroid) this is intentional diff --git a/src/move.cpp b/src/move.cpp index 3fc1984e65e..a44544f0e10 100644 --- a/src/move.cpp +++ b/src/move.cpp @@ -260,7 +260,7 @@ static void moveShuffleDroid(DROID *psDroid, Vector2i s) rvx = svy; // 90° to the... left? rvy = -svx; - const auto droidPropType = getPropulsionStats(psDroid)->propulsionType; + const auto droidPropType = psDroid->getPropulsionStats()->propulsionType; // check for blocking tiles if (fpathBlockingTile(map_coord((SDWORD)psDroid->pos.x + lvx), map_coord((SDWORD)psDroid->pos.y + lvy), droidPropType)) @@ -351,7 +351,7 @@ static void moveShuffleDroid(DROID *psDroid, Vector2i s) void moveStopDroid(DROID *psDroid) { CHECK_DROID(psDroid); - PROPULSION_STATS* psPropStats = getPropulsionStats(psDroid); + PROPULSION_STATS* psPropStats = psDroid->getPropulsionStats(); ASSERT_OR_RETURN(, psPropStats != nullptr, "invalid propulsion stats pointer"); if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT) @@ -456,7 +456,7 @@ static int32_t moveDirectPathToWaypoint(DROID *psDroid, unsigned positionIndex) Vector2i delta = dst - src; int32_t dist = iHypot(delta); BLOCKING_CALLBACK_DATA data; - data.propulsionType = getPropulsionStats(psDroid)->propulsionType; + data.propulsionType = psDroid->getPropulsionStats()->propulsionType; data.blocking = false; data.src = src; data.dst = dst; @@ -554,7 +554,7 @@ static SDWORD moveObjRadius(const BASE_OBJECT *psObj) } else { - const BODY_STATS *psBdyStats = getBodyStats(psDroid); + const BODY_STATS *psBdyStats = psDroid->getBodyStats(); switch (psBdyStats->size) { case SIZE_LIGHT: @@ -761,7 +761,7 @@ static void moveOpenGates(DROID *psDroid) // TODO See if this function can be simplified. static void moveCalcBlockingSlide(DROID *psDroid, int32_t *pmx, int32_t *pmy, uint16_t tarDir, uint16_t *pSlideDir) { - PROPULSION_TYPE propulsion = getPropulsionStats(psDroid)->propulsionType; + PROPULSION_TYPE propulsion = psDroid->getPropulsionStats()->propulsionType; SDWORD horizX, horizY, vertX, vertY; uint16_t slideDir; // calculate the new coords and see if they are on a different tile @@ -1153,7 +1153,7 @@ static Vector2i moveGetObstacleVector(DROID *psDroid, Vector2i dest) { int32_t numObst = 0, distTot = 0; Vector2i dir(0, 0); - PROPULSION_STATS *psPropStats = getPropulsionStats(psDroid); + PROPULSION_STATS *psPropStats = psDroid->getPropulsionStats(); ASSERT_OR_RETURN(dir, psPropStats, "invalid propulsion stats pointer"); int ourMaxSpeed = psPropStats->maxSpeed; @@ -1194,7 +1194,7 @@ static Vector2i moveGetObstacleVector(DROID *psDroid, Vector2i dest) continue; } - PROPULSION_STATS *obstaclePropStats = getPropulsionStats(psObstacle); + PROPULSION_STATS *obstaclePropStats = psObstacle->getPropulsionStats(); int obstacleMaxSpeed = obstaclePropStats->maxSpeed; int obstacleRadius = moveObjRadius(psObstacle); int totalRadius = ourRadius + obstacleRadius; @@ -1318,7 +1318,7 @@ SDWORD moveCalcDroidSpeed(DROID *psDroid) // NOTE: This screws up since the transporter is offscreen still (on a mission!), and we are trying to find terrainType of a tile (that is offscreen!) if (psDroid->droidType == DROID_SUPERTRANSPORTER && missionIsOffworld()) { - PROPULSION_STATS *propulsion = getPropulsionStats(psDroid); + PROPULSION_STATS *propulsion = psDroid->getPropulsionStats(); speed = propulsion->maxSpeed; } else @@ -1345,7 +1345,7 @@ SDWORD moveCalcDroidSpeed(DROID *psDroid) { if (psDroid->asWeaps[0].nStat > 0 && psDroid->asWeaps[0].lastFired + FOM_MOVEPAUSE > gameTime) { - psWStats = getWeaponStats(psDroid, 0); + psWStats = psDroid->getWeaponStats(0); if (!psWStats->fireOnMove) { speed = 0; @@ -1573,7 +1573,7 @@ static void moveUpdateGroundModel(DROID *psDroid, SDWORD speed, uint16_t directi return; } - psPropStats = getPropulsionStats(psDroid); + psPropStats = psDroid->getPropulsionStats(); spinSpeed = psDroid->baseSpeed * psPropStats->spinSpeed; turnSpeed = psDroid->baseSpeed * psPropStats->turnSpeed; spinAngle = DEG(psPropStats->spinAngle); @@ -1637,7 +1637,7 @@ static void moveUpdatePersonModel(DROID *psDroid, SDWORD speed, uint16_t directi return; } - psPropStats = getPropulsionStats(psDroid); + psPropStats = psDroid->getPropulsionStats(); spinSpeed = psDroid->baseSpeed * psPropStats->spinSpeed; turnSpeed = psDroid->baseSpeed * psPropStats->turnSpeed; @@ -1734,7 +1734,7 @@ static void moveUpdateVtolModel(DROID *psDroid, SDWORD speed, uint16_t direction return; } - psPropStats = getPropulsionStats(psDroid); + psPropStats = psDroid->getPropulsionStats(); spinSpeed = DEG(psPropStats->spinSpeed); turnSpeed = DEG(psPropStats->turnSpeed); @@ -1867,7 +1867,7 @@ static void movePlayDroidMoveAudio(DROID *psDroid) if ((psDroid != nullptr) && (psDroid->visibleForLocalDisplay())) { - PROPULSION_STATS *psPropStats = getPropulsionStats(psDroid); + PROPULSION_STATS *psPropStats = psDroid->getPropulsionStats(); ASSERT_OR_RETURN(, psPropStats != nullptr, "Invalid propulsion stats pointer"); iPropType = psPropStats->propulsionType; psPropType = &asPropulsionTypes[iPropType]; @@ -1927,7 +1927,7 @@ static void movePlayAudio(DROID *psDroid, bool bStarted, bool bStoppedBefore, SD AUDIO_CALLBACK pAudioCallback = nullptr; /* get prop stats */ - psPropStats = getPropulsionStats(psDroid); + psPropStats = psDroid->getPropulsionStats(); ASSERT_OR_RETURN(, psPropStats != nullptr, "Invalid propulsion stats pointer"); propType = psPropStats->propulsionType; psPropType = &asPropulsionTypes[propType]; @@ -2076,7 +2076,7 @@ void moveUpdateDroid(DROID *psDroid) CHECK_DROID(psDroid); - psPropStats = getPropulsionStats(psDroid); + psPropStats = psDroid->getPropulsionStats(); ASSERT_OR_RETURN(, psPropStats != nullptr, "Invalid propulsion stats pointer"); // If the droid has been attacked by an EMP weapon, it is temporarily disabled diff --git a/src/multistruct.cpp b/src/multistruct.cpp index 759c0ad8f0b..8234dc8f1f4 100644 --- a/src/multistruct.cpp +++ b/src/multistruct.cpp @@ -228,7 +228,7 @@ bool recvLasSat(NETQUEUE queue) if (psStruct && psObj && psStruct->pStructureType->psWeapStat[0]->weaponSubClass == WSC_LAS_SAT) { // Lassats have just one weapon - unsigned firePause = weaponFirePause(asWeaponStats[psStruct->asWeaps[0].nStat], player); + unsigned firePause = weaponFirePause(*psStruct->getWeaponStats(0), player); unsigned damLevel = PERCENT(psStruct->body, psStruct->structureBody()); if (damLevel < HEAVY_DAMAGE_LEVEL) diff --git a/src/oprint.cpp b/src/oprint.cpp index 68a0a0d1b9d..008dad255ca 100644 --- a/src/oprint.cpp +++ b/src/oprint.cpp @@ -203,7 +203,7 @@ void printDroidInfo(const DROID *psDroid) if (psDroid->asWeaps[0].nStat > 0) { - printWeaponInfo(getWeaponStats(psDroid, 0)); + printWeaponInfo(psDroid->getWeaponStats(0)); } for (int i = 0; i < COMP_NUMCOMPONENTS; ++i) @@ -281,7 +281,7 @@ void printDroidInfo(const DROID *psDroid) if (psDroid->asBits[i] > 0) { CONPRINTF("%s", "Repair: "); - psRepairStats = getRepairStats(psDroid); + psRepairStats = psDroid->getRepairStats(); printComponentInfo((COMPONENT_STATS *)psRepairStats); CONPRINTF(" repPnts %d loc %d imd %p\n", repairPoints(*psRepairStats, psDroid->player), diff --git a/src/order.cpp b/src/order.cpp index f9397a208f2..5a7d27ca9d1 100644 --- a/src/order.cpp +++ b/src/order.cpp @@ -415,7 +415,7 @@ void orderUpdateDroid(DROID *psDroid) SDWORD xdiff, ydiff; bool bAttack; SDWORD xoffset, yoffset; - const WEAPON_STATS *psWeapStats = getWeaponStats(psDroid, 0); + const WEAPON_STATS *psWeapStats = psDroid->getWeaponStats(0); // clear the target if it has died if (psDroid->order.psObj && psDroid->order.psObj->died) { @@ -1368,7 +1368,7 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder) { UDWORD iFactoryDistSq; STRUCTURE *psFactory; - const PROPULSION_STATS *psPropStats = getPropulsionStats(psDroid); + const PROPULSION_STATS *psPropStats = psDroid->getPropulsionStats(); const Vector3i rPos(psOrder->pos, 0); syncDebugDroid(psDroid, '-'); syncDebug("%d ordered %s", psDroid->id, getDroidOrderName(psOrder->type)); @@ -1466,14 +1466,14 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder) case DORDER_SCOUT: // can't move vtols to blocking tiles if (psDroid->isVtol() - && fpathBlockingTile(map_coord(psOrder->pos), getPropulsionStats(psDroid)->propulsionType)) + && fpathBlockingTile(map_coord(psOrder->pos), psDroid->getPropulsionStats()->propulsionType)) { break; } //in multiPlayer, cannot move Transporter to blocking tile either if (game.type == LEVEL_TYPE::SKIRMISH && psDroid->isTransporter() - && fpathBlockingTile(map_coord(psOrder->pos), getPropulsionStats(psDroid)->propulsionType)) + && fpathBlockingTile(map_coord(psOrder->pos), psDroid->getPropulsionStats()->propulsionType)) { break; } @@ -2470,7 +2470,7 @@ static bool orderDroidObjAdd(DROID *psDroid, DroidOrder const &order, bool add) DROID_ORDER chooseOrderLoc(DROID *psDroid, UDWORD x, UDWORD y, bool altOrder) { DROID_ORDER order = DORDER_NONE; - PROPULSION_TYPE propulsion = getPropulsionStats(psDroid)->propulsionType; + PROPULSION_TYPE propulsion = psDroid->getPropulsionStats()->propulsionType; if (psDroid->isTransporter() && game.type == LEVEL_TYPE::CAMPAIGN) { @@ -2683,7 +2683,7 @@ DroidOrder chooseOrderObj(DROID *psDroid, BASE_OBJECT *psObj, bool altOrder) && psObj->player != psDroid->player && !aiCheckAlliances(psObj->player , psDroid->player)) { - const auto sensorType = getSensorStats(psDroid)->type; + const auto sensorType = psDroid->getSensorStats()->type; //check for standard sensor or VTOL intercept sensor if (sensorType == STANDARD_SENSOR || sensorType == VTOL_INTERCEPT_SENSOR @@ -2729,7 +2729,7 @@ DroidOrder chooseOrderObj(DROID *psDroid, BASE_OBJECT *psObj, bool altOrder) (psDroid->droidType == DROID_WEAPON || psDroid->droidType == DROID_CYBORG || psDroid->droidType == DROID_CYBORG_SUPER) && - proj_Direct(getWeaponStats(psDroid, 0))) + proj_Direct(psDroid->getWeaponStats(0))) { order = DroidOrder(DORDER_GUARD, psObj); assignSensorTarget(psObj); @@ -2827,7 +2827,7 @@ DroidOrder chooseOrderObj(DROID *psDroid, BASE_OBJECT *psObj, bool altOrder) else if ((psDroid->droidType == DROID_WEAPON || psDroid->droidType == DROID_CYBORG || psDroid->droidType == DROID_CYBORG_SUPER) - && proj_Direct(getWeaponStats(psDroid, 0))) + && proj_Direct(psDroid->getWeaponStats(0))) { order = DroidOrder(DORDER_GUARD, psObj); } @@ -3087,7 +3087,7 @@ bool secondarySupported(const DROID *psDroid, SECONDARY_ORDER sec) { for (unsigned i = 0; i < psDroid->numWeaps; ++i) { - const WEAPON_STATS *weaponStats = getWeaponStats(psDroid, i); + const WEAPON_STATS *weaponStats = psDroid->getWeaponStats(i); if (proj_GetLongRange(*weaponStats, psDroid->player) == proj_GetShortRange(*weaponStats, psDroid->player)) { diff --git a/src/projectile.cpp b/src/projectile.cpp index bda26effa02..e5d723e53e0 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -993,7 +993,7 @@ static void proj_radiusSweep(PROJECTILE *psObj, WEAPON_STATS *psStats, Vector3i switch (psCurr->type) { case OBJ_DROID: - bTargetInAir = asPropulsionTypes[getPropulsionStats((DROID*)psCurr)->propulsionType].travel == AIR && ((DROID *)psCurr)->sMove.Status != MOVEINACTIVE; + bTargetInAir = asPropulsionTypes[((DROID*)psCurr)->getPropulsionStats()->propulsionType].travel == AIR && ((DROID*)psCurr)->sMove.Status != MOVEINACTIVE; useSphere = true; break; case OBJ_STRUCTURE: @@ -1572,8 +1572,8 @@ UDWORD calcDamage(UDWORD baseDamage, WEAPON_EFFECT weaponEffect, const BASE_OBJE } else if (psTarget->type == OBJ_DROID) { - const int propulsion = getPropulsionStats((const DROID*)psTarget)->propulsionType; - const int body = getBodyStats((const DROID*)psTarget)->size; + const int propulsion = ((const DROID*)psTarget)->getPropulsionStats()->propulsionType; + const int body = ((const DROID*)psTarget)->getBodyStats()->size; damage += baseDamage * (asWeaponModifier[weaponEffect][propulsion] - 100); damage += baseDamage * (asWeaponModifierBody[weaponEffect][body] - 100); } @@ -1760,7 +1760,7 @@ int establishTargetHeight(BASE_OBJECT const *psTarget) case OBJ_DROID: { DROID const *psDroid = (DROID const *)psTarget; - unsigned int height = getBodyStats(psDroid)->pIMD->max.y - getBodyStats(psDroid)->pIMD->min.y; + unsigned int height = psDroid->getBodyStats()->pIMD->max.y - psDroid->getBodyStats()->pIMD->min.y; unsigned int utilityHeight = 0, yMax = 0, yMin = 0; // Temporaries for addition of utility's height to total height // VTOL's don't have pIMD either it seems... @@ -1774,7 +1774,7 @@ int establishTargetHeight(BASE_OBJECT const *psTarget) case DROID_WEAPON: if (psDroid->numWeaps > 0) { - const auto* weaponImd = getWeaponStats(psDroid, 0)->pIMD; + const auto* weaponImd = psDroid->getWeaponStats(0)->pIMD; // Don't do this for Barbarian Propulsions as they don't possess a turret (and thus have pIMD == NULL) if (weaponImd == nullptr) { @@ -1788,28 +1788,28 @@ int establishTargetHeight(BASE_OBJECT const *psTarget) case DROID_SENSOR: { - const auto* sensorImd = getSensorStats(psDroid)->pIMD; + const auto* sensorImd = psDroid->getSensorStats()->pIMD; yMax = sensorImd->max.y; yMin = sensorImd->min.y; break; } case DROID_ECM: { - const auto* ecmImd = getECMStats(psDroid)->pIMD; + const auto* ecmImd = psDroid->getECMStats()->pIMD; yMax = ecmImd->max.y; yMin = ecmImd->min.y; break; } case DROID_CONSTRUCT: { - const auto* constructImd = getConstructStats(psDroid)->pIMD; + const auto* constructImd = psDroid->getConstructStats()->pIMD; yMax = constructImd->max.y; yMin = constructImd->min.y; break; } case DROID_REPAIR: { - const auto repairImd = getRepairStats(psDroid)->pIMD; + const auto repairImd = psDroid->getRepairStats()->pIMD; yMax = repairImd->max.y; yMin = repairImd->min.y; break; diff --git a/src/quickjs_backend.cpp b/src/quickjs_backend.cpp index 58ec21de735..2c22772f1ef 100644 --- a/src/quickjs_backend.cpp +++ b/src/quickjs_backend.cpp @@ -815,7 +815,7 @@ JSValue convStructure(const STRUCTURE *psStruct, JSContext *ctx) { if (psStruct->asWeaps[i].nStat) { - WEAPON_STATS *psWeap = &asWeaponStats[psStruct->asWeaps[i].nStat]; + WEAPON_STATS *psWeap = psStruct->getWeaponStats(i); aa = aa || psWeap->surfaceToAir & SHOOT_IN_AIR; ga = ga || psWeap->surfaceToAir & SHOOT_ON_GROUND; indirect = indirect || psWeap->movementModel == MM_INDIRECT || psWeap->movementModel == MM_HOMINGINDIRECT; @@ -865,7 +865,7 @@ JSValue convStructure(const STRUCTURE *psStruct, JSContext *ctx) for (int j = 0; j < psStruct->numWeaps; j++) { JSValue weapon = JS_NewObject(ctx); - const WEAPON_STATS *psStats = &asWeaponStats[psStruct->asWeaps[j].nStat]; + const WEAPON_STATS *psStats = psStruct->getWeaponStats(j); QuickJS_DefinePropertyValue(ctx, weapon, "fullname", JS_NewString(ctx, psStats->name.toUtf8().c_str()), JS_PROP_ENUMERABLE); QuickJS_DefinePropertyValue(ctx, weapon, "name", JS_NewString(ctx, psStats->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); // will be changed to contain full name QuickJS_DefinePropertyValue(ctx, weapon, "id", JS_NewString(ctx, psStats->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); @@ -962,14 +962,14 @@ JSValue convDroid(const DROID *psDroid, JSContext *ctx) bool ga = false; bool indirect = false; int range = -1; - const BODY_STATS *psBodyStats = getBodyStats(psDroid); + const BODY_STATS *psBodyStats = psDroid->getBodyStats(); for (int i = 0; i < psDroid->numWeaps; i++) { if (psDroid->asWeaps[i].nStat) { ASSERT(psDroid->asWeaps[i].nStat < asWeaponStats.size(), "Invalid nStat (%d) referenced for asWeaps[%d]; numWeaponStats (%zu); droid: \"%s\" (numWeaps: %u)", psDroid->asWeaps[i].nStat, i, asWeaponStats.size(), psDroid->aName, psDroid->numWeaps); - WEAPON_STATS *psWeap = getWeaponStats(psDroid, i); + WEAPON_STATS *psWeap = psDroid->getWeaponStats(i); aa = aa || psWeap->surfaceToAir & SHOOT_IN_AIR; ga = ga || psWeap->surfaceToAir & SHOOT_ON_GROUND; indirect = indirect || psWeap->movementModel == MM_INDIRECT || psWeap->movementModel == MM_HOMINGINDIRECT; @@ -1020,8 +1020,8 @@ JSValue convDroid(const DROID *psDroid, JSContext *ctx) QuickJS_DefinePropertyValue(ctx, value, "experience", JS_NewFloat64(ctx, (double)psDroid->experience / 65536.0), JS_PROP_ENUMERABLE); QuickJS_DefinePropertyValue(ctx, value, "health", JS_NewFloat64(ctx, 100.0 / (double)psDroid->originalBody * (double)psDroid->body), JS_PROP_ENUMERABLE); - QuickJS_DefinePropertyValue(ctx, value, "body", JS_NewString(ctx, getBodyStats(psDroid)->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); - QuickJS_DefinePropertyValue(ctx, value, "propulsion", JS_NewString(ctx, getPropulsionStats(psDroid)->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + QuickJS_DefinePropertyValue(ctx, value, "body", JS_NewString(ctx, psDroid->getBodyStats()->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + QuickJS_DefinePropertyValue(ctx, value, "propulsion", JS_NewString(ctx, psDroid->getPropulsionStats()->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); QuickJS_DefinePropertyValue(ctx, value, "armed", JS_NewFloat64(ctx, 0.0), JS_PROP_ENUMERABLE); // deprecated! JSValue weaponlist = JS_NewArray(ctx); @@ -1029,7 +1029,7 @@ JSValue convDroid(const DROID *psDroid, JSContext *ctx) { int armed = droidReloadBar(psDroid, &psDroid->asWeaps[j], j); JSValue weapon = JS_NewObject(ctx); - const WEAPON_STATS *psStats = getWeaponStats(psDroid, j); + const WEAPON_STATS *psStats = psDroid->getWeaponStats(j); QuickJS_DefinePropertyValue(ctx, weapon, "fullname", JS_NewString(ctx, psStats->name.toUtf8().c_str()), JS_PROP_ENUMERABLE); QuickJS_DefinePropertyValue(ctx, weapon, "name", JS_NewString(ctx, psStats->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); // will be changed to contain full name QuickJS_DefinePropertyValue(ctx, weapon, "id", JS_NewString(ctx, psStats->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); @@ -1117,17 +1117,17 @@ JSValue convTemplate(const DROID_TEMPLATE *psTempl, JSContext *ctx) QuickJS_DefinePropertyValue(ctx, value, "power", JS_NewUint32(ctx, calcTemplatePower(psTempl)), JS_PROP_ENUMERABLE); // deprecated, use cost below QuickJS_DefinePropertyValue(ctx, value, "cost", JS_NewUint32(ctx, calcTemplatePower(psTempl)), JS_PROP_ENUMERABLE); QuickJS_DefinePropertyValue(ctx, value, "droidType", JS_NewInt32(ctx, psTempl->droidType), JS_PROP_ENUMERABLE); - QuickJS_DefinePropertyValue(ctx, value, "body", JS_NewString(ctx, asBodyStats[psTempl->asParts[COMP_BODY]].id.toUtf8().c_str()), JS_PROP_ENUMERABLE); - QuickJS_DefinePropertyValue(ctx, value, "propulsion", JS_NewString(ctx, asPropulsionStats[psTempl->asParts[COMP_PROPULSION]].id.toUtf8().c_str()), JS_PROP_ENUMERABLE); - QuickJS_DefinePropertyValue(ctx, value, "brain", JS_NewString(ctx, asBrainStats[psTempl->asParts[COMP_BRAIN]].id.toUtf8().c_str()), JS_PROP_ENUMERABLE); - QuickJS_DefinePropertyValue(ctx, value, "repair", JS_NewString(ctx, asRepairStats[psTempl->asParts[COMP_REPAIRUNIT]].id.toUtf8().c_str()), JS_PROP_ENUMERABLE); - QuickJS_DefinePropertyValue(ctx, value, "ecm", JS_NewString(ctx, asECMStats[psTempl->asParts[COMP_ECM]].id.toUtf8().c_str()), JS_PROP_ENUMERABLE); - QuickJS_DefinePropertyValue(ctx, value, "sensor", JS_NewString(ctx, asSensorStats[psTempl->asParts[COMP_SENSOR]].id.toUtf8().c_str()), JS_PROP_ENUMERABLE); - QuickJS_DefinePropertyValue(ctx, value, "construct", JS_NewString(ctx, asConstructStats[psTempl->asParts[COMP_CONSTRUCT]].id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + QuickJS_DefinePropertyValue(ctx, value, "body", JS_NewString(ctx, psTempl->getBodyStats()->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + QuickJS_DefinePropertyValue(ctx, value, "propulsion", JS_NewString(ctx, psTempl->getPropulsionStats()->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + QuickJS_DefinePropertyValue(ctx, value, "brain", JS_NewString(ctx, psTempl->getBrainStats()->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + QuickJS_DefinePropertyValue(ctx, value, "repair", JS_NewString(ctx, psTempl->getRepairStats()->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + QuickJS_DefinePropertyValue(ctx, value, "ecm", JS_NewString(ctx, psTempl->getECMStats()->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + QuickJS_DefinePropertyValue(ctx, value, "sensor", JS_NewString(ctx, psTempl->getSensorStats()->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + QuickJS_DefinePropertyValue(ctx, value, "construct", JS_NewString(ctx, psTempl->getConstructStats()->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); JSValue weaponlist = JS_NewArray(ctx); for (int j = 0; j < psTempl->numWeaps; j++) { - JS_DefinePropertyValueUint32(ctx, weaponlist, j, JS_NewString(ctx, asWeaponStats[psTempl->asWeaps[j]].id.toUtf8().c_str()), JS_PROP_ENUMERABLE); + JS_DefinePropertyValueUint32(ctx, weaponlist, j, JS_NewString(ctx, psTempl->getWeaponStats(j)->id.toUtf8().c_str()), JS_PROP_ENUMERABLE); } QuickJS_DefinePropertyValue(ctx, value, "weapons", weaponlist, JS_PROP_ENUMERABLE); return value; diff --git a/src/selection.cpp b/src/selection.cpp index 4fac5ec05a4..bf1124d92bc 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -94,11 +94,11 @@ static bool selTrue(DROID *droid) } static bool selProp(DROID *droid, PROPULSION_TYPE prop) { - return getPropulsionStats(droid)->propulsionType == prop && !selTransporter(droid); + return droid->getPropulsionStats()->propulsionType == prop && !selTransporter(droid); } static bool selPropArmed(DROID *droid, PROPULSION_TYPE prop) { - return getPropulsionStats(droid)->propulsionType == prop && vtolFull(droid) && !selTransporter(droid); + return droid->getPropulsionStats()->propulsionType == prop && vtolFull(droid) && !selTransporter(droid); } static bool selType(DROID *droid, DROID_TYPE type) { @@ -110,7 +110,7 @@ static bool selCombat(DROID *droid) } static bool selCombatLand(DROID *droid) { - PROPULSION_TYPE type = getPropulsionStats(droid)->propulsionType; + PROPULSION_TYPE type = droid->getPropulsionStats()->propulsionType; return droid->asWeaps[0].nStat > 0 && (type == PROPULSION_TYPE_WHEELED || type == PROPULSION_TYPE_HALF_TRACKED || type == PROPULSION_TYPE_TRACKED || @@ -119,7 +119,7 @@ static bool selCombatLand(DROID *droid) } static bool selCombatCyborg(DROID *droid) { - PROPULSION_TYPE type = getPropulsionStats(droid)->propulsionType; + PROPULSION_TYPE type = droid->getPropulsionStats()->propulsionType; return droid->asWeaps[0].nStat > 0 && type == PROPULSION_TYPE_LEGGED; } static bool selDamaged(DROID *droid) diff --git a/src/stats.cpp b/src/stats.cpp index d8f624ffac1..32eba101284 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -1835,7 +1835,7 @@ bool objRadarDetector(const BASE_OBJECT *psObj) else if (psObj->type == OBJ_DROID) { const DROID *psDroid = (const DROID *)psObj; - SENSOR_STATS *psSensor = getSensorStats(psDroid); + SENSOR_STATS *psSensor = psDroid->getSensorStats(); return (psSensor && psSensor->type == RADAR_DETECTOR_SENSOR); } diff --git a/src/structure.cpp b/src/structure.cpp index 78e2a178e41..e72864a14f7 100644 --- a/src/structure.cpp +++ b/src/structure.cpp @@ -1553,7 +1553,7 @@ STRUCTURE *buildStructureDir(STRUCTURE_STATS *pStructureType, UDWORD x, UDWORD y psBuilding->asWeaps[0].lastFired = gameTime; } psBuilding->asWeaps[weapon].nStat = pStructureType->psWeapStat[weapon] - asWeaponStats.data(); - psBuilding->asWeaps[weapon].ammo = asWeaponStats[psBuilding->asWeaps[weapon].nStat].upgrade[psBuilding->player].numRounds; + psBuilding->asWeaps[weapon].ammo = psBuilding->getWeaponStats(weapon)->upgrade[psBuilding->player].numRounds; psBuilding->numWeaps++; } } @@ -1570,7 +1570,7 @@ STRUCTURE *buildStructureDir(STRUCTURE_STATS *pStructureType, UDWORD x, UDWORD y psBuilding->asWeaps[0].lastFired = gameTime; } psBuilding->asWeaps[0].nStat = pStructureType->psWeapStat[0] - asWeaponStats.data(); - psBuilding->asWeaps[0].ammo = asWeaponStats[psBuilding->asWeaps[0].nStat].upgrade[psBuilding->player].numRounds; + psBuilding->asWeaps[0].ammo = psBuilding->getWeaponStats(0)->upgrade[psBuilding->player].numRounds; } } @@ -2614,7 +2614,7 @@ static bool IsFactoryCommanderGroupFull(const FACTORY *psFactory) } // allow any number of IDF droids - if (templateIsIDF(psFactory->psSubject) || asPropulsionStats[psFactory->psSubject->asParts[COMP_PROPULSION]].propulsionType == PROPULSION_TYPE_LIFT) + if (templateIsIDF(psFactory->psSubject) || psFactory->psSubject->getPropulsionStats()->propulsionType == PROPULSION_TYPE_LIFT) { return false; } @@ -2972,7 +2972,7 @@ static void aiUpdateStructure(STRUCTURE *psStructure, bool isMission) /* Check lassat */ if (isLasSat(psStructure->pStructureType) - && gameTime - psStructure->asWeaps[0].lastFired > weaponFirePause(asWeaponStats[psStructure->asWeaps[0].nStat], psStructure->player) + && gameTime - psStructure->asWeaps[0].lastFired > weaponFirePause(*psStructure->getWeaponStats(0), psStructure->player) && psStructure->asWeaps[0].ammo > 0) { triggerEventStructureReady(psStructure); @@ -2985,9 +2985,9 @@ static void aiUpdateStructure(STRUCTURE *psStructure, bool isMission) //structures always update their targets for (UDWORD i = 0; i < psStructure->numWeaps; i++) { - bDirect = proj_Direct(&asWeaponStats[psStructure->asWeaps[i].nStat]); + bDirect = proj_Direct(psStructure->getWeaponStats(i)); if (psStructure->asWeaps[i].nStat > 0 && - asWeaponStats[psStructure->asWeaps[i].nStat].weaponSubClass != WSC_LAS_SAT) + psStructure->getWeaponStats(i)->weaponSubClass != WSC_LAS_SAT) { if (aiChooseTarget(psStructure, &psChosenObjs[i], i, true, &tmpOrigin)) { @@ -3022,7 +3022,7 @@ static void aiUpdateStructure(STRUCTURE *psStructure, bool isMission) if (psChosenObjs[i] != nullptr && !aiObjectIsProbablyDoomed(psChosenObjs[i], bDirect)) { // get the weapon stat to see if there is a visible turret to rotate - psWStats = &asWeaponStats[psStructure->asWeaps[i].nStat]; + psWStats = psStructure->getWeaponStats(i); //if were going to shoot at something move the turret first then fire when locked on if (psWStats->pMountGraphic == nullptr)//no turret so lock on whatever @@ -3441,7 +3441,7 @@ static void aiUpdateStructure(STRUCTURE *psStructure, bool isMission) { // set rearm value to no runs made psDroid->asWeaps[i].usedAmmo = 0; - psDroid->asWeaps[i].ammo = getWeaponStats(psDroid, i)->upgrade[psDroid->player].numRounds; + psDroid->asWeaps[i].ammo = psDroid->getWeaponStats(i)->upgrade[psDroid->player].numRounds; psDroid->asWeaps[i].lastFired = 0; } objTrace(psDroid->id, "fully loaded"); @@ -3451,7 +3451,7 @@ static void aiUpdateStructure(STRUCTURE *psStructure, bool isMission) for (unsigned i = 0; i < psDroid->numWeaps; i++) // rearm one weapon at a time { // Make sure it's a rearmable weapon (and so we don't divide by zero) - if (psDroid->asWeaps[i].usedAmmo > 0 && getWeaponStats(psDroid, i)->upgrade[psDroid->player].numRounds > 0) + if (psDroid->asWeaps[i].usedAmmo > 0 && psDroid->getWeaponStats(i)->upgrade[psDroid->player].numRounds > 0) { // Do not "simplify" this formula. // It is written this way to prevent rounding errors. @@ -3462,7 +3462,7 @@ static void aiUpdateStructure(STRUCTURE *psStructure, bool isMission) if (ammoToAddThisTime) { // reset ammo and lastFired - psDroid->asWeaps[i].ammo = getWeaponStats(psDroid, i)->upgrade[psDroid->player].numRounds; + psDroid->asWeaps[i].ammo = psDroid->getWeaponStats(i)->upgrade[psDroid->player].numRounds; psDroid->asWeaps[i].lastFired = 0; break; } @@ -4378,7 +4378,7 @@ bool validLocation(BASE_STATS *psStats, Vector2i pos, uint16_t direction, unsign } else if (psTemplate != nullptr) { - PROPULSION_STATS *psPropStats = &asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]]; + PROPULSION_STATS *psPropStats = psTemplate->getPropulsionStats(); if (fpathBlockingTile(b.map.x, b.map.y, psPropStats->propulsionType)) { @@ -5349,7 +5349,7 @@ static unsigned int countAssignedDroids(const STRUCTURE *psStructure) && psCurr->order.psObj->id == psStructure->id && psCurr->player == psStructure->player) { - const MOVEMENT_MODEL weapontype = getWeaponStats(psCurr, 0)->movementModel; + const MOVEMENT_MODEL weapontype = psCurr->getWeaponStats(0)->movementModel; if (weapontype == MM_INDIRECT || weapontype == MM_HOMINGINDIRECT @@ -5523,7 +5523,7 @@ bool validTemplateForFactory(const DROID_TEMPLATE *psTemplate, STRUCTURE *psFact } //check for VTOL droid else if (psTemplate->asParts[COMP_PROPULSION] && - (asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]].propulsionType == PROPULSION_TYPE_LIFT)) + (psTemplate->getPropulsionStats()->propulsionType == PROPULSION_TYPE_LIFT)) { if (psFactory->pStructureType->type != REF_VTOL_FACTORY) { @@ -5549,7 +5549,7 @@ bool validTemplateForFactory(const DROID_TEMPLATE *psTemplate, STRUCTURE *psFact else if (psFactory->pStructureType->type == REF_VTOL_FACTORY) { if (!psTemplate->asParts[COMP_PROPULSION] || - (asPropulsionStats[psTemplate->asParts[COMP_PROPULSION]].propulsionType != PROPULSION_TYPE_LIFT)) + (psTemplate->getPropulsionStats()->propulsionType != PROPULSION_TYPE_LIFT)) { debug(level, "Can only build vtol in vtol factory, not in %s.", objInfo(psFactory)); return false; @@ -6520,7 +6520,7 @@ bool structSensorDroidWeapon(const STRUCTURE *psStruct, const DROID *psDroid) //Added a safety check: Only units with weapons can be assigned. if (psDroid->numWeaps > 0) { - const auto* weaponStats = getWeaponStats(psDroid, 0); + const auto* weaponStats = psDroid->getWeaponStats(0); //Standard Sensor Tower + indirect weapon droid (non VTOL) //else if (structStandardSensor(psStruct) && (psDroid->numWeaps && if (structStandardSensor(psStruct) && (psDroid->asWeaps[0].nStat > 0 && @@ -6974,7 +6974,7 @@ bool lasSatStructSelected(const STRUCTURE *psStruct) { if ((psStruct->selected || (bMultiPlayer && !isHumanPlayer(psStruct->player))) && psStruct->asWeaps[0].nStat - && (asWeaponStats[psStruct->asWeaps[0].nStat].weaponSubClass == WSC_LAS_SAT)) + && (psStruct->getWeaponStats(0)->weaponSubClass == WSC_LAS_SAT)) { return true; } diff --git a/src/template.cpp b/src/template.cpp index ead20666db4..c59d3847c62 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -253,53 +253,53 @@ bool designableTemplate(const DROID_TEMPLATE *psTempl, int player) psTempl->droidType == DROID_CYBORG_REPAIR) { bool repair = ((psTempl->asParts[COMP_REPAIRUNIT] == 0) || - (!designablePart(asRepairStats[psTempl->asParts[COMP_REPAIRUNIT]], "Repair unit") && asRepairStats[psTempl->asParts[COMP_REPAIRUNIT]].usageClass == UsageClass::Cyborg) || + (!designablePart(*psTempl->getRepairStats(), "Repair unit") && psTempl->getRepairStats()->usageClass == UsageClass::Cyborg) || (psTempl->asParts[COMP_REPAIRUNIT] != 0 && selfRepairEnabled(player))); - bool isSuperCyborg = asBodyStats[psTempl->asParts[COMP_BODY]].usageClass == UsageClass::SuperCyborg; + bool isSuperCyborg = psTempl->getBodyStats()->usageClass == UsageClass::SuperCyborg; designable = - !designablePart(asBodyStats[psTempl->asParts[COMP_BODY]], "Body") - && (strcmp(asBodyStats[psTempl->asParts[COMP_BODY]].bodyClass.toStdString().c_str(), "Cyborgs") == 0) - && !designablePart(asPropulsionStats[psTempl->asParts[COMP_PROPULSION]], "Propulsion") - && asPropulsionStats[psTempl->asParts[COMP_PROPULSION]].propulsionType == PROPULSION_TYPE_LEGGED - && asPropulsionStats[psTempl->asParts[COMP_PROPULSION]].usageClass == UsageClass::Cyborg + !designablePart(*psTempl->getBodyStats(), "Body") + && (strcmp(psTempl->getBodyStats()->bodyClass.toStdString().c_str(), "Cyborgs") == 0) + && !designablePart(*psTempl->getPropulsionStats(), "Propulsion") + && psTempl->getPropulsionStats()->propulsionType == PROPULSION_TYPE_LEGGED + && psTempl->getPropulsionStats()->usageClass == UsageClass::Cyborg && repair - && ((psTempl->asParts[COMP_BRAIN] == 0) || (!designablePart(asBrainStats[psTempl->asParts[COMP_BRAIN]], "Brain") && asBrainStats[psTempl->asParts[COMP_BRAIN]].usageClass == UsageClass::Cyborg)) - && ((psTempl->asParts[COMP_ECM] == 0) || (!designablePart(asECMStats[psTempl->asParts[COMP_ECM]], "ECM") && asECMStats[psTempl->asParts[COMP_ECM]].usageClass == UsageClass::Cyborg)) - && ((psTempl->asParts[COMP_SENSOR] == 0) || (!designablePart(asSensorStats[psTempl->asParts[COMP_SENSOR]], "Sensor") && asSensorStats[psTempl->asParts[COMP_SENSOR]].usageClass == UsageClass::Cyborg)) - && ((psTempl->asParts[COMP_CONSTRUCT] == 0) || (!designablePart(asConstructStats[psTempl->asParts[COMP_CONSTRUCT]], "Construction part") && asConstructStats[psTempl->asParts[COMP_CONSTRUCT]].usageClass == UsageClass::Cyborg)) - && ((psTempl->numWeaps <= 0) || (asBrainStats[psTempl->asParts[COMP_BRAIN]].psWeaponStat == &asWeaponStats[psTempl->asWeaps[0]]) - || (!designablePart(asWeaponStats[psTempl->asWeaps[0]], "Weapon 0") && ((!isSuperCyborg && asWeaponStats[psTempl->asWeaps[0]].usageClass == UsageClass::Cyborg) || (isSuperCyborg && asWeaponStats[psTempl->asWeaps[0]].usageClass == UsageClass::SuperCyborg)))) - && ((psTempl->numWeaps <= 1) || (!designablePart(asWeaponStats[psTempl->asWeaps[1]], "Weapon 1") && ((!isSuperCyborg && asWeaponStats[psTempl->asWeaps[1]].usageClass == UsageClass::Cyborg) || (isSuperCyborg && asWeaponStats[psTempl->asWeaps[1]].usageClass == UsageClass::SuperCyborg)))) - && ((psTempl->numWeaps <= 2) || (!designablePart(asWeaponStats[psTempl->asWeaps[2]], "Weapon 2") && ((!isSuperCyborg && asWeaponStats[psTempl->asWeaps[2]].usageClass == UsageClass::Cyborg) || (isSuperCyborg && asWeaponStats[psTempl->asWeaps[2]].usageClass == UsageClass::SuperCyborg)))); + && ((psTempl->asParts[COMP_BRAIN] == 0) || (!designablePart(*psTempl->getBrainStats(), "Brain") && psTempl->getBrainStats()->usageClass == UsageClass::Cyborg)) + && ((psTempl->asParts[COMP_ECM] == 0) || (!designablePart(*psTempl->getECMStats(), "ECM") && psTempl->getECMStats()->usageClass == UsageClass::Cyborg)) + && ((psTempl->asParts[COMP_SENSOR] == 0) || (!designablePart(*psTempl->getSensorStats(), "Sensor") && psTempl->getSensorStats()->usageClass == UsageClass::Cyborg)) + && ((psTempl->asParts[COMP_CONSTRUCT] == 0) || (!designablePart(*psTempl->getConstructStats(), "Construction part") && psTempl->getConstructStats()->usageClass == UsageClass::Cyborg)) + && ((psTempl->numWeaps <= 0) || (psTempl->getBrainStats()->psWeaponStat == psTempl->getWeaponStats(0)) + || (!designablePart(*psTempl->getWeaponStats(0), "Weapon 0") && ((!isSuperCyborg && psTempl->getWeaponStats(0)->usageClass == UsageClass::Cyborg) || (isSuperCyborg && psTempl->getWeaponStats(0)->usageClass == UsageClass::SuperCyborg)))) + && ((psTempl->numWeaps <= 1) || (!designablePart(*psTempl->getWeaponStats(1), "Weapon 1") && ((!isSuperCyborg && psTempl->getWeaponStats(1)->usageClass == UsageClass::Cyborg) || (isSuperCyborg && psTempl->getWeaponStats(1)->usageClass == UsageClass::SuperCyborg)))) + && ((psTempl->numWeaps <= 2) || (!designablePart(*psTempl->getWeaponStats(2), "Weapon 2") && ((!isSuperCyborg && psTempl->getWeaponStats(2)->usageClass == UsageClass::Cyborg) || (isSuperCyborg && psTempl->getWeaponStats(2)->usageClass == UsageClass::SuperCyborg)))); } else { bool repair = ((psTempl->asParts[COMP_REPAIRUNIT] == 0) || - designablePart(asRepairStats[psTempl->asParts[COMP_REPAIRUNIT]], "Repair unit") || + designablePart(*psTempl->getRepairStats(), "Repair unit") || (psTempl->asParts[COMP_REPAIRUNIT] != 0 && selfRepairEnabled(player))); bool transporter = (psTempl->droidType == DROID_TRANSPORTER) || (psTempl->droidType == DROID_SUPERTRANSPORTER); designable = - (transporter || (!transporter && designablePart(asBodyStats[psTempl->asParts[COMP_BODY]], "Body"))) - && designablePart(asPropulsionStats[psTempl->asParts[COMP_PROPULSION]], "Propulsion") - && (psTempl->asParts[COMP_BRAIN] == 0 || designablePart(asBrainStats [psTempl->asParts[COMP_BRAIN]], "Brain")) + (transporter || (!transporter && designablePart(*psTempl->getBodyStats(), "Body"))) + && designablePart(*psTempl->getPropulsionStats(), "Propulsion") + && (psTempl->asParts[COMP_BRAIN] == 0 || designablePart(*psTempl->getBrainStats(), "Brain")) && repair - && (psTempl->asParts[COMP_ECM] == 0 || designablePart(asECMStats [psTempl->asParts[COMP_ECM]], "ECM")) - && (psTempl->asParts[COMP_SENSOR] == 0 || designablePart(asSensorStats [psTempl->asParts[COMP_SENSOR]], "Sensor")) - && (psTempl->asParts[COMP_CONSTRUCT] == 0 || designablePart(asConstructStats[psTempl->asParts[COMP_CONSTRUCT]], "Construction part")) - && (psTempl->numWeaps <= 0 || asBrainStats[psTempl->asParts[COMP_BRAIN]].psWeaponStat == &asWeaponStats[psTempl->asWeaps[0]] - || designablePart(asWeaponStats[psTempl->asWeaps[0]], "Weapon 0")) - && (psTempl->numWeaps <= 1 || designablePart(asWeaponStats[psTempl->asWeaps[1]], "Weapon 1")) - && (psTempl->numWeaps <= 2 || designablePart(asWeaponStats[psTempl->asWeaps[2]], "Weapon 2")); + && (psTempl->asParts[COMP_ECM] == 0 || designablePart(*psTempl->getECMStats(), "ECM")) + && (psTempl->asParts[COMP_SENSOR] == 0 || designablePart(*psTempl->getSensorStats(), "Sensor")) + && (psTempl->asParts[COMP_CONSTRUCT] == 0 || designablePart(*psTempl->getConstructStats(), "Construction part")) + && (psTempl->numWeaps <= 0 || psTempl->getBrainStats()->psWeaponStat == psTempl->getWeaponStats(0) + || designablePart(*psTempl->getWeaponStats(0), "Weapon 0")) + && (psTempl->numWeaps <= 1 || designablePart(*psTempl->getWeaponStats(1), "Weapon 1")) + && (psTempl->numWeaps <= 2 || designablePart(*psTempl->getWeaponStats(2), "Weapon 2")); if (transporter && designable) { - designable = (asPropulsionStats[psTempl->asParts[COMP_PROPULSION]].propulsionType == PROPULSION_TYPE_LIFT) && - !designablePart(asBodyStats[psTempl->asParts[COMP_BODY]], "Body"); + designable = (psTempl->getPropulsionStats()->propulsionType == PROPULSION_TYPE_LIFT) && + !designablePart(*psTempl->getBodyStats(), "Body"); if (designable) { - designable = strcmp(asBodyStats[psTempl->asParts[COMP_BODY]].bodyClass.toStdString().c_str(), "Transports") == 0; + designable = strcmp(psTempl->getBodyStats()->bodyClass.toStdString().c_str(), "Transports") == 0; } } } @@ -405,39 +405,39 @@ nlohmann::json saveTemplateCommon(const DROID_TEMPLATE *psCurr) default: ASSERT(false, "No such droid type \"%d\" for %s", psCurr->droidType, psCurr->name.toUtf8().c_str()); } ASSERT(psCurr->asParts[COMP_BODY] < asBodyStats.size(), "asParts[COMP_BODY] (%d) exceeds numBodyStats (%zu)", (int)psCurr->asParts[COMP_BODY], asBodyStats.size()); - templateObj["body"] = asBodyStats[psCurr->asParts[COMP_BODY]].id; + templateObj["body"] = psCurr->getBodyStats()->id; ASSERT(psCurr->asParts[COMP_PROPULSION] < asPropulsionStats.size(), "asParts[COMP_PROPULSION] (%d) exceeds numPropulsionStats (%zu)", (int)psCurr->asParts[COMP_PROPULSION], asPropulsionStats.size()); - templateObj["propulsion"] = asPropulsionStats[psCurr->asParts[COMP_PROPULSION]].id; + templateObj["propulsion"] = psCurr->getPropulsionStats()->id; if (psCurr->asParts[COMP_BRAIN] != 0) { ASSERT(psCurr->asParts[COMP_BRAIN] < asBrainStats.size(), "asParts[COMP_BRAIN] (%d) exceeds numBrainStats (%zu)", (int)psCurr->asParts[COMP_BRAIN], asBrainStats.size()); - templateObj["brain"] = asBrainStats[psCurr->asParts[COMP_BRAIN]].id; + templateObj["brain"] = psCurr->getBrainStats()->id; } - if (asRepairStats[psCurr->asParts[COMP_REPAIRUNIT]].location == LOC_TURRET) // avoid auto-repair... + if (psCurr->getRepairStats()->location == LOC_TURRET) // avoid auto-repair... { ASSERT(psCurr->asParts[COMP_REPAIRUNIT] < asRepairStats.size(), "asParts[COMP_REPAIRUNIT] (%d) exceeds numRepairStats (%zu)", (int)psCurr->asParts[COMP_REPAIRUNIT], asRepairStats.size()); - templateObj["repair"] = asRepairStats[psCurr->asParts[COMP_REPAIRUNIT]].id; + templateObj["repair"] = psCurr->getRepairStats()->id; } - if (asECMStats[psCurr->asParts[COMP_ECM]].location == LOC_TURRET) + if (psCurr->getECMStats()->location == LOC_TURRET) { ASSERT(psCurr->asParts[COMP_ECM] < asECMStats.size(), "asParts[COMP_ECM] (%d) exceeds numECMStats (%zu)", (int)psCurr->asParts[COMP_ECM], asECMStats.size()); - templateObj["ecm"] = asECMStats[psCurr->asParts[COMP_ECM]].id; + templateObj["ecm"] = psCurr->getECMStats()->id; } - if (asSensorStats[psCurr->asParts[COMP_SENSOR]].location == LOC_TURRET) + if (psCurr->getSensorStats()->location == LOC_TURRET) { ASSERT(psCurr->asParts[COMP_SENSOR] < asSensorStats.size(), "asParts[COMP_SENSOR] (%d) exceeds numSensorStats (%zu)", (int)psCurr->asParts[COMP_SENSOR], asSensorStats.size()); - templateObj["sensor"] = asSensorStats[psCurr->asParts[COMP_SENSOR]].id; + templateObj["sensor"] = psCurr->getSensorStats()->id; } if (psCurr->asParts[COMP_CONSTRUCT] != 0) { ASSERT(psCurr->asParts[COMP_CONSTRUCT] < asConstructStats.size(), "asParts[COMP_CONSTRUCT] (%d) exceeds numConstructStats (%zu)", (int)psCurr->asParts[COMP_CONSTRUCT], asConstructStats.size()); - templateObj["construct"] = asConstructStats[psCurr->asParts[COMP_CONSTRUCT]].id; + templateObj["construct"] = psCurr->getConstructStats()->id; } nlohmann::json weapons = nlohmann::json::array(); for (int j = 0; j < psCurr->numWeaps; j++) { ASSERT(psCurr->asWeaps[j] < asWeaponStats.size(), "psCurr->asWeaps[%d] (%d) exceeds numWeaponStats (%zu)", j, (int)psCurr->asWeaps[j], asWeaponStats.size()); - weapons.push_back(asWeaponStats[psCurr->asWeaps[j]].id); + weapons.push_back(psCurr->getWeaponStats(j)->id); } if (!weapons.empty()) { @@ -492,6 +492,46 @@ DROID_TEMPLATE::DROID_TEMPLATE() // This constructor replaces a memset in scrAs std::fill_n(asWeaps, MAX_WEAPONS, 0); } +BODY_STATS* DROID_TEMPLATE::getBodyStats() const +{ + return &asBodyStats[asParts[COMP_BODY]]; +} + +BRAIN_STATS* DROID_TEMPLATE::getBrainStats() const +{ + return &asBrainStats[asParts[COMP_BRAIN]]; +} + +PROPULSION_STATS* DROID_TEMPLATE::getPropulsionStats() const +{ + return &asPropulsionStats[asParts[COMP_PROPULSION]]; +} + +SENSOR_STATS* DROID_TEMPLATE::getSensorStats() const +{ + return &asSensorStats[asParts[COMP_SENSOR]]; +} + +ECM_STATS* DROID_TEMPLATE::getECMStats() const +{ + return &asECMStats[asParts[COMP_ECM]]; +} + +REPAIR_STATS* DROID_TEMPLATE::getRepairStats() const +{ + return &asRepairStats[asParts[COMP_REPAIRUNIT]]; +} + +CONSTRUCT_STATS* DROID_TEMPLATE::getConstructStats() const +{ + return &asConstructStats[asParts[COMP_CONSTRUCT]]; +} + +WEAPON_STATS* DROID_TEMPLATE::getWeaponStats(int weaponSlot) const +{ + return &asWeaponStats[asWeaps[weaponSlot]]; +} + bool loadDroidTemplates(const char *filename) { WzConfig ini(filename, WzConfig::ReadOnlyAndRequired); @@ -743,7 +783,7 @@ bool templateIsIDF(const DROID_TEMPLATE *psTemplate) return false; } - if (proj_Direct(&asWeaponStats[psTemplate->asWeaps[0]])) + if (proj_Direct(psTemplate->getWeaponStats(0))) { return false; } @@ -799,14 +839,14 @@ std::vector fillTemplateList(STRUCTURE *psFactory) } //check the factory can cope with this sized body - if (asBodyStats[psCurr->asParts[COMP_BODY]].size <= iCapacity) + if (psCurr->getBodyStats()->size <= iCapacity) { pList.push_back(psCurr); } else if (bMultiPlayer && (iCapacity == SIZE_HEAVY)) { // Special case for Super heavy bodyies (Super Transporter) - if (asBodyStats[psCurr->asParts[COMP_BODY]].size == SIZE_SUPER_HEAVY) + if (psCurr->getBodyStats()->size == SIZE_SUPER_HEAVY) { pList.push_back(psCurr); } diff --git a/src/transporter.cpp b/src/transporter.cpp index 23703a6d48f..85dd3fca08a 100644 --- a/src/transporter.cpp +++ b/src/transporter.cpp @@ -1121,7 +1121,7 @@ int transporterSpaceRequired(const DROID *psDroid) { // all droids are the same weight for campaign games. // TODO - move this into a droid flag - return bMultiPlayer ? getBodyStats(psDroid)->size + 1 : 1; + return bMultiPlayer ? psDroid->getBodyStats()->size + 1 : 1; } /*sets which list of droids to use for the transporter interface*/ diff --git a/src/visibility.cpp b/src/visibility.cpp index bf339682204..0ab0dbe0a07 100644 --- a/src/visibility.cpp +++ b/src/visibility.cpp @@ -526,7 +526,7 @@ int visibleObject(const BASE_OBJECT *psViewer, const BASE_OBJECT *psTarget, bool } if (psTarget->type == OBJ_DROID && ((const DROID*)psTarget)->isVtol() - && asWeaponStats[psStruct->asWeaps[0].nStat].surfaceToAir == SHOOT_IN_AIR) + && psStruct->getWeaponStats(0)->surfaceToAir == SHOOT_IN_AIR) { range = 3 * range / 2; // increase vision range of AA vs VTOL } @@ -960,11 +960,11 @@ bool lineOfFire(const SIMPLE_OBJECT *psViewer, const BASE_OBJECT *psTarget, int if (psViewer->type == OBJ_DROID) { - psStats = getWeaponStats((const DROID*)psViewer, weapon_slot); + psStats = ((const DROID*)psViewer)->getWeaponStats(weapon_slot); } else if (psViewer->type == OBJ_STRUCTURE) { - psStats = &asWeaponStats[((const STRUCTURE *)psViewer)->asWeaps[weapon_slot].nStat]; + psStats = ((const STRUCTURE*)psViewer)->getWeaponStats(weapon_slot); } // 2d distance int distance = iHypot((psTarget->pos - psViewer->pos).xy()); diff --git a/src/visibility.h b/src/visibility.h index 19e1de94808..e17f2462947 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -81,12 +81,12 @@ inline int objSensorRange(const BASE_OBJECT *psObj) { if (psObj->type == OBJ_DROID) { - const int ecmrange = getECMStats((const DROID*)psObj)->upgrade[psObj->player].range; + const int ecmrange = ((const DROID*)psObj)->getECMStats()->upgrade[psObj->player].range; if (ecmrange > 0) { return ecmrange; } - return getSensorStats((const DROID*)psObj)->upgrade[psObj->player].range; + return ((const DROID*)psObj)->getSensorStats()->upgrade[psObj->player].range; } else if (psObj->type == OBJ_STRUCTURE) { @@ -104,7 +104,7 @@ static inline int objJammerPower(const BASE_OBJECT *psObj) { if (psObj->type == OBJ_DROID) { - return getECMStats((const DROID *)psObj)->upgrade[psObj->player].range; + return ((const DROID*)psObj)->getECMStats()->upgrade[psObj->player].range; } else if (psObj->type == OBJ_STRUCTURE) { diff --git a/src/warcam.cpp b/src/warcam.cpp index bb54a9350cd..67227af48fb 100644 --- a/src/warcam.cpp +++ b/src/warcam.cpp @@ -563,7 +563,7 @@ static void updateCameraAcceleration(UBYTE update) */ const int angle = 90 - abs((playerPos.r.x / 182) % 90); - const PROPULSION_STATS *psPropStats = getPropulsionStats(trackingCamera.target); + const PROPULSION_STATS *psPropStats = trackingCamera.target->getPropulsionStats(); if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT) { @@ -675,7 +675,7 @@ static void updateCameraRotationAcceleration(UBYTE update) SDWORD xPos = 0, yPos = 0, zPos = 0; bTooLow = false; - psPropStats = getPropulsionStats(trackingCamera.target); + psPropStats = trackingCamera.target->getPropulsionStats(); if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT) { int droidHeight, difHeight, droidMapHeight; @@ -838,7 +838,7 @@ static bool camTrackCamera() /* Update the acceleration,velocity and rotation of the camera for rotation */ /* You can track roll as well (z axis) but it makes you ill and looks like a flight sim, so for now just pitch and orientation */ - psPropStats = getPropulsionStats(trackingCamera.target); + psPropStats = trackingCamera.target->getPropulsionStats(); if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT) { bFlying = true; diff --git a/src/wzapi.cpp b/src/wzapi.cpp index 5e459286f57..f15ab9bbd14 100644 --- a/src/wzapi.cpp +++ b/src/wzapi.cpp @@ -1577,7 +1577,7 @@ optional wzapi::pickStructLocation(WZAPI_PARAMS(const DROID *psDro Vector2i offset(psStat->baseWidth * (TILE_UNITS / 2), psStat->baseBreadth * (TILE_UNITS / 2)); - PROPULSION_TYPE propType = (psDroid) ? getPropulsionStats(psDroid)->propulsionType : PROPULSION_TYPE_WHEELED; + PROPULSION_TYPE propType = (psDroid) ? psDroid->getPropulsionStats()->propulsionType : PROPULSION_TYPE_WHEELED; // save a lot of typing... checks whether a position is valid #define LOC_OK(_x, _y) (tileOnMap(_x, _y) && \ @@ -1651,7 +1651,7 @@ optional wzapi::pickStructLocation(WZAPI_PARAMS(const DROID *psDro bool wzapi::droidCanReach(WZAPI_PARAMS(const DROID *psDroid, int x, int y)) { SCRIPT_ASSERT(false, context, psDroid, "No valid droid provided"); - const PROPULSION_STATS* psPropStats = getPropulsionStats(psDroid); + const PROPULSION_STATS* psPropStats = psDroid->getPropulsionStats(); return fpathCheck(psDroid->pos, Vector3i(world_coord(x), world_coord(y), 0), psPropStats->propulsionType); } diff --git a/src/wzscriptdebug.cpp b/src/wzscriptdebug.cpp index 740b82d1888..683906dd165 100644 --- a/src/wzscriptdebug.cpp +++ b/src/wzscriptdebug.cpp @@ -2694,13 +2694,13 @@ void WZScriptDebugger::selected(const BASE_OBJECT *psObj) selectedObjectDetails["Move pause time"] = psDroid->sMove.pauseTime; selectedObjectDetails["Move shuffle start"] = psDroid->sMove.shuffleStart; selectedObjectDetails["Move vert speed"] = psDroid->sMove.iVertSpeed; - selectedObjectDetails["Body"] = componentToString(getBodyStats(psDroid), psObj->player); - selectedObjectDetails["Brain"] = componentToString(getBrainStats(psDroid), psObj->player); - selectedObjectDetails["Propulsion"] = componentToString(getPropulsionStats(psDroid), psObj->player); - selectedObjectDetails["ECM"] = componentToString(getECMStats(psDroid), psObj->player); - selectedObjectDetails["Sensor"] = componentToString(getSensorStats(psDroid), psObj->player); - selectedObjectDetails["Construct"] = componentToString(getConstructStats(psDroid), psObj->player); - selectedObjectDetails["Repair"] = componentToString(getRepairStats(psDroid), psObj->player); + selectedObjectDetails["Body"] = componentToString(psDroid->getBodyStats(), psObj->player); + selectedObjectDetails["Brain"] = componentToString(psDroid->getBrainStats(), psObj->player); + selectedObjectDetails["Propulsion"] = componentToString(psDroid->getPropulsionStats(), psObj->player); + selectedObjectDetails["ECM"] = componentToString(psDroid->getECMStats(), psObj->player); + selectedObjectDetails["Sensor"] = componentToString(psDroid->getSensorStats(), psObj->player); + selectedObjectDetails["Construct"] = componentToString(psDroid->getConstructStats(), psObj->player); + selectedObjectDetails["Repair"] = componentToString(psDroid->getRepairStats(), psObj->player); } else if (psObj->type == OBJ_STRUCTURE) {