Attached Files |
-
gradual-reclaim-0.1.patch (6,117 bytes) 2006-08-02 20:56
Index: rts/Game/UI/MouseHandler.cpp
===================================================================
--- rts/Game/UI/MouseHandler.cpp (revision 1727)
+++ rts/Game/UI/MouseHandler.cpp (working copy)
@@ -591,11 +591,17 @@
} else {
s=feature->def->description;
}
- std::string metalColor = feature->def->metal > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
- std::string energyColor = feature->def->energy > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
+
+ float remainingMetal = feature->RemainingMetal();
+ float remainingEnergy = feature->RemainingEnergy();
+
+ std::string metalColor = remainingMetal > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
+ std::string energyColor = remainingEnergy > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
+
char tmp[500];
sprintf(tmp,"\n\xff\xd3\xdb\xffMetal: %s%.0f \xff\xd3\xdb\xff Energy: %s%.0f",
- metalColor.c_str(), feature->def->metal, energyColor.c_str(), feature->def->energy);
+ metalColor.c_str(), remainingMetal,
+ energyColor.c_str(), remainingEnergy);
s+=tmp;
return s;
Index: rts/Sim/Misc/Feature.cpp
===================================================================
--- rts/Sim/Misc/Feature.cpp (revision 1727)
+++ rts/Sim/Misc/Feature.cpp (working copy)
@@ -137,24 +137,61 @@
bool CFeature::AddBuildPower(float amount, CUnit* builder)
{
+ float oldReclaimLeft = reclaimLeft;
+ float fractionReclaimed;
if(amount>0){
- return false; //cant repair a feature
+ return false; // cant repair a feature
} else {
- if(reclaimLeft<0) //avoid multisuck :)
+ if(reclaimLeft <= 0) // avoid multisuck when reclaim has completed this tick
return false;
- if(lastReclaim==gs->frameNum) //make sure several units cant reclaim at once on a single feature
+
+ if(featureHandler->multiReclaim == 0 && lastReclaim == gs->frameNum) // make sure several units cant reclaim at once on a single feature
return true;
+
float part=(100-amount)*0.02/max(10.0f,(def->metal+def->energy));
reclaimLeft-=part;
- lastReclaim=gs->frameNum;
- if(reclaimLeft<0){
+
+ // Stop the last bit giving too much resource
+ if(reclaimLeft < 0) reclaimLeft = 0;
+
+ fractionReclaimed = oldReclaimLeft-reclaimLeft;
+
+ if(featureHandler->reclaimMethod == 1 && reclaimLeft == 0) // All-at-end method
+ {
builder->AddMetal(def->metal);
builder->AddEnergy(def->energy);
+ }
+ else if(featureHandler->reclaimMethod == 0) // Gradual reclaim
+ {
+ builder->AddMetal(def->metal * fractionReclaimed);
+ builder->AddEnergy(def->energy * fractionReclaimed);
+ }
+ else // Chunky reclaiming
+ {
+ // Work out how many chunk boundaries we crossed
+ float chunkSize = 1.0 / featureHandler->reclaimMethod;
+ int oldChunk = ChunkNumber(oldReclaimLeft);
+ int newChunk = ChunkNumber(reclaimLeft);
+ if (oldChunk != newChunk)
+ {
+ float noChunks = (float)oldChunk - (float)newChunk;
+ builder->AddMetal(noChunks * def->metal * chunkSize);
+ builder->AddEnergy(noChunks * def->energy * chunkSize);
+ }
+ }
+
+ // Has the reclaim finished?
+ if(reclaimLeft<=0)
+ {
featureHandler->DeleteFeature(this);
return false;
}
+
+ lastReclaim=gs->frameNum;
return true;
}
+ // Should never get here
+ assert(false);
return false;
}
@@ -250,5 +287,36 @@
glPopMatrix();
}
+int CFeature::ChunkNumber(float f)
+{
+ return (int) ceil(f * featureHandler->reclaimMethod);
+}
+
+float CFeature::RemainingResource(float res)
+{
+ // Old style - all reclaimed at the end
+ if(featureHandler->reclaimMethod == 0)
+ return res * reclaimLeft;
+
+ // Gradual reclaim
+ if(featureHandler->reclaimMethod == 1)
+ return res;
+
+ // Otherwise we are doing chunk reclaiming
+ float chunkSize = res / featureHandler->reclaimMethod; // resource/no_chunks
+ float chunksLeft = ceil(reclaimLeft * featureHandler->reclaimMethod);
+ return chunkSize * chunksLeft;
+}
+
+float CFeature::RemainingMetal()
+{
+ return RemainingResource(def->metal);
+}
+float CFeature::RemainingEnergy()
+{
+ return RemainingResource(def->energy);
+}
+
+
FeatureDef::~FeatureDef() {
}
Index: rts/Sim/Misc/Feature.h
===================================================================
--- rts/Sim/Misc/Feature.h (revision 1727)
+++ rts/Sim/Misc/Feature.h (working copy)
@@ -27,6 +27,10 @@
void Kill(float3& impulse);
virtual bool Update(void);
void StartFire(void);
+ float RemainingResource(float res);
+ float RemainingMetal(void);
+ float RemainingEnergy(void);
+ int ChunkNumber(float f);
void DrawS3O();
void CalculateTransform();
CUnit* LastBuilder;
Index: rts/Sim/Misc/FeatureHandler.cpp
===================================================================
--- rts/Sim/Misc/FeatureHandler.cpp (revision 1727)
+++ rts/Sim/Misc/FeatureHandler.cpp (working copy)
@@ -46,6 +46,24 @@
LoadWreckFeatures();
treeDrawer=CBaseTreeDrawer::GetTreeDrawer();
+
+ // Get the reclaim options for the mod
+
+ // Defaults:
+ multiReclaim = 0;
+ reclaimMethod = 1;
+
+ // See if the mod overrides the defaults:
+ try
+ {
+ TdfParser reclaimOptions("gamedata/RECLAIM.tdf");
+ multiReclaim = atoi(reclaimOptions.SGetValueDef("0", "RECLAIM\\MultiReclaim").c_str());
+ reclaimMethod = atoi(reclaimOptions.SGetValueDef("1", "RECLAIM\\ReclaimMethod").c_str());
+ }
+ catch(content_error) // If the RECLAIM.tdf isnt found
+ {
+ // We already set the defaults so we should be able to ignore this
+ }
}
CFeatureHandler::~CFeatureHandler()
Index: rts/Sim/Misc/FeatureHandler.h
===================================================================
--- rts/Sim/Misc/FeatureHandler.h (revision 1727)
+++ rts/Sim/Misc/FeatureHandler.h (working copy)
@@ -67,6 +67,11 @@
int drawQuadsY;
int numQuads;
+ // Reclaim behaviour
+ int multiReclaim; // 0 = 1 reclaimer per feature max, otherwise unlimited
+ int reclaimMethod; // 0 = gradual reclaim, 1 = all reclaimed at end,
+ // otherwise reclaim in reclaimMethod chunks
+
int overrideId; //used when loading from savefile
void DrawFar(CFeature* feature,CVertexArray* va);
FeatureDef* GetFeatureDef(const std::string name);
-
gradual-reclaim-0.2.patch (10,678 bytes) 2006-08-04 19:00
Index: rts/Game/UI/MouseHandler.cpp
===================================================================
--- rts/Game/UI/MouseHandler.cpp (revision 1747)
+++ rts/Game/UI/MouseHandler.cpp (working copy)
@@ -591,11 +591,17 @@
} else {
s=feature->def->description;
}
- std::string metalColor = feature->def->metal > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
- std::string energyColor = feature->def->energy > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
+
+ float remainingMetal = feature->RemainingMetal();
+ float remainingEnergy = feature->RemainingEnergy();
+
+ std::string metalColor = remainingMetal > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
+ std::string energyColor = remainingEnergy > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
+
char tmp[500];
sprintf(tmp,"\n\xff\xd3\xdb\xffMetal: %s%.0f \xff\xd3\xdb\xff Energy: %s%.0f",
- metalColor.c_str(), feature->def->metal, energyColor.c_str(), feature->def->energy);
+ metalColor.c_str(), remainingMetal,
+ energyColor.c_str(), remainingEnergy);
s+=tmp;
return s;
Index: rts/Sim/Misc/Feature.cpp
===================================================================
--- rts/Sim/Misc/Feature.cpp (revision 1747)
+++ rts/Sim/Misc/Feature.cpp (working copy)
@@ -7,9 +7,11 @@
#include "QuadField.h"
#include "DamageArray.h"
#include "Map/ReadMap.h"
+#include "Game/Team.h"
#include "Game/UI/InfoConsole.h"
#include "Sim/Units/Unit.h"
#include "Rendering/Env/BaseTreeDrawer.h"
+#include "Sim/ModInfo.h"
#include "Sim/Projectiles/FireProjectile.h"
#include "Sim/Projectiles/SmokeProjectile.h"
#include "Sim/Projectiles/ProjectileHandler.h"
@@ -20,6 +22,7 @@
CR_REG_METADATA(CFeature, (
CR_MEMBER(createdFromUnit),
+ CR_MEMBER(isRepairingBeforeResurrect),
CR_MEMBER(resurrectProgress),
CR_MEMBER(health),
CR_MEMBER(reclaimLeft),
@@ -47,6 +50,7 @@
tempNum(0),
emitSmokeTime(0),
lastReclaim(0),
+ isRepairingBeforeResurrect(false),
resurrectProgress(0),
health(0),
id(0),
@@ -137,24 +141,98 @@
bool CFeature::AddBuildPower(float amount, CUnit* builder)
{
+ float oldReclaimLeft = reclaimLeft;
+ float fractionReclaimed;
if(amount>0){
- return false; //cant repair a feature
+
+ // Check they are trying to repair a feature that can be resurrected
+ if(createdFromUnit == "")
+ return false;
+
+ // 'Repairing' previously-sucked features prior to resurrection
+ // This is reclaim-option independant - repairing features should always
+ // be like other repairing - gradual and multi-unit
+ // Lots of this code is stolen from unit->AddBuildPower
+
+ isRepairingBeforeResurrect = true; // Stop them exploiting chunk reclaiming
+
+ if (reclaimLeft >= 1)
+ return false; // cant repair a 'fresh' feature
+
+ // Work out how much to try to put back, based on the speed this unit would reclaim at.
+ float part=(100-amount)*0.02/max(10.0f,(def->metal+def->energy));
+
+ // Work out how much that will cost
+ float metalUse=def->metal*part;
+ float energyUse=def->energy*part;
+ if (gs->Team(builder->team)->metal >= metalUse && gs->Team(builder->team)->energy >= energyUse)
+ {
+ builder->UseMetal(metalUse);
+ builder->UseEnergy(energyUse);
+ reclaimLeft+=part;
+ if(reclaimLeft>=1)
+ isRepairingBeforeResurrect = false; // They can start reclaiming it again if they so wish
+ reclaimLeft = 1;
+ return true;
+ }
+ return false;
+
+
} else {
- if(reclaimLeft<0) //avoid multisuck :)
+ // Reclaiming
+ if(reclaimLeft <= 0) // avoid multisuck when reclaim has already completed during this frame
return false;
- if(lastReclaim==gs->frameNum) //make sure several units cant reclaim at once on a single feature
+
+ if(isRepairingBeforeResurrect && modInfo->reclaimMethod > 1) // don't let them exploit chunk reclaim
+ return false;
+
+ if(modInfo->multiReclaim == 0 && lastReclaim == gs->frameNum) // make sure several units cant reclaim at once on a single feature
return true;
+
float part=(100-amount)*0.02/max(10.0f,(def->metal+def->energy));
reclaimLeft-=part;
- lastReclaim=gs->frameNum;
- if(reclaimLeft<0){
+
+ // Stop the last bit giving too much resource
+ if(reclaimLeft < 0) reclaimLeft = 0;
+
+ fractionReclaimed = oldReclaimLeft-reclaimLeft;
+
+ if(modInfo->reclaimMethod == 1 && reclaimLeft == 0) // All-at-end method
+ {
builder->AddMetal(def->metal);
builder->AddEnergy(def->energy);
+ }
+ else if(modInfo->reclaimMethod == 0) // Gradual reclaim
+ {
+ builder->AddMetal(def->metal * fractionReclaimed);
+ builder->AddEnergy(def->energy * fractionReclaimed);
+ }
+ else // Chunky reclaiming
+ {
+ // Work out how many chunk boundaries we crossed
+ float chunkSize = 1.0 / modInfo->reclaimMethod;
+ int oldChunk = ChunkNumber(oldReclaimLeft);
+ int newChunk = ChunkNumber(reclaimLeft);
+ if (oldChunk != newChunk)
+ {
+ float noChunks = (float)oldChunk - (float)newChunk;
+ builder->AddMetal(noChunks * def->metal * chunkSize);
+ builder->AddEnergy(noChunks * def->energy * chunkSize);
+ }
+ }
+
+ // Has the reclaim finished?
+ if(reclaimLeft<=0)
+ {
featureHandler->DeleteFeature(this);
return false;
}
+
+ lastReclaim=gs->frameNum;
return true;
}
+ // Should never get here
+ assert(false);
return false;
}
@@ -250,5 +328,36 @@
glPopMatrix();
}
+int CFeature::ChunkNumber(float f)
+{
+ return (int) ceil(f * modInfo->reclaimMethod);
+}
+
+float CFeature::RemainingResource(float res)
+{
+ // Old style - all reclaimed at the end
+ if(modInfo->reclaimMethod == 0)
+ return res * reclaimLeft;
+
+ // Gradual reclaim
+ if(modInfo->reclaimMethod == 1)
+ return res;
+
+ // Otherwise we are doing chunk reclaiming
+ float chunkSize = res / modInfo->reclaimMethod; // resource/no_chunks
+ float chunksLeft = ceil(reclaimLeft * modInfo->reclaimMethod);
+ return chunkSize * chunksLeft;
+}
+
+float CFeature::RemainingMetal()
+{
+ return RemainingResource(def->metal);
+}
+float CFeature::RemainingEnergy()
+{
+ return RemainingResource(def->energy);
+}
+
+
FeatureDef::~FeatureDef() {
}
Index: rts/Sim/Misc/Feature.h
===================================================================
--- rts/Sim/Misc/Feature.h (revision 1747)
+++ rts/Sim/Misc/Feature.h (working copy)
@@ -27,11 +27,20 @@
void Kill(float3& impulse);
virtual bool Update(void);
void StartFire(void);
+ float RemainingResource(float res);
+ float RemainingMetal(void);
+ float RemainingEnergy(void);
+ int ChunkNumber(float f);
void DrawS3O();
void CalculateTransform();
CUnit* LastBuilder;
std::string createdFromUnit;
+ // This flag is used to stop a potential exploit involving tripping a unit back and forth
+ // across a chunk boundary to get unlimited resources. Basically, once a corspe has been a little bit
+ // reclaimed, if they start rezzing then they cannot reclaim again until the corpse has been fully
+ // 'repaired'.
+ bool isRepairingBeforeResurrect;
float resurrectProgress;
float health;
Index: rts/Sim/ModInfo.cpp
===================================================================
--- rts/Sim/ModInfo.cpp (revision 1747)
+++ rts/Sim/ModInfo.cpp (working copy)
@@ -18,6 +18,22 @@
// Load the users preference for team coloured nanospray
gu->teamNanospray = configHandler.GetInt ("TeamNanoSpray", 0);
}
+
+ // Get the reclaim options for the mod
+ multiReclaim = 0;
+ reclaimMethod = 1;
+ // See if the mod overrides the defaults:
+ try
+ {
+ TdfParser reclaimOptions("gamedata/RECLAIM.tdf");
+ multiReclaim = atoi(reclaimOptions.SGetValueDef("0", "RECLAIM\\MultiReclaim").c_str());
+ reclaimMethod = atoi(reclaimOptions.SGetValueDef("1", "RECLAIM\\ReclaimMethod").c_str());
+ }
+ catch(content_error) // If the RECLAIM.tdf isnt found
+ {
+ // We already set the defaults so we should be able to ignore this
+ }
+
}
CModInfo::~CModInfo(){}
Index: rts/Sim/ModInfo.h
===================================================================
--- rts/Sim/ModInfo.h (revision 1747)
+++ rts/Sim/ModInfo.h (working copy)
@@ -10,6 +10,11 @@
std::string name;
bool allowTeamColors;
+
+ // Reclaim behaviour
+ int multiReclaim; // 0 = 1 reclaimer per feature max, otherwise unlimited
+ int reclaimMethod; // 0 = gradual reclaim, 1 = all reclaimed at end, otherwise reclaim in reclaimMethod chunks
+
};
extern CModInfo *modInfo;
Index: rts/Sim/Units/UnitTypes/Builder.cpp
===================================================================
--- rts/Sim/Units/UnitTypes/Builder.cpp (revision 1747)
+++ rts/Sim/Units/UnitTypes/Builder.cpp (working copy)
@@ -6,6 +6,7 @@
#include "Builder.h"
#include "Building.h"
#include "Sim/Units/UnitLoader.h"
+#include "Sim/ModInfo.h"
#include "Sim/Projectiles/GfxProjectile.h"
#include "Game/GameHelper.h"
#include "Sim/Units/UnitHandler.h"
@@ -196,18 +197,28 @@
} else if(curResurrect && curResurrect->pos.distance2D(pos)<buildDistance+curResurrect->radius && inBuildStance){
UnitDef* ud=unitDefHandler->GetUnitByName(curResurrect->createdFromUnit);
if(ud){
- if(UseEnergy(ud->energyCost*buildSpeed/ud->buildTime*0.5)){
- curResurrect->resurrectProgress+=buildSpeed/ud->buildTime;
- CreateNanoParticle(curResurrect->midPos,curResurrect->radius*0.7,gs->randInt()&1);
+ if( modInfo->reclaimMethod != 1 && curResurrect->reclaimLeft < 1)
+ {
+ // This corpse has been reclaimed a little, need to restore the resources
+ // before we can let the player resurrect it.
+ curReclaim->AddBuildPower(buildSpeed,this);
}
- if(curResurrect->resurrectProgress>1){ //resurrect finished
- curResurrect->UnBlock();
- CUnit* u=unitLoader.LoadUnit(curResurrect->createdFromUnit,curResurrect->pos,team,false,curResurrect->buildFacing);
- u->health*=0.05;
- lastResurrected=u->id;
- curResurrect->resurrectProgress=0;
- featureHandler->DeleteFeature(curResurrect);
- StopBuild(true);
+ else
+ {
+ // Corpse has been restored, begin resurrection
+ if(UseEnergy(ud->energyCost*buildSpeed/ud->buildTime*0.5)){
+ curResurrect->resurrectProgress+=buildSpeed/ud->buildTime;
+ CreateNanoParticle(curResurrect->midPos,curResurrect->radius*0.7,gs->randInt()&1);
+ }
+ if(curResurrect->resurrectProgress>1){ //resurrect finished
+ curResurrect->UnBlock();
+ CUnit* u=unitLoader.LoadUnit(curResurrect->createdFromUnit,curResurrect->pos,team,false,curResurrect->buildFacing);
+ u->health*=0.05;
+ lastResurrected=u->id;
+ curResurrect->resurrectProgress=0;
+ featureHandler->DeleteFeature(curResurrect);
+ StopBuild(true);
+ }
}
} else {
StopBuild(true);
-
gradual-reclaim-0.3.patch (10,739 bytes) 2006-08-04 19:06
Index: rts/Game/UI/MouseHandler.cpp
===================================================================
--- rts/Game/UI/MouseHandler.cpp (revision 1747)
+++ rts/Game/UI/MouseHandler.cpp (working copy)
@@ -591,11 +591,17 @@
} else {
s=feature->def->description;
}
- std::string metalColor = feature->def->metal > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
- std::string energyColor = feature->def->energy > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
+
+ float remainingMetal = feature->RemainingMetal();
+ float remainingEnergy = feature->RemainingEnergy();
+
+ std::string metalColor = remainingMetal > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
+ std::string energyColor = remainingEnergy > 0 ? "\xff\x50\xff\x50" : "\xff\xff\x50\x01";
+
char tmp[500];
sprintf(tmp,"\n\xff\xd3\xdb\xffMetal: %s%.0f \xff\xd3\xdb\xff Energy: %s%.0f",
- metalColor.c_str(), feature->def->metal, energyColor.c_str(), feature->def->energy);
+ metalColor.c_str(), remainingMetal,
+ energyColor.c_str(), remainingEnergy);
s+=tmp;
return s;
Index: rts/Sim/Misc/Feature.cpp
===================================================================
--- rts/Sim/Misc/Feature.cpp (revision 1747)
+++ rts/Sim/Misc/Feature.cpp (working copy)
@@ -7,9 +7,11 @@
#include "QuadField.h"
#include "DamageArray.h"
#include "Map/ReadMap.h"
+#include "Game/Team.h"
#include "Game/UI/InfoConsole.h"
#include "Sim/Units/Unit.h"
#include "Rendering/Env/BaseTreeDrawer.h"
+#include "Sim/ModInfo.h"
#include "Sim/Projectiles/FireProjectile.h"
#include "Sim/Projectiles/SmokeProjectile.h"
#include "Sim/Projectiles/ProjectileHandler.h"
@@ -20,6 +22,7 @@
CR_REG_METADATA(CFeature, (
CR_MEMBER(createdFromUnit),
+ CR_MEMBER(isRepairingBeforeResurrect),
CR_MEMBER(resurrectProgress),
CR_MEMBER(health),
CR_MEMBER(reclaimLeft),
@@ -47,6 +50,7 @@
tempNum(0),
emitSmokeTime(0),
lastReclaim(0),
+ isRepairingBeforeResurrect(false),
resurrectProgress(0),
health(0),
id(0),
@@ -137,24 +141,98 @@
bool CFeature::AddBuildPower(float amount, CUnit* builder)
{
+ float oldReclaimLeft = reclaimLeft;
+ float fractionReclaimed;
if(amount>0){
- return false; //cant repair a feature
+
+ // Check they are trying to repair a feature that can be resurrected
+ if(createdFromUnit == "")
+ return false;
+
+ // 'Repairing' previously-sucked features prior to resurrection
+ // This is reclaim-option independant - repairing features should always
+ // be like other repairing - gradual and multi-unit
+ // Lots of this code is stolen from unit->AddBuildPower
+
+ isRepairingBeforeResurrect = true; // Stop them exploiting chunk reclaiming
+
+ if (reclaimLeft >= 1)
+ return false; // cant repair a 'fresh' feature
+
+ // Work out how much to try to put back, based on the speed this unit would reclaim at.
+ float part=(100-amount)*0.02/max(10.0f,(def->metal+def->energy));
+
+ // Work out how much that will cost
+ float metalUse=def->metal*part;
+ float energyUse=def->energy*part;
+ if (gs->Team(builder->team)->metal >= metalUse && gs->Team(builder->team)->energy >= energyUse)
+ {
+ builder->UseMetal(metalUse);
+ builder->UseEnergy(energyUse);
+ reclaimLeft+=part;
+ if(reclaimLeft>=1)
+ isRepairingBeforeResurrect = false; // They can start reclaiming it again if they so wish
+ reclaimLeft = 1;
+ return true;
+ }
+ return false;
+
+
} else {
- if(reclaimLeft<0) //avoid multisuck :)
+ // Reclaiming
+ if(reclaimLeft <= 0) // avoid multisuck when reclaim has already completed during this frame
return false;
- if(lastReclaim==gs->frameNum) //make sure several units cant reclaim at once on a single feature
+
+ if(isRepairingBeforeResurrect && modInfo->reclaimMethod > 1) // don't let them exploit chunk reclaim
+ return false;
+
+ if(modInfo->multiReclaim == 0 && lastReclaim == gs->frameNum) // make sure several units cant reclaim at once on a single feature
return true;
+
float part=(100-amount)*0.02/max(10.0f,(def->metal+def->energy));
reclaimLeft-=part;
- lastReclaim=gs->frameNum;
- if(reclaimLeft<0){
+
+ // Stop the last bit giving too much resource
+ if(reclaimLeft < 0) reclaimLeft = 0;
+
+ fractionReclaimed = oldReclaimLeft-reclaimLeft;
+
+ if(modInfo->reclaimMethod == 1 && reclaimLeft == 0) // All-at-end method
+ {
builder->AddMetal(def->metal);
builder->AddEnergy(def->energy);
+ }
+ else if(modInfo->reclaimMethod == 0) // Gradual reclaim
+ {
+ builder->AddMetal(def->metal * fractionReclaimed);
+ builder->AddEnergy(def->energy * fractionReclaimed);
+ }
+ else // Chunky reclaiming
+ {
+ // Work out how many chunk boundaries we crossed
+ float chunkSize = 1.0 / modInfo->reclaimMethod;
+ int oldChunk = ChunkNumber(oldReclaimLeft);
+ int newChunk = ChunkNumber(reclaimLeft);
+ if (oldChunk != newChunk)
+ {
+ float noChunks = (float)oldChunk - (float)newChunk;
+ builder->AddMetal(noChunks * def->metal * chunkSize);
+ builder->AddEnergy(noChunks * def->energy * chunkSize);
+ }
+ }
+
+ // Has the reclaim finished?
+ if(reclaimLeft<=0)
+ {
featureHandler->DeleteFeature(this);
return false;
}
+
+ lastReclaim=gs->frameNum;
return true;
}
+ // Should never get here
+ assert(false);
return false;
}
@@ -250,5 +328,36 @@
glPopMatrix();
}
+int CFeature::ChunkNumber(float f)
+{
+ return (int) ceil(f * modInfo->reclaimMethod);
+}
+
+float CFeature::RemainingResource(float res)
+{
+ // Old style - all reclaimed at the end
+ if(modInfo->reclaimMethod == 0)
+ return res * reclaimLeft;
+
+ // Gradual reclaim
+ if(modInfo->reclaimMethod == 1)
+ return res;
+
+ // Otherwise we are doing chunk reclaiming
+ float chunkSize = res / modInfo->reclaimMethod; // resource/no_chunks
+ float chunksLeft = ceil(reclaimLeft * modInfo->reclaimMethod);
+ return chunkSize * chunksLeft;
+}
+
+float CFeature::RemainingMetal()
+{
+ return RemainingResource(def->metal);
+}
+float CFeature::RemainingEnergy()
+{
+ return RemainingResource(def->energy);
+}
+
+
FeatureDef::~FeatureDef() {
}
Index: rts/Sim/Misc/Feature.h
===================================================================
--- rts/Sim/Misc/Feature.h (revision 1747)
+++ rts/Sim/Misc/Feature.h (working copy)
@@ -27,11 +27,20 @@
void Kill(float3& impulse);
virtual bool Update(void);
void StartFire(void);
+ float RemainingResource(float res);
+ float RemainingMetal(void);
+ float RemainingEnergy(void);
+ int ChunkNumber(float f);
void DrawS3O();
void CalculateTransform();
CUnit* LastBuilder;
std::string createdFromUnit;
+ // This flag is used to stop a potential exploit involving tripping a unit back and forth
+ // across a chunk boundary to get unlimited resources. Basically, once a corspe has been a little bit
+ // reclaimed, if they start rezzing then they cannot reclaim again until the corpse has been fully
+ // 'repaired'.
+ bool isRepairingBeforeResurrect;
float resurrectProgress;
float health;
Index: rts/Sim/ModInfo.cpp
===================================================================
--- rts/Sim/ModInfo.cpp (revision 1747)
+++ rts/Sim/ModInfo.cpp (working copy)
@@ -18,6 +18,23 @@
// Load the users preference for team coloured nanospray
gu->teamNanospray = configHandler.GetInt ("TeamNanoSpray", 0);
}
+
+ // Get the reclaim options for the mod
+ multiReclaim = 0;
+ reclaimMethod = 1;
+ // See if the mod overrides the defaults:
+ try
+ {
+ TdfParser reclaimOptions("gamedata/modrules.tdf");
+ multiReclaim = atoi(reclaimOptions.SGetValueDef("0", "RECLAIM\\MultiReclaim").c_str());
+ reclaimMethod = atoi(reclaimOptions.SGetValueDef("1", "RECLAIM\\ReclaimMethod").c_str());
+ }
+ catch(content_error) // If the modrules.tdf isnt found
+ {
+ // We already set the defaults so we should be able to ignore this
+ // Other optional mod rules MUST set their defaults...
+ }
+
}
CModInfo::~CModInfo(){}
Index: rts/Sim/ModInfo.h
===================================================================
--- rts/Sim/ModInfo.h (revision 1747)
+++ rts/Sim/ModInfo.h (working copy)
@@ -10,6 +10,11 @@
std::string name;
bool allowTeamColors;
+
+ // Reclaim behaviour
+ int multiReclaim; // 0 = 1 reclaimer per feature max, otherwise unlimited
+ int reclaimMethod; // 0 = gradual reclaim, 1 = all reclaimed at end, otherwise reclaim in reclaimMethod chunks
+
};
extern CModInfo *modInfo;
Index: rts/Sim/Units/UnitTypes/Builder.cpp
===================================================================
--- rts/Sim/Units/UnitTypes/Builder.cpp (revision 1747)
+++ rts/Sim/Units/UnitTypes/Builder.cpp (working copy)
@@ -6,6 +6,7 @@
#include "Builder.h"
#include "Building.h"
#include "Sim/Units/UnitLoader.h"
+#include "Sim/ModInfo.h"
#include "Sim/Projectiles/GfxProjectile.h"
#include "Game/GameHelper.h"
#include "Sim/Units/UnitHandler.h"
@@ -196,18 +197,28 @@
} else if(curResurrect && curResurrect->pos.distance2D(pos)<buildDistance+curResurrect->radius && inBuildStance){
UnitDef* ud=unitDefHandler->GetUnitByName(curResurrect->createdFromUnit);
if(ud){
- if(UseEnergy(ud->energyCost*buildSpeed/ud->buildTime*0.5)){
- curResurrect->resurrectProgress+=buildSpeed/ud->buildTime;
- CreateNanoParticle(curResurrect->midPos,curResurrect->radius*0.7,gs->randInt()&1);
+ if( modInfo->reclaimMethod != 1 && curResurrect->reclaimLeft < 1)
+ {
+ // This corpse has been reclaimed a little, need to restore the resources
+ // before we can let the player resurrect it.
+ curReclaim->AddBuildPower(buildSpeed,this);
}
- if(curResurrect->resurrectProgress>1){ //resurrect finished
- curResurrect->UnBlock();
- CUnit* u=unitLoader.LoadUnit(curResurrect->createdFromUnit,curResurrect->pos,team,false,curResurrect->buildFacing);
- u->health*=0.05;
- lastResurrected=u->id;
- curResurrect->resurrectProgress=0;
- featureHandler->DeleteFeature(curResurrect);
- StopBuild(true);
+ else
+ {
+ // Corpse has been restored, begin resurrection
+ if(UseEnergy(ud->energyCost*buildSpeed/ud->buildTime*0.5)){
+ curResurrect->resurrectProgress+=buildSpeed/ud->buildTime;
+ CreateNanoParticle(curResurrect->midPos,curResurrect->radius*0.7,gs->randInt()&1);
+ }
+ if(curResurrect->resurrectProgress>1){ //resurrect finished
+ curResurrect->UnBlock();
+ CUnit* u=unitLoader.LoadUnit(curResurrect->createdFromUnit,curResurrect->pos,team,false,curResurrect->buildFacing);
+ u->health*=0.05;
+ lastResurrected=u->id;
+ curResurrect->resurrectProgress=0;
+ featureHandler->DeleteFeature(curResurrect);
+ StopBuild(true);
+ }
}
} else {
StopBuild(true);
|
---|