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