Fix: now building node under house type is corrected, related function refactored .

This commit is contained in:
Zero Fanker 2024-12-16 00:27:15 -05:00
parent ea4c214b04
commit a91ff89091
12 changed files with 154 additions and 79 deletions

View file

@ -134,4 +134,15 @@ inline CString WaypointToString(int num)
ret += firstChar;
ret += secondChar;
return ret;
}
inline void GetNodeID(CString& name, int n)
{
name.Format("%03d", n);
}
inline CString GetNodeID(int n)
{
CString ret;
GetNodeID(ret, n);
return ret;
}

View file

@ -61,7 +61,6 @@ static char THIS_FILE[] = __FILE__;
/* Externals */
extern ACTIONDATA AD;
void GetNodeName(CString& name, int n);
/* --------- */
/* Overlay picture table (maximum overlay count=0xFF) */

View file

@ -33,6 +33,7 @@
#include "Structs.h"
#include "Tube.h"
#include "IniMega.h"
#include "Helpers.h"
#ifdef _DEBUG
#undef THIS_FILE
@ -50,10 +51,6 @@ void DoEvents()
}*/
}
void GetNodeName(CString& name, int n);
CString GetFree(const char* sectionName)
{
auto const ini = Map->GetIniFile();
@ -1768,7 +1765,7 @@ void CMapData::UpdateNodes(BOOL bSave)
int nodeCount = sec.GetInteger("NodeCount");
for (auto idx = 0; idx < nodeCount; idx++) {
CString nodeName;
GetNodeName(nodeName, idx);
GetNodeID(nodeName, idx);
auto const& nodeVal = sec.GetString(nodeName);
CString type, sx, sy;
type = GetParam(nodeVal, 0);
@ -2034,26 +2031,9 @@ void CMapData::DeleteTerrain(DWORD dwIndex)
}
void CMapData::DeleteNode(LPCTSTR lpHouse, DWORD dwIndex)
void CMapData::DeleteNode(const CString& house, const int dwIndex)
{
CString nodeName; // p is last node
auto const nodeCount = m_mapfile.GetInteger(lpHouse, "NodeCount");
GetNodeName(nodeName, nodeCount - 1);
for (auto i = dwIndex; i < nodeCount - 1; i++) {
CString prevNodeName, nextNodeName;
GetNodeName(prevNodeName, i);
GetNodeName(nextNodeName, i + 1);
m_mapfile.SetString(lpHouse, prevNodeName, m_mapfile.GetString(lpHouse, nextNodeName));
}
auto const& pSec = m_mapfile.TryGetSection(lpHouse);
pSec->RemoveAt(dwIndex);
char nodeCountStr[50];
itoa(nodeCount - 1, nodeCountStr, 10);
m_mapfile.SetString(lpHouse, "NodeCount", nodeCountStr);
DeleteBuildingNodeFrom(house, dwIndex, m_mapfile);
UpdateNodes(FALSE);
}
@ -2168,7 +2148,7 @@ BOOL CMapData::AddNode(NODE* lpNode, WORD dwPos)
nodeCount--;
CString p;
GetNodeName(p, nodeCount);
GetNodeID(p, nodeCount);
auto&& nodeRecord = node.type
+ "," + node.y + "," + node.x;

View file

@ -264,7 +264,7 @@ public:
CString GetStructureData(DWORD dwIndex, STRUCTURE* lpStructure) const;
BOOL AddWaypoint(CString lpID, DWORD dwPos);
void DeleteNode(LPCTSTR lpHouse, DWORD dwIndex);
void DeleteNode(const CString& house, const int index);
void DeleteTerrain(DWORD dwIndex);
void DeleteAircraft(DWORD dwIndex);
void DeleteStructure(DWORD dwIndex);

View file

@ -1320,27 +1320,7 @@ CString GetFreeID()
return "";
}
void GetNodeName(CString& name, int n)
{
char c[5];
char p[6];
memset(p, 0, 6);
_itoa_s(n, c, 10);
strcpy_s(p, c);
if (strlen(c) == 1) {
memcpy(c, "00", 2);
strcpy_s(c + 2, sizeof(c) - 2, p);
} else if (strlen(c) == 2) {
memcpy(c, "0", 1);
strcpy_s(c + 1, sizeof(c) - 1, p);
} else if (strlen(c) == 3) {
strcpy_s(c, p);
}
name = c;
}
// UNUSED
int GetNodeAt(CString& owner, CString& buildingTypeID, int x, int y)
{
CIniFile& ini = Map->GetIniFile();
@ -1362,7 +1342,7 @@ int GetNodeAt(CString& owner, CString& buildingTypeID, int x, int y)
for (auto i = 0; i < nodeCount; i++) {
CString nodeName;
GetNodeName(nodeName, i);
GetNodeID(nodeName, i);
CString sx, sy;
buildingTypeID = GetParam(ownerSection.GetString(nodeName), 0);

View file

@ -26,6 +26,8 @@
#include <array>
#include "Helpers.h"
class CIniFile;
class CSliderCtrl;
using std::string;
bool deleteFile(const std::string& u8FilePath);
@ -56,9 +58,28 @@ std::string utf16ToUtf8(const std::wstring& utf16);
std::string utf16ToACP(const std::wstring& utf16);
// map functions
int GetNodeAt(string& owner, string& type, int x, int y);
int SetNodeAt(string owner, string type, int x, int y);
void ClearNode(int n, string owner);
inline void DeleteBuildingNodeFrom(const CString& house, const int index, CIniFile& ini)
{
auto const nodeCount = ini.GetInteger(house, "NodeCount");
ASSERT(nodeCount > 0);
// override value from current ID
CString prevNodeName, nextNodeName, lastData;
for (auto i = index; i < nodeCount - 1; i++) {
GetNodeID(prevNodeName, i);
GetNodeID(nextNodeName, i + 1);
lastData = ini.GetString(house, nextNodeName);
ini.SetString(house, prevNodeName, lastData);
}
auto const& pSec = ini.TryGetSection(house);
ASSERT(pSec != nullptr);
if (pSec) {
// always remove the last one
auto const result = pSec->RemoveByKey(GetNodeID(nodeCount - 1));
ASSERT(result == true);
}
ini.SetInteger(house, "NodeCount", nodeCount - 1);
}
CString GetFreeID();

View file

@ -1,31 +1,7 @@
#include "stdafx.h"
#include "StdAfx.h"
#include "CIni_Test.h"
#include "../MissionEditor/IniFile.h"
class IniTestHelper
{
std::string m_fileName;
void writeDownContent(const char* pContent) {
std::ofstream iniFile(m_fileName.c_str());
ASSERT(iniFile.is_open() == true);
iniFile << pContent;
iniFile.flush();
iniFile.close();
}
public:
IniTestHelper(std::string&& name, const char* pContent) :
m_fileName(std::move(name))
{
ASSERT(!m_fileName.empty());
ASSERT(pContent != nullptr);
writeDownContent(pContent);
}
~IniTestHelper() {
remove(m_fileName.c_str());
}
};
TEST(CIniFileClass, LoadFileTest) {
auto const fileName = "test.ini";

28
UnitTest/CIni_Test.h Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#include "StdAfx.h"
class IniTestHelper
{
std::string m_fileName;
void writeDownContent(const char* pContent) {
std::ofstream iniFile(m_fileName.c_str());
ASSERT(iniFile.is_open() == true);
iniFile << pContent;
iniFile.flush();
iniFile.close();
}
public:
IniTestHelper(std::string&& name, const char* pContent) :
m_fileName(std::move(name))
{
ASSERT(!m_fileName.empty());
ASSERT(pContent != nullptr);
writeDownContent(pContent);
}
~IniTestHelper() {
remove(m_fileName.c_str());
}
};

View file

@ -1,6 +1,9 @@
#include "stdafx.h"
#include "StdAfx.h"
#include "MissionEditorPackLib.h"
#include "IniFile.h"
#include "functions.h"
#include "CIni_Test.h"
using std::cout;
using std::endl;
@ -109,4 +112,75 @@ TEST(SerdeTest, OverlayDataPackSerde)
ASSERT_EQ(b64Input.size(), strlen(reinterpret_cast<char*>(encoded.get())));
ASSERT_TRUE(0 == memcmp(encoded.get(), b64Input.data(), b64Input.size()));
}
TEST(SerdeTest, HouseBuildingNodeTest)
{
ASSERT_EQ("000", GetNodeID(0));
ASSERT_EQ("005", GetNodeID(5));
ASSERT_EQ("010", GetNodeID(10));
ASSERT_EQ("123", GetNodeID(123));
}
TEST(SerdeTest, HouseBuildingNodeDeleteTest)
{
auto const fileName = "test.ini";
IniTestHelper helper(fileName, R"(
[Russian1 House]
IQ=5
000=NALASR,86,63
001=NALASR,89,64
002=NALASR,83,64
003=NARADR,71,48
004=NAREFN,69,66
005=NALASR,78,42
006=NALASR,73,42
007=NAFLAK,61,34
008=NAFLAK,61,32
009=NAFLAK,62,41
010=TESLA,61,41
011=NAFLAK,61,40
012=NAPOWR,91,23
013=NAFLAK,64,63
014=NAFLAK,91,63
015=NAPOWR,62,39
016=TESLA,71,41
017=NAHAND,76,57
018=NAPOWR,65,37
019=NALASR,83,50
020=NAWEAP,63,59
021=NAWEAP,63,54
022=NALASR,77,24
023=NAFLAK,81,63
024=NALASR,79,24
025=TESLA,81,24
Edge=North
Color=DarkRed
Allies=C2 House,Russian1 House,Russian2 House,CivilianArmy House,Civilian1 House,Other1 House,Civilian2 House
Country=Russian1
Credits=600
NodeCount=26
TechLevel=5
PercentBuilt=100
PlayerControl=no
)");
CString houseName = "Russian1 House";
CIniFile file;
ASSERT_EQ(file.LoadFile(std::string(fileName)), 0);
// remove last
DeleteBuildingNodeFrom(houseName, 25, file);
ASSERT_EQ(file.GetInteger(houseName, "NodeCount"), 25);
// remove middle
DeleteBuildingNodeFrom(houseName, 23, file);
ASSERT_EQ(file.GetInteger(houseName, "NodeCount"), 24);
ASSERT_EQ(file.GetString(houseName, GetNodeID(23)), "NALASR,79,24");
// remove first
DeleteBuildingNodeFrom(houseName, 0, file);
ASSERT_EQ(file.GetInteger(houseName, "NodeCount"), 23);
ASSERT_EQ(file.GetString(houseName, GetNodeID(0)), "NALASR,89,64");
ASSERT_EQ(file.GetString(houseName, GetNodeID(22)), "NALASR,79,24");
}

View file

@ -26,6 +26,8 @@
#include <gtest/gtest.h>
#include <iostream>
#include <afxwin.h>
#include <string>
#include <fstream>
using std::cout;
using std::endl;

View file

@ -148,6 +148,7 @@
<ItemGroup>
<ClInclude Include="..\MissionEditor\IniFile.h" />
<ClInclude Include="..\MissionEditor\INIMeta.h" />
<ClInclude Include="CIni_Test.h" />
<ClInclude Include="StdAfx.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View file

@ -47,5 +47,8 @@
<ClInclude Include="..\MissionEditor\INIMeta.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="CIni_Test.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
</Project>