- bugfix for AI repairing fixes a long standing legacy bug where the AI never repaired units with a cell map starting with a 0 at the first x,y in the cellmap (like magic faction).
This commit is contained in:
parent
ae9d20a6cf
commit
f71f83d2b8
|
@ -367,7 +367,7 @@ const Resource *AiInterface::getResource(const ResourceType *rt){
|
||||||
return world->getFaction(factionIndex)->getResource(rt);
|
return world->getFaction(factionIndex)->getResource(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Unit *AiInterface::getMyUnit(int unitIndex){
|
Unit *AiInterface::getMyUnitPtr(int unitIndex) {
|
||||||
if(unitIndex >= world->getFaction(factionIndex)->getUnitCount()) {
|
if(unitIndex >= world->getFaction(factionIndex)->getUnitCount()) {
|
||||||
char szBuf[1024]="";
|
char szBuf[1024]="";
|
||||||
sprintf(szBuf,"In [%s::%s Line: %d] unitIndex >= world->getFaction(factionIndex)->getUnitCount(), unitIndex = %d, world->getFaction(factionIndex)->getUnitCount() = %d",__FILE__,__FUNCTION__,__LINE__,unitIndex,world->getFaction(factionIndex)->getUnitCount());
|
sprintf(szBuf,"In [%s::%s Line: %d] unitIndex >= world->getFaction(factionIndex)->getUnitCount(), unitIndex = %d, world->getFaction(factionIndex)->getUnitCount() = %d",__FILE__,__FUNCTION__,__LINE__,unitIndex,world->getFaction(factionIndex)->getUnitCount());
|
||||||
|
@ -377,6 +377,10 @@ const Unit *AiInterface::getMyUnit(int unitIndex){
|
||||||
return world->getFaction(factionIndex)->getUnit(unitIndex);
|
return world->getFaction(factionIndex)->getUnit(unitIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Unit *AiInterface::getMyUnit(int unitIndex) {
|
||||||
|
return getMyUnitPtr(unitIndex);
|
||||||
|
}
|
||||||
|
|
||||||
const Unit *AiInterface::getOnSightUnit(int unitIndex) {
|
const Unit *AiInterface::getOnSightUnit(int unitIndex) {
|
||||||
|
|
||||||
int count=0;
|
int count=0;
|
||||||
|
|
|
@ -81,6 +81,7 @@ public:
|
||||||
int onSightUnitCount();
|
int onSightUnitCount();
|
||||||
const Resource *getResource(const ResourceType *rt);
|
const Resource *getResource(const ResourceType *rt);
|
||||||
const Unit *getMyUnit(int unitIndex);
|
const Unit *getMyUnit(int unitIndex);
|
||||||
|
Unit *getMyUnitPtr(int unitIndex);
|
||||||
const Unit *getOnSightUnit(int unitIndex);
|
const Unit *getOnSightUnit(int unitIndex);
|
||||||
const FactionType *getMyFactionType();
|
const FactionType *getMyFactionType();
|
||||||
Faction *getMyFaction();
|
Faction *getMyFaction();
|
||||||
|
|
|
@ -91,16 +91,37 @@ AiRuleRepair::AiRuleRepair(Ai *ai):
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double AiRuleRepair::getMinCastleHpRatio() {
|
||||||
|
return 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AiRuleRepair::getMinUnitsToRepairCastle() {
|
||||||
|
int minUnitsRepairingCastle = 7;
|
||||||
|
if(ai->getCountOfClass(ucWorker) <= 4) {
|
||||||
|
minUnitsRepairingCastle = 1;
|
||||||
|
}
|
||||||
|
else if(ai->getCountOfClass(ucWorker) <= 6) {
|
||||||
|
minUnitsRepairingCastle = 2;
|
||||||
|
}
|
||||||
|
else if(ai->getCountOfClass(ucWorker) <= 10) {
|
||||||
|
minUnitsRepairingCastle = 5;
|
||||||
|
}
|
||||||
|
return minUnitsRepairingCastle;
|
||||||
|
}
|
||||||
|
|
||||||
bool AiRuleRepair::test(){
|
bool AiRuleRepair::test(){
|
||||||
AiInterface *aiInterface= ai->getAiInterface();
|
AiInterface *aiInterface= ai->getAiInterface();
|
||||||
|
|
||||||
const int minUnitsRepairingCastle = 7;
|
int minUnitsRepairingCastle = getMinUnitsToRepairCastle();
|
||||||
|
const double minCastleHpRatio = getMinCastleHpRatio();
|
||||||
|
|
||||||
// look for a damaged unit and give priority to the factions bases
|
// look for a damaged unit and give priority to the factions bases
|
||||||
// (units that produce workers and store resources)
|
// (units that produce workers and store resources)
|
||||||
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
||||||
const Unit *u= aiInterface->getMyUnit(i);
|
const Unit *u= aiInterface->getMyUnit(i);
|
||||||
//printf("\n\n\n\n!!!!!! Is damaged unit [%d - %s] u->getHpRatio() = %f, hp = %d, mapHp = %d\n",u->getId(),u->getType()->getName().c_str(),u->getHpRatio(),u->getHp(),u->getType()->getTotalMaxHp(u->getTotalUpgrade()));
|
//printf("\n\n\n\n!!!!!! Is damaged unit [%d - %s] u->getHpRatio() = %f, hp = %d, mapHp = %d\n",u->getId(),u->getType()->getName().c_str(),u->getHpRatio(),u->getHp(),u->getType()->getTotalMaxHp(u->getTotalUpgrade()));
|
||||||
if(u->getHpRatio() < 1.f) {
|
if(u->getHpRatio() < 1.f) {
|
||||||
|
//printf("\n\n\n\n!!!!!! Is damaged unit [%d - %s] u->getHpRatio() = %f, hp = %d, mapHp = %d\n",u->getId(),u->getType()->getName().c_str(),u->getHpRatio(),u->getHp(),u->getType()->getTotalMaxHp(u->getTotalUpgrade()));
|
||||||
|
|
||||||
bool unitCanProduceWorker = false;
|
bool unitCanProduceWorker = false;
|
||||||
for(int j = 0; unitCanProduceWorker == false &&
|
for(int j = 0; unitCanProduceWorker == false &&
|
||||||
|
@ -114,6 +135,7 @@ bool AiRuleRepair::test(){
|
||||||
const UnitType *ut = dynamic_cast<const UnitType *>(pt);
|
const UnitType *ut = dynamic_cast<const UnitType *>(pt);
|
||||||
if( ut != NULL && ut->hasCommandClass(ccHarvest) == true &&
|
if( ut != NULL && ut->hasCommandClass(ccHarvest) == true &&
|
||||||
u->getType()->getStoredResourceCount() > 0) {
|
u->getType()->getStoredResourceCount() > 0) {
|
||||||
|
//printf("\n\n\n\n!!!!!! found candidate castle unit to repair [%d - %s]\n",u->getId(),u->getType()->getName().c_str());
|
||||||
unitCanProduceWorker = true;
|
unitCanProduceWorker = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +152,10 @@ bool AiRuleRepair::test(){
|
||||||
//if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u1->getId(),u1->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType()));
|
//if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u1->getId(),u1->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType()));
|
||||||
|
|
||||||
if(rct != NULL) {
|
if(rct != NULL) {
|
||||||
if(u1->getCurrSkill()->getClass() == scStop || u1->getCurrSkill()->getClass() == scMove) {
|
//printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can repair damaged unit [%d] Castles hp-ratio = %f\n",u1->getId(),u1->getType()->getName().c_str(),u1->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType()),u->getHpRatio());
|
||||||
|
|
||||||
|
if(u1->getCurrSkill()->getClass() == scStop || u1->getCurrSkill()->getClass() == scMove ||
|
||||||
|
u->getHpRatio() <= minCastleHpRatio) {
|
||||||
if(rct->isRepairableUnitType(u->getType())) {
|
if(rct->isRepairableUnitType(u->getType())) {
|
||||||
candidatedamagedUnitIndex= i;
|
candidatedamagedUnitIndex= i;
|
||||||
//return true;
|
//return true;
|
||||||
|
@ -140,6 +165,7 @@ bool AiRuleRepair::test(){
|
||||||
Command *cmd = u1->getCurrCommand();
|
Command *cmd = u1->getCurrCommand();
|
||||||
if(cmd != NULL && cmd->getCommandType()->getClass() == ccRepair) {
|
if(cmd != NULL && cmd->getCommandType()->getClass() == ccRepair) {
|
||||||
if(cmd->getUnit() != NULL && cmd->getUnit()->getId() == u->getId()) {
|
if(cmd->getUnit() != NULL && cmd->getUnit()->getId() == u->getId()) {
|
||||||
|
//printf("\n\n\n\n^^^^^^^^^^ unit is ALREADY repairer unit [%d - %s]\n",u1->getId(),u1->getType()->getName().c_str());
|
||||||
unitCountAlreadyRepairingDamagedUnit++;
|
unitCountAlreadyRepairingDamagedUnit++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,6 +174,7 @@ bool AiRuleRepair::test(){
|
||||||
}
|
}
|
||||||
|
|
||||||
if(candidatedamagedUnitIndex >= 0 && unitCountAlreadyRepairingDamagedUnit < minUnitsRepairingCastle) {
|
if(candidatedamagedUnitIndex >= 0 && unitCountAlreadyRepairingDamagedUnit < minUnitsRepairingCastle) {
|
||||||
|
//printf("\n\n\n\n^^^^^^^^^^ AI test will repair damaged unit [%d - %s]\n",u->getId(),u->getType()->getName().c_str());
|
||||||
damagedUnitIndex = candidatedamagedUnitIndex;
|
damagedUnitIndex = candidatedamagedUnitIndex;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -183,18 +210,41 @@ void AiRuleRepair::execute() {
|
||||||
const Unit *damagedUnit= aiInterface->getMyUnit(damagedUnitIndex);
|
const Unit *damagedUnit= aiInterface->getMyUnit(damagedUnitIndex);
|
||||||
//printf("\n\n\n\n###^^^^^^^^^^ Looking for repairer for damaged unit [%d - %s]\n",damagedUnit->getId(),damagedUnit->getType()->getName().c_str());
|
//printf("\n\n\n\n###^^^^^^^^^^ Looking for repairer for damaged unit [%d - %s]\n",damagedUnit->getId(),damagedUnit->getType()->getName().c_str());
|
||||||
|
|
||||||
|
int minUnitsRepairingCastle = getMinUnitsToRepairCastle();
|
||||||
|
const double minCastleHpRatio = getMinCastleHpRatio();
|
||||||
|
|
||||||
//find a repairer and issue command
|
//find a repairer and issue command
|
||||||
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
||||||
const Unit *u= aiInterface->getMyUnit(i);
|
const Unit *u= aiInterface->getMyUnit(i);
|
||||||
const RepairCommandType *rct= static_cast<const RepairCommandType *>(u->getType()->getFirstCtOfClass(ccRepair));
|
const RepairCommandType *rct= static_cast<const RepairCommandType *>(u->getType()->getFirstCtOfClass(ccRepair));
|
||||||
//if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u->getId(),u->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(damagedUnit->getType()));
|
//if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u->getId(),u->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(damagedUnit->getType()));
|
||||||
|
|
||||||
if(rct != NULL && (u->getCurrSkill()->getClass() == scStop || u->getCurrSkill()->getClass() == scMove)) {
|
if(rct != NULL) {
|
||||||
if(rct->isRepairableUnitType(damagedUnit->getType())) {
|
//printf("\n\n\n\n^^^^^^^^^^ possible excute repairer unit [%d - %s] current skill [%d] can repair damaged unit [%d] Castles hp-ratio = %f\n",u->getId(),u->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(damagedUnit->getType()),damagedUnit->getHpRatio());
|
||||||
//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
||||||
aiInterface->giveCommand(i, rct, damagedUnit->getPos());
|
if((u->getCurrSkill()->getClass() == scStop || u->getCurrSkill()->getClass() == scMove || damagedUnit->getHpRatio() <= minCastleHpRatio)) {
|
||||||
aiInterface->printLog(3, "Repairing order issued");
|
if(rct->isRepairableUnitType(damagedUnit->getType())) {
|
||||||
return;
|
//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
//printf("\n\n\n\n^^^^^^^^^^ AI execute will repair damaged unit [%d - %s] at pos [%s] cellmapPos [%s] using unit [%d -%s]\n",damagedUnit->getId(),damagedUnit->getType()->getName().c_str(),damagedUnit->getPos().getString().c_str(),damagedUnit->getPosWithCellMapSet().getString().c_str(),u->getId(),u->getType()->getName().c_str());
|
||||||
|
|
||||||
|
/*
|
||||||
|
Map *map= aiInterface->getWorld()->getMap();
|
||||||
|
Cell *cell = map->getCell(damagedUnit->getPosWithCellMapSet());
|
||||||
|
if(cell != NULL) {
|
||||||
|
printf("\n\n\n\n^^^^^^^^^^ cell is ok\n");
|
||||||
|
|
||||||
|
Unit *cellUnit = cell->getUnit(damagedUnit->getCurrField());
|
||||||
|
if(cellUnit != NULL) {
|
||||||
|
printf("\n\n\n\n^^^^^^^^^^ cell unit [%d - %s] at pos [%s]\n",cellUnit->getId(),cellUnit->getType()->getName().c_str(),cellUnit->getPos().getString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//aiInterface->giveCommand(i, rct, damagedUnit->getPos());
|
||||||
|
aiInterface->giveCommand(i, rct, damagedUnit->getPosWithCellMapSet());
|
||||||
|
aiInterface->printLog(3, "Repairing order issued");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,9 @@ class AiRuleRepair: public AiRule{
|
||||||
private:
|
private:
|
||||||
int damagedUnitIndex;
|
int damagedUnitIndex;
|
||||||
|
|
||||||
|
int getMinUnitsToRepairCastle();
|
||||||
|
double getMinCastleHpRatio();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AiRuleRepair(Ai *ai);
|
AiRuleRepair(Ai *ai);
|
||||||
|
|
||||||
|
|
|
@ -2136,6 +2136,11 @@ bool Unit::isLastStuckFrameWithinCurrentFrameTolerance() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec2i Unit::getPosWithCellMapSet() const {
|
||||||
|
Vec2i cellMapPos = this->getType()->getFirstOccupiedCellInCellMap(pos);
|
||||||
|
return cellMapPos;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Unit::toString() const {
|
std::string Unit::toString() const {
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
|
|
||||||
|
|
|
@ -389,6 +389,7 @@ public:
|
||||||
|
|
||||||
//pos
|
//pos
|
||||||
Vec2i getPos() const {return pos;}
|
Vec2i getPos() const {return pos;}
|
||||||
|
Vec2i getPosWithCellMapSet() const;
|
||||||
Vec2i getLastPos() const {return lastPos;}
|
Vec2i getLastPos() const {return lastPos;}
|
||||||
Vec2i getCenteredPos() const;
|
Vec2i getCenteredPos() const;
|
||||||
Vec2f getFloatCenteredPos() const;
|
Vec2f getFloatCenteredPos() const;
|
||||||
|
|
|
@ -612,6 +612,25 @@ bool UnitType::hasEmptyCellMap() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec2i UnitType::getFirstOccupiedCellInCellMap(Vec2i currentPos) const {
|
||||||
|
Vec2i cell = currentPos;
|
||||||
|
//printf("\n\n\n\n^^^^^^^^^^ currentPos [%s] size [%d]\n",currentPos.getString().c_str(),size);
|
||||||
|
|
||||||
|
//checkItemInVault(&(this->size),this->size);
|
||||||
|
for(int i = 0; i < size; ++i) {
|
||||||
|
for(int j = 0; j < size; ++j){
|
||||||
|
if(cellMap[i*size+j] == true) {
|
||||||
|
cell.x += i;
|
||||||
|
cell.y += j;
|
||||||
|
//printf("\n^^^^^^^^^^ cell [%s] i [%d] j [%d]\n",cell.getString().c_str(),i,j);
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
bool UnitType::getCellMapCell(int x, int y, CardinalDir facing) const {
|
bool UnitType::getCellMapCell(int x, int y, CardinalDir facing) const {
|
||||||
assert(cellMap);
|
assert(cellMap);
|
||||||
if(cellMap == NULL) {
|
if(cellMap == NULL) {
|
||||||
|
|
|
@ -200,6 +200,7 @@ public:
|
||||||
bool hasCellMap() const {return cellMap!=NULL;}
|
bool hasCellMap() const {return cellMap!=NULL;}
|
||||||
bool getAllowEmptyCellMap() const {return allowEmptyCellMap;}
|
bool getAllowEmptyCellMap() const {return allowEmptyCellMap;}
|
||||||
bool hasEmptyCellMap() const;
|
bool hasEmptyCellMap() const;
|
||||||
|
Vec2i getFirstOccupiedCellInCellMap(Vec2i currentPos) const;
|
||||||
|
|
||||||
//is
|
//is
|
||||||
bool isOfClass(UnitClass uc) const;
|
bool isOfClass(UnitClass uc) const;
|
||||||
|
|
Loading…
Reference in New Issue