Elin Decompiled Documentation EA 23.183 Nightly Patch 1
Loading...
Searching...
No Matches
ActMelee.cs
Go to the documentation of this file.
1using System.Collections.Generic;
2using UnityEngine;
3
4public class ActMelee : ActBaseAttack
5{
6 public virtual float BaseDmgMTP => 1f;
7
8 public virtual bool UseWeaponDist => true;
9
10 public override int PerformDistance
11 {
12 get
13 {
14 if (Act.CC != null)
15 {
16 return Act.CC.body.GetMeleeDistance();
17 }
18 return 1;
19 }
20 }
21
22 public override bool ResetAxis => true;
23
24 public override bool CanPressRepeat => true;
25
26 public bool HideHint(Card c)
27 {
28 if (!EClass.pc.isBlind && c != null)
29 {
30 if (c.isChara)
31 {
32 return !EClass.pc.CanSee(c);
33 }
34 return false;
35 }
36 return true;
37 }
38
39 public override string GetHintText(string str = "")
40 {
41 return "";
42 }
43
44 public override string GetTextSmall(Card c)
45 {
46 if (!HideHint(c))
47 {
48 return base.GetTextSmall(c);
49 }
50 return null;
51 }
52
53 public override CursorInfo GetCursorIcon(Card c)
54 {
55 if (!HideHint(c))
56 {
58 }
59 return null;
60 }
61
62 public override bool ShowMouseHint(Card c)
63 {
64 return !HideHint(c);
65 }
66
67 public override bool CanPerform()
68 {
69 if (Act.TC == null || !Act.TC.IsAliveInCurrentZone)
70 {
71 return false;
72 }
74 {
75 return false;
76 }
77 if (PerformDistance == 1)
78 {
80 {
81 return false;
82 }
83 }
84 else if (!Act.CC.CanSeeLos(Act.TC))
85 {
86 return false;
87 }
88 return base.CanPerform();
89 }
90
91 public override bool Perform()
92 {
93 Act.CurrentAct = this;
94 bool result = Attack();
95 Act.CurrentAct = null;
96 return result;
97 }
98
99 public bool Attack(float dmgMulti = 1f, bool maxRoll = false)
100 {
101 Act.CC.combatCount = 10;
102 Act.CC.LookAt(Act.TC);
104 if (Act.CC.HasCondition<ConFear>())
105 {
106 Act.CC.Say("fear", Act.CC, Act.TC);
107 if (Act.CC.IsPC)
108 {
109 EInput.Consume(consumeAxis: true);
110 }
111 return true;
112 }
114 bool intercepted = (Act.TC?.Chara?.RequestProtection(Act.CC, delegate(Chara c)
115 {
116 Act.TC = c;
117 })).GetValueOrDefault();
118 Act.TP.Set(Act.TC.pos);
119 CellEffect effect = Act.TP.cell.effect;
120 if (effect != null && effect.id == 6 && EClass.rnd(2) == 0)
121 {
122 Act.CC.PlaySound("miss");
123 Act.CC.Say("abMistOfDarkness_miss", Act.CC);
124 return true;
125 }
126 bool hasHit = false;
127 bool usedWeapon = false;
128 bool usedTalisman = false;
129 int count = 0;
130 int dist = Act.CC.Dist(Act.TC);
131 Point orgPos = Act.TC.pos.Copy();
132 Card orgTC = Act.TC;
134 foreach (BodySlot slot in Act.CC.body.slots)
135 {
136 _Attack(slot);
137 }
138 if (!usedWeapon)
139 {
140 _Attack(null);
141 }
143 {
144 EClass.Wait(0.25f, Act.CC);
145 }
146 if (!hasHit)
147 {
148 Act.CC.PlaySound("miss");
149 }
150 if (EClass.rnd(2) == 0)
151 {
152 Act.CC.RemoveCondition<ConInvisibility>();
153 }
154 return true;
155 void _Attack(BodySlot slot)
156 {
157 Act.TC = orgTC;
158 Act.TP = orgPos;
159 Thing w;
160 int splash;
161 int chaser;
162 int flurry;
163 int frustration;
164 int feint;
165 int knockback;
166 int mod_talisman;
167 if (Act.TC != null && Act.TC.IsAliveInCurrentZone)
168 {
169 w = null;
170 if (slot != null)
171 {
172 if (slot.thing == null || slot.elementId != 35 || slot.thing.source.offense.Length < 2)
173 {
174 return;
175 }
176 w = slot.thing;
177 }
178 int num = 1 + Mathf.Max(Act.CC.Evalue(666), (w != null) ? w.Evalue(666) : 0);
179 if (!UseWeaponDist || dist <= 1 || dist <= num || intercepted)
180 {
181 int num2 = GetWeaponEnc(606, addSelfEnc: false);
182 int scatter = GetWeaponEnc(607, addSelfEnc: false);
183 splash = GetWeaponEnc(608, addSelfEnc: true);
184 chaser = GetWeaponEnc(620, addSelfEnc: true);
185 flurry = GetWeaponEnc(621, addSelfEnc: true);
186 frustration = GetWeaponEnc(624, addSelfEnc: true);
187 int num3 = GetWeaponEnc(622, addSelfEnc: true);
188 feint = GetWeaponEnc(623, addSelfEnc: true);
189 knockback = GetWeaponEnc(603, addSelfEnc: true);
190 mod_talisman = GetWeaponEnc(609, addSelfEnc: true);
191 List<Point> list2 = EClass._map.ListPointsInLine(Act.CC.pos, Act.TC.pos, num2 / 10 + ((num2 % 10 > EClass.rnd(10)) ? 1 : 0) + 1);
192 if (w != null)
193 {
194 if (safety)
195 {
196 if (!w.HasElement(486))
197 {
198 return;
199 }
200 num2 = (scatter = (splash = (num3 = 0)));
201 }
202 usedWeapon = true;
203 if (w.IsMeleeWithAmmo && Act.CC.IsPC && w.c_ammo <= 0 && !Act.CC.HasCondition<ConReload>())
204 {
206 }
207 }
208 AttackWithFlurry(Act.TC, Act.TP, 1f, subAttack: false);
209 if (num2 > 0)
210 {
211 foreach (Point item in list2)
212 {
213 if (!item.Equals(orgPos))
214 {
215 Chara firstChara = item.FirstChara;
216 if (firstChara != null && firstChara.IsHostile(Act.CC))
217 {
218 AttackWithFlurry(firstChara, item, 1f, subAttack: false);
219 }
220 }
221 }
222 }
223 else if (scatter > 0)
224 {
225 Act.TP.ForeachNeighbor(delegate(Point p)
226 {
227 if (!p.Equals(orgPos))
228 {
229 Chara firstChara2 = p.FirstChara;
230 if (firstChara2 != null && firstChara2.IsHostile(Act.CC))
231 {
232 AttackWithFlurry(firstChara2, p, Mathf.Min(0.5f + 0.05f * Mathf.Sqrt(scatter), 1f + 0.01f * Mathf.Sqrt(scatter)), subAttack: true);
233 }
234 }
235 });
236 }
237 else if (num3 > 0)
238 {
239 List<Point> list = new List<Point>();
240 Act.TP.ForeachNeighbor(delegate(Point p)
241 {
242 if (!p.Equals(Act.TP))
243 {
244 list.Add(p.Copy());
245 }
246 });
247 list.Shuffle();
248 int num4 = 0;
249 for (int i = 0; i < 9 && num3 > EClass.rnd(10 + (int)Mathf.Pow(3f, i + 2)); i++)
250 {
251 num4++;
252 }
253 foreach (Point item2 in list)
254 {
255 foreach (Card item3 in item2.ListCards().Copy())
256 {
257 if (num4 <= 0 || !Act.CC.IsAliveInCurrentZone)
258 {
259 break;
260 }
261 if (item3.trait.CanBeAttacked || (item3.isChara && item3.Chara.IsHostile(Act.CC)))
262 {
263 AttackWithFlurry(item3, item2, 1f, subAttack: true);
264 num4--;
265 }
266 }
267 }
268 }
269 count++;
270 }
271 }
272 void Attack(Card _tc, Point _tp, float mtp, bool subAttack)
273 {
274 Act.TC = _tc;
275 Act.TP = _tp;
277 int num5 = 1;
278 if (chaser > 0)
279 {
280 for (int j = 0; j < 10; j++)
281 {
282 if (chaser > EClass.rnd(4 + (int)Mathf.Pow(4f, j + 2)))
283 {
284 num5++;
285 }
286 }
287 }
288 bool flag = false;
289 for (int k = 0; k < num5; k++)
290 {
292 {
293 break;
294 }
296 {
297 break;
298 }
299 if (k > 0)
300 {
301 Act.CC.Say("attack_chaser");
302 }
303 flag = AttackProcess.Current.Perform(count, hasHit, dmgMulti * mtp * BaseDmgMTP, maxRoll, subAttack);
304 if (!flag && frustration > 0 && 10f + 2f * Mathf.Sqrt(frustration) > (float)EClass.rnd(100))
305 {
306 AttackProcess.Current.critFury = true;
307 flag = AttackProcess.Current.Perform(count, hasHit, dmgMulti * mtp, maxRoll, subAttack);
308 AttackProcess.Current.critFury = false;
309 }
311 {
312 break;
313 }
314 }
315 Act.TC = _tc;
316 Act.TP = _tp;
317 if (w != null && w.c_ammo > 0 && !Act.CC.HasCondition<ConReload>() && !safety)
318 {
319 bool flag2 = true;
320 TraitAmmo traitAmmo = ((w.ammoData == null) ? null : (w.ammoData.trait as TraitAmmo));
321 if (traitAmmo != null && traitAmmo is TraitAmmoTalisman traitAmmoTalisman)
322 {
323 flag2 = false;
324 if (flag && !usedTalisman && Act.TC != null && Act.TC.IsAliveInCurrentZone)
325 {
326 Act act = Act.CC.elements.GetElement(traitAmmoTalisman.owner.refVal)?.act ?? ACT.Create(traitAmmoTalisman.owner.refVal);
327 Act.powerMod = traitAmmo.owner.encLV;
328 if (act.Perform(Act.CC, Act.TC, Act.TP))
329 {
330 usedTalisman = true;
331 flag2 = true;
332 if (mod_talisman > 0 && Mathf.Min(10f + Mathf.Sqrt(mod_talisman) * 5f, 90f) > (float)EClass.rnd(100))
333 {
334 flag2 = false;
335 }
336 int spellExp = Act.CC.elements.GetSpellExp(Act.CC, act, 200);
337 Act.CC.ModExp(act.id, spellExp);
338 }
339 Act.powerMod = 100;
340 }
341 }
342 if (flag2)
343 {
344 w.c_ammo--;
345 if (w.ammoData != null)
346 {
347 w.ammoData.Num = w.c_ammo;
348 }
349 if (w.c_ammo <= 0)
350 {
351 w.c_ammo = 0;
352 w.ammoData = null;
353 }
355 }
356 }
357 Act.TC = _tc;
359 {
361 if (feint > 0 && 10f + 4f * Mathf.Sqrt(feint) > (float)EClass.rnd(100))
362 {
363 Act.TC.Chara.AddCondition<ConSupress>(100 + 5 * (int)Mathf.Sqrt(feint));
364 }
365 }
366 if (splash > 0)
367 {
368 Act.TP.ForeachNeighbor(delegate(Point p)
369 {
370 if (p.Equals(Act.TP) || p.Equals(Act.CC.pos))
371 {
372 return;
373 }
374 if (!p.IsBlocked)
375 {
376 p.PlayEffect("smoke_shockwave");
377 p.Copy().Animate(AnimeID.QuakeMini, animeBlock: true);
378 }
379 foreach (Card item4 in p.ListCards())
380 {
381 if ((item4.trait.CanBeAttacked || (item4.isChara && item4.Chara.IsHostile(Act.CC))) && !item4.HasElement(430))
382 {
383 int rawDamage2 = AttackProcess.Current.GetRawDamage(0.1f + 0.05f * Mathf.Sqrt(splash), crit: false, maxRoll: false);
384 rawDamage2 = item4.ApplyProtection(rawDamage2);
385 item4.DamageHP(rawDamage2, 0, 100, AttackSource.Shockwave, Act.CC);
386 }
387 }
388 });
389 }
390 if (Act.TC.isChara && !Act.TC.HasCondition<ConGravity>() && Act.TC.ExistsOnMap && knockback > 0 && knockback * 2 + 15 > EClass.rnd(100) && !Act.TC.isRestrained)
391 {
393 bool flag3 = Act.CC.id == "tsunami";
394 if (num6 == Card.MoveResult.Success)
395 {
396 Act.TC.renderer.SetFirst(first: true);
397 Act.TC.PlaySound("wave_hit_small");
398 if (flag3)
399 {
400 Act.TC.Chara.AddCondition<ConParalyze>(20, force: true);
401 Act.TC.Chara.AddCondition<ConSuffocation>(100, force: true);
402 }
403 }
404 else if (flag3)
405 {
406 Act.TC.PlaySound("wave_hit");
407 Act.TC.pos.PlayEffect("wave_hit");
408 Act.TC.Chara.AddCondition<ConSuffocation>(200, force: true);
409 if (!Act.TC.HasElement(430))
410 {
411 int rawDamage = AttackProcess.Current.GetRawDamage(1f, crit: false, maxRoll: false);
412 rawDamage = Act.TC.ApplyProtection(rawDamage);
413 Act.TC.DamageHP(rawDamage, 0, 100, AttackSource.Shockwave, Act.CC);
414 }
415 Act.CC.Die();
416 }
417 }
418 }
419 void AttackWithFlurry(Card _tc, Point _tp, float mtp, bool subAttack)
420 {
421 int num7 = 1;
422 if (flurry > 0)
423 {
424 for (int l = 0; l < 10 && flurry > EClass.rnd(25 + (int)Mathf.Pow(5f, l + 2)); l++)
425 {
426 num7++;
427 }
428 }
429 for (int m = 0; m < num7; m++)
430 {
432 {
433 break;
434 }
435 if (!_tc.IsAliveInCurrentZone)
436 {
437 break;
438 }
439 if (m > 0)
440 {
441 Act.CC.Say("attack_flurry");
442 }
443 Attack(_tc, _tp, mtp, subAttack);
444 }
445 }
446 int GetWeaponEnc(int ele, bool addSelfEnc)
447 {
448 return AttackProcess.GetWeaponEnc(Act.CC, w, ele, addSelfEnc);
449 }
450 }
451 }
452}
AnimeID
Definition: AnimeID.cs:2
AttackSource
Definition: AttackSource.cs:2
Definition: ACT.cs:6
static Act Create(int id)
Definition: ACT.cs:36
override bool ResetAxis
Definition: ActMelee.cs:22
bool Attack(float dmgMulti=1f, bool maxRoll=false)
Definition: ActMelee.cs:99
override CursorInfo GetCursorIcon(Card c)
Definition: ActMelee.cs:53
bool HideHint(Card c)
Definition: ActMelee.cs:26
override bool CanPerform()
Definition: ActMelee.cs:67
override bool Perform()
Definition: ActMelee.cs:91
override string GetTextSmall(Card c)
Definition: ActMelee.cs:44
override bool CanPressRepeat
Definition: ActMelee.cs:24
override string GetHintText(string str="")
Definition: ActMelee.cs:39
virtual float BaseDmgMTP
Definition: ActMelee.cs:6
override int PerformDistance
Definition: ActMelee.cs:11
virtual bool UseWeaponDist
Definition: ActMelee.cs:8
override bool ShowMouseHint(Card c)
Definition: ActMelee.cs:62
static bool TryReload(Thing weapon, Thing ammo=null)
Definition: ActRanged.cs:341
Definition: ACT.cs:62
virtual bool Perform()
Definition: ACT.cs:266
static Card TC
Definition: ACT.cs:79
static Point TP
Definition: ACT.cs:81
static Chara CC
Definition: ACT.cs:77
void Prepare(Chara _CC, Thing _weapon, Card _TC=null, Point _TP=null, int _attackIndex=0, bool _isThrow=false)
bool Perform(int count, bool hasHit, float dmgMulti=1f, bool maxRoll=false, bool subAttack=false)
static AttackProcess Current
Definition: AttackProcess.cs:8
int GetRawDamage(float dmgMulti, bool crit, bool maxRoll)
static int GetWeaponEnc(Chara CC, Thing w, int ele, bool addSelfEnc=false)
int elementId
Definition: BodySlot.cs:6
Thing thing
Definition: BodySlot.cs:8
void PlayAnime(AnimeID id, bool force)
virtual void NextFrame()
virtual void SetFirst(bool first, Vector3 pos)
Definition: Card.cs:11
bool IsPCFactionOrMinion
Definition: Card.cs:2234
virtual Chara Chara
Definition: Card.cs:2032
ElementContainerCard elements
Definition: Card.cs:39
int c_ammo
Definition: Card.cs:1435
void DamageHP(int dmg, AttackSource attackSource=AttackSource.None, Card origin=null)
Definition: Card.cs:3955
bool HasElement(int ele, int req=1)
Definition: Card.cs:5638
bool isRestrained
Definition: Card.cs:552
SoundSource PlaySound(string id, float v=1f, bool spatial=true)
Definition: Card.cs:5852
Point pos
Definition: Card.cs:57
virtual int ApplyProtection(int dmg, int mod=100)
Definition: Card.cs:3930
Trait trait
Definition: Card.cs:51
int encLV
Definition: Card.cs:312
virtual bool IsAliveInCurrentZone
Definition: Card.cs:2089
MoveResult
Definition: Card.cs:13
virtual bool isChara
Definition: Card.cs:2045
int Evalue(int ele)
Definition: Card.cs:2533
int Dist(Card c)
Definition: Card.cs:7315
void ModExp(string alias, int a)
Definition: Card.cs:2610
CardRenderer renderer
Definition: Card.cs:59
void Say(string lang, string ref1=null, string ref2=null)
Definition: Card.cs:6499
CellEffect effect
Definition: Cell.cs:94
int GetMeleeDistance()
Definition: CharaBody.cs:420
List< BodySlot > slots
Definition: CharaBody.cs:8
Definition: Chara.cs:10
override bool IsAliveInCurrentZone
Definition: Chara.cs:559
CharaBody body
Definition: Chara.cs:94
MoveResult TryMoveFrom(Point p)
Definition: Chara.cs:2605
Condition AddCondition(string id, int p=100, bool force=false)
Definition: Chara.cs:8769
override bool IsPC
Definition: Chara.cs:610
bool CanSeeLos(Card c, int dist=-1)
Definition: Chara.cs:1232
bool RequestProtection(Chara attacker, Action< Chara > action)
Definition: Chara.cs:7972
bool HasCondition(string alias)
Definition: Chara.cs:8926
bool CanSee(Card c)
Definition: Chara.cs:1200
override void Die(Element e=null, Card origin=null, AttackSource attackSource=AttackSource.None, Chara originalTarget=null)
Definition: Chara.cs:5054
bool CanInteractTo(Card c)
Definition: Chara.cs:2444
void DoHostileAction(Card _tg, bool immediate=false)
Definition: Chara.cs:6016
bool isBlind
Definition: Chara.cs:130
bool IsHostile()
Definition: Chara.cs:6193
override void LookAt(Card c)
Definition: Chara.cs:3454
new GameConfig game
Definition: CoreConfig.cs:602
CoreConfig config
Definition: Core.cs:70
static CursorInfo IconMelee
Definition: EClass.cs:5
static Core core
Definition: EClass.cs:6
static void Wait(float a, Card c)
Definition: EClass.cs:102
static Map _map
Definition: EClass.cs:18
static int rnd(long a)
Definition: EClass.cs:58
static Chara pc
Definition: EClass.cs:14
Definition: EInput.cs:8
static void Consume(int _skipFrame)
Definition: EInput.cs:656
int GetSpellExp(Chara c, Element e, int costMod=100)
Element GetElement(string alias)
int id
Definition: ELEMENT.cs:248
Act act
Definition: ELEMENT.cs:392
static void SetDirty(Thing t)
List< Point > ListPointsInLine(Point center, Point to, int radius)
Definition: Map.cs:2313
Definition: Point.cs:9
List< Card > ListCards(bool includeMasked=false)
Definition: Point.cs:1031
Point Copy()
Definition: Point.cs:479
Point Set(int _x, int _z)
Definition: Point.cs:491
void ForeachNeighbor(Action< Point > action, bool diagonal=true)
Definition: Point.cs:1377
bool IsBlocked
Definition: Point.cs:351
bool Equals(int _x, int _z)
Definition: Point.cs:940
Effect PlayEffect(string id)
Definition: Point.cs:1228
Cell cell
Definition: Point.cs:51
void Animate(AnimeID id, bool animeBlock=false)
Definition: Point.cs:1282
Definition: Thing.cs:8
SourceThing.Row source
Definition: Thing.cs:11
bool IsMeleeWithAmmo
Definition: Thing.cs:20
virtual bool CanBeAttacked
Definition: Trait.cs:164
Card owner
Definition: Trait.cs:27