mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 11:42:31 +01:00
2019 lines
81 KiB
C++
2019 lines
81 KiB
C++
// ==============================================================
|
|
// This file is part of Glest (www.glest.org)
|
|
//
|
|
// Copyright (C) 2001-2008 Martiño Figueroa
|
|
//
|
|
// You can redistribute this code 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
|
|
// ==============================================================
|
|
|
|
#include "commander.h"
|
|
|
|
#include "world.h"
|
|
#include "unit.h"
|
|
#include "conversion.h"
|
|
#include "upgrade.h"
|
|
#include "command.h"
|
|
#include "command_type.h"
|
|
#include "network_manager.h"
|
|
#include "console.h"
|
|
#include "config.h"
|
|
#include "platform_util.h"
|
|
#include "game.h"
|
|
#include "game_settings.h"
|
|
#include "game.h"
|
|
|
|
using namespace
|
|
Shared::Graphics;
|
|
using namespace
|
|
Shared::Util;
|
|
using namespace
|
|
Shared::Platform;
|
|
|
|
namespace
|
|
Glest
|
|
{
|
|
namespace
|
|
Game
|
|
{
|
|
|
|
// =====================================================
|
|
// class Commander
|
|
// =====================================================
|
|
Commander::Commander ()
|
|
{
|
|
this->world = NULL;
|
|
this->
|
|
pauseNetworkCommands = false;
|
|
}
|
|
|
|
Commander::~
|
|
Commander ()
|
|
{
|
|
}
|
|
|
|
void
|
|
Commander::init (World * world)
|
|
{
|
|
this->world = world;
|
|
}
|
|
|
|
bool
|
|
Commander::canSubmitCommandType (const Unit * unit,
|
|
const CommandType * commandType) const
|
|
{
|
|
bool
|
|
canSubmitCommand = true;
|
|
const MorphCommandType *
|
|
mct = dynamic_cast < const
|
|
MorphCommandType * >(commandType);
|
|
if (mct && unit->getCommandSize () > 0)
|
|
{
|
|
Command *
|
|
cur_command = unit->getCurrCommand ();
|
|
if (cur_command != NULL)
|
|
{
|
|
const MorphCommandType *
|
|
cur_mct = dynamic_cast < const
|
|
MorphCommandType * >(cur_command->getCommandType ());
|
|
if (cur_mct && unit->getCurrSkill ()
|
|
&& unit->getCurrSkill ()->getClass () == scMorph)
|
|
{
|
|
const UnitType *
|
|
morphUnitType = mct->getMorphUnit ();
|
|
const UnitType *
|
|
cur_morphUnitType = cur_mct->getMorphUnit ();
|
|
|
|
if (morphUnitType != NULL && cur_morphUnitType != NULL
|
|
&& morphUnitType->getId () ==
|
|
cur_morphUnitType->getId ())
|
|
{
|
|
canSubmitCommand = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return
|
|
canSubmitCommand;
|
|
}
|
|
|
|
std::pair < CommandResult,
|
|
string > Commander::tryGiveCommand (const Selection * selection,
|
|
const CommandType * commandType,
|
|
const Vec2i & pos,
|
|
const UnitType * unitType,
|
|
CardinalDir facing, bool tryQueue,
|
|
Unit * targetUnit) const
|
|
{
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d]\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__);
|
|
|
|
if (this->pauseNetworkCommands == true)
|
|
{
|
|
return std::pair < CommandResult, string > (crFailUndefined, "");
|
|
}
|
|
|
|
std::pair <
|
|
CommandResult,
|
|
string >
|
|
result (crFailUndefined, "");
|
|
if (selection->isEmpty () == false && commandType != NULL)
|
|
{
|
|
Vec2i
|
|
refPos;
|
|
CommandResultContainer
|
|
results;
|
|
|
|
refPos = world->getMap ()->computeRefPos (selection);
|
|
|
|
const Unit *
|
|
builderUnit =
|
|
world->getMap ()->findClosestUnitToPos (selection, pos, unitType);
|
|
|
|
int
|
|
builderUnitId = builderUnit->getId ();
|
|
CommandStateType
|
|
commandStateType = cst_None;
|
|
int
|
|
commandStateValue = -1;
|
|
|
|
int
|
|
unitCommandGroupId = -1;
|
|
if (selection->getCount () > 1)
|
|
{
|
|
unitCommandGroupId = world->getNextCommandGroupId ();
|
|
}
|
|
|
|
//give orders to all selected units
|
|
for (int i = 0; i < selection->getCount (); ++i)
|
|
{
|
|
const Unit *
|
|
unit = selection->getUnit (i);
|
|
|
|
|
|
std::pair < CommandResult, string > resultCur (crFailUndefined,
|
|
"");
|
|
bool
|
|
canSubmitCommand = canSubmitCommandType (unit, commandType);
|
|
if (canSubmitCommand == true)
|
|
{
|
|
int
|
|
unitId = unit->getId ();
|
|
Vec2i
|
|
currPos =
|
|
world->getMap ()->computeDestPos (refPos,
|
|
unit->
|
|
getPosNotThreadSafe (),
|
|
pos);
|
|
|
|
Vec2i
|
|
usePos = currPos;
|
|
const CommandType *
|
|
useCommandtype = commandType;
|
|
if (dynamic_cast <
|
|
const BuildCommandType * >(commandType) != NULL)
|
|
{
|
|
usePos = pos;
|
|
if (builderUnit->getId () != unitId)
|
|
{
|
|
useCommandtype =
|
|
unit->getType ()->
|
|
getFirstRepairCommand (unitType);
|
|
commandStateType = cst_linkedUnit;
|
|
commandStateValue = builderUnitId;
|
|
}
|
|
else
|
|
{
|
|
commandStateType = cst_None;
|
|
commandStateValue = -1;
|
|
}
|
|
}
|
|
|
|
if (useCommandtype != NULL)
|
|
{
|
|
NetworkCommand
|
|
networkCommand (this->world, nctGiveCommand, unitId,
|
|
useCommandtype->getId (), usePos,
|
|
unitType->getId (),
|
|
(targetUnit !=
|
|
NULL ? targetUnit->getId () : -1),
|
|
facing, tryQueue, commandStateType,
|
|
commandStateValue, unitCommandGroupId);
|
|
|
|
//every unit is ordered to a the position
|
|
resultCur = pushNetworkCommand (&networkCommand);
|
|
}
|
|
}
|
|
|
|
results.push_back (resultCur);
|
|
}
|
|
|
|
return computeResult (results);
|
|
}
|
|
return std::pair < CommandResult, string > (crFailUndefined, "");
|
|
}
|
|
|
|
std::pair < CommandResult,
|
|
string > Commander::tryGiveCommand (const Unit * unit,
|
|
const CommandType * commandType,
|
|
const Vec2i & pos,
|
|
const UnitType * unitType,
|
|
CardinalDir facing, bool tryQueue,
|
|
Unit * targetUnit,
|
|
int unitGroupCommandId) const
|
|
{
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d]\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__);
|
|
|
|
if (this->pauseNetworkCommands == true)
|
|
{
|
|
return std::pair < CommandResult, string > (crFailUndefined, "");
|
|
}
|
|
|
|
Chrono
|
|
chrono;
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled)
|
|
chrono.start ();
|
|
|
|
assert (this->world != NULL);
|
|
assert (unit != NULL);
|
|
assert (commandType != NULL);
|
|
assert (unitType != NULL);
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s] Line: %d took msecs: %lld\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
std::pair < CommandResult, string > result (crFailUndefined, "");
|
|
bool
|
|
canSubmitCommand = canSubmitCommandType (unit, commandType);
|
|
if (canSubmitCommand == true)
|
|
{
|
|
NetworkCommand
|
|
networkCommand (this->world, nctGiveCommand, unit->getId (),
|
|
commandType->getId (), pos, unitType->getId (),
|
|
(targetUnit != NULL ? targetUnit->getId () : -1),
|
|
facing, tryQueue, cst_None, -1, unitGroupCommandId);
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).enabled
|
|
&& chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s] Line: %d took msecs: %lld\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
result = pushNetworkCommand (&networkCommand);
|
|
}
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s] Line: %d took msecs: %lld\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
return result;
|
|
}
|
|
|
|
std::pair < CommandResult,
|
|
string > Commander::tryGiveCommand (const Selection * selection,
|
|
CommandClass commandClass,
|
|
const Vec2i & pos,
|
|
const Unit * targetUnit,
|
|
bool tryQueue) const
|
|
{
|
|
|
|
if (this->pauseNetworkCommands == true)
|
|
{
|
|
return std::pair < CommandResult, string > (crFailUndefined, "");
|
|
}
|
|
|
|
std::pair <
|
|
CommandResult,
|
|
string >
|
|
result (crFailUndefined, "");
|
|
if (selection->isEmpty () == false)
|
|
{
|
|
Vec2i
|
|
refPos,
|
|
currPos;
|
|
CommandResultContainer
|
|
results;
|
|
|
|
refPos = world->getMap ()->computeRefPos (selection);
|
|
|
|
int
|
|
unitCommandGroupId = -1;
|
|
if (selection->getCount () > 1)
|
|
{
|
|
unitCommandGroupId = world->getNextCommandGroupId ();
|
|
}
|
|
|
|
//give orders to all selected units
|
|
for (int i = 0; i < selection->getCount (); ++i)
|
|
{
|
|
const Unit *
|
|
unit = selection->getUnit (i);
|
|
const CommandType *
|
|
ct = unit->getType ()->getFirstCtOfClass (commandClass);
|
|
if (ct != NULL)
|
|
{
|
|
std::pair < CommandResult,
|
|
string > resultCur (crFailUndefined, "");
|
|
|
|
bool
|
|
canSubmitCommand = canSubmitCommandType (unit, ct);
|
|
if (canSubmitCommand == true)
|
|
{
|
|
|
|
int
|
|
targetId =
|
|
targetUnit ==
|
|
NULL ? Unit::invalidId : targetUnit->getId ();
|
|
int
|
|
unitId = selection->getUnit (i)->getId ();
|
|
Vec2i
|
|
currPos = world->getMap ()->computeDestPos (refPos,
|
|
selection->
|
|
getUnit
|
|
(i)->
|
|
getPosNotThreadSafe
|
|
(), pos);
|
|
NetworkCommand
|
|
networkCommand (this->world, nctGiveCommand,
|
|
unitId, ct->getId (), currPos, -1,
|
|
targetId, -1, tryQueue, cst_None, -1,
|
|
unitCommandGroupId);
|
|
|
|
//every unit is ordered to a different pos
|
|
resultCur = pushNetworkCommand (&networkCommand);
|
|
}
|
|
results.push_back (resultCur);
|
|
}
|
|
else
|
|
{
|
|
results.push_back (std::pair < CommandResult,
|
|
string > (crFailUndefined, ""));
|
|
}
|
|
}
|
|
return computeResult (results);
|
|
}
|
|
else
|
|
{
|
|
return std::pair < CommandResult, string > (crFailUndefined, "");
|
|
}
|
|
}
|
|
|
|
std::pair < CommandResult,
|
|
string > Commander::tryGiveCommand (const Selection * selection,
|
|
const CommandType * commandType,
|
|
const Vec2i & pos,
|
|
const Unit * targetUnit,
|
|
bool tryQueue) const
|
|
{
|
|
|
|
if (this->pauseNetworkCommands == true)
|
|
{
|
|
return std::pair < CommandResult, string > (crFailUndefined, "");
|
|
}
|
|
|
|
std::pair <
|
|
CommandResult,
|
|
string >
|
|
result (crFailUndefined, "");
|
|
|
|
if (!selection->isEmpty () && commandType != NULL)
|
|
{
|
|
Vec2i
|
|
refPos;
|
|
CommandResultContainer
|
|
results;
|
|
|
|
refPos = world->getMap ()->computeRefPos (selection);
|
|
|
|
int
|
|
unitCommandGroupId = -1;
|
|
if (selection->getCount () > 1)
|
|
{
|
|
unitCommandGroupId = world->getNextCommandGroupId ();
|
|
}
|
|
|
|
//give orders to all selected units
|
|
for (int i = 0; i < selection->getCount (); ++i)
|
|
{
|
|
const Unit *
|
|
unit = selection->getUnit (i);
|
|
assert (unit != NULL);
|
|
|
|
std::pair < CommandResult, string > resultCur (crFailUndefined,
|
|
"");
|
|
|
|
bool
|
|
canSubmitCommand = canSubmitCommandType (unit, commandType);
|
|
if (canSubmitCommand == true)
|
|
{
|
|
int
|
|
targetId =
|
|
targetUnit ==
|
|
NULL ? Unit::invalidId : targetUnit->getId ();
|
|
int
|
|
unitId = unit->getId ();
|
|
Vec2i
|
|
currPos =
|
|
world->getMap ()->computeDestPos (refPos,
|
|
unit->
|
|
getPosNotThreadSafe (),
|
|
pos);
|
|
NetworkCommand
|
|
networkCommand (this->world, nctGiveCommand, unitId,
|
|
commandType->getId (), currPos, -1,
|
|
targetId, -1, tryQueue, cst_None, -1,
|
|
unitCommandGroupId);
|
|
|
|
//every unit is ordered to a different position
|
|
resultCur = pushNetworkCommand (&networkCommand);
|
|
}
|
|
results.push_back (resultCur);
|
|
}
|
|
|
|
return computeResult (results);
|
|
}
|
|
else
|
|
{
|
|
return std::pair < CommandResult, string > (crFailUndefined, "");
|
|
}
|
|
}
|
|
|
|
//auto command
|
|
std::pair < CommandResult,
|
|
string > Commander::tryGiveCommand (const Selection * selection,
|
|
const Vec2i & pos,
|
|
const Unit * targetUnit,
|
|
bool tryQueue,
|
|
int unitCommandGroupId) const
|
|
{
|
|
|
|
if (this->pauseNetworkCommands == true)
|
|
{
|
|
return std::pair < CommandResult, string > (crFailUndefined, "");
|
|
}
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d]\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__);
|
|
|
|
std::pair < CommandResult, string > result (crFailUndefined, "");
|
|
|
|
if (selection->isEmpty () == false)
|
|
{
|
|
Vec2i
|
|
refPos,
|
|
currPos;
|
|
CommandResultContainer
|
|
results;
|
|
|
|
if (unitCommandGroupId == -1 && selection->getCount () > 1)
|
|
{
|
|
unitCommandGroupId = world->getNextCommandGroupId ();
|
|
}
|
|
|
|
//give orders to all selected units
|
|
refPos = world->getMap ()->computeRefPos (selection);
|
|
for (int i = 0; i < selection->getCount (); ++i)
|
|
{
|
|
//every unit is ordered to a different pos
|
|
const Unit *
|
|
unit = selection->getUnit (i);
|
|
assert (unit != NULL);
|
|
|
|
currPos =
|
|
world->getMap ()->computeDestPos (refPos,
|
|
unit->
|
|
getPosNotThreadSafe (),
|
|
pos);
|
|
|
|
//get command type
|
|
const CommandType *
|
|
commandType = unit->computeCommandType (pos, targetUnit);
|
|
|
|
//give commands
|
|
if (commandType != NULL)
|
|
{
|
|
int
|
|
targetId =
|
|
targetUnit ==
|
|
NULL ? Unit::invalidId : targetUnit->getId ();
|
|
int
|
|
unitId = unit->getId ();
|
|
|
|
std::pair < CommandResult,
|
|
string > resultCur (crFailUndefined, "");
|
|
|
|
bool
|
|
canSubmitCommand =
|
|
canSubmitCommandType (unit, commandType);
|
|
if (canSubmitCommand == true)
|
|
{
|
|
NetworkCommand
|
|
networkCommand (this->world, nctGiveCommand,
|
|
unitId, commandType->getId (), currPos,
|
|
-1, targetId, -1, tryQueue, cst_None,
|
|
-1, unitCommandGroupId);
|
|
resultCur = pushNetworkCommand (&networkCommand);
|
|
}
|
|
results.push_back (resultCur);
|
|
}
|
|
else if (unit->isMeetingPointSettable () == true)
|
|
{
|
|
NetworkCommand
|
|
command (this->world, nctSetMeetingPoint,
|
|
unit->getId (), -1, currPos, -1, -1, -1, false,
|
|
cst_None, -1, unitCommandGroupId);
|
|
|
|
std::pair < CommandResult, string > resultCur =
|
|
pushNetworkCommand (&command);
|
|
results.push_back (resultCur);
|
|
}
|
|
else
|
|
{
|
|
results.push_back (std::pair < CommandResult,
|
|
string > (crFailUndefined, ""));
|
|
}
|
|
}
|
|
result = computeResult (results);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
CommandResult
|
|
Commander::tryCancelCommand (const Selection * selection) const
|
|
{
|
|
if (this->pauseNetworkCommands == true)
|
|
{
|
|
return crFailUndefined;
|
|
}
|
|
|
|
int
|
|
unitCommandGroupId = -1;
|
|
if (selection->getCount () > 1)
|
|
{
|
|
unitCommandGroupId = world->getNextCommandGroupId ();
|
|
}
|
|
|
|
for (int i = 0; i < selection->getCount (); ++i)
|
|
{
|
|
NetworkCommand
|
|
command (this->world, nctCancelCommand,
|
|
selection->getUnit (i)->getId (), -1, Vec2i (0), -1, -1,
|
|
-1, false, cst_None, -1, unitCommandGroupId);
|
|
pushNetworkCommand (&command);
|
|
}
|
|
|
|
return crSuccess;
|
|
}
|
|
|
|
void
|
|
Commander::trySetMeetingPoint (const Unit * unit, const Vec2i & pos) const
|
|
{
|
|
if (this->pauseNetworkCommands == true)
|
|
{
|
|
return;
|
|
}
|
|
|
|
NetworkCommand
|
|
command (this->world, nctSetMeetingPoint, unit->getId (), -1, pos);
|
|
pushNetworkCommand (&command);
|
|
}
|
|
|
|
void
|
|
Commander::trySwitchTeam (const Faction * faction, int teamIndex) const
|
|
{
|
|
if (this->pauseNetworkCommands == true)
|
|
{
|
|
return;
|
|
}
|
|
|
|
NetworkCommand
|
|
command (this->world, nctSwitchTeam, faction->getIndex (), teamIndex);
|
|
pushNetworkCommand (&command);
|
|
}
|
|
|
|
void
|
|
Commander::trySwitchTeamVote (const Faction * faction,
|
|
SwitchTeamVote * vote) const
|
|
{
|
|
if (this->pauseNetworkCommands == true)
|
|
{
|
|
return;
|
|
}
|
|
|
|
NetworkCommand
|
|
command (this->world, nctSwitchTeamVote, faction->getIndex (),
|
|
vote->factionIndex, Vec2i (0), vote->allowSwitchTeam);
|
|
pushNetworkCommand (&command);
|
|
}
|
|
|
|
void
|
|
Commander::tryDisconnectNetworkPlayer (const Faction * faction,
|
|
int playerIndex) const
|
|
{
|
|
NetworkCommand
|
|
command (this->world, nctDisconnectNetworkPlayer, faction->getIndex (),
|
|
playerIndex);
|
|
pushNetworkCommand (&command);
|
|
}
|
|
|
|
void
|
|
Commander::tryPauseGame (bool joinNetworkGame, bool clearCaches) const
|
|
{
|
|
NetworkCommand
|
|
command (this->world, nctPauseResume, 1);
|
|
command.
|
|
commandTypeId = (clearCaches == true ? 1 : 0);
|
|
command.
|
|
unitTypeId = (joinNetworkGame == true ? 1 : 0);
|
|
pushNetworkCommand (&command);
|
|
}
|
|
|
|
void
|
|
Commander::tryResumeGame (bool joinNetworkGame, bool clearCaches) const
|
|
{
|
|
NetworkCommand
|
|
command (this->world, nctPauseResume, 0);
|
|
command.
|
|
commandTypeId = (clearCaches == true ? 1 : 0);
|
|
command.
|
|
unitTypeId = (joinNetworkGame == true ? 1 : 0);
|
|
pushNetworkCommand (&command);
|
|
}
|
|
|
|
void
|
|
Commander::tryNetworkPlayerDisconnected (int factionIndex) const
|
|
{
|
|
//printf("tryNetworkPlayerDisconnected factionIndex: %d\n",factionIndex);
|
|
|
|
//if(this->pauseNetworkCommands == true) {
|
|
// return;
|
|
//}
|
|
|
|
NetworkCommand
|
|
command (this->world, nctPlayerStatusChange, factionIndex,
|
|
npst_Disconnected);
|
|
pushNetworkCommand (&command);
|
|
}
|
|
|
|
// ==================== PRIVATE ====================
|
|
|
|
std::pair <
|
|
CommandResult,
|
|
string >
|
|
Commander::computeResult (const CommandResultContainer & results) const
|
|
{
|
|
std::pair <
|
|
CommandResult,
|
|
string >
|
|
result (crFailUndefined, "");
|
|
switch (results.size ())
|
|
{
|
|
case 0:
|
|
return std::pair < CommandResult, string > (crFailUndefined, "");
|
|
case
|
|
1:
|
|
return
|
|
results.
|
|
front ();
|
|
default:for (int i = 0; i < (int) results.size (); ++i)
|
|
{
|
|
if (results[i].first != crSuccess)
|
|
{
|
|
return std::pair < CommandResult, string > (crSomeFailed,
|
|
results[i].
|
|
second);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return std::pair < CommandResult, string > (crSuccess, "");
|
|
}
|
|
|
|
std::pair < CommandResult,
|
|
string >
|
|
Commander::pushNetworkCommand (const NetworkCommand *
|
|
networkCommand) const
|
|
{
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().getGameNetworkInterface ();
|
|
std::pair <
|
|
CommandResult,
|
|
string >
|
|
result (crSuccess, "");
|
|
|
|
//validate unit
|
|
const Unit *
|
|
unit = NULL;
|
|
if (networkCommand->getNetworkCommandType () != nctSwitchTeam &&
|
|
networkCommand->getNetworkCommandType () != nctSwitchTeamVote &&
|
|
networkCommand->getNetworkCommandType () != nctPauseResume &&
|
|
networkCommand->getNetworkCommandType () != nctPlayerStatusChange &&
|
|
networkCommand->getNetworkCommandType () !=
|
|
nctDisconnectNetworkPlayer)
|
|
{
|
|
unit = world->findUnitById (networkCommand->getUnitId ());
|
|
if (unit == NULL)
|
|
{
|
|
char
|
|
szBuf[8096] = "";
|
|
snprintf (szBuf, 8096,
|
|
"In [%s::%s - %d] Command refers to non existent unit id = %d. Game out of synch.",
|
|
extractFileFromDirectoryPath (__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__, networkCommand->getUnitId ());
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().getGameNetworkInterface ();
|
|
if (gameNetworkInterface != NULL)
|
|
{
|
|
char
|
|
szMsg[8096] = "";
|
|
snprintf (szMsg, 8096,
|
|
"Player detected an error: Command refers to non existent unit id = %d. Game out of synch.",
|
|
networkCommand->getUnitId ());
|
|
gameNetworkInterface->
|
|
sendTextMessage (szMsg, -1, true, "");
|
|
}
|
|
throw
|
|
megaglest_runtime_error (szBuf);
|
|
}
|
|
}
|
|
|
|
//add the command to the interface
|
|
gameNetworkInterface->requestCommand (networkCommand);
|
|
|
|
//calculate the result of the command
|
|
if (unit != NULL
|
|
&& networkCommand->getNetworkCommandType () == nctGiveCommand)
|
|
{
|
|
//printf("In [%s::%s Line: %d] result.first = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result.first);
|
|
Command *
|
|
command = buildCommand (networkCommand);
|
|
result = unit->checkCommand (command);
|
|
delete
|
|
command;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void
|
|
Commander::signalNetworkUpdate (Game * game)
|
|
{
|
|
updateNetwork (game);
|
|
}
|
|
|
|
bool
|
|
Commander::getReplayCommandListForFrame (int worldFrameCount)
|
|
{
|
|
bool
|
|
haveReplyCommands = false;
|
|
if (replayCommandList.empty () == false)
|
|
{
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf ("worldFrameCount = %d replayCommandList.size() = "
|
|
MG_SIZE_T_SPECIFIER "\n", worldFrameCount,
|
|
replayCommandList.size ());
|
|
|
|
std::vector < NetworkCommand > replayList;
|
|
for (unsigned int i = 0; i < replayCommandList.size (); ++i)
|
|
{
|
|
std::pair < int,
|
|
NetworkCommand > &
|
|
cmd = replayCommandList[i];
|
|
if (cmd.first <= worldFrameCount)
|
|
{
|
|
replayList.push_back (cmd.second);
|
|
haveReplyCommands = true;
|
|
}
|
|
}
|
|
if (haveReplyCommands == true)
|
|
{
|
|
replayCommandList.erase (replayCommandList.begin (),
|
|
replayCommandList.begin () +
|
|
replayList.size ());
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf
|
|
("worldFrameCount = %d GIVING COMMANDS replayList.size() = "
|
|
MG_SIZE_T_SPECIFIER "\n", worldFrameCount,
|
|
replayList.size ());
|
|
for (int i = 0; i < (int) replayList.size (); ++i)
|
|
{
|
|
giveNetworkCommand (&replayList[i]);
|
|
}
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().getGameNetworkInterface ();
|
|
gameNetworkInterface->setKeyframe (worldFrameCount);
|
|
}
|
|
}
|
|
return haveReplyCommands;
|
|
}
|
|
|
|
bool
|
|
Commander::hasReplayCommandListForFrame () const
|
|
{
|
|
return (replayCommandList.empty () == false);
|
|
}
|
|
|
|
int
|
|
Commander::getReplayCommandListForFrameCount () const
|
|
{
|
|
return (int)
|
|
replayCommandList.
|
|
size ();
|
|
}
|
|
|
|
void
|
|
Commander::updateNetwork (Game * game)
|
|
{
|
|
if (world == NULL)
|
|
{
|
|
return;
|
|
}
|
|
NetworkManager & networkManager = NetworkManager::getInstance ();
|
|
|
|
//check that this is a keyframe
|
|
if (game != NULL)
|
|
{
|
|
GameSettings *
|
|
gameSettings = game->getGameSettings ();
|
|
if (networkManager.isNetworkGame () == false ||
|
|
(world->getFrameCount () %
|
|
gameSettings->getNetworkFramePeriod ()) == 0)
|
|
{
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugSystem).enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] networkManager.isNetworkGame() = %d,world->getFrameCount() = %d, gameSettings->getNetworkFramePeriod() = %d\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__,
|
|
networkManager.isNetworkGame (),
|
|
world->getFrameCount (),
|
|
gameSettings->
|
|
getNetworkFramePeriod ());
|
|
|
|
if (getReplayCommandListForFrame (world->getFrameCount ()) ==
|
|
false)
|
|
{
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().getGameNetworkInterface ();
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled)
|
|
perfTimer.start ();
|
|
//update the keyframe
|
|
gameNetworkInterface->updateKeyframe (world->
|
|
getFrameCount ());
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && perfTimer.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] gameNetworkInterface->updateKeyframe for %d took %lld msecs\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
world->getFrameCount (),
|
|
perfTimer.getMillis ());
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled)
|
|
perfTimer.start ();
|
|
//give pending commands
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf
|
|
("START process: %d network commands in frame: %d\n",
|
|
gameNetworkInterface->getPendingCommandCount (),
|
|
this->world->getFrameCount ());
|
|
for (int i = 0;
|
|
i < gameNetworkInterface->getPendingCommandCount ();
|
|
++i)
|
|
{
|
|
giveNetworkCommand (gameNetworkInterface->
|
|
getPendingCommand (i));
|
|
}
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf ("END process: %d network commands in frame: %d\n",
|
|
gameNetworkInterface->getPendingCommandCount (),
|
|
this->world->getFrameCount ());
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && perfTimer.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] giveNetworkCommand took %lld msecs, PendingCommandCount = %d\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
perfTimer.getMillis (),
|
|
gameNetworkInterface->
|
|
getPendingCommandCount ());
|
|
gameNetworkInterface->clearPendingCommands ();
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf ("Cleared network commands in frame: %d\n",
|
|
this->world->getFrameCount ());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
Commander::addToReplayCommandList (NetworkCommand & command,
|
|
int worldFrameCount)
|
|
{
|
|
replayCommandList.push_back (make_pair (worldFrameCount, command));
|
|
}
|
|
|
|
void
|
|
Commander::giveNetworkCommand (NetworkCommand * networkCommand) const
|
|
{
|
|
Chrono
|
|
chrono;
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled)
|
|
chrono.
|
|
start ();
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [START]\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
|
|
world->
|
|
getGame ()->
|
|
addNetworkCommandToReplayList (networkCommand, world->getFrameCount ());
|
|
|
|
networkCommand->
|
|
preprocessNetworkCommand (this->world);
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [after networkCommand->preprocessNetworkCommand]\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
bool
|
|
commandWasHandled = false;
|
|
// Handle special commands first (that just use network command members as placeholders)
|
|
switch (networkCommand->getNetworkCommandType ())
|
|
{
|
|
case nctSwitchTeam:
|
|
{
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctSwitchTeam\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
|
|
commandWasHandled = true;
|
|
int
|
|
factionIndex = networkCommand->getUnitId ();
|
|
int
|
|
newTeam = networkCommand->getCommandTypeId ();
|
|
|
|
// Auto join empty team or ask players to join
|
|
bool
|
|
autoJoinTeam = true;
|
|
for (int i = 0; i < world->getFactionCount (); ++i)
|
|
{
|
|
if (newTeam == world->getFaction (i)->getTeam ())
|
|
{
|
|
autoJoinTeam = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (autoJoinTeam == true)
|
|
{
|
|
Faction *
|
|
faction = world->getFaction (factionIndex);
|
|
int
|
|
oldTeam = faction->getTeam ();
|
|
faction->setTeam (newTeam);
|
|
GameSettings *
|
|
settings = world->getGameSettingsPtr ();
|
|
settings->setTeam (factionIndex, newTeam);
|
|
world->getStats ()->setTeam (factionIndex, newTeam);
|
|
|
|
if (factionIndex == world->getThisFactionIndex ())
|
|
{
|
|
world->setThisTeamIndex (newTeam);
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().
|
|
getGameNetworkInterface ();
|
|
if (gameNetworkInterface != NULL)
|
|
{
|
|
|
|
Lang & lang = Lang::getInstance ();
|
|
const
|
|
vector <
|
|
string >
|
|
languageList =
|
|
settings->getUniqueNetworkPlayerLanguages ();
|
|
for (unsigned int i = 0; i < languageList.size ();
|
|
++i)
|
|
{
|
|
char
|
|
szMsg[8096] = "";
|
|
if (lang.
|
|
hasString ("PlayerSwitchedTeam",
|
|
languageList[i]) == true)
|
|
{
|
|
snprintf (szMsg, 8096,
|
|
lang.
|
|
getString ("PlayerSwitchedTeam",
|
|
languageList[i]).
|
|
c_str (),
|
|
settings->
|
|
getNetworkPlayerName (factionIndex).
|
|
c_str (), oldTeam, newTeam);
|
|
}
|
|
else
|
|
{
|
|
snprintf (szMsg, 8096,
|
|
"Player %s switched from team# %d to team# %d.",
|
|
settings->
|
|
getNetworkPlayerName (factionIndex).
|
|
c_str (), oldTeam, newTeam);
|
|
}
|
|
bool
|
|
localEcho =
|
|
lang.isLanguageLocal (languageList[i]);
|
|
gameNetworkInterface->sendTextMessage (szMsg, -1,
|
|
localEcho,
|
|
languageList
|
|
[i]);
|
|
}
|
|
}
|
|
world->getGame ()->reInitGUI ();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < world->getFactionCount (); ++i)
|
|
{
|
|
if (newTeam == world->getFaction (i)->getTeam ())
|
|
{
|
|
Faction *
|
|
faction = world->getFaction (factionIndex);
|
|
|
|
SwitchTeamVote
|
|
vote;
|
|
vote.factionIndex = factionIndex;
|
|
vote.allowSwitchTeam = false;
|
|
vote.oldTeam = faction->getTeam ();
|
|
vote.newTeam = newTeam;
|
|
vote.voted = false;
|
|
|
|
world->getFaction (i)->setSwitchTeamVote (vote);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).enabled
|
|
&& chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__, chrono.getMillis ());
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctSetMeetingPoint\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
}
|
|
break;
|
|
|
|
case nctSwitchTeamVote:
|
|
{
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctSwitchTeamVote\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
|
|
commandWasHandled = true;
|
|
|
|
int
|
|
votingFactionIndex = networkCommand->getUnitId ();
|
|
int
|
|
factionIndex = networkCommand->getCommandTypeId ();
|
|
bool
|
|
allowSwitchTeam = networkCommand->getUnitTypeId () != 0;
|
|
|
|
Faction *
|
|
faction = world->getFaction (votingFactionIndex);
|
|
|
|
SwitchTeamVote *
|
|
vote = faction->getSwitchTeamVote (factionIndex);
|
|
if (vote == NULL)
|
|
{
|
|
throw
|
|
megaglest_runtime_error ("vote == NULL");
|
|
}
|
|
vote->voted = true;
|
|
vote->allowSwitchTeam = allowSwitchTeam;
|
|
|
|
// Join the new team if > 50 % said yes
|
|
int
|
|
newTeamTotalMemberCount = 0;
|
|
int
|
|
newTeamVotedYes = 0;
|
|
int
|
|
newTeamVotedNo = 0;
|
|
|
|
for (int i = 0; i < world->getFactionCount (); ++i)
|
|
{
|
|
if (vote->newTeam == world->getFaction (i)->getTeam ())
|
|
{
|
|
newTeamTotalMemberCount++;
|
|
|
|
SwitchTeamVote *
|
|
teamVote =
|
|
world->getFaction (i)->getSwitchTeamVote (factionIndex);
|
|
if (teamVote != NULL && teamVote->voted == true)
|
|
{
|
|
if (teamVote->allowSwitchTeam == true)
|
|
{
|
|
newTeamVotedYes++;
|
|
}
|
|
else
|
|
{
|
|
newTeamVotedNo++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If > 50% of team vote yes, switch th eplayers team
|
|
if (newTeamTotalMemberCount > 0 && newTeamVotedYes > 0 &&
|
|
static_cast < float >(newTeamVotedYes) / static_cast <
|
|
float >(newTeamTotalMemberCount) > 0.5)
|
|
{
|
|
Faction *
|
|
faction = world->getFaction (factionIndex);
|
|
int
|
|
oldTeam = faction->getTeam ();
|
|
faction->setTeam (vote->newTeam);
|
|
GameSettings *
|
|
settings = world->getGameSettingsPtr ();
|
|
settings->setTeam (factionIndex, vote->newTeam);
|
|
world->getStats ()->setTeam (factionIndex, vote->newTeam);
|
|
|
|
if (factionIndex == world->getThisFactionIndex ())
|
|
{
|
|
world->setThisTeamIndex (vote->newTeam);
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().
|
|
getGameNetworkInterface ();
|
|
if (gameNetworkInterface != NULL)
|
|
{
|
|
|
|
Lang & lang = Lang::getInstance ();
|
|
const
|
|
vector <
|
|
string >
|
|
languageList =
|
|
settings->getUniqueNetworkPlayerLanguages ();
|
|
for (unsigned int i = 0; i < languageList.size ();
|
|
++i)
|
|
{
|
|
char
|
|
szMsg[8096] = "";
|
|
if (lang.
|
|
hasString ("PlayerSwitchedTeam",
|
|
languageList[i]) == true)
|
|
{
|
|
snprintf (szMsg, 8096,
|
|
lang.
|
|
getString ("PlayerSwitchedTeam",
|
|
languageList[i]).
|
|
c_str (),
|
|
settings->
|
|
getNetworkPlayerName (factionIndex).
|
|
c_str (), oldTeam, vote->newTeam);
|
|
}
|
|
else
|
|
{
|
|
snprintf (szMsg, 8096,
|
|
"Player %s switched from team# %d to team# %d.",
|
|
settings->
|
|
getNetworkPlayerName (factionIndex).
|
|
c_str (), oldTeam, vote->newTeam);
|
|
}
|
|
bool
|
|
localEcho =
|
|
lang.isLanguageLocal (languageList[i]);
|
|
gameNetworkInterface->sendTextMessage (szMsg, -1,
|
|
localEcho,
|
|
languageList
|
|
[i]);
|
|
}
|
|
}
|
|
world->getGame ()->reInitGUI ();
|
|
}
|
|
}
|
|
else if (newTeamTotalMemberCount ==
|
|
(newTeamVotedYes + newTeamVotedNo))
|
|
{
|
|
if (factionIndex == world->getThisFactionIndex ())
|
|
{
|
|
GameSettings *
|
|
settings = world->getGameSettingsPtr ();
|
|
Faction *
|
|
faction = world->getFaction (factionIndex);
|
|
int
|
|
oldTeam = faction->getTeam ();
|
|
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().
|
|
getGameNetworkInterface ();
|
|
if (gameNetworkInterface != NULL)
|
|
{
|
|
|
|
Lang & lang = Lang::getInstance ();
|
|
const
|
|
vector <
|
|
string >
|
|
languageList =
|
|
settings->getUniqueNetworkPlayerLanguages ();
|
|
for (unsigned int i = 0; i < languageList.size ();
|
|
++i)
|
|
{
|
|
char
|
|
szMsg[8096] = "";
|
|
if (lang.
|
|
hasString ("PlayerSwitchedTeamDenied",
|
|
languageList[i]) == true)
|
|
{
|
|
snprintf (szMsg, 8096,
|
|
lang.
|
|
getString
|
|
("PlayerSwitchedTeamDenied",
|
|
languageList[i]).c_str (),
|
|
settings->
|
|
getNetworkPlayerName (factionIndex).
|
|
c_str (), oldTeam, vote->newTeam);
|
|
}
|
|
else
|
|
{
|
|
snprintf (szMsg, 8096,
|
|
"Player %s was denied the request to switch from team# %d to team# %d.",
|
|
settings->
|
|
getNetworkPlayerName (factionIndex).
|
|
c_str (), oldTeam, vote->newTeam);
|
|
}
|
|
bool
|
|
localEcho =
|
|
lang.isLanguageLocal (languageList[i]);
|
|
gameNetworkInterface->sendTextMessage (szMsg, -1,
|
|
localEcho,
|
|
languageList
|
|
[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).enabled
|
|
&& chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__, chrono.getMillis ());
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctSetMeetingPoint\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
}
|
|
break;
|
|
|
|
case nctDisconnectNetworkPlayer:
|
|
{
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctDisconnectNetworkPlayer\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
|
|
commandWasHandled = true;
|
|
|
|
NetworkManager & networkManager = NetworkManager::getInstance ();
|
|
NetworkRole
|
|
role = networkManager.getNetworkRole ();
|
|
//GameSettings *settings = world->getGameSettingsPtr();
|
|
|
|
if (role == nrServer)
|
|
{
|
|
//int factionIndex = networkCommand->getUnitId();
|
|
int
|
|
playerIndex = networkCommand->getCommandTypeId ();
|
|
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().getGameNetworkInterface ();
|
|
if (gameNetworkInterface != NULL)
|
|
{
|
|
ServerInterface *
|
|
server = networkManager.getServerInterface ();
|
|
if (server != NULL
|
|
&& server->isClientConnected (playerIndex) == true)
|
|
{
|
|
|
|
MutexSafeWrapper
|
|
safeMutex (server->getSlotMutex (playerIndex),
|
|
CODE_AT_LINE);
|
|
ConnectionSlot *
|
|
slot = server->getSlot (playerIndex, false);
|
|
if (slot != NULL)
|
|
{
|
|
safeMutex.ReleaseLock ();
|
|
NetworkMessageQuit
|
|
networkMessageQuit;
|
|
slot->sendMessage (&networkMessageQuit);
|
|
sleep (5);
|
|
|
|
//printf("Sending nctDisconnectNetworkPlayer\n");
|
|
server =
|
|
networkManager.getServerInterface (false);
|
|
if (server != NULL)
|
|
{
|
|
MutexSafeWrapper
|
|
safeMutex2 (server->
|
|
getSlotMutex (playerIndex),
|
|
CODE_AT_LINE);
|
|
slot = server->getSlot (playerIndex, false);
|
|
if (slot != NULL)
|
|
{
|
|
safeMutex2.ReleaseLock ();
|
|
slot->close ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctDisconnectNetworkPlayer\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
}
|
|
break;
|
|
|
|
case nctPauseResume:
|
|
{
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctPauseResume\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
|
|
commandWasHandled = true;
|
|
|
|
bool
|
|
pauseGame = networkCommand->getUnitId () != 0;
|
|
bool
|
|
clearCaches = (networkCommand->getCommandTypeId () == 1);
|
|
bool
|
|
joinNetworkGame = (networkCommand->getUnitTypeId () == 1);
|
|
Game *
|
|
game = this->world->getGame ();
|
|
|
|
//printf("nctPauseResume pauseGame = %d\n",pauseGame);
|
|
game->setPaused (pauseGame, true, clearCaches, joinNetworkGame);
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctPauseResume\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
}
|
|
break;
|
|
|
|
case nctPlayerStatusChange:
|
|
{
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctPlayerStatusChange\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
|
|
commandWasHandled = true;
|
|
|
|
int
|
|
factionIndex = networkCommand->getUnitId ();
|
|
int
|
|
playerStatus = networkCommand->getCommandTypeId ();
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"nctPlayerStatusChange factionIndex = %d playerStatus = %d\n",
|
|
factionIndex, playerStatus);
|
|
|
|
//printf("#1 nctPlayerStatusChange factionIndex = %d playerStatus = %d\n",factionIndex,playerStatus);
|
|
|
|
GameSettings *
|
|
settings = world->getGameSettingsPtr ();
|
|
if (playerStatus == npst_Disconnected)
|
|
{
|
|
//printf("Commander nctPlayerStatusChange factionIndex: %d\n",factionIndex);
|
|
|
|
settings->setNetworkPlayerStatuses (factionIndex,
|
|
npst_Disconnected);
|
|
|
|
//printf("nctPlayerStatusChange -> faction->getPersonalityType() = %d index [%d] control [%d] networkstatus [%d]\n",
|
|
// world->getFaction(factionIndex)->getPersonalityType(),world->getFaction(factionIndex)->getIndex(),world->getFaction(factionIndex)->getControlType(),settings->getNetworkPlayerStatuses(factionIndex));
|
|
|
|
//printf("#2 nctPlayerStatusChange factionIndex = %d playerStatus = %d\n",factionIndex,playerStatus);
|
|
settings->setFactionControl (factionIndex, ctCpuUltra);
|
|
settings->setResourceMultiplierIndex (factionIndex,
|
|
settings->
|
|
getFallbackCpuMultiplier
|
|
());
|
|
//Game *game = this->world->getGame();
|
|
//game->get
|
|
Faction *
|
|
faction = this->world->getFaction (factionIndex);
|
|
faction->setControlType (ctCpuUltra);
|
|
|
|
if (!world->getGame ()->getGameOver ()
|
|
&& !this->world->getGame ()->
|
|
factionLostGame (factionIndex))
|
|
{
|
|
// use the fallback multiplier here
|
|
|
|
// mark player as "leaver"
|
|
this->world->getStats ()->
|
|
setPlayerLeftBeforeEnd (factionIndex, true);
|
|
// set disconnect time for endgame stats
|
|
this->world->getStats ()->setTimePlayerLeft (factionIndex,
|
|
this->world->
|
|
getStats ()->
|
|
getFramesToCalculatePlaytime
|
|
());
|
|
}
|
|
}
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctPlayerStatusChange\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__);
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
if (commandWasHandled == false)
|
|
{
|
|
Unit *
|
|
unit = world->findUnitById (networkCommand->getUnitId ());
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).enabled
|
|
&& chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [after world->findUnitById]\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED)
|
|
printf
|
|
("Running command NetworkCommandType = %d, unitid = %d [%p] factionindex = %d\n",
|
|
networkCommand->getNetworkCommandType (),
|
|
networkCommand->getUnitId (), unit,
|
|
(unit != NULL ? unit->getFactionIndex () : -1));
|
|
//execute command, if unit is still alive
|
|
if (unit != NULL)
|
|
{
|
|
switch (networkCommand->getNetworkCommandType ())
|
|
{
|
|
case nctGiveCommand:
|
|
{
|
|
assert (networkCommand->getCommandTypeId () !=
|
|
CommandType::invalidId);
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
networkCommand->getUnitId ());
|
|
|
|
Command *
|
|
command = buildCommand (networkCommand);
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [after buildCommand]\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] command = %p\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
command);
|
|
|
|
unit->giveCommand (command,
|
|
(networkCommand->getWantQueue () !=
|
|
0));
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [after unit->giveCommand]\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
networkCommand->getUnitId ());
|
|
}
|
|
break;
|
|
case nctCancelCommand:
|
|
{
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctCancelCommand\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__);
|
|
|
|
unit->cancelCommand ();
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [after unit->cancelCommand]\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctCancelCommand\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__);
|
|
}
|
|
break;
|
|
case nctSetMeetingPoint:
|
|
{
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctSetMeetingPoint\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__);
|
|
|
|
unit->setMeetingPos (networkCommand->getPosition ());
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] found nctSetMeetingPoint\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
assert (false);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (SystemFlags::
|
|
getSystemSettingType (SystemFlags::debugSystem).enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] NULL Unit for id = %d, networkCommand->getNetworkCommandType() = %d\n",
|
|
extractFileFromDirectoryPath
|
|
(__FILE__).c_str (), __FUNCTION__,
|
|
__LINE__,
|
|
networkCommand->getUnitId (),
|
|
networkCommand->
|
|
getNetworkCommandType ());
|
|
}
|
|
}
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance).
|
|
enabled && chrono.getMillis () > 0)
|
|
SystemFlags::OutputDebug (SystemFlags::debugPerformance,
|
|
"In [%s::%s Line: %d] took msecs: %lld [END]\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__,
|
|
chrono.getMillis ());
|
|
}
|
|
|
|
// Reconstruct a network command received.
|
|
Command *
|
|
Commander::buildCommand (const NetworkCommand * networkCommand) const
|
|
{
|
|
// Check a new command is actually being given (and not a cancel command, switch team etc.).
|
|
assert (networkCommand->getNetworkCommandType () == nctGiveCommand);
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d] networkCommand [%s]\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__,
|
|
networkCommand->toString ().c_str ());
|
|
|
|
// Check there is a world.
|
|
if (world == NULL)
|
|
{
|
|
char
|
|
szBuf[8096] = "";
|
|
snprintf (szBuf, 8096,
|
|
"In [%s::%s Line: %d] world == NULL for unit with id: %d",
|
|
extractFileFromDirectoryPath (__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__, networkCommand->getUnitId ());
|
|
throw
|
|
megaglest_runtime_error (szBuf);
|
|
}
|
|
|
|
// Get the unit.
|
|
Unit *
|
|
target = NULL;
|
|
const CommandType *
|
|
ct = NULL;
|
|
const Unit *
|
|
unit = world->findUnitById (networkCommand->getUnitId ());
|
|
|
|
// Validate unit is in game.
|
|
if (unit == NULL)
|
|
{
|
|
char
|
|
szBuf[8096] = "";
|
|
snprintf (szBuf, 8096,
|
|
"In [%s::%s Line: %d] Can not find unit with id: %d. Game out of synch.",
|
|
extractFileFromDirectoryPath (__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__, networkCommand->getUnitId ());
|
|
SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n", szBuf);
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n",
|
|
szBuf);
|
|
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().getGameNetworkInterface ();
|
|
if (gameNetworkInterface != NULL)
|
|
{
|
|
char
|
|
szMsg[8096] = "";
|
|
snprintf (szMsg, 8096,
|
|
"Player detected an error: Can not find unit with id: %d. Game out of synch.",
|
|
networkCommand->getUnitId ());
|
|
gameNetworkInterface->sendTextMessage (szMsg, -1, true, "");
|
|
}
|
|
|
|
throw
|
|
megaglest_runtime_error (szBuf);
|
|
}
|
|
|
|
// Get the command type for the unit.
|
|
ct =
|
|
unit->getType ()->findCommandTypeById (networkCommand->
|
|
getCommandTypeId ());
|
|
|
|
// Check that the unit from the network command is the same faction as the unit in the local game.
|
|
if (unit->getFaction ()->getIndex () !=
|
|
networkCommand->getUnitFactionIndex ())
|
|
{
|
|
|
|
char
|
|
szBuf[8096] = "";
|
|
snprintf (szBuf, 8096,
|
|
"In [%s::%s Line: %d]\nUnit / Faction mismatch for network command = [%s]\n%s\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.",
|
|
__FILE__, __FUNCTION__, __LINE__,
|
|
networkCommand->toString ().c_str (),
|
|
unit->getType ()->getCommandTypeListDesc ().c_str (),
|
|
unit->getId (), unit->getFullName (false).c_str (),
|
|
unit->getDesc (false).c_str (),
|
|
unit->getFaction ()->getIndex ());
|
|
|
|
SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n", szBuf);
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n",
|
|
szBuf);
|
|
//std::string worldLog = world->DumpWorldToLog();
|
|
world->DumpWorldToLog ();
|
|
|
|
// Broadcast the error if player is still connected and print locally.
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().getGameNetworkInterface ();
|
|
if (gameNetworkInterface != NULL
|
|
&& gameNetworkInterface->isConnected () == true)
|
|
{
|
|
char
|
|
szMsg[8096] = "";
|
|
snprintf (szMsg, 8096,
|
|
"Player detected an error: Unit / Faction mismatch for unitId: %d",
|
|
networkCommand->getUnitId ());
|
|
gameNetworkInterface->sendTextMessage (szMsg, -1, true, "");
|
|
snprintf (szMsg, 8096,
|
|
"Local faction index = %d, remote index = %d. Game out of synch.",
|
|
unit->getFaction ()->getIndex (),
|
|
networkCommand->getUnitFactionIndex ());
|
|
gameNetworkInterface->sendTextMessage (szMsg, -1, true, "");
|
|
|
|
}
|
|
|
|
// Else if it's a network game but the user disconnected, print the error locally only.
|
|
else if (gameNetworkInterface != NULL)
|
|
{
|
|
char
|
|
szMsg[8096] = "";
|
|
snprintf (szMsg, 8096,
|
|
"Player detected an error: Connection lost, possible Unit / Faction mismatch for unitId: %d",
|
|
networkCommand->getUnitId ());
|
|
gameNetworkInterface->sendTextMessage (szMsg, -1, true, "");
|
|
snprintf (szMsg, 8096,
|
|
"Local faction index = %d, remote index = %d. Game out of synch.",
|
|
unit->getFaction ()->getIndex (),
|
|
networkCommand->getUnitFactionIndex ());
|
|
gameNetworkInterface->sendTextMessage (szMsg, -1, true, "");
|
|
}
|
|
|
|
// Kill the game.
|
|
std::string sError =
|
|
"Error [#1]: Game is out of sync (Unit / Faction mismatch)\nplease check log files for details.";
|
|
throw
|
|
megaglest_runtime_error (sError);
|
|
}
|
|
|
|
const UnitType *
|
|
unitType =
|
|
world->findUnitTypeById (unit->getFaction ()->getType (),
|
|
networkCommand->getUnitTypeId ());
|
|
|
|
// debug test!
|
|
//throw megaglest_runtime_error("Test missing command type!");
|
|
|
|
//validate command type
|
|
|
|
// !!!Test out of synch behaviour
|
|
//ct = NULL;
|
|
|
|
// Check if the command was for the unit before it morphed, if so cancel it.
|
|
bool
|
|
isCancelPreMorphCommand = false;
|
|
if (ct == NULL && unit->getPreMorphType () != NULL)
|
|
{
|
|
const CommandType *
|
|
ctPreMorph =
|
|
unit->getPreMorphType ()->findCommandTypeById (networkCommand->
|
|
getCommandTypeId
|
|
());
|
|
if (ctPreMorph != NULL)
|
|
{
|
|
ct = unit->getType ()->getFirstCtOfClass (ccStop);
|
|
isCancelPreMorphCommand = true;
|
|
}
|
|
}
|
|
|
|
// Throw an error if a valid command for the unit is still not found.
|
|
if (ct == NULL)
|
|
{
|
|
char
|
|
szBuf[8096] = "";
|
|
snprintf (szBuf, 8096,
|
|
"In [%s::%s Line: %d]\nCan not find command type for network command = [%s]\n%s\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nUnit Type Info:\n[%s]\nNetwork unit type:\n[%s]\nisCancelPreMorphCommand: %d\nGame out of synch.",
|
|
extractFileFromDirectoryPath (__FILE__).c_str (),
|
|
__FUNCTION__, __LINE__,
|
|
networkCommand->toString ().c_str (),
|
|
unit->getType ()->getCommandTypeListDesc ().c_str (),
|
|
unit->getId (), unit->getFullName (false).c_str (),
|
|
unit->getDesc (false).c_str (),
|
|
unit->getFaction ()->getIndex (),
|
|
unit->getType ()->toString ().c_str (),
|
|
(unitType !=
|
|
NULL ? unitType->getName (false).c_str () : "null"),
|
|
isCancelPreMorphCommand);
|
|
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", szBuf);
|
|
SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n", szBuf);
|
|
world->DumpWorldToLog ();
|
|
|
|
GameNetworkInterface *
|
|
gameNetworkInterface =
|
|
NetworkManager::getInstance ().getGameNetworkInterface ();
|
|
if (gameNetworkInterface != NULL)
|
|
{
|
|
char
|
|
szMsg[8096] = "";
|
|
snprintf (szMsg, 8096,
|
|
"Player detected an error: Can not find command type: %d for unitId: %d [%s]. isCancelPreMorphCommand: %d Game out of synch.",
|
|
networkCommand->getCommandTypeId (),
|
|
networkCommand->getUnitId (),
|
|
(unitType !=
|
|
NULL ? unitType->getName (false).c_str () : "null"),
|
|
isCancelPreMorphCommand);
|
|
gameNetworkInterface->sendTextMessage (szMsg, -1, true, "");
|
|
}
|
|
|
|
std::string sError =
|
|
"Error [#3]: Game is out of sync, please check log files for details.";
|
|
//abort();
|
|
throw
|
|
megaglest_runtime_error (sError);
|
|
}
|
|
|
|
CardinalDir
|
|
facing;
|
|
// Get direction of the command target unit.
|
|
if (isCancelPreMorphCommand == false)
|
|
{
|
|
// If target is a building.
|
|
if (ct->getClass () == ccBuild)
|
|
{
|
|
// Check the target building ID is valid. If not, throw an error.
|
|
/// TODO: What is happening here? The error returned does not match the condition. Why is there a constant of 4?
|
|
if (networkCommand->getTargetId () < 0
|
|
|| networkCommand->getTargetId () >= 4)
|
|
{
|
|
char
|
|
szBuf[8096] = "";
|
|
snprintf (szBuf, 8096,
|
|
"networkCommand->getTargetId() >= 0 && networkCommand->getTargetId() < 4, [%s]",
|
|
networkCommand->toString ().c_str ());
|
|
throw
|
|
megaglest_runtime_error (szBuf);
|
|
}
|
|
facing = CardinalDir (networkCommand->getTargetId ());
|
|
}
|
|
// Get the target unit if the ID is valid.
|
|
else if (networkCommand->getTargetId () != Unit::invalidId)
|
|
{
|
|
target = world->findUnitById (networkCommand->getTargetId ());
|
|
}
|
|
}
|
|
|
|
// Create the command.
|
|
Command *
|
|
command = NULL;
|
|
if (isCancelPreMorphCommand == false)
|
|
{
|
|
if (unitType != NULL)
|
|
{
|
|
command =
|
|
new Command (ct, networkCommand->getPosition (), unitType,
|
|
facing);
|
|
}
|
|
else if (target == NULL)
|
|
{
|
|
command = new Command (ct, networkCommand->getPosition ());
|
|
}
|
|
else
|
|
{
|
|
command = new Command (ct, target);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
command = new Command (ct, NULL);
|
|
}
|
|
|
|
// Add in any special state
|
|
CommandStateType
|
|
commandStateType = networkCommand->getCommandStateType ();
|
|
int
|
|
commandStateValue = networkCommand->getCommandStateValue ();
|
|
|
|
command->setStateType (commandStateType);
|
|
command->setStateValue (commandStateValue);
|
|
command->setUnitCommandGroupId (networkCommand->
|
|
getUnitCommandGroupId ());
|
|
|
|
if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem).
|
|
enabled)
|
|
SystemFlags::OutputDebug (SystemFlags::debugSystem,
|
|
"In [%s::%s Line: %d]\n",
|
|
extractFileFromDirectoryPath (__FILE__).
|
|
c_str (), __FUNCTION__, __LINE__);
|
|
|
|
//issue command
|
|
return command;
|
|
}
|
|
|
|
}
|
|
} //end namespace
|