//////////////////////////////////////////////////////////////////////////////// // Scorched3D (c) 2000-2003 // // This file is part of Scorched3D. // // Scorched3D is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // Scorched3D is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Scorched3D; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include TankAIComputerBuyer::Entry::Entry(const Entry &other) { (*this) = other; } TankAIComputerBuyer::Entry &TankAIComputerBuyer::Entry::operator=(const Entry &other) { level = other.level; std::list::const_iterator aitor; for (aitor = other.buyAccessories.begin(); aitor != other.buyAccessories.end(); aitor++) { buyAccessories.push_back(*aitor); } return *this; } TankAIComputerBuyer::TankAIComputerBuyer() : currentTank_(0) { } TankAIComputerBuyer::~TankAIComputerBuyer() { } bool TankAIComputerBuyer::parseConfig(AccessoryStore &store, XMLNode *node) { // Weapons XMLNode *weaponNode = 0; while (node->getNamedChild("weapon", weaponNode, false)) { std::string wtype, wname; int wlevel; if (!weaponNode->getNamedChild("name", wname)) return false; if (!weaponNode->getNamedChild("level", wlevel)) return false; if (!weaponNode->getNamedChild("type", wtype)) return false; if (!addAccessory(store, wname.c_str(), wlevel)) return false; if (0 != strcmp(wtype.c_str(), "dig") && 0 != strcmp(wtype.c_str(), "sniper") && 0 != strcmp(wtype.c_str(), "explosionsmall") && 0 != strcmp(wtype.c_str(), "explosionlarge") && 0 != strcmp(wtype.c_str(), "defense")) { dialogExit("TankAIComputerBuyer", formatString("Unknown ai weapon type \"%s\"\n" "Should be one of dig, sniper, defense, explosionsmall, explosionlarge", wtype.c_str())); } buyTypes_.insert( std::pair(wtype, wname)); } return node->failChildren(); } void TankAIComputerBuyer::clearAccessories() { buyEntries_.clear(); } bool TankAIComputerBuyer::addAccessory(AccessoryStore &store, const char *accessoryName, int buyLevel) { Accessory *accessory = store.findByPrimaryAccessoryName(accessoryName); if (!accessory) { dialogMessage("TankAIComputerBuyer", formatString("Failed to find accessory \"%s\"", accessoryName)); return false; } std::list::iterator itor; for (itor = buyEntries_.begin(); itor != buyEntries_.end(); itor++) { Entry ¤t = (*itor); if (current.level > buyLevel) { break; } if (current.level == buyLevel) { current.buyAccessories.push_back(accessoryName); return true; } } Entry newEntry; newEntry.level = buyLevel; newEntry.buyAccessories.push_back(accessoryName); if (itor == buyEntries_.end()) { buyEntries_.push_back(newEntry); } else if (itor == buyEntries_.begin()) { buyEntries_.push_front(newEntry); } else { itor--; buyEntries_.insert(itor, newEntry); } return true; } void TankAIComputerBuyer::buyAccessories(int no) { for (int i=0; i buyList; // For each set of accessories std::list::iterator itor; for (itor = buyEntries_.begin(); itor != buyEntries_.end(); itor++) { std::list::iterator aitor; for (aitor = (*itor).buyAccessories.begin(); aitor != (*itor).buyAccessories.end(); aitor++) { std::string &name = (*aitor); Accessory *current = ScorchedServer::instance()-> getAccessoryStore().findByPrimaryAccessoryName(name.c_str()); if (!current) { dialogExit("TankAIComputerBuyer", formatString("Failed to find accessory \"%s\"", name.c_str())); } // Check if the tank has each accessory if (currentTank_->getAccessories().getAccessoryCount(current) == 0) { // It does not have this one yet buyList.push_back(current); } } // Do we need any accessories at this level if (!buyList.empty()) break; } // We don't need any weapons if (buyList.empty()) return; // Buy a random accessory on the list of possible // accessories int no = int(RAND * float(buyList.size())); int count = 0; std::list::iterator aitor; for (aitor = buyList.begin(); aitor != buyList.end(); aitor++, count++) { Accessory *current = *aitor; if (count == no) { // Buy the accessory if (currentTank_->getScore().getMoney() >= current->getPrice()) { currentTank_->getAccessories().add(current, current->getBundle()); currentTank_->getScore().setMoney(currentTank_->getScore().getMoney() - current->getPrice()); } break; } } } void TankAIComputerBuyer::dumpAccessories() { Logger::log( "-------------"); std::list::iterator itor; for (itor = buyEntries_.begin(); itor != buyEntries_.end(); itor++) { std::list::iterator itor2; for (itor2 = (*itor).buyAccessories.begin(); itor2 != (*itor).buyAccessories.end(); itor2++) { Logger::log(formatString("%s", (*itor2).c_str())); } } Logger::log( "-------------"); } std::vector TankAIComputerBuyer::getWeaponType(const char *type) { std::vector result; std::pair::iterator, std::multimap::iterator> findItor = getTypes().equal_range(type); std::multimap::iterator itor; for (itor = findItor.first; itor != findItor.second; itor++) { Accessory *accessory = ScorchedServer::instance()-> getAccessoryStore().findByPrimaryAccessoryName( (*itor).second.c_str()); if (currentTank_->getAccessories().getAccessoryCount(accessory) != 0) { result.push_back(accessory); } } return result; }