1332
|
1
|
|
2 #include "MM7.h"
|
|
3 #include "mm7_data.h"
|
|
4 #include "Actor.h"
|
|
5 #include "Player.h"
|
|
6 #include "Party.h"
|
|
7 #include "AudioPlayer.h"
|
|
8 #include "SpriteObject.h"
|
2044
|
9 #include "Timer.h"
|
1332
|
10 #include "stru298.h"
|
|
11 #include "IconFrameTable.h"
|
|
12 #include "Viewport.h"
|
|
13 #include "FactionTable.h"
|
|
14
|
|
15 #include "TurnEngine.h"
|
|
16
|
|
17
|
|
18 #include "TurnEngine.h"
|
|
19 struct stru262_TurnBased *pTurnEngine = new stru262_TurnBased;
|
|
20
|
|
21
|
|
22 //----- (00404544) --------------------------------------------------------
|
|
23 void stru262_TurnBased::SortTurnQueue()
|
2242
|
24 {
|
|
25 int active_actors;
|
|
26 TurnBased_QueueElem *current_top; // eax@16
|
|
27 TurnBased_QueueElem *test_element; // ecx@18
|
|
28 TurnBased_QueueElem temp_elem;
|
|
29 int i,j;
|
|
30 unsigned int p_type;
|
|
31 unsigned int p_id;
|
1332
|
32
|
2242
|
33 active_actors = this->uActorQueueSize;
|
|
34 //set non active actors in queue initiative that not allow them to paticipate
|
|
35 for( i = 0; i < uActorQueueSize; ++i)
|
|
36 {
|
|
37 p_type = PID_TYPE(pQueue[i].uPackedID);
|
|
38 p_id = PID_ID(pQueue[i].uPackedID);
|
|
39
|
|
40 if ( p_type == OBJECT_Actor )
|
|
41 {
|
|
42 pActors[p_id].uAttributes |= 0x80;
|
|
43 if ( !pActors[p_id].CanAct() )
|
|
44 {
|
|
45 --active_actors;
|
|
46 pQueue[i].actor_initiative = 1001;
|
|
47 pActors[p_id].uAttributes &= ~0x80;
|
|
48 }
|
|
49 }
|
|
50 else if ( p_type == OBJECT_Player)
|
1332
|
51 {
|
2242
|
52 if ( !pParty->pPlayers[p_id].CanAct() )
|
|
53 {
|
|
54 --active_actors;
|
|
55 pQueue[i].actor_initiative = 1001;
|
|
56 }
|
|
57 }
|
|
58 }
|
|
59 //sort
|
|
60 if (uActorQueueSize > 0)
|
|
61 {
|
|
62 for( i = 0; i < uActorQueueSize-1; ++i)
|
|
63 {
|
|
64 current_top=&pQueue[i];
|
|
65 for ( j = i+1; j < uActorQueueSize; ++j )
|
|
66 {
|
|
67 test_element=&pQueue[j];
|
|
68 if ( test_element->actor_initiative < current_top->actor_initiative || // if less initiative -> top
|
|
69 ((test_element->actor_initiative == current_top->actor_initiative) &&
|
|
70 (((PID_TYPE(test_element->uPackedID) == OBJECT_Player) && (PID_TYPE(current_top->uPackedID) == OBJECT_Actor)) || //player preferable
|
|
71 ((PID_TYPE(test_element->uPackedID) == PID_TYPE(current_top->uPackedID)) && (PID_ID(test_element->uPackedID) < PID_ID(current_top->uPackedID)))))) //less id preferable
|
|
72 { //swap
|
|
73 memcpy(&temp_elem,current_top,sizeof(TurnBased_QueueElem));
|
|
74 memcpy(current_top,test_element, sizeof(TurnBased_QueueElem));
|
|
75 memcpy(test_element, &temp_elem, sizeof(TurnBased_QueueElem));
|
1332
|
76 }
|
2242
|
77 }
|
1332
|
78 }
|
2242
|
79 }
|
|
80 uActorQueueSize = active_actors;
|
|
81 if ( PID_TYPE(pQueue[0].uPackedID) == OBJECT_Player) //we have player at queue top
|
|
82 {
|
|
83 uActiveCharacter = PID_ID(pQueue[0].uPackedID)+1;
|
|
84 field_18 |= TE_PLAYER_TURN;
|
|
85 }
|
|
86 else
|
|
87 {
|
|
88 uActiveCharacter = 0;
|
|
89 field_18 &= ~TE_PLAYER_TURN;
|
|
90 }
|
|
91 for ( i = 0; i < uActorQueueSize; ++i)
|
|
92 {
|
|
93 if ( PID_TYPE(pQueue[i].uPackedID) == OBJECT_Player) //set recovery times
|
|
94 pParty->pPlayers[PID_ID(pQueue[i].uPackedID)].uTimeToRecovery = (unsigned __int16)((double)pQueue[i].actor_initiative * 0.46875);
|
|
95 }
|
|
96 }
|
1332
|
97 //----- (0040471C) --------------------------------------------------------
|
1448
|
98 void stru262_TurnBased::ApplyPlayerAction()
|
2242
|
99 {
|
|
100 if ( pParty->bTurnBasedModeOn == 1 )
|
|
101 {
|
|
102 if ( pTurnEngine->turn_stage == TE_ATTACK )
|
|
103 _406457(0);
|
|
104 }
|
|
105 }
|
1332
|
106
|
|
107 //----- (004059DB) --------------------------------------------------------
|
|
108 void stru262_TurnBased::Start()
|
2242
|
109 {
|
|
110 int v17; // edx@22
|
|
111 AIDirection v30; // [sp+Ch] [bp-68h]@10
|
|
112 AIDirection v31; // [sp+28h] [bp-4Ch]@10
|
|
113 AIDirection a3; // [sp+44h] [bp-30h]@10
|
|
114 int activ_players[4];
|
|
115 int players_recovery_time[4];
|
|
116 int a_players_count;
|
|
117 int i,j;
|
|
118 int temp;
|
1342
|
119
|
2242
|
120 pTurnEngine->field_18 &= ~TE_HAVE_PENDING_ACTIONS;
|
|
121 pEventTimer->TrackGameTime();
|
|
122 pAudioPlayer->StopChannels(-1, -1);
|
|
123 pAudioPlayer->PlaySound(SOUND_207, 0, 0, -1, 0, 0, 0, 0);
|
|
124 //pPlayer = pParty->pPlayers.data();
|
|
125 dword_50C998_turnbased_icon_1A = 8 * pIconsFrameTable->pIcons[uIconID_TurnStart].uAnimLength;
|
|
126 dword_50C994 = 0;
|
1332
|
127
|
2242
|
128 this->turn_initiative = 100;
|
|
129 this->turns_count = 0;
|
|
130 this->ai_turn_timer = 64;
|
|
131 this->turn_stage = TE_WAIT;
|
|
132 this->uActorQueueSize = 0;
|
1332
|
133
|
2242
|
134 for ( uint pl_id = 0; pl_id < 4 ; ++pl_id )
|
|
135 {
|
|
136 if ( pParty->pPlayers[pl_id].CanAct() )
|
|
137 {
|
|
138 this->pQueue[this->uActorQueueSize].uPackedID = PID(OBJECT_Player,pl_id);
|
|
139 this->pQueue[this->uActorQueueSize].AI_action_type = TE_AI_PURSUE;
|
|
140 this->pQueue[this->uActorQueueSize].uActionLength = 0;
|
|
141 pParty->pTurnBasedPlayerRecoveryTimes[this->uActorQueueSize] = 0;
|
|
142 ++this->uActorQueueSize;
|
|
143 }
|
|
144 }
|
1332
|
145
|
2242
|
146 for ( int i = 0; i < ai_arrays_size ; ++i )
|
|
147 {
|
|
148 if (ai_near_actors_ids[i] == 10)
|
|
149 continue;
|
|
150 if ( pActors[ai_near_actors_ids[i]].CanAct() )
|
|
151 {
|
|
152 if ( pActors[ai_near_actors_ids[i]].uAttributes & 0x8000 )
|
|
153 {
|
|
154 pActors[ai_near_actors_ids[i]].uAttributes |= 0x80;
|
|
155 Actor::GetDirectionInfo(PID(OBJECT_Actor,ai_near_actors_ids[i]), ai_near_actors_targets_pid[ai_near_actors_ids[i]], &v31, 0);
|
|
156 memcpy(&v30, &v31, sizeof(AIDirection));
|
|
157 Actor::AI_StandOrBored(ai_near_actors_ids[i], 4, 32, &v30);
|
|
158 this->pQueue[this->uActorQueueSize].uPackedID = PID(OBJECT_Actor,ai_near_actors_ids[i]);
|
|
159 this->pQueue[this->uActorQueueSize].AI_action_type = TE_AI_PURSUE;
|
|
160 this->pQueue[this->uActorQueueSize].uActionLength = 0;
|
|
161 ++this->uActorQueueSize;
|
|
162 }
|
|
163 }
|
|
164 }
|
1332
|
165
|
2242
|
166 a_players_count = 0;
|
|
167 for ( int k = 0; k < this->uActorQueueSize; ++k )
|
|
168 {
|
|
169 //set initial initiative for turn actors
|
|
170 if ( PID_TYPE(this->pQueue[k].uPackedID) == OBJECT_Player )
|
|
171 {
|
|
172 if ( pPlayers[PID_ID(this->pQueue[k].uPackedID) + 1]->uTimeToRecovery != 0 )
|
|
173 this->pQueue[k].actor_initiative = (signed int)((double)pPlayers[PID_ID(this->pQueue[k].uPackedID) + 1]->uTimeToRecovery * 0.46875);
|
|
174 else
|
|
175 {
|
|
176 activ_players[a_players_count] = k;
|
|
177 ++a_players_count;
|
|
178 }
|
|
179 }
|
|
180 else if ( PID_TYPE(this->pQueue[k].uPackedID) == OBJECT_Actor )
|
|
181 {
|
|
182 v17 = rand() % 99;
|
|
183 if ( v17 < 33 )
|
|
184 this->pQueue[k].actor_initiative = 1;
|
|
185 else
|
|
186 this->pQueue[k].actor_initiative= (v17 >= 66)? 5 : 3;
|
|
187 }
|
|
188 else //fot non player and actor
|
|
189 this->pQueue[k].actor_initiative = 666;
|
|
190 this->pQueue[k].actor_initiative += 16;
|
|
191 }
|
|
192
|
|
193 if ( a_players_count > 0 )
|
|
194 {
|
|
195 for ( i = 0; i < a_players_count; ++i)
|
|
196 players_recovery_time[i] = pParty->pPlayers[PID_ID(this->pQueue[activ_players[i]].uPackedID)].GetAttackRecoveryTime(0);
|
|
197 //sort players by recovery time
|
|
198 for ( i = 0; i < a_players_count-1; ++i)
|
|
199 {
|
|
200 for ( j = i + 1; j < a_players_count; ++j )
|
|
201 {
|
|
202 if (players_recovery_time[j] < players_recovery_time[i]) //swap values
|
|
203 {
|
|
204 temp = players_recovery_time[i];
|
|
205 players_recovery_time[i] = players_recovery_time[j];
|
|
206 players_recovery_time[j] = temp;
|
|
207 temp = activ_players[i];
|
|
208 activ_players[i] = activ_players[j];
|
|
209 activ_players[j] = temp;
|
1332
|
210 }
|
2242
|
211 }
|
1332
|
212 }
|
2242
|
213 for ( i = 0; i < a_players_count; ++i)
|
|
214 this->pQueue[activ_players[i]].actor_initiative = i + 2;
|
|
215 }
|
|
216 this->SortTurnQueue();
|
|
217 }
|
1332
|
218
|
|
219 //----- (00405CFF) --------------------------------------------------------
|
|
220 void stru262_TurnBased::End(bool bPlaySound)
|
2242
|
221 {
|
|
222 ObjectType objType; // eax@13
|
|
223 int objID; // esi@13
|
|
224 int i;
|
1332
|
225
|
2242
|
226 this->turn_stage = TE_NONE;
|
|
227 for( i = 0; i < uActorQueueSize; ++i)
|
|
228 {
|
|
229 if ( PID_TYPE(pQueue[i].uPackedID) == OBJECT_Actor )
|
|
230 pActors[PID_ID(pQueue[i].uPackedID)].uAttributes &= ~0x80;
|
|
231 }
|
1332
|
232
|
2242
|
233 for( i = 0; i < uNumSpriteObjects; ++i)
|
|
234 {
|
|
235 if (pSpriteObjects[i].uAttributes & 4)
|
|
236 pSpriteObjects[i].uAttributes &= ~0x04;
|
|
237 }
|
1332
|
238
|
2242
|
239 for( i = 0; i < uActorQueueSize; ++i)
|
|
240 {
|
|
241 objType = (ObjectType)PID_TYPE(pQueue[i].uPackedID);
|
|
242 objID = PID_ID(pQueue[i].uPackedID);
|
|
243 if ( objType == OBJECT_Player )
|
|
244 pPlayers[objID + 1]->uTimeToRecovery = (unsigned __int16)((double)pQueue[i].actor_initiative * 2.133333333333333);
|
|
245 else if ( objType == OBJECT_Actor )
|
|
246 pActors[objID].pMonsterInfo.uRecoveryTime = (unsigned __int16)((double)pQueue[i].actor_initiative * 2.133333333333333);
|
|
247 }
|
|
248 pAudioPlayer->StopChannels(-1, -1);
|
|
249 if ( bPlaySound != 0 )
|
|
250 pAudioPlayer->PlaySound(SOUND_206, 0, 0, -1, 0, 0, 0, 0);
|
|
251 pTurnEngine->field_18 &= ~TE_HAVE_PENDING_ACTIONS;
|
|
252 pEventTimer->StopGameTime();
|
|
253 dword_50C994 = 0;
|
|
254 dword_50C998_turnbased_icon_1A = 0;
|
|
255 }
|
1332
|
256 // 50C994: using guessed type int dword_50C994;
|
|
257 // 50C998: using guessed type int dword_50C998_turnbased_icon_1A;
|
|
258
|
|
259 //----- (00405E14) --------------------------------------------------------
|
1448
|
260 void stru262_TurnBased::AITurnBasedAction()
|
2242
|
261 {
|
|
262 AIDirection v6; // esi@21
|
|
263 AIDirection a3; // [sp+4h] [bp-68h]@21
|
|
264 AIDirection v14; // [sp+20h] [bp-4Ch]@21
|
|
265 AIDirection v15; // [sp+3Ch] [bp-30h]@21
|
|
266 Actor *curr_actor; // [sp+58h] [bp-14h]@2
|
|
267 int target_pid; // [sp+5Ch] [bp-10h]@6
|
|
268 int shrinked;
|
|
269 int i, j;
|
|
270
|
|
271 for (i = 0; i < uNumActors; ++i )
|
|
272 {
|
|
273 curr_actor=&pActors[i];
|
|
274 shrinked=pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime > 0;
|
|
275 for (j = 0; j < 22; ++j) //check expired spell Buffs
|
1332
|
276 {
|
2242
|
277 if (j != 10)
|
|
278 pActors[i].pActorBuffs[j].IsBuffExpiredToTime(pParty->uTimePlayed);
|
|
279 }
|
|
280 if (shrinked && pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime <= 0) //buff 3 expired
|
|
281 pActors[i].uActorHeight = pMonsterList->pMonsters[pActors[i].pMonsterInfo.uID - 1].uMonsterHeight;
|
|
282 if (!(curr_actor->uAttributes & 0x80) && (!curr_actor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime) &&
|
|
283 (!curr_actor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime))
|
|
284 {
|
|
285 curr_actor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
|
|
286 if (curr_actor->uCurrentActionTime>=curr_actor->uCurrentActionLength)
|
|
287 {
|
|
288 target_pid = ai_near_actors_targets_pid[i];
|
|
289 Actor::GetDirectionInfo(PID(OBJECT_Actor,i), target_pid, &v6, 0);
|
|
290 memcpy(&v15, &v6, sizeof(AIDirection));
|
|
291 memcpy(&v14, &v15, sizeof(AIDirection));
|
|
292 if ( curr_actor->uAIState == Dying )
|
1332
|
293 {
|
2242
|
294 curr_actor->uCurrentActionTime = 0;
|
|
295 curr_actor->uCurrentActionLength = 0;
|
|
296 curr_actor->uAIState = Dead;
|
|
297 curr_actor->UpdateAnimation();
|
1340
|
298 }
|
2242
|
299 else if ( (curr_actor->uAIState > AIState::Removed) && (curr_actor->uAIState < AIState::Disabled))
|
|
300 Actor::AI_StandOrBored(i, target_pid, 32, &v14);
|
|
301 }
|
|
302 }
|
|
303 }
|
|
304 if ( turn_stage == TE_WAIT )
|
|
305 {
|
|
306 if ( ai_turn_timer == 64 )
|
|
307 ActorAISetMovementDecision();
|
|
308 else if ( ai_turn_timer > 0 )
|
|
309 ActorAIDoAdditionalMove();
|
|
310 else
|
|
311 {
|
|
312 ActorAIStopMovement();
|
|
313 turn_initiative = 100;
|
1332
|
314 }
|
2242
|
315 ai_turn_timer -= pEventTimer->uTimeElapsed;
|
|
316 }
|
|
317 else if ( turn_stage == TE_ATTACK )
|
|
318 {
|
|
319 if ( !(field_18 &TE_FLAG_1))
|
|
320 {
|
|
321 if ( turn_initiative == 100 )
|
|
322 {
|
|
323 StartTurn();
|
|
324 SetAIRecoveryTimes();
|
|
325 return;
|
|
326 }
|
|
327 if ( turn_initiative > 0 || pQueue[0].actor_initiative <= 0 )
|
|
328 {
|
|
329 _4065B0();
|
|
330 SetAIRecoveryTimes();
|
|
331 return;
|
|
332 }
|
|
333 }
|
|
334 NextTurn();
|
|
335 }
|
|
336 else if ( turn_stage == TE_MOVEMENT )
|
|
337 {
|
|
338 if ( (uActionPointsLeft > 0) && (!(field_18 & TE_FLAG_8)) )
|
|
339 ActorAIChooseNewTargets();
|
|
340 else
|
|
341 {
|
|
342 field_18 &= ~TE_FLAG_8;
|
|
343 turn_stage = TE_WAIT;
|
|
344 ai_turn_timer = 64;
|
|
345 }
|
|
346 }
|
|
347 }
|
1332
|
348
|
|
349
|
|
350 //----- (00406051) --------------------------------------------------------
|
2242
|
351 void stru262_TurnBased::StartTurn()
|
|
352 {
|
|
353 int player_num, actor_num, i, j;
|
1332
|
354
|
2242
|
355 pending_actions = 0;
|
|
356 //add player to queue if he can act
|
|
357 for ( player_num = 0; player_num < 4; ++player_num)
|
|
358 {
|
|
359 for ( j = 0; j < uActorQueueSize; ++j )
|
|
360 {
|
|
361 if (PID_TYPE(pQueue[j].uPackedID) == OBJECT_Player)
|
|
362 {
|
|
363 if (pPlayers[PID_ID(pQueue[j].uPackedID) + 1]->CanAct() && (player_num != PID_ID(pQueue[j].uPackedID)) )
|
|
364 break;
|
|
365 }
|
|
366 }
|
|
367 if ( j == uActorQueueSize )
|
|
368 {
|
|
369 pQueue[uActorQueueSize].uPackedID = PID(OBJECT_Player,player_num);
|
|
370 pQueue[uActorQueueSize].actor_initiative = 100;
|
|
371 pQueue[uActorQueueSize].uActionLength = 0;
|
|
372 pQueue[uActorQueueSize].AI_action_type = TE_AI_STAND;
|
|
373 ++uActorQueueSize;
|
1332
|
374 }
|
2242
|
375 }
|
|
376 //add new arrived actors
|
|
377 for ( actor_num = 0; actor_num < ai_arrays_size; ++actor_num )
|
|
378 {
|
|
379 for ( j = 0; j < uActorQueueSize; ++j )
|
|
380 {
|
|
381 if ((PID_TYPE(pQueue[j].uPackedID)== OBJECT_Actor)&&
|
|
382 ai_near_actors_ids[actor_num] == PID_ID(pQueue[j].uPackedID))
|
|
383 break;
|
|
384 }
|
|
385 if ( j == uActorQueueSize )
|
|
386 {
|
|
387 pQueue[uActorQueueSize].uPackedID = PID(OBJECT_Actor,ai_near_actors_ids[actor_num]);
|
|
388 pQueue[uActorQueueSize].actor_initiative = 1;
|
|
389 pQueue[uActorQueueSize].uActionLength = 0;
|
|
390 pQueue[uActorQueueSize].AI_action_type = TE_AI_STAND;
|
|
391 ++uActorQueueSize;
|
|
392 }
|
|
393 }
|
|
394 ++turns_count;
|
|
395 turn_initiative = 100;
|
|
396 for ( i = 0; i < uActorQueueSize; ++i )
|
|
397 {
|
|
398 if (pQueue[i].actor_initiative == 0 )
|
|
399 pQueue[i].actor_initiative = 100;
|
|
400 }
|
|
401 StepTurnQueue();
|
|
402 for ( i = 0; i < uActorQueueSize; ++i )
|
|
403 {
|
|
404 if ((PID_TYPE(pQueue[i].uPackedID) == OBJECT_Player) || (pQueue[i].actor_initiative > 0))
|
|
405 break;
|
|
406 AI_Action_(i);
|
|
407 }
|
|
408 }
|
1332
|
409 // 4F75D8: using guessed type int ai_arrays_size;
|
|
410
|
1341
|
411 //----- (004061CA) --------------------------------------------------------
|
|
412 void stru262_TurnBased::NextTurn()
|
2242
|
413 {
|
|
414 int v13; // [sp+10h] [bp-4h]@7
|
|
415 int monster_id; // eax@5
|
1341
|
416
|
2242
|
417 SortTurnQueue();
|
|
418 if (PID_TYPE(pQueue[0].uPackedID) == OBJECT_Player)
|
|
419 uActiveCharacter = PID_ID(pQueue[0].uPackedID) + 1;
|
|
420 else
|
|
421 uActiveCharacter = 0;
|
|
422 viewparams->bRedrawGameUI = true;
|
1341
|
423
|
2242
|
424 if ( pending_actions )
|
|
425 {
|
|
426 pTurnEngine->field_18 |= TE_HAVE_PENDING_ACTIONS;
|
|
427 return;
|
|
428 }
|
|
429 pTurnEngine->field_18 &= ~TE_HAVE_PENDING_ACTIONS;
|
|
430 if ( pQueue[0].actor_initiative <= 0 )
|
|
431 return;
|
1332
|
432
|
2242
|
433 v13 = 0;
|
|
434 if (uActorQueueSize > 0 )
|
|
435 {
|
|
436 for ( int i = 0; i < uActorQueueSize; ++i )
|
|
437 {
|
|
438 if (PID_TYPE(pQueue[i].uPackedID) == OBJECT_Actor)
|
|
439 {
|
|
440 monster_id = PID_ID(pQueue[i].uPackedID);
|
|
441 if ( (pActors[monster_id].uAIState == AIState::Dying) || (pActors[monster_id].uAIState == AIState::Stunned)
|
|
442 || (pActors[monster_id].uAIState == AIState::AttackingMelee) || (pActors[monster_id].uAIState == AIState::AttackingRanged1)
|
|
443 || (pActors[monster_id].uAIState == AIState::AttackingRanged2) || (pActors[monster_id].uAIState == AIState::AttackingRanged3)
|
|
444 || (pActors[monster_id].uAIState == AIState::AttackingRanged4) || (pActors[monster_id].uAIState ==AIState::Summoned))
|
|
445 {
|
|
446 pActors[monster_id].uCurrentActionTime += pEventTimer->uTimeElapsed;
|
|
447 if ( pActors[monster_id].uCurrentActionTime < pActors[monster_id].uCurrentActionLength )
|
|
448 v13 = 1;
|
|
449 else if ( pActors[monster_id].uAIState == AIState::Dying )// Dying
|
|
450 {
|
|
451 pActors[monster_id].uAIState = AIState::Dead;
|
|
452 pActors[monster_id].uCurrentActionTime = 0;
|
|
453 pActors[monster_id].uCurrentActionLength = 0;
|
|
454 pActors[monster_id].UpdateAnimation();
|
|
455 }
|
|
456 else
|
|
457 {
|
|
458 if ( pActors[monster_id].uAIState == AIState::Stunned ) //Stunned
|
|
459 Actor::AI_StandOrBored(monster_id, ai_near_actors_targets_pid[monster_id], 32, 0);
|
|
460 }
|
|
461 }
|
|
462 }
|
|
463 }
|
|
464 if ( v13 != 0 )
|
|
465 {
|
|
466 field_18 |= TE_FLAG_1;
|
|
467 return;
|
|
468 }
|
|
469 }
|
1332
|
470
|
2242
|
471 field_18 &= ~TE_FLAG_1;
|
|
472 //set all actors to stay
|
|
473 for ( int i = 0; i < uActorQueueSize; ++i )
|
|
474 {
|
|
475 if(PID_TYPE(pQueue[i].uPackedID) == OBJECT_Actor)
|
|
476 {
|
|
477 monster_id = PID_ID(pQueue[i].uPackedID);
|
|
478 if ((pActors[monster_id].uAIState != AIState::Dead) && (pActors[monster_id].uAIState != AIState::Dying) &&
|
|
479 (pActors[monster_id].uAIState != AIState::Removed) && (pActors[monster_id].uAIState != AIState::Summoned) &&
|
|
480 (pActors[monster_id].uAIState != AIState::Disabled))
|
|
481 {
|
|
482 pQueue[i].uActionLength = 0;
|
|
483 Actor::AI_StandOrBored(monster_id, ai_near_actors_targets_pid[monster_id], 32, nullptr);
|
|
484 }
|
|
485 }
|
|
486 }
|
|
487 // turn tick
|
|
488 turn_stage = TE_MOVEMENT;
|
|
489 pParty->uTimePlayed += 213i64;
|
|
490 _494035_timed_effects__water_walking_damage__etc();
|
|
491 uActionPointsLeft = 130;
|
|
492 }
|
1332
|
493
|
2242
|
494 //----- (004063A1) --------------------------------------------------------
|
|
495 bool stru262_TurnBased::StepTurnQueue()
|
|
496 {
|
|
497 int v9; // dx@12
|
|
498 int j;
|
1332
|
499
|
2242
|
500 SortTurnQueue();
|
|
501 viewparams->bRedrawGameUI = 1;
|
|
502 if ( pQueue[0].actor_initiative != 0 )
|
|
503 {
|
|
504 if (PID_TYPE(pQueue[0].uPackedID) == OBJECT_Player)
|
|
505 {
|
|
506 do
|
|
507 {
|
|
508 for (j = 0; j < uActorQueueSize; ++j )
|
|
509 --pQueue[j].actor_initiative;
|
|
510 --turn_initiative;
|
|
511 if (turn_initiative == 0)
|
|
512 return true;
|
|
513 }
|
|
514 while (pQueue[0].actor_initiative != 0);
|
|
515 }
|
|
516 else
|
|
517 {
|
|
518 if ( pQueue[0].actor_initiative > 0 )
|
|
519 {
|
|
520 v9 = pActors[PID_ID(pQueue[0].uPackedID)].uAIState;
|
|
521 if (!(v9 == AIState::Dying || v9 == AIState::Dead ||
|
|
522 v9 == AIState::Disabled || v9 == AIState::Removed))
|
|
523 {
|
|
524 do
|
|
525 {
|
|
526 for ( j = 0; j < uActorQueueSize; ++j )
|
|
527 {
|
|
528 --pQueue[j].actor_initiative;
|
|
529 if (pQueue[j].actor_initiative == 0)
|
|
530 pQueue[j].uActionLength = 0;
|
|
531 }
|
|
532 --turn_initiative;
|
|
533 if (turn_initiative == 0)
|
|
534 return true;
|
|
535 }
|
|
536 while (pQueue[0].actor_initiative > 0);
|
|
537 }
|
|
538 }
|
|
539 }
|
|
540 }
|
|
541 return false;
|
|
542 }
|
1332
|
543
|
|
544 //----- (00406457) --------------------------------------------------------
|
1340
|
545 void stru262_TurnBased::_406457( int a2 )
|
2242
|
546 {
|
|
547 signed int v4; // ecx@2
|
|
548 signed int v6; // eax@2
|
|
549 int i;
|
|
550 v6 = 0;
|
|
551 if ( PID_TYPE(pQueue[a2].uPackedID) == OBJECT_Player)
|
|
552 {
|
|
553 v4 = PID_ID(pQueue[a2].uPackedID);
|
|
554 if ( pParty->pTurnBasedPlayerRecoveryTimes[v4] )
|
|
555 pParty->pTurnBasedPlayerRecoveryTimes[v4] = 0;
|
1332
|
556 else
|
2242
|
557 v6 = pPlayers[v4 + 1]->GetAttackRecoveryTime(0);
|
|
558 if ( v6 < 30 )
|
|
559 v6 = 30;
|
|
560 }
|
|
561 else
|
|
562 v6 = pMonsterStats->pInfos[pActors[PID_ID(pQueue[a2].uPackedID)].pMonsterInfo.uID].uRecoveryTime;
|
1340
|
563
|
2242
|
564 pQueue[a2].actor_initiative = v6;
|
|
565 SortTurnQueue();
|
|
566 if (PID_TYPE(pQueue[0].uPackedID) == OBJECT_Player)
|
|
567 uActiveCharacter = PID_ID(pQueue[0].uPackedID) + 1;
|
|
568 else
|
|
569 uActiveCharacter = 0;
|
|
570 viewparams->bRedrawGameUI = 1;
|
|
571 while ( (pQueue[0].actor_initiative > 0) && (turn_initiative > 0) )
|
|
572 {
|
|
573 for ( i = 0; i < uActorQueueSize; ++i)
|
|
574 {
|
|
575 --pQueue[i].actor_initiative;
|
|
576 if (pQueue[i].actor_initiative == 0)
|
|
577 pQueue[i].uActionLength=0;
|
1332
|
578 }
|
2242
|
579 --turn_initiative;
|
|
580 }
|
|
581 }
|
1332
|
582
|
|
583 //----- (0040652A) --------------------------------------------------------
|
1448
|
584 void stru262_TurnBased::SetAIRecoveryTimes()
|
2242
|
585 {
|
|
586 int i;
|
|
587 int monster_ai_state;
|
|
588 Actor *monster; // eax@5
|
1332
|
589
|
2242
|
590 for ( i = 0; i < uActorQueueSize; ++i )
|
|
591 {
|
|
592 if (pQueue[i].actor_initiative == 0)
|
|
593 {
|
|
594 if(PID_TYPE(pQueue[i].uPackedID) == OBJECT_Player)
|
|
595 break;
|
|
596 monster=&pActors[PID_ID(pQueue[i].uPackedID)];
|
|
597 monster_ai_state=monster->uAIState;
|
|
598 if (monster_ai_state == AIState::Standing ||
|
|
599 monster_ai_state == AIState::Fleeing ||
|
|
600 monster_ai_state == AIState::Fidgeting)
|
|
601 {
|
|
602 pQueue[i].actor_initiative = pMonsterStats->pInfos[monster->pMonsterInfo.uID].uRecoveryTime;
|
|
603 if (monster->pActorBuffs[ACTOR_BUFF_SLOWED].uExpireTime > 0)
|
|
604 pQueue[i].actor_initiative*=2;
|
|
605 }
|
1340
|
606 }
|
2242
|
607 }
|
|
608 }
|
1332
|
609
|
|
610 //----- (004065B0) --------------------------------------------------------
|
|
611 void stru262_TurnBased::_4065B0()
|
1333
|
612 {
|
2242
|
613 int i;
|
1332
|
614
|
2242
|
615 SortTurnQueue();
|
|
616 if (pQueue[0].actor_initiative <= 0)
|
|
617 {
|
|
618 for ( i = 0; i < uActorQueueSize; ++i )
|
|
619 {
|
|
620 if ((PID_TYPE(pQueue[i].uPackedID) == OBJECT_Player)|| (pQueue[i].actor_initiative > 0) )
|
|
621 break;
|
|
622 if ((pQueue[i].uActionLength <= 0) && (PID_TYPE(pQueue[i].uPackedID) == OBJECT_Actor))
|
|
623 AI_Action_(i);
|
|
624 }
|
|
625 }
|
|
626 else
|
|
627 {
|
|
628 StepTurnQueue();
|
|
629 if (PID_TYPE(pQueue[0].uPackedID) == OBJECT_Player)
|
|
630 uActiveCharacter = PID_ID(pQueue[0].uPackedID) + 1;
|
1333
|
631 else
|
2242
|
632 uActiveCharacter = 0;
|
|
633 viewparams->bRedrawGameUI = 1;
|
|
634 }
|
|
635 for ( i = 0; i < uActorQueueSize; ++i )
|
|
636 AIAttacks(i);
|
1333
|
637 }
|
1332
|
638
|
|
639 //----- (00406648) --------------------------------------------------------
|
1448
|
640 void stru262_TurnBased::AIAttacks( unsigned int queue_index )
|
1546
|
641 {
|
2242
|
642 //TurnBased_QueueElem *v1; // ecx@1
|
|
643 //int v3; // eax@1
|
|
644 unsigned int actor_id; // ebx@2
|
|
645 //Actor *v5; // esi@2
|
|
646 char v19; // al@24
|
|
647 AIDirection a3; // [sp+Ch] [bp-3Ch]@2
|
|
648 AIDirection a4; // [sp+28h] [bp-20h]@2
|
|
649 //TurnBased_QueueElem *v28; // [sp+44h] [bp-4h]@1
|
|
650 //unsigned int a2a; // [sp+50h] [bp+8h]@2
|
1332
|
651
|
2242
|
652 //v1 = &pQueue[queue_index];
|
|
653 //v28 = v1;
|
|
654 //v3 = pQueue[queue_index].uPackedID;
|
|
655 if (PID_TYPE(pQueue[queue_index].uPackedID) == OBJECT_Actor)
|
|
656 {
|
|
657 actor_id = PID_ID(pQueue[queue_index].uPackedID);
|
|
658 //a2a = ai_near_actors_targets_pid[v4];
|
|
659 Actor::GetDirectionInfo(pQueue[queue_index].uPackedID, ai_near_actors_targets_pid[actor_id], &a3, 0);
|
|
660 memcpy(&a4, &a3, sizeof(a4));
|
|
661 //v5 = &pActors[v4];
|
|
662 //LOWORD(v3) = v5->uAIState;
|
|
663 if (( pActors[actor_id].uAIState != AIState::Dead ) && ( pActors[actor_id].uAIState != AIState::Disabled )
|
|
664 &&( pActors[actor_id].uAIState != AIState::Removed ))
|
|
665 {
|
|
666 pActors[actor_id].uCurrentActionTime += pEventTimer->uTimeElapsed;
|
|
667 if ( (signed int)pActors[actor_id].uCurrentActionTime >= pActors[actor_id].uCurrentActionLength )
|
|
668 {
|
|
669 switch (pActors[actor_id].uAIState)
|
1332
|
670 {
|
2242
|
671 case AIState::AttackingMelee:
|
|
672 v19 = pActors[actor_id].special_ability_use_check(actor_id);
|
|
673 AttackerInfo.Add( pQueue[queue_index].uPackedID, 5120, pActors[actor_id].vPosition.x, pActors[actor_id].vPosition.y,
|
|
674 pActors[actor_id].vPosition.z + ((signed int)pActors[actor_id].uActorHeight >> 1), v19, 1);
|
|
675 Actor::AI_Stand(actor_id, ai_near_actors_targets_pid[actor_id], 0, &a4);
|
|
676 break;
|
|
677 case AIState::AttackingRanged1:
|
|
678 Actor::AI_RangedAttack(actor_id, &a4, pActors[actor_id].pMonsterInfo.uMissleAttack1Type, 0);
|
|
679 Actor::AI_Stand(actor_id, ai_near_actors_targets_pid[actor_id], 0,&a4);
|
|
680 break;
|
|
681 case AIState::Dying:
|
|
682 pActors[actor_id].uCurrentActionTime = 0;
|
|
683 pActors[actor_id].uCurrentActionLength = 0;
|
|
684 pActors[actor_id].uAIState = Dead;
|
|
685 pActors[actor_id].UpdateAnimation();
|
|
686 break;
|
|
687 case AIState::Stunned:
|
|
688 Actor::AI_Stand(actor_id, ai_near_actors_targets_pid[actor_id], 0,&a4);
|
|
689 break;
|
|
690 case AIState::AttackingRanged2:
|
|
691 Actor::AI_RangedAttack(actor_id, &a4, pActors[actor_id].pMonsterInfo.uMissleAttack2Type, 1);
|
|
692 Actor::AI_Stand(actor_id, ai_near_actors_targets_pid[actor_id], 0,&a4);
|
|
693 break;
|
|
694 case AIState::AttackingRanged3:
|
|
695 Actor::AI_SpellAttack(actor_id, &a4, pActors[actor_id].pMonsterInfo.uSpell1ID, 2, pActors[actor_id].pMonsterInfo.uSpellSkillAndMastery1);
|
|
696 Actor::AI_Stand(actor_id, ai_near_actors_targets_pid[actor_id], 0, &a4);
|
|
697 break;
|
|
698 case AIState::AttackingRanged4:
|
|
699 Actor::AI_SpellAttack(actor_id, &a4, pActors[actor_id].pMonsterInfo.uSpell2ID, 3, pActors[actor_id].pMonsterInfo.uSpellSkillAndMastery2);
|
|
700 Actor::AI_Stand(actor_id, ai_near_actors_targets_pid[actor_id], 0, &a4);
|
|
701 break;
|
|
702 default:
|
|
703 if ( !(rand() % 2) )
|
|
704 Actor::AI_Bored(actor_id, ai_near_actors_targets_pid[actor_id], &a4);
|
|
705 else
|
|
706 Actor::AI_Stand(actor_id, ai_near_actors_targets_pid[actor_id], 64,&a4);
|
1343
|
707 }
|
2242
|
708 }
|
1332
|
709 }
|
2242
|
710 }
|
|
711 }
|
2059
|
712 // 50FE08: using guessed type stru298 AttackerInfo;
|
1332
|
713
|
|
714 //----- (0040680F) --------------------------------------------------------
|
1450
|
715 void stru262_TurnBased::AI_Action_( int queue_index )
|
2242
|
716 {
|
|
717 unsigned int actor_id; // edi@2
|
|
718 AIDirection v7; // esi@10
|
|
719 int v9; // ecx@10
|
|
720 signed int v10; // eax@13
|
|
721 int v14; // eax@29
|
|
722 AIDirection a3; // [sp+Ch] [bp-44h]@10
|
|
723 AIDirection v18; // [sp+28h] [bp-28h]@10
|
|
724 signed int v22; // [sp+58h] [bp+8h]@10
|
1367
|
725
|
2242
|
726 pQueue[queue_index].uActionLength = 0;
|
|
727 if (PID_TYPE(pQueue[queue_index].uPackedID) == OBJECT_Actor)
|
|
728 {
|
|
729 actor_id = PID_ID(pQueue[queue_index].uPackedID);
|
|
730 if (!(pActors[actor_id].uAIState == AIState::Dying || pActors[actor_id].uAIState == AIState::Dead || pActors[actor_id].uAIState == AIState::Summoned ||
|
|
731 pActors[actor_id].uAIState == AIState::Disabled || pActors[actor_id].uAIState == AIState::Removed))
|
|
732 {
|
|
733 Actor::_SelectTarget(actor_id, &ai_near_actors_targets_pid[actor_id], true);
|
|
734 v22 = ai_near_actors_targets_pid[actor_id];
|
|
735 if ( pActors[actor_id].pMonsterInfo.uHostilityType && !v22)
|
|
736 pActors[actor_id].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
|
|
737 Actor::GetDirectionInfo(PID(OBJECT_Actor,actor_id), v22, &v7, 0);
|
|
738 memcpy(&a3, &v7, sizeof(AIDirection));
|
|
739 memcpy(&v18, &a3, sizeof(AIDirection));
|
|
740 v9 = a3.uDistance - pActors[actor_id].uActorRadius;
|
|
741 if ( v9 < 0 )
|
|
742 v9 = 0;
|
|
743 if (PID_TYPE(v22) == OBJECT_Actor)
|
|
744 //v10 = (unsigned __int8)*(&byte_5C8D1A[89 * (pMonsterStats->pInfos[pActors[PID_ID(v22)].pMonsterInfo.uID].uID - 1) / 3] + (v5->pMonsterInfo.uID - 1) / 3);
|
|
745 v10 = pFactionTable->relations[(pMonsterStats->pInfos[pActors[PID_ID(v22)].pMonsterInfo.uID].uID) / 3 + 1][(pActors[actor_id].pMonsterInfo.uID - 1) / 3 + 1];
|
|
746 else
|
|
747 v10 = 4;
|
|
748 switch (v10)
|
|
749 {
|
|
750 case 1:
|
|
751 if ( (double)(signed int)v9 < 307.2 )
|
|
752 pActors[actor_id].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
|
|
753 break;
|
|
754 case 2:
|
|
755 if ( v9 < 1024 )
|
|
756 pActors[actor_id].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
|
|
757 break;
|
|
758 case 3:
|
|
759 if ( v9 < 2560 )
|
|
760 pActors[actor_id].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
|
|
761 break;
|
|
762 case 4:
|
|
763 if ( v9 < 5120 )
|
|
764 pActors[actor_id].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
|
|
765 break;
|
|
766 }
|
|
767 if ( pActors[actor_id].pMonsterInfo.uHostilityType == 4 && v22 && (signed int)v9 < 5120 )
|
|
768 {
|
|
769 v14 = pActors[actor_id].special_ability_use_check(actor_id);
|
|
770 pQueue[queue_index].AI_action_type = TE_AI_STAND;
|
|
771 switch (v14)
|
|
772 {
|
|
773 case 1:
|
|
774 if ( pActors[actor_id].pMonsterInfo.uMissleAttack2Type )
|
|
775 {
|
|
776 Actor::AI_MissileAttack2(actor_id, v22, &v18);
|
|
777 pQueue[queue_index].AI_action_type = TE_AI_RANGED_ATTACK;
|
1367
|
778 }
|
2242
|
779 break;
|
|
780 case 2:
|
|
781 if ( pActors[actor_id].pMonsterInfo.uSpell1ID )
|
|
782 {
|
|
783 Actor::AI_SpellAttack1(actor_id, v22, &v18);
|
|
784 pQueue[queue_index].AI_action_type = TE_AI_RANGED_ATTACK;
|
|
785 }
|
|
786 break;
|
|
787 case 3:
|
|
788 if (pActors[actor_id].pMonsterInfo.uSpell2ID)
|
|
789 {
|
|
790 Actor::AI_SpellAttack2(actor_id, v22, &v18);
|
|
791 pQueue[queue_index].AI_action_type = TE_AI_RANGED_ATTACK;
|
|
792 }
|
|
793 break;
|
|
794 default:
|
|
795 if ( pActors[actor_id].pMonsterInfo.uMissleAttack1Type )
|
|
796 {
|
|
797 Actor::AI_MissileAttack1(actor_id, v22, &v18);
|
|
798 pQueue[queue_index].AI_action_type = TE_AI_RANGED_ATTACK;
|
|
799 }
|
1367
|
800 }
|
2244
|
801 //if (!pQueue[queue_index].AI_action_type)
|
2242
|
802 if ( (double)v9 < 307.2)
|
|
803 {
|
|
804 Actor::AI_MeleeAttack(actor_id, v22, &v18);
|
|
805 pQueue[queue_index].AI_action_type = TE_AI_MELEE_ATTACK;
|
2244
|
806 pQueue[queue_index].uActionLength = pActors[actor_id].uCurrentActionLength;
|
|
807 return;
|
2242
|
808 }
|
|
809 else
|
|
810 {
|
|
811 Actor::AI_Stand(actor_id, v22, 64, &v18);
|
|
812 pQueue[queue_index].AI_action_type = TE_AI_STAND;
|
2244
|
813 pQueue[queue_index].uActionLength = pActors[actor_id].uCurrentActionLength;
|
|
814 return;
|
2242
|
815 }
|
|
816 }
|
|
817 else
|
|
818 {
|
|
819 Actor::AI_Stand(actor_id, v22, 64, &v18);
|
|
820 pQueue[queue_index].AI_action_type = TE_AI_STAND;
|
|
821 }
|
|
822 pQueue[queue_index].uActionLength = pActors[actor_id].uCurrentActionLength;
|
1332
|
823 }
|
2242
|
824 }
|
|
825 }
|
1332
|
826
|
|
827 //----- (00406A63) --------------------------------------------------------
|
1450
|
828 void stru262_TurnBased::ActorAISetMovementDecision()
|
2242
|
829 {
|
|
830 AIDirection a3; // [sp+8h] [bp-44h]@5
|
|
831 AIDirection v7; // [sp+24h] [bp-28h]@5
|
|
832 unsigned int target_pid; // [sp+40h] [bp-Ch]@5
|
|
833 int i;
|
1332
|
834
|
2242
|
835 this->ai_turn_timer = 64;
|
|
836 dword_50C994 = 0;
|
|
837 uActiveCharacter = 0;
|
|
838 for ( i = 0; i < uActorQueueSize; ++i )
|
|
839 {
|
|
840 if (PID_TYPE(pQueue[i].uPackedID) == OBJECT_Actor)
|
|
841 {
|
|
842 target_pid = ai_near_actors_targets_pid[PID_ID(pQueue[i].uPackedID)];
|
|
843 Actor::GetDirectionInfo(pQueue[i].uPackedID, target_pid, &v7, 0);
|
|
844 if ( !ActorMove(i) )
|
|
845 Actor::AI_Stand(PID_ID(pQueue[i].uPackedID), target_pid, 32, &v7);
|
1332
|
846 }
|
2242
|
847 }
|
|
848 }
|
1332
|
849 // 50C994: using guessed type int dword_50C994;
|
|
850
|
|
851 //----- (00406AFE) --------------------------------------------------------
|
1450
|
852 void stru262_TurnBased::ActorAIStopMovement()
|
2242
|
853 {
|
|
854 AIDirection a3; // [sp+4h] [bp-48h]@5
|
|
855 AIDirection v7; // [sp+20h] [bp-2Ch]@5
|
|
856 unsigned int target_pid;
|
|
857 int i;
|
1332
|
858
|
2242
|
859 for ( i = 0; i < uActorQueueSize; ++i )
|
|
860 {
|
|
861 if (PID_TYPE(pQueue[i].uPackedID) == OBJECT_Actor)
|
|
862 {
|
|
863 target_pid = ai_near_actors_targets_pid[PID_ID(pQueue[i].uPackedID)];
|
|
864 Actor::GetDirectionInfo(pQueue[i].uPackedID, target_pid, &v7, 0);
|
|
865 Actor::AI_Stand(PID_ID(pQueue[i].uPackedID), target_pid, 32, &v7);
|
|
866 pQueue[i].AI_action_type = TE_AI_STAND;
|
|
867 pQueue[i].uActionLength = 0;
|
1332
|
868 }
|
2242
|
869 }
|
|
870 turn_stage = TE_ATTACK;
|
|
871 ai_turn_timer = 100;
|
|
872 }
|
1332
|
873
|
|
874 //----- (00406B9F) --------------------------------------------------------
|
1450
|
875 void stru262_TurnBased::ActorAIDoAdditionalMove()
|
2242
|
876 {
|
|
877 AIDirection a3; // [sp+0h] [bp-50h]@15
|
|
878 AIDirection v9; // [sp+1Ch] [bp-34h]@15
|
|
879 unsigned int v13; // [sp+44h] [bp-Ch]@8
|
|
880 unsigned int monster_id;
|
|
881
|
|
882 for ( int i = 0; i < uActorQueueSize; ++i )
|
|
883 {
|
|
884 if (PID_TYPE(pQueue[i].uPackedID) == OBJECT_Actor)
|
1332
|
885 {
|
2242
|
886 monster_id = PID_ID(pQueue[i].uPackedID);
|
|
887 if ( !(pActors[monster_id].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0|| (pActors[monster_id].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0) ||
|
|
888 pActors[monster_id].uAIState == AIState::Dead || pActors[monster_id].uAIState == AIState::Removed || pActors[monster_id].uAIState == AIState::Disabled) )
|
|
889 {
|
|
890 v13 = ai_near_actors_targets_pid[PID_ID(pQueue[i].uPackedID)];
|
|
891 Actor::GetDirectionInfo(pQueue[i].uPackedID, v13, &v9, 0);
|
|
892 if ( pActors[monster_id].uAIState == AIState::Pursuing || pActors[monster_id].uAIState == AIState::Tethered )
|
1332
|
893 {
|
2242
|
894 if ( (double)(signed int)v9.uDistance < 307.2 )
|
|
895 Actor::AI_Stand(PID_ID(pQueue[i].uPackedID), v13, 32, &v9);
|
|
896 }
|
|
897 else
|
|
898 {
|
|
899 pActors[monster_id].uCurrentActionTime += pEventTimer->uTimeElapsed;
|
|
900 if ( pActors[monster_id].uCurrentActionTime > pActors[monster_id].uCurrentActionLength )
|
|
901 {
|
|
902 if ( pActors[monster_id].uAIState == AIState::Dying )
|
1332
|
903 {
|
2242
|
904 pActors[monster_id].uCurrentActionTime = 0;
|
|
905 pActors[monster_id].uCurrentActionLength = 0;
|
|
906 pActors[monster_id].uAIState = AIState::Dead;
|
|
907 pActors[monster_id].UpdateAnimation();
|
1332
|
908 }
|
2242
|
909 if ( !ActorMove(i) )
|
|
910 Actor::AI_Stand(PID_ID(pQueue[i].uPackedID), v13, 32, &v9);
|
|
911 }
|
1332
|
912 }
|
2242
|
913 }
|
1332
|
914 }
|
2242
|
915 }
|
|
916 }
|
1332
|
917
|
|
918 //----- (00406D10) --------------------------------------------------------
|
1450
|
919 bool stru262_TurnBased::ActorMove(signed int queue_position)
|
2242
|
920 {
|
|
921 AIDirection v9; // esi@10
|
|
922 int v11; // ecx@10
|
|
923 unsigned __int8 pHostileType; // al@12
|
|
924 AIDirection a3; // [sp+Ch] [bp-48h]@10
|
|
925 AIDirection pDir; // [sp+28h] [bp-2Ch]@10
|
|
926 unsigned int uActorID; // [sp+50h] [bp-4h]@2
|
1448
|
927
|
2242
|
928 if (PID_TYPE(pQueue[queue_position].uPackedID) == OBJECT_Player)
|
|
929 return 0;
|
|
930 uActorID = PID_ID(pQueue[queue_position].uPackedID);
|
|
931 if ( pActors[uActorID].uAIState == AIState::Dead || pActors[uActorID].uAIState == AIState::Dying ||
|
|
932 pActors[uActorID].uAIState == AIState::Removed|| pActors[uActorID].uAIState == AIState::Disabled ||
|
|
933 pActors[uActorID].uAIState == AIState::Summoned )
|
|
934 return 1;
|
|
935 Actor::_SelectTarget(uActorID, &ai_near_actors_targets_pid[uActorID], true);
|
|
936 if ( pActors[uActorID].pMonsterInfo.uHostilityType && !ai_near_actors_targets_pid[uActorID] )
|
|
937 pActors[uActorID].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
|
|
938 Actor::GetDirectionInfo(pQueue[queue_position].uPackedID, ai_near_actors_targets_pid[uActorID], &v9, 0);
|
|
939 memcpy(&a3, &v9, sizeof(AIDirection));
|
|
940 memcpy(&pDir, &a3, sizeof(AIDirection));
|
|
941 v11 = a3.uDistance - pActors[uActorID].uActorRadius;
|
|
942 if ( v11 < 0 )
|
|
943 v11 = 0;
|
|
944 pHostileType = pActors[uActorID].pMonsterInfo.uHostilityType;
|
|
945 switch (pHostileType)
|
|
946 {
|
|
947 case 1:
|
|
948 if ( (double)v11 < 307.2 )
|
|
949 pActors[uActorID].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
|
|
950 break;
|
|
951 case 2:
|
|
952 if ( v11 < 1024 )
|
|
953 pActors[uActorID].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
|
|
954 break;
|
|
955 case 3:
|
|
956 if ( v11 < 2560 )
|
|
957 pActors[uActorID].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
|
|
958 break;
|
|
959 }
|
|
960 if ( pActors[uActorID].pActorBuffs[ACTOR_BUFF_AFRAID].uExpireTime > 0 )
|
|
961 {
|
|
962 if (v11 < 10240 )
|
|
963 {
|
|
964 Actor::AI_Flee(uActorID, ai_near_actors_targets_pid[uActorID], 0, &pDir);
|
|
965 pTurnEngine->pQueue[queue_position].AI_action_type = 4;
|
|
966 }
|
|
967 else
|
|
968 {
|
|
969 Actor::AI_RandomMove(uActorID, ai_near_actors_targets_pid[uActorID], 1024, 0);
|
|
970 pTurnEngine->pQueue[queue_position].AI_action_type = TE_AI_PURSUE;
|
|
971 }
|
|
972 pTurnEngine->pQueue[queue_position].uActionLength = pActors[uActorID].uCurrentActionLength;
|
|
973 return true;
|
|
974 }
|
|
975 if ( pActors[uActorID].pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Long )
|
|
976 {
|
|
977 if ( !(pActors[uActorID].uAttributes & 0x020000) || pActors[uActorID].pMonsterInfo.uAIType == 1 )
|
|
978 {
|
|
979 if ( pActors[uActorID].pMonsterInfo.uAIType == 1 )
|
|
980 {
|
|
981 if ( pActors[uActorID].pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
|
|
982 Actor::AI_Stand(uActorID, ai_near_actors_targets_pid[uActorID], 32, 0);
|
|
983 else
|
|
984 Actor::AI_Flee(uActorID, ai_near_actors_targets_pid[uActorID], 32, 0);
|
|
985 pTurnEngine->pQueue[queue_position].AI_action_type = TE_AI_FLEE;
|
|
986 pTurnEngine->pQueue[queue_position].uActionLength = pActors[uActorID].uCurrentActionLength;
|
|
987 return true;
|
|
988 }
|
|
989 if ( pActors[uActorID].pMonsterInfo.uAIType == 2 )
|
|
990 {
|
|
991 if (((double)pActors[uActorID].pMonsterInfo.uHP * 0.2) > (double)pActors[uActorID].sCurrentHP && (v11 < 10240 ) )
|
1332
|
992 {
|
2242
|
993 if ( pActors[uActorID].pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
|
|
994 Actor::AI_Stand(uActorID, ai_near_actors_targets_pid[uActorID], 32, 0);
|
|
995 else
|
|
996 Actor::AI_Flee(uActorID, ai_near_actors_targets_pid[uActorID], 32, 0);
|
|
997 pTurnEngine->pQueue[queue_position].AI_action_type = TE_AI_FLEE;
|
|
998 pTurnEngine->pQueue[queue_position].uActionLength = pActors[uActorID].uCurrentActionLength;
|
|
999 return true;
|
|
1000 }
|
|
1001 }
|
|
1002 if ( pActors[uActorID].pMonsterInfo.uAIType == 3 )
|
|
1003 {
|
|
1004 if ( ((double)pActors[uActorID].pMonsterInfo.uHP * 0.1) > (double)pActors[uActorID].sCurrentHP && (v11 < 10240 ))
|
|
1005 {
|
|
1006 if ( pActors[uActorID].pMonsterInfo.uMovementType == MONSTER_MOVEMENT_TYPE_STAIONARY )
|
|
1007 Actor::AI_Stand(uActorID, ai_near_actors_targets_pid[uActorID], 32, 0);
|
|
1008 else
|
|
1009 Actor::AI_Flee(uActorID, ai_near_actors_targets_pid[uActorID], 32, 0);
|
|
1010 pTurnEngine->pQueue[queue_position].AI_action_type = TE_AI_FLEE;
|
|
1011 pTurnEngine->pQueue[queue_position].uActionLength = pActors[uActorID].uCurrentActionLength;
|
|
1012 return true;
|
1332
|
1013 }
|
2242
|
1014 }
|
|
1015 }
|
|
1016 if ( (double)(signed int)v11 < 307.2 )
|
|
1017 return 0;
|
1332
|
1018 if ( (signed int)v11 < 5120 )
|
2242
|
1019 {
|
|
1020 if ( pActors[uActorID].pMonsterInfo.uMissleAttack1Type && (signed int)v11 < 1024 )
|
|
1021 Actor::AI_Pursue1(uActorID, ai_near_actors_targets_pid[uActorID], uActorID, 32, &pDir);
|
|
1022 else
|
|
1023 Actor::AI_Pursue2(uActorID, ai_near_actors_targets_pid[uActorID], 32, &pDir, 307);
|
|
1024 pTurnEngine->pQueue[queue_position].AI_action_type = TE_AI_PURSUE;
|
|
1025 pTurnEngine->pQueue[queue_position].uActionLength = pActors[uActorID].uCurrentActionLength;
|
|
1026 return true;
|
1332
|
1027 }
|
2242
|
1028 }
|
|
1029 switch(pActors[uActorID].pMonsterInfo.uMovementType)
|
|
1030 {
|
|
1031 case MONSTER_MOVEMENT_TYPE_SHORT:
|
|
1032 Actor::AI_RandomMove(uActorID, ai_near_actors_targets_pid[uActorID], 1024, 32);
|
|
1033 break;
|
|
1034 case MONSTER_MOVEMENT_TYPE_MEDIUM:
|
|
1035 Actor::AI_RandomMove(uActorID, ai_near_actors_targets_pid[uActorID], 2560, 32);
|
|
1036 break;
|
|
1037 case MONSTER_MOVEMENT_TYPE_LONG:
|
|
1038 Actor::AI_RandomMove(uActorID, ai_near_actors_targets_pid[uActorID], 5120, 32);
|
|
1039 break;
|
|
1040 case MONSTER_MOVEMENT_TYPE_FREE:
|
|
1041 Actor::AI_RandomMove(uActorID, ai_near_actors_targets_pid[uActorID], 10240, 32);
|
|
1042 break;
|
|
1043 case MONSTER_MOVEMENT_TYPE_STAIONARY:
|
|
1044 Actor::AI_Stand(uActorID, ai_near_actors_targets_pid[uActorID], 32, 0);
|
|
1045 break;
|
|
1046 default:
|
|
1047 return true;
|
|
1048 }
|
|
1049 pTurnEngine->pQueue[queue_position].AI_action_type = TE_AI_PURSUE;
|
|
1050 pTurnEngine->pQueue[queue_position].uActionLength = pActors[uActorID].uCurrentActionLength;
|
|
1051 return true;
|
|
1052 }
|
1332
|
1053
|
1367
|
1054 //----- (00406FA8) --------------------------------------------------------
|
1450
|
1055 void stru262_TurnBased::ActorAIChooseNewTargets()
|
2242
|
1056 {
|
|
1057 Actor *curr_acror; // ebx@4
|
|
1058 AIDirection a3; // [sp+Ch] [bp-6Ch]@8
|
|
1059 AIDirection v9; // [sp+28h] [bp-50h]@8
|
|
1060 AIDirection a4; // [sp+44h] [bp-34h]@8
|
|
1061 unsigned int target_pid; // [sp+60h] [bp-18h]@1
|
|
1062 int uActorID; // [sp+68h] [bp-10h]@4
|
|
1063 int i;
|
|
1064
|
|
1065 for ( i = 0; i < uActorQueueSize; ++i )
|
|
1066 {
|
|
1067 if (PID_TYPE(pQueue[i].uPackedID) == OBJECT_Actor)
|
1332
|
1068 {
|
2242
|
1069 uActorID=PID_ID(pQueue[i].uPackedID);
|
|
1070 curr_acror = &pActors[uActorID];
|
|
1071 if ( !( curr_acror->uAIState == AIState::Summoned|| curr_acror->uAIState == AIState::Dead ||
|
|
1072 curr_acror->uAIState == AIState::Removed || curr_acror->uAIState == AIState::Disabled) )
|
|
1073 {
|
|
1074 target_pid = ai_near_actors_targets_pid[uActorID];
|
|
1075 Actor::_SelectTarget(uActorID, &ai_near_actors_targets_pid[uActorID], true);
|
|
1076 Actor::GetDirectionInfo(pQueue[i].uPackedID, target_pid, &v9, 0);
|
|
1077 memcpy(&a4, &v9, sizeof(AIDirection));
|
|
1078 curr_acror->uCurrentActionTime += pEventTimer->uTimeElapsed;
|
|
1079 if ( curr_acror->uCurrentActionTime > curr_acror->uCurrentActionLength )
|
1332
|
1080 {
|
2242
|
1081 if ( curr_acror->uAIState == AIState::Dying )
|
|
1082 {
|
|
1083 curr_acror->uCurrentActionTime = 0;
|
|
1084 curr_acror->uCurrentActionLength = 0;
|
|
1085 curr_acror->uAIState = AIState::Dead;
|
|
1086 curr_acror->UpdateAnimation();
|
|
1087 break;
|
|
1088 }
|
|
1089 if ( rand() % 2 )
|
|
1090 Actor::AI_Stand(uActorID, target_pid, 64, &a4);
|
|
1091 else
|
|
1092 Actor::AI_Bored(uActorID, target_pid, &a4);
|
1332
|
1093 }
|
2242
|
1094 }
|
1332
|
1095 }
|
2242
|
1096 }
|
|
1097 }
|
1332
|
1098
|