/** ** Change player faction. ** ** @param faction New faction. */ void CPlayer::SetFaction(const std::string &faction) { for (int i = 0; i < FactionMax; ++i) { if (!PlayerRaces.FactionNames[this->Race][i].empty() && PlayerRaces.FactionNames[this->Race][i] == faction) { if (!IsNetworkGame()) { //only set the faction's name as the player's name if this is a single player game this->SetName(faction); } this->Faction = i; int PrimaryColor; int SecondaryColor; for (int j = 0; j < PlayerColorMax; ++j) { if (PlayerColorNames[j] == PlayerRaces.FactionColors[this->Race][i]) { PrimaryColor = j; } if (PlayerColorNames[j] == PlayerRaces.FactionSecondaryColors[this->Race][i]) { SecondaryColor = j; } } bool color_used = false; for (int j = 0; j < PlayerMax; ++j) { if (this->Index != j && Players[j].Faction != -1 && Players[j].Color == PlayerColors[PrimaryColor][0]) { color_used = true; } } if (!color_used) { this->Color = PlayerColors[PrimaryColor][0]; this->UnitColors.Colors = PlayerColorsRGB[PrimaryColor]; } else { this->Color = PlayerColors[SecondaryColor][0]; this->UnitColors.Colors = PlayerColorsRGB[SecondaryColor]; } } } }
/** ** Draw menu button area. */ void DrawMenuButtonArea(void) { if (!IsNetworkGame()) { if (UI.MenuButton.X != -1) { DrawMenuButton(UI.MenuButton.Style, (ButtonAreaUnderCursor == ButtonAreaMenu && ButtonUnderCursor == ButtonUnderMenu ? MI_FLAGS_ACTIVE : 0) | (GameMenuButtonClicked ? MI_FLAGS_CLICKED : 0), UI.MenuButton.X, UI.MenuButton.Y, UI.MenuButton.Text); } } else { if (UI.NetworkMenuButton.X != -1) { DrawMenuButton(UI.NetworkMenuButton.Style, (ButtonAreaUnderCursor == ButtonAreaMenu && ButtonUnderCursor == ButtonUnderNetworkMenu ? MI_FLAGS_ACTIVE : 0) | (GameMenuButtonClicked ? MI_FLAGS_CLICKED : 0), UI.NetworkMenuButton.X, UI.NetworkMenuButton.Y, UI.NetworkMenuButton.Text); } if (UI.NetworkDiplomacyButton.X != -1) { DrawMenuButton(UI.NetworkDiplomacyButton.Style, (ButtonAreaUnderCursor == ButtonAreaMenu && ButtonUnderCursor == ButtonUnderNetworkDiplomacy ? MI_FLAGS_ACTIVE : 0) | (GameDiplomacyButtonClicked ? MI_FLAGS_CLICKED : 0), UI.NetworkDiplomacyButton.X, UI.NetworkDiplomacyButton.Y, UI.NetworkDiplomacyButton.Text); } } }
/** ** Called if message for the network is ready. ** (by WaitEventsOneFrame) */ void NetworkEvent() { if (!IsNetworkGame()) { NetworkInSync = true; return; } // Read the packet. unsigned char buf[1024]; CHost host; int len = NetworkFildes.Recv(&buf, sizeof(buf), &host); if (len < 0) { DebugPrint("Server/Client gone?\n"); // just hope for an automatic recover right now.. NetworkInSync = false; return; } // Setup messages if (NetConnectRunning) { if (NetworkParseSetupEvent(buf, len, host)) { return; } } const unsigned char msgtype = buf[0]; if (msgtype == MessageInit_FromClient || msgtype == MessageInit_FromServer) { return; } NetworkParseInGameEvent(buf, len, host); }
/** ** Send command: Diplomacy changed. ** ** @param player Player which changes his state. ** @param state New diplomacy state. ** @param opponent Opponent. */ void SendCommandDiplomacy(int player, int state, int opponent) { if (!IsNetworkGame()) { switch (state) { case DiplomacyNeutral: CommandLog("diplomacy", NoUnitP, 0, player, opponent, NoUnitP, "neutral", -1); break; case DiplomacyAllied: CommandLog("diplomacy", NoUnitP, 0, player, opponent, NoUnitP, "allied", -1); break; case DiplomacyEnemy: CommandLog("diplomacy", NoUnitP, 0, player, opponent, NoUnitP, "enemy", -1); break; case DiplomacyCrazy: CommandLog("diplomacy", NoUnitP, 0, player, opponent, NoUnitP, "crazy", -1); break; } CommandDiplomacy(player, state, opponent); } else { NetworkSendExtendedCommand(ExtendedMessageDiplomacy, -1, player, state, opponent, 0); } }
/** ** Draw menu button area. */ void DrawMenuButtonArea() { if (!IsNetworkGame()) { DrawMenuButtonArea_noNetwork(); } else { DrawMenuButtonArea_Network(); } }
/** ** Send command: Buy an item from a building. ** ** @param unit pointer to unit. ** @param pos map tile position to move to. */ void SendCommandBuy(CUnit &unit, CUnit *sold_unit, int player) { if (!IsNetworkGame()) { CommandLog("buy", &unit, 0, -1, -1, sold_unit, NULL, player); CommandBuy(unit, sold_unit, player); } else { NetworkSendCommand(MessageCommandBuy, unit, player, 0, sold_unit, 0, 0); } }
/** ** Send command: Produce a resource. */ void SendCommandProduceResource(CUnit &unit, int resource) { if (!IsNetworkGame()) { CommandLog("produce-resource", &unit, 0, 0, -1, NoUnitP, NULL, resource); CommandProduceResource(unit, resource); } else { NetworkSendCommand(MessageCommandProduceResource, unit, resource, 0, NoUnitP, NULL, 0); } }
/** ** Send command: Set new rally point for unit. ** ** @param unit pointer to unit. ** @param pos map tile position to move to. */ void SendCommandRallyPoint(CUnit &unit, const Vec2i &pos, int z) { if (!IsNetworkGame()) { CommandLog("rally-point", &unit, 0, pos.x, pos.y, NoUnitP, NULL, -1); CommandRallyPoint(unit, pos, z); } else { NetworkSendCommand(MessageCommandMove, unit, pos.x, pos.y, NoUnitP, 0, 0); } }
/** ** Send command: Unit stop. ** ** @param unit pointer to unit. */ void SendCommandStopUnit(CUnit &unit) { if (!IsNetworkGame()) { CommandLog("stop", &unit, FlushCommands, -1, -1, NoUnitP, NULL, -1); CommandStopUnit(unit); } else { NetworkSendCommand(MessageCommandStop, unit, 0, 0, NoUnitP, 0, FlushCommands); } }
/** ** Send command: Building starts upgrading to. ** ** @param unit pointer to unit. ** @param what pointer to unit-type of the unit upgrade. ** @param flush Flag flush all pending commands. */ void SendCommandUpgradeTo(CUnit &unit, CUnitType &what, int flush) { if (!IsNetworkGame()) { CommandLog("upgrade-to", &unit, flush, -1, -1, NoUnitP, what.Ident.c_str(), -1); CommandUpgradeTo(unit, what, flush); } else { NetworkSendCommand(MessageCommandUpgrade, unit, 0, 0, NoUnitP, &what, flush); } }
/** ** Send command: Unit harvest resources ** ** @param unit pointer to unit. ** @param dest pointer to destination (oil-platform,gold mine). ** @param flush Flag flush all pending commands. */ void SendCommandResource(CUnit &unit, CUnit &dest, int flush) { if (!IsNetworkGame()) { CommandLog("resource", &unit, flush, -1, -1, &dest, NULL, -1); CommandResource(unit, dest, flush); } else { NetworkSendCommand(MessageCommandResource, unit, 0, 0, &dest, 0, flush); } }
/** ** Send command: Unit unload unit. ** ** @param unit pointer to unit. ** @param pos map tile position of unload. ** @param what Passagier to be unloaded. ** @param flush Flag flush all pending commands. */ void SendCommandUnload(CUnit &unit, const Vec2i &pos, CUnit *what, int flush) { if (!IsNetworkGame()) { CommandLog("unload", &unit, flush, pos.x, pos.y, what, NULL, -1); CommandUnload(unit, pos, what, flush); } else { NetworkSendCommand(MessageCommandUnload, unit, pos.x, pos.y, what, 0, flush); } }
/** ** Send command: Unit patrol between current and position. ** ** @param unit pointer to unit. ** @param pos map tile position to patrol between. ** @param flush Flag flush all pending commands. */ void SendCommandPatrol(CUnit &unit, const Vec2i &pos, int flush) { if (!IsNetworkGame()) { CommandLog("patrol", &unit, flush, pos.x, pos.y, NoUnitP, NULL, -1); CommandPatrolUnit(unit, pos, flush); } else { NetworkSendCommand(MessageCommandPatrol, unit, pos.x, pos.y, NoUnitP, 0, flush); } }
/** ** Send command: Unit attack ground. ** ** @param unit pointer to unit. ** @param pos map tile position to fire on. ** @param flush Flag flush all pending commands. */ void SendCommandAttackGround(CUnit &unit, const Vec2i &pos, int flush) { if (!IsNetworkGame()) { CommandLog("attack-ground", &unit, flush, pos.x, pos.y, NoUnitP, NULL, -1); CommandAttackGround(unit, pos, flush); } else { NetworkSendCommand(MessageCommandGround, unit, pos.x, pos.y, NoUnitP, 0, flush); } }
/** ** Send command: Unit attack unit or at position. ** ** @param unit pointer to unit. ** @param pos map tile position to attack. ** @param attack or !=NoUnitP unit to be attacked. ** @param flush Flag flush all pending commands. */ void SendCommandAttack(CUnit &unit, const Vec2i &pos, CUnit *attack, int flush) { if (!IsNetworkGame()) { CommandLog("attack", &unit, flush, pos.x, pos.y, attack, NULL, -1); CommandAttack(unit, pos, attack, flush); } else { NetworkSendCommand(MessageCommandAttack, unit, pos.x, pos.y, attack, 0, flush); } }
/** ** Send command: Unit repair. ** ** @param unit Pointer to unit. ** @param pos map tile position to repair. ** @param dest Unit to be repaired. ** @param flush Flag flush all pending commands. */ void SendCommandRepair(CUnit &unit, const Vec2i &pos, CUnit *dest, int flush) { if (!IsNetworkGame()) { CommandLog("repair", &unit, flush, pos.x, pos.y, dest, NULL, -1); CommandRepair(unit, pos, dest, flush); } else { NetworkSendCommand(MessageCommandRepair, unit, pos.x, pos.y, dest, 0, flush); } }
/** ** Send command: Pick up item. ** ** @param unit pointer to unit. ** @param dest pick up this item. ** @param flush Flag flush all pending commands. */ void SendCommandPickUp(CUnit &unit, CUnit &dest, int flush) { if (!IsNetworkGame()) { CommandLog("pick-up", &unit, flush, -1, -1, &dest, NULL, -1); CommandPickUp(unit, dest, flush); } else { NetworkSendCommand(MessageCommandPickUp, unit, 0, 0, &dest, 0, flush); } }
/** ** Send command: Unit auto repair. ** ** @param unit pointer to unit. ** @param on 1 for auto repair on, 0 for off. */ void SendCommandAutoRepair(CUnit &unit, int on) { if (!IsNetworkGame()) { CommandLog("auto-repair", &unit, FlushCommands, on, -1, NoUnitP, NULL, 0); CommandAutoRepair(unit, on); } else { NetworkSendCommand(MessageCommandAutoRepair, unit, on, -1, NoUnitP, NULL, FlushCommands); } }
/** ** Send command: Unit builds building at position. ** ** @param unit pointer to unit. ** @param pos map tile position of construction. ** @param what pointer to unit-type of the building. ** @param flush Flag flush all pending commands. */ void SendCommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int flush) { if (!IsNetworkGame()) { CommandLog("build", &unit, flush, pos.x, pos.y, NoUnitP, what.Ident.c_str(), -1); CommandBuildBuilding(unit, pos, what, flush); } else { NetworkSendCommand(MessageCommandBuild, unit, pos.x, pos.y, NoUnitP, &what, flush); } }
/** ** Send command: Unit return goods. ** ** @param unit pointer to unit. ** @param goal pointer to destination of the goods. (NULL=search best) ** @param flush Flag flush all pending commands. */ void SendCommandReturnGoods(CUnit &unit, CUnit *goal, int flush) { if (!IsNetworkGame()) { CommandLog("return", &unit, flush, -1, -1, goal, NULL, -1); CommandReturnGoods(unit, goal, flush); } else { NetworkSendCommand(MessageCommandReturn, unit, 0, 0, goal, 0, flush); } }
/** ** Send command: Unit harvests a location (wood for now). ** ** @param unit pointer to unit. ** @param pos map tile position where to harvest. ** @param flush Flag flush all pending commands. */ void SendCommandResourceLoc(CUnit &unit, const Vec2i &pos, int flush) { if (!IsNetworkGame()) { CommandLog("resource-loc", &unit, flush, pos.x, pos.y, NoUnitP, NULL, -1); CommandResourceLoc(unit, pos, flush); } else { NetworkSendCommand(MessageCommandResourceLoc, unit, pos.x, pos.y, NoUnitP, 0, flush); } }
/** ** Send command: Unit starts upgrading to. ** ** @param unit pointer to unit. ** @param what pointer to unit-type of the unit upgrade. ** @param flush Flag flush all pending commands. */ void SendCommandTransformInto(CUnit &unit, CUnitType &what, int flush) { if (!IsNetworkGame()) { CommandLog("transform-into", &unit, flush, -1, -1, NoUnitP, what.Ident.c_str(), -1); CommandTransformIntoType(unit, what); } else { NetworkSendCommand(MessageCommandUpgrade, unit, 2, 0, NoUnitP, &what, flush); //use X as a way to mark that this is a transformation and not an upgrade } }
/** ** Send command: Defend some unit. ** ** @param unit pointer to unit. ** @param dest defend this unit. ** @param flush Flag flush all pending commands. */ void SendCommandDefend(CUnit &unit, CUnit &dest, int flush) { if (!IsNetworkGame()) { CommandLog("defend", &unit, flush, -1, -1, &dest, NULL, -1); CommandDefend(unit, dest, flush); } else { NetworkSendCommand(MessageCommandDefend, unit, 0, 0, &dest, 0, flush); } }
/** ** Send command: Building starts upgrading to. ** ** @param unit pointer to unit. ** @param what pointer to unit-type of the unit upgrade. ** @param flush Flag flush all pending commands. */ void SendCommandTransformInto(CUnit &unit, CUnitType &what, int flush) { if (!IsNetworkGame()) { CommandLog("transform-into", &unit, flush, -1, -1, NoUnitP, what.Ident.c_str(), -1); CommandTransformIntoType(unit, what); } else { NetworkSendCommand(MessageCommandTransform, unit, 0, 0, NoUnitP, &what, flush); } }
/** ** Send command: Buy a resource with copper. */ void SendCommandBuyResource(CUnit &unit, int resource, int player) { if (!IsNetworkGame()) { CommandLog("buy-resource", &unit, 0, resource, -1, NoUnitP, NULL, player); CommandBuyResource(unit, resource, player); } else { NetworkSendCommand(MessageCommandBuyResource, unit, resource, player, NoUnitP, NULL, 0); } }
/** ** Send command: Unit stand ground. ** ** @param unit pointer to unit. ** @param flush Flag flush all pending commands. */ void SendCommandStandGround(CUnit &unit, int flush) { if (!IsNetworkGame()) { CommandLog("stand-ground", &unit, flush, -1, -1, NoUnitP, NULL, -1); CommandStandGround(unit, flush); } else { NetworkSendCommand(MessageCommandStand, unit, 0, 0, NoUnitP, 0, flush); } }
/** ** Send command: Follow unit to position. ** ** @param unit pointer to unit. ** @param dest follow this unit. ** @param flush Flag flush all pending commands. */ void SendCommandFollow(CUnit &unit, CUnit &dest, int flush) { if (!IsNetworkGame()) { CommandLog("follow", &unit, flush, -1, -1, &dest, NULL, -1); CommandFollow(unit, dest, flush); } else { NetworkSendCommand(MessageCommandFollow, unit, 0, 0, &dest, 0, flush); } }
/** ** Send command: Accept new quest for the unit's player. ** ** @param unit pointer to unit. ** @param pos map tile position to move to. */ void SendCommandQuest(CUnit &unit, CQuest *quest) { if (!IsNetworkGame()) { CommandLog("quest", &unit, 0, 0, 0, NoUnitP, quest->Ident.c_str(), -1); CommandQuest(unit, quest); } else { NetworkSendCommand(MessageCommandQuest, unit, quest->ID, 0, NoUnitP, NULL, 0); } }
/** ** Wait for interactive input event for one frame. ** ** Handles system events, joystick, keyboard, mouse. ** Handles the network messages. ** Handles the sound queue. ** ** All events available are fetched. Sound and network only if available. ** Returns if the time for one frame is over. */ void WaitEventsOneFrame() { ++FrameCounter; Uint32 ticks = SDL_GetTicks(); if (ticks > NextFrameTicks) { // We are too slow :( ++SlowFrameCounter; } InputMouseTimeout(*GetCallbacks(), ticks); InputKeyTimeout(*GetCallbacks(), ticks); CursorAnimate(ticks); int interrupts = 0; for (;;) { // Time of frame over? This makes the CPU happy. :( ticks = SDL_GetTicks(); if (!interrupts && ticks < NextFrameTicks) { SDL_Delay(NextFrameTicks - ticks); ticks = SDL_GetTicks(); } while (ticks >= NextFrameTicks) { ++interrupts; FrameFraction += FrameRemainder; if (FrameFraction > 10) { FrameFraction -= 10; ++NextFrameTicks; } NextFrameTicks += FrameTicks; } SDL_Event event[1]; const int i = SDL_PollEvent(event); if (i) { // Handle SDL event SdlDoEvent(*GetCallbacks(), *event); } // Network int s = 0; if (IsNetworkGame()) { s = NetworkFildes.HasDataToRead(0); if (s > 0) { GetCallbacks()->NetworkEvent(); } } // No more input and time for frame over: return if (!i && s <= 0 && interrupts) { break; } } handleInput(NULL); if (!SkipGameCycle--) { SkipGameCycle = SkipFrames; } }
/** ** Send command: Unit auto spell cast. ** ** @param unit pointer to unit. ** @param spellid Spell type id. ** @param on 1 for auto cast on, 0 for off. */ void SendCommandAutoSpellCast(CUnit &unit, int spellid, int on) { if (!IsNetworkGame()) { CommandLog("auto-spell-cast", &unit, FlushCommands, on, -1, NoUnitP, NULL, spellid); CommandAutoSpellCast(unit, spellid, on); } else { NetworkSendCommand(MessageCommandSpellCast + spellid, unit, on, -1, NoUnitP, NULL, FlushCommands); } }