251
|
1 #include <string.h>
|
|
2 #include <stdlib.h>
|
|
3
|
|
4 #include "Allocator.h"
|
|
5 #include "texts.h"
|
|
6 #include "Party.h"
|
|
7 #include "LOD.h"
|
|
8 #include "Autonotes.h"
|
|
9 #include "Awards.h"
|
|
10 #include "mm7_data.h"
|
|
11 #include "MM7.h"
|
|
12 #include "NPC.h"
|
|
13
|
|
14
|
|
15 void InitializeAwards();
|
|
16 void InitializeScrolls();
|
|
17 void InitializeMerchants();
|
|
18 void InitializeTransitions();
|
|
19 void InitializeAutonotes();
|
|
20 void InitializeQuests();
|
307
|
21 bool CheckPortretAgainstSex(int portret_num, int sex);
|
251
|
22
|
|
23 //----- (00476977) --------------------------------------------------------
|
291
|
24 void NPCStats::InitializeNPCText()
|
251
|
25 {
|
|
26 int i;
|
|
27 char* test_string;
|
|
28 unsigned char c;
|
|
29 bool break_loop;
|
|
30 unsigned int temp_str_len;
|
|
31 char* tmp_pos;
|
|
32 int decode_step;
|
|
33
|
|
34 if (pNPCTextTXT_Raw)
|
|
35 pAllocator->FreeChunk(pNPCTextTXT_Raw);
|
|
36 pNPCTextTXT_Raw =NULL;
|
|
37 pNPCTextTXT_Raw = (char *)pEvents_LOD->LoadRaw("npctext.txt", 0);
|
|
38 strtok(pNPCTextTXT_Raw, "\r");
|
|
39
|
|
40 for (i=0; i<789; ++i)
|
|
41 {
|
|
42 test_string = strtok(NULL, "\r") + 1;
|
|
43 break_loop = false;
|
|
44 decode_step=0;
|
|
45 do
|
|
46 {
|
|
47 c = *(unsigned char*)test_string;
|
|
48 temp_str_len = 0;
|
|
49 while((c!='\t')&&(c>0))
|
|
50 {
|
|
51 ++temp_str_len;
|
|
52 c=test_string[temp_str_len];
|
|
53 }
|
|
54 tmp_pos=test_string+temp_str_len;
|
|
55 if (*tmp_pos == 0)
|
|
56 break_loop = true;
|
|
57 *tmp_pos = 0;
|
|
58 if (temp_str_len)
|
|
59 {
|
|
60 if ( decode_step == 1)
|
|
61 pNPCTopics[i].pText =RemoveQuotes(test_string);
|
|
62 }
|
|
63 else
|
|
64 {
|
|
65 break_loop = true;
|
|
66 }
|
|
67 ++decode_step;
|
|
68 test_string=tmp_pos+1;
|
|
69 } while ((decode_step<2)&&!break_loop);
|
|
70 }
|
|
71
|
|
72 if (pNPCTopicTXT_Raw)
|
|
73 pAllocator->FreeChunk(pNPCTopicTXT_Raw);
|
|
74 pNPCTopicTXT_Raw =NULL;
|
|
75 pNPCTopicTXT_Raw = (char *)pEvents_LOD->LoadRaw("npctopic.txt", 0);
|
|
76 strtok(pNPCTopicTXT_Raw, "\r");
|
|
77
|
|
78 for (i=0; i<579; ++i)
|
|
79 {
|
|
80 test_string = strtok(NULL, "\r") + 1;
|
|
81 break_loop = false;
|
|
82 decode_step=0;
|
|
83 do
|
|
84 {
|
|
85 c = *(unsigned char*)test_string;
|
|
86 temp_str_len = 0;
|
|
87 while((c!='\t')&&(c>0))
|
|
88 {
|
|
89 ++temp_str_len;
|
|
90 c=test_string[temp_str_len];
|
|
91 }
|
|
92 tmp_pos=test_string+temp_str_len;
|
|
93 if (*tmp_pos == 0)
|
|
94 break_loop = true;
|
|
95 *tmp_pos = 0;
|
|
96 if (temp_str_len)
|
|
97 {
|
|
98 if ( decode_step == 1)
|
|
99 pNPCTopics[i].pTopic = RemoveQuotes(test_string);
|
|
100 }
|
|
101 else
|
|
102 {
|
|
103 break_loop = true;
|
|
104 }
|
|
105 ++decode_step;
|
|
106 test_string=tmp_pos+1;
|
|
107 } while ((decode_step<2)&&!break_loop);
|
|
108 }
|
|
109
|
|
110 if (pNPCDistTXT_Raw)
|
|
111 pAllocator->FreeChunk(pNPCDistTXT_Raw);
|
|
112 pNPCDistTXT_Raw = NULL;
|
|
113 pNPCDistTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcdist.txt", 0);
|
|
114 strtok(pNPCDistTXT_Raw, "\r");
|
|
115 strtok(NULL, "\r");
|
|
116
|
|
117 for (i=1; i<59; ++i)
|
|
118 {
|
|
119 test_string = strtok(NULL, "\r") + 1;
|
|
120 break_loop = false;
|
|
121 decode_step=0;
|
|
122 do
|
|
123 {
|
|
124 c = *(unsigned char*)test_string;
|
|
125 temp_str_len = 0;
|
|
126 while((c!='\t')&&(c>0))
|
|
127 {
|
|
128 ++temp_str_len;
|
|
129 c=test_string[temp_str_len];
|
|
130 }
|
|
131 tmp_pos=test_string+temp_str_len;
|
|
132 if (*tmp_pos == 0)
|
|
133 break_loop = true;
|
|
134 *tmp_pos = 0;
|
|
135 if (temp_str_len)
|
|
136 {
|
|
137 if ((decode_step>0)&&(decode_step<77))
|
|
138 {
|
291
|
139 pProfessionChance[decode_step].professionChancePerArea[i]=atoi(test_string);
|
251
|
140 }
|
|
141 else if (decode_step==0)
|
|
142 {
|
291
|
143 pProfessionChance[0].professionChancePerArea[i]=10;
|
251
|
144 }
|
|
145 }
|
|
146 else
|
|
147 {
|
|
148 break_loop = true;
|
|
149 }
|
|
150 ++decode_step;
|
|
151 test_string=tmp_pos+1;
|
|
152 } while ((decode_step<78)&&!break_loop);
|
|
153 }
|
|
154
|
|
155 for (i=0; i<78; ++i)
|
|
156 {
|
291
|
157 pProfessionChance[i].uTotalprofChance=0;
|
251
|
158 for (int ii=1; ii<59; ++ii)
|
|
159 {
|
291
|
160 pProfessionChance[i].uTotalprofChance+=pProfessionChance[i].professionChancePerArea[ii];
|
251
|
161 }
|
293
|
162 pProfessionChance[i].professionChancePerArea[0]=0;
|
|
163 pProfessionChance[i].professionChancePerArea[59]=0;
|
251
|
164 }
|
|
165
|
|
166 if (pNPCDistTXT_Raw)
|
|
167 {
|
|
168 pAllocator->FreeChunk(pNPCDistTXT_Raw);
|
|
169 pNPCDistTXT_Raw = NULL;
|
|
170 }
|
|
171 }
|
|
172
|
|
173 //----- (00476C60) --------------------------------------------------------
|
|
174 void NPCStats::_476C60()
|
|
175 {
|
|
176 for (unsigned int i = 1; i < uNumNewNPCs; ++i)
|
291
|
177 pNewNPCData[i].pName = pNPCUnicNames[i - 1];
|
251
|
178
|
|
179 if (pParty->pHirelings[0].pName)
|
|
180 pParty->pHirelings[0].pName = pParty->pHireling1Name;
|
|
181 if (pParty->pHirelings[1].pName)
|
|
182 pParty->pHirelings[1].pName = pParty->pHireling2Name;
|
|
183 }
|
|
184
|
|
185 //----- (00476CB5) --------------------------------------------------------
|
291
|
186 void NPCStats::InitializeNPCData()
|
251
|
187 {
|
291
|
188 int i;
|
|
189 char* test_string;
|
|
190 unsigned char c;
|
|
191 bool break_loop;
|
|
192 unsigned int temp_str_len;
|
|
193 char* tmp_pos;
|
|
194 int decode_step;
|
|
195
|
|
196 pNPCDataTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcdata.txt", 0);
|
|
197 strtok(pNPCDataTXT_Raw, "\r");
|
|
198 strtok(NULL, "\r");
|
251
|
199
|
291
|
200 for (i=0; i<500; ++i)
|
251
|
201 {
|
291
|
202 test_string = strtok(NULL, "\r") + 1;
|
|
203 break_loop = false;
|
|
204 decode_step=0;
|
|
205 do
|
251
|
206 {
|
291
|
207 c = *(unsigned char*)test_string;
|
|
208 temp_str_len = 0;
|
|
209 while((c!='\t')&&(c>0))
|
251
|
210 {
|
291
|
211 ++temp_str_len;
|
|
212 c=test_string[temp_str_len];
|
|
213 }
|
|
214 tmp_pos=test_string+temp_str_len;
|
|
215 if (*tmp_pos == 0)
|
|
216 break_loop = true;
|
|
217 *tmp_pos = 0;
|
|
218 if (temp_str_len)
|
|
219 { //i+1
|
|
220 switch (decode_step)
|
251
|
221 {
|
291
|
222 case 1:
|
|
223 pNPCUnicNames[i] = RemoveQuotes(test_string);
|
|
224 pNPCData[i+1].pName=pNPCUnicNames[i];
|
251
|
225 break;
|
291
|
226 case 2:
|
|
227 pNPCData[i+1].uPortraitID = atoi(test_string);
|
251
|
228 break;
|
|
229 case 6:
|
291
|
230 pNPCData[i+1].Location2D = atoi(test_string);
|
251
|
231 break;
|
|
232 case 7:
|
291
|
233 pNPCData[i+1].uProfession = atoi(test_string);
|
251
|
234 break;
|
|
235 case 8:
|
291
|
236 pNPCData[i+1].greet = atoi(test_string);
|
251
|
237 break;
|
|
238 case 9:
|
291
|
239 pNPCData[i+1].joins = (*test_string == 'y')?1:0;
|
251
|
240 break;
|
|
241 case 10:
|
291
|
242 pNPCData[i+1].evt_A = atoi(test_string);
|
251
|
243 break;
|
|
244 case 11:
|
291
|
245 pNPCData[i+1].evt_B = atoi(test_string);
|
251
|
246 break;
|
|
247 case 12:
|
291
|
248 pNPCData[i+1].evt_C = atoi(test_string);
|
251
|
249 break;
|
|
250 case 13:
|
291
|
251 pNPCData[i+1].evt_D = atoi(test_string);
|
251
|
252 break;
|
|
253 case 14:
|
291
|
254 pNPCData[i+1].evt_E = atoi(test_string);
|
251
|
255 break;
|
291
|
256 case 15:
|
|
257 pNPCData[i+1].evt_F = atoi(test_string);
|
251
|
258 break;
|
|
259 }
|
|
260 }
|
291
|
261 ++decode_step;
|
|
262 test_string=tmp_pos+1;
|
|
263 } while ((decode_step<16)&&!break_loop);
|
251
|
264 }
|
291
|
265 uNumNewNPCs = 501;
|
|
266 pNPCGreetTXT_Raw = (char*)pEvents_LOD->LoadRaw("npcgreet.txt", 0);
|
|
267 strtok(pNPCGreetTXT_Raw, "\r");
|
|
268 for (i=0; i<205; ++i)
|
|
269 {
|
|
270 test_string = strtok(NULL, "\r") + 1;
|
|
271 break_loop = false;
|
|
272 decode_step=0;
|
|
273 do
|
251
|
274 {
|
291
|
275 c = *(unsigned char*)test_string;
|
|
276 temp_str_len = 0;
|
|
277 while((c!='\t')&&(c>0))
|
251
|
278 {
|
291
|
279 ++temp_str_len;
|
|
280 c=test_string[temp_str_len];
|
|
281 }
|
|
282 tmp_pos=test_string+temp_str_len;
|
|
283 if (*tmp_pos == 0)
|
|
284 break_loop = true;
|
|
285 *tmp_pos = 0;
|
|
286 if (temp_str_len)
|
|
287 { //i+1
|
|
288 switch (decode_step)
|
251
|
289 {
|
291
|
290 case 1:
|
|
291 pNPCGreetings[i].pGreeting1 = RemoveQuotes(test_string);
|
|
292 break;
|
|
293 case 2:
|
|
294 pNPCGreetings[i].pGreeting2 = RemoveQuotes(test_string);
|
|
295 break;
|
251
|
296 }
|
|
297 }
|
291
|
298 ++decode_step;
|
|
299 test_string=tmp_pos+1;
|
|
300 } while ((decode_step<3)&&!break_loop);
|
|
301 }
|
|
302
|
|
303 pNCPGroupTXT_Raw = (char*)pEvents_LOD->LoadRaw("npcgroup.txt", 0);
|
|
304 strtok(pNCPGroupTXT_Raw, "\r");
|
|
305
|
|
306 for (i=0; i<51; ++i)
|
|
307 {
|
|
308 test_string = strtok(NULL, "\r") + 1;
|
|
309 break_loop = false;
|
|
310 decode_step=0;
|
|
311 do
|
|
312 {
|
|
313 c = *(unsigned char*)test_string;
|
|
314 temp_str_len = 0;
|
|
315 while((c!='\t')&&(c>0))
|
|
316 {
|
|
317 ++temp_str_len;
|
|
318 c=test_string[temp_str_len];
|
|
319 }
|
|
320 tmp_pos=test_string+temp_str_len;
|
|
321 if (*tmp_pos == 0)
|
|
322 break_loop = true;
|
|
323 *tmp_pos = 0;
|
|
324 if (temp_str_len)
|
|
325 { //i+1
|
|
326 if (decode_step==1)
|
251
|
327 {
|
291
|
328 pGroups[i] = atoi(test_string);
|
251
|
329 }
|
291
|
330 }
|
|
331 ++decode_step;
|
|
332 test_string=tmp_pos+1;
|
|
333 } while ((decode_step<2)&&!break_loop);
|
|
334 }
|
|
335
|
|
336 pNPCNewsTXT_Raw = (char*)pEvents_LOD->LoadRaw("npcnews.txt", 0);
|
|
337 strtok(pNPCNewsTXT_Raw, "\r");
|
|
338
|
|
339
|
|
340 for (i=0; i<51; ++i)
|
|
341 {
|
|
342 test_string = strtok(NULL, "\r") + 1;
|
|
343 break_loop = false;
|
|
344 decode_step=0;
|
|
345 do
|
|
346 {
|
|
347 c = *(unsigned char*)test_string;
|
|
348 temp_str_len = 0;
|
|
349 while((c!='\t')&&(c>0))
|
|
350 {
|
|
351 ++temp_str_len;
|
|
352 c=test_string[temp_str_len];
|
|
353 }
|
|
354 tmp_pos=test_string+temp_str_len;
|
|
355 if (*tmp_pos == 0)
|
|
356 break_loop = true;
|
|
357 *tmp_pos = 0;
|
|
358 if (temp_str_len)
|
|
359 { //i+1
|
|
360 if (decode_step==1)
|
|
361 pCatchPhrases[i] = RemoveQuotes(test_string);
|
|
362 }
|
|
363 ++decode_step;
|
|
364 test_string=tmp_pos+1;
|
|
365 } while ((decode_step<2)&&!break_loop);
|
|
366 }
|
251
|
367 }
|
|
368
|
|
369 //----- (0047702F) --------------------------------------------------------
|
|
370 void NPCStats::Initialize()
|
291
|
371 {
|
|
372 int i;
|
|
373 char* test_string;
|
|
374 unsigned char c;
|
|
375 bool break_loop;
|
|
376 unsigned int temp_str_len;
|
|
377 char* tmp_pos;
|
|
378 int decode_step;
|
251
|
379
|
291
|
380 InitializeNPCData();
|
|
381 InitializeNPCText();
|
|
382 InitializeQuests();
|
|
383 InitializeAutonotes();
|
|
384 InitializeAwards();
|
|
385 InitializeTransitions();
|
|
386 InitializeMerchants();
|
|
387 InitializeScrolls();
|
251
|
388
|
291
|
389 pNPCNamesTXT_Raw = NULL;
|
|
390 pNPCNamesTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcnames.txt", 0);
|
|
391 strtok(pNPCNamesTXT_Raw, "\r");
|
|
392
|
|
393 uNewlNPCBufPos = 0;
|
|
394
|
|
395 for (i=0; i<540; ++i)
|
251
|
396 {
|
291
|
397 test_string = strtok(NULL, "\r") + 1;
|
|
398 break_loop = false;
|
|
399 decode_step=0;
|
|
400 do
|
251
|
401 {
|
291
|
402 c = *(unsigned char*)test_string;
|
|
403 temp_str_len = 0;
|
|
404 if (c=='\t')
|
251
|
405 {
|
291
|
406 if ( (decode_step == 1)&&(!uNumNPCNames[1]))
|
|
407 uNumNPCNames[1]=i;
|
251
|
408 }
|
|
409 else
|
|
410 {
|
291
|
411 while((c!='\n')&&(c!='\t')&&(c>0))
|
|
412 {
|
|
413 ++temp_str_len;
|
|
414 c=test_string[temp_str_len];
|
|
415 }
|
|
416 tmp_pos=test_string+temp_str_len;
|
|
417 if (*tmp_pos == 0)
|
|
418 break_loop = true;
|
|
419
|
|
420 if (temp_str_len)
|
|
421 {
|
|
422 *tmp_pos = 0;
|
|
423 if ( decode_step == 0)
|
|
424 pNPCNames[i][0] =RemoveQuotes(test_string);
|
|
425 else if ( decode_step == 1)
|
|
426 pNPCNames[i][1] =RemoveQuotes(test_string);
|
|
427 }
|
|
428 else
|
|
429 {
|
|
430 if ( (decode_step == 1)&&(!uNumNPCNames[1]))
|
|
431 uNumNPCNames[1]=i;
|
|
432 }
|
251
|
433 }
|
291
|
434 ++decode_step;
|
|
435 test_string=tmp_pos+1;
|
|
436 } while ((decode_step<2)&&!break_loop);
|
|
437 }
|
|
438 uNumNPCNames[0] = i;
|
|
439
|
|
440 pNPCProfTXT_Raw = NULL;
|
|
441 pNPCProfTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcprof.txt", 0);
|
|
442 strtok(pNPCProfTXT_Raw, "\r");
|
|
443 strtok(NULL, "\r");
|
|
444 strtok(NULL, "\r");
|
|
445 strtok(NULL, "\r");
|
|
446
|
|
447 for (i=1; i<59; ++i)
|
|
448 {
|
|
449 test_string = strtok(NULL, "\r") + 1;
|
|
450 break_loop = false;
|
|
451 decode_step=0;
|
|
452 do
|
251
|
453 {
|
291
|
454 c = *(unsigned char*)test_string;
|
|
455 temp_str_len = 0;
|
|
456 while((c!='\t')&&(c>0))
|
251
|
457 {
|
291
|
458 ++temp_str_len;
|
|
459 c=test_string[temp_str_len];
|
|
460 }
|
|
461 tmp_pos=test_string+temp_str_len;
|
|
462 if (*tmp_pos == 0)
|
|
463 break_loop = true;
|
|
464 *tmp_pos = 0;
|
|
465 if (temp_str_len)
|
|
466 {
|
|
467 switch(decode_step)
|
|
468 {
|
|
469 case 2:
|
|
470 pProfessions[i].uHirePrice = atoi(test_string);
|
|
471 break;
|
|
472 case 3:
|
|
473 pProfessions[i].pActionText = RemoveQuotes(test_string);
|
|
474 break;
|
|
475 case 4:
|
|
476 pProfessions[i].pBenefits= RemoveQuotes(test_string);
|
|
477 break;
|
|
478 case 5:
|
|
479 pProfessions[i].pJoinText = RemoveQuotes(test_string);
|
|
480 break;
|
|
481 case 6:
|
|
482 pProfessions[i].pDismissText = RemoveQuotes(test_string);
|
|
483 }
|
251
|
484 }
|
291
|
485 else
|
|
486 {
|
|
487 if (!decode_step)
|
|
488 break_loop = true;
|
|
489 }
|
|
490 ++decode_step;
|
|
491 test_string=tmp_pos+1;
|
|
492 } while ((decode_step<7)&&!break_loop);
|
251
|
493 }
|
291
|
494 uNumNPCProfessions = 59;
|
251
|
495 }
|
|
496
|
|
497 //----- (00477266) --------------------------------------------------------
|
|
498 void NPCStats::Release()
|
|
499 {
|
291
|
500 pAllocator->FreeChunk(pNPCTopicTXT_Raw);
|
|
501 pNPCTopicTXT_Raw = NULL;
|
|
502 pAllocator->FreeChunk(pNPCTextTXT_Raw);
|
|
503 pNPCTextTXT_Raw = NULL;
|
|
504 pAllocator->FreeChunk(pNPCNewsTXT_Raw);
|
|
505 pNPCNewsTXT_Raw = NULL;
|
|
506 pAllocator->FreeChunk(pNPCProfTXT_Raw);
|
|
507 pNPCProfTXT_Raw = NULL;
|
|
508 pAllocator->FreeChunk(pNPCNamesTXT_Raw);
|
|
509 pNPCNamesTXT_Raw = NULL;
|
|
510 pAllocator->FreeChunk(pNPCDataTXT_Raw);
|
|
511 pNPCDataTXT_Raw = NULL;
|
|
512 pAllocator->FreeChunk(pNPCDistTXT_Raw);
|
|
513 pNPCDistTXT_Raw = NULL;
|
|
514 pAllocator->FreeChunk(pNPCGreetTXT_Raw);
|
|
515 pNPCGreetTXT_Raw = NULL;
|
|
516 pAllocator->FreeChunk(pNCPGroupTXT_Raw);
|
|
517 pNCPGroupTXT_Raw = NULL;
|
251
|
518 }
|
|
519
|
|
520 //----- (0047730C) --------------------------------------------------------
|
307
|
521 bool CheckPortretAgainstSex(int a1, int)
|
251
|
522 {
|
291
|
523 return true;
|
251
|
524 }
|
|
525 // 47730C: using guessed type int __stdcall const_1(int);
|
|
526
|
|
527 //----- (0047732C) --------------------------------------------------------
|
291
|
528 void NPCStats::InitializeAdditionalNPCs(NPCData *pNPCDataBuff, int npc_uid, int uLocation2D, int uMapId)
|
251
|
529 {
|
292
|
530 int rep_gen;
|
291
|
531 int uNPCSex; // esi@1
|
|
532 int uGeneratedPortret; // ecx@23
|
|
533 int test_prof_summ; // ecx@37
|
|
534 int gen_profession; // eax@37
|
|
535 int max_prof_cap; // edx@37
|
251
|
536 signed int result; // eax@39
|
291
|
537 int uRace; // [sp+Ch] [bp-Ch]@1
|
|
538 bool break_gen; // [sp+10h] [bp-8h]@1
|
|
539 signed int gen_attempts; // [sp+14h] [bp-4h]@1
|
|
540 int uPortretMin; // [sp+24h] [bp+Ch]@1
|
|
541 int uPortretMax;
|
|
542
|
|
543 static const unsigned __int8 NPCSexGenTable[86] ={
|
293
|
544 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
545 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
|
546 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0,
|
|
547 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
548 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
|
|
549 static const unsigned __int8 NPCRaceGenTable[86] ={
|
|
550 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 1,
|
|
551 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
552 0, 0, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
|
|
553 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
554 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0};
|
251
|
555
|
307
|
556 unsigned __int8 seed = (unsigned __int8)((double)(npc_uid - 1)/3.0);
|
291
|
557 uNPCSex = NPCSexGenTable[seed];
|
|
558 uRace = NPCRaceGenTable[seed];
|
|
559 pNPCDataBuff->uSex = uNPCSex;
|
|
560 pNPCDataBuff->pName = pNPCNames[rand() % uNumNPCNames[uNPCSex]][uNPCSex];
|
|
561
|
|
562 gen_attempts = 0;
|
|
563 break_gen = false;
|
251
|
564
|
291
|
565 do
|
251
|
566 {
|
293
|
567 switch ( uRace )
|
|
568 {
|
|
569 case 0:
|
|
570 if ( uNPCSex == 0 )
|
291
|
571 {
|
|
572 uPortretMin = 2;
|
|
573 uPortretMax = 100;
|
251
|
574 }
|
|
575 else
|
|
576 {
|
293
|
577 uPortretMin = 201;
|
|
578 uPortretMax = 250;
|
|
579 }
|
|
580 case 1:
|
|
581 if ( uNPCSex == 0 )
|
|
582 {
|
|
583 uPortretMin = 400;
|
|
584 uPortretMax = 430;
|
|
585 }
|
|
586 else
|
|
587 {
|
|
588 uPortretMin = 460;
|
|
589 uPortretMax = 490;
|
|
590 }
|
|
591 break;
|
|
592 case 2:
|
|
593 if ( uNPCSex == 0 )
|
|
594 {
|
|
595 uPortretMin = 500;
|
|
596 uPortretMax = 520;
|
|
597 }
|
|
598 else
|
|
599 {
|
|
600 uPortretMin = 530;
|
|
601 uPortretMax = 550;
|
|
602 }
|
|
603 break;
|
|
604 case 3:
|
|
605 if ( uNPCSex == 0 )
|
|
606 {
|
|
607 uPortretMin = 300;
|
|
608 uPortretMax = 330;
|
|
609 }
|
|
610 else
|
|
611 {
|
|
612 uPortretMin = 360;
|
|
613 uPortretMax = 387;
|
251
|
614 }
|
291
|
615
|
293
|
616 break;
|
|
617 }
|
|
618
|
291
|
619 uGeneratedPortret = uPortretMin + rand() % (uPortretMax - uPortretMin + 1);
|
307
|
620 if ( CheckPortretAgainstSex(uGeneratedPortret, uNPCSex))
|
291
|
621 break_gen = true;
|
|
622 ++gen_attempts;
|
|
623 if ( gen_attempts >= 4 )
|
251
|
624 {
|
291
|
625 uGeneratedPortret = uPortretMin;
|
|
626 break_gen = true;
|
251
|
627 }
|
|
628 }
|
291
|
629 while(!break_gen);
|
251
|
630
|
293
|
631 pNPCDataBuff->uPortraitID = uGeneratedPortret;
|
|
632 pNPCDataBuff->uFlags = 0;
|
|
633 pNPCDataBuff->fame = 0;
|
|
634 //generate reputation
|
|
635 rep_gen = rand() % 100 + 1;
|
251
|
636
|
293
|
637 if ( rep_gen >= 60 )
|
251
|
638 {
|
293
|
639 if ( rep_gen >= 90 )
|
251
|
640 {
|
293
|
641 if ( rep_gen >= 95 )
|
|
642 {
|
|
643 if ( rep_gen >= 98 )
|
|
644 pNPCDataBuff->rep = -600;
|
|
645 else
|
|
646 pNPCDataBuff->rep = 400;
|
|
647 }
|
251
|
648 else
|
293
|
649 pNPCDataBuff->rep = -300;
|
251
|
650 }
|
|
651 else
|
293
|
652 pNPCDataBuff->rep = 200;
|
251
|
653 }
|
|
654 else
|
293
|
655 pNPCDataBuff->rep = 0;
|
291
|
656
|
293
|
657 max_prof_cap = rand() % pProfessionChance[uMapId].uTotalprofChance+1;
|
|
658 test_prof_summ = 0;
|
|
659 gen_profession = 0;
|
251
|
660
|
293
|
661 if ( max_prof_cap > 0 )
|
|
662 {
|
|
663 do
|
|
664 test_prof_summ += pProfessionChance[uMapId].professionChancePerArea[gen_profession++];
|
|
665 while ( test_prof_summ < max_prof_cap );
|
|
666 }
|
|
667 pNPCDataBuff->uProfession = gen_profession - 1;
|
|
668 pNPCDataBuff->Location2D = uLocation2D;
|
|
669 pNPCDataBuff->field_24 = 1;
|
|
670 pNPCDataBuff->joins = 1;
|
251
|
671 }
|
|
672
|
|
673
|
257
|
674 //----- (00476387) --------------------------------------------------------
|
|
675 bool PartyHasDragon()
|
|
676 {
|
|
677 return pNPCStats->pNewNPCData[57].Hired();
|
|
678 }
|
251
|
679
|
|
680 //----- (00476395) --------------------------------------------------------
|
|
681 //0x26 Wizard eye at skill level 2
|
|
682 bool __thiscall CheckHiredNPCSpeciality(unsigned int uProfession)
|
|
683 {
|
|
684 bool result; // eax@2
|
|
685 signed int v2; // esi@3
|
|
686 char *v3; // eax@4
|
|
687
|
|
688 if ( bNoNPCHiring == 1 )
|
|
689 return 0;
|
|
690 v2 = 0;
|
|
691 if ( (signed int)pNPCStats->uNumNewNPCs <= 0 )
|
|
692 {
|
|
693 LABEL_8:
|
|
694 result = 0;
|
|
695 if ( pParty->pHirelings[0].uProfession != uProfession )
|
|
696 {
|
|
697 LOBYTE(result) = pParty->pHirelings[1].uProfession == uProfession;
|
|
698 return result;
|
|
699 }
|
|
700 }
|
|
701 else
|
|
702 {
|
|
703 v3 = (char *)&pNPCStats->pNewNPCData[0].uFlags;
|
|
704 while ( *((int *)v3 + 4) != uProfession || !(*v3 & 0x80) )
|
|
705 {
|
|
706 ++v2;
|
|
707 v3 += 76;
|
|
708 if ( v2 >= (signed int)pNPCStats->uNumNewNPCs )
|
|
709 goto LABEL_8;
|
|
710 }
|
|
711 result = 0;
|
|
712 }
|
|
713 ++result;
|
|
714 return result;
|
|
715 }
|
|
716 // 6BE3C5: using guessed type char bNoNPCHiring;
|
|
717
|
|
718 //----- (004763E0) --------------------------------------------------------
|
|
719 void InitializeAwards()
|
|
720 {
|
|
721
|
|
722 int i;
|
|
723 char* test_string;
|
|
724 unsigned char c;
|
|
725 bool break_loop;
|
|
726 unsigned int temp_str_len;
|
|
727 char* tmp_pos;
|
|
728 int decode_step;
|
|
729
|
|
730 if ( pAwardsTXT_Raw )
|
|
731 pAllocator->FreeChunk(pAwardsTXT_Raw);
|
|
732 pAwardsTXT_Raw = NULL;
|
|
733 pAwardsTXT_Raw = (char *)pEvents_LOD->LoadRaw("awards.txt", 0);
|
|
734 strtok(pAwardsTXT_Raw, "\r");
|
|
735
|
|
736 for (i=1; i<104; ++i)
|
|
737 {
|
|
738 test_string = strtok(NULL, "\r") + 1;
|
|
739 break_loop = false;
|
|
740 decode_step=0;
|
|
741 do
|
|
742 {
|
|
743 c = *(unsigned char*)test_string;
|
|
744 temp_str_len = 0;
|
|
745 while((c!='\t')&&(c>0))
|
|
746 {
|
|
747 ++temp_str_len;
|
|
748 c=test_string[temp_str_len];
|
|
749 }
|
|
750 tmp_pos=test_string+temp_str_len;
|
|
751 if (*tmp_pos == 0)
|
|
752 break_loop = true;
|
|
753 *tmp_pos = 0;
|
|
754 if (temp_str_len)
|
|
755 {
|
|
756 if (decode_step==1)
|
|
757 pAwards[i].pText=RemoveQuotes(test_string);
|
|
758 else if (decode_step==2)
|
|
759 pAwards[i].uSort=atoi(test_string);
|
|
760 }
|
|
761 else
|
|
762 {
|
|
763 break_loop = true;
|
|
764 }
|
|
765 ++decode_step;
|
|
766 test_string=tmp_pos+1;
|
|
767 } while ((decode_step<3)&&!break_loop);
|
|
768 }
|
|
769
|
|
770 }
|
|
771 // 7241C8: using guessed type int dword_7241C8;
|
|
772
|
|
773 //----- (004764C2) --------------------------------------------------------
|
|
774 void InitializeScrolls()
|
|
775 {
|
|
776
|
|
777 int i;
|
|
778 char* test_string;
|
|
779 unsigned char c;
|
|
780 bool break_loop;
|
|
781 unsigned int temp_str_len;
|
|
782 char* tmp_pos;
|
|
783 int decode_step;
|
|
784
|
|
785 if ( pScrollsTXT_Raw )
|
|
786 pAllocator->FreeChunk(pScrollsTXT_Raw);
|
|
787 pScrollsTXT_Raw = NULL;
|
|
788 pScrollsTXT_Raw = (char *)pEvents_LOD->LoadRaw("scroll.txt", 0);
|
|
789 strtok(pScrollsTXT_Raw, "\r");
|
|
790 for (i=0; i<82; ++i)
|
|
791 {
|
|
792 test_string = strtok(NULL, "\r") + 1;
|
|
793 break_loop = false;
|
|
794 decode_step=0;
|
|
795 do
|
|
796 {
|
|
797 c = *(unsigned char*)test_string;
|
|
798 temp_str_len = 0;
|
|
799 while((c!='\t')&&(c>0))
|
|
800 {
|
|
801 ++temp_str_len;
|
|
802 c=test_string[temp_str_len];
|
|
803 }
|
|
804 tmp_pos=test_string+temp_str_len;
|
|
805 if (*tmp_pos == 0)
|
|
806 break_loop = true;
|
|
807 *tmp_pos = 0;
|
|
808 if (temp_str_len)
|
|
809 {
|
|
810 if ( decode_step == 1)
|
|
811 pScrolls[i]=RemoveQuotes(test_string);
|
|
812 }
|
|
813 else
|
|
814 {
|
|
815 break_loop = true;
|
|
816 }
|
|
817 ++decode_step;
|
|
818 test_string=tmp_pos+1;
|
|
819 } while ((decode_step<2)&&!break_loop);
|
|
820 }
|
|
821 }
|
|
822
|
|
823
|
|
824 //----- (00476590) --------------------------------------------------------
|
|
825 void InitializeMerchants()
|
|
826 {
|
|
827 int i;
|
|
828 char* test_string;
|
|
829 unsigned char c;
|
|
830 bool break_loop;
|
|
831 unsigned int temp_str_len;
|
|
832 char* tmp_pos;
|
|
833 int decode_step;
|
|
834
|
|
835 if ( pMerchantsTXT_Raw )
|
|
836 pAllocator->FreeChunk(pMerchantsTXT_Raw);
|
|
837 pMerchantsTXT_Raw = NULL;
|
|
838 pMerchantsTXT_Raw = (char *)pEvents_LOD->LoadRaw("merchant.txt", 0);
|
|
839 strtok(pMerchantsTXT_Raw, "\r");
|
|
840
|
|
841 for (i=0; i<7; ++i)
|
|
842 {
|
|
843 test_string = strtok(NULL, "\r") + 1;
|
|
844 break_loop = false;
|
|
845 decode_step=0;
|
|
846 do
|
|
847 {
|
|
848 c = *(unsigned char*)test_string;
|
|
849 temp_str_len = 0;
|
|
850 while((c!='\t')&&(c>0))
|
|
851 {
|
|
852 ++temp_str_len;
|
|
853 c=test_string[temp_str_len];
|
|
854 }
|
|
855 tmp_pos=test_string+temp_str_len;
|
|
856 if (*tmp_pos == 0)
|
|
857 break_loop = true;
|
|
858 *tmp_pos = 0;
|
|
859 if (temp_str_len)
|
|
860 {
|
|
861 switch (decode_step)
|
|
862 {
|
|
863 case 1:
|
|
864 pMerchantsBuyPhrases[i]=RemoveQuotes(test_string);
|
|
865 break;
|
|
866 case 2:
|
|
867 pMerchantsSellPhrases[i]=RemoveQuotes(test_string);
|
|
868 break;
|
|
869 case 3:
|
|
870 pMerchantsRepairPhrases[i]=RemoveQuotes(test_string);
|
|
871 break;
|
|
872 case 4:
|
|
873 pMerchantsIdentifyPhrases[i]=RemoveQuotes(test_string);
|
|
874 break;
|
|
875 }
|
|
876 }
|
|
877 else
|
|
878 {
|
|
879 break_loop = true;
|
|
880 }
|
|
881 ++decode_step;
|
|
882 test_string=tmp_pos+1;
|
|
883 } while ((decode_step<5)&&!break_loop);
|
|
884 }
|
|
885
|
|
886 }
|
|
887
|
|
888 //----- (00476682) --------------------------------------------------------
|
|
889 void InitializeTransitions()
|
|
890 {
|
|
891 int i;
|
|
892 char* test_string;
|
|
893 unsigned char c;
|
|
894 bool break_loop;
|
|
895 unsigned int temp_str_len;
|
|
896 char* tmp_pos;
|
|
897 int decode_step;
|
|
898
|
|
899 if ( pTransitionsTXT_Raw )
|
|
900 pAllocator->FreeChunk(pTransitionsTXT_Raw);
|
|
901 pTransitionsTXT_Raw = NULL;
|
|
902 pTransitionsTXT_Raw = (char *)pEvents_LOD->LoadRaw("trans.txt", 0);
|
|
903 strtok(pTransitionsTXT_Raw, "\r");
|
|
904
|
|
905 for (i=0; i<464; ++i)
|
|
906 {
|
|
907 test_string = strtok(NULL, "\r") + 1;
|
|
908 break_loop = false;
|
|
909 decode_step=0;
|
|
910 do
|
|
911 {
|
|
912 c = *(unsigned char*)test_string;
|
|
913 temp_str_len = 0;
|
|
914 while((c!='\t')&&(c>0))
|
|
915 {
|
|
916 ++temp_str_len;
|
|
917 c=test_string[temp_str_len];
|
|
918 }
|
|
919 tmp_pos=test_string+temp_str_len;
|
|
920 if (*tmp_pos == 0)
|
|
921 break_loop = true;
|
|
922 *tmp_pos = 0;
|
|
923 if (temp_str_len)
|
|
924 {
|
|
925 if ( decode_step == 1)
|
|
926 pTransitionStrings[i]=RemoveQuotes(test_string);
|
|
927 }
|
|
928 else
|
|
929 {
|
|
930 break_loop = true;
|
|
931 }
|
|
932 ++decode_step;
|
|
933 test_string=tmp_pos+1;
|
|
934 } while ((decode_step<2)&&!break_loop);
|
|
935 }
|
|
936 }
|
|
937
|
|
938 //----- (00476750) --------------------------------------------------------
|
|
939 void __cdecl InitializeAutonotes()
|
|
940 {
|
|
941 int i;
|
|
942 char* test_string;
|
|
943 unsigned char c;
|
|
944 bool break_loop;
|
|
945 unsigned int temp_str_len;
|
|
946 char* tmp_pos;
|
|
947 int decode_step;
|
|
948
|
|
949 if ( pAutonoteTXT_Raw )
|
|
950 pAllocator->FreeChunk(pAutonoteTXT_Raw);
|
|
951 pAutonoteTXT_Raw = 0;
|
|
952 pAutonoteTXT_Raw = (char *)pEvents_LOD->LoadRaw("autonote.txt", 0);
|
|
953 strtok(pAutonoteTXT_Raw, "\r");
|
|
954
|
|
955 for (i=0; i<195; ++i)
|
|
956 {
|
|
957 test_string = strtok(NULL, "\r") + 1;
|
|
958 break_loop = false;
|
|
959 decode_step=0;
|
|
960 do
|
|
961 {
|
|
962 c = *(unsigned char*)test_string;
|
|
963 temp_str_len = 0;
|
|
964 while((c!='\t')&&(c>0))
|
|
965 {
|
|
966 ++temp_str_len;
|
|
967 c=test_string[temp_str_len];
|
|
968 }
|
|
969 tmp_pos=test_string+temp_str_len;
|
|
970 if (*tmp_pos == 0)
|
|
971 break_loop = true;
|
|
972 *tmp_pos = 0;
|
|
973 if (temp_str_len)
|
|
974 {
|
|
975 switch (decode_step)
|
|
976 {
|
|
977 case 1:
|
|
978 pAutonoteTxt[i].pText=RemoveQuotes(test_string);
|
|
979 break;
|
|
980 case 2:
|
|
981 {
|
|
982 if ( !_strcmpi(test_string, "potion"))
|
|
983 {
|
|
984 pAutonoteTxt[i].eType = AUTONOTE_POTION_RECEPIE;
|
|
985 break;
|
|
986 }
|
|
987 if ( !_strcmpi(test_string, "stat") )
|
|
988 {
|
|
989 pAutonoteTxt[i].eType = AUTONOTE_STAT_HINT;
|
|
990 break;
|
|
991 }
|
|
992 if ( !_strcmpi(test_string, "seer") )
|
|
993 {
|
|
994 pAutonoteTxt[i].eType = AUTONOTE_SEER;
|
|
995 break;
|
|
996 }
|
|
997 if ( !_strcmpi(test_string, "obelisk") )
|
|
998 {
|
|
999 pAutonoteTxt[i].eType = AUTONOTE_OBELISK;
|
|
1000 break;
|
|
1001 }
|
|
1002 if ( !_strcmpi(test_string, "teacher") )
|
|
1003 {
|
|
1004 pAutonoteTxt[i].eType = AUTONOTE_TEACHER;
|
|
1005 break;
|
|
1006 }
|
|
1007 pAutonoteTxt[i].eType =AUTONOTE_MISC;
|
|
1008 break;
|
|
1009 }
|
|
1010 }
|
|
1011 }
|
|
1012 else
|
|
1013 {
|
|
1014 break_loop = true;
|
|
1015 }
|
|
1016 ++decode_step;
|
|
1017 test_string=tmp_pos+1;
|
|
1018 } while ((decode_step<3)&&!break_loop);
|
|
1019 }
|
|
1020 }
|
|
1021
|
|
1022
|
|
1023 //----- (004768A9) --------------------------------------------------------
|
|
1024 void __cdecl InitializeQuests()
|
|
1025 {
|
|
1026 int i;
|
|
1027 char* test_string;
|
|
1028 unsigned char c;
|
|
1029 bool break_loop;
|
|
1030 unsigned int temp_str_len;
|
|
1031 char* tmp_pos;
|
|
1032 int decode_step;
|
|
1033
|
|
1034 if ( pQuestsTXT_Raw )
|
|
1035 pAllocator->FreeChunk(pQuestsTXT_Raw);
|
|
1036 pQuestsTXT_Raw = NULL;
|
|
1037 pQuestsTXT_Raw = (char *)pEvents_LOD->LoadRaw("quests.txt", 0);
|
|
1038 strtok(pQuestsTXT_Raw, "\r");
|
|
1039
|
|
1040 for (i=0; i<512; ++i)
|
|
1041 {
|
|
1042 test_string = strtok(NULL, "\r") + 1;
|
|
1043 break_loop = false;
|
|
1044 decode_step=0;
|
|
1045 do
|
|
1046 {
|
|
1047 c = *(unsigned char*)test_string;
|
|
1048 temp_str_len = 0;
|
|
1049 while((c!='\t')&&(c>0))
|
|
1050 {
|
|
1051 ++temp_str_len;
|
|
1052 c=test_string[temp_str_len];
|
|
1053 }
|
|
1054 tmp_pos=test_string+temp_str_len;
|
|
1055 if (*tmp_pos == 0)
|
|
1056 break_loop = true;
|
|
1057 *tmp_pos = 0;
|
|
1058 if (temp_str_len)
|
|
1059 {
|
|
1060 if ( decode_step == 1)
|
|
1061 pQuestTable[i] =RemoveQuotes(test_string);
|
|
1062 }
|
|
1063 else
|
|
1064 {
|
|
1065 break_loop = true;
|
|
1066 }
|
|
1067 ++decode_step;
|
|
1068 test_string=tmp_pos+1;
|
|
1069 } while ((decode_step<2)&&!break_loop);
|
|
1070 }
|
|
1071 }
|
|
1072
|