summaryrefslogtreecommitdiffstats
path: root/src/peds/PedStats.cpp
blob: 147f11e2615675ea4ebb019b7542e5363d95b8ba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "common.h"
#include "patcher.h"
#include "General.h"
#include "FileMgr.h"
#include "PedStats.h"

//CPedStats *(&CPedStats::ms_apPedStats)[NUM_PEDSTATS] = *(CPedStats *(*)[NUM_PEDSTATS]) *(uintptr*)0x9404D4;
CPedStats *CPedStats::ms_apPedStats[NUM_PEDSTATS];

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];
	int 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;
}

STARTPATCHES
	InjectHook(0x4EF460, &CPedStats::Initialise, PATCH_JUMP);
	InjectHook(0x4EF540, &CPedStats::Shutdown, PATCH_JUMP);
	InjectHook(0x4EF580, &CPedStats::LoadPedStats, PATCH_JUMP);
	InjectHook(0x4EF780, &CPedStats::GetPedStatType, PATCH_JUMP);
ENDPATCHES