1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
// The Mana World scripts.
// Author:
// Reid
// Jesusalva
// Description:
// Artis's Legion of Aemil officier of the fighting room.
// Note:
// ATL - Artis Training Legion
001-2-32,27,27,0 script Serena NPC_SERENA,{
mesn;
mesq l("Oh darling, what brought you here?"); // TRANSLATORS: Darling - Expresses familiarity or elderliness in relation to PC.
next;
select
l("I wanna fight."),
l("Nothing.");
mes "";
if (@menu == 1) {
mes l("Just walk right and talk to me. I'll be there in no time.");
mesc l("Challenge time limit: 60 minutes after entering the room.");
}
close;
OnInit:
.distance = 3;
end;
}
001-2-35,26,27,0 script Serena#Ctrl NPC_SERENA,{
function checkVictory;
// We can't begin if we're already doing it
if (.atlf) {
// TODO: We should check if the timers are running
//doevent(instance_npcname(.name$)+"::OnVerify");
if (getq(Artis_Legion_Progress) == 4)
npctalk l("You're already done with the training, so feel free to leave.");
else
npctalk l("Focus on the fight!");
end;
}
// Enemies of the Legion of Aemil cannot train, obviously
if (faction_standing("LEGION", true) < 1) {
mesn;
mesq l("Sorry, but I can only train you if Lieutenant Lozerk authorizes.");
close;
}
// Otherwise, begin it
mesn;
mesq l("Are you ready for your training?");
next;
if (askyesno() == ASK_NO) {
mesn;
mesq l("Oh dear, please come back later then.");
close;
}
@ATLFIGHT=true;
// FALL THROUGH
OnBegin:
mapannounce getmap(), l("Training Arena, %s, get ready!", strcharinfo(0)), bc_all;
// Save permanent data
.atl_blv=BaseLevel;
.atl_Str=readbattleparam(getcharid(3), UDT_STR);
.atl_Agi=readbattleparam(getcharid(3), UDT_AGI);
.atl_Vit=readbattleparam(getcharid(3), UDT_VIT);
.atl_Int=readbattleparam(getcharid(3), UDT_INT);
.atl_Dex=readbattleparam(getcharid(3), UDT_DEX);
.atl_Luk=readbattleparam(getcharid(3), UDT_LUK);
.atl_Dly=readbattleparam(getcharid(3), UDT_ADELAY);
.atl_Rng=readbattleparam(getcharid(3), UDT_ATKRANGE);
// Save (b)ase data
.atl_bhp=MaxHp;
.atl_bAtk1=readbattleparam(getcharid(3), UDT_ATKMIN);
.atl_bAtk2=readbattleparam(getcharid(3), UDT_ATKMAX);
.atl_bMatk=readbattleparam(getcharid(3), UDT_MATKMAX);
.atl_bDef=readbattleparam(getcharid(3), UDT_DEF);
.atl_bMdef=readbattleparam(getcharid(3), UDT_MDEF);
.atl_bHit=readbattleparam(getcharid(3), UDT_FLEE)*8/10;
.atl_bFlee=readbattleparam(getcharid(3), UDT_HIT)*7/10;
.atl_bCrit=readbattleparam(getcharid(3), UDT_CRIT);
// Save (p)rogression data
.atl_php=.atl_bhp/6;
.atl_pAtk1=.atl_bAtk1/12;
.atl_pAtk2=.atl_bAtk2/12;
.atl_pMatk=.atl_bMatk/5;
.atl_pDef=.atl_bDef/5;
.atl_pMdef=.atl_bMdef/5;
.atl_pHit=.atl_bFlee/10;
.atl_pFlee=.atl_bHit/15;
.atl_pCrit=.atl_bCrit/10;
// Begin the battle
doevent(instance_npcname(.name$)+"::OnGladius");
addtimer(5000, instance_npcname(.name$)+"::OnVerify");
closeclientdialog;
close;
OnGladius:
sleep(800);
// TODO: Coordinates, Helpers?
.@mg=monster(instance_mapname("001-2-35"), any(25, 30, 35), any(29, 35, 40, 46), "Gladiator", any(LegionSwordswoman, LegionHalberdier, LegionLieutenant, LegionLieutenant), 1, instance_npcname(.name$)+"::OnGladius");
// Set "permanent" data
setunitdata(.@mg, UDT_ADELAY, .atl_Dly-.atlf);
setunitdata(.@mg, UDT_ATKRANGE, .atl_Rng+cap_value(.atlf/10, 0, 3));
// Set base data
setunitdata(.@mg, UDT_LEVEL, .atl_blv+.atlf);
setunitdata(.@mg, UDT_STR, .atl_Str+.atlf);
setunitdata(.@mg, UDT_AGI, .atl_Agi+.atlf);
setunitdata(.@mg, UDT_VIT, .atl_Vit+.atlf);
setunitdata(.@mg, UDT_INT, .atl_Int+.atlf);
setunitdata(.@mg, UDT_DEX, .atl_Dex+.atlf);
setunitdata(.@mg, UDT_LUK, .atl_Luk+.atlf);
// Set variable data
setunitdata(.@mg, UDT_MAXHP, .atl_bhp+.atl_php*(.atlf-1));
setunitdata(.@mg, UDT_HP, .atl_bhp+.atl_php*(.atlf-1));
setunitdata(.@mg, UDT_ATKMIN, .atl_bAtk1+.atl_pAtk1*(.atlf-1));
setunitdata(.@mg, UDT_ATKMAX, .atl_bAtk2+.atl_pAtk2*(.atlf-1));
setunitdata(.@mg, UDT_MATKMIN, .atl_bMatk+.atl_pMatk*(.atlf-1));
setunitdata(.@mg, UDT_MATKMAX, .atl_bMatk+.atl_pMatk*(.atlf-1));
setunitdata(.@mg, UDT_DEF, .atl_bDef+.atl_pDef*(.atlf-1));
setunitdata(.@mg, UDT_MDEF, .atl_Mdef+.atl_pMdef*(.atlf-1));
setunitdata(.@mg, UDT_HIT, .atl_bHit+.atl_pHit*(.atlf-1));
setunitdata(.@mg, UDT_FLEE, .atl_bFlee+.atl_pFlee*(.atlf-1));
setunitdata(.@mg, UDT_CRIT, .atl_bCrit+.atl_pCrit*(.atlf-1));
setunitdata(.@mg, UDT_PDODGE, min(30, .atl_Luk/10+(.atlf/3)));
.atlf+=1;
mapannounce instance_mapname("001-2-35"), ("Training Arena, wave " + .atlf + "!"), bc_all;
maptimer(instance_mapname("001-2-35"), 10, instance_npcname(.name$)+"::OnATLUpdate");
end;
OnATLUpdate:
if (.atlf > ATLRANK)
ATLRANK=.atlf;
getexp .atlf*7, .atlf*5; // Provide some reward
end;
// Check for possible cheats, and update default values
OnVerify:
if (!.atlf)
end;
if (readbattleparam(getcharid(3), UDT_ATKRANGE) > .atl_Rng)
.atl_Rng=readbattleparam(getcharid(3), UDT_ATKRANGE);
if (readbattleparam(getcharid(3), UDT_ATKMAX) > .atl_bAtk1) {
.atl_bAtk1=readbattleparam(getcharid(3), UDT_ATKMIN);
.atl_bAtk2=readbattleparam(getcharid(3), UDT_ATKMAX);
.atl_pAtk1=.atl_bAtk1/10;
.atl_pAtk2=.atl_bAtk2/10;
}
if (readbattleparam(getcharid(3), UDT_DEF) > .atl_bDef) {
.atl_bDef=readbattleparam(getcharid(3), UDT_DEF);
.atl_pDef=.atl_bDef/5;
}
if (readbattleparam(getcharid(3), UDT_MDEF) > .atl_bMdef) {
.atl_bMdef=readbattleparam(getcharid(3), UDT_MDEF);
.atl_pMdef=.atl_bMdef/5;
}
if (readbattleparam(getcharid(3), UDT_MATKMAX) > .atl_bMatk) {
.atl_bMatk=readbattleparam(getcharid(3), UDT_MATKMAX);
.atl_pMatk=.atl_bMatk/5;
}
// TODO: Ignore haste potion effects
// TODO: Update battle statuses on the fly
if (readbattleparam(getcharid(3), UDT_ADELAY) < .atl_bDly)
.atl_bDly=readbattleparam(getcharid(3), UDT_DELAY);
// Victory conditions
if (getq(Artis_Legion_Progress) == 3)
checkVictory();
addtimer(5000, instance_npcname(.name$)+"::OnVerify");
end;
// Victory conditions
function checkVictory {
if (.atlf > 3) {
npctalk l("Congratulations, %s. I think this is enough. You can continue fighting to set a good score or report to Lozerk.", strcharinfo(0));
// Duplicate the dialog in case player miss it
dispbottom l("Congratulations, %s. I think this is enough. You can continue fighting to set a good score or report to Lozerk.", strcharinfo(0));
setq Artis_Legion_Progress, 4, 0;
}
return;
}
}
// Helper function for failure
function script ATLFightEnd {
if (@ATLFIGHT) {
@ATLFIGHT=false;
.@mapn$="atl2@"+getcharid(0);
killmonster(.@mapn$, "all", false);
.@q2=getq2(Artis_Legion_Progress);
set(getvariableofnpc(.atlf, instance_npcname("Serena#Ctrl", .@q2)), 0);
}
return;
}
|