- 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:
Mark Vejvoda 2011-05-01 05:36:04 +00:00
parent ae9d20a6cf
commit f71f83d2b8
8 changed files with 94 additions and 10 deletions

View File

@ -367,7 +367,7 @@ const Resource *AiInterface::getResource(const ResourceType *rt){
return world->getFaction(factionIndex)->getResource(rt);
}
const Unit *AiInterface::getMyUnit(int unitIndex){
Unit *AiInterface::getMyUnitPtr(int unitIndex) {
if(unitIndex >= world->getFaction(factionIndex)->getUnitCount()) {
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());
@ -377,6 +377,10 @@ const Unit *AiInterface::getMyUnit(int unitIndex){
return world->getFaction(factionIndex)->getUnit(unitIndex);
}
const Unit *AiInterface::getMyUnit(int unitIndex) {
return getMyUnitPtr(unitIndex);
}
const Unit *AiInterface::getOnSightUnit(int unitIndex) {
int count=0;

View File

@ -81,6 +81,7 @@ public:
int onSightUnitCount();
const Resource *getResource(const ResourceType *rt);
const Unit *getMyUnit(int unitIndex);
Unit *getMyUnitPtr(int unitIndex);
const Unit *getOnSightUnit(int unitIndex);
const FactionType *getMyFactionType();
Faction *getMyFaction();

View File

@ -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(){
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
// (units that produce workers and store resources)
for(int i = 0; i < aiInterface->getMyUnitCount(); ++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()));
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;
for(int j = 0; unitCanProduceWorker == false &&
@ -114,6 +135,7 @@ bool AiRuleRepair::test(){
const UnitType *ut = dynamic_cast<const UnitType *>(pt);
if( ut != NULL && ut->hasCommandClass(ccHarvest) == true &&
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;
}
}
@ -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 != 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())) {
candidatedamagedUnitIndex= i;
//return true;
@ -140,6 +165,7 @@ bool AiRuleRepair::test(){
Command *cmd = u1->getCurrCommand();
if(cmd != NULL && cmd->getCommandType()->getClass() == ccRepair) {
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++;
}
}
@ -148,6 +174,7 @@ bool AiRuleRepair::test(){
}
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;
return true;
}
@ -183,18 +210,41 @@ void AiRuleRepair::execute() {
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());
int minUnitsRepairingCastle = getMinUnitsToRepairCastle();
const double minCastleHpRatio = getMinCastleHpRatio();
//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 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 != NULL && (u->getCurrSkill()->getClass() == scStop || u->getCurrSkill()->getClass() == scMove)) {
if(rct->isRepairableUnitType(damagedUnit->getType())) {
//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());
aiInterface->printLog(3, "Repairing order issued");
return;
if(rct != NULL) {
//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((u->getCurrSkill()->getClass() == scStop || u->getCurrSkill()->getClass() == scMove || damagedUnit->getHpRatio() <= minCastleHpRatio)) {
if(rct->isRepairableUnitType(damagedUnit->getType())) {
//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;
}
}
}
}

View File

@ -113,6 +113,9 @@ class AiRuleRepair: public AiRule{
private:
int damagedUnitIndex;
int getMinUnitsToRepairCastle();
double getMinCastleHpRatio();
public:
AiRuleRepair(Ai *ai);

View File

@ -2136,6 +2136,11 @@ bool Unit::isLastStuckFrameWithinCurrentFrameTolerance() const {
return result;
}
Vec2i Unit::getPosWithCellMapSet() const {
Vec2i cellMapPos = this->getType()->getFirstOccupiedCellInCellMap(pos);
return cellMapPos;
}
std::string Unit::toString() const {
std::string result = "";

View File

@ -389,6 +389,7 @@ public:
//pos
Vec2i getPos() const {return pos;}
Vec2i getPosWithCellMapSet() const;
Vec2i getLastPos() const {return lastPos;}
Vec2i getCenteredPos() const;
Vec2f getFloatCenteredPos() const;

View File

@ -612,6 +612,25 @@ bool UnitType::hasEmptyCellMap() const {
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 {
assert(cellMap);
if(cellMap == NULL) {

View File

@ -200,6 +200,7 @@ public:
bool hasCellMap() const {return cellMap!=NULL;}
bool getAllowEmptyCellMap() const {return allowEmptyCellMap;}
bool hasEmptyCellMap() const;
Vec2i getFirstOccupiedCellInCellMap(Vec2i currentPos) const;
//is
bool isOfClass(UnitClass uc) const;