=== modified file 'src/CMakeLists.txt' --- src/CMakeLists.txt 2009-06-02 22:00:36 +0000 +++ src/CMakeLists.txt 2009-06-06 17:26:22 +0000 @@ -33,6 +33,7 @@ ctrlComboBox.cpp ctrlComboBox.h ctrlDeepening.cpp ctrlDeepening.h ctrlEdit.cpp ctrlEdit.h + ctrlSpinbox.cpp ctrlSpinbox.h ctrlGroup.cpp ctrlGroup.h ctrlImage.cpp ctrlImage.h ctrlList.cpp ctrlList.h === modified file 'src/GameCommands.cpp' --- src/GameCommands.cpp 2009-06-05 22:00:39 +0000 +++ src/GameCommands.cpp 2009-06-07 12:10:26 +0000 @@ -22,10 +22,12 @@ #include "main.h" #include "GameCommands.h" #include "GameClientPlayer.h" +#include "GameServer.h" #include "GameWorld.h" #include "nobUsual.h" #include "nobMilitary.h" #include "nobBaseWarehouse.h" +#include "GlobalGameSettings.h" using namespace gc; @@ -58,6 +60,7 @@ case SURRENDER: return new Surrender(ser); case CHEAT_ARMAGEDDON: return new CheatArmageddon(ser); case DESTROYALL: return new DestroyAll(ser); + case CHANGEGGS: return new ChangeGGS(ser); } return NULL; @@ -175,3 +178,15 @@ void SuggestPact::Execute(GameWorldGame& gwg, GameClientPlayer& player, const unsigned char playerid) { } + +void ChangeGGS::Execute(GameWorldGame& gwg, GameClientPlayer& player, const unsigned char playerid) +{ + Serializer ser; + for (unsigned short i = 0; i < data.size(); ++i) + ser.PushUnsignedChar(data[i]); + GlobalGameSettings ggs; + ggs.Deserialize(&ser); + GAMESERVER.ChangeGlobalGameSettings(ggs); +} + + === modified file 'src/GameCommands.h' --- src/GameCommands.h 2009-06-07 09:55:32 +0000 +++ src/GameCommands.h 2009-06-07 12:12:42 +0000 @@ -4,6 +4,8 @@ #include "Serializer.h" #include "GameConsts.h" #include "MapConsts.h" +#include "GlobalGameSettings.h" +#include "GameClient.h" #include #include @@ -39,10 +41,11 @@ CHANGEINVENTORYSETTING, CHANGEALLINVENTORYSETTINGS, CHANGERESERVE, - SUGGESTPACT, + SUGGESTPACT, SURRENDER, CHEAT_ARMAGEDDON, - DESTROYALL + DESTROYALL, + CHANGEGGS }; @@ -64,10 +67,10 @@ /// Führt das GameCommand aus virtual void Execute(GameWorldGame& gwg, GameClientPlayer& player, const unsigned char playerid) = 0; -}; - - - +}; + + + /// Basisklasse für sämtliche GameCommands mit Koordinaten class Coords : public GameCommand { @@ -601,41 +604,78 @@ /// Führt das GameCommand aus void Execute(GameWorldGame& gwg, GameClientPlayer& player, const unsigned char playerid); }; - -/// Unterbreitet anderen Spielern einen Bündnisvertrag -class SuggestPact : public GameCommand + +/// Unterbreitet anderen Spielern einen Bündnisvertrag +class SuggestPact : public GameCommand +{ + /// Vertrags-ID, um sich später darauf hier beziehen zu können + const unsigned id; + /// Spieler, dem das Angebot unterbreitet werden soll + const unsigned char player; + /// Art des Vertrages + const PactType pt; + /// Dauer des Vertrages + const unsigned duration; + +public: + + SuggestPact(const unsigned id, const unsigned char player, const PactType pt, const unsigned duration) : GameCommand(SUGGESTPACT), + id(id), player(player), pt(pt), duration(duration) {} + SuggestPact(Serializer * ser) : GameCommand(SUGGESTPACT), + id(ser->PopUnsignedInt()), player(ser->PopUnsignedChar()), pt(PactType(ser->PopUnsignedChar())), duration(ser->PopUnsignedInt()) {} + + + virtual void Serialize(Serializer *ser) const + { + ser->PushUnsignedInt(id); + ser->PushUnsignedChar(player); + ser->PushUnsignedChar(static_cast(pt)); + ser->PushUnsignedInt(duration); + } + + /// Führt das GameCommand aus + void Execute(GameWorldGame& gwg, GameClientPlayer& player, const unsigned char playerid); +}; + + +/// GGS ändern +class ChangeGGS : public GameCommand { - /// Vertrags-ID, um sich später darauf hier beziehen zu können - const unsigned id; - /// Spieler, dem das Angebot unterbreitet werden soll - const unsigned char player; - /// Art des Vertrages - const PactType pt; - /// Dauer des Vertrages - const unsigned duration; - + friend class GameClient; + + std::vector data; public: - - SuggestPact(const unsigned id, const unsigned char player, const PactType pt, const unsigned duration) : GameCommand(SUGGESTPACT), - id(id), player(player), pt(pt), duration(duration) {} - SuggestPact(Serializer * ser) : GameCommand(SUGGESTPACT), - id(ser->PopUnsignedInt()), player(ser->PopUnsignedChar()), pt(PactType(ser->PopUnsignedChar())), duration(ser->PopUnsignedInt()) {} - - - virtual void Serialize(Serializer *ser) const - { - ser->PushUnsignedInt(id); - ser->PushUnsignedChar(player); - ser->PushUnsignedChar(static_cast(pt)); - ser->PushUnsignedInt(duration); - } - - /// Führt das GameCommand aus - void Execute(GameWorldGame& gwg, GameClientPlayer& player, const unsigned char playerid); -}; - -} - + //ChangeGGS(const std::vector& data) + // : GameCommand(CHANGEGGS), data(data) {} + ChangeGGS(Serializer * ser) + : GameCommand(CHANGEGGS) + { + // there's no static 'length' constant + for(unsigned i = 0;iPopUnsignedChar()); + } + ChangeGGS(const GlobalGameSettings & ggs) + : GameCommand(CHANGEGGS) + { + Serializer ser; + ggs.Serialize(&ser); + for(unsigned i = 0;iPushUnsignedChar(data[i]); + } + + /// Führt das GameCommand aus + void Execute(GameWorldGame& gwg, GameClientPlayer& player, const unsigned char playerid); +}; + +} + + #endif === modified file 'src/GameServer.cpp' --- src/GameServer.cpp 2009-06-01 22:00:30 +0000 +++ src/GameServer.cpp 2009-06-07 17:55:24 +0000 @@ -577,6 +577,22 @@ // Spieleinstellungen verschicken void GameServer::ChangeGlobalGameSettings(const GlobalGameSettings& ggs) { + std::queue > > diff = ggs.enhs.Compare(this->ggs.enhs); + if (!diff.empty()) + { + std::string text = ""; + text += _("Game settings changed") + std::string(":"); + std::pair > entry; + while (!diff.empty()) + { + entry = diff.front(); diff.pop(); + text += "\n\"" + ggs.enhs.by_id(entry.first)->GetName() + "\" from \"" + + this->ggs.enhs.by_id(entry.first)->GetStateStr() + "\" to \"" + + ggs.enhs.by_id(entry.first)->GetStateStr() + "\""; + + } + SendToAll(GameMessage_Server_Chat(0, CD_SYSTEM, text)); + } this->ggs = ggs; SendToAll(GameMessage_GGSChange(ggs)); LOG.write("SERVER >>> BROADCAST: NMS_GGS_CHANGE\n"); === modified file 'src/GlobalGameSettings.cpp' --- src/GlobalGameSettings.cpp 2009-05-26 22:00:35 +0000 +++ src/GlobalGameSettings.cpp 2009-06-03 19:15:56 +0000 @@ -40,7 +40,7 @@ ser->PushUnsignedChar(static_cast(exploration)); ser->PushBool(team_view); ser->PushUnsignedChar(static_cast(demolition_prohibition)); - enhs.Serialize(ser); + enhs.Serialize(*ser); } void GlobalGameSettings::Deserialize(Serializer * ser) @@ -52,5 +52,5 @@ exploration = static_cast(ser->PopUnsignedChar()); team_view = ser->PopBool(); demolition_prohibition = static_cast(ser->PopUnsignedChar()); - enhs.Deserialize(ser); + enhs.Deserialize(*ser); } === modified file 'src/GlobalGameSettings.h' --- src/GlobalGameSettings.h 2009-05-26 22:00:35 +0000 +++ src/GlobalGameSettings.h 2009-06-03 19:15:56 +0000 @@ -50,7 +50,7 @@ /// Größe des Serialisierungsbuffers // static const unsigned GGS_BUFFER_SIZE = 7; - unsigned GetLength() const {return 7 + 1 + 8 * enhs.size(); } + const unsigned GetLength() const {return 7 + enhs.GetLength(); } /// Serialisierung und Deserialisierung void Serialize(Serializer * ser) const; === modified file 'src/Settings.cpp' --- src/Settings.cpp 2009-05-26 22:00:35 +0000 +++ src/Settings.cpp 2009-06-03 19:15:56 +0000 @@ -198,7 +198,7 @@ return LoadDefaults(); } } - enhs->Deserialize(&ser); + enhs->Deserialize(ser); return true; } @@ -260,7 +260,7 @@ // We have to do a little encoding to save the default enhancement options, for we can't use 0x00 in the raw data Serializer ser; - enhs->Serialize(&ser); + enhs->Serialize(ser); unsigned char c; std::string enhText = ""; for (unsigned short pos = 0; pos < ser.GetLength(); ++pos) === modified file 'src/Window.cpp' --- src/Window.cpp 2009-05-26 22:00:35 +0000 +++ src/Window.cpp 2009-06-07 17:55:24 +0000 @@ -543,6 +543,36 @@ /////////////////////////////////////////////////////////////////////////////// /** + * fügt ein SpinboxCtrl hinzu. + * + * @author Divan + */ +ctrlSpinbox *Window::AddSpinbox(unsigned int id, + unsigned short x, + unsigned short y, + unsigned short width, + unsigned short height, + TextureColor tc, + glArchivItem_Font *font, + bool disabled, + bool notify, + int min, + int max) +{ + if(scale) + { + x = ScaleX(x); + y = ScaleY(y); + width = ScaleX(width); + height = ScaleY(height); + } + + return AddCtrl(id, new ctrlSpinbox(this, id, x, y, width, height, tc, font, disabled, notify, min, max)); +} + + +/////////////////////////////////////////////////////////////////////////////// +/** * fügt eine Gruppe hinzu. * * @author FloSoft === modified file 'src/Window.h' --- src/Window.h 2009-05-26 22:00:35 +0000 +++ src/Window.h 2009-06-07 17:55:24 +0000 @@ -41,6 +41,7 @@ class ctrlDeepening; class ctrlColorDeepening; class ctrlEdit; +class ctrlSpinbox; class ctrlGroup; class ctrlImage; class ctrlList; @@ -157,6 +158,8 @@ ctrlColorDeepening *AddColorDeepening(unsigned int id, unsigned short x, unsigned short y, unsigned short width, unsigned short height, TextureColor tc, unsigned int fillColor); /// fügt ein EditCtrl hinzu. ctrlEdit *AddEdit(unsigned int id, unsigned short x, unsigned short y, unsigned short width, unsigned short height, TextureColor tc, glArchivItem_Font *font, unsigned short maxlength = 0, bool password = false, bool disabled = false, bool notify = false); + /// fügt ein SpinboxCtrl hinzu. + ctrlSpinbox *AddSpinbox(unsigned int id, unsigned short x, unsigned short y, unsigned short width, unsigned short height, TextureColor tc, glArchivItem_Font *font, bool disabled = false, bool notify = false, int min = 0, int max = 0xFF); /// fügt eine Gruppe hinzu. ctrlGroup *AddGroup(unsigned int id, bool scale = false); /// fügt ein ImageCtrl hinzu. === modified file 'src/controls.h' --- src/controls.h 2009-04-27 22:00:38 +0000 +++ src/controls.h 2009-06-07 17:55:24 +0000 @@ -26,6 +26,7 @@ #include "ctrlComboBox.h" #include "ctrlDeepening.h" #include "ctrlEdit.h" +#include "ctrlSpinbox.h" #include "ctrlGroup.h" #include "ctrlImage.h" #include "ctrlList.h" === modified file 'src/ctrlButton.cpp' --- src/ctrlButton.cpp 2009-06-03 22:00:33 +0000 +++ src/ctrlButton.cpp 2009-06-07 12:10:26 +0000 @@ -221,6 +221,7 @@ { } +/// Abgeleitete Klassen müssen erweiterten Button-Inhalt zeichnen (Text in dem Fall) void ctrlImageButton::DrawContent() const { // Bild @@ -229,7 +230,6 @@ } -/// Abgeleitete Klassen müssen erweiterten Button-Inhalt zeichnen (Text in dem Fall) ctrlColorButton::ctrlColorButton(Window *parent, unsigned int id, unsigned short x, unsigned short y, unsigned short width, unsigned short height, const TextureColor tc, unsigned int fillColor, const std::string& tooltip) : === modified file 'src/ctrlCheck.h' --- src/ctrlCheck.h 2009-04-27 22:00:38 +0000 +++ src/ctrlCheck.h 2009-05-31 14:42:45 +0000 @@ -32,6 +32,8 @@ bool GetCheck() const { return check; } void SetReadOnly(bool readonly) { this->readonly = readonly; } bool GetReadOnly() const { return readonly; } + /// Setzt Text + void SetText(const std::string& text) { this->text = text; } virtual bool Msg_LeftDown(const MouseCoords& mc); === modified file 'src/ctrlComboBox.cpp' --- src/ctrlComboBox.cpp 2009-05-07 22:00:30 +0000 +++ src/ctrlComboBox.cpp 2009-05-31 13:35:20 +0000 @@ -64,7 +64,8 @@ void ctrlComboBox::Msg_PaintAfter() { // Button und Liste malen - DrawControls(); + if (visible) + DrawControls(); } /////////////////////////////////////////////////////////////////////////////// === modified file 'src/ctrlComboBox.h' --- src/ctrlComboBox.h 2009-05-07 22:00:30 +0000 +++ src/ctrlComboBox.h 2009-05-31 13:35:20 +0000 @@ -29,6 +29,9 @@ public: ctrlComboBox(Window *parent, unsigned int id, unsigned short x, unsigned short y, unsigned short width, unsigned short height, TextureColor tc, glArchivItem_Font *font, unsigned short list_height, bool readonly); + void SetReadOnly(bool readonly) { this->readonly = readonly; } + bool GetReadOnly() const { return readonly; } + void AddString(const std::string& text); void DeleteAllItems(); === modified file 'src/ctrlMultiline.cpp' --- src/ctrlMultiline.cpp 2009-05-09 22:00:30 +0000 +++ src/ctrlMultiline.cpp 2009-05-31 13:35:20 +0000 @@ -53,35 +53,39 @@ AddScrollBar(0, width - SCROLLBAR_WIDTH, 0, SCROLLBAR_WIDTH, height, SCROLLBAR_WIDTH, tc, lines_in_control); } +/////////////////////////////////////////////////////////////////////////////// +/** + * deletes all text + * + * @author OLiver + */ +void ctrlMultiline::DeleteAllItems() +{ + lines.clear(); + ctrlScrollBar *scrollbar = GetCtrl(0); + scrollbar->SetRange(0); + scrollbar->SetPos(0); +} + ///////////////////////////////////////////////////////////////////////////////// -///** -// * fügt einen mehrzeiligen Text hinzu. -// * -// * @author FloSoft -// */ -//void ctrlMultiline::AddText(const std::string& text, unsigned int color) -//{ -// size_t i; -// size_t length = strlen(text); -// char *temp = new char[length + 1]; -// char *s = temp; -// -// // In temporaeren String kopieren, damit man diesen zerlegen kann -// memcpy(temp, text, length); -// -// // Zeilenweise einfuegen -// for (i = 0; i < length; ++i) { -// if(temp[i] == '\n') { -// temp[i] = '\0'; -// AddString(s, color, false); -// s = &temp[i + 1]; -// } -// } -// if (s < &temp[i]) AddString(s, color, false); - -// delete[] temp; -//} +/** + * fügt einen mehrzeiligen Text hinzu. + * + * @author FloSoft + */ +void ctrlMultiline::AddText(const std::string& text, unsigned int color) +{ + glArchivItem_Font::WrapInfo wi; + font->GetWrapInfo(text, GetWidth(), GetWidth(), wi); + if (wi.count > lines_in_control) + font->GetWrapInfo(text, GetWidth()-ctrlMultiline::SCROLLBAR_WIDTH, GetWidth()-ctrlMultiline::SCROLLBAR_WIDTH, wi); + std::string * lines = new std::string[wi.count]; + wi.CreateSingleStrings(text, lines); + for (unsigned i = 0; i < wi.count; ++i) + AddString(lines[i], color, false); + delete [] lines; +} /////////////////////////////////////////////////////////////////////////////// /** === modified file 'src/ctrlMultiline.h' --- src/ctrlMultiline.h 2009-05-24 22:00:34 +0000 +++ src/ctrlMultiline.h 2009-05-31 13:35:20 +0000 @@ -31,7 +31,8 @@ public: ctrlMultiline(Window *parent, unsigned int id, unsigned short x, unsigned short y, unsigned short width, unsigned short height, TextureColor tc, glArchivItem_Font *font, unsigned int format = 0); - //void AddText(const std::string& text, unsigned int color); + void DeleteAllItems(); + void AddText(const std::string& text, unsigned int color); void AddString(const std::string& str, unsigned int color, bool scroll = true); unsigned GetLineCount() { return unsigned(lines.size()); } /// Gibt den index-ten Eintrag zurück === modified file 'src/dskGameInterface.cpp' --- src/dskGameInterface.cpp 2009-05-26 22:00:35 +0000 +++ src/dskGameInterface.cpp 2009-06-01 11:08:54 +0000 @@ -38,6 +38,7 @@ #include "LobbyClient.h" #include "ctrlButton.h" #include "GameMessages.h" +#include "enhOption.h" #include "iwChat.h" #include "iwHQ.h" @@ -233,6 +234,8 @@ { // in "richtige" Map-Koordinaten Konvertieren, den aktuellen selektierten Punkt unsigned short cselx=gwv->GetSelX(),csely = gwv->GetSelY(); + // Um auf Wasserweglängenbegrenzun reagieren zu können: + unsigned short cselx2 = cselx, csely2 = csely; if(cselx == road.point_x && csely == road.point_y) { @@ -260,18 +263,27 @@ else { if(BuildRoadPart(cselx,csely,1)) - CommandBuildRoad(); + { + // Ist der Zielpunkt der gleiche geblieben? + if (cselx2==cselx && csely2==csely) + CommandBuildRoad(); + } else - ShowRoadWindow(mc.x,mc.y); + if (cselx2==cselx && csely2==csely) + ShowRoadWindow(mc.x,mc.y); } } // Wurde auf eine Flagge geklickt und ist diese Flagge nicht der Weganfangspunkt? else if(gwv->GetNO(cselx,csely)->GetType() == NOP_FLAG && !(cselx == road.start_x && csely == road.start_y)) { if(BuildRoadPart(cselx,csely,1)) - CommandBuildRoad(); + { + if (cselx2==cselx && csely2==csely) + CommandBuildRoad(); + } else - ShowRoadWindow(mc.x,mc.y); + if (cselx2==cselx && csely2==csely) + ShowRoadWindow(mc.x,mc.y); } else @@ -636,7 +648,7 @@ * * @author OLiver */ -bool dskGameInterface::BuildRoadPart(const int cselx, const int csely,bool end) +bool dskGameInterface::BuildRoadPart(short unsigned int &cselx, short unsigned int &csely,bool end) { std::vector new_route; bool path_found = gwv->FindRoadPath(road.point_x,road.point_y,cselx,csely,new_route, road.mode == RM_BOAT); @@ -644,6 +656,18 @@ // Weg gefunden? if(!path_found) return false; + + // Test on water way length + unsigned short max_length = GAMECLIENT.GetGGS().enhs.by_id(ENH_WATERWAYLENGTH)->GetState(); + if(road.mode == RM_BOAT) + { + unsigned short length = road.route.size() + new_route.size(); + if (max_length > 0) while(length > max_length) // max_length == 0: beliebig lang + { + new_route.pop_back(); + --length; + } + } // Weg (visuell) bauen for(unsigned i = 0;iGetPointA(road.point_x,road.point_y, new_route[i]); gwv->CalcRoad(road.point_x,road.point_y,GAMECLIENT.GetPlayerID()); } + // Zielpunkt updaten (für Wasserweg) + cselx = road.point_x; + csely = road.point_y; road.route.insert(road.route.end(), new_route.begin(), new_route.end()); @@ -792,10 +819,6 @@ void dskGameInterface::CI_GGSChanged(const GlobalGameSettings& ggs) { - // TODO: print what has changed - char text[256]; - snprintf(text, 256, _("Note: Game settings changed by the server%s"),""); - messenger.AddMessage("", 0, CD_SYSTEM, text); } void dskGameInterface::CI_Chat(const unsigned player_id, const ChatDestination cd, const std::string& msg) === modified file 'src/dskGameInterface.h' --- src/dskGameInterface.h 2009-05-26 22:00:35 +0000 +++ src/dskGameInterface.h 2009-05-31 20:29:22 +0000 @@ -119,7 +119,8 @@ friend class RoadSegment; // Sucht einen Weg von road_point_x/y zu cselx/y und baut ihn ( nur visuell ) - bool BuildRoadPart(const int cselx, const int csely,bool end); + // Bei Wasserwegen kann die Reichweite nicht genügen, dann werden die Zielkoordinaten neu gesetzt, damit nicht das Abbruchfenster gezeigt werden muss. + bool BuildRoadPart(short unsigned int &cselx, short unsigned int &csely,bool end); // Prft, ob x;y auf der bereits gebauten Strecke liegt und gibt die Position+1 zurck vom Startpunkt der Strecke aus // wenn der Punkt nicht draufliegt, kommt 0 zurck unsigned TestBuiltRoad(const int x, const int y); === modified file 'src/dskHostGame.cpp' --- src/dskHostGame.cpp 2009-06-01 22:00:30 +0000 +++ src/dskHostGame.cpp 2009-06-07 17:55:24 +0000 @@ -93,8 +93,8 @@ AddCheckBox(19, 600, 460, 180, 26, TC_GREY, _("Shared team view"), NormalFont, !GAMECLIENT.IsHost()||GAMECLIENT.IsSavegame()); // "Enhancements" - AddText(21, 400, 499, _("Enhancements:"), COLOR_YELLOW, 0, NormalFont); - AddTextButton(22, 600, 495, 180, 22, TC_GREEN1, (GAMECLIENT.IsHost() ? _("Change Settings...") : _("View Settings...")),NormalFont); + AddText(21, 400, 499, _("Game Settings:"), COLOR_YELLOW, 0, NormalFont); + AddTextButton(22, 600, 495, 180, 22, TC_GREEN1, (GAMECLIENT.IsHost() ? _("Change...") : _("View...")),NormalFont); ctrlComboBox *combo; @@ -461,10 +461,10 @@ { unsigned char policy; if (GAMECLIENT.IsHost()) - policy = (GAMECLIENT.IsSavegame() ? ENH_POLICY_SERVERINGAME : ENH_POLICY_HOSTMENU); + policy = (GAMECLIENT.IsSavegame() ? ENH_POLICY_HOSTMENUINGAME : ENH_POLICY_HOSTMENU); else policy = ENH_POLICY_READONLY; - WindowManager::inst().Show(new iwEnhancements(&ggs.enhs, policy, &dskHostGame::UpdateGGS, this)); + WindowManager::inst().Show(new iwEnhancements(&ggs.enhs, policy)); } break; } } @@ -764,8 +764,12 @@ char time_string[64]; TIME.FormatTime(time_string, "(%H:%i:%s)", NULL); - GetCtrl(1)->AddMessage(time_string,GAMECLIENT.GetPlayer(player_id)->name.c_str(), - COLORS[GAMECLIENT.GetPlayer(player_id)->color],msg.c_str(),0xFFFFFF00); + if (cd != CD_SYSTEM) + GetCtrl(1)->AddMessage(time_string,GAMECLIENT.GetPlayer(player_id)->name.c_str(), + COLORS[GAMECLIENT.GetPlayer(player_id)->color],msg.c_str(),COLOR_YELLOW); + else + GetCtrl(1)->AddMessage(time_string,_("SYSTEM"), + COLOR_GREY,msg.c_str(),COLOR_YELLOW); } } === modified file 'src/enhOption.cpp' --- src/enhOption.cpp 2009-05-26 22:00:35 +0000 +++ src/enhOption.cpp 2009-06-07 17:55:24 +0000 @@ -21,55 +21,131 @@ #include "main.h" ////////////////////////////////////////////////// +// Enhancement options' definitions here +// The 'real' code follows below + +void enhOptions::FillOptions() +{ + enhOption *enh; + + /* First, a short example with explainations: + + // Define an ID in enhOption.h! + + // Construct a new enhOption instance. + // Arguments are: + // id - Your chosen Id + // type - One of OPT_BOOL, OPT_SELECT, OPT_INT + // def - A default value. For OPT_BOOL: true = 1, false = 0. + // For OPT_SELECT: index value, starting with 0 + // original - What value reproduces the original behaviour? + // Choose def, if not applicable + // name - A (short) name string. Enclose in _("") for translation + // ingameChangeable - Whether the option may be changed while playing + // not implemented right now + // group - one of OPT_NONE, OPT_MILITARY, OPT_ECONOMY, OPT_CONSTRUCTION + // Maybe we will once have so many options that we need groups + enh = new enhOption(unsigned int id, OptType type, int def, std::string name, bool ingameChangeable, OptGroup group); + + // Set the description text. + // This should make clear what this option does - the user doesn't + // want to start a game to test the effect. + // Using \n for a newline or \n\n for an empty line makes long texts + // a lot easier to read. Don't put spaces around the \n's! + enh->description = _("Your desription\nThis comes into a new line, even if not wrapped by the automatic wrapper.\n\n\nThis leaves 2 empty lines."); + + // For OPT_INT, you have to set the the limits + // Values are implemented as int (4-byte), this should fit any purpose + enh->min = -399; + enh->max = 50000; + + // For OPT_SELECT, you now have to define the choices + // and set the maximum value accordingly. + enh->selections.push_back("First option"); + enh->selections.push_back("Second option"); + enh->selections.push_back("Third option"); + enh->max = 2; + + */ + + +/* // example boolean option + enh = new enhOption(ENH_EXAMPLE1, OPT_BOOL, 0, 0, "Example option bool", true, OPT_NONE); + enh->description="Have fun using it"; + enh_by_id.insert(std::make_pair(enh->GetId(), enh)); + enh_by_order.push_back(enh);*/ + +/* // example multiple choice option + enh = new enhOption(ENH_EXAMPLE2, OPT_SELECT, 1, 1, "Example option select", false, OPT_NONE); + enh->description="testing a long text that should wrap and make new lines:\n\n\n\n Yay!"; + enh->selections.push_back("First option"); + enh->selections.push_back("Second option"); + enh->selections.push_back("Third option"); + enh->max = 2; + enh_by_id.insert(std::make_pair(enh->GetId(), enh)); + enh_by_order.push_back(enh);*/ + + // waterway length + enh = new enhOption(ENH_WATERWAYLENGTH, OPT_INT, 4, 4, _("Waterway length"), true, OPT_CONSTRUCTION); + enh->description = _("Limits the distance settlers may travel per boat.\n\n\"0\" allows any length.\n\"1\" actually prevents usage of waterways."); + enh->min = 0; + enh->max = 255; + enh_by_id.insert(std::make_pair(enh->GetId(), enh)); + enh_by_order.push_back(enh); +} + +// end of definitions +////////////////////////////////////////////////// + +////////////////////////////////////////////////// // Class enhOption -enhOption::enhOption(unsigned int id, OptType type, int def, int min, int max, std::string name, bool ingameChangeable, OptGroup group) +enhOption::enhOption(unsigned int id, OptType type, int def, int original, std::string name, bool ingameChangeable, OptGroup group) { this->id = id; this->type = type; this->def = def; + this->original = original; this->state = def; - this->min = min; - this->max = max; + min = 0; max = 0; + if (type == OPT_BOOL) + max = 1; this->name = name; this->description = ""; this->ingameChangeable = ingameChangeable; this->group = group; } +const std::string enhOption::GetStateStr(int state) const +{ + std::string s; + switch(GetType()) + { + case OPT_BOOL: + { + s = (state == 1 ? _("Enabled") : _("Disabled")); + } break; + case OPT_SELECT: + { + s = GetSelections(state); + } break; + case OPT_INT: + { + std::stringstream ss; + ss << state; + s = ss.str(); + } break; + } + return s; +} + ////////////////////////////////////////////////// // Class enhOptions -// enhancement option Ids -#define ENH_EXAMPLE1 10010000 -#define ENH_EXAMPLE2 10010002 -#define ENH_WATERWAYLENGTH 10010001 enhOptions::enhOptions(void) { - // Prepare enhancement options - enhOption *enh; - - // example boolean option - - enh = new enhOption(ENH_EXAMPLE1, OPT_BOOL, 0, 0, 1, "Example option bool", true, OPT_NONE); - enh->description="Have fun using it"; - enh_by_id.insert(std::make_pair(enh->GetId(), enh)); - enh_by_order.push_back(enh); - - enh = new enhOption(ENH_EXAMPLE2, OPT_SELECT, 1, 0, 2, "Example option select", false, OPT_NONE); - enh->description="Have fun using it"; - enh->selections.push_back("First option"); - enh->selections.push_back("Second option"); - enh->selections.push_back("Third option"); - enh_by_id.insert(std::make_pair(enh->GetId(), enh)); - enh_by_order.push_back(enh); - - // waterway length - enh = new enhOption(ENH_WATERWAYLENGTH, OPT_INT, 4, 0, 255, _("Waterway's maximum length"), true, OPT_CONSTRUCTION); - enh->description = _("0 means infinite"); - enh_by_id.insert(std::make_pair(enh->GetId(), enh)); - enh_by_order.push_back(enh); + FillOptions(); } enhOptions::~enhOptions() @@ -105,34 +181,53 @@ return *this; } -void enhOptions::Serialize(Serializer * ser) const +void enhOptions::Serialize(Serializer & ser) const { // number of options - ser->PushUnsignedChar(size()); + ser.PushUnsignedChar(size()); for(unsigned char i=0; i < size(); ++i) { - ser->PushUnsignedInt(enh_by_order[i]->GetId()); - ser->PushSignedInt(enh_by_order[i]->GetState()); + ser.PushUnsignedInt(enh_by_order[i]->GetId()); + ser.PushSignedInt(enh_by_order[i]->GetState()); } } -void enhOptions::Deserialize(Serializer * ser) +void enhOptions::Deserialize(Serializer & ser) { - unsigned char count = ser->PopUnsignedChar(); + unsigned char count = ser.PopUnsignedChar(); for(unsigned char i=0; i < count; ++i) { - const unsigned int id = ser->PopUnsignedInt(); + const unsigned int id = ser.PopUnsignedInt(); std::map::iterator it = enh_by_id.find(id); // Do we have an option with this id? Stay compatible with older savegames (and modified clients)! if (it->second->GetId() == id) { - it->second->SetState(ser->PopSignedInt()); + it->second->SetState(ser.PopSignedInt()); } else { - const int value = ser->PopSignedInt(); + const int value = ser.PopSignedInt(); LOG.lprintf("Warning: The game settings either loaded from Savegame or received from the server contain an unknown enhancement option with ID %d and value %d.\n", id, value); } } } + +std::queue > > enhOptions::Compare(const enhOptions& other) const +{ + std::queue > > result; + std::pair > entry; + int oldvalue, newvalue; + for (unsigned short i = 0; i < size(); ++i) + { + oldvalue = other.by_order(i)->GetState(); + newvalue = by_order(i)->GetState(); + if (oldvalue != newvalue) + { + entry = std::make_pair(by_order(i)->GetId(), std::make_pair(oldvalue, newvalue)); + result.push(entry); + } + } + return result; +} + === modified file 'src/enhOption.h' --- src/enhOption.h 2009-05-26 22:00:35 +0000 +++ src/enhOption.h 2009-06-07 17:55:24 +0000 @@ -21,8 +21,11 @@ #define ENHOPTION_H_INCLUDED #include +#include #include #include +#include +#include #include "main.h" // TODO: Work out what is needed from main.h #include "Serializer.h" @@ -41,6 +44,14 @@ OPT_CONSTRUCTION }; +/// option IDs +// Choose unique ones of course +// this list should stay sorted by number +#define ENH_EXAMPLE1 10010000 +#define ENH_EXAMPLE2 10010002 +#define ENH_WATERWAYLENGTH 10010001 + + class enhOption; class enhOptions; @@ -50,25 +61,27 @@ friend class enhOptions; public: /// Constructors - enhOption(void) : id(0), type(OPT_BOOL), def(0), state(0), min(0), max(0), name(""), description(""), ingameChangeable(false), group(OPT_NONE) {} - enhOption(unsigned int id, OptType type, int def, int min, int max, std::string name, bool isIngameChangeable, OptGroup group); + enhOption(unsigned int id, OptType type, int def, int original, std::string name, bool isIngameChangeable, OptGroup group); /// Destructor ~enhOption(void) {} - + // id inline const unsigned int GetId() const {return id; } // return type of option (bool, selections, integer) inline const OptType GetType() const { return type; } // return def value inline const int GetDef() const { return def; } - // get maximum value (useful for OPT_SELECT only, where min is 0) + // return original value + inline const int GetOriginal() const { return original; } + // get current state inline const int GetState() const { return state; } - // set current state, tell about success + const std::string GetStateStr(int state) const; + const std::string GetStateStr() const { return GetStateStr(GetState()); } + // get minimum value inline const int GetMin() const { return min; } - // return current state + // get minimum value inline const int GetMax() const { return max; } - // get maximum value (useful for OPT_SELECT only, where min is 0) // return name/description inline const std::string GetName() const { return name; } @@ -96,7 +109,7 @@ private: unsigned int id; OptType type; - int def, state, min, max; + int def, original, state, min, max; std::string name, description; bool ingameChangeable; OptGroup group; @@ -114,11 +127,15 @@ // Destructor ~enhOptions(void); - void Serialize(Serializer * serializer) const; - void Deserialize(Serializer * serializer); + void Serialize(Serializer & serializer) const; + void Deserialize(Serializer & serializer); enhOptions& operator=(enhOptions const& other); + // To keep track of changes + // returns queue of nested pairs: < id, < old value, new value > > + std::queue > > Compare(const enhOptions& other) const; + // get Option by ID enhOption* by_id(const unsigned int id) const { return (enh_by_id.find(id))->second; } // get Option by Number (for getting all of them in a predefined order) @@ -129,6 +146,9 @@ unsigned char * Serialize() const; void Deserialize(const unsigned char * buffer); +private: + void FillOptions(); + protected: std::map enh_by_id; std::vector enh_by_order; === modified file 'src/glArchivItem_Font.cpp' --- src/glArchivItem_Font.cpp 2009-04-27 22:00:38 +0000 +++ src/glArchivItem_Font.cpp 2009-05-31 13:35:20 +0000 @@ -339,8 +339,8 @@ // Leerzeichen, Umbruch oder ende? if(text[i] == '\n' || text[i] == ' ' || i == length) { - // Passt das letzte Wort mit auf die Zeile? (bzw bei newline immer neue zeile anfangen) - if(text[i] != '\n' && word_width + line_width <= ((wi.count==1) ? primary_width : secondary_width)) + // Passt das letzte Wort mit auf die Zeile? + if(word_width + line_width <= ((wi.count==1) ? primary_width : secondary_width)) { // Länge des Leerzeichens mit draufaddieren line_width += word_width; @@ -356,7 +356,7 @@ { // Ansonsten neue Zeile anfangen - // Passt das Wort wenigsens komplett überhaupt in die nächste Zeile? + // Passt das Wort wenigsens komplett überhaupt in die nächste Zeile? if(word_width <= secondary_width) { // neue Zeile anfangen mit diesem Wort @@ -403,6 +403,14 @@ } } } + // Bei Newline immer neue Zeile anfangen + if(text[i] == '\n' && i < length-1) + { + word_start = i+1; + word_width = 0; + line_width = 0; + wi.positions[wi.count++] = word_start; + } } else { === modified file 'src/iwEnhancements.cpp' --- src/iwEnhancements.cpp 2009-05-26 22:00:35 +0000 +++ src/iwEnhancements.cpp 2009-06-07 17:55:24 +0000 @@ -20,11 +20,12 @@ /////////////////////////////////////////////////////////////////////////////// // Header #include "main.h" -#include #include "iwEnhancements.h" #include "controls.h" +#include "GameServer.h" #include "GameClient.h" +#include "GameCommands.h" #include "GlobalVars.h" #include "WindowManager.h" @@ -38,33 +39,38 @@ static char THIS_FILE[] = __FILE__; #endif -#define BEGIN_ENH_CTRLS 100 - /////////////////////////////////////////////////////////////////////////////// /** * Konstruktor von @p iwEnhancements. * * @author Divan */ -iwEnhancements::iwEnhancements(enhOptions * original, const unsigned char policy, void (dskHostGame::*notifyFunc)(), dskHostGame * notifyInst) - : IngameWindow(CGI_ENHANCEMENTS, 0xFFFF, 0xFFFF, 700, 500, _("Enhancements"), GetImage(resource_dat, 41), - (policy == ENH_POLICY_ALL || policy == ENH_POLICY_READONLY) ? false : true) +iwEnhancements::iwEnhancements(enhOptions * original, const unsigned char policy) + : IngameWindow(CGI_ENHANCEMENTS, 0xFFFF, 0xFFFF, 700, 500, _("Game Settings"), + GetImage(resource_dat, 41), + (policy == ENH_POLICY_ALL || policy == ENH_POLICY_READONLY ? false : true)), + original(original), policy(policy), selection_id(0) { this->policy = policy; // store a pointer to the options we want to view/change this->original = original; - this->notifyFunc = notifyFunc; - this->notifyInst = notifyInst; - switch(policy) { case ENH_POLICY_HOSTMENU: - case ENH_POLICY_SERVERINGAME: + case ENH_POLICY_HOSTMENUINGAME: { // make a local copy so we can apply changes later this->enhs = new enhOptions(*original); } break; + case ENH_POLICY_SERVERINGAME: + { + // we don't wan't the window opening this one have to include the GameClient stuff + this->enhs = new enhOptions(GAMECLIENT.GetGGS().enhs); + // Are we allowed to do something? + if (!GAMECLIENT.IsHost()) + this->policy = ENH_POLICY_READONLY; + } break; case ENH_POLICY_ALL: case ENH_POLICY_READONLY: { @@ -77,6 +83,7 @@ switch(policy) { case ENH_POLICY_HOSTMENU: + case ENH_POLICY_HOSTMENUINGAME: case ENH_POLICY_SERVERINGAME: { AddTextButton(1, width - 220, height - 45 , 200, 22, TC_GREEN2, _("Apply Changes"),NormalFont); @@ -89,60 +96,35 @@ } break; } - // Add controls for each option - unsigned int BEGIN_OTHER_CTRLS = BEGIN_ENH_CTRLS + enhs->size(); + AddText(3,20,30,_("Modified:"), COLOR_YELLOW, 0, NormalFont); + AddText(4,width-230+20,30,_("Available:"), COLOR_YELLOW, 0, NormalFont); + + AddList(5,20,50,230-2*20,height-75-2*20, TC_GREY, NormalFont); + ctrlList *list_all = AddList(6,width-230+20,50,230-2*20,height-75-2*20, TC_GREY, NormalFont); + list_ids = new unsigned int[enhs->size()]; + enhOption* enh; - ctrlCheck* check; - ctrlComboBox* combo; - ctrlEdit* edit; - ctrlText* text; - unsigned int y = 30; - bool isChangeable; - - if (enhs->size() > 0) for (unsigned int i = 0; i < enhs->size(); ++i) + for (unsigned int i = 0; i < enhs->size(); ++i) { enh = enhs->by_order(i); - isChangeable = - (policy < ENH_POLICY_READONLY) - && - (policy < ENH_POLICY_SERVERINGAME - || - enh->isIngameChangeable() - ); - switch(enh->GetType()) - { - case OPT_BOOL: - { - check = AddCheckBox(i + BEGIN_ENH_CTRLS, 30, y, width - 60, 22, TC_GREY, enh->GetName(), NormalFont, !isChangeable); - check->SetCheck(enh->GetState() == 1); - y += 22; - } break; - case OPT_SELECT: - { - text = AddText(i + BEGIN_OTHER_CTRLS, 30, y + 3, enh->GetName() + ":", COLOR_YELLOW, 0, NormalFont); - unsigned short int w = NormalFont->getWidth(text->GetText()); - combo = AddComboBox(i + BEGIN_ENH_CTRLS, 30 + w + 10, y, width - 60 - 10 - w, 20, TC_GREY, NormalFont, width - 160, !isChangeable); - if (enh->GetMax()>0) for(int j = 0; j <= enh->GetMax(); ++j) - combo->AddString(enh->GetSelections(j)); - combo->SetSelection(enh->GetState()); - y += 20; - } break; - case OPT_INT: - { - text = AddText(i + BEGIN_OTHER_CTRLS, 30, y + 3, enh->GetName() + ":", COLOR_YELLOW, 0, NormalFont); - unsigned short int w = NormalFont->getWidth(text->GetText()); - edit = AddEdit(i + BEGIN_ENH_CTRLS, 30 + w + 10, y, width - 60 - 10 - w, 22, TC_GREY, NormalFont, width - 160, false, !isChangeable , true); - // maybe add a special SpinBox control later - std::stringstream ssvalue; - ssvalue << enh->GetState(); - std::string svalue = ssvalue.str(); - edit->SetText(svalue); - y += 22; - } break; - } - y += 10; + list_all->AddString(enh->GetName()); } - + UpdateList(); + + name = AddMultiline(7, 230, 50, 240, 3*NormalFont->getHeight()+4 , TC_GREEN1, NormalFont, glArchivItem_Font::DF_LEFT | glArchivItem_Font::DF_TOP); + name->EnableBox(false); + def = AddMultiline(8, 230, 50+4*14, 240, 4*NormalFont->getHeight()+4 , TC_GREEN1, NormalFont, glArchivItem_Font::DF_LEFT | glArchivItem_Font::DF_TOP); + def->EnableBox(false); + text = AddText(9,230+2,50 + 9*14, _("Current value:"), COLOR_YELLOW, 0, NormalFont); + text->SetVisible(false); + check = AddCheckBox(100, 230, 50+10*14, 240, 22, TC_GREY, _("Enabled"), NormalFont); + check->SetVisible(false); + combo = AddComboBox(101, 230, 50+10*14, 240, 22, TC_GREY, NormalFont, height-50-10*14-30); + combo->SetVisible(false); + edit = AddSpinbox(102, 230, 50+10*14, 240, 22, TC_GREY, NormalFont, false, true); + edit->SetVisible(false); + desc = AddMultiline(13, 230, 50+13*14, 240, GetHeight()-65-50-11*14 , TC_GREEN1, NormalFont, glArchivItem_Font::DF_LEFT | glArchivItem_Font::DF_TOP); + } /** @@ -152,7 +134,8 @@ */ iwEnhancements::~iwEnhancements() { - // If we made up an own instance, destroy it! + delete [] list_ids; + // If we made up an EnhOptions own instance, destroy it! // We could as well check the value of policy here if (original != enhs) if(enhs != NULL) @@ -161,50 +144,21 @@ void iwEnhancements::Msg_CheckboxChange(const unsigned int ctrl_id, const bool check) { - if (ctrl_id >= BEGIN_ENH_CTRLS) - enhs->by_order(ctrl_id - BEGIN_ENH_CTRLS)->SetState(check ? 1 : 0); + enhs->by_id(selection_id)->SetState(check ? 1 : 0); + this->check->SetText(check ? _("Enabled") : _("Disabled")); + UpdateList(); } void iwEnhancements::Msg_ComboSelectItem(const unsigned int ctrl_id, const unsigned short selection) { - if (ctrl_id >= BEGIN_ENH_CTRLS) - enhs->by_order(ctrl_id - BEGIN_ENH_CTRLS)->SetState(selection); + enhs->by_id(selection_id)->SetState(selection); + UpdateList(); } void iwEnhancements::Msg_EditChange(const unsigned int ctrl_id) { - if (ctrl_id >= BEGIN_ENH_CTRLS) - { - enhOption* enh = enhs->by_order(ctrl_id - BEGIN_ENH_CTRLS); - ctrlEdit* edit = GetCtrl(ctrl_id); - if (!enh->SetState(atoi(edit->GetText().c_str()))) - // load stored value again, for the case of nonvalid input entered - { - std::stringstream ssvalue; - ssvalue << enh->GetState(); - std::string svalue = ssvalue.str(); - edit->SetText(svalue); - } - } -} - -void iwEnhancements::Msg_EditEnter(const unsigned int ctrl_id) -{ - switch(ctrl_id) - { - case 1: - { - } break; - case 3: - { - } break; - case 5: - { - } break; - } -} - - - + enhs->by_id(selection_id)->SetState(edit->GetValue()); + UpdateList(); +} void iwEnhancements::Msg_ButtonClick(const unsigned int ctrl_id) { @@ -213,13 +167,23 @@ // Save Changes case 1: { - if (policy < ENH_POLICY_READONLY) + // Submit changes + // Maybe if in future more than one player shall be able to change, only send enhs.Compare(ggs.enhs) + if (policy >= ENH_POLICY_HOSTMENU && policy <= ENH_POLICY_HOSTMENUINGAME) { *original = *enhs; - // Notify about Changes if neccessary - if (policy > ENH_POLICY_ALL) - if (notifyFunc != NULL) - (notifyInst->*notifyFunc)(); + GlobalGameSettings ggs = GAMECLIENT.GetGGS(); + ggs.enhs = *enhs; + GAMESERVER.ChangeGlobalGameSettings(ggs); + } + else if (policy == ENH_POLICY_SERVERINGAME) + { + // send a game command by ourselves + // send together with "normal" GGS, maybe make them + // changeable, too + GlobalGameSettings ggs = GAMECLIENT.GetGGS(); + ggs.enhs = *enhs; + GAMECLIENT.AddGC(new gc::ChangeGGS(ggs)); } Close(); } break; @@ -231,3 +195,108 @@ } } +void iwEnhancements::Msg_ListSelectItem(const unsigned int ctrl_id, const unsigned short selection) +{ + ctrlList * list = GetCtrl(ctrl_id); + switch(ctrl_id) + { + case 6: /*list of all available options*/ + { + name->DeleteAllItems(); + def->DeleteAllItems(); + text->SetVisible(false); + desc->DeleteAllItems(); + check->SetVisible(false); + combo->DeleteAllItems(); + combo->SetVisible(false); + edit->SetVisible(false); + if (selection < list->GetLineCount()) + { + enhOption * enh = enhs->by_order(selection); + selection_id = enh->GetId(); + + text->SetVisible(true); + name->AddText(enh->GetName(), COLOR_YELLOW); + desc->AddText(enh->GetDescription(), COLOR_YELLOW); + + bool isChangeable = + (policy < ENH_POLICY_READONLY) + && + (policy <= ENH_POLICY_HOSTMENU + || + enh->isIngameChangeable() + ); + check->SetReadOnly(!isChangeable); + combo->SetReadOnly(!isChangeable); + edit->SetDisabled(!isChangeable); + text->SetColor(isChangeable ? COLOR_YELLOW : COLOR_GREY); + def->AddText(std::string(_("Default") + std::string(": ")) + enh->GetStateStr(enh->GetDef()), COLOR_YELLOW); + def->AddText(std::string(_("Settlers II") + std::string(": ")) + enh->GetStateStr(enh->GetOriginal()), COLOR_YELLOW); + switch(enh->GetType()) + { + case OPT_BOOL: + { + check->SetCheck(enh->GetState() == 1); + check->SetText(enh->GetState() == 1 ? _("Enabled") : _("Disabled")); + check->SetVisible(true); + } break; + case OPT_SELECT: + { + if (enh->GetMax()>0) for(int j = 0; j <= enh->GetMax(); ++j) + combo->AddString(enh->GetSelections(j)); + combo->SetSelection(enh->GetState()); + combo->SetVisible(true); + } break; + case OPT_INT: + { + def->AddText(std::string(_("Range") + std::string(": ")) + enh->GetStateStr(enh->GetMin()) + " - " + enh->GetStateStr(enh->GetMax()), COLOR_YELLOW); + edit->SetMin(enh->GetMin()); + edit->SetMax(enh->GetMax()); + edit->SetValue(enh->GetState()); + edit->SetVisible(true); + } break; + } + } + else //deselected + selection_id = 0; + } break; + case 5: /*list of modified options*/ + { + if (selection / 2 < list->GetLineCount()) + { + enhOption * enh = enhs->by_id(list_ids[selection / 2]); + selection_id = enh->GetId(); + + for (unsigned int i = 0; i < enhs->size(); ++i) + { + if (enhs->by_order(i)->GetId() == selection_id) + { + Msg_ListSelectItem(6, i); + GetCtrl(6)->SetSelection(i); + break; + } + } + list->SetSelection(2 * (selection / 2)); + } + } break; + } +} + +void iwEnhancements::UpdateList() +{ + ctrlList * list = GetCtrl(5); // left list + list->DeleteAllItems(); + + enhOption* enh; + for (unsigned int i = 0; i < enhs->size(); ++i) + { + enh = enhs->by_order(i); + if (enh->GetState() != enh->GetOriginal()) + { + list_ids[list->GetLineCount()/2] = enh->GetId(); + list->AddString(enh->GetName() + ":"); + list->AddString(" " + enh->GetStateStr()); + } + } +} + === modified file 'src/iwEnhancements.h' --- src/iwEnhancements.h 2009-05-26 22:00:35 +0000 +++ src/iwEnhancements.h 2009-06-07 17:55:24 +0000 @@ -27,13 +27,15 @@ #define ENH_POLICY_ALL 0 #define ENH_POLICY_HOSTMENU 1 -#define ENH_POLICY_SERVERINGAME 2 +#define ENH_POLICY_HOSTMENUINGAME 2 +#define ENH_POLICY_SERVERINGAME 3 #define ENH_POLICY_READONLY 255 class iwEnhancements : public IngameWindow { public: - iwEnhancements(enhOptions * original, const unsigned char policy, void (dskHostGame::*notifyFunc)() = NULL, dskHostGame * notifyInst = NULL); + iwEnhancements(enhOptions * original = NULL, + const unsigned char policy = ENH_POLICY_READONLY); ~iwEnhancements(void); private: @@ -42,15 +44,27 @@ void Msg_CheckboxChange(const unsigned int ctrl_id, const bool check); void Msg_ComboSelectItem(const unsigned int ctrl_id, const unsigned short selection); void Msg_EditChange(const unsigned int ctrl_id); - void Msg_EditEnter(const unsigned int ctrl_id); void Msg_ButtonClick(const unsigned int ctrl_id); + void Msg_ListSelectItem(const unsigned int ctrl_id, const unsigned short selection); private: + void UpdateList(); + +protected: enhOptions *enhs, *original; unsigned char policy; - void (dskHostGame::*notifyFunc)(); - dskHostGame * notifyInst; - + + unsigned int selection_id; + ctrlMultiline * name; + ctrlMultiline * desc; + ctrlMultiline * def; + ctrlText * text; + + ctrlCheck * check; + ctrlComboBox * combo; + ctrlSpinbox * edit; + + unsigned int * list_ids; //stores the ids of the options in the left list (the modified ones) }; #endif // !iwENHANCEMENTS_H_INCLUDED === modified file 'src/iwMainMenu.cpp' --- src/iwMainMenu.cpp 2009-06-03 22:00:33 +0000 +++ src/iwMainMenu.cpp 2009-06-07 12:10:26 +0000 @@ -36,6 +36,8 @@ #include "iwBuildingProductivities.h" #include "iwStatistics.h" #include "iwDiplomacy.h" +#include "iwEnhancements.h" +#include "GameClient.h" /////////////////////////////////////////////////////////////////////////////// // Makros / Defines @@ -82,6 +84,8 @@ AddImageButton( 11, 68, 166, 53, 44, TC_GREY, GetImage(io_dat, 190), _("Diplomacy")); //// Schiffe //AddImageButton( 9, 124, 118, 53, 44, TC_GREY, GetImage(io_dat, 175), _("Ship register")); + // Enhancement options + AddImageButton(12, 124, 166, 53, 44,TC_GREY, GetImage(io_dat, 79), _("Game Settings")); // Optionen AddImageButton(30, 12, 231, 165, 32, TC_GREY, GetImage(io_dat, 37), _("Options")); @@ -135,6 +139,10 @@ { WindowManager::inst().Show(new iwDiplomacy); } break; + case 12: // Enhancement + { + WindowManager::inst().Show(new iwEnhancements(NULL, ENH_POLICY_SERVERINGAME)); + } break; case 30: // Optionen