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