Permalink
Browse files

Merge branch 'bugfixes' into 3.1

  • Loading branch information...
2 parents efb9ebc + 8c83693 commit 68b1103c7caf02c3c3dc4c1f96fd391aa2feadb1 automerge committed with cybersphinx Sep 24, 2012
Showing with 62 additions and 137 deletions.
  1. +15 −20 src/action.cpp
  2. +0 −6 src/ai.cpp
  3. +43 −90 src/droid.cpp
  4. +0 −3 src/droid.h
  5. +3 −17 src/structure.cpp
  6. +1 −1 src/structure.h
View
@@ -363,12 +363,10 @@ bool actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, WEAPON *
WEAPON_STATS *psWeapStats = asWeaponStats + psWeapon->nStat;
uint16_t tRotation, tPitch;
int32_t rotRate, pitchRate;
- uint16_t targetRotation, targetPitch;
- int32_t pitchError;
- int32_t rotationError, dx, dy, dz;
+ uint16_t targetRotation;
+ int32_t rotationError;
int32_t rotationTolerance = 0;
bool onTarget;
- int32_t dxy;
int32_t pitchLowerLimit, pitchUpperLimit;
bool bRepair;
@@ -397,14 +395,20 @@ bool actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, WEAPON *
//set the pitch limits based on the weapon stats of the attacker
pitchLowerLimit = pitchUpperLimit = 0;
+ Vector3i attackerMuzzlePos = psAttacker->pos; // Using for calculating the pitch, but not the direction, in case using the exact direction causes bugs somewhere.
if (psAttacker->type == OBJ_STRUCTURE)
{
+ STRUCTURE *psStructure = (STRUCTURE *)psAttacker;
+ int weapon_slot = psWeapon - psStructure->asWeaps; // Should probably be passed weapon_slot instead of psWeapon.
+ calcStructureMuzzleLocation(psStructure, &attackerMuzzlePos, weapon_slot);
pitchLowerLimit = DEG(psWeapStats->minElevation);
pitchUpperLimit = DEG(psWeapStats->maxElevation);
}
else if (psAttacker->type == OBJ_DROID)
{
DROID *psDroid = (DROID *)psAttacker;
+ int weapon_slot = psWeapon - psDroid->asWeaps; // Should probably be passed weapon_slot instead of psWeapon.
+ calcDroidMuzzleLocation(psDroid, &attackerMuzzlePos, weapon_slot);
if (psDroid->droidType == DROID_WEAPON || psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_SUPERTRANSPORTER
|| psDroid->droidType == DROID_COMMAND || psDroid->droidType == DROID_CYBORG
@@ -447,20 +451,17 @@ bool actionTargetTurret(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, WEAPON *
onTarget = abs(angleDelta(targetRotation - (tRotation + psAttacker->rot.direction))) <= rotationTolerance;
/* set muzzle pitch if direct fire */
- if (!bRepair && (proj_Direct(psWeapStats) || ((psAttacker->type == OBJ_DROID)
- && !proj_Direct(psWeapStats)
- && actionInsideMinRange((DROID *)psAttacker, psTarget, psWeapStats))))
+ if (!bRepair && (proj_Direct(psWeapStats)
+ || (psAttacker->type == OBJ_DROID && !proj_Direct(psWeapStats)
+ && actionInsideMinRange((DROID *)psAttacker, psTarget, psWeapStats))))
{
- dx = psTarget->pos.x - psAttacker->pos.x;
- dy = psTarget->pos.y - psAttacker->pos.y;
- dz = psTarget->pos.z - psAttacker->pos.z;
-
/* get target distance */
- dxy = iHypot(dx, dy);
+ Vector3i delta = psTarget->pos - attackerMuzzlePos;
+ int32_t dxy = iHypot(delta.x, delta.y);
- targetPitch = iAtan2(dz, dxy);
+ uint16_t targetPitch = iAtan2(delta.z, dxy);
targetPitch = (uint16_t)clip(angleDelta(targetPitch), pitchLowerLimit, pitchUpperLimit); // Cast wrapping intended.
- pitchError = angleDelta(targetPitch - tPitch);
+ int pitchError = angleDelta(targetPitch - tPitch);
tPitch += clip(pitchError, -pitchRate, pitchRate); // Addition wrapping intended.
onTarget = onTarget && targetPitch == tPitch;
@@ -867,12 +868,6 @@ void actionUpdateDroid(DROID *psDroid)
}
}
}
- // Still not doing anything? See if we need to self repair.
- if ((psDroid->action == DACTION_NONE || psDroid->action == DACTION_WAITFORREPAIR)
- && selfRepairEnabled(psDroid->player))
- {
- droidSelfRepair(psDroid);
- }
break;
case DACTION_WAITDURINGREPAIR:
// Check that repair facility still exists
View
@@ -1054,12 +1054,6 @@ void aiUpdateDroid(DROID *psDroid)
{
lookForTarget = false;
}
- // except when self-repairing
- if (psDroid->action == DACTION_DROIDREPAIR &&
- psDroid->psActionTarget[0] == (BASE_OBJECT *)psDroid)
- {
- lookForTarget = true;
- }
// don't look for a target if sulking
if (psDroid->action == DACTION_SULK)
{
View
@@ -104,9 +104,11 @@ extern DROID_TEMPLATE sDefaultDesignTemplate;
DROID *psLastDroidHit;
//determines the best IMD to draw for the droid - A TEMP MEASURE!
-void groupConsoleInformOfSelection( UDWORD groupNumber );
-void groupConsoleInformOfCreation( UDWORD groupNumber );
-void groupConsoleInformOfCentering( UDWORD groupNumber );
+static void groupConsoleInformOfSelection(UDWORD groupNumber);
+static void groupConsoleInformOfCreation(UDWORD groupNumber);
+static void groupConsoleInformOfCentering(UDWORD groupNumber);
+
+static void droidUpdateDroidSelfRepair(DROID *psRepairDroid);
void cancelBuild(DROID *psDroid)
{
@@ -826,6 +828,12 @@ void droidUpdate(DROID *psDroid)
}
// -----------------
+ // See if we can and need to self repair.
+ if (!isVtolDroid(psDroid) && psDroid->body < psDroid->originalBody && psDroid->asBits[COMP_REPAIRUNIT].nStat != 0 && selfRepairEnabled(psDroid->player))
+ {
+ droidUpdateDroidSelfRepair(psDroid);
+ }
+
/* Update the fire damage data */
if (psDroid->burnStart != 0 && psDroid->burnStart != gameTime - deltaGameTime) // -deltaGameTime, since projectiles are updated after droids.
{
@@ -1122,27 +1130,16 @@ bool droidStartDemolishing( DROID *psDroid )
bool droidUpdateDemolishing( DROID *psDroid )
{
- STRUCTURE *psStruct;
- UDWORD pointsToAdd, constructPoints;
-
CHECK_DROID(psDroid);
ASSERT_OR_RETURN(false, psDroid->action == DACTION_DEMOLISH, "unit is not demolishing");
- psStruct = (STRUCTURE *)psDroid->order.psObj;
+ STRUCTURE *psStruct = (STRUCTURE *)psDroid->order.psObj;
ASSERT_OR_RETURN(false, psStruct->type == OBJ_STRUCTURE, "target is not a structure");
- //constructPoints = (asConstructStats + psDroid->asBits[COMP_CONSTRUCT].nStat)->
- // constructPoints;
- constructPoints = 5 * constructorPoints(asConstructStats + psDroid->
- asBits[COMP_CONSTRUCT].nStat, psDroid->player);
-
- pointsToAdd = constructPoints * (gameTime - psDroid->actionStarted) /
- GAME_TICKS_PER_SEC;
+ int constructRate = 5 * constructorPoints(asConstructStats + psDroid->asBits[COMP_CONSTRUCT].nStat, psDroid->player);
+ int pointsToAdd = gameTimeAdjustedAverage(constructRate);
- structureDemolish(psStruct, psDroid, pointsToAdd - psDroid->actionPoints);
-
- //store the amount just subtracted
- psDroid->actionPoints = pointsToAdd;
+ structureDemolish(psStruct, psDroid, pointsToAdd);
addConstructorEffect(psStruct);
@@ -1187,29 +1184,6 @@ bool droidStartDroidRepair( DROID *psDroid )
return true;
}
-/*checks a droids current body points to see if need to self repair*/
-void droidSelfRepair(DROID *psDroid)
-{
- CHECK_DROID(psDroid);
-
- if (!isVtolDroid(psDroid))
- {
- if (psDroid->body < psDroid->originalBody)
- {
- if (psDroid->asBits[COMP_REPAIRUNIT].nStat != 0)
- {
- psDroid->action = DACTION_DROIDREPAIR;
- setDroidActionTarget(psDroid, (BASE_OBJECT *)psDroid, 0);
- psDroid->actionStarted = gameTime;
- psDroid->actionPoints = 0;
- }
- }
- }
-
- CHECK_DROID(psDroid);
-}
-
-
/*Start a EW weapon droid working on a low resistance structure*/
bool droidStartRestore( DROID *psDroid )
{
@@ -1301,27 +1275,16 @@ int getRecoil(WEAPON const &weapon)
bool droidUpdateRepair( DROID *psDroid )
{
- STRUCTURE *psStruct;
- UDWORD iPointsToAdd, iRepairPoints;
-
CHECK_DROID(psDroid);
ASSERT_OR_RETURN(false, psDroid->action == DACTION_REPAIR, "unit does not have repair order");
- psStruct = (STRUCTURE *)psDroid->psActionTarget[0];
+ STRUCTURE *psStruct = (STRUCTURE *)psDroid->psActionTarget[0];
ASSERT_OR_RETURN(false, psStruct->type == OBJ_STRUCTURE, "target is not a structure");
- iRepairPoints = constructorPoints(asConstructStats + psDroid->asBits[COMP_CONSTRUCT].nStat, psDroid->player);
- iPointsToAdd = iRepairPoints * (gameTime - psDroid->actionStarted) / GAME_TICKS_PER_SEC;
+ int iRepairRate = constructorPoints(asConstructStats + psDroid->asBits[COMP_CONSTRUCT].nStat, psDroid->player);
/* add points to structure */
- if (iPointsToAdd - psDroid->actionPoints > 0)
- {
- if (structureRepair(psStruct, psDroid, iPointsToAdd - psDroid->actionPoints))
- {
- /* store the amount just added */
- psDroid->actionPoints = iPointsToAdd;
- }
- }
+ structureRepair(psStruct, psDroid, iRepairRate);
/* if not finished repair return true else complete repair and return false */
if (psStruct->body < structureBody(psStruct))
@@ -1330,60 +1293,34 @@ bool droidUpdateRepair( DROID *psDroid )
}
else
{
- objTrace(psDroid->id, "Repaired of %s all done with %u - %u points", objInfo((BASE_OBJECT *)psStruct), iPointsToAdd, psDroid->actionPoints);
- psStruct->body = (UWORD)structureBody(psStruct);
+ objTrace(psDroid->id, "Repaired of %s all done with %u", objInfo(psStruct), iRepairRate);
return false;
}
}
/*Updates a Repair Droid working on a damaged droid*/
-bool droidUpdateDroidRepair(DROID *psRepairDroid)
+static bool droidUpdateDroidRepairBase(DROID *psRepairDroid, DROID *psDroidToRepair)
{
- DROID *psDroidToRepair;
- UDWORD iPointsToAdd, iRepairPoints;
- Vector3i iVecEffect;
-
CHECK_DROID(psRepairDroid);
- ASSERT_OR_RETURN(false, psRepairDroid->action == DACTION_DROIDREPAIR, "Unit does not have unit repair order");
- ASSERT_OR_RETURN(false, psRepairDroid->asBits[COMP_REPAIRUNIT].nStat != 0, "Unit does not have a repair turret");
-
- psDroidToRepair = (DROID *)psRepairDroid->psActionTarget[0];
- ASSERT_OR_RETURN(false, psDroidToRepair->type == OBJ_DROID, "Target is not a unit");
-
- iRepairPoints = repairPoints(asRepairStats + psRepairDroid->
- asBits[COMP_REPAIRUNIT].nStat, psRepairDroid->player);
+ int iRepairRateNumerator = repairPoints(asRepairStats + psRepairDroid->asBits[COMP_REPAIRUNIT].nStat, psRepairDroid->player);
+ int iRepairRateDenominator = 1;
//if self repair then add repair points depending on the time delay for the stat
if (psRepairDroid == psDroidToRepair)
{
- iPointsToAdd = iRepairPoints * (gameTime - psRepairDroid->actionStarted) /
- (asRepairStats + psRepairDroid->asBits[COMP_REPAIRUNIT].nStat)->time;
- }
- else
- {
- iPointsToAdd = iRepairPoints * (gameTime - psRepairDroid->actionStarted) /
- GAME_TICKS_PER_SEC;
+ iRepairRateNumerator *= GAME_TICKS_PER_SEC;
+ iRepairRateDenominator *= (asRepairStats + psRepairDroid->asBits[COMP_REPAIRUNIT].nStat)->time;
}
- iPointsToAdd -= psRepairDroid->actionPoints;
+ int iPointsToAdd = gameTimeAdjustedAverage(iRepairRateNumerator, iRepairRateDenominator);
- //just add the points if the power cost is negligable
- //if these points would make the droid healthy again then just add
- if (psDroidToRepair->body + iPointsToAdd >= psDroidToRepair->originalBody)
- {
- //anothe HACK but sorts out all the rounding errors when values get small
- iPointsToAdd = psDroidToRepair->originalBody - psDroidToRepair->body;
- }
- psDroidToRepair->body += iPointsToAdd;
- psRepairDroid->actionPoints += iPointsToAdd;
+ psDroidToRepair->body = clip(psDroidToRepair->body + iPointsToAdd, 0, psDroidToRepair->originalBody);
/* add plasma repair effect whilst being repaired */
if ((ONEINFIVE) && (psDroidToRepair->visible[selectedPlayer]))
{
- iVecEffect.x = psDroidToRepair->pos.x + DROID_REPAIR_SPREAD;
- iVecEffect.y = psDroidToRepair->pos.z + rand()%8;;
- iVecEffect.z = psDroidToRepair->pos.y + DROID_REPAIR_SPREAD;
+ Vector3i iVecEffect = swapYZ(psDroidToRepair->pos + Vector3i(DROID_REPAIR_SPREAD, DROID_REPAIR_SPREAD, rand()%8));
effectGiveAuxVar(90+rand()%20);
addEffect(&iVecEffect, EFFECT_EXPLOSION, EXPLOSION_TYPE_LASER, false, NULL, 0, gameTime - deltaGameTime + 1 + rand()%deltaGameTime);
droidAddWeldSound( iVecEffect );
@@ -1395,6 +1332,22 @@ bool droidUpdateDroidRepair(DROID *psRepairDroid)
return psDroidToRepair->body < psDroidToRepair->originalBody;
}
+bool droidUpdateDroidRepair(DROID *psRepairDroid)
+{
+ ASSERT_OR_RETURN(false, psRepairDroid->action == DACTION_DROIDREPAIR, "Unit does not have unit repair order");
+ ASSERT_OR_RETURN(false, psRepairDroid->asBits[COMP_REPAIRUNIT].nStat != 0, "Unit does not have a repair turret");
+
+ DROID *psDroidToRepair = (DROID *)psRepairDroid->psActionTarget[0];
+ ASSERT_OR_RETURN(false, psDroidToRepair->type == OBJ_DROID, "Target is not a unit");
+
+ return droidUpdateDroidRepairBase(psRepairDroid, psDroidToRepair);
+}
+
+static void droidUpdateDroidSelfRepair(DROID *psRepairDroid)
+{
+ droidUpdateDroidRepairBase(psRepairDroid, psRepairDroid);
+}
+
// return whether a droid is IDF
bool idfDroid(DROID *psDroid)
{
View
@@ -157,9 +157,6 @@ extern bool droidStartDroidRepair( DROID *psDroid );
/*Updates a Repair Droid working on a damaged droid - returns true whilst repairing*/
extern bool droidUpdateDroidRepair(DROID *psRepairDroid);
-/*checks a droids current body points to see if need to self repair*/
-extern void droidSelfRepair(DROID *psDroid);
-
/* Update a construction droid while it is building
returns true while building continues */
extern bool droidUpdateBuild(DROID *psDroid);
View
@@ -967,9 +967,9 @@ void structureDemolish(STRUCTURE *psStruct, DROID *psDroid, int buildPoints)
structureBuild(psStruct, psDroid, -buildPoints);
}
-bool structureRepair(STRUCTURE *psStruct, DROID *psDroid, int buildPoints)
+void structureRepair(STRUCTURE *psStruct, DROID *psDroid, int buildRate)
{
- int repairAmount = (buildPoints * structureBody(psStruct))/psStruct->pStructureType->buildPoints;
+ int repairAmount = gameTimeAdjustedAverage(buildRate*structureBody(psStruct), psStruct->pStructureType->buildPoints);
/* (droid construction power * current max hitpoints [incl. upgrades])
/ construction power that was necessary to build structure in the first place
@@ -978,21 +978,7 @@ bool structureRepair(STRUCTURE *psStruct, DROID *psDroid, int buildPoints)
This happens with expensive, but weak buildings like mortar pits. In this case, do nothing
and notify the caller (read: droid) of your idleness by returning false.
*/
- if (repairAmount != 0) // didn't get truncated to zero
- {
- psStruct->body += repairAmount;
- psStruct->body = MIN(psStruct->body, structureBody(psStruct));
- if (psStruct->body == 0)
- {
- removeStruct(psStruct, true);
- }
- return true;
- }
- else
- {
- // got truncated to zero; wait until droid has accumulated enough buildpoints
- return false;
- }
+ psStruct->body = clip(psStruct->body + repairAmount, 0, structureBody(psStruct));
}
/* Set the type of droid for a factory to build */
View
@@ -116,7 +116,7 @@ int gateCurrentOpenHeight(STRUCTURE const *psStructure, uint32_t time, int minim
int32_t structureDamage(STRUCTURE *psStructure, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond);
extern void structureBuild(STRUCTURE *psStructure, DROID *psDroid, int buildPoints, int buildRate = 1);
extern void structureDemolish(STRUCTURE *psStructure, DROID *psDroid, int buildPoints);
-extern bool structureRepair(STRUCTURE *psStruct, DROID *psDroid, int buildPoints);
+void structureRepair(STRUCTURE *psStruct, DROID *psDroid, int buildRate);
/* Set the type of droid for a factory to build */
extern bool structSetManufacture(STRUCTURE *psStruct, DROID_TEMPLATE *psTempl, QUEUE_MODE mode);

0 comments on commit 68b1103

Please sign in to comment.