Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
1A5830.c
Go to the documentation of this file.
1#include "battle/battle.h"
2#include "script_api/battle.h"
3#include "effects.h"
4#include "hud_element.h"
5#include "sprite.h"
6#include "dx/debug_menu.h"
7
9 ActorPart* partIt = actor->partsTable;
10 s32 ret = FALSE;
11
12 while (partIt != NULL) {
14 ret = TRUE;
15 break;
16 } else {
17 partIt = partIt->nextPart;
18 }
19 }
20
21 return ret;
22}
23
24void dispatch_event_general(Actor* actor, s32 event) {
25 switch (actor->actorID & ACTOR_CLASS_MASK) {
28 break;
31 break;
33 dispatch_event_actor(actor, event);
34 break;
35 }
36}
37
38void play_hit_sound(Actor* actor, f32 x, f32 y, f32 z, u32 hitSound) {
39 s32 actorClass = actor->actorID & ACTOR_CLASS_MASK;
40
41 switch (hitSound) {
42 case HIT_SOUND_MISS:
44 break;
45 case HIT_SOUND_BONES:
47 break;
49 switch (actorClass) {
52 break;
55 break;
58 break;
59 }
60 break;
61 case HIT_SOUND_FIRE:
62 switch (actorClass) {
65 break;
68 break;
71 break;
72 }
73 break;
74 case HIT_SOUND_ICE:
75 switch (actorClass) {
78 break;
81 break;
84 break;
85 }
86 break;
87 case HIT_SOUND_SHOCK:
88 switch (actorClass) {
91 break;
94 break;
97 break;
98 }
99 break;
100 }
101}
102
103void dispatch_event_actor(Actor* actor, s32 event) {
104 Evt* handleEventScript = actor->handleEventScript;
105 s32 onHitID = actor->handleEventScriptID;
106
107 if (actor->handleEventSource != NULL) {
108 Evt* newScript;
109
110 actor->lastEventType = event;
112 actor->handleEventScript = newScript;
113 actor->handleEventScriptID = newScript->id;
114 newScript->owner1.actorID = actor->actorID;
115 }
116
117 if (actor->takeTurnScript != NULL) {
120 actor->takeTurnScript = NULL;
121 }
122
123 if (handleEventScript != NULL) {
124 kill_script_by_ID(onHitID);
125 }
126}
127
129 PlayerData* playerData = &gPlayerData;
130 BattleStatus* battleStatus = &gBattleStatus;
131 s32 targetID = battleStatus->curTargetID;
132 s32 targetPartIdx = battleStatus->curTargetPart;
133 Actor* target;
134 Actor* target2;
135 ActorPart* targetPart;
136 s32 actorClass;
137 s32 hitResult;
138
139 battleStatus->curTargetID2 = battleStatus->curTargetID;
140 battleStatus->curTargetPart2 = battleStatus->curTargetPart;
141
142 target = get_actor(targetID);
143 if (target == NULL) {
144 return HIT_RESULT_HIT;
145 }
146
147 targetPart = get_actor_part(target, targetPartIdx);
148 ASSERT(targetPart != NULL);
149
150 actorClass = targetID & ACTOR_CLASS_MASK;
151 switch (actorClass) {
153 target->curHP = playerData->curHP;
154 break;
156 target->curHP = 127;
157 break;
159 break;
160 }
161
162 if (battleStatus->curAttackElement & DAMAGE_TYPE_TRIGGER_LUCKY) {
164 return HIT_RESULT_HIT;
165 }
166
167 hitResult = HIT_RESULT_HIT;
168 target2 = target;
169 if (targetPart->eventFlags & ACTOR_EVENT_FLAG_ILLUSORY || battleStatus->outtaSightActive || target2->transparentStatus == STATUS_KEY_TRANSPARENT) {
170 if (!(battleStatus->curAttackElement & DAMAGE_TYPE_MAGIC)) {
171 hitResult = HIT_RESULT_MISS;
172 }
173 }
174
175 if (hitResult == HIT_RESULT_MISS) {
176 return HIT_RESULT_MISS;
177 }
178 hitResult = HIT_RESULT_HIT;
179 switch (actorClass) {
181 if (battleStatus->cloudNineTurnsLeft) {
182 if (rand_int(100) < battleStatus->cloudNineDodgeChance) {
183 hitResult = HIT_RESULT_MISS;
184 break;
185 }
186 } else {
188 if (rand_int(100) < 10) {
189 hitResult = HIT_RESULT_LUCKY;
190 break;
191 }
192 }
193 if (player_team_is_ability_active(target2, ABILITY_CLOSE_CALL) && (target2->curHP < 6)) {
194 if (rand_int(100) < 30) {
195 hitResult = HIT_RESULT_LUCKY;
196 break;
197 }
198 }
200 if (rand_int(100) < 20) {
201 hitResult = HIT_RESULT_LUCKY;
202 break;
203 }
204 }
205 }
206 break;
208 break;
210 break;
211 }
212
213 if (hitResult == HIT_RESULT_MISS) {
214 return HIT_RESULT_MISS;
215 }
216
217 if (hitResult == HIT_RESULT_LUCKY) {
218 return HIT_RESULT_LUCKY;
219 }
220
221 if (target2->stoneStatus == STATUS_KEY_STONE) {
222 return HIT_RESULT_IMMUNE;
223 }
224
225 if (target2->staticStatus == STATUS_KEY_STATIC) {
227 }
228
229 return HIT_RESULT_HIT;
230}
231
233 BattleStatus* battleStatus = &gBattleStatus;
234 ActorState* state = &attacker->state;
235 s32 targetID = battleStatus->curTargetID;
236 s32 targetPartIdx = battleStatus->curTargetPart;
237 s32 actorClass;
238 Actor* target;
239 ActorPart* targetPart;
240 s32 hitResult;
241 s32 one = TRUE;
242 s32 statusInflicted = FALSE;
243 s32 statusInflicted2 = FALSE;
244 s32 isFire = FALSE;
245 s32 isWater = FALSE;
246 s32 isIce = FALSE;
247 s32 isElectric = FALSE;
248 s32 madeElectricContact = FALSE;
249 s32 isPlayer;
250 s32 defense;
251 s32 event;
252 s32 damage;
253 Evt* script;
254
255 battleStatus->wasStatusInflicted = FALSE;
256 battleStatus->lastAttackDamage = 0;
257
258 battleStatus->attackerActorID = attacker->actorID;
259 battleStatus->curTargetID2 = targetID;
260 battleStatus->curTargetPart2 = targetPartIdx;
261
262 target = get_actor(targetID);
263 if (target == NULL) {
264 return HIT_RESULT_HIT;
265 }
266
267 targetPart = get_actor_part(target, targetPartIdx);
268 ASSERT(targetPart != NULL);
269
270 actorClass = targetID & ACTOR_CLASS_MASK;
271 target->lastDamageTaken = 0;
272
273 switch (actorClass) {
275 target->curHP = gPlayerData.curHP;
276 break;
278 target->curHP = 127;
279 break;
281 break;
282 }
283
284 // handle defender status
285
286 if (targetPart->eventFlags & ACTOR_EVENT_FLAG_ILLUSORY) {
287 return HIT_RESULT_MISS;
288 }
289
291 || (targetPart->eventFlags & ACTOR_EVENT_FLAG_BURIED && !(battleStatus->curAttackElement & DAMAGE_TYPE_QUAKE))
292 ) {
293 return HIT_RESULT_MISS;
294 }
295
296 if (target->stoneStatus == STATUS_KEY_STONE) {
297 show_immune_bonk(state->goalPos.x, state->goalPos.y, state->goalPos.z, 0, 1, -1);
298 show_next_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, 0, 0);
299 play_hit_sound(attacker, state->goalPos.x, state->goalPos.y, state->goalPos.z, 0);
301 return HIT_RESULT_HIT;
302 }
303
304 // handle attack element
305
306 if (battleStatus->curAttackElement & DAMAGE_TYPE_BLAST) {
307 if (!(battleStatus->curAttackElement & DAMAGE_TYPE_NO_CONTACT)
309 ) {
310 play_hit_sound(attacker, state->goalPos.x, state->goalPos.y, state->goalPos.z, 3);
312 return HIT_RESULT_BACKFIRE;
313 }
314 }
315 if ((battleStatus->curAttackElement & DAMAGE_TYPE_QUAKE) && (target->flags & ACTOR_FLAG_FLYING)) {
316 play_hit_sound(attacker, state->goalPos.x, state->goalPos.y, state->goalPos.z, 1);
318 }
319 if (battleStatus->curAttackElement & DAMAGE_TYPE_FIRE) {
320 fx_ring_blast(0, state->goalPos.x, state->goalPos.y, state->goalPos.z + 5.0f, 1.0f, 24);
321 isFire = TRUE;
322 }
323 if (battleStatus->curAttackElement & DAMAGE_TYPE_SHOCK) {
324 apply_shock_effect(target);
325 isElectric = TRUE;
326 }
327 if (battleStatus->curAttackElement & DAMAGE_TYPE_WATER) {
328 fx_water_splash(0, state->goalPos.x, state->goalPos.y, state->goalPos.z + 5.0f, 1.0f, 24);
329 isWater = TRUE;
330 }
331 if (battleStatus->curAttackElement & DAMAGE_TYPE_ICE) {
332 fx_big_snowflakes(0, state->goalPos.x, state->goalPos.y, state->goalPos.z + 5.0f);
333 isIce = TRUE;
334 }
335
336 if (!(attacker->staticStatus == STATUS_KEY_STATIC)
337 && ((target->staticStatus == STATUS_KEY_STATIC) || (targetPart->eventFlags & ACTOR_EVENT_FLAG_ELECTRIFIED))
340 && !has_enchanted_part(attacker)) // enchanted attacks ignore electrified defenders
341 {
342 madeElectricContact = TRUE;
344 }
345
346 // ------------------------------------------------------------------------
347 // damage calculation
348
349 gBattleStatus.flags1 &= ~BS_FLAGS1_ATK_BLOCKED;
350
351 // determine target defense
352
353 defense = get_defense(target, targetPart->defenseTable, battleStatus->curAttackElement);
354
355 if (!(battleStatus->curAttackElement & DAMAGE_TYPE_IGNORE_DEFENSE)) {
356 defense += target->defenseBoost;
357
358 if (actorClass == ACTOR_CLASS_PLAYER) {
359 if (battleStatus->waterBlockTurnsLeft > 0) {
360 if ((battleStatus->curAttackElement & (DAMAGE_TYPE_BLAST | DAMAGE_TYPE_FIRE))) {
361 defense += 2;
362 } else {
363 defense += 1;
364 }
365 }
366
368 defense += 1;
369 }
370 }
371 }
372
373 // apply attacker damage modifiers
374
375 damage = battleStatus->curAttackDamage;
376
377 switch (actorClass) {
379 damage -= battleStatus->merleeDefenseBoost;
380 break;
383 break;
384 }
385
386 damage += attacker->attackBoost;
387
388 if (attacker->chillOutTurns != 0) {
389 damage -= attacker->chillOutAmount;
390 }
391
392 if (attacker->debuff == STATUS_KEY_SHRINK) {
393 if (damage > 0) {
394 damage /= 2;
395 }
396 }
397
398 if (damage > 99) {
399 damage = 99;
400 }
401 if (damage < 1) {
402 defense = 0;
403 }
404
405 target->hpChangeCounter = 0;
406 damage -= defense;
407
408 // apply damage mitigation from defensive badges
409
410 isPlayer = actorClass == ACTOR_CLASS_PLAYER;
411 if (isPlayer) {
413 if (battleStatus->curAttackElement & DAMAGE_TYPE_FIRE) {
414 damage--;
415 }
416 }
417
421
422 if (target->curHP <= 5) {
424 damage /= 2;
425 }
426 }
427 }
428
429 // apply damage mitigation from blocking
430
431 switch (actorClass) {
433 // TODO figure out how to better write target->debuff >= STATUS_KEY_POISON
434 if ((target->debuff == 0 || target->debuff >= STATUS_KEY_POISON)
435 && (target->stoneStatus == 0)
436 && !(battleStatus->curAttackElement & DAMAGE_TYPE_UNBLOCKABLE)
437 ) {
438 s32 blocked;
439
441 blocked = rand_int(1);
442 } else {
443 blocked = check_block_input(BUTTON_A);
444 }
445
446 if (blocked) {
447 damage--;
450 show_action_rating(ACTION_RATING_NICE, target, state->goalPos.x, state->goalPos.y, state->goalPos.z);
452 break;
453 }
454 func_80266970(target);
455 }
456 break;
458 if (target->stoneStatus == 0) {
459 if (target->koStatus == 0 && !(battleStatus->curAttackElement & DAMAGE_TYPE_UNBLOCKABLE)) {
461 damage = 0;
463 show_action_rating(ACTION_RATING_NICE, target, state->goalPos.x, state->goalPos.y, state->goalPos.z);
465 break;
466 }
467 func_80266970(target);
468 }
469 }
470 break;
471 }
472
474 func_80266970(target);
475 }
476
477 // deal damage and determine resulting battle event
478
479 event = EVENT_HIT_COMBO;
480 if (damage < 1) {
481 target->hpChangeCounter = 0;
482 if (!(battleStatus->curAttackElement & DAMAGE_TYPE_STATUS_ALWAYS_HITS)) {
483 hitResult = HIT_RESULT_NO_DAMAGE;
484 event = EVENT_ZERO_DAMAGE;
485 } else {
486 hitResult = HIT_RESULT_NO_DAMAGE;
487 event = EVENT_ZERO_DAMAGE;
488 if (target->curHP < 1) {
489 event = EVENT_DEATH;
490 }
491 }
492 battleStatus->lastAttackDamage = 0;
493 } else {
494 target->damageCounter += damage;
495 target->hpChangeCounter -= damage;
496 battleStatus->lastAttackDamage = 0;
497 hitResult = HIT_RESULT_HIT;
498 if (!(targetPart->flags & ACTOR_PART_FLAG_DAMAGE_IMMUNE)
500 ) {
501 if (!(target->flags & ACTOR_FLAG_NO_DMG_APPLY)) {
502 target->curHP -= damage;
503 }
504
505 if (target->curHP < 1) {
506 target->curHP = 0;
507 event = EVENT_DEATH;
508 }
509 }
510 battleStatus->lastAttackDamage += damage;
511 target->lastDamageTaken = battleStatus->lastAttackDamage;
512 target->hpChangeCounter = 0;
513
514 if (actorClass == ACTOR_CLASS_PLAYER) {
515 battleStatus->damageTaken += damage;
516 gPlayerData.curHP = target->curHP;
517 }
518 }
519
521 if (event == EVENT_HIT_COMBO) {
522 event = EVENT_HIT;
523 }
524 if (event == EVENT_ZERO_DAMAGE) {
525 event = EVENT_IMMUNE;
526 }
527 if (target->curHP < 1 && event == EVENT_IMMUNE) {
528 event = EVENT_DEATH;
529 }
530 } else if (event == EVENT_DEATH) {
531 event = EVENT_HIT_COMBO;
532 }
533
535 clear_part_pal_adjustment(targetPart);
536 }
537
540 && (targetPart->eventFlags & ACTOR_EVENT_FLAG_FLIPABLE)
541 ) {
542 if (event == EVENT_HIT) {
543 event = EVENT_FLIP_TRIGGER;
544 }
545 if (event == EVENT_IMMUNE) {
546 event = EVENT_FLIP_TRIGGER;
547 }
548 }
549
552 && (targetPart->eventFlags & ACTOR_EVENT_FLAG_FLIPABLE)
553 ) {
554 if (event == EVENT_HIT_COMBO) {
555 event = EVENT_FLIP_TRIGGER;
556 }
557 if (event == EVENT_ZERO_DAMAGE) {
558 event = EVENT_FLIP_TRIGGER;
559 }
560 }
561
564 ) {
565 if (event == EVENT_HIT) {
566 event = EVENT_BURN_HIT;
567 }
568 if (event == EVENT_DEATH) {
569 event = EVENT_FIRE_DEATH;
570 }
571 isFire = TRUE;
572 }
573
575 if (event == EVENT_HIT_COMBO) {
576 event = EVENT_18;
577 }
578 if (event == EVENT_HIT) {
579 event = EVENT_BLOCK;
580 }
581 if (event == EVENT_ZERO_DAMAGE) {
582 event = EVENT_18;
583 }
584 if (event == EVENT_IMMUNE) {
585 event = EVENT_BLOCK;
586 }
587 if (event == EVENT_BURN_HIT) {
588 event = EVENT_BLOCK;
589 }
590 }
591
592 // try inflicting status effect
593
595 && battleStatus->lastAttackDamage >= 0
596 && event != EVENT_DEATH
597 && event != EVENT_SPIN_SMASH_DEATH
598 && event != EVENT_EXPLODE_TRIGGER
601 && !(actorClass == ACTOR_PLAYER && is_ability_active(ABILITY_HEALTHY_HEALTHY) && (rand_int(100) < 50)))
602 {
604 statusInflicted = one;
605 statusInflicted2 = one;
606 }
608 statusInflicted = one;
609 statusInflicted2 = one;
610 }
612 statusInflicted = one;
613 statusInflicted2 = one;
614 }
616 statusInflicted = one;
617 statusInflicted2 = one;
618 }
620 statusInflicted = one;
621 statusInflicted2 = one;
622 }
624 statusInflicted = one;
625 statusInflicted2 = one;
626 }
628 statusInflicted = one;
629 statusInflicted2 = one;
630 }
632 statusInflicted = one;
633 statusInflicted2 = one;
634 }
636 statusInflicted = one;
637 statusInflicted2 = one;
638 }
639
642 statusInflicted = one;
643 statusInflicted2 = one;
644 }
646 statusInflicted = one;
647 statusInflicted2 = one;
648 }
649
651 statusInflicted = one;
652 statusInflicted2 = one;
653 }
654
655 if (statusInflicted) {
656 if (event == EVENT_ZERO_DAMAGE) {
657 event = EVENT_HIT_COMBO;
658 }
659 if (event == EVENT_IMMUNE) {
660 event = EVENT_HIT;
661 }
662 }
663 }
664
665 // dispatch events and play damage effects
666
667 battleStatus->wasStatusInflicted = statusInflicted;
668
669 switch (actorClass) {
672 break;
675 break;
677 dispatch_event_actor(target, event);
678 break;
679 }
680
681 if (actorClass == ACTOR_CLASS_PARTNER
682 && battleStatus->lastAttackDamage > 0
684 && !(target->flags & ACTOR_FLAG_NO_DMG_APPLY))
685 {
687 }
688
689 if (!(target->flags & ACTOR_FLAG_NO_DMG_POPUP)) {
690 switch (actorClass) {
693 if (battleStatus->lastAttackDamage == 0) {
694 if (!statusInflicted2 && !statusInflicted) {
695 // immune star fx?
696 show_immune_bonk(state->goalPos.x, state->goalPos.y, state->goalPos.z, 0, 1, -3);
697 }
698 } else if (battleStatus->curAttackElement & (DAMAGE_TYPE_MULTIPLE_POPUPS | DAMAGE_TYPE_SMASH)) {
699 show_next_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage, 1);
700 show_damage_fx(target, state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage);
701 } else {
702 show_primary_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage, 1);
703 show_damage_fx(target, state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage);
704 break;
705 }
706 break;
708 if (battleStatus->lastAttackDamage == 0) {
709 if (!statusInflicted2 && !statusInflicted) {
710 show_immune_bonk(state->goalPos.x, state->goalPos.y, state->goalPos.z, 0, 1, 3);
711 }
712 } else if (battleStatus->curAttackElement & (DAMAGE_TYPE_MULTIPLE_POPUPS | DAMAGE_TYPE_SMASH)) {
713 show_next_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage, 0);
714 show_damage_fx(target, state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage);
715 } else {
716 show_primary_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage, 0);
717 show_damage_fx(target, state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage);
718 }
719 break;
720 }
721 }
722
723 if (battleStatus->lastAttackDamage > 0) {
724 u32 hitSound;
725
726 set_actor_flash_mode(target, 1);
727
728 if (attacker->actorTypeData1[5] != SOUND_NONE) {
730 }
731
732 if (isFire) {
733 hitSound = HIT_SOUND_FIRE;
734 } else if (!isElectric) {
735 hitSound = HIT_SOUND_NORMAL;
736 } else {
737 hitSound = HIT_SOUND_SHOCK;
738 }
739
740 play_hit_sound(target, state->goalPos.x, state->goalPos.y, state->goalPos.z, hitSound);
741 }
742
743 if ((battleStatus->lastAttackDamage < 1 && !statusInflicted2 && !madeElectricContact) || targetPart->flags & ACTOR_PART_FLAG_DAMAGE_IMMUNE) {
745 }
746
747 if ((battleStatus->curAttackStatus & STATUS_FLAG_SLEEP) && statusInflicted) {
749 script->varTable[0] = state->goalPos.x;
750 script->varTable[1] = state->goalPos.y;
751 script->varTable[2] = state->goalPos.z;
753 }
754 if ((battleStatus->curAttackStatus & STATUS_FLAG_DIZZY) && statusInflicted) {
756 script->varTable[0] = state->goalPos.x;
757 script->varTable[1] = state->goalPos.y;
758 script->varTable[2] = state->goalPos.z;
760 }
761 if ((battleStatus->curAttackStatus & STATUS_FLAG_PARALYZE) && statusInflicted) {
763 script->varTable[0] = state->goalPos.x;
764 script->varTable[1] = state->goalPos.y;
765 script->varTable[2] = state->goalPos.z;
767 }
768 if ((battleStatus->curAttackStatus & STATUS_FLAG_POISON) && statusInflicted) {
770 script->varTable[0] = state->goalPos.x;
771 script->varTable[1] = state->goalPos.y;
772 script->varTable[2] = state->goalPos.z;
774 }
775 if ((battleStatus->curAttackStatus & STATUS_FLAG_STOP) && statusInflicted) {
777 script->varTable[0] = state->goalPos.x;
778 script->varTable[1] = state->goalPos.y;
779 script->varTable[2] = state->goalPos.z;
781 }
782 if ((battleStatus->curAttackStatus & STATUS_FLAG_FROZEN) && statusInflicted) {
784 script->varTable[0] = state->goalPos.x;
785 script->varTable[1] = state->goalPos.y;
786 script->varTable[2] = state->goalPos.z;
787 script->varTablePtr[3] = target;
789 }
790 if ((battleStatus->curAttackStatus & STATUS_FLAG_SHRINK) && statusInflicted) {
792 script->varTable[0] = state->goalPos.x;
793 script->varTable[1] = state->goalPos.y;
794 script->varTable[2] = state->goalPos.z;
795 script->varTablePtr[3] = target;
797 }
798
799 if ((battleStatus->curAttackElement & DAMAGE_TYPE_SMASH) && target->actorType == ACTOR_TYPE_GOOMNUT_TREE) {
801 }
802
803 show_actor_health_bar(target);
804
805 if (attacker->staticStatus != STATUS_KEY_STATIC
807 && !(battleStatus->curAttackElement & DAMAGE_TYPE_NO_CONTACT)
810 && !has_enchanted_part(attacker))
811 {
813 apply_shock_effect(attacker);
815 return HIT_RESULT_BACKFIRE;
816 }
817
818 return hitResult;
819}
820
821s32 dispatch_damage_event_actor(Actor* actor, s32 damageAmount, s32 originalEvent, s32 stopMotion) {
822 BattleStatus* battleStatus = &gBattleStatus;
823 ActorState* state = &actor->state;
824 s32 dispatchEvent = originalEvent;
825 s32 currentAttackDamage;
826 s32 hpChangeCounter;
827 s32 hpChange;
828 s32 flagCheck;
829 s32 new_var;
830
831 battleStatus->curAttackDamage = damageAmount;
832 hpChange = (s16) damageAmount;
833 actor->hpChangeCounter += hpChange;
834 new_var = actor->hpChangeCounter;
835 hpChange = new_var;
836 actor->damageCounter += hpChange;
837 actor->hpChangeCounter -= hpChange;
838 battleStatus->lastAttackDamage = 0;
839 actor->curHP -= hpChange;
840
841 if (actor->curHP <= 0) {
842 dispatchEvent = EVENT_DEATH;
843 battleStatus->lastAttackDamage += actor->curHP;
844 actor->curHP = 0;
845 }
846
847 battleStatus->lastAttackDamage += hpChange;
848 actor->lastDamageTaken = battleStatus->lastAttackDamage;
849 battleStatus->curDamageSource = DMG_SRC_DEFAULT;
850 if (battleStatus->flags1 & BS_FLAGS1_TRIGGER_EVENTS) {
851 if (dispatchEvent == EVENT_HIT_COMBO) {
852 dispatchEvent = EVENT_HIT;
853 }
854 if (dispatchEvent == EVENT_ZERO_DAMAGE) {
855 dispatchEvent = EVENT_IMMUNE;
856 }
857 }
858 if (dispatchEvent == EVENT_DEATH) {
859 if (originalEvent == EVENT_SPIN_SMASH_LAUNCH_HIT) {
860 dispatchEvent = EVENT_SPIN_SMASH_LAUNCH_DEATH;
861 }
862 if (originalEvent == EVENT_SHOCK_HIT) {
863 dispatchEvent = EVENT_SHOCK_DEATH;
864 }
865 }
866
867 if (!stopMotion) {
868 s32 savedTargetActorID = actor->targetActorID;
869
870 if (func_80263230(actor, actor) != 0) {
871 show_next_damage_popup(actor->targetData[0].truePos.x, actor->targetData[0].truePos.y, actor->targetData[0].truePos.z, battleStatus->lastAttackDamage, 0);
872 show_damage_fx(actor, actor->targetData[0].truePos.x, actor->targetData[0].truePos.y, actor->targetData[0].truePos.z, battleStatus->lastAttackDamage);
873 }
874 actor->targetActorID = savedTargetActorID;
875
876 } else {
877 show_next_damage_popup(state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage, 0);
878 show_damage_fx(actor, state->goalPos.x, state->goalPos.y, state->goalPos.z, battleStatus->lastAttackDamage);
879 }
880
881 if (battleStatus->lastAttackDamage > 0) {
882 set_actor_flash_mode(actor, 1);
883 }
885 dispatch_event_actor(actor, dispatchEvent);
886 return 0;
887}
888
889s32 dispatch_damage_event_actor_0(Actor* actor, s32 damageAmount, s32 event) {
890 return dispatch_damage_event_actor(actor, damageAmount, event, FALSE);
891}
892
893s32 dispatch_damage_event_actor_1(Actor* actor, s32 damageAmount, s32 event) {
894 return dispatch_damage_event_actor(actor, damageAmount, event, TRUE);
895}
896
897API_CALLABLE(BindTakeTurn) {
898 Bytecode* args = script->ptrReadPos;
899 s32 actorID = evt_get_variable(script, *args++);
900 EvtScript* takeTurnScript;
901
902 if (actorID == ACTOR_SELF) {
903 actorID = script->owner1.actorID;
904 }
905
906 takeTurnScript = (EvtScript*) evt_get_variable(script, *args++);
907 get_actor(actorID)->takeTurnSource = takeTurnScript;
908 return ApiStatus_DONE2;
909}
910
911API_CALLABLE(PauseTakeTurn) {
912 Bytecode* args = script->ptrReadPos;
913 s32 actorID = evt_get_variable(script, *args++);
914
915 if (actorID == ACTOR_SELF) {
916 actorID = script->owner1.actorID;
917 }
918
919 evt_get_variable(script, *args++);
920 suspend_all_script(get_actor(actorID)->takeTurnScriptID);
921 return ApiStatus_DONE2;
922}
923
924API_CALLABLE(ResumeTakeTurn) {
925 Bytecode* args = script->ptrReadPos;
926 s32 actorID = evt_get_variable(script, *args++);
927
928 if (actorID == ACTOR_SELF) {
929 actorID = script->owner1.actorID;
930 }
931
932 evt_get_variable(script, *args++);
933 resume_all_script(get_actor(actorID)->takeTurnScriptID);
934 return ApiStatus_DONE2;
935}
936
937API_CALLABLE(BindIdle) {
938 Bytecode* args = script->ptrReadPos;
939 s32 actorID = evt_get_variable(script, *args++);
940 EvtScript* idleCode;
941 Actor* actor;
942 Evt* newScriptContext;
943
944 if (actorID == ACTOR_SELF) {
945 actorID = script->owner1.actorID;
946 }
947
948 idleCode = (EvtScript*) evt_get_variable(script, *args++);
949 actor = get_actor(actorID);
950
951 if (actor->idleScript != 0) {
953 actor->idleScript = 0;
954 }
955
956 actor->idleSource = idleCode;
957 newScriptContext = start_script(idleCode, EVT_PRIORITY_A, 0);
958 actor->idleScript = newScriptContext;
959 actor->idleScriptID = newScriptContext->id;
960 newScriptContext->owner1.actorID = actorID;
961 return ApiStatus_DONE2;
962}
963
964API_CALLABLE(EnableIdleScript) {
965 Bytecode* args = script->ptrReadPos;
966 s32 actorID = evt_get_variable(script, *args++);
967 s32 var1;
968 Actor* actor;
969
970 if (actorID == ACTOR_SELF) {
971 actorID = script->owner1.actorID;
972 }
973
974 var1 = evt_get_variable(script, *args++);
975 actor = get_actor(actorID);
976
977 if (actor->idleScript != NULL) {
978 switch (var1) {
982 break;
985 break;
988 break;
989 }
990 }
991
992 return ApiStatus_DONE2;
993}
994
995API_CALLABLE(BindHandleEvent) {
996 Bytecode* args = script->ptrReadPos;
997 s32 actorID = evt_get_variable(script, *args++);
998 EvtScript* src;
999
1000 if (actorID == ACTOR_SELF) {
1001 actorID = script->owner1.actorID;
1002 }
1003
1004 src = (EvtScript*) evt_get_variable(script, *args++);
1005 get_actor(actorID)->handleEventSource = src;
1006 return ApiStatus_DONE2;
1007}
1008
1009API_CALLABLE(BindHandlePhase) {
1010 Bytecode* args = script->ptrReadPos;
1011 s32 actorID = evt_get_variable(script, *args++);
1012 EvtScript* src;
1013
1014 if (actorID == ACTOR_SELF) {
1015 actorID = script->owner1.actorID;
1016 }
1017
1018 src = (EvtScript*) evt_get_variable(script, *args++);
1019 get_actor(actorID)->handlePhaseSource = src;
1020 return ApiStatus_DONE2;
1021}
1022
1023API_CALLABLE(JumpToGoal) {
1024 Bytecode* args = script->ptrReadPos;
1025 Actor* actor;
1026 ActorState* actorState;
1027 s32 actorID;
1028 f32 posX, posY, posZ;
1029 f32 goalX, goalY, goalZ;
1030 f32 moveDist;
1031
1032 if (isInitialCall) {
1033 script->functionTemp[0] = 0;
1034 }
1035
1036 if (script->functionTemp[0] == 0) {
1037 actorID = evt_get_variable(script, *args++);
1038 if (actorID == ACTOR_SELF) {
1039 actorID = script->owner1.enemyID;
1040 }
1041 script->functionTempPtr[1] = actor = get_actor(actorID);
1042 actorState = &actor->state;
1043 actorState->moveTime = evt_get_variable(script, *args++);
1044 script->functionTemp[2] = evt_get_variable(script, *args++);
1045 script->functionTemp[3] = 0;
1046 if (evt_get_variable(script, *args++) != 0) {
1047 script->functionTemp[3] |= 1;
1048 }
1049 if (evt_get_variable(script, *args++) != 0) {
1050 script->functionTemp[3] |= 2;
1051 }
1052
1053 actorState->curPos.x = actor->curPos.x;
1054 actorState->curPos.y = actor->curPos.y;
1055 actorState->curPos.z = actor->curPos.z;
1056
1057 posX = actorState->curPos.x;
1058 posY = actorState->curPos.y;
1059 posZ = actorState->curPos.z;
1060 goalX = actorState->goalPos.x;
1061 goalY = actorState->goalPos.y;
1062 goalZ = actorState->goalPos.z;
1063 actorState->angle = atan2(posX, posZ, goalX, goalZ);
1064 actorState->dist = dist2D(posX, posZ, goalX, goalZ);
1065
1066 // make relative
1067 posX = (goalX - posX);
1068 posY = (goalY - posY);
1069 posZ = (goalZ - posZ);
1070
1071 if (actorState->moveTime == 0) {
1072 actorState->moveTime = actorState->dist / actorState->speed;
1073 moveDist = actorState->dist - (actorState->moveTime * actorState->speed);
1074 } else {
1075 actorState->speed = actorState->dist / actorState->moveTime;
1076 moveDist = actorState->dist - (actorState->moveTime * actorState->speed);
1077 }
1078
1079 if (actorState->moveTime == 0) {
1080 return ApiStatus_DONE2;
1081 }
1082
1083 actorState->vel = (actorState->acceleration * actorState->moveTime * 0.5f) + (posY / actorState->moveTime);
1084 actorState->speed += (moveDist / actorState->moveTime);
1085
1086 if (script->functionTemp[2] != 0) {
1087 set_actor_anim(actor->actorID, (s8) actor->state.jumpPartIndex, actor->state.animJumpRise);
1088 }
1089 if (!(script->functionTemp[3] & 2) && (actor->actorTypeData1[4] != 0)) {
1091 }
1092 script->functionTemp[0] = 1;
1093 }
1094
1095 actor = script->functionTempPtr[1];
1096 actorState = &actor->state;
1097
1098 actorState->curPos.y += actorState->vel;
1099 actorState->vel -= actorState->acceleration;
1100
1101 if ((script->functionTemp[2] != 0) && (actorState->vel < 0.0f)) {
1102 set_actor_anim(actor->actorID, (s8) actorState->jumpPartIndex, actorState->animJumpFall);
1103 }
1104 if (actorState->vel < 0.0f) {
1105 if (actorState->curPos.y < actorState->goalPos.y) {
1106 actorState->curPos.y = actorState->goalPos.y;
1107 }
1108 }
1109
1110 add_xz_vec3f(&actorState->curPos, actorState->speed, actorState->angle);
1111 actor->curPos.x = actorState->curPos.x;
1112 actor->curPos.y = actorState->curPos.y;
1113 actor->curPos.z = actorState->curPos.z;
1114
1115 actorState->moveTime--;
1116 if (actorState->moveTime > 0) {
1117 return ApiStatus_BLOCK;
1118 }
1119
1120 if (script->functionTemp[3] & 1) {
1121 play_movement_dust_effects(2, actorState->goalPos.x, actorState->goalPos.y, actorState->goalPos.z, actorState->angle);
1122 }
1123 actor->curPos.x = actorState->goalPos.x;
1124 actor->curPos.y = actorState->goalPos.y;
1125 actor->curPos.z = actorState->goalPos.z;
1126 if (script->functionTemp[2] != 0) {
1127 set_actor_anim(actor->actorID, (s8) actorState->jumpPartIndex, actorState->animJumpLand);
1128 }
1129 return ApiStatus_DONE1;
1130}
1131
1132API_CALLABLE(IdleJumpToGoal) {
1133 Bytecode* args = script->ptrReadPos;
1134 Actor* actor;
1135 ActorMovement* movement;
1136 f32 posX, posY, posZ;
1137 f32 goalX, goalY, goalZ;
1138 f32 moveDist;
1139
1140 if (isInitialCall) {
1141 script->functionTemp[0] = FALSE;
1142 }
1143
1144 if (!script->functionTemp[0]) {
1145 s32 actorID = evt_get_variable(script, *args++);
1146
1147 if (actorID == ACTOR_SELF) {
1148 actorID = script->owner1.actorID;
1149 }
1150
1151 script->functionTempPtr[1] = actor = get_actor(actorID);
1152 movement = &actor->fly;
1153
1154 actor->fly.flyTime = evt_get_variable(script, *args++);
1155 script->functionTemp[2] = evt_get_variable(script, *args++);
1156 script->functionTemp[3] = evt_get_variable(script, *args++);
1157
1158 movement->curPos.x = actor->curPos.x;
1159 movement->curPos.y = actor->curPos.y;
1160 movement->curPos.z = actor->curPos.z;
1161
1162 posX = movement->curPos.x;
1163 posY = movement->curPos.y;
1164 posZ = movement->curPos.z;
1165 goalX = movement->goalPos.x;
1166 goalY = movement->goalPos.y;
1167 goalZ = movement->goalPos.z;
1168 movement->angle = atan2(posX, posZ, goalX, goalZ);
1169 movement->dist = dist2D(posX, posZ, goalX, goalZ);
1170
1171 // make relative
1172 posX = (goalX - posX);
1173 posY = (goalY - posY);
1174 posZ = (goalZ - posZ);
1175
1176 if (movement->flyTime == 0) {
1177 movement->flyTime = movement->dist / movement->speed;
1178 moveDist = movement->dist - (movement->flyTime * movement->speed);
1179 } else {
1180 movement->speed = movement->dist / movement->flyTime;
1181 moveDist = movement->dist - (movement->flyTime * movement->speed);
1182 }
1183
1184 if (movement->flyTime == 0) {
1185 return ApiStatus_DONE2;
1186 }
1187
1188 movement->vel = (movement->acceleration * movement->flyTime * 0.5f) + (posY / movement->flyTime);
1189 movement->speed += moveDist / movement->flyTime;
1190 script->functionTemp[0] = TRUE;
1191 }
1192
1193 actor = script->functionTempPtr[1];
1194 movement = &actor->fly;
1195
1196 movement->curPos.y += movement->vel;
1197 movement->vel -= movement->acceleration;
1198 if (movement->vel < 0.0f && movement->goalPos.y > movement->curPos.y) {
1199 movement->curPos.y = movement->goalPos.y;
1200 }
1201 add_xz_vec3f_copy2(&movement->curPos, movement->speed, movement->angle);
1202 actor->curPos.x = movement->curPos.x;
1203 actor->curPos.y = movement->curPos.y;
1204 actor->curPos.z = movement->curPos.z;
1205
1206 movement->flyTime--;
1207 if (movement->flyTime <= 0) {
1208 if (script->functionTemp[3] != 0) {
1209 play_movement_dust_effects(2, movement->goalPos.x, movement->goalPos.y, movement->goalPos.z, movement->angle);
1210 }
1211 actor->curPos.x = movement->goalPos.x;
1212 actor->curPos.y = movement->goalPos.y;
1213 actor->curPos.z = movement->goalPos.z;
1214 return ApiStatus_DONE1;
1215 }
1216
1217 return ApiStatus_BLOCK;
1218}
1219
1220API_CALLABLE(JumpToGoalSimple2) {
1221 Bytecode* args = script->ptrReadPos;
1222 ActorState* state;
1223 f32 posX, posY, posZ;
1224 f32 goalX, goalY, goalZ;
1225 f32 moveDist;
1226 Actor* actor;
1227
1228 if (isInitialCall) {
1229 script->functionTemp[0] = FALSE;
1230 }
1231
1232 if (!script->functionTemp[0]) {
1233 s32 actorID = evt_get_variable(script, *args++);
1234
1235 if (actorID == ACTOR_SELF) {
1236 actorID = script->owner1.actorID;
1237 }
1238
1239 script->functionTempPtr[1] = actor = get_actor(actorID);
1240 state = &actor->state;
1241
1242 state->moveTime = evt_get_variable(script, *args++);
1243 state->curPos.x = actor->curPos.x;
1244 state->curPos.y = actor->curPos.y;
1245 state->curPos.z = actor->curPos.z;
1246
1247 posX = state->curPos.x;
1248 posY = state->curPos.y;
1249 posZ = state->curPos.z;
1250 goalX = state->goalPos.x;
1251 goalY = state->goalPos.y;
1252 goalZ = state->goalPos.z;
1253 state->angle = atan2(posX, posZ, goalX, goalZ);
1254 state->dist = dist2D(posX, posZ, goalX, goalZ);
1255
1256 // make relative (note: negated)
1257 posX = (posX - goalX);
1258 posY = (posY - goalY);
1259 posZ = (posZ - goalZ);
1260
1261 if (state->moveTime == 0) {
1262 state->moveTime = state->dist / state->speed;
1263 moveDist = state->dist - (state->moveTime * state->speed);
1264 } else {
1265 state->speed = state->dist / state->moveTime;
1266 moveDist = state->dist - (state->moveTime * state->speed);
1267 }
1268
1269 if (state->moveTime == 0) {
1270 return ApiStatus_DONE2;
1271 }
1272
1273 state->vel = ((state->acceleration * state->moveTime) * 0.5f) + (posY / state->moveTime);
1274 state->speed += moveDist / state->moveTime;
1275 if (actor->actorTypeData1[4] != 0) {
1277 }
1278 script->functionTemp[0] = TRUE;
1279 }
1280
1281 actor = script->functionTempPtr[1];
1282 state = &actor->state;
1283
1284 state->curPos.y -= state->vel;
1285 state->vel -= state->acceleration;
1286 if (state->vel > 0.0f && state->goalPos.y < state->curPos.y) {
1287 state->curPos.y = state->goalPos.y;
1288 }
1289 add_xz_vec3f(&state->curPos, state->speed, state->angle);
1290 actor->curPos.x = state->curPos.x;
1291 actor->curPos.y = state->curPos.y;
1292 actor->curPos.z = state->curPos.z;
1293
1294 state->moveTime--;
1295 if (state->moveTime <= 0) {
1296 play_movement_dust_effects(2, state->goalPos.x, state->goalPos.y, state->goalPos.z, state->angle);
1297 actor->curPos.x = state->goalPos.x;
1298 actor->curPos.y = state->goalPos.y;
1299 actor->curPos.z = state->goalPos.z;
1300 return ApiStatus_DONE1;
1301 }
1302
1303 return ApiStatus_BLOCK;
1304}
1305
1306API_CALLABLE(JumpWithBounce) {
1307 Bytecode* args = script->ptrReadPos;
1308 Actor* actor;
1309 ActorState* actorState;
1310 s32 actorID;
1311 f32 posX, posY, posZ;
1312 f32 goalX, goalY, goalZ;
1313 f32 moveDist;
1314
1315 if (isInitialCall) {
1316 script->functionTemp[0] = FALSE;
1317 }
1318
1319 if (!script->functionTemp[0]) {
1320 actorID = evt_get_variable(script, *args++);
1321 if (actorID == ACTOR_SELF) {
1322 actorID = script->owner1.enemyID;
1323 }
1324 script->functionTempPtr[1] = actor = get_actor(actorID);
1325 actorState = &actor->state;
1326
1327 actorState->moveTime = evt_get_variable(script, *args++);
1328 actorState->bounceDivisor = evt_get_float_variable(script, *args++);
1329
1330 actorState->curPos.x = actor->curPos.x;
1331 actorState->curPos.y = actor->curPos.y;
1332 actorState->curPos.z = actor->curPos.z;
1333
1334 posX = actorState->curPos.x;
1335 posY = actorState->curPos.y;
1336 posZ = actorState->curPos.z;
1337 goalX = actorState->goalPos.x;
1338 goalZ = actorState->goalPos.z;
1339 goalY = actorState->goalPos.y;
1340 actorState->angle = atan2(posX, posZ, goalX, goalZ);
1341 actorState->dist = dist2D(posX, posZ, goalX, goalZ);
1342
1343 // make relative
1344 posX = (goalX - posX);
1345 posY = (goalY - posY);
1346 posZ = (goalZ - posZ);
1347
1348 if (actorState->moveTime == 0) {
1349 actorState->moveTime = (s32) (actorState->dist / actorState->speed);
1350 moveDist = actorState->dist - (actorState->moveTime * actorState->speed);
1351 } else {
1352 actorState->speed = actorState->dist / actorState->moveTime;
1353 moveDist = actorState->dist - (actorState->moveTime * actorState->speed);
1354 }
1355
1356 if (actorState->moveTime == 0) {
1357 return ApiStatus_DONE2;
1358 }
1359
1360 actorState->vel = (actorState->acceleration * actorState->moveTime * 0.5f) + (posY / actorState->moveTime);
1361 actorState->speed += moveDist / actorState->moveTime;
1362
1363 if (actor->actorTypeData1[4] != 0) {
1365 }
1366 script->functionTemp[0] = TRUE;
1367 }
1368
1369 actor = script->functionTempPtr[1];
1370 actorState = &actor->state;
1371
1372 switch (script->functionTemp[0]) {
1373 case 1:
1374 actorState->curPos.y += actorState->vel;
1375 actorState->vel -= actorState->acceleration;
1376 if ((actorState->vel < 0.0f) && (actorState->curPos.y < actorState->goalPos.y)) {
1377 actorState->acceleration = -actorState->acceleration;
1378 actorState->vel /= actorState->bounceDivisor;
1379 script->functionTemp[0] = 2;
1380 }
1381 add_xz_vec3f(&actorState->curPos, actorState->speed, actorState->angle);
1382 break;
1383 case 2:
1384 actorState->curPos.y += actorState->vel;
1385 actorState->vel -= actorState->acceleration;
1386 if (actorState->vel > 0.0f) {
1387 if (actorState->goalPos.y < actorState->curPos.y) {
1388 actorState->curPos.y = actorState->goalPos.y;
1389 script->functionTemp[0] = 3;
1390 }
1391 }
1392 add_xz_vec3f(&actorState->curPos, actorState->speed, actorState->angle);
1393 actor->curPos.x = actorState->curPos.x;
1394 actor->curPos.y = actorState->curPos.y;
1395 actor->curPos.z = actorState->curPos.z;
1396 break;
1397
1398 case 3:
1399 return ApiStatus_DONE2;
1400 }
1401
1402 actor->curPos.x = actorState->curPos.x;
1403 actor->curPos.y = actorState->curPos.y;
1404 actor->curPos.z = actorState->curPos.z;
1405 return ApiStatus_BLOCK;
1406}
1407
1408API_CALLABLE(LandJump) {
1409 Bytecode* args = script->ptrReadPos;
1410 Actor* actor;
1411
1412 if (isInitialCall) {
1413 script->functionTemp[0] = FALSE;
1414 }
1415
1416 if (!script->functionTemp[0]) {
1417 s32 actorID = evt_get_variable(script, *args++);
1418
1419 if (actorID == ACTOR_SELF) {
1420 actorID = script->owner1.actorID;
1421 }
1422
1423 actor = get_actor(actorID);
1424 script->functionTempPtr[1] = actor;
1425 actor->state.curPos.x = actor->curPos.x;
1426 actor->state.curPos.y = actor->curPos.y;
1427 actor->state.curPos.z = actor->curPos.z;
1428 script->functionTemp[0] = TRUE;
1429 }
1430
1431 actor = script->functionTempPtr[1];
1432 actor->state.curPos.y += actor->state.vel;
1433 actor->state.vel -= actor->state.acceleration;
1434
1435 add_xz_vec3f(&actor->state.curPos, actor->state.speed, actor->state.angle);
1436 actor->curPos.x = actor->state.curPos.x;
1437 actor->curPos.y = actor->state.curPos.y;
1438 actor->curPos.z = actor->state.curPos.z;
1439
1440 if (actor->curPos.y < 0.0f) {
1441 actor->curPos.y = 0.0f;
1442 play_movement_dust_effects(2, actor->curPos.x, actor->curPos.y, actor->curPos.z, actor->yaw);
1443 return ApiStatus_DONE1;
1444 }
1445
1446 return ApiStatus_BLOCK;
1447}
1448
1449API_CALLABLE(FallToGoal) {
1450 Bytecode* args = script->ptrReadPos;
1451 Actor* actor;
1452 ActorState* state;
1453 f32 posX, posY, posZ;
1454 f32 goalX, goalY, goalZ;
1455
1456 if (isInitialCall) {
1457 script->functionTemp[0] = 0;
1458 }
1459
1460 if (script->functionTemp[0] == 0) {
1461 s32 actorID = evt_get_variable(script, *args++);
1462
1463 if (actorID == ACTOR_SELF) {
1464 actorID = script->owner1.enemyID;
1465 }
1466 actor = get_actor(actorID);
1467 state = &actor->state;
1468 script->functionTempPtr[1] = actor;
1469
1470 actor->state.moveTime = evt_get_variable(script, *args++);
1471
1472 actor->state.curPos.x = actor->curPos.x;
1473 actor->state.curPos.y = actor->curPos.y;
1474 actor->state.curPos.z = actor->curPos.z;
1475
1476 posX = actor->state.curPos.x;
1477 posY = actor->state.curPos.y;
1478 posZ = actor->state.curPos.z;
1479 goalX = actor->state.goalPos.x;
1480 goalY = actor->state.goalPos.y;
1481 goalZ = actor->state.goalPos.z;
1482
1483 actor->state.angle = atan2(posX, posZ, goalX, goalZ);
1484 actor->state.dist = dist2D(posX, posZ, goalX, goalZ);
1485
1486 // make relative
1487 posX = (goalX - posX);
1488 posY = (goalY - posY);
1489 posZ = (goalZ - posZ);
1490
1491 if (actor->state.moveTime == 0) {
1492 actor->state.moveTime = actor->state.dist / actor->state.speed;
1493 } else {
1494 actor->state.speed = actor->state.dist / actor->state.moveTime;
1495 }
1496
1497 state->vel = 0.0f;
1498 state->acceleration = (posY / state->moveTime - state->vel) / (-state->moveTime * 0.5);
1499
1500 if (actor->actorTypeData1[4] != 0) {
1502 }
1503 script->functionTemp[0] = 1;
1504 }
1505
1506 actor = script->functionTempPtr[1];
1507 actor->state.curPos.y += actor->state.vel;
1508 actor->state.vel -= actor->state.acceleration;
1509 add_xz_vec3f(&actor->state.curPos, actor->state.speed, actor->state.angle);
1510 actor->curPos.x = actor->state.curPos.x;
1511 actor->curPos.y = actor->state.curPos.y;
1512 actor->curPos.z = actor->state.curPos.z;
1513 actor->state.moveTime--;
1514
1515 if (actor->state.moveTime <= 0) {
1516 play_movement_dust_effects(2, actor->state.goalPos.x, actor->state.goalPos.y, actor->state.goalPos.z, actor->state.angle);
1517 actor->curPos.x = actor->state.goalPos.x;
1518 actor->curPos.y = actor->state.goalPos.y;
1519 actor->curPos.z = actor->state.goalPos.z;
1520 return ApiStatus_DONE1;
1521 } else {
1522 return ApiStatus_BLOCK;
1523 }
1524}
1525
1526API_CALLABLE(RunToGoal) {
1527 Bytecode* args = script->ptrReadPos;
1528 Actor* actor;
1529 ActorState* actorState;
1530 s32 actorID;
1531 f32 posX, posY, posZ;
1532 f32 goalX, goalY, goalZ;
1533
1534 if (isInitialCall) {
1535 script->functionTemp[0] = FALSE;
1536 }
1537
1538 if (!script->functionTemp[0]) {
1539 actorID = evt_get_variable(script, *args++);
1540 if (actorID == ACTOR_SELF) {
1541 actorID = script->owner1.enemyID;
1542 }
1543 script->functionTempPtr[1] = actor = get_actor(actorID);
1544 actorState = &actor->state;
1545
1546 actorState->moveTime = evt_get_variable(script, *args++);
1547 script->functionTemp[2] = evt_get_variable(script, *args++);
1548
1549 actorState->curPos.x = actor->curPos.x;
1550 actorState->curPos.y = actor->curPos.y;
1551 actorState->curPos.z = actor->curPos.z;
1552
1553 goalX = actorState->goalPos.x;
1554 goalY = actorState->goalPos.y;
1555 goalZ = actorState->goalPos.z;
1556 posX = actorState->curPos.x;
1557 posY = actorState->curPos.y;
1558 posZ = actorState->curPos.z;
1559
1560 actorState->unk_18.x = goalX;
1561 actorState->unk_18.y = goalY;
1562 actorState->unk_18.z = goalZ;
1563
1564 actorState->angle = atan2(posX, posZ, goalX, goalZ);
1565 actorState->dist = dist2D(posX, posZ, goalX, goalZ);
1566
1567 if (actorState->moveTime == 0) {
1568 actorState->moveTime = actorState->dist / actorState->speed;
1569 if (actorState->moveTime == 0) {
1570 actorState->moveTime = 1;
1571 }
1572 actorState->speed += (actorState->dist - (actorState->moveTime * actorState->speed)) / actorState->moveTime;
1573 } else {
1574 actorState->speed = actorState->dist / actorState->moveTime;
1575 }
1576
1577 if (actor->actorTypeData1b[0] >= 0) {
1578 actorState->dist = actor->actorTypeData1b[0] + 1;
1579 } else {
1580 actorState->dist = ~actor->actorTypeData1b[0]; //TODO optimization?
1581 }
1582 if ((actor->actorTypeData1[0] != 0) && (actor->actorTypeData1[1] == 0)) {
1584 }
1585 script->functionTemp[0] = TRUE;
1586 }
1587
1588 actor = script->functionTempPtr[1];
1589 actorState = &actor->state;
1590
1591 add_xz_vec3f(&actorState->curPos, actorState->speed, actorState->angle);
1592 if (script->functionTemp[2] == 0) {
1593 if (actorState->speed < 4.0f) {
1594 play_movement_dust_effects(0, actorState->curPos.x, actorState->curPos.y, actorState->curPos.z, actorState->angle);
1595 } else {
1596 play_movement_dust_effects(1, actorState->curPos.x, actorState->curPos.y, actorState->curPos.z, actorState->angle);
1597 }
1598 }
1599 actor->curPos.x = actorState->curPos.x;
1600 actor->curPos.z = actorState->curPos.z;
1601
1602 if ((actor->actorTypeData1[0] != 0) && (actor->actorTypeData1[1] != 0)) {
1603 if (actor->actorTypeData1b[0] >= 0) {
1604 actorState->dist += actorState->speed;
1605 if (actor->actorTypeData1b[0] < actorState->dist) {
1606 actor->footStepCounter++;
1607 actorState->dist = 0.0f;
1608 if (actor->footStepCounter & 1) {
1609 if (actor->actorTypeData1[0] != 0) {
1611 }
1612 } else {
1613 if (actor->actorTypeData1[1] != 0) {
1615 }
1616 }
1617 }
1618 } else {
1619 actorState->dist += 1.0f;
1620 if (-actor->actorTypeData1b[0] <= actorState->dist) {
1621 actor->footStepCounter++;
1622 actorState->dist = 0.0f;
1623 if (actor->footStepCounter & 1) {
1624 if (actor->actorTypeData1[0] != 0) {
1626 }
1627 } else {
1628 if (actor->actorTypeData1[1] != 0) {
1630 }
1631 }
1632 }
1633 }
1634 }
1635
1636 actorState->moveTime--;
1637 if (actorState->moveTime > 0) {
1638 return ApiStatus_BLOCK;
1639 }
1640
1641 actor->curPos.x = actorState->unk_18.x;
1642 actor->curPos.z = actorState->unk_18.z;
1643 if (actor->actorTypeData1[0] != 0) {
1644 if (actor->actorTypeData1[1] == 0) {
1645 snd_stop_sound(actor->actorTypeData1[0]);
1646 }
1647 }
1648 return ApiStatus_DONE1;
1649}
1650
1651API_CALLABLE(IdleRunToGoal) {
1652 Bytecode* args = script->ptrReadPos;
1653 Actor* actor;
1654 ActorMovement* movement;
1655 f32 posX, posY, posZ;
1656 f32 goalX, goalY, goalZ;
1657 s32 actorID;
1658
1659 if (isInitialCall) {
1660 script->functionTemp[0] = FALSE;
1661 }
1662
1663 if (!script->functionTemp[0]) {
1664 actorID = evt_get_variable(script, *args++);
1665 if (actorID == ACTOR_SELF) {
1666 actorID = script->owner1.actorID;
1667 }
1668 script->functionTempPtr[1] = actor = get_actor(actorID);
1669 movement = &actor->fly;
1670
1671 movement->flyTime = evt_get_variable(script, *args++);
1672
1673 movement->curPos.x = actor->curPos.x;
1674 movement->curPos.y = actor->curPos.y;
1675 movement->curPos.z = actor->curPos.z;
1676
1677 goalX = movement->goalPos.x;
1678 goalY = movement->goalPos.y;
1679 goalZ = movement->goalPos.z;
1680
1681 posX = movement->curPos.x;
1682 posY = movement->curPos.y;
1683 posZ = movement->curPos.z;
1684
1685 movement->unk_18.x = goalX;
1686 movement->unk_18.y = goalY;
1687 movement->unk_18.z = goalZ;
1688
1689 movement->angle = atan2(posX, posZ, goalX, goalZ);
1690 movement->dist = dist2D(posX, posZ, goalX, goalZ);
1691
1692 if (movement->flyTime == 0) {
1693 movement->flyTime = movement->dist / movement->speed;
1694 if (movement->flyTime == 0) {
1695 movement->flyTime = 1;
1696 }
1697 // this simplifies to: flyMotion->speed = flyMotion->distance / flyMotion->flyTime
1698 movement->speed += (movement->dist - movement->flyTime * movement->speed) / movement->flyTime;
1699 } else {
1700 movement->speed = movement->dist / movement->flyTime;
1701 }
1702
1703 if (actor->actorTypeData1b[0] >= 0) {
1704 movement->dist = actor->actorTypeData1b[0] + 1;
1705 } else {
1706 movement->dist = ~actor->actorTypeData1b[0];
1707 }
1708 script->functionTemp[0] = TRUE;
1709 }
1710
1711 actor = script->functionTempPtr[1];
1712 movement = &actor->fly;
1713
1714 add_xz_vec3f_copy2(&movement->curPos, movement->speed, movement->angle);
1715 if (movement->speed < 4.0f) {
1716 play_movement_dust_effects(0, movement->curPos.x, movement->curPos.y, movement->curPos.z, movement->angle);
1717 } else {
1718 play_movement_dust_effects(1, movement->curPos.x, movement->curPos.y, movement->curPos.z, movement->angle);
1719 }
1720 actor->curPos.x = movement->curPos.x;
1721 actor->curPos.z = movement->curPos.z;
1722
1723 movement->flyTime--;
1724 if (movement->flyTime > 0) {
1725 return ApiStatus_BLOCK;
1726 }
1727
1728 actor->curPos.x = movement->unk_18.x;
1729 actor->curPos.z = movement->unk_18.z;
1730 if (actor->actorTypeData1[0] != 0 && actor->actorTypeData1[1] == 0) {
1731 snd_stop_sound(actor->actorTypeData1[0]);
1732 }
1733 return ApiStatus_DONE1;
1734}
1735
1736API_CALLABLE(JumpPartTo) {
1737 Bytecode* args = script->ptrReadPos;
1738 Actor* actor;
1739 ActorPart* part;
1740 ActorPartMovement* movement;
1741 s32 actorID, partID;
1742 f32 posX, posY, posZ;
1743 f32 goalX, goalY, goalZ;
1744 f32 deltaDist;
1745
1746 if (isInitialCall) {
1747 script->functionTemp[0] = 0;
1748 }
1749
1750 if (script->functionTemp[0] == 0) {
1751 actorID = evt_get_variable(script, *args++);
1752 if (actorID == ACTOR_SELF) {
1753 actorID = script->owner1.actorID;
1754 }
1755 partID = evt_get_variable(script, *args++);
1756
1757 actor = get_actor(actorID);
1758 part = get_actor_part(actor, partID);
1759 script->functionTempPtr[1] = actor;
1760 script->functionTempPtr[2] = part;
1761 movement = part->movement;
1762
1763 posX = evt_get_variable(script, *args++);
1764 posY = evt_get_variable(script, *args++);
1765 posZ = evt_get_variable(script, *args++);
1766 movement->goalPos.x = posX;
1767 movement->goalPos.y = posY;
1768 movement->goalPos.z = posZ;
1769 movement->moveTime = evt_get_variable(script, *args++);
1770 script->functionTemp[3] = evt_get_variable(script, *args++);
1771
1772 goalX = movement->goalPos.x;
1773 goalY = movement->goalPos.y;
1774 goalZ = movement->goalPos.z;
1775
1776 movement->absolutePos.x = part->absolutePos.x;
1777 movement->absolutePos.y = part->absolutePos.y;
1778 movement->absolutePos.z = part->absolutePos.z;
1779
1780 posX = movement->absolutePos.x;
1781 posY = movement->absolutePos.y;
1782 posZ = movement->absolutePos.z;
1783
1784 movement->angle = atan2(posX, posZ, goalX, goalZ);
1785 movement->dist = dist2D(posX, posZ, goalX, goalZ);
1786
1787 // make relative
1788 posX = (goalX - posX);
1789 posY = (goalY - posY);
1790 posZ = (goalZ - posZ);
1791
1792 if (movement->moveTime == 0) {
1793 movement->moveTime = movement->dist / movement->moveSpeed;
1794 deltaDist = movement->dist - movement->moveTime * movement->moveSpeed;
1795 } else {
1796 movement->moveSpeed = movement->dist / movement->moveTime;
1797 deltaDist = movement->dist - movement->moveTime * movement->moveSpeed;
1798 }
1799 movement->moveSpeed += deltaDist / movement->moveTime;
1800 movement->unk_2C = movement->jumpScale * movement->moveTime * 0.5f + posY / movement->moveTime;
1801 if (part->partTypeData[4] != 0) {
1803 }
1804 script->functionTemp[0] = 1;
1805 }
1806
1807 part = script->functionTempPtr[2];
1808 movement = part->movement;
1809 movement->absolutePos.y += movement->unk_2C;
1810 movement->unk_2C -= movement->jumpScale;
1811 add_xz_vec3f_copy1(&movement->absolutePos, movement->moveSpeed, movement->angle);
1812 part->absolutePos.x = movement->absolutePos.x;
1813 part->absolutePos.y = movement->absolutePos.y;
1814 part->absolutePos.z = movement->absolutePos.z;
1815 movement->moveTime--;
1816
1817 if (movement->moveTime <= 0) {
1818 if (script->functionTemp[3] != 0) {
1819 play_movement_dust_effects(2, movement->goalPos.x, movement->goalPos.y, movement->goalPos.z, movement->angle);
1820 }
1821 part->absolutePos.x = movement->goalPos.x;
1822 part->absolutePos.y = movement->goalPos.y;
1823 part->absolutePos.z = movement->goalPos.z;
1824 return ApiStatus_DONE1;
1825 } else {
1826 return ApiStatus_BLOCK;
1827 }
1828}
1829
1830API_CALLABLE(FallPartTo) {
1831 Bytecode* args = script->ptrReadPos;
1832 Actor* actor;
1833 ActorPart* part;
1834 ActorPartMovement* movement;
1835 s32 actorID, partID;
1836 f32 posX, posY, posZ;
1837 f32 goalX, goalY, goalZ;
1838
1839 if (isInitialCall) {
1840 script->functionTemp[0] = 0;
1841 }
1842
1843 if (script->functionTemp[0] == 0) {
1844 actorID = evt_get_variable(script, *args++);
1845 if (actorID == ACTOR_SELF) {
1846 actorID = script->owner1.actorID;
1847 }
1848 partID = evt_get_variable(script, *args++);
1849
1850 actor = get_actor(actorID);
1851 part = get_actor_part(actor, partID);
1852 script->functionTempPtr[1] = actor;
1853 script->functionTempPtr[2] = part;
1854 movement = part->movement;
1855
1856 posX = evt_get_variable(script, *args++);
1857 posY = evt_get_variable(script, *args++);
1858 posZ = evt_get_variable(script, *args++);
1859 movement->goalPos.x = posX;
1860 movement->goalPos.y = posY;
1861 movement->goalPos.z = posZ;
1862 movement->moveTime = evt_get_variable(script, *args++);
1863
1864 goalX = movement->goalPos.x;
1865 goalY = movement->goalPos.y;
1866 goalZ = movement->goalPos.z;
1867
1868 movement->absolutePos.x = part->absolutePos.x;
1869 movement->absolutePos.y = part->absolutePos.y;
1870 movement->absolutePos.z = part->absolutePos.z;
1871
1872 posX = movement->absolutePos.x;
1873 posY = movement->absolutePos.y;
1874 posZ = movement->absolutePos.z;
1875
1876 movement->angle = atan2(posX, posZ, goalX, goalZ);
1877 movement->dist = dist2D(posX, posZ, goalX, goalZ);
1878
1879 // make relative
1880 posX = (goalX - posX);
1881 posY = (goalY - posY);
1882 posZ = (goalZ - posZ);
1883
1884 if (movement->moveTime == 0) {
1885 movement->moveTime = movement->dist / movement->moveSpeed;
1886 } else {
1887 movement->moveSpeed = movement->dist / movement->moveTime;
1888 }
1889
1890 movement->unk_2C = 0.0f;
1891 movement->jumpScale = (posY / movement->moveTime - movement->unk_2C) / (-movement->moveTime * 0.5);
1892 if (part->partTypeData[4] != 0) {
1894 }
1895 script->functionTemp[0] = 1;
1896 }
1897
1898 part = script->functionTempPtr[2];
1899 movement = part->movement;
1900 movement->absolutePos.y += movement->unk_2C;
1901 movement->unk_2C -= movement->jumpScale;
1902 add_xz_vec3f_copy1(&movement->absolutePos, movement->moveSpeed, movement->angle);
1903 part->absolutePos.x = movement->absolutePos.x;
1904 part->absolutePos.y = movement->absolutePos.y;
1905 part->absolutePos.z = movement->absolutePos.z;
1906 movement->moveTime--;
1907
1908 if (movement->moveTime <= 0) {
1909 play_movement_dust_effects(2, movement->goalPos.x, movement->goalPos.y, movement->goalPos.z, movement->angle);
1910 part->absolutePos.x = movement->goalPos.x;
1911 part->absolutePos.y = movement->goalPos.y;
1912 part->absolutePos.z = movement->goalPos.z;
1913 return ApiStatus_DONE1;
1914 } else {
1915 return ApiStatus_BLOCK;
1916 }
1917}
1918
1919API_CALLABLE(LandJumpPart) {
1920 Bytecode* args = script->ptrReadPos;
1921 Actor* actor;
1922 ActorPart* part;
1923 ActorPartMovement* movement;
1924
1925 if (isInitialCall) {
1926 script->functionTemp[0] = 0;
1927 }
1928
1929 if (script->functionTemp[0] == 0) {
1930 s32 actorID = evt_get_variable(script, *args++);
1931 s32 partID = evt_get_variable(script, *args++);
1932
1933 if (actorID == ACTOR_SELF) {
1934 actorID = script->owner1.actorID;
1935 }
1936
1937 actor = get_actor(actorID);
1938 part = get_actor_part(actor, partID);
1939 script->functionTempPtr[1] = actor;
1940 script->functionTempPtr[2] = part;
1941 movement = part->movement;
1942 movement->absolutePos.x = part->absolutePos.x;
1943 movement->absolutePos.y = part->absolutePos.y;
1944 movement->absolutePos.z = part->absolutePos.z;
1945 script->functionTemp[0] = 1;
1946 }
1947
1948 part = script->functionTempPtr[2];
1949 movement = part->movement;
1950 movement->absolutePos.y += movement->unk_2C;
1951 movement->unk_2C -= movement->jumpScale;
1952 add_xz_vec3f_copy1(&movement->absolutePos, movement->moveSpeed, movement->angle);
1953 part->absolutePos.x = movement->absolutePos.x;
1954 part->absolutePos.y = movement->absolutePos.y;
1955 part->absolutePos.z = movement->absolutePos.z;
1956
1957 if (part->absolutePos.y < 0.0f) {
1958 part->absolutePos.y = 0.0f;
1959 play_movement_dust_effects(2, part->absolutePos.x, part->absolutePos.y, part->absolutePos.z, part->yaw);
1960 return ApiStatus_DONE1;
1961 }
1962
1963 return ApiStatus_BLOCK;
1964}
1965
1966API_CALLABLE(RunPartTo) {
1967 Bytecode* args = script->ptrReadPos;
1968 Actor* actor;
1969 ActorPart* part;
1970 ActorPartMovement* movement;
1971 s32 actorID, partID;
1972 f32 posX, posY, posZ;
1973 f32 goalX, goalY, goalZ;
1974 f32 deltaDist;
1975
1976 if (isInitialCall) {
1977 script->functionTemp[0] = 0;
1978 }
1979
1980 if (script->functionTemp[0] == 0) {
1981 actorID = evt_get_variable(script, *args++);
1982 if (actorID == ACTOR_SELF) {
1983 actorID = script->owner1.actorID;
1984 }
1985 partID = evt_get_variable(script, *args++);
1986
1987 actor = get_actor(actorID);
1988 part = get_actor_part(actor, partID);
1989 script->functionTempPtr[1] = actor;
1990 script->functionTempPtr[2] = part;
1991 movement = part->movement;
1992
1993 posX = evt_get_variable(script, *args++);
1994 posY = evt_get_variable(script, *args++);
1995 posZ = evt_get_variable(script, *args++);
1996 movement->goalPos.x = posX;
1997 movement->goalPos.y = posY;
1998 movement->goalPos.z = posZ;
1999 movement->moveTime = evt_get_variable(script, *args++);
2000
2001 goalX = movement->goalPos.x;
2002 goalY = movement->goalPos.y;
2003 goalZ = movement->goalPos.z;
2004
2005 movement->absolutePos.x = part->absolutePos.x;
2006 movement->absolutePos.y = part->absolutePos.y;
2007 movement->absolutePos.z = part->absolutePos.z;
2008
2009 posX = movement->absolutePos.x;
2010 posY = movement->absolutePos.y;
2011 posZ = movement->absolutePos.z;
2012
2013 movement->angle = atan2(posX, posZ, goalX, goalZ);
2014 movement->dist = dist2D(posX, posZ, goalX, goalZ);
2015
2016 if (movement->moveTime == 0) {
2017 movement->moveTime = movement->dist / movement->moveSpeed;
2018 } else {
2019 movement->moveSpeed = movement->dist / movement->moveTime;
2020 }
2021 if (part->actorTypeData2b[0] >= 0) {
2022 movement->dist = part->actorTypeData2b[0] + 1;
2023 } else {
2024 movement->dist = ~part->actorTypeData2b[0];
2025 }
2026 if (part->partTypeData[0] != 0 && part->partTypeData[1] == 0) {
2028 }
2029 script->functionTemp[0] = 1;
2030 }
2031
2032 part = script->functionTempPtr[2];
2033 movement = part->movement;
2034 actor = script->functionTempPtr[1];
2035
2036 add_xz_vec3f_copy1(&movement->absolutePos, movement->moveSpeed, movement->angle);
2037 if (movement->moveSpeed < 4.0f) {
2038 play_movement_dust_effects(0, movement->absolutePos.x, movement->absolutePos.y, movement->absolutePos.z, movement->angle);
2039 } else {
2040 play_movement_dust_effects(1, movement->absolutePos.x, movement->absolutePos.y, movement->absolutePos.z, movement->angle);
2041 }
2042 part->absolutePos.x = movement->absolutePos.x;
2043 part->absolutePos.y = movement->absolutePos.y;
2044 part->absolutePos.z = movement->absolutePos.z;
2045
2046 if (part->partTypeData[0] != 0 && part->partTypeData[1] != 0) {
2047 if (part->actorTypeData2b[0] >= 0) {
2048 movement->dist += movement->moveSpeed;
2049 if (part->actorTypeData2b[0] < movement->dist) {
2050 actor->footStepCounter++;
2051 movement->dist = 0;
2052 if (actor->footStepCounter % 2 != 0) {
2053 if (part->partTypeData[0] != 0) {
2055 }
2056 } else {
2057 if (part->partTypeData[1] != 0) {
2059 }
2060 }
2061 }
2062 } else {
2063 movement->dist += 1.0f;
2064 if (-part->actorTypeData2b[0] <= movement->dist) {
2065 actor->footStepCounter++;
2066 movement->dist = 0;
2067 if (actor->footStepCounter % 2 != 0) {
2068 if (part->partTypeData[0] != 0) {
2070 }
2071 } else {
2072 if (part->partTypeData[1] != 0) {
2074 }
2075 }
2076 }
2077 }
2078 }
2079
2080 movement->moveTime--;
2081 if (movement->moveTime > 0) {
2082 return ApiStatus_BLOCK;
2083 } else {
2084 part->absolutePos.x = movement->goalPos.x;
2085 part->absolutePos.z = movement->goalPos.z;
2086 if (part->partTypeData[0] != 0 && part->partTypeData[1] == 0) {
2087 snd_stop_sound(part->partTypeData[0]);
2088 }
2089 return ApiStatus_DONE1;
2090 }
2091}
2092
2093f32 update_lerp_battle(s32 easing, f32 start, f32 end, s32 elapsed, s32 duration) {
2094 s32 timeLeft;
2095 f32 absMag;
2096 f64 start1;
2097 f64 start2;
2098 f32 len1;
2099 f32 len2;
2100 f32 len3;
2101 f32 len4;
2102 f64 len5;
2103 f32 len6;
2104 f64 len7;
2105
2106 switch (easing) {
2107 case EASING_LINEAR:
2108 return start + (end - start) * elapsed / duration;
2110 return start + SQ(elapsed) * (end - start) / SQ(duration);
2111 case EASING_CUBIC_IN:
2112 return start + CUBE(elapsed) * (end - start) / CUBE(duration);
2113 case EASING_QUARTIC_IN:
2114 return start + QUART(elapsed) * (end - start) / QUART(duration);
2116 len1 = end - start;
2117 return end - (len1 * cos_rad(((f32)elapsed / duration) * PI_D * 4.0) * (duration - elapsed) *
2118 (duration - elapsed)) / SQ((f32)duration);
2120 len2 = end - start;
2121 return end - (len2 * cos_rad((((f32)SQ(elapsed) / duration) * PI_D * 4.0) / 15.0) * (duration - elapsed) *
2122 (duration - elapsed)) / SQ((f32)duration);
2124 timeLeft = duration - elapsed;
2125 return start + (end - start) - ((SQ(timeLeft) * (end - start))) / SQ(duration);
2126 case EASING_CUBIC_OUT:
2127 len3 = end - start;
2128 timeLeft = duration - elapsed;
2129 return start + len3 - ((CUBE(timeLeft) * len3)) / CUBE(duration);
2130 case EASING_QUARTIC_OUT:
2131 len4 = end - start;
2132 timeLeft = duration - elapsed;
2133 return start + len4 - ((QUART(timeLeft) * len4)) / QUART(duration);
2134 case EASING_COS_BOUNCE:
2135 absMag = cos_rad((((f32)SQ(elapsed) / duration) * PI_D * 4.0) / 40.0) * (duration - elapsed) *
2136 (duration - elapsed) / SQ((f32)duration);
2137 if (absMag < 0.0f) {
2138 absMag = -absMag;
2139 }
2140 return end - (end - start) * absMag;
2141 case EASING_COS_IN_OUT:
2142 len5 = end - start;
2143 start1 = start;
2144 return start1 + (len5 * (1.0 - cos_rad(((f32)elapsed * PI_D) / (f32)duration)) / 2);
2145 case EASING_SIN_OUT:
2146 len6 = end - start;
2147 return start + (len6 * sin_rad((((f32) elapsed) * (PI_D / 2)) / ((f32) duration)));
2148 case EASING_COS_IN:
2149 len7 = end - start;
2150 start2 = start;
2151 return start2 + (len7 * (1.0 - cos_rad(((f32)elapsed * (PI_D / 2)) / (f32)duration)));
2152 }
2153
2154 return 0.0f;
2155}
2156
2157API_CALLABLE(FlyToGoal) {
2158 Bytecode* args = script->ptrReadPos;
2159 Actor* actor;
2160 ActorState* actorState;
2161 s32 actorID;
2162 f32 posX, posY, posZ;
2163 f32 goalX, goalY, goalZ;
2164 f32 deltaX, deltaY, deltaZ;
2165 f32 dist3D;
2166 f32 offsetY;
2167
2168 if (isInitialCall) {
2169 actorID = evt_get_variable(script, *args++);
2170 if (actorID == ACTOR_SELF) {
2171 actorID = script->owner1.enemyID;
2172 }
2173 script->functionTempPtr[1] = actor = get_actor(actorID);
2174 actorState = &actor->state;
2175
2176 actorState->moveTime = evt_get_variable(script, *args++);
2177 actorState->moveArcAmplitude = evt_get_variable(script, *args++);
2178 script->functionTemp[3] = evt_get_variable(script, *args++);
2179 actorState->functionTemp[0] = FALSE;
2180
2181 if (script->functionTemp[3] >= 100) {
2182 script->functionTemp[3] -= 100;
2183 actorState->functionTemp[0] = TRUE;
2184 }
2185
2186 goalX = actorState->goalPos.x;
2187 goalY = actorState->goalPos.y;
2188 goalZ = actorState->goalPos.z;
2189
2190 posX = actor->curPos.x;
2191 posY = actor->curPos.y;
2192 posZ = actor->curPos.z;
2193
2194 deltaX = posX - goalX;
2195 deltaY = posY - goalY;
2196 deltaZ = posZ - goalZ;
2197
2198 actorState->curPos.x = posX;
2199 actorState->unk_18.x = posX;
2200 actorState->curPos.y = posY;
2201 actorState->unk_18.y = posY;
2202 actorState->curPos.z = posZ;
2203 actorState->unk_18.z = posZ;
2204
2205 actorState->dist = sqrtf(SQ(deltaX) + SQ(deltaY) + SQ(deltaZ));
2206
2207 if (actorState->moveTime == 0) {
2208 actorState->moveTime = actorState->dist / actorState->speed;
2209 } else {
2210 actorState->speed = actorState->dist / actorState->moveTime;
2211 }
2212 if (actorState->moveTime == 0) {
2213 return ApiStatus_DONE2;
2214 }
2215
2216 actorState->bounceDivisor = 0.0f;
2217 actorState->angle = 0.0f;
2218 if (actor->actorTypeData1b[1] >= 0) {
2219 actorState->vel = actor->actorTypeData1b[1] + 1;
2220 } else {
2221 actorState->vel = ~actor->actorTypeData1b[1];
2222 }
2223 if ((actor->actorTypeData1[2] != 0) && (actor->actorTypeData1[3] == 0)) {
2225 }
2226 }
2227
2228 actor = script->functionTempPtr[1];
2229 actorState = &actor->state;
2230
2231 actorState->curPos.x = update_lerp_battle(script->functionTemp[3], actorState->unk_18.x, actorState->goalPos.x, actorState->bounceDivisor, actorState->moveTime);
2232 actorState->curPos.y = update_lerp_battle(script->functionTemp[3], actorState->unk_18.y, actorState->goalPos.y, actorState->bounceDivisor, actorState->moveTime);
2233 actorState->curPos.z = update_lerp_battle(script->functionTemp[3], actorState->unk_18.z, actorState->goalPos.z, actorState->bounceDivisor, actorState->moveTime);
2234 if ((actorState->functionTemp[0]) && (actorState->curPos.y < 0.0f)) {
2235 actorState->bounceDivisor = actorState->moveTime;
2236 actorState->goalPos.x = actorState->curPos.x;
2237 actorState->goalPos.y = 0.0f;
2238 actorState->goalPos.z = actorState->curPos.z;
2239 }
2240 actorState->bounceDivisor += 1.0f;
2241 if (actorState->moveTime < actorState->bounceDivisor) {
2242 actor->curPos.x = actorState->goalPos.x;
2243 actor->curPos.y = actorState->goalPos.y;
2244 actor->curPos.z = actorState->goalPos.z;
2245 if (actor->actorTypeData1[2] != 0) {
2246 if (actor->actorTypeData1[3] == 0) {
2247 snd_stop_sound(actor->actorTypeData1[2]);
2248 }
2249 }
2250 return ApiStatus_DONE2;
2251 }
2252 if ((actor->actorTypeData1[2] != 0) && (actor->actorTypeData1[3] != 0)) {
2253 if (actor->actorTypeData1b[1] >= 0) {
2254 actorState->vel += actorState->speed;
2255 if (actor->actorTypeData1b[1] < actorState->vel) {
2256 actor->footStepCounter++;
2257 actorState->vel = 0.0f;
2258 if (actor->footStepCounter & 1) {
2259 if (actor->actorTypeData1[2] != 0) {
2261 }
2262 } else {
2263 if (actor->actorTypeData1[3] != 0) {
2265 }
2266 }
2267 }
2268 } else {
2269 actorState->vel += 1.0f;
2270 if (-actor->actorTypeData1b[1] <= actorState->vel) {
2271 actor->footStepCounter++;
2272 actorState->vel = 0.0f;
2273 if (actor->footStepCounter & 1) {
2274 if (actor->actorTypeData1[2] != 0) {
2276 }
2277 } else {
2278 if (actor->actorTypeData1[3] != 0) {
2280 }
2281 }
2282 }
2283 }
2284 }
2285
2286 deltaX = actorState->goalPos.x - actorState->curPos.x;
2287 deltaY = actorState->goalPos.y - actorState->curPos.y;
2288 deltaZ = actorState->goalPos.z - actorState->curPos.z;
2289 dist3D = sqrtf(SQ(deltaX) + SQ(deltaY) + SQ(deltaZ));
2290 if (dist3D == 0.0f) {
2291 dist3D = 1.0f;
2292 }
2293 if (actorState->dist == 0.0f) {
2294 actorState->dist = 1.0f;
2295 }
2296 offsetY = sin_deg((1.0 - (dist3D / actorState->dist)) * 180.0);
2297 if (actorState->moveArcAmplitude == 0) {
2298 offsetY = 0.0f;
2299 }
2300 if (actorState->moveArcAmplitude < 0) {
2301 offsetY = -offsetY * -actorState->moveArcAmplitude;
2302 }
2303 if (actorState->moveArcAmplitude > 0) {
2304 offsetY = offsetY * actorState->moveArcAmplitude;
2305 }
2306 actor->curPos.x = actorState->curPos.x;
2307 actor->curPos.y = actorState->curPos.y + offsetY;
2308 actor->curPos.z = actorState->curPos.z;
2309 return ApiStatus_BLOCK;
2310}
2311
2312API_CALLABLE(IdleFlyToGoal) {
2313 Bytecode* args = script->ptrReadPos;
2314 Actor* actor;
2315 ActorMovement* movement;
2316 s32 actorID;
2317 f32 posX, posY, posZ;
2318 f32 goalX, goalY, goalZ;
2319 f32 deltaX, deltaY, deltaZ;
2320 f32 dist3D;
2321 f32 offsetY;
2322
2323 if (isInitialCall) {
2324 actorID = evt_get_variable(script, *args++);
2325 if (actorID == ACTOR_SELF) {
2326 actorID = script->owner1.enemyID;
2327 }
2328 script->functionTempPtr[1] = actor = get_actor(actorID);
2329 movement = &actor->fly;
2330
2331 movement->flyTime = evt_get_variable(script, *args++);
2332 movement->flyArcAmplitude = evt_get_variable(script, *args++);
2333 script->functionTemp[3] = evt_get_variable(script, *args++);
2334
2335 goalX = movement->goalPos.x;
2336 goalY = movement->goalPos.y;
2337 goalZ = movement->goalPos.z;
2338
2339 posX = actor->curPos.x;
2340 posY = actor->curPos.y;
2341 posZ = actor->curPos.z;
2342
2343 deltaX = posX - goalX;
2344 deltaY = posY - goalY;
2345 deltaZ = posZ - goalZ;
2346
2347 movement->curPos.x = posX;
2348 movement->unk_18.x = posX;
2349 movement->curPos.y = posY;
2350 movement->unk_18.y = posY;
2351 movement->curPos.z = posZ;
2352 movement->unk_18.z = posZ;
2353
2354 movement->dist = sqrtf(SQ(deltaX) + SQ(deltaY) + SQ(deltaZ));
2355
2356 if (movement->flyTime == 0) {
2357 movement->flyTime = movement->dist / movement->speed;
2358 } else {
2359 movement->speed = movement->dist / movement->flyTime;
2360 }
2361 if (movement->flyTime == 0) {
2362 return ApiStatus_DONE2;
2363 }
2364
2365 movement->flyElapsed = 0.0f;
2366 movement->angle = 0.0f;
2367 movement->vel = 0.0f;
2368 }
2369
2370 actor = script->functionTempPtr[1];
2371 movement = &actor->fly;
2372
2373 movement->curPos.x = update_lerp_battle(script->functionTemp[3], movement->unk_18.x, movement->goalPos.x, movement->flyElapsed, movement->flyTime);
2374 movement->curPos.y = update_lerp_battle(script->functionTemp[3], movement->unk_18.y, movement->goalPos.y, movement->flyElapsed, movement->flyTime);
2375 movement->curPos.z = update_lerp_battle(script->functionTemp[3], movement->unk_18.z, movement->goalPos.z, movement->flyElapsed, movement->flyTime);
2376
2377 movement->flyElapsed += 1.0f;
2378 if (movement->flyTime < movement->flyElapsed) {
2379 actor->curPos.x = movement->goalPos.x;
2380 actor->curPos.y = movement->goalPos.y;
2381 actor->curPos.z = movement->goalPos.z;
2382 return ApiStatus_DONE2;
2383 }
2384
2385 deltaX = movement->goalPos.x - movement->curPos.x;
2386 deltaY = movement->goalPos.y - movement->curPos.y;
2387 deltaZ = movement->goalPos.z - movement->curPos.z;
2388 dist3D = sqrtf(SQ(deltaX) + SQ(deltaY) + SQ(deltaZ));
2389 if (dist3D == 0.0f) {
2390 dist3D = 1.0f;
2391 }
2392 if (movement->dist == 0.0f) {
2393 movement->dist = 1.0f;
2394 }
2395
2396 offsetY = sin_deg((1.0 - (dist3D / movement->dist)) * 180.0);
2397 if (movement->flyArcAmplitude == 0) {
2398 offsetY = 0.0f;
2399 }
2400 if (movement->flyArcAmplitude < 0) {
2401 offsetY = -offsetY * -movement->flyArcAmplitude;
2402 }
2403 if (movement->flyArcAmplitude > 0) {
2404 offsetY = offsetY * movement->flyArcAmplitude;
2405 }
2406
2407 actor->curPos.x = movement->curPos.x;
2408 actor->curPos.y = movement->curPos.y + offsetY;
2409 actor->curPos.z = movement->curPos.z;
2410 return ApiStatus_BLOCK;
2411}
2412
2413API_CALLABLE(FlyPartTo) {
2414 Bytecode* args = script->ptrReadPos;
2415 Actor* actor;
2416 ActorPart* part;
2417 ActorPartMovement* partMovement;
2418 s32 actorID;
2419 s32 partID;
2420
2421 f32 posX, posY, posZ;
2422 f32 goalX, goalY, goalZ;
2423 f32 deltaX, deltaY, deltaZ;
2424 f32 dist3D;
2425 f32 offsetY;
2426
2427 if (isInitialCall) {
2428 actorID = evt_get_variable(script, *args++);
2429 if (actorID == ACTOR_SELF) {
2430 actorID = script->owner1.actorID;
2431 }
2432 partID = evt_get_variable(script, *args++);
2433
2434 actor = get_actor(actorID);
2435 part = get_actor_part(actor, partID);
2436 script->functionTempPtr[1] = actor;
2437 script->functionTempPtr[2] = part;
2438 partMovement = part->movement;
2439
2440 partMovement->goalPos.x = evt_get_variable(script, *args++);
2441 partMovement->goalPos.y = evt_get_variable(script, *args++);
2442 partMovement->goalPos.z = evt_get_variable(script, *args++);
2443 partMovement->moveTime = evt_get_variable(script, *args++);
2444 partMovement->unk_3A = evt_get_variable(script, *args++);
2445 script->functionTemp[3] = evt_get_variable(script, *args++);
2446
2447 goalX = partMovement->goalPos.x;
2448 posX = part->absolutePos.x;
2449 deltaX = posX - goalX;
2450 partMovement->absolutePos.x = posX;
2451 partMovement->unk_18.x = posX;
2452
2453 goalY = partMovement->goalPos.y;
2454 posY = part->absolutePos.y;
2455 deltaY = posY - goalY;
2456 partMovement->absolutePos.y = posY;
2457 partMovement->unk_18.y = posY;
2458
2459 goalZ = partMovement->goalPos.z;
2460 posZ = part->absolutePos.z;
2461 deltaZ = posZ - goalZ;
2462 partMovement->absolutePos.z = posZ;
2463 partMovement->unk_18.z = posZ;
2464
2465 partMovement->dist = sqrtf(SQ(deltaX) + SQ(deltaY) + SQ(deltaZ));
2466
2467 if (partMovement->moveTime == 0) {
2468 partMovement->moveTime = partMovement->dist / partMovement->moveSpeed;
2469 } else {
2470 partMovement->moveSpeed = partMovement->dist / partMovement->moveTime;
2471 }
2472
2473 if (partMovement->moveTime == 0) {
2474 return ApiStatus_DONE2;
2475 }
2476
2477 if (part->partTypeData[2] != 0 && part->partTypeData[3] == 0) {
2479 }
2480 partMovement->unk_3C = 0;
2481 partMovement->angle = 0.0f;
2482
2483 if (part->actorTypeData2b[1] >= 0) {
2484 partMovement->unk_2C = actor->actorTypeData1b[1] + 1;
2485 } else {
2486 partMovement->unk_2C = ~actor->actorTypeData1b[1];
2487 }
2488 }
2489
2490 part = script->functionTempPtr[2];
2491 actor = script->functionTempPtr[1];
2492 partMovement = part->movement;
2493 partMovement->absolutePos.x = update_lerp_battle(script->functionTemp[3], partMovement->unk_18.x, partMovement->goalPos.x, partMovement->unk_3C, partMovement->moveTime);
2494 partMovement->absolutePos.y = update_lerp_battle(script->functionTemp[3], partMovement->unk_18.y, partMovement->goalPos.y, partMovement->unk_3C, partMovement->moveTime);
2495 partMovement->absolutePos.z = update_lerp_battle(script->functionTemp[3], partMovement->unk_18.z, partMovement->goalPos.z, partMovement->unk_3C, partMovement->moveTime);
2496 partMovement->unk_3C++;
2497
2498 if (partMovement->moveTime < partMovement->unk_3C) {
2499 part->absolutePos.x = partMovement->goalPos.x;
2500 part->absolutePos.y = partMovement->goalPos.y;
2501 part->absolutePos.z = partMovement->goalPos.z;
2502 if (part->partTypeData[2] != 0 && part->partTypeData[3] == 0) {
2503 snd_stop_sound(part->partTypeData[2]);
2504 }
2505 return ApiStatus_DONE2;
2506 }
2507
2508 if (part->partTypeData[2] != 0 && part->partTypeData[3] != 0) {
2509 if (part->actorTypeData2b[1] >= 0) {
2510 partMovement->unk_2C += partMovement->moveSpeed;
2511 if (part->actorTypeData2b[1] < partMovement->unk_2C) {
2512 actor->footStepCounter++;
2513 partMovement->unk_2C = 0;
2514 if (actor->footStepCounter % 2 != 0) {
2515 if (part->partTypeData[2] != 0) {
2517 }
2518 } else {
2519 if (part->partTypeData[3] != 0) {
2521 }
2522 }
2523 }
2524 } else {
2525 partMovement->unk_2C += 1.0f;
2526 if (-part->actorTypeData2b[1] <= partMovement->unk_2C) {
2527 actor->footStepCounter++;
2528 partMovement->unk_2C = 0;
2529 if (actor->footStepCounter % 2 != 0) {
2530 if (part->partTypeData[2] != 0) {
2532 }
2533 } else {
2534 if (part->partTypeData[3] != 0) {
2536 }
2537 }
2538 }
2539 }
2540 }
2541
2542 deltaX = partMovement->goalPos.x - partMovement->absolutePos.x;
2543 deltaY = partMovement->goalPos.y - partMovement->absolutePos.y;
2544 deltaZ = partMovement->goalPos.z - partMovement->absolutePos.z;
2545 dist3D = sqrtf(SQ(deltaX) + SQ(deltaY) + SQ(deltaZ));
2546 if (dist3D == 0.0f) {
2547 dist3D = 1.0f;
2548 }
2549 if (partMovement->dist == 0.0f) {
2550 partMovement->dist = 1.0f;
2551 }
2552
2553 offsetY = sin_deg((1.0 - dist3D / partMovement->dist) * 180.0);
2554 if (partMovement->unk_3A == 0) {
2555 offsetY = 0.0f;
2556 }
2557 if (partMovement->unk_3A < 0) {
2558 offsetY = -offsetY * (-partMovement->unk_3A);
2559 }
2560 if (partMovement->unk_3A > 0) {
2561 offsetY = offsetY * partMovement->unk_3A;
2562 }
2563
2564 part->absolutePos.x = partMovement->absolutePos.x;
2565 part->absolutePos.y = partMovement->absolutePos.y + offsetY;
2566 part->absolutePos.z = partMovement->absolutePos.z;
2567 return ApiStatus_BLOCK;
2568}
2569
2570API_CALLABLE(GetLastEvent) {
2571 Bytecode* args = script->ptrReadPos;
2572 s32 actorID = evt_get_variable(script, *args++);
2573 s32 outVar;
2574
2575 if (actorID == ACTOR_SELF) {
2576 actorID = script->owner1.actorID;
2577 }
2578
2579 outVar = *args++;
2580 evt_set_variable(script, outVar, get_actor(actorID)->lastEventType);
2581 return ApiStatus_DONE2;
2582}
2583
2584API_CALLABLE(SetTargetActor) {
2585 Bytecode* args = script->ptrReadPos;
2586 s32 actorID = evt_get_variable(script, *args++);
2587 s32 targetActorID;
2588 Actor* actor;
2589
2590 if (actorID == ACTOR_SELF) {
2591 actorID = script->owner1.actorID;
2592 }
2593
2594 targetActorID = evt_get_variable(script, *args++);
2595 actor = get_actor(actorID);
2596 actor->targetActorID = targetActorID;
2597 actor->targetPartID = 1;
2598 return ApiStatus_DONE2;
2599}
2600
2601API_CALLABLE(SetEnemyHP) {
2602 Bytecode* args = script->ptrReadPos;
2603 s32 actorID = evt_get_variable(script, *args++);
2604 s8 newHP;
2605 Actor* actor;
2606
2607 if (actorID == ACTOR_SELF) {
2608 actorID = script->owner1.actorID;
2609 }
2610
2611 newHP = evt_get_variable(script, *args++);
2612 actor = get_actor(actorID);
2613
2614 actor->curHP = newHP;
2615 if (newHP > actor->maxHP) {
2616 actor->curHP = actor->maxHP;
2617 }
2618
2619 actor->healthFraction = (actor->curHP * 25) / actor->maxHP;
2620
2621 return ApiStatus_DONE2;
2622}
2623
2624API_CALLABLE(GetActorHP) {
2625 PlayerData* playerData = &gPlayerData;
2626 Bytecode* args = script->ptrReadPos;
2627 s32 actorID = evt_get_variable(script, *args++);
2628 Actor* actor;
2629 s32 outVar;
2630 s32 outVal;
2631
2632 if (actorID == ACTOR_SELF) {
2633 actorID = script->owner1.actorID;
2634 }
2635 outVar = *args++;
2636
2637 actor = get_actor(actorID);
2638
2639 switch (actorID & ACTOR_CLASS_MASK) {
2640 case ACTOR_CLASS_PLAYER:
2641 outVal = playerData->curHP;
2642 break;
2644 outVal = 99;
2645 break;
2646 default:
2647 outVal = actor->curHP;
2648 break;
2649 }
2650
2651 evt_set_variable(script, outVar, outVal);
2652 return ApiStatus_DONE2;
2653}
2654
2655API_CALLABLE(GetEnemyMaxHP) {
2656 Bytecode* args = script->ptrReadPos;
2657 s32 actorID = evt_get_variable(script, *args++);
2658 s32 outVar;
2659
2660 if (actorID == ACTOR_SELF) {
2661 actorID = script->owner1.actorID;
2662 }
2663
2664 outVar = *args++;
2665 evt_set_variable(script, outVar, get_actor(actorID)->maxHP);
2666 return ApiStatus_DONE2;
2667}
2668
2669API_CALLABLE(RemoveActor) {
2670 BattleStatus* battleStatus = &gBattleStatus;
2671 EncounterStatus* currentEncounter = &gCurrentEncounter;
2672 Bytecode* args = script->ptrReadPos;
2673 s32 actorID = evt_get_variable(script, *args++);
2674 Actor* actor;
2675 s32 i;
2676 s32 numEnemies;
2677 s16* enemyIDs;
2678
2679 if (actorID == ACTOR_SELF) {
2680 actorID = script->owner1.actorID;
2681 }
2682
2683 actor = get_actor(actorID);
2684 numEnemies = battleStatus->numEnemyActors;
2685 enemyIDs = battleStatus->enemyIDs;
2686
2687 for (i = 0; i < numEnemies; i++) {
2688 if (actor == battleStatus->enemyActors[enemyIDs[i] & 0xFF]) {
2689 enemyIDs[i] = -1;
2690 }
2691 }
2692
2693 currentEncounter->coinsEarned += actor->extraCoinBonus;
2694 currentEncounter->coinsEarned += actor->actorBlueprint->coinReward;
2695 btl_delete_actor(actor);
2696 battleStatus->enemyActors[actorID & 0xFF] = NULL;
2697
2698 return ApiStatus_DONE2;
2699}
2700
2705 100, 100, 100,
2706 110,
2707 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
2708};
2709
2710API_CALLABLE(DropStarPoints) {
2711 BattleStatus* battleStatus = &gBattleStatus;
2712 PlayerData* playerData = &gPlayerData;
2713 Bytecode* args = script->ptrReadPos;
2714 Actor* dropper;
2715 f32 playerLevel;
2716 f32 enemyLevel;
2717 s32 actorID;
2718 f32 ntd;
2719 s32 numToDrop;
2720
2721 actorID = evt_get_variable(script, *args++);
2722 if (actorID == ACTOR_SELF) {
2723 actorID = script->owner1.enemyID;
2724 }
2725 dropper = get_actor(actorID);
2726
2727 enemyLevel = dropper->actorBlueprint->level;
2728 if (dropper->actorBlueprint->level == 0.0f) {
2729 enemyLevel = 1.0f;
2730 }
2731
2732 playerLevel = playerData->level;
2733 if (playerLevel == 0.0f) {
2734 playerLevel = 1.0f;
2735 }
2736
2737 ntd = 0.0f;
2738 if (!(enemyLevel < playerLevel)) {
2739 ntd = ((enemyLevel - playerLevel) * 0.5f) * StarPointMultiplier[battleStatus->initialEnemyCount];
2740 ntd = (ntd + 50.0f) / 100.0f;
2741 }
2742 numToDrop = ntd;
2743
2744 if (playerData->level < 27) {
2745 s32 spawnMode;
2746 s32 i;
2747
2748 if (dropper->flags & ACTOR_FLAG_UPSIDE_DOWN) {
2749 spawnMode = ITEM_SPAWN_MODE_TOSS_FADE3;
2750 } else {
2751 spawnMode = ITEM_SPAWN_MODE_TOSS_FADE1;
2752 }
2753
2754 for (i = 0; i < numToDrop; i++) {
2755 make_item_entity_delayed(ITEM_STAR_POINT,
2756 dropper->curPos.x, dropper->curPos.y, dropper->curPos.z, spawnMode, i, 0);
2757 }
2758
2759 battleStatus->incrementStarPointDelay = 40;
2760 battleStatus->pendingStarPoints += numToDrop;
2761 }
2762
2764 return ApiStatus_DONE2;
2765}
2766
2767API_CALLABLE(SetDefenseTable) {
2768 Bytecode* args = script->ptrReadPos;
2769 s32 actorID = evt_get_variable(script, *args++);
2770 s32 partID;
2771 u32* table;
2772
2773 if (actorID == ACTOR_SELF) {
2774 actorID = script->owner1.actorID;
2775 }
2776
2777 partID = evt_get_variable(script, *args++);
2778 table = (u32*) evt_get_variable(script, *args++);
2779 get_actor_part(get_actor(actorID), partID)->defenseTable = table;
2780 return ApiStatus_DONE2;
2781}
2782
2783API_CALLABLE(SetStatusTable) {
2784 Bytecode* args = script->ptrReadPos;
2785 s32 actorID = evt_get_variable(script, *args++);
2786 u32* table;
2787
2788 if (actorID == ACTOR_SELF) {
2789 actorID = script->owner1.actorID;
2790 }
2791
2792 table = (u32*) evt_get_variable(script, *args++);
2793 get_actor(actorID)->statusTable = table;
2794 return ApiStatus_DONE2;
2795}
2796
2797API_CALLABLE(SetIdleAnimations) {
2798 Bytecode* args = script->ptrReadPos;
2799 s32 actorID = evt_get_variable(script, *args++);
2800 s32 partID;
2801 AnimID* idleAnims;
2802
2803 if (actorID == ACTOR_SELF) {
2804 actorID = script->owner1.actorID;
2805 }
2806
2807 partID = evt_get_variable(script, *args++);
2808 idleAnims = (u32*) evt_get_variable(script, *args++);
2809 get_actor_part(get_actor(actorID), partID)->idleAnimations = idleAnims;
2810 return ApiStatus_DONE2;
2811}
2812
2813API_CALLABLE(func_8027CC10) {
2814 Bytecode* args = script->ptrReadPos;
2815 s32 actorID = evt_get_variable(script, *args++);
2816 s32 partID;
2817
2818 if (actorID == ACTOR_SELF) {
2819 actorID = script->owner1.actorID;
2820 }
2821
2822 partID = evt_get_variable(script, *args++);
2823
2824 // weirdly unused
2825 evt_get_variable(script, *args++);
2826 evt_get_variable(script, *args++);
2827
2828 get_actor_part(get_actor(actorID), partID);
2829 return ApiStatus_DONE2;
2830}
2831
2832API_CALLABLE(EnemyDamageTarget) {
2833 Bytecode* args = script->ptrReadPos;
2834 BattleStatus* battleStatus = &gBattleStatus;
2835 s32 actorID = evt_get_variable(script, *args++);
2836 Actor* actor;
2837 s32 outVar;
2838 s32 hitResult;
2839 s32 battleStatusFlags1Temp;
2840 s32 battleFlagsModifier;
2841
2842 if (actorID == ACTOR_SELF) {
2843 actorID = script->owner1.enemyID;
2844 }
2845
2846 actor = get_actor(actorID);
2847 outVar = *args++;
2848 battleStatus->curAttackElement = *args++;
2849 battleStatus->curAttackEventSuppression = *args++;
2850 battleStatus->curAttackStatus = *args++;
2851 battleStatus->curAttackDamage = evt_get_variable(script, *args++);
2852 battleFlagsModifier = *args++;
2853
2854 #if DX_DEBUG_MENU
2855 if (dx_debug_is_cheat_enabled(DEBUG_CHEAT_GOD_MODE)) {
2856 battleStatus->curAttackDamage = 0;
2857 battleStatus->curAttackStatus = 0;
2858 }
2859 #endif
2860
2861 // BS_FLAGS1_INCLUDE_POWER_UPS and BS_FLAGS1_TRIGGER_EVENTS are mutually exclusive
2862 if (battleFlagsModifier & BS_FLAGS1_INCLUDE_POWER_UPS) {
2864 gBattleStatus.flags1 &= ~BS_FLAGS1_TRIGGER_EVENTS;
2865 } else if (battleFlagsModifier & BS_FLAGS1_TRIGGER_EVENTS) {
2866 gBattleStatus.flags1 &= ~BS_FLAGS1_INCLUDE_POWER_UPS;
2868 } else {
2869 gBattleStatus.flags1 &= ~BS_FLAGS1_INCLUDE_POWER_UPS;
2870 gBattleStatus.flags1 &= ~BS_FLAGS1_TRIGGER_EVENTS;
2871 }
2872
2873 if (battleFlagsModifier & BS_FLAGS1_NICE_HIT) {
2875 } else {
2876 gBattleStatus.flags1 &= ~BS_FLAGS1_NICE_HIT;
2877 }
2878
2879 if (battleFlagsModifier & BS_FLAGS1_SUPER_HIT) {
2881 } else {
2882 gBattleStatus.flags1 &= ~BS_FLAGS1_SUPER_HIT;
2883 }
2884
2885 if (battleFlagsModifier & BS_FLAGS1_NO_RATING) {
2887 } else {
2888 gBattleStatus.flags1 &= ~BS_FLAGS1_NO_RATING;
2889 }
2890
2891 battleStatus->curTargetID = actor->targetActorID;
2892 battleStatus->curTargetPart = actor->targetPartID;
2893
2894 battleStatus->statusChance = battleStatus->curAttackStatus & 0xFF;
2895 if (battleStatus->statusChance == STATUS_KEY_NEVER) {
2896 battleStatus->statusChance = 0;
2897 }
2898 battleStatus->statusDuration = (battleStatus->curAttackStatus & 0xF00) >> 8;
2899
2900 hitResult = calc_enemy_damage_target(actor);
2901 if (hitResult < 0) {
2902 return ApiStatus_FINISH;
2903 }
2904
2905 evt_set_variable(script, outVar, hitResult);
2906 if (!(does_script_exist_by_ref(script))) {
2907 return ApiStatus_FINISH;
2908 }
2909
2910 return ApiStatus_DONE2;
2911}
2912
2913API_CALLABLE(EnemyFollowupAfflictTarget) {
2914 BattleStatus* battleStatus = &gBattleStatus;
2915 BattleStatus* anotherBattleStatus = &gBattleStatus;
2916 Bytecode* args = script->ptrReadPos;
2917 Actor* actor;
2918 s32 actorID = evt_get_variable(script, *args++);
2919 s32 hitResults;
2920 s32 outVar;
2921
2922 if (actorID == ACTOR_SELF) {
2923 actorID = script->owner1.actorID;
2924 }
2925
2926 actor = get_actor(actorID);
2927 outVar = *args++;
2928
2929 battleStatus->curTargetID = actor->targetActorID;
2930 battleStatus->curTargetPart = actor->targetPartID;
2931 battleStatus->statusChance = battleStatus->curAttackStatus;
2932
2933 if (battleStatus->statusChance == STATUS_KEY_NEVER) {
2934 battleStatus->statusChance = 0;
2935 }
2936
2937 anotherBattleStatus->statusDuration = (anotherBattleStatus->curAttackStatus & 0xF00) >> 8;
2938 hitResults = calc_enemy_damage_target(actor);
2939
2940 if (hitResults < 0) {
2941 return ApiStatus_FINISH;
2942 }
2943
2944 evt_set_variable(script, outVar, hitResults);
2945 if (does_script_exist_by_ref(script) == NULL) {
2946 return ApiStatus_FINISH;
2947 }
2948 return ApiStatus_DONE2;
2949}
2950
2951API_CALLABLE(EnemyTestTarget) {
2952 Bytecode* args = script->ptrReadPos;
2953 BattleStatus* battleStatus = &gBattleStatus;
2954 s32 actorID = evt_get_variable(script, *args++);
2955 Actor *actor;
2956 s32 outVar;
2957 s32 hitResult;
2958 u8 attackStatus;
2959 s32 battleStatusFlags1Temp;
2960 s32 battleFlagsModifier;
2961
2962 if (actorID == ACTOR_SELF) {
2963 actorID = script->owner1.enemyID;
2964 }
2965
2966 actor = get_actor(actorID);
2967 outVar = *args++;
2968 battleStatus->curAttackElement = *args++;
2969 battleStatus->curAttackEventSuppression = 0;
2970 battleStatus->curAttackStatus = *args++;
2971 battleStatus->curAttackDamage = evt_get_variable(script, *args++);
2972 battleFlagsModifier = *args++;
2973
2974 if (battleFlagsModifier & BS_FLAGS1_INCLUDE_POWER_UPS) {
2976 gBattleStatus.flags1 &= ~BS_FLAGS1_TRIGGER_EVENTS;
2977 } else if (battleFlagsModifier & BS_FLAGS1_TRIGGER_EVENTS) {
2978 gBattleStatus.flags1 &= ~BS_FLAGS1_INCLUDE_POWER_UPS;
2980 } else {
2981 gBattleStatus.flags1 &= ~BS_FLAGS1_INCLUDE_POWER_UPS;
2982 gBattleStatus.flags1 &= ~BS_FLAGS1_TRIGGER_EVENTS;
2983 }
2984
2985 if (battleFlagsModifier & BS_FLAGS1_NICE_HIT) {
2987 } else {
2988 gBattleStatus.flags1 &= ~BS_FLAGS1_NICE_HIT;
2989 }
2990 if (battleFlagsModifier & BS_FLAGS1_SUPER_HIT) {
2992 } else {
2993 gBattleStatus.flags1 &= ~BS_FLAGS1_SUPER_HIT;
2994 }
2995 if (battleFlagsModifier & BS_FLAGS1_NO_RATING) {
2997 } else {
2998 gBattleStatus.flags1 &= ~BS_FLAGS1_NO_RATING;
2999 }
3000
3001 attackStatus = battleStatus->curAttackStatus;
3002 battleStatus->curTargetID = actor->targetActorID;
3003
3004 battleStatus->curTargetPart = actor->targetPartID;
3005 battleStatus->statusChance = attackStatus;
3006
3007 if ((attackStatus & 0xFF) == 0xFF) {
3008 battleStatus->statusChance = 0;
3009 }
3010
3011 battleStatus->statusDuration = (battleStatus->curAttackStatus & 0xF00) >> 8;
3012 hitResult = calc_enemy_test_target(actor);
3013
3014 if (hitResult < 0) {
3015 return ApiStatus_FINISH;
3016 }
3017
3018 evt_set_variable(script, outVar, hitResult);
3019
3020 return ApiStatus_DONE2;
3021}
3022
3023API_CALLABLE(DispatchDamageEvent) {
3024 Bytecode* args = script->ptrReadPos;
3025 s32 actorID = evt_get_variable(script, *args++);
3026 Actor* actor;
3027 s32 damageAmount;
3028 s32 eventID;
3029
3030 if (actorID == ACTOR_SELF) {
3031 actorID = script->owner1.actorID;
3032 }
3033
3034 actor = get_actor(actorID);
3035 damageAmount = evt_get_variable(script, *args++);
3036 eventID = evt_get_variable(script, *args++);
3037
3038 if (dispatch_damage_event_actor_0(actor, damageAmount, eventID) < 0) {
3039 return ApiStatus_BLOCK;
3040 }
3041
3042 if (does_script_exist_by_ref(script)) {
3043 return ApiStatus_DONE2;
3044 } else {
3045 return ApiStatus_BLOCK;
3046 }
3047}
3048
3049API_CALLABLE(DispatchEvent) {
3050 Bytecode* args = script->ptrReadPos;
3051 s32 actorID = evt_get_variable(script, *args++);
3052
3053 if (actorID == ACTOR_SELF) {
3054 actorID = script->owner1.actorID;
3055 }
3056
3057 dispatch_event_actor(get_actor(actorID), evt_get_variable(script, *args++));
3058 return ApiStatus_DONE2;
3059}
3060
3061API_CALLABLE(ShowHealthBar) {
3062 s32 actorID = evt_get_variable(script, *script->ptrReadPos);
3063
3064 if (actorID == ACTOR_SELF) {
3065 actorID = script->owner1.actorID;
3066 }
3067
3069 return ApiStatus_DONE2;
3070}
3071
3072API_CALLABLE(HideHealthBar) {
3073 s32 actorID = evt_get_variable(script, *script->ptrReadPos);
3074
3075 if (actorID == ACTOR_SELF) {
3076 actorID = script->owner1.actorID;
3077 }
3078
3080 return ApiStatus_DONE2;
3081}
3082
3083API_CALLABLE(SetTargetOffset) {
3084 Bytecode* args = script->ptrReadPos;
3085 s32 actorID = evt_get_variable(script, *args++);
3086 s32 partID;
3087 ActorPart* part;
3088 s32 x;
3089 s32 y;
3090
3091 if (actorID == ACTOR_SELF) {
3092 actorID = script->owner1.actorID;
3093 }
3094
3095 partID = evt_get_variable(script, *args++);
3096 part = get_actor_part(get_actor(actorID), partID);
3097
3098 x = evt_get_variable(script, *args++);
3099 y = evt_get_variable(script, *args++);
3100
3101 part->targetOffset.x = x;
3102 part->targetOffset.y = y;
3103
3104 return ApiStatus_DONE2;
3105}
3106
3107API_CALLABLE(func_8027D434) {
3108 Bytecode* args = script->ptrReadPos;
3109 s32 actorID = evt_get_variable(script, *args++);
3110 s32 partID;
3111 ActorPart* part;
3112
3113 if (actorID == ACTOR_SELF) {
3114 actorID = script->owner1.actorID;
3115 }
3116
3117 partID = evt_get_variable(script, *args++);
3118 part = get_actor_part(get_actor(actorID), partID);
3119 part->targetPriorityOffset = evt_get_variable(script, *args++);
3120 return ApiStatus_DONE2;
3121}
3122
3123API_CALLABLE(SetProjectileTargetOffset) {
3124 Bytecode* args = script->ptrReadPos;
3125 s32 actorID = evt_get_variable(script, *args++);
3126 s32 partID;
3127 ActorPart* part;
3128 s32 dx;
3129 s32 dy;
3130
3131 if (actorID == ACTOR_SELF) {
3132 actorID = script->owner1.actorID;
3133 }
3134
3135 partID = evt_get_variable(script, *args++);
3136 part = get_actor_part(get_actor(actorID), partID);
3137
3138 dx = evt_get_variable(script, *args++);
3139 dy = evt_get_variable(script, *args++);
3140
3141 part->projectileTargetOffset.x = dx;
3142 part->projectileTargetOffset.y = dy;
3143
3144 return ApiStatus_DONE2;
3145}
3146
3147API_CALLABLE(EnableActorBlur) {
3148 Bytecode* args = script->ptrReadPos;
3149 s32 actorID = evt_get_variable(script, *args++);
3150 s32 enable = evt_get_variable(script, *args++);
3151 Actor* actor;
3152
3153 if (actorID == ACTOR_SELF) {
3154 actorID = script->owner1.actorID;
3155 }
3156
3157 actor = get_actor(actorID);
3158
3159 if (enable == ACTOR_BLUR_DISABLE) {
3160 disable_actor_blur(actor);
3161 } else if (enable == ACTOR_BLUR_ENABLE) {
3162 enable_actor_blur(actor);
3163 } else {
3164 reset_actor_blur(actor);
3165 }
3166 return ApiStatus_DONE2;
3167}
3168
3169API_CALLABLE(ForceDisableActorBlur) {
3170 Bytecode* args = script->ptrReadPos;
3171 s32 actorID = evt_get_variable(script, *args++);
3172 Actor* actor;
3173
3174 if (actorID == ACTOR_SELF) {
3175 actorID = script->owner1.actorID;
3176 }
3177
3178 actor = get_actor(actorID);
3180 return ApiStatus_DONE2;
3181}
3182
3183API_CALLABLE(AfflictActor) {
3184 Bytecode* args = script->ptrReadPos;
3185 s32 actorID = evt_get_variable(script, *args++);
3186 Actor* actor;
3187 s32 statusTypeKey;
3188 s32 duration;
3189 s32 statusDurationKey;
3190
3191 statusTypeKey = evt_get_variable(script, *args++);
3192 duration = evt_get_variable(script, *args++);
3193
3194 if (actorID == ACTOR_SELF) {
3195 actorID = script->owner1.actorID;
3196 }
3197 actor = get_actor(actorID);
3198
3199 switch (statusTypeKey) {
3200 case STATUS_KEY_FROZEN:
3201 statusDurationKey = STATUS_TURN_MOD_FROZEN;
3202 break;
3203 case STATUS_KEY_SLEEP:
3204 statusDurationKey = STATUS_TURN_MOD_SLEEP;
3205 break;
3207 statusDurationKey = STATUS_TURN_MOD_PARALYZE;
3208 break;
3209 case STATUS_KEY_DIZZY:
3210 statusDurationKey = STATUS_TURN_MOD_DIZZY;
3211 break;
3212 default:
3213 statusDurationKey = STATUS_TURN_MOD_PARALYZE;
3214 break;
3215 }
3216
3217 inflict_status_set_duration(actor, statusTypeKey, statusDurationKey, duration);
3218
3219 return ApiStatus_DONE2;
3220}
3221
3222API_CALLABLE(GetInstigatorValue) {
3223 Bytecode* args = script->ptrReadPos;
3224 s32 actorID = evt_get_variable(script, *args++);
3225 s32 outVar = *args++;
3226
3227 if (actorID == ACTOR_SELF) {
3228 actorID = script->owner1.actorID;
3229 }
3230
3231 evt_set_variable(script, outVar, get_actor(actorID)->instigatorValue);
3232 return ApiStatus_DONE2;
3233}
3234
3235API_CALLABLE(GetEncounterTrigger) {
3236 evt_set_variable(script, *script->ptrReadPos, gCurrentEncounter.hitType);
3237 return ApiStatus_DONE2;
3238}
3239
3240API_CALLABLE(YieldTurn) {
3242 return ApiStatus_DONE2;
3243}
3244
3245API_CALLABLE(SetActorSize) {
3246 Bytecode* args = script->ptrReadPos;
3247 s32 actorID = evt_get_variable(script, *args++);
3248 s32 y = evt_get_variable(script, *args++);
3249 s32 x = evt_get_variable(script, *args++);
3250 Actor* actor;
3251
3252 if (actorID == ACTOR_SELF) {
3253 actorID = script->owner1.actorID;
3254 }
3255
3256 actor = get_actor(actorID);
3257
3258 if (y != EVT_IGNORE_ARG) {
3259 actor->size.y = y;
3260 }
3261 if (x != EVT_IGNORE_ARG) {
3262 actor->size.x = x;
3263 }
3264 actor->shadowScale = actor->size.x / 24.0;
3265
3266 return ApiStatus_DONE2;
3267}
3268
3269API_CALLABLE(GetActorSize) {
3270 Bytecode* args = script->ptrReadPos;
3271 s32 actorID = evt_get_variable(script, *args++);
3272 s32 outY = *args++;
3273 s32 outX = *args++;
3274 Actor* actor;
3275
3276 if (actorID == ACTOR_SELF) {
3277 actorID = script->owner1.actorID;
3278 }
3279
3280 actor = get_actor(actorID);
3281 evt_set_variable(script, outY, actor->size.y);
3282 evt_set_variable(script, outX, actor->size.x);
3283 return ApiStatus_DONE2;
3284}
3285
3286API_CALLABLE(SetPartSize) {
3287 Bytecode* args = script->ptrReadPos;
3288 s32 actorID = evt_get_variable(script, *args++);
3289 s32 partID = evt_get_variable(script, *args++);
3290 s32 sizeY = evt_get_variable(script, *args++);
3291 s32 sizeX = evt_get_variable(script, *args++);
3292 ActorPart* part;
3293
3294 if (actorID == ACTOR_SELF) {
3295 actorID = script->owner1.actorID;
3296 }
3297
3298 part = get_actor_part(get_actor(actorID), partID);
3299
3300 if (sizeY != EVT_IGNORE_ARG) {
3301 part->size.y = sizeY;
3302 }
3303
3304 if (sizeX != EVT_IGNORE_ARG) {
3305 part->size.x = sizeX;
3306 }
3307
3308 part->shadowScale = part->size.x / 24.0;
3309
3310 return ApiStatus_DONE2;
3311}
3312
3313API_CALLABLE(GetOriginalActorType) {
3314 Bytecode* args = script->ptrReadPos;
3315 s32 actorID = evt_get_variable(script, *args++);
3316 s32 outVar = *args++;
3317
3318 if (actorID == ACTOR_SELF) {
3319 actorID = script->owner1.actorID;
3320 }
3321
3322 evt_set_variable(script, outVar, get_actor(actorID)->actorBlueprint->type);
3323 return ApiStatus_DONE2;
3324}
3325
3326API_CALLABLE(GetCurrentActorType) {
3327 Bytecode* args = script->ptrReadPos;
3328 s32 actorID = evt_get_variable(script, *args++);
3329 s32 outVar = *args++;
3330
3331 if (actorID == ACTOR_SELF) {
3332 actorID = script->owner1.actorID;
3333 }
3334
3335 evt_set_variable(script, outVar, get_actor(actorID)->actorType);
3336 return ApiStatus_DONE2;
3337}
3338
3339API_CALLABLE(GetLastDamage) {
3340 Bytecode* args = script->ptrReadPos;
3341 s32 actorID = evt_get_variable(script, *args++);
3342 s32 outVar;
3343
3344 if (actorID == ACTOR_SELF) {
3345 actorID = script->owner1.actorID;
3346 }
3347 outVar = *args++;
3348
3349 evt_set_variable(script, outVar, get_actor(actorID)->lastDamageTaken);
3350 return ApiStatus_DONE2;
3351}
3352
3353API_CALLABLE(EnableActorGlow) {
3354 Bytecode* args = script->ptrReadPos;
3355 s32 actorID = evt_get_variable(script, *args++);
3356 s32 flag;
3357 Actor* actor;
3358
3359 if (actorID == ACTOR_SELF) {
3360 actorID = script->owner1.actorID;
3361 }
3362
3363 flag = evt_get_variable(script, *args++);
3364 actor = get_actor(actorID);
3365 actor->isGlowing = flag;
3366
3367 if (!flag) {
3368 ActorPart* it = actor->partsTable;
3369
3370 while (it != NULL) {
3371 if (it->idleAnimations != NULL) {
3372 set_npc_imgfx_all(it->spriteInstanceID, IMGFX_CLEAR, 0, 0, 0, 0, 0);
3373 }
3374 it = it->nextPart;
3375 }
3377 }
3378
3379 return ApiStatus_DONE2;
3380}
3381
3382API_CALLABLE(WasStatusInflicted) {
3383 Bytecode* args = script->ptrReadPos;
3384 BattleStatus* battleStatus = &gBattleStatus;
3385 s32 outVal;
3386
3387 evt_get_variable(script, *args++);
3388
3389 if (script) { // can be args or script but not 1 or do while 0, nor does else work after
3390 outVal = battleStatus->wasStatusInflicted;
3391 }
3392 outVal = battleStatus->wasStatusInflicted;
3393
3394 evt_set_variable(script, *args++, outVal);
3395
3396 return ApiStatus_DONE2;
3397}
3398
3399API_CALLABLE(CopyStatusEffects) {
3400 Bytecode* args = script->ptrReadPos;
3401 s32 actorIDTo;
3402 s32 actorIDFrom;
3403 Actor* actorTo;
3404 Actor* actorFrom;
3405
3406 actorIDFrom = evt_get_variable(script, *args++);
3407 if (actorIDFrom == ACTOR_SELF) {
3408 actorIDFrom = script->owner1.actorID;
3409 }
3410 actorFrom = get_actor(actorIDFrom);
3411
3412 actorIDTo = evt_get_variable(script, *args++);
3413 if (actorIDTo == ACTOR_SELF) {
3414 actorIDTo = script->owner1.actorID;
3415 }
3416 actorTo = get_actor(actorIDTo);
3417
3418 inflict_status(actorTo, actorFrom->debuff, actorFrom->debuffDuration);
3419 inflict_status(actorTo, actorFrom->staticStatus, actorFrom->staticDuration);
3420 inflict_status(actorTo, actorFrom->stoneStatus, actorFrom->stoneDuration);
3421 inflict_status(actorTo, actorFrom->koStatus, actorFrom->koDuration);
3422 inflict_status(actorTo, actorFrom->transparentStatus, actorFrom->transparentDuration);
3423
3424 actorFrom->statusAfflicted = 0;
3425 actorTo->statusAfflicted = 0;
3426
3427 return ApiStatus_DONE2;
3428}
3429
3430API_CALLABLE(ClearStatusEffects) {
3431 Bytecode* args = script->ptrReadPos;
3432 s32 actorID = evt_get_variable(script, *args++);
3433 s32 flag;
3434 Actor* actor;
3435
3436 if (actorID == ACTOR_SELF) {
3437 actorID = script->owner1.actorID;
3438 }
3439
3440 actor = get_actor(actorID);
3441
3442 if (actor->debuff != 0) {
3443 actor->debuffDuration = 0;
3444 actor->debuff = 0;
3446 }
3447
3448 if (actor->staticStatus != 0) {
3449 actor->staticDuration = 0;
3450 actor->staticStatus = 0;
3452 }
3453
3454 if (actor->transparentStatus != 0) {
3455 actor->transparentDuration = 0;
3456 actor->transparentStatus = 0;
3458 }
3459
3460 if (actor->stoneStatus != 0) {
3461 actor->stoneDuration = 0;
3462 actor->stoneStatus = 0;
3463 }
3464
3465 actor->koStatus = 0;
3466 actor->koDuration = 0;
3468 actor->attackBoost = 0;
3469 actor->defenseBoost = 0;
3470 actor->isGlowing = FALSE;
3471
3472 return ApiStatus_DONE2;
3473}
s32 dispatch_damage_event_actor_1(Actor *actor, s32 damageAmount, s32 event)
Definition 1A5830.c:893
void dispatch_event_actor(Actor *actor, s32 event)
Definition 1A5830.c:103
HitResult calc_enemy_test_target(Actor *actor)
Definition 1A5830.c:128
void dispatch_event_general(Actor *actor, s32 event)
Definition 1A5830.c:24
f32 update_lerp_battle(s32 easing, f32 start, f32 end, s32 elapsed, s32 duration)
Definition 1A5830.c:2093
s32 dispatch_damage_event_actor(Actor *actor, s32 damageAmount, s32 originalEvent, s32 stopMotion)
Definition 1A5830.c:821
void play_hit_sound(Actor *actor, f32 x, f32 y, f32 z, u32 hitSound)
Definition 1A5830.c:38
s32 StarPointMultiplier[]
Star Point multiplier, indexed by actor count.
Definition 1A5830.c:2704
s32 dispatch_damage_event_actor_0(Actor *actor, s32 damageAmount, s32 event)
Definition 1A5830.c:889
s32 has_enchanted_part(Actor *actor)
Definition 1A5830.c:8
HitResult calc_enemy_damage_target(Actor *attacker)
Definition 1A5830.c:232
void snd_stop_sound(s32 soundID)
Definition 30450.c:256
s32 check_block_input(s32 buttonMask)
Definition action_cmd.c:537
struct EffectInstance * disableEffect
struct Evt * takeTurnScript
s32 idleScriptID
u32 * idleAnimations
s8 transparentStatus
struct ActorPartMovement * movement
EvtScript * handleEventSource
EvtScript * idleSource
f32 shadowScale
s16 lastDamageTaken
struct ActorBlueprint * actorBlueprint
s32 actorTypeData1[6]
s16 targetPriorityOffset
s8 healthFraction
Vec2b projectileTargetOffset
u8 footStepCounter
struct Evt * idleScript
s8 extraCoinBonus
ActorState state
s32 partTypeData[6]
s16 damageCounter
struct Evt * handleEventScript
struct ActorPart * partsTable
s32 takeTurnScriptID
s16 actorTypeData1b[2]
struct SelectableTarget targetData[24]
EvtScript * handlePhaseSource
s16 targetActorID
s8 chillOutAmount
Vec2bu size
s32 handleEventScriptID
union Evt::@8 owner1
Initially -1.
s16 hudElementDataIndex
ActorMovement fly
EvtScript * takeTurnSource
Vec3f curPos
s16 actorTypeData2b[2]
s16 hpChangeCounter
Bytecode EvtScript[]
s8 statusAfflicted
struct ActorPart * nextPart
s8 staticDuration
s32 * statusTable
s8 debuffDuration
u32 AnimID
s8 transparentDuration
#define sfx_play_sound_at_position
#define sqrtf
#define sin_deg
#define rand_int
#define atan2
struct DisableXFXData * disableX
Definition effects.h:2529
EffectData data
Definition effects.h:2605
#define ASSERT(condition)
@ ACTION_RATING_NICE
sets nice hits = 1
Definition enums.h:1979
@ ACTOR_CLASS_ENEMY
Definition enums.h:2079
@ ACTOR_CLASS_PLAYER
Definition enums.h:2077
@ ACTOR_CLASS_PARTNER
Definition enums.h:2078
@ ACTOR_CLASS_MASK
Definition enums.h:2080
@ BUTTON_A
Definition enums.h:2790
@ IMGFX_CLEAR
Definition enums.h:5117
@ GLOW_PAL_OFF
Definition enums.h:2258
@ BS_FLAGS1_TUTORIAL_BATTLE
Definition enums.h:3594
@ BS_FLAGS1_NO_RATING
Definition enums.h:3577
@ BS_FLAGS1_STAR_POINTS_DROPPED
Definition enums.h:3593
@ BS_FLAGS1_SUPER_HIT
Definition enums.h:3579
@ BS_FLAGS1_YIELD_TURN
Definition enums.h:3590
@ BS_FLAGS1_PLAYER_DEFENDING
Definition enums.h:3591
@ BS_FLAGS1_NICE_HIT
Definition enums.h:3576
@ BS_FLAGS1_TRIGGER_EVENTS
Definition enums.h:3575
@ BS_FLAGS1_ATK_BLOCKED
Definition enums.h:3600
@ BS_FLAGS1_INCLUDE_POWER_UPS
Definition enums.h:3571
@ HIT_SOUND_NORMAL
Definition enums.h:2187
@ HIT_SOUND_FIRE
Definition enums.h:2188
@ HIT_SOUND_SHOCK
Definition enums.h:2190
@ HIT_SOUND_BONES
Definition enums.h:2186
@ HIT_SOUND_ICE
Definition enums.h:2189
@ HIT_SOUND_MISS
Definition enums.h:2185
@ ACTOR_EVENT_FLAG_STAR_ROD_ENCHANTED
Actor glows and listens for Star Beam and Peach Beam events.
Definition enums.h:3386
@ ACTOR_EVENT_FLAG_ELECTRIFIED
Player takes shock damage upon contact.
Definition enums.h:3375
@ ACTOR_EVENT_FLAG_BURIED
Actor can only by hit by quake-element attacks.
Definition enums.h:3379
@ ACTOR_EVENT_FLAG_FLIPABLE
Actor can be flipped; triggered by jump and quake attacks.
Definition enums.h:3380
@ ACTOR_EVENT_FLAG_EXPLODE_ON_IGNITION
Blast and fire attacks trigger an explosion.
Definition enums.h:3377
@ ACTOR_EVENT_FLAG_ILLUSORY
Player attacks pass through and miss.
Definition enums.h:3374
@ ACTOR_EVENT_FLAG_ENCHANTED
Actor glows and listens for the Star Beam event.
Definition enums.h:3385
@ ITEM_SPAWN_MODE_TOSS_FADE3
Definition enums.h:2316
@ ITEM_SPAWN_MODE_TOSS_FADE1
Definition enums.h:2314
@ BS_FLAGS2_IS_FIRST_STRIKE
Definition enums.h:3618
@ STATUS_KEY_PARALYZE
Definition enums.h:2201
@ STATUS_TURN_MOD_PARALYZE
Definition enums.h:2234
@ STATUS_KEY_FROZEN
Definition enums.h:2203
@ STATUS_TURN_MOD_SLEEP
Definition enums.h:2228
@ STATUS_TURN_MOD_DIZZY
Definition enums.h:2232
@ STATUS_KEY_TRANSPARENT
Definition enums.h:2210
@ STATUS_KEY_STATIC
Definition enums.h:2207
@ STATUS_TURN_MOD_POISON
Definition enums.h:2233
@ STATUS_KEY_FEAR
Definition enums.h:2199
@ STATUS_TURN_MOD_STOP
Definition enums.h:2237
@ STATUS_KEY_SLEEP
Definition enums.h:2202
@ STATUS_KEY_STONE
Definition enums.h:2208
@ STATUS_KEY_STOP
Definition enums.h:2204
@ STATUS_TURN_MOD_STONE
Definition enums.h:2236
@ STATUS_TURN_MOD_FROZEN
Definition enums.h:2230
@ STATUS_KEY_SHRINK
Definition enums.h:2206
@ STATUS_KEY_DIZZY
Definition enums.h:2200
@ STATUS_KEY_POISON
Definition enums.h:2205
@ STATUS_TURN_MOD_STATIC
Definition enums.h:2229
@ STATUS_TURN_MOD_FEAR
Definition enums.h:2231
@ STATUS_TURN_MOD_SHRINK
Definition enums.h:2235
@ STATUS_KEY_DAZE
Definition enums.h:2209
HitResult
Definition enums.h:1948
@ HIT_RESULT_HIT_STATIC
Definition enums.h:1957
@ HIT_RESULT_BACKFIRE
Definition enums.h:1949
@ HIT_RESULT_NO_DAMAGE
Definition enums.h:1952
@ HIT_RESULT_HIT
Definition enums.h:1950
@ HIT_RESULT_LUCKY
Definition enums.h:1955
@ HIT_RESULT_IMMUNE
Definition enums.h:1958
@ HIT_RESULT_MISS
Definition enums.h:1956
@ SUPPRESS_EVENT_SHOCK_CONTACT
Definition enums.h:2903
@ EASING_SIN_OUT
Definition enums.h:521
@ EASING_COS_IN
Definition enums.h:522
@ EASING_CUBIC_IN
Definition enums.h:512
@ EASING_CUBIC_OUT
Definition enums.h:515
@ EASING_QUARTIC_IN
Definition enums.h:513
@ EASING_COS_BOUNCE
Definition enums.h:519
@ EASING_COS_SLOW_OVERSHOOT
Definition enums.h:517
@ EASING_QUADRATIC_IN
Definition enums.h:511
@ EASING_COS_IN_OUT
Definition enums.h:520
@ EASING_QUARTIC_OUT
Definition enums.h:516
@ EASING_QUADRATIC_OUT
Definition enums.h:514
@ EASING_LINEAR
Definition enums.h:510
@ EASING_COS_FAST_OVERSHOOT
Definition enums.h:518
@ IDLE_SCRIPT_RESTART
Definition enums.h:6409
@ IDLE_SCRIPT_ENABLE
Definition enums.h:6408
@ IDLE_SCRIPT_DISABLE
Definition enums.h:6407
@ STATUS_FLAG_FEAR
Definition enums.h:2815
@ STATUS_FLAG_STOP
Definition enums.h:2821
@ STATUS_FLAG_FROZEN
Definition enums.h:2814
@ STATUS_FLAG_STATIC
Definition enums.h:2813
@ STATUS_FLAG_SHRINK
Definition enums.h:2819
@ STATUS_FLAG_PARALYZE
Definition enums.h:2816
@ STATUS_FLAG_STONE
Definition enums.h:2820
@ STATUS_FLAG_DIZZY
Definition enums.h:2818
@ STATUS_FLAG_SLEEP
Definition enums.h:2812
@ STATUS_FLAG_POISON
Definition enums.h:2817
@ DMG_SRC_DEFAULT
Definition enums.h:1988
@ ABILITY_BERSERKER
Definition enums.h:457
@ ABILITY_P_DOWN_D_UP
Definition enums.h:473
@ ABILITY_CLOSE_CALL
Definition enums.h:469
@ ABILITY_HEALTHY_HEALTHY
Definition enums.h:491
@ ABILITY_DEFEND_PLUS
Definition enums.h:463
@ ABILITY_DAMAGE_DODGE
Definition enums.h:487
@ ABILITY_LAST_STAND
Definition enums.h:468
@ ABILITY_P_UP_D_DOWN
Definition enums.h:470
@ ABILITY_FIRE_SHIELD
Definition enums.h:443
@ ABILITY_LUCKY_DAY
Definition enums.h:471
@ ABILITY_PRETTY_LUCKY
Definition enums.h:444
@ SOUND_IMMUNE
Definition enums.h:745
@ SOUND_DAMAGE_STARS
Definition enums.h:950
@ SOUND_INFLICT_STATUS
Definition enums.h:1355
@ SOUND_HIT_PLAYER_ICE
Definition enums.h:721
@ SOUND_HIT_PLAYER_SHOCK
Definition enums.h:1194
@ SOUND_NONE
Definition enums.h:547
@ SOUND_HIT_PLAYER_FIRE
Definition enums.h:720
@ SOUND_HIT_NORMAL
Definition enums.h:724
@ SOUND_SMACK_TREE
Definition enums.h:787
@ SOUND_HIT_SHOCK
Definition enums.h:1195
@ SOUND_HIT_ICE
Definition enums.h:726
@ SOUND_HIT_FIRE
Definition enums.h:725
@ SOUND_HIT_BONES
Definition enums.h:746
@ SOUND_HIT_PLAYER_NORMAL
Definition enums.h:719
@ SOUND_INFLICT_SLEEP
Definition enums.h:1354
@ ACTOR_PLAYER
Definition enums.h:2085
@ ACTOR_SELF
Definition enums.h:2084
@ ACTOR_FLAG_FLYING
Quake Hammer can't hit.
Definition enums.h:3329
@ ACTOR_FLAG_NO_DMG_POPUP
Hide damage popup.
Definition enums.h:3341
@ ACTOR_FLAG_HEALTH_BAR_HIDDEN
Definition enums.h:3338
@ ACTOR_FLAG_UPSIDE_DOWN
HP bar offset below actor (e.g. Swooper when upside-down).
Definition enums.h:3331
@ ACTOR_FLAG_NO_DMG_APPLY
Damage is not applied to actor HP.
Definition enums.h:3340
@ SOUND_SPACE_DEFAULT
Definition enums.h:1737
@ ACTOR_BLUR_ENABLE
Definition enums.h:6414
@ ACTOR_BLUR_DISABLE
Definition enums.h:6413
@ EVENT_LUCKY
Definition enums.h:2172
@ EVENT_HIT
Definition enums.h:2132
@ EVENT_SPIN_SMASH_LAUNCH_HIT
Definition enums.h:2138
@ EVENT_BURN_HIT
Definition enums.h:2136
@ EVENT_FIRE_DEATH
Definition enums.h:2162
@ EVENT_IMMUNE
Definition enums.h:2146
@ EVENT_ZERO_DAMAGE
Definition enums.h:2144
@ EVENT_SHOCK_DEATH
Definition enums.h:2159
@ EVENT_EXPLODE_TRIGGER
Definition enums.h:2155
@ EVENT_BLOCK
Definition enums.h:2147
@ EVENT_SPIN_SMASH_DEATH
Definition enums.h:2154
@ EVENT_18
Definition enums.h:2145
@ EVENT_HIT_COMBO
Definition enums.h:2131
@ EVENT_DEATH
Definition enums.h:2153
@ EVENT_SPIN_SMASH_LAUNCH_DEATH
Definition enums.h:2158
@ EVENT_FLIP_TRIGGER
Definition enums.h:2135
@ EVENT_SHOCK_HIT
Definition enums.h:2165
@ ACTOR_PART_FLAG_DAMAGE_IMMUNE
electrified Plays extra hurt SFX?
Definition enums.h:3358
@ DAMAGE_TYPE_POW
Definition enums.h:2861
@ DAMAGE_TYPE_4000
Definition enums.h:2865
@ DAMAGE_TYPE_ICE
Definition enums.h:2854
@ DAMAGE_TYPE_STATUS_ALWAYS_HITS
Definition enums.h:2880
@ DAMAGE_TYPE_SMASH
Definition enums.h:2857
@ DAMAGE_TYPE_UNBLOCKABLE
Definition enums.h:2875
@ DAMAGE_TYPE_IGNORE_DEFENSE
Definition enums.h:2877
@ DAMAGE_TYPE_MAGIC
Definition enums.h:2855
@ DAMAGE_TYPE_SHOCK
Definition enums.h:2856
@ DAMAGE_TYPE_BLAST
Definition enums.h:2860
@ DAMAGE_TYPE_FIRE
Definition enums.h:2852
@ DAMAGE_TYPE_TRIGGER_LUCKY
Definition enums.h:2881
@ DAMAGE_TYPE_QUAKE
Definition enums.h:2862
@ DAMAGE_TYPE_JUMP
Definition enums.h:2858
@ DAMAGE_TYPE_NO_CONTACT
Definition enums.h:2878
@ DAMAGE_TYPE_MULTIPLE_POPUPS
Definition enums.h:2879
@ DAMAGE_TYPE_WATER
Definition enums.h:2853
@ EVT_PRIORITY_A
Definition evt.h:153
#define ApiStatus_DONE2
Definition evt.h:118
s32 Bytecode
Definition evt.h:7
#define ApiStatus_FINISH
Definition evt.h:120
#define ApiStatus_DONE1
Definition evt.h:117
#define ApiStatus_BLOCK
Definition evt.h:116
@ EVT_FLAG_RUN_IMMEDIATELY
don't wait for next update_scripts call
Definition evt.h:161
void show_primary_damage_popup(f32 x, f32 y, f32 z, s32 attack, s32 a)
Definition 190B20.c:2269
void enable_actor_blur(Actor *)
s32 does_script_exist_by_ref(Evt *script)
s32 evt_get_variable(Evt *script, Bytecode var)
Definition evt.c:1690
s32 is_ability_active(s32 arg0)
Definition inventory.c:1725
s32 player_team_is_ability_active(Actor *actor, s32 ability)
Definition 190B20.c:2765
void show_immune_bonk(f32 x, f32 y, f32 z, s32, s32, s32)
void remove_status_debuff(s32)
void disable_actor_blur(Actor *)
void add_xz_vec3f_copy1(Vec3f *vector, f32 speed, f32 angleDeg)
Definition 190B20.c:1148
void hide_actor_health_bar(Actor *)
Definition 190B20.c:2510
void show_actor_health_bar(Actor *)
Definition 190B20.c:2505
void remove_status_static(s32)
void clear_part_pal_adjustment(ActorPart *)
Definition 190B20.c:2618
f32 dist3D(f32 ax, f32 ay, f32 az, f32 bx, f32 by, f32 bz)
Definition 43F0.c:677
Evt * get_script_by_index(s32 index)
s32 suspend_all_script(s32 id)
s32 evt_set_variable(Evt *script, Bytecode var, s32 value)
Definition evt.c:1847
f32 cos_rad(f32 x)
Definition 43F0.c:717
void remove_status_transparent(s32)
void dispatch_event_player(s32)
Definition dmg_player.c:131
void set_actor_flash_mode(Actor *actor, s32 arg1)
Definition 190B20.c:2696
void show_damage_fx(Actor *actor, f32 x, f32 y, f32 z, s32 damage)
Definition 190B20.c:2334
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
void add_xz_vec3f(Vec3f *vector, f32 speed, f32 angleDeg)
Definition 190B20.c:1139
Evt * start_script(EvtScript *source, s32 priority, s32 initialState)
s32 inflict_status(Actor *, s32, s32)
Definition 190B20.c:2084
ActorPart * get_actor_part(Actor *actor, s32 partID)
Definition 190B20.c:1191
s32 func_80263230(Actor *, Actor *)
Definition 190B20.c:558
void set_actor_glow_pal(Actor *actor, s32 arg1)
Definition 190B20.c:2654
s32 get_defense(Actor *actor, s32 *defenseTable, s32 elementFlags)
Definition 190B20.c:2219
void add_xz_vec3f_copy2(Vec3f *vector, f32 speed, f32 angleDeg)
Definition 190B20.c:1157
void set_actor_anim(s32 actorID, s32 partID, AnimID animID)
Definition 190B20.c:1005
Actor * get_actor(s32 actorID)
Definition actor_api.c:155
void kill_script_by_ID(s32 id)
void func_80266970(Actor *)
Definition 190B20.c:2439
void reset_actor_blur(Actor *)
void play_movement_dust_effects(s32 var0, f32 xPos, f32 yPos, f32 zPos, f32 angleDeg)
Definition 190B20.c:1166
void force_disable_actor_blur(Actor *)
s32 inflict_status_set_duration(Actor *actor, s32 statusTypeKey, s32 statusDurationKey, s32 duration)
Definition 190B20.c:2581
s32 resume_all_script(s32 id)
f32 evt_get_float_variable(Evt *script, Bytecode var)
Definition evt.c:1930
void btl_delete_actor(Actor *actor)
Definition 16C8E0.c:1111
f32 sin_rad(f32 x)
Definition 43F0.c:713
void show_next_damage_popup(f32 x, f32 y, f32 z, s32 damageAmount, s32)
Definition 190B20.c:2295
void apply_shock_effect(Actor *)
s32 make_item_entity_delayed(s32 itemID, f32 x, f32 y, f32 z, s32 itemSpawnMode, s32 pickupDelay, s32 pickupVar)
void show_action_rating(s32, Actor *, f32, f32, f32)
Definition 190B20.c:2360
s32 try_inflict_status(Actor *, s32, s32)
Definition 190B20.c:2532
s32 inflict_partner_ko(Actor *target, s32 statusTypeKey, s32 duration)
Definition 190B20.c:2203
Evt * restart_script(Evt *script)
void dispatch_event_partner(s32)
Definition dmg_partner.c:7
EvtScript EVS_PlayStopHitFX
Definition dmg_player.c:109
EvtScript EVS_PlayFreezeHitFX
Definition dmg_player.c:115
EvtScript EVS_PlayShrinkHitFX
Definition dmg_player.c:125
EvtScript EVS_PlayParalyzeHitFX
Definition dmg_player.c:97
EvtScript EVS_PlayPoisonHitFX
Definition dmg_player.c:103
EvtScript EVS_PlaySleepHitFX
Definition dmg_player.c:85
EvtScript EVS_PlayDizzyHitFX
Definition dmg_player.c:91
s16 coinsEarned
Definition npc.h:377
EncounterStatus gCurrentEncounter
Definition encounter.c:176
#define PI_D
Definition macros.h:127
#define QUART(x)
Definition macros.h:168
#define EVT_IGNORE_ARG
Definition macros.h:46
#define STATUS_KEY_NEVER
Definition macros.h:223
#define CUBE(x)
Definition macros.h:167
#define SQ(x)
Definition macros.h:166
void set_npc_imgfx_all(s32 spriteIdx, ImgFXType imgfxType, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5)
Definition sprite.c:1254
s32 curAttackEventSuppression
struct Actor * enemyActors[24]
PlayerData gPlayerData
Definition 77480.c:40
BattleStatus gBattleStatus
Definition battle.c:11