EA 23.168 Nightly
July 16, 2025
12 files modified.
Important Changes
None.
AI_Idle
@@ -60,11 +60,7 @@ public override IEnumerable<Status> Run()
}
if (EClass.rnd(owner.IsPCParty ? 10 : 100) == 0 && owner.hunger.GetPhase() >= 3)
{
Thing thing = owner.things.Find((Thing a) => owner.CanEat(a, owner.IsPCFaction) && !a.c_isImportant, recursive: false);
if (thing == null && owner.IsPCFaction)
{
thing = owner.FindBestFoodToEat();
}
Thing thing = (owner.IsPCFaction ? owner.FindBestFoodToEat() : owner.things.Find((Thing a) => owner.CanEat(a, owner.IsPCFaction) && !a.c_isImportant, recursive: false));
if (thing == null && owner.IsPCFaction && EClass._zone.IsPCFaction)
{
thing = EClass._zone.branch.GetMeal(owner);
@@ -82,11 +78,15 @@ public override IEnumerable<Status> Run()
else if (!owner.things.IsFull())
{
thing = ThingGen.CreateFromCategory("food", EClass.rnd(EClass.rnd(60) + 1) + 10);
thing.isNPCProperty = true;
if ((thing.ChildrenAndSelfWeight < 5000 || !owner.IsPCParty) && thing.trait.CanEat(owner))
if (thing.trait.CanEat(owner))
{
thing.isNPCProperty = true;
thing = owner.AddThing(thing);
}
else
{
thing = null;
}
}
}
if (thing != null)
@@ -105,39 +105,47 @@ public override IEnumerable<Status> Run()
}
}
}
if (EClass.rnd(3) == 0 && owner.mana.value > 0 && !EClass._zone.IsRegion)
if (!EClass._zone.IsRegion)
{
Act act = null;
Act actRevive = null;
foreach (ActList.Item item in owner.ability.list.items)
if (EClass.rnd(10) == 0 && owner.ability.Has(6627) && ((float)owner.hp < (float)owner.MaxHP * 0.8f || EClass.rnd(10) == 0) && owner.GetNearbyCatToSniff() != null && !owner.HasCondition<ConHOT>())
{
Act act2 = item.act;
if (act2.id == 8430)
{
actRevive = act2;
}
string[] abilityType = act2.source.abilityType;
if (!abilityType.IsEmpty() && (abilityType[0] == "heal" || abilityType[0] == "hot"))
{
act = item.act;
}
owner.Sniff(owner.GetNearbyCatToSniff());
yield return KeepRunning();
}
if (act != null)
if (EClass.rnd(3) == 0 && owner.mana.value > 0)
{
List<Chara> list = (owner.IsPCParty ? EClass.pc.party.members : new List<Chara> { owner });
foreach (Chara item2 in list)
Act act = null;
Act actRevive = null;
foreach (ActList.Item item in owner.ability.list.items)
{
if (!((float)item2.hp > (float)item2.MaxHP * 0.75f) && owner.CanSeeLos(item2) && (!(act.source.abilityType[0] == "hot") || !item2.HasCondition<ConHOT>()))
Act act2 = item.act;
if (act2.id == 8430)
{
owner.UseAbility(act, item2);
yield return KeepRunning();
break;
actRevive = act2;
}
string[] abilityType = act2.source.abilityType;
if (!abilityType.IsEmpty() && (abilityType[0] == "heal" || abilityType[0] == "hot"))
{
act = item.act;
}
}
}
if (actRevive != null && owner.IsPCFaction && EClass.game.cards.globalCharas.Where((KeyValuePair<int, Chara> a) => a.Value.isDead && a.Value.faction == EClass.pc.faction && !a.Value.isSummon && a.Value.c_wasInPcParty).ToList().Count > 0 && owner.UseAbility(actRevive.source.alias, owner))
{
yield return KeepRunning();
if (act != null)
{
List<Chara> list = (owner.IsPCParty ? EClass.pc.party.members : new List<Chara> { owner });
foreach (Chara item2 in list)
{
if (!((float)item2.hp > (float)item2.MaxHP * 0.75f) && owner.CanSeeLos(item2) && (!(act.source.abilityType[0] == "hot") || !item2.HasCondition<ConHOT>()))
{
owner.UseAbility(act, item2);
yield return KeepRunning();
break;
}
}
}
if (actRevive != null && owner.IsPCFaction && EClass.game.cards.globalCharas.Where((KeyValuePair<int, Chara> a) => a.Value.isDead && a.Value.faction == EClass.pc.faction && !a.Value.isSummon && a.Value.c_wasInPcParty).ToList().Count > 0 && owner.UseAbility(actRevive.source.alias, owner))
{
yield return KeepRunning();
}
}
}
if (owner.IsPCFaction && EClass._zone.IsPCFaction)
ActEffect
break;
}
case EffectId.CatSniff:
CC.Say("abCatSniff", CC, TC);
{
Chara nearbyCatToSniff = CC.GetNearbyCatToSniff();
if (nearbyCatToSniff != null)
{
CC.Sniff(nearbyCatToSniff);
}
break;
}
case EffectId.Steal:
{
if (EClass._zone.instance is ZoneInstanceBout)
ActMelee
@@ -239,7 +239,10 @@ void _Attack(BodySlot slot)
List<Point> list = new List<Point>();
Act.TP.ForeachNeighbor(delegate(Point p)
{
list.Add(p.Copy());
if (!p.Equals(Act.TP))
{
list.Add(p.Copy());
}
});
list.Shuffle();
int num4 = 0;
Affinity
@@ -60,6 +60,15 @@ public bool CanInvite()
return true;
}
public bool CanGiveCard()
{
if (!EClass.debug.marryAnytime)
{
return CurrentStage >= Stage.Love;
}
return true;
}
public bool CanMarry()
{
if (!EClass.debug.marryAnytime)
Card
@@ -3894,7 +3894,7 @@ public virtual int ApplyProtection(int dmg, int mod = 100)
num2 = num3 / 10 + 1;
sides = num3 / num2 + 1;
bonus = 0;
dmg = dmg * 100 / (100 + num);
dmg = dmg * 100 / Mathf.Max(100 + num, 1);
}
int num4 = Dice.Roll(num2, sides, bonus, this);
dmg -= num4 * mod / 100;
CardRenderer
@@ -467,7 +467,7 @@ public void RemoveExtra(string id)
public override void OnLeaveScreen()
{
isSynced = false;
if (hasActor && (!owner.ExistsOnMap || !data.persistActor))
if (hasActor && (!owner.ExistsOnMap || !data.persistActor || owner.isMasked))
{
KillActor();
}
Chara
@@ -5758,7 +5758,7 @@ public int CalcCastingChance(Element e, int num = 1)
{
num5 = 0;
}
return Mathf.Clamp(100 + e.Value - 10 - e.source.LV * e.source.cost[0] * num4 / (10 + num3 * 10), 0, 100 - num5);
return Mathf.Clamp(100 + e.Value - 10 - e.source.LV * e.source.cost[0] * num4 / Mathf.Max(10 + num3 * 10, 1), 0, 100 - num5);
}
public void DoAI(int wait, Action onPerform)
@@ -6547,13 +6547,24 @@ public void ShowDialog()
{
ShowDialog("_chara", "sleep");
}
else if (EClass.pc.isHidden && !CanSee(EClass.pc))
{
ShowDialog("_chara", "invisible");
}
else if (base.isRestrained)
{
ShowDialog("_chara", "strain");
}
else if (EClass.pc.isHidden && !CanSee(EClass.pc))
else if (base.IsUnique && !EClass.player.codex.DroppedCard(id) && affinity.CanGiveCard())
{
ShowDialog("_chara", "invisible");
EClass.player.codex.MarkCardDrop(id);
ShowDialog("_chara", "give_card");
Thing thing = ThingGen.Create("figure");
thing.MakeFigureFrom(id);
EClass.player.DropReward(thing);
thing = ThingGen.Create("figure3");
thing.MakeFigureFrom(id);
EClass.player.DropReward(thing);
}
else if (IsEscorted())
{
@@ -6617,18 +6628,10 @@ public void ShowDialog()
}
return;
case "ashland":
if (zone_Nymelle != null && zone_Nymelle.IsCrystalLv)
{
SoundManager.ForceBGM();
LayerDrama.ActivateMain("mono", "nymelle_crystal");
}
else
{
ShowDialog("ashland");
}
ShowDialog("ashland");
return;
case "fiama":
if (zone_Nymelle != null && zone_Nymelle.IsCrystalLv)
if (zone_Nymelle != null && zone_Nymelle.IsCrystalLv && EClass.game.quests.GetPhase<QuestExploration>() == 3)
{
SoundManager.ForceBGM();
LayerDrama.ActivateMain("mono", "nymelle_crystal");
@@ -7493,6 +7496,28 @@ public SourceCategory.Row GetFavCat()
return r;
}
public Chara GetNearbyCatToSniff()
{
using (List<Chara>.Enumerator enumerator = pos.ListCharasInRadius(this, 3, (Chara c) => c != this && c.race.id == "cat").GetEnumerator())
{
if (enumerator.MoveNext())
{
return enumerator.Current;
}
}
return null;
}
public void Sniff(Chara c)
{
Say("abCatSniff", this, c);
AddCondition<ConHOT>(EClass.curve(50 + c.CHA * 5, 400, 100));
c.ShowEmo(Emo.angry);
ShowEmo(Emo.love);
Talk("sniff");
c.Talk(new string[4] { "labor", "disgust", "scold", "callGuards" }.RandomItem());
}
public int GetTotalFeat()
{
int num = 0;
CharaAbility
@@ -157,4 +157,16 @@ public void Remove(int id)
}
Refresh();
}
public bool Has(int id)
{
foreach (ActList.Item item in list.items)
{
if (item.act.id == id)
{
return true;
}
}
return false;
}
}
GoalCombat
@@ -522,79 +522,9 @@ public virtual bool TryUseAbility(int dist, bool beforeMove = false)
{
continue;
}
switch (act.id)
{
case 6603:
if (!tc.IsPCParty || tc.Evalue(418) < 0)
{
break;
}
foreach (Chara member in EClass.pc.party.members)
{
if (member.Evalue(418) < 0)
{
owner.enemy = (tc = member);
return false;
}
}
break;
case 6602:
if (dist <= 1 || tc.HasCondition<ConEntangle>())
{
continue;
}
break;
case 6450:
if (isPCFaction && (tc.HasElement(1221) || tc.HasElement(1223) || tc.id == "hedgehog_ether"))
{
continue;
}
break;
case 8200:
case 8201:
if (owner.HasElement(400))
{
continue;
}
break;
case 6400:
if (isPCFaction)
{
continue;
}
break;
case 8790:
case 8791:
if (tc.host != null)
{
continue;
}
break;
}
bool isHOT;
switch (text)
{
case "special":
if (ability.act.id != 6900 || owner.IsPC)
{
continue;
}
if (owner.IsPCParty)
{
foreach (Chara member2 in EClass.pc.party.members)
{
float num2 = 100f - (float)(member2.mana.value * 100) / MathF.Max(1f, member2.mana.max);
if (num2 > (float)num)
{
num = (int)num2;
}
}
}
else
{
num = 100 - owner.mana.value * 100 / Mathf.Max(1, owner.mana.max);
}
break;
case "any":
if (owner.isBerserk)
{
@@ -618,16 +548,16 @@ public virtual bool TryUseAbility(int dist, bool beforeMove = false)
break;
case "taunt":
{
bool flag6 = owner.HasCondition<StanceTaunt>();
bool flag7 = tactics.source.taunt != -1 && 100 * owner.hp / owner.MaxHP >= tactics.source.taunt;
num = ((flag6 && !flag7) ? 100 : ((!flag6 && flag7) ? 100 : 0));
bool flag7 = owner.HasCondition<StanceTaunt>();
bool flag8 = tactics.source.taunt != -1 && 100 * owner.hp / owner.MaxHP >= tactics.source.taunt;
num = ((flag7 && !flag8) ? 100 : ((!flag7 && flag8) ? 100 : 0));
break;
}
case "song":
{
bool flag9 = owner.HasCondition<BaseSong>();
bool flag10 = owner.mana.value > owner.mana.max / 3;
num = ((flag9 && !flag10) ? 100 : ((!flag9 && flag10) ? 100 : 0));
bool flag10 = owner.HasCondition<BaseSong>();
bool flag11 = owner.mana.value > owner.mana.max / 3;
num = ((flag10 && !flag11) ? 100 : ((!flag10 && flag11) ? 100 : 0));
break;
}
case "melee":
@@ -711,13 +641,13 @@ public virtual bool TryUseAbility(int dist, bool beforeMove = false)
{
continue;
}
bool flag8 = text == "dot";
if (flag8 && (owner.isRestrained || (tc != null && tc.IsRestrainedResident)))
bool flag9 = text == "dot";
if (flag9 && (owner.isRestrained || (tc != null && tc.IsRestrainedResident)))
{
continue;
}
num = ((text == "attackMelee") ? tactics.P_Melee : tactics.P_Spell) + GetAttackMod(act);
if (num > 0 && flag8)
if (num > 0 && flag9)
{
num += 10;
}
@@ -733,13 +663,13 @@ public virtual bool TryUseAbility(int dist, bool beforeMove = false)
{
continue;
}
bool flag11 = ability.act is ActBolt;
bool flag6 = ability.act is ActBolt;
if (!flag || (owner.IsPCParty && (EClass._zone.IsTown || EClass._zone.IsPCFaction)) || (act.id == 9150 && EClass._zone.IsPCFaction && owner.IsNeutralOrAbove()))
{
continue;
}
GetNumEnemy(flag11 ? 6 : 5);
if (numEnemy == 0 || (owner.IsPCFactionOrMinion && GetNumNeutral(flag11 ? 6 : 5) > 0))
GetNumEnemy(flag6 ? 6 : 5);
if (numEnemy == 0 || (owner.IsPCFactionOrMinion && GetNumNeutral(flag6 ? 6 : 5) > 0))
{
continue;
}
@@ -815,12 +745,12 @@ public virtual bool TryUseAbility(int dist, bool beforeMove = false)
{
continue;
}
int num3 = EClass._zone.CountMinions(owner);
if (num3 >= owner.MaxSummon)
int num2 = EClass._zone.CountMinions(owner);
if (num2 >= owner.MaxSummon)
{
continue;
}
num = tactics.P_Summon - 20 * num3 / owner.MaxSummon;
num = tactics.P_Summon - 20 * num2 / owner.MaxSummon;
break;
}
case "summonAlly":
@@ -861,6 +791,83 @@ public virtual bool TryUseAbility(int dist, bool beforeMove = false)
num = 0;
break;
}
switch (act.id)
{
case 6603:
if (!tc.IsPCParty || tc.Evalue(418) < 0)
{
break;
}
foreach (Chara member in EClass.pc.party.members)
{
if (member.Evalue(418) < 0)
{
owner.enemy = (tc = member);
return false;
}
}
break;
case 6602:
if (dist <= 1 || tc.HasCondition<ConEntangle>())
{
continue;
}
break;
case 6450:
if (isPCFaction && (tc.HasElement(1221) || tc.HasElement(1223) || tc.id == "hedgehog_ether"))
{
continue;
}
break;
case 8200:
case 8201:
if (owner.HasElement(400))
{
continue;
}
break;
case 6400:
if (isPCFaction)
{
continue;
}
break;
case 8790:
case 8791:
if (tc.host != null)
{
continue;
}
break;
case 6900:
if (owner.IsPC)
{
continue;
}
if (owner.IsPCParty)
{
foreach (Chara member2 in EClass.pc.party.members)
{
float num3 = 100f - (float)(member2.mana.value * 100) / MathF.Max(1f, member2.mana.max);
if (num3 > (float)num)
{
num = (int)num3;
}
}
}
else
{
num = 100 - owner.mana.value * 100 / Mathf.Max(1, owner.mana.max);
}
break;
case 6627:
if (Act.CC.GetNearbyCatToSniff() == null || Act.CC.HasCondition<ConHOT>())
{
continue;
}
num = 100 - owner.hp * 100 / Mathf.Max(1, owner.MaxHP);
break;
}
if (s.target == "Neighbor")
{
if (dist > 1)
@@ -913,36 +920,36 @@ int HealFactor(Chara c)
{
return 0;
}
float num9 = (float)c.hp / (float)c.MaxHP;
if (num9 > (isHOT ? 0.85f : 0.75f))
float num6 = (float)c.hp / (float)c.MaxHP;
if (num6 > (isHOT ? 0.85f : 0.75f))
{
return 0;
}
int num10 = tactics.P_Heal - (int)((float)tactics.P_Heal * num9) + (isHOT ? 50 : 25);
int num7 = tactics.P_Heal - (int)((float)tactics.P_Heal * num6) + (isHOT ? 50 : 25);
foreach (Condition condition in c.conditions)
{
if (condition is ConFear)
{
num10 += 10;
num7 += 10;
}
else if (condition is ConPoison)
{
num10 += 2;
num7 += 2;
}
else if (condition is ConConfuse)
{
num10 += 4;
num7 += 4;
}
else if (condition is ConDim)
{
num10 += 6;
num7 += 6;
}
else if (condition is ConBleed)
{
num10 += 8;
num7 += 8;
}
}
return num10;
return num7;
}
}
abilities.Sort((ItemAbility a, ItemAbility b) => b.priority - a.priority);
@@ -1028,8 +1035,8 @@ void BuildCharaList()
{
if (chara2 != owner)
{
int num6 = owner.Dist(chara2);
if (num6 > sightRadius || !owner.CanSeeLos(chara2, num6))
int num10 = owner.Dist(chara2);
if (num10 > sightRadius || !owner.CanSeeLos(chara2, num10))
{
continue;
}
return func(owner);
}
BuildCharaList();
int num7 = 0;
int num4 = 0;
foreach (Chara chara3 in charas)
{
int num8 = func(chara3);
if (num8 > 0)
int num5 = func(chara3);
if (num5 > 0)
{
if (isFriendlyAbility)
{
}
if (chara3 != owner)
{
num8 += tactics.P_Party;
num5 += tactics.P_Party;
}
}
else if (!owner.IsHostile(chara3))
{
continue;
}
if (num8 >= num7)
if (num5 >= num4)
{
a.tg = chara3;
num7 = num8;
num4 = num5;
}
}
}
return num7;
return num4;
}
int GetAttackMod(Act a)
{
@@ -1088,30 +1095,30 @@ int GetAttackMod(Act a)
{
return 0;
}
int num4 = ((a.source.aliasRef == "mold") ? owner.MainElement.id : EClass.sources.elements.alias[a.source.aliasRef].id);
int num5 = -15 * tc.ResistLvFrom(num4);
switch (num4)
int num8 = ((a.source.aliasRef == "mold") ? owner.MainElement.id : EClass.sources.elements.alias[a.source.aliasRef].id);
int num9 = -15 * tc.ResistLvFrom(num8);
switch (num8)
{
case 910:
if (tc.isWet)
{
num5 -= 30;
num9 -= 30;
}
break;
case 911:
if (tc.HasCondition<ConBurning>())
{
num5 -= 30;
num9 -= 30;
}
break;
case 912:
if (tc.isWet)
{
num5 += 30;
num9 += 30;
}
break;
}
return num5;
return num9;
}
void GetNumEnemy(int radius)
{
Player
@@ -1555,22 +1555,9 @@ public string GetBackgroundText()
stringBuilder.Replace("#he", (EClass.pc.IsMale ? "he" : "she").lang());
stringBuilder.Replace("#his", (EClass.pc.IsMale ? "his" : "her").lang());
stringBuilder.Replace("#him", (EClass.pc.IsMale ? "him" : "her").lang());
string text = "_period".lang();
string[] array = stringBuilder.ToString().Split(text);
string text2 = "";
if (array.Length != 0)
{
string[] array2 = array;
foreach (string text3 in array2)
{
text2 += text3.ToTitleCase();
if (text3 != text && text3 != Environment.NewLine && text3.Length > 2 && text3 != array[^1])
{
text2 += text;
}
}
}
return text2.TrimEnd(Environment.NewLine.ToCharArray());
string separator = "_period".lang();
stringBuilder.ToString().Split(separator);
return stringBuilder.ToString().TrimEnd(Environment.NewLine.ToCharArray());
}
public void EditBackgroundText()
TraitFakeBlock
@@ -17,7 +17,7 @@ public override void OnCrafted(Recipe recipe, List<Thing> ings)
public override void TrySetHeldAct(ActPlan p)
{
if (p.pos.cell._block != 0)
if (p.pos.cell._block != 0 && !p.pos.sourceBlock.ContainsTag("noFake"))
{
p.TrySetAct("actCopyBlock", delegate
{
Zone
@@ -665,12 +665,22 @@ public void Activate()
IO.DeleteDirectory(pathTemp + "Texture Replace");
Debug.Log(pathTemp);
}
zoneExportData = Import(pathExport);
base.isGenerated = true;
isImported = true;
if (flag3)
try
{
zoneExportData.orgMap = GameIO.LoadFile<Map>(base.pathSave + "map");
zoneExportData = Import(pathExport);
base.isGenerated = true;
isImported = true;
if (flag3)
{
zoneExportData.orgMap = GameIO.LoadFile<Map>(base.pathSave + "map");
}
}
catch (Exception message)
{
Debug.Log(message);
zoneExportData = Import(CorePath.ZoneSave + "fail.z");
base.isGenerated = true;
isImported = true;
}
}
EClass.game.countLoadedMaps++;