This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

Changeset 10064 for ps


Ignore:
Timestamp:
08/22/11 23:45:39 (13 years ago)
Author:
ben
Message:

Fixes Atlas player panel getting out of sync with simulation. Fixes #927.
Fixes object panel not being notified of map loading.
Fixes bug where opening a new map before using the player panel prevented default player data being displayed for new players.
Fixes wxGTK 2.8 bug: wxChoicebook control doesn't update the choice control when adding/removing pages.
Notifies player that deleting player in Atlas will delete all their objects (and gives them the option).
Changes DeleteObject to DeleteObjects to support multiple selections.
Implements undo for map resize (experimental).
Removes annoying debug message from attempted undo of map settings.
Tweaks a few Atlas UI controls.

Location:
ps/trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • ps/trunk/binaries/data/mods/public/simulation/components/PlayerManager.js

    r10008 r10064  
    3737};
    3838
     39PlayerManager.prototype.RemoveAllPlayers = function()
     40{
     41    // Destroy existing player entities
     42    for each (id in this.playerEntities)
     43    {
     44        Engine.DestroyEntity(id);
     45    }
     46    this.playerEntities = [];
     47};
     48
    3949Engine.RegisterComponentType(IID_PlayerManager, "PlayerManager", PlayerManager);
  • ps/trunk/binaries/data/mods/public/simulation/helpers/Player.js

    r10014 r10064  
    44 * all other initialization must be done after loading map (terrain/entities).
    55 * DO NOT use other components here, as they may fail unpredictably.
    6  */
    7 function LoadPlayerSettings(settings)
     6 * settings is the object containing settings for this map.
     7 * newPlayers if true will remove any old player entities and add new ones
     8 *  (used when loading a map or when Atlas changes the number of players).
     9 */
     10function LoadPlayerSettings(settings, newPlayers)
    811{
    912    // Default settings
     
    1720    if (!(rawData && rawData.PlayerData))
    1821    {
    19         throw("Player.js: Error reading player default data (player_defaults.json)");
     22        throw("Player.js: Error reading player_defaults.json");
    2023    }
    2124
     
    2528    var numPlayers = 8;
    2629   
    27     if (settings.PlayerData)
    28     {   // Get number of players including gaia
    29         numPlayers = settings.PlayerData.length + 1;
    30     }
    31     else
    32     {
    33         warn("Player.js: Setup has no player data - using defaults");
    34     }
    35    
    3630    // Get player manager
    37     var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
    38 
     31    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     32   
     33    // Remove existing players and add new ones
     34    if (newPlayers)
     35    {
     36        cmpPlayerManager.RemoveAllPlayers();
     37   
     38        if (settings.PlayerData)
     39        {   // Get number of players including gaia
     40            numPlayers = settings.PlayerData.length + 1;
     41        }
     42        else
     43        {
     44            warn("Player.js: Setup has no player data - using defaults");
     45        }
     46       
     47        for (var i = 0; i < numPlayers; ++i)
     48        {
     49            // Add player entity to engine
     50            // TODO: Get player template name from civ data
     51            var entID = Engine.AddEntity("special/player");
     52            var cmpPlayer = Engine.QueryInterface(entID, IID_Player);
     53            if (!cmpPlayer)
     54            {
     55                throw("Player.js: Error creating player entity "+i);
     56            }
     57           
     58            cmpPlayer.SetPlayerID(i);
     59           
     60            // Add player to player manager
     61            cmpPlayerManager.AddPlayer(entID);
     62        }
     63    }
     64   
     65    numPlayers = cmpPlayerManager.GetNumPlayers();
     66   
     67    // Initialize the player data
    3968    for (var i = 0; i < numPlayers; ++i)
    4069    {
    41         // Add player entity to engine
    42         var entID = Engine.AddEntity("special/player");
    43        
    44         // Retrieve entity
    45         var cmpPlayer = Engine.QueryInterface(entID, IID_Player);
    46         if (!cmpPlayer)
    47         {
    48             throw("Player.js: Error creating player entity "+i);
    49         }
    50        
    51         cmpPlayer.SetPlayerID(i);
    52        
     70        var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player);
    5371        var pDefs = playerDefaults ? playerDefaults[i] : {};
    5472       
     
    5876            var pData = settings.PlayerData ? settings.PlayerData[i-1] : {};
    5977           
    60             // Copy player data
    6178            cmpPlayer.SetName(getSetting(pData, pDefs, "Name"));
    6279            cmpPlayer.SetCiv(getSetting(pData, pDefs, "Civ"));
     
    121138            }
    122139        }
    123        
    124         // Add player to player manager
    125         cmpPlayerMan.AddPlayer(entID);
    126140    }
    127141}
     
    147161function QueryOwnerInterface(ent, iid)
    148162{
    149     var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     163    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
    150164
    151165    var cmpOwnership = Engine.QueryInterface(ent, IID_Ownership);
     
    153167        return null;
    154168
    155     var playerEnt = cmpPlayerMan.GetPlayerByID(cmpOwnership.GetOwner());
     169    var playerEnt = cmpPlayerManager.GetPlayerByID(cmpOwnership.GetOwner());
    156170    if (!playerEnt)
    157171        return null;
     
    167181function QueryPlayerIDInterface(id, iid)
    168182{
    169     var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
    170 
    171     var playerEnt = cmpPlayerMan.GetPlayerByID(id);
     183    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     184
     185    var playerEnt = cmpPlayerManager.GetPlayerByID(id);
    172186    if (!playerEnt)
    173187        return null;
     
    194208        targetOwner = cmpOwnershipTarget.GetOwner();
    195209
    196     var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
    197     var cmpPlayer = Engine.QueryInterface(cmpPlayerMan.GetPlayerByID(owner), IID_Player);
     210    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     211    var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(owner), IID_Player);
    198212
    199213    // Check for allied diplomacy status
     
    224238        targetOwner = cmpOwnershipTarget.GetOwner();
    225239
    226     var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
    227     var cmpPlayer = Engine.QueryInterface(cmpPlayerMan.GetPlayerByID(player), IID_Player);
     240    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     241    var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(player), IID_Player);
    228242
    229243    // Check for allied diplomacy status
     
    245259        targetOwner = cmpOwnershipTarget.GetOwner();
    246260
    247     var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
    248     var cmpPlayer = Engine.QueryInterface(cmpPlayerMan.GetPlayerByID(player), IID_Player);
     261    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     262    var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(player), IID_Player);
    249263
    250264    // Check for allied diplomacy status
  • ps/trunk/source/graphics/MapReader.cpp

    r9672 r10064  
    10301030int CMapReader::LoadPlayerSettings()
    10311031{
    1032     pSimulation2->LoadPlayerSettings();
     1032    pSimulation2->LoadPlayerSettings(true);
    10331033    return 0;
    10341034}
  • ps/trunk/source/simulation2/Simulation2.cpp

    r9889 r10064  
    479479}
    480480
    481 void CSimulation2::LoadPlayerSettings()
    482 {
    483     GetScriptInterface().CallFunctionVoid(GetScriptInterface().GetGlobalObject(), "LoadPlayerSettings", m->m_MapSettings);
     481void CSimulation2::LoadPlayerSettings(bool newPlayers)
     482{
     483    GetScriptInterface().CallFunctionVoid(GetScriptInterface().GetGlobalObject(), "LoadPlayerSettings", m->m_MapSettings, newPlayers);
    484484}
    485485
  • ps/trunk/source/simulation2/Simulation2.h

    r9617 r10064  
    7070    /**
    7171     * Loads the player settings script (called before map is loaded)
    72      */
    73     void LoadPlayerSettings();
     72     * @param newPlayers will delete all the existing player entities (if any) and create new ones
     73     *  (needed for loading maps, but Atlas might want to update existing player data)
     74     */
     75    void LoadPlayerSettings(bool newPlayers);
    7476
    7577    /**
  • ps/trunk/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp

    r10037 r10064  
    730730{
    731731    m_SectionLayout.OnMapReload();
     732
     733    // Notify observers, here so it's independent of individual panels
     734    m_MapSettings.NotifyObservers();
    732735}
    733736
  • ps/trunk/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp

    r10037 r10064  
    146146
    147147    wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5);
     148    gridSizer->AddGrowableCol(1);
    148149    gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Reveal map")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
    149150    gridSizer->Add(new wxCheckBox(this, ID_MapReveal, wxEmptyString));
    150151    gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Game type")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
    151     gridSizer->Add(new wxChoice(this, ID_MapType, wxDefaultPosition, wxDefaultSize, gameTypes));
     152    gridSizer->Add(new wxChoice(this, ID_MapType, wxDefaultPosition, wxDefaultSize, gameTypes), wxSizerFlags().Expand());
    152153    gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Lock teams")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
    153154    gridSizer->Add(new wxCheckBox(this, ID_MapTeams, wxEmptyString));
    154     sizer->Add(gridSizer);
     155    sizer->Add(gridSizer, wxSizerFlags().Expand());
    155156
    156157    sizer->AddSpacer(5);
     
    405406    if (m_SimState == SimInactive)
    406407    {
     408        // Force update of player settings
     409        POST_MESSAGE(LoadPlayerSettings, (false));
     410
    407411        POST_MESSAGE(SimStateSave, (L"default"));
    408412        POST_MESSAGE(GuiSwitchPage, (L"page_session.xml"));
  • ps/trunk/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Player/Player.cpp

    r10037 r10064  
    102102        gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Food")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
    103103        wxSpinCtrl* foodCtrl = new wxSpinCtrl(this, ID_PlayerFood, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, 0, INT_MAX);
    104         gridSizer->Add(Tooltipped(foodCtrl, _("Initial value of food resource")));
     104        gridSizer->Add(Tooltipped(foodCtrl, _("Initial value of food resource")), wxSizerFlags().Expand());
    105105        m_Controls.food = foodCtrl;
    106106        gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Wood")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
    107107        wxSpinCtrl* woodCtrl = new wxSpinCtrl(this, ID_PlayerWood, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, 0, INT_MAX);
    108         gridSizer->Add(Tooltipped(woodCtrl, _("Initial value of wood resource")));
     108        gridSizer->Add(Tooltipped(woodCtrl, _("Initial value of wood resource")), wxSizerFlags().Expand());
    109109        m_Controls.wood = woodCtrl;
    110110        gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Metal")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
    111111        wxSpinCtrl* metalCtrl = new wxSpinCtrl(this, ID_PlayerMetal, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, 0, INT_MAX);
    112         gridSizer->Add(Tooltipped(metalCtrl, _("Initial value of metal resource")));
     112        gridSizer->Add(Tooltipped(metalCtrl, _("Initial value of metal resource")), wxSizerFlags().Expand());
    113113        m_Controls.metal = metalCtrl;
    114114        gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Stone")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
    115115        wxSpinCtrl* stoneCtrl = new wxSpinCtrl(this, ID_PlayerStone, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, 0, INT_MAX);
    116         gridSizer->Add(Tooltipped(stoneCtrl, _("Initial value of stone resource")));
     116        gridSizer->Add(Tooltipped(stoneCtrl, _("Initial value of stone resource")), wxSizerFlags().Expand());
    117117        m_Controls.stone = stoneCtrl;
    118118        gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Pop limit")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
    119119        wxSpinCtrl* popCtrl = new wxSpinCtrl(this, ID_PlayerPop, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, 0, INT_MAX);
    120         gridSizer->Add(Tooltipped(popCtrl, _("Population limit for this player")));
     120        gridSizer->Add(Tooltipped(popCtrl, _("Population limit for this player")), wxSizerFlags().Expand());
    121121        m_Controls.pop = popCtrl;
    122122
     
    286286    void ResizePlayers(size_t numPlayers)
    287287    {
     288        wxASSERT(numPlayers <= m_Pages.size());
     289
    288290        // We don't really want to destroy the windows corresponding
    289         //      to the tabs, so we've kept them in a vector and will
    290         //      only remove and add them to the notebook as needed
    291         if (numPlayers <= m_Pages.size())
    292         {
    293             size_t pageCount = GetPageCount();
    294             if (numPlayers > pageCount)
     291        //  to the tabs, so we've kept them in a vector and will
     292        //  only remove and add them to the notebook as needed
     293        int selection = GetSelection();
     294        size_t pageCount = GetPageCount();
     295
     296        if (numPlayers > pageCount)
     297        {
     298            // Add previously removed pages
     299            for (size_t i = pageCount; i < numPlayers; ++i)
    295300            {
    296                 // Add previously removed pages
    297                 for (size_t i = pageCount; i < numPlayers; ++i)
    298                 {
    299                     AddPage(m_Pages[i], m_Pages[i]->GetPlayerName());
    300                 }
     301                AddPage(m_Pages[i], m_Pages[i]->GetPlayerName());
    301302            }
    302             else
     303        }
     304        else
     305        {
     306            // Remove previously added pages
     307            // we have to manually hide them or they remain visible
     308            for (size_t i = pageCount - 1; i >= numPlayers; --i)
    303309            {
    304                 // Remove previously added pages
    305                 // we have to manually hide them or they remain visible
    306                 for (size_t i = pageCount - 1; i >= numPlayers; --i)
    307                 {
    308                     m_Pages[i]->Hide();
    309                     RemovePage(i);
    310                 }
     310                m_Pages[i]->Hide();
     311                RemovePage(i);
    311312            }
    312313        }
     314
     315        // Workaround for bug on wxGTK 2.8: wxChoice selection doesn't update
     316        //  (in fact it loses its selection when adding/removing pages)
     317        GetChoiceCtrl()->SetSelection(selection);
    313318    }
    314319
     
    364369    }
    365370
    366     void OnNumPlayersChanged(wxSpinEvent& WXUNUSED(evt))
     371    void OnPlayerColour(wxCommandEvent& WXUNUSED(evt))
    367372    {
    368373        if (!m_InGUIUpdate)
    369374        {
    370             m_Players->ResizePlayers(wxDynamicCast(FindWindow(ID_NumPlayers), wxSpinCtrl)->GetValue());
    371375            SendToEngine();
     376
     377            // Update player settings, to show new colour
     378            POST_MESSAGE(LoadPlayerSettings, (false));
     379        }
     380    }
     381
     382    void OnNumPlayersText(wxCommandEvent& WXUNUSED(evt))
     383    {   // Ignore because it will also trigger EVT_SPINCTRL
     384        //  and we don't want to handle the same event twice
     385    }
     386
     387    void OnNumPlayersSpin(wxSpinEvent& evt)
     388    {
     389        if (!m_InGUIUpdate)
     390        {
     391            wxASSERT(evt.GetInt() > 0);
    372392           
    373             // Notify observers
     393            // When wxMessageBox pops up, wxSpinCtrl loses focus, which
     394            //  forces another EVT_SPINCTRL event, which we don't want
     395            //  to handle, so we check here for a change
     396            if (evt.GetInt() == (int)m_NumPlayers)
     397            {
     398                return; // No change
     399            }
     400           
     401            size_t oldNumPlayers = m_NumPlayers;
     402            m_NumPlayers = evt.GetInt();
     403
     404            if (m_NumPlayers < oldNumPlayers)
     405            {
     406                // Remove players, but check if they own any entities
     407                bool notified = false;
     408                for (size_t i = oldNumPlayers; i > m_NumPlayers; --i)
     409                {
     410                    qGetPlayerObjects objectsQry(i);
     411                    objectsQry.Post();
     412
     413                    std::vector<AtlasMessage::ObjectID> ids = *objectsQry.ids;
     414
     415                    if (ids.size() > 0)
     416                    {
     417                        if (!notified)
     418                        {
     419                            // TODO: Add option to reassign objects?
     420                            if (wxMessageBox(_("WARNING: All objects belonging to the removed players will be deleted. Continue anyway?"), _("Remove player confirmation"), wxICON_EXCLAMATION | wxYES_NO) != wxYES)
     421                            {
     422                                // Restore previous player count
     423                                m_NumPlayers = oldNumPlayers;
     424                                wxDynamicCast(FindWindow(ID_NumPlayers), wxSpinCtrl)->SetValue(m_NumPlayers);
     425                                return;
     426                            }
     427
     428                            notified = true;
     429                        }
     430
     431                        // Delete objects
     432                        // TODO: Merge multiple commands?
     433                        POST_COMMAND(DeleteObjects, (ids));
     434                    }
     435                }
     436            }
     437
     438            m_Players->ResizePlayers(m_NumPlayers);
     439            SendToEngine();
     440
     441            // Reload players, notify observers
     442            POST_MESSAGE(LoadPlayerSettings, (true));
    374443            m_MapSettings.NotifyObservers();
    375444        }
    376445    }
    377446
     447    // TODO: we shouldn't hardcode this, but instead dynamically create
     448    //  new player notebook pages on demand; of course the default data
     449    //  will be limited by the entries in player_defaults.json
    378450    static const size_t MAX_NUM_PLAYERS = 8;
    379451
     
    384456    std::vector<PlayerPageControls> m_PlayerControls;
    385457    Observable<AtObj>& m_MapSettings;
     458    size_t m_NumPlayers;
    386459
    387460    DECLARE_EVENT_TABLE();
     
    389462
    390463BEGIN_EVENT_TABLE(PlayerSettingsControl, wxPanel)
    391     EVT_BUTTON(ID_PlayerColour, PlayerSettingsControl::OnEdit)
     464    EVT_BUTTON(ID_PlayerColour, PlayerSettingsControl::OnPlayerColour)
    392465    EVT_BUTTON(ID_CameraSet, PlayerSettingsControl::OnEdit)
    393466    EVT_BUTTON(ID_CameraClear, PlayerSettingsControl::OnEdit)
    394467    EVT_CHOICE(wxID_ANY, PlayerSettingsControl::OnEdit)
     468    EVT_TEXT(ID_NumPlayers, PlayerSettingsControl::OnNumPlayersText)
    395469    EVT_TEXT(wxID_ANY, PlayerSettingsControl::OnEdit)
    396     EVT_SPINCTRL(ID_NumPlayers, PlayerSettingsControl::OnNumPlayersChanged)
     470    EVT_SPINCTRL(ID_NumPlayers, PlayerSettingsControl::OnNumPlayersSpin)
    397471    EVT_SPINCTRL(ID_PlayerFood, PlayerSettingsControl::OnEditSpin)
    398472    EVT_SPINCTRL(ID_PlayerWood, PlayerSettingsControl::OnEditSpin)
     
    403477
    404478PlayerSettingsControl::PlayerSettingsControl(wxWindow* parent, ScenarioEditor& scenarioEditor)
    405     : wxPanel(parent, wxID_ANY), m_ScenarioEditor(scenarioEditor), m_InGUIUpdate(false), m_MapSettings(scenarioEditor.GetMapSettings())
     479    : wxPanel(parent, wxID_ANY), m_ScenarioEditor(scenarioEditor), m_InGUIUpdate(false), m_MapSettings(scenarioEditor.GetMapSettings()), m_NumPlayers(0)
    406480{
    407481    // To prevent recursion, don't handle GUI events right now
     
    503577
    504578    AtIter player = m_MapSettings["PlayerData"]["item"];
    505     size_t numPlayers = player.count();
    506 
    507     if (!m_MapSettings.defined() || !player.defined() || numPlayers == 0)
    508     {
    509         // Player data missing - set number of players manually
    510         numPlayers = MAX_NUM_PLAYERS;
    511     }
     579    if (!m_MapSettings.defined() || !player.defined() || player.count() == 0)
     580    {
     581        // Player data missing - set number of players to max
     582        m_NumPlayers = MAX_NUM_PLAYERS;
     583    }
     584    else
     585    {
     586        m_NumPlayers = player.count();
     587    }
     588
     589    wxASSERT(m_NumPlayers <= MAX_NUM_PLAYERS && m_NumPlayers != 0);
    512590
    513591    // To prevent recursion, don't handle GUI events right now
     
    518596    ++playerDefs;   // skip gaia
    519597
    520     wxDynamicCast(FindWindow(ID_NumPlayers), wxSpinCtrl)->SetValue(numPlayers);
     598    wxDynamicCast(FindWindow(ID_NumPlayers), wxSpinCtrl)->SetValue(m_NumPlayers);
    521599
    522600    // Remove / add extra player pages as needed
    523     m_Players->ResizePlayers(numPlayers);
    524 
    525     for (size_t i = 0; i < numPlayers && i < MAX_NUM_PLAYERS; ++i, ++player, ++playerDefs)
     601    m_Players->ResizePlayers(m_NumPlayers);
     602
     603    for (size_t i = 0; i < MAX_NUM_PLAYERS; ++i, ++player, ++playerDefs)
    526604    {
    527605        PlayerPageControls controls = m_PlayerControls[i];
     
    538616        // civ
    539617        wxChoice* choice = controls.civ;
    540         wxString civCode(player["Civ"]);
     618        wxString civCode;
     619        if (player["Civ"].defined())
     620            civCode = wxString(player["Civ"]);
     621        else
     622            civCode = wxString(playerDefs["Civ"]);
     623
    541624        for (size_t j = 0; j < choice->GetCount(); ++j)
    542625        {
     
    652735    // Update player data in the map settings
    653736    AtIter oldPlayer = m_MapSettings["PlayerData"]["item"];
    654     size_t numPlayers = wxDynamicCast(FindWindow(ID_NumPlayers), wxSpinCtrl)->GetValue();
    655737    AtObj players;
    656738    players.set("@array", L"");
    657739
    658     for (size_t i = 0; i < numPlayers && i < MAX_NUM_PLAYERS; ++i)
     740    wxASSERT(m_NumPlayers <= MAX_NUM_PLAYERS);
     741
     742    for (size_t i = 0; i < m_NumPlayers; ++i)
    659743    {
    660744        PlayerPageControls controls = m_PlayerControls[i];
  • ps/trunk/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp

    r10037 r10064  
    9595        m_MainSizer->Add(sizer, wxSizerFlags().Expand().Border(wxTOP, 10));
    9696
    97         wxSizer* visSizer = new wxFlexGridSizer(2, 5, 5);
    98         sizer->Add(visSizer);
     97        wxFlexGridSizer* visSizer = new wxFlexGridSizer(2, 5, 5);
     98        visSizer->AddGrowableCol(1);
     99        sizer->Add(visSizer, wxSizerFlags().Expand());
    99100
    100101        wxArrayString defaultChoices;
     
    104105
    105106        visSizer->Add(new wxStaticText(this, wxID_ANY, _("Passability")), wxSizerFlags().Align(wxALIGN_CENTER|wxALIGN_RIGHT));
    106         visSizer->Add(m_PassabilityChoice);
     107        visSizer->Add(m_PassabilityChoice, wxSizerFlags().Expand());
    107108
    108109        visSizer->Add(new wxStaticText(this, wxID_ANY, _("Priorities")), wxSizerFlags().Align(wxALIGN_CENTER|wxALIGN_RIGHT));
  • ps/trunk/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp

    r9649 r10064  
    217217
    218218    // TODO: These are yucky
    219     wxSizer* spinnerSizer = new wxFlexGridSizer(2, 2, 5, 5);
     219    wxFlexGridSizer* spinnerSizer = new wxFlexGridSizer(2, 5, 5);
     220    spinnerSizer->AddGrowableCol(1);
    220221    spinnerSizer->Add(new wxStaticText(parent, wxID_ANY, _("Size")), wxSizerFlags().Align(wxALIGN_CENTER|wxALIGN_RIGHT));
    221     spinnerSizer->Add(new BrushSizeCtrl(parent, *this));
     222    spinnerSizer->Add(new BrushSizeCtrl(parent, *this), wxSizerFlags().Expand());
    222223    spinnerSizer->Add(new wxStaticText(parent, wxID_ANY, _("Strength")), wxSizerFlags().Align(wxALIGN_CENTER|wxALIGN_RIGHT));
    223     spinnerSizer->Add(new BrushStrengthCtrl(parent, *this));
     224    spinnerSizer->Add(new BrushStrengthCtrl(parent, *this), wxSizerFlags().Expand());
    224225    sizer->Add(spinnerSizer, wxSizerFlags().Expand());
    225226}
  • ps/trunk/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/TransformObject.cpp

    r6929 r10064  
    100100            if (type == KEY_CHAR && evt.GetKeyCode() == WXK_DELETE)
    101101            {
    102                 for (size_t i = 0; i < g_SelectedObjects.size(); ++i)
    103                     POST_COMMAND(DeleteObject, (g_SelectedObjects[i]));
     102                POST_COMMAND(DeleteObjects, (g_SelectedObjects));
    104103
    105104                g_SelectedObjects.clear();
  • ps/trunk/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp

    r9720 r10064  
    140140}
    141141
    142 QUERYHANDLER(GetMapSizes)
    143 {
    144     msg->sizes = g_Game->GetSimulation2()->GetMapSizes();
    145 }
    146 
    147142BEGIN_COMMAND(SetMapSettings)
    148143{
     144    std::string m_OldSettings, m_NewSettings;
     145   
     146    void SetSettings(const std::string& settings)
     147    {
     148        g_Game->GetSimulation2()->SetMapSettings(settings);
     149    }
     150
    149151    void Do()
    150152    {
    151         Redo();
    152     }
    153 
     153        m_OldSettings = g_Game->GetSimulation2()->GetMapSettingsString();
     154        m_NewSettings = *msg->settings;
     155       
     156        SetSettings(m_NewSettings);
     157    }
     158
     159    // TODO: we need some way to notify the Atlas UI when the settings are changed
     160    //  externally, otherwise this will have no visible effect
    154161    void Undo()
    155162    {
    156         // TODO
    157         debug_warn(L"Can't undo SetMapSettings");
     163        // SetSettings(m_OldSettings);
    158164    }
    159165
    160166    void Redo()
    161167    {
    162         g_Game->GetSimulation2()->SetMapSettings(*msg->settings);
     168        // SetSettings(m_NewSettings);
     169    }
     170
     171    void MergeIntoPrevious(cSetMapSettings* prev)
     172    {
     173        prev->m_NewSettings = m_NewSettings;
    163174    }
    164175};
    165176END_COMMAND(SetMapSettings)
    166177
     178MESSAGEHANDLER(LoadPlayerSettings)
     179{
     180    g_Game->GetSimulation2()->LoadPlayerSettings(msg->newplayers);
     181}
     182
     183QUERYHANDLER(GetMapSizes)
     184{
     185    msg->sizes = g_Game->GetSimulation2()->GetMapSizes();
     186}
     187
    167188QUERYHANDLER(GetRMSData)
    168189{
     
    172193BEGIN_COMMAND(ResizeMap)
    173194{
     195    int m_OldTiles, m_NewTiles;
     196
    174197    cResizeMap()
    175198    {
     
    187210    }
    188211
     212    void ResizeTerrain(int tiles)
     213    {
     214        CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
     215
     216        terrain->Resize(tiles / PATCH_SIZE);
     217
     218        MakeDirty();
     219    }
     220
    189221    void Do()
    190222    {
    191         Redo();
     223        CmpPtr<ICmpTerrain> cmpTerrain(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
     224        if (cmpTerrain.null())
     225        {
     226            m_OldTiles = m_NewTiles = 0;
     227        }
     228        else
     229        {
     230            m_OldTiles = (int)cmpTerrain->GetTilesPerSide();
     231            m_NewTiles = msg->tiles;
     232        }
     233
     234        ResizeTerrain(m_NewTiles);
    192235    }
    193236
    194237    void Undo()
    195238    {
    196         // TODO
    197         debug_warn(L"Can't undo ResizeMap");
     239        ResizeTerrain(m_OldTiles);
    198240    }
    199241
    200242    void Redo()
    201243    {
    202         CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
    203 
    204         terrain->Resize(msg->tiles / PATCH_SIZE);
    205 
    206         MakeDirty();
     244        ResizeTerrain(m_NewTiles);
    207245    }
    208246};
  • ps/trunk/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp

    r9362 r10064  
    1 /* Copyright (C) 2010 Wildfire Games.
     1/* Copyright (C) 2011 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
     
    544544
    545545
    546 BEGIN_COMMAND(DeleteObject)
     546BEGIN_COMMAND(DeleteObjects)
    547547{
    548548    // Saved copy of the important aspects of a unit, to allow undo
    549     entity_id_t m_EntityID;
    550     CStr m_TemplateName;
    551     int32_t m_Owner;
    552     CFixedVector3D m_Pos;
    553     CFixedVector3D m_Rot;
    554     // TODO: random selections
    555 
    556     cDeleteObject()
    557     : m_EntityID(INVALID_ENTITY), m_Owner(-1)
     549    struct OldObject
     550    {
     551        entity_id_t entityID;
     552        CStr templateName;
     553        int32_t owner;
     554        CFixedVector3D pos;
     555        CFixedVector3D rot;
     556    };
     557
     558    std::vector<OldObject> oldObjects;
     559
     560    cDeleteObjects()
    558561    {
    559562    }
     
    570573        ENSURE(!cmpTemplateManager.null());
    571574
    572         m_EntityID = (entity_id_t)msg->id;
    573         m_TemplateName = cmpTemplateManager->GetCurrentTemplateName(m_EntityID);
    574 
    575         CmpPtr<ICmpOwnership> cmpOwner(sim, m_EntityID);
    576         if (!cmpOwner.null())
    577             m_Owner = cmpOwner->GetOwner();
    578 
    579         CmpPtr<ICmpPosition> cmpPosition(sim, m_EntityID);
    580         if (!cmpPosition.null())
    581         {
    582             m_Pos = cmpPosition->GetPosition();
    583             m_Rot = cmpPosition->GetRotation();
    584         }
    585 
    586         g_Game->GetSimulation2()->DestroyEntity(m_EntityID);
    587     }
    588 
    589     void Undo()
    590     {
    591         CSimulation2& sim = *g_Game->GetSimulation2();
    592         entity_id_t ent = sim.AddEntity(m_TemplateName.FromUTF8(), m_EntityID);
    593         if (ent == INVALID_ENTITY)
    594             LOGERROR(L"Failed to load entity template '%hs'", m_TemplateName.c_str());
    595         else
    596         {
    597             CmpPtr<ICmpPosition> cmpPosition(sim, m_EntityID);
     575        std::vector<ObjectID> ids = *msg->ids;
     576        for (size_t i = 0; i < ids.size(); ++i)
     577        {
     578            OldObject obj;
     579
     580            obj.entityID = (entity_id_t)ids[i];
     581            obj.templateName = cmpTemplateManager->GetCurrentTemplateName(obj.entityID);
     582
     583            CmpPtr<ICmpOwnership> cmpOwner(sim, obj.entityID);
     584            if (!cmpOwner.null())
     585                obj.owner = cmpOwner->GetOwner();
     586
     587            CmpPtr<ICmpPosition> cmpPosition(sim, obj.entityID);
    598588            if (!cmpPosition.null())
    599589            {
    600                 cmpPosition->JumpTo(m_Pos.X, m_Pos.Z);
    601                 cmpPosition->SetXZRotation(m_Rot.X, m_Rot.Z);
    602                 cmpPosition->SetYRotation(m_Rot.Y);
     590                obj.pos = cmpPosition->GetPosition();
     591                obj.rot = cmpPosition->GetRotation();
    603592            }
    604593
    605             CmpPtr<ICmpOwnership> cmpOwner(sim, m_EntityID);
    606             if (!cmpOwner.null())
    607                 cmpOwner->SetOwner(m_Owner);
    608         }
     594            oldObjects.push_back(obj);
     595            g_Game->GetSimulation2()->DestroyEntity(obj.entityID);
     596        }
     597    }
     598
     599    void Undo()
     600    {
     601        CSimulation2& sim = *g_Game->GetSimulation2();
     602
     603        for (size_t i = 0; i < oldObjects.size(); ++i)
     604        {
     605            entity_id_t ent = sim.AddEntity(oldObjects[i].templateName.FromUTF8(), oldObjects[i].entityID);
     606            if (ent == INVALID_ENTITY)
     607            {
     608                LOGERROR(L"Failed to load entity template '%hs'", oldObjects[i].templateName.c_str());
     609            }
     610            else
     611            {
     612                CmpPtr<ICmpPosition> cmpPosition(sim, oldObjects[i].entityID);
     613                if (!cmpPosition.null())
     614                {
     615                    cmpPosition->JumpTo(oldObjects[i].pos.X, oldObjects[i].pos.Z);
     616                    cmpPosition->SetXZRotation(oldObjects[i].rot.X, oldObjects[i].rot.Z);
     617                    cmpPosition->SetYRotation(oldObjects[i].rot.Y);
     618                }
     619
     620                CmpPtr<ICmpOwnership> cmpOwner(sim, oldObjects[i].entityID);
     621                if (!cmpOwner.null())
     622                    cmpOwner->SetOwner(oldObjects[i].owner);
     623            }
     624        }
     625
     626        oldObjects.clear();
    609627    }
    610628};
    611 END_COMMAND(DeleteObject)
    612 
    613 
    614 }
     629END_COMMAND(DeleteObjects)
     630
     631QUERYHANDLER(GetPlayerObjects)
     632{
     633    std::vector<ObjectID> ids;
     634    player_id_t playerID = msg->player;
     635
     636    const CSimulation2::InterfaceListUnordered& cmps = g_Game->GetSimulation2()->GetEntitiesWithInterfaceUnordered(IID_Ownership);
     637    for (CSimulation2::InterfaceListUnordered::const_iterator eit = cmps.begin(); eit != cmps.end(); ++eit)
     638    {
     639        if (static_cast<ICmpOwnership*>(eit->second)->GetOwner() == playerID)
     640        {
     641            ids.push_back(eit->first);
     642        }
     643    }
     644
     645    msg->ids = ids;
     646}
     647
     648}
  • ps/trunk/source/tools/atlas/GameInterface/Messages.h

    r10029 r10064  
    153153        );
    154154
     155COMMAND(SetMapSettings, MERGE,
     156        ((std::string, settings))
     157        );
     158
     159MESSAGE(LoadPlayerSettings,
     160        ((bool, newplayers))
     161        );
     162
    155163QUERY(GetMapSizes,
    156164        ,
    157165        ((std::string, sizes))
    158         );
    159 
    160 COMMAND(SetMapSettings, NOMERGE,
    161         ((std::string, settings))
    162166        );
    163167
     
    419423      );
    420424
    421 COMMAND(SetEnvironmentSettings, MERGE,
     425COMMAND(SetEnvironmentSettings, MERGE,  // merge lots of small changes into one undoable command
    422426        ((sEnvironmentSettings, settings))
    423427        );
     
    487491        );
    488492
    489 COMMAND(DeleteObject, NOMERGE,
    490         ((ObjectID, id))
     493COMMAND(DeleteObjects, NOMERGE,
     494        ((std::vector<ObjectID>, ids))
    491495        );
    492496
     
    506510        ((ObjectID, id))
    507511        ((sObjectSettings, settings))
     512        );
     513
     514QUERY(GetPlayerObjects,
     515        ((int, player))
     516        ,
     517        ((std::vector<ObjectID>, ids))
    508518        );
    509519
Note: See TracChangeset for help on using the changeset viewer.