Elin Decompiled Documentation EA 23.102 Nightly
Loading...
Searching...
No Matches
GoalCombat.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using UnityEngine;
4
5public class GoalCombat : Goal
6{
7 public class ItemAbility
8 {
9 public Act act;
10
11 public int priority;
12
13 public int priorityMod;
14
15 public int chance;
16
17 public Chara tg;
18
19 public bool pt;
20
21 public bool aiPt;
22 }
23
25
26 public Chara tc;
27
28 public int idleCount;
29
30 public int moveFail;
31
32 public List<ItemAbility> abilities;
33
34 public List<Chara> charas = new List<Chara>();
35
37
38 public override bool CancelWhenDamaged => false;
39
40 public override bool CancelOnAggro => false;
41
43
44 public override bool CanManualCancel()
45 {
46 return true;
47 }
48
49 public override IEnumerable<Status> Run()
50 {
51 if (destEnemy != null)
52 {
53 owner.enemy = destEnemy;
54 destEnemy = null;
55 }
56 int count = 0;
57 int lostCount = 0;
58 bool dontWander = owner.IsPCParty && !owner.IsPC && EClass.game.config.tactics.dontWander;
59 while (true)
60 {
61 bool canSeeLos = false;
63 {
64 Debug.Log("■" + owner.Name + "/" + count + "/" + lostCount);
65 }
67 {
68 owner.enemy = null;
69 owner.ShowEmo(Emo.happy);
70 yield return Success();
71 }
72 count++;
73 if (dontWander && owner.enemy != null && !EClass.pc.isBlind && !EClass.pc.CanSeeLos(owner.enemy) && (owner.Dist(EClass.pc) > 4 || owner.Dist(owner.enemy) > 1))
74 {
76 if (firstStep.IsValid && !firstStep.HasChara)
77 {
78 owner.enemy = null;
79 }
80 }
81 tc = owner.enemy;
82 if (tc != null && owner.IsPCFaction)
83 {
85 {
86 owner.enemy = null;
87 yield return Success();
88 }
90 {
91 tc = (owner.enemy = null);
92 }
93 }
94 if (tc == null || tc.isDead || !tc.ExistsOnMap || !tc.pos.IsInBounds || lostCount >= (owner.IsPowerful ? 50 : 5) || !owner.CanSee(tc))
95 {
96 tc = (owner.enemy = null);
98 {
99 yield return Success();
100 }
102 lostCount = 0;
103 if (owner.enemy == null)
104 {
105 yield return Success();
106 }
107 tc = owner.enemy;
108 }
109 else
110 {
111 canSeeLos = owner.CanSeeLos(tc);
112 lostCount = ((!canSeeLos) ? (lostCount + 1) : 0);
113 }
114 if (owner.IsPC && tc.HasEditorTag(EditorTag.Invulnerable))
115 {
116 Msg.Say("abort_idle");
117 yield return Success();
118 }
119 if (tc.IsPCFaction && owner.id == "melilith_boss" && EClass._map.plDay.list.Count > 1 && EClass._map.plDay.list[0].data.id != 107)
120 {
121 EClass._zone.SetBGM(107);
122 }
123 if (abilities == null)
124 {
125 abilities = new List<ItemAbility>();
127 }
128 if (owner.IsPCFaction && tc.IsPCFaction && EClass.rnd(5) == 0 && count > 2)
129 {
130 CalmDown();
131 yield return Success();
132 }
134 {
135 if (owner.calmCheckTurn < 0 || (!owner.enemy.IsPCParty && EClass.rnd(10) == 0))
136 {
137 CalmDown();
138 yield return Success();
139 }
141 }
142 if (owner.IsPC)
143 {
144 CursorSystem.ignoreCount = 1;
145 }
146 if (tc.host != null && (tc.hp == 0 || EClass.rnd(5) == 0))
147 {
149 }
150 if (tc.parasite != null && !tc.isRestrained && tc.parasite.hp > 0 && EClass.rnd(5) == 0)
151 {
153 }
154 if (tc.ride != null && !tc.isRestrained && tc.ride.hp > 0 && EClass.rnd(5) == 0)
155 {
157 }
158 if (tc.enemy != null)
159 {
161 }
162 if (!tc.IsMinion && EClass.rnd(10) == 0 && EClass.rnd(tc.DEX + 10) > owner.LV && tc.HasElement(1315) && !owner.HasElement(1315) && owner.race.IsMachine && owner.CanBeTempAlly(tc))
163 {
164 owner.Say("dominate_machine", tc, owner);
165 owner.PlayEffect("boost");
166 owner.PlaySound("boost");
167 owner.ShowEmo(Emo.love);
168 owner.lastEmo = Emo.angry;
170 yield return Success();
171 }
172 if (EClass.rnd(5) == 0 && tc.HasElement(1325) && owner.race.IsPlant && owner.CanBeTempAlly(tc))
173 {
174 owner.Say("dominate_plant", tc, owner);
175 owner.ShowEmo(Emo.love);
176 owner.lastEmo = Emo.angry;
178 yield return Success();
179 }
180 if (EClass.rnd(20) == 0 && owner.isRestrained)
181 {
182 owner.Talk("restrained");
183 }
184 if (this is GoalAutoCombat)
185 {
187 EClass.pc.ModExp(135, 20);
188 }
189 int dist = owner.Dist(tc);
190 bool move = owner.host == null && (tactics.ChanceMove > EClass.rnd(100) || (owner.IsPC && tc.HasCondition<ConFear>() && dist >= EClass.pc.GetSightRadius() - 1));
191 bool haltSecondMove = false;
192 if (!owner.IsPC && owner.IsNeutralOrAbove() && !owner.isBlind && !owner.isSummon && !owner.IsMinion)
193 {
194 int num = -1;
195 if (tc.HasElement(1221))
196 {
197 num = 1;
198 }
199 if (tc.source.HasTag(CTAG.suicide) && !tc.HasCondition<ConWet>())
200 {
201 num = 3;
202 }
203 if (num > 0)
204 {
205 if (dist <= num)
206 {
207 if (EClass.rnd(15) == 0)
208 {
209 owner.Talk("run_suicide");
210 }
211 if (owner.host == null && owner.TryMoveFrom(tc.pos) != 0)
212 {
213 yield return Status.Running;
214 idleCount = 0;
215 continue;
216 }
218 {
219 Debug.Log("Failed to Run: " + owner.Name);
220 }
221 }
222 if (dist == num + 1)
223 {
224 haltSecondMove = true;
225 move = false;
226 idleCount = 0;
227 }
228 }
229 }
230 if (dontWander)
231 {
232 int num2 = owner.Dist(EClass.pc);
233 if (num2 > 3)
234 {
235 int x = tc.pos.x;
236 int z = tc.pos.z;
237 if (EClass.pc.pos.Distance(owner.pos.x + ((x > owner.pos.x) ? 1 : ((x < owner.pos.x) ? (-1) : 0)), owner.pos.z + ((z > owner.pos.z) ? 1 : ((z < owner.pos.z) ? (-1) : 0))) >= num2)
238 {
239 move = false;
240 haltSecondMove = true;
241 }
242 }
243 }
244 if ((owner.IsPC && EClass.game.config.autoCombat.bDontChase) || (!canSeeLos && tc.isHidden))
245 {
246 move = false;
247 haltSecondMove = true;
248 }
250 {
251 Debug.Log(owner.Name + "/" + move + "/" + haltSecondMove + "/" + dist);
252 }
253 if (move)
254 {
255 if (owner.IsPC && dist <= owner.GetSightRadius() && TryUseAbility(dist, beforeMove: true))
256 {
257 yield return Status.Running;
258 idleCount = 0;
259 continue;
260 }
261 if (TryMove(dist))
262 {
264 {
265 Debug.Log("moved:" + owner.Name);
266 }
267 yield return Status.Running;
268 idleCount = 0;
269 continue;
270 }
271 }
272 if (owner == null)
273 {
274 yield return Cancel();
275 }
276 if (dist <= owner.GetSightRadius() && TryUseAbility(dist))
277 {
278 yield return Status.Running;
279 idleCount = 0;
280 continue;
281 }
283 {
284 Debug.Log(owner.Name + "/" + move + "/" + haltSecondMove + "/" + tactics.ChanceSecondMove);
285 }
286 if (!move && !haltSecondMove && tactics.ChanceSecondMove > EClass.rnd(100) && TryMove(dist))
287 {
288 yield return Status.Running;
289 idleCount = 0;
290 continue;
291 }
292 if (owner == null)
293 {
294 yield return Cancel();
295 }
296 idleCount++;
297 if (TryAbortCombat())
298 {
299 yield return Success();
300 }
301 if (idleCount > 2)
302 {
303 if (dontWander)
304 {
305 yield return Success();
306 }
307 idleCount = 0;
308 string aiIdle = owner.source.aiIdle;
309 if (aiIdle == "stand" || aiIdle == "root")
310 {
311 yield return Success();
312 }
313 yield return DoGoto(tc.pos);
314 }
315 else if (owner.FindNearestNewEnemy())
316 {
317 yield return Status.Running;
318 continue;
319 }
320 yield return Status.Running;
321 }
322 void CalmDown()
323 {
324 owner.enemy = null;
325 if (owner.ride != null)
326 {
327 owner.ride.enemy = null;
328 }
329 if (owner.parasite != null)
330 {
331 owner.parasite.enemy = null;
332 }
333 owner.hostility = owner.OriginalHostility;
334 if (tc.enemy == owner)
335 {
336 tc.enemy = null;
337 if (tc.ride != null)
338 {
339 tc.ride.enemy = null;
340 }
341 if (tc.parasite != null)
342 {
343 tc.parasite.enemy = null;
344 }
345 tc.hostility = tc.OriginalHostility;
346 }
347 owner.Say("calmDown", owner);
348 }
349 }
350
351 public bool TryMove(int dist)
352 {
354 {
355 Debug.Log("TryMove: " + owner.Name + "/" + dist);
356 }
357 if (owner.host != null)
358 {
359 return false;
360 }
361 if (owner.isBlind)
362 {
363 return owner.MoveRandom();
364 }
365 int num = (tc.HasCondition<ConFear>() ? 1 : tactics.DestDist);
366 if (!owner.IsPC && (tactics.source.id == "archer" || tactics.source.id == "gunner") && !owner.TryEquipRanged())
367 {
368 num = 1;
369 }
370 if (!owner.IsPC && num > 1)
371 {
372 if (tactics.DestDist == 2)
373 {
374 if (EClass.rnd(5) == 0)
375 {
376 num = 1;
377 }
378 }
379 else if (owner.turn / 3 % 5 > 2)
380 {
381 num--;
382 }
383 }
384 bool flag = false;
385 if (dist > num)
386 {
387 flag = owner.TryMoveTowards(tc.pos) != Card.MoveResult.Fail;
388 if (!flag)
389 {
390 moveFail++;
391 }
392 }
393 else if (dist < num)
394 {
395 flag = owner.TryMoveFrom(tc.pos) != Card.MoveResult.Fail;
396 }
397 if (flag)
398 {
399 moveFail = 0;
400 }
402 {
403 Debug.Log("TryMove:" + owner.Name + "/" + flag + "/" + dist + "/" + num);
404 }
405 return flag;
406 }
407
408 public void AddAbility(Act a, int mod = 0, int chance = 100, bool aiPt = false)
409 {
410 abilities.Add(new ItemAbility
411 {
412 act = a,
413 priorityMod = mod,
414 chance = chance,
415 aiPt = aiPt
416 });
417 }
418
419 public virtual bool TryUseRanged(int dist)
420 {
421 if (owner.TryEquipRanged())
422 {
423 return ACT.Ranged.Perform(owner, tc);
424 }
425 return false;
426 }
427
428 public virtual bool TryThrow(int dist)
429 {
430 if (dist > owner.GetSightRadius())
431 {
432 return false;
433 }
434 Thing thing = owner.TryGetThrowable();
435 if (thing == null)
436 {
437 return false;
438 }
439 if (!ACT.Throw.CanPerform(owner, tc, tc.pos))
440 {
441 return false;
442 }
443 ActThrow.Throw(owner, tc.pos, tc, thing.HasElement(410) ? thing : thing.Split(1));
444 return true;
445 }
446
447 public virtual bool TryUseAbility(int dist, bool beforeMove = false)
448 {
449 if (abilities.Count == 0)
450 {
451 Debug.Log("no ability:" + owner);
452 return false;
453 }
454 int numEnemy = -1;
455 int numFriend = -1;
456 int numNeutral = -1;
457 bool charaBuilt = false;
458 bool flag = owner.CanSeeLos(tc, dist);
459 bool isPCFaction = owner.IsPCFaction;
460 bool flag2 = owner.HasCondition<ConSilence>();
461 bool isBlind = owner.isBlind;
462 bool flag3 = owner.HasCondition<ConFear>();
463 bool isConfused = owner.isConfused;
464 bool flag4 = owner.HasCondition<ConDim>();
465 bool flag5 = owner.HasCondition<ConSupress>();
466 foreach (ItemAbility ability in abilities)
467 {
468 Act act = ability.act;
469 ability.priority = 0;
470 ability.tg = null;
471 ability.pt = false;
472 if (EClass.rnd(100) >= ability.chance || (isBlind && ability.act.HasTag("reqSight")))
473 {
474 continue;
475 }
476 int num = 0;
478 if (s.abilityType.Length == 0 || (owner.IsPC && flag2 && act is Spell) || (beforeMove && !act.HasTag("before_move")))
479 {
480 continue;
481 }
482 string text = s.abilityType[0];
483 if (flag5 && !(text == "melee") && !(text == "range") && EClass.rnd(2) == 0)
484 {
485 continue;
486 }
487 switch (act.id)
488 {
489 case 6602:
490 if (dist <= 1 || tc.HasCondition<ConEntangle>())
491 {
492 continue;
493 }
494 break;
495 case 6450:
496 if (isPCFaction && (tc.HasElement(1221) || tc.HasElement(1223) || tc.id == "hedgehog_ether"))
497 {
498 continue;
499 }
500 break;
501 case 8200:
502 case 8201:
503 if (owner.HasElement(400))
504 {
505 continue;
506 }
507 break;
508 case 6400:
509 if (isPCFaction)
510 {
511 continue;
512 }
513 break;
514 }
515 bool isHOT;
516 switch (text)
517 {
518 case "item":
519 num = (ability.act as ActItem).BuildAct(owner);
520 break;
521 case "wait":
522 if (owner.IsPCParty)
523 {
524 continue;
525 }
526 num = 50;
527 break;
528 case "taunt":
529 {
530 bool flag6 = owner.HasCondition<StanceTaunt>();
531 bool flag7 = tactics.source.taunt != -1 && 100 * owner.hp / owner.MaxHP >= tactics.source.taunt;
532 num = ((flag6 && !flag7) ? 100 : ((!flag6 && flag7) ? 100 : 0));
533 break;
534 }
535 case "melee":
536 if (dist > owner.body.GetMeleeDistance())
537 {
538 continue;
539 }
540 num = ((!flag3) ? tactics.P_Melee : ((!owner.IsPC) ? (tactics.P_Melee / 2) : 0));
541 if (isConfused)
542 {
543 num -= (owner.IsPC ? 30 : 10);
544 }
545 if (isBlind)
546 {
547 num -= (owner.IsPC ? 50 : 10);
548 }
549 if (dist <= 1)
550 {
551 if (tc.HasElement(1221))
552 {
553 num -= 40;
554 }
555 if (tc.HasElement(1223))
556 {
557 num -= 40;
558 }
559 if (!owner.IsPC && owner.IsPCFaction && tc.id == "hedgehog_ether")
560 {
561 continue;
562 }
563 if (!owner.IsPCFaction && num < 10)
564 {
565 num = 10;
566 }
567 }
568 break;
569 case "range":
570 if (!flag || EClass.rnd(100) > tactics.RangedChance)
571 {
572 continue;
573 }
574 num = ((!flag3) ? tactics.P_Range : ((!owner.IsPC) ? (tactics.P_Range / 2) : 0));
575 if (isConfused)
576 {
577 num -= (owner.IsPC ? 30 : 10);
578 }
579 if (isBlind)
580 {
581 num -= (owner.IsPC ? 50 : 10);
582 }
583 if (owner.ranged != null && owner.ranged.trait is TraitToolRangeCane && owner.mana.value <= 0)
584 {
585 continue;
586 }
587 break;
588 case "teleport":
589 num = 40;
590 break;
591 case "any":
592 num = 50;
593 break;
594 case "hot":
595 case "heal":
596 isHOT = text == "hot";
597 num = ForeachChara(ability, (Chara c) => HealFactor(c), isFriendlyAbility: true);
598 if (ability.aiPt || (owner.IsPC && tactics.CastPartyBuff))
599 {
600 ability.pt = true;
601 }
602 break;
603 case "dot":
604 case "attack":
605 case "attackMelee":
606 {
607 if (!flag)
608 {
609 continue;
610 }
611 bool flag8 = text == "dot";
612 if (flag8 && (owner.isRestrained || (tc != null && tc.IsRestrainedResident)))
613 {
614 continue;
615 }
616 num = ((text == "attackMelee") ? tactics.P_Melee : tactics.P_Spell) + GetAttackMod(act);
617 if (num > 0 && flag8)
618 {
619 num += 10;
620 }
621 if (ability.aiPt)
622 {
623 ability.pt = true;
624 }
625 break;
626 }
627 case "attackArea":
628 {
629 if (owner.isRestrained || (tc != null && tc.IsRestrainedResident))
630 {
631 continue;
632 }
633 bool flag9 = ability.act is ActBolt;
635 {
636 continue;
637 }
638 GetNumEnemy(flag9 ? 6 : 5);
639 if (numEnemy == 0 || (owner.IsPCFactionOrMinion && GetNumNeutral(flag9 ? 6 : 5) > 0))
640 {
641 continue;
642 }
643 num = tactics.P_Spell - 20 + numEnemy * 10 + GetAttackMod(act);
644 break;
645 }
646 case "buff":
647 num = ForeachChara(ability, (Chara c) => (!c.HasCondition(s.proc[1])) ? tactics.P_Buff : 0, isFriendlyAbility: true);
648 if (ability.aiPt || (owner.IsPC && tactics.CastPartyBuff))
649 {
650 ability.pt = true;
651 }
652 break;
653 case "buffStats":
654 num = ForeachChara(ability, delegate(Chara c)
655 {
656 Element buffStats2 = c.GetBuffStats(s.proc[1]);
657 return (buffStats2 == null || buffStats2.Value < 0) ? tactics.P_Buff : 0;
658 }, isFriendlyAbility: true);
659 if (ability.aiPt || (owner.IsPC && tactics.CastPartyBuff))
660 {
661 ability.pt = true;
662 }
663 break;
664 case "debuff":
665 if (!flag)
666 {
667 continue;
668 }
669 num = tactics.P_Debuff;
670 if (ability.aiPt)
671 {
672 ability.pt = true;
673 }
674 break;
675 case "debuffStats":
676 if (!flag)
677 {
678 continue;
679 }
680 num = ForeachChara(ability, delegate(Chara c)
681 {
682 Element buffStats = c.GetBuffStats(s.proc[1]);
683 return (buffStats == null || buffStats.Value > 0) ? tactics.P_Debuff : 0;
684 }, isFriendlyAbility: false);
685 if (ability.aiPt)
686 {
687 ability.pt = true;
688 }
689 break;
690 case "ground":
691 if (!flag || owner.isRestrained || (tc != null && tc.IsRestrainedResident))
692 {
693 continue;
694 }
695 num = 50;
696 if (isPCFaction)
697 {
698 num -= 10;
699 }
700 break;
701 case "summon":
702 {
703 if (owner.isRestrained || (tc != null && tc.IsRestrainedResident))
704 {
705 continue;
706 }
707 int num2 = EClass._zone.CountMinions(owner);
708 if (num2 >= owner.MaxSummon)
709 {
710 continue;
711 }
712 num = tactics.P_Summon - 20 * num2 / owner.MaxSummon;
713 break;
714 }
715 case "summonAlly":
716 if (owner.isRestrained || (tc != null && tc.IsRestrainedResident))
717 {
718 continue;
719 }
720 if (owner.IsPC)
721 {
722 if (EClass.player.lastEmptyAlly <= 0)
723 {
724 continue;
725 }
726 }
727 else if (EClass._zone.CountMinions(owner) > 0)
728 {
729 continue;
730 }
731 num = tactics.P_Summon;
732 break;
733 case "suicide":
735 {
736 continue;
737 }
738 if (owner.HasTag(CTAG.kamikaze))
739 {
740 num = ((dist <= 1) ? 1000 : 0);
741 break;
742 }
743 num = 100 - 125 * owner.hp / owner.MaxHP;
744 if (EClass.rnd(200) <= num)
745 {
746 break;
747 }
748 continue;
749 default:
750 num = 0;
751 break;
752 }
753 if (s.target == "Neighbor")
754 {
755 if (dist > 1)
756 {
757 continue;
758 }
759 num += 10;
760 }
761 if (s.proc.Length != 0 && s.proc[0] == "Debuff" && tc.HasCondition(s.proc[1]))
762 {
763 continue;
764 }
765 if (s.abilityType.Length > 1)
766 {
767 num += (owner.IsPC ? s.abilityType[2] : s.abilityType[1]).ToInt();
768 }
769 if (act is Spell)
770 {
771 if (owner.IsPC)
772 {
773 if (act.vPotential <= 0)
774 {
775 continue;
776 }
777 if (flag2 || isConfused || flag4)
778 {
779 num -= 50;
780 }
781 }
782 else
783 {
784 if (flag2)
785 {
786 num -= 30;
787 }
788 if (isConfused || flag4)
789 {
790 num -= 10;
791 }
792 }
793 }
794 if (num > 0)
795 {
796 num += ability.priorityMod + EClass.rnd(tactics.RandomFacotr + ability.priorityMod);
797 }
798 ability.priority = num;
799 int HealFactor(Chara c)
800 {
801 if (isHOT && c.HasCondition(s.proc[1]))
802 {
803 return 0;
804 }
805 float num3 = (float)c.hp / (float)c.MaxHP;
806 if (num3 > (isHOT ? 0.85f : 0.75f))
807 {
808 return 0;
809 }
810 int num4 = tactics.P_Heal - (int)((float)tactics.P_Heal * num3) + (isHOT ? 50 : 25);
811 foreach (Condition condition in c.conditions)
812 {
813 if (condition is ConFear)
814 {
815 num4 += 10;
816 }
817 else if (condition is ConPoison)
818 {
819 num4 += 2;
820 }
821 else if (condition is ConConfuse)
822 {
823 num4 += 4;
824 }
825 else if (condition is ConDim)
826 {
827 num4 += 6;
828 }
829 else if (condition is ConBleed)
830 {
831 num4 += 8;
832 }
833 }
834 return num4;
835 }
836 }
837 abilities.Sort((ItemAbility a, ItemAbility b) => b.priority - a.priority);
838 foreach (ItemAbility ability2 in abilities)
839 {
840 if (ability2.priority <= 0)
841 {
842 continue;
843 }
845 {
846 Debug.Log(ability2.act.Name + "/" + ability2.priority);
847 }
848 if (ability2.act.source.alias == "ActRanged")
849 {
850 if (TryThrow(dist))
851 {
852 return true;
853 }
854 if (TryUseRanged(dist))
855 {
856 return true;
857 }
858 continue;
859 }
860 Cost cost = ability2.act.GetCost(owner);
861 if (owner.IsPCParty && ability2.pt && !ability2.act.IsTargetHostileParty() && !ability2.act.TargetType.ForceParty && cost.cost * EClass.pc.party.members.Count > owner.mana.value)
862 {
863 continue;
864 }
865 if (isPCFaction && cost.cost > 0)
866 {
867 switch (cost.type)
868 {
869 case CostType.MP:
870 if (cost.cost > owner.mana.value)
871 {
872 continue;
873 }
874 break;
875 case CostType.SP:
876 if (cost.cost > owner.stamina.value)
877 {
878 continue;
879 }
880 break;
881 }
882 }
883 if (cost.cost > 0 && EClass.rnd(100) > tactics.AbilityChance)
884 {
885 continue;
886 }
887 Chara chara = owner;
888 if (ability2.act.CanPerform(owner, ability2.tg ?? tc) && owner.UseAbility(ability2.act, ability2.tg ?? tc, null, (ability2.act.HaveLongPressAction && ability2.pt) || ability2.aiPt))
889 {
891 {
892 Debug.Log("Used Ability: " + chara?.ToString() + "/" + ability2.act?.ToString() + "/" + ability2.tg?.ToString() + "/" + tc);
893 Debug.Log(ability2.act.CanPerform(chara, ability2.tg ?? tc));
894 }
895 return true;
896 }
897 }
899 {
900 Debug.Log(owner.Name + "/" + abilities.Count);
901 foreach (ItemAbility ability3 in abilities)
902 {
903 Debug.Log(ability3.act.Name + "/" + ability3.priority);
904 }
905 }
906 return false;
907 void BuildCharaList()
908 {
909 if (charaBuilt)
910 {
911 return;
912 }
913 charas.Clear();
914 charaBuilt = true;
915 int sightRadius = owner.GetSightRadius();
916 foreach (Chara chara2 in EClass._map.charas)
917 {
918 if (chara2 != owner)
919 {
920 int num7 = owner.Dist(chara2);
921 if (num7 > sightRadius || !owner.CanSeeLos(chara2, num7))
922 {
923 continue;
924 }
925 }
926 charas.Add(chara2);
927 }
928 }
929 int ForeachChara(ItemAbility a, Func<Chara, int> func, bool isFriendlyAbility)
930 {
931 if (a.act.TargetType.Range == TargetRange.Self)
932 {
933 a.tg = owner;
934 return func(owner);
935 }
936 BuildCharaList();
937 int num8 = 0;
938 foreach (Chara chara3 in charas)
939 {
940 int num9 = func(chara3);
941 if (num9 > 0)
942 {
943 if (isFriendlyAbility)
944 {
945 if (owner.IsPCParty)
946 {
947 if (!chara3.IsPCParty)
948 {
949 continue;
950 }
951 }
952 else if (!owner.IsFriendOrAbove(chara3))
953 {
954 continue;
955 }
956 if (chara3 != owner)
957 {
958 num9 += tactics.P_Party;
959 }
960 }
961 else if (!owner.IsHostile(chara3))
962 {
963 continue;
964 }
965 if (num9 >= num8)
966 {
967 a.tg = chara3;
968 num8 = num9;
969 }
970 }
971 }
972 return num8;
973 }
974 int GetAttackMod(Act a)
975 {
976 if (!owner.IsPCParty || a.source.aliasRef.IsEmpty())
977 {
978 return 0;
979 }
980 int num5 = ((a.source.aliasRef == "mold") ? owner.MainElement.id : EClass.sources.elements.alias[a.source.aliasRef].id);
981 int num6 = -15 * tc.ResistLvFrom(num5);
982 switch (num5)
983 {
984 case 910:
985 if (tc.isWet)
986 {
987 num6 -= 30;
988 }
989 break;
990 case 911:
992 {
993 num6 -= 30;
994 }
995 break;
996 case 912:
997 if (tc.isWet)
998 {
999 num6 += 30;
1000 }
1001 break;
1002 }
1003 return num6;
1004 }
1005 void GetNumEnemy(int radius)
1006 {
1007 if (numEnemy != -1)
1008 {
1009 return;
1010 }
1011 BuildCharaList();
1012 numEnemy = 0;
1013 foreach (Chara chara4 in charas)
1014 {
1015 if (chara4.host == null && owner.IsHostile(chara4) && owner.Dist(chara4) < radius && owner.CanSeeLos(chara4))
1016 {
1017 numEnemy++;
1018 }
1019 }
1020 }
1021 int GetNumNeutral(int radius)
1022 {
1023 if (numNeutral != -1)
1024 {
1025 return numNeutral;
1026 }
1027 BuildCharaList();
1028 numNeutral = 0;
1029 foreach (Chara chara5 in charas)
1030 {
1031 if (!chara5.IsPCFactionOrMinion && chara5.IsNeutralOrAbove() && owner.Dist(chara5) <= radius && owner.CanSeeLos(chara5))
1032 {
1033 numNeutral++;
1034 }
1035 }
1036 return numNeutral;
1037 }
1038 }
1039
1040 public virtual void BuildAbilityList()
1041 {
1042 foreach (ActList.Item item in owner.ability.list.items)
1043 {
1044 AddAbility(item.act, 0, item.chance, item.pt);
1045 }
1049 }
1050
1051 public virtual bool TryAbortCombat()
1052 {
1053 return false;
1054 }
1055}
BossType
Definition: BossType.cs:2
CTAG
Definition: CTAG.cs:2
EditorTag
Definition: EditorTag.cs:2
Emo
Definition: Emo.cs:2
Hostility
Definition: Hostility.cs:2
MinionType
Definition: MinionType.cs:2
TargetRange
Definition: TargetRange.cs:2
Definition: ACT.cs:6
static ActRanged Ranged
Definition: ACT.cs:17
static ActThrow Throw
Definition: ACT.cs:19
static ActMelee Melee
Definition: ACT.cs:15
static ActItem Item
Definition: ACT.cs:21
virtual Status Cancel()
Definition: AIAct.cs:291
virtual bool ShouldAllyAttack(Chara tg)
Definition: AIAct.cs:134
new Chara owner
Definition: AIAct.cs:14
Status
Definition: AIAct.cs:8
override string ToString()
Definition: AIAct.cs:124
Status DoGoto(Point pos, int dist=0, bool ignoreConnection=false, Func< Status > _onChildFail=null)
Definition: AIAct.cs:432
void SetTurbo(int mtp=-1)
Definition: AM_Adv.cs:1040
List< Item > items
Definition: ActList.cs:14
override bool Perform()
Definition: ActRanged.cs:65
static EffectIRenderer Throw(Card c, Point p, Thing t, ThrowMethod method=ThrowMethod.Default, float failChance=0f)
Definition: ActThrow.cs:93
override bool CanPerform()
Definition: ActThrow.cs:25
Definition: ACT.cs:62
CostType
Definition: ACT.cs:64
virtual TargetType TargetType
Definition: ACT.cs:140
virtual bool HaveLongPressAction
Definition: ACT.cs:131
virtual bool CanPerform()
Definition: ACT.cs:301
bool IsTargetHostileParty()
Definition: ACT.cs:239
static AM_Adv Adv
Definition: ActionMode.cs:15
Definition: Card.cs:11
bool IsPCFactionOrMinion
Definition: Card.cs:2132
Thing Split(int a)
Definition: Card.cs:3231
string id
Definition: Card.cs:31
int GetSightRadius()
Definition: Card.cs:5649
bool IsRestrainedResident
Definition: Card.cs:2118
bool HasElement(int ele, int req=1)
Definition: Card.cs:5214
bool isRestrained
Definition: Card.cs:538
SoundSource PlaySound(string id, float v=1f, bool spatial=true)
Definition: Card.cs:5404
void Talk(string idTopic, string ref1=null, string ref2=null, bool forceSync=false)
Definition: Card.cs:5949
int hp
Definition: Card.cs:226
string Name
Definition: Card.cs:2013
bool ExistsOnMap
Definition: Card.cs:1961
bool HasTag(CTAG tag)
Definition: Card.cs:2455
Point pos
Definition: Card.cs:55
int DEX
Definition: Card.cs:2195
Effect PlayEffect(string id, bool useRenderPos=true, float range=0f, Vector3 fix=default(Vector3))
Definition: Card.cs:5438
void ShowEmo(Emo _emo=Emo.none, float duration=0f, bool skipSame=true)
Definition: Card.cs:5372
Trait trait
Definition: Card.cs:49
bool IsPowerful
Definition: Card.cs:1970
MoveResult
Definition: Card.cs:13
bool HasEditorTag(EditorTag tag)
Definition: Card.cs:2460
BossType c_bossType
Definition: Card.cs:1157
int turn
Definition: Card.cs:61
int Dist(Card c)
Definition: Card.cs:6777
bool isHidden
Definition: Card.cs:502
void ModExp(string alias, int a)
Definition: Card.cs:2508
int LV
Definition: Card.cs:370
int ResistLvFrom(int ele)
Definition: Card.cs:5204
void Say(string lang, string ref1=null, string ref2=null)
Definition: Card.cs:6046
ActList list
Definition: CharaAbility.cs:12
int GetMeleeDistance()
Definition: CharaBody.cs:414
Definition: Chara.cs:10
bool UseAbility(string idAct, Card tc=null, Point pos=null, bool pt=false)
Definition: Chara.cs:5228
Element MainElement
Definition: Chara.cs:702
new TraitChara trait
Definition: Chara.cs:488
Hostility OriginalHostility
Definition: Chara.cs:456
CharaBody body
Definition: Chara.cs:91
AIAct ai
Definition: Chara.cs:187
MoveResult TryMoveFrom(Point p)
Definition: Chara.cs:2382
Element GetBuffStats(string alias)
Definition: Chara.cs:8580
bool isWet
Definition: Chara.cs:137
override bool IsPC
Definition: Chara.cs:597
Chara host
Definition: Chara.cs:33
Point GetFirstStep(Point newPoint, PathManager.MoveType moveType=PathManager.MoveType.Default)
Definition: Chara.cs:2279
bool CanSeeLos(Card c, int dist=-1)
Definition: Chara.cs:1059
override bool IsPCParty
Definition: Chara.cs:600
override string ToString()
Definition: Chara.cs:981
Party party
Definition: Chara.cs:43
List< Condition > conditions
Definition: Chara.cs:196
bool HasCondition(string alias)
Definition: Chara.cs:8568
bool IsNeutralOrAbove()
Definition: Chara.cs:5928
override bool IsMinion
Definition: Chara.cs:612
bool MoveRandom()
Definition: Chara.cs:2284
override bool IsPCFaction
Definition: Chara.cs:656
int MaxSummon
Definition: Chara.cs:699
Thing TryGetThrowable()
Definition: Chara.cs:7005
int calmCheckTurn
Definition: Chara.cs:113
void MakeMinion(Chara _master, MinionType type=MinionType.Default)
Definition: Chara.cs:2058
bool CanSee(Card c)
Definition: Chara.cs:1027
override bool IsPCFactionMinion
Definition: Chara.cs:640
bool IsFriendOrAbove()
Definition: Chara.cs:5972
override int MaxHP
Definition: Chara.cs:693
Thing ranged
Definition: Chara.cs:95
SourceChara.Row source
Definition: Chara.cs:143
Stats mana
Definition: Chara.cs:963
bool FindNewEnemy()
Definition: Chara.cs:5800
Stats stamina
Definition: Chara.cs:955
Chara parasite
Definition: Chara.cs:30
Chara ride
Definition: Chara.cs:27
bool CanBeTempAlly(Chara c)
Definition: Chara.cs:2045
MoveResult TryMoveTowards(Point p)
Definition: Chara.cs:2320
bool FindNearestNewEnemy()
Definition: Chara.cs:5869
Chara enemy
Definition: Chara.cs:83
CharaAbility ability
Definition: Chara.cs:409
Chara SetEnemy(Chara c=null)
Definition: Chara.cs:5658
bool isBlind
Definition: Chara.cs:125
Tactics tactics
Definition: Chara.cs:787
bool IsHostile()
Definition: Chara.cs:5884
bool isDead
Definition: Chara.cs:374
bool isConfused
Definition: Chara.cs:121
bool TryEquipRanged()
Definition: Chara.cs:7081
void TrySetEnemy(Chara c)
Definition: Chara.cs:5675
SourceRace.Row race
Definition: Chara.cs:449
Definition: ConDim.cs:2
Definition: ConWet.cs:2
bool logCombat
Definition: CoreDebug.cs:244
static CursorInfo IconMelee
Definition: EClass.cs:5
static Game game
Definition: EClass.cs:8
static int rnd(int a)
Definition: EClass.cs:50
static Zone _zone
Definition: EClass.cs:20
static Map _map
Definition: EClass.cs:18
static SourceManager sources
Definition: EClass.cs:42
static Player player
Definition: EClass.cs:12
static Chara pc
Definition: EClass.cs:14
static CoreDebug debug
Definition: EClass.cs:48
int id
Definition: ELEMENT.cs:240
SourceElement.Row source
Definition: ELEMENT.cs:263
int vPotential
Definition: ELEMENT.cs:246
bool HasTag(string tag)
Definition: ELEMENT.cs:463
int Value
Definition: ELEMENT.cs:282
virtual string Name
Definition: ELEMENT.cs:294
virtual Act.Cost GetCost(Chara c)
Definition: ELEMENT.cs:853
Act act
Definition: ELEMENT.cs:384
ConfigTactics tactics
Definition: Game.cs:90
ConfigAutoCombat autoCombat
Definition: Game.cs:93
Config config
Definition: Game.cs:215
virtual bool TryUseRanged(int dist)
Definition: GoalCombat.cs:419
override IEnumerable< Status > Run()
Definition: GoalCombat.cs:49
virtual bool TryThrow(int dist)
Definition: GoalCombat.cs:428
virtual void BuildAbilityList()
Definition: GoalCombat.cs:1040
Chara tc
Definition: GoalCombat.cs:26
Tactics tactics
Definition: GoalCombat.cs:42
int idleCount
Definition: GoalCombat.cs:28
virtual bool TryAbortCombat()
Definition: GoalCombat.cs:1051
override bool CancelOnAggro
Definition: GoalCombat.cs:40
bool TryMove(int dist)
Definition: GoalCombat.cs:351
Chara destEnemy
Definition: GoalCombat.cs:24
List< ItemAbility > abilities
Definition: GoalCombat.cs:32
List< Chara > charas
Definition: GoalCombat.cs:34
virtual bool TryUseAbility(int dist, bool beforeMove=false)
Definition: GoalCombat.cs:447
override CursorInfo CursorIcon
Definition: GoalCombat.cs:36
override bool CancelWhenDamaged
Definition: GoalCombat.cs:38
int moveFail
Definition: GoalCombat.cs:30
override bool CanManualCancel()
Definition: GoalCombat.cs:44
void AddAbility(Act a, int mod=0, int chance=100, bool aiPt=false)
Definition: GoalCombat.cs:408
Definition: Goal.cs:4
Playlist plDay
Definition: Map.cs:77
List< Chara > charas
Definition: Map.cs:81
Definition: Msg.cs:5
static string Say(string idLang, string ref1, string ref2=null, string ref3=null, string ref4=null)
Definition: Msg.cs:58
List< Chara > members
Definition: Party.cs:18
bool IsCriminal
Definition: Player.cs:1138
int lastEmptyAlly
Definition: Player.cs:994
Definition: Point.cs:9
int x
Definition: Point.cs:36
int z
Definition: Point.cs:39
bool IsValid
Definition: Point.cs:88
int Distance(Point p)
Definition: Point.cs:953
bool IsInBounds
Definition: Point.cs:104
bool HasChara
Definition: Point.cs:226
string[] abilityType
SourceElement elements
bool isPeace
Definition: Spatial.cs:406
Definition: SPELL.cs:468
virtual int value
Definition: Stats.cs:56
int ChanceSecondMove
Definition: Tactics.cs:56
int RandomFacotr
Definition: Tactics.cs:12
int P_Party
Definition: Tactics.cs:71
int P_Spell
Definition: Tactics.cs:100
bool CastPartyBuff
Definition: Tactics.cs:118
int P_Debuff
Definition: Tactics.cs:113
int P_Buff
Definition: Tactics.cs:111
int P_Melee
Definition: Tactics.cs:74
int DestDist
Definition: Tactics.cs:24
int RangedChance
Definition: Tactics.cs:146
SourceTactics.Row source
Definition: Tactics.cs:3
int AbilityChance
Definition: Tactics.cs:130
int P_Range
Definition: Tactics.cs:86
int P_Summon
Definition: Tactics.cs:115
virtual TargetRange Range
Definition: TargetType.cs:25
virtual bool ForceParty
Definition: TargetType.cs:41
Definition: Thing.cs:8
void SetBGM(List< int > ids, bool refresh=true)
Definition: Zone.cs:2706
int CountMinions(Chara c)
Definition: Zone.cs:3420
virtual bool IsTown
Definition: Zone.cs:220
bool IsPCFaction
Definition: Zone.cs:464
Definition: ACT.cs:71
CostType type
Definition: ACT.cs:74
int cost
Definition: ACT.cs:72