Elin Decompiled Documentation EA 23.359.1 Nightly
Loading...
Searching...
No Matches
Chara.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using Algorithms;
6using Newtonsoft.Json;
7using UnityEngine;
8
9public class Chara : Card, IPathfindWalker
10{
11 public const int LevelLimit = 99999999;
12
13 private static Point shared = new Point();
14
15 private static List<Hobby> listHobby = new List<Hobby>();
16
17 public static string[] IDTimeTable = new string[2] { "default", "owl" };
18
19 [JsonProperty]
20 public int contribution;
21
22 [JsonProperty]
23 public Point orgPos;
24
25 [JsonProperty]
26 public Quest quest;
27
28 [JsonProperty]
29 public Chara ride;
30
31 [JsonProperty]
33
34 [JsonProperty]
35 public Chara host;
36
37 [JsonProperty]
39
41
43
44 [JsonProperty(PropertyName = "T1")]
45 public Party party;
46
47 [JsonProperty(PropertyName = "T2")]
49
50 [JsonProperty(PropertyName = "T3")]
51 public List<int> _hobbies;
52
53 [JsonProperty(PropertyName = "T4")]
54 public List<int> _works;
55
56 [JsonProperty(PropertyName = "T5")]
58
59 [JsonProperty(PropertyName = "T6")]
60 public List<int> _cooldowns;
61
62 [JsonProperty(PropertyName = "T7")]
63 public List<int> _listAbility;
64
65 [JsonProperty(PropertyName = "T8")]
66 public List<List<string>> _historyFood;
67
68 [JsonProperty(PropertyName = "1")]
69 public PCCData pccData;
70
71 [JsonProperty(PropertyName = "2")]
72 public Card held;
73
74 [JsonProperty(PropertyName = "3")]
75 public int[] rawSlots;
76
77 [JsonProperty(PropertyName = "4")]
79
80 [JsonProperty(PropertyName = "8")]
81 public string[] _strs = new string[5];
82
83 [JsonProperty(PropertyName = "9")]
84 public int[] _cints = new int[30];
85
87
88 public Chara enemy;
89
90 public Chara master;
91
92 public new Point lastPos = new Point();
93
95
96 public CharaBody body = new CharaBody();
97
99
100 public Thing ranged;
101
103
105
107
109
110 public Emo2 emoIcon;
111
112 public int happiness;
113
114 public int turnLastSeen = -100;
115
116 public int idleActTimer;
117
118 public int combatCount;
119
120 public int calmCheckTurn;
121
122 public int sharedCheckTurn;
123
124 public float idleTimer;
125
126 public bool isBerserk;
127
128 public bool isDrunk;
129
130 public bool isConfused;
131
132 public bool isFainted;
133
134 public bool isBlind;
135
136 public bool isParalyzed;
137
138 public bool _isLevitating;
139
140 public bool isCreated;
141
142 public bool canSeeInvisible;
143
144 public bool hasTelepathy;
145
146 public bool isWet;
147
148 public bool bossText;
149
150 public bool ignoreSPAbsorb;
151
152 public bool wasInWater;
153
155
156 public bool isWeakToSunlight;
157
158 public bool isAstralBody;
159
161
163
165
167
169
171
172 public static List<SourceRace.Row> ListAdvRace = new List<SourceRace.Row>();
173
174 public static List<SourceJob.Row> ListAdvJob = new List<SourceJob.Row>();
175
176 public bool dirtySpeed = true;
177
178 private long _Speed;
179
180 private static Point _sharedPos = new Point();
181
182 private bool hasMovedThisTurn;
183
184 public float actTime = 0.3f;
185
186 public static bool consumeTurn;
187
188 public static bool preventRegen;
189
190 public static bool isOnCreate;
191
192 private static List<Chara> _pts = new List<Chara>();
193
194 public int stealthSeen;
195
196 private static List<Thing> _ListItems = new List<Thing>();
197
198 private static List<SourceThing.Row> _listFavFood = new List<SourceThing.Row>();
199
200 private static List<SourceCategory.Row> _listFavCat = new List<SourceCategory.Row>();
201
202 public static NoGoal _NoGoalPC = new NoGoal();
203
204 public static NoGoal _NoGoalRepeat = new NoGoal();
205
206 public GoalList goalList = new GoalList();
207
208 public AIAct ai = new NoGoal();
209
211
212 private static GoalWork _goalWork = new GoalWork();
213
214 private static GoalHobby _goalHobby = new GoalHobby();
215
216 [JsonProperty]
217 public List<Condition> conditions = new List<Condition>();
218
219 [JsonProperty]
220 public Dictionary<int, int> resistCon;
221
222 public string Aka => _alias.IsEmpty(source.GetText("aka", returnNull: true) ?? "");
223
224 public string _alias
225 {
226 get
227 {
228 return _strs[0];
229 }
230 set
231 {
232 _strs[0] = value;
233 }
234 }
235
236 public string idFaith
237 {
238 get
239 {
240 return _strs[1];
241 }
242 set
243 {
244 _strs[1] = value;
245 }
246 }
247
248 public string idFaction
249 {
250 get
251 {
252 return _strs[2];
253 }
254 set
255 {
256 _strs[2] = value;
257 }
258 }
259
261 {
262 get
263 {
264 return RefZone.Get(_cints[1]);
265 }
266 set
267 {
268 _cints[1] = RefZone.Set(value);
269 }
270 }
271
273 {
274 get
275 {
276 return RefZone.Get(_cints[2]);
277 }
278 set
279 {
280 _cints[2] = RefZone.Set(value);
281 }
282 }
283
285 {
286 get
287 {
288 return _cints[3].ToEnum<GoalListType>();
289 }
290 set
291 {
292 _cints[3] = (int)value;
293 }
294 }
295
297 {
298 get
299 {
300 return _cints[4].ToEnum<Hostility>();
301 }
302 set
303 {
304 _cints[4] = (int)value;
305 }
306 }
307
308 public int _affinity
309 {
310 get
311 {
312 return _cints[5];
313 }
314 set
315 {
316 _cints[5] = value;
317 }
318 }
319
320 public Affinity affinity => Affinity.Get(this);
321
322 public int interest
323 {
324 get
325 {
326 return _cints[6];
327 }
328 set
329 {
330 _cints[6] = value;
331 }
332 }
333
334 public int daysStarved
335 {
336 get
337 {
338 return _cints[7];
339 }
340 set
341 {
342 _cints[7] = value;
343 }
344 }
345
346 public int _idTimeTable
347 {
348 get
349 {
350 return _cints[9];
351 }
352 set
353 {
354 _cints[9] = value;
355 }
356 }
357
358 public int uidEditor
359 {
360 get
361 {
362 return _cints[10];
363 }
364 set
365 {
366 _cints[10] = value;
367 }
368 }
369
370 public int _maxStamina
371 {
372 get
373 {
374 return _cints[20];
375 }
376 set
377 {
378 _cints[20] = value;
379 }
380 }
381
382 public int corruption
383 {
384 get
385 {
386 return _cints[21];
387 }
388 set
389 {
390 _cints[21] = value;
391 }
392 }
393
394 public bool isDead
395 {
396 get
397 {
398 return _cbits1[0];
399 }
400 set
401 {
402 _cbits1[0] = value;
403 }
404 }
405
406 public bool isAlawysVisible
407 {
408 get
409 {
410 return _cbits1[1];
411 }
412 set
413 {
414 _cbits1[1] = value;
415 }
416 }
417
418 public bool knowFav
419 {
420 get
421 {
422 return _cbits1[3];
423 }
424 set
425 {
426 _cbits1[3] = value;
427 }
428 }
429
431
433 {
434 get
435 {
436 return _faction ?? (_faction = EClass.game.factions.dictAll.TryGetValue(idFaction));
437 }
438 set
439 {
440 idFaction = value?.uid;
441 }
442 }
443
445 {
446 get
447 {
448 return EClass.game.religions.dictAll.TryGetValue(idFaith) ?? EClass.game.religions.dictAll["eyth"];
449 }
450 set
451 {
452 idFaith = value?.id;
453 }
454 }
455
456 public override CardRow sourceCard => source;
457
458 public override CardRow sourceRenderCard
459 {
460 get
461 {
462 if (pccData != null && !(source.renderData is RenderDataPcc))
463 {
465 }
466 return source;
467 }
468 }
469
470 public SourceRace.Row race => _race ?? (_race = EClass.sources.races.map.TryGetValue(base.c_idRace.IsEmpty(source.race))) ?? EClass.sources.races.map["norland"];
471
472 public SourceJob.Row job => _job ?? (_job = EClass.sources.jobs.map.TryGetValue(base.c_idJob.IsEmpty(source.job))) ?? EClass.sources.jobs.map["none"];
473
475
477 {
478 get
479 {
480 if (EClass.pc == null || !IsPCFaction)
481 {
482 if (base.c_originalHostility == (Hostility)0)
483 {
484 if (!source.hostility.IsEmpty())
485 {
486 return source.hostility.ToEnum<Hostility>();
487 }
488 return Hostility.Enemy;
489 }
490 return base.c_originalHostility;
491 }
492 return Hostility.Ally;
493 }
494 }
495
496 public string IDPCCBodySet
497 {
498 get
499 {
500 if (source.idActor.Length <= 1)
501 {
502 return "female";
503 }
504 return source.idActor[1];
505 }
506 }
507
509
510 public new TraitChara trait
511 {
512 get
513 {
514 return base.trait as TraitChara;
515 }
516 set
517 {
518 base.trait = value;
519 }
520 }
521
522 public string NameBraced => GetName(NameStyle.Full);
523
524 public string NameTitled => (EClass.game.principal.permadeath ? "★" : "") + NameBraced;
525
526 public override string actorPrefab
527 {
528 get
529 {
530 if (IsPCC)
531 {
532 return "CharaActorPCC";
533 }
534 return "CharaActor";
535 }
536 }
537
538 public override int PrefIndex
539 {
540 get
541 {
542 if (sourceCard._tiles.Length != 0 || renderer.replacer != null)
543 {
544 if (base.dir != 1 && base.dir != 2)
545 {
546 return 0;
547 }
548 return 1;
549 }
550 return base.dir;
551 }
552 }
553
554 public override bool flipX
555 {
556 get
557 {
558 if (base.dir != 1)
559 {
560 return base.dir == 2;
561 }
562 return true;
563 }
564 }
565
566 public override string AliasMaterialOnCreate => race.material;
567
568 public override bool IsAliveInCurrentZone
569 {
570 get
571 {
572 if (!isDead)
573 {
574 return base.ExistsOnMap;
575 }
576 return false;
577 }
578 }
579
580 public override bool IsDeadOrSleeping
581 {
582 get
583 {
584 if (!isDead && conSleep == null && conSuspend == null)
585 {
586 return isFainted;
587 }
588 return true;
589 }
590 }
591
592 public override bool IsDisabled
593 {
594 get
595 {
596 if (!isDead && conSleep == null && !isFainted)
597 {
598 return isParalyzed;
599 }
600 return true;
601 }
602 }
603
604 public bool IsLevitating
605 {
606 get
607 {
608 if (ride != null)
609 {
610 return ride._isLevitating;
611 }
612 return _isLevitating;
613 }
614 }
615
616 public bool IsMarried
617 {
618 get
619 {
620 if (base.c_love != null)
621 {
622 return base.c_love.dateMarriage != 0;
623 }
624 return false;
625 }
626 }
627
628 public override bool IsMoving => idleTimer > 0f;
629
630 public override bool IsGlobal => global != null;
631
632 public override bool IsPC => this == EClass.player.chara;
633
634 public override bool IsPCParty
635 {
636 get
637 {
638 if (party != null)
639 {
640 return party.leader == EClass.pc;
641 }
642 return false;
643 }
644 }
645
646 public override bool IsMinion
647 {
648 get
649 {
650 if (master == null)
651 {
652 return base.c_uidMaster != 0;
653 }
654 return true;
655 }
656 }
657
658 public override bool IsPCPartyMinion
659 {
660 get
661 {
662 if (master != null)
663 {
664 if (!master.IsPCParty)
665 {
666 return master.IsPCPartyMinion;
667 }
668 return true;
669 }
670 return false;
671 }
672 }
673
674 public override bool IsPCFactionMinion
675 {
676 get
677 {
678 if (master != null)
679 {
680 if (!master.IsPCFaction)
681 {
683 }
684 return true;
685 }
686 return false;
687 }
688 }
689
690 public override bool IsPCFaction
691 {
692 get
693 {
694 if (EClass.pc != null)
695 {
696 return faction == EClass.pc.faction;
697 }
698 return false;
699 }
700 }
701
702 public override bool IsPCC => pccData != null;
703
704 public override bool isThing => false;
705
706 public override bool isChara => true;
707
708 public override bool HasHost => host != null;
709
710 public override bool isSynced
711 {
712 get
713 {
714 if (renderer == null || !renderer.isSynced)
715 {
716 if (host != null)
717 {
718 return host.isSynced;
719 }
720 return false;
721 }
722 return true;
723 }
724 }
725
726 public override bool IsMultisize => sourceCard.multisize;
727
728 public override int MaxHP => (int)Mathf.Clamp(((long)(base.END * 2 + base.STR + base.WIL / 2) * (long)Mathf.Min(base.LV, 25) / 25 + base.END + 10) * Evalue(60) / 100 * ((base.IsPCFactionOrMinion ? 100 : (100 + (int)base.rarity * 300)) + (IsPC ? (EClass.player.lastEmptyAlly * Evalue(1646)) : 0)) / 100, 1f, 1E+09f);
729
730 public override int WeightLimit => (int)Mathf.Clamp(((long)base.STR * 500L + base.END * 250 + Evalue(207) * 2000) * ((!HasElement(1411)) ? 1 : 5) + 45000, 1000f, 1.0737418E+09f);
731
732 public override int SelfWeight => ((bio.weight > 2000000) ? 2000000 : bio.weight) * 1000;
733
734 public int MaxSummon => Mathf.Max((int)Mathf.Sqrt(base.CHA), 1) + Evalue(1647) + ((!base.IsPCFactionOrMinion) ? ((int)base.rarity * 5) : 0);
735
737 {
738 get
739 {
740 if (base.c_idMainElement == 0)
741 {
742 return Element.Void;
743 }
744 return elements.GetElement(base.c_idMainElement);
745 }
746 }
747
748 public override int DV
749 {
750 get
751 {
752 if (IsPCFaction)
753 {
754 return WeaknessMod(elements.Value(64));
755 }
756 int num = base.LV;
757 if (num > 50)
758 {
759 num = 50 + (num - 50) / 10;
760 }
761 return WeaknessMod(num + elements.Value(64) * (100 + num + race.DV * 5) / 100);
762 int WeaknessMod(int a)
763 {
764 if (HasCondition<ConWeakness>())
765 {
766 if (a <= 0)
767 {
768 return a * 2;
769 }
770 return a / 2;
771 }
772 return a;
773 }
774 }
775 }
776
777 public override int PV
778 {
779 get
780 {
781 if (IsPCFaction)
782 {
783 return WeaknessMod(elements.Value(65));
784 }
785 int num = base.LV;
786 if (num > 50)
787 {
788 num = 50 + (num - 50) / 10;
789 }
790 return WeaknessMod(num + elements.Value(65) * (100 + num + race.PV * 5) / 100);
791 int WeaknessMod(int a)
792 {
793 if (HasCondition<ConWeakness>())
794 {
795 if (a <= 0)
796 {
797 return a * 2;
798 }
799 return a / 2;
800 }
801 return a;
802 }
803 }
804 }
805
806 public override SourcePref Pref
807 {
808 get
809 {
810 if (spriteReplacer != null)
811 {
813 {
814 spriteReplacer.data.tryFixPrefNotLoadedAtStart = true;
816 }
817 if (spriteReplacer.data?.pref != null)
818 {
819 return spriteReplacer.data.pref;
820 }
822 {
824 }
825 }
826 else if (base.idSkin > 0)
827 {
828 switch (sourceCard.tiles.TryGet(base.idSkin))
829 {
830 case 2319:
831 case 2619:
832 case 2621:
833 case 2623:
834 case 2625:
836 case 2320:
837 case 2611:
838 case 2620:
839 case 2622:
840 case 2624:
841 case 2626:
842 case 2828:
844 }
845 }
847 }
848 }
849
850 public bool CanOpenDoor
851 {
852 get
853 {
854 if (base.INT < 5)
855 {
856 if (IsPCFaction)
857 {
858 return memberType == FactionMemberType.Default;
859 }
860 return false;
861 }
862 return true;
863 }
864 }
865
866 public Tactics tactics => _tactics ?? (_tactics = new Tactics(this));
867
869
871 {
872 get
873 {
874 if (!HasTag(CTAG.ride))
875 {
876 if (!HasTag(CTAG.noRide))
877 {
878 if (!race.tag.Contains("ride"))
879 {
880 if (!race.tag.Contains("noRide"))
881 {
882 return Ridability.Default;
883 }
884 return Ridability.BadRide;
885 }
886 return Ridability.GoodRide;
887 }
888 return Ridability.BadRide;
889 }
890 return Ridability.GoodRide;
891 }
892 }
893
895
896 public bool IsLocalChara
897 {
898 get
899 {
900 if (!IsGlobal && !base.isSubsetCard && homeZone == EClass._zone)
901 {
902 return !base.isSummon;
903 }
904 return false;
905 }
906 }
907
908 public bool IsIdle
909 {
910 get
911 {
912 if (!IsDeadOrSleeping)
913 {
914 return ai.Current.IsIdle;
915 }
916 return false;
917 }
918 }
919
920 public bool IsInCombat => ai is GoalCombat;
921
922 public bool IsAnimal
923 {
924 get
925 {
926 if (!race.IsAnimal)
927 {
928 return HasTag(CTAG.animal);
929 }
930 return true;
931 }
932 }
933
934 public bool IsHuman
935 {
936 get
937 {
938 if (!race.IsHuman)
939 {
940 return HasTag(CTAG.human);
941 }
942 return true;
943 }
944 }
945
946 public bool IsUndead
947 {
948 get
949 {
950 if (!race.IsUndead)
951 {
952 return HasTag(CTAG.undead);
953 }
954 return true;
955 }
956 }
957
958 public bool IsMachine
959 {
960 get
961 {
962 if (!race.IsMachine)
963 {
964 return HasTag(CTAG.machine);
965 }
966 return true;
967 }
968 }
969
970 public bool IsHorror
971 {
972 get
973 {
974 if (!race.IsHorror)
975 {
976 return HasTag(CTAG.horror);
977 }
978 return true;
979 }
980 }
981
982 public bool IsFish
983 {
984 get
985 {
986 if (!race.IsFish)
987 {
988 return HasTag(CTAG.fish);
989 }
990 return true;
991 }
992 }
993
994 public bool IsFairy
995 {
996 get
997 {
998 if (!race.IsFairy)
999 {
1000 return HasTag(CTAG.fairy);
1001 }
1002 return true;
1003 }
1004 }
1005
1006 public bool IsGod
1007 {
1008 get
1009 {
1010 if (!race.IsGod)
1011 {
1012 return HasTag(CTAG.god);
1013 }
1014 return true;
1015 }
1016 }
1017
1018 public bool IsDragon
1019 {
1020 get
1021 {
1022 if (!race.IsDragon)
1023 {
1024 return HasTag(CTAG.dragon);
1025 }
1026 return true;
1027 }
1028 }
1029
1030 public bool IsPlant
1031 {
1032 get
1033 {
1034 if (!race.IsPlant)
1035 {
1036 return HasTag(CTAG.plant);
1037 }
1038 return true;
1039 }
1040 }
1041
1042 public bool IsCat
1043 {
1044 get
1045 {
1046 if (!(race.id == "cat") && !(race.id == "catsister"))
1047 {
1048 return race.id == "catgod";
1049 }
1050 return true;
1051 }
1052 }
1053
1055
1056 public bool HasNoGoal => ai.IsNoGoal;
1057
1058 public bool CanWitness
1059 {
1060 get
1061 {
1062 if (!IsHuman && !IsFairy && !IsGod)
1063 {
1064 return race.id == "mutant";
1065 }
1066 return true;
1067 }
1068 }
1069
1070 public bool IsHumanSpeak
1071 {
1072 get
1073 {
1074 if (!IsHuman && !race.tag.Contains("humanSpeak"))
1075 {
1076 return HasTag(CTAG.humanSpeak);
1077 }
1078 return true;
1079 }
1080 }
1081
1082 public bool IsMaid
1083 {
1084 get
1085 {
1086 if (EClass.Branch != null)
1087 {
1088 return EClass.Branch.uidMaid == base.uid;
1089 }
1090 return false;
1091 }
1092 }
1093
1094 public bool IsPrisoner => false;
1095
1096 public bool IsAdventurer
1097 {
1098 get
1099 {
1100 if (global != null && faction != EClass.pc.faction)
1101 {
1102 return IsPCC;
1103 }
1104 return false;
1105 }
1106 }
1107
1108 public bool IsEyth => faith.id == "eyth";
1109
1110 public bool IsWealthy
1111 {
1112 get
1113 {
1114 if (!source.works.Contains("Rich"))
1115 {
1116 return source.hobbies.Contains("Rich");
1117 }
1118 return true;
1119 }
1120 }
1121
1123
1124 public int MaxGeneSlot => race.geneCap - (HasElement(1237) ? 2 : 0) + Evalue(1242) + Evalue(1273) + (base.IsSlimeEvolvable ? (Evalue(1274) - 7) : 0);
1125
1126 public int GeneCostMTP
1127 {
1128 get
1129 {
1130 if (!IsPC)
1131 {
1132 return 100;
1133 }
1134 return 5;
1135 }
1136 }
1137
1139 {
1140 get
1141 {
1142 if (base.c_genes != null)
1143 {
1144 return base.c_genes.GetGeneSlot(this);
1145 }
1146 return 0;
1147 }
1148 }
1149
1150 public int Speed
1151 {
1152 get
1153 {
1154 if (dirtySpeed)
1155 {
1156 RefreshSpeed();
1157 }
1158 if (_Speed > 100000000)
1159 {
1160 return 100000000;
1161 }
1162 return (int)_Speed;
1163 }
1164 }
1165
1166 public bool IsMofuable
1167 {
1168 get
1169 {
1170 if (!race.tag.Contains("mofu"))
1171 {
1172 return HasElement(419);
1173 }
1174 return true;
1175 }
1176 }
1177
1178 public int SpriteSkin
1179 {
1180 get
1181 {
1182 if (sourceCard.tiles.Length > 1)
1183 {
1184 if (base.idSkin == 0 && !source.staticSkin)
1185 {
1186 return base.uid % sourceCard.tiles.Length / 2 * 2 + ((!base.IsMale) ? 1 : 0);
1187 }
1188 return base.idSkin;
1189 }
1190 return 0;
1191 }
1192 }
1193
1195 {
1196 get
1197 {
1198 if (_baseWorkElements == null)
1199 {
1201 foreach (Hobby item in ListHobbies())
1202 {
1203 Build(item);
1204 }
1205 foreach (Hobby item2 in ListWorks())
1206 {
1207 Build(item2);
1208 }
1209 }
1210 return _baseWorkElements;
1211 void Build(Hobby h)
1212 {
1213 if (!h.source.elements.IsEmpty())
1214 {
1215 for (int i = 0; i < h.source.elements.Length; i += 2)
1216 {
1217 int ele = h.source.elements[i];
1218 int v = h.source.elements[i + 1];
1219 _baseWorkElements.ModBase(ele, v);
1220 }
1221 }
1222 }
1223 }
1224 }
1225
1226 public Stats hunger => Stats.Hunger.Set(_cints, 10, this);
1227
1228 public Stats burden => Stats.Burden.Set(_cints, 11, this);
1229
1230 public Stats stamina => Stats.Stamina.Set(_cints, 12, this);
1231
1233
1234 public Stats bladder => Stats.Bladder.Set(_cints, 14, this);
1235
1236 public Stats hygiene => Stats.Hygiene.Set(_cints, 15, this);
1237
1238 public Stats mana => Stats.Mana.Set(_cints, 16, this);
1239
1241
1242 public Stats SAN => Stats.SAN.Set(_cints, 18, this);
1243
1245 {
1246 get
1247 {
1248 if (base.rarity >= Rarity.Legendary)
1249 {
1250 return !IsPCFaction;
1251 }
1252 return false;
1253 }
1254 }
1255
1256 public override string ToString()
1257 {
1258 return base.Name + "(" + ai?.ToString() + ")" + pos?.ToString() + "/" + base.ExistsOnMap + "/" + isDead;
1259 }
1260
1261 public bool IsCriticallyWounded(bool includeRide = false)
1262 {
1263 if (host == null || includeRide)
1264 {
1265 if (Evalue(1421) <= 0)
1266 {
1267 return base.hp < MaxHP / 5;
1268 }
1269 return base.hp + mana.value < (MaxHP + mana.max) / 5;
1270 }
1271 return false;
1272 }
1273
1274 public bool HasHigherGround(Card c)
1275 {
1276 if (c == null)
1277 {
1278 return false;
1279 }
1280 float num = renderer.position.y - pos.Position(0).y + (_isLevitating ? 0.4f : 0f);
1281 float num2 = c.renderer.position.y - c.pos.Position(0).y + ((c.isChara && c.Chara._isLevitating) ? 0.4f : 0f);
1282 return num > num2 + 0.1f;
1283 }
1284
1285 public bool CanSeeSimple(Point p)
1286 {
1287 if (!p.IsValid || p.IsHidden)
1288 {
1289 return false;
1290 }
1291 if (IsPC)
1292 {
1293 if (fov != null)
1294 {
1295 return fov.lastPoints.ContainsKey(p.index);
1296 }
1297 return false;
1298 }
1299 return true;
1300 }
1301
1302 public bool CanSee(Card c)
1303 {
1304 if (c == this)
1305 {
1306 return true;
1307 }
1308 if (!c.pos.IsValid)
1309 {
1310 return false;
1311 }
1312 if (c.isChara)
1313 {
1315 {
1316 return true;
1317 }
1318 if (c.isHidden && c != this && !canSeeInvisible)
1319 {
1320 return false;
1321 }
1322 }
1323 if (IsPC)
1324 {
1325 if (fov != null)
1326 {
1327 return fov.lastPoints.ContainsKey(c.pos.index);
1328 }
1329 return false;
1330 }
1331 return true;
1332 }
1333
1334 public bool CanSeeLos(Card c, int dist = -1)
1335 {
1337 {
1338 return false;
1339 }
1340 return CanSeeLos(c.pos, dist);
1341 }
1342
1343 public bool CanSeeLos(Point p, int dist = -1)
1344 {
1345 if (dist == -1)
1346 {
1347 dist = pos.Distance(p);
1348 }
1349 if (dist > GetSightRadius())
1350 {
1351 return false;
1352 }
1353 if (IsPC)
1354 {
1355 if (fov != null)
1356 {
1357 return fov.lastPoints.ContainsKey(p.index);
1358 }
1359 return false;
1360 }
1361 if ((pos.IsBlocked || p.IsBlocked) && dist <= 1)
1362 {
1363 return true;
1364 }
1365 return Los.IsVisible(pos, p);
1366 }
1367
1368 public bool HasAccess(Card c)
1369 {
1370 return HasAccess(c.pos);
1371 }
1372
1373 public bool HasAccess(Point p)
1374 {
1375 if (!EClass._zone.IsPCFaction || p.cell.room == null || IsPC)
1376 {
1377 return true;
1378 }
1379 return p.cell.room.data.accessType switch
1380 {
1381 BaseArea.AccessType.Resident => memberType == FactionMemberType.Default,
1382 BaseArea.AccessType.Private => false,
1383 _ => true,
1384 };
1385 }
1386
1387 public bool CanSleep()
1388 {
1389 if (EClass._zone.events.GetEvent<ZoneEventQuest>() != null)
1390 {
1391 return false;
1392 }
1393 if (!EClass.debug.godMode && sleepiness.GetPhase() == 0)
1394 {
1395 return stamina.GetPhase() <= 1;
1396 }
1397 return true;
1398 }
1399
1400 protected override void OnSerializing()
1401 {
1402 if (enemy != null)
1403 {
1404 SetInt(55, enemy.uid);
1405 }
1406 _cints[0] = (int)_cbits1.Bits;
1407 List<BodySlot> slots = body.slots;
1408 rawSlots = new int[slots.Count];
1409 for (int i = 0; i < slots.Count; i++)
1410 {
1411 rawSlots[i] = slots[i].elementId;
1412 }
1413 }
1414
1415 protected override void OnDeserialized()
1416 {
1417 isCreated = true;
1418 _cbits1.Bits = (uint)_cints[0];
1419 InitStats(onDeserialize: true);
1420 body.SetOwner(this, deserialized: true);
1421 elements.ApplyElementMap(base.uid, SourceValueType.Chara, job.elementMap, base.DefaultLV);
1422 elements.ApplyElementMap(base.uid, SourceValueType.Chara, race.elementMap, base.DefaultLV);
1423 if (global != null && global.goal != null)
1424 {
1425 global.goal.SetOwner(this);
1426 }
1427 if (IsPCC)
1428 {
1429 pccData.state = (base.isCensored ? PCCState.Naked : PCCState.Normal);
1430 }
1431 if (tempElements != null)
1432 {
1433 tempElements.SetParent(this);
1434 }
1435 UpdateAngle();
1437 Refresh();
1438 if (source.tag.Contains("boss"))
1439 {
1440 bossText = true;
1441 }
1442 sharedCheckTurn = EClass.rnd(200);
1443 }
1444
1445 public override string GetName(NameStyle style, int num = -1)
1446 {
1447 if (mimicry != null && mimicry.Card != this)
1448 {
1449 return mimicry.GetName(style, num);
1450 }
1451 if (base.isBackerContent && EClass.core.config.backer.Show(base.c_idBacker))
1452 {
1453 if (id == "follower" && !IsGlobal)
1454 {
1455 return "_follower".lang(EClass.sources.backers.map[base.c_idBacker].Name, faith.Name);
1456 }
1457 return EClass.sources.backers.map[base.c_idBacker].Name;
1458 }
1459 string text = base.c_altName ?? source.GetName(this);
1460 if (HasCondition<ConTransmuteShadow>())
1461 {
1462 text = EClass.sources.charas.map["shade"].GetName(this);
1463 }
1464 text = text.Replace("#ele5", MainElement.source.GetAltname(3)).Replace("#ele4", MainElement.source.GetAltname(2)).Replace("#ele3", MainElement.source.GetAltname(1))
1465 .Replace("#ele2", MainElement.source.GetAltname(0))
1466 .Replace("#ele", MainElement.source.GetName().ToLower());
1467 if (base.c_bossType == BossType.Evolved)
1468 {
1469 text = "_evolved".lang(text.ToTitleCase(wholeText: true));
1470 }
1471 trait.SetName(ref text);
1472 if (text.Length > 0 && char.IsLower(text[0]))
1473 {
1474 if (base.rarity >= Rarity.Legendary)
1475 {
1476 text = text.ToTitleCase();
1477 }
1478 else if (num != 0)
1479 {
1480 text = text.AddArticle();
1481 }
1482 }
1483 if (style == NameStyle.Simple)
1484 {
1485 return text;
1486 }
1487 int num2 = ((base.rarity == Rarity.Mythical) ? 3 : ((base.rarity >= Rarity.Mythical) ? 2 : ((base.rarity >= Rarity.Legendary) ? 2 : ((!_alias.IsEmpty()) ? 1 : (-1)))));
1488 if (trait is TraitAdventurer)
1489 {
1490 num2 = 1;
1491 }
1492 text = ((Aka.IsEmpty() || !(Aka != text)) ? text.Bracket(num2) : (num2 switch
1493 {
1494 -1 => "_aka",
1495 1 => "_aka3",
1496 _ => "_aka2",
1497 }).lang((num2 == -1) ? Aka : Aka.ToTitleCase(wholeText: true), text.Bracket(num2)));
1498 string text2 = (base.isSale ? "forSale".lang(Lang._currency(GetPrice(CurrencyType.Money, sell: true, PriceType.PlayerShop), "money")) : "");
1499 return text + text2;
1500 }
1501
1502 public override void ChangeRarity(Rarity r)
1503 {
1504 if (r != base.rarity)
1505 {
1506 base.rarity = r;
1507 if (renderer != null && renderer.isSynced)
1508 {
1510 }
1511 base.hp = MaxHP;
1512 }
1513 }
1514
1516 {
1517 _faction = null;
1518 faction = f;
1520 return this;
1521 }
1522
1524 {
1525 homeZone = zone;
1526 SetGlobal();
1527 return this;
1528 }
1529
1531 {
1532 Hostility hostility = (base.c_originalHostility = h);
1533 this.hostility = hostility;
1534 return this;
1535 }
1536
1537 public void OnBanish()
1538 {
1539 if (!IsGlobal)
1540 {
1541 return;
1542 }
1543 memberType = FactionMemberType.Default;
1544 foreach (Thing item in things.List((Thing a) => a.HasTag(CTAG.godArtifact)).ToList())
1545 {
1547 }
1548 UniqueData uniqueData = base.c_uniqueData;
1549 if (uniqueData != null)
1550 {
1551 Debug.Log(uniqueData.uidZone + "/" + EClass.game.spatials.map.ContainsKey(uniqueData.uidZone) + "/" + uniqueData.x + "/" + uniqueData.y);
1552 }
1553 if (uniqueData != null && EClass.game.spatials.map.ContainsKey(uniqueData.uidZone))
1554 {
1555 MoveHome(EClass.game.spatials.map[uniqueData.uidZone] as Zone, uniqueData.x, uniqueData.y);
1556 return;
1557 }
1558 Zone z = EClass.game.spatials.Find("somewhere");
1559 if (trait is TraitAdventurer)
1560 {
1561 z = (from zone in EClass.world.region.ListTowns()
1562 where zone != EClass._zone
1563 select zone).RandomItem();
1564 SetHomeZone(z);
1565 }
1566 MoveZone(z, ZoneTransition.EnterState.RandomVisit);
1567 }
1568
1569 public Chara SetGlobal(Zone _home, int x, int z)
1570 {
1571 SetGlobal();
1572 homeZone = _home;
1573 _home.AddCard(this, x, z);
1574 global.transition = new ZoneTransition
1575 {
1576 state = ZoneTransition.EnterState.Exact,
1577 x = x,
1578 z = z
1579 };
1580 orgPos = new Point(x, z);
1581 return this;
1582 }
1583
1585 {
1586 if (!IsGlobal)
1587 {
1589 global = new GlobalData();
1590 base.isSubsetCard = false;
1591 enemy = null;
1592 base.c_uidMaster = 0;
1593 }
1594 return this;
1595 }
1596
1597 public void RemoveGlobal()
1598 {
1599 if (IsGlobal)
1600 {
1601 global = null;
1603 }
1604 }
1605
1606 public override void OnBeforeCreate()
1607 {
1608 if (source.job == "*r")
1609 {
1610 base.c_idJob = EClass.sources.jobs.rows.Where((SourceJob.Row j) => j.playable < 4).RandomItem().id;
1611 }
1612 if (bp.idJob != null)
1613 {
1614 base.c_idJob = bp.idJob;
1615 }
1616 if (bp.idRace != null)
1617 {
1618 base.c_idRace = bp.idRace;
1619 }
1620 }
1621
1622 public override void OnCreate(int genLv)
1623 {
1624 if (source.tag.Contains("boss"))
1625 {
1626 bossText = true;
1627 }
1628 int num = ((bp.lv != -999) ? bp.lv : base.LV);
1629 if (trait.AdvType == TraitChara.Adv_Type.Adv || trait.AdvType == TraitChara.Adv_Type.Adv_Fairy)
1630 {
1631 if (ListAdvRace.Count == 0)
1632 {
1633 ListAdvRace = EClass.sources.races.rows.Where((SourceRace.Row a) => a.playable <= 1 && a.id != "fairy").ToList();
1634 ListAdvJob = EClass.sources.jobs.rows.Where((SourceJob.Row a) => a.playable <= 4).ToList();
1635 }
1636 if (trait.AdvType == TraitChara.Adv_Type.Adv)
1637 {
1638 base.c_idRace = ListAdvRace.RandomItem().id;
1639 }
1640 base.c_idJob = ListAdvJob.RandomItem().id;
1641 _race = null;
1642 _job = null;
1643 num = 10 + EClass.rnd(40);
1644 }
1645 bio = new Biography();
1646 bio.Generate(this);
1647 if (source.idActor.Length != 0 && source.idActor[0] == "pcc" && pccData == null)
1648 {
1649 pccData = PCCData.Create(IDPCCBodySet);
1650 if (source.idActor.Length > 2)
1651 {
1652 pccData.SetPart("body", IDPCCBodySet, source.idActor[2]);
1653 }
1654 else
1655 {
1656 pccData.Randomize(IDPCCBodySet);
1657 }
1658 }
1659 if (source.mainElement.Length != 0)
1660 {
1661 int _genLv = Mathf.Min(genLv, 100);
1662 List<Tuple<string, int, int>> list = new List<Tuple<string, int, int>>();
1663 string[] mainElement = source.mainElement;
1664 for (int num2 = 0; num2 < mainElement.Length; num2++)
1665 {
1666 string[] array = mainElement[num2].Split('/');
1667 SourceElement.Row row = EClass.sources.elements.alias["ele" + array[0]];
1668 int num3 = source.LV * row.eleP / 100;
1669 if (list.Count == 0 || num3 < _genLv || array[0] == bp.idEle)
1670 {
1671 list.Add(new Tuple<string, int, int>(array[0], (array.Length > 1) ? int.Parse(array[1]) : 0, num3));
1672 }
1673 }
1674 Tuple<string, int, int> tuple = list.RandomItemWeighted((Tuple<string, int, int> a) => 10000 / Mathf.Max(100 + (_genLv - a.Item3) * 25, 1));
1675 if (!bp.idEle.IsEmpty())
1676 {
1677 tuple = list.Where((Tuple<string, int, int> a) => a.Item1 == bp.idEle || "ele" + a.Item1 == bp.idEle).FirstOrDefault() ?? tuple;
1678 }
1679 SetMainElement(tuple.Item1, (tuple.Item2 == 0) ? 10 : tuple.Item2, elemental: true);
1680 if (list.Count >= 2)
1681 {
1682 num = tuple.Item3 + base.LV - source.LV;
1683 }
1684 }
1685 if (trait.UseRandomName)
1686 {
1687 base.c_altName = NameGen.getRandomName();
1688 }
1690 {
1691 _alias = AliasGen.GetRandomAlias();
1692 }
1693 happiness = EClass.rnd(100);
1694 contribution = EClass.rnd(100);
1695 RerollHobby();
1696 _idTimeTable = ((EClass.rnd(5) == 0) ? 1 : 0);
1697 ApplyRace();
1698 ApplyJob();
1699 ChangeMaterial(source.defMat.IsEmpty(race.material), ignoreFixedMaterial: true);
1700 if (num != source.LV)
1701 {
1702 SetLv(num);
1703 }
1704 if (base.LV > 5 && race.id == "mutant")
1705 {
1706 for (int num4 = 0; num4 < Mathf.Min(1 + base.LV / 5, 20); num4++)
1707 {
1708 SetFeat(1644, num4 + 1);
1709 }
1710 }
1711 switch (id)
1712 {
1713 case "putty_mech_b":
1714 case "putty_mech":
1715 case "robot":
1716 SetFeat(1248, 1 + EClass.rnd(5));
1717 break;
1718 case "shojo":
1719 case "younglady":
1720 if (EClass.rnd(EClass.debug.enable ? 2 : 20) == 0)
1721 {
1722 SetFeat(1432);
1723 }
1724 break;
1725 }
1726 InitStats();
1727 body.SetOwner(this);
1729 if (race.EQ.Length != 0 || !source.equip.IsEmpty())
1730 {
1731 TryRestock(onCreate: true);
1732 }
1733 switch (id)
1734 {
1735 case "dodo":
1736 base.idSkin = EClass.rnd(4);
1737 break;
1738 case "putty_snow":
1739 if (EClass.rnd(100) == 0 || EClass.debug.enable)
1740 {
1741 base.idSkin = EClass.rnd(4);
1742 }
1743 break;
1744 case "snail":
1745 base.idSkin = 5;
1746 break;
1747 case "olderyoungersister":
1748 base.idSkin = 1;
1749 break;
1750 case "sister_undead":
1751 case "dog":
1752 case "cat":
1753 base.idSkin = EClass.rnd(sourceCard.tiles.Length);
1754 if (id == "sister_undead" && EClass.rnd(10) == 0)
1755 {
1757 if (row2 != null && (!EClass.player.doneBackers.Contains(row2.id) || EClass.core.config.test.ignoreBackerDestoryFlag))
1758 {
1759 ApplyBacker(row2.id);
1760 }
1761 }
1762 break;
1763 case "baby":
1764 case "ika":
1765 SetFeat(1232, 3);
1766 break;
1767 }
1768 if (HasTag(CTAG.random_color))
1769 {
1770 DyeRandom();
1771 }
1772 SetAI(new NoGoal());
1773 if (!source.faith.IsEmpty())
1774 {
1775 SetFaith(source.faith);
1776 }
1777 else if (EClass.game.activeZone != null && EClass.game.activeZone.id == "foxtown")
1778 {
1780 }
1781 else if (EClass.game.activeZone != null && EClass.game.activeZone.id == "foxtown_nefu")
1782 {
1784 }
1785 else
1786 {
1787 SetFaith(EClass.game.religions.GetRandomReligion(onlyJoinable: true, EClass.rnd(10) == 0));
1788 }
1789 _affinity = 0;
1790 interest = 100;
1793 Refresh();
1794 stamina.value = stamina.max;
1795 mana.value = mana.max;
1796 isCreated = true;
1797 }
1798
1800 {
1802 {
1803 SetLv(base.LV + EClass._zone.DangerLvBoost);
1805 TryRestock(onCreate: true);
1806 }
1807 return this;
1808 }
1809
1810 public void SetFaith(string id)
1811 {
1813 }
1814
1815 public void SetFaith(Religion r)
1816 {
1817 faith = r;
1819 }
1820
1821 public void HealAll()
1822 {
1823 Cure(CureType.HealComplete);
1824 base.hp = MaxHP;
1825 mana.value = mana.max;
1826 stamina.value = stamina.max;
1827 Refresh();
1828 }
1829
1830 public void Refresh(bool calledRecursive = false)
1831 {
1832 if (source == null)
1833 {
1834 Debug.LogError("source is null");
1835 SetSource();
1836 }
1837 if (ride != null && ride.source != null)
1838 {
1839 ride.Refresh(calledRecursive: true);
1840 }
1841 hasTelepathy = false;
1842 isWet = false;
1843 _isLevitating = HasElement(401) || (ride != null && ride._isLevitating);
1845 isWeakToSunlight = HasElement(1251) && !HasElement(431);
1846 base.isHidden = HasElement(415);
1847 isAstralBody = HasElement(1430);
1848 foreach (Condition condition in conditions)
1849 {
1850 condition.OnRefresh();
1851 }
1852 if (isWet)
1853 {
1854 base.isHidden = false;
1855 }
1857 SetDirtySpeed();
1858 if (host != null && !calledRecursive && host.source != null)
1859 {
1860 host.Refresh(calledRecursive: true);
1861 }
1862 }
1863
1864 public bool TryFuse(float chance = 1f)
1865 {
1866 if (chance < EClass.rndf(1f))
1867 {
1868 return false;
1869 }
1870 List<Chara> list = ListFussableCharas(3);
1871 if (list.Count < 7)
1872 {
1873 return false;
1874 }
1875 Say("fuse", this);
1876 string text = "marshmallow_king";
1877 string text2 = "fusion";
1878 switch (id)
1879 {
1880 case "imotoroid":
1881 text = "imotomaton";
1882 text2 = "fusion2";
1883 break;
1884 case "shojo":
1885 text = "shojomaton";
1886 text2 = "fusion2";
1887 break;
1888 case "sister_cat":
1889 text = "sister_catmaton";
1890 text2 = "fusion2";
1891 break;
1892 case "younglady":
1893 text = "ojomaton";
1894 text2 = "fusion2";
1895 break;
1896 }
1897 Chara chara = EClass._zone.SpawnMob(text, pos);
1898 chara.SetHostility(hostility);
1899 list.Shuffle();
1900 int num = 0;
1901 foreach (Chara item in list)
1902 {
1903 if (!text2.IsEmpty())
1904 {
1905 item.Talk(text2);
1906 }
1907 Effect.Get<EffectIRenderer>("throw_fuse").Play(item, item, item.pos, pos);
1908 item.Destroy();
1909 num++;
1910 if (num >= 7)
1911 {
1912 break;
1913 }
1914 }
1915 Destroy();
1916 chara.PlayAnime(AnimeID.FallSky);
1917 chara.pos.PlaySound("fuse");
1918 chara.pos.PlayEffect("vanish");
1919 return true;
1920 }
1921
1922 public bool IsFusable(Chara c)
1923 {
1924 if (c == this)
1925 {
1926 return false;
1927 }
1928 if (c.id != id)
1929 {
1930 return false;
1931 }
1932 if (c.IsPCFactionOrMinion || base.IsPCFactionOrMinion)
1933 {
1934 return false;
1935 }
1936 if (c.c_bossType != BossType.none || base.c_bossType != BossType.none)
1937 {
1938 return false;
1939 }
1941 {
1942 return false;
1943 }
1944 return true;
1945 }
1946
1947 public List<Chara> ListFussableCharas(int radius = 2)
1948 {
1949 return pos.ListCharasInRadius(this, radius, (Chara c) => IsFusable(c));
1950 }
1951
1953 {
1954 if (EClass._zone.IsRegion)
1955 {
1956 return false;
1957 }
1959 {
1960 return false;
1961 }
1962 if (corruption >= 100)
1963 {
1964 return false;
1965 }
1966 if (con != DuplicateCondition.Water && con != DuplicateCondition.Quantum && (HasCondition<ConPoison>() || HasCondition<ConConfuse>() || HasCondition<ConDim>() || HasCondition<ConParalyze>() || HasCondition<ConSleep>() || HasCondition<ConBurning>() || HasCondition<ConFreeze>() || HasCondition<ConMiasma>()))
1967 {
1968 return false;
1969 }
1970 switch (con)
1971 {
1972 case DuplicateCondition.Scarab:
1974 {
1975 return false;
1976 }
1977 break;
1978 case DuplicateCondition.SpiderEgg:
1979 if (pos.cell.light > 0 || pos.IsSunLit)
1980 {
1981 return false;
1982 }
1983 break;
1984 }
1985 return true;
1986 }
1987
1988 public Chara TryDuplicate(DuplicateCondition con = DuplicateCondition.Default, Point dest = null, bool inheritHostility = false)
1989 {
1990 if (dest == null)
1991 {
1992 dest = pos;
1993 }
1994 dest = dest.GetRandomPoint(2, requireLos: false, allowChara: false, allowBlocked: false, 200);
1995 if (dest == null || dest.Equals(pos) || !dest.IsValid || !CanDuplicate(con))
1996 {
1997 Say("split_fail", this);
1998 return null;
1999 }
2000 Chara chara = Duplicate();
2001 EClass._zone.AddCard(chara, dest);
2002 if (inheritHostility)
2003 {
2004 chara.SetHostility(hostility);
2005 }
2006 Say("split", this);
2007 return chara;
2008 }
2009
2011 {
2012 Chara chara = CharaGen.Create(id);
2013 chara.mana.value = mana.value;
2014 chara.stamina.value = stamina.value;
2015 foreach (KeyValuePair<int, Element> item in elements.dict)
2016 {
2017 if (item.Key != 1275)
2018 {
2019 Element orCreateElement = chara.elements.GetOrCreateElement(item.Key);
2020 orCreateElement.vBase = item.Value.ValueWithoutLink - orCreateElement.vSource;
2021 }
2022 }
2023 chara.SetFaith(faith);
2024 chara.bio = IO.DeepCopy(bio);
2025 chara.LV = base.LV;
2026 chara.c_daysWithGod = base.c_daysWithGod;
2027 chara.RefreshFaithElement();
2028 chara.hp = (int)Mathf.Clamp((float)chara.MaxHP * ((float)base.hp / (float)MaxHP) * 0.99f, 0f, chara.MaxHP);
2029 chara.isCopy = true;
2030 chara.isScaled = base.isScaled;
2031 chara.c_altName = base.c_altName;
2032 chara._alias = _alias;
2033 if (pccData != null)
2034 {
2035 chara.pccData = IO.DeepCopy(pccData);
2036 }
2037 if (HaveFur())
2038 {
2039 chara.c_fur = -1;
2040 }
2041 return chara;
2042 }
2043
2044 public int GetBurden(Card t = null, int num = -1)
2045 {
2046 int num2 = (base.ChildrenWeight + ((t != null) ? ((num == -1) ? t.ChildrenAndSelfWeight : (t.SelfWeight * num)) : 0)) * 100 / WeightLimit;
2047 if (num2 < 0)
2048 {
2049 num2 = 1000;
2050 }
2052 {
2053 num2 = 0;
2054 }
2055 int num3 = ((num2 >= 100) ? ((num2 - 100) / 10 + 1) : 0);
2056 if (num3 > 9)
2057 {
2058 num3 = 9;
2059 }
2060 return num3;
2061 }
2062
2063 public void CalcBurden()
2064 {
2065 int num = base.ChildrenWeight * 100 / Mathf.Max(1, WeightLimit);
2066 if (num < 0)
2067 {
2068 num = 1000;
2069 }
2071 {
2072 num = 0;
2073 }
2074 burden.Set(num);
2075 SetDirtySpeed();
2076 }
2077
2078 public void Stumble(int mtp = 100)
2079 {
2080 bool flag = EClass._map.FindThing((Thing t) => t.IsInstalled && t.pos.Equals(EClass.pc.pos) && t.trait is TraitStairsUp) != null;
2081 Say(flag ? "dmgBurdenStairs" : "dmgBurdenFallDown", this);
2082 long num = MaxHP;
2083 if (Evalue(1421) > 0)
2084 {
2085 num = mana.max;
2086 }
2087 long num2 = (num * (base.ChildrenWeight * 100 / WeightLimit) / (flag ? 100 : 200) + 1) * mtp / 100;
2088 if (base.hp <= 0)
2089 {
2090 num2 *= 2;
2091 }
2092 DamageHP(num2, flag ? AttackSource.BurdenStairs : AttackSource.BurdenFallDown);
2093 }
2094
2095 public void SetDirtySpeed()
2096 {
2097 dirtySpeed = true;
2098 if (host != null)
2099 {
2101 }
2102 }
2103
2104 public void RefreshSpeed(Element.BonusInfo info = null)
2105 {
2106 if (currentZone != EClass._zone)
2107 {
2108 dirtySpeed = true;
2109 return;
2110 }
2111 if (ride != null && !ride.IsDeadOrSleeping)
2112 {
2114 _Speed = ride._Speed;
2115 info?.AddText("rideSpeed".lang(_Speed.ToString() ?? ""));
2116 }
2117 else if (host != null)
2118 {
2119 if (host.ride == this)
2120 {
2121 _Speed = Evalue(79);
2122 int a = Evalue(1423);
2123 int num = ((!HasElement(495)) ? 1 : 3);
2124 int value = 100 + (int)_Speed * ((Ridability != Ridability.BadRide) ? 1 : 5) * Mathf.Max(a, 1) / num - base.STR - host.EvalueRiding() * 2 - ((Ridability == Ridability.GoodRide) ? 50 : 0);
2125 _Speed = _Speed * 100 / Mathf.Clamp(value, 100, 1000);
2126 }
2127 else
2128 {
2129 _Speed = (Evalue(79) + host.Evalue(79)) / 2;
2130 }
2131 }
2132 else
2133 {
2134 _Speed = Evalue(79) + Evalue(407) / 2;
2135 }
2136 if (body.GetSlot(37, onlyEmpty: false)?.thing != null && HasElement(1209) && !HasElement(419))
2137 {
2138 _Speed -= 25L;
2139 info?.AddText(-25L, EClass.sources.elements.map[1209].GetName());
2140 }
2141 if (parasite != null)
2142 {
2143 long speed = _Speed;
2144 int num2 = ((!HasElement(495)) ? 1 : 3);
2145 _Speed = _Speed * 100 / Mathf.Clamp(120 + parasite.LV * 2 / num2 - base.STR - Evalue(227) * 2, 100, 1000);
2146 info?.AddText(_Speed - speed, "parasiteSpeed".lang());
2147 }
2148 if (_Speed < elements.ValueWithoutLink(79) / 3)
2149 {
2151 info?.AddText("minSpeed".lang((elements.ValueWithoutLink(79) / 3).ToString() ?? ""));
2152 }
2153 int num3 = 100;
2154 if (EClass._zone.map != null && (EClass._zone.IsUnderwater || (base.Cell.IsTopWaterAndNoSnow && !base.Cell.isFloating)))
2155 {
2156 int num4 = Evalue(200);
2157 int num5 = Evalue(1252);
2158 num3 = 50 + Mathf.Clamp((int)Mathf.Sqrt(num4) * 5 - EClass._zone.DangerLv / 50, (num5 > 0) ? 50 : ((base.IsPowerful || IsMultisize) ? 40 : 0), 50) + Mathf.Clamp((int)Mathf.Sqrt(num4), 0, 25);
2159 if (info != null && num3 != 100)
2160 {
2161 info.AddFix(num3 - 100, EClass.sources.elements.map[200].GetName().ToTitleCase());
2162 }
2163 if (num5 > 0)
2164 {
2165 num3 += num5 * 20;
2166 info?.AddFix(num5 * 20, EClass.sources.elements.map[1252].GetName().ToTitleCase());
2167 }
2168 }
2169 if (IsPCFaction)
2170 {
2171 switch (burden.GetPhase())
2172 {
2173 case 1:
2174 num3 -= 10;
2175 info?.AddFix(-10, burden.GetPhaseStr());
2176 break;
2177 case 2:
2178 num3 -= 20;
2179 info?.AddFix(-20, burden.GetPhaseStr());
2180 break;
2181 case 3:
2182 num3 -= 30;
2183 info?.AddFix(-30, burden.GetPhaseStr());
2184 break;
2185 case 4:
2186 num3 -= (IsPC ? 50 : 100);
2187 info?.AddFix(IsPC ? (-50) : (-100), burden.GetPhaseStr());
2188 break;
2189 }
2190 if (IsPC)
2191 {
2192 switch (stamina.GetPhase())
2193 {
2194 case 1:
2195 num3 -= 10;
2196 info?.AddFix(-10, stamina.GetPhaseStr());
2197 break;
2198 case 0:
2199 num3 -= 20;
2200 info?.AddFix(-20, stamina.GetPhaseStr());
2201 break;
2202 }
2203 switch (sleepiness.GetPhase())
2204 {
2205 case 2:
2206 num3 -= 10;
2207 info?.AddFix(-10, sleepiness.GetPhaseStr());
2208 break;
2209 case 3:
2210 num3 -= 20;
2211 info?.AddFix(-20, sleepiness.GetPhaseStr());
2212 break;
2213 }
2214 switch (hunger.GetPhase())
2215 {
2216 case 3:
2217 case 4:
2218 num3 -= 10;
2219 info?.AddFix(-10, hunger.GetPhaseStr());
2220 break;
2221 case 5:
2222 num3 -= 30;
2223 info?.AddFix(-30, hunger.GetPhaseStr());
2224 break;
2225 }
2226 num3 += EClass.player.lastEmptyAlly * Evalue(1646);
2227 info?.AddFix(EClass.player.lastEmptyAlly * Evalue(1646), EClass.sources.elements.map[1646].GetName());
2228 }
2230 {
2231 num3 += EClass.player.lastEmptyAlly * 10 - 10;
2232 info?.AddFix(EClass.player.lastEmptyAlly * 10 - 10, "exceedParty".lang());
2233 }
2234 }
2235 else if (base.LV >= 1000 && !EClass.game.principal.disableVoidBlessing && !base.IsPCFactionOrMinion)
2236 {
2237 num3 += EClass.curve((base.LV - 900) / 100 * 10, 500, 100);
2238 info?.AddFix(EClass.curve((base.LV - 900) / 100 * 10, 500, 100), "enemySpeedBuff".lang());
2239 }
2240 if (HasCondition<ConGravity>())
2241 {
2242 num3 -= 30;
2243 info?.AddFix(-30, GetCondition<ConGravity>().Name);
2244 }
2245 if (_Speed < 10)
2246 {
2247 _Speed = 10L;
2248 }
2249 _Speed = _Speed * num3 / 100;
2250 if (_Speed < 10)
2251 {
2252 _Speed = 10L;
2253 info?.AddText("minSpeed".lang(10.ToString() ?? ""));
2254 }
2255 dirtySpeed = false;
2256 }
2257
2259 {
2260 int num = base.END;
2261 int num2 = 0;
2262 foreach (Element value in elements.dict.Values)
2263 {
2264 if (value.source.category == "skill")
2265 {
2266 num = ((!IsPC) ? (num + Mathf.Max(value.ValueWithoutLink, 0)) : (num + Mathf.Max(value.vBase, 0)));
2267 }
2268 }
2269 num2 = EClass.curve(num, 30, 10, 60);
2270 if (num2 < 10)
2271 {
2272 num2 = 10;
2273 }
2274 _maxStamina = num2 + 15;
2275 }
2276
2277 public override void ApplyEditorTags(EditorTag tag)
2278 {
2279 switch (tag)
2280 {
2281 case EditorTag.HostilityNeutral:
2282 {
2283 Hostility hostility = (base.c_originalHostility = Hostility.Neutral);
2284 this.hostility = hostility;
2285 break;
2286 }
2287 case EditorTag.HostilityEnemy:
2288 {
2289 Hostility hostility = (base.c_originalHostility = Hostility.Enemy);
2290 this.hostility = hostility;
2291 break;
2292 }
2293 case EditorTag.HostilityFriend:
2294 {
2295 Hostility hostility = (base.c_originalHostility = Hostility.Friend);
2296 this.hostility = hostility;
2297 break;
2298 }
2299 case EditorTag.Male:
2300 bio.SetGender(2);
2301 base.c_idPortrait = Portrait.GetRandomPortrait(2, GetIdPortraitCat());
2302 break;
2303 case EditorTag.Female:
2304 bio.SetGender(1);
2305 base.c_idPortrait = Portrait.GetRandomPortrait(1, GetIdPortraitCat());
2306 break;
2307 case EditorTag.baby:
2308 SetFeat(1232);
2309 break;
2310 }
2311 base.ApplyEditorTags(tag);
2312 }
2313
2314 public override void SetSource()
2315 {
2316 source = EClass.sources.charas.map.TryGetValue(id);
2317 if (source == null)
2318 {
2319 Debug.LogWarning("Chara " + id + " not found");
2320 id = "chicken";
2321 source = EClass.sources.charas.map[id];
2322 }
2323 path.walker = this;
2324 }
2325
2326 public void SetMainElement(string id, int v = 0, bool elemental = false)
2327 {
2328 if (!id.StartsWith("ele"))
2329 {
2330 id = "ele" + id;
2331 }
2332 SetMainElement(EClass.sources.elements.alias[id].id, v, elemental);
2333 }
2334
2335 public void SetMainElement(int id, int v = 0, bool elemental = false)
2336 {
2337 if (base.c_idMainElement != 0)
2338 {
2339 SetElements(base.c_idMainElement, remove: true);
2340 base.c_idMainElement = 0;
2341 }
2342 if (id != 0)
2343 {
2344 _ = EClass.sources.elements.map[id];
2345 SetElements(id, remove: false);
2346 base.c_idMainElement = id;
2347 if (elemental)
2348 {
2349 base.isElemental = true;
2350 _colorInt = 0;
2351 Color colorSprite = EClass.setting.elements[MainElement.source.alias].colorSprite;
2352 base.c_lightColor = (byte)Mathf.Clamp(colorSprite.r * 3f, 1f, 31f) * 1024 + (byte)Mathf.Clamp(colorSprite.g * 3f, 1f, 31f) * 32 + (byte)Mathf.Clamp(colorSprite.b * 3f, 1f, 31f);
2353 }
2354 _ability = null;
2355 }
2356 void SetElements(int idEle, bool remove)
2357 {
2358 elements.SetBase(idEle, (!remove) ? ((v == 0) ? 10 : v) : 0);
2359 elements.ModBase(EClass.sources.elements.alias[EClass.sources.elements.map[idEle].aliasRef].id, remove ? (-20) : 20);
2360 switch (idEle)
2361 {
2362 case 910:
2363 elements.ModBase(951, remove ? 10 : (-10));
2364 break;
2365 case 911:
2366 elements.ModBase(950, remove ? 10 : (-10));
2367 break;
2368 case 912:
2369 elements.ModBase(953, remove ? 10 : (-10));
2370 break;
2371 case 913:
2372 elements.ModBase(952, remove ? 10 : (-10));
2373 break;
2374 case 916:
2375 elements.ModBase(960, remove ? 10 : (-10));
2376 break;
2377 case 919:
2378 elements.ModBase(956, remove ? 10 : (-10));
2379 break;
2380 case 925:
2381 elements.ModBase(962, remove ? 10 : (-10));
2382 break;
2383 case 922:
2384 elements.ModBase(965, remove ? 10 : (-10));
2385 break;
2386 case 921:
2387 elements.ModBase(971, remove ? 10 : (-10));
2388 break;
2389 case 926:
2390 elements.ModBase(961, remove ? 10 : (-10));
2391 break;
2392 case 914:
2393 case 915:
2394 case 917:
2395 case 918:
2396 case 920:
2397 case 923:
2398 case 924:
2399 break;
2400 }
2401 }
2402 }
2403
2404 public void ApplyJob(bool remove = false)
2405 {
2406 elements.ApplyElementMap(base.uid, SourceValueType.Chara, job.elementMap, base.DefaultLV, remove, applyFeat: true);
2407 if (IsPCC)
2408 {
2409 EClass.game.uniforms.Apply(pccData, job.id, base.IsMale, canUseOtherGender: true);
2410 }
2411 }
2412
2413 public void ChangeJob(string idNew)
2414 {
2415 ApplyJob(remove: true);
2416 base.c_idJob = idNew;
2417 _job = null;
2418 ApplyJob();
2419 if (IsPCC)
2420 {
2421 PCC.Get(pccData).Build();
2422 }
2423 }
2424
2425 private int ParseBodySlot(string s)
2426 {
2427 return s switch
2428 {
2429 "é ­" => 30,
2430 "首" => 31,
2431 "体" => 32,
2432 "背" => 33,
2433 "手" => 35,
2434 "指" => 36,
2435 "è…•" => 34,
2436 "è…°" => 37,
2437 "è¶³" => 39,
2438 _ => -1,
2439 };
2440 }
2441
2442 public void AddRandomBodyPart(bool msg = false)
2443 {
2444 int ele = new int[9] { 30, 31, 33, 35, 35, 36, 34, 37, 39 }.RandomItem();
2445 body.AddBodyPart(ele);
2446 if (msg)
2447 {
2448 Say("gain_bodyparts", this, Element.Get(ele).GetName().ToLower());
2449 PlaySound("offering");
2450 }
2451 }
2452
2453 public void RemoveLastBodyPart(bool msg = false)
2454 {
2455 if (body.slots.Count != 0)
2456 {
2457 BodySlot bodySlot = body.slots.LastItem();
2458 body.RemoveBodyPartAt(body.slots.Count - 1);
2459 if (msg)
2460 {
2461 Say("lose_bodyparts", this, Element.Get(bodySlot.elementId).GetName().ToLower());
2462 PlaySound("offering");
2463 }
2464 }
2465 }
2466
2467 public void ResetBody()
2468 {
2469 for (int num = body.slots.Count - 1; num >= 0; num--)
2470 {
2471 BodySlot bodySlot = body.slots[num];
2472 if (bodySlot.elementId == 45 || bodySlot.elementId == 40)
2473 {
2474 return;
2475 }
2476 body.RemoveBodyPart(num);
2477 }
2478 string[] array = race.figure.Split('|');
2479 foreach (string s in array)
2480 {
2481 int num2 = ParseBodySlot(s);
2482 if (num2 != -1)
2483 {
2484 body.AddBodyPart(num2);
2485 }
2486 }
2488 }
2489
2490 public void ApplyRace(bool remove = false)
2491 {
2492 string[] array = race.figure.Split('|');
2493 foreach (string s in array)
2494 {
2495 int num = ParseBodySlot(s);
2496 if (num != -1)
2497 {
2498 if (remove)
2499 {
2500 body.RemoveBodyPart(num);
2501 }
2502 else
2503 {
2504 body.AddBodyPart(num);
2505 }
2506 }
2507 }
2509 elements.ApplyElementMap(base.uid, SourceValueType.Chara, race.elementMap, base.DefaultLV, remove, applyFeat: true);
2510 if (remove)
2511 {
2512 if (HasElement(1423))
2513 {
2514 SetFeat(1423, 0);
2515 }
2516 return;
2517 }
2518 bool flag = id == "chara" || id == "player";
2519 if (race.id == "bike" && id != "bike_cub")
2520 {
2521 SetFeat(1423, flag ? 10 : (1 + EClass.rnd(10)));
2522 }
2523 if (id == "moa")
2524 {
2525 SetFeat(1423, flag ? 7 : (1 + EClass.rnd(7)));
2526 }
2527 if (race.id == "horse" && EClass.rnd(5) == 0)
2528 {
2529 SetFeat(1423, flag ? 5 : (1 + EClass.rnd(5)));
2530 }
2531 }
2532
2533 public void ChangeRace(string idNew)
2534 {
2535 ApplyRace(remove: true);
2536 base.c_idRace = idNew;
2537 _race = null;
2538 ApplyRace();
2539 ChangeMaterial(source.defMat.IsEmpty(race.material));
2540 }
2541
2542 public void MakePartyMemeber()
2543 {
2544 _MakeAlly();
2545 EClass.pc.party.AddMemeber(this);
2546 }
2547
2548 public void MakeAlly(bool msg = true)
2549 {
2550 if (IsLocalChara && !base.IsUnique)
2551 {
2552 Debug.Log("Creating Replacement NPC for:" + this);
2554 }
2555 _MakeAlly();
2556 if (msg)
2557 {
2558 EClass.pc.Say("hire", this);
2559 EClass.Sound.Play("good");
2560 }
2561 EClass.pc.party.AddMemeber(this);
2562 if (EClass._zone.IsTown)
2563 {
2565 }
2566 }
2567
2568 public void _MakeAlly()
2569 {
2570 if (EClass.pc.homeBranch != null)
2571 {
2573 }
2574 else
2575 {
2576 SetGlobal();
2578 }
2579 Hostility hostility = (base.c_originalHostility = Hostility.Ally);
2580 this.hostility = hostility;
2581 orgPos = null;
2582 base.c_summonDuration = 0;
2583 base.isSummon = false;
2584 UnmakeMinion();
2585 SetInt(32);
2586 Refresh();
2587 }
2588
2589 public bool CanBeTempAlly(Chara c)
2590 {
2591 if (IsPCFaction || IsGlobal || IsMinion || IsMultisize || EClass._zone.CountMinions(c) > c.MaxSummon || base.rarity >= Rarity.Legendary)
2592 {
2593 return false;
2594 }
2595 if (HasElement(1222))
2596 {
2597 return false;
2598 }
2599 return true;
2600 }
2601
2602 public void Banish(Chara owner)
2603 {
2604 owner?.Say("summon_vanish", this);
2605 pos.PlayEffect("vanish");
2606 pos.PlaySound("vanish");
2607 pos.PlayEffect("teleport");
2608 Destroy();
2609 }
2610
2611 public void MakeMinion(Chara _master, MinionType type = MinionType.Default)
2612 {
2613 UnmakeMinion();
2614 Hostility hostility = (base.c_originalHostility = (_master.IsPCFaction ? Hostility.Ally : _master.hostility));
2615 this.hostility = hostility;
2616 base.c_uidMaster = _master.uid;
2617 base.c_minionType = type;
2618 master = _master;
2619 Refresh();
2620 }
2621
2622 public void UnmakeMinion()
2623 {
2624 base.c_uidMaster = 0;
2625 master = null;
2626 enemy = null;
2627 foreach (Chara chara in EClass._map.charas)
2628 {
2629 if (chara.enemy == this)
2630 {
2631 chara.SetEnemy();
2632 chara.ai.Cancel();
2633 }
2634 }
2635 ai.Cancel();
2636 Refresh();
2637 }
2638
2639 public void BanishAllMinions()
2640 {
2641 List<Chara> list = new List<Chara>();
2642 foreach (Chara chara in EClass._map.charas)
2643 {
2644 if (chara.IsMinion && chara.master == this)
2645 {
2646 list.Add(chara);
2647 }
2648 }
2649 foreach (Chara item in list)
2650 {
2651 item.Banish(this);
2652 }
2653 }
2654
2655 public bool HasMinion(string id)
2656 {
2657 foreach (Chara chara in EClass._map.charas)
2658 {
2659 if (chara.c_uidMaster == base.uid)
2660 {
2661 return true;
2662 }
2663 }
2664 return false;
2665 }
2666
2667 public void SetSummon(int duration, bool dropCorpse = false)
2668 {
2669 base.c_summonDuration = duration;
2670 base.isSummon = true;
2671 if (dropCorpse)
2672 {
2673 SetBool(136, enable: true);
2674 }
2675 }
2676
2678 {
2679 if (IsMinion)
2680 {
2681 master = EClass._map.FindChara(base.c_uidMaster);
2682 }
2683 return master;
2684 }
2685
2686 public bool IsEscorted()
2687 {
2688 if (!IsPCPartyMinion)
2689 {
2690 return false;
2691 }
2692 foreach (Quest item in EClass.game.quests.list)
2693 {
2694 if (item is QuestEscort questEscort && questEscort.uidChara == base.uid)
2695 {
2696 return true;
2697 }
2698 }
2699 return false;
2700 }
2701
2702 public bool CanDestroyPath()
2703 {
2704 if (!IsMultisize)
2705 {
2706 if (base.rarity >= Rarity.Superior && !base.IsPCFactionOrMinion && ai is GoalCombat)
2707 {
2708 return !EClass._zone.IsPCFaction;
2709 }
2710 return false;
2711 }
2712 return true;
2713 }
2714
2715 public bool CanMoveTo(Point p, bool allowDestroyPath = true)
2716 {
2717 if (!p.IsValid)
2718 {
2719 return false;
2720 }
2721 int num = ((p.z >= pos.z) ? ((p.x > pos.x) ? 1 : ((p.z > pos.z) ? 2 : 3)) : 0);
2722 if (allowDestroyPath && CanDestroyPath())
2723 {
2724 if (!p.IsInBounds)
2725 {
2726 return false;
2727 }
2728 }
2729 else
2730 {
2732 {
2733 return false;
2734 }
2735 if (p.x != pos.x && p.z != pos.z)
2736 {
2737 Cell[,] cells = EClass._map.cells;
2738 int x = p.x;
2739 int z = pos.z;
2740 int num2 = ((z >= pos.z) ? ((x > pos.x) ? 1 : ((z > pos.z) ? 2 : 3)) : 0);
2741 if (cells[pos.x, pos.z].weights[num2] == 0)
2742 {
2743 return false;
2744 }
2745 if (cells[x, z].blocked && (!IsAstralBody || cells[x, z].IsSky || EClass._zone.IsRegion))
2746 {
2747 return false;
2748 }
2749 num2 = ((z >= p.z) ? ((x > p.x) ? 1 : ((z > p.z) ? 2 : 3)) : 0);
2750 if (cells[p.x, p.z].weights[num2] == 0)
2751 {
2752 return false;
2753 }
2754 x = pos.x;
2755 z = p.z;
2756 num2 = ((z >= pos.z) ? ((x > pos.x) ? 1 : ((z > pos.z) ? 2 : 3)) : 0);
2757 if (cells[pos.x, pos.z].weights[num2] == 0)
2758 {
2759 return false;
2760 }
2761 if (cells[x, z].blocked && (!IsAstralBody || cells[x, z].IsSky || EClass._zone.IsRegion))
2762 {
2763 return false;
2764 }
2765 num2 = ((z >= p.z) ? ((x > p.x) ? 1 : ((z > p.z) ? 2 : 3)) : 0);
2766 if (cells[p.x, p.z].weights[num2] == 0)
2767 {
2768 return false;
2769 }
2770 }
2771 }
2772 if (IsPC)
2773 {
2774 if (IsEnemyOnPath(p))
2775 {
2776 return false;
2777 }
2778 }
2779 else if (p.HasChara && !IsMultisize && !CanReplace(p.FirstChara))
2780 {
2781 return false;
2782 }
2783 return true;
2784 }
2785
2786 public bool IsEnemyOnPath(Point p, bool cancelAI = true)
2787 {
2788 if (!currentZone.IsRegion && p.IsValid)
2789 {
2790 CellDetail detail = p.detail;
2791 if (detail != null && detail.charas.Count > 0)
2792 {
2793 foreach (Chara chara in p.detail.charas)
2794 {
2795 if (chara.mimicry == null && (chara.IsHostile(this) || chara.IsHostile() || !chara.trait.CanBePushed))
2796 {
2797 if (cancelAI && EClass.pc.ai is GoalManualMove)
2798 {
2799 EClass.pc.ai.Cancel();
2800 }
2801 return true;
2802 }
2803 }
2804 }
2805 }
2806 return false;
2807 }
2808
2809 public bool CanInteractTo(Card c)
2810 {
2811 return CanInteractTo(c.pos);
2812 }
2813
2814 public bool CanInteractTo(Point p)
2815 {
2816 if (!p.IsValid)
2817 {
2818 return false;
2819 }
2820 if (EClass._map.cells[p.x, p.z].blocked)
2821 {
2822 return true;
2823 }
2824 if (!IsMultisize)
2825 {
2826 int num = ((p.z >= pos.z) ? ((p.x > pos.x) ? 1 : ((p.z > pos.z) ? 2 : 3)) : 0);
2827 if (EClass._map.cells[pos.x, pos.z].weights[num] == 0)
2828 {
2829 return false;
2830 }
2831 if (p.x != pos.x && p.z != pos.z)
2832 {
2833 Cell[,] cells = EClass._map.cells;
2834 int x = p.x;
2835 int z = pos.z;
2836 int num2 = ((z >= pos.z) ? ((x > pos.x) ? 1 : ((z > pos.z) ? 2 : 3)) : 0);
2837 if (cells[pos.x, pos.z].weights[num2] == 0)
2838 {
2839 return false;
2840 }
2841 num2 = ((z >= p.z) ? ((x > p.x) ? 1 : ((z > p.z) ? 2 : 3)) : 0);
2842 if (cells[p.x, p.z].weights[num2] == 0)
2843 {
2844 return false;
2845 }
2846 x = pos.x;
2847 z = p.z;
2848 num2 = ((z >= pos.z) ? ((x > pos.x) ? 1 : ((z > pos.z) ? 2 : 3)) : 0);
2849 if (cells[pos.x, pos.z].weights[num2] == 0)
2850 {
2851 return false;
2852 }
2853 num2 = ((z >= p.z) ? ((x > p.x) ? 1 : ((z > p.z) ? 2 : 3)) : 0);
2854 if (cells[p.x, p.z].weights[num2] == 0)
2855 {
2856 return false;
2857 }
2858 }
2859 }
2860 return true;
2861 }
2862
2863 public Point GetFirstStep(Point newPoint, PathManager.MoveType moveType = PathManager.MoveType.Default)
2864 {
2865 return PathManager.Instance.GetFirstStep(pos, newPoint, this, IsPC ? 40 : 10, (!IsMultisize) ? moveType : PathManager.MoveType.Default);
2866 }
2867
2868 public bool MoveRandom()
2869 {
2870 Point randomNeighbor = pos.GetRandomNeighbor();
2871 if (!randomNeighbor.Equals(pos) && !randomNeighbor.HasChara && HasAccess(randomNeighbor))
2872 {
2873 if ((race.tag.Contains("water") || source.tag.Contains("water")) && pos.cell.IsTopWaterAndNoSnow && !randomNeighbor.IsDeepWater)
2874 {
2875 return false;
2876 }
2877 return TryMove(randomNeighbor) == MoveResult.Success;
2878 }
2879 return false;
2880 }
2881
2883 {
2884 List<Point> list = new List<Point>();
2885 pos.ForeachNeighbor(delegate(Point p)
2886 {
2887 list.Add(p.Copy());
2888 });
2889 list.Shuffle();
2890 foreach (Point item in list)
2891 {
2892 if (!item.Equals(pos) && !item.HasChara && TryMove(item) == MoveResult.Success)
2893 {
2894 return true;
2895 }
2896 }
2897 return false;
2898 }
2899
2900 public void MoveByForce(Point newPoint, Card c = null, bool checkWall = false)
2901 {
2902 if (!newPoint.sourceBlock.tileType.IsBlockPass && (!checkWall || (Dist(newPoint) <= 1 && CanMoveTo(newPoint, allowDestroyPath: false))) && _Move(newPoint, MoveType.Force) == MoveResult.Success && ai.Current.CancelWhenMoved)
2903 {
2904 ai.Current.TryCancel(c);
2905 }
2906 }
2907
2909 {
2910 if (p.Equals(pos))
2911 {
2912 return MoveResult.Success;
2913 }
2915 {
2916 return MoveResult.Fail;
2917 }
2918 bool flag = true;
2919 Point point = null;
2920 _sharedPos.Set(p);
2921 if (CanDestroyPath())
2922 {
2924 {
2925 return MoveResult.Success;
2926 }
2927 Debug.Log(CanMoveTo(pos));
2929 }
2930 int num = pos.Distance(p);
2931 PathProgress pathProgress = PathManager.Instance.RequestPathImmediate(pos, p, this, PathManager.MoveType.Default, num + 4, 1);
2932 if (pathProgress.HasPath && pathProgress.nodes.Count < num + 4)
2933 {
2934 PathFinderNode pathFinderNode = pathProgress.nodes[pathProgress.nodes.Count - 1];
2935 if (TryMove(new Point(pathFinderNode.X, pathFinderNode.Z)) == MoveResult.Success)
2936 {
2937 return MoveResult.Success;
2938 }
2939 }
2940 pathProgress = PathManager.Instance.RequestPathImmediate(pos, p, this, PathManager.MoveType.Combat, num + 4, 1);
2941 if (pathProgress.HasPath && pathProgress.nodes.Count < num + 4)
2942 {
2943 PathFinderNode pathFinderNode2 = pathProgress.nodes[pathProgress.nodes.Count - 1];
2944 if (TryMove(new Point(pathFinderNode2.X, pathFinderNode2.Z)) == MoveResult.Success)
2945 {
2946 return MoveResult.Success;
2947 }
2948 }
2949 pathProgress = PathManager.Instance.RequestPathImmediate(pos, p, this, PathManager.MoveType.Default, num + 25, 2);
2950 if (pathProgress.HasPath && pathProgress.nodes.Count < num + 25)
2951 {
2952 PathFinderNode pathFinderNode3 = pathProgress.nodes[pathProgress.nodes.Count - 1];
2953 if (TryMove(new Point(pathFinderNode3.X, pathFinderNode3.Z)) == MoveResult.Success)
2954 {
2955 return MoveResult.Success;
2956 }
2957 }
2958 pathProgress = PathManager.Instance.RequestPathImmediate(pos, p, this, PathManager.MoveType.Combat, num + 25, 2);
2959 if (pathProgress.HasPath && pathProgress.nodes.Count < num + 25)
2960 {
2961 PathFinderNode pathFinderNode4 = pathProgress.nodes[pathProgress.nodes.Count - 1];
2962 if (TryMove(new Point(pathFinderNode4.X, pathFinderNode4.Z)) == MoveResult.Success)
2963 {
2964 return MoveResult.Success;
2965 }
2966 }
2967 return MoveResult.Fail;
2968 }
2969
2970 public override MoveResult TryMove(Point newPoint, bool allowDestroyPath = true)
2971 {
2972 foreach (Condition condition in conditions)
2973 {
2974 if (!condition.TryMove(newPoint))
2975 {
2976 return MoveResult.Fail;
2977 }
2978 }
2979 if (base.isRestrained)
2980 {
2981 if (!IsPC)
2982 {
2983 return MoveResult.Fail;
2984 }
2985 base.isRestrained = false;
2986 }
2987 if (!CanMoveTo(newPoint, allowDestroyPath))
2988 {
2989 return MoveResult.Fail;
2990 }
2991 return _Move(newPoint);
2992 }
2993
2994 public override MoveResult _Move(Point newPoint, MoveType type = MoveType.Walk)
2995 {
2996 if (isDead)
2997 {
2998 return MoveResult.Fail;
2999 }
3000 if (IsPC)
3001 {
3002 float num = EClass.setting.defaultActPace;
3003 switch (burden.GetPhase())
3004 {
3005 case 3:
3006 num *= 1.5f;
3007 break;
3008 case 4:
3009 num *= 2f;
3010 break;
3011 }
3013 {
3014 int num2 = 30;
3015 if (!EClass.pc.HasElement(408))
3016 {
3018 {
3019 case Weather.Condition.Rain:
3020 num2 += 5;
3021 break;
3022 case Weather.Condition.RainHeavy:
3023 num2 += 10;
3024 num *= 1.5f;
3025 break;
3026 case Weather.Condition.Snow:
3027 num2 += 10;
3028 break;
3029 case Weather.Condition.SnowHeavy:
3030 num2 += 15;
3031 num *= 1.5f;
3032 break;
3033 }
3034 }
3035 if (newPoint.matFloor.id == 48)
3036 {
3037 num2 += 20;
3038 num *= 1.8f;
3039 }
3040 num2 = num2 * 100 / (100 + EClass.sqrt(EvalueMax(240, -20) * 10) + EvalueMax(407, -5) * 5);
3041 EClass.world.date.AdvanceMin(num2 * 6);
3042 EClass.player.lastZonePos = null;
3044 int num3 = base.hp;
3045 for (int i = 0; i < num2 * 4; i++)
3046 {
3047 EClass.pc.party.members.ForeachReverse(delegate(Chara m)
3048 {
3049 if (!m.isDead)
3050 {
3051 m.TickConditions();
3052 }
3053 });
3054 if (base.hp < MaxHP / 5 && base.hp < num3 && !EClass.player.regionMoveWarned)
3055 {
3056 EClass.player.regionMoveWarned = true;
3057 Msg.Say("regionAbortMove");
3058 EInput.Consume(consumeAxis: true);
3059 SetAI(new NoGoal());
3060 return MoveResult.Fail;
3061 }
3062 }
3063 if (newPoint.cell.CanSuffocate())
3064 {
3065 bool flag = HasElement(1252);
3066 if (!flag)
3067 {
3068 AddCondition<ConSuffocation>((Evalue(200) != 0) ? (2000 / (100 + EvalueMax(200, -5) * 10)) : 30, force: true);
3069 }
3070 int num4 = GetCondition<ConSuffocation>()?.GetPhase() ?? 0;
3071 if (num4 >= 2)
3072 {
3073 DamageHP(EClass.rndHalf(10 + MaxHP / 5), AttackSource.Condition);
3074 }
3075 if (!isDead && !HasElement(429))
3076 {
3077 ModExp(200, ((!flag) ? 1 : 10) + num4 * 12);
3078 }
3079 }
3080 EClass.player.regionMoveWarned = false;
3081 if (isDead)
3082 {
3083 return MoveResult.Fail;
3084 }
3085 }
3086 if (num > EClass.setting.defaultActPace * 3f)
3087 {
3088 num = EClass.setting.defaultActPace * 3f;
3089 }
3090 actTime = num;
3091 }
3092 if (IsPCFaction && EClass.rnd(5) == 0 && newPoint.cell.CanSuffocate())
3093 {
3094 int num5 = Mathf.Min(5 + EClass._zone.DangerLv / 10, 200);
3095 ModExp(200, EClass._zone.IsRegion ? 50 : num5);
3096 if (ride != null)
3097 {
3098 ride.ModExp(200, EClass._zone.IsRegion ? 50 : num5);
3099 }
3100 if (parasite != null)
3101 {
3102 parasite.ModExp(200, EClass._zone.IsRegion ? 50 : num5);
3103 }
3104 }
3105 Chara chara = ((ride == null) ? this : ride);
3106 if (!EClass._zone.IsRegion || chara.IsPC)
3107 {
3108 bool flag2 = (chara.isConfused && EClass.rnd(2) == 0) || (chara.isDrunk && EClass.rnd(IsIdle ? 2 : 8) == 0 && !chara.HasElement(1215));
3109 if (host != null && host.ride == this && ((host.isConfused && EClass.rnd(2) == 0) || (host.isDrunk && EClass.rnd(IsIdle ? 2 : 8) == 0 && !host.HasElement(1215))))
3110 {
3111 flag2 = true;
3112 }
3113 if (flag2 && !HasElement(493) && newPoint.Distance(pos) <= 1)
3114 {
3115 Point randomNeighbor = pos.GetRandomNeighbor();
3116 if (CanMoveTo(randomNeighbor, allowDestroyPath: false))
3117 {
3118 newPoint = randomNeighbor;
3119 if (isDrunk)
3120 {
3121 Talk("drunk");
3122 }
3123 }
3124 }
3125 }
3126 if (newPoint.x != pos.x || newPoint.z != pos.z)
3127 {
3128 LookAt(newPoint);
3129 }
3130 CellEffect effect = base.Cell.effect;
3131 if (effect != null && effect.id == 7)
3132 {
3133 CellEffect effect2 = base.Cell.effect;
3134 if (race.height < 500 && !race.tag.Contains("webfree") && !HasElement(493) && EClass.rnd(effect2.power + 25) > EClass.rnd(base.STR + base.DEX + 1))
3135 {
3136 Say("abWeb_caught", this);
3137 PlaySound("web");
3138 effect2.power = effect2.power * 3 / 4;
3139 renderer.PlayAnime(AnimeID.Shiver);
3140 return MoveResult.Fail;
3141 }
3142 Say("abWeb_pass", this);
3143 EClass._map.SetEffect(base.Cell.x, base.Cell.z);
3144 }
3145 if (IsPC)
3146 {
3147 EClass.player.renderExtraTime = 0f;
3148 if (EClass._zone.IsRegion)
3149 {
3151 }
3152 else if ((newPoint.x > pos.x && newPoint.z > pos.z) || (newPoint.x < pos.x && newPoint.z < pos.z))
3153 {
3154 EClass.player.renderExtraTime = actTime * EClass.setting.render.anime.diagonalSpeed;
3155 }
3156 }
3157 if (newPoint.HasChara)
3158 {
3159 foreach (Chara item in newPoint.ListCharas())
3160 {
3161 if (item.mimicry != null && item.IsHostile(this))
3162 {
3163 if (item.mimicry.ShouldRevealOnPush)
3164 {
3165 item.mimicry.Reveal(this, surprise: true);
3166 }
3167 return MoveResult.Event;
3168 }
3169 }
3170 }
3171 if (newPoint.cell.hasDoor)
3172 {
3173 foreach (Thing thing in pos.Things)
3174 {
3175 if (thing.trait is TraitDoor traitDoor && traitDoor.owner.c_lockLv > 0)
3176 {
3177 if (base.INT < 10)
3178 {
3179 return MoveResult.Fail;
3180 }
3181 traitDoor.TryOpenLock(this);
3182 return MoveResult.Door;
3183 }
3184 }
3185 }
3186 Cell cell = newPoint.cell;
3187 Cell cell2 = pos.cell;
3188 bool flag3 = cell.HasLiquid && !IsLevitating;
3189 bool hasBridge = cell.HasBridge;
3190 bool hasRamp = cell.HasRamp;
3191 bool flag4 = EClass._zone.IsSnowCovered && !cell.HasRoof && !cell.isClearSnow;
3192 TileRow tileRow = (hasRamp ? ((TileRow)cell.sourceBlock) : ((TileRow)(hasBridge ? cell.sourceBridge : cell.sourceFloor)));
3193 SourceMaterial.Row row = (hasRamp ? cell.matBlock : (hasBridge ? cell.matBridge : cell.matFloor));
3194 bool flag5 = cell.IsTopWater && !cell.isFloating;
3195 if (!EClass._zone.IsRegion)
3196 {
3197 if (cell.hasDoorBoat)
3198 {
3199 tileRow = FLOOR.sourceWood;
3200 row = MATERIAL.sourceOak;
3201 flag5 = false;
3202 }
3203 else if (flag4 && !tileRow.ignoreSnow)
3204 {
3205 if (tileRow.tileType.IsWater)
3206 {
3207 tileRow = FLOOR.sourceIce;
3208 row = MATERIAL.sourceIce;
3209 }
3210 else
3211 {
3212 tileRow = FLOOR.sourceSnow;
3213 row = MATERIAL.sourceSnow;
3214 }
3215 flag5 = false;
3216 }
3217 }
3218 if ((pos.sourceFloor.isBeach || cell2.IsSnowTile) && !pos.HasObj)
3219 {
3220 EClass._map.SetFoormark(pos, 1, (int)Util.GetAngle(pos.x - newPoint.x, pos.z - newPoint.z), cell2.IsSnowTile ? 312 : 304);
3221 }
3222 if (isSynced)
3223 {
3224 string text = ((flag3 || flag5) ? "water" : tileRow.soundFoot.IsEmpty(row.soundFoot.IsEmpty("default")));
3225 if (cell.obj != 0 && cell.sourceObj.tileType.IsPlayFootSound && !cell.matObj.soundFoot.IsEmpty())
3226 {
3227 text = cell.matObj.soundFoot;
3228 }
3229 if (IsPC)
3230 {
3231 foreach (Thing thing2 in newPoint.Things)
3232 {
3233 if (thing2.IsInstalled && (thing2.trait.IsChangeFloorHeight || thing2.Pref.Surface))
3234 {
3235 text = thing2.material.soundFoot;
3236 }
3237 }
3238 }
3239 if (!text.IsEmpty())
3240 {
3241 SoundManager.altLastData = IsPC;
3242 PlaySound("Footstep/" + text, IsPC ? 1f : 0.9f);
3243 }
3244 if (!flag5)
3245 {
3247 PCOrbit pcOrbit = EClass.screen.pcOrbit;
3248 bool flag6 = scene.actionMode.gameSpeed > 1f;
3249 scene.psFoot.transform.position = renderer.position + pcOrbit.footPos;
3250 scene.psFoot.startColor = row.matColor;
3251 scene.psFoot.Emit(pcOrbit.emitFoot * ((!flag6) ? 1 : 2));
3252 if (flag6 && IsPC)
3253 {
3254 scene.psSmoke.transform.position = renderer.position + pcOrbit.smokePos;
3255 scene.psSmoke.Emit(pcOrbit.emitSmoke);
3256 }
3257 }
3258 if (flag3 || flag5)
3259 {
3260 Effect.Get("ripple").Play(newPoint);
3261 }
3262 }
3263 lastPos.Set(pos);
3264 if (type != MoveType.Force)
3265 {
3266 if (newPoint.HasChara && ai.Current.PushChara)
3267 {
3268 TryPush(newPoint);
3269 }
3270 if (newPoint.HasChara && newPoint.Charas.Count == 1)
3271 {
3272 Chara chara2 = newPoint.Charas[0];
3273 if (CanReplace(chara2))
3274 {
3275 chara2.MoveByForce(lastPos, this);
3276 if (chara.IsPC)
3277 {
3278 Say("replace_pc", chara, chara2);
3279 }
3280 }
3281 }
3282 }
3283 if (cell.hasDoor)
3284 {
3285 foreach (Thing thing3 in newPoint.Things)
3286 {
3287 if (thing3.trait is TraitDoor traitDoor2)
3288 {
3289 traitDoor2.TryOpen(this);
3290 }
3291 }
3292 }
3293 EClass._zone.map.MoveCard(newPoint, this);
3294 SyncRide();
3296 {
3297 foreach (Chara member in EClass.pc.party.members)
3298 {
3299 if (member.isLeashed && !member.IsPC && member.host == null && !member.IsDisabled && !member.HasCondition<ConEntangle>() && !member.IsInCombat && member.Dist(EClass.pc) > 1)
3300 {
3301 member.TryMoveTowards(EClass.pc.pos);
3302 }
3303 }
3304 }
3306 {
3308 }
3309 if (IsPC)
3310 {
3311 PlaySound("Footstep/Extra/pcfootstep");
3312 if (pos.HasThing)
3313 {
3314 foreach (Card item2 in pos.ListCards())
3315 {
3316 if (!item2.isThing || item2.placeState != PlaceState.roaming || item2.ignoreAutoPick)
3317 {
3318 continue;
3319 }
3321 {
3323 ContainerFlag containerFlag = item2.category.GetRoot().id.ToEnum<ContainerFlag>();
3324 if (containerFlag == ContainerFlag.none)
3325 {
3326 containerFlag = ContainerFlag.other;
3327 }
3328 if ((dataPick.noRotten && item2.IsDecayed) || (dataPick.onlyRottable && item2.trait.Decay == 0))
3329 {
3330 continue;
3331 }
3332 if (dataPick.userFilter)
3333 {
3334 switch (dataPick.IsFilterPass(item2.GetName(NameStyle.Full, 1)))
3335 {
3336 case Window.SaveData.FilterResult.PassWithoutFurtherTest:
3337 Pick(item2.Thing);
3338 continue;
3339 case Window.SaveData.FilterResult.Block:
3340 continue;
3341 }
3342 }
3343 if (dataPick.advDistribution)
3344 {
3345 foreach (int cat in dataPick.cats)
3346 {
3347 if (item2.category.uid == cat)
3348 {
3349 Pick(item2.Thing);
3350 }
3351 }
3352 }
3353 else if (!dataPick.flag.HasFlag(containerFlag))
3354 {
3355 Pick(item2.Thing);
3356 }
3357 }
3358 else
3359 {
3360 Pick(item2.Thing);
3361 }
3362 }
3363 }
3364 if (EClass._zone.IsRegion)
3365 {
3367 if (cell3?.zone != null && !cell3.zone.HiddenInRegionMap && (!(cell3.zone is Zone_Field) || cell3.zone.children.Count > 0 || cell3.zone.IsPCFaction))
3368 {
3369 Msg.Say((!cell3.zone.source.GetText("textFlavor").IsEmpty()) ? cell3.zone.source.GetText("textFlavor") : (cell3.zone.ShowDangerLv ? "seeZoneDanger" : "seeZone"), cell3.zone.Name, cell3.zone.DangerLv.ToString() ?? "");
3370 }
3371 if (pos.matFloor.alias == "snow" && EClass.rnd(3) == 0)
3372 {
3374 Msg.Say(Lang.GetList("walk_snow").RandomItem());
3375 }
3376 else if (EClass.world.weather.CurrentCondition == Weather.Condition.RainHeavy && EClass.rnd(3) == 0)
3377 {
3379 Msg.Say(Lang.GetList("walk_storm").RandomItem());
3380 }
3381 }
3382 ActWait.Search(this);
3383 }
3384 if (IsPCC)
3385 {
3386 int num6 = Mathf.Abs(cell2.topHeight - cell.topHeight);
3387 if ((num6 >= 3 && lastPos.sourceBlock.tileType.slopeHeight == 0 && newPoint.sourceBlock.tileType.slopeHeight == 0) || cell2.hasDoorBoat || cell.hasDoorBoat)
3388 {
3389 renderer.PlayAnime((cell2.topHeight >= cell.topHeight) ? AnimeID.JumpDown : ((num6 >= 6) ? AnimeID.Jump : AnimeID.JumpSmall));
3390 }
3391 else
3392 {
3393 float surfaceHeight = cell2.GetSurfaceHeight();
3394 float surfaceHeight2 = cell.GetSurfaceHeight();
3395 num6 = (int)Mathf.Abs((surfaceHeight - surfaceHeight2) * 100f);
3396 if (num6 >= 15)
3397 {
3398 renderer.PlayAnime((surfaceHeight >= surfaceHeight2) ? AnimeID.JumpDown : ((num6 >= 40) ? AnimeID.Jump : AnimeID.JumpSmall));
3399 }
3400 }
3401 }
3402 if (IsPC)
3403 {
3404 if (renderer.anime == null && renderer.replacer != null && renderer.replacer.pccData == null)
3405 {
3407 }
3409 {
3410 if (!FLOOR.IsTatami(pos.cell.sourceSurface.id) && pos.cell.room == null)
3411 {
3412 EClass.player.flags.isShoesOff = false;
3413 EClass.pc.Say("shoes_on", EClass.pc);
3414 EClass.pc.SetPCCState(PCCState.Normal);
3415 }
3416 }
3417 else if (FLOOR.IsTatami(pos.cell.sourceSurface.id) && pos.cell.room != null)
3418 {
3419 EClass.player.flags.isShoesOff = true;
3420 EClass.pc.Say("shoes_off", EClass.pc);
3421 EClass.pc.SetPCCState(PCCState.ShoesOff);
3422 }
3423 }
3424 bool flag7 = flag5 || EClass._zone.IsUnderwater;
3425 if (wasInWater != flag7)
3426 {
3427 wasInWater = flag7;
3428 RefreshSpeed();
3429 }
3430 lastPos.Things.ForeachReverse(delegate(Thing t)
3431 {
3432 t.trait.OnSteppedOut(this);
3433 });
3434 if (!IsPC)
3435 {
3436 pos.Things.ForeachReverse(delegate(Thing t)
3437 {
3438 t.trait.OnStepped(this);
3439 });
3440 }
3441 if (CanDestroyPath())
3442 {
3444 }
3445 if (!isDead)
3446 {
3447 if (Evalue(492) > 0 && EClass.rnd(10000 / (80 + Evalue(492) * 2)) == 0)
3448 {
3449 AddExp(Mathf.Clamp((int)Mathf.Sqrt(base.ExpToNext / 100), 1, 1000));
3450 }
3451 if (pos.IsBlocked && EClass.rnd(IsPC ? 1 : 20) == 0)
3452 {
3453 stamina.Mod(-1);
3454 }
3455 }
3456 hasMovedThisTurn = true;
3457 return MoveResult.Success;
3458 }
3459
3460 public void DestroyPath(Point pos)
3461 {
3462 bool broke = false;
3463 pos.ForeachMultiSize(base.W, base.H, delegate(Point _p, bool main)
3464 {
3465 if (_p.IsValid)
3466 {
3467 if (_p.HasBlock)
3468 {
3469 EClass._map.MineBlock(_p, recoverBlock: false, this);
3470 if (_p.HasObj)
3471 {
3472 EClass._map.MineObj(_p, null, this);
3473 }
3474 broke = true;
3475 }
3476 if (_p.HasObj && _p.IsBlocked)
3477 {
3478 EClass._map.MineObj(_p, null, this);
3479 broke = true;
3480 }
3481 _p.Things.ForeachReverse(delegate(Thing t)
3482 {
3483 if (t.IsInstalled && (t.trait.IsBlockPath || t.trait.IsDoor))
3484 {
3485 if (t.isNPCProperty && t.trait.CanBeDestroyed)
3486 {
3487 t.Destroy();
3488 }
3489 else if (!t.IsUnique && !t.trait.CanBeDestroyed)
3490 {
3491 t.SetPlaceState(PlaceState.roaming);
3492 }
3493 }
3494 });
3495 }
3496 });
3497 if (broke)
3498 {
3499 Msg.Say("stomp");
3500 Shaker.ShakeCam("stomp");
3501 }
3502 }
3503
3504 public void TryPush(Point point)
3505 {
3506 List<Chara> list = point.ListCharas();
3507 if (list.Count == 0)
3508 {
3509 return;
3510 }
3511 list.ForeachReverse(delegate(Chara c)
3512 {
3513 if ((trait is TraitSnitch && c.IsPCFactionOrMinion) || (!c.ai.IsMoveAI && !c.IsPC && c.trait.CanBePushed && c != this && !c.noMove && (!EClass._zone.IsRegion || c.IsPCFactionOrMinion)))
3514 {
3515 List<Point> list2 = new List<Point>();
3516 for (int i = point.x - 1; i <= point.x + 1; i++)
3517 {
3518 for (int j = point.z - 1; j <= point.z + 1; j++)
3519 {
3520 if (i != point.x || j != point.z)
3521 {
3522 Point point2 = new Point(i, j);
3523 if (point2.IsValid && !point2.HasChara && !point2.IsBlocked && !point2.cell.hasDoor && !point2.IsBlockByHeight(point))
3524 {
3525 list2.Add(point2);
3526 }
3527 }
3528 }
3529 }
3530 if (list2.Count > 0)
3531 {
3532 if (list2.Count > 1)
3533 {
3534 list2.ForeachReverse(delegate(Point p)
3535 {
3536 if (p.Equals(new Point(point.x + point.x - pos.x, point.z + point.z - pos.z)))
3537 {
3538 list2.Remove(p);
3539 }
3540 });
3541 }
3542 Point newPoint = list2.RandomItem();
3543 if (IsPC)
3544 {
3545 Say("displace", this, c);
3546 PlaySound("push");
3547 }
3548 else if (c.isSynced)
3549 {
3550 c.PlayEffect("push");
3551 }
3552 c.MoveByForce(newPoint, this, checkWall: true);
3553 if (!c.IsPC && c.trait is TraitRogue && EClass.rnd(3) == 0 && GetCurrency() > 20 && !HasElement(426))
3554 {
3555 int num = EClass.rndHalf(10 + Mathf.Min(GetCurrency() / 100, 1000));
3556 c.Talk("pushed");
3557 Say("pushed_money", this, c);
3558 ModCurrency(-num);
3559 c.ModCurrency(num);
3560 c.PlaySound("steal_money");
3561 }
3562 else if (IsPC && !c.IsPCParty && !c.IsUnique && c.IsHumanSpeak && EClass.rnd(5) == 0)
3563 {
3564 c.Talk("pushed");
3565 }
3566 }
3567 }
3568 });
3569 }
3570
3571 public bool CanReplace(Chara c)
3572 {
3573 if (c.IsMultisize || !c.trait.CanBePushed || c.isRestrained || c.noMove || IsHostile(c) || IsMinion || (EClass._zone.IsRegion && !c.IsPCFactionOrMinion))
3574 {
3575 return false;
3576 }
3577 if (IsPC)
3578 {
3579 return true;
3580 }
3581 if (c.IsPC || c.pos.Equals(EClass.pc.pos) || c.host != null)
3582 {
3583 return false;
3584 }
3585 if (!IsHostile(c))
3586 {
3587 if (c.c_uidMaster != 0 || c.isSummon || base.IsPowerful || IsEscorted())
3588 {
3589 return true;
3590 }
3591 if (DestDist < c.DestDist)
3592 {
3593 return true;
3594 }
3595 if (IsPCParty && !c.IsPCParty)
3596 {
3597 return true;
3598 }
3599 if (IsPCFaction && !c.IsPCParty)
3600 {
3601 return true;
3602 }
3603 }
3604 return false;
3605 }
3606
3607 public void MoveZone(string alias)
3608 {
3609 MoveZone(EClass.game.spatials.Find(alias));
3610 }
3611
3613 {
3614 MoveZone(z, new ZoneTransition
3615 {
3616 state = state
3617 });
3618 }
3619
3620 public void MoveZone(Zone z, ZoneTransition transition)
3621 {
3622 if (z == currentZone)
3623 {
3624 return;
3625 }
3626 if (EClass.game.IsSurvival && z.IsRegion)
3627 {
3628 z = EClass.pc.homeZone;
3629 transition = new ZoneTransition
3630 {
3631 state = ZoneTransition.EnterState.Return
3632 };
3633 }
3634 if (HasCondition<ConInvulnerable>())
3635 {
3636 RemoveCondition<ConInvulnerable>();
3637 }
3638 if (IsPC)
3639 {
3640 EClass.player.nextZone = z;
3641 if (IsInActiveZone && !EClass.player.simulatingZone)
3642 {
3643 TryDropCarryOnly();
3644 if (z.instance == null && currentZone.instance == null && !EClass.player.deathZoneMove && !EClass.pc.isDead && (z.IsPCFaction || z.WillAutoSave) && z.GetTopZone() != EClass._zone.GetTopZone())
3645 {
3646 if (EClass.player.returnInfo != null)
3647 {
3648 EClass.player.returnInfo.turns += 5;
3649 }
3651 {
3652 EClass.game.Save(isAutoSave: true);
3653 }
3654 }
3655 EClass.player.deathZoneMove = false;
3656 }
3657 currentZone.events.OnLeaveZone();
3658 if (currentZone.instance != null)
3659 {
3660 ZoneInstance instance = currentZone.instance;
3661 z = EClass.game.spatials.Find(instance.uidZone) ?? EClass.pc.homeZone;
3662 transition = new ZoneTransition
3663 {
3664 state = instance.ReturnState,
3665 x = instance.x,
3666 z = instance.z
3667 };
3668 instance.OnLeaveZone();
3669 Debug.Log(z);
3670 }
3671 EInput.Consume(consumeAxis: true);
3672 EClass.player.uidLastZone = currentZone.uid;
3674 {
3675 if (currentZone.IsRegion)
3676 {
3677 Msg.Say("enterZone", z.Name);
3678 }
3679 else
3680 {
3681 if (z.IsRegion)
3682 {
3683 Msg.Say("leaveZone", currentZone.Name);
3684 }
3685 else if (z.id != currentZone.id)
3686 {
3687 Msg.Say("enterZone", z.Name);
3688 }
3689 EClass.player.lastZonePos = pos.Copy();
3690 }
3691 EClass.player.lastTransition = transition;
3692 }
3693 foreach (Chara item in EClass._map.charas.Where((Chara c) => c.IsPCPartyMinion && c.master != EClass.pc).ToList())
3694 {
3696 }
3697 EClass.player.listCarryoverMap = EClass._map.charas.Where((Chara c) => c.c_uidMaster != 0 && c.FindMaster() == EClass.pc && c.c_minionType == MinionType.Default).ToList();
3698 if (!z.IsRegion && (z is Zone_Tent || currentZone is Zone_Tent))
3699 {
3700 foreach (Chara chara in EClass._map.charas)
3701 {
3702 if (chara.c_uidMaster == 0 && !chara.IsGlobal && !chara.isNPCProperty && (chara.id == "reaper" || chara.id == "messenger_death") && ((chara.enemy != null && chara.enemy.IsPCFactionOrMinion) || chara.Dist(EClass.pc) < 5))
3703 {
3704 EClass.player.listCarryoverMap.Add(chara);
3705 }
3706 }
3707 }
3708 foreach (Chara item2 in EClass.player.listCarryoverMap)
3709 {
3710 EClass._zone.RemoveCard(item2);
3711 }
3712 }
3713 if (party != null && party.leader == this)
3714 {
3715 foreach (Chara member in party.members)
3716 {
3717 if (member != this && !member.isDead && member.parent is Zone)
3718 {
3719 member.MoveZone(z);
3720 }
3721 }
3722 }
3723 if (global == null)
3724 {
3725 Debug.Log(base.Name);
3726 return;
3727 }
3728 transition.uidLastZone = currentZone?.uid ?? 0;
3729 global.transition = transition;
3730 if (z.IsActiveZone)
3731 {
3732 Point spawnPos = z.GetSpawnPos(this);
3733 global.transition = null;
3734 if (IsPC)
3735 {
3736 EClass.player.lastTransition = null;
3737 }
3738 z.AddCard(this, spawnPos);
3739 if (IsBranchMember())
3740 {
3742 }
3743 }
3744 else
3745 {
3746 z.AddCard(this);
3747 }
3748 }
3749
3750 public void MoveHome(string id, int x = -1, int z = -1)
3751 {
3752 MoveHome(EClass.game.world.FindZone(id), x, z);
3753 }
3754
3755 public void MoveHome(Zone zone, int x = -1, int z = -1)
3756 {
3757 if (isDead)
3758 {
3759 Revive();
3760 }
3761 else
3762 {
3763 Cure(CureType.Death);
3764 }
3765 CureCondition<ConSuspend>();
3766 if (IsPCParty)
3767 {
3769 }
3770 FactionBranch factionBranch = homeBranch;
3771 if (x == -1)
3772 {
3773 x = 50;
3774 }
3775 if (z == -1)
3776 {
3777 z = 50;
3778 }
3779 Point point = new Point(x, z);
3780 if (zone.IsActiveZone)
3781 {
3782 point = point.GetNearestPoint(allowBlock: false, allowChara: false);
3783 }
3784 zone.AddCard(this, point);
3785 SetHomeZone(zone);
3786 global.transition = new ZoneTransition
3787 {
3788 state = ZoneTransition.EnterState.Dead,
3789 x = point.x,
3790 z = point.z
3791 };
3792 orgPos = new Point(x, z);
3793 if (factionBranch != null)
3794 {
3795 RefreshWorkElements();
3796 factionBranch.policies.Validate();
3797 }
3798 }
3799
3800 public void FallFromZone()
3801 {
3802 Msg.Say("skyFall", EClass.pc, EClass._zone.Name);
3803 Zone zone = (EClass._zone.isExternalZone ? null : EClass._zone.GetTopZone().FindZone(EClass._zone.lv - 1));
3804 zone = zone ?? EClass.world.region;
3805 MoveZone(zone ?? EClass.world.region, new ZoneTransition
3806 {
3807 state = ZoneTransition.EnterState.Fall,
3808 x = pos.x,
3809 z = pos.z
3810 });
3811 }
3812
3813 public override void SetDir(int d)
3814 {
3815 base.dir = d;
3816 UpdateAngle();
3817 renderer.RefreshSprite();
3818 }
3819
3820 public override void Rotate(bool reverse = false)
3821 {
3822 if (renderer.hasActor)
3823 {
3824 base.dir = (base.dir + ((!reverse) ? 1 : (-1))).Clamp(0, 3, loop: true);
3825 }
3826 else
3827 {
3828 base.dir = ((base.dir == 0) ? 1 : 0);
3829 }
3830 UpdateAngle();
3831 renderer.RefreshSprite();
3832 }
3833
3834 public override void LookAt(Card c)
3835 {
3836 LookAt(c.pos);
3837 }
3838
3839 public override void LookAt(Point p)
3840 {
3841 angle = Util.GetAngle(p.x - pos.x, p.z - pos.z);
3842 if (EClass._zone.IsRegion)
3843 {
3844 if (angle > 100f && angle < 170f)
3845 {
3846 base.dir = 2;
3847 }
3848 else if (angle > 170f && angle < 190f)
3849 {
3850 base.dir = 0;
3851 }
3852 else if (angle > 190f || (angle < -10f && angle > -100f))
3853 {
3854 base.dir = 3;
3855 }
3856 else
3857 {
3858 base.dir = 1;
3859 }
3860 angle -= 45f;
3861 }
3862 else if (angle > 170f && angle < 235f)
3863 {
3864 base.dir = 0;
3865 }
3866 else if (angle > 80f && angle < 145f)
3867 {
3868 base.dir = 1;
3869 }
3870 else if (angle > -100f && angle < -35f)
3871 {
3872 base.dir = 3;
3873 }
3874 else if (angle > -10f && angle < 55f)
3875 {
3876 base.dir = 2;
3877 }
3878 renderer.RefreshSprite();
3879 }
3880
3881 public void UpdateAngle()
3882 {
3883 if (IsPCC)
3884 {
3885 if (base.dir == 0)
3886 {
3887 angle = 225f;
3888 }
3889 else if (base.dir == 1)
3890 {
3891 angle = 135f;
3892 }
3893 else if (base.dir == 2)
3894 {
3895 angle = 45f;
3896 }
3897 else if (base.dir == 3)
3898 {
3899 angle = -45f;
3900 }
3901 }
3902 else if (base.dir == 0)
3903 {
3904 angle = 165f;
3905 }
3906 else if (base.dir == 1)
3907 {
3908 angle = 300f;
3909 }
3910 else if (base.dir == 2)
3911 {
3912 angle = 0f;
3913 }
3914 else if (base.dir == 3)
3915 {
3916 angle = 120f;
3917 }
3918 }
3919
3920 public int GetCurrentDir()
3921 {
3922 Debug.Log(angle);
3923 if (!renderer.hasActor)
3924 {
3925 if (angle == 0f || angle == 45f || angle == 90f)
3926 {
3927 return 2;
3928 }
3929 if (angle == -135f || angle == 180f || angle == -90f)
3930 {
3931 return 1;
3932 }
3933 if (angle == 135f)
3934 {
3935 return 0;
3936 }
3937 return 3;
3938 }
3939 return renderer.actor.currentDir;
3940 }
3941
3942 public void UpdateSight()
3943 {
3944 int num = 4;
3945 for (int i = -num; i < num + 1; i++)
3946 {
3947 for (int j = -num; j < num + 1; j++)
3948 {
3949 shared.Set(pos.x + i, pos.z + j);
3950 if (shared.IsValid && !shared.cell.isSeen && i >= -1 && i <= 1 && j >= -1)
3951 {
3952 _ = 1;
3953 }
3954 }
3955 }
3956 }
3957
3958 public bool WillConsumeTurn()
3959 {
3960 for (int num = conditions.Count - 1; num >= 0; num--)
3961 {
3962 if (conditions[num].ConsumeTurn)
3963 {
3964 return true;
3965 }
3966 }
3967 return false;
3968 }
3969
3970 public void TickConditions()
3971 {
3972 if (_cooldowns != null)
3973 {
3974 TickCooldown();
3975 }
3976 turn++;
3977 consumeTurn = false;
3978 preventRegen = false;
3979 emoIcon = Emo2.none;
3980 if (base.isSummon)
3981 {
3982 base.c_summonDuration--;
3983 if (base.c_summonDuration <= 0)
3984 {
3985 Die();
3986 return;
3987 }
3988 }
3989 if (EClass.world.weather.IsRaining && !EClass._map.IsIndoor && !pos.cell.HasRoof)
3990 {
3991 AddCondition<ConWet>(20);
3992 }
3993 switch (turn % 50)
3994 {
3995 case 0:
3996 happiness = (hunger.value + stamina.value + depression.value + bladder.value + hygiene.value) / 5;
3997 break;
3998 case 1:
3999 if (!IsPC || !EClass.debug.godMode)
4000 {
4001 if (EClass.rnd(2) == 0 && !HasCondition<ConAwakening>())
4002 {
4003 sleepiness.Mod(1);
4004 }
4005 if (EClass.rnd(3) == 0)
4006 {
4007 hunger.Mod(1);
4008 }
4009 if (IsPC && (sleepiness.GetPhase() != 0 || stamina.GetPhase() <= 1))
4010 {
4011 Tutorial.Play("sleep");
4012 }
4013 }
4014 break;
4015 case 2:
4016 if (parasite != null)
4017 {
4018 ModExp(227, (int)((EClass._zone.IsRegion ? 5 : 40) + parasite.affinity.CurrentStage));
4019 }
4020 if (ride != null)
4021 {
4022 ModExp(226, (int)((EClass._zone.IsRegion ? 5 : 40) + ride.affinity.CurrentStage));
4023 }
4024 break;
4025 case 3:
4026 {
4027 int phase = hygiene.GetPhase();
4028 int num = 0;
4029 num = ((!IsPC) ? ((phase > 3) ? 50 : 0) : ((phase > 3) ? 50 : 0));
4030 if (num > EClass.rnd(100))
4031 {
4032 hygiene.Mod(-1);
4033 }
4034 break;
4035 }
4036 case 4:
4037 if (IsPC)
4038 {
4040 }
4041 break;
4042 case 5:
4043 case 30:
4044 if (isWeakToSunlight && pos.IsSunLit && !EClass.debug.godMode)
4045 {
4046 AddCondition<ConBurning>(1000, force: true);
4047 }
4048 break;
4049 case 10:
4050 if (HasElement(1250))
4051 {
4052 if (!HasCondition<ConVampire>())
4053 {
4054 AddCondition<ConVampire>();
4055 }
4056 if (!IsPC && !HasCooldown(8793))
4057 {
4058 bool flag = false;
4059 flag = ((!HasCondition<ConTransmuteBat>()) ? (!HasElement(431) && pos.IsSunLit) : (body.HasElement(431) || (EClass.world.date.IsNight && !pos.IsSunLit)));
4060 if (flag && base.IsPCFactionOrMinion && !EClass._zone.IsPCFactionOrTent && EClass._zone.HasLaw && pos.ListWitnesses(this).Count > 0 && !HasCondition<ConBurning>())
4061 {
4062 flag = false;
4063 }
4064 if (flag)
4065 {
4066 UseAbility("SpTransmuteBat", this);
4067 }
4068 }
4069 }
4070 if (HasElement(1423) && !HasCondition<ConPeaky>())
4071 {
4072 AddCondition<ConPeaky>();
4073 }
4074 break;
4075 }
4076 if (turn % 200 == 0)
4077 {
4078 DiminishTempElements();
4079 }
4080 if (IsPCParty)
4081 {
4082 if (dirtyWeight)
4083 {
4084 CalcBurden();
4085 }
4086 int phase2 = burden.GetPhase();
4087 int phase3 = hunger.GetPhase();
4088 if (phase3 >= 4)
4089 {
4090 preventRegen = true;
4091 }
4092 if (EClass.rnd(EClass._zone.IsRegion ? 100 : 30) == 0 && phase2 >= 3)
4093 {
4094 Say("dmgBurden", this);
4095 DamageHP(MaxHP * (base.ChildrenWeight * 100 / WeightLimit) / 1000 + 1, AttackSource.Burden);
4096 if (isDead)
4097 {
4098 return;
4099 }
4100 }
4101 if (EClass.rnd(12) == 0)
4102 {
4103 if (IsPC)
4104 {
4105 if (phase2 > 0)
4106 {
4107 ModExp(207, 1 + phase2 * phase2);
4108 }
4109 }
4110 else
4111 {
4112 ModExp(207, 4);
4113 }
4114 }
4115 if (IsPC)
4116 {
4117 if (phase3 >= 5)
4118 {
4119 if (!(ai is AI_Eat) && EClass.rnd(5) == 0)
4120 {
4121 DamageHP(1 + EClass.rnd(2) + MaxHP / 50, AttackSource.Hunger);
4122 }
4123 if (!isDead && EClass.rnd(3) == 0)
4124 {
4125 stamina.Mod(-1);
4126 }
4127 }
4128 if (isDead)
4129 {
4130 return;
4131 }
4132 phase3 = stamina.GetPhase();
4133 if (phase3 <= 0)
4134 {
4135 preventRegen = true;
4136 }
4137 if (currentZone.IsRegion && EClass.world.weather.CurrentCondition == Weather.Condition.RainHeavy && !EClass.pc.HasElement(408))
4138 {
4139 if (EClass.rnd(100) == 0 && !isConfused)
4140 {
4141 Msg.Say("rain_confuse");
4142 AddCondition<ConConfuse>(500);
4143 }
4144 if (EClass.rnd(300) == 0 && !isBlind)
4145 {
4146 Msg.Say("rain_confuse");
4147 AddCondition<ConBlind>(200);
4148 }
4149 }
4150 if (turn % (200000 / Mathf.Max(100 + Evalue(409) * 10, 50)) == 0)
4151 {
4152 ModCorruption(1);
4153 }
4154 }
4155 }
4156 if (!IsPC)
4157 {
4158 int num2 = Evalue(409);
4159 if (num2 > 0 && turn % (200000 / Mathf.Max(100 + num2 * 10, 50)) == 0)
4160 {
4161 ModCorruption(1);
4162 }
4163 }
4164 for (int num3 = conditions.Count - 1; num3 >= 0; num3--)
4165 {
4166 if (num3 < conditions.Count)
4167 {
4168 Condition condition = conditions[num3];
4169 if (!condition.TimeBased)
4170 {
4171 condition.Tick();
4172 }
4173 if (!condition.IsKilled)
4174 {
4175 if (condition.ConsumeTurn)
4176 {
4177 consumeTurn = true;
4178 }
4179 if (condition.PreventRegen)
4180 {
4181 preventRegen = true;
4182 }
4183 if (condition.EmoIcon != Emo2.none && condition.EmoIcon > emoIcon)
4184 {
4185 emoIcon = condition.EmoIcon;
4186 }
4187 }
4188 if (isDead)
4189 {
4190 return;
4191 }
4192 }
4193 }
4194 switch (id)
4195 {
4196 case "cocoon_alien":
4197 case "cocoon":
4198 if (!EClass._zone.IsRegion && !IsDisabled && 1.0005f - (float)base.hp / (float)MaxHP > EClass.rndf(1f) && !pos.IsSunLit)
4199 {
4200 HatchEgg();
4201 return;
4202 }
4203 consumeTurn = true;
4204 break;
4205 case "tsunami":
4206 if (elements.Base(79) >= 30)
4207 {
4208 if (IsInCombat)
4209 {
4210 elements.SetTo(79, elements.Base(79) * 3 / 4);
4211 }
4212 break;
4213 }
4214 Die();
4215 return;
4216 }
4217 if (pos.IsBlocked && pos.HasBlock)
4218 {
4219 preventRegen = true;
4220 }
4221 if (preventRegen)
4222 {
4223 return;
4224 }
4225 if (EClass.rnd(25) == 0 && base.hp < MaxHP)
4226 {
4227 HealHP(EClass.rnd(Evalue(300) / 3 + 1) + 1);
4228 elements.ModExp(300, 8f);
4229 }
4230 if (EClass.rnd(8) == 0 && mana.value < mana.max)
4231 {
4232 mana.Mod(EClass.rnd(Evalue(301) / 2 + 1) + 1);
4233 elements.ModExp(301, 8f);
4234 }
4235 if (EClass.rnd(20) != 0)
4236 {
4237 return;
4238 }
4239 if (IsPC)
4240 {
4242 {
4243 EClass.player.RecoverStamina(Evalue(62) / 100 + ((Evalue(62) % 100 > EClass.rnd(100)) ? 1 : 0));
4244 }
4245 }
4246 else if (stamina.value < stamina.max)
4247 {
4248 stamina.Mod(EClass.rnd(5) + 1);
4249 }
4250 }
4251
4252 public void SyncRide()
4253 {
4254 if (host != null)
4255 {
4256 host.SyncRide();
4257 }
4258 if (ride != null)
4259 {
4260 SyncRide(ride);
4261 }
4262 if (parasite != null)
4263 {
4264 SyncRide(parasite);
4265 }
4266 }
4267
4268 public void SyncRide(Chara c)
4269 {
4270 if (!c.pos.Equals(pos))
4271 {
4272 if (!pos.IsValid)
4273 {
4274 Debug.LogError("exception: pos is not valid:" + pos?.ToString() + "/" + this);
4275 pos = new Point();
4276 }
4277 EClass._map.MoveCard(pos, c);
4278 }
4279 }
4280
4281 public override void Tick()
4282 {
4283 SyncRide();
4284 combatCount--;
4285 ignoreSPAbsorb = false;
4286 if (IsPC)
4287 {
4288 if (hasMovedThisTurn)
4289 {
4290 pos.Things.ForeachReverse(delegate(Thing t)
4291 {
4293 {
4294 AI_Goto aI_Goto = ai.Current as AI_Goto;
4295 if ((aI_Goto == null && !(ai is GoalManualMove)) || (aI_Goto != null && !aI_Goto.dest.Equals(pos)))
4296 {
4297 return;
4298 }
4299 }
4300 t.trait.OnStepped(this);
4301 });
4302 if (isDead)
4303 {
4304 return;
4305 }
4306 hasMovedThisTurn = false;
4308 {
4309 EClass.player.haltMove = false;
4310 ActionMode.Adv.TryCancelInteraction(sound: false);
4311 EInput.Consume(1);
4312 return;
4313 }
4314 if (EClass._zone.IsRegion)
4315 {
4317 {
4318 foreach (Chara member in EClass.pc.party.members)
4319 {
4320 if (member.hunger.value > 65)
4321 {
4322 member.InstantEat(null, sound: false);
4323 }
4324 }
4325 }
4326 Chara chara = null;
4328 if (cell != null && (cell.zone == null || (cell.zone is Zone_Field && !cell.zone.IsPCFaction)))
4329 {
4330 foreach (Chara chara2 in EClass._map.charas)
4331 {
4332 if (!chara2.IsPCFactionOrMinion && !chara2.IsGlobal && chara2.pos.Equals(EClass.pc.pos))
4333 {
4334 chara = chara2;
4335 break;
4336 }
4337 }
4338 }
4339 if (chara != null)
4340 {
4342 {
4343 EClass.player.safeTravel = 5 + EClass.rnd(5);
4344 }
4345 EClass._zone.RemoveCard(chara);
4346 Msg.Say("encounter");
4347 EClass.player.EnterLocalZone(encounter: true, chara);
4348 }
4349 else if (EClass.player.safeTravel <= 0)
4350 {
4351 if (cell != null && cell.zone == null && !EClass.debug.ignoreEncounter)
4352 {
4354 if (!tileInfo.shore)
4355 {
4356 bool num = EClass.pc.HasCondition<ConWardMonster>();
4357 bool flag = EClass.pc.HasCondition<ConDrawMonster>();
4358 bool flag2 = EClass.game.quests.Get<QuestEscort>() != null;
4359 int num2 = (tileInfo.isRoad ? 22 : 12);
4360 if (flag2)
4361 {
4362 num2 = (tileInfo.isRoad ? 16 : 10);
4363 }
4364 if (num)
4365 {
4366 num2 *= (flag2 ? 2 : 20);
4367 }
4368 if (flag)
4369 {
4370 num2 /= 2;
4371 }
4372 if (EClass.rnd(num2) == 0)
4373 {
4374 Msg.Say("encounter");
4375 if (!flag)
4376 {
4377 EClass.player.safeTravel = 5 + EClass.rnd(5);
4378 }
4379 EClass.player.EnterLocalZone(encounter: true);
4380 }
4381 }
4382 }
4383 }
4384 else
4385 {
4387 }
4388 }
4389 }
4390 EClass.player.pickupDelay = 0f;
4391 if (EClass.player.returnInfo != null)
4392 {
4394 if (EClass.player.returnInfo.turns <= 0)
4395 {
4397 {
4398 EClass.player.returnInfo = null;
4400 }
4401 else
4402 {
4404 {
4405 int uidDest = EClass.player.returnInfo.uidDest;
4406 Zone zone = null;
4407 if (uidDest != 0)
4408 {
4409 zone = EClass.game.spatials.map.TryGetValue(uidDest) as Zone;
4410 }
4411 if (zone == null || zone.destryoed)
4412 {
4413 zone = EClass.world.region;
4414 }
4416 {
4417 Msg.Say("returnFail");
4418 }
4419 else
4420 {
4421 Msg.Say("returnComplete");
4422 EClass.player.uidLastTravelZone = 0;
4424 EClass.player.lastZonePos = null;
4425 }
4426 EClass.player.returnInfo = null;
4427 return;
4428 }
4429 EClass.player.returnInfo = null;
4430 Msg.Say("returnOverweight");
4431 }
4432 }
4433 }
4434 if ((HasNoGoal || !ai.IsRunning) && !WillConsumeTurn())
4435 {
4436 SetAI(_NoGoalPC);
4437 return;
4438 }
4441 {
4442 RecipeUpdater.dirty = true;
4443 }
4444 actTime = EClass.player.baseActTime;
4445 }
4446 else
4447 {
4448 actTime = EClass.player.baseActTime * Mathf.Max(0.1f, (float)EClass.pc.Speed / (float)Speed);
4449 hasMovedThisTurn = false;
4450 }
4451 TickConditions();
4452 if (!IsAliveInCurrentZone)
4453 {
4454 return;
4455 }
4456 renderer.RefreshStateIcon();
4457 if (host != null && !consumeTurn)
4458 {
4459 if (host.ride == this && ((host.hasMovedThisTurn && IsInCombat) || (enemy != null && turn % 3 != 0)))
4460 {
4461 consumeTurn = true;
4462 }
4463 if (host.parasite == this && enemy != null && EClass.rnd(10) > EClass.rnd(host.Evalue(227) + 10))
4464 {
4465 if (Dist(enemy) < 3 && EClass.rnd(2) == 0)
4466 {
4467 Say("parasite_fail", this, host);
4468 if (EClass.rnd(2) == 0 && GetInt(106) == 0)
4469 {
4470 Talk("parasite_fail");
4471 }
4472 }
4473 consumeTurn = true;
4474 }
4475 }
4476 if (consumeTurn)
4477 {
4478 if (IsPC)
4479 {
4481 }
4482 }
4483 else
4484 {
4485 if (base.isRestrained)
4486 {
4487 TryUnrestrain();
4488 }
4489 if (enemy != null)
4490 {
4492 {
4493 enemy = null;
4494 }
4495 else if (!IsPC && (ai.CancelOnAggro || !ai.IsRunning))
4496 {
4497 SetAIAggro();
4498 }
4499 }
4500 if (HasNoGoal || !ai.IsRunning)
4501 {
4502 ChooseNewGoal();
4503 }
4504 ai.Tick();
4505 }
4506 Cell cell2 = base.Cell;
4507 if (EClass._zone.IsUnderwater || (cell2.IsTopWaterAndNoSnow && !cell2.isFloating))
4508 {
4509 AddCondition<ConWet>(50);
4510 if (pos.IsHotSpring)
4511 {
4512 hygiene.Mod(2);
4513 }
4514 }
4515 if (cell2.sourceSurface.id == 20)
4516 {
4517 AddCondition<ConBurning>();
4518 }
4519 if (IsPC && !EClass._zone.IsRegion && cell2.CanSuffocate() && !EClass.debug.godMode && !HasElement(1252))
4520 {
4521 AddCondition<ConSuffocation>(800 / (100 + EvalueMax(200, -5) * 10), force: true);
4522 }
4523 CellEffect e;
4524 if (cell2.effect != null)
4525 {
4526 e = cell2.effect;
4527 switch (e.id)
4528 {
4529 case 1:
4530 case 2:
4531 case 4:
4532 if (IsLevitating)
4533 {
4534 Say("levitating");
4535 break;
4536 }
4537 AddCondition<ConWet>(50);
4538 ProcEffect();
4539 break;
4540 case 3:
4541 PlaySound("fire_step");
4542 AddCondition<ConBurning>(30);
4543 break;
4544 case 5:
4545 if (!isWet)
4546 {
4547 PlaySound("bubble");
4548 AddCondition<ConWet>(30);
4549 ProcEffect();
4550 }
4551 break;
4552 case 6:
4553 if (hasMovedThisTurn)
4554 {
4555 Say("abMistOfDarkness_step", this);
4556 }
4557 AddCondition<ConDark>(e.power);
4558 break;
4559 }
4560 }
4561 if (IsPC)
4562 {
4563 if (EClass.player.currentHotItem.Thing != null)
4564 {
4566 }
4568 }
4569 void ClearEffect()
4570 {
4571 EClass._map.SetLiquid(cell2.x, cell2.z, 0, 0);
4572 }
4573 void ProcEffect()
4574 {
4575 if (e.idEffect != EffectId.None)
4576 {
4577 ActEffect.ProcAt(e.idEffect, e.power, e.isBlessed ? BlessedState.Blessed : (e.isCursed ? BlessedState.Cursed : BlessedState.Normal), this, this, new Point(pos), e.isHostileAct, new ActRef
4578 {
4579 aliasEle = EClass.sources.elements.map[e.idEle].alias,
4580 n1 = e.n1,
4581 refVal = e.refVal
4582 });
4583 ClearEffect();
4584 }
4585 }
4586 }
4587
4588 public bool CanLift(Card c)
4589 {
4590 return true;
4591 }
4592
4593 public bool CanAutoPick(Card c)
4594 {
4595 return true;
4596 }
4597
4598 public bool CanPick(Card c)
4599 {
4600 if (c.isDestroyed)
4601 {
4602 return false;
4603 }
4604 Card rootCard = c.GetRootCard();
4605 if (rootCard.isDestroyed || (rootCard.ExistsOnMap && rootCard.pos.Distance(pos) > 1))
4606 {
4607 return false;
4608 }
4609 if (rootCard != this && things.IsFull(c.Thing))
4610 {
4611 return false;
4612 }
4613 return true;
4614 }
4615
4616 public void PickOrDrop(Point p, string idThing, int idMat = -1, int num = 1, bool msg = true)
4617 {
4618 if (num != 0)
4619 {
4620 PickOrDrop(p, ThingGen.Create(idThing, idMat).SetNum(num), msg);
4621 }
4622 }
4623
4624 public void PickOrDrop(Point p, Thing t, bool msg = true)
4625 {
4626 if (things.GetDest(t).IsValid)
4627 {
4628 Pick(t, msg);
4629 }
4630 else
4631 {
4632 EClass._zone.AddCard(t, p);
4633 }
4634 }
4635
4636 public Thing Pick(Thing t, bool msg = true, bool tryStack = true)
4637 {
4638 if (t.trait is TraitCard && t.isNew && EClass.game.config.autoCollectCard && !t.c_idRefCard.IsEmpty())
4639 {
4641 return t;
4642 }
4643 if (t.parent == this)
4644 {
4645 return t;
4646 }
4647 t = TryPoisonPotion(t);
4648 ThingContainer.DestData dest = things.GetDest(t, tryStack);
4649 if (!dest.IsValid)
4650 {
4651 if (t.parent != EClass._zone)
4652 {
4653 if (IsPC)
4654 {
4655 Say("backpack_full_drop", t);
4656 SE.Drop();
4657 }
4658 return EClass._zone.AddCard(t, pos).Thing;
4659 }
4660 if (IsPC)
4661 {
4662 Say("backpack_full", t);
4663 }
4664 return t;
4665 }
4666 if (dest.stack != null)
4667 {
4668 if (msg)
4669 {
4670 PlaySound("pick_thing");
4671 Say("pick_thing", this, t);
4672 }
4673 t.TryStackTo(dest.stack);
4674 return dest.stack;
4675 }
4676 TryAbsorbRod(t);
4677 if (msg)
4678 {
4679 PlaySound("pick_thing");
4680 Say("pick_thing", this, t);
4681 }
4682 TryReservePickupTutorial(t);
4683 return dest.container.AddThing(t, tryStack);
4684 }
4685
4687 {
4688 if (t.trait is TraitPotion && t.id != "1165" && !t.source.tag.Contains("neg") && EClass.rnd(2) == 0 && HasElement(1565))
4689 {
4690 string text = EClass.sources.things.rows.Where((SourceThing.Row a) => a._origin == "potion" && a.tag.Contains("neg") && a.chance > 100).ToList().RandomItemWeighted((SourceThing.Row a) => a.chance)
4691 .id;
4692 Say("poisonDrip", this);
4693 int num = t.Num;
4694 t.Destroy();
4695 t = ThingGen.Create(text).SetNum(num);
4696 }
4697 return t;
4698 }
4699
4700 public void TryAbsorbRod(Thing t)
4701 {
4702 if (!IsPC || !(t.trait is TraitRod) || t.c_charges <= 0 || !HasElement(1564))
4703 {
4704 return;
4705 }
4706 Say("absorbRod", this, t);
4707 TraitRod rod = t.trait as TraitRod;
4708 bool flag = false;
4709 if (rod.source != null)
4710 {
4711 using IEnumerator<SourceElement.Row> enumerator = EClass.sources.elements.rows.Where((SourceElement.Row a) => a.id == rod.source.id).GetEnumerator();
4712 if (enumerator.MoveNext())
4713 {
4714 SourceElement.Row current = enumerator.Current;
4715 if (IsPC)
4716 {
4717 GainAbility(current.id, t.c_charges * 100, t);
4718 flag = true;
4719 }
4720 }
4721 }
4722 if (!flag)
4723 {
4724 mana.Mod(-50 * t.c_charges);
4725 }
4726 t.c_charges = 0;
4728 }
4729
4731 {
4732 if (t.id == "axe")
4733 {
4734 Tutorial.Reserve("tool");
4735 }
4736 if (t.category.id == "mushroom")
4737 {
4738 Tutorial.Reserve("food");
4739 }
4740 if (t.category.id == "herb")
4741 {
4742 Tutorial.Reserve("herb");
4743 }
4744 if (t.id == "pasture")
4745 {
4746 Tutorial.Reserve("pasture");
4747 }
4748 if (t.id == "log")
4749 {
4750 Tutorial.Reserve("process");
4751 }
4752 }
4753
4754 public void TryPickGroundItem(Func<Card, bool> func = null)
4755 {
4756 foreach (Card item in pos.ListCards())
4757 {
4758 if ((IsPC || !(EClass.pc.ai is AI_UseCrafter aI_UseCrafter) || !aI_UseCrafter.ings.Contains(item)) && item.isThing && item.placeState == PlaceState.roaming && CanPick(item) && (func == null || func(item)))
4759 {
4760 Thing thing = Pick(item.Thing);
4761 if (thing != null && !IsPC)
4762 {
4763 thing.isNPCProperty = true;
4764 }
4765 break;
4766 }
4767 }
4768 }
4769
4770 public void TryPutShared(Thing t, List<Thing> containers = null, bool dropIfFail = true)
4771 {
4772 if (!EClass._zone.TryAddThingInSharedContainer(t, containers) && dropIfFail)
4773 {
4774 EClass._zone.AddCard(t, pos);
4775 }
4776 }
4777
4778 public bool TryHoldCard(Card t, int num = -1, bool pickHeld = false)
4779 {
4780 if (held == t)
4781 {
4782 return true;
4783 }
4784 if (t.isDestroyed || t.Num <= 0)
4785 {
4786 return false;
4787 }
4788 if (!CanPick(t))
4789 {
4790 if (t.parent == null)
4791 {
4792 EClass._zone.AddCard(t, pos);
4793 }
4794 return false;
4795 }
4796 HoldCard(t, num);
4797 return true;
4798 }
4799
4800 public void HoldCard(Card t, int num = -1)
4801 {
4802 if (held == t || t.isDestroyed || t.Num <= 0)
4803 {
4804 return;
4805 }
4806 if (IsPC && t.isNPCProperty)
4807 {
4808 t.isNPCProperty = false;
4809 if (!t.GetBool(128))
4810 {
4812 pos.TryWitnessCrime(this);
4813 }
4814 }
4815 PickHeld();
4816 if (t.isChara)
4817 {
4819 {
4820 t.ShowEmo(Emo.love);
4821 }
4822 EClass.player.altHeldPos = t.renderer.data.ForceAltHeldPosition || EClass.rnd(2) == 0;
4823 }
4824 else
4825 {
4826 if (num == -1 || num > t.Num)
4827 {
4828 num = t.Num;
4829 }
4830 if (num < t.Num)
4831 {
4832 t = t.Split(num);
4833 }
4834 }
4835 if (t.GetRootCard() != this)
4836 {
4837 t = Pick(t.Thing, msg: false, tryStack: false);
4838 if (t.GetRootCard() != this)
4839 {
4840 return;
4841 }
4842 }
4843 held = t;
4844 held._CreateRenderer();
4845 if (held.GetLightRadius() > 0)
4846 {
4847 RecalculateFOV();
4848 }
4849 if (IsPC)
4850 {
4852 WidgetHotbar.dirtyCurrentItem = true;
4853 }
4854 }
4855
4856 public void PickHeld(bool msg = false)
4857 {
4858 if (held == null)
4859 {
4860 return;
4861 }
4862 Card card = held;
4863 if (IsPC && held.invY == 1)
4864 {
4865 WidgetHotbar.dirtyCurrentItem = true;
4867 held = null;
4868 return;
4869 }
4870 if (held.isChara)
4871 {
4872 DropHeld();
4873 return;
4874 }
4875 if (IsPC && !held.IsHotItem && held.trait.CanOnlyCarry)
4876 {
4877 Say("canOnlyCarry", held);
4878 DropHeld();
4879 return;
4880 }
4881 bool flag = held != things.TryStack(held.Thing);
4882 if (!flag && things.IsOverflowing())
4883 {
4884 if (IsPC)
4885 {
4886 Say("backpack_full_drop", held);
4887 SE.Drop();
4888 }
4889 DropHeld();
4890 return;
4891 }
4892 if (msg)
4893 {
4894 PlaySound("pick_thing");
4895 Say("pick_held", this, card);
4896 if (IsPC && card.id == "statue_weird")
4897 {
4898 Say("statue_pick");
4899 }
4900 }
4901 if (IsPC)
4902 {
4903 WidgetHotbar.dirtyCurrentItem = true;
4904 if (!flag)
4905 {
4907 if (held.GetRootCard() != EClass.pc)
4908 {
4909 Pick(held.Thing, msg: false);
4910 }
4911 }
4912 }
4913 held = null;
4914 }
4915
4916 public Card SplitHeld(int a)
4917 {
4918 return held.Split(a);
4919 }
4920
4921 public void TryDropCarryOnly()
4922 {
4923 if (held != null && held.trait.CanOnlyCarry)
4924 {
4925 DropHeld();
4926 }
4927 foreach (Thing item in things.List((Thing t) => t.trait.CanOnlyCarry))
4928 {
4929 DropThing(item);
4930 }
4931 }
4932
4933 public Card DropHeld(Point dropPos = null)
4934 {
4935 if (held == null)
4936 {
4937 return null;
4938 }
4939 if (IsPC)
4940 {
4941 WidgetHotbar.dirtyCurrentItem = true;
4943 }
4944 Card card = EClass._zone.AddCard(held, dropPos ?? pos);
4945 card.OnLand();
4946 if (card.trait.CanOnlyCarry)
4947 {
4948 card.SetPlaceState(PlaceState.installed);
4949 }
4950 return card;
4951 }
4952
4953 public void DropThing(Thing t, int num = -1)
4954 {
4955 if (t.c_isImportant)
4956 {
4957 Msg.Say("markedImportant");
4958 return;
4959 }
4960 if (!t.trait.CanBeDropped)
4961 {
4962 Msg.Say("cantDrop", t);
4963 return;
4964 }
4965 if (t.trait is TraitAbility)
4966 {
4967 SE.Trash();
4968 t.Destroy();
4969 return;
4970 }
4971 Msg.Say("dropItem", t.Name);
4972 t.ignoreAutoPick = true;
4973 PlaySound("drop");
4974 EClass._zone.AddCard(t, pos);
4975 if (t.trait.CanOnlyCarry)
4976 {
4977 t.Install();
4978 }
4979 }
4980
4982 {
4983 int num = Evalue(131);
4984 int num2 = Evalue(130);
4985 int num3 = Evalue(123);
4986 if (num > num2 && num > num3)
4987 {
4988 return AttackStyle.TwoWield;
4989 }
4990 if (num2 > num && num2 > num3)
4991 {
4992 return AttackStyle.TwoHand;
4993 }
4994 if (num3 > num && num3 > num2)
4995 {
4996 return AttackStyle.Shield;
4997 }
4998 return AttackStyle.Default;
4999 }
5000
5002 {
5003 return elements.ListElements((Element e) => e.source.categorySub == "weapon" && !e.HasTag("ranged")).FindMax((Element a) => a.Value);
5004 }
5005
5007 {
5008 if (elements.Value(122) > elements.Value(120))
5009 {
5010 return elements.GetElement(122);
5011 }
5012 return elements.GetElement(120);
5013 }
5014
5015 public void TryRestock(bool onCreate)
5016 {
5017 isOnCreate = onCreate;
5018 if (onCreate || (!IsPCFaction && (base.IsUnique || trait is TraitAdventurer || trait is TraitGuard)))
5019 {
5020 RestockEquip((!EClass.core.IsGameStarted || !(EClass._zone is Zone_Music)) && onCreate);
5021 }
5022 RestockInventory(onCreate);
5023 }
5024
5025 public void RestockEquip(bool onCreate)
5026 {
5027 string equip = source.equip;
5028 if (equip.IsEmpty())
5029 {
5030 equip = job.equip;
5031 }
5032 if (equip == "none")
5033 {
5034 return;
5035 }
5036 bool flag = true;
5037 switch (id)
5038 {
5039 case "kettle":
5040 case "quru":
5041 case "loytel":
5042 case "shojo":
5043 EQ_ID("staff_long", 1);
5044 EQ_CAT("head");
5045 EQ_CAT("torso");
5046 EQ_CAT("arm");
5047 return;
5048 case "adv_yukiimo":
5049 if (onCreate)
5050 {
5051 EQ_ID("tail_snowleopard");
5052 }
5053 break;
5054 case "adv_kiria":
5055 if (onCreate)
5056 {
5057 EQ_ID("sword_zephir");
5058 }
5059 break;
5060 case "adv_schwert":
5061 if (onCreate)
5062 {
5063 EQ_ID("sword", -1, Rarity.Legendary);
5064 }
5065 if (onCreate)
5066 {
5067 EQ_ID("dagger", -1, Rarity.Legendary);
5068 }
5069 break;
5070 case "adv_mesherada":
5071 if (onCreate)
5072 {
5073 EQ_ID("dagger_hathaway");
5074 }
5075 break;
5076 case "adv_verna":
5077 if (onCreate)
5078 {
5079 EQ_ID("staff_long", -1, Rarity.Legendary);
5080 }
5081 if (onCreate)
5082 {
5083 EQ_ID("cloak_wing", -1, Rarity.Mythical);
5084 }
5085 break;
5086 case "big_sister":
5087 if (onCreate)
5088 {
5089 EQ_ID("sword_muramasa");
5090 }
5091 break;
5092 case "adv_gaki":
5093 if (onCreate)
5094 {
5095 EQ_ID("dagger_gaki");
5096 }
5097 if (onCreate)
5098 {
5099 EQ_ID("dagger_ninto");
5100 }
5101 break;
5102 case "adv_ivory":
5103 EQ_ID("dagger", -1, Rarity.Legendary);
5104 AddThing("60");
5105 break;
5106 case "adv_wini":
5107 if (onCreate)
5108 {
5109 EQ_ID("staff_Cat", -1, Rarity.Mythical);
5110 }
5111 AddCard(ThingGen.CreateSpellbook(9150));
5112 if (onCreate)
5113 {
5114 AddThing("1071");
5115 }
5116 break;
5117 case "mamani":
5118 EQ_ID("lightsaber_double", -1, Rarity.Mythical);
5119 if (onCreate)
5120 {
5121 EQ_ID("cloak_mani2");
5122 EQ_ID("boots_dal");
5123 AddThing("gun_gravity2");
5124 AddThing("gun_mani");
5125 }
5126 break;
5127 case "namamani":
5128 if (onCreate)
5129 {
5130 AddThing("gun_gravity2");
5131 }
5132 break;
5133 case "lomias":
5134 if (onCreate)
5135 {
5136 AddThing("bow_vindale");
5137 }
5138 break;
5139 case "unseenhand":
5140 if (onCreate)
5141 {
5142 EQ_ID("martial_ring");
5143 }
5144 break;
5145 case "larnneire":
5146 if (onCreate)
5147 {
5148 EQ_ID("EtherDagger2");
5149 }
5150 break;
5151 case "keeper_garden":
5152 if (!body.HasWeapon())
5153 {
5154 EQ_ID("sword_ragnarok");
5155 }
5156 break;
5157 case "ungaga_pap":
5158 if (onCreate)
5159 {
5160 EQ_ID("axe_destruction");
5161 }
5162 break;
5163 case "lurie_boss":
5164 if (onCreate)
5165 {
5166 EQ_ID("ribbon_duponne");
5167 }
5168 break;
5169 case "seeker":
5170 if (onCreate)
5171 {
5172 EQ_ID("helm_seeker");
5173 }
5174 EQ_ID("robe_pope");
5175 EQ_ID("sword_katana");
5176 EQ_ID("staff");
5177 EQ_ID("sword_katana");
5178 if (onCreate)
5179 {
5180 EQ_ID("boots_seven");
5181 }
5182 if (onCreate)
5183 {
5184 for (int i = 0; i < 20; i++)
5185 {
5186 AddThing(ThingGen.CreateFromCategory("book", 50));
5187 }
5188 EQ_Item("panty");
5189 AddThing("plat").SetNum(6);
5190 }
5191 break;
5192 case "ephrond":
5193 if (onCreate)
5194 {
5195 AddThing("guitar_efrond");
5196 }
5197 break;
5198 case "ashland":
5199 if (onCreate)
5200 {
5201 AddThing("guitar_ash");
5202 }
5203 break;
5204 case "swordkeeper":
5205 if (onCreate)
5206 {
5207 EQ_ID("EtherDagger");
5208 }
5209 break;
5210 case "mech_angel":
5211 if (onCreate)
5212 {
5213 Thing thing = ThingGen.Create("pole_holy");
5214 thing.SetReplica(on: true);
5215 thing.rarity = Rarity.Normal;
5216 thing.elements.SetTo(60, -15);
5217 thing.elements.SetTo(418, -100);
5218 thing.elements.SetTo(93, 50);
5219 AddThing(thing);
5220 body.Equip(thing);
5221 flag = false;
5222 }
5223 break;
5224 case "azzrasizzle":
5225 if (onCreate)
5226 {
5227 EQ_ID("staff_magius");
5228 }
5229 break;
5230 case "sorin":
5231 if (onCreate)
5232 {
5233 EQ_ID("staff_insanity");
5234 }
5235 break;
5236 case "robot":
5237 if (onCreate)
5238 {
5239 EQ_ID("sword_katana");
5240 }
5241 break;
5242 case "samurai_kamikaze":
5243 if (onCreate)
5244 {
5245 EQ_ID("sword_katana");
5246 }
5247 break;
5248 case "mimu":
5249 if (onCreate)
5250 {
5251 EQ_ID("staff_leek");
5252 }
5253 break;
5254 case "kumatan":
5255 if (onCreate)
5256 {
5257 EQ_ID("dagger_hocho");
5258 }
5259 break;
5260 case "mad_rich":
5261 if (onCreate)
5262 {
5263 int a = (EClass._zone.IsUserZone ? 200 : EClass.rndHalf(100 + (EClass.debug.enable ? 10 : EClass._zone.influence) * 50 + (int)Mathf.Sqrt(EClass._zone.DangerLv) * 100 + (int)Mathf.Sqrt(EClass.pc.FameLv) * 100 + EClass._zone.development * 10));
5264 ModCurrency(a);
5265 }
5266 break;
5267 }
5268 if (!TryEquipRanged())
5269 {
5270 switch (id)
5271 {
5272 case "tyche":
5273 case "trooper":
5274 case "mech_scarab":
5275 AddThing("gun_laser");
5276 break;
5277 case "ojomaton":
5278 case "sister_catmaton":
5279 case "shojomaton":
5280 case "imotomaton":
5281 case "rocketman":
5282 {
5283 Thing thing2 = AddThing("panzerfaust");
5284 thing2.ChangeMaterial("iron");
5285 thing2.c_ammo = 0;
5286 break;
5287 }
5288 default:
5289 switch (equip)
5290 {
5291 case "archer":
5292 EQ_CAT((EClass.rnd(4) == 0) ? "crossbow" : "bow");
5293 break;
5294 case "inquisitor":
5295 case "gunner":
5296 EQ_CAT("gun");
5297 break;
5298 }
5299 break;
5300 }
5301 }
5302 int num = ((base.rarity >= Rarity.Mythical) ? (base.LV * 3) : ((base.rarity >= Rarity.Legendary) ? (base.LV * 2) : base.LV));
5303 if (trait is TraitAdventurer)
5304 {
5305 num *= 3;
5306 }
5307 if (race.id == "asura")
5308 {
5309 for (int j = 0; j < 4; j++)
5310 {
5311 EQ_CAT(job.weapon.RandomItem());
5312 }
5313 }
5314 for (int k = 0; k < ((!(race.id == "mutant")) ? 1 : Mathf.Min(2 + base.LV / 30, 20)); k++)
5315 {
5316 if (flag)
5317 {
5318 if (source.ContainsTag("boxer"))
5319 {
5320 EQ_CAT("martial");
5321 }
5322 else if (!job.weapon.IsEmpty())
5323 {
5324 if (race.id == "mutant" || (body.slotMainHand != null && body.slotMainHand.thing == null))
5325 {
5326 EQ_CAT(job.weapon.RandomItem());
5327 }
5328 if (race.id == "mutant" || (Evalue(131) > 0 && EClass.rnd(2) == 0))
5329 {
5330 EQ_CAT(job.weapon.RandomItem());
5331 }
5332 }
5333 }
5334 EQ_CAT("torso");
5335 if (EClass.rnd(num) > 5)
5336 {
5337 EQ_CAT("arm");
5338 }
5339 if (EClass.rnd(num) > 10)
5340 {
5341 EQ_CAT("head");
5342 }
5343 if (EClass.rnd(num) > 15)
5344 {
5345 EQ_CAT("back");
5346 }
5347 if (EClass.rnd(num) > 20)
5348 {
5349 EQ_CAT("ring");
5350 }
5351 if (EClass.rnd(num) > 25)
5352 {
5353 EQ_CAT("amulet");
5354 }
5355 if (EClass.rnd(num) > 30)
5356 {
5357 EQ_CAT("foot");
5358 }
5359 if (EClass.rnd(num) > 35)
5360 {
5361 EQ_CAT("waist");
5362 }
5363 if (EClass.rnd(num) > 40)
5364 {
5365 EQ_CAT("ring");
5366 }
5367 }
5368 if (trait is TraitBard)
5369 {
5370 AddThing(ThingGen.Create("lute"));
5371 if (EClass.debug.enable || EClass.rnd(100) == 0)
5372 {
5373 EQ_ID("shield_lute");
5374 }
5375 }
5376 if (HasTag(CTAG.shield))
5377 {
5378 EQ_CAT("shield");
5379 }
5380 }
5381
5382 public void RestockInventory(bool onCreate)
5383 {
5384 switch (id)
5385 {
5386 case "lomias":
5387 if (ShouldRestock("_meat"))
5388 {
5389 AddCard(ThingGen.Create("_meat").MakeRefFrom("begger"));
5390 }
5391 break;
5392 case "fiama":
5393 Restock("book_story", 1);
5394 break;
5395 case "rock_thrower":
5396 Restock("stone", 10 + EClass.rnd(10));
5397 break;
5398 case "giant":
5399 Restock("rock", 2 + EClass.rnd(10));
5400 break;
5401 case "farris":
5402 Restock("lute", 1);
5403 Restock("book_story_home", 1);
5404 break;
5405 case "begger":
5406 break;
5407 }
5408 void Restock(string id, int num)
5409 {
5410 if (ShouldRestock(id))
5411 {
5412 AddCard(ThingGen.Create(id).SetNum(num));
5413 }
5414 }
5415 bool ShouldRestock(string id)
5416 {
5417 return things.Find(id) == null;
5418 }
5419 }
5420
5421 private void SetEQQuality()
5422 {
5424 Rarity rarity = Rarity.Normal;
5425 int num = ((base.LV >= 1000) ? 7 : ((base.LV >= 500) ? 5 : ((base.LV >= 250) ? 3 : ((base.LV >= 100) ? 2 : ((base.LV >= 50) ? 1 : 0)))));
5426 Rarity rarity2 = base.rarity;
5427 if (id == "big_sister")
5428 {
5429 num = (isOnCreate ? 8 : 4);
5430 }
5431 if (!isOnCreate && EClass.rnd(10) != 0)
5432 {
5433 num /= 2;
5434 }
5435 if (rarity2 == Rarity.Superior && EClass.rnd(10) <= num)
5436 {
5437 rarity = Rarity.Superior;
5438 }
5439 else if (rarity2 == Rarity.Legendary)
5440 {
5441 rarity = ((EClass.rnd(10) <= num) ? Rarity.Legendary : ((EClass.rnd(5) <= num) ? Rarity.Superior : Rarity.Normal));
5442 }
5443 else if (rarity2 >= Rarity.Mythical)
5444 {
5445 rarity = ((EClass.rnd(30) <= num) ? Rarity.Mythical : ((EClass.rnd(10) > num) ? Rarity.Superior : Rarity.Legendary));
5446 }
5447 if (rarity == Rarity.Normal && EClass.rnd(1000) == 0)
5448 {
5449 rarity = Rarity.Legendary;
5450 }
5451 CardBlueprint.current.rarity = rarity;
5452 }
5453
5454 public Thing EQ_ID(string s, int mat = -1, Rarity r = Rarity.Random)
5455 {
5456 SetEQQuality();
5457 if (r != Rarity.Random)
5458 {
5459 CardBlueprint.current.rarity = r;
5460 }
5461 Thing thing = ThingGen.Create(s, mat, base.LV);
5462 if (body.GetSlot(thing, onlyEmpty: true) == null)
5463 {
5464 return thing;
5465 }
5466 AddThing(thing);
5467 if (!body.Equip(thing))
5468 {
5469 thing.Destroy();
5470 }
5471 return thing;
5472 }
5473
5474 public void EQ_CAT(string s)
5475 {
5476 int slot = EClass.sources.categories.map[s].slot;
5477 BodySlot bodySlot = ((slot == 0) ? null : body.GetSlot(slot));
5478 if ((slot == 0 || bodySlot != null) && (slot != 37 || !HasElement(1209)))
5479 {
5480 SetEQQuality();
5481 Thing thing = ThingGen.CreateFromCategory(s, base.LV);
5482 AddThing(thing);
5483 if (bodySlot != null && !body.Equip(thing, bodySlot))
5484 {
5485 thing.Destroy();
5486 }
5487 }
5488 }
5489
5490 public void EQ_Item(string s, int num = 1)
5491 {
5492 SetEQQuality();
5493 Thing t = ThingGen.Create(s, -1, base.LV).SetNum(num);
5494 AddThing(t);
5495 }
5496
5497 public void Drink(Card t)
5498 {
5499 Say("drink", this, t.Duplicate(1));
5500 Say("quaff");
5501 PlaySound("drink");
5502 t.ModNum(-1);
5503 FoodEffect.ProcDrink(this, t.Thing);
5504 _ = IsPC;
5505 }
5506
5507 public bool CanRevive()
5508 {
5509 return EClass.world.date.IsExpired(base.c_dateDeathLock);
5510 }
5511
5512 public void GetRevived()
5513 {
5514 Revive(EClass.pc.pos.GetNearestPoint(allowBlock: false, allowChara: false), msg: true);
5515 if (!IsPCFaction)
5516 {
5517 return;
5518 }
5519 if (!IsPC && (!trait.CanJoinPartyResident || !trait.CanJoinParty || memberType != FactionMemberType.Default))
5520 {
5521 if (homeZone != null && EClass._zone != homeZone)
5522 {
5523 Msg.Say("returnHome", this, homeZone.Name);
5524 MoveZone(homeZone);
5525 }
5526 }
5527 else if ((!EClass._zone.IsPCFaction || homeBranch != EClass.Branch || base.c_wasInPcParty) && EClass._zone.events.GetEvent<ZoneEventWedding>() == null)
5528 {
5529 EClass.pc.party.AddMemeber(this, showMsg: true);
5530 }
5531 }
5532
5533 public void Revive(Point p = null, bool msg = false)
5534 {
5535 if (!isDead)
5536 {
5537 return;
5538 }
5539 isDead = false;
5540 base.hp = MaxHP / 3;
5541 mana.value = 0;
5542 stamina.value = 0;
5543 if (hunger.value > 30)
5544 {
5545 hunger.value = 30;
5546 }
5547 sleepiness.value = 0;
5548 hostility = OriginalHostility;
5549 RemoveCondition<StanceTaunt>();
5550 if (id == "keeper_garden")
5551 {
5552 SaiyanRevive();
5553 }
5554 if (IsPC)
5555 {
5557 {
5558 Msg.Say("noDeathPenalty2", this);
5559 }
5561 {
5562 Msg.Say("noDeathPenalty", this);
5563 }
5564 else
5565 {
5567 }
5568 List<Thing> dropList = new List<Thing>();
5569 EClass.pc.things.Foreach(delegate(Thing t)
5570 {
5572 {
5573 t.ignoreAutoPick = true;
5574 dropList.Add(t);
5575 }
5576 }, onlyAccessible: false);
5577 foreach (Thing item in dropList)
5578 {
5580 Msg.Say("backpack_full_drop", item);
5581 }
5582 EClass.player.preventDeathPenalty = false;
5583 }
5584 if (IsPCFaction && homeBranch != null)
5585 {
5586 homeBranch.Log("bRevive", this);
5587 }
5588 if (p != null)
5589 {
5590 if (!p.IsInBounds)
5591 {
5593 }
5594 EClass._zone.AddCard(this, p);
5595 if (msg)
5596 {
5597 SE.Play("revive");
5598 Msg.Say("revive", this);
5599 PlayEffect("revive");
5600 }
5601 SetCensored(enable: false);
5602 }
5603 }
5604
5605 public void SaiyanRevive()
5606 {
5607 ModCorruption(-100000);
5608 if (base.LV < 10000000)
5609 {
5610 SetLv(base.LV * 10 + 9);
5611 }
5612 Refresh();
5613 base.hp = MaxHP;
5614 mana.value = mana.max;
5615 stamina.value = stamina.max;
5616 bossText = true;
5617 }
5618
5619 public void MakeGrave(string lastword)
5620 {
5621 if (!EClass._zone.IsRegion)
5622 {
5623 List<string> list = new List<string> { "930", "931", "947", "948", "949", "950", "951", "952" };
5624 if (IsPC && EClass.rnd(2) == 0 && EClass.pc.things.Find("letter_will") != null)
5625 {
5626 list = new List<string> { "944", "946", "backerGrave", "backerGrave2" };
5627 }
5628 Thing thing = ThingGen.Create(list.RandomItem());
5629 thing.MakeRefFrom(this);
5630 if (!lastword.IsEmpty())
5631 {
5632 thing.c_note = lastword;
5633 }
5634 thing.isModified = true;
5635 EClass._zone.AddCard(thing, pos).Install();
5636 }
5637 }
5638
5639 public void ApplyDeathPenalty()
5640 {
5641 if (!IsPC)
5642 {
5643 return;
5644 }
5645 int currency = GetCurrency();
5646 if (currency > 0)
5647 {
5648 int num = currency / 3 + EClass.rnd(currency / 3 + 1);
5649 if (num <= 0)
5650 {
5651 num = 1;
5652 }
5653 Msg.Say("panaltyMoney", this, Lang._currency(num));
5654 ModCurrency(-num);
5656 }
5657 foreach (Element value in EClass.pc.elements.dict.Values)
5658 {
5659 if (EClass.rnd(5) == 0 && value.IsMainAttribute)
5660 {
5661 EClass.pc.elements.ModExp(value.id, -500f);
5662 }
5663 }
5664 }
5665
5666 public void Vomit()
5667 {
5668 base.c_vomit++;
5669 Say("vomit", this);
5670 PlaySound("vomit");
5671 if (!EClass._zone.IsRegion)
5672 {
5673 Thing thing = ThingGen.Create("731");
5675 {
5676 thing.MakeRefFrom(this);
5677 }
5678 EClass._zone.AddCard(thing, pos);
5679 }
5680 if (HasCondition<ConAnorexia>())
5681 {
5682 ModExp(70, -50);
5683 ModExp(71, -75);
5684 ModExp(77, -100);
5685 }
5686 else if (base.c_vomit > 10)
5687 {
5688 AddCondition<ConAnorexia>();
5689 }
5690 AddCondition<ConDim>();
5691 if (HasCondition<ConAnorexia>())
5692 {
5693 ModWeight(-1 * (1 + EClass.rnd(5)));
5694 }
5695 if (hunger.GetPhase() >= 4)
5696 {
5697 DamageHP(9999L, AttackSource.Hunger);
5698 }
5699 hunger.Mod(30);
5700 }
5701
5702 public override void Die(Element e = null, Card origin = null, AttackSource attackSource = AttackSource.None, Chara originalTarget = null)
5703 {
5704 combatCount = 0;
5705 if (isDead)
5706 {
5707 return;
5708 }
5709 if (host != null)
5710 {
5711 base.hp = -1;
5712 if ((uint)(attackSource - 17) > 1u)
5713 {
5714 AddCondition<ConFaint>(200, force: true);
5715 return;
5716 }
5717 ActRide.Unride(host, this);
5718 }
5719 bool isInActiveZone = IsInActiveZone;
5720 if (isInActiveZone)
5721 {
5722 if (id == "putty" && origin != null && origin.IsPCParty)
5723 {
5725 }
5726 if (IsPC)
5727 {
5729 }
5730 if (base.isSummon && !GetBool(136))
5731 {
5732 if (id == "tsunami")
5733 {
5734 pos.PlaySound("water");
5735 }
5736 else
5737 {
5738 Say("summon_vanish", this);
5739 pos.PlayEffect("vanish");
5740 pos.PlaySound("vanish");
5741 }
5742 Destroy();
5743 return;
5744 }
5745 if ((uint)(attackSource - 17) <= 1u)
5746 {
5747 if (attackSource == AttackSource.Euthanasia && trait is TraitLittleOne)
5748 {
5749 MakeEgg();
5750 if (IsPCFaction)
5751 {
5752 homeBranch.RemoveMemeber(this);
5753 }
5754 }
5755 PlayEffect("revive");
5756 PlaySound("chime_angel");
5757 }
5758 else
5759 {
5760 Effect.Get("blood").Play((parent is Chara) ? (parent as Chara).pos : pos).SetParticleColor(EClass.Colors.matColors[base.material.alias].main)
5761 .Emit(50);
5762 AddBlood(AI_Slaughter.slaughtering ? 12 : (2 + EClass.rnd(2)));
5763 PlaySound(base.material.GetSoundDead(source));
5764 }
5765 renderer.RefreshSprite();
5766 renderer.RefreshStateIcon();
5767 ClearFOV();
5768 }
5769 if (base.hp >= 0)
5770 {
5771 base.hp = -1;
5772 }
5773 string text = "";
5774 "dead_in".langGame(EClass._zone.Name);
5775 string text2 = ((origin == null) ? "" : origin.GetName(NameStyle.Full));
5776 if (LangGame.Has("dead_" + attackSource))
5777 {
5778 text = "dead_" + attackSource;
5779 }
5780 else
5781 {
5782 if (e != Element.Void && e != null)
5783 {
5784 text = "dead_" + e.source.alias;
5785 }
5786 if (text == "" || !LangGame.Has(text))
5787 {
5788 text = "dead";
5789 }
5790 }
5791 if (IsPC)
5792 {
5793 EClass.player.staminaRecovery = 0;
5794 EClass._zone.isDeathLocation = true;
5795 string s = ((origin == null) ? text : "dead_by");
5797 if (attackSource == AttackSource.Wrath)
5798 {
5800 }
5801 EClass.player.deathMsg = GameLang.Parse(s.langGame(), thirdPerson: true, EClass.pc.NameBraced, "dead_in".langGame(EClass._zone.Name), text2);
5803 if (EClass._zone.instance is ZoneInstanceRandomQuest zoneInstanceRandomQuest)
5804 {
5805 zoneInstanceRandomQuest.status = ZoneInstance.Status.Fail;
5806 }
5807 AI_PlayMusic.keepPlaying = false;
5808 }
5809 if (isInActiveZone)
5810 {
5811 if (attackSource == AttackSource.DeathSentence || attackSource == AttackSource.Euthanasia)
5812 {
5813 Msg.Say("goto_heaven", this);
5814 }
5815 else
5816 {
5817 if (originalTarget != null || origin == null || !origin.isSynced || (attackSource != AttackSource.Melee && attackSource != AttackSource.Range))
5818 {
5819 Msg.Say(text, this, "", text2);
5820 }
5821 string text3 = TalkTopic("dead");
5822 if (!text3.IsEmpty())
5823 {
5824 text3 = text3.StripBrackets();
5825 }
5826 bool flag = base.rarity >= Rarity.Legendary && !IsPCFaction;
5827 if (!IsPC && flag)
5828 {
5829 MakeGrave(text3);
5830 }
5831 Msg.SetColor();
5832 SpawnLoot(origin);
5833 }
5834 if (IsPC)
5835 {
5836 TryDropCarryOnly();
5837 }
5838 }
5839 if (IsPCFaction)
5840 {
5841 if (homeBranch != null)
5842 {
5843 homeBranch.Log(text, this, "");
5844 }
5845 WidgetPopText.Say("popDead".lang(base.Name), FontColor.Bad);
5846 if (!IsPC)
5847 {
5848 if (EClass.player.stats.allyDeath == 0)
5849 {
5850 Tutorial.Reserve("death_pet");
5851 }
5853 }
5854 }
5855 if (id == "mandrake" || HasElement(488))
5856 {
5857 Say("a_scream", this);
5858 ActEffect.ProcAt(EffectId.Scream, base.LV * 3 + 200, BlessedState.Normal, this, this, pos, isNeg: true);
5859 }
5860 daysStarved = 0;
5861 isDead = true;
5862 ClearTempElements();
5863 enemy = null;
5864 _cooldowns = null;
5865 base.isSale = false;
5866 SetInt(70);
5867 EClass._map.props.sales.Remove(this);
5868 Cure(CureType.Death);
5869 SetAI(new NoGoal());
5870 TryDropBossLoot();
5871 if (isInActiveZone && EClass._zone.HasLaw && IsHuman && OriginalHostility >= Hostility.Neutral)
5872 {
5873 pos.TalkWitnesses(origin?.Chara, "witness", 3, WitnessType.crime, (Chara c) => !c.IsPCParty && !c.IsUnique);
5874 }
5875 if (IsPC)
5876 {
5877 EClass.player.returnInfo = null;
5878 EClass.player.uidLastTravelZone = 0;
5879 foreach (Chara chara3 in EClass._map.charas)
5880 {
5881 if (chara3.IsHostile())
5882 {
5883 chara3.hostility = chara3.OriginalHostility;
5884 }
5885 if (chara3.enemy == EClass.pc)
5886 {
5887 chara3.enemy = null;
5888 }
5889 }
5890 if (EClass.pc.things.Find("letter_will") != null && EClass.rnd(10) == 0)
5891 {
5892 EClass.player.preventDeathPenalty = true;
5893 }
5894 }
5895 else
5896 {
5897 bool flag2 = currentZone.IsActiveZone && IsLocalChara && !currentZone.IsPCFaction;
5898 if (currentZone is Zone_LittleGarden && id == "littleOne")
5899 {
5900 flag2 = false;
5901 }
5902 if (flag2)
5903 {
5904 EClass._map.deadCharas.Add(this);
5905 }
5906 currentZone.RemoveCard(this);
5907 }
5908 if ((origin != null && origin.IsPCParty) || IsPCFaction)
5909 {
5910 int a = -10;
5911 if (IsPCFaction && !IsPCParty && (origin == null || !origin.IsPCParty))
5912 {
5913 a = -5;
5914 }
5915 ModAffinity(EClass.pc, a, show: false);
5916 string text4 = id;
5917 if (!(text4 == "quru"))
5918 {
5919 if (text4 == "corgon")
5920 {
5921 EClass.game.cards.globalCharas.Find("quru")?.ModAffinity(EClass.pc, -20, show: false);
5922 }
5923 }
5924 else
5925 {
5926 EClass.game.cards.globalCharas.Find("corgon")?.ModAffinity(EClass.pc, -20, show: false);
5927 }
5928 }
5929 if (origin != null)
5930 {
5931 if (origin.IsPCParty || origin.IsPCPartyMinion)
5932 {
5933 int num = 0;
5934 if (trait is TraitMerchantTravel && !base.isSummon)
5935 {
5936 num = -20;
5937 }
5938 else if (OriginalHostility >= Hostility.Friend && IsHuman && !base.IsPCFactionOrMinion)
5939 {
5940 num = -5;
5941 }
5942 else if (race.id == "cat" && OriginalHostility >= Hostility.Neutral)
5943 {
5944 EClass.pc.Say("killcat");
5945 num = -1;
5946 }
5947 if (EClass.pc.party.HasElement(1563) && num < 0)
5948 {
5949 num = num * 30 / 100;
5950 }
5951 if (num != 0)
5952 {
5953 EClass.player.ModKarma(num);
5954 }
5955 }
5956 if (origin == EClass.pc)
5957 {
5958 EClass.pc.faith.Revelation("kill", EClass.pc, 10);
5959 }
5960 else if (origin.IsPCFaction)
5961 {
5962 origin.Chara.ModAffinity(EClass.pc, 1, show: false);
5963 origin.Chara.ShowEmo(Emo.love);
5964 }
5965 }
5966 if (base.sourceBacker != null && origin != null && origin.IsPCParty)
5967 {
5968 EClass.player.doneBackers.Add(base.sourceBacker.id);
5969 }
5970 if (base.IsPCFactionOrMinion)
5971 {
5973 {
5974 Msg.Say("abort_allyDead");
5975 }
5976 }
5978 {
5979 Msg.Say("abort_enemyDead");
5980 }
5981 if (IsPCParty && !IsPC)
5982 {
5984 base.c_wasInPcParty = true;
5985 EClass.pc.Say("allyDead");
5986 }
5987 switch (id)
5988 {
5989 case "littleOne":
5990 if (attackSource != AttackSource.Euthanasia && !IsPCFaction)
5991 {
5992 EClass.player.flags.little_killed = true;
5994 }
5995 break;
5996 case "big_daddy":
5997 case "big_daddy2":
5998 if (!IsPCFaction)
5999 {
6000 Chara chara = CharaGen.Create("littleOne");
6001 EClass._zone.AddCard(chara, pos.Copy());
6002 Msg.Say("little_pop");
6004 }
6005 break;
6006 case "shark_sister":
6007 if (!IsPCFaction)
6008 {
6009 Chara t = CharaGen.Create("sister_shark");
6010 EClass._zone.AddCard(t, pos.Copy());
6011 Msg.Say("shark_pop");
6012 }
6013 break;
6014 }
6015 if (attackSource == AttackSource.Finish && origin != null && origin.Evalue(665) > 0)
6016 {
6017 Chara chara2 = CharaGen.CreateFromFilter("c_plant", base.LV);
6018 EClass._zone.AddCard(chara2, pos.Copy());
6019 if (chara2.LV < base.LV)
6020 {
6021 chara2.SetLv(base.LV);
6022 }
6023 chara2.MakeMinion((origin.IsPCParty || origin.IsPCPartyMinion) ? EClass.pc : origin.Chara, MinionType.Friend);
6024 Msg.Say("plant_pop", this, chara2);
6025 }
6028 trait.OnDie();
6029 }
6030
6031 public void TryDropBossLoot()
6032 {
6033 if (IsPCFaction || IsPCFactionMinion)
6034 {
6035 return;
6036 }
6037 int num = 0;
6038 bool flag = false;
6039 bool flag2 = false;
6040 Point point = pos.GetNearestPoint(allowBlock: true, allowChara: false, allowInstalled: false, ignoreCenter: true) ?? pos;
6041 TreasureType type = TreasureType.BossQuest;
6042 if (EClass._zone.Boss == this)
6043 {
6044 type = TreasureType.BossNefia;
6045 num = 2 + EClass.rnd(2);
6046 flag = (flag2 = true);
6047 EClass._zone.Boss = null;
6048 Msg.Say("boss_win", EClass._zone.Name);
6050 {
6051 Msg.Say("boss_win_void", EClass._zone.Name);
6052 EClass.player.flags.KilledBossInVoid = true;
6053 }
6054 if (EClass._zone.IsNefia)
6055 {
6058 SE.Play("Jingle/fanfare2");
6059 EClass._zone.SetBGM(114, refresh: true, 3f);
6060 }
6063 }
6064 switch (id)
6065 {
6066 case "azzrasizzle":
6067 num = 5;
6068 flag = (flag2 = true);
6069 EClass.Sound.StopBGM(3f);
6070 EClass._zone.SetBGM(1, refresh: false);
6072 {
6073 EClass.game.quests.Get<QuestIntoDarkness>().UpdateOnTalk();
6074 }
6075 break;
6076 case "vernis_boss":
6077 num = 5;
6078 flag = (flag2 = true);
6079 EClass.Sound.StopBGM(3f);
6080 EClass._zone.SetBGM(1, refresh: false);
6082 {
6083 EClass.game.quests.Get<QuestVernis>().UpdateOnTalk();
6084 }
6085 break;
6086 case "lurie_boss":
6087 if (!(EClass._zone is Zone_Exile))
6088 {
6089 num = 5;
6090 flag = (flag2 = true);
6091 EClass._zone.SetBGM(120, refresh: true, 3f);
6093 {
6094 EClass.game.quests.Get<QuestNegotiationDarkness>().ChangePhase(4);
6095 EClass.player.flags.killedDuponne = true;
6096 }
6097 }
6098 break;
6099 case "ungaga_pap":
6100 num = 5;
6101 flag = (flag2 = true);
6103 {
6104 EClass._zone.SetBGM(46, refresh: true, 3f);
6105 }
6106 break;
6107 case "melilith_boss":
6108 num = 5;
6109 flag = (flag2 = true);
6110 EClass.Sound.StopBGM(3f);
6111 EClass._zone.SetBGM(1, refresh: false);
6112 break;
6113 case "doga":
6114 {
6115 QuestCurry questCurry = EClass.game.quests.Get<QuestCurry>();
6116 if (questCurry != null)
6117 {
6118 num = 5;
6119 flag = (flag2 = true);
6120 EClass.Sound.StopBGM(3f);
6121 EClass._zone.SetBGM(1, refresh: false);
6122 questCurry.NextPhase();
6123 }
6124 break;
6125 }
6126 case "fairy_raina":
6127 case "fairy_poina":
6128 {
6129 bool num2 = EClass._map.FindChara((id == "fairy_raina") ? "fairy_poina" : "fairy_raina") == null;
6130 QuestNasu questNasu = EClass.game.quests.Get<QuestNasu>();
6131 if (num2 && questNasu != null && questNasu.phase <= 1)
6132 {
6133 if (questNasu.phase == 0)
6134 {
6135 questNasu.NextPhase();
6136 }
6137 num = 5;
6138 flag = (flag2 = true);
6139 EClass.Sound.StopBGM(3f);
6140 EClass._zone.SetBGM(1, refresh: false);
6141 EClass.player.DropReward(ThingGen.Create("backpack_holding"));
6142 questNasu.NextPhase();
6143 }
6144 break;
6145 }
6146 case "isygarad":
6147 {
6148 num = 5;
6149 flag = (flag2 = true);
6150 QuestExploration questExploration = EClass.game.quests.Get<QuestExploration>();
6151 if (questExploration != null)
6152 {
6153 SE.Play("kill_boss");
6154 questExploration.ChangePhase(3);
6155 EClass.Sound.StopBGM(3f);
6156 EClass._zone.SetBGM(1, refresh: false);
6157 }
6158 break;
6159 }
6160 case "swordkeeper":
6161 num = 10;
6162 flag = true;
6163 SE.Play("kill_boss");
6164 SoundManager.ForceBGM();
6165 LayerDrama.Activate("_event", "event", "swordkeeper_defeat");
6166 break;
6167 }
6168 if (flag)
6169 {
6170 SE.Play("kill_boss");
6171 }
6172 if (num != 0)
6173 {
6175 {
6176 EClass.player.stats.deepest = EClass._zone.DangerLv;
6177 Msg.Say("update_deepest", EClass.player.stats.deepest.ToString() ?? "");
6178 }
6180 {
6181 EClass.player.stats.deepestVoid = -EClass._zone.lv;
6182 Msg.Say("update_deepest_void", EClass.player.stats.deepestVoid.ToString() ?? "");
6183 }
6184 EClass.player.willAutoSave = true;
6185 Thing thing = ThingGen.CreateTreasure("chest_boss", base.LV, type);
6186 point.SetBlock();
6187 point.SetObj();
6188 EClass._zone.AddCard(thing, point).Install();
6189 ThingGen.TryLickChest(thing);
6190 }
6191 if (flag2)
6192 {
6194 }
6195 }
6196
6197 public bool UseAbility(int idAct, Card tc = null, Point pos = null, bool pt = false)
6198 {
6199 return UseAbility(elements.GetElement(idAct)?.act ?? ACT.Create(idAct), tc, pos, pt);
6200 }
6201
6202 public bool UseAbility(string idAct, Card tc = null, Point pos = null, bool pt = false)
6203 {
6204 return UseAbility(elements.GetElement(idAct)?.act ?? ACT.Create(idAct), tc, pos, pt);
6205 }
6206
6207 public bool UseAbility(Act a, Card tc = null, Point pos = null, bool pt = false)
6208 {
6209 if (HasCooldown(a.id))
6210 {
6211 return false;
6212 }
6213 if (!a.ValidatePerform(this, tc, pos))
6214 {
6215 return false;
6216 }
6217 if (a.source.proc.TryGet(0) == "Heal" && HasElement(1422) && !IsPC)
6218 {
6219 List<int> list = new List<int> { 8400, 8401, 8402, 8403, 8404, 8405 };
6220 int num = list.IndexOf(a.id);
6221 if (num != -1)
6222 {
6223 int num2 = list.TryGet(num + Evalue(1422));
6224 a = elements.GetElement(num2)?.act ?? ACT.Create(num2);
6225 }
6226 }
6227 int num3 = 1;
6228 Act.Cost cost = a.GetCost(this);
6229 a.GetPower(this);
6230 int n = 1;
6231 int num4 = 0;
6232 bool flag = a.IsTargetHostileParty();
6233 bool flag2 = ability.Has(a.id);
6234 if (IsPC && HasCondition<StanceManaCost>())
6235 {
6236 num4 = Evalue(1657);
6237 }
6238 _pts.Clear();
6239 if (a.TargetType.ForceParty)
6240 {
6241 pt = true;
6242 }
6243 if (pt)
6244 {
6245 n = 0;
6246 if (flag)
6247 {
6248 ForeachEnemy(delegate
6249 {
6250 n++;
6251 });
6252 }
6253 else
6254 {
6255 ForeachParty(delegate
6256 {
6257 n++;
6258 });
6259 }
6260 }
6261 if (a is Spell && IsPC && a.vPotential < n && !flag2)
6262 {
6263 n = 1;
6264 _pts.Clear();
6265 _pts.Add(this);
6266 pt = false;
6267 }
6268 int num5 = 100;
6269 if (!a.TargetType.ForceParty && n > 1)
6270 {
6271 num5 = (IsPC ? (n * 100) : (50 + n * 50));
6272 }
6273 int num6 = cost.cost * num5 / 100;
6274 if (cost.type == Act.CostType.MP && Evalue(483) > 0)
6275 {
6276 num6 = num6 * 100 / (100 + (int)Mathf.Sqrt(Evalue(483) * 10) * 3);
6277 }
6278 if (n == 0)
6279 {
6280 if (IsPC)
6281 {
6283 }
6284 return false;
6285 }
6286 if (!IsPC && cost.type == Act.CostType.MP && mana.value < 0 && (EClass.rnd(4) != 0 || IsPCFaction || (base.IsPowerful && mana.value < -20)))
6287 {
6288 return false;
6289 }
6290 if (IsPC)
6291 {
6292 if (!Dialog.warned && cost.type == Act.CostType.MP && cost.cost > 0 && mana.value < num6 && !EClass.debug.godMode)
6293 {
6294 Card cardBk = EClass.scene.mouseTarget.card;
6295 ActPlan.warning = true;
6296 Dialog.TryWarnMana(delegate
6297 {
6298 EClass.scene.mouseTarget.card = cardBk;
6299 if (UseAbility(a, tc, pos, pt))
6300 {
6302 }
6303 });
6304 return false;
6305 }
6306 EClass.ui.CloseLayers();
6307 }
6308 if ((isConfused && EClass.rnd(4) == 0) || (isBlind && (pt || (pos != null && !pos.Equals(base.pos)) || (tc != null && tc.pos != null && !tc.pos.Equals(base.pos))) && EClass.rnd(2) == 0))
6309 {
6310 Say("shakeHead", this);
6311 return true;
6312 }
6313 if (tc != null && tc != this)
6314 {
6315 LookAt(tc.pos);
6316 }
6317 if (pos != null && !base.pos.Equals(pos))
6318 {
6319 LookAt(pos);
6320 }
6321 if (a.CanRapidFire && HasElement(1648))
6322 {
6323 num3 = 1 + Evalue(1648);
6324 }
6325 if (IsPC && cost.cost > 0 && a.Value == 0 && !flag2)
6326 {
6328 return false;
6329 }
6330 if (a is Spell)
6331 {
6332 string s = (isConfused ? "_cast_confuse" : (HasCondition<ConDim>() ? "_cast_dim" : ""));
6333 if (!a.source.tag.Contains("useHand"))
6334 {
6335 Say(race.castStyle.IsEmpty("cast"), this, a.source.GetName().ToLower(), s.lang());
6336 }
6337 if (IsPC)
6338 {
6339 _ = (n + 1) / 2;
6340 if (a.vPotential < n && !flag2)
6341 {
6342 Msg.Say("noSpellStock");
6343 EInput.Consume();
6344 return false;
6345 }
6346 if (num4 > 0 && (a.vPotential >= n * 2 || flag2))
6347 {
6348 if (!flag2)
6349 {
6350 a.vPotential -= n * 2;
6351 }
6352 num6 = num6 * (100 - num4 * 20) / 100;
6353 }
6354 else if (!flag2)
6355 {
6356 a.vPotential -= n;
6357 }
6359 }
6360 }
6361 else
6362 {
6363 if (IsPC && a.vPotential < 0 && !flag2 && !a.HasTag("dontForget"))
6364 {
6365 Msg.Say("noSpellStock");
6366 EInput.Consume();
6367 return false;
6368 }
6369 if (a.source.langAct.Length != 0 && tc != null)
6370 {
6371 string text = a.source.langAct[0];
6372 string text2 = ((a.source.langAct.Length >= 2) ? a.source.langAct[1] : "");
6373 if (text == "spell_hand")
6374 {
6375 string[] list2 = Lang.GetList("attack" + race.meleeStyle.IsEmpty("Touch"));
6376 string @ref = text2.lang(list2[4]);
6377 Say(tc.IsPCParty ? "cast_hand_ally" : "cast_hand", this, tc, @ref, tc.IsPCParty ? list2[1] : list2[2]);
6378 }
6379 else
6380 {
6381 Say(text, this, tc, text2.IsEmpty() ? "" : text2.lang());
6382 }
6383 if (a.source.id == 6630)
6384 {
6385 Talk("insult_" + (base.IsMale ? "m" : "f"));
6386 }
6387 }
6388 }
6389 switch (cost.type)
6390 {
6391 case Act.CostType.MP:
6392 if (Evalue(1421) >= 2 && base.hp <= MaxHP / Mathf.Max(1, 9 - Evalue(1421) * 2))
6393 {
6394 num6 /= 2;
6395 }
6396 if (isSynced)
6397 {
6398 PlayEffect("cast");
6399 }
6400 mana.Mod(-num6);
6401 if (isDead)
6402 {
6403 return true;
6404 }
6405 elements.ModExp(304, Mathf.Clamp(num6 * 2, 1, 200));
6406 break;
6407 case Act.CostType.SP:
6408 {
6409 int value = stamina.value;
6410 stamina.Mod(-num6);
6411 if (IsPC && a.HasTag("recovery"))
6412 {
6413 EClass.player.staminaRecovery += value - stamina.value;
6414 }
6415 ignoreSPAbsorb = true;
6416 break;
6417 }
6418 }
6419 if (a is Spell && GetCondition<ConSilence>() != null)
6420 {
6421 Say("cast_silence", this);
6422 return true;
6423 }
6424 if (isDead)
6425 {
6426 return true;
6427 }
6428 int spellExp = elements.GetSpellExp(this, a, num5);
6429 if (EClass.rnd(100) >= CalcCastingChance(a, n) && !EClass.debug.godMode)
6430 {
6431 Say("fizzle", this);
6432 PlayEffect("fizzle");
6433 PlaySound("fizzle");
6434 if (cost.cost > 0 && a.source.lvFactor > 0)
6435 {
6436 ModExp(a.id, spellExp / 5);
6437 }
6438 RemoveCondition<ConInvisibility>();
6439 return true;
6440 }
6441 bool flag3 = true;
6442 if (a.source.cooldown > 0 && (!IsPC || !a.source.tag.Contains("CD_npc")))
6443 {
6444 AddCooldown(a.id, a.source.cooldown);
6445 }
6446 if (HasTalk("phrase_" + a.source.alias))
6447 {
6448 EClass.player.forceTalk = true;
6449 Talk("phrase_" + a.source.alias);
6450 }
6451 if (pt)
6452 {
6453 Act.forcePt = true;
6454 if (flag)
6455 {
6456 ForeachEnemy(delegate(Chara c)
6457 {
6458 a.Perform(this, c, c.pos);
6459 });
6460 }
6461 else
6462 {
6463 ForeachParty(delegate(Chara c)
6464 {
6465 a.Perform(this, c, c.pos);
6466 });
6467 }
6468 Act.forcePt = false;
6469 }
6470 else
6471 {
6472 for (int num7 = 0; num7 < num3; num7++)
6473 {
6474 if (a.TargetType != TargetType.SelfParty && tc != null && !tc.IsAliveInCurrentZone)
6475 {
6476 break;
6477 }
6478 ActEffect.RapidCount = num7;
6479 ActEffect.RapidDelay = a.RapidDelay;
6480 flag3 = a.Perform(this, tc, pos);
6481 }
6482 }
6483 if (flag3 && !isDead)
6484 {
6485 if (IsPC && flag2 && elements.Base(a.id) == 0 && a.PotentialAsStock)
6486 {
6487 elements.ModBase(a.id, 1);
6488 }
6489 if (cost.cost > 0 && a.source.lvFactor > 0)
6490 {
6491 ModExp(a.id, spellExp);
6492 }
6493 }
6494 ActEffect.RapidCount = 0;
6495 if (flag3 && !a.source.tag.Contains("keepInvisi") && EClass.rnd(2) == 0)
6496 {
6497 RemoveCondition<ConInvisibility>();
6498 RemoveCondition<ConDark>();
6499 }
6500 if (!base.IsPCFactionOrMinion && a.HasTag("specialAbility") && renderer.isSynced)
6501 {
6502 string name = a.Name;
6503 renderer.Say("| " + name + " ");
6504 }
6505 return flag3;
6506 void ForeachEnemy(Action<Chara> action)
6507 {
6508 if (_pts.Count == 0)
6509 {
6510 for (int num8 = EClass._map.charas.Count - 1; num8 >= 0; num8--)
6511 {
6512 Chara chara = EClass._map.charas[num8];
6513 if (chara != this && CanSeeLos(chara) && chara.IsHostile(this))
6514 {
6515 _pts.Add(chara);
6516 }
6517 }
6518 }
6519 for (int num9 = _pts.Count - 1; num9 >= 0; num9--)
6520 {
6521 action(_pts[num9]);
6522 }
6523 }
6524 void ForeachParty(Action<Chara> action)
6525 {
6526 if (_pts.Count == 0)
6527 {
6528 if (IsPCParty)
6529 {
6530 for (int num8 = EClass.pc.party.members.Count - 1; num8 >= 0; num8--)
6531 {
6532 Chara chara = EClass.pc.party.members[num8];
6533 if (chara == this || chara.host != null || CanSeeLos(chara))
6534 {
6535 _pts.Add(chara);
6536 }
6537 }
6538 }
6539 else
6540 {
6541 for (int num9 = EClass._map.charas.Count - 1; num9 >= 0; num9--)
6542 {
6543 Chara chara2 = EClass._map.charas[num9];
6544 if ((chara2 == this || (chara2.IsFriendOrAbove(this) && CanSeeLos(chara2))) && (chara2 == tc || _pts.Count < 3 || EClass.rnd(_pts.Count * _pts.Count) > 6))
6545 {
6546 _pts.Add(chara2);
6547 }
6548 }
6549 }
6550 }
6551 int num10 = _pts.IndexOf(this);
6552 if (num10 != -1)
6553 {
6554 _pts.RemoveAt(num10);
6555 _pts.Insert(0, this);
6556 }
6557 for (int num11 = _pts.Count - 1; num11 >= 0; num11--)
6558 {
6559 action(_pts[num11]);
6560 }
6561 }
6562 }
6563
6564 public int EvalueRiding()
6565 {
6566 if (ride != null && ride.HasCondition<ConTransmuteBroom>() && HasElement(1417))
6567 {
6568 return 25 + Evalue(226) * 125 / 100;
6569 }
6570 return Evalue(226);
6571 }
6572
6573 public int CalcCastingChance(Element e, int num = 1)
6574 {
6575 if (!(e is Spell))
6576 {
6577 return 100;
6578 }
6579 if (!IsPC)
6580 {
6581 int num2 = 95;
6582 if (host != null)
6583 {
6584 if (host.ride == this)
6585 {
6586 return num2 * 100 / (100 + 300 / Mathf.Max(5, 10 + host.EvalueRiding()));
6587 }
6588 if (host.parasite == this)
6589 {
6590 return num2 * 100 / (100 + 300 / Mathf.Max(5, 10 + host.Evalue(227)));
6591 }
6592 }
6593 return num2;
6594 }
6595 int num3 = Evalue(304);
6596 if (!IsPCFaction)
6597 {
6598 num3 = Mathf.Max(num3, base.LV + 5);
6599 }
6600 int num4 = 0;
6601 int num5 = 0;
6602 bool num6 = GetArmorSkill() == 122;
6603 AttackStyle attackStyle = body.GetAttackStyle();
6604 if (num6)
6605 {
6606 num4 = 20 - Evalue(122) / 5;
6607 num5 += 10 - Evalue(1654) * 4;
6608 }
6609 else
6610 {
6611 num4 = 10 - Evalue(120) / 5;
6612 }
6613 if (num4 < 5)
6614 {
6615 num4 = 5;
6616 }
6617 if (ride != null)
6618 {
6619 num4 += 5;
6620 }
6621 if (parasite != null)
6622 {
6623 num4 += 10;
6624 }
6625 if (attackStyle == AttackStyle.TwoWield)
6626 {
6627 num4 += 5;
6628 }
6629 if (attackStyle == AttackStyle.Shield)
6630 {
6631 num4 += 10;
6632 num5 += 20 - Evalue(1654) * 8;
6633 }
6634 if (isConfused)
6635 {
6636 num4 += 10000;
6637 }
6638 if (HasCondition<ConDim>())
6639 {
6640 num4 += ((Evalue(1654) >= 3) ? 1500 : 2500);
6641 }
6642 if (num > 1)
6643 {
6644 num4 += 5 * num;
6645 }
6646 if (num5 < 0)
6647 {
6648 num5 = 0;
6649 }
6650 return Mathf.Clamp(100 + e.Value - 10 - e.source.LV * e.source.cost[0] * num4 / Mathf.Max(10 + num3 * 10, 1), 0, 100 - num5);
6651 }
6652
6653 public void DoAI(int wait, Action onPerform)
6654 {
6655 SetAI(new DynamicAIAct("", delegate
6656 {
6657 onPerform();
6658 return true;
6659 })
6660 {
6661 wait = wait
6662 });
6663 }
6664
6665 public void Cuddle(Chara c, bool headpat = false)
6666 {
6667 Talk("goodBoy");
6668 Say(headpat ? "headpat" : "cuddle", this, c);
6669 c.ShowEmo(Emo.love);
6670 if (EClass.rnd(IsPC ? 100 : 5000) == 0)
6671 {
6672 c.MakeEgg();
6673 }
6674 if (headpat && this != c)
6675 {
6676 if (c.interest > 0)
6677 {
6678 c.ModAffinity(EClass.pc, 1 + EClass.rnd(3));
6679 c.interest -= 20 + EClass.rnd(10);
6680 }
6682 {
6683 foreach (Chara member in c.party.members)
6684 {
6685 if (!member.IsPC && CanSeeLos(member))
6686 {
6687 member.AddCondition<ConEuphoric>(100 + Evalue(6904) * 5);
6688 }
6689 }
6690 }
6691 }
6692 if (c.Evalue(1221) > 0)
6693 {
6694 int ele = ((c.MainElement == Element.Void) ? 924 : c.MainElement.id);
6695 if (c.id == "hedgehog_ether")
6696 {
6697 ele = 922;
6698 }
6699 Say("reflect_thorne", this, c);
6700 DamageHP(10L, ele, Power, AttackSource.Condition);
6701 }
6702 }
6703
6704 public void Kiss(Chara c)
6705 {
6706 EClass.player.forceTalk = true;
6707 Talk("kiss", null, null, IsPC);
6708 PlaySound("kiss");
6709 renderer.PlayAnime(AnimeID.Kiss, c);
6710 int num = 2 + EClass.rnd(4) + ((!c.IsPC && c.affinity.CurrentStage < Affinity.Stage.Fond) ? (-EClass.rnd(10)) : 0);
6711 c.ShowEmo((num > 0) ? Emo.love : Emo.sad);
6712 if (num > 0 && EClass.rnd(IsPC ? 100 : 5000) == 0)
6713 {
6714 c.MakeEgg();
6715 }
6716 if (IsPC && this != c)
6717 {
6718 if (c.interest > 0)
6719 {
6720 c.ModAffinity(EClass.pc, num);
6721 c.interest -= 20 + EClass.rnd(10);
6722 }
6723 else
6724 {
6725 c.Say("affinityNone", c, EClass.pc);
6726 }
6727 }
6728 Effect.Get("love")._Play(pos, isSynced ? renderer.position : pos.Position(), 0f, c.pos);
6729 }
6730
6731 public void Slap(Chara c, bool slapToDeath = false)
6732 {
6733 if (id == "olderyoungersister")
6734 {
6736 }
6737 PlaySound("whip");
6738 Say("slap", this, c);
6739 c.PlayAnime(AnimeID.Shiver);
6740 c.DamageHP(slapToDeath ? (c.MaxHP * 2) : (5 + EClass.rndHalf(EClass.pc.MaxHP / 3)), 919, 100, AttackSource.Condition);
6741 c.OnInsulted();
6742 if (slapToDeath && c.IsAliveInCurrentZone)
6743 {
6744 c.Die();
6745 }
6746 }
6747
6748 public Chara SetEnemy(Chara c = null)
6749 {
6750 enemy = c;
6751 if (c == null)
6752 {
6753 if (ai is GoalCombat)
6754 {
6755 ai.Cancel();
6756 }
6757 }
6758 else
6759 {
6760 calmCheckTurn = 10 + EClass.rnd(30);
6761 }
6762 return c;
6763 }
6764
6765 public void TrySetEnemy(Chara c)
6766 {
6767 if ((!IsPC || !EClass.game.config.autoCombat.bDontChangeTarget) && (enemy == null || (EClass.rnd(5) == 0 && Dist(c) <= 1)) && ((!IsPCFaction && !IsPCFactionMinion) || (!c.IsPCFaction && !c.IsPCFactionMinion)) && (hostility != Hostility.Enemy || c.hostility != Hostility.Enemy) && (!c.IsPC || hostility < Hostility.Neutral))
6768 {
6769 SetEnemy(c);
6770 }
6771 }
6772
6773 public void GoHostile(Card _tg)
6774 {
6775 if (enemy == null && !IsPC)
6776 {
6777 if (GetInt(106) == 0)
6778 {
6779 TalkTopic("aggro");
6780 }
6781 if (OriginalHostility != Hostility.Enemy)
6782 {
6783 ShowEmo(Emo.angry);
6784 }
6785 SetEnemy(_tg.Chara);
6786 }
6787 if (!IsPCFaction && !IsPCFactionMinion && (_tg.IsPCFaction || _tg.IsPCFactionMinion))
6788 {
6789 if (hostility >= Hostility.Neutral)
6790 {
6791 Say("angry", this);
6792 }
6793 hostility = Hostility.Enemy;
6794 }
6795 }
6796
6797 public void DoHostileAction(Card _tg, bool immediate = false)
6798 {
6799 if (_tg == null || !_tg.isChara)
6800 {
6801 return;
6802 }
6803 Chara chara = _tg.Chara;
6804 if (chara.IsPC)
6805 {
6806 EClass.pc.combatCount = 10;
6807 }
6808 if (!chara.IsAliveInCurrentZone || !IsAliveInCurrentZone || chara == this)
6809 {
6810 return;
6811 }
6812 if ((IsPCFaction || IsPCFactionMinion) && (chara.IsPCFaction || chara.IsPCFactionMinion))
6813 {
6814 chara.Say("frown", this, chara);
6815 }
6816 else
6817 {
6818 if (EClass._zone.IsRegion)
6819 {
6820 return;
6821 }
6822 if (IsPC)
6823 {
6824 if (chara.IsFriendOrAbove() && !immediate)
6825 {
6826 chara.Say("frown", this, chara);
6827 chara.ShowEmo(Emo.sad);
6828 chara.hostility = Hostility.Neutral;
6829 return;
6830 }
6831 if (!chara.IsPCFaction && chara.hostility >= Hostility.Neutral && !EClass._zone.IsPCFaction)
6832 {
6833 bool flag = chara.id == "fanatic";
6834 if (EClass.rnd(4) == 0 || flag)
6835 {
6836 chara.Say("callHelp", chara);
6837 chara.CallHelp(this, flag);
6838 }
6839 }
6840 if (chara.hostility <= Hostility.Enemy)
6841 {
6842 foreach (Chara member in EClass.pc.party.members)
6843 {
6844 if (member != EClass.pc && member.enemy == null && member.CanSee(chara))
6845 {
6846 member.SetEnemy(chara);
6847 }
6848 }
6849 }
6850 }
6851 else if (chara.IsPC && hostility <= Hostility.Enemy)
6852 {
6853 foreach (Chara member2 in EClass.pc.party.members)
6854 {
6855 if (member2 != EClass.pc && member2.enemy == null && member2.CanSee(this))
6856 {
6857 member2.SetEnemy(this);
6858 }
6859 }
6860 }
6861 if (chara.calmCheckTurn <= 0 || IsPC)
6862 {
6863 chara.calmCheckTurn = (IsPC ? (20 + EClass.rnd(30)) : (10 + EClass.rnd(10)));
6864 }
6865 if (hostility != Hostility.Enemy || chara.hostility != Hostility.Enemy)
6866 {
6867 GoHostile(chara);
6868 chara.GoHostile(this);
6869 if (base.isHidden && !chara.CanSee(this) && !chara.IsDisabled && !chara.IsPCParty && !chara.IsPCPartyMinion && EClass.rnd(10 + Dist(chara) * 10) == 0)
6870 {
6871 Thing t = ThingGen.Create("49");
6872 ActThrow.Throw(chara, pos, t);
6873 Act.TC = chara;
6874 }
6875 }
6876 }
6877 }
6878
6879 public void CallHelp(Chara tg, bool fanatic = false)
6880 {
6881 foreach (Chara chara in EClass._map.charas)
6882 {
6883 if (!chara.IsPCFaction && chara.OriginalHostility == OriginalHostility && (fanatic || Dist(chara) <= 6) && (EClass.rnd(3) != 0 || fanatic))
6884 {
6885 chara.GoHostile(tg);
6886 }
6887 }
6888 }
6889
6890 public bool FindNewEnemy()
6891 {
6892 if (EClass._zone.isPeace && base.IsPCFactionOrMinion && !IsPC)
6893 {
6894 return false;
6895 }
6896 if (enemy != null && !enemy.IsAliveInCurrentZone)
6897 {
6898 enemy = null;
6899 }
6900 if (enemy != null)
6901 {
6902 return false;
6903 }
6904 if (IsPCParty && EClass.pc.isHidden && base.isHidden)
6905 {
6906 return false;
6907 }
6908 if (mimicry != null && mimicry.IsThing)
6909 {
6910 return false;
6911 }
6912 if (!base.IsPCFactionOrMinion && OriginalHostility == Hostility.Neutral && !(trait is TraitGuard) && id != "unicorn")
6913 {
6914 return false;
6915 }
6916 bool flag = enemy != null || ai is GoalCombat;
6917 int num = (base.PER + Evalue(210) * 2) * ((!flag) ? 1 : 2);
6918 bool flag2 = IsPCParty && !IsPC && EClass.game.config.tactics.dontWander;
6919 bool flag3 = !IsPCParty;
6920 Chara chara = null;
6921 int num2 = 9999;
6922 for (int i = 0; i < EClass._map.charas.Count; i++)
6923 {
6924 Chara chara2 = EClass._map.charas[i];
6925 if (chara2 == this || !IsHostile(chara2) || !CanSee(chara2) || (chara2.mimicry != null && chara2.mimicry.IsThing))
6926 {
6927 continue;
6928 }
6929 int num3 = Dist(chara2);
6930 int num4 = GetSightRadius() + (flag ? 1 : 0);
6931 if (num3 > num4)
6932 {
6933 continue;
6934 }
6935 if (flag3 && EClass.rnd(chara2.Evalue(152) + 5) * (100 + num3 * num3 * 10) / 100 > EClass.rnd(num))
6936 {
6937 if (this == pos.FirstChara)
6938 {
6939 chara2.ModExp(152, Mathf.Clamp((num - chara2.Evalue(152)) / 2, 1, Mathf.Max(30 - stealthSeen * 2, 1)));
6940 }
6941 stealthSeen++;
6942 }
6943 else if (CanSeeLos(chara2) && (!flag2 || EClass.pc.isBlind || EClass.pc.CanSeeLos(chara2)) && (!base.IsPCFactionOrMinion || EClass.pc.ai.ShouldAllyAttack(chara2)))
6944 {
6945 if (!IsPCParty)
6946 {
6947 DoHostileAction(chara2);
6948 enemy = chara2;
6949 return true;
6950 }
6951 if (num3 < num2)
6952 {
6953 num2 = num3;
6954 chara = chara2;
6955 }
6956 }
6957 }
6958 if (chara != null)
6959 {
6960 DoHostileAction(chara);
6961 enemy = chara;
6962 return true;
6963 }
6964 return false;
6965 }
6966
6968 {
6969 for (int i = 0; i < EClass._map.charas.Count; i++)
6970 {
6971 Chara chara = EClass._map.charas[i];
6972 if (chara != this && chara != enemy && (chara.mimicry == null || !chara.mimicry.IsThing) && IsHostile(chara) && Dist(chara) <= 1 && CanInteractTo(chara.pos))
6973 {
6974 DoHostileAction(chara);
6975 enemy = chara;
6976 return true;
6977 }
6978 }
6979 return false;
6980 }
6981
6982 public bool IsHostile()
6983 {
6984 return hostility <= Hostility.Enemy;
6985 }
6986
6987 public bool IsHostile(Chara c)
6988 {
6989 if (c == null)
6990 {
6991 return false;
6992 }
6993 if (base.IsPCFactionOrMinion)
6994 {
6995 if (((c == EClass.pc.enemy || c == enemy) && !c.IsPCFactionOrMinion) || c.hostility <= Hostility.Enemy)
6996 {
6997 return true;
6998 }
6999 }
7000 else
7001 {
7002 if (trait is TraitGuard && c.IsPCParty && EClass.player.IsCriminal && EClass._zone.instance == null)
7003 {
7004 return true;
7005 }
7006 if (OriginalHostility >= Hostility.Friend)
7007 {
7008 if (hostility <= Hostility.Enemy && c.IsPCFactionOrMinion)
7009 {
7010 return true;
7011 }
7012 if (c.hostility <= Hostility.Enemy && c.OriginalHostility == Hostility.Enemy)
7013 {
7014 return true;
7015 }
7016 }
7017 else if (OriginalHostility <= Hostility.Enemy && (c.IsPCFactionOrMinion || (c.OriginalHostility != Hostility.Enemy && c.hostility >= Hostility.Friend)))
7018 {
7019 return true;
7020 }
7021 }
7022 if (id == "unicorn" && (Evalue(418) < 0 || (c.HasElement(1216) && c.Evalue(418) < 1)))
7023 {
7024 return true;
7025 }
7026 return false;
7027 }
7028
7029 public bool IsNeutral()
7030 {
7031 return hostility == Hostility.Neutral;
7032 }
7033
7034 public bool IsNeutralOrAbove()
7035 {
7036 return hostility >= Hostility.Neutral;
7037 }
7038
7039 public bool IsBranchMember()
7040 {
7041 if (faction == EClass.Home)
7042 {
7043 return homeZone == EClass.game.activeZone;
7044 }
7045 return false;
7046 }
7047
7048 public bool IsHomeMember()
7049 {
7050 return faction == EClass.Home;
7051 }
7052
7053 public bool IsInHomeZone()
7054 {
7055 return EClass.game.activeZone == currentZone;
7056 }
7057
7058 public bool IsInSpot<T>() where T : TraitSpot
7059 {
7060 foreach (T item in EClass._map.props.installed.traits.List<T>())
7061 {
7062 foreach (Point item2 in item.ListPoints())
7063 {
7064 if (pos.Equals(item2))
7065 {
7066 return true;
7067 }
7068 }
7069 }
7070 return false;
7071 }
7072
7073 public bool IsGuest()
7074 {
7075 return memberType == FactionMemberType.Guest;
7076 }
7077
7078 public bool IsFriendOrAbove()
7079 {
7080 return hostility >= Hostility.Friend;
7081 }
7082
7083 public bool IsFriendOrAbove(Chara c)
7084 {
7085 if (base.IsPCFactionOrMinion || IsFriendOrAbove())
7086 {
7088 {
7089 return true;
7090 }
7091 }
7092 else if (IsHostile() && c.IsHostile())
7093 {
7094 return true;
7095 }
7096 return false;
7097 }
7098
7100 {
7101 CardRenderer cardRenderer = renderer;
7102 CharaRenderer charaRenderer = new CharaRenderer();
7103 if (source.skinAntiSpider != 0)
7104 {
7105 base.idSkin = (EClass.core.config.game.antiSpider ? source.skinAntiSpider : 0);
7106 }
7107 if (host != null)
7108 {
7109 charaRenderer.pccData = PCCData.Create("ride");
7110 string idPart = base.c_idRidePCC.IsEmpty(EClass.core.pccs.sets["ride"].map["body"].map.Keys.First());
7111 charaRenderer.pccData.SetPart("body", "ride", idPart);
7112 charaRenderer.pccData.ride = EClass.core.pccs.GetRideData(idPart);
7113 }
7114 else
7115 {
7116 foreach (Condition condition in conditions)
7117 {
7118 RendererReplacer rendererReplacer = condition.GetRendererReplacer();
7119 if (rendererReplacer != null)
7120 {
7121 charaRenderer.replacer = rendererReplacer;
7122 charaRenderer.data = rendererReplacer.data;
7123 charaRenderer.pccData = rendererReplacer.pccData;
7124 break;
7125 }
7126 }
7127 if (charaRenderer.replacer == null)
7128 {
7129 charaRenderer.pccData = pccData;
7130 }
7131 }
7132 renderer = charaRenderer;
7133 renderer.SetOwner(this);
7134 if (cardRenderer != null)
7135 {
7136 renderer.SetFirst(first: false, cardRenderer.position);
7137 }
7138 return charaRenderer;
7139 }
7140
7141 public void SetPCCState(PCCState state)
7142 {
7143 if (IsPCC)
7144 {
7145 PCC.Get(pccData).Build(state);
7146 }
7147 }
7148
7149 public override Sprite GetSprite(int dir = 0)
7150 {
7151 string str = GetStr("sprite_override");
7152 if (!str.IsEmpty() && (spriteReplacer == null || spriteReplacer != SpriteReplacer.dictOverrides.TryGetValue(str)))
7153 {
7154 Sprite sprite = ModUtil.LoadSprite(str);
7155 if ((bool)sprite)
7156 {
7157 return sprite;
7158 }
7159 }
7160 if (IsPCC)
7161 {
7162 PCC pCC = PCC.Get(pccData);
7163 pCC.Build();
7164 return pCC.variation.idle[0, 0];
7165 }
7166 bool snow = EClass.core.IsGameStarted && EClass._zone.IsSnowCovered;
7167 return GetSpriteData(dir, snow)?.GetSprite() ?? sourceCard.GetSprite(dir, SpriteSkin, snow);
7168 }
7169
7170 public override SpriteData GetSpriteData(int dir = 0, bool snow = false)
7171 {
7172 SpriteData spriteData = sourceCard.GetSpriteData(dir, SpriteSkin, snow, this);
7173 if (!IsPCC)
7174 {
7175 if (spriteReplacer?.data == null)
7176 {
7177 return spriteData;
7178 }
7179 return spriteReplacer.GetData(dir, 0, snow, this);
7180 }
7181 return null;
7182 }
7183
7184 public void SetTempHand(int right = 0, int left = 0)
7185 {
7186 if (IsPC && !IsPC)
7187 {
7188 pccData.tempRight = EClass.scene.screenElin.renderTempEQ.ConvertTile(right);
7189 pccData.tempLeft = EClass.scene.screenElin.renderTempEQ.ConvertTile(left);
7190 }
7191 }
7192
7193 public override SubPassData GetSubPassData()
7194 {
7195 if (IsPCC)
7196 {
7197 if (IsDeadOrSleeping || (!EClass.player.altHeldPos && parent is Chara))
7198 {
7200 }
7201 }
7202 else if (conSleep != null && host == null && pos.Equals(EClass.pc.pos) && IsHuman && (GetBool(123) || affinity.CanSleepBeside()))
7203 {
7204 return EClass.setting.pass.subDead;
7205 }
7206 return SubPassData.Default;
7207 }
7208
7209 public override void SetRenderParam(RenderParam p)
7210 {
7211 p.mat = base.material;
7212 p.matColor = base.colorInt;
7213 if (!renderer.usePass)
7214 {
7215 return;
7216 }
7217 if (renderer.replacer != null)
7218 {
7219 p.tile = renderer.replacer.tile * ((!flipX) ? 1 : (-1));
7220 if (renderer.replacer.mat != -1)
7221 {
7222 p.mat = EClass.sources.materials.rows.TryGet(renderer.replacer.mat, 0);
7223 p.matColor = BaseTileMap.GetColorInt(ref p.mat.matColor, 100);
7224 p.color -= 1048576f;
7225 }
7226 }
7227 else if (source._tiles_snow.Length != 0 && EClass._zone.IsSnowCovered)
7228 {
7229 if (source._tiles_snow.Length > 1)
7230 {
7231 int num = ((base.idSkin != 0 || source.staticSkin) ? base.idSkin : (base.uid % source._tiles_snow.Length / 2 * 2 + ((!base.IsMale) ? 1 : 0)));
7232 if (num < 0)
7233 {
7234 num = 0;
7235 }
7236 p.tile = source._tiles_snow[(num < source._tiles_snow.Length) ? num : 0] * ((!flipX) ? 1 : (-1));
7237 }
7238 else
7239 {
7240 p.tile = source._tiles_snow[0] * ((!flipX) ? 1 : (-1));
7241 }
7242 }
7243 else if (sourceCard._tiles.Length > 1)
7244 {
7245 int num2 = ((base.idSkin != 0 || source.staticSkin) ? base.idSkin : (base.uid % sourceCard._tiles.Length / 2 * 2 + ((!base.IsMale) ? 1 : 0)));
7246 if (num2 < 0)
7247 {
7248 num2 = 0;
7249 }
7250 p.tile = sourceCard._tiles[(num2 >= 0 && num2 < sourceCard._tiles.Length) ? num2 : 0] * ((!flipX) ? 1 : (-1));
7251 }
7252 else
7253 {
7254 p.tile = sourceCard._tiles[0] * ((!flipX) ? 1 : (-1));
7255 }
7256 p.dir = base.dir;
7257 }
7258
7259 public override string GetHoverText()
7260 {
7261 if (mimicry != null && mimicry.IsThing)
7262 {
7263 return mimicry.GetHoverText();
7264 }
7265 string text = ((mimicry != null && mimicry.Card != this) ? mimicry.GetName(NameStyle.Full) : base.Name);
7266 if (IsFriendOrAbove())
7267 {
7268 text = text.TagColor(EClass.Colors.colorFriend);
7269 }
7270 else if (IsHostile())
7271 {
7272 text = text.TagColor(EClass.Colors.colorHostile);
7273 }
7274 int num = 2;
7275 int lV = EClass.pc.LV;
7276 if (base.LV >= lV * 5)
7277 {
7278 num = 0;
7279 }
7280 else if (base.LV >= lV * 2)
7281 {
7282 num = 1;
7283 }
7284 else if (base.LV <= lV / 4)
7285 {
7286 num = 4;
7287 }
7288 else if (base.LV <= lV / 2)
7289 {
7290 num = 3;
7291 }
7292 string text2 = Lang.GetList("lvComparison")[num];
7293 text2 = (" (" + text2 + ") ").TagSize(14).TagColor(EClass.Colors.gradientLVComparison.Evaluate(0.25f * (float)num));
7294 string s = (IsFriendOrAbove() ? "HostilityAlly" : (IsNeutral() ? "HostilityNeutral" : "HostilityEnemy"));
7295 s = (" (" + s.lang() + ") ").TagSize(14);
7296 s = "";
7297 if (memberType == FactionMemberType.Guest)
7298 {
7299 s += (" (" + "guest".lang() + ") ").TagSize(14);
7300 }
7301 else if (memberType == FactionMemberType.Livestock)
7302 {
7303 s += (" (" + "livestock".lang() + ") ").TagSize(14);
7304 }
7305 if (!EClass.pc.IsMoving)
7306 {
7307 if (EClass.pc.HasHigherGround(this))
7308 {
7309 text2 += "lowerGround".lang();
7310 }
7311 else if (HasHigherGround(EClass.pc))
7312 {
7313 text2 += "higherGround".lang();
7314 }
7315 }
7316 if (Evalue(1232) > 0)
7317 {
7318 text2 = "milkBaby".lang().TagSize(14) + text2;
7319 }
7320 if (Guild.Fighter.ShowBounty(this) && Guild.Fighter.HasBounty(this))
7321 {
7322 text2 = "hasBounty".lang().TagSize(14) + text2;
7323 }
7324 if (EClass.pc.HasElement(481))
7325 {
7326 text2 += ("(" + faith.Name + ")").TagSize(14);
7327 }
7328 if (EClass.pc.HasElement(6607))
7329 {
7330 s += CraftUtil.GetBloodText(this).TagSize(14).TagColor(EClass.Colors.colorBlood);
7331 }
7332 return text + text2 + s;
7333 }
7334
7335 public override string GetHoverText2()
7336 {
7337 if (mimicry != null && mimicry.IsThing)
7338 {
7339 return mimicry.GetHoverText2();
7340 }
7341 string text = "";
7342 if (knowFav)
7343 {
7344 text += Environment.NewLine;
7345 text = text + "<size=14>" + "favgift".lang(GetFavCat().GetName().ToLower(), GetFavFood().GetName()) + "</size>";
7346 }
7347 string text2 = "";
7349 {
7350 text2 += Environment.NewLine;
7351 text2 = text2 + "Lv:" + base.LV + " HP:" + base.hp + "/" + MaxHP + " MP:" + mana.value + "/" + mana.max + " DV:" + DV + " PV:" + PV + " Hunger:" + hunger.value;
7352 text2 += Environment.NewLine;
7353 text2 = text2 + "Global:" + IsGlobal + " AI:" + ai?.ToString() + " " + source.tactics.IsEmpty(EClass.sources.tactics.map.TryGetValue(id)?.id ?? EClass.sources.tactics.map.TryGetValue(job.id)?.id ?? "predator");
7354 text2 += Environment.NewLine;
7355 text2 = text2 + base.uid + IsMinion + "/" + base.c_uidMaster + "/" + master;
7356 text2 = text2 + " dir:" + base.dir + " skin:" + base.idSkin + " scaled:" + base.isScaled;
7357 }
7358 if (EClass.pc.held?.trait is TraitWhipLove && IsPCFaction)
7359 {
7360 text2 += Environment.NewLine;
7361 text2 += "<size=14>";
7362 foreach (Hobby item in ListWorks())
7363 {
7364 text2 = text2 + item.Name + ", ";
7365 }
7366 foreach (Hobby item2 in ListHobbies())
7367 {
7368 text2 = text2 + item2.Name + ", ";
7369 }
7370 text2 = text2.TrimEnd(", ".ToCharArray()) + "</size>";
7371 }
7372 string text3 = "";
7373 IEnumerable<BaseStats> enumerable = conditions.Concat((!IsPCFaction) ? new BaseStats[0] : new BaseStats[2] { hunger, stamina });
7374 if (enumerable.Count() > 0)
7375 {
7376 text3 += Environment.NewLine;
7377 text3 += "<size=14>";
7378 int num = 0;
7379 foreach (BaseStats item3 in enumerable)
7380 {
7381 if (item3 is ConBaseTransmuteMimic)
7382 {
7383 continue;
7384 }
7385 string text4 = item3.GetPhaseStr();
7386 if (text4.IsEmpty() || text4 == "#")
7387 {
7388 continue;
7389 }
7390 Color c = Color.white;
7391 switch (item3.source.group)
7392 {
7393 case "Bad":
7394 case "Debuff":
7395 case "Disease":
7397 break;
7398 case "Buff":
7400 break;
7401 }
7403 {
7404 text4 = text4 + "(" + item3.GetValue() + ")";
7405 if (resistCon != null && resistCon.ContainsKey(item3.id))
7406 {
7407 text4 = text4 + "{" + resistCon[item3.id] + "}";
7408 }
7409 }
7410 num++;
7411 text3 = text3 + text4.TagColor(c) + ", ";
7412 }
7413 if (num == 0)
7414 {
7415 text3 = "";
7416 }
7417 else
7418 {
7419 text = "";
7420 text3 = text3.TrimEnd(", ".ToCharArray()) + "</size>";
7421 }
7422 }
7424 {
7425 text3 += Environment.NewLine;
7426 foreach (ActList.Item item4 in ability.list.items)
7427 {
7428 text3 = text3 + item4.act.Name + ", ";
7429 }
7430 text3 = text3.TrimEnd(", ".ToCharArray());
7431 }
7432 return text + text2 + text3;
7433 }
7434
7435 public string GetTopicText(string topic = "calm")
7436 {
7437 ConTransmuteHuman condition = GetCondition<ConTransmuteHuman>();
7438 string key = ((condition == null) ? source : condition.chara.source).idText.IsEmpty((condition == null) ? id : condition.chara.id);
7439 if (id == "littleOne" && EClass._zone is Zone_LittleGarden)
7440 {
7441 key = "littleOne2";
7442 }
7443 SourceCharaText.Row row = EClass.sources.charaText.map.TryGetValue(key);
7444 if (row == null)
7445 {
7446 return null;
7447 }
7448 string text = row.GetText(topic, returnNull: true);
7449 if (text.IsEmpty())
7450 {
7451 return null;
7452 }
7453 if (text.StartsWith("@"))
7454 {
7455 row = EClass.sources.charaText.map.TryGetValue(text.Replace("@", ""));
7456 if (row == null)
7457 {
7458 return null;
7459 }
7460 text = row.GetText(topic, returnNull: true);
7461 if (text.IsEmpty())
7462 {
7463 return null;
7464 }
7465 }
7466 return text.Split(Environment.NewLine.ToCharArray()).RandomItem();
7467 }
7468
7469 public string TalkTopic(string topic = "calm")
7470 {
7471 if (host == null && !IsInActiveZone)
7472 {
7473 return null;
7474 }
7475 if (!isSynced && (host == null || !host.isSynced) && topic != "dead")
7476 {
7477 return null;
7478 }
7479 if (IsPCParty)
7480 {
7481 int num = EClass.pc.party.members.Count - 1;
7482 switch (topic)
7483 {
7484 case "calm":
7485 if (EClass.rnd(num * 5) != 0)
7486 {
7487 return null;
7488 }
7489 break;
7490 case "aggro":
7491 if (EClass.rnd(num * 10) != 0)
7492 {
7493 return null;
7494 }
7495 break;
7496 case "kill":
7497 if (EClass.rnd(num * 3) != 0)
7498 {
7499 return null;
7500 }
7501 break;
7502 case "fov":
7503 return null;
7504 }
7505 }
7506 string topicText = GetTopicText(topic);
7507 if (topicText.IsEmpty())
7508 {
7509 return null;
7510 }
7511 HashSet<string> obj = new HashSet<string>
7512 {
7513 "_bracketTalk".lang(),
7514 "\"",
7515 "“",
7516 "「"
7517 };
7518 bool flag = topicText.StartsWith("*");
7519 bool flag2 = topicText.StartsWith("(");
7520 bool flag3 = obj.Any(topicText.StartsWith);
7521 topicText = ApplyTone(topicText);
7522 topicText = topicText.Replace('~', '*');
7523 Msg.SetColor(flag2 ? Msg.colors.Thinking : (flag3 ? Msg.colors.Talk : Msg.colors.Ono));
7524 Msg.Say(StripTalkSpecialCharacters(topicText.Replace("&", "")));
7525 if (topic == "dead")
7526 {
7527 EClass.ui.popGame.PopText(ApplyNewLine(topicText.StripBrackets()), null, "PopTextDead", default(Color), pos.Position() + EClass.setting.render.tc.textPosDead);
7528 }
7529 else if (flag || flag3 || flag2)
7530 {
7531 (host ?? this).renderer.Say(ApplyNewLine(topicText.StripBrackets()), default(Color), IsPCParty ? 0.6f : 0f);
7532 }
7533 return topicText;
7534 }
7535
7536 public override Sprite GetImageSprite()
7537 {
7538 return GetSprite();
7539 }
7540
7542 {
7543 memberType = type;
7544 }
7545
7546 public void ShowDialog()
7547 {
7548 Zone_Nymelle zone_Nymelle = EClass._zone as Zone_Nymelle;
7549 if (conSuspend != null && IsPCParty)
7550 {
7551 RemoveCondition<ConSuspend>();
7552 }
7553 if (LayerDrama.forceJump == null)
7554 {
7555 if (IsDeadOrSleeping)
7556 {
7557 ShowDialog("_chara", "sleep");
7558 return;
7559 }
7560 if (EClass.pc.isHidden && !CanSee(EClass.pc))
7561 {
7562 ShowDialog("_chara", "invisible");
7563 return;
7564 }
7565 if (!IsPC && !EClass.player.codex.DroppedCard(id) && affinity.CanGiveCard())
7566 {
7568 ShowDialog("_chara", "give_card");
7569 Thing thing = ThingGen.Create("figure");
7570 thing.MakeFigureFrom(id);
7571 EClass.player.DropReward(thing);
7572 thing = ThingGen.Create("figure3");
7573 thing.MakeFigureFrom(id);
7574 EClass.player.DropReward(thing);
7575 return;
7576 }
7577 if (GetInt(71) == -2)
7578 {
7579 ShowDialog("_chara", "give_lunch");
7580 Thing t = CraftUtil.MakeLoveLunch(this);
7582 SetInt(71, EClass.world.date.GetRaw() + 43200);
7583 return;
7584 }
7585 if (base.isRestrained)
7586 {
7587 ShowDialog("_chara", "strain");
7588 return;
7589 }
7590 if (IsEscorted())
7591 {
7592 ShowDialog("_chara", "escort");
7593 return;
7594 }
7596 {
7597 string step = ((!(EClass._zone is Zone_Wedding)) ? "party" : (IsPCParty ? "wedding_love" : ((IsMarried || affinity.IsWeddingHater) ? "wedding_hater" : "wedding")));
7598 if (EClass._zone is Zone_Wedding && IsPCParty && base.c_love != null && !base.c_love.gaveCutter)
7599 {
7600 step = "wedding_cutter";
7601 EClass.player.DropReward(ThingGen.Create("dagger_cakecutter"));
7602 base.c_love.gaveCutter = true;
7603 }
7604 ShowDialog("_chara", step);
7605 return;
7606 }
7607 if (EClass.game.quests.OnShowDialog(this))
7608 {
7609 return;
7610 }
7611 if (id == "nino")
7612 {
7614 }
7615 switch (id)
7616 {
7617 case "loytel":
7618 {
7620 {
7621 EClass.game.quests.Get("pre_debt_runaway").Complete();
7622 EClass.player.flags.loytelEscaped = false;
7623 EClass.game.quests.Add("debt", "loytel");
7624 ShowDialog("loytel", "loytelEscaped");
7625 return;
7626 }
7627 QuestDebt questDebt = EClass.game.quests.Get<QuestDebt>();
7628 if (questDebt != null && questDebt.paid)
7629 {
7630 questDebt.stage++;
7631 if (questDebt.stage > 7)
7632 {
7633 questDebt.stage = 7;
7634 }
7635 ShowDialog("loytel", "debt" + questDebt.stage);
7636 return;
7637 }
7638 break;
7639 }
7640 case "farris":
7641 if (EClass._zone.id == "startVillage" || EClass._zone.id == "startVillage3" || EClass.game.IsSurvival)
7642 {
7643 ShowDialog("farris");
7644 return;
7645 }
7647 {
7648 case -1:
7649 ShowDialog("farris", "nymelle_noQuest");
7650 break;
7651 case 0:
7652 ShowDialog("farris", "nymelle_first");
7653 break;
7654 case 1:
7655 ShowDialog("farris", "home_first");
7656 break;
7657 default:
7658 ShowDialog("farris");
7659 break;
7660 }
7661 return;
7662 case "ashland":
7663 ShowDialog("ashland");
7664 return;
7665 case "fiama":
7666 if (zone_Nymelle != null && zone_Nymelle.IsCrystalLv && EClass.game.quests.GetPhase<QuestExploration>() == 3)
7667 {
7668 SoundManager.ForceBGM();
7669 LayerDrama.ActivateMain("mono", "nymelle_crystal");
7670 }
7672 {
7674 {
7675 EClass.player.flags.fiamaFirstDream = true;
7676 ShowDialog("fiama", "firstDream");
7677 }
7679 {
7680 ShowDialog("fiama", "giveStoryBook").SetOnKill(delegate
7681 {
7682 EClass.player.flags.fiamaStoryBookGiven = true;
7683 EClass.player.DropReward(ThingGen.Create("book_story"));
7684 });
7685 }
7686 else
7687 {
7688 ShowDialog("fiama");
7689 }
7690 }
7691 else
7692 {
7693 ShowDialog("fiama");
7694 }
7695 return;
7696 case "big_sister":
7698 {
7699 ShowDialog("big_sister", "little_saved");
7700 EClass.player.flags.little_saved = false;
7701 return;
7702 }
7704 {
7705 ShowDialog("big_sister", "little_dead");
7706 EClass.player.flags.little_killed = false;
7707 return;
7708 }
7709 break;
7710 }
7711 if (trait is TraitGuildDoorman)
7712 {
7713 string tag = ((trait is TraitDoorman_Fighter) ? "fighter" : ((trait is TraitDoorman_Mage) ? "mage" : "thief"));
7714 ShowDialog("guild_doorman", "main", tag);
7715 return;
7716 }
7717 if (trait is TraitGuildClerk)
7718 {
7719 string tag2 = ((trait is TraitClerk_Fighter) ? "fighter" : ((trait is TraitClerk_Mage) ? "mage" : "thief"));
7720 ShowDialog("guild_clerk", "main", tag2);
7721 return;
7722 }
7723 }
7724 bool flag = true;
7725 if (id == "parttimer_jure" && (!EClass._zone.IsFestival || !(EClass._zone is Zone_Noyel) || EClass.pc.faith == EClass.game.religions.Healing))
7726 {
7727 flag = false;
7728 }
7729 string book = "_chara";
7730 if (flag)
7731 {
7732 string text = GetStr("drama_override").IsEmpty(id);
7733 if (File.Exists(PackageIterator.GetFiles("Dialog/Drama/" + text + ".xlsx").LastOrDefault()?.FullName ?? (CorePath.DramaData + id + ".xlsx")))
7734 {
7735 book = text;
7736 }
7737 }
7738 ShowDialog(book);
7739 }
7740
7741 public LayerDrama ShowDialog(string book, string step = "main", string tag = "")
7742 {
7743 return _ShowDialog(book, null, step, tag);
7744 }
7745
7746 private LayerDrama _ShowDialog(string book, string sheet, string step = "main", string tag = "")
7747 {
7748 EClass.Sound.Play("pop_drama");
7749 if (book == "_chara" && IsPC)
7750 {
7751 step = "pc";
7752 }
7753 if (id == "lomias")
7754 {
7756 }
7757 return LayerDrama.Activate(book, sheet, step, this, null, tag);
7758 }
7759
7761 {
7762 return (ai.IsRunning ? ai.GetDestination() : pos).Copy();
7763 }
7764
7765 public int GetHireCost()
7766 {
7767 return base.LV / 2 + 4;
7768 }
7769
7770 public int GetHappiness()
7771 {
7772 int num = 50;
7773 if (FindBed() != null)
7774 {
7775 num += 50;
7776 }
7777 return num;
7778 }
7779
7780 public string GetTextHappiness()
7781 {
7782 return GetHappiness().ToString() ?? "";
7783 }
7784
7785 public string GetActionText()
7786 {
7787 string result = "?????";
7788 if (ai != null)
7789 {
7790 result = ai.GetCurrentActionText();
7791 }
7792 return result;
7793 }
7794
7795 public override void WriteNote(UINote n, Action<UINote> onWriteNote = null, IInspect.NoteMode mode = IInspect.NoteMode.Default, Recipe recipe = null)
7796 {
7797 n.Clear();
7798 UIItem uIItem = n.AddHeaderCard(base.Name.ToTitleCase());
7799 SetImage(uIItem.image2);
7800 uIItem.text2.SetText(race.GetText().ToTitleCase(wholeText: true) + " " + job.GetText().ToTitleCase(wholeText: true));
7801 n.AddText("");
7802 n.Build();
7803 }
7804
7806 {
7807 switch (m)
7808 {
7809 case UIList.SortMode.ByJob:
7810 sortVal = job._index * 10000 + sourceCard._index;
7811 break;
7812 case UIList.SortMode.ByRace:
7813 sortVal = race._index * 10000 * ((!IsHuman) ? 1 : (-1)) + sourceCard._index;
7814 break;
7815 case UIList.SortMode.ByFeat:
7816 sortVal = -GetTotalFeat();
7817 break;
7818 case UIList.SortMode.ByPartyOrder:
7819 sortVal = EClass.pc.party.members.IndexOf(this);
7820 return;
7821 default:
7822 sortVal = sourceCard._index * ((!IsHuman) ? 1 : (-1));
7823 break;
7824 case UIList.SortMode.ByWorkk:
7825 break;
7826 }
7827 if (base.isFav)
7828 {
7829 sortVal -= 100000000;
7830 }
7831 }
7832
7833 public void ClearBed(Map map = null)
7834 {
7835 if (map == null)
7836 {
7837 map = EClass._map;
7838 }
7839 foreach (Card item in map.props.installed.all)
7840 {
7841 if (item.trait is TraitBed traitBed && traitBed.IsHolder(this))
7842 {
7843 traitBed.RemoveHolder(this);
7844 }
7845 }
7846 }
7847
7849 {
7850 foreach (Card item in EClass._map.props.installed.all)
7851 {
7852 if (item.trait is TraitBed traitBed && traitBed.IsHolder(this))
7853 {
7854 return traitBed;
7855 }
7856 }
7857 return null;
7858 }
7859
7861 {
7862 if (!IsPCFaction && !IsGuest())
7863 {
7864 return null;
7865 }
7866 foreach (Card item in EClass._map.props.installed.all)
7867 {
7868 if (item.trait is TraitBed traitBed && traitBed.CanAssign(this))
7869 {
7870 traitBed.AddHolder(this);
7871 Msg.Say("claimBed", this);
7872 return traitBed;
7873 }
7874 }
7875 return null;
7876 }
7877
7878 public void TryPutSharedItems(IEnumerable<Thing> containers, bool msg = true)
7879 {
7880 if (GetInt(113) != 0)
7881 {
7882 return;
7883 }
7884 _ListItems.Clear();
7885 Thing bestRangedWeapon = GetBestRangedWeapon();
7886 foreach (Thing thing in things)
7887 {
7888 if (!thing.IsAmmo && !thing.c_isImportant)
7889 {
7890 if (thing.category.slot != 0 && !thing.isEquipped && !thing.HasTag(CTAG.gift))
7891 {
7892 _ListItems.Add(thing);
7893 }
7894 else if (thing.IsRangedWeapon && thing.category.slot == 0 && bestRangedWeapon != thing)
7895 {
7896 _ListItems.Add(thing);
7897 }
7898 }
7899 }
7900 if (_ListItems.Count == 0)
7901 {
7902 return;
7903 }
7904 List<Thing> containers2 = containers.ToList();
7905 foreach (Thing listItem in _ListItems)
7906 {
7907 EClass._zone.TryAddThingInSharedContainer(listItem, containers2, add: true, msg: true, this);
7908 }
7909 }
7910
7911 public void TryPutSharedItems(bool msg = true)
7912 {
7913 TryPutSharedItems(EClass._map.props.installed.containers);
7914 }
7915
7916 public void TryTakeSharedItems(bool msg = true)
7917 {
7918 TryTakeSharedItems(EClass._map.props.installed.containers);
7919 }
7920
7921 public void TryTakeSharedItems(IEnumerable<Thing> containers, bool msg = true, bool shouldEat = true)
7922 {
7923 if (base.isSummon || (memberType == FactionMemberType.Livestock && homeBranch != null && !homeBranch.policies.IsActive(2715)))
7924 {
7925 return;
7926 }
7927 int num = 2;
7928 int num2 = 1;
7929 int num3 = 2;
7930 bool flag = GetInt(113) == 0;
7931 int num4 = 2;
7932 int num5 = 2;
7933 int num6 = 2;
7934 if (homeBranch != null && homeBranch.HasItemProtection && !IsPCParty)
7935 {
7936 num5 = 0;
7937 num6 = 0;
7938 }
7939 foreach (Thing thing3 in things)
7940 {
7941 if (CanEat(thing3, shouldEat))
7942 {
7943 if (thing3.HasElement(757))
7944 {
7945 num2 -= thing3.Num;
7946 num -= thing3.Num;
7947 }
7948 else
7949 {
7950 num -= thing3.Num;
7951 }
7952 }
7953 if (thing3.trait.GetHealAction(this) != null)
7954 {
7955 num3 -= thing3.Num;
7956 }
7957 if (thing3.id == "polish_powder")
7958 {
7959 num4 -= thing3.Num;
7960 }
7961 if (thing3.trait is TraitBlanketColdproof)
7962 {
7963 num5 -= thing3.Num;
7964 }
7965 if (thing3.trait is TraitBlanketFireproof)
7966 {
7967 num6 -= thing3.Num;
7968 }
7969 }
7970 _ListItems.Clear();
7971 foreach (Thing container in containers)
7972 {
7973 if (!container.IsSharedContainer)
7974 {
7975 continue;
7976 }
7977 foreach (Thing thing4 in container.things)
7978 {
7979 if (!thing4.c_isImportant && thing4.IsIdentified && thing4 != EClass.pc.held)
7980 {
7981 if (num4 > 0 && thing4.id == "polish_powder")
7982 {
7983 _ListItems.Add(thing4);
7984 num4 -= thing4.Num;
7985 }
7986 else if (num5 > 0 && !HasElement(1236) && thing4.trait is TraitBlanketColdproof)
7987 {
7988 _ListItems.Add(thing4);
7989 num5 -= thing4.Num;
7990 }
7991 else if (num6 > 0 && thing4.trait is TraitBlanketFireproof)
7992 {
7993 _ListItems.Add(thing4);
7994 num6 -= thing4.Num;
7995 }
7996 else if (num2 > 0 && CanEat(thing4, shouldEat) && !thing4.c_isImportant && thing4.HasElement(757))
7997 {
7998 _ListItems.Add(thing4);
7999 num2 -= thing4.Num;
8000 }
8001 else if (num > 0 && CanEat(thing4, shouldEat) && !thing4.c_isImportant)
8002 {
8003 _ListItems.Add(thing4);
8004 num -= thing4.Num;
8005 }
8006 else if (num3 > 0 && thing4.trait.GetHealAction(this) != null)
8007 {
8008 _ListItems.Add(thing4);
8009 num3 -= thing4.Num;
8010 }
8011 else if (flag && thing4.IsEquipmentOrRanged && !thing4.HasTag(CTAG.gift) && ShouldEquip(thing4, useFav: true))
8012 {
8013 _ListItems.Add(thing4);
8014 }
8015 }
8016 }
8017 }
8018 if (_ListItems.Count == 0)
8019 {
8020 return;
8021 }
8022 _ListItems.ForeachReverse(delegate(Thing t)
8023 {
8024 if (t.IsEquipmentOrRanged)
8025 {
8026 bool flag3 = false;
8027 int slot = t.category.slot;
8028 int equipValue = t.GetEquipValue();
8029 foreach (Thing listItem in _ListItems)
8030 {
8031 if (listItem.category.slot == slot && listItem.GetEquipValue() > equipValue)
8032 {
8033 flag3 = true;
8034 break;
8035 }
8036 }
8037 if (flag3)
8038 {
8039 _ListItems.Remove(t);
8040 }
8041 }
8042 });
8043 bool flag2 = false;
8044 foreach (Thing listItem2 in _ListItems)
8045 {
8046 Thing thing = listItem2;
8047 if (things.IsFull(thing))
8048 {
8049 break;
8050 }
8051 Thing thing2 = listItem2.parent as Thing;
8052 if (thing.HasElement(757))
8053 {
8054 if (thing.Num > 1)
8055 {
8056 thing = thing.Split(1);
8057 }
8058 }
8059 else if (thing.Num > 2)
8060 {
8061 thing = thing.Split(2);
8062 }
8063 if (msg)
8064 {
8065 Say("takeSharedItem", this, thing, thing2.GetName(NameStyle.Full));
8066 }
8067 AddCard(thing);
8068 if (ShouldEquip(thing, useFav: true) && thing.category.slot != 0)
8069 {
8070 TryEquip(thing, useFav: true);
8071 flag2 = true;
8072 }
8073 }
8074 if (flag2 && flag)
8075 {
8076 TryPutSharedItems(containers);
8077 }
8078 }
8079
8081 {
8082 Thing result = null;
8083 int num = -1;
8084 if (IsPC)
8085 {
8086 return null;
8087 }
8088 foreach (Thing item in things.List((Thing t) => CanEat(t, shouldEat: true) && !t.c_isImportant, onlyAccessible: true))
8089 {
8090 int num2 = CountNumEaten(item);
8091 int num3 = 100 - num2 + (item.HasElement(757) ? 10 : 0);
8092 if (num3 > num)
8093 {
8094 result = item;
8095 num = num3;
8096 }
8097 }
8098 return result;
8099 }
8100
8101 public void InstantEat(Thing t = null, bool sound = true)
8102 {
8103 if (t == null)
8104 {
8105 t = FindBestFoodToEat();
8106 }
8107 if (t == null)
8108 {
8109 t = things.Find((Thing a) => CanEat(a, shouldEat: true) && !a.c_isImportant);
8110 }
8111 if (t == null)
8112 {
8113 t = things.Find((Thing a) => CanEat(a) && !a.c_isImportant);
8114 }
8115 if (t != null)
8116 {
8117 Say("eat_start", this, t.Duplicate(1));
8118 if (sound)
8119 {
8120 PlaySound("eat");
8121 }
8122 FoodEffect.Proc(this, t);
8123 }
8124 }
8125
8126 public bool CanEat(Thing t, bool shouldEat = false)
8127 {
8128 if (t.IsDecayed && !HasElement(480))
8129 {
8130 return false;
8131 }
8132 if (HasElement(1250) && !t.HasElement(710))
8133 {
8134 return false;
8135 }
8136 if (shouldEat && (!(t.trait is TraitFoodPrepared) || t.c_isImportant))
8137 {
8138 return false;
8139 }
8140 if ((IsPC || (homeBranch != null && homeBranch.GetCivility() >= 50)) && (t.HasTag(CTAG.dish_fail) || t.id == "731"))
8141 {
8142 return false;
8143 }
8144 if (!t.IsNegativeGift && !t.HasTag(CTAG.ignoreUse) && !t.isEquipped)
8145 {
8146 return t.trait.CanEat(this);
8147 }
8148 return false;
8149 }
8150
8151 public bool ShouldEquip(Thing t, bool useFav = false)
8152 {
8153 if (t.IsRangedWeapon && t.category.slot == 0)
8154 {
8155 if (!CanEquipRanged(t))
8156 {
8157 return false;
8158 }
8159 int num = 0;
8160 foreach (Thing thing in things)
8161 {
8162 if (thing.IsRangedWeapon)
8163 {
8164 if (thing.category.slot != 0 && thing.isEquipped)
8165 {
8166 return false;
8167 }
8168 if (CanEquipRanged(thing) && thing.GetEquipValue() > num)
8169 {
8170 num = thing.GetEquipValue();
8171 }
8172 }
8173 }
8174 if (t.GetEquipValue() > num)
8175 {
8176 return true;
8177 }
8178 return false;
8179 }
8180 BodySlot bodySlot = body.GetSlot(t);
8181 if (bodySlot == null)
8182 {
8183 return false;
8184 }
8185 if (useFav)
8186 {
8187 switch (GetFavAttackStyle())
8188 {
8189 case AttackStyle.Default:
8190 case AttackStyle.TwoHand:
8191 if (t.IsMeleeWeapon)
8192 {
8193 bodySlot = body.slotMainHand;
8194 }
8195 else if (bodySlot.elementId == 35)
8196 {
8197 return false;
8198 }
8199 break;
8200 case AttackStyle.Shield:
8201 if (t.IsMeleeWeapon)
8202 {
8203 bodySlot = body.slotMainHand;
8204 }
8205 else if (bodySlot.elementId == 35 && t.IsMeleeWeapon)
8206 {
8207 return false;
8208 }
8209 break;
8210 case AttackStyle.TwoWield:
8211 if (bodySlot.elementId == 35 && !t.IsMeleeWeapon)
8212 {
8213 return false;
8214 }
8215 break;
8216 }
8217 }
8218 if (!body.IsEquippable(t, bodySlot, text: false))
8219 {
8220 return false;
8221 }
8222 if (bodySlot.thing != null && (bodySlot.thing.blessedState <= BlessedState.Cursed || bodySlot.thing.GetEquipValue() >= t.GetEquipValue()))
8223 {
8224 return false;
8225 }
8226 if (!base.IsPCFactionOrMinion)
8227 {
8228 int num2 = 0;
8229 foreach (Element value in t.elements.dict.Values)
8230 {
8231 if (value.Value <= 0)
8232 {
8233 int num3 = 100;
8234 switch (value.id)
8235 {
8236 case 418:
8237 num3 = 10;
8238 break;
8239 case 60:
8240 case 61:
8241 case 62:
8242 num3 = 200;
8243 break;
8244 case 962:
8245 num3 = 10000;
8246 break;
8247 }
8248 num2 += value.Value * num3 / 100;
8249 }
8250 }
8251 if (num2 < -40)
8252 {
8253 return false;
8254 }
8255 }
8256 if (t.HasTag(CTAG.gift) && t.c_uidAttune != base.uid)
8257 {
8258 return false;
8259 }
8260 return true;
8261 }
8262
8263 public bool TryEquip(Thing t, bool useFav = false)
8264 {
8265 if (!ShouldEquip(t, useFav))
8266 {
8267 return false;
8268 }
8269 if (t.category.slot == 0)
8270 {
8271 return false;
8272 }
8273 if (useFav)
8274 {
8275 BodySlot slot = body.GetSlot(t);
8276 switch (GetFavAttackStyle())
8277 {
8278 case AttackStyle.Default:
8279 case AttackStyle.TwoHand:
8280 if (t.IsMeleeWeapon)
8281 {
8282 slot = body.slotMainHand;
8283 }
8284 break;
8285 case AttackStyle.Shield:
8286 if (t.IsMeleeWeapon)
8287 {
8288 slot = body.slotMainHand;
8289 }
8290 break;
8291 }
8292 body.Equip(t, slot);
8293 }
8294 else
8295 {
8296 body.Equip(t);
8297 }
8298 Say("equip", this, t);
8299 return true;
8300 }
8301
8302 public bool CanEquipRanged(Thing t)
8303 {
8304 return !body.IsTooHeavyToEquip(t);
8305 }
8306
8308 {
8309 Thing dest = null;
8310 if (IsPC)
8311 {
8313 {
8314 return FindThrowable(hotbar: true);
8315 }
8316 return null;
8317 }
8318 things.Foreach(delegate(Thing t)
8319 {
8320 if (t.HasTag(CTAG.throwWeapon) || (!base.IsPCFactionOrMinion && t.HasTag(CTAG.throwWeaponEnemy)))
8321 {
8322 dest = t;
8323 }
8324 });
8325 return dest;
8326 Thing FindThrowable(bool hotbar)
8327 {
8328 things.Foreach(delegate(Thing t)
8329 {
8330 if (dest == null)
8331 {
8332 if (t.IsHotItem)
8333 {
8334 if (!hotbar)
8335 {
8336 return;
8337 }
8338 }
8339 else if (hotbar)
8340 {
8341 return;
8342 }
8343 if (t.HasTag(CTAG.throwWeapon))
8344 {
8345 dest = t;
8346 }
8347 }
8348 });
8349 return dest;
8350 }
8351 }
8352
8354 {
8355 TraitToolRange ranged = weapon.trait as TraitToolRange;
8356 Thing thing = (IsPC ? EClass.pc.things.Find<TraitQuiver>() : null);
8357 if (thing != null)
8358 {
8359 Thing thing2 = thing.things.Find((Thing t) => ranged.IsAmmo(t));
8360 if (thing2 != null)
8361 {
8362 return thing2;
8363 }
8364 }
8365 return things.Find((Thing t) => ranged.IsAmmo(t));
8366 }
8367
8369 {
8370 Thing result = null;
8371 int num = 0;
8372 foreach (Thing thing in things)
8373 {
8374 if (thing.IsRangedWeapon && CanEquipRanged(thing) && thing.GetEquipValue() > num)
8375 {
8376 num = thing.GetEquipValue();
8377 result = thing;
8378 }
8379 }
8380 return result;
8381 }
8382
8384 {
8385 return things.List((Thing t) => t.IsRangedWeapon && CanEquipRanged(t)).RandomItem();
8386 }
8387
8388 public bool TryEquipRanged()
8389 {
8390 if (id == "mamani")
8391 {
8392 ranged = GetRandomRangedWeapon();
8393 }
8394 if (IsPC)
8395 {
8397 if (thing?.trait is TraitToolRange && CanEquipRanged(thing))
8398 {
8399 ranged = thing;
8400 return true;
8401 }
8402 return false;
8403 }
8404 if (ranged != null && ranged.parent == this)
8405 {
8406 return true;
8407 }
8408 ranged = GetBestRangedWeapon();
8409 return ranged != null;
8410 }
8411
8412 public override int GetArmorSkill()
8413 {
8414 if (body.GetWeight(armorOnly: true) <= (HasElement(1204) ? 6000 : 30000))
8415 {
8416 return 120;
8417 }
8418 return 122;
8419 }
8420
8421 public bool TryUse(Thing t)
8422 {
8423 if (t.id == "338" && t.blessedState >= BlessedState.Normal)
8424 {
8425 Thing thing = things.Find((Thing a) => a.IsEquipmentOrRanged && !a.isAcidproof);
8426 if (thing != null)
8427 {
8428 Say("dip", this, thing, t.GetName(NameStyle.Full, 1));
8429 SE.Change();
8430 t.trait.OnBlend(thing, this);
8431 return true;
8432 }
8433 return false;
8434 }
8435 if (t.IsNegativeGift || t.source.HasTag(CTAG.ignoreUse))
8436 {
8437 return false;
8438 }
8439 if (t.id == "cigar")
8440 {
8441 (t.trait as TraitItemProc).OnUse(this);
8442 return true;
8443 }
8444 if (t.trait.CanDrink(this))
8445 {
8446 Drink(t);
8447 return true;
8448 }
8449 if (t.trait.CanEat(this) && hunger.GetPhase() > ((IsPCFaction || IsPCFactionMinion) ? 2 : 0))
8450 {
8451 SetAIImmediate(new AI_Eat
8452 {
8453 target = t
8454 });
8455 return true;
8456 }
8457 if (t.trait.CanRead(this))
8458 {
8459 SetAIImmediate(new AI_Read
8460 {
8461 target = t
8462 });
8463 return true;
8464 }
8465 if (base.hp < MaxHP * 90 / 100)
8466 {
8467 Action healAction = t.trait.GetHealAction(this);
8468 if (healAction != null)
8469 {
8470 healAction();
8471 return true;
8472 }
8473 }
8474 return false;
8475 }
8476
8478 {
8479 return FindBed()?.owner.pos.cell.room;
8480 }
8481
8482 public void ModAffinity(Chara c, int a, bool show = true, bool showOnlyEmo = false)
8483 {
8484 if (c == this)
8485 {
8486 return;
8487 }
8488 if (IsPC)
8489 {
8490 c.ModAffinity(EClass.pc, a, show);
8491 }
8492 else
8493 {
8494 if (!trait.CanChangeAffinity)
8495 {
8496 return;
8497 }
8498 int num = StatsHygiene.GetAffinityMod(EClass.pc.hygiene.GetPhase()) + (HasElement(417) ? 30 : 0) + (EClass.pc.HasCondition<ConSmoking>() ? (-30) : 0);
8499 if (IsPCFaction && homeBranch != null)
8500 {
8501 num += (int)Mathf.Sqrt(homeBranch.Evalue(2117)) * 5;
8502 }
8503 bool flag = a > 0;
8504 if (flag)
8505 {
8506 a = a * num / 100;
8507 if (affinity.GetLunchChance() > EClass.rnd(100) && GetInt(71) >= 0 && GetInt(71) < EClass.world.date.GetRaw())
8508 {
8509 SetInt(71, -1);
8510 }
8511 }
8512 if (show)
8513 {
8514 if (a == 0)
8515 {
8516 if (!showOnlyEmo)
8517 {
8518 Say("affinityNone", this, c);
8519 }
8520 }
8521 else
8522 {
8523 ShowEmo((!flag) ? Emo.angry : Emo.love);
8524 c.ShowEmo(flag ? Emo.love : Emo.sad);
8525 if (!showOnlyEmo)
8526 {
8527 Say(flag ? "affinityPlus" : "affinityMinus", this, c);
8528 }
8529 }
8530 }
8531 if (c.IsPC)
8532 {
8533 a = affinity.Mod(a);
8534 }
8535 }
8536 }
8537
8538 public bool TryIdentify(Thing t, int count = 1, bool show = true)
8539 {
8540 int num = Evalue(289);
8541 if (num == 0)
8542 {
8543 return false;
8544 }
8545 int lV = t.LV;
8546 if (EClass.rnd(num * num + 5) > EClass.rnd(lV * lV) * 20)
8547 {
8548 t.Identify(show, (num >= 20) ? IDTSource.SkillHigh : IDTSource.Skill);
8549 int num2 = 50;
8550 if (lV > num)
8551 {
8552 num2 += (lV - num) * 10;
8553 }
8554 elements.ModExp(289, Mathf.Min(num2, 1000));
8555 return true;
8556 }
8557 return false;
8558 }
8559
8561 {
8562 Chara chara = CharaGen.Create(id);
8563 chara.c_originalHostility = base.c_originalHostility;
8564 if (chara.c_originalHostility != 0)
8565 {
8566 chara.hostility = chara.c_originalHostility;
8567 }
8568 if (orgPos != null)
8569 {
8570 chara.orgPos = orgPos.Copy();
8571 }
8572 chara.pos = pos.Copy();
8573 chara.isImported = true;
8574 chara.c_editorTags = base.c_editorTags;
8575 chara.c_editorTraitVal = base.c_editorTraitVal;
8576 chara.c_idTrait = base.c_idTrait;
8577 chara.homeZone = homeZone;
8578 return chara;
8579 }
8580
8582 {
8583 if (ModUtil.TryGetContent<CustomBiographyContent>("Biography/" + id, out var content))
8584 {
8585 content.RefreshCharaBio(this);
8586 if (!content.favFood.IsEmpty() && EClass.sources.things.map.TryGetValue(content.favFood, out var value))
8587 {
8588 return value;
8589 }
8590 }
8591 string str = GetStr(72);
8592 if (!str.IsEmpty() && EClass.sources.things.map.TryGetValue(str, out var value2))
8593 {
8594 return value2;
8595 }
8596 if (_listFavFood.Count == 0)
8597 {
8598 foreach (SourceThing.Row row in EClass.sources.things.rows)
8599 {
8600 if (row._origin == "dish" && row.value != 0 && row.chance != 0)
8601 {
8602 _listFavFood.Add(row);
8603 }
8604 }
8605 }
8606 SourceThing.Row r = null;
8607 Rand.UseSeed(base.uid + EClass.game.seed, delegate
8608 {
8609 r = _listFavFood.RandomItem();
8610 });
8611 return r;
8612 }
8613
8615 {
8616 if (ModUtil.TryGetContent<CustomBiographyContent>("Biography/" + id, out var content))
8617 {
8618 content.RefreshCharaBio(this);
8619 if (!content.favCategory.IsEmpty() && EClass.sources.categories.map.TryGetValue(content.favCategory, out var value) && value.gift > 0)
8620 {
8621 return value;
8622 }
8623 }
8624 string str = GetStr(73);
8625 if (!str.IsEmpty() && EClass.sources.categories.map[str] != null)
8626 {
8627 return EClass.sources.categories.map[str];
8628 }
8629 SourceCategory.Row r = null;
8630 if (_listFavCat.Count == 0)
8631 {
8632 foreach (SourceCategory.Row row in EClass.sources.categories.rows)
8633 {
8634 if (row.gift > 0)
8635 {
8636 _listFavCat.Add(row);
8637 }
8638 }
8639 }
8640 Rand.UseSeed(base.uid + EClass.game.seed, delegate
8641 {
8642 r = _listFavCat.RandomItem();
8643 });
8644 return r;
8645 }
8646
8647 public void Marry(Chara c)
8648 {
8649 if (base.c_love == null)
8650 {
8651 base.c_love = new LoveData();
8652 }
8653 base.c_love.dateMarriage = EClass.world.date.GetRaw();
8654 base.c_love.uidZoneMarriage = EClass._zone.uid;
8655 base.c_love.nameZoneMarriage = EClass._zone.Name;
8656 SetFeat(1275, 1, msg: true);
8658 }
8659
8660 public void Divorce(Chara c)
8661 {
8662 if (base.c_love != null)
8663 {
8664 base.c_love.dateMarriage = 0;
8665 base.c_love.dateWedding = 0;
8666 SetFeat(1275, 0);
8668 }
8669 }
8670
8672 {
8673 using (List<Chara>.Enumerator enumerator = pos.ListCharasInRadius(this, 3, (Chara c) => c != this && c.race.id == "cat").GetEnumerator())
8674 {
8675 if (enumerator.MoveNext())
8676 {
8677 return enumerator.Current;
8678 }
8679 }
8680 return null;
8681 }
8682
8683 public void Sniff(Chara c)
8684 {
8685 Say("abCatSniff", this, c);
8686 AddCondition<ConHOT>(EClass.curve(50 + c.CHA * 5, 400, 100));
8687 c.ShowEmo(Emo.angry);
8688 ShowEmo(Emo.love);
8689 Talk("sniff");
8690 c.Talk(new string[4] { "labor", "disgust", "scold", "callGuards" }.RandomItem());
8691 }
8692
8693 public int GetTotalFeat()
8694 {
8695 int num = 0;
8696 if (base.c_upgrades != null)
8697 {
8698 num += base.c_upgrades.spent;
8699 }
8700 if (base.c_genes != null)
8701 {
8702 num += base.c_genes.GetTotalCost();
8703 }
8704 return num + base.feat;
8705 }
8706
8707 public bool CanInsult()
8708 {
8709 foreach (ActList.Item item in ability.list.items)
8710 {
8711 if (item.act.id == 6630)
8712 {
8713 return true;
8714 }
8715 }
8716 return false;
8717 }
8718
8719 public string GetIdPortraitCat()
8720 {
8721 string text = race.id;
8722 if ((text == "mifu" || text == "nefu") && EClass.rnd(2) == 0)
8723 {
8724 return "foxfolk";
8725 }
8726 if (trait is TraitGuard)
8727 {
8728 return "guard";
8729 }
8730 return "";
8731 }
8732
8733 public string GetIdPortrait()
8734 {
8735 string str = GetStr("portrait_override");
8736 if (!str.IsEmpty() && Portrait.allIds.Contains(str + ".png"))
8737 {
8738 return str;
8739 }
8740 if (id == "olderyoungersister")
8741 {
8742 if (base.idSkin != 2)
8743 {
8744 return "UN_olderyoungersister";
8745 }
8746 return "UN_olderyoungersister_alt";
8747 }
8748 if (Portrait.allIds.Contains("UN_" + id + ".png"))
8749 {
8750 return "UN_" + id;
8751 }
8752 return base.c_idPortrait;
8753 }
8754
8755 public Thing MakeGene(DNA.Type? type = null)
8756 {
8757 return DNA.GenerateGene(((HasElement(1290) || HasElement(1292)) && Evalue(418) >= 0) ? EClass.sources.charas.map["caladrius"].model.Chara : this, type);
8758 }
8759
8761 {
8762 return DNA.GenerateGene(this, DNA.Type.Brain);
8763 }
8764
8765 public void OnInsulted()
8766 {
8767 if (isDead)
8768 {
8769 return;
8770 }
8771 if (HasElement(1231))
8772 {
8773 Talk("insulted");
8774 AddCondition<ConEuphoric>(100 * Evalue(1231));
8775 }
8776 else if (EClass.rnd(20) == 0)
8777 {
8778 SetFeat(1231, 1, msg: true);
8779 if (IsPC)
8780 {
8782 }
8783 }
8784 }
8785
8786 public bool IsValidGiftWeight(Card t, int num = -1)
8787 {
8788 int num2 = ((!HasElement(1411)) ? 1 : 3);
8789 if (GetBurden(t, num) >= num2)
8790 {
8791 return false;
8792 }
8793 return true;
8794 }
8795
8796 public bool CanAcceptItem(Card t, int num = -1, bool skipImportantCheck = false)
8797 {
8799 {
8800 return true;
8801 }
8802 if (!IsValidGiftWeight(t, num))
8803 {
8804 return false;
8805 }
8806 if (!skipImportantCheck && t.c_isImportant)
8807 {
8808 return false;
8809 }
8810 if ((t.category.IsChildOf("furniture") || t.category.IsChildOf("junk")) && (!(t.trait is TraitFigure) || !HasElement(1427)) && !HasElement(1411))
8811 {
8812 return false;
8813 }
8814 return true;
8815 }
8816
8817 public bool CanAcceptGift(Chara c, Card t)
8818 {
8819 if (things.IsFull())
8820 {
8821 return false;
8822 }
8823 if (t.c_isImportant)
8824 {
8825 return false;
8826 }
8827 if (t.id == "1084")
8828 {
8829 return true;
8830 }
8831 if (t.trait is TraitBookExp)
8832 {
8833 return true;
8834 }
8835 if (t.trait.CanOnlyCarry || !t.trait.CanBeDestroyed || t.trait.CanExtendBuild || t.rarity == Rarity.Artifact || t.IsContainer)
8836 {
8837 return false;
8838 }
8839 if (base.IsPowerful && t.trait is TraitScroll { source: not null } traitScroll && traitScroll.source.abilityType.Contains("summon"))
8840 {
8841 return false;
8842 }
8843 return true;
8844 }
8845
8846 public void GiveGift(Chara c, Thing t)
8847 {
8848 if (c.IsHostile() || c.IsDeadOrSleeping)
8849 {
8850 Msg.Say("affinityNone", c, this);
8851 return;
8852 }
8853 if (!t.isCopy && t.IsCursed && t.IsEquipmentOrRanged && !t.IsAmmo && c.HasElement(1414))
8854 {
8855 bool num = t.blessedState == BlessedState.Doomed;
8856 int num2 = 200 + t.LV * 3;
8857 if (t.rarity == Rarity.Legendary)
8858 {
8859 num2 *= 3;
8860 }
8861 if (t.rarity >= Rarity.Mythical)
8862 {
8863 num2 *= 5;
8864 }
8865 if (num)
8866 {
8867 num2 *= 2;
8868 }
8869 PlayEffect("identify");
8870 PlaySound("identify");
8871 c.PlayEffect("mutation");
8872 c.Say("draw_curse", c, t);
8873 t.Destroy();
8874 List<Element> list = new List<Element>();
8875 foreach (Element value in elements.dict.Values)
8876 {
8877 if (value is Spell)
8878 {
8879 list.Add(value);
8880 }
8881 }
8882 if (list.Count == 0)
8883 {
8884 SayNothingHappans();
8885 return;
8886 }
8887 Element element = list.RandomItem();
8888 ModExp(element.id, num2);
8889 Say("draw_curse2", this, element.Name);
8890 c.AddExp(Mathf.Min(num2 / 3, c.ExpToNext));
8891 return;
8892 }
8893 if ((t.id == "lovepotion" || t.id == "dreambug") && !Application.isEditor)
8894 {
8895 GiveLovePotion(c, t);
8896 return;
8897 }
8898 if (t.trait is TraitErohon && c.id == t.c_idRefName)
8899 {
8900 c.OnGiveErohon(t);
8901 return;
8902 }
8903 if (t.trait is TraitTicketMassage)
8904 {
8905 t.ModNum(-1);
8906 c.Talk("ticket");
8907 switch (t.id)
8908 {
8909 case "ticket_massage":
8910 c.ModAffinity(EClass.pc, 10);
8912 {
8913 target = c
8914 });
8915 break;
8916 case "ticket_armpillow":
8917 c.ModAffinity(EClass.pc, 20);
8918 EClass.pc.AddCondition<ConSleep>(300, force: true);
8919 c.SetAI(new AI_ArmPillow
8920 {
8921 target = EClass.pc
8922 });
8923 break;
8924 case "ticket_champagne":
8925 c.ModAffinity(EClass.pc, 10);
8927 break;
8928 }
8929 return;
8930 }
8931 if (t.id == "flyer")
8932 {
8933 stamina.Mod(-1);
8934 if (c.things.Find((Thing a) => a.id == "flyer") != null)
8935 {
8936 c.Talk("flyer_miss");
8937 DoHostileAction(c);
8938 return;
8939 }
8940 if (EClass.rnd(20) != 0 && c.CHA > EClass.rnd(base.CHA + Evalue(291) * 3 + 10))
8941 {
8942 Msg.Say("affinityNone", c, this);
8943 t.Destroy();
8944 elements.ModExp(291, 10f);
8945 return;
8946 }
8947 elements.ModExp(291, 50f);
8948 }
8949 if (t.id == "statue_weird")
8950 {
8951 EClass.pc.Say("statue_sell");
8952 }
8953 t.isGifted = true;
8954 c.nextUse = c.affinity.OnGift(t);
8955 if (!t.isDestroyed)
8956 {
8957 EClass.game.quests.list.ForeachReverse(delegate(Quest q)
8958 {
8959 q.OnGiveItem(c, t);
8960 });
8961 if (c.TryEquip(t))
8962 {
8963 c.nextUse = null;
8964 }
8965 }
8966 if (c.IsPCParty)
8967 {
8969 }
8970 }
8971
8972 public void OnGiveErohon(Thing t)
8973 {
8974 Say("give_erohon", this);
8975 AddCondition<ConParalyze>(50, force: true);
8976 AddCondition<ConConfuse>(50, force: true);
8977 AddCondition<ConFear>(1000, force: true);
8978 ModAffinity(EClass.pc, 100);
8979 t.Destroy();
8980 Talk("pervert");
8981 }
8982
8983 public void GiveLovePotion(Chara c, Thing t)
8984 {
8985 c.Say("give_love", c, t);
8986 c.PlaySound(t.material.GetSoundDead());
8987 c.ShowEmo(Emo.angry);
8988 c.ModAffinity(EClass.pc, -20, show: false);
8989 c.Talk("pervert");
8990 t.Destroy();
8991 }
8992
8993 public bool RequestProtection(Chara attacker, Action<Chara> action)
8994 {
8995 if (HasCondition<StanceTaunt>() || base.isRestrained || attacker == this)
8996 {
8997 return false;
8998 }
8999 if (host != null && host.isRestrained)
9000 {
9001 return false;
9002 }
9003 if (base.IsPCFactionOrMinion && attacker.IsPCFactionOrMinion)
9004 {
9005 return false;
9006 }
9007 bool flag = false;
9008 foreach (Chara chara in EClass._map.charas)
9009 {
9010 if (chara == attacker || chara.enemy == this || chara == this || chara.host != null || chara.IsDisabled || !chara.IsFriendOrAbove(this) || chara.conSuspend != null || (chara.IsPCParty && !IsPCParty) || (IsPCFaction && !chara.IsPCFaction) || (attacker.IsPCFactionOrMinion && chara.IsPCFactionOrMinion) || chara.HasElement(1277))
9011 {
9012 continue;
9013 }
9014 bool flag2 = chara.HasElement(1225) && !chara.GetBool(126);
9015 if ((!flag2 && (flag || EClass.rnd(2) == 0 || !chara.HasCondition<StanceTaunt>())) || chara.HasCooldown(1225))
9016 {
9017 continue;
9018 }
9019 int num = Mathf.Max(chara.Evalue(1649), (!flag2) ? 1 : 3);
9020 int num2 = Dist(chara);
9021 if (num2 > 25)
9022 {
9023 continue;
9024 }
9025 if (num2 > num || !chara.CanSeeLos(pos, num2))
9026 {
9027 if (!flag2)
9028 {
9029 continue;
9030 }
9031 Point nearestPoint = pos.GetNearestPoint(allowBlock: false, allowChara: false, allowInstalled: true, ignoreCenter: true);
9032 if (!nearestPoint.IsValid)
9033 {
9034 continue;
9035 }
9036 chara.Teleport(nearestPoint);
9037 chara.AddCooldown(1225, 10);
9038 num2 = Dist(chara);
9039 Say("intercept_loyal", chara, this);
9040 chara.SetEnemy(attacker);
9041 attacker.SetEnemy(chara);
9042 if (num2 > num || !chara.CanSeeLos(pos, num2))
9043 {
9044 continue;
9045 }
9046 }
9047 if (!flag && !HasElement(1225))
9048 {
9049 Say("intercept", chara, this);
9050 if (EClass.rnd(10) == 0)
9051 {
9052 chara.Talk("intercept", base.NameSimple);
9053 }
9054 if (attacker.enemy == this)
9055 {
9056 attacker.SetEnemy(chara);
9057 }
9058 action(chara);
9059 flag = true;
9060 }
9061 }
9062 return flag;
9063 }
9064
9066 {
9067 if (IsPCFaction)
9068 {
9069 if (t.IsFood && t.category.id != "fish" && !t.IsDecayed)
9070 {
9071 return false;
9072 }
9073 if (t.trait.GetHealAction(this) != null)
9074 {
9075 return false;
9076 }
9077 if (t.IsThrownWeapon || t.IsRangedWeapon || t.IsAmmo)
9078 {
9079 return false;
9080 }
9081 if (t.trait is TraitBlanket || t.trait is TraitItemProc || t.trait is TraitBookSkill)
9082 {
9083 return false;
9084 }
9085 }
9086 if (t.isEquipped || t.rarity >= Rarity.Legendary || !t.trait.CanBeDestroyed || t.c_isImportant)
9087 {
9088 return false;
9089 }
9090 if (t.trait is TraitCurrency || t.trait is TraitTool)
9091 {
9092 return false;
9093 }
9094 switch (type)
9095 {
9096 case ClearInventoryType.SellAtTown:
9097 if (!t.isGifted && !t.isNPCProperty)
9098 {
9099 return false;
9100 }
9101 break;
9102 case ClearInventoryType.Purge:
9103 switch (t.category.id)
9104 {
9105 case "fish":
9106 if (EClass.rnd(3) == 0)
9107 {
9108 return true;
9109 }
9110 break;
9111 case "junk":
9112 case "garbage":
9113 if (EClass.rnd(3) != 0)
9114 {
9115 return true;
9116 }
9117 break;
9118 }
9119 if (t.id == "flyer")
9120 {
9121 return true;
9122 }
9123 if (!t.IsDecayed && EClass.rnd(3) == 0)
9124 {
9125 return false;
9126 }
9127 if (!things.IsFull() && t.IsRangedWeapon)
9128 {
9129 return false;
9130 }
9131 break;
9132 }
9133 return true;
9134 }
9135
9136 public void TryClearInventory()
9137 {
9138 if (IsPC)
9139 {
9140 return;
9141 }
9142 if (IsPCParty)
9143 {
9144 if (!things.IsAlmostFull())
9145 {
9146 return;
9147 }
9148 bool flag = EClass._zone.IsTown;
9149 if (!flag && EClass._zone.IsPCFactionOrTent)
9150 {
9151 foreach (Chara chara in EClass._map.charas)
9152 {
9153 if (chara.IsPCFaction && chara.trait.ShopType != ShopType.None)
9154 {
9155 flag = true;
9156 }
9157 }
9158 }
9159 if (flag)
9160 {
9161 ClearInventory(ClearInventoryType.SellAtTown);
9162 }
9163 }
9164 else
9165 {
9166 ClearInventory(ClearInventoryType.Purge);
9167 }
9168 }
9169
9171 {
9172 int num = 0;
9173 for (int num2 = things.Count - 1; num2 >= 0; num2--)
9174 {
9175 Thing thing = things[num2];
9176 if (ShouldThrowAway(thing, type))
9177 {
9178 num += thing.GetPrice(CurrencyType.Money, sell: true, PriceType.Default, this) * thing.Num;
9179 thing.Destroy();
9180 }
9181 }
9182 if (num > 0)
9183 {
9184 ModCurrency(num);
9185 if (type == ClearInventoryType.SellAtTown)
9186 {
9187 Msg.Say("party_sell", this, num.ToString() ?? "");
9188 PlaySound("pay");
9189 }
9190 }
9191 }
9192
9193 public void ResetUpgrade()
9194 {
9195 _ = base.c_upgrades;
9196 }
9197
9198 public void TryUpgrade(bool msg = true)
9199 {
9200 if (!EClass.debug.enable || IsPC || !IsGlobal || !IsPCFaction)
9201 {
9202 return;
9203 }
9204 for (int i = 0; i < 100; i++)
9205 {
9206 if (base.feat == 0)
9207 {
9208 break;
9209 }
9210 if (base.c_upgrades == null)
9211 {
9212 base.c_upgrades = new CharaUpgrade();
9213 }
9214 if (base.c_upgrades.halt)
9215 {
9216 break;
9217 }
9218 Rand.SetSeed(base.uid + base.c_upgrades.count);
9219 int num = EClass.rnd(100);
9220 int num2 = 0;
9221 int num3 = 1;
9222 int num4 = 0;
9223 bool flag = false;
9224 IEnumerable<SourceElement.Row> ie = EClass.sources.elements.rows.Where((SourceElement.Row a) => !elements.Has(a) && a.category == "skill" && !a.tag.Contains("noPet"));
9225 List<Element> list = ListAvailabeFeats(pet: true);
9226 if (num >= 90 && list.Count > 0)
9227 {
9228 Element element = list.RandomItem();
9229 num2 = element.id;
9230 num4 = element.CostLearn;
9231 }
9232 else if (num >= 60 && ie.Any())
9233 {
9234 num2 = ie.RandomItem().id;
9235 num4 = 3;
9236 }
9237 else
9238 {
9239 num2 = Element.List_MainAttributesMajor.RandomItem();
9240 num4 = 1;
9241 num3 = 2;
9242 flag = true;
9243 }
9244 Rand.SetSeed();
9245 if (num4 > base.feat)
9246 {
9247 break;
9248 }
9249 base.feat -= num4;
9250 base.c_upgrades.count++;
9251 base.c_upgrades.spent += num4;
9252 bool flag2 = false;
9253 if (flag)
9254 {
9255 foreach (CharaUpgrade.Item item in base.c_upgrades.items)
9256 {
9257 if (item.idEle == num2)
9258 {
9259 item.value += num3;
9260 item.cost += num4;
9261 flag2 = true;
9262 break;
9263 }
9264 }
9265 }
9266 if (!flag2)
9267 {
9268 base.c_upgrades.items.Add(new CharaUpgrade.Item
9269 {
9270 idEle = num2,
9271 value = num3,
9272 cost = num4
9273 });
9274 }
9275 SourceElement.Row row = EClass.sources.elements.map[num2];
9276 if (row.category == "feat")
9277 {
9278 SetFeat(num2, elements.ValueWithoutLink(num2) + 1, msg: true);
9279 }
9280 else if (elements.ValueWithoutLink(row.id) == 0)
9281 {
9282 elements.Learn(row.id);
9283 }
9284 else
9285 {
9286 elements.ModBase(num2, num3);
9287 }
9288 }
9289 }
9290
9291 public bool CanBloom()
9292 {
9293 if (IsPC || base.isScaled || HasElement(1273))
9294 {
9295 return false;
9296 }
9297 if (!EClass.debug.godMode)
9298 {
9299 if (base.c_daysWithPC > 360)
9300 {
9301 return affinity.CanSleepBeside();
9302 }
9303 return false;
9304 }
9305 return true;
9306 }
9307
9308 public void AddCooldown(int idEle, int turns = 0)
9309 {
9310 if (_cooldowns == null)
9311 {
9312 _cooldowns = new List<int>();
9313 }
9314 if (turns != 0)
9315 {
9316 _cooldowns.Add(idEle * 1000 + turns);
9317 return;
9318 }
9319 SourceElement.Row row = EClass.sources.elements.map[idEle];
9320 if (row.cooldown > 0)
9321 {
9322 _cooldowns.Add(idEle * 1000 + row.cooldown);
9323 }
9324 }
9325
9326 public void SetCooldown(int idEle, int turns = 0)
9327 {
9328 if (_cooldowns == null)
9329 {
9330 _cooldowns = new List<int>();
9331 }
9332 bool flag = false;
9333 for (int i = 0; i < _cooldowns.Count; i++)
9334 {
9335 if (_cooldowns[i] / 1000 == idEle)
9336 {
9337 if (turns == 0)
9338 {
9339 _cooldowns.RemoveAt(i);
9340 }
9341 else
9342 {
9343 _cooldowns[i] = idEle * 1000 + turns;
9344 }
9345 flag = true;
9346 break;
9347 }
9348 }
9349 if (!flag && turns > 0)
9350 {
9351 AddCooldown(idEle, turns);
9352 }
9353 if (_cooldowns.Count == 0)
9354 {
9355 _cooldowns = null;
9356 }
9357 }
9358
9359 public bool HasCooldown(int idEle)
9360 {
9361 return GetCooldown(idEle) != 0;
9362 }
9363
9364 public int GetCooldown(int idEle)
9365 {
9366 if (_cooldowns != null)
9367 {
9368 for (int i = 0; i < _cooldowns.Count; i++)
9369 {
9370 if (_cooldowns[i] / 1000 == idEle)
9371 {
9372 return _cooldowns[i] % 1000;
9373 }
9374 }
9375 }
9376 return 0;
9377 }
9378
9379 public void TickCooldown()
9380 {
9381 for (int num = _cooldowns.Count - 1; num >= 0; num--)
9382 {
9383 if (_cooldowns[num] % 1000 == 1)
9384 {
9385 _cooldowns.RemoveAt(num);
9386 }
9387 else
9388 {
9389 _cooldowns[num]--;
9390 }
9391 }
9392 if (_cooldowns.Count == 0)
9393 {
9394 _cooldowns = null;
9395 }
9396 }
9397
9398 public void ChooseNewGoal()
9399 {
9400 if (IsPC && EClass.AdvMode)
9401 {
9402 SetNoGoal();
9403 return;
9404 }
9405 if (IsPCParty || base.noMove)
9406 {
9407 SetAI(new GoalIdle());
9408 return;
9409 }
9410 if ((IsHomeMember() && IsInHomeZone()) || IsGuest())
9411 {
9412 Goal goalFromTimeTable = GetGoalFromTimeTable(EClass.world.date.hour);
9413 if (goalFromTimeTable != null)
9414 {
9415 SetAI(goalFromTimeTable);
9416 if (goalFromTimeTable is GoalWork)
9417 {
9418 goalFromTimeTable.Tick();
9419 }
9420 return;
9421 }
9422 }
9423 if (goalList.index == -2)
9424 {
9425 goalList.Refresh(this, goalListType);
9426 }
9427 SetAI(goalList.Next());
9428 }
9429
9431 {
9432 if (IsPC)
9433 {
9434 return null;
9435 }
9436 switch (TimeTable.GetSpan(idTimeTable, hour))
9437 {
9438 case TimeTable.Span.Sleep:
9439 if (sleepiness.value > 10 || EClass._zone.isSimulating)
9440 {
9441 return new GoalSleep();
9442 }
9443 break;
9444 case TimeTable.Span.Eat:
9445 return new GoalIdle();
9446 case TimeTable.Span.Work:
9447 if (IsGuest())
9448 {
9449 return new GoalIdle();
9450 }
9451 return GetGoalWork();
9452 case TimeTable.Span.Free:
9453 if (IsGuest())
9454 {
9455 return new GoalIdle();
9456 }
9457 return GetGoalHobby();
9458 }
9459 return null;
9460 }
9461
9463 {
9464 if (IsPrisoner)
9465 {
9466 return new GoalIdle();
9467 }
9468 if (memberType == FactionMemberType.Livestock)
9469 {
9470 return new GoalGraze();
9471 }
9472 return new GoalWork();
9473 }
9474
9476 {
9477 if (IsPrisoner)
9478 {
9479 return new GoalIdle();
9480 }
9481 if (memberType == FactionMemberType.Livestock)
9482 {
9483 return new GoalGraze();
9484 }
9485 return new GoalHobby();
9486 }
9487
9488 public bool HasHobbyOrWork(string alias)
9489 {
9490 int num = EClass.sources.hobbies.alias.TryGetValue(alias)?.id ?? 0;
9491 listHobby.Clear();
9492 if (_works == null || _hobbies == null)
9493 {
9494 RerollHobby();
9495 }
9496 foreach (int work in _works)
9497 {
9498 if (work == num)
9499 {
9500 return true;
9501 }
9502 }
9503 foreach (int hobby in _hobbies)
9504 {
9505 if (hobby == num)
9506 {
9507 return true;
9508 }
9509 }
9510 return false;
9511 }
9512
9513 public void SetAIIdle()
9514 {
9515 }
9516
9517 public void SetAIAggro()
9518 {
9519 SetAI(new GoalCombat());
9520 }
9521
9523 {
9524 return SetAI(_NoGoalPC);
9525 }
9526
9528 {
9529 if (IsPC)
9530 {
9532 }
9533 if (ai.IsRunning)
9534 {
9535 if (ai == g && ai.IsNoGoal)
9536 {
9537 return g;
9538 }
9539 ai.Cancel();
9540 if (ai == g)
9541 {
9542 Debug.Log("goal is g:" + ai?.ToString() + "/" + this);
9543 return g;
9544 }
9545 }
9546 if (HasCondition<ConWait>())
9547 {
9548 RemoveCondition<ConWait>();
9549 }
9550 ai = g;
9551 ai.SetOwner(this);
9552 if (IsPC)
9553 {
9554 renderer.RefreshStateIcon();
9555 }
9556 return g;
9557 }
9558
9559 public void SetAIImmediate(AIAct g)
9560 {
9561 bool hasNoGoal = HasNoGoal;
9562 SetAI(g);
9563 if ((EClass.scene.actionMode != ActionMode.Sim || !EClass.scene.paused) && hasNoGoal && !(renderer as CharaRenderer).IsMoving)
9564 {
9565 Tick();
9566 }
9567 }
9568
9570 {
9571 BaseArea result = null;
9572 foreach (Hobby item in ListWorks())
9573 {
9574 AIWork aI = item.GetAI(this);
9575 if (aI.SetDestination())
9576 {
9577 if (aI.destArea != null)
9578 {
9579 result = aI.destArea;
9580 }
9581 else if (aI.destThing != null)
9582 {
9583 result = aI.destThing.pos.cell.room;
9584 }
9585 break;
9586 }
9587 }
9588 return result;
9589 }
9590
9591 public List<Hobby> ListWorks(bool useMemberType = true)
9592 {
9593 listHobby.Clear();
9594 if (useMemberType && memberType == FactionMemberType.Livestock)
9595 {
9596 listHobby.Add(new Hobby
9597 {
9598 id = 45
9599 });
9600 }
9601 else
9602 {
9603 if (_works == null)
9604 {
9605 RerollHobby();
9606 }
9607 foreach (int work in _works)
9608 {
9609 listHobby.Add(new Hobby
9610 {
9611 id = work
9612 });
9613 }
9614 }
9615 return listHobby;
9616 }
9617
9618 public List<Hobby> ListHobbies(bool useMemberType = true)
9619 {
9620 listHobby.Clear();
9621 if (!useMemberType || memberType != FactionMemberType.Livestock)
9622 {
9623 if (_hobbies == null)
9624 {
9625 RerollHobby();
9626 }
9627 foreach (int hobby in _hobbies)
9628 {
9629 listHobby.Add(new Hobby
9630 {
9631 id = hobby
9632 });
9633 }
9634 }
9635 return listHobby;
9636 }
9637
9638 public Hobby GetWork(string id)
9639 {
9640 foreach (Hobby item in ListWorks())
9641 {
9642 if (item.source.alias == id)
9643 {
9644 return item;
9645 }
9646 }
9647 foreach (Hobby item2 in ListHobbies())
9648 {
9649 if (item2.source.alias == id)
9650 {
9651 return item2;
9652 }
9653 }
9654 return null;
9655 }
9656
9657 public void RefreshWorkElements(ElementContainer parent = null)
9658 {
9659 if (workElements != null)
9660 {
9661 workElements.SetParent();
9662 }
9663 workElements = null;
9664 if (IsPCParty || homeBranch == null || homeBranch.owner == null)
9665 {
9666 return;
9667 }
9668 foreach (Hobby item in ListHobbies())
9669 {
9670 TryAdd(item);
9671 }
9672 foreach (Hobby item2 in ListWorks())
9673 {
9674 TryAdd(item2);
9675 }
9676 if (workElements != null)
9677 {
9678 workElements.SetParent(parent);
9679 }
9680 void TryAdd(Hobby h)
9681 {
9682 if (!h.source.elements.IsEmpty())
9683 {
9684 if (workElements == null)
9685 {
9686 workElements = new ElementContainer();
9687 }
9688 for (int i = 0; i < h.source.elements.Length; i += 2)
9689 {
9690 int num = h.source.elements[i];
9691 int num2 = h.source.elements[i + 1];
9692 int num3 = 100;
9693 if (num != 2115 && num != 2207)
9694 {
9695 num3 = h.GetEfficiency(this) * homeBranch.efficiency / 100;
9696 if (num3 <= 0)
9697 {
9698 continue;
9699 }
9700 }
9701 workElements.ModBase(num, (num2 < 0) ? (num2 / 10) : Mathf.Max(1, h.source.elements[i + 1] * num3 / 1000));
9702 }
9703 }
9704 }
9705 }
9706
9707 public string GetTextHobby(bool simple = false)
9708 {
9709 string text = (simple ? "" : ("hobby".lang() + ":"));
9710 foreach (Hobby item in ListHobbies())
9711 {
9712 text = text + " " + item.Name.TagColor((item.GetEfficiency(this) > 0) ? FontColor.Good : FontColor.Warning) + ",";
9713 }
9714 return text.TrimEnd(',');
9715 }
9716
9717 public string GetTextWork(bool simple = false)
9718 {
9719 string text = (simple ? "" : ("work".lang() + ":"));
9720 foreach (Hobby item in ListWorks())
9721 {
9722 text = text + " " + item.Name.TagColor((item.GetEfficiency(this) > 0) ? FontColor.Good : FontColor.Warning) + ",";
9723 }
9724 return text.TrimEnd(',');
9725 }
9726
9727 public void AddHobby(int id)
9728 {
9729 foreach (int hobby in _hobbies)
9730 {
9731 if (hobby == id)
9732 {
9733 return;
9734 }
9735 }
9736 _hobbies.Add(id);
9737 }
9738
9739 public void AddWork(int id)
9740 {
9741 foreach (int work in _works)
9742 {
9743 if (work == id)
9744 {
9745 return;
9746 }
9747 }
9748 _works.Add(id);
9749 }
9750
9751 public void RerollHobby(bool extraSlotChance = true)
9752 {
9753 if (_hobbies != null && _works != null)
9754 {
9755 _hobbies.Clear();
9756 _works.Clear();
9757 }
9758 else
9759 {
9760 _hobbies = new List<int>();
9761 _works = new List<int>();
9762 }
9763 if (source.hobbies.IsEmpty())
9764 {
9765 AddHobby(EClass.sources.hobbies.listHobbies.RandomItem().id);
9766 }
9767 else
9768 {
9769 string[] hobbies = source.hobbies;
9770 foreach (string text in hobbies)
9771 {
9772 if (EClass.sources.hobbies.alias.TryGetValue(text.Trim(), out var value))
9773 {
9774 AddHobby(value.id);
9775 continue;
9776 }
9777 ModUtil.LogModError("source chara row '" + source.id + "' has invalid hobby '" + text + "'", source);
9778 }
9779 }
9780 if (source.works.IsEmpty())
9781 {
9782 AddWork(EClass.sources.hobbies.listWorks.RandomItem().id);
9783 }
9784 else
9785 {
9786 string[] hobbies = source.works;
9787 foreach (string text2 in hobbies)
9788 {
9789 if (EClass.sources.hobbies.alias.TryGetValue(text2.Trim(), out var value2))
9790 {
9791 AddWork(value2.id);
9792 continue;
9793 }
9794 ModUtil.LogModError("source chara row '" + source.id + "' has invalid work '" + text2 + "'", source);
9795 }
9796 }
9797 GetWorkSummary().Reset();
9798 }
9799
9801 {
9802 if (_workSummary == null)
9803 {
9804 _workSummary = new WorkSummary();
9805 }
9806 return _workSummary;
9807 }
9808
9809 public void TickWork(VirtualDate date)
9810 {
9811 TimeTable.Span span = TimeTable.GetSpan(idTimeTable, date.hour);
9812 if (span != TimeTable.Span.Work && span != TimeTable.Span.Free)
9813 {
9814 return;
9815 }
9816 WorkSummary workSummary = GetWorkSummary();
9817 if (span == TimeTable.Span.Work)
9818 {
9819 if (workSummary.work != null)
9820 {
9821 PerformWork(workSummary.work, isHobby: false, date.IsRealTime);
9822 }
9823 }
9824 else if (workSummary.hobbies.Count > 0)
9825 {
9826 PerformWork(workSummary.hobbies.RandomItem(), isHobby: true, date.IsRealTime);
9827 }
9828 }
9829
9830 public bool TryWorkOutside(SourceHobby.Row sourceWork)
9831 {
9832 if (EClass.world.date.IsExpired(GetInt(51)))
9833 {
9834 Expedition expedition = Expedition.Create(this, sourceWork.expedition.ToEnum<ExpeditionType>());
9835 SetInt(51, EClass.world.date.GetRaw() + 60 * (expedition.hours + 24));
9836 homeBranch.expeditions.Add(expedition);
9837 return true;
9838 }
9839 return false;
9840 }
9841
9842 public void PerformWork(WorkSession session, bool isHobby = false, bool IsRealTime = false)
9843 {
9844 Hobby hobby = new Hobby();
9845 hobby.id = session.id;
9846 WorkSummary workSummary = _workSummary;
9847 hobby.GetAI(this).OnPerformWork(IsRealTime);
9848 if (!isHobby)
9849 {
9850 workSummary.progress += EClass.rnd(5) + 5;
9851 }
9852 int num = PerformWork(hobby, 0, isHobby);
9853 int num2 = PerformWork(hobby, 1, isHobby);
9854 int num3 = PerformWork(hobby, 2, isHobby);
9855 int num4 = PerformWork(hobby, 3, isHobby);
9856 workSummary.money += num;
9857 workSummary.food += num2;
9858 workSummary.knowledge += num3;
9859 workSummary.material += num4;
9860 int PerformWork(Hobby work, int idx, bool flag)
9861 {
9862 if (idx >= work.source.resources.Length)
9863 {
9864 return 0;
9865 }
9866 int num5 = work.source.resources[idx];
9867 int num6 = num5;
9868 num5 = Rand.Range(num5 * (100 - work.source.resources[idx]) / 100, num5);
9869 num5 = num5 * (flag ? 50 : 100) * session.efficiency / 10000;
9870 if (num6 > 0 && num5 <= 0)
9871 {
9872 num5 = 1;
9873 }
9874 return num5;
9875 }
9876 }
9877
9878 public void ValidateWorks()
9879 {
9880 _goalWork.FindWork(this, setAI: false);
9881 _goalHobby.ValidateHobby(this);
9882 }
9883
9884 public void InitStats(bool onDeserialize = false)
9885 {
9886 if (!onDeserialize)
9887 {
9888 _cints[10] = 20;
9889 _cints[11] = 70;
9890 _cints[13] = 70;
9891 _cints[14] = 70;
9892 _cints[15] = 70;
9893 _cints[17] = 0;
9894 _cints[18] = 0;
9895 }
9896 foreach (Condition condition in conditions)
9897 {
9898 condition.SetOwner(this, onDeserialize);
9899 }
9900 }
9901
9902 public Condition AddCondition<T>(int p = 100, bool force = false) where T : Condition
9903 {
9904 return AddCondition(typeof(T).Name, p, force);
9905 }
9906
9907 public Condition AddCondition<T>(int p, int p2, bool force = false) where T : Condition
9908 {
9909 return AddCondition(typeof(T).Name, p, p2, force);
9910 }
9911
9912 public Condition AddCondition(string id, int p = 100, bool force = false)
9913 {
9914 return AddCondition(Condition.Create(id, p), force);
9915 }
9916
9917 public Condition AddCondition(string id, int p, int p2, bool force = false)
9918 {
9919 Condition condition = Condition.Create(id, p);
9920 condition.P2 = p2;
9921 return AddCondition(condition, force);
9922 }
9923
9924 public Condition AddCondition(Condition c, bool force = false)
9925 {
9926 return AddCondition(c, null, force);
9927 }
9928
9929 public Condition AddCondition(Condition c, Chara giver, bool force = false)
9930 {
9931 c.owner = this;
9932 if (giver != null)
9933 {
9934 c._giver = giver;
9935 c.idGiver = giver.uid;
9936 }
9937 if (!(c is ConBurning))
9938 {
9939 if (c is ConBleed && ResistLv(964) >= 3)
9940 {
9941 return null;
9942 }
9943 }
9944 else if (ResistLv(950) >= 3)
9945 {
9946 return null;
9947 }
9948 if (c.GainResistFactor > 0 && CanGainConResist)
9949 {
9950 if (c.GainResistFactor >= 400)
9951 {
9952 c.power /= 2;
9953 }
9954 ResistCon(c);
9955 if (c.power <= 0)
9956 {
9957 return null;
9958 }
9959 }
9960 if (!force)
9961 {
9962 if (c.source.negate.Length != 0)
9963 {
9964 string[] negate = c.source.negate;
9965 foreach (string text in negate)
9966 {
9967 if (HasElement(text))
9968 {
9969 return null;
9970 }
9971 }
9972 }
9973 Element defenseAttribute = c.GetDefenseAttribute(this);
9974 if (defenseAttribute != null)
9975 {
9976 c.power = MathEx.ClampToInt(100L * (long)c.power / Mathf.Max(100 + defenseAttribute.Value, 1));
9977 }
9978 if (c.source.resistance.Length != 0)
9979 {
9980 int num = ResistLv(EClass.sources.elements.alias[c.source.resistance[0]].id);
9981 if (num > 0)
9982 {
9983 c.power /= num * num + 1;
9984 if (c.power <= 40)
9985 {
9986 return null;
9987 }
9988 }
9989 }
9990 c.power = c.EvaluatePower(c.power);
9991 if (c.power <= 0)
9992 {
9993 return null;
9994 }
9995 }
9996 int num2 = c.EvaluateTurn(c.power);
9997 if (c is ConDeathSentense && HasElement(494))
9998 {
9999 num2 = num2 * (100 + (int)Mathf.Sqrt(Evalue(494)) * 10) / 100;
10000 }
10001 if (num2 == 0)
10002 {
10003 return null;
10004 }
10005 for (int j = 0; j < conditions.Count; j++)
10006 {
10007 if (conditions[j].id != c.id)
10008 {
10009 continue;
10010 }
10011 if (c.Type == ConditionType.Stance || c.IsToggle)
10012 {
10013 conditions[j].Kill();
10014 return null;
10015 }
10016 if (conditions[j].CanStack(c))
10017 {
10018 if (conditions[j].ShouldOverride(c))
10019 {
10020 if (conditions[j].IsOverrideConditionMet(c, num2))
10021 {
10022 conditions[j].Kill(silent: true);
10023 continue;
10024 }
10025 return null;
10026 }
10027 if (CanGainConResist)
10028 {
10029 AddResistCon(c);
10030 }
10031 conditions[j].OnStacked(c.power);
10032 conditions[j].OnStartOrStack();
10033 conditions[j].PlayEffect();
10034 }
10035 if (!conditions[j].AllowMultipleInstance)
10036 {
10037 return null;
10038 }
10039 }
10040 foreach (Condition condition in conditions)
10041 {
10042 if (condition.TryNullify(c))
10043 {
10044 return null;
10045 }
10046 }
10047 c.value = num2;
10048 conditions.Add(c);
10049 if (CanGainConResist)
10050 {
10051 AddResistCon(c);
10052 }
10053 c.SetOwner(this);
10054 c.Start();
10055 SetDirtySpeed();
10056 if (c.ShouldRefresh)
10057 {
10058 Refresh();
10059 }
10060 if (c.CancelAI)
10061 {
10062 ai.Cancel();
10063 }
10064 if (IsPC && c.ConsumeTurn && !EClass.pc.isRestrained)
10065 {
10067 }
10068 if (c.SyncRide && (ride != null || parasite != null))
10069 {
10070 if (ride != null)
10071 {
10072 ride.AddCondition(Condition.Create(c.source.alias, c.power));
10073 }
10074 if (parasite != null)
10075 {
10076 parasite.AddCondition(Condition.Create(c.source.alias, c.power));
10077 }
10078 }
10079 return c;
10080 }
10081
10082 public override bool HasCondition<T>()
10083 {
10084 for (int i = 0; i < conditions.Count; i++)
10085 {
10086 if (conditions[i] is T)
10087 {
10088 return true;
10089 }
10090 }
10091 return false;
10092 }
10093
10094 public bool HasCondition(string alias)
10095 {
10096 for (int i = 0; i < conditions.Count; i++)
10097 {
10098 if (conditions[i].source.alias == alias)
10099 {
10100 return true;
10101 }
10102 }
10103 return false;
10104 }
10105
10106 public Element GetBuffStats(string alias)
10107 {
10108 return GetBuffStats(EClass.sources.elements.alias[alias].id);
10109 }
10110
10111 public Element GetBuffStats(int ele)
10112 {
10113 for (int i = 0; i < conditions.Count; i++)
10114 {
10115 if (conditions[i] is ConBuffStats conBuffStats && conBuffStats.refVal == ele)
10116 {
10117 return conBuffStats.elements.GetElement(ele);
10118 }
10119 }
10120 return null;
10121 }
10122
10123 public int CountDebuff()
10124 {
10125 int num = 0;
10126 foreach (Condition condition in conditions)
10127 {
10128 if (condition.Type == ConditionType.Debuff)
10129 {
10130 num++;
10131 }
10132 }
10133 return num;
10134 }
10135
10136 public void CureCondition<T>(int v = 99999) where T : Condition
10137 {
10138 T condition = GetCondition<T>();
10139 if (condition != null)
10140 {
10141 int value = condition.value - v;
10142 condition.value = value;
10143 if (condition.value <= 0)
10144 {
10145 condition.Kill();
10146 }
10147 }
10148 }
10149
10150 public BaseCondition GetCondition(string idCon)
10151 {
10152 for (int i = 0; i < conditions.Count; i++)
10153 {
10154 if (conditions[i].source.alias == idCon)
10155 {
10156 return conditions[i];
10157 }
10158 }
10159 return null;
10160 }
10161
10162 public override T GetCondition<T>()
10163 {
10164 for (int i = 0; i < conditions.Count; i++)
10165 {
10166 if (conditions[i] is T)
10167 {
10168 return conditions[i] as T;
10169 }
10170 }
10171 return null;
10172 }
10173
10174 public void RemoveCondition<T>() where T : Condition
10175 {
10176 for (int num = conditions.Count - 1; num >= 0; num--)
10177 {
10178 if (conditions[num] is T)
10179 {
10180 conditions[num].Kill();
10181 break;
10182 }
10183 }
10184 }
10185
10186 public void CureHost(CureType type, int p = 100, BlessedState state = BlessedState.Normal)
10187 {
10188 if (parasite != null)
10189 {
10190 parasite.Cure(type, p, state);
10191 }
10192 if (ride != null)
10193 {
10194 ride.Cure(type, p, state);
10195 }
10196 Cure(type, p, state);
10197 }
10198
10199 public void Cure(CureType type, int p = 100, BlessedState state = BlessedState.Normal)
10200 {
10201 bool flag = state == BlessedState.Blessed;
10202 switch (type)
10203 {
10204 case CureType.Heal:
10205 case CureType.Prayer:
10206 CureCondition<ConFear>();
10207 CureCondition<ConBlind>(2 * p / 100 + 5);
10208 CureCondition<ConPoison>(5 * p / 100 + 5);
10209 CureCondition<ConConfuse>(10 * p / 100 + 10);
10210 CureCondition<ConDim>(p / 100 + 5);
10211 CureCondition<ConBleed>(2 * p / 100 + 10);
10212 if (flag)
10213 {
10214 SAN.Mod(-15);
10215 }
10216 break;
10217 case CureType.CureBody:
10218 CureCondition<ConBlind>(5 * p / 100 + 15);
10219 CureCondition<ConPoison>(10 * p / 100 + 15);
10220 CureCondition<ConBleed>(5 * p / 100 + 20);
10221 CureTempElements(p, body: true, mind: false);
10222 break;
10223 case CureType.CureMind:
10224 CureCondition<ConFear>();
10225 CureCondition<ConDim>(3 * p / 100 + 10);
10226 CureTempElements(p, body: false, mind: true);
10227 break;
10228 case CureType.Sleep:
10229 {
10230 for (int num2 = conditions.Count - 1; num2 >= 0; num2--)
10231 {
10232 Condition condition2 = conditions[num2];
10233 if (!(condition2 is ConSleep) && !(condition2 is ConFaint))
10234 {
10235 if (condition2.isPerfume)
10236 {
10237 condition2.Mod(-1, force: true);
10238 }
10239 else if (condition2.Type == ConditionType.Bad || condition2.Type == ConditionType.Debuff)
10240 {
10241 condition2.Kill();
10242 }
10243 }
10244 }
10245 CureCondition<ConWait>();
10246 CureCondition<ConDisease>((EClass.rnd(20) + 10) * p / 100);
10247 bool flag2 = HasCondition<ConAnorexia>();
10248 base.c_vomit -= (flag2 ? 3 : 2) * p / 100;
10249 if (base.c_vomit < 0)
10250 {
10251 base.c_vomit = 0;
10252 if (flag2)
10253 {
10254 RemoveCondition<ConAnorexia>();
10255 }
10256 }
10257 break;
10258 }
10259 case CureType.HealComplete:
10260 case CureType.Death:
10261 case CureType.Jure:
10262 case CureType.Boss:
10263 case CureType.Unicorn:
10264 {
10265 CureTempElements(p * 100, body: true, mind: true);
10266 for (int num = conditions.Count - 1; num >= 0; num--)
10267 {
10268 Condition condition = conditions[num];
10269 if (condition is ConAnorexia && type != CureType.Death && type != CureType.Unicorn && type != CureType.Jure)
10270 {
10271 continue;
10272 }
10273 switch (condition.Type)
10274 {
10275 case ConditionType.Bad:
10276 case ConditionType.Debuff:
10277 case ConditionType.Disease:
10278 condition.Kill();
10279 continue;
10280 case ConditionType.Stance:
10281 if (type == CureType.Death)
10282 {
10283 condition.Kill();
10284 continue;
10285 }
10286 break;
10287 }
10288 if (type == CureType.Death && condition.isPerfume)
10289 {
10290 condition.Kill();
10291 }
10292 }
10293 CureCondition<ConWait>();
10294 CureCondition<ConSleep>();
10295 switch (type)
10296 {
10297 case CureType.Death:
10298 case CureType.Boss:
10299 case CureType.Unicorn:
10300 SAN.Mod(-20);
10301 RemoveCondition<ConBrightnessOfLife>();
10302 RemoveCondition<ConDeathSentense>();
10303 break;
10304 case CureType.Jure:
10305 SAN.Mod(-999);
10306 if (HasElement(1206))
10307 {
10308 SetFeat(1206, 0, msg: true);
10309 }
10310 RemoveCondition<ConBrightnessOfLife>();
10311 RemoveCondition<ConDeathSentense>();
10312 break;
10313 case CureType.CureBody:
10314 case CureType.CureMind:
10315 case CureType.Prayer:
10316 break;
10317 }
10318 break;
10319 }
10320 }
10321 }
10322
10323 public void RemoveAllStances()
10324 {
10325 for (int num = conditions.Count - 1; num >= 0; num--)
10326 {
10327 Condition condition = conditions[num];
10328 if (condition.Type == ConditionType.Stance)
10329 {
10330 condition.Kill();
10331 }
10332 }
10333 }
10334
10335 public bool TryNeckHunt(Chara TC, int power, bool harvest = false)
10336 {
10337 if (TC == null || TC.HasCondition<ConInvulnerable>() || TC.Evalue(1421) > 0 || !TC.ExistsOnMap)
10338 {
10339 return false;
10340 }
10341 if (TC.hp > (long)TC.MaxHP * (long)(Mathf.Min(5 + (int)Mathf.Sqrt(power), harvest ? 35 : 25) + Evalue(1426) * 5) / (TC.IsPowerful ? 200 : 100))
10342 {
10343 return false;
10344 }
10345 if (TC.HasElement(427))
10346 {
10347 return false;
10348 }
10349 if (TC.IsPC && EClass.player.invlunerable)
10350 {
10351 return false;
10352 }
10353 PlaySound("hit_finish");
10354 Say("finish");
10355 Say("finish2", this, TC);
10356 TC.DamageHP(TC.MaxHP, AttackSource.Finish, this);
10357 return false;
10358 }
10359
10360 public void AddResistCon(Condition con)
10361 {
10362 if (con.power > 0 && con.GainResistFactor > 0)
10363 {
10364 int key = con.id;
10365 if (resistCon == null)
10366 {
10367 resistCon = new Dictionary<int, int>();
10368 }
10369 if (resistCon.ContainsKey(key))
10370 {
10371 resistCon[key] += con.power * con.GainResistFactor / 100;
10372 }
10373 else
10374 {
10375 resistCon[key] = con.power * con.GainResistFactor / 100;
10376 }
10377 }
10378 }
10379
10380 public void ResistCon(Condition con)
10381 {
10382 if (con.power > 0 && resistCon != null)
10383 {
10384 int a = ClassExtension.TryGetValue<int, int>((IDictionary<int, int>)resistCon, con.id, 0);
10385 if (1000 < EClass.rnd(a))
10386 {
10387 con.power = 0;
10388 }
10389 else if (500 < EClass.rnd(a))
10390 {
10391 con.power /= 5;
10392 }
10393 else if (200 < EClass.rnd(a))
10394 {
10395 con.power /= 3;
10396 }
10397 else if (100 < EClass.rnd(a))
10398 {
10399 con.power /= 2;
10400 }
10401 }
10402 }
10403
10404 public void Sleep(Thing bed = null, Thing pillow = null, bool pickup = false, ItemPosition posBed = null, ItemPosition posPillow = null)
10405 {
10406 RemoveCondition<ConAwakening>();
10407 AddCondition(Condition.Create(100, delegate(ConSleep con)
10408 {
10409 con.pcSleep = 15;
10410 con.pcBed = bed;
10411 con.pcPillow = pillow;
10412 con.pickup = pickup;
10413 con.posBed = posBed;
10414 con.posPillow = posPillow;
10415 }), force: true);
10416 }
10417
10418 public void OnSleep(Thing bed = null, int days = 1)
10419 {
10420 bool isSunLit = pos.IsSunLit;
10421 TraitPillow traitPillow = pos.FindThing<TraitPillow>();
10422 int num = bed?.Power ?? 20;
10423 if (traitPillow != null)
10424 {
10425 num += traitPillow.owner.Power / 2;
10426 }
10427 if (bed != null)
10428 {
10429 num += bed.Evalue(750) * 5;
10430 if (bed.trait is TraitBedCoffin)
10431 {
10432 isSunLit = false;
10433 }
10434 }
10435 OnSleep(num, days, isSunLit);
10436 }
10437
10438 public void OnSleep(int power, int days = 1, bool isSunLit = false)
10439 {
10440 if (days < 1)
10441 {
10442 days = 1;
10443 }
10444 int num = power * days;
10445 if (stamina.value < 0)
10446 {
10447 stamina.Set(1);
10448 }
10449 if (IsPC)
10450 {
10452 foreach (BodySlot slot in body.slots)
10453 {
10454 if (slot.thing != null && slot.thing.GetBool(135))
10455 {
10457 slot.thing.SetBool(135, enable: false);
10458 }
10459 }
10460 }
10461 if (isWeakToSunlight && isSunLit)
10462 {
10463 base.hp = 0;
10464 if (mana.value > 0)
10465 {
10466 mana.Set(0);
10467 }
10468 AddCondition<ConBurning>(1000, force: true);
10469 }
10470 else
10471 {
10472 HealHP(num);
10473 stamina.Mod(10 + 25 * num / 100 * (100 + elements.GetFeatRef(1642)) / 100);
10474 mana.Mod(num);
10475 }
10476 if (IsPCFaction)
10477 {
10478 hunger.Mod(20);
10479 }
10480 sleepiness.Set(0);
10481 if (!IsMinion)
10482 {
10483 interest = 100;
10484 }
10485 Cure(CureType.Sleep, power);
10486 }
10487
10488 public void ModHeight(int a)
10489 {
10490 if (!HasElement(450))
10491 {
10492 long num = bio.height;
10493 num = num * (100 + a) / 100 + ((a > 0) ? 1 : (-1));
10494 if (num < 1)
10495 {
10496 num = 1L;
10497 }
10498 if (num > 999999999)
10499 {
10500 num = 999999999L;
10501 }
10502 if (num != bio.height)
10503 {
10504 bio.height = (int)num;
10505 Say((a > 0) ? "height_gain" : "height_lose", this);
10506 }
10507 }
10508 }
10509
10510 public void ModWeight(int a, bool ignoreLimit = false)
10511 {
10512 if (HasElement(450) || a == 0)
10513 {
10514 return;
10515 }
10516 long num = bio.weight;
10517 long num2 = bio.height;
10518 long num3 = num2 * num2 * 18 / 25000;
10519 long num4 = num2 * num2 * 24 / 10000;
10520 if (ignoreLimit || (num > num3 && num < num4))
10521 {
10522 num = num * (100 + a) / 100 + ((a > 0) ? 1 : (-1));
10523 if (num < 1)
10524 {
10525 num = 1L;
10526 }
10527 if (num > 999999999)
10528 {
10529 num = 999999999L;
10530 }
10531 if (num != bio.weight)
10532 {
10533 bio.weight = (int)num;
10534 Say((a > 0) ? "weight_gain" : "weight_lose", this);
10535 }
10536 }
10537 }
10538
10539 public void ModCorruption(int a)
10540 {
10541 if (a > 0)
10542 {
10543 if (Evalue(962) >= 25 || (ResistLv(962) > 0 && EClass.rnd(ResistLv(962) + 1) != 0))
10544 {
10545 return;
10546 }
10547 int num = Evalue(412);
10548 if (num != 0)
10549 {
10550 float num2 = (float)a * 100f / (float)Mathf.Max(100 + num * 2, 10);
10551 a = (int)num2 + ((EClass.rndf(1f) < num2 % 1f) ? 1 : 0);
10552 }
10553 }
10554 if (a == 0)
10555 {
10556 return;
10557 }
10558 int num3 = (corruption + a) / 100 - corruption / 100;
10559 for (int i = 0; i < Mathf.Abs(num3); i++)
10560 {
10561 if (!MutateRandom((num3 > 0) ? 1 : (-1), 100, ether: true))
10562 {
10563 break;
10564 }
10565 }
10566 corruption += a;
10567 int num4 = 0;
10568 foreach (Element value in elements.dict.Values)
10569 {
10570 if (value.source.category == "ether")
10571 {
10572 num4 += value.Value;
10573 }
10574 }
10575 if (num4 > 0 && IsPC)
10576 {
10577 Tutorial.Reserve("ether");
10578 }
10579 corruption = num4 * 100 + corruption % 100;
10580 }
10581
10582 public List<Element> ListAvailabeFeats(bool pet = false, bool showAll = false, bool purchaseFeat = false)
10583 {
10584 List<Element> list = new List<Element>();
10585 foreach (SourceElement.Row item in EClass.sources.elements.rows.Where((SourceElement.Row a) => a.group == "FEAT" && a.cost[0] != -1 && !a.categorySub.IsEmpty()))
10586 {
10587 Feat feat = elements.GetOrCreateElement(item.id) as Feat;
10588 int num = ((feat.ValueWithoutLink <= 0) ? 1 : (feat.ValueWithoutLink + 1));
10589 if (purchaseFeat)
10590 {
10591 num -= feat.GetDNABonus(this);
10592 }
10593 if (num <= feat.source.max && !feat.HasTag("class") && !feat.HasTag("hidden") && !feat.HasTag("innate") && (!pet || !feat.HasTag("noPet")) && (showAll || feat.IsPurchaseFeatReqMet(elements)))
10594 {
10595 list.Add(Element.Create(feat.id, num) as Feat);
10596 }
10597 }
10598 return list;
10599 }
10600
10601 public void SetFeat(int id, int value = 1, bool msg = false)
10602 {
10603 Feat feat = elements.GetElement(id) as Feat;
10604 int num = 0;
10605 if (feat != null && feat.ValueWithoutLink > 0)
10606 {
10607 if (value == feat.ValueWithoutLink)
10608 {
10609 return;
10610 }
10611 num = feat.ValueWithoutLink;
10612 feat.Apply(-feat.ValueWithoutLink, elements);
10613 }
10614 feat = elements.SetBase(id, value - (feat?.vSource ?? 0)) as Feat;
10615 if (feat != null && feat.ValueWithoutLink != 0)
10616 {
10617 feat.Apply(feat.ValueWithoutLink, elements);
10618 }
10620 {
10621 Refresh();
10622 CalculateMaxStamina();
10623 }
10624 if (!msg)
10625 {
10626 return;
10627 }
10628 if (feat != null)
10629 {
10630 if (feat.source.textInc.IsEmpty())
10631 {
10632 PlaySound("ding_skill");
10634 Say("gainFeat", this, feat.FullName);
10635 }
10636 else
10637 {
10638 bool flag = value < num;
10639 if (feat.source.tag.Contains("neg"))
10640 {
10641 flag = !flag;
10642 }
10643 switch (id)
10644 {
10645 case 1270:
10646 if (!flag)
10647 {
10648 PlaySound("chime_angel");
10649 }
10650 break;
10651 case 1271:
10652 if (!flag)
10653 {
10654 PlaySound("chime_devil");
10655 }
10656 break;
10657 default:
10658 PlaySound("mutation");
10659 break;
10660 }
10662 Say((value > num) ? feat.source.GetText("textInc") : feat.source.GetText("textDec"), this, feat.FullName);
10663 }
10664 }
10665 elements.CheckSkillActions();
10666 }
10667
10668 public void SetMutation(int idEle, int a = 0)
10669 {
10670 SourceElement.Row row = EClass.sources.elements.map[idEle];
10672 Element element = elements.GetElement(idEle);
10673 Element element2 = elements.GetElement(row2.id);
10674 int num = element?.Value ?? 0;
10675 if (a < 0)
10676 {
10677 a = 0;
10678 }
10679 if (a > row.max)
10680 {
10681 a = row.max;
10682 }
10683 bool flag = (row.tag.Contains("neg") ? (a > num) : (a < num));
10684 if (a == 0 && (element == null || element.Value == 0))
10685 {
10686 SayNothingHappans();
10687 return;
10688 }
10689 if (element != null && element.Value == a)
10690 {
10691 SayNothingHappans();
10692 return;
10693 }
10694 if (element2 != null && element2.Value > 0)
10695 {
10696 SetFeat(element2.id, 0);
10697 }
10698 SetFeat(idEle, a);
10699 PlaySound("mutation");
10700 PlayEffect("mutation");
10702 Say(row.GetText(flag ? "textDec" : "textInc", returnNull: true) ?? row.alias, this);
10703 }
10704
10705 public bool MutateRandom(int vec = 0, int tries = 100, bool ether = false, BlessedState state = BlessedState.Normal)
10706 {
10707 if (!ether && vec >= 0 && HasElement(406) && EClass.rnd(5) != 0)
10708 {
10709 Say("resistMutation", this);
10710 return false;
10711 }
10712 IEnumerable<SourceElement.Row> ie = EClass.sources.elements.rows.Where((SourceElement.Row a) => a.category == (ether ? "ether" : "mutation") && !a.tag.Contains("noRandomMutation"));
10713 for (int num = 0; num < tries; num++)
10714 {
10715 SourceElement.Row row = ie.RandomItem();
10716 if (num == 0 && vec < 0 && ether && base.c_corruptionHistory != null && base.c_corruptionHistory.Count > 0)
10717 {
10718 if (EClass.sources.elements.map.ContainsKey(base.c_corruptionHistory.LastItem()))
10719 {
10720 row = EClass.sources.elements.map[base.c_corruptionHistory.LastItem()];
10721 }
10722 base.c_corruptionHistory.RemoveAt(base.c_corruptionHistory.Count - 1);
10723 if (base.c_corruptionHistory.Count == 0)
10724 {
10725 base.c_corruptionHistory = null;
10726 }
10727 }
10728 Element element = elements.GetElement(row.id);
10729 int num2 = 1;
10730 if ((vec > 0 && ((row.id == 1563 && corruption < 300) || (row.id == 1562 && corruption < 1000 && base.IsPowerful))) || (vec < 0 && (element == null || element.Value <= 0)) || (vec > 0 && element != null && element.Value >= row.max))
10731 {
10732 continue;
10733 }
10734 if (element == null && !row.aliasParent.IsEmpty() && elements.Has(row.aliasParent))
10735 {
10736 row = EClass.sources.elements.alias[row.aliasParent];
10737 element = elements.GetElement(row.id);
10738 }
10739 bool flag = row.tag.Contains("neg");
10740 if (vec > 0)
10741 {
10742 if ((state >= BlessedState.Blessed && flag) || (state <= BlessedState.Cursed && !flag))
10743 {
10744 continue;
10745 }
10746 }
10747 else if (vec < 0 && ((state >= BlessedState.Blessed && !flag) || (state <= BlessedState.Cursed && flag)))
10748 {
10749 continue;
10750 }
10751 bool flag2 = true;
10752 if (element != null)
10753 {
10754 num2 = element.Value + ((vec != 0) ? vec : ((EClass.rnd(2) == 0) ? 1 : (-1)));
10755 if (num2 > element.source.max)
10756 {
10757 num2 = element.source.max - 1;
10758 }
10759 flag = (flag && num2 > element.Value) || (!flag && num2 < element.Value);
10760 flag2 = num2 > element.Value;
10761 if (vec > 0 && !flag2)
10762 {
10763 continue;
10764 }
10765 }
10766 Say(flag2 ? "mutation_gain" : "mutation_loose", this);
10767 SetFeat(row.id, num2);
10768 if (flag2 && ether)
10769 {
10770 if (base.c_corruptionHistory == null)
10771 {
10772 base.c_corruptionHistory = new List<int>();
10773 }
10774 base.c_corruptionHistory.Add(row.id);
10775 if (IsPCFaction)
10776 {
10777 Element element2 = elements.GetElement(row.id);
10778 WidgetPopText.Say("popEther".lang(element2.Name, base.Name));
10779 }
10780 if (IsPC && !EClass.player.flags.gotEtherDisease)
10781 {
10782 EClass.player.flags.gotEtherDisease = true;
10783 Thing thing = ThingGen.Create("parchment");
10784 thing.SetStr(53, "letter_ether");
10785 Thing thing2 = ThingGen.Create("1165");
10786 thing2.SetBlessedState(BlessedState.Normal);
10787 Thing p = ThingGen.CreateParcel(null, thing2, thing);
10789 }
10790 }
10791 if (EClass.core.IsGameStarted && pos != null)
10792 {
10793 PlaySound(ether ? "mutation_ether" : "mutation");
10794 PlayEffect("mutation");
10796 Say(row.GetText(flag ? "textDec" : "textInc", returnNull: true) ?? row.alias, this);
10797 }
10798 return true;
10799 }
10800 Say("nothingHappens");
10801 return false;
10802 }
10803
10804 public void GainAbility(int ele, int mtp = 100, Thing origin = null)
10805 {
10806 Element orCreateElement = elements.GetOrCreateElement(ele);
10807 if (orCreateElement.ValueWithoutLink == 0)
10808 {
10809 elements.ModBase(orCreateElement.id, 1);
10810 }
10811 if (orCreateElement is Spell)
10812 {
10813 int num = EClass.curve(Evalue(307), 50, 20) + (HasElement(307) ? 20 : 0);
10814 int num2 = origin?.Evalue(765) ?? 0;
10815 num = num * (100 - num2) / 100;
10816 int a = mtp * orCreateElement.source.charge * (100 + num) / 100 / 100;
10817 a = Mathf.Max(1, EClass.rndHalf(a));
10818 if (orCreateElement.source.charge == 1)
10819 {
10820 a = 1;
10821 }
10822 orCreateElement.vPotential += a;
10823 }
10824 Say("spell_gain", this, orCreateElement.Name);
10825 LayerAbility.SetDirty(orCreateElement);
10826 }
10827
10828 public bool TryNullifyCurse()
10829 {
10830 if (IsPCParty)
10831 {
10832 foreach (Chara member in EClass.pc.party.members)
10833 {
10834 if (member.HasElement(1641) && EClass.rnd(3) != 0)
10835 {
10836 Msg.Say("curse_nullify", member);
10837 return true;
10838 }
10839 }
10840 }
10841 else if (HasElement(1641) && EClass.rnd(3) != 0)
10842 {
10843 Say("curse_nullify", this);
10844 return true;
10845 }
10846 if (GetCondition<ConHolyVeil>() != null && EClass.rnd(5) != 0)
10847 {
10848 Say("curse_nullify", this);
10849 return true;
10850 }
10851 return false;
10852 }
10853
10854 public void OnAdvanceDay()
10855 {
10856 if (_historyFood != null)
10857 {
10858 while (_historyFood.Count > 5)
10859 {
10860 _historyFood.RemoveAt(_historyFood.Count - 1);
10861 }
10862 if (_historyFood[0].Count > 0)
10863 {
10864 _historyFood.Insert(0, new List<string>());
10865 }
10866 }
10867 }
10868
10870 {
10871 if (!IsPCFaction || !IsGlobal)
10872 {
10873 _historyFood = null;
10874 return;
10875 }
10876 if (_historyFood == null)
10877 {
10878 _historyFood = new List<List<string>>
10879 {
10880 new List<string>()
10881 };
10882 }
10883 if (_historyFood[0].Count < 5)
10884 {
10885 _historyFood[0].Add(food.id);
10886 }
10887 }
10888
10890 {
10891 if (_historyFood == null)
10892 {
10893 return -1;
10894 }
10895 int num = 0;
10896 foreach (List<string> item in _historyFood)
10897 {
10898 foreach (string item2 in item)
10899 {
10900 if (item2 == food.id)
10901 {
10902 num++;
10903 }
10904 }
10905 }
10906 return num;
10907 }
10908
10909 public int GetPietyValue()
10910 {
10911 if (base._IsPC)
10912 {
10913 return 10 + (int)(Mathf.Sqrt(base.c_daysWithGod) * 2f + (float)Evalue(85)) / 2;
10914 }
10915 return 10 + (int)(Mathf.Sqrt(base.LV) * 5f + (float)Evalue(306)) / 2;
10916 }
10917
10919 {
10920 if (faithElements != null)
10921 {
10922 faithElements.SetParent();
10923 }
10924 faithElements = new ElementContainer();
10925 if (idFaith == "eyth" && !HasElement(1228))
10926 {
10927 return;
10928 }
10929 SourceReligion.Row row = EClass.sources.religions.map.TryGetValue(idFaith);
10930 if (row == null)
10931 {
10932 return;
10933 }
10934 faithElements = new ElementContainer();
10935 if (!HasCondition<ConExcommunication>())
10936 {
10937 SourceElement.Row row2 = EClass.sources.elements.alias.TryGetValue("featGod_" + row.id + "1");
10938 if (row2 != null)
10939 {
10940 faithElements.SetBase(row2.id, 1);
10941 }
10942 int[] array = row.elements;
10943 int num = GetPietyValue() * (120 + Evalue(1407) * 15 + Evalue(1228) * 20) / 100;
10944 for (int i = 0; i < array.Length; i += 2)
10945 {
10946 int num2 = array[i + 1] * num / 50;
10947 if (array[i] == 79)
10948 {
10949 num2 = EClass.curve(num2, array[i + 1] * 2, 10, 50);
10950 }
10951 if (num2 >= 20 && array[i] >= 950 && array[i] < 970)
10952 {
10953 num2 = 20;
10954 }
10955 faithElements.SetBase(array[i], Mathf.Max(num2, 1));
10956 }
10957 }
10958 faithElements.SetParent(this);
10959 }
10960
10961 public void ModTempElement(int ele, int a, bool naturalDecay = false, bool onlyRenew = false)
10962 {
10963 if (a < 0 && !naturalDecay && HasElement(EClass.sources.elements.alias["sustain_" + EClass.sources.elements.map[ele].alias]?.id ?? 0))
10964 {
10965 return;
10966 }
10967 bool flag = HasElement(1215);
10968 if (tempElements == null)
10969 {
10970 tempElements = new ElementContainer();
10971 tempElements.SetParent(this);
10972 }
10973 if (a > 0 && flag)
10974 {
10975 a = a * 150 / 100;
10976 }
10977 int num = elements.ValueWithoutLink(ele);
10978 int num2 = Mathf.Abs(num) + 100;
10979 int num3 = num2 / (flag ? 2 : 4);
10980 int num4 = -num - 100;
10981 int num5 = tempElements.Base(ele);
10982 int num6 = num5 + a;
10983 if (onlyRenew)
10984 {
10985 num3 = Mathf.Min(a, num3);
10986 num4 = Mathf.Max(a, -num2 / 3);
10987 }
10988 if (a > 0 && num6 > num3)
10989 {
10990 a = ((num3 > num5) ? (num3 - num5) : 0);
10991 }
10992 if (a < 0 && num6 < num4)
10993 {
10994 a = ((num4 < num5) ? (num4 - num5) : 0);
10995 }
10996 Element element = tempElements.ModBase(ele, a);
10997 if (element.vBase == 0)
10998 {
10999 tempElements.Remove(element.id);
11000 if (tempElements.dict.Count == 0)
11001 {
11002 tempElements = null;
11003 }
11004 }
11005 }
11006
11007 public void DamageTempElements(int p, bool body, bool mind, bool onlyRenew = false)
11008 {
11009 if (body)
11010 {
11011 DamageTempElement(Element.List_Body.RandomItem(), p, onlyRenew);
11012 }
11013 if (mind)
11014 {
11015 DamageTempElement(Element.List_Mind.RandomItem(), p, onlyRenew);
11016 }
11017 }
11018
11019 public void DamageTempElement(int ele, int p, bool onlyRenew = false)
11020 {
11021 ModTempElement(ele, onlyRenew ? (-p / 20) : (-(p / 100 + EClass.rnd(p / 100 + 1) + 1)), naturalDecay: false, onlyRenew);
11022 }
11023
11024 public void EnhanceTempElements(int p, bool body, bool mind, bool onlyRenew = false)
11025 {
11026 int[] array = (body ? Element.List_Body : Element.List_Mind);
11027 foreach (int ele in array)
11028 {
11029 EnhanceTempElement(ele, p, onlyRenew);
11030 }
11031 }
11032
11033 public void EnhanceTempElement(int ele, int p, bool onlyRenew = false)
11034 {
11035 ModTempElement(ele, onlyRenew ? (p / 20) : (p / 100 + EClass.rnd(p / 100 + 1)), naturalDecay: false, onlyRenew);
11036 }
11037
11038 public void DiminishTempElements(int a = 1)
11039 {
11040 if (tempElements == null)
11041 {
11042 return;
11043 }
11044 foreach (Element item in tempElements.dict.Values.ToList())
11045 {
11046 if (item.vBase > 0)
11047 {
11048 ModTempElement(item.id, -Mathf.Min(item.vBase * 5 / 100 + 1, item.vBase), naturalDecay: true);
11049 }
11050 }
11051 }
11052
11053 public void CureTempElements(int p, bool body, bool mind)
11054 {
11055 if (tempElements != null)
11056 {
11057 if (body)
11058 {
11059 Cure(Element.List_Body);
11060 }
11061 if (mind)
11062 {
11063 Cure(Element.List_Mind);
11064 }
11065 }
11066 void Cure(int[] eles)
11067 {
11068 foreach (int ele in eles)
11069 {
11070 if (tempElements == null)
11071 {
11072 break;
11073 }
11074 Element element = tempElements.GetElement(ele);
11075 if (element != null && element.vBase < 0)
11076 {
11077 ModTempElement(ele, Mathf.Clamp(p / 20 + EClass.rnd(p / 20), 1, -element.vBase));
11078 }
11079 }
11080 }
11081 }
11082
11083 public void ClearTempElements()
11084 {
11085 if (tempElements != null)
11086 {
11087 tempElements.SetParent();
11088 tempElements = null;
11089 }
11090 }
11091}
AnimeID
Definition: AnimeID.cs:2
AttackSource
Definition: AttackSource.cs:2
AttackStyle
Definition: AttackStyle.cs:2
BlessedState
Definition: BlessedState.cs:2
BossType
Definition: BossType.cs:2
CTAG
Definition: CTAG.cs:2
@ ride
@ currency
ClearInventoryType
ConditionType
Definition: ConditionType.cs:2
ContainerFlag
Definition: ContainerFlag.cs:5
CureType
Definition: CureType.cs:2
CurrencyType
Definition: CurrencyType.cs:2
if(!match.Success)
DuplicateCondition
EditorTag
Definition: EditorTag.cs:2
EffectId
Definition: EffectId.cs:2
@ ChangeMaterial
Emo2
Definition: Emo2.cs:2
Emo
Definition: Emo.cs:2
@ harvest
ExpeditionType
FactionMemberType
FontColor
Definition: FontColor.cs:2
GoalListType
Definition: GoalListType.cs:2
Hostility
Definition: Hostility.cs:2
IDTSource
Definition: IDTSource.cs:2
ID_Achievement
MinionType
Definition: MinionType.cs:2
NameStyle
Definition: NameStyle.cs:2
PlaceState
Definition: PlaceState.cs:2
PriceType
Definition: PriceType.cs:2
Rarity
Definition: Rarity.cs:2
Ridability
Definition: Ridability.cs:2
ShopType
Definition: ShopType.cs:2
SourceValueType
TreasureType
Definition: TreasureType.cs:2
WitnessType
Definition: WitnessType.cs:2
Definition: ACT.cs:6
static Act Create(int id)
Definition: ACT.cs:36
Definition: AIAct.cs:6
Status Tick()
Definition: AIAct.cs:366
virtual bool IsIdle
Definition: AIAct.cs:78
AIAct Current
Definition: AIAct.cs:103
bool TryCancel(Card c)
Definition: AIAct.cs:280
bool IsMoveAI
Definition: AIAct.cs:55
virtual bool IsRunning
Definition: AIAct.cs:31
virtual bool PushChara
Definition: AIAct.cs:82
virtual Status Cancel()
Definition: AIAct.cs:305
virtual bool ShouldAllyAttack(Chara tg)
Definition: AIAct.cs:134
virtual bool IsNoGoal
Definition: AIAct.cs:74
virtual bool CancelOnAggro
Definition: AIAct.cs:80
void SetOwner(Chara c)
Definition: AIAct.cs:189
override string ToString()
Definition: AIAct.cs:124
virtual bool CancelWhenMoved
Definition: AIAct.cs:96
string GetCurrentActionText()
Definition: AIAct.cs:157
virtual Point GetDestination()
Definition: AIAct.cs:139
Definition: AIWork.cs:6
Thing destThing
Definition: AIWork.cs:17
bool SetDestination()
Definition: AIWork.cs:56
virtual void OnPerformWork(bool realtime)
Definition: AIWork.cs:155
BaseArea destArea
Definition: AIWork.cs:13
Definition: AI_Eat.cs:5
static bool slaughtering
Definition: AI_Slaughter.cs:6
bool TryCancelInteraction(bool sound=true)
Definition: AM_Adv.cs:1120
void SetTurbo(int mtp=-1)
Definition: AM_Adv.cs:1091
static void ProcAt(EffectId id, int power, BlessedState state, Card cc, Card tc, Point tp, bool isNeg, ActRef actRef=default(ActRef))
Definition: ActEffect.cs:519
List< Item > items
Definition: ActList.cs:14
static void Unride(Chara host, Chara mount, bool talk=true)
Definition: ActRide.cs:107
static EffectIRenderer Throw(Card c, Point p, Thing t, ThrowMethod method=ThrowMethod.Default, float failChance=0f)
Definition: ActThrow.cs:97
static void Search(Chara c, bool manual=false)
Definition: ActWait.cs:46
Definition: ACT.cs:62
CostType
Definition: ACT.cs:64
virtual bool Perform()
Definition: ACT.cs:266
virtual TargetType TargetType
Definition: ACT.cs:144
virtual float RapidDelay
Definition: ACT.cs:177
virtual bool ValidatePerform(Chara _cc, Card _tc, Point _tp)
Definition: ACT.cs:321
bool IsTargetHostileParty()
Definition: ACT.cs:241
virtual bool CanRapidFire
Definition: ACT.cs:175
static AM_Sim Sim
Definition: ActionMode.cs:11
static AM_Adv Adv
Definition: ActionMode.cs:15
static Affinity Get(Chara c)
Definition: Affinity.cs:38
int Mod(int a)
Definition: Affinity.cs:212
Stage CurrentStage
Definition: Affinity.cs:32
bool CanSleepBeside()
Definition: Affinity.cs:88
int GetLunchChance()
Definition: Affinity.cs:97
bool CanGiveCard()
Definition: Affinity.cs:70
bool IsWeddingHater
Definition: Affinity.cs:36
Thing OnGift(Thing t)
Definition: Affinity.cs:140
static int indexSister
virtual bool IsToggle
virtual RendererReplacer GetRendererReplacer()
virtual bool PreventRegen
virtual int EvaluatePower(int p)
virtual int GainResistFactor
virtual bool TryMove(Point p)
virtual bool ConsumeTurn
Element GetDefenseAttribute(Chara c=null)
virtual int EvaluateTurn(int p)
virtual bool TimeBased
virtual void OnRefresh()
void Mod(int a, bool force=false)
virtual void SetOwner(Chara _owner, bool onDeserialize=false)
virtual bool TryNullify(Condition c)
virtual void OnEndPlayerTurn()
virtual ConditionType Type
Definition: BaseStats.cs:33
virtual string GetPhaseStr()
Definition: BaseStats.cs:61
SourceStat.Row source
Definition: BaseStats.cs:16
virtual Emo2 EmoIcon
Definition: BaseStats.cs:31
int id
Definition: BaseStats.cs:11
virtual int GetValue()
Definition: BaseStats.cs:66
static int GetColorInt(ref Color matColor, int p)
void SetGender(int g)
Definition: Biography.cs:469
int weight
Definition: Biography.cs:41
void Generate(Chara c)
Definition: Biography.cs:323
int elementId
Definition: BodySlot.cs:6
Thing thing
Definition: BodySlot.cs:8
virtual bool isPCC
Definition: CardActor.cs:43
static void Set(CardBlueprint _bp=null)
static CardBlueprint CharaGenEQ
Chara Find(string id)
Definition: CardManager.cs:20
GlobalCharaList globalCharas
Definition: CardManager.cs:46
void PlayAnime(AnimeID id, bool force)
RendererReplacer replacer
Definition: CardRenderer.cs:29
Vector3 position
Definition: CardRenderer.cs:21
TransAnime anime
Definition: CardRenderer.cs:23
virtual void NextFrame()
void RefreshExtra()
CardActor actor
Definition: CardRenderer.cs:11
string id
Definition: CardRow.cs:7
Definition: Card.cs:11
bool IsNegativeGift
Definition: Card.cs:2466
bool isDestroyed
Definition: Card.cs:78
MinionType c_minionType
Definition: Card.cs:1015
int FameLv
Definition: Card.cs:2368
virtual string GetName(NameStyle style, int num=-1)
Definition: Card.cs:2748
bool IsPCFactionOrMinion
Definition: Card.cs:2342
void Teleport(Point point, bool silent=false, bool force=false)
Definition: Card.cs:6194
bool IsDecayed
Definition: Card.cs:2357
virtual bool isThing
Definition: Card.cs:2133
bool IsAmmo
Definition: Card.cs:2301
bool isSummon
Definition: Card.cs:713
virtual Chara Chara
Definition: Card.cs:2122
Thing Split(int a)
Definition: Card.cs:3665
int EvalueMax(int ele, int min=0)
Definition: Card.cs:2718
void MakeFigureFrom(string id)
Definition: Card.cs:6022
ElementContainerCard elements
Definition: Card.cs:42
string id
Definition: Card.cs:36
bool isNPCProperty
Definition: Card.cs:557
int GetSightRadius()
Definition: Card.cs:6905
bool IsUnique
Definition: Card.cs:2143
Hostility c_originalHostility
Definition: Card.cs:1003
bool isRestrained
Definition: Card.cs:569
bool IsThrownWeapon
Definition: Card.cs:2299
int ExpToNext
Definition: Card.cs:2060
CardBlueprint bp
Definition: Card.cs:80
SourceMaterial.Row material
Definition: Card.cs:2103
SoundSource PlaySound(string id, float v=1f, bool spatial=true)
Definition: Card.cs:6651
Card ChangeMaterial(int idNew, bool ignoreFixedMaterial=false)
Definition: Card.cs:3217
bool isCopy
Definition: Card.cs:881
void SetInt(string id, int value=0)
Definition: Card.cs:2586
Card MakeRefFrom(string id)
Definition: Card.cs:6027
void ClampInitialSkill()
Definition: Card.cs:3115
virtual int GetPrice(CurrencyType currency=CurrencyType.Money, bool sell=false, PriceType priceType=PriceType.Default, Chara c=null)
Definition: Card.cs:7786
int c_lockLv
Definition: Card.cs:991
bool ignoreAutoPick
Definition: Card.cs:509
int GetEquipValue()
Definition: Card.cs:7683
Fov fov
Definition: Card.cs:58
int invY
Definition: Card.cs:2007
virtual CardRenderer _CreateRenderer()
Definition: Card.cs:6440
bool IsCursed
Definition: Card.cs:2309
int c_uidMaster
Definition: Card.cs:1489
Biography bio
Definition: Card.cs:45
Thing AddThing(string id, int lv=-1)
Definition: Card.cs:3280
void Talk(string idTopic, string ref1=null, string ref2=null, bool forceSync=false)
Definition: Card.cs:7211
Card SetLv(int a)
Definition: Card.cs:3070
Rarity rarity
Definition: Card.cs:317
string Name
Definition: Card.cs:2191
bool IsRangedWeapon
Definition: Card.cs:2297
int CHA
Definition: Card.cs:2417
ICardParent parent
Definition: Card.cs:56
bool ExistsOnMap
Definition: Card.cs:2137
bool IsHotItem
Definition: Card.cs:122
Thing SetNum(int a)
Definition: Card.cs:3676
void SetReplica(bool on)
Definition: Card.cs:3251
bool IsFood
Definition: Card.cs:2229
PlaceState placeState
Definition: Card.cs:86
virtual void SetBlessedState(BlessedState s)
Definition: Card.cs:4076
bool isAcidproof
Definition: Card.cs:689
bool HasTag(CTAG tag)
Definition: Card.cs:2728
Point pos
Definition: Card.cs:60
void DyeRandom()
Definition: Card.cs:6473
int uid
Definition: Card.cs:125
Effect PlayEffect(string id, bool useRenderPos=true, float range=0f, Vector3 fix=default(Vector3))
Definition: Card.cs:6685
bool IsEquipmentOrRanged
Definition: Card.cs:2272
void TryStack(Thing t)
Definition: Card.cs:7489
void ShowEmo(Emo _emo=Emo.none, float duration=0f, bool skipSame=true)
Definition: Card.cs:6619
Trait trait
Definition: Card.cs:54
void ModCurrency(int a, string id="money")
Definition: Card.cs:4142
virtual bool IsAliveInCurrentZone
Definition: Card.cs:2179
MoveType
Definition: Card.cs:21
void DamageHP(long dmg, AttackSource attackSource=AttackSource.None, Card origin=null)
Definition: Card.cs:4276
bool isNew
Definition: Card.cs:485
void Destroy()
Definition: Card.cs:5314
bool c_isImportant
Definition: Card.cs:1051
MoveResult
Definition: Card.cs:13
bool noMove
Definition: Card.cs:773
bool HaveFur()
Definition: Card.cs:8456
void SetStr(string id, string value=null)
Definition: Card.cs:2600
ThingContainer things
Definition: Card.cs:39
BossType c_bossType
Definition: Card.cs:1261
bool IsInstalled
Definition: Card.cs:2451
bool IsMeleeWeapon
Definition: Card.cs:2295
virtual bool isChara
Definition: Card.cs:2135
virtual Thing Thing
Definition: Card.cs:2110
Card GetRootCard()
Definition: Card.cs:3607
int Evalue(int ele)
Definition: Card.cs:2704
bool GetBool(string id)
Definition: Card.cs:2557
int Dist(Card c)
Definition: Card.cs:8246
bool isHidden
Definition: Card.cs:533
virtual bool IsPCFaction
Definition: Card.cs:2339
bool isGifted
Definition: Card.cs:785
BlessedState blessedState
Definition: Card.cs:281
Thing Duplicate(int num)
Definition: Card.cs:3625
int _colorInt
Definition: Card.cs:70
bool isScaled
Definition: Card.cs:917
bool TryStackTo(Thing to)
Definition: Card.cs:3578
virtual bool IsPCFactionMinion
Definition: Card.cs:2209
Card Install()
Definition: Card.cs:3922
void ApplyBacker(int bid)
Definition: Card.cs:7506
Card parentCard
Definition: Card.cs:106
void ModExp(string alias, int a)
Definition: Card.cs:2781
string c_idRefName
Definition: Card.cs:1681
int GetLightRadius()
Definition: Card.cs:6914
int genLv
Definition: Card.cs:197
int Num
Definition: Card.cs:161
void PlayAnime(AnimeID id, bool force=false)
Definition: Card.cs:6670
SourceCategory.Row category
Definition: Card.cs:2101
void SetBool(string id, bool enable)
Definition: Card.cs:2562
void ModNum(int a, bool notify=true)
Definition: Card.cs:3696
virtual RenderRow TileRow
Definition: Card.cs:2187
bool isLeashed
Definition: Card.cs:845
bool IsIdentified
Definition: Card.cs:2447
bool IsContainer
Definition: Card.cs:2141
int c_charges
Definition: Card.cs:1309
CardRenderer renderer
Definition: Card.cs:64
void AddExp(int a, bool applyMod=true)
Definition: Card.cs:3123
bool HasElement(int ele, bool includeNagative=false)
Definition: Card.cs:6383
int LV
Definition: Card.cs:389
void Say(string lang, string ref1=null, string ref2=null)
Definition: Card.cs:7329
string c_idRefCard
Definition: Card.cs:1777
int c_uidAttune
Definition: Card.cs:1212
Thing MakeEgg(bool effect=true, int num=1, bool addToZone=true, int fertChance=20, BlessedState? state=null)
Definition: Card.cs:6045
List< Chara > charas
Definition: CellDetail.cs:13
bool isHostileAct
Definition: CellEffect.cs:74
EffectId idEffect
Definition: CellEffect.cs:38
bool isCursed
Definition: CellEffect.cs:98
SourceCellEffect.Row source
Definition: CellEffect.cs:145
bool isBlessed
Definition: CellEffect.cs:86
Definition: Cell.cs:7
Room room
Definition: Cell.cs:122
SourceBlock.Row sourceBlock
Definition: Cell.cs:1090
bool IsSnowTile
Definition: Cell.cs:818
SourceFloor.Row sourceFloor
Definition: Cell.cs:1092
CellEffect effect
Definition: Cell.cs:114
int obj
Definition: Cell.cs:50
bool hasDoorBoat
Definition: Cell.cs:510
bool HasBridge
Definition: Cell.cs:707
bool IsTopWaterAndNoSnow
Definition: Cell.cs:748
bool isClearSnow
Definition: Cell.cs:462
bool isFloating
Definition: Cell.cs:486
SourceMaterial.Row matObj
Definition: Cell.cs:1074
byte topHeight
Definition: Cell.cs:100
byte light
Definition: Cell.cs:80
SourceFloor.Row sourceBridge
Definition: Cell.cs:1094
bool IsSky
Definition: Cell.cs:970
byte z
Definition: Cell.cs:78
bool HasRoof
Definition: Cell.cs:684
SourceMaterial.Row matFloor
Definition: Cell.cs:1068
bool isSeen
Definition: Cell.cs:294
SourceObj.Row sourceObj
Definition: Cell.cs:1112
byte x
Definition: Cell.cs:76
bool HasRamp
Definition: Cell.cs:873
bool hasDoor
Definition: Cell.cs:279
SourceFloor.Row sourceSurface
Definition: Cell.cs:1097
float GetSurfaceHeight()
Definition: Cell.cs:1766
bool CanSuffocate()
Definition: Cell.cs:1151
ActList list
Definition: CharaAbility.cs:13
bool Has(int id)
bool HasWeapon()
Definition: CharaBody.cs:429
void RemoveBodyPartAt(int idx)
Definition: CharaBody.cs:373
void SetOwner(Chara chara, bool deserialized=false)
Definition: CharaBody.cs:18
void AddBodyPart(int ele, Thing thing=null)
Definition: CharaBody.cs:312
bool HasElement(int idEle)
Definition: CharaBody.cs:441
List< BodySlot > slots
Definition: CharaBody.cs:8
BodySlot slotMainHand
Definition: CharaBody.cs:10
bool IsTooHeavyToEquip(Thing thing)
Definition: CharaBody.cs:187
AttackStyle GetAttackStyle()
Definition: CharaBody.cs:508
bool IsEquippable(Thing thing, BodySlot slot, bool text=true)
Definition: CharaBody.cs:114
int GetWeight(bool armorOnly=false)
Definition: CharaBody.cs:465
bool Equip(Thing thing, BodySlot slot=null, bool msg=true)
Definition: CharaBody.cs:213
BodySlot GetSlot(Thing t, bool onlyEmpty=false, bool secondSlot=false)
Definition: CharaBody.cs:398
void RefreshBodyParts()
Definition: CharaBody.cs:338
void RemoveBodyPart(int ele)
Definition: CharaBody.cs:367
static Chara CreateFromFilter(string id, int lv=-1, int levelRange=-1)
Definition: CharaGen.cs:22
static Chara Create(string id, int lv=-1)
Definition: CharaGen.cs:17
override void SetOwner(Card c)
PCCData pccData
Definition: Chara.cs:10
void OnInsulted()
Definition: Chara.cs:8765
SourceCategory.Row GetFavCat()
Definition: Chara.cs:8614
void GetRevived()
Definition: Chara.cs:5512
string[] _strs
Definition: Chara.cs:81
bool IsHumanSpeak
Definition: Chara.cs:1071
void DamageTempElement(int ele, int p, bool onlyRenew=false)
Definition: Chara.cs:11019
Stats depression
Definition: Chara.cs:1232
bool UseAbility(string idAct, Card tc=null, Point pos=null, bool pt=false)
Definition: Chara.cs:6202
void Refresh(bool calledRecursive=false)
Definition: Chara.cs:1830
void ChangeRace(string idNew)
Definition: Chara.cs:2533
override SourcePref Pref
Definition: Chara.cs:807
bool HasHobbyOrWork(string alias)
Definition: Chara.cs:9488
static List< Chara > _pts
Definition: Chara.cs:192
string IDPCCBodySet
Definition: Chara.cs:497
void TickConditions()
Definition: Chara.cs:3970
const int LevelLimit
Definition: Chara.cs:11
override string actorPrefab
Definition: Chara.cs:527
bool wasInWater
Definition: Chara.cs:152
void UpdateSight()
Definition: Chara.cs:3942
int _affinity
Definition: Chara.cs:309
Stats sleepiness
Definition: Chara.cs:1240
static Point _sharedPos
Definition: Chara.cs:180
override bool IsAliveInCurrentZone
Definition: Chara.cs:569
void SetDirtySpeed()
Definition: Chara.cs:2095
bool IsFriendOrAbove(Chara c)
Definition: Chara.cs:7083
int GetBurden(Card t=null, int num=-1)
Definition: Chara.cs:2044
override void ApplyEditorTags(EditorTag tag)
Definition: Chara.cs:2277
BaseCondition GetCondition(string idCon)
Definition: Chara.cs:10150
Element MainElement
Definition: Chara.cs:737
Thing FindBestFoodToEat()
Definition: Chara.cs:8080
new TraitChara trait
Definition: Chara.cs:511
Hostility OriginalHostility
Definition: Chara.cs:477
void ResetBody()
Definition: Chara.cs:2467
CharaBody body
Definition: Chara.cs:96
void TryPickGroundItem(Func< Card, bool > func=null)
Definition: Chara.cs:4754
LayerDrama _ShowDialog(string book, string sheet, string step="main", string tag="")
Definition: Chara.cs:7746
Card held
Definition: Chara.cs:72
bool IsEyth
Definition: Chara.cs:1108
bool isAlawysVisible
Definition: Chara.cs:407
List< Element > ListAvailabeFeats(bool pet=false, bool showAll=false, bool purchaseFeat=false)
Definition: Chara.cs:10582
bool CanAcceptGift(Chara c, Card t)
Definition: Chara.cs:8817
bool IsLevitating
Definition: Chara.cs:605
WorkSummary GetWorkSummary()
Definition: Chara.cs:9800
float idleTimer
Definition: Chara.cs:124
override void Rotate(bool reverse=false)
Definition: Chara.cs:3820
AIAct ai
Definition: Chara.cs:208
void RemoveGlobal()
Definition: Chara.cs:1597
Chara CreateReplacement()
Definition: Chara.cs:8560
bool TryUse(Thing t)
Definition: Chara.cs:8421
override Sprite GetImageSprite()
Definition: Chara.cs:7536
void ValidateWorks()
Definition: Chara.cs:9878
bool IsFusable(Chara c)
Definition: Chara.cs:1922
override SpriteData GetSpriteData(int dir=0, bool snow=false)
Definition: Chara.cs:7170
void MoveHome(Zone zone, int x=-1, int z=-1)
Definition: Chara.cs:3755
void ChangeMemberType(FactionMemberType type)
Definition: Chara.cs:7541
void TickCooldown()
Definition: Chara.cs:9379
void CureTempElements(int p, bool body, bool mind)
Definition: Chara.cs:11053
bool IsDragon
Definition: Chara.cs:1019
bool TryNeckHunt(Chara TC, int power, bool harvest=false)
Definition: Chara.cs:10335
void UnmakeMinion()
Definition: Chara.cs:2622
int SpriteSkin
Definition: Chara.cs:1179
Element GetBuffStats(string alias)
Definition: Chara.cs:10106
bool IsWealthy
Definition: Chara.cs:1111
bool isWet
Definition: Chara.cs:146
static NoGoal _NoGoalPC
Definition: Chara.cs:202
void Cuddle(Chara c, bool headpat=false)
Definition: Chara.cs:6665
List< Chara > ListFussableCharas(int radius=2)
Definition: Chara.cs:1947
ConSuspend conSuspend
Definition: Chara.cs:106
bool IsCriticallyWounded(bool includeRide=false)
Definition: Chara.cs:1261
void ModTempElement(int ele, int a, bool naturalDecay=false, bool onlyRenew=false)
Definition: Chara.cs:10961
bool CanRevive()
Definition: Chara.cs:5507
bool isAstralBody
Definition: Chara.cs:158
bool CanPick(Card c)
Definition: Chara.cs:4598
void SetAIIdle()
Definition: Chara.cs:9513
string idFaith
Definition: Chara.cs:237
bool CanInteractTo(Point p)
Definition: Chara.cs:2814
override void SetSortVal(UIList.SortMode m, CurrencyType currency=CurrencyType.Money)
Definition: Chara.cs:7805
void TryPutShared(Thing t, List< Thing > containers=null, bool dropIfFail=true)
Definition: Chara.cs:4770
void CureHost(CureType type, int p=100, BlessedState state=BlessedState.Normal)
Definition: Chara.cs:10186
int[] _cints
Definition: Chara.cs:84
int stealthSeen
Definition: Chara.cs:194
bool canSeeInvisible
Definition: Chara.cs:142
int sharedCheckTurn
Definition: Chara.cs:122
void RefreshWorkElements(ElementContainer parent=null)
Definition: Chara.cs:9657
bool MutateRandom(int vec=0, int tries=100, bool ether=false, BlessedState state=BlessedState.Normal)
Definition: Chara.cs:10705
void InstantEat(Thing t=null, bool sound=true)
Definition: Chara.cs:8101
Goal GetGoalFromTimeTable(int hour)
Definition: Chara.cs:9430
Condition AddCondition(string id, int p=100, bool force=false)
Definition: Chara.cs:9912
override Sprite GetSprite(int dir=0)
Definition: Chara.cs:7149
bool IsHostile(Chara c)
Definition: Chara.cs:6987
Faction _faction
Definition: Chara.cs:162
Thing FindAmmo(Thing weapon)
Definition: Chara.cs:8353
Faction faction
Definition: Chara.cs:433
override bool isThing
Definition: Chara.cs:704
int Speed
Definition: Chara.cs:1151
void ModAffinity(Chara c, int a, bool show=true, bool showOnlyEmo=false)
Definition: Chara.cs:8482
override bool IsPC
Definition: Chara.cs:632
string idFaction
Definition: Chara.cs:249
int combatCount
Definition: Chara.cs:118
GoalListType goalListType
Definition: Chara.cs:285
bool CanAcceptItem(Card t, int num=-1, bool skipImportantCheck=false)
Definition: Chara.cs:8796
override CardRow sourceRenderCard
Definition: Chara.cs:459
void Divorce(Chara c)
Definition: Chara.cs:8660
void _MakeAlly()
Definition: Chara.cs:2568
override int GetArmorSkill()
Definition: Chara.cs:8412
void EnhanceTempElement(int ele, int p, bool onlyRenew=false)
Definition: Chara.cs:11033
static bool consumeTurn
Definition: Chara.cs:186
bool isDrunk
Definition: Chara.cs:128
Chara host
Definition: Chara.cs:35
bool knowFav
Definition: Chara.cs:419
void SetFaith(Religion r)
Definition: Chara.cs:1815
Thing MakeBraineCell()
Definition: Chara.cs:8760
bool IsPlant
Definition: Chara.cs:1031
bool IsValidGiftWeight(Card t, int num=-1)
Definition: Chara.cs:8786
Condition AddCondition(Condition c, bool force=false)
Definition: Chara.cs:9924
SourceJob.Row job
Definition: Chara.cs:472
Point GetFirstStep(Point newPoint, PathManager.MoveType moveType=PathManager.MoveType.Default)
Definition: Chara.cs:2863
Chara GetNearbyCatToSniff()
Definition: Chara.cs:8671
void RemoveAllStances()
Definition: Chara.cs:10323
List< int > _cooldowns
Definition: Chara.cs:60
static List< SourceCategory.Row > _listFavCat
Definition: Chara.cs:200
void SetFeat(int id, int value=1, bool msg=false)
Definition: Chara.cs:10601
void ResetUpgrade()
Definition: Chara.cs:9193
bool CanSeeLos(Card c, int dist=-1)
Definition: Chara.cs:1334
AIAct SetNoGoal()
Definition: Chara.cs:9522
bool IsMofuable
Definition: Chara.cs:1167
bool IsMaid
Definition: Chara.cs:1083
override bool IsGlobal
Definition: Chara.cs:630
override bool IsPCParty
Definition: Chara.cs:635
static Point shared
Definition: Chara.cs:13
bool IsAstralBody
Definition: Chara.cs:508
int DestDist
Definition: Chara.cs:1054
override MoveResult TryMove(Point newPoint, bool allowDestroyPath=true)
Definition: Chara.cs:2970
void ShowDialog()
Definition: Chara.cs:7546
override void WriteNote(UINote n, Action< UINote > onWriteNote=null, IInspect.NoteMode mode=IInspect.NoteMode.Default, Recipe recipe=null)
Definition: Chara.cs:7795
override string ToString()
Definition: Chara.cs:1256
Party party
Definition: Chara.cs:45
Chara TryDuplicate(DuplicateCondition con=DuplicateCondition.Default, Point dest=null, bool inheritHostility=false)
Definition: Chara.cs:1988
void TryTakeSharedItems(IEnumerable< Thing > containers, bool msg=true, bool shouldEat=true)
Definition: Chara.cs:7921
bool CanDestroyPath()
Definition: Chara.cs:2702
ElementContainer tempElements
Definition: Chara.cs:38
void TryPutSharedItems(bool msg=true)
Definition: Chara.cs:7911
void SetMainElement(int id, int v=0, bool elemental=false)
Definition: Chara.cs:2335
Stats hygiene
Definition: Chara.cs:1236
int interest
Definition: Chara.cs:323
void ApplyRace(bool remove=false)
Definition: Chara.cs:2490
int corruption
Definition: Chara.cs:383
bool RequestProtection(Chara attacker, Action< Chara > action)
Definition: Chara.cs:8993
void OnAdvanceDay()
Definition: Chara.cs:10854
int GetHappiness()
Definition: Chara.cs:7770
void ModHeight(int a)
Definition: Chara.cs:10488
PathProgress path
Definition: Chara.cs:94
bool isParalyzed
Definition: Chara.cs:136
int EvalueRiding()
Definition: Chara.cs:6564
bool IsInCombat
Definition: Chara.cs:920
bool TryWorkOutside(SourceHobby.Row sourceWork)
Definition: Chara.cs:9830
TraitBed TryAssignBed()
Definition: Chara.cs:7860
void UpdateAngle()
Definition: Chara.cs:3881
override void OnSerializing()
Definition: Chara.cs:1400
List< Condition > conditions
Definition: Chara.cs:217
int MaxGeneSlot
Definition: Chara.cs:1124
bool IsBranchMember()
Definition: Chara.cs:7039
void SetMutation(int idEle, int a=0)
Definition: Chara.cs:10668
void HoldCard(Card t, int num=-1)
Definition: Chara.cs:4800
void PickHeld(bool msg=false)
Definition: Chara.cs:4856
static bool isOnCreate
Definition: Chara.cs:190
bool HasCondition(string alias)
Definition: Chara.cs:10094
SpriteReplacer spriteReplacer
Definition: Chara.cs:160
void Banish(Chara owner)
Definition: Chara.cs:2602
void Kiss(Chara c)
Definition: Chara.cs:6704
static List< Thing > _ListItems
Definition: Chara.cs:196
AIAct SetAI(AIAct g)
Definition: Chara.cs:9527
Chara SetHomeZone(Zone zone)
Definition: Chara.cs:1523
bool IsIdle
Definition: Chara.cs:909
Chara SetFaction(Faction f)
Definition: Chara.cs:1515
void SetMainElement(string id, int v=0, bool elemental=false)
Definition: Chara.cs:2326
void HealAll()
Definition: Chara.cs:1821
override bool IsDisabled
Definition: Chara.cs:593
void Marry(Chara c)
Definition: Chara.cs:8647
int CurrentGeneSlot
Definition: Chara.cs:1139
Thing GetBestRangedWeapon()
Definition: Chara.cs:8368
TraitBed FindBed()
Definition: Chara.cs:7848
bool CanDuplicate(DuplicateCondition con=DuplicateCondition.Default)
Definition: Chara.cs:1952
bool IsPrisoner
Definition: Chara.cs:1094
bool IsNeutralOrAbove()
Definition: Chara.cs:7034
bool IsAdventurer
Definition: Chara.cs:1097
bool _isLevitating
Definition: Chara.cs:138
bool hasMovedThisTurn
Definition: Chara.cs:182
int happiness
Definition: Chara.cs:112
void DiminishTempElements(int a=1)
Definition: Chara.cs:11038
Thing GetRandomRangedWeapon()
Definition: Chara.cs:8383
int uidEditor
Definition: Chara.cs:359
Stats hunger
Definition: Chara.cs:1226
int GetCurrentDir()
Definition: Chara.cs:3920
override string GetName(NameStyle style, int num=-1)
Definition: Chara.cs:1445
override bool IsMinion
Definition: Chara.cs:647
int GetHireCost()
Definition: Chara.cs:7765
Chara SetGlobal(Zone _home, int x, int z)
Definition: Chara.cs:1569
void EnhanceTempElements(int p, bool body, bool mind, bool onlyRenew=false)
Definition: Chara.cs:11024
override string GetHoverText()
Definition: Chara.cs:7259
override int WeightLimit
Definition: Chara.cs:730
override void OnDeserialized()
Definition: Chara.cs:1415
override void SetSource()
Definition: Chara.cs:2314
int contribution
Definition: Chara.cs:20
bool TryHoldCard(Card t, int num=-1, bool pickHeld=false)
Definition: Chara.cs:4778
override bool isSynced
Definition: Chara.cs:711
static List< Hobby > listHobby
Definition: Chara.cs:15
Point orgPos
Definition: Chara.cs:23
int CalcCastingChance(Element e, int num=1)
Definition: Chara.cs:6573
bool ShouldEquip(Thing t, bool useFav=false)
Definition: Chara.cs:8151
bool CanMoveTo(Point p, bool allowDestroyPath=true)
Definition: Chara.cs:2715
Emo2 emoIcon
Definition: Chara.cs:110
bool IsHuman
Definition: Chara.cs:935
WorkSummary _workSummary
Definition: Chara.cs:57
bool HasMinion(string id)
Definition: Chara.cs:2655
override bool HasHost
Definition: Chara.cs:708
bool MoveRandom()
Definition: Chara.cs:2868
bool IsAnimal
Definition: Chara.cs:923
void DestroyPath(Point pos)
Definition: Chara.cs:3460
int daysStarved
Definition: Chara.cs:335
int CountDebuff()
Definition: Chara.cs:10123
override CardRenderer _CreateRenderer()
Definition: Chara.cs:7099
void PickOrDrop(Point p, string idThing, int idMat=-1, int num=1, bool msg=true)
Definition: Chara.cs:4616
void TryPutSharedItems(IEnumerable< Thing > containers, bool msg=true)
Definition: Chara.cs:7878
override bool IsPCFaction
Definition: Chara.cs:691
override bool IsPCPartyMinion
Definition: Chara.cs:659
bool TryNullifyCurse()
Definition: Chara.cs:10828
override int SelfWeight
Definition: Chara.cs:732
void CalculateMaxStamina()
Definition: Chara.cs:2258
int MaxSummon
Definition: Chara.cs:734
Chara ScaleByPrincipal()
Definition: Chara.cs:1799
Thing TryGetThrowable()
Definition: Chara.cs:8307
void MoveZone(Zone z, ZoneTransition transition)
Definition: Chara.cs:3620
void TryUpgrade(bool msg=true)
Definition: Chara.cs:9198
int calmCheckTurn
Definition: Chara.cs:120
void MakeMinion(Chara _master, MinionType type=MinionType.Default)
Definition: Chara.cs:2611
override void LookAt(Point p)
Definition: Chara.cs:3839
void OnBanish()
Definition: Chara.cs:1537
override bool flipX
Definition: Chara.cs:555
string NameBraced
Definition: Chara.cs:522
Condition AddCondition(string id, int p, int p2, bool force=false)
Definition: Chara.cs:9917
bool CanSee(Card c)
Definition: Chara.cs:1302
bool HasAccess(Card c)
Definition: Chara.cs:1368
Goal GetGoalWork()
Definition: Chara.cs:9462
override int DV
Definition: Chara.cs:749
ConSleep conSleep
Definition: Chara.cs:104
override bool IsPCFactionMinion
Definition: Chara.cs:675
void Vomit()
Definition: Chara.cs:5666
void SetCooldown(int idEle, int turns=0)
Definition: Chara.cs:9326
void AddWork(int id)
Definition: Chara.cs:9739
bool IsFriendOrAbove()
Definition: Chara.cs:7078
void Slap(Chara c, bool slapToDeath=false)
Definition: Chara.cs:6731
override MoveResult _Move(Point newPoint, MoveType type=MoveType.Walk)
Definition: Chara.cs:2994
bool CanEat(Thing t, bool shouldEat=false)
Definition: Chara.cs:8126
float actTime
Definition: Chara.cs:184
Tactics _tactics
Definition: Chara.cs:170
bool ShouldThrowAway(Thing t, ClearInventoryType type)
Definition: Chara.cs:9065
int GeneCostMTP
Definition: Chara.cs:1127
void SetAIAggro()
Definition: Chara.cs:9517
ElementContainer _baseWorkElements
Definition: Chara.cs:210
override void Die(Element e=null, Card origin=null, AttackSource attackSource=AttackSource.None, Chara originalTarget=null)
Definition: Chara.cs:5702
Chara Duplicate()
Definition: Chara.cs:2010
void MakePartyMemeber()
Definition: Chara.cs:2542
void SetAIImmediate(AIAct g)
Definition: Chara.cs:9559
void PerformWork(WorkSession session, bool isHobby=false, bool IsRealTime=false)
Definition: Chara.cs:9842
void PickOrDrop(Point p, Thing t, bool msg=true)
Definition: Chara.cs:4624
static GoalHobby _goalHobby
Definition: Chara.cs:214
void ClearTempElements()
Definition: Chara.cs:11083
override int MaxHP
Definition: Chara.cs:728
Zone currentZone
Definition: Chara.cs:261
bool IsFairy
Definition: Chara.cs:995
bool HasAccess(Point p)
Definition: Chara.cs:1373
override bool isChara
Definition: Chara.cs:706
string Aka
Definition: Chara.cs:222
override bool IsDeadOrSleeping
Definition: Chara.cs:581
Stats bladder
Definition: Chara.cs:1234
bool CanReplace(Chara c)
Definition: Chara.cs:3571
List< Hobby > ListHobbies(bool useMemberType=true)
Definition: Chara.cs:9618
void TryClearInventory()
Definition: Chara.cs:9136
Thing ranged
Definition: Chara.cs:100
Stats SAN
Definition: Chara.cs:1242
void MakeAlly(bool msg=true)
Definition: Chara.cs:2548
void RemoveLastBodyPart(bool msg=false)
Definition: Chara.cs:2453
ElementContainer baseWorkElements
Definition: Chara.cs:1195
void TickWork(VirtualDate date)
Definition: Chara.cs:9809
Goal GetGoalHobby()
Definition: Chara.cs:9475
int _maxStamina
Definition: Chara.cs:371
bool isWeakToSunlight
Definition: Chara.cs:156
void Stumble(int mtp=100)
Definition: Chara.cs:2078
void SetSummon(int duration, bool dropCorpse=false)
Definition: Chara.cs:2667
void ClearInventory(ClearInventoryType type)
Definition: Chara.cs:9170
SourceChara.Row source
Definition: Chara.cs:164
new Point lastPos
Definition: Chara.cs:92
void GainAbility(int ele, int mtp=100, Thing origin=null)
Definition: Chara.cs:10804
bool isCreated
Definition: Chara.cs:140
Stats mana
Definition: Chara.cs:1238
void MoveByForce(Point newPoint, Card c=null, bool checkWall=false)
Definition: Chara.cs:2900
bool FindNewEnemy()
Definition: Chara.cs:6890
FactionMemberType memberType
Definition: Chara.cs:48
string TalkTopic(string topic="calm")
Definition: Chara.cs:7469
int _idTimeTable
Definition: Chara.cs:347
void TryDropBossLoot()
Definition: Chara.cs:6031
override int PV
Definition: Chara.cs:778
string GetIdPortraitCat()
Definition: Chara.cs:8719
SourceRace.Row _race
Definition: Chara.cs:166
Stats stamina
Definition: Chara.cs:1230
bool CanGainConResist
Definition: Chara.cs:1245
string NameTitled
Definition: Chara.cs:524
bool HasHigherGround(Card c)
Definition: Chara.cs:1274
void TryRestock(bool onCreate)
Definition: Chara.cs:5015
void RestockInventory(bool onCreate)
Definition: Chara.cs:5382
List< List< string > > _historyFood
Definition: Chara.cs:66
bool MoveNeighborDefinitely()
Definition: Chara.cs:2882
bool CanSleep()
Definition: Chara.cs:1387
bool UseAbility(int idAct, Card tc=null, Point pos=null, bool pt=false)
Definition: Chara.cs:6197
Stats burden
Definition: Chara.cs:1228
void AddHobby(int id)
Definition: Chara.cs:9727
bool visibleWithTelepathy
Definition: Chara.cs:154
void ChangeJob(string idNew)
Definition: Chara.cs:2413
GlobalData global
Definition: Chara.cs:78
SourceThing.Row GetFavFood()
Definition: Chara.cs:8581
override bool IsMoving
Definition: Chara.cs:628
void SetTempHand(int right=0, int left=0)
Definition: Chara.cs:7184
int[] rawSlots
Definition: Chara.cs:75
void GoHostile(Card _tg)
Definition: Chara.cs:6773
void ApplyJob(bool remove=false)
Definition: Chara.cs:2404
bool IsGod
Definition: Chara.cs:1007
bool IsHomeMember()
Definition: Chara.cs:7048
Chara parasite
Definition: Chara.cs:32
void AddRandomBodyPart(bool msg=false)
Definition: Chara.cs:2442
string GetActionText()
Definition: Chara.cs:7785
void SyncRide(Chara c)
Definition: Chara.cs:4268
Chara master
Definition: Chara.cs:90
List< Hobby > ListWorks(bool useMemberType=true)
Definition: Chara.cs:9591
Card DropHeld(Point dropPos=null)
Definition: Chara.cs:4933
void Revive(Point p=null, bool msg=false)
Definition: Chara.cs:5533
void TryReservePickupTutorial(Thing t)
Definition: Chara.cs:4730
Chara ride
Definition: Chara.cs:29
LayerDrama ShowDialog(string book, string step="main", string tag="")
Definition: Chara.cs:7741
Zone homeZone
Definition: Chara.cs:273
void RefreshFaithElement()
Definition: Chara.cs:10918
ElementContainer faithElements
Definition: Chara.cs:40
override void ChangeRarity(Rarity r)
Definition: Chara.cs:1502
void GiveLovePotion(Chara c, Thing t)
Definition: Chara.cs:8983
bool IsUndead
Definition: Chara.cs:947
void AddCooldown(int idEle, int turns=0)
Definition: Chara.cs:9308
bool IsGuest()
Definition: Chara.cs:7073
int GetTotalFeat()
Definition: Chara.cs:8693
Hobby GetWork(string id)
Definition: Chara.cs:9638
GoalList goalList
Definition: Chara.cs:206
bool IsHorror
Definition: Chara.cs:971
SourceJob.Row _job
Definition: Chara.cs:168
bool CanOpenDoor
Definition: Chara.cs:851
void SetEQQuality()
Definition: Chara.cs:5421
void RerollHobby(bool extraSlotChance=true)
Definition: Chara.cs:9751
Thing MakeGene(DNA.Type? type=null)
Definition: Chara.cs:8755
void RefreshSpeed(Element.BonusInfo info=null)
Definition: Chara.cs:2104
static List< SourceRace.Row > ListAdvRace
Definition: Chara.cs:172
bool IsLocalChara
Definition: Chara.cs:897
bool CanBeTempAlly(Chara c)
Definition: Chara.cs:2589
bool CanBloom()
Definition: Chara.cs:9291
int GetCooldown(int idEle)
Definition: Chara.cs:9364
override string AliasMaterialOnCreate
Definition: Chara.cs:566
void ModWeight(int a, bool ignoreLimit=false)
Definition: Chara.cs:10510
bool ignoreSPAbsorb
Definition: Chara.cs:150
void AddFoodHistory(Thing food)
Definition: Chara.cs:10869
override CardRow sourceCard
Definition: Chara.cs:456
BaseArea GetRoomWork()
Definition: Chara.cs:9569
bool CanInteractTo(Card c)
Definition: Chara.cs:2809
Thing nextUse
Definition: Chara.cs:102
Affinity affinity
Definition: Chara.cs:320
string GetTopicText(string topic="calm")
Definition: Chara.cs:7435
static NoGoal _NoGoalRepeat
Definition: Chara.cs:204
void ModCorruption(int a)
Definition: Chara.cs:10539
void RestockEquip(bool onCreate)
Definition: Chara.cs:5025
override void SetDir(int d)
Definition: Chara.cs:3813
MoveResult TryMoveTowards(Point p)
Definition: Chara.cs:2908
bool isBerserk
Definition: Chara.cs:126
void BanishAllMinions()
Definition: Chara.cs:2639
Religion faith
Definition: Chara.cs:445
List< int > _hobbies
Definition: Chara.cs:51
bool FindNearestNewEnemy()
Definition: Chara.cs:6967
string GetIdPortrait()
Definition: Chara.cs:8733
bool HasNoGoal
Definition: Chara.cs:1056
bool IsMarried
Definition: Chara.cs:617
Element GetFavWeaponSkill()
Definition: Chara.cs:5001
void DropThing(Thing t, int num=-1)
Definition: Chara.cs:4953
Chara enemy
Definition: Chara.cs:88
void GiveGift(Chara c, Thing t)
Definition: Chara.cs:8846
void EQ_Item(string s, int num=1)
Definition: Chara.cs:5490
BitArray32 _cbits1
Definition: Chara.cs:86
string GetTextHappiness()
Definition: Chara.cs:7780
CharaAbility ability
Definition: Chara.cs:430
bool IsInActiveZone
Definition: Chara.cs:894
override void Tick()
Definition: Chara.cs:4281
Quest quest
Definition: Chara.cs:26
Chara FindMaster()
Definition: Chara.cs:2677
override bool IsMultisize
Definition: Chara.cs:726
Chara SetEnemy(Chara c=null)
Definition: Chara.cs:6748
void SyncRide()
Definition: Chara.cs:4252
void CallHelp(Chara tg, bool fanatic=false)
Definition: Chara.cs:6879
void DoHostileAction(Card _tg, bool immediate=false)
Definition: Chara.cs:6797
bool isBlind
Definition: Chara.cs:134
bool CanSeeSimple(Point p)
Definition: Chara.cs:1285
bool dirtySpeed
Definition: Chara.cs:176
Thing EQ_ID(string s, int mat=-1, Rarity r=Rarity.Random)
Definition: Chara.cs:5454
void ClearBed(Map map=null)
Definition: Chara.cs:7833
bool IsMachine
Definition: Chara.cs:959
override void SetRenderParam(RenderParam p)
Definition: Chara.cs:7209
void AddResistCon(Condition con)
Definition: Chara.cs:10360
void MoveZone(Zone z, ZoneTransition.EnterState state=ZoneTransition.EnterState.Auto)
Definition: Chara.cs:3612
bool UseAbility(Act a, Card tc=null, Point pos=null, bool pt=false)
Definition: Chara.cs:6207
bool TryEquip(Thing t, bool useFav=false)
Definition: Chara.cs:8263
Room FindRoom()
Definition: Chara.cs:8477
override SubPassData GetSubPassData()
Definition: Chara.cs:7193
bool CanSeeLos(Point p, int dist=-1)
Definition: Chara.cs:1343
int CountNumEaten(Thing food)
Definition: Chara.cs:10889
Point GetDestination()
Definition: Chara.cs:7760
int turnLastSeen
Definition: Chara.cs:114
static bool preventRegen
Definition: Chara.cs:188
void ResistCon(Condition con)
Definition: Chara.cs:10380
string _alias
Definition: Chara.cs:225
FactionBranch homeBranch
Definition: Chara.cs:1122
Element GetFavArmorSkill()
Definition: Chara.cs:5006
int GetPietyValue()
Definition: Chara.cs:10909
void ChooseNewGoal()
Definition: Chara.cs:9398
void DamageTempElements(int p, bool body, bool mind, bool onlyRenew=false)
Definition: Chara.cs:11007
bool IsEnemyOnPath(Point p, bool cancelAI=true)
Definition: Chara.cs:2786
void FallFromZone()
Definition: Chara.cs:3800
void Drink(Card t)
Definition: Chara.cs:5497
Hostility hostility
Definition: Chara.cs:297
void InitStats(bool onDeserialize=false)
Definition: Chara.cs:9884
bool isFainted
Definition: Chara.cs:132
void MoveHome(string id, int x=-1, int z=-1)
Definition: Chara.cs:3750
Tactics tactics
Definition: Chara.cs:866
bool CanWitness
Definition: Chara.cs:1059
Card SplitHeld(int a)
Definition: Chara.cs:4916
void TryDropCarryOnly()
Definition: Chara.cs:4921
bool IsHostile()
Definition: Chara.cs:6982
Condition AddCondition(Condition c, Chara giver, bool force=false)
Definition: Chara.cs:9929
bool IsInHomeZone()
Definition: Chara.cs:7053
bool isDead
Definition: Chara.cs:395
bool TryIdentify(Thing t, int count=1, bool show=true)
Definition: Chara.cs:8538
Thing TryPoisonPotion(Thing t)
Definition: Chara.cs:4686
long _Speed
Definition: Chara.cs:178
void TryTakeSharedItems(bool msg=true)
Definition: Chara.cs:7916
override void LookAt(Card c)
Definition: Chara.cs:3834
bool isConfused
Definition: Chara.cs:130
static List< SourceThing.Row > _listFavFood
Definition: Chara.cs:198
ConBaseTransmuteMimic mimicry
Definition: Chara.cs:108
void SaiyanRevive()
Definition: Chara.cs:5605
bool TryEquipRanged()
Definition: Chara.cs:8388
void SetFaith(string id)
Definition: Chara.cs:1810
PCCData pccData
Definition: Chara.cs:69
void ApplyDeathPenalty()
Definition: Chara.cs:5639
void Cure(CureType type, int p=100, BlessedState state=BlessedState.Normal)
Definition: Chara.cs:10199
static string[] IDTimeTable
Definition: Chara.cs:17
TimeTable.Span CurrentSpan
Definition: Chara.cs:868
Chara SetHostility(Hostility h)
Definition: Chara.cs:1530
Thing Pick(Thing t, bool msg=true, bool tryStack=true)
Definition: Chara.cs:4636
bool CanLift(Card c)
Definition: Chara.cs:4588
List< int > _listAbility
Definition: Chara.cs:63
void TrySetEnemy(Chara c)
Definition: Chara.cs:6765
string idTimeTable
Definition: Chara.cs:474
override void OnCreate(int genLv)
Definition: Chara.cs:1622
void TryAbsorbRod(Thing t)
Definition: Chara.cs:4700
bool CanAutoPick(Card c)
Definition: Chara.cs:4593
void Sniff(Chara c)
Definition: Chara.cs:8683
List< int > _works
Definition: Chara.cs:54
string GetTextWork(bool simple=false)
Definition: Chara.cs:9717
override bool IsPCC
Definition: Chara.cs:702
bool TryFuse(float chance=1f)
Definition: Chara.cs:1864
void TryPush(Point point)
Definition: Chara.cs:3504
string GetTextHobby(bool simple=false)
Definition: Chara.cs:9707
Dictionary< int, int > resistCon
Definition: Chara.cs:220
void OnSleep(Thing bed=null, int days=1)
Definition: Chara.cs:10418
bool hasTelepathy
Definition: Chara.cs:144
CharaAbility _ability
Definition: Chara.cs:98
Chara SetGlobal()
Definition: Chara.cs:1584
bool CanInsult()
Definition: Chara.cs:8707
void EQ_CAT(string s)
Definition: Chara.cs:5474
bool bossText
Definition: Chara.cs:148
override string GetHoverText2()
Definition: Chara.cs:7335
bool IsEscorted()
Definition: Chara.cs:2686
int ParseBodySlot(string s)
Definition: Chara.cs:2425
bool CanEquipRanged(Thing t)
Definition: Chara.cs:8302
void Sleep(Thing bed=null, Thing pillow=null, bool pickup=false, ItemPosition posBed=null, ItemPosition posPillow=null)
Definition: Chara.cs:10404
void OnGiveErohon(Thing t)
Definition: Chara.cs:8972
override int PrefIndex
Definition: Chara.cs:539
AttackStyle GetFavAttackStyle()
Definition: Chara.cs:4981
bool HasCooldown(int idEle)
Definition: Chara.cs:9359
static GoalWork _goalWork
Definition: Chara.cs:212
int idleActTimer
Definition: Chara.cs:116
bool IsFish
Definition: Chara.cs:983
bool IsCat
Definition: Chara.cs:1043
void OnSleep(int power, int days=1, bool isSunLit=false)
Definition: Chara.cs:10438
void DoAI(int wait, Action onPerform)
Definition: Chara.cs:6653
ElementContainer workElements
Definition: Chara.cs:42
bool WillConsumeTurn()
Definition: Chara.cs:3958
bool IsNeutral()
Definition: Chara.cs:7029
static List< SourceJob.Row > ListAdvJob
Definition: Chara.cs:174
void MoveZone(string alias)
Definition: Chara.cs:3607
void CalcBurden()
Definition: Chara.cs:2063
void SetPCCState(PCCState state)
Definition: Chara.cs:7141
SourceRace.Row race
Definition: Chara.cs:470
Element GetBuffStats(int ele)
Definition: Chara.cs:10111
void MakeGrave(string lastword)
Definition: Chara.cs:5619
override void OnBeforeCreate()
Definition: Chara.cs:1606
bool DroppedCard(string id)
Definition: CodexManager.cs:46
void MarkCardDrop(string id)
Definition: CodexManager.cs:41
Color colorHostile
Color colorBlood
Color colorDebuff
Color colorFriend
UD_String_MatData matColors
Gradient gradientLVComparison
virtual string GetHoverText2()
virtual string GetName(NameStyle style, int num=-1)
virtual string GetHoverText()
virtual bool IsKilled
Definition: Condition.cs:8
void Kill(bool silent=false)
Definition: Condition.cs:108
override void Tick()
Definition: Condition.cs:87
static Condition Create(string alias, int power=100, Action< Condition > onCreate=null)
Definition: Condition.cs:47
bool allyKeepDistance
Definition: ConfigTactics.cs:6
static void Collect(Thing t)
bool ignoreBackerDestoryFlag
Definition: CoreConfig.cs:578
new GameConfig game
Definition: CoreConfig.cs:629
BackerContentConfig backer
Definition: CoreConfig.cs:633
bool ignoreWeight
Definition: CoreDebug.cs:203
bool godMode
Definition: CoreDebug.cs:189
bool showExtra
Definition: CoreDebug.cs:184
bool ignoreEncounter
Definition: CoreDebug.cs:217
bool enable
Definition: CoreDebug.cs:302
bool ignoreAutoSave
Definition: CoreDebug.cs:142
static string DramaData
Definition: CorePath.cs:174
SourcePref snowputit2
Definition: CoreRef.cs:329
SourcePref sonwputit1
Definition: CoreRef.cs:327
SourcePref replacer1
Definition: CoreRef.cs:333
PrefData prefs
Definition: CoreRef.cs:420
CoreRef refs
Definition: Core.cs:51
bool IsGameStarted
Definition: Core.cs:87
PCCManager pccs
Definition: Core.cs:41
CoreConfig config
Definition: Core.cs:70
static Thing MakeLoveLunch(Chara c)
Definition: CraftUtil.cs:221
static string GetBloodText(Chara c)
Definition: CraftUtil.cs:118
Definition: DNA.cs:9
Type
Definition: DNA.cs:11
static Thing GenerateGene(Chara c, Type? type=null)
Definition: DNA.cs:106
int hour
Definition: Date.cs:74
int GetRaw(int offsetHours=0)
Definition: Date.cs:328
bool IsExpired(int time)
Definition: Date.cs:338
bool IsNight
Definition: Date.cs:112
Definition: Dialog.cs:7
static bool warned
Definition: Dialog.cs:50
static void TryWarnMana(Action action)
Definition: Dialog.cs:399
Definition: EClass.cs:6
static Game game
Definition: EClass.cs:9
static int curve(long _a, int start, int step, int rate=75)
Definition: EClass.cs:69
static Scene scene
Definition: EClass.cs:31
static Faction Home
Definition: EClass.cs:27
static ColorProfile Colors
Definition: EClass.cs:39
static Core core
Definition: EClass.cs:7
static Zone _zone
Definition: EClass.cs:21
static World world
Definition: EClass.cs:41
static Map _map
Definition: EClass.cs:19
static int rnd(long a)
Definition: EClass.cs:59
static SourceManager sources
Definition: EClass.cs:43
static bool AdvMode
Definition: EClass.cs:11
static float rndf(float a)
Definition: EClass.cs:102
static FactionBranch Branch
Definition: EClass.cs:23
static BaseGameScreen screen
Definition: EClass.cs:33
static int rndHalf(int a)
Definition: EClass.cs:97
static Player player
Definition: EClass.cs:13
static Chara pc
Definition: EClass.cs:15
static int sqrt(int a)
Definition: EClass.cs:88
static CoreDebug debug
Definition: EClass.cs:49
static SoundManager Sound
Definition: EClass.cs:47
static UI ui
Definition: EClass.cs:17
static GameSetting setting
Definition: EClass.cs:35
Definition: EInput.cs:8
static void Consume(int _skipFrame)
Definition: EInput.cs:667
Definition: Effect.cs:7
Effect _Play(Point from, Vector3 fromV, float fixY=0f, Point to=null, Sprite sprite=null)
Definition: Effect.cs:117
static Effect Get(Effect original)
Definition: Effect.cs:80
void Play(float delay, Point from, float fixY=0f, Point to=null, Sprite sprite=null)
Definition: Effect.cs:100
void ModExp(int ele, float a, bool chain=false)
Dictionary< int, Element > dict
void SetParent(Card c)
int Value(int ele)
int ValueWithoutLink(int ele)
Element ModBase(int ele, int v)
void ApplyElementMap(int uid, SourceValueType type, Dictionary< int, int > map, int lv, bool invert=false, bool applyFeat=false)
void SetTo(int id, int v)
Element SetBase(string alias, int v, int potential=0)
void Remove(int id)
Element GetElement(string alias)
int GetDNABonus(Chara c)
Definition: ELEMENT.cs:531
int ValueWithoutLink
Definition: ELEMENT.cs:303
static int[] List_Body
Definition: ELEMENT.cs:253
int id
Definition: ELEMENT.cs:259
int vBase
Definition: ELEMENT.cs:261
SourceElement.Row source
Definition: ELEMENT.cs:282
int vPotential
Definition: ELEMENT.cs:265
static SourceElement.Row Get(int id)
Definition: ELEMENT.cs:410
bool HasTag(string tag)
Definition: ELEMENT.cs:482
virtual int GetPower(Card c)
Definition: ELEMENT.cs:1134
int Value
Definition: ELEMENT.cs:301
virtual string Name
Definition: ELEMENT.cs:313
static Element Create(int id, int v=0)
Definition: ELEMENT.cs:1163
virtual Act.Cost GetCost(Chara c)
Definition: ELEMENT.cs:1092
static List< SourceElement.Row > ListElements
Definition: ELEMENT.cs:277
virtual bool PotentialAsStock
Definition: ELEMENT.cs:345
int vSource
Definition: ELEMENT.cs:271
static Element Void
Definition: ELEMENT.cs:247
static int[] List_Mind
Definition: ELEMENT.cs:255
virtual int CostLearn
Definition: ELEMENT.cs:323
static int[] List_MainAttributesMajor
Definition: ELEMENT.cs:251
Act act
Definition: ELEMENT.cs:403
bool IsMainAttribute
Definition: ELEMENT.cs:392
Zone zone
Definition: EloMap.cs:11
bool shore
Definition: EloMap.cs:50
Cell GetCell(Point pos)
Definition: EloMap.cs:272
TileInfo GetTileInfo(int gx, int gy)
Definition: EloMap.cs:286
void Add(Expedition ex)
static Expedition Create(Chara c, ExpeditionType type)
Definition: Expedition.cs:119
int hours
Definition: Expedition.cs:7
Definition: FLOOR.cs:2
static SourceFloor.Row sourceSnow
Definition: FLOOR.cs:31
static SourceFloor.Row sourceIce
Definition: FLOOR.cs:35
static bool IsTatami(int id)
Definition: FLOOR.cs:39
static SourceFloor.Row sourceWood
Definition: FLOOR.cs:37
ExpeditionManager expeditions
int Evalue(int ele)
void RemoveMemeber(Chara c)
PolicyManager policies
string Log(string idLang, string ref1=null, string ref2=null, string ref3=null, string ref4=null)
bool HasItemProtection
void AddMemeber(Chara c)
Dictionary< string, Faction > dictAll
Hostility GetHostility()
Definition: FACTION.cs:255
Definition: FEAT.cs:345
override string FullName
Definition: FEAT.cs:355
virtual List< string > Apply(int a, ElementContainer owner, bool hint=false)
Definition: FEAT.cs:425
override bool IsPurchaseFeatReqMet(ElementContainer owner, int lv=-1)
Definition: FEAT.cs:399
static void ProcDrink(Chara c, Thing food)
Definition: FoodEffect.cs:368
static void Proc(Chara c, Thing food, bool consume=true)
Definition: FoodEffect.cs:16
Dictionary< int, byte > lastPoints
Definition: Fov.cs:36
void AdvanceMin(int a)
Definition: GameDate.cs:24
static string Parse(string text, bool thirdPerson, string val1, string val2=null, string val3=null, string val4=null)
Definition: GameLang.cs:177
bool disableVoidBlessing
bool disableDeathPenaltyProtection
RenderData renderTempEQ
Definition: GameScreen.cs:7
float defaultActPace
Definition: GameSetting.cs:374
PassSetting pass
Definition: GameSetting.cs:350
RenderSetting render
Definition: GameSetting.cs:348
UD_String_ElementRef elements
Definition: GameSetting.cs:362
bool autoCollectCard
Definition: Game.cs:52
ConfigPreference preference
Definition: Game.cs:97
ConfigTactics tactics
Definition: Game.cs:91
ConfigAutoCombat autoCombat
Definition: Game.cs:94
ReligionManager religions
Definition: Game.cs:159
GamePrincipal principal
Definition: Game.cs:225
bool Save(bool isAutoSave=false, bool silent=false)
Definition: Game.cs:1090
SpatialManager spatials
Definition: Game.cs:153
PCCUniformManager uniforms
Definition: Game.cs:195
CardManager cards
Definition: Game.cs:156
Zone activeZone
Definition: Game.cs:252
bool IsSurvival
Definition: Game.cs:276
new World world
Definition: Game.cs:177
Config config
Definition: Game.cs:219
QuestManager quests
Definition: Game.cs:183
int seed
Definition: Game.cs:201
FactionManager factions
Definition: Game.cs:162
GlobalGoal goal
Definition: GlobalData.cs:9
void SetOwner(Chara c)
Definition: GlobalGoal.cs:10
int index
Definition: GoalList.cs:5
void Refresh(Chara owner, GoalListType type)
Definition: GoalList.cs:9
Goal Next()
Definition: GoalList.cs:39
void ValidateHobby(Chara c)
Definition: GoalWork.cs:21
bool FindWork(Chara c, bool setAI=true)
Definition: GoalWork.cs:55
Definition: Goal.cs:4
bool ShowBounty(Chara c)
Definition: GuildFighter.cs:39
bool HasBounty(Chara c)
Definition: GuildFighter.cs:44
Definition: Guild.cs:2
static GuildFighter Fighter
Definition: Guild.cs:56
Definition: Hobby.cs:5
SourceHobby.Row source
Definition: Hobby.cs:8
int GetEfficiency(Chara c)
Definition: Hobby.cs:31
AIWork GetAI(Chara c)
Definition: Hobby.cs:12
virtual Thing Thing
Definition: HotItem.cs:38
static bool Has(string id)
Definition: LangGame.cs:99
Definition: Lang.cs:7
static string[] GetList(string id)
Definition: Lang.cs:113
static string _currency(object a, string IDCurrency)
Definition: Lang.cs:161
static void SetDirty(Element a)
static LayerDrama Activate(string book, string idSheet, string idStep, Chara target=null, Card ref1=null, string tag="")
Definition: LayerDrama.cs:66
static string forceJump
Definition: LayerDrama.cs:18
static LayerDrama ActivateMain(string idSheet, string idStep=null, Chara target=null, Card ref1=null, string tag="")
Definition: LayerDrama.cs:61
static void SetDirty(Thing t)
Definition: Los.cs:5
static bool IsVisible(Point p1, Point p2, Action< Point, bool > _onVisit=null)
Definition: Los.cs:167
static SourceMaterial.Row sourceOak
Definition: MATERIAL.cs:47
static SourceMaterial.Row sourceSnow
Definition: MATERIAL.cs:41
static SourceMaterial.Row sourceIce
Definition: MATERIAL.cs:43
Point GetCenterPos()
Definition: MapBounds.cs:52
bool Contains(int dx, int dz)
Definition: MapBounds.cs:38
Definition: Map.cs:13
bool IsIndoor
Definition: Map.cs:136
Thing FindThing(Func< Thing, bool > func)
Definition: Map.cs:2799
Chara FindChara(string id)
Definition: Map.cs:2775
void MoveCard(Point p, Card t)
Definition: Map.cs:953
void SetLiquid(int x, int z, CellEffect effect=null)
Definition: Map.cs:1638
void SetFoormark(Point pos, int id, int angle, int offset=0)
Definition: Map.cs:2221
List< Chara > deadCharas
Definition: Map.cs:49
PropsManager props
Definition: Map.cs:94
RoomManager rooms
Definition: Map.cs:34
Cell[,] cells
Definition: Map.cs:88
void SetEffect(int x, int z, CellEffect effect=null)
Definition: Map.cs:1669
List< Chara > charas
Definition: Map.cs:84
MapBounds bounds
Definition: Map.cs:55
Definition: MathEx.cs:2
static int ClampToInt(long a)
Definition: MathEx.cs:25
Color Negative
Definition: MsgColors.cs:15
Color Thinking
Definition: MsgColors.cs:17
Color MutateBad
Definition: MsgColors.cs:21
Color Talk
Definition: MsgColors.cs:7
Color Ono
Definition: MsgColors.cs:13
Color Ding
Definition: MsgColors.cs:11
Color MutateGood
Definition: MsgColors.cs:19
Definition: Msg.cs:5
static MsgColors colors
Definition: Msg.cs:20
static ThirstPersonInfo thirdPerson1
Definition: Msg.cs:6
static string SayNothingHappen()
Definition: Msg.cs:96
static string Say(string idLang, string ref1, string ref2=null, string ref3=null, string ref4=null)
Definition: Msg.cs:58
static void SetColor()
Definition: Msg.cs:22
Definition: NoGoal.cs:4
int emitFoot
Definition: PCOrbit.cs:9
int emitSmoke
Definition: PCOrbit.cs:11
Vector3 smokePos
Definition: PCOrbit.cs:15
Vector3 footPos
Definition: PCOrbit.cs:13
Definition: Party.cs:7
bool HasElement(int ele, bool excludePC=false)
Definition: Party.cs:212
void RemoveMember(Chara c)
Definition: Party.cs:116
Chara leader
Definition: Party.cs:31
List< Chara > members
Definition: Party.cs:19
void AddMemeber(Chara c, bool showMsg=false)
Definition: Party.cs:71
void RequestPathImmediate(PathProgress progress)
Definition: PathManager.cs:41
Point GetFirstStep(Point origin, Point _dest, IPathfindWalker walker, int maxDist=20, MoveType moveType=MoveType.Default)
Definition: PathManager.cs:67
static PathManager Instance
Definition: PathManager.cs:16
List< PathFinderNode > nodes
Definition: PathProgress.cs:16
bool KilledBossInVoid
Definition: Player.cs:448
bool gotEtherDisease
Definition: Player.cs:496
bool loytelEscaped
Definition: Player.cs:508
int storyFiama
Definition: Player.cs:652
bool little_saved
Definition: Player.cs:472
bool fiamaStoryBookGiven
Definition: Player.cs:328
bool fiamaFirstDream
Definition: Player.cs:340
bool little_killed
Definition: Player.cs:484
bool isShoesOff
Definition: Player.cs:376
int deepest
Definition: Player.cs:111
long nefiaBeaten
Definition: Player.cs:153
int married
Definition: Player.cs:129
int turns
Definition: Player.cs:84
int deepestVoid
Definition: Player.cs:114
int allyDeath
Definition: Player.cs:108
int divorced
Definition: Player.cs:132
int days
Definition: Player.cs:75
int distanceTravel
Definition: Player.cs:969
bool IsCriminal
Definition: Player.cs:1421
Flags flags
Definition: Player.cs:1173
bool TooHeavyToMove()
Definition: Player.cs:2688
CodexManager codex
Definition: Player.cs:1194
bool preventDeathPenalty
Definition: Player.cs:1249
bool deathZoneMove
Definition: Player.cs:1251
void ModFame(int a)
Definition: Player.cs:2201
void ModKarma(int a)
Definition: Player.cs:2645
Stats stats
Definition: Player.cs:1095
int staminaRecovery
Definition: Player.cs:1047
bool haltMove
Definition: Player.cs:1253
bool EnableDreamStory
Definition: Player.cs:1352
bool invlunerable
Definition: Player.cs:1255
float baseActTime
Definition: Player.cs:1281
void EndTurn(bool consume=true)
Definition: Player.cs:2188
void EnterLocalZone(bool encounter=false, Chara mob=null)
Definition: Player.cs:2053
List< Chara > listCarryoverMap
Definition: Player.cs:1305
int little_dead
Definition: Player.cs:1002
HashSet< int > doneBackers
Definition: Player.cs:1152
void RecoverStamina(int a)
Definition: Player.cs:1606
Window.SaveData dataPick
Definition: Player.cs:1113
HotItem currentHotItem
Definition: Player.cs:1179
int safeTravel
Definition: Player.cs:996
Thing DropReward(Thing t, bool silent=false)
Definition: Player.cs:2677
ReturnInfo returnInfo
Definition: Player.cs:942
bool regionMoveWarned
Definition: Player.cs:1239
Chara chara
Definition: Player.cs:1287
void UpdateNyan()
Definition: Player.cs:2517
bool TryAbortAutoCombat(bool immediate=true)
Definition: Player.cs:2539
bool simulatingZone
Definition: Player.cs:1261
int lastEmptyAlly
Definition: Player.cs:1275
bool altHeldPos
Definition: Player.cs:1235
QueueManager queues
Definition: Player.cs:1293
string deathMsg
Definition: Player.cs:1267
Definition: Point.cs:9
int eloY
Definition: Point.cs:77
SourceMaterial.Row matFloor
Definition: Point.cs:53
int index
Definition: Point.cs:45
SourceBlock.Row sourceBlock
Definition: Point.cs:59
void ForeachMultiSize(int w, int h, Action< Point, bool > action)
Definition: Point.cs:1387
void SetObj(int id=0, int value=1, int dir=0)
Definition: Point.cs:930
ref Vector3 Position(int height)
Definition: Point.cs:549
List< Card > ListCards(bool includeMasked=false)
Definition: Point.cs:1053
Point Copy()
Definition: Point.cs:487
override string ToString()
Definition: Point.cs:520
Point Set(int _x, int _z)
Definition: Point.cs:499
void ForeachNeighbor(Action< Point > action, bool diagonal=true)
Definition: Point.cs:1399
CellDetail detail
Definition: Point.cs:67
bool IsBlocked
Definition: Point.cs:359
List< Thing > Things
Definition: Point.cs:334
int x
Definition: Point.cs:36
Point GetNearestPoint(bool allowBlock=false, bool allowChara=true, bool allowInstalled=true, bool ignoreCenter=false, int minRadius=0)
Definition: Point.cs:620
int z
Definition: Point.cs:39
List< Chara > Charas
Definition: Point.cs:336
SoundSource PlaySound(string id, bool synced=true, float v=1f, bool spatial=true)
Definition: Point.cs:1255
int eloX
Definition: Point.cs:75
Point GetPointTowards(Point dest)
Definition: Point.cs:802
List< Chara > ListCharasInRadius(Chara cc, int dist, Func< Chara, bool > func, bool onlyVisible=true)
Definition: Point.cs:1222
bool HasThing
Definition: Point.cs:247
bool Equals(int _x, int _z)
Definition: Point.cs:962
List< Chara > ListCharas()
Definition: Point.cs:1173
SourceFloor.Row sourceFloor
Definition: Point.cs:61
bool IsSunLit
Definition: Point.cs:178
void SetBlock(int idMat=0, int idBlock=0)
Definition: Point.cs:920
bool IsValid
Definition: Point.cs:84
Effect PlayEffect(string id)
Definition: Point.cs:1250
bool HasObj
Definition: Point.cs:133
int Distance(Point p)
Definition: Point.cs:991
bool IsHidden
Definition: Point.cs:343
Chara FirstChara
Definition: Point.cs:284
bool IsInBounds
Definition: Point.cs:100
Cell cell
Definition: Point.cs:47
Point GetRandomNeighbor()
Definition: Point.cs:760
bool HasChara
Definition: Point.cs:234
bool IsDeepWater
Definition: Point.cs:272
Point GetRandomPoint(int radius, bool requireLos=true, bool allowChara=true, bool allowBlocked=false, int tries=100)
Definition: Point.cs:770
bool IsActive(int id, int days=-1)
static string GetRandomPortrait(string idDict)
Definition: Portrait.cs:155
static HashSet< string > allIds
Definition: Portrait.cs:34
PropsInstalled installed
Definition: PropsManager.cs:8
List< Card > sales
Definition: PropsManager.cs:14
TraitManager traits
Definition: Props.cs:18
List< Thing > containers
Definition: Props.cs:22
PropSet all
Definition: Props.cs:8
bool paid
Definition: QuestDebt.cs:10
int stage
Definition: QuestDebt.cs:13
int uidChara
Definition: QuestEscort.cs:6
List< Quest > list
Definition: QuestManager.cs:11
bool OnShowDialog(Chara c)
Quest Add(string id, string idGlobalChara=null)
Definition: QuestManager.cs:29
bool IsStarted(string id)
int GetPhase(string id)
Quest Get(string id)
Definition: Quest.cs:7
virtual void OnGiveItem(Chara c, Thing t)
Definition: Quest.cs:536
int phase
Definition: Quest.cs:40
void NextPhase()
Definition: Quest.cs:572
void ChangePhase(int a)
Definition: Quest.cs:577
void Complete()
Definition: Quest.cs:473
void OnSetGoal(AIAct newGoal)
Definition: QueueManager.cs:23
Definition: Rand.cs:4
static int Range(int min, int max)
Definition: Rand.cs:49
static void UseSeed(int seed, Action action)
Definition: Rand.cs:24
static void SetSeed(int a=-1)
Definition: Rand.cs:44
Definition: Recipe.cs:7
static int Set(Zone zone)
Definition: RefZone.cs:12
static Zone Get(int uid)
Definition: RefZone.cs:3
List< Zone > ListTowns()
Definition: Region.cs:273
Dictionary< string, Religion > dictAll
ReligionMoonShadow MoonShadow
ReligionTrickery Trickery
ReligionHealing Healing
Religion GetRandomReligion(bool onlyJoinable=true, bool includeMinor=false)
static Religion recentWrath
Definition: Religion.cs:29
virtual void Revelation(string idTalk, Card c, int chance=100)
Definition: Religion.cs:167
virtual string NameShort
Definition: Religion.cs:55
virtual string Name
Definition: Religion.cs:37
int ConvertTile(int tile)
Definition: RenderData.cs:111
RenderData data
Definition: RenderObject.cs:34
SourceMaterial.Row mat
Definition: RenderParam.cs:17
SpriteReplacer replacer
Definition: RenderRow.cs:92
bool multisize
Definition: RenderRow.cs:64
RenderData renderData
Definition: RenderRow.cs:71
SourcePref pref
Definition: RenderRow.cs:68
bool ContainsTag(string _tag)
Definition: RenderRow.cs:162
TileType tileType
Definition: RenderRow.cs:77
int[] _tiles
Definition: RenderRow.cs:12
int[] tiles
Definition: RenderRow.cs:10
Sprite GetSprite(int dir=0, int skin=0, bool snow=false)
Definition: RenderRow.cs:295
SpriteData GetSpriteData(int dir, int skin, bool snow, Card card=null)
Definition: RenderRow.cs:286
void AssignCharas()
Definition: RoomManager.cs:39
Definition: Room.cs:4
Definition: Scene.cs:8
ParticleSystem psSmoke
Definition: Scene.cs:113
GameScreen screenElin
Definition: Scene.cs:93
ActionMode actionMode
Definition: Scene.cs:79
ParticleSystem psFoot
Definition: Scene.cs:111
EloMap elomap
Definition: Scene.cs:149
PointTarget mouseTarget
Definition: Scene.cs:135
bool paused
Definition: Scene.cs:140
Definition: Shaker.cs:5
static void ShakeCam(string id="default", float magnitude=1f)
Definition: Shaker.cs:25
List< Row > listSister
string[] works
Definition: SourceChara.cs:47
string[] hobbies
Definition: SourceChara.cs:49
static Row rowDefaultPCC
Definition: SourceChara.cs:158
List< Row > listWorks
Definition: SourceHobby.cs:112
List< Row > listHobbies
Definition: SourceHobby.cs:109
string[] weapon
Definition: SourceJob.cs:37
string equip
Definition: SourceJob.cs:39
string id
Definition: SourceJob.cs:9
SourceMaterial materials
SourceRace races
SourceThing things
SourceHobby hobbies
SourceCharaText charaText
SourceBacker backers
SourceCategory categories
SourceElement elements
SourceChara charas
SourceJob jobs
SourceReligion religions
SourceTactics tactics
bool Surface
Definition: SourcePref.cs:369
string meleeStyle
Definition: SourceRace.cs:75
string castStyle
Definition: SourceRace.cs:77
Zone Find(string id)
GlobalSpatialList map
int lv
Definition: Spatial.cs:142
int uid
Definition: Spatial.cs:70
virtual bool ShowDangerLv
Definition: Spatial.cs:503
virtual bool IsRegion
Definition: Spatial.cs:515
virtual string Name
Definition: Spatial.cs:509
virtual int DangerLvBoost
Definition: Spatial.cs:489
virtual bool IsSnowCovered
Definition: Spatial.cs:545
SourceZone.Row source
Definition: Spatial.cs:453
bool destryoed
Definition: Spatial.cs:45
string id
Definition: Spatial.cs:13
int development
Definition: Spatial.cs:238
bool isConquered
Definition: Spatial.cs:382
bool isPeace
Definition: Spatial.cs:406
int influence
Definition: Spatial.cs:214
List< Spatial > children
Definition: Spatial.cs:37
Zone FindZone(int lv)
Definition: Spatial.cs:728
Definition: SPELL.cs:710
bool tryFixPrefNotLoadedAtStart
Definition: SpriteData.cs:34
void LoadPrefAndFixDensity()
Definition: SpriteData.cs:77
SourcePref pref
Definition: SpriteData.cs:32
SpriteData data
SpriteData GetData(int dir, int skin, bool snow, Card card=null)
static Dictionary< string, SpriteReplacer > dictOverrides
static int GetAffinityMod(int phase)
Definition: StatsHygiene.cs:19
Definition: Stats.cs:5
static StatsSAN SAN
Definition: Stats.cs:46
static StatsSleepiness Sleepiness
Definition: Stats.cs:21
virtual void Mod(int a)
Definition: Stats.cs:135
static StatsHygiene Hygiene
Definition: Stats.cs:36
static StatsBurden Burden
Definition: Stats.cs:11
Stats Set(int[] _raw, int _rawIndex, Chara _CC)
Definition: Stats.cs:109
override int GetPhase()
Definition: Stats.cs:117
static StatsMana Mana
Definition: Stats.cs:41
virtual int value
Definition: Stats.cs:56
static StatsStamina Stamina
Definition: Stats.cs:16
static Stats Depression
Definition: Stats.cs:26
static StatsHunger Hunger
Definition: Stats.cs:6
virtual int max
Definition: Stats.cs:68
static Stats Bladder
Definition: Stats.cs:31
Definition: Steam.cs:12
static void GetAchievement(ID_Achievement id)
Definition: Steam.cs:53
static SubPassData Default
Definition: SubPassData.cs:7
Definition: TC.cs:4
int DestDist
Definition: Tactics.cs:24
static TargetTypeSelfParty SelfParty
Definition: TargetType.cs:9
virtual bool ForceParty
Definition: TargetType.cs:41
List< Thing > List(Func< Thing, bool > func, bool onlyAccessible=false)
void DestroyAll(Func< Thing, bool > funcExclude=null)
Thing Find(int uid)
void Foreach(Action< Thing > action, bool onlyAccessible=true)
static void TryLickChest(Thing chest)
Definition: ThingGen.cs:453
static Thing CreateTreasure(string id, int lv, TreasureType type=TreasureType.Map)
Definition: ThingGen.cs:264
static Thing CreateParcel(string idLang=null, params Thing[] things)
Definition: ThingGen.cs:42
static Thing CreateSpellbook(string alias, int num=1)
Definition: ThingGen.cs:159
static Thing CreateFromCategory(string idCat, int lv=-1)
Definition: ThingGen.cs:75
static Thing CreateScroll(int ele, int num=1)
Definition: ThingGen.cs:190
static Thing CreateCurrency(int a, string id="money")
Definition: ThingGen.cs:37
static Thing Create(string id, int idMat=-1, int lv=-1)
Definition: ThingGen.cs:53
Definition: Thing.cs:8
SourceThing.Row source
Definition: Thing.cs:11
bool isEquipped
Definition: Thing.cs:17
override int SelfWeight
Definition: Thing.cs:64
override int GetPrice(CurrencyType currency=CurrencyType.Money, bool sell=false, PriceType priceType=PriceType.Default, Chara c=null)
Definition: Thing.cs:833
override string GetName(NameStyle style, int _num=-1)
Definition: Thing.cs:536
override SourcePref Pref
Definition: Thing.cs:50
bool IsSharedContainer
Definition: Thing.cs:110
Thing Identify(bool show=true, IDTSource idtSource=IDTSource.Identify)
Definition: Thing.cs:2166
void Set(string n)
bool ignoreSnow
Definition: TileRow.cs:7
string soundFoot
Definition: TileRow.cs:15
virtual bool IsWater
Definition: TileType.cs:171
static Span GetSpan(string id, int hour)
Definition: TimeTable.cs:45
void AddHolder(Chara c)
Definition: TraitBed.cs:107
bool IsHolder(Chara c)
Definition: TraitBed.cs:135
bool CanAssign(Chara c)
Definition: TraitBed.cs:165
virtual Adv_Type AdvType
Definition: TraitChara.cs:102
virtual bool UseRandomName
Definition: TraitChara.cs:134
virtual bool UseRandomAlias
Definition: TraitChara.cs:136
virtual bool CanBePushed
Definition: TraitChara.cs:120
virtual SourceElement.Row source
Definition: TraitScroll.cs:5
virtual bool IsAmmo(Thing t)
virtual bool CanExtendBuild
Definition: Trait.cs:181
virtual bool IsBlockPath
Definition: Trait.cs:54
virtual void OnTickHeld()
Definition: Trait.cs:1249
virtual void OnSteppedOut(Chara c)
Definition: Trait.cs:1283
virtual bool IgnoreOnSteppedWhenMoving
Definition: Trait.cs:385
virtual bool CanBeDestroyed
Definition: Trait.cs:307
virtual bool CanRead(Chara c)
Definition: Trait.cs:1168
virtual ShopType ShopType
Definition: Trait.cs:536
virtual bool IsDoor
Definition: Trait.cs:58
virtual bool CanEat(Chara c)
Definition: Trait.cs:1177
virtual bool IsChangeFloorHeight
Definition: Trait.cs:74
virtual void OnStepped(Chara c)
Definition: Trait.cs:1279
Card owner
Definition: Trait.cs:28
virtual bool CanBeDropped
Definition: Trait.cs:313
virtual Action GetHealAction(Chara c)
Definition: Trait.cs:641
virtual void SetName(ref string s)
Definition: Trait.cs:739
virtual bool CanDrink(Chara c)
Definition: Trait.cs:1186
virtual bool CanOnlyCarry
Definition: Trait.cs:305
virtual void OnBlend(Thing t, Chara c)
Definition: Trait.cs:651
static void Reserve(string idStep, Action onBeforePlay=null)
Definition: Tutorial.cs:55
static void Play(string idStep)
Definition: Tutorial.cs:7
Definition: UIItem.cs:5
Image image2
Definition: UIItem.cs:16
UIText text2
Definition: UIItem.cs:8
Definition: UIList.cs:9
SortMode
Definition: UIList.cs:27
Definition: UINote.cs:6
UIItem AddHeaderCard(string text, Sprite sprite=null)
Definition: UINote.cs:84
void Clear()
Definition: UINote.cs:35
UIItem AddText(string text, FontColor color=FontColor.DontChange)
Definition: UINote.cs:113
void Build()
Definition: UINote.cs:49
void SetText(string s)
Definition: UIText.cs:163
int uidZone
Definition: UniqueData.cs:12
bool IsRealTime
Definition: VirtualDate.cs:7
Condition
Definition: Weather.cs:16
Condition CurrentCondition
Definition: Weather.cs:79
bool IsRaining
Definition: Weather.cs:117
static void Say(string text, FontColor fontColor=FontColor.Default, Sprite sprite=null)
FilterResult IsFilterPass(string text)
Definition: Window.cs:498
ContainerFlag flag
Definition: Window.cs:267
HashSet< int > cats
Definition: Window.cs:119
bool userFilter
Definition: Window.cs:132
bool noRotten
Definition: Window.cs:439
bool advDistribution
Definition: Window.cs:427
Definition: Window.cs:13
int efficiency
Definition: WorkSession.cs:28
WorkSession work
Definition: WorkSummary.cs:10
List< WorkSession > hobbies
Definition: WorkSummary.cs:13
Region region
Definition: World.cs:23
GameDate date
Definition: World.cs:6
void SendPackage(Thing p)
Definition: World.cs:68
Weather weather
Definition: World.cs:12
void OnCharaDie(Chara c)
virtual ZoneTransition.EnterState ReturnState
Definition: ZoneInstance.cs:26
virtual void OnLeaveZone()
Definition: ZoneInstance.cs:36
bool IsCrystalLv
Definition: Zone_Nymelle.cs:25
Definition: Zone.cs:12
bool isSimulating
Definition: Zone.cs:78
void RefreshDeathSentense()
Definition: Zone.cs:1209
ZoneEventManager events
Definition: Zone.cs:43
virtual bool IsNefia
Definition: Zone.cs:292
int CountMinions(Chara c)
Definition: Zone.cs:4038
Zone GetTopZone()
Definition: Zone.cs:2116
bool IsPCFactionOrTent
Definition: Zone.cs:483
FactionBranch branch
Definition: Zone.cs:34
virtual bool HasLaw
Definition: Zone.cs:236
void SetBGM(List< int > ids, bool refresh=true, float fadeDuration=0f)
Definition: Zone.cs:3263
Chara Boss
Definition: Zone.cs:91
bool TryAddThingInSharedContainer(Thing t, List< Thing > containers=null, bool add=true, bool msg=false, Chara chara=null, bool sharedOnly=true)
Definition: Zone.cs:2317
virtual bool IsFestival
Definition: Zone.cs:216
virtual bool IsTown
Definition: Zone.cs:230
Chara SpawnMob(string id, Point pos=null)
Definition: Zone.cs:2989
void RemoveCard(Card t)
Definition: Zone.cs:2200
bool IsActiveZone
Definition: Zone.cs:502
virtual bool PetFollow
Definition: Zone.cs:294
override int DangerLv
Definition: Zone.cs:115
bool IsPCFaction
Definition: Zone.cs:480
void ResetHostility()
Definition: Zone.cs:2923
virtual bool IsUnderwater
Definition: Zone.cs:276
ZoneInstance instance
Definition: Zone.cs:58
virtual bool WillAutoSave
Definition: Zone.cs:270
virtual bool KeepAllyDistance
Definition: Zone.cs:309
virtual bool HiddenInRegionMap
Definition: Zone.cs:420
void RefreshListCitizen()
Definition: Zone.cs:3877
Card AddCard(Card t, Point point)
Definition: Zone.cs:2160
Map map
Definition: Zone.cs:66
Point GetSpawnPos(Chara c, ZoneTransition.EnterState destState=ZoneTransition.EnterState.Auto)
Definition: Zone.cs:1501
NoteMode
Definition: IInspect.cs:7
Definition: ActRef.cs:2
Definition: ACT.cs:71
CostType type
Definition: ACT.cs:74
int cost
Definition: ACT.cs:72
uint Bits
Definition: BitArray32.cs:6