Elin Decompiled Documentation EA 23.253 Nightly
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 bool AllowCounter => true;
7
8 public virtual bool AllowParry => true;
9
10 public virtual bool ShouldRollMax => false;
11
12 public virtual float BaseDmgMTP => 1f;
13
14 public virtual bool UseWeaponDist => true;
15
16 public override int PerformDistance
17 {
18 get
19 {
20 if (Act.CC != null)
21 {
22 return Act.CC.body.GetMeleeDistance();
23 }
24 return 1;
25 }
26 }
27
28 public override bool ResetAxis => true;
29
30 public override bool CanPressRepeat => true;
31
32 public bool HideHint(Card c)
33 {
34 if (!EClass.pc.isBlind && c != null)
35 {
36 if (c.isChara)
37 {
38 return !EClass.pc.CanSee(c);
39 }
40 return false;
41 }
42 return true;
43 }
44
45 public override string GetHintText(string str = "")
46 {
47 return "";
48 }
49
50 public override string GetTextSmall(Card c)
51 {
52 if (!HideHint(c))
53 {
54 return base.GetTextSmall(c);
55 }
56 return null;
57 }
58
59 public override CursorInfo GetCursorIcon(Card c)
60 {
61 if (!HideHint(c))
62 {
64 }
65 return null;
66 }
67
68 public override bool ShowMouseHint(Card c)
69 {
70 return !HideHint(c);
71 }
72
73 public override bool CanPerform()
74 {
75 if (Act.TC == null || !Act.TC.IsAliveInCurrentZone)
76 {
77 return false;
78 }
80 {
81 return false;
82 }
83 if (PerformDistance == 1)
84 {
86 {
87 return false;
88 }
89 }
90 else if (!Act.CC.CanSeeLos(Act.TC))
91 {
92 return false;
93 }
94 return base.CanPerform();
95 }
96
97 public override bool Perform()
98 {
99 Act.CurrentAct = this;
100 bool result = Attack();
101 Act.CurrentAct = null;
102 return result;
103 }
104
105 public bool Attack(float dmgMulti = 1f)
106 {
107 Act.CC.combatCount = 10;
108 Act.CC.LookAt(Act.TC);
110 if (Act.CC.HasCondition<ConFear>())
111 {
112 Act.CC.Say("fear", Act.CC, Act.TC);
113 if (Act.CC.IsPC)
114 {
115 EInput.Consume(consumeAxis: true);
116 }
117 return true;
118 }
120 bool intercepted = (Act.TC?.Chara?.RequestProtection(Act.CC, delegate(Chara c)
121 {
122 Act.TC = c;
123 })).GetValueOrDefault();
124 Act.TP.Set(Act.TC.pos);
125 CellEffect effect = Act.TP.cell.effect;
126 if (effect != null && effect.id == 6 && EClass.rnd(2) == 0)
127 {
128 Act.CC.PlaySound("miss");
129 Act.CC.Say("abMistOfDarkness_miss", Act.CC);
130 return true;
131 }
132 bool hasHit = false;
133 bool hasMissed = false;
134 bool usedWeapon = false;
135 bool usedTalisman = false;
136 bool maxRoll = ShouldRollMax;
137 int count = 0;
138 int dist = Act.CC.Dist(Act.TC);
139 Point orgPos = Act.TC.pos.Copy();
140 Chara cC = Act.CC;
141 Card orgTC = Act.TC;
143 bool parried = false;
144 foreach (BodySlot slot in Act.CC.body.slots)
145 {
146 _Attack(slot);
147 if (parried)
148 {
149 break;
150 }
151 }
152 if (!usedWeapon)
153 {
154 _Attack(null);
155 }
157 {
158 EClass.Wait(0.25f, Act.CC);
159 }
160 if (EClass.rnd(2) == 0)
161 {
162 Act.CC.RemoveCondition<ConInvisibility>();
163 Act.CC.RemoveCondition<ConDark>();
164 }
165 if (orgTC.isChara && orgTC.ExistsOnMap && orgTC != cC && !orgTC.IsRestrainedResident && !orgTC.IsDisabled && ACT.Melee.CanPerform(orgTC.Chara, cC) && (!orgTC.IsPCFactionOrMinion || !EClass._zone.isPeace))
166 {
167 if (parried)
168 {
169 new ActMeleeParry().Perform(orgTC.Chara, cC);
170 }
171 else if (AllowCounter && hasMissed && !cC.HasElement(439) && orgTC.HasElement(380))
172 {
173 orgTC.Say((orgTC.isChara && orgTC.Chara.IsHostile()) ? "counter_enemy" : "counter");
174 new ActMeleeCounter().Perform(orgTC.Chara, cC);
175 }
176 }
177 Act.TC = orgTC;
178 Act.CC = cC;
179 if (!hasHit)
180 {
181 Act.CC.PlaySound("miss");
182 }
183 return true;
184 void _Attack(BodySlot slot)
185 {
186 Act.TC = orgTC;
187 Act.TP = orgPos;
188 Thing w;
189 int splash;
190 int chaser;
191 int flurry;
192 int frustration;
193 int feint;
194 int knockback;
195 int mod_talisman;
196 if (Act.TC != null && Act.TC.IsAliveInCurrentZone)
197 {
198 w = null;
199 if (slot != null)
200 {
201 if (slot.thing == null || slot.elementId != 35 || slot.thing.source.offense.Length < 2)
202 {
203 return;
204 }
205 w = slot.thing;
206 }
207 int num = 1 + Mathf.Max(Act.CC.Evalue(666), (w != null) ? w.Evalue(666) : 0);
208 if (!UseWeaponDist || dist <= 1 || dist <= num || intercepted)
209 {
210 int num2 = GetWeaponEnc(606, addSelfEnc: false);
211 int scatter = GetWeaponEnc(607, addSelfEnc: false);
212 splash = GetWeaponEnc(608, addSelfEnc: true);
213 chaser = GetWeaponEnc(620, addSelfEnc: true);
214 flurry = GetWeaponEnc(621, addSelfEnc: true);
215 frustration = GetWeaponEnc(624, addSelfEnc: true);
216 int num3 = GetWeaponEnc(622, addSelfEnc: true);
217 feint = GetWeaponEnc(623, addSelfEnc: true);
218 knockback = Act.CC.Evalue(603);
219 mod_talisman = GetWeaponEnc(609, addSelfEnc: true);
220 List<Point> list2 = EClass._map.ListPointsInLine(Act.CC.pos, Act.TC.pos, num2 / 10 + ((num2 % 10 > EClass.rnd(10)) ? 1 : 0) + 1);
221 if (w != null)
222 {
223 if (safety)
224 {
225 if (!w.HasElement(486))
226 {
227 return;
228 }
229 num2 = (scatter = (splash = (num3 = 0)));
230 }
231 usedWeapon = true;
232 if (w.IsMeleeWithAmmo && Act.CC.IsPC && w.c_ammo <= 0 && !Act.CC.HasCondition<ConReload>())
233 {
235 }
236 }
237 AttackWithFlurry(Act.TC, Act.TP, 1f, subAttack: false);
238 if (!parried)
239 {
240 if (num2 > 0)
241 {
242 foreach (Point item in list2)
243 {
244 if (!item.Equals(orgPos))
245 {
246 Chara firstChara = item.FirstChara;
247 if (firstChara != null && firstChara.IsHostile(Act.CC))
248 {
249 AttackWithFlurry(firstChara, item, 1f, subAttack: false);
250 }
251 }
252 }
253 }
254 else if (scatter > 0)
255 {
256 Act.TP.ForeachNeighbor(delegate(Point p)
257 {
258 if (!p.Equals(orgPos))
259 {
260 Chara firstChara2 = p.FirstChara;
261 if (firstChara2 != null && firstChara2.IsHostile(Act.CC))
262 {
263 AttackWithFlurry(firstChara2, p, Mathf.Min(0.5f + 0.05f * Mathf.Sqrt(scatter), 1f + 0.01f * Mathf.Sqrt(scatter)), subAttack: true);
264 }
265 }
266 });
267 }
268 else if (num3 > 0)
269 {
270 List<Point> list = new List<Point>();
271 Act.TP.ForeachNeighbor(delegate(Point p)
272 {
273 if (!p.Equals(Act.TP))
274 {
275 list.Add(p.Copy());
276 }
277 });
278 list.Shuffle();
279 int num4 = 0;
280 for (int i = 0; i < 9 && num3 > EClass.rnd(10 + (int)Mathf.Pow(3f, i + 2)); i++)
281 {
282 num4++;
283 }
284 foreach (Point item2 in list)
285 {
286 foreach (Card item3 in item2.ListCards().Copy())
287 {
288 if (num4 <= 0 || !Act.CC.IsAliveInCurrentZone)
289 {
290 break;
291 }
292 if (item3.trait.CanBeAttacked || (item3.isChara && item3.Chara.IsHostile(Act.CC)))
293 {
294 AttackWithFlurry(item3, item2, 1f, subAttack: true);
295 if (parried)
296 {
297 break;
298 }
299 num4--;
300 }
301 }
302 }
303 }
304 }
305 count++;
306 }
307 }
308 void Attack(Card _tc, Point _tp, float mtp, bool subAttack)
309 {
310 Act.TC = _tc;
311 Act.TP = _tp;
314 {
315 int num5 = Act.TC.Evalue(437);
316 if (num5 > 0 && !Act.CC.HasElement(439))
317 {
318 int num6 = EClass.curve(5 + num5 / 3, 10, 3, 70);
319 int ele2 = 123;
320 int num7 = Act.TC.Evalue(ele2);
321 if (Act.TC.isChara)
322 {
323 num6 += Act.TC.Evalue(1750) * 2 * ((Act.TC.Chara.body.GetAttackStyle() != AttackStyle.Shield) ? 1 : 2);
324 foreach (BodySlot slot2 in Act.TC.Chara.body.slots)
325 {
326 if (slot2.thing != null && slot2.thing.HasElement(437) && Act.TC.Evalue(slot2.thing.category.skill) > num7)
327 {
328 ele2 = slot2.thing.category.skill;
329 num7 = Act.TC.Evalue(ele2);
330 }
331 }
332 }
333 num6 = num6 * 100 / (int)Mathf.Clamp((float)AttackProcess.Current.weaponSkill.Value / (float)num7 * 100f, 50f, 150f);
334 if (EClass.rnd(100) < num6)
335 {
336 Act.TC.Say((Act.TC.isChara && Act.TC.Chara.IsHostile()) ? "parry_enemy" : "parry");
337 Act.TC.PlaySound("parry");
338 Act.TC.ModExp(ele2, 20);
339 parried = true;
340 return;
341 }
342 }
343 }
344 int num8 = 1;
345 if (chaser > 0)
346 {
347 for (int j = 0; j < 10; j++)
348 {
349 if (chaser > EClass.rnd(4 + (int)Mathf.Pow(4f, j + 2)))
350 {
351 num8++;
352 }
353 }
354 }
355 bool flag = false;
356 for (int k = 0; k < num8; k++)
357 {
359 {
360 break;
361 }
363 {
364 break;
365 }
366 if (k > 0)
367 {
368 Act.CC.Say(Act.CC.IsHostile() ? "attack_chaser_enemy" : "attack_chaser");
369 }
370 flag = AttackProcess.Current.Perform(count, hasHit, dmgMulti * mtp * BaseDmgMTP, maxRoll, subAttack);
371 if (!flag && frustration > 0 && !Act.TC.HasElement(439) && 10f + 2f * Mathf.Sqrt(frustration) > (float)EClass.rnd(100))
372 {
373 AttackProcess.Current.critFury = true;
374 flag = AttackProcess.Current.Perform(count, hasHit, dmgMulti * mtp, maxRoll, subAttack);
375 AttackProcess.Current.critFury = false;
376 }
378 {
379 break;
380 }
381 }
382 if (flag)
383 {
384 hasHit = true;
385 }
386 else
387 {
388 hasMissed = true;
389 }
390 Act.TC = _tc;
391 Act.TP = _tp;
392 if (w != null && w.c_ammo > 0 && !Act.CC.HasCondition<ConReload>() && !safety)
393 {
394 bool flag2 = true;
395 TraitAmmo traitAmmo = ((w.ammoData == null) ? null : (w.ammoData.trait as TraitAmmo));
396 if (traitAmmo != null && traitAmmo is TraitAmmoTalisman traitAmmoTalisman)
397 {
398 flag2 = false;
399 if (flag && !usedTalisman && Act.TC != null && Act.TC.IsAliveInCurrentZone)
400 {
401 Act act = Act.CC.elements.GetElement(traitAmmoTalisman.owner.refVal)?.act ?? ACT.Create(traitAmmoTalisman.owner.refVal);
402 Act.powerMod = traitAmmo.owner.encLV;
403 if (act.Perform(Act.CC, Act.TC, Act.TP))
404 {
405 usedTalisman = true;
406 flag2 = true;
407 if (mod_talisman > 0 && Mathf.Min(10f + Mathf.Sqrt(mod_talisman) * 5f, 90f) > (float)EClass.rnd(100))
408 {
409 flag2 = false;
410 }
411 int spellExp = Act.CC.elements.GetSpellExp(Act.CC, act, 200);
412 Act.CC.ModExp(act.id, spellExp);
413 }
414 Act.powerMod = 100;
415 }
416 }
417 if (flag2)
418 {
419 w.c_ammo--;
420 if (w.ammoData != null)
421 {
422 w.ammoData.Num = w.c_ammo;
423 }
424 if (w.c_ammo <= 0)
425 {
426 w.c_ammo = 0;
427 w.ammoData = null;
428 }
430 }
431 }
432 Act.TC = _tc;
434 {
436 if (feint > 0 && 10f + 4f * Mathf.Sqrt(feint) > (float)EClass.rnd(100))
437 {
438 Act.TC.Chara.AddCondition<ConSupress>(100 + 5 * (int)Mathf.Sqrt(feint));
439 }
440 }
441 if (splash > 0)
442 {
443 Act.TP.ForeachNeighbor(delegate(Point p)
444 {
445 if (p.Equals(Act.TP) || p.Equals(Act.CC.pos))
446 {
447 return;
448 }
449 if (!p.IsBlocked)
450 {
451 p.PlayEffect("smoke_shockwave");
452 p.Copy().Animate(AnimeID.QuakeMini, animeBlock: true);
453 }
454 foreach (Card item4 in p.ListCards().Copy())
455 {
456 if ((item4.trait.CanBeAttacked || (item4.isChara && item4.Chara.IsHostile(Act.CC))) && !item4.HasElement(430))
457 {
458 long rawDamage2 = AttackProcess.Current.GetRawDamage(0.1f + 0.05f * Mathf.Sqrt(splash), crit: false, maxRoll: false);
459 rawDamage2 = item4.ApplyProtection(rawDamage2);
460 item4.DamageHP(rawDamage2, 0, 100, AttackSource.Shockwave, Act.CC);
461 }
462 }
463 });
464 }
465 if (Act.TC.isChara && !Act.TC.HasCondition<ConGravity>() && Act.TC.ExistsOnMap && knockback > 0 && knockback * 2 + 15 > EClass.rnd(100) && !Act.TC.isRestrained)
466 {
468 bool flag3 = Act.CC.id == "tsunami";
469 if (num9 == Card.MoveResult.Success)
470 {
471 Act.TC.renderer.SetFirst(first: true);
472 Act.TC.PlaySound("wave_hit_small");
473 if (flag3)
474 {
475 Act.TC.Chara.AddCondition<ConParalyze>(20, force: true);
476 Act.TC.Chara.AddCondition<ConSuffocation>(100, force: true);
477 }
478 }
479 else if (flag3)
480 {
481 Act.TC.PlaySound("wave_hit");
482 Act.TC.pos.PlayEffect("wave_hit");
483 Act.TC.Chara.AddCondition<ConSuffocation>(200, force: true);
484 if (!Act.TC.HasElement(430))
485 {
486 long rawDamage = AttackProcess.Current.GetRawDamage(1f, crit: false, maxRoll: false);
487 rawDamage = Act.TC.ApplyProtection(rawDamage);
488 Act.TC.DamageHP(rawDamage, 0, 100, AttackSource.Shockwave, Act.CC);
489 }
490 Act.CC.Die();
491 }
492 }
493 }
494 void AttackWithFlurry(Card _tc, Point _tp, float mtp, bool subAttack)
495 {
496 int num10 = 1;
497 if (flurry > 0)
498 {
499 for (int l = 0; l < 10 && flurry > EClass.rnd(25 + (int)Mathf.Pow(5f, l + 2)); l++)
500 {
501 num10++;
502 }
503 }
504 for (int m = 0; m < num10; m++)
505 {
507 {
508 break;
509 }
510 if (!_tc.IsAliveInCurrentZone)
511 {
512 break;
513 }
514 if (m > 0)
515 {
516 Act.CC.Say(Act.CC.IsHostile() ? "attack_flurry_enemy" : "attack_flurry");
517 }
518 Attack(_tc, _tp, mtp, subAttack);
519 if (parried)
520 {
521 break;
522 }
523 }
524 }
525 int GetWeaponEnc(int ele, bool addSelfEnc)
526 {
527 return AttackProcess.GetWeaponEnc(Act.CC, w, ele, addSelfEnc);
528 }
529 }
530 }
531}
AnimeID
Definition: AnimeID.cs:2
AttackSource
Definition: AttackSource.cs:2
AttackStyle
Definition: AttackStyle.cs:2
Definition: ACT.cs:6
static Act Create(int id)
Definition: ACT.cs:36
static ActMelee Melee
Definition: ACT.cs:15
override bool ResetAxis
Definition: ActMelee.cs:28
virtual bool ShouldRollMax
Definition: ActMelee.cs:10
override CursorInfo GetCursorIcon(Card c)
Definition: ActMelee.cs:59
bool HideHint(Card c)
Definition: ActMelee.cs:32
override bool CanPerform()
Definition: ActMelee.cs:73
virtual bool AllowCounter
Definition: ActMelee.cs:6
override bool Perform()
Definition: ActMelee.cs:97
override string GetTextSmall(Card c)
Definition: ActMelee.cs:50
override bool CanPressRepeat
Definition: ActMelee.cs:30
override string GetHintText(string str="")
Definition: ActMelee.cs:45
bool Attack(float dmgMulti=1f)
Definition: ActMelee.cs:105
virtual float BaseDmgMTP
Definition: ActMelee.cs:12
virtual bool AllowParry
Definition: ActMelee.cs:8
override int PerformDistance
Definition: ActMelee.cs:17
virtual bool UseWeaponDist
Definition: ActMelee.cs:14
override bool ShowMouseHint(Card c)
Definition: ActMelee.cs:68
static bool TryReload(Thing weapon, Thing ammo=null)
Definition: ActRanged.cs:410
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
long 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:2272
virtual Chara Chara
Definition: Card.cs:2070
ElementContainerCard elements
Definition: Card.cs:41
int c_ammo
Definition: Card.cs:1461
bool IsRestrainedResident
Definition: Card.cs:2258
bool isRestrained
Definition: Card.cs:566
virtual bool IsDisabled
Definition: Card.cs:2111
SoundSource PlaySound(string id, float v=1f, bool spatial=true)
Definition: Card.cs:6178
Point pos
Definition: Card.cs:59
virtual long ApplyProtection(long dmg, int mod=100)
Definition: Card.cs:4038
Trait trait
Definition: Card.cs:53
int encLV
Definition: Card.cs:326
virtual bool IsAliveInCurrentZone
Definition: Card.cs:2127
void DamageHP(long dmg, AttackSource attackSource=AttackSource.None, Card origin=null)
Definition: Card.cs:4063
MoveResult
Definition: Card.cs:13
virtual bool isChara
Definition: Card.cs:2083
int Evalue(int ele)
Definition: Card.cs:2571
int Dist(Card c)
Definition: Card.cs:7698
void ModExp(string alias, int a)
Definition: Card.cs:2648
SourceCategory.Row category
Definition: Card.cs:2049
CardRenderer renderer
Definition: Card.cs:61
bool HasElement(int ele, bool includeNagative=false)
Definition: Card.cs:5933
void Say(string lang, string ref1=null, string ref2=null)
Definition: Card.cs:6851
CellEffect effect
Definition: Cell.cs:94
int GetMeleeDistance()
Definition: CharaBody.cs:451
List< BodySlot > slots
Definition: CharaBody.cs:8
AttackStyle GetAttackStyle()
Definition: CharaBody.cs:464
Definition: Chara.cs:10
override bool IsAliveInCurrentZone
Definition: Chara.cs:561
CharaBody body
Definition: Chara.cs:94
MoveResult TryMoveFrom(Point p)
Definition: Chara.cs:2678
Condition AddCondition(string id, int p=100, bool force=false)
Definition: Chara.cs:9250
override bool IsPC
Definition: Chara.cs:612
bool CanSeeLos(Card c, int dist=-1)
Definition: Chara.cs:1250
bool RequestProtection(Chara attacker, Action< Chara > action)
Definition: Chara.cs:8380
bool HasCondition(string alias)
Definition: Chara.cs:9411
bool CanSee(Card c)
Definition: Chara.cs:1218
override void Die(Element e=null, Card origin=null, AttackSource attackSource=AttackSource.None, Chara originalTarget=null)
Definition: Chara.cs:5311
bool CanInteractTo(Card c)
Definition: Chara.cs:2517
void DoHostileAction(Card _tg, bool immediate=false)
Definition: Chara.cs:6355
bool isBlind
Definition: Chara.cs:130
bool IsHostile()
Definition: Chara.cs:6532
override void LookAt(Card c)
Definition: Chara.cs:3528
new GameConfig game
Definition: CoreConfig.cs:609
CoreConfig config
Definition: Core.cs:70
static CursorInfo IconMelee
Definition: EClass.cs:6
static int curve(int _a, int start, int step, int rate=75)
Definition: EClass.cs:69
static Core core
Definition: EClass.cs:7
static void Wait(float a, Card c)
Definition: EClass.cs:112
static Zone _zone
Definition: EClass.cs:21
static Map _map
Definition: EClass.cs:19
static int rnd(long a)
Definition: EClass.cs:59
static Chara pc
Definition: EClass.cs:15
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:250
Act act
Definition: ELEMENT.cs:394
static void SetDirty(Thing t)
List< Point > ListPointsInLine(Point center, Point to, int radius)
Definition: Map.cs:2326
Definition: Point.cs:9
List< Card > ListCards(bool includeMasked=false)
Definition: Point.cs:1051
Point Copy()
Definition: Point.cs:491
Point Set(int _x, int _z)
Definition: Point.cs:503
void ForeachNeighbor(Action< Point > action, bool diagonal=true)
Definition: Point.cs:1397
bool IsBlocked
Definition: Point.cs:363
bool Equals(int _x, int _z)
Definition: Point.cs:960
Effect PlayEffect(string id)
Definition: Point.cs:1248
Cell cell
Definition: Point.cs:51
void Animate(AnimeID id, bool animeBlock=false)
Definition: Point.cs:1302
bool isPeace
Definition: Spatial.cs:406
Definition: Thing.cs:8
SourceThing.Row source
Definition: Thing.cs:11
bool IsMeleeWithAmmo
Definition: Thing.cs:20
virtual bool CanBeAttacked
Definition: Trait.cs:166
Card owner
Definition: Trait.cs:27