Alchemy
Loading...
Searching...
No Matches

psynergy.c

Go to the documentation of this file.
1/// @file
2/// Using Psynergy on the field.
3/// Part of object.c, the field object, compiled only through it.
4
6
7/// Uses Psynergy on the field. code holds the Psynergy (bits 0 to 9), its
8/// user (bits 10 to 13; 15 for character 0) and ACT_PACKED to use it without
9/// paying PP. Checks it can be used here (Reveal not on the world map, Retreat
10/// where it is not blocked, after asking), pays its PP, then plays its effect
11/// between the scene's Psynergy events for what the leader faces: phase 1
12/// before and phase 0 after. A phase 5 event is not run here; it only makes
13/// the effect aim at the actor ahead, and the effects that act on it (Force,
14/// Frost, Reveal) find it themselves. An after event whose trigger has flag
15/// 0x400 plays the effect itself. Called by Field_RunScene for the Psynergy
16/// request (work->command); sets work->resolvingAction while the effect plays.
18 s32 abilityId = ABILITY_ID(code);
19 struct FieldWork *work = (struct FieldWork *)gEventWork;
20 const struct SceneEvent *before;
21 const struct SceneEvent *after;
22 const struct SceneEvent *during;
23 s32 userId;
24 s32 target;
25 s32 retreat;
26 s32 abilityGroup;
27 s32 ppCost;
28 s32 declined;
29
30 abilityGroup = BattleActGet(abilityId)->type0c;
31 userId = ACT_UNIT(code);
32 // The leader is looked up and the result is not used.
34 retreat = 0;
37 if (userId == UNIT_NONE)
38 userId = 0;
39
40 // Where Psynergy has no effect.
42 PSYNERGY_MESSAGE(userId, abilityId, MsgNothingHappened);
43 return 0;
44 }
45 if (work->mode == MODE_WORLD_MAP && abilityId == ABILITY_REVEAL) {
46 PSYNERGY_MESSAGE(userId, ABILITY_REVEAL, MsgNothingHappened);
47 return 0;
48 }
49
50 // Retreat: ask, then go back to where the party entered this place.
51 if (abilityId == ABILITY_RETREAT) {
53 PSYNERGY_MESSAGE(userId, ABILITY_RETREAT, MsgDoesNotWorkHere);
54 return 0;
55 }
57 UiText_ShowPositionedMessageAndWaitFar(MsgUseAbilityConfirm, 13);
58 declined = Menu_AskYesNo(1); // 0 is yes
60 if (declined != 0)
61 return 0;
62 {
63 struct GameState *state = &gGameState;
64 s32 scene, returnEntrance;
65 scene = (u16)state->retreatScene;
66 state->scene = scene;
67 returnEntrance = (u16)state->retreatEntrance;
68 state->entrance = returnEntrance;
69 }
70 work->exit = EXIT_RETREAT;
71 retreat = 1;
72 }
73 // A use that pays no PP only runs the scene's events (phases 3 and 2).
74 if (code & ACT_PACKED)
75 return Field_RunPsynergyEvents(code);
76
77 // A party member pays the PP.
78 if (userId <= ALLY_MAX) {
79 ppCost = BattleActGet(abilityId)->ppCost;
80 if (UnitGetFar(userId)->pp < ppCost) {
81 PSYNERGY_MESSAGE(userId, abilityId, MsgNotEnoughPp);
82 // Retreat was already accepted: take its exit back (the scene and
83 // entrance it chose stay in the game state).
84 if (retreat)
85 work->exit = 0;
86 return 0;
87 }
88 Unit_AddPpFar(userId, -ppCost);
89 }
90
91 // Find the scene's events, and choose how the effect plays. The before
92 // event runs before the two flags are read, so its script can change them.
93 before = BattleFx_FindMatchingEvent(PSYNERGY_EV(1), abilityGroup, &target);
94 after = BattleFx_FindMatchingEvent(PSYNERGY_EV(0), abilityGroup, &target);
95 during = BattleFx_FindMatchingEvent(PSYNERGY_EV(5), abilityGroup, &target);
96 target = -1;
99 if (before || after || during) {
100 target =
102 // An event with trigger flag 0x400 plays the effect itself.
103 if (after && (after->trigger & 0x400)) {
106 }
107 } else
109
110 // Play the effect.
111 if (work->mode == MODE_WORLD_MAP)
114 work->resolvingAction = 1;
117
118 Field_RunEventAction(before, userId, target);
122 else
123 BattleFx_Run();
124 }
126 Field_RunEventAction(after, userId, target);
131 work->resolvingAction = 0;
133 if (work->mode == MODE_WORLD_MAP)
135 return 0;
136}
137
138/// Returns whether the scene has a Psynergy event, in any phase, for
139/// Psynergy of group and what the leader faces. Exported as
140/// BattleFx_HasMatchingEvent5Far, which no ☀️ code names.
142 s32 target;
143 s32 eventAddress =
145 return (u32)((-eventAddress) | eventAddress) >> 31;
146}
147
148/// Returns whether the scene has an event for item and what the leader faces.
149/// Called by the item menu (menu/item.c) through BattleFx_HasTriggerFar: such
150/// an item closes the menu and is used on the field.
152 s32 eventAddress;
153
154 eventAddress = Field_FindItemEvent(item);
155 return (u32)((0 - eventAddress) | eventAddress) >> 31;
156}
@ ABILITY_REVEAL
Definition ability_ids.h:19
@ ABILITY_RETREAT
Definition ability_ids.h:24
void * ObjectTable_Get(u32 actorIndex)
Returns the actor in slot index (0 to 65), or NULL.
Definition actors.c:462
void BattleEffect_ClearOutOfBoundsObjects(void)
Destroys the placed actors far from the view's centre: more than 160 pixels to either side,...
Definition actors.c:357
void BattleEffect_ClearAllObjects(void)
Destroys every placed actor and places the scene's actors again from its first placement table after ...
Definition actors.c:417
#define ALLY_MAX
the last party member's unit id
struct BattleUnit * UnitGetFar(u32 owner)
s16 Unit_AddPpFar(s32 owner, s32 delta)
s32 GameFlag_TestFar(s32 flag)
struct BattleAct * BattleActGet(s32 actionId)
Far call to BattleAction_GetDirect.
s32 GameFlag_SetBitFar(s32 flag)
void GameFlag_ClearBitFar(s32 flag)
void UiText_ShowPositionedMessageAndWaitFar(s32 no, s32 flags)
void UiWork_PushValueSlotFar(u32 value, u32 kind)
void UiWork_FinalizePendingCoreFar(void)
#define FLAG_RETREAT_BLOCKED
Retreat is blocked, from Psynergy or an item.
Definition flags.h:55
#define FLAG_ITEM_USE
the Psynergy comes from an item
Definition flags.h:56
#define FLAG_IN_LINK_LOBBY
Set when the cleared game's menu goes to the link lobby: there Psynergy has no effect and the system ...
Definition flags.h:80
struct GameState gGameState
void * BattleFx_FindMatchingEvent(s32 eventFlags, s32 group, void *target)
Returns the scene's Psynergy event (kind 5) for Psynergy of the given group that applies to what the ...
Definition items.c:206
s32 Field_FindItemEvent(s32 item)
Returns the scene's item event (kind 4) for item that applies to what the leader faces,...
Definition items.c:16
s32 Field_RunPsynergyEvents(s32 packed)
Runs the scene's events for Psynergy without paying its PP or showing its usual effect (phases 3 and ...
Definition items.c:253
s32 Field_UsePsynergy(u32 code)
Uses Psynergy on the field.
Definition psynergy.c:17
u32 BattleFx_HasTrigger(u16 item)
Returns whether the scene has an event for item and what the leader faces.
Definition psynergy.c:151
s32 BattleFx_HasMatchingEvent5(s32 group)
Returns whether the scene has a Psynergy event, in any phase, for Psynergy of group and what the lead...
Definition psynergy.c:141
s32 Field_FindNearbyPsynergyTarget(s32 id, s32 kind)
Returns the actor nearest in front of actor id that a field Psynergy of the given kind can reach,...
Definition targets.c:110
void BattleFx_DispatchRequestKind(void)
Casts the current Psynergy effect on its target (secondObjectId): runs the handler of its kind.
Definition dispatch.c:127
s32 Field_RunEventAction(const void *event, s32 param, s32 target)
Runs the event tied to an effect: a result below 0x10000 is a message, shown at target; a larger one ...
Definition dispatch.c:242
void BattleFx_ClearChildValueOnMismatch(void)
Finishes the current effect when it is Mind Read: ends the effect and lets its target move again,...
Definition dispatch.c:202
void BattleFx_Run(void)
Casts the current Psynergy effect with no target: runs the body of its kind (scene->fieldKind).
Definition dispatch.c:35
s32 Menu_AskYesNo(s32 atBottom)
Asks yes or no at the top of the screen, or at the bottom with atBottom set.
Definition events.c:468
void Leader_StopMoving(void)
Stops the leader where it stands: no horizontal velocity, the normal walking speed (1....
Definition events.c:67
void BattleFx_SetupObjectPair(s32 userId, s32 targetId)
Records the caster and the target of an effect.
Definition setup.c:56
void EffectRuntime_StopCurrentObject(void)
Stops the caster's per-frame hook and restores its colours.
Definition setup.c:94
void BattleEffect_CleanupSceneObjects(void)
Ends a Psynergy effect: frees the effect slots still in use and, unless another effect is being resol...
Definition setup.c:110
void EventObject_Initialize(void)
Starts casting: the caster takes its casting pose (animation 20) and stops.
Definition setup.c:186
void BattleFx_LoadActionEffectResources(s32 abilityId, s32 mode)
Prepares the work of the Psynergy effect for ability (heap slot 56) and loads its spark tiles.
Definition setup.c:13
What every part of object.c shares: its includes and the macros and types more than one part uses.
#define ABILITY_ID(c)
the Psynergy
#define ACT_PACKED
use it without paying PP
#define UNIT_NONE
#define EXIT_RETREAT
the exit Retreat takes
#define ACT_UNIT(c)
who uses it
#define FLAG_PSYNERGY_EFFECT
play the usual effect
#define PSYNERGY_MESSAGE(who, act, m)
Shows message m with the user's and the Psynergy's names, and waits.
#define FLAG_PSYNERGY_TARGET
aim the effect at the target
#define PSYNERGY_EV_ANY
any phase
#define PSYNERGY_EV(phase)
The flags of a Psynergy event (kind 5) in the given phase.
struct EventWork * gEventWork
u8 type0c
The field Psynergy the ability works as, 1 (Move) to 16 (Avoid); 0 for none.
u8 ppCost
PP the ability costs.
Full event work allocated by Field_RunScene (heap slot 27).
s16 exit
the exit taken, which ends the scene
s8 resolvingAction
set while Psynergy takes effect
s16 mode
MODE_WORLD_MAP (3) on the world map.
The game's state: play time, coins, the scene and the leader's position, the active party and the opt...
Definition game_state.h:14
s16 retreatEntrance
where Retreat goes; the group's first entrance
Definition game_state.h:109
s16 retreatScene
where Retreat goes; the group's first entrance
Definition game_state.h:108
s16 entrance
Definition game_state.h:37
s32 selectedActor
the leader: its unit and its actor
Definition game_state.h:59
A scene event: its kind and detail, the trigger it answers, its condition and its value (a message or...
s16 trigger
What the event answers: an actor id, a tile's collision code, a marker id or a raised value.
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
unsigned short u16
Definition types.h:13
#define MODE_WORLD_MAP
the world map
Definition object.h:78