diff --git a/MissionEditor/FinalSunDlg.cpp b/MissionEditor/FinalSunDlg.cpp index ab0d4f8..abfc200 100644 --- a/MissionEditor/FinalSunDlg.cpp +++ b/MissionEditor/FinalSunDlg.cpp @@ -1767,23 +1767,28 @@ void CFinalSunDlg::OnFileNew() int i; int count = Map->GetTerrainCount(); if (!bImportTrees) { - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) { Map->DeleteTerrain(0); + } } if (!bImportUnits) { count = Map->GetInfantryCount(); - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) { Map->DeleteInfantry(0); + } count = Map->GetUnitCount(); - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) { Map->DeleteUnit(0); + } count = Map->GetStructureCount(); - for (i = 0; i < count; i++) - Map->DeleteStructure(0); + for (i = count; i >= 0; i--) { + Map->DeleteNthStructure(0); + } count = Map->GetAircraftCount(); - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) { Map->DeleteAircraft(0); + } } ini.SetString("Basic", "Name", "Noname"); diff --git a/MissionEditor/IsoView.cpp b/MissionEditor/IsoView.cpp index cf07500..7771ee6 100644 --- a/MissionEditor/IsoView.cpp +++ b/MissionEditor/IsoView.cpp @@ -1541,8 +1541,9 @@ void CIsoView::OnMouseMove(UINT nFlags, CPoint point) int id = Map->GetNodeAt(dwPos, house); Map->DeleteNode(house, id); } - if (cur_field.structure != oldData[i][e].structure) + if (cur_field.structure != oldData[i][e].structure && cur_field.structure >= 0) { Map->DeleteStructure(cur_field.structure); + } if (cur_field.terrain != oldData[i][e].terrain) Map->DeleteTerrain(cur_field.terrain); #ifdef SMUDGE_SUPP @@ -4168,10 +4169,21 @@ void CIsoView::UpdateStatusBar(int x, int y) objId = n; } - if (objId >= 0 && type != TechnoType::Infantry) { + do { + if (type == TechnoType::Infantry) { + break; + } + if (objId < 0) { + break; + } + if (type == TechnoType::Building) { + auto const data = Map->GetDataOfTechnoByID(objId, type); + Map->ParseTechnoData(data, type, techno); + break; + } auto const [_, data] = Map->GetNthDataOfTechno(objId, type); Map->ParseTechnoData(data, type, techno); - } + } while (0); if (techno.basic.type.GetLength() > 0) { char c[50]; @@ -4975,9 +4987,13 @@ DWORD CIsoView::PlaceCurrentObjectAt(int x, int y) int t = Map->GetStructureAt(expectingPos); if (t >= 0) { STRUCTURE structure; - auto const id = Map->GetStructureData(t, &structure); + Map->GetStructureData(t, &structure); Map->DeleteStructure(t); structure.basic.house = AD.data_s; + + CString id; + id.Format("%d", t); + Map->AddStructure(&structure, nullptr, nullptr, 0, std::move(id)); bchanged = TRUE; } @@ -5757,7 +5773,7 @@ void CIsoView::DrawMap() if (shouldDraw) { STRUCTUREPAINT objp; - Map->GetStructurePaint(m.structure, &objp); + Map->GetStructurePaint(m.structure, objp); const auto drawCoordsBld = GetRenderTargetCoordinates(MapCoords(objp.x, objp.y)); int id = m.structuretype; diff --git a/MissionEditor/MapData.cpp b/MissionEditor/MapData.cpp index 6a84cf2..b6273fc 100644 --- a/MissionEditor/MapData.cpp +++ b/MissionEditor/MapData.cpp @@ -1585,11 +1585,9 @@ void CMapData::UpdateStructures(BOOL bSave) m_structurepaint.clear(); - auto const& sec = m_mapfile["Structures"]; - - for (auto i = 0; i < sec.Size(); i++) { + for (auto const& [index, val] : m_mapfile.GetSection("Structures")) { STRUCTUREPAINT sp; - auto const& val = sec.Nth(i).second; + const size_t indexNum = atoi(index); sp.col = ((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview->GetColor(GetParam(val, 0)); sp.strength = atoi(GetParam(val, 2)); sp.upgrade1 = GetParam(val, 12); @@ -1605,17 +1603,17 @@ void CMapData::UpdateStructures(BOOL bSave) TruncSpace(sp.upgrade2); TruncSpace(sp.upgrade3); - m_structurepaint.push_back(sp); + m_structurepaint.insert_or_assign(indexNum, sp); int x = atoi(GetParam(val, 4)); int y = atoi(GetParam(val, 3)); int d, e; - int bid = buildingid[GetParam(val, 1)]; + int bid = buildingid.at(sp.type); for (d = 0; d < buildinginfo[bid].h; d++) { for (e = 0; e < buildinginfo[bid].w; e++) { int pos = (x + d) + (y + e) * GetIsoSize(); if (pos < fielddata.size()) { - fielddata[pos].structure = i; + fielddata[pos].structure = indexNum; fielddata[pos].structuretype = bid; } @@ -1968,7 +1966,7 @@ void CMapData::DeleteUnit(DWORD dwIndex) Mini_UpdatePos(x, y, IsMultiplayer()); } -void CMapData::DeleteStructure(DWORD dwIndex) +void CMapData::DeleteNthStructure(const size_t dwIndex) { if (dwIndex >= GetStructureCount()) { return; @@ -1983,9 +1981,18 @@ void CMapData::DeleteStructure(DWORD dwIndex) pSec->RemoveAt(dwIndex); +#if 1 + if (auto fieldData = GetFielddataAt(x, y)) { + auto const refCout = m_structurepaint.erase(fieldData->structure); + ASSERT(refCout == 1); + fieldData->structure = -1; + fieldData->structuretype = -1; + } +#else if (!m_noAutoObjectUpdate) { UpdateStructures(FALSE); } +#endif int d, e; int bid = buildingid[type]; @@ -1998,6 +2005,18 @@ void CMapData::DeleteStructure(DWORD dwIndex) } } +bool CMapData::DeleteStructure(const size_t id) +{ + CString idStr; + idStr.Format("%d", id); + auto const idx = m_mapfile.GetSection("Structures").FindIndex(idStr); + if (idx >= 0) { + DeleteNthStructure(idx); + return true; + } + return false; +} + void CMapData::DeleteAircraft(DWORD dwIndex) { if (dwIndex >= GetAircraftCount()) return; @@ -2090,7 +2109,7 @@ BOOL CMapData::AddWaypoint(CString id, DWORD dwPos) -CString CMapData::GetStructureData(DWORD dwIndex, STRUCTURE* lpStructure) const +CString CMapData::GetNthStructureData(DWORD dwIndex, STRUCTURE* lpStructure) const { auto const [id, data] = GetNthDataOfTechno(dwIndex, TechnoType::Building); if (!ParseStructureData(data, *lpStructure)) { @@ -2099,7 +2118,23 @@ CString CMapData::GetStructureData(DWORD dwIndex, STRUCTURE* lpStructure) const return id; } -void CMapData::GetStdStructureData(DWORD dwIndex, STDOBJECTDATA* lpStdStructure) const +void CMapData::GetStructureData(size_t id, STRUCTURE* lpStructure) const +{ + auto const& data = GetDataOfTechnoByID(id, TechnoType::Building); + if (!data.IsEmpty()) { + ParseStructureData(data, *lpStructure); + } +} + +void CMapData::GetStdStructureData(const size_t id, STDOBJECTDATA* lpStdStructure) const +{ + auto const& data = GetDataOfTechnoByID(id, TechnoType::Building); + if (!data.IsEmpty()) { + ParseBasicTechnoData(data, *lpStdStructure); + } +} + +void CMapData::GetNthStdStructureData(DWORD dwIndex, STDOBJECTDATA* lpStdStructure) const { auto const [_, data] = GetNthDataOfTechno(dwIndex, TechnoType::Building); ParseBasicTechnoData(data, *lpStdStructure); @@ -2498,7 +2533,7 @@ bool CMapData::ParseStructureData(const CString& rawText, STRUCTURE& structure) return true; } -std::pair CMapData::GetNthDataOfTechno(const size_t index, const TechnoType type) const +static CString GetDataSection(const TechnoType type) { CString sectionID; switch (type) @@ -2518,13 +2553,25 @@ std::pair CMapData::GetNthDataOfTechno(const size_t index, con default: break; } - auto const& section = m_mapfile.GetSection(sectionID); + return sectionID; +} + +std::pair CMapData::GetNthDataOfTechno(const size_t index, const TechnoType type) const +{ + auto const& section = m_mapfile.GetSection(GetDataSection(type)); if (index >= section.Size()) { return {}; } return section.Nth(index); } +CString CMapData::GetDataOfTechnoByID(const size_t id, const TechnoType type) const +{ + CString idStr; + idStr.Format("%d", id); + return m_mapfile.GetString(GetDataSection(type), idStr); +} + bool CMapData::ParseBasicTechnoData(const CString& rawText, STDOBJECTDATA& data) const { if (rawText.IsEmpty()) { @@ -2874,6 +2921,7 @@ void CMapData::GetStdAircraftData(DWORD dwIndex, STDOBJECTDATA* lpStdAircraft) c auto const [_, data] = GetNthDataOfTechno(dwIndex, TechnoType::Aircraft); ParseBasicTechnoData(data, *lpStdAircraft); } + void CMapData::GetStdUnitData(DWORD dwIndex, STDOBJECTDATA* lpStdUnit) const { auto const [_, data] = GetNthDataOfTechno(dwIndex, TechnoType::Unit); @@ -5506,11 +5554,12 @@ void CMapData::Paste(int x, int y, int z_mod) CloseClipboard(); } -void CMapData::GetStructurePaint(int index, STRUCTUREPAINT* lpStructurePaint) const +void CMapData::GetStructurePaint(int index, STRUCTUREPAINT& structurePaint) const { - if (index < 0 || index >= m_structurepaint.size()) return; - - *lpStructurePaint = m_structurepaint[index]; + auto const it = m_structurepaint.find(index); + if (it != m_structurepaint.end()) { + structurePaint = it->second; + } } void CMapData::InitMinimap() @@ -5721,8 +5770,9 @@ void CMapData::ResizeMap(int iLeft, int iTop, DWORD dwNewWidth, DWORD dwNewHeigh str[i] = obj; } - for (int i = str_count - 1; i >= 0; i--) - DeleteStructure(i); + for (int i = str_count - 1; i >= 0; i--) { + DeleteNthStructure(i); + } for (int i = 0; i < unit_count; i++) { UNIT obj; @@ -6194,14 +6244,14 @@ BOOL CMapData::IsYRMap() count = GetStructureCount(); for (i = 0; i < count; i++) { - STRUCTURE str; - GetStructureData(i, &str); + STRUCTURE structure; + GetNthStructureData(i, &structure); - if (str.deleted) { + if (structure.deleted) { continue; } - if (g_data["YRBuildings"].Exists(str.basic.type)) { + if (g_data["YRBuildings"].Exists(structure.basic.type)) { return TRUE; } } diff --git a/MissionEditor/MapData.h b/MissionEditor/MapData.h index 984c68d..eb31233 100644 --- a/MissionEditor/MapData.h +++ b/MissionEditor/MapData.h @@ -257,6 +257,7 @@ public: BOOL AddCelltag(LPCTSTR lpTag, DWORD dwPos); std::pair GetNthDataOfTechno(const size_t index, const TechnoType type) const; + CString GetDataOfTechnoByID(const size_t id, const TechnoType type) const; bool ParseBasicTechnoData(const CString& rawText, STDOBJECTDATA& data) const; bool ParseTechnoData(const CString& rawText, const TechnoType type, TECHNODATA& data) const; CString GetAircraftData(DWORD dwIndex, AIRCRAFT* lpAircraft) const; @@ -269,20 +270,23 @@ public: void GetStdInfantryData(DWORD dwIndex, STDOBJECTDATA* lpStdInfantry) const; void GetStdUnitData(DWORD dwIndex, STDOBJECTDATA* lpStdUnit) const; void GetStdAircraftData(DWORD dwIndex, STDOBJECTDATA* lpStdAircraft) const; - void GetStdStructureData(DWORD dwIndex, STDOBJECTDATA* lpStdStructure) const; + void GetStdStructureData(const size_t id, STDOBJECTDATA* lpStdStructure) const; + void GetNthStdStructureData(DWORD dwIndex, STDOBJECTDATA* lpStdStructure) const; INT GetUnitTypeID(LPCTSTR lpType); void InitializeUnitTypes(); BOOL AddStructure(STRUCTURE* lpStructure, LPCTSTR lpType = NULL, LPCTSTR lpHouse = NULL, DWORD dwPos = 0, CString suggestedID = ""); BOOL AddInfantry(INFANTRY* lpInfantry, int suggestedIndex = -1, LPCTSTR lpType = NULL, LPCTSTR lpHouse = NULL, DWORD dwPos = 0); BOOL AddNode(NODE* lpNode, WORD dwPos); - CString GetStructureData(DWORD dwIndex, STRUCTURE* lpStructure) const; + CString GetNthStructureData(DWORD dwIndex, STRUCTURE* lpStructure) const; + void GetStructureData(size_t id, STRUCTURE* lpStructure) const; BOOL AddWaypoint(CString lpID, DWORD dwPos); void DeleteNode(const CString& house, const int index); void DeleteTerrain(DWORD dwIndex); void DeleteAircraft(DWORD dwIndex); - void DeleteStructure(DWORD dwIndex); + void DeleteNthStructure(const size_t dwIndex); + bool DeleteStructure(const size_t id); void DeleteUnit(DWORD dwIndex); void DeleteCelltag(DWORD dwIndex); void DeleteWaypoint(DWORD id); @@ -326,7 +330,7 @@ public: } INT GetStructureAt(DWORD dwPos) const { - if (fielddata[dwPos].structure > -1) { + if (fielddata[dwPos].structure >= 0) { return fielddata[dwPos].structure; } return -1; @@ -528,7 +532,7 @@ private: int m_cursnapshot; int m_money; - vector m_structurepaint; + std::unordered_map m_structurepaint; protected: @@ -656,7 +660,7 @@ public: int GetMoneyOnMap() const; int CalcMoneyOnMap(); void GetMinimap(BYTE** lpData, BITMAPINFO* lpBI, int* pitch); - void GetStructurePaint(int index, STRUCTUREPAINT* lpStructurePaint) const; + void GetStructurePaint(int index, STRUCTUREPAINT& structurePaint) const; void Paste(int x, int y, int z_mod); void Copy(int left = 0, int top = 0, int right = 0, int bottom = 0); CString GetTheater(); diff --git a/MissionEditor/UserScriptsDlg.cpp b/MissionEditor/UserScriptsDlg.cpp index f5b6ac3..973b9d2 100644 --- a/MissionEditor/UserScriptsDlg.cpp +++ b/MissionEditor/UserScriptsDlg.cpp @@ -2180,20 +2180,27 @@ void CUserScriptsDlg::OnOK() // check bool if (paramcount > 1) { if (params[1].GetLength() > 0) { - if (!IsValSet(params[1])) goto nextline; + if (!IsValSet(params[1])) { + goto nextline; + } } } - if (!bDeleteAllowed) goto nextline; + if (!bDeleteAllowed) { + goto nextline; + } - int index = atoi(params[0]); + int id = atoi(params[0]); + CString idStr; + idStr.Format("%d", id); + auto const index = ini.GetSection("Structures").FindIndex(idStr); if (index < 0 || index >= Map->GetStructureCount()) { report += "Structure deletion failed, invalid index\r\n"; goto nextline; } lastStructureDeleted = ini["Structures"].Nth(index).first; - Map->DeleteStructure(index); + Map->DeleteNthStructure(index); report += "Structure deleted\r\n";