00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <set>
00022 #include <tankai/TankAIAdder.h>
00023 #include <tankai/TankAIStore.h>
00024 #include <tankai/TankAIStrings.h>
00025 #include <tank/TankColorGenerator.h>
00026 #include <tank/TankContainer.h>
00027 #include <tank/TankModelStore.h>
00028 #include <tank/TankAvatar.h>
00029 #include <tank/TankModelContainer.h>
00030 #include <tank/TankState.h>
00031 #include <server/ServerState.h>
00032 #include <coms/ComsAddPlayerMessage.h>
00033 #include <coms/ComsMessageSender.h>
00034 #include <coms/ComsPlayerStateMessage.h>
00035 #include <common/OptionsScorched.h>
00036 #include <common/OptionsTransient.h>
00037 #include <common/Logger.h>
00038 #include <common/StatsLogger.h>
00039 #include <common/Defines.h>
00040
00041 unsigned int TankAIAdder::getNextTankId(const char *uniqueId, ScorchedContext &context)
00042 {
00043
00044 if (uniqueId[0])
00045 {
00046 unsigned int id = StatsLogger::instance()->getStatsId(uniqueId);
00047 if (id != 0 &&
00048 !context.getTargetContainer().getTargetById(id))
00049 {
00050 DIALOG_ASSERT(id >= TargetID::MIN_TANK_ID && id <= TargetID::MAX_TANK_ID);
00051 return id;
00052 }
00053 }
00054
00055
00056 static unsigned int id = TargetID::START_TRANSIENT_TANK_ID;
00057 while (context.getTargetContainer().getTargetById(id))
00058 {
00059 ++id;
00060 if (id >= TargetID::MAX_TANK_ID) id = TargetID::START_TRANSIENT_TANK_ID;
00061 }
00062
00063 DIALOG_ASSERT(id >= TargetID::START_TRANSIENT_TANK_ID && id <= TargetID::MAX_TANK_ID);
00064 return id;
00065 }
00066
00067 unsigned int TankAIAdder::getNextTargetId(ScorchedContext &context)
00068 {
00069 unsigned int targetId_ = TargetID::MIN_TARGET_TRANSIENT_ID;
00070 while (context.getTargetContainer().getTargetById(targetId_))
00071 {
00072 ++targetId_;
00073 if (targetId_ >= TargetID::MAX_TARGET_ID) targetId_ = TargetID::MIN_TARGET_TRANSIENT_ID;
00074 }
00075
00076 return targetId_;
00077 }
00078
00079 void TankAIAdder::addTankAIs(ScorchedServer &context)
00080 {
00081
00082
00083 int maxComputerAIs = context.getOptionsGame().getNoMaxPlayers();
00084 for (int i=0; i<maxComputerAIs; i++)
00085 {
00086 const char *playerType =
00087 context.getOptionsGame().getPlayerType(i);
00088 if (0 != stricmp(playerType, "Human"))
00089 {
00090 addTankAI(context, playerType);
00091 }
00092 }
00093 }
00094
00095 void TankAIAdder::addTankAI(ScorchedServer &context, const char *aiName)
00096 {
00097 TankAI *ai = context.getTankAIs().getAIByName(aiName);
00098 if (ai)
00099 {
00100
00101 char uniqueId[256];
00102 {
00103 std::set<int> usedIds;
00104 snprintf(uniqueId, 256, "%s - computer - %%i", aiName);
00105 std::map<unsigned int, Tank *> &playingTanks =
00106 context.getTankContainer().getPlayingTanks();
00107 std::map<unsigned int, Tank *>::iterator playingItor;
00108 for (playingItor = playingTanks.begin();
00109 playingItor != playingTanks.end();
00110 playingItor++)
00111 {
00112 Tank *current = (*playingItor).second;
00113 if (current->getDestinationId() == 0)
00114 {
00115 int id = 1;
00116 if (sscanf(current->getUniqueId(), uniqueId, &id) == 1)
00117 {
00118 usedIds.insert(id);
00119 }
00120 }
00121 }
00122
00123 int uniqueIdCount = 1;
00124 while (usedIds.find(uniqueIdCount) != usedIds.end()) uniqueIdCount++;
00125
00126 snprintf(uniqueId, 256, "%s - computer - %i", aiName, uniqueIdCount);
00127 }
00128
00129
00130 int team = 0;
00131 if (context.getOptionsGame().getTeams() > 1)
00132 {
00133 team = context.getOptionsTransient().getLeastUsedTeam(
00134 context.getTankContainer());
00135 }
00136
00137
00138 LangString newname =
00139 LANG_STRING(context.getOptionsGame().getBotNamePrefix());
00140 newname += LANG_STRING(TankAIStrings::instance()->getAIPlayerName(
00141 ScorchedServer::instance()->getContext()));
00142
00143
00144 Vector color = TankColorGenerator::instance()->getNextColor(
00145 context.getTankContainer().getPlayingTanks());
00146 TankModel *tankModel =
00147 context.getTankModels().getRandomModel(team, false);
00148
00149
00150 Tank *tank = new Tank(
00151 context.getContext(),
00152 getNextTankId(uniqueId, context.getContext()),
00153 0,
00154 newname,
00155 color,
00156 tankModel->getName(),
00157 tankModel->getTypeName());
00158
00159 tank->getAvatar().loadFromFile(S3D::getDataFile("data/avatars/computer.png"));
00160 tank->setUniqueId(uniqueId);
00161 tank->setTankAI(ai->createCopy(tank));
00162 tank->getState().setState(TankState::sInitializing);
00163 tank->getState().setState(TankState::sPending);
00164 context.getTankContainer().addTank(tank);
00165
00166 if (context.getOptionsGame().getTeams() > 1)
00167 {
00168 tank->setTeam(team);
00169 }
00170
00171 Logger::log(S3D::formatStringBuffer("Player connected dest=\"%i\" id=\"%i\" name=\"%s\" unique=[%s]",
00172 tank->getDestinationId(),
00173 tank->getPlayerId(),
00174 tank->getCStrName().c_str(),
00175 tank->getUniqueId()));
00176
00177 StatsLogger::instance()->tankConnected(tank);
00178 StatsLogger::instance()->tankJoined(tank);
00179
00180 if (true)
00181 {
00182
00183 ComsAddPlayerMessage addPlayerMessage(
00184 tank->getPlayerId(),
00185 tank->getTargetName(),
00186 tank->getColor(),
00187 tank->getModelContainer().getTankModelName(),
00188 tank->getModelContainer().getTankTypeName(),
00189 tank->getDestinationId(),
00190 tank->getTeam(),
00191 "");
00192 addPlayerMessage.setPlayerIconName(tank->getAvatar().getName());
00193 addPlayerMessage.getPlayerIcon().addDataToBuffer(
00194 tank->getAvatar().getFile().getBuffer(),
00195 tank->getAvatar().getFile().getBufferUsed());
00196 ComsMessageSender::sendToAllConnectedClients(addPlayerMessage);
00197 }
00198
00199 if (context.getGameState().getState() == ServerState::ServerStateTooFewPlayers ||
00200 context.getGameState().getState() == ServerState::ServerStateStarting)
00201 {
00202 ComsPlayerStateMessage message(false, false);
00203 ComsMessageSender::sendToAllConnectedClients(message);
00204 }
00205 }
00206 }