summaryrefslogtreecommitdiff
path: root/src/peds/PedType.cpp
diff options
context:
space:
mode:
authorclaude-bot <[email protected]>2026-07-13 12:27:07 +0000
committerclaude-bot <[email protected]>2026-07-13 12:27:07 +0000
commit9f61c9e6ac6b1ac5692cf6352d2ebbd47a31a686 (patch)
treea84756b82513739a2672db3a1f0ec579db6d18ff /src/peds/PedType.cpp
downloadre3-miami.tar.gz
re3-miami.zip
Import Cai1Hsu/re3 @ miami (reVC / GTA:VC decompilation)HEADmiami
Snapshot import (no upstream history) into git.ancap.in.ua/claude, per @lzcnt. Source: https://github.com/Cai1Hsu/re3 branch miami.
Diffstat (limited to 'src/peds/PedType.cpp')
-rw-r--r--src/peds/PedType.cpp316
1 files changed, 316 insertions, 0 deletions
diff --git a/src/peds/PedType.cpp b/src/peds/PedType.cpp
new file mode 100644
index 0000000..bacb1a7
--- /dev/null
+++ b/src/peds/PedType.cpp
@@ -0,0 +1,316 @@
+#include "common.h"
+
+#include "General.h"
+#include "FileMgr.h"
+#include "PedType.h"
+
+CPedType *CPedType::ms_apPedType[NUM_PEDTYPES];
+CPedStats *CPedStats::ms_apPedStats[NUM_PEDSTATS];
+
+void
+CPedType::Initialise(void)
+{
+ int i;
+
+ debug("Initialising CPedType...\n");
+ for(i = 0; i < NUM_PEDTYPES; i++){
+ ms_apPedType[i] = new CPedType;
+ ms_apPedType[i]->m_flag = PED_FLAG_PLAYER1;
+ ms_apPedType[i]->unknown1 = 0.0f;
+ ms_apPedType[i]->unknown2 = 0.0f;
+ // unknown3 not initialized
+ ms_apPedType[i]->unknown4 = 0.0f;
+ ms_apPedType[i]->unknown5 = 0.0f;
+ ms_apPedType[i]->m_threats = 0;
+ ms_apPedType[i]->m_avoid = 0;
+ }
+ debug("Loading ped data...\n");
+ LoadPedData();
+ debug("CPedType ready\n");
+}
+
+void
+CPedType::Shutdown(void)
+{
+ int i;
+ debug("Shutting down CPedType...\n");
+ for(i = 0; i < NUM_PEDTYPES; i++)
+ delete ms_apPedType[i];
+ debug("CPedType shut down\n");
+}
+
+void
+CPedType::LoadPedData(void)
+{
+ char *buf;
+ char line[256];
+ char word[32];
+ ssize_t bp, buflen;
+ int lp, linelen;
+ int type;
+ uint32 flags;
+ float f1, f2, f3, f4, f5;
+
+ type = NUM_PEDTYPES;
+ buf = new char[16 * 1024];
+
+ CFileMgr::SetDir("DATA");
+ buflen = CFileMgr::LoadFile("PED.DAT", (uint8*)buf, 16 * 1024, "r");
+ CFileMgr::SetDir("");
+
+ for(bp = 0; bp < buflen; ){
+ // read file line by line
+ for(linelen = 0; buf[bp] != '\n' && bp < buflen; bp++){
+ if(buf[bp] == '\r' || buf[bp] == ',' || buf[bp] == '\t')
+ line[linelen++] = ' ';
+ else
+ line[linelen++] = buf[bp];
+ }
+ bp++;
+ line[linelen] = '\0';
+
+ // skip white space
+ for(lp = 0; line[lp] <= ' '; lp++);
+
+ if(lp >= linelen || // FIX: game uses == here, but this is safer if we have empty lines
+ line[lp] == '#')
+ continue;
+
+ // Game uses just "line" here since sscanf already trims whitespace, but this is safer
+ sscanf(&line[lp], "%s", word);
+
+ if(strcmp(word, "Threat") == 0){
+ flags = 0;
+ lp += 7;
+ while(sscanf(&line[lp], "%s", word) == 1 && lp <= linelen){
+ flags |= FindPedFlag(word);
+ // skip word
+ while(line[lp] != ' ' && line[lp] != '\n' && line[lp] != '\0')
+ lp++;
+ // skip white space
+ while(line[lp] == ' ')
+ lp++;
+ }
+ ms_apPedType[type]->m_threats = flags;
+ }else if(strcmp(word, "Avoid") == 0){
+ flags = 0;
+ lp += 6;
+ while(sscanf(&line[lp], "%s", word) == 1 && lp <= linelen){
+ flags |= FindPedFlag(word);
+ // skip word
+ while(line[lp] != ' ' && line[lp] != '\n' && line[lp] != '\0')
+ lp++;
+ // skip white space
+ while(line[lp] == ' ')
+ lp++;
+ }
+ ms_apPedType[type]->m_avoid = flags;
+ }else{
+ sscanf(line, "%s %f %f %f %f %f", word, &f1, &f2, &f3, &f4, &f5);
+ type = FindPedType(word);
+ ms_apPedType[type]->m_flag = FindPedFlag(word);
+ // unknown values
+ ms_apPedType[type]->unknown1 = f1 / 50.0f;
+ ms_apPedType[type]->unknown2 = f2 / 50.0f;
+ ms_apPedType[type]->unknown3 = f3 / 50.0f;
+ ms_apPedType[type]->unknown4 = f4;
+ ms_apPedType[type]->unknown5 = f5;
+
+ }
+ }
+
+ delete[] buf;
+}
+
+ePedType
+CPedType::FindPedType(char *type)
+{
+ if(strcmp(type, "PLAYER1") == 0) return PEDTYPE_PLAYER1;
+ if(strcmp(type, "PLAYER2") == 0) return PEDTYPE_PLAYER2;
+ if(strcmp(type, "PLAYER3") == 0) return PEDTYPE_PLAYER3;
+ if(strcmp(type, "PLAYER4") == 0) return PEDTYPE_PLAYER4;
+ if(strcmp(type, "CIVMALE") == 0) return PEDTYPE_CIVMALE;
+ if(strcmp(type, "CIVFEMALE") == 0) return PEDTYPE_CIVFEMALE;
+ if(strcmp(type, "COP") == 0) return PEDTYPE_COP;
+ if(strcmp(type, "GANG1") == 0) return PEDTYPE_GANG1;
+ if(strcmp(type, "GANG2") == 0) return PEDTYPE_GANG2;
+ if(strcmp(type, "GANG3") == 0) return PEDTYPE_GANG3;
+ if(strcmp(type, "GANG4") == 0) return PEDTYPE_GANG4;
+ if(strcmp(type, "GANG5") == 0) return PEDTYPE_GANG5;
+ if(strcmp(type, "GANG6") == 0) return PEDTYPE_GANG6;
+ if(strcmp(type, "GANG7") == 0) return PEDTYPE_GANG7;
+ if(strcmp(type, "GANG8") == 0) return PEDTYPE_GANG8;
+ if(strcmp(type, "GANG9") == 0) return PEDTYPE_GANG9;
+ if(strcmp(type, "EMERGENCY") == 0) return PEDTYPE_EMERGENCY;
+ if(strcmp(type, "FIREMAN") == 0) return PEDTYPE_FIREMAN;
+ if(strcmp(type, "CRIMINAL") == 0) return PEDTYPE_CRIMINAL;
+ if(strcmp(type, "SPECIAL") == 0) return PEDTYPE_SPECIAL;
+ if(strcmp(type, "PROSTITUTE") == 0) return PEDTYPE_PROSTITUTE;
+ Error("Unknown ped type, Pedtype.cpp");
+ return NUM_PEDTYPES;
+}
+
+uint32
+CPedType::FindPedFlag(char *type)
+{
+ if(strcmp(type, "PLAYER1") == 0) return PED_FLAG_PLAYER1;
+ if(strcmp(type, "PLAYER2") == 0) return PED_FLAG_PLAYER2;
+ if(strcmp(type, "PLAYER3") == 0) return PED_FLAG_PLAYER3;
+ if(strcmp(type, "PLAYER4") == 0) return PED_FLAG_PLAYER4;
+ if(strcmp(type, "CIVMALE") == 0) return PED_FLAG_CIVMALE;
+ if(strcmp(type, "CIVFEMALE") == 0) return PED_FLAG_CIVFEMALE;
+ if(strcmp(type, "COP") == 0) return PED_FLAG_COP;
+ if(strcmp(type, "GANG1") == 0) return PED_FLAG_GANG1;
+ if(strcmp(type, "GANG2") == 0) return PED_FLAG_GANG2;
+ if(strcmp(type, "GANG3") == 0) return PED_FLAG_GANG3;
+ if(strcmp(type, "GANG4") == 0) return PED_FLAG_GANG4;
+ if(strcmp(type, "GANG5") == 0) return PED_FLAG_GANG5;
+ if(strcmp(type, "GANG6") == 0) return PED_FLAG_GANG6;
+ if(strcmp(type, "GANG7") == 0) return PED_FLAG_GANG7;
+ if(strcmp(type, "GANG8") == 0) return PED_FLAG_GANG8;
+ if(strcmp(type, "GANG9") == 0) return PED_FLAG_GANG9;
+ if(strcmp(type, "EMERGENCY") == 0) return PED_FLAG_EMERGENCY;
+ if(strcmp(type, "FIREMAN") == 0) return PED_FLAG_FIREMAN;
+ if(strcmp(type, "CRIMINAL") == 0) return PED_FLAG_CRIMINAL;
+ if(strcmp(type, "SPECIAL") == 0) return PED_FLAG_SPECIAL;
+ if(strcmp(type, "GUN") == 0) return PED_FLAG_GUN;
+ if(strcmp(type, "COP_CAR") == 0) return PED_FLAG_COP_CAR;
+ if(strcmp(type, "FAST_CAR") == 0) return PED_FLAG_FAST_CAR;
+ if(strcmp(type, "EXPLOSION") == 0) return PED_FLAG_EXPLOSION;
+ if(strcmp(type, "PROSTITUTE") == 0) return PED_FLAG_PROSTITUTE;
+ if(strcmp(type, "DEADPEDS") == 0) return PED_FLAG_DEADPEDS;
+ return 0;
+}
+
+void
+CPedType::Save(uint8 *buf, uint32 *size)
+{
+ *size = sizeof(CPedType) * NUM_PEDTYPES + SAVE_HEADER_SIZE;
+INITSAVEBUF
+ WriteSaveHeader(buf, 'P','T','P','\0', *size - SAVE_HEADER_SIZE);
+ for(int i = 0; i < NUM_PEDTYPES; i++)
+ WriteSaveBuf(buf, *ms_apPedType[i]);
+VALIDATESAVEBUF(*size)
+}
+
+void
+CPedType::Load(uint8 *buf, uint32 size)
+{
+INITSAVEBUF
+ // original: SkipSaveBuf(buf, SAVE_HEADER_SIZE);
+ CheckSaveHeader(buf, 'P', 'T', 'P', '\0', size - SAVE_HEADER_SIZE);
+
+ for(int i = 0; i < NUM_PEDTYPES; i++)
+ *ms_apPedType[i] = ReadSaveBuf<CPedType>(buf);
+VALIDATESAVEBUF(size)
+}
+
+void
+CPedStats::Initialise(void)
+{
+ int i;
+
+ debug("Initialising CPedStats...\n");
+ for(i = 0; i < NUM_PEDSTATS; i++){
+ ms_apPedStats[i] = new CPedStats;
+ ms_apPedStats[i]->m_type = PEDSTAT_PLAYER;
+ ms_apPedStats[i]->m_name[8] = 'R'; // WHAT?
+ ms_apPedStats[i]->m_fleeDistance = 20.0f;
+ ms_apPedStats[i]->m_headingChangeRate = 15.0f;
+ ms_apPedStats[i]->m_fear = 50;
+ ms_apPedStats[i]->m_temper = 50;
+ ms_apPedStats[i]->m_lawfulness = 50;
+ ms_apPedStats[i]->m_sexiness = 50;
+ ms_apPedStats[i]->m_attackStrength = 1.0f;
+ ms_apPedStats[i]->m_defendWeakness = 1.0f;
+ ms_apPedStats[i]->m_flags = 0;
+ }
+ debug("Loading pedstats data...\n");
+ CPedStats::LoadPedStats();
+ debug("CPedStats ready\n");
+}
+
+void
+CPedStats::Shutdown(void)
+{
+ int i;
+ debug("Shutting down CPedStats...\n");
+ for(i = 0; i < NUM_PEDSTATS; i++)
+ delete ms_apPedStats[i];
+ debug("CPedStats shut down\n");
+}
+
+void
+CPedStats::LoadPedStats(void)
+{
+ char *buf;
+ char line[256];
+ char name[32];
+ ssize_t bp, buflen;
+ int lp, linelen;
+ int type;
+ float fleeDist, headingChangeRate, attackStrength, defendWeakness;
+ int fear, temper, lawfullness, sexiness, flags;
+
+ type = 0;
+ buf = new char[16 * 1024];
+
+ CFileMgr::SetDir("DATA");
+ buflen = CFileMgr::LoadFile("PEDSTATS.DAT", (uint8*)buf, 16 * 1024, "r");
+ CFileMgr::SetDir("");
+
+ for(bp = 0; bp < buflen; ){
+ // read file line by line
+ for(linelen = 0; buf[bp] != '\n' && bp < buflen; bp++){
+ if(buf[bp] == '\r' || buf[bp] == ',' || buf[bp] == '\t')
+ line[linelen++] = ' ';
+ else
+ line[linelen++] = buf[bp];
+ }
+ bp++;
+ line[linelen] = '\0';
+
+ // skip white space
+ for(lp = 0; line[lp] <= ' '; lp++);
+
+ if(lp >= linelen || // FIX: game uses == here, but this is safer if we have empty lines
+ line[lp] == '#')
+ continue;
+
+ sscanf(&line[lp], "%s %f %f %d %d %d %d %f %f %d",
+ name,
+ &fleeDist,
+ &headingChangeRate,
+ &fear,
+ &temper,
+ &lawfullness,
+ &sexiness,
+ &attackStrength,
+ &defendWeakness,
+ &flags);
+ ms_apPedStats[type]->m_type = (ePedStats)type;
+ strncpy(ms_apPedStats[type]->m_name, name, 24); // FIX: game uses strcpy
+ ms_apPedStats[type]->m_fleeDistance = fleeDist;
+ ms_apPedStats[type]->m_headingChangeRate = headingChangeRate;
+ ms_apPedStats[type]->m_fear = fear;
+ ms_apPedStats[type]->m_temper = temper;
+ ms_apPedStats[type]->m_lawfulness = lawfullness;
+ ms_apPedStats[type]->m_sexiness = sexiness;
+ ms_apPedStats[type]->m_attackStrength = attackStrength;
+ ms_apPedStats[type]->m_defendWeakness = defendWeakness;
+ ms_apPedStats[type]->m_flags = flags;
+ type++;
+ }
+
+ delete[] buf;
+}
+
+ePedStats
+CPedStats::GetPedStatType(char *name)
+{
+ for(uint16 type = 0; type < NUM_PEDSTATS; type++)
+ if(!CGeneral::faststrcmp(ms_apPedStats[type]->m_name, name))
+ return (ePedStats) type;
+
+ return NUM_PEDSTATS;
+}