Merge branch 'feat/command-priority' into play

This commit is contained in:
pavanvo 2022-09-06 17:54:44 +04:00
commit edc9de3d15
No known key found for this signature in database
GPG Key ID: 34C1C36681B4AD84
12 changed files with 356 additions and 387 deletions

View File

@ -120,9 +120,11 @@ std::pair<CommandResult,string> Commander::tryGiveCommand(const Selection *selec
}
if(useCommandtype != NULL) {
auto mct= unit->getCurrMorphCt();
int nextUnitTypeId= mct? mct->getMorphUnit()->getId(): -1;
NetworkCommand networkCommand(this->world,nctGiveCommand, unitId,
useCommandtype->getId(), usePos, unitType->getId(),
(targetUnit != NULL ? targetUnit->getId() : -1),
useCommandtype->getId(), usePos, unitType->getId(), nextUnitTypeId,
(targetUnit != NULL ? targetUnit->getId() : -1),
facing, tryQueue, commandStateType,commandStateValue,
unitCommandGroupId);
@ -162,8 +164,10 @@ std::pair<CommandResult,string> Commander::tryGiveCommand(const Unit* unit, cons
std::pair<CommandResult,string> result(crFailUndefined,"");
bool canSubmitCommand=canSubmitCommandType(unit, commandType);
if(canSubmitCommand == true) {
auto mct= unit->getCurrMorphCt();
int nextUnitTypeId= mct? mct->getMorphUnit()->getId(): -1;
NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(),
commandType->getId(), pos, unitType->getId(),
commandType->getId(), pos, unitType->getId(), nextUnitTypeId,
(targetUnit != NULL ? targetUnit->getId() : -1),
facing, tryQueue,cst_None,-1,unitGroupCommandId);
@ -210,8 +214,10 @@ std::pair<CommandResult,string> Commander::tryGiveCommand(const Selection *selec
int unitId= selection->getUnit(i)->getId();
Vec2i currPos= world->getMap()->computeDestPos(refPos,
selection->getUnit(i)->getPosNotThreadSafe(), pos);
auto mct= unit->getCurrMorphCt();
int nextUnitTypeId= mct? mct->getMorphUnit()->getId(): -1;
NetworkCommand networkCommand(this->world,nctGiveCommand,
unitId, ct->getId(), currPos, -1, targetId, -1,
unitId, ct->getId(), currPos, -1, nextUnitTypeId, targetId, -1,
tryQueue,cst_None,-1,unitCommandGroupId);
//every unit is ordered to a different pos
@ -263,8 +269,11 @@ std::pair<CommandResult,string> Commander::tryGiveCommand(const Selection *selec
int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId();
int unitId= unit->getId();
Vec2i currPos= world->getMap()->computeDestPos(refPos, unit->getPosNotThreadSafe(), pos);
auto mct= unit->getCurrMorphCt();
int nextUnitTypeId= mct? mct->getMorphUnit()->getId(): -1;
NetworkCommand networkCommand(this->world,nctGiveCommand, unitId,
commandType->getId(), currPos, -1, targetId, -1, tryQueue,
commandType->getId(), currPos, -1, nextUnitTypeId, targetId, -1, tryQueue,
cst_None, -1, unitCommandGroupId);
//every unit is ordered to a different position
@ -310,19 +319,22 @@ std::pair<CommandResult,string> Commander::tryGiveCommand(const Selection *selec
currPos= world->getMap()->computeDestPos(refPos, unit->getPosNotThreadSafe(), pos);
//get command type
const CommandType *commandType= unit->computeCommandType(pos, targetUnit);
auto mct= unit->getCurrMorphCt();
auto nextUnitType= mct? mct->getMorphUnit(): NULL;
const CommandType *commandType= unit->computeCommandType(pos, targetUnit, nextUnitType);
//give commands
if(commandType != NULL) {
int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId();
int unitId= unit->getId();
int nextUnitTypeId= nextUnitType? nextUnitType->getId(): -1;
std::pair<CommandResult,string> resultCur(crFailUndefined,"");
bool canSubmitCommand=canSubmitCommandType(unit, commandType);
if(canSubmitCommand == true) {
NetworkCommand networkCommand(this->world,nctGiveCommand,
unitId, commandType->getId(), currPos, -1, targetId,
unitId, commandType->getId(), currPos, -1, nextUnitTypeId, targetId,
-1, tryQueue, cst_None, -1, unitCommandGroupId);
resultCur= pushNetworkCommand(&networkCommand);
}
@ -330,7 +342,7 @@ std::pair<CommandResult,string> Commander::tryGiveCommand(const Selection *selec
}
else if(unit->isMeetingPointSettable() == true) {
NetworkCommand command(this->world,nctSetMeetingPoint,
unit->getId(), -1, currPos,-1,-1,-1,false,
unit->getId(), -1, currPos,-1,-1,-1,-1,false,
cst_None,-1,unitCommandGroupId);
std::pair<CommandResult,string> resultCur= pushNetworkCommand(&command);
@ -358,7 +370,7 @@ CommandResult Commander::tryCancelCommand(const Selection *selection) const {
for(int i = 0; i < selection->getCount(); ++i) {
NetworkCommand command(this->world,nctCancelCommand,
selection->getUnit(i)->getId(),-1,Vec2i(0),-1,-1,-1,false,
selection->getUnit(i)->getId(),-1,Vec2i(0),-1,-1,-1,-1,false,
cst_None,-1,unitCommandGroupId);
pushNetworkCommand(&command);
}
@ -950,7 +962,7 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const {
throw megaglest_runtime_error(szBuf);
}
ct = unit->getType()->findCommandTypeById(networkCommand->getCommandTypeId());
ct = unit->getType()->findCommandTypeById(networkCommand->getCommandTypeId());
if(unit->getFaction()->getIndex() != networkCommand->getUnitFactionIndex()) {
@ -984,7 +996,13 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const {
throw megaglest_runtime_error(sError);
}
const UnitType* unitType= world->findUnitTypeById(unit->getFaction()->getType(), networkCommand->getUnitTypeId());
const UnitType* unitType= world->findUnitTypeById(unit->getFaction()->getType(), networkCommand->getUnitTypeId());
if(networkCommand->getNextUnitTypeId() > -1 && networkCommand->getWantQueue()) { //Morph Queue
auto nextUnitType= world->findUnitTypeById(unit->getFaction()->getType(), networkCommand->getNextUnitTypeId());
auto mct = nextUnitType->findCommandTypeById(networkCommand->getCommandTypeId());
if(mct) ct = mct;
}
// debug test!
//throw megaglest_runtime_error("Test missing command type!");

View File

@ -5005,7 +5005,10 @@ void Game::keyUp(SDL_KeyboardEvent key) {
gameCamera.setMoveX(0);
camRightButtonDown= false;
calcCameraMoveX();
} else {
gui.hotKeyReleased(key);
}
}
}
catch(const exception &ex) {

View File

@ -460,6 +460,16 @@ void Gui::hotKey(SDL_KeyboardEvent key) {
break;
}
}
if(isKeyDown(queueCommandKey)) {
computeDisplay();
}
}
void Gui::hotKeyReleased(SDL_KeyboardEvent key) {
if(!isKeyDown(queueCommandKey)) {
computeDisplay();
}
}
void Gui::switchToNextDisplayColor(){
@ -567,7 +577,7 @@ void Gui::giveTwoClickOrders(int x, int y , bool prepared) {
else {
result= commander->tryGiveCommand(&selection, activeCommandClass,
targetPos, targetUnit,queueKeyDown);
}
}
}
else {
//selecting building
@ -697,6 +707,8 @@ void Gui::mouseDownDisplayUnitSkills(int posDisplay) {
if (activeCommandClass == ccAttack) {
ct = selection.getUnitFromCC(ccAttack)->getType()->getFirstCtOfClass(activeCommandClass);
}
auto mct= unit->getCurrMorphCt();
if(mct && isKeyDown(queueCommandKey)) ct= mct->getMorphUnit()->getFirstCtOfClass(activeCommandClass);
if(activeCommandType!=NULL && activeCommandType->getClass()==ccBuild){
assert(selection.isUniform());
@ -969,6 +981,10 @@ void Gui::computeDisplay(){
//uniform selection
if(u->isBuilt()){
//printf("u->isBuilt()\n");
auto mct = u->getCurrMorphCt();
if(mct && isKeyDown(queueCommandKey)) {//Morph Queue
ut=mct->getMorphUnit();
}//TODO on queueCommandKey presed disable stop cmd
int morphPos= CommandHelper::getRowPos(crMorphs);
for(int i= 0; i < ut->getCommandTypeSortedCount(); ++i){
@ -993,7 +1009,7 @@ void Gui::computeDisplay(){
display.setCommandType(displayPos, ct);
display.setCommandClass(displayPos, ct->getClass());
bool reqOk=u->getFaction()->reqsOk(ct);
display.setDownLighted(displayPos,reqOk);
display.setDownLighted(displayPos, reqOk && !(!ct->isQueueAppendable() && isKeyDown(queueCommandKey)));
if (reqOk && produced != NULL) {
if (possibleAmount == 0) {

View File

@ -197,6 +197,7 @@ public:
void mouseDoubleClickLeftGraphics(int x, int y);
void groupKey(int groupIndex);
void hotKey(SDL_KeyboardEvent key);
void hotKeyReleased(SDL_KeyboardEvent key);
//misc
void switchToNextDisplayColor();

View File

@ -28,12 +28,13 @@ namespace Glest{ namespace Game{
NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId,
int commandTypeId, const Vec2i &pos, int unitTypeId,
int targetId, int facing, bool wantQueue,
int nextUnitTypeId, int targetId, int facing, bool wantQueue,
CommandStateType commandStateType,
int commandStateValue, int unitCommandGroupId)
: networkCommandType(networkCommandType)
, unitId(unitId)
, unitTypeId(unitTypeId)
, nextUnitTypeId(nextUnitTypeId)
, commandTypeId(commandTypeId)
, positionX(pos.x)
, positionY(pos.y)
@ -48,43 +49,44 @@ NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId,
this->targetId = targetId >= 0 ? targetId : facing;
this->fromFactionIndex = world->getThisFactionIndex();
if(this->networkCommandType == nctGiveCommand) {
const Unit *unit= world->findUnitById(this->unitId);
if(this->networkCommandType == nctGiveCommand) {
const Unit *unit= world->findUnitById(this->unitId);
//validate unit
if(unit != NULL) {
this->unitFactionIndex = unit->getFaction()->getIndex();
this->unitFactionUnitCount = unit->getFaction()->getUnitCount();
//validate unit
if(unit != NULL) {
this->unitFactionIndex = unit->getFaction()->getIndex();
this->unitFactionUnitCount = unit->getFaction()->getUnitCount();
//const UnitType *unitType= world->findUnitTypeById(unit->getFaction()->getType(), this->unitTypeId);
const CommandType *ct = unit->getType()->findCommandTypeById(this->commandTypeId);
if(ct != NULL && ct->getClass() == ccBuild) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str());
CardinalDir::assertDirValid(facing);
assert(targetId == -1);
}
}
}
const CommandType *ct= unit->getType()->findCommandTypeById(this->commandTypeId);
if(ct != NULL && ct->getClass() == ccBuild) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str());
CardinalDir::assertDirValid(facing);
assert(targetId == -1);
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Created NetworkCommand as follows:\n%s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Created NetworkCommand as follows:\n%s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str());
}
void NetworkCommand::preprocessNetworkCommand(World *world) {
if(networkCommandType == nctGiveCommand) {
const Unit *unit= world->findUnitById(unitId);
if(networkCommandType == nctGiveCommand) {
const Unit *unit= world->findUnitById(unitId);
//validate unit
if(unit != NULL) {
//const UnitType *unitType= world->findUnitTypeById(unit->getFaction()->getType(), unitTypeId);
const CommandType *ct = unit->getType()->findCommandTypeById(commandTypeId);
if(ct != NULL && ct->getClass() == ccBuild && targetId >= 0) {
//validate unit
if(unit != NULL) {
const CommandType *ct= unit->getType()->findCommandTypeById(commandTypeId);
if(ct != NULL && ct->getClass() == ccBuild && targetId >= 0) {
CardinalDir::assertDirValid(targetId);
}
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] (unit == NULL) %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str());
}
}
}
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] (unit == NULL) %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str());
}
}
}

View File

@ -94,6 +94,7 @@ public:
networkCommandType=0;
unitId=0;
unitTypeId=0;
nextUnitTypeId=0;
commandTypeId=0;
positionX=0;
positionY=0;
@ -114,6 +115,7 @@ public:
int commandTypeId= -1,
const Vec2i &pos= Vec2i(0),
int unitTypeId= -1,
int nextUnitTypeId= -1,
int targetId= -1,
int facing= -1,
bool wantQueue = false,
@ -124,6 +126,7 @@ public:
int16 networkCommandType;
int32 unitId;
int16 unitTypeId;
int16 nextUnitTypeId;
int16 commandTypeId;
int16 positionX;
int16 positionY;
@ -141,6 +144,7 @@ public:
int getCommandTypeId() const {return commandTypeId;}
Vec2i getPosition() const {return Vec2i(positionX, positionY);}
int getUnitTypeId() const {return unitTypeId;}
int getNextUnitTypeId() const {return nextUnitTypeId;}
int getTargetId() const {return targetId;}
int getWantQueue() const {return wantQueue;}
int getFromFactionIndex() const {return fromFactionIndex;}

View File

@ -76,12 +76,6 @@ Command::Command(const CommandType *ct, const Vec2i &pos, const UnitType *unitTy
//}
}
int Command::getPriority(){
if(this->commandType->commandTypeClass==ccAttack && getUnit()==NULL){
return 5; // attacks to the ground have low priority
}
return this->commandType->getTypePriority();
}
// =============== set ===============
void Command::setCommandType(const CommandType *commandType) {

View File

@ -71,9 +71,6 @@ public:
inline const UnitType* getUnitType() const {return unitType;}
inline CardinalDir getFacing() const {return facing;}
//Priority: commands of higher priority will cancel commands of lower priority
virtual int getPriority();
//set
void setCommandType(const CommandType *commandType);
void setPos(const Vec2i &pos);

View File

@ -745,6 +745,15 @@ void Unit::cleanupAllParticlesystems() {
}
const MorphCommandType* Unit::getCurrMorphCt() const {
auto result = std::find_if(commands.rbegin(), commands.rend(),[](Command *i)
{ return i->getCommandType()->getClass() == ccMorph; });//TODO set CurrMorphCt on push comands instead of looping
if(result != commands.rend()) {
return static_cast<const MorphCommandType*>((*result)->getCommandType());
}
else return NULL;
}
ParticleSystem * Unit::getFire() const {
if(this->fire != NULL &&
Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) {
@ -1828,8 +1837,6 @@ std::pair<CommandResult,string> Unit::giveCommand(Command *command, bool tryQueu
throw megaglest_runtime_error("command->getCommandType() == NULL");
}
const int command_priority = command->getPriority();
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
//printf("In [%s::%s] Line: %d unit [%d - %s] command [%s] tryQueue = %d command->getCommandType()->isQueuable(tryQueue) = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getId(),this->getType()->getName().c_str(), command->getCommandType()->getName().c_str(), tryQueue,command->getCommandType()->isQueuable(tryQueue));
@ -1839,32 +1846,6 @@ std::pair<CommandResult,string> Unit::giveCommand(Command *command, bool tryQueu
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] Command is Queable\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
if(command->getCommandType()->isQueuable() == qAlways && tryQueue){
// Its a produce or upgrade command called without queued key
// in this case we must NOT delete lower priority commands!
// we just queue it!
}
else {
//Delete all lower-prioirty commands
for(list<Command*>::iterator i= commands.begin(); i != commands.end();){
if((*i)->getPriority() < command_priority){
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled)
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] Deleting lower priority command [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(*i)->toString(false).c_str());
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId);
deleteQueuedCommand(*i);
i= commands.erase(i);
safeMutex.ReleaseLock();
}
else {
++i;
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
//cancel current command if it is not queuable
@ -2183,8 +2164,9 @@ void Unit::resetHighlight(){
highlight= 1.f;
}
const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *targetUnit) const{
const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *targetUnit, const UnitType* unitType) const{
const CommandType *commandType= NULL;
unitType= unitType? unitType: type;
if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) {
throw megaglest_runtime_error("#6 Invalid path position = " + pos.getString());
@ -2192,22 +2174,21 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target
SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(pos));
if(type == NULL) {
if(unitType == NULL) {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str());
snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: unitType == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str());
throw megaglest_runtime_error(szBuf);
}
//printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)"));
if(targetUnit != NULL) {
//attack enemies
if(isAlly(targetUnit) == false) {
commandType= type->getFirstAttackCommand(targetUnit->getCurrField());
commandType= unitType->getFirstAttackCommand(targetUnit->getCurrField());
}
//repair allies
else {
if(targetUnit->isBuilt() == false || targetUnit->isDamaged() == true) {
commandType= type->getFirstRepairCommand(targetUnit->getType());
commandType= unitType->getFirstRepairCommand(targetUnit->getType());
}
//printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s] commandType [%p]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)"),commandType);
@ -2223,7 +2204,7 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target
targetUnit->getType() != NULL &&
targetUnit->getType()->getStore(this->getLoadType()) > 0) {
commandType = type->getFirstHarvestEmergencyReturnCommand();
commandType = unitType->getFirstHarvestEmergencyReturnCommand();
}
}
}
@ -2232,7 +2213,7 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target
//check harvest command
Resource *resource= sc->getResource();
if(resource != NULL) {
commandType= type->getFirstHarvestCommand(resource->getType(),this->getFaction());
commandType= unitType->getFirstHarvestCommand(resource->getType(),this->getFaction());
}
}
@ -2247,7 +2228,7 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target
(targetUnit->isBuilt() == false || targetUnit->isDamaged() == true)) {
const RepairCommandType *rct= this->getType()->getFirstRepairCommand(targetUnit->getType());
if(rct != NULL) {
commandType= type->getFirstRepairCommand(targetUnit->getType());
commandType= unitType->getFirstRepairCommand(targetUnit->getType());
//printf("************ Unit will repair building built = %d, repair = %d\n",targetUnit->isBuilt(),targetUnit->isDamaged());
}
}
@ -2257,7 +2238,7 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target
//default command is move command
if(commandType == NULL) {
commandType= type->getFirstCtOfClass(ccMove);
commandType= unitType->getFirstCtOfClass(ccMove);
}
return commandType;
@ -3848,12 +3829,16 @@ std::pair<CommandResult,string> Unit::checkCommand(Command *command) const {
(ignoreCheckCommand == false && this->getFaction()->reqsOk(command->getCommandType()) == false)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] isOperative() = %d, command->getUnit() = %p, getType()->hasCommandType(command->getCommandType()) = %d, this->getFaction()->reqsOk(command->getCommandType()) = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__, __LINE__,isOperative(),command->getUnit(),getType()->hasCommandType(command->getCommandType()),this->getFaction()->reqsOk(command->getCommandType()));
auto mct = getCurrMorphCt();
// Allow self healing if able to heal own unit type
if( command->getUnit() == this &&
command->getCommandType()->getClass() == ccRepair &&
this->getType()->getFirstRepairCommand(this->getType()) != NULL) {
}
else if(mct && mct->getMorphUnit()->hasCommandType(command->getCommandType())) {
// Allow Current Morph Commands
}
else {
//printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command);

View File

@ -653,6 +653,7 @@ public:
}
return NULL;
}
const MorphCommandType* getCurrMorphCt() const;
void replaceCurrCommand(Command *cmd);
int getCountOfProducedUnitsPreExistence(const UnitType *ut) const;
unsigned int getCommandSize() const;
@ -673,7 +674,7 @@ public:
//other
void resetHighlight();
const CommandType *computeCommandType(const Vec2i &pos, const Unit *targetUnit= NULL) const;
const CommandType *computeCommandType(const Vec2i &pos, const Unit *targetUnit= NULL, const UnitType* unitType= NULL) const;
string getDesc(bool translatedValue) const;
string getDescExtension(bool translatedValue) const;
bool computeEp();

View File

@ -125,8 +125,6 @@ public:
Queueability q = isQueuable();
return (q != qNever) && (q != qOnlyLast);
}
//Priority: commands of higher priority will cancel commands of lower priority
virtual int getTypePriority() const {return 10;}
virtual bool usesPathfinder() const= 0;
//get
@ -156,7 +154,6 @@ public:
virtual string getDesc(const TotalUpgrade *totalUpgrade, bool translatedValue) const;
virtual string toString(bool translatedValue) const;
virtual Queueability isQueuable() const {return qNever;}
virtual int getTypePriority() const {return 100000;}
//get
const StopSkillType *getStopSkillType() const {return stopSkillType;};
@ -230,6 +227,7 @@ public:
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,vector<pair<string, string> > > &loadedFileList, string parentLoader);
virtual string getDesc(const TotalUpgrade *totalUpgrade, bool translatedValue) const;
virtual Queueability isQueuable() const {return qOnlyLast;}
virtual string toString(bool translatedValue) const;
//get
@ -386,7 +384,6 @@ public:
virtual string toString(bool translatedValue) const;
virtual const ProducibleType *getProduced() const;
virtual Queueability isQueuable() const {return qAlways;}
virtual int getTypePriority() const {return 15;}
//get
const ProduceSkillType *getProduceSkillType() const {return produceSkillType;}
@ -416,7 +413,6 @@ public:
virtual string getReqDesc(bool translatedValue) const;
virtual const ProducibleType *getProduced() const;
virtual Queueability isQueuable() const {return qAlways;}
virtual int getTypePriority() const {return 15;}
//get
const UpgradeSkillType *getUpgradeSkillType() const {return upgradeSkillType;}
@ -446,7 +442,7 @@ public:
virtual string toString(bool translatedValue) const;
virtual string getReqDesc(bool translatedValue) const;
virtual const ProducibleType *getProduced() const;
Queueability isQueuable() const {return qOnlyLast;} //After morph anything can happen
Queueability isQueuable() const {return qAlways;} //After morph anything can happen
//get
const MorphSkillType *getMorphSkillType() const {return morphSkillType;}

View File

@ -720,167 +720,137 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if( (command->getUnit() == NULL || !(command->getUnit()->isAlive()) ) && unit->getCommandSize() > 1) {
if(attackableOnRange(unit, &target, act->getAttackSkillType(),(frameIndex >= 0))) {
if(frameIndex < 0) {
unit->finishCommand(); // all queued "ground attacks" are skipped if somthing else is queued after them.
if(unit->getEp() >= act->getAttackSkillType()->getEpCost()) {
unit->setCurrSkill(act->getAttackSkillType());
unit->setTarget(target);
}
else {
unit->setCurrSkill(scStop);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
char szBuf[8096]="";
snprintf(szBuf,8096,"[updateAttack]");
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
}
return;
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
//if found
//if(frameIndex < 0) {
{
if(attackableOnRange(unit, &target, act->getAttackSkillType(),(frameIndex >= 0))) {
if(frameIndex < 0) {
if(unit->getEp() >= act->getAttackSkillType()->getEpCost()) {
unit->setCurrSkill(act->getAttackSkillType());
unit->setTarget(target);
}
else {
unit->setCurrSkill(scStop);
}
else {
//compute target pos
Vec2i pos;
if(command->getUnit() != NULL) {
pos= command->getUnit()->getCenteredPos();
}
else if(attackableOnSight(unit, &target, act->getAttackSkillType(), (frameIndex >= 0))) {
pos= target->getPos();
}
else {
pos= command->getPos();
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
char szBuf[8096]="";
snprintf(szBuf,8096,"[updateAttack] pos [%s] unit->getPos() [%s]",pos.getString().c_str(),unit->getPos().getString().c_str());
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
TravelState tsValue = tsImpossible;
//if(frameIndex < 0) {
{
//printf("In [%s::%s Line: %d] START pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str());
//fflush(stdout);
switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic:
tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex);
break;
default:
throw megaglest_runtime_error("detected unsupported pathfinder type!");
}
//printf("In [%s::%s Line: %d] END pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str());
//fflush(stdout);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(frameIndex < 0) {
if(command->getUnit() != NULL && !command->getUnit()->isAlive() && unit->getCommandSize() > 1) {
// don't run over to dead body if there is still something to do in the queue
unit->finishCommand();
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
char szBuf[8096]="";
snprintf(szBuf,8096,"[updateAttack]");
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
else {
//compute target pos
Vec2i pos;
if(command->getUnit() != NULL) {
pos= command->getUnit()->getCenteredPos();
}
else if(attackableOnSight(unit, &target, act->getAttackSkillType(), (frameIndex >= 0))) {
pos= target->getPos();
}
else {
pos= command->getPos();
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
char szBuf[8096]="";
snprintf(szBuf,8096,"[updateAttack] pos [%s] unit->getPos() [%s]",pos.getString().c_str(),unit->getPos().getString().c_str());
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
TravelState tsValue = tsImpossible;
//if(frameIndex < 0) {
{
//printf("In [%s::%s Line: %d] START pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str());
//fflush(stdout);
switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic:
tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex);
//if unit arrives destPos order has ended
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"#1 [updateAttack] tsValue = %d",tsValue);
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
switch (tsValue) {
case tsMoving:
unit->setCurrSkill(act->getMoveSkillType());
break;
case tsBlocked:
if(unit->getPath()->isBlocked()) {
unit->finishCommand();
}
break;
default:
throw megaglest_runtime_error("detected unsupported pathfinder type!");
}
//printf("In [%s::%s Line: %d] END pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str());
//fflush(stdout);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(frameIndex < 0) {
if(command->getUnit() != NULL && !command->getUnit()->isAlive() && unit->getCommandSize() > 1) {
// don't run over to dead body if there is still something to do in the queue
unit->finishCommand();
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
char szBuf[8096]="";
snprintf(szBuf,8096,"[updateAttack]");
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
unit->finishCommand();
break;
}
}
else {
//if unit arrives destPos order has ended
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"#1 [updateAttack] tsValue = %d",tsValue);
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
switch (tsValue) {
case tsMoving:
unit->setCurrSkill(act->getMoveSkillType());
break;
case tsBlocked:
if(unit->getPath()->isBlocked()) {
unit->finishCommand();
}
break;
default:
unit->finishCommand();
break;
}
/*
case tsMoving:
unit->setCurrSkill(act->getMoveSkillType());
{
std::pair<bool,Unit *> beingAttacked = unitBeingAttacked(unit);
if(beingAttacked.first == true) {
Unit *enemy = beingAttacked.second;
const AttackCommandType *act_forenemy = unit->getType()->getFirstAttackCommand(enemy->getCurrField());
if(act_forenemy != NULL) {
if(unit->getEp() >= act_forenemy->getAttackSkillType()->getEpCost()) {
unit->setCurrSkill(act_forenemy->getAttackSkillType());
unit->setTarget(enemy);
}
//aiInterface->giveCommand(i, act_forenemy, beingAttacked.second->getPos());
case tsMoving:
unit->setCurrSkill(act->getMoveSkillType());
{
std::pair<bool,Unit *> beingAttacked = unitBeingAttacked(unit);
if(beingAttacked.first == true) {
Unit *enemy = beingAttacked.second;
const AttackCommandType *act_forenemy = unit->getType()->getFirstAttackCommand(enemy->getCurrField());
if(act_forenemy != NULL) {
if(unit->getEp() >= act_forenemy->getAttackSkillType()->getEpCost()) {
unit->setCurrSkill(act_forenemy->getAttackSkillType());
unit->setTarget(enemy);
}
else {
const AttackStoppedCommandType *asct_forenemy = unit->getType()->getFirstAttackStoppedCommand(enemy->getCurrField());
if(asct_forenemy != NULL) {
//aiInterface->giveCommand(i, asct_forenemy, beingAttacked.second->getCenteredPos());
if(unit->getEp() >= asct_forenemy->getAttackSkillType()->getEpCost()) {
unit->setCurrSkill(asct_forenemy->getAttackSkillType());
unit->setTarget(enemy);
}
//aiInterface->giveCommand(i, act_forenemy, beingAttacked.second->getPos());
}
else {
const AttackStoppedCommandType *asct_forenemy = unit->getType()->getFirstAttackStoppedCommand(enemy->getCurrField());
if(asct_forenemy != NULL) {
//aiInterface->giveCommand(i, asct_forenemy, beingAttacked.second->getCenteredPos());
if(unit->getEp() >= asct_forenemy->getAttackSkillType()->getEpCost()) {
unit->setCurrSkill(asct_forenemy->getAttackSkillType());
unit->setTarget(enemy);
}
}
}
}
break;
case tsBlocked:
if(unit->getPath()->isBlocked()){
unit->finishCommand();
}
break;
default:
}
break;
case tsBlocked:
if(unit->getPath()->isBlocked()){
unit->finishCommand();
}
}
break;
default:
unit->finishCommand();
}
*/
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"#2 [updateAttack] tsValue = %d",tsValue);
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 &&
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) {
char szBuf[8096]="";
snprintf(szBuf,8096,"#2 [updateAttack] tsValue = %d",tsValue);
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
@ -1350,7 +1320,7 @@ void UnitUpdater::updateHarvestEmergencyReturn(Unit *unit, int frameIndex) {
if(previousHarvestCmd != NULL) {
//printf("\n\n#1a return harvested resources\n\n");
NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), previousHarvestCmd->getId(), unit->getLastHarvestedResourcePos(),
-1, Unit::invalidId, -1, false, cst_None, -1, -1);
-1, -1, Unit::invalidId, -1, false, cst_None, -1, -1);
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -2088,7 +2058,7 @@ void UnitUpdater::updateRepair(Unit *unit, int frameIndex) {
const CommandType *ctbuild = unit->getType()->getFirstCtOfClass(ccBuild);
NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), ctbuild->getId(), command->getPos(),
command->getUnitType()->getId(), -1, CardinalDir(CardinalDir::NORTH), true, command->getStateType(),
command->getUnitType()->getId(), -1, -1, CardinalDir(CardinalDir::NORTH), true, command->getStateType(),
command->getStateValue());
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -2918,97 +2888,86 @@ void UnitUpdater::findEnemiesForCell(const Vec2i pos, int size, int sightRange,
//if the unit has any enemy on range
bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
const AttackSkillType *ast,bool evalMode) {
const AttackSkillType *ast,bool evalMode) {
bool result=false;
try {
vector<Unit*> enemies;
enemies.reserve(100);
vector<Unit*> enemies;
enemies.reserve(100);
//we check command target
const Unit *commandTarget = NULL;
if(unit->anyCommand() && unit->getCurrCommand() != NULL) {
commandTarget = static_cast<const Unit*>(unit->getCurrCommand()->getUnit());
}
if(commandTarget != NULL && commandTarget->isDead()) {
commandTarget = NULL;
}
//aux vars
int size = unit->getType()->getSize();
Vec2i center = unit->getPos();
Vec2f floatCenter = unit->getFloatCenteredPos();
//we check command target
const Unit *commandTarget = NULL;
if(unit->anyCommand() && unit->getCurrCommand() != NULL) {
commandTarget = static_cast<const Unit*>(unit->getCurrCommand()->getUnit());
}
if(commandTarget != NULL && commandTarget->isDead()) {
commandTarget = NULL;
}
//aux vars
int size = unit->getType()->getSize();
Vec2i center = unit->getPos();
Vec2f floatCenter = unit->getFloatCenteredPos();
//bool foundInCache = true;
if(findCachedCellsEnemies(center,range,size,enemies,ast,
unit,commandTarget) == false) {
//bool foundInCache = true;
if(findCachedCellsEnemies(center,range,size,enemies,ast,
unit,commandTarget) == false) {
//foundInCache = false;
//nearby cells
UnitRangeCellsLookupItem cacheItem;
for(int i = center.x - range; i < center.x + range + size; ++i) {
for(int j = center.y - range; j < center.y + range + size; ++j) {
//cells inside map and in range
//foundInCache = false;
//nearby cells
UnitRangeCellsLookupItem cacheItem;
for(int i = center.x - range; i < center.x + range + size; ++i) {
for(int j = center.y - range; j < center.y + range + size; ++j) {
//cells inside map and in range
#ifdef USE_STREFLOP
if(map->isInside(i, j) && streflop::floor(static_cast<streflop::Simple>(floatCenter.dist(Vec2f((float)i, (float)j)))) <= (range+1)){
if(map->isInside(i, j) && streflop::floor(static_cast<streflop::Simple>(floatCenter.dist(Vec2f((float)i, (float)j)))) <= (range+1))
#else
if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){
if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1))
#endif
Cell *cell = map->getCell(i,j);
findEnemiesForCell(ast,cell,unit,commandTarget,enemies);
{
Cell *cell = map->getCell(i,j);
findEnemiesForCell(ast,cell,unit,commandTarget,enemies);
cacheItem.rangeCellList.push_back(cell);
cacheItem.rangeCellList.push_back(cell);
}
}
}
// Ok update our caches with the latest info
if(cacheItem.rangeCellList.empty() == false) {
MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache,string(__FILE__) + "_" + intToStr(__LINE__));
UnitRangeCellsLookupItemCache[center][size][range] = cacheItem;
}
}
// Ok update our caches with the latest info
if(cacheItem.rangeCellList.empty() == false) {
MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache,string(__FILE__) + "_" + intToStr(__LINE__));
UnitRangeCellsLookupItemCache[center][size][range] = cacheItem;
}
}
//attack enemies that can attack first
float distToUnit= -1;
Unit* enemySeen= NULL;
std::vector<Unit*> fightingEnemiesInRange;
std::vector<Unit*> damagedFightingEnemiesInRange;
Unit* myFightingEnemyInRange= NULL;
float distToStandingUnit= -1;
Unit* attackingEnemySeen= NULL;
ControlType controlType= unit->getFaction()->getControlType();
bool isUltra= controlType == ctCpuUltra || controlType == ctNetworkCpuUltra;
bool isMega= controlType == ctCpuMega || controlType == ctNetworkCpuMega;
string randomInfoData = "enemies.size() = " + intToStr(enemies.size());
//printf("unit %d has control:%d\n",unit->getId(),controlType);
for(int i = 0; i< (int)enemies.size(); ++i) {
Unit *enemy = enemies[i];
if(enemy != NULL && enemy->isAlive() == true) {
// Here we default to first enemy if no attackers found
if(enemySeen == NULL) {
*rangedPtr = enemy;
enemySeen = enemy;
result = true;
}
//randomInfoData += " i = " + intToStr(i) + " alive = true result = " + intToStr(result);
// Attackers get first priority
if(enemy->getType()->hasSkillClass(scAttack) == true) {
float currentDist = unit->getCenteredPos().dist(enemy->getCenteredPos());
//randomInfoData += " currentDist = " + floatToStr(currentDist);
//attack enemies that can attack first
float distToUnit= -1;
Unit* enemySeen= NULL;
std::vector<Unit*> fightingEnemiesInRange;
std::vector<Unit*> damagedFightingEnemiesInRange;
Unit* myFightingEnemyInRange= NULL;
float distToStandingUnit= -1;
Unit* attackingEnemySeen= NULL;
ControlType controlType= unit->getFaction()->getControlType();
bool isUltra= controlType == ctCpuUltra || controlType == ctNetworkCpuUltra;
bool isMega= controlType == ctCpuMega || controlType == ctNetworkCpuMega;
string randomInfoData = "enemies.size() = " + intToStr(enemies.size());
//printf("unit %d has control:%d\n",unit->getId(),controlType);
for(int i = 0; i< (int)enemies.size(); ++i) {
Unit *enemy = enemies[i];
if(enemy != NULL && enemy->isAlive() == true) {
// Here we default to first enemy if no attackers found
if(enemySeen == NULL) {
*rangedPtr = enemy;
enemySeen = enemy;
result = true;
}
//randomInfoData += " i = " + intToStr(i) + " alive = true result = " + intToStr(result);
// Attackers get first priority
if(enemy->getType()->hasSkillClass(scAttack) == true) {
float currentDist = unit->getCenteredPos().dist(enemy->getCenteredPos());
//randomInfoData += " currentDist = " + floatToStr(currentDist);
// Select closest attacking unit
if (distToUnit < 0 || currentDist < distToUnit) {
distToUnit = currentDist;
@ -3041,10 +3000,9 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
}
}
}
}
}
}
}
}
}
if (evalMode == false) {
bool doUltra = false;
if (isMega) {
@ -3062,7 +3020,6 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
unitList = &damagedFightingEnemiesInRange;
else
unitList = &fightingEnemiesInRange;
//printf("Choosing new one\n");
int myChoice = unit->getRandom()->randRange(1, unitList->size(), extractFileFromDirectoryPath(__FILE__) + intToStr(__LINE__));
//printf("myChoice=%d\n", myChoice);
@ -3085,95 +3042,90 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
}
if(result == true) {
if(result == true) {
//const Unit* teamUnit = NULL;
const Unit* enemyUnit = NULL;
bool onlyEnemyUnits = true;
//const Unit* teamUnit = NULL;
const Unit* enemyUnit = NULL;
bool onlyEnemyUnits = true;
if(unit->getTeam() == world->getThisTeamIndex()) {
//teamUnit = unit;
enemyUnit = enemySeen;
onlyEnemyUnits = false;
}
else if(enemySeen->getTeam() == world->getThisTeamIndex()) {
//teamUnit = enemySeen;
enemyUnit = unit;
onlyEnemyUnits = false;
}
if(unit->getTeam() == world->getThisTeamIndex()) {
//teamUnit = unit;
enemyUnit = enemySeen;
onlyEnemyUnits = false;
}
else if(enemySeen->getTeam() == world->getThisTeamIndex()) {
//teamUnit = enemySeen;
enemyUnit = unit;
onlyEnemyUnits = false;
}
if(evalMode == false && onlyEnemyUnits == false &&
enemyUnit->getTeam() != world->getThisTeamIndex()) {
Vec2f enemyFloatCenter = enemyUnit->getFloatCenteredPos();
// find nearest Attack and cleanup old dates
AttackWarningData *nearest = NULL;
float currentDistance = 0.f;
float nearestDistance = 0.f;
if(evalMode == false && onlyEnemyUnits == false &&
enemyUnit->getTeam() != world->getThisTeamIndex()) {
Vec2f enemyFloatCenter = enemyUnit->getFloatCenteredPos();
// find nearest Attack and cleanup old dates
AttackWarningData *nearest = NULL;
float currentDistance = 0.f;
float nearestDistance = 0.f;
MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
for(int i = (int)attackWarnings.size() - 1; i >= 0; --i) {
if(world->getFrameCount() - attackWarnings[i]->lastFrameCount > 200) { //after 200 frames attack break we warn again
AttackWarningData *toDelete =attackWarnings[i];
attackWarnings.erase(attackWarnings.begin()+i);
delete toDelete; // old one
}
else {
#ifdef USE_STREFLOP
currentDistance = streflop::floor(static_cast<streflop::Simple>(enemyFloatCenter.dist(attackWarnings[i]->attackPosition))); // no need for streflops here!
#else
currentDistance = floor(enemyFloatCenter.dist(attackWarnings[i]->attackPosition)); // no need for streflops here!
#endif
if(nearest == NULL) {
nearest = attackWarnings[i];
nearestDistance = currentDistance;
MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
for(int i = (int)attackWarnings.size() - 1; i >= 0; --i) {
if(world->getFrameCount() - attackWarnings[i]->lastFrameCount > 200) { //after 200 frames attack break we warn again
AttackWarningData *toDelete =attackWarnings[i];
attackWarnings.erase(attackWarnings.begin()+i);
delete toDelete; // old one
}
else {
if(currentDistance < nearestDistance) {
#ifdef USE_STREFLOP
currentDistance = streflop::floor(static_cast<streflop::Simple>(enemyFloatCenter.dist(attackWarnings[i]->attackPosition))); // no need for streflops here!
#else
currentDistance = floor(enemyFloatCenter.dist(attackWarnings[i]->attackPosition)); // no need for streflops here!
#endif
if(nearest == NULL) {
nearest = attackWarnings[i];
nearestDistance = currentDistance;
}
else {
if(currentDistance < nearestDistance) {
nearest = attackWarnings[i];
nearestDistance = currentDistance;
}
}
}
}
}
if(nearest != NULL) {
// does it fit?
if(nearestDistance < attackWarnRange) {
// update entry with current values
nearest->lastFrameCount=world->getFrameCount();
nearest->attackPosition.x=enemyFloatCenter.x;
nearest->attackPosition.y=enemyFloatCenter.y;
}
else {
//Must be a different Attack!
nearest=NULL; //set to null to force a new entry in next step
}
}
// add new attack
if(nearest == NULL) {
// no else!
AttackWarningData* awd= new AttackWarningData();
awd->lastFrameCount=world->getFrameCount();
awd->attackPosition.x=enemyFloatCenter.x;
awd->attackPosition.y=enemyFloatCenter.y;
MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
attackWarnings.push_back(awd);
if(nearest != NULL) {
// does it fit?
if(nearestDistance < attackWarnRange) {
// update entry with current values
nearest->lastFrameCount=world->getFrameCount();
nearest->attackPosition.x=enemyFloatCenter.x;
nearest->attackPosition.y=enemyFloatCenter.y;
}
else {
//Must be a different Attack!
nearest=NULL; //set to null to force a new entry in next step
}
}
// add new attack
if(nearest == NULL) {
// no else!
AttackWarningData* awd= new AttackWarningData();
awd->lastFrameCount=world->getFrameCount();
awd->attackPosition.x=enemyFloatCenter.x;
awd->attackPosition.y=enemyFloatCenter.y;
MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
attackWarnings.push_back(awd);
if(world->getAttackWarningsEnabled() == true) {
SoundRenderer::getInstance().playFx(CoreData::getInstance().getAttentionSound(),true);
world->addAttackEffects(enemyUnit);
}
}
if(world->getAttackWarningsEnabled() == true) {
SoundRenderer::getInstance().playFx(CoreData::getInstance().getAttentionSound(),true);
world->addAttackEffects(enemyUnit);
}
}
}
}
}
}
catch(const exception &ex) {
//setRunningStatus(false);