Skip to content

Commit 01692d4

Browse files
committed
Add skill: HerosMovement: Swap
1 parent e168f88 commit 01692d4

File tree

11 files changed

+229
-2
lines changed

11 files changed

+229
-2
lines changed
227 Bytes
Loading

Contents/Texts/Source/texts/HerosMovement.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ Unit moves to opposite side of target ally.[X]
1414
## MSG_SKILL_Reposition
1515
Reposition: Allows unit to pull an[NL]
1616
adjacent ally to its opposite side.[X]
17+
18+
## MSG_SKILL_Swap
19+
Swap: Allows unit to swap positions[NL]
20+
with an adjacent ally.[X]

Data/SkillSys/Source/SkillInfo.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3934,4 +3934,11 @@ const struct SkillInfo gSkillInfos[MAX_SKILL_NUM + 1] = {
39343934
.icon = GFX_SkillIcon_Reposition,
39353935
},
39363936
#endif
3937+
3938+
#if (defined(SID_Swap) && COMMON_SKILL_VALID(SID_Swap))
3939+
[SID_Swap] = {
3940+
.desc = MSG_SKILL_Swap,
3941+
.icon = GFX_SkillIcon_Swap,
3942+
},
3943+
#endif
39373944
};

Debug/Event/Source/debug-event.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,8 @@ static void modify_unit_status(void)
466466
AddSkillDbgListByPid(CHARACTER_EIRIKA, SID_Enrage);
467467
#endif
468468

469-
#if defined(SID_Reposition) && (COMMON_SKILL_VALID(SID_Reposition))
470-
AddSkillDbgListByPid(CHARACTER_EPHRAIM, SID_Reposition);
469+
#if defined(SID_Swap) && (COMMON_SKILL_VALID(SID_Swap))
470+
AddSkillDbgListByPid(CHARACTER_EPHRAIM, SID_Swap);
471471
#endif
472472
}
473473

Kernel/Data/SkillSys/Data/SkillActionInfo.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,8 @@ const SkillActionFunc_t gSkillActionFuncTable[MAX_SKILL_NUM + 1] = {
8282
#if (defined(SID_Reposition) && COMMON_SKILL_VALID(SID_Reposition))
8383
[SID_Reposition] = Action_Reposition,
8484
#endif
85+
86+
#if (defined(SID_Swap) && COMMON_SKILL_VALID(SID_Swap))
87+
[SID_Swap] = Action_Swap,
88+
#endif
8589
};

Kernel/Data/SkillSys/Data/SkillMenuInfo.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,4 +344,17 @@ struct MenuItemDef const *const gSkillMenuInfos[MAX_SKILL_NUM + 1] = {
344344
.onSwitchOut = NULL,
345345
},
346346
#endif
347+
348+
#if (defined(SID_Swap) && COMMON_SKILL_VALID(SID_Swap))
349+
[SID_Swap] = &(const struct MenuItemDef) {
350+
.name = " 入れ替え",
351+
.color = TEXT_COLOR_SYSTEM_WHITE,
352+
.isAvailable = Swap_Usability,
353+
.onDraw = NULL,
354+
.onSelected = Swap_OnSelected,
355+
.onIdle = NULL,
356+
.onSwitchIn = NULL,
357+
.onSwitchOut = NULL,
358+
},
359+
#endif
347360
};

Kernel/Wizardry/Misc/SkillEffects/MenuSkills/HerosMovement/HerosMovement.event

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22

33
#include "Source/Pivot.lyn.event"
44
#include "Source/Reposition.lyn.event"
5+
#include "Source/Swap.lyn.event"

Kernel/Wizardry/Misc/SkillEffects/MenuSkills/HerosMovement/Source/HmuCommon.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ const u16 HerosMovementSkills[HMU_TYPE_COUNT] = {
1212
#if (defined(SID_Reposition) && COMMON_SKILL_VALID(SID_Reposition))
1313
[HMU_REPOSITION] = SID_Reposition,
1414
#endif
15+
16+
#if (defined(SID_Swap) && COMMON_SKILL_VALID(SID_Swap))
17+
[HMU_SWAP] = SID_Swap,
18+
#endif
1519
};
1620

1721
STATIC_DECLAR bool HerosMovementSkillRequired(void)
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#include "common-chax.h"
2+
#include "skill-system.h"
3+
#include "constants/skills.h"
4+
#include "constants/texts.h"
5+
#include "weapon-range.h"
6+
#include "heros-movement.h"
7+
8+
static void try_add_target(struct Unit *unit)
9+
{
10+
if (UnitOnMapAvaliable(unit) && AreUnitsAllied(gSubjectUnit->index, unit->index)) {
11+
if (!CanUnitCrossTerrain(unit, gBmMapTerrain[gActiveUnit->yPos][gActiveUnit->xPos]))
12+
return;
13+
14+
if (!CanUnitCrossTerrain(gActiveUnit, gBmMapTerrain[unit->yPos][unit->xPos]))
15+
return;
16+
17+
AddTarget(unit->xPos, unit->yPos, unit->index, 1);
18+
}
19+
}
20+
21+
static void make_target_list(struct Unit *unit)
22+
{
23+
int x = unit->xPos;
24+
int y = unit->yPos;
25+
26+
gSubjectUnit = unit;
27+
28+
ForEachAdjacentUnit(x, y, try_add_target);
29+
}
30+
31+
u8 Swap_Usability(const struct MenuItemDef *def, int number)
32+
{
33+
if (gActiveUnit->state & US_CANTOING)
34+
return MENU_NOTSHOWN;
35+
36+
if (!HasSelectTarget(gActiveUnit, make_target_list))
37+
return MENU_DISABLED;
38+
39+
return MENU_ENABLED;
40+
}
41+
42+
static u8 select_target_on_switchin(ProcPtr proc, struct SelectTarget* target)
43+
{
44+
int x, y;
45+
46+
BmMapFill(gBmMapMovement, -1);
47+
BmMapFill(gBmMapRange, 0);
48+
49+
x = target->x;
50+
y = target->y;
51+
52+
gBmMapRange[y][x] = 1;
53+
DisplayMoveRangeGraphics(MOVLIMITV_RMAP_BLUE);
54+
return 0;
55+
}
56+
57+
static u8 select_target_on_select(ProcPtr proc, struct SelectTarget *target)
58+
{
59+
gActionData.xOther = target->x;
60+
gActionData.yOther = target->y;
61+
gActionData.targetIndex = target->uid;
62+
63+
HideMoveRangeGraphics();
64+
65+
BG_Fill(gBG2TilemapBuffer, 0);
66+
BG_EnableSyncByMask(BG2_SYNC_BIT);
67+
68+
#if defined(SID_Swap) && (COMMON_SKILL_VALID(SID_Swap))
69+
gActionData.unk08 = SID_Swap;
70+
#endif
71+
72+
gActionData.unitActionType = CONFIG_UNIT_ACTION_EXPA_ExecSkill;
73+
74+
return TARGETSELECTION_ACTION_ENDFAST | TARGETSELECTION_ACTION_END | TARGETSELECTION_ACTION_SE_6A | TARGETSELECTION_ACTION_CLEARBGS;
75+
}
76+
77+
static u8 select_target_on_cancel(ProcPtr proc, struct SelectTarget* target)
78+
{
79+
HideMoveRangeGraphics();
80+
81+
return GenericSelection_BackToUM(proc, target);
82+
}
83+
84+
static const struct SelectInfo select_info = {
85+
.onInit = NULL,
86+
.onEnd = NULL,
87+
.onSwitchIn = select_target_on_switchin,
88+
.onSelect = select_target_on_select,
89+
.onCancel = select_target_on_cancel,
90+
.onHelp = NULL,
91+
};
92+
93+
u8 Swap_OnSelected(struct MenuProc *menu, struct MenuItemProc *item)
94+
{
95+
if (item->availability == MENU_DISABLED) {
96+
MenuFrozenHelpBox(menu, MSG_HMU_ERROR_TERRAIN);
97+
return MENU_ACT_SND6B;
98+
}
99+
100+
ClearBg0Bg1();
101+
102+
make_target_list(gActiveUnit);
103+
BmMapFill(gBmMapMovement, -1);
104+
105+
StartSubtitleHelp(
106+
NewTargetSelection(&select_info),
107+
GetStringFromIndex(MSG_HMU_SELECTTARGET_SUBTITLEHELP));
108+
109+
return MENU_ACT_SKIPCURSOR | MENU_ACT_END | MENU_ACT_SND6A;
110+
}
111+
112+
static void action_init(struct ProcHmu *proc)
113+
{
114+
struct Unit *unit = GetUnit(gActionData.targetIndex);
115+
116+
proc->mu1 = GetUnitMu(gActiveUnit);
117+
if (!proc->mu1) {
118+
HideUnitSprite(gActiveUnit);
119+
proc->mu1 = StartMu(gActiveUnit);
120+
}
121+
SetMuFacing(proc->mu1, GetFacingDirection(gActiveUnit->xPos, gActiveUnit->yPos, gActionData.xOther, gActionData.yOther));
122+
123+
proc->mu2 = GetUnitMu(unit);
124+
if (!proc->mu2) {
125+
HideUnitSprite(unit);
126+
proc->mu2 = StartMu(unit);
127+
}
128+
SetMuFacing(proc->mu2, GetFacingDirection(gActionData.xOther, gActionData.yOther, gActiveUnit->xPos, gActiveUnit->yPos));
129+
130+
DisableMuCamera(proc->mu2);
131+
proc->timer1 = proc->timer2 = 0;
132+
}
133+
134+
static void action_loop(struct ProcHmu *proc)
135+
{
136+
if (proc->timer1 < 1) {
137+
Mu_OnStateMovement(proc->mu1);
138+
139+
if (proc->mu1->move_clock_q4 == 0)
140+
proc->timer1++;
141+
}
142+
143+
if (proc->timer2 < 1) {
144+
Mu_OnStateMovement(proc->mu2);
145+
146+
if (proc->mu2->move_clock_q4 == 0)
147+
proc->timer2++;
148+
}
149+
150+
if (proc->timer1 >= 1 && proc->timer2 >= 1)
151+
Proc_Break(proc);
152+
}
153+
154+
static void action_end(struct ProcHmu *proc)
155+
{
156+
struct Unit *unit = GetUnit(gActionData.targetIndex);
157+
158+
unit->xPos = gActiveUnit->xPos;
159+
unit->yPos = gActiveUnit->yPos;
160+
161+
gActionData.xMove = gActiveUnit->xPos = gActionData.xOther;
162+
gActionData.yMove = gActiveUnit->yPos = gActionData.yOther;
163+
}
164+
165+
static const struct ProcCmd proc_scr_action[] = {
166+
PROC_YIELD,
167+
PROC_CALL(action_init),
168+
PROC_YIELD,
169+
PROC_REPEAT(action_loop),
170+
PROC_YIELD,
171+
PROC_CALL(action_end),
172+
PROC_END
173+
};
174+
175+
static void callback_anim(ProcPtr proc)
176+
{
177+
Proc_StartBlocking(proc_scr_action, proc);
178+
}
179+
180+
bool Action_Swap(ProcPtr parent)
181+
{
182+
int sid = gActionData.unk08;
183+
184+
if (SkillListTester(gActiveUnit, sid))
185+
NewMuSkillAnimOnActiveUnitWithDeamon(parent, sid, callback_anim, NULL);
186+
else
187+
callback_anim(parent);
188+
189+
return true;
190+
}

include/constants/skills-others.enum.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ SID_DivineReprieve
294294
// HerosMovement skills
295295
SID_Pivot
296296
SID_Reposition
297+
SID_Swap
297298

298299
// Art skills
299300
SID_COMBAT_Galeforce

0 commit comments

Comments
 (0)