Skip to content

Commit

Permalink
Simplify repair logic, where a droid is repairing a droid or structure.
Browse files Browse the repository at this point in the history
Repairing structures with 0 hp will no longer risk suddenly destroying the structure, although this probably makes
no difference, as structures do not ever have 0 hp. The .actionStarted and .actionPoints fields are no longer used
when droids repair stuff.
  • Loading branch information
Cyp committed Sep 23, 2012
1 parent d608f37 commit 2402562
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 76 deletions.
74 changes: 16 additions & 58 deletions src/droid.cpp
Expand Up @@ -1122,27 +1122,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);
int constructRate = 5 * constructorPoints(asConstructStats + psDroid->asBits[COMP_CONSTRUCT].nStat, psDroid->player);
int pointsToAdd = gameTimeAdjustedAverage(constructRate);

pointsToAdd = constructPoints * (gameTime - psDroid->actionStarted) /
GAME_TICKS_PER_SEC;

structureDemolish(psStruct, psDroid, pointsToAdd - psDroid->actionPoints);

//store the amount just subtracted
psDroid->actionPoints = pointsToAdd;
structureDemolish(psStruct, psDroid, pointsToAdd);

addConstructorEffect(psStruct);

Expand Down Expand Up @@ -1301,27 +1290,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))
Expand All @@ -1330,60 +1308,40 @@ 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)
{
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];
DROID *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 );
Expand Down
20 changes: 3 additions & 17 deletions src/structure.cpp
Expand Up @@ -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
Expand All @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion src/structure.h
Expand Up @@ -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);

Expand Down

0 comments on commit 2402562

Please sign in to comment.