1 /************************************************************************
2 * *
3 * FreeSynd - a remake of the classic Bullfrog game "Syndicate". *
4 * *
5 * Copyright (C) 2005 Stuart Binge <skbinge@gmail.com> *
6 * Copyright (C) 2005 Joost Peters <joostp@users.sourceforge.net> *
7 * Copyright (C) 2006 Trent Waddington <qg@biodome.org> *
8 * Copyright (C) 2006 Tarjei Knapstad <tarjei.knapstad@gmail.com> *
9 * Copyright (C) 2010 Bohdan Stelmakh <chamel@users.sourceforge.net> *
10 * *
11 * This program is free software; you can redistribute it and / or *
12 * modify it under the terms of the GNU General Public License as *
13 * published by the Free Software Foundation; either version 2 of the *
14 * License, or (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19 * General Public License for more details. *
20 * *
21 * You can view the GNU General Public License, online, at the GNU *
22 * project's web site; see <http://www.gnu.org/licenses/gpl.html>. *
23 * The full text of the license is also included in the file COPYING. *
24 * *
25 ************************************************************************/
26
27 #include <stdio.h>
28 #include <assert.h>
29
30 #include "utils/log.h"
31 #include "pedmanager.h"
32 #include "core/gamecontroller.h"
33
PedManager()34 PedManager::PedManager()
35 {
36 }
37
initAnimation(Ped * pedanim,unsigned short baseAnim)38 void PedManager::initAnimation(Ped *pedanim, unsigned short baseAnim)
39 {
40 if (baseAnim == 1) {
41 pedanim->setStandAnim(Weapon::Unarmed_Anim, 0 + baseAnim);
42 pedanim->setWalkAnim(Weapon::Unarmed_Anim, 8 + baseAnim);
43 pedanim->setStandAnim(Weapon::EnergyShield_Anim, 16 + baseAnim);
44 pedanim->setStandAnim(Weapon::Pistol_Anim, 24 + baseAnim);
45 pedanim->setStandAnim(Weapon::Uzi_Anim, 24 + baseAnim);
46 pedanim->setStandAnim(Weapon::Shotgun_Anim, 24 + baseAnim);
47 pedanim->setStandAnim(Weapon::Gauss_Anim, 24 + baseAnim);
48 pedanim->setStandAnim(Weapon::Minigun_Anim, 32 + baseAnim);
49 pedanim->setStandAnim(Weapon::Laser_Anim, 24 + baseAnim);
50 pedanim->setStandAnim(Weapon::Flamer_Anim, 40 + baseAnim);
51 pedanim->setStandAnim(Weapon::LongRange_Anim, 48 + baseAnim);
52 pedanim->setWalkAnim(Weapon::EnergyShield_Anim, 56 + baseAnim);
53 pedanim->setWalkAnim(Weapon::Pistol_Anim, 64 + baseAnim);
54 pedanim->setWalkAnim(Weapon::Uzi_Anim, 64 + baseAnim);
55 pedanim->setWalkAnim(Weapon::Shotgun_Anim, 64 + baseAnim);
56 pedanim->setWalkAnim(Weapon::Gauss_Anim, 64 + baseAnim);
57 pedanim->setWalkAnim(Weapon::Minigun_Anim, 72 + baseAnim);
58 pedanim->setWalkAnim(Weapon::Laser_Anim, 64 + baseAnim);
59 pedanim->setWalkAnim(Weapon::Flamer_Anim, 80 + baseAnim);
60 pedanim->setWalkAnim(Weapon::LongRange_Anim, 88 + baseAnim);
61 // I think 97 was the original pistol shoot anim, but it wasn't sexy enough.
62 //pedanim->setStandFireAnim(Weapon::Laser_Anim, 96 + baseAnim);
63 pedanim->setStandFireAnim(Weapon::Pistol_Anim, 104 + baseAnim);
64 pedanim->setStandFireAnim(Weapon::Uzi_Anim, 104 + baseAnim);
65 pedanim->setStandFireAnim(Weapon::Shotgun_Anim, 104 + baseAnim);
66 pedanim->setStandFireAnim(Weapon::Gauss_Anim, 104 + baseAnim);
67 pedanim->setStandFireAnim(Weapon::Minigun_Anim, 112 + baseAnim);
68 pedanim->setStandFireAnim(Weapon::Laser_Anim, 120 + baseAnim);
69 pedanim->setStandFireAnim(Weapon::Flamer_Anim, 128 + baseAnim);
70 pedanim->setStandFireAnim(Weapon::LongRange_Anim, 136 + baseAnim);
71 pedanim->setWalkFireAnim(Weapon::Pistol_Anim, 152 + baseAnim);
72 pedanim->setWalkFireAnim(Weapon::Uzi_Anim, 152 + baseAnim);
73 pedanim->setWalkFireAnim(Weapon::Shotgun_Anim, 152 + baseAnim);
74 pedanim->setWalkFireAnim(Weapon::Gauss_Anim, 152 + baseAnim);
75 pedanim->setWalkFireAnim(Weapon::Minigun_Anim, 160 + baseAnim);
76 pedanim->setWalkFireAnim(Weapon::Laser_Anim, 168 + baseAnim);
77 pedanim->setWalkFireAnim(Weapon::Flamer_Anim, 176 + baseAnim);
78 pedanim->setWalkFireAnim(Weapon::LongRange_Anim, 184 + baseAnim);
79 } else {
80 // NOTE: peds other then agents have pistol like animations for
81 // all weapons
82 pedanim->setStandAnim(Weapon::Unarmed_Anim, 0 + baseAnim);
83 pedanim->setWalkAnim(Weapon::Unarmed_Anim, 8 + baseAnim);
84 pedanim->setStandAnim(Weapon::EnergyShield_Anim, 0 + baseAnim);
85 pedanim->setStandAnim(Weapon::Pistol_Anim, 24 + baseAnim);
86 pedanim->setStandAnim(Weapon::Uzi_Anim, 24 + baseAnim);
87 pedanim->setStandAnim(Weapon::Shotgun_Anim, 24 + baseAnim);
88 pedanim->setStandAnim(Weapon::Gauss_Anim, 24 + baseAnim);
89 pedanim->setStandAnim(Weapon::Minigun_Anim, 24 + baseAnim);
90 pedanim->setStandAnim(Weapon::Laser_Anim, 24 + baseAnim);
91 pedanim->setStandAnim(Weapon::Flamer_Anim, 24 + baseAnim);
92 pedanim->setStandAnim(Weapon::LongRange_Anim, 24 + baseAnim);
93 pedanim->setWalkAnim(Weapon::EnergyShield_Anim, 24 + baseAnim);
94 pedanim->setWalkAnim(Weapon::Pistol_Anim, 64 + baseAnim);
95 pedanim->setWalkAnim(Weapon::Uzi_Anim, 64 + baseAnim);
96 pedanim->setWalkAnim(Weapon::Shotgun_Anim, 64 + baseAnim);
97 pedanim->setWalkAnim(Weapon::Gauss_Anim, 64 + baseAnim);
98 pedanim->setWalkAnim(Weapon::Minigun_Anim, 64 + baseAnim);
99 pedanim->setWalkAnim(Weapon::Laser_Anim, 64 + baseAnim);
100 pedanim->setWalkAnim(Weapon::Flamer_Anim, 64 + baseAnim);
101 pedanim->setWalkAnim(Weapon::LongRange_Anim, 64 + baseAnim);
102 // I think 97 was the original pistol shoot anim, but it wasn't sexy enough.
103 //pedanim->setStandFireAnim(Weapon::Laser_Anim, 96 + baseAnim);
104 pedanim->setStandFireAnim(Weapon::Pistol_Anim, 104 + baseAnim);
105 pedanim->setStandFireAnim(Weapon::Uzi_Anim, 104 + baseAnim);
106 pedanim->setStandFireAnim(Weapon::Shotgun_Anim, 104 + baseAnim);
107 pedanim->setStandFireAnim(Weapon::Gauss_Anim, 104 + baseAnim);
108 pedanim->setStandFireAnim(Weapon::Minigun_Anim, 104 + baseAnim);
109 pedanim->setStandFireAnim(Weapon::Laser_Anim, 104 + baseAnim);
110 pedanim->setStandFireAnim(Weapon::Flamer_Anim, 104 + baseAnim);
111 pedanim->setStandFireAnim(Weapon::LongRange_Anim, 104 + baseAnim);
112 pedanim->setWalkFireAnim(Weapon::Pistol_Anim, 104 + baseAnim);
113 pedanim->setWalkFireAnim(Weapon::Uzi_Anim, 104 + baseAnim);
114 pedanim->setWalkFireAnim(Weapon::Shotgun_Anim, 104 + baseAnim);
115 pedanim->setWalkFireAnim(Weapon::Gauss_Anim, 104 + baseAnim);
116 pedanim->setWalkFireAnim(Weapon::Minigun_Anim, 104 + baseAnim);
117 pedanim->setWalkFireAnim(Weapon::Laser_Anim, 104 + baseAnim);
118 pedanim->setWalkFireAnim(Weapon::Flamer_Anim, 104 + baseAnim);
119 pedanim->setWalkFireAnim(Weapon::LongRange_Anim, 104 + baseAnim);
120 }
121 pedanim->setPickupAnim(192 + baseAnim);
122 pedanim->setHitAnim(193 + baseAnim);
123 pedanim->setVaporizeAnim(197 + baseAnim);
124 pedanim->setSinkAnim(201 + baseAnim);
125 // 203 - die, 204 - dead, agent only
126 pedanim->setDieAgentAnim(203 + baseAnim);
127 pedanim->setDeadAgentAnim(205);
128 pedanim->setDieAnim(205 + baseAnim);
129 pedanim->setDeadAnim(206 + baseAnim);
130 // when this burning should be used?
131 pedanim->setStandBurnAnim(208);
132 // this one used when hit with flamethrower
133 pedanim->setWalkBurnAnim(209);
134 pedanim->setDieBurnAnim(210);
135 pedanim->setSmokeBurnAnim(211);
136 pedanim->setDeadBurnAnim(828);
137 pedanim->setPersuadeAnim(236);
138 }
139
140 /*!
141 * Instanciate a PedInstance from the given data.
142 * \param gamdata
143 * \param ped_idx Index of the ped in the file.
144 * \param map id of the map
145 * \return NULL if the ped could not be created.
146 */
loadInstance(const LevelData::People & gamdata,uint16 ped_idx,int map,uint32 playerGroupId)147 PedInstance *PedManager::loadInstance(const LevelData::People & gamdata, uint16 ped_idx, int map, uint32 playerGroupId)
148 {
149 if(gamdata.type == 0x0 ||
150 gamdata.location == LevelData::kPeopleLocNotVisible ||
151 gamdata.location == LevelData::kPeopleLocAboveWalkSurf)
152 return NULL;
153
154 bool isOurAgent = ped_idx < AgentManager::kMaxSlot;
155 if (isOurAgent && !g_gameCtrl.agents().isSquadSlotActive(ped_idx)) {
156 // Creates agent only if he's active
157 return NULL;
158 }if (ped_idx >= 4 && ped_idx < 8) {
159 // Ped between index 4 and 7 are not used
160 // In original game must be the place where persuaded agents were stored
161 return NULL;
162 }
163
164 Ped *pedanim = new Ped();
165 initAnimation(pedanim, READ_LE_UINT16(gamdata.index_base_anim));
166 PedInstance *newped = new PedInstance(pedanim, ped_idx, map, isOurAgent);
167
168 int hp = READ_LE_INT16(gamdata.health);
169 if (isOurAgent) {
170 // not in all missions our agents health is 16, this fixes it
171 hp = PedInstance::kAgentMaxHealth;
172 }else if (hp <= 0) {
173 hp = 2;
174 }
175
176 newped->setStartHealth(hp);
177
178 newped->setDirection(gamdata.orientation);
179 if (gamdata.state == LevelData::kPeopleStateDead) {
180 newped->setDrawnAnim(PedInstance::ad_DeadAnim);
181 newped->setHealth(-1);
182 newped->setStateMasks(PedInstance::pa_smDead);
183 } else {
184 newped->setHealth(hp);
185 newped->setStateMasks(PedInstance::pa_smStanding);
186 if (gamdata.state == 0x10) {
187 LOG(Log::k_FLG_GAME, "PedManager","loadInstance", ("Unhandled gamedata state for ped %d", newped->id()))
188 /* PedInstance::actionQueueGroupType as;
189 newped->createActQWalking(as, NULL, NULL, gamdata.orientation);
190 as.main_act = as.actions.size() - 1;
191 as.group_desc = PedInstance::gd_mStandWalk;
192 as.origin_desc = fs_action::kOrigDefault;
193 newped->addActQToQueue(as);
194 */
195 }
196 }
197 // this is tile based Z we get, realword Z is in gamdata,
198 // for correct calculations of viewpoint, target hit etc.
199 // Zr = (Zt * 128) / 256
200 int z = READ_LE_UINT16(gamdata.mapposz) >> 7;
201 // some peds have z = 0 - map paraguay
202 int oz = gamdata.mapposz[0] & 0x7F;
203 newped->setSizeX(32);
204 newped->setSizeY(32);
205 newped->setSizeZ(256);
206 //printf("x %i y %i z %i ox %i oy %i oz %i\n", gamdata.mapposx[1], gamdata.mapposy[1], z, gamdata.mapposx[0], gamdata.mapposy[0], oz);
207 newped->setPosition(gamdata.mapposx[1], gamdata.mapposy[1],
208 z, gamdata.mapposx[0],
209 gamdata.mapposy[0], oz);
210 newped->setTypeFromValue(gamdata.type_ped);
211
212 newped->setAllAdrenaLevels(gamdata.adrena_amount,
213 gamdata.adrena_dependency, gamdata.adrena_effect);
214 newped->setAllInteliLevels(gamdata.inteli_amount,
215 gamdata.inteli_dependency, gamdata.inteli_effect);
216 newped->setAllPercepLevels(gamdata.percep_amount,
217 gamdata.percep_dependency, gamdata.percep_effect);
218
219 if (isOurAgent) {
220 // We're loading one of our agents
221 Agent *pAg = g_gameCtrl.agents().squadMember(ped_idx);
222 initOurAgent(pAg, playerGroupId, newped);
223 } else {
224 unsigned int mt = newped->type();
225 newped->setObjGroupDef(mt);
226 if (mt == PedInstance::og_dmAgent) {
227 initEnemyAgent(newped);
228 } else if (mt == PedInstance::og_dmGuard) {
229 initGuard(newped);
230 } else if (mt == PedInstance::og_dmPolice) {
231 initPolice(newped);
232 } else if (mt == PedInstance::og_dmCivilian) {
233 initCivilian(newped);
234 } else if (mt == PedInstance::og_dmCriminal) {
235 initCriminal(newped);
236 }
237 newped->setSightRange(7 * 256);
238 }
239
240 return newped;
241 }
242
243 /*!
244 * Initialize the ped instance as one of our agent.
245 * \param pAgent The agent reference
246 * \param obj_group_id Id of the agent's group.
247 * \param pPed The ped to initialize
248 */
initOurAgent(Agent * pAgent,unsigned int obj_group_id,PedInstance * pPed)249 void PedManager::initOurAgent(Agent *pAgent, unsigned int obj_group_id, PedInstance *pPed) {
250 LOG(Log::k_FLG_GAME, "PedManager","initOurAgent", ("Create player agent with id %d", pAgent->getId()))
251
252 while (pAgent->numWeapons()) {
253 WeaponInstance *wi = pAgent->removeWeaponAtIndex(0);
254 pPed->addWeapon(wi);
255 wi->setOwner(pPed);
256 }
257 *((ModOwner *)pPed) = *((ModOwner *)pAgent);
258
259 pPed->setObjGroupID(obj_group_id);
260 pPed->setObjGroupDef(PedInstance::og_dmAgent);
261 pPed->addEnemyGroupDef(2);
262 pPed->addEnemyGroupDef(3);
263 pPed->setHostileDesc(PedInstance::pd_smArmed);
264 pPed->setSightRange(7 * 256);
265 pPed->setBaseSpeed(256);
266 pPed->setTimeBeforeCheck(400);
267 pPed->setBaseModAcc(0.5);
268
269 // Set components of behaviour for our agent
270 pPed->behaviour().addComponent(new CommonAgentBehaviourComponent(pPed));
271 pPed->behaviour().addComponent(new PersuaderBehaviourComponent());
272 }
273
274 /*!
275 * Initialize the ped instance as an enemy agent.
276 * \param p_agent The agent reference
277 * \param obj_group_id Id of the agent's group.
278 * \param pPed The ped to initialize
279 */
initEnemyAgent(PedInstance * pPed)280 void PedManager::initEnemyAgent(PedInstance *pPed) {
281 LOG(Log::k_FLG_GAME, "PedManager","initEnemyAgent", ("Create enemy agent with id %d", pPed->id()))
282
283 pPed->setObjGroupID(2);
284 pPed->addEnemyGroupDef(1);
285 pPed->setBaseSpeed(256);
286 // enemies get top version of mods
287 pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_LEGS));
288 pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_LEGS));
289 pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_ARMS));
290 pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_CHEST));
291 pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_HEART));
292 pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_EYES));
293 pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_BRAIN));
294 pPed->setTimeBeforeCheck(400);
295 pPed->setBaseModAcc(0.5);
296
297 pPed->behaviour().addComponent(new PlayerHostileBehaviourComponent());
298 }
299
300 /*!
301 * Initialize the ped instance as a guard.
302 * \param p_agent The agent reference
303 * \param obj_group_id Id of the agent's group.
304 * \param pPed The ped to initialize
305 */
initGuard(PedInstance * pPed)306 void PedManager::initGuard(PedInstance *pPed) {
307 LOG(Log::k_FLG_GAME, "PedManager","initGuard", ("Create guard with id %d", pPed->id()))
308
309 pPed->setObjGroupID(3);
310 pPed->addEnemyGroupDef(1);
311 pPed->setBaseSpeed(192);
312 pPed->setTimeBeforeCheck(300);
313 pPed->setBaseModAcc(0.45);
314
315 pPed->behaviour().addComponent(new PlayerHostileBehaviourComponent());
316 }
317
318 /*!
319 * Initialize the ped instance as a police.
320 * \param p_agent The agent reference
321 * \param obj_group_id Id of the agent's group.
322 * \param pPed The ped to initialize
323 */
initPolice(PedInstance * pPed)324 void PedManager::initPolice(PedInstance *pPed) {
325 LOG(Log::k_FLG_GAME, "PedManager","initPolice", ("Create police with id %d", pPed->id()))
326
327 pPed->setObjGroupID(4);
328 pPed->setHostileDesc(PedInstance::pd_smArmed);
329 pPed->setBaseSpeed(160);
330 pPed->setTimeBeforeCheck(400);
331 pPed->setBaseModAcc(0.4);
332
333 pPed->behaviour().addComponent(new PoliceBehaviourComponent());
334 }
335
336 /*!
337 * Initialize the ped instance as a civilian.
338 * \param p_agent The agent reference
339 * \param obj_group_id Id of the agent's group.
340 * \param pPed The ped to initialize
341 */
initCivilian(PedInstance * pPed)342 void PedManager::initCivilian(PedInstance *pPed) {
343 LOG(Log::k_FLG_GAME, "PedManager","initCivilian", ("Create civilian with id %d", pPed->id()))
344
345 pPed->setObjGroupID(5);
346 pPed->addEnemyGroupDef(6);
347 pPed->setHostileDesc(PedInstance::pd_smArmed);
348 pPed->setBaseSpeed(128);
349 pPed->setTimeBeforeCheck(600);
350 pPed->setBaseModAcc(0.2);
351
352 pPed->behaviour().addComponent(new PanicComponent());
353 }
354
355 /*!
356 * Initialize the ped instance as a criminal.
357 * \param p_agent The agent reference
358 * \param obj_group_id Id of the agent's group.
359 * \param pPed The ped to initialize
360 */
initCriminal(PedInstance * pPed)361 void PedManager::initCriminal(PedInstance *pPed) {
362 LOG(Log::k_FLG_GAME, "PedManager","initCriminal", ("Create criminal with id %d", pPed->id()))
363
364 pPed->setObjGroupID(6);
365 pPed->setBaseSpeed(128);
366 pPed->setTimeBeforeCheck(500);
367 pPed->setBaseModAcc(0.2);
368 }
369