/** ** Find all units of type. ** ** @param type type of unit requested ** @param table table in which we have to store the units ** @param tablesize size of table array ** ** @return Returns the number of units found. */ int FindUnitsByType(const CUnitType *type, CUnit **table, int tablesize) { int num = 0; for (int i = 0; i < NumUnits && num < tablesize; ++i) { CUnit *unit = Units[i]; if (unit->Type == type && !unit->IsUnusable()) { table[num++] = unit; } } return num; }
bool ResourceUnitFinder::MineIsUsable(const CUnit &mine) const { //Wyrmgus start // return mine.Type->BoolFlag[CANHARVEST_INDEX].value && mine.ResourcesHeld return (mine_on_top ? mine.Type->BoolFlag[CANHARVEST_INDEX].value : !mine.Type->BoolFlag[CANHARVEST_INDEX].value) && mine.ResourcesHeld //Wyrmgus end //Wyrmgus start && !mine.IsUnusable(false) // && (resinfo.HarvestFromOutside && (mine.Type->BoolFlag[HARVESTFROMOUTSIDE_INDEX].value //Wyrmgus end || mine.Player->Index == PlayerMax - 1 || mine.Player == worker.Player || (worker.IsAllied(mine) && mine.IsAllied(worker))); }
/** ** Find all units of type. ** ** @param player we're looking for the units of this player ** @param type type of unit requested ** @param table table in which we have to store the units ** @param tablesize size of table array ** ** @return Returns the number of units found. */ int FindPlayerUnitsByType(const CPlayer *player, const CUnitType *type, CUnit **table, int tablesize) { int nunits = player->TotalNumUnits; int typecount = player->UnitTypesCount[type->Slot]; int num = 0; for (int i = 0; i < nunits && typecount && num < tablesize; ++i) { CUnit *unit = player->Units[i]; if (unit->Type == type) { if (!unit->IsUnusable()) { table[num++] = unit; } --typecount; } } return num; }
/** ** Try to move a unit that's in the way */ static void AiMoveUnitInTheWay(CUnit *unit) { static int dirs[8][2] = {{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}}; int ux0; int uy0; int ux1; int uy1; int bx0; int by0; int bx1; int by1; int x; int y; int trycount,i; CUnit *blocker; CUnitType *unittype; CUnitType *blockertype; CUnit *movableunits[16]; int movablepos[16][2]; int movablenb; AiPlayer = unit->Player->Ai; unittype = unit->Type; ux0 = unit->X; uy0 = unit->Y; ux1 = ux0 + unittype->TileWidth - 1; uy1 = uy0 + unittype->TileHeight - 1; movablenb = 0; // Try to make some unit moves around it for (i = 0; i < NumUnits; ++i) { blocker = Units[i]; if (blocker->IsUnusable()) { continue; } if (!blocker->IsIdle()) { continue; } if (blocker->Player != unit->Player) { // Not allied if (!(blocker->Player->Allied & (1 << unit->Player->Index))) { continue; } } blockertype = blocker->Type; if (blockertype->UnitType != unittype->UnitType) { continue; } if (!CanMove(blocker)) { continue; } bx0 = blocker->X; by0 = blocker->Y; bx1 = bx0 + blocker->Type->TileWidth - 1; by1 = by0 + blocker->Type->TileHeight - 1;; // Check for collision if (!((ux0 == bx1 + 1 || ux1 == bx0 - 1) && (std::max(by0, uy0) <= std::min(by1, uy1))) && !((uy0 == by1 + 1 || uy1 == by0 - 1) && (std::max(bx0, ux0) <= std::min(bx1, ux1)))) { continue; } if (unit == blocker) { continue; } // Move blocker in a rand dir i = SyncRand() & 7; trycount = 8; while (trycount > 0) { i = (i + 1) & 7; --trycount; x = blocker->X + dirs[i][0]; y = blocker->Y + dirs[i][1]; // Out of the map => no ! if (x < 0 || y < 0 || x >= Map.Info.MapWidth || y >= Map.Info.MapHeight) { continue; } // move to blocker ? => no ! if (x == ux0 && y == uy0) { continue; } movableunits[movablenb] = blocker; movablepos[movablenb][0] = x; movablepos[movablenb][1] = y; ++movablenb; trycount = 0; } if (movablenb >= 16) { break; } } // Don't move more than 1 unit. if (movablenb) { i = SyncRand() % movablenb; CommandMove(movableunits[i], movablepos[i][0], movablepos[i][1], FlushCommands); } }