Changeset View
Standalone View
source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp
Show All 35 Lines | enum | ||||
ID_MapName, | ID_MapName, | ||||
ID_MapDescription, | ID_MapDescription, | ||||
ID_MapReveal, | ID_MapReveal, | ||||
ID_MapType, | ID_MapType, | ||||
ID_MapPreview, | ID_MapPreview, | ||||
ID_MapTeams, | ID_MapTeams, | ||||
ID_MapKW_Demo, | ID_MapKW_Demo, | ||||
ID_MapKW_Naval, | ID_MapKW_Naval, | ||||
ID_VC_Conquest, | |||||
ID_VC_ConquestUnits, | |||||
ID_VC_ConquestStructures, | |||||
ID_VC_CaptureTheRelic, | |||||
ID_VC_Wonder, | |||||
ID_VC_Regicide, | |||||
elexis: I guess that's the same TODO as below, insert after loading from JSON | |||||
Not Done Inline Actionsyes bb: yes
(don't duplicate todos) | |||||
Not Done Inline Actionsshould have a ticket afterwards elexis: should have a ticket afterwards | |||||
ID_RandomScript, | ID_RandomScript, | ||||
ID_RandomSize, | ID_RandomSize, | ||||
ID_RandomNomad, | ID_RandomNomad, | ||||
ID_RandomSeed, | ID_RandomSeed, | ||||
ID_RandomReseed, | ID_RandomReseed, | ||||
ID_RandomGenerate, | ID_RandomGenerate, | ||||
ID_SimPlay, | ID_SimPlay, | ||||
ID_SimFast, | ID_SimFast, | ||||
Show All 40 Lines | |||||
public: | public: | ||||
MapSettingsControl(wxWindow* parent, ScenarioEditor& scenarioEditor); | MapSettingsControl(wxWindow* parent, ScenarioEditor& scenarioEditor); | ||||
void CreateWidgets(); | void CreateWidgets(); | ||||
void ReadFromEngine(); | void ReadFromEngine(); | ||||
void SetMapSettings(const AtObj& obj); | void SetMapSettings(const AtObj& obj); | ||||
AtObj UpdateSettingsObject(); | AtObj UpdateSettingsObject(); | ||||
private: | private: | ||||
void SendToEngine(); | void SendToEngine(); | ||||
void OnConquestChanged(); | |||||
void OnEdit(wxCommandEvent& WXUNUSED(evt)) | void OnEdit(wxCommandEvent& evt) | ||||
{ | { | ||||
SendToEngine(); | SendToEngine(); | ||||
if (evt.GetId() == ID_VC_Conquest) | |||||
OnConquestChanged(); | |||||
} | } | ||||
std::set<std::wstring> m_MapSettingsKeywords; | std::set<std::wstring> m_MapSettingsKeywords; | ||||
std::set<std::wstring> m_MapSettingsVictoryConditions; | |||||
std::vector<wxChoice*> m_PlayerCivChoices; | std::vector<wxChoice*> m_PlayerCivChoices; | ||||
Observable<AtObj>& m_MapSettings; | Observable<AtObj>& m_MapSettings; | ||||
DECLARE_EVENT_TABLE(); | DECLARE_EVENT_TABLE(); | ||||
}; | }; | ||||
BEGIN_EVENT_TABLE(MapSettingsControl, wxPanel) | BEGIN_EVENT_TABLE(MapSettingsControl, wxPanel) | ||||
EVT_TEXT(ID_MapName, MapSettingsControl::OnEdit) | EVT_TEXT(ID_MapName, MapSettingsControl::OnEdit) | ||||
Show All 26 Lines | void MapSettingsControl::CreateWidgets() | ||||
sizer->Add(0, 2); | sizer->Add(0, 2); | ||||
sizer->Add(new wxStaticText(this, wxID_ANY, _("Description"))); | sizer->Add(new wxStaticText(this, wxID_ANY, _("Description"))); | ||||
sizer->Add(Tooltipped(new wxTextCtrl(this, ID_MapDescription, wxEmptyString, wxDefaultPosition, wxSize(-1, 100), wxTE_MULTILINE), | sizer->Add(Tooltipped(new wxTextCtrl(this, ID_MapDescription, wxEmptyString, wxDefaultPosition, wxSize(-1, 100), wxTE_MULTILINE), | ||||
_("Short description used on the map selection screen")), wxSizerFlags().Expand()); | _("Short description used on the map selection screen")), wxSizerFlags().Expand()); | ||||
sizer->AddSpacer(5); | sizer->AddSpacer(5); | ||||
// TODO: replace by filenames in binaries/data/mods/public/simulation/data/settings/victory_conditions/ | |||||
wxArrayString gameTypes; | |||||
gameTypes.Add(_T("conquest")); | |||||
gameTypes.Add(_T("conquest_structures")); | |||||
gameTypes.Add(_T("conquest_units")); | |||||
gameTypes.Add(_T("wonder")); | |||||
gameTypes.Add(_T("endless")); | |||||
gameTypes.Add(_T("regicide")); | |||||
gameTypes.Add(_T("capture_the_relic")); | |||||
wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5); | wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5); | ||||
gridSizer->AddGrowableCol(1); | gridSizer->AddGrowableCol(1); | ||||
// TODO: have preview selector tool? | // TODO: have preview selector tool? | ||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Preview")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); | gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Preview")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); | ||||
gridSizer->Add(Tooltipped(new wxTextCtrl(this, ID_MapPreview, wxEmptyString), | gridSizer->Add(Tooltipped(new wxTextCtrl(this, ID_MapPreview, wxEmptyString), | ||||
_("Texture used for map preview")), wxSizerFlags().Expand()); | _("Texture used for map preview")), wxSizerFlags().Expand()); | ||||
CREATE_CHECKBOX(this, gridSizer, "Reveal map", "If checked, players won't need to explore", ID_MapReveal); | CREATE_CHECKBOX(this, gridSizer, "Reveal map", "If checked, players won't need to explore", ID_MapReveal); | ||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Game type")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); | |||||
gridSizer->Add(Tooltipped(new wxChoice(this, ID_MapType, wxDefaultPosition, wxDefaultSize, gameTypes), | |||||
_("Select the game type (or victory condition)")), wxSizerFlags().Expand()); | |||||
CREATE_CHECKBOX(this, gridSizer, "Lock teams", "If checked, teams will be locked", ID_MapTeams); | CREATE_CHECKBOX(this, gridSizer, "Lock teams", "If checked, teams will be locked", ID_MapTeams); | ||||
Not Done Inline ActionsVery good, but perhaps we should inline the macro, or move it above the function? elexis: Very good, but perhaps we should inline the macro, or move it above the function? | |||||
Not Done Inline Actionswe use it for the nomad checkbox too in the function below, so thought file head was the best place, no strong opinion bb: we use it for the nomad checkbox too in the function below, so thought file head was the best… | |||||
sizer->Add(gridSizer, wxSizerFlags().Expand()); | sizer->Add(gridSizer, wxSizerFlags().Expand()); | ||||
sizer->AddSpacer(5); | sizer->AddSpacer(5); | ||||
// TODO: replace by names in binaries/data/mods/public/simulation/data/settings/victory_conditions/ | |||||
Done Inline Actionsalso a macro probably elexis: also a macro probably | |||||
Not Done Inline Actionswould be a macro for all the checkboxes bb: would be a macro for all the checkboxes | |||||
wxStaticBoxSizer* victoryConditionSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Victory Conditions")); | |||||
wxFlexGridSizer* vcGridSizer = new wxFlexGridSizer(2, 5, 5); | |||||
vcGridSizer->AddGrowableCol(1); | |||||
CREATE_CHECKBOX(this, vcGridSizer, "Conquest", "Select Conquest victory condition", ID_VC_Conquest); | |||||
CREATE_CHECKBOX(this, vcGridSizer, "Conquest Units", "Select Conquest Units victory condition", ID_VC_ConquestUnits); | |||||
CREATE_CHECKBOX(this, vcGridSizer, "Conquest Structures", "Select Conquest Structures victory condition", ID_VC_ConquestStructures); | |||||
CREATE_CHECKBOX(this, vcGridSizer, "Capture the Relic", "Select Capture the Relic victory condition", ID_VC_CaptureTheRelic); | |||||
CREATE_CHECKBOX(this, vcGridSizer, "Wonder", "Select Wonder victory condition", ID_VC_Wonder); | |||||
CREATE_CHECKBOX(this, vcGridSizer, "Regicide", "Select Regicide victory condition", ID_VC_Regicide); | |||||
victoryConditionSizer->Add(vcGridSizer); | |||||
sizer->Add(victoryConditionSizer, wxSizerFlags().Expand()); | |||||
sizer->AddSpacer(5); | |||||
Done Inline ActionsBit unexpected for existing atlas users that this consumes so much GUI space. But no real alternatives since it can influence mapgen, so ought to remain above the generate button. Perhaps we can scrape off some pixels by reducing the distance between the checkboxes. elexis: Bit unexpected for existing atlas users that this consumes so much GUI space. But no real… | |||||
Not Done Inline Actions(could be done with the keywords too) bb: (could be done with the keywords too) | |||||
wxStaticBoxSizer* keywordsSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Keywords")); | wxStaticBoxSizer* keywordsSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Keywords")); | ||||
wxFlexGridSizer* kwGridSizer = new wxFlexGridSizer(4, 5, 5); | wxFlexGridSizer* kwGridSizer = new wxFlexGridSizer(4, 5, 5); | ||||
CREATE_CHECKBOX(this, kwGridSizer, "Demo", "If checked, map will only be visible using filters in game setup", ID_MapKW_Demo); | CREATE_CHECKBOX(this, kwGridSizer, "Demo", "If checked, map will only be visible using filters in game setup", ID_MapKW_Demo); | ||||
CREATE_CHECKBOX(this, kwGridSizer, "Naval", "If checked, map will only be visible using filters in game setup", ID_MapKW_Naval); | CREATE_CHECKBOX(this, kwGridSizer, "Naval", "If checked, map will only be visible using filters in game setup", ID_MapKW_Naval); | ||||
keywordsSizer->Add(kwGridSizer); | keywordsSizer->Add(kwGridSizer); | ||||
sizer->Add(keywordsSizer, wxSizerFlags().Expand()); | sizer->Add(keywordsSizer, wxSizerFlags().Expand()); | ||||
} | } | ||||
Show All 14 Lines | void MapSettingsControl::ReadFromEngine() | ||||
wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->ChangeValue(wxString(m_MapSettings["Description"])); | wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->ChangeValue(wxString(m_MapSettings["Description"])); | ||||
// map preview | // map preview | ||||
wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->ChangeValue(wxString(m_MapSettings["Preview"])); | wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->ChangeValue(wxString(m_MapSettings["Preview"])); | ||||
// reveal map | // reveal map | ||||
wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->SetValue(wxString(m_MapSettings["RevealMap"]) == L"true"); | wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->SetValue(wxString(m_MapSettings["RevealMap"]) == L"true"); | ||||
// game type / victory conditions | // victory conditions | ||||
if (m_MapSettings["GameType"].defined()) | m_MapSettingsVictoryConditions.clear(); | ||||
wxDynamicCast(FindWindow(ID_MapType), wxChoice)->SetStringSelection(wxString(m_MapSettings["GameType"])); | for (AtIter victoryCondition = m_MapSettings["VictoryConditions"]["item"]; victoryCondition.defined(); ++victoryCondition) | ||||
else | m_MapSettingsVictoryConditions.insert(std::wstring(victoryCondition)); | ||||
wxDynamicCast(FindWindow(ID_MapType), wxChoice)->SetSelection(0); | |||||
wxWindow* window; | |||||
Not Done Inline ActionsIt'd be better to find window, put in a variable and check on nullptr. Because currently it's not safe. vladislavbelov: It'd be better to find window, put in a variable and check on `nullptr`. Because currently it's… | |||||
Not Done Inline Actionsthat could be done inside a macro? elexis: that could be done inside a macro? | |||||
Not Done Inline ActionsMacro could be, but I'd prefer to make a list of elements, if it's possible. vladislavbelov: Macro could be, but I'd prefer to make a list of elements, if it's possible. | |||||
Not Done Inline Actions(at some point we should load them from json) bb: (at some point we should load them from json) | |||||
#define INIT_CHECKBOX(ID, mapSettings, value) \ | |||||
window = FindWindow(ID_VC_Conquest); \ | |||||
if (window != nullptr) \ | |||||
wxDynamicCast(window, wxCheckBox)->SetValue(mapSettings.count(value) != 0); | |||||
INIT_CHECKBOX(ID_VC_Conquest, m_MapSettingsVictoryConditions, L"conquest"); | |||||
INIT_CHECKBOX(ID_VC_ConquestUnits, m_MapSettingsVictoryConditions, L"conquest_units"); | |||||
INIT_CHECKBOX(ID_VC_ConquestStructures, m_MapSettingsVictoryConditions, L"conquest_structures"); | |||||
INIT_CHECKBOX(ID_VC_CaptureTheRelic, m_MapSettingsVictoryConditions, L"capture_the_relic"); | |||||
INIT_CHECKBOX(ID_VC_Wonder, m_MapSettingsVictoryConditions, L"wonder"); | |||||
INIT_CHECKBOX(ID_VC_Regicide, m_MapSettingsVictoryConditions, L"regicide"); | |||||
OnConquestChanged(); | |||||
Done Inline ActionsBetter rename the macro to reflect that it only works for victory conditions, like INIT_VC_CHECKBOX or something else. Macros that are defined inside a function are usually #undefined before leaving the function. Rest ok. elexis: Better rename the macro to reflect that it only works for victory conditions, like… | |||||
Not Done Inline Actionshow does it only work for vc? (see 10 lines below) bb: how does it only work for vc? (see 10 lines below) | |||||
Not Done Inline ActionsThe #define in the previous patch used ID_VC_Conquest, so it would have been awkward to use it for non-VC, ok now. elexis: The #define in the previous patch used `ID_VC_Conquest`, so it would have been awkward to use… | |||||
Not Done Inline Actions(I guess that caused the bug, you mentioned) bb: (I guess that caused the bug, you mentioned) | |||||
// lock teams | // lock teams | ||||
wxDynamicCast(FindWindow(ID_MapTeams), wxCheckBox)->SetValue(wxString(m_MapSettings["LockTeams"]) == L"true"); | wxDynamicCast(FindWindow(ID_MapTeams), wxCheckBox)->SetValue(wxString(m_MapSettings["LockTeams"]) == L"true"); | ||||
// keywords | // keywords | ||||
{ | { | ||||
m_MapSettingsKeywords.clear(); | m_MapSettingsKeywords.clear(); | ||||
for (AtIter keyword = m_MapSettings["Keywords"]["item"]; keyword.defined(); ++keyword) | for (AtIter keyword = m_MapSettings["Keywords"]["item"]; keyword.defined(); ++keyword) | ||||
m_MapSettingsKeywords.insert(std::wstring(keyword)); | m_MapSettingsKeywords.insert(std::wstring(keyword)); | ||||
wxDynamicCast(FindWindow(ID_MapKW_Demo), wxCheckBox)->SetValue(m_MapSettingsKeywords.count(L"demo") != 0); | INIT_CHECKBOX(ID_MapKW_Demo, m_MapSettingsKeywords, L"demo"); | ||||
wxDynamicCast(FindWindow(ID_MapKW_Naval), wxCheckBox)->SetValue(m_MapSettingsKeywords.count(L"naval") != 0); | INIT_CHECKBOX(ID_MapKW_Naval, m_MapSettingsKeywords, L"naval"); | ||||
} | } | ||||
} | } | ||||
void MapSettingsControl::SetMapSettings(const AtObj& obj) | void MapSettingsControl::SetMapSettings(const AtObj& obj) | ||||
{ | { | ||||
m_MapSettings = obj; | m_MapSettings = obj; | ||||
m_MapSettings.NotifyObservers(); | m_MapSettings.NotifyObservers(); | ||||
SendToEngine(); | SendToEngine(); | ||||
} | } | ||||
void MapSettingsControl::OnConquestChanged() | |||||
{ | |||||
bool conqestEnabled = wxDynamicCast(FindWindow(ID_VC_Conquest), wxCheckBox)->GetValue(); | |||||
Not Done Inline ActionsHere too. vladislavbelov: Here too. | |||||
wxCheckBox* conquestUnitsCheckbox = wxDynamicCast(FindWindow(ID_VC_ConquestUnits), wxCheckBox); | |||||
conquestUnitsCheckbox->Enable(!conqestEnabled); | |||||
wxCheckBox* conquestStructuresCheckbox = wxDynamicCast(FindWindow(ID_VC_ConquestStructures), wxCheckBox); | |||||
conquestStructuresCheckbox->Enable(!conqestEnabled); | |||||
if (conqestEnabled) | |||||
{ | |||||
conquestUnitsCheckbox->SetValue(false); | |||||
conquestStructuresCheckbox->SetValue(false); | |||||
} | |||||
} | |||||
Done Inline ActionsSince I didn't point it out before explicitly, the hardcoding is a bit of a defect. The JSON file allows it for any victory condition but atlas only for this one. It's a consequence of the notdone TODO. But ok to keep it as is, the code is it's own TODO. (Wouldn't reject if it is stated here too.) elexis: Since I didn't point it out before explicitly, the hardcoding is a bit of a defect. The JSON… | |||||
AtObj MapSettingsControl::UpdateSettingsObject() | AtObj MapSettingsControl::UpdateSettingsObject() | ||||
{ | { | ||||
// map name | // map name | ||||
m_MapSettings.set("Name", wxDynamicCast(FindWindow(ID_MapName), wxTextCtrl)->GetValue()); | m_MapSettings.set("Name", wxDynamicCast(FindWindow(ID_MapName), wxTextCtrl)->GetValue()); | ||||
// map description | // map description | ||||
m_MapSettings.set("Description", wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->GetValue()); | m_MapSettings.set("Description", wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->GetValue()); | ||||
// map preview | // map preview | ||||
m_MapSettings.set("Preview", wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->GetValue()); | m_MapSettings.set("Preview", wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->GetValue()); | ||||
// reveal map | // reveal map | ||||
m_MapSettings.setBool("RevealMap", wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->GetValue()); | m_MapSettings.setBool("RevealMap", wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->GetValue()); | ||||
// game type / victory conditions | // victory conditions | ||||
m_MapSettings.set("GameType", wxDynamicCast(FindWindow(ID_MapType), wxChoice)->GetStringSelection()); | #define INSERT_VICTORY_CONDITION_CHECKBOX(name, ID) \ | ||||
if (wxDynamicCast(FindWindow(ID), wxCheckBox)->GetValue()) \ | |||||
m_MapSettingsVictoryConditions.insert(name); \ | |||||
else \ | |||||
m_MapSettingsVictoryConditions.erase(name); | |||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"conquest", ID_VC_Conquest); | |||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"conquest_units", ID_VC_ConquestUnits); | |||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"conquest_structures", ID_VC_ConquestStructures); | |||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"capture_the_relic", ID_VC_CaptureTheRelic); | |||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"wonder", ID_VC_Wonder); | |||||
Not Done Inline Actionsgood elexis: good | |||||
INSERT_VICTORY_CONDITION_CHECKBOX(L"regicide", ID_VC_Regicide); | |||||
AtObj victoryConditions; | |||||
victoryConditions.set("@array", L""); | |||||
for (std::set<std::wstring>::iterator it = m_MapSettingsVictoryConditions.begin(); it != m_MapSettingsVictoryConditions.end(); ++it) | |||||
victoryConditions.add("item", it->c_str()); | |||||
m_MapSettings.set("VictoryConditions", victoryConditions); | |||||
// keywords | // keywords | ||||
{ | { | ||||
if (wxDynamicCast(FindWindow(ID_MapKW_Demo), wxCheckBox)->GetValue()) | if (wxDynamicCast(FindWindow(ID_MapKW_Demo), wxCheckBox)->GetValue()) | ||||
m_MapSettingsKeywords.insert(L"demo"); | m_MapSettingsKeywords.insert(L"demo"); | ||||
else | else | ||||
m_MapSettingsKeywords.erase(L"demo"); | m_MapSettingsKeywords.erase(L"demo"); | ||||
if (wxDynamicCast(FindWindow(ID_MapKW_Naval), wxCheckBox)->GetValue()) | if (wxDynamicCast(FindWindow(ID_MapKW_Naval), wxCheckBox)->GetValue()) | ||||
m_MapSettingsKeywords.insert(L"naval"); | m_MapSettingsKeywords.insert(L"naval"); | ||||
else | else | ||||
Done Inline Actionsmacro INSERT_VICTORY_CONDITION_CHECKBOX("regicide", ID_VC_Regicide); elexis: macro
INSERT_VICTORY_CONDITION_CHECKBOX("regicide", ID_VC_Regicide); | |||||
m_MapSettingsKeywords.erase(L"naval"); | m_MapSettingsKeywords.erase(L"naval"); | ||||
AtObj keywords; | AtObj keywords; | ||||
keywords.set("@array", L""); | keywords.set("@array", L""); | ||||
for (std::set<std::wstring>::iterator it = m_MapSettingsKeywords.begin(); it != m_MapSettingsKeywords.end(); ++it) | for (std::set<std::wstring>::iterator it = m_MapSettingsKeywords.begin(); it != m_MapSettingsKeywords.end(); ++it) | ||||
keywords.add("item", it->c_str()); | keywords.add("item", it->c_str()); | ||||
m_MapSettings.set("Keywords", keywords); | m_MapSettings.set("Keywords", keywords); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 323 Lines • Show Last 20 Lines |
I guess that's the same TODO as below, insert after loading from JSON