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