EA 23.236 Nightly Patch 1
November 18, 2025
15 files modified. 1 new file created.
Important Changes
None.
AI_Eat
public override IEnumerable<Status> Run()
{
owner.Say("eat_end", owner, target.GetName(NameStyle.Full, 1));
owner.ShowEmo(Emo.happy);
if (target.trait is TraitFoodChuryu && !owner.IsCat)
{
foreach (Chara item in owner.pos.ListCharasInRadius(owner, 5, (Chara c) => c.IsCat))
{
item.Say("angry", item);
item.ShowEmo(Emo.angry);
item.PlaySound("Animal/Cat/cat_angry");
if (owner.IsPC)
{
EClass.player.ModKarma(-3);
}
}
}
FoodEffect.Proc(owner, target.Thing);
}
}AI_Fuck
{
EClass.player.stats.kimo++;
}
if (variation != Variation.NTR)
{
break;
}
Thing thing = chara2.things.Find<TraitDreamBug>();
if (thing != null)
if (variation == Variation.NTR)
{
thing.ModNum(-1);
if (chara.IsPC)
Thing thing = chara2.things.Find<TraitDreamBug>();
if (thing != null)
{
Msg.Say("dream_spell", EClass.sources.elements.map[9156].GetName().ToLowerInvariant());
EClass.pc.GainAbility(9156, EClass.rnd(2) + 1);
thing.ModNum(-1);
if (chara.IsPC)
{
Msg.Say("dream_spell", EClass.sources.elements.map[9156].GetName().ToLowerInvariant());
EClass.pc.GainAbility(9156, EClass.rnd(2) + 1);
}
}
}
if (!chara.HasElement(1239) || chara2.HasElement(1216))
{
break;
}
if (chara2.HasElement(758))
{
if (chara.ExistsOnMap)
if (chara.HasElement(1239) && !chara2.HasElement(1216))
{
chara.stamina.Mod(-1000000);
if (chara2.HasElement(758))
{
if (chara.ExistsOnMap)
{
chara.stamina.Mod(-1000000);
}
}
else if (chara2.ExistsOnMap)
{
chara2.stamina.Mod((!chara2.IsPCFaction) ? (-10000) : (chara2.IsPC ? (-25) : (-50)));
}
}
}
else if (chara2.ExistsOnMap)
if (variation == Variation.Bloodsuck && chara2.HasElement(758) && chara.ExistsOnMap)
{
chara2.stamina.Mod((!chara2.IsPCFaction) ? (-10000) : (chara2.IsPC ? (-25) : (-50)));
chara.stamina.Mod(-1000000);
}
break;
}ActThrow
public static EffectIRenderer Throw(Card c, Point p, Card target, Thing t, Throw
t.Die(null, null, AttackSource.Throw);
c.ModExp(108, 50);
break;
case ThrowType.Dice:
t.SetDir(EClass.rnd(6));
break;
case ThrowType.Snow:
flag = true;
flag2 = false;CardRenderer
public SourcePref GetPref()
{
if (replacer != null)
{
return replacer.pref;
}
if ((owner.IsPCC && replacer == null) || (owner.HasHost && owner.Chara.host.ride == owner))
{
return EClass.core.refs.prefs.pcc;Chara
public class Chara : Card, IPathfindWalker
public ConSuspend conSuspend;
public ConTransmute conTrans;
public Emo2 emoIcon;
public int happiness;public override SourcePref Pref
{
get
{
if (renderer.replacer != null)
{
return renderer.replacer.pref;
}
if (spriteReplacer != null)
{
return spriteReplacer.data?.pref ?? EClass.core.refs.prefs.replacer1;public bool UseAbility(Act a, Card tc = null, Point pos = null, bool pt = false)
return true;
}
bool flag2 = true;
if (a.source.cooldown > 0 && (!IsPC || !a.source.tag.Contains("CD_npc")))
{
AddCooldown(a.id, a.source.cooldown);
}
if (HasTalk("phrase_" + a.source.alias))
{
EClass.player.forceTalk = true;public bool UseAbility(Act a, Card tc = null, Point pos = null, bool pt = false)
}
}
ActEffect.RapidCount = 0;
if (a.source.cooldown > 0 && (!IsPC || !a.source.tag.Contains("CD_npc")))
{
AddCooldown(a.id, a.source.cooldown);
}
if (flag2 && !a.source.tag.Contains("keepInvisi") && EClass.rnd(2) == 0)
{
RemoveCondition<ConInvisibility>();public void AddCooldown(int idEle, int turns = 0)
}
}
public void SetCooldown(int idEle, int turns = 0)
{
if (_cooldowns == null)
{
_cooldowns = new List<int>();
}
bool flag = false;
for (int i = 0; i < _cooldowns.Count; i++)
{
if (_cooldowns[i] / 1000 == idEle)
{
if (turns == 0)
{
_cooldowns.RemoveAt(i);
}
else
{
_cooldowns[i] = idEle * 1000 + turns;
}
flag = true;
break;
}
}
if (!flag && turns > 0)
{
AddCooldown(idEle, turns);
}
if (_cooldowns.Count == 0)
{
_cooldowns = null;
}
}
public bool HasCooldown(int idEle)
{
return GetCooldown(idEle) != 0;ConTransmute
public override void OnStart()
{
owner.conTrans = this;
owner._CreateRenderer();
if (owner.IsPCParty)
{public override void OnStart()
public override void OnRemoved()
{
owner.conTrans = null;
owner._CreateRenderer();
if (owner.IsPCParty)
{ConTransmuteBat
public class ConTransmuteBat : ConTransmute
{
public override bool HasDuration => false;
public override bool CanManualRemove => !owner.HasCooldown(8793);
public override RendererReplacer GetRendererReplacer()
{
return RendererReplacer.CreateFrom("bat");
return RendererReplacer.CreateFrom("bat_trans");
}
public override void Tick()
{
}
public override void OnStart()
{
base.OnStart();
owner.PlaySound("bat");
}
public override void OnRemoved()
{
base.OnRemoved();
owner.HealHP(owner.MaxHP / 2, HealSource.Item);
owner.SetCooldown(8793);
}
}Condition
public void Kill(bool silent = false)
owner.Say(base.source.GetText("textEnd"), owner, RefString1);
}
PlayEndEffect();
OnRemoved();
if (elements != null)
{
elements.SetParent();
}
OnRemoved();
owner.SetDirtySpeed();
if (ShouldRefresh)
{CraftUtil
public static void MakeDish(Thing food, int lv, Chara crafter = null, int seed =
RecipeManager.BuildList();
List<Thing> list = new List<Thing>();
RecipeSource recipeSource = RecipeManager.Get(food.id);
if (recipeSource == null)
if (recipeSource == null || !recipeSource.IsCraftable())
{
return;
}public static Thing MakeBloodMeal(Chara sucker, Chara feeder)
{
thing.elements.Remove(701);
}
thing.elements.ModBase(710, 30);
thing.elements.SetTo(2, Mathf.Min(EClass.curve(feeder.LV, 30, 10, 60), 200));
thing.elements.ModBase(710, 20 + (int)Mathf.Min(Mathf.Sqrt(sucker.Evalue(6607) + sucker.LER), 50f));
thing.elements.SetTo(2, Mathf.Min(EClass.curve(feeder.LV, 30, 10, 65), 200));
return thing;
}FoodEffect
public static bool IsLeftoverable(Thing food)
public static void Proc(Chara c, Thing food, bool consume = true)
{
Chara c2 = c;
if (food.id == "bloodsample")
{
food.ModNum(-1);
return;
}
food.CheckJustCooked();
bool flag = EClass._zone.IsPCFaction && c.IsInSpot<TraitSpotDining>();
bool flag = EClass._zone.IsPCFaction && c2.IsInSpot<TraitSpotDining>();
int num = (food.isCrafted ? ((EClass.pc.Evalue(1650) >= 3) ? 5 : 0) : 0);
float num2 = (float)(100 + (food.HasElement(757) ? 10 : 0) + (flag ? 10 : 0) + num + Mathf.Min(food.QualityLv * 10, 100)) / 200f;
if (num2 < 0.1f)public static void Proc(Chara c, Thing food, bool consume = true)
string idTaste = "";
bool flag2 = food.HasElement(708);
bool flag3 = food.HasElement(709);
bool flag4 = c.HasElement(1205);
bool flag4 = c2.HasElement(1205);
bool flag5 = food.IsDecayed || flag3;
bool flag6 = IsLeftoverable(food);
c.AddFoodHistory(food);
if (c.IsPCFaction && !c.IsPC)
c2.AddFoodHistory(food);
if (c2.IsPCFaction && !c2.IsPC)
{
int num6 = c.CountNumEaten(food);
bool flag7 = c.GetFavFood().id == food.id;
int num6 = c2.CountNumEaten(food);
bool flag7 = c2.GetFavFood().id == food.id;
if (num6 < 2 || flag7)
{
if (num6 == 1 || flag7 || EClass.rnd(4) == 0)
{
c.Talk("foodNice");
c2.Talk("foodNice");
}
}
else if (num6 > 3 && EClass.rnd(num6) >= 3)
{
c.Talk("foodBored");
c2.Talk("foodBored");
}
}
if (food.IsBlessed)public static void Proc(Chara c, Thing food, bool consume = true)
num5 = 0f;
num2 *= 0.5f;
}
if (c.HasElement(1250))
if (c2.HasElement(1250))
{
if (food.HasElement(710))
{public static void Proc(Chara c, Thing food, bool consume = true)
num3 /= 10;
}
}
if (c.HasElement(1200))
if (c2.HasElement(1200))
{
num2 *= 1f + (float)c.Evalue(1200) * 0.25f;
num2 *= 1f + (float)c2.Evalue(1200) * 0.25f;
}
if (!c.IsPC)
if (!c2.IsPC)
{
num2 *= 3f;
}
if (flag5 && !c.HasElement(480))
if (flag5 && !c2.HasElement(480))
{
if (c.IsPC)
if (c2.IsPC)
{
if (flag3)
{
c.Say("food_undead");
c2.Say("food_undead");
}
c.Say("food_rot");
c2.Say("food_rot");
}
num5 = 0f;
num3 /= 2;public static void Proc(Chara c, Thing food, bool consume = true)
switch (food.source._origin)
{
case "meat":
if (c.IsPC)
if (c2.IsPC)
{
c.Say("food_raw_meat");
c2.Say("food_raw_meat");
}
num2 *= 0.7f;
num5 = 0.5f;
break;
case "fish":
if (c.IsHuman)
if (c2.IsHuman)
{
if (c.IsPC)
if (c2.IsPC)
{
c.Say("food_raw_fish");
c2.Say("food_raw_fish");
}
num2 *= 0.9f;
num5 = 0.5f;
}
break;
case "dough":
if (c.IsPC)
if (c2.IsPC)
{
c.Say("food_raw_powder");
c2.Say("food_raw_powder");
}
num2 *= 0.9f;
num5 = 0.5f;
break;
}
}
float num7 = Mathf.Min(c.hunger.value, num3);
if (c.hunger.GetPhase() >= 3)
float num7 = Mathf.Min(c2.hunger.value, num3);
if (c2.hunger.GetPhase() >= 3)
{
num7 *= 1.1f;
}
if (flag5 && !c.HasElement(480))
if (flag5 && !c2.HasElement(480))
{
c.ModExp(70, -300);
c.ModExp(71, -300);
c.ModExp(72, -200);
c.ModExp(73, -200);
c.ModExp(74, -200);
c.ModExp(75, 500);
c.ModExp(76, -200);
c.ModExp(77, -300);
c2.ModExp(70, -300);
c2.ModExp(71, -300);
c2.ModExp(72, -200);
c2.ModExp(73, -200);
c2.ModExp(74, -200);
c2.ModExp(75, 500);
c2.ModExp(76, -200);
c2.ModExp(77, -300);
}
else
{
num2 = num2 * num7 / 10f;
if (c.HasCondition<ConAnorexia>())
if (c2.HasCondition<ConAnorexia>())
{
num2 = 0.01f;
}public static void Proc(Chara c, Thing food, bool consume = true)
string[] foodEffect = value.source.foodEffect;
int id = value.id;
float num8 = num2 * (float)value.Value;
if (value.source.category == "food" && c.IsPC)
if (value.source.category == "food" && c2.IsPC)
{
bool flag8 = num8 >= 0f;
string text = value.source.GetText(flag8 ? "textInc" : "textDec", returnNull: true);
if (text != null)
{
Msg.SetColor(flag8 ? "positive" : "negative");
c.Say(text);
c2.Say(text);
}
}
switch (foodEffect[0])
{
case "god":
{
int int2 = c.GetInt(117);
int int2 = c2.GetInt(117);
if (int2 < 10)
{
foreach (Element value2 in c.elements.dict.Values)
foreach (Element value2 in c2.elements.dict.Values)
{
if (value2.IsMainAttribute)
{
c.elements.ModPotential(value2.id, 2);
c2.elements.ModPotential(value2.id, 2);
}
}
}
c.Say("little_eat", c);
c.PlaySound("ding_potential");
c.elements.ModExp(306, -1000f);
c.SetInt(117, int2 + 1);
c2.Say("little_eat", c2);
c2.PlaySound("ding_potential");
c2.elements.ModExp(306, -1000f);
c2.SetInt(117, int2 + 1);
flag6 = false;
break;
}public static void Proc(Chara c, Thing food, bool consume = true)
{
id = ((foodEffect.Length > 1) ? EClass.sources.elements.alias[foodEffect[1]].id : value.id);
int a = (int)(num8 * (float)((foodEffect.Length > 2) ? foodEffect[2].ToInt() : 4)) * 2 / 3;
c.ModExp(id, a);
c2.ModExp(id, a);
break;
}
case "pot":
{
id = ((foodEffect.Length > 1) ? EClass.sources.elements.alias[foodEffect[1]].id : value.id);
int vTempPotential = c.elements.GetElement(id).vTempPotential;
int vTempPotential = c2.elements.GetElement(id).vTempPotential;
int num9 = EClass.rndHalf((int)(num8 / 5f) + 1);
num9 = num9 * 100 / Mathf.Max(100, vTempPotential * 2 / 3);
c.elements.ModTempPotential(id, num9, 8);
c2.elements.ModTempPotential(id, num9, 8);
break;
}
case "karma":
if (c.IsPCParty)
if (c2.IsPCParty)
{
EClass.player.ModKarma(-5);
}
break;
case "poison":
ActEffect.Poison(c, EClass.pc, value.Value * 10);
if (!c.isDead)
ActEffect.Poison(c2, EClass.pc, value.Value * 10);
if (!c2.isDead)
{
break;
}
goto IL_0f76;
case "love":
ActEffect.LoveMiracle(c, EClass.pc, value.Value * 10);
ActEffect.LoveMiracle(c2, EClass.pc, value.Value * 10);
break;
case "loseWeight":
c.ModWeight(-EClass.rndHalf(value.Value), ignoreLimit: true);
c2.ModWeight(-EClass.rndHalf(value.Value), ignoreLimit: true);
break;
case "gainWeight":
c.ModWeight(EClass.rndHalf(value.Value), ignoreLimit: true);
c2.ModWeight(EClass.rndHalf(value.Value), ignoreLimit: true);
break;
case "little":
{
int @int = c.GetInt(112);
int @int = c2.GetInt(112);
if (@int < 30)
{
c.Say("little_eat", c);
c.PlaySound("ding_potential");
c2.Say("little_eat", c2);
c2.PlaySound("ding_potential");
int v = Mathf.Max(5 - @int / 2, 1);
Debug.Log("sister eaten:" + @int + "/" + v);
foreach (Element value3 in c.elements.dict.Values)
foreach (Element value3 in c2.elements.dict.Values)
{
if (value3.IsMainAttribute)
{
c.elements.ModPotential(value3.id, v);
c2.elements.ModPotential(value3.id, v);
}
}
}
if (c.race.id == "mutant" && c.elements.Base(1230) < 10)
if (c2.race.id == "mutant" && c2.elements.Base(1230) < 10)
{
c.Say("little_adam", c);
c.SetFeat(1230, c.elements.Base(1230) + 1);
c2.Say("little_adam", c2);
c2.SetFeat(1230, c2.elements.Base(1230) + 1);
}
c.SetInt(112, @int + 1);
c2.SetInt(112, @int + 1);
break;
}
}
}
}
ProcTrait(c, food);
ProcTrait(c2, food);
num4 += (float)food.Evalue(70);
num4 += (float)(food.Evalue(72) / 2);
num4 += (float)(food.Evalue(73) / 2);public static void Proc(Chara c, Thing food, bool consume = true)
{
idTaste = "food_bad";
}
if (c.IsPC)
if (c2.IsPC)
{
c.Say(idTaste);
c2.Say(idTaste);
if (flag2)
{
c.Say(flag4 ? "food_human_pos" : "food_human_neg");
c2.Say(flag4 ? "food_human_pos" : "food_human_neg");
}
else if (flag4)
{
c.Say("food_human_whine");
c2.Say("food_human_whine");
}
}
}
if (LangGame.Has(idTaste + "2"))
{
c.Say(idTaste + "2", c, food);
c2.Say(idTaste + "2", c2, food);
}
if (!c.IsPCParty)
if (!c2.IsPCParty)
{
num3 *= 2;
}
num3 = num3 * (100 + c.Evalue(1235) * 10) / (100 + c.Evalue(1234) * 10 + c.Evalue(1236) * 15);
c.hunger.Mod(-num3);
num3 = num3 * (100 + c2.Evalue(1235) * 10) / (100 + c2.Evalue(1234) * 10 + c2.Evalue(1236) * 15);
c2.hunger.Mod(-num3);
if (flag2)
{
if (!flag4)
{
if (c.IsHuman)
if (c2.IsHuman)
{
c.AddCondition<ConInsane>(200);
c.SAN.Mod(15);
c2.AddCondition<ConInsane>(200);
c2.SAN.Mod(15);
}
if (EClass.rnd(c.IsHuman ? 5 : 20) == 0)
if (EClass.rnd(c2.IsHuman ? 5 : 20) == 0)
{
c.SetFeat(1205, 1, msg: true);
c2.SetFeat(1205, 1, msg: true);
flag4 = true;
}
}
if (flag4)
{
c.SetInt(31, EClass.world.date.GetRaw() + 10080);
c2.SetInt(31, EClass.world.date.GetRaw() + 10080);
}
}
else if (flag4 && c.GetInt(31) < EClass.world.date.GetRaw())
else if (flag4 && c2.GetInt(31) < EClass.world.date.GetRaw())
{
c.SetFeat(1205, 0, msg: true);
c2.SetFeat(1205, 0, msg: true);
}
if (flag5 && !c.HasElement(480))
if (flag5 && !c2.HasElement(480))
{
c.AddCondition<ConParalyze>();
c.AddCondition<ConConfuse>(200);
c2.AddCondition<ConParalyze>();
c2.AddCondition<ConConfuse>(200);
}
if (c.HasCondition<ConAnorexia>())
if (c2.HasCondition<ConAnorexia>())
{
c.Vomit();
c2.Vomit();
}
if (num3 > 20 && c.HasElement(1413))
if (num3 > 20 && c2.HasElement(1413))
{
Thing thing = ThingGen.Create("seed");
if (EClass.rnd(EClass.debug.enable ? 2 : 10) == 0)public static void Proc(Chara c, Thing food, bool consume = true)
TraitSeed.ApplySeed(thing, (EClass.rnd(4) == 0) ? 118 : ((EClass.rnd(3) == 0) ? 119 : 90));
}
thing.SetNum(2 + EClass.rnd(3));
c.Talk("vomit");
c.Say("fairy_vomit", c, thing);
c.PickOrDrop(c.pos, thing);
c2.Talk("vomit");
c2.Say("fairy_vomit", c2, thing);
c2.PickOrDrop(c2.pos, thing);
}
food.trait.OnEat(c);
food.trait.OnEat(c2);
if (food.trait is TraitDrink)
{
food.trait.OnDrink(c);
food.trait.OnDrink(c2);
}
goto IL_0f76;
IL_0f76:
if (!consume)
if (consume)
{
num7 += 5f;
if (flag6 && (float)food.Evalue(10) > num7 + 10f)
{
food.elements.SetTo(10, (int)Mathf.Max((float)food.Evalue(10) - num7, 1f));
food.SetBool(125, enable: true);
if (food.HasElement(1229))
{
food.elements.Remove(1229);
}
}
else
{
food.ModNum(-1);
}
}
if (c2.IsCat || !(food.trait is TraitFoodChuryu))
{
return;
}
num7 += 5f;
if (flag6 && (float)food.Evalue(10) > num7 + 10f)
foreach (Chara item in c2.pos.ListCharasInRadius(c2, 5, (Chara c) => c.IsCat))
{
food.elements.SetTo(10, (int)Mathf.Max((float)food.Evalue(10) - num7, 1f));
food.SetBool(125, enable: true);
if (food.HasElement(1229))
item.Say("angry", item);
item.ShowEmo(Emo.angry);
item.PlaySound("Animal/Cat/cat_angry");
if (c2.IsPC)
{
food.elements.Remove(1229);
EClass.player.ModKarma(-3);
}
}
else
{
food.ModNum(-1);
}
}
public static void ProcTrait(Chara c, Card t)HotItemNoItem
public static bool _TrySetAct(ActPlan p)
EClass.player.RefreshCurrentHotItem();
ActionMode.Adv.planRight.Update(ActionMode.Adv.mouseTarget);
EClass.pc.renderer.Refresh();
if (!(EClass.pc.held.trait is TraitShackle))
if (EClass.pc.held.trait is TraitToolMusic)
{
HotItemHeld.disableTool = true;
}Player
{
c.AddCard(ThingGen.Create("mixer"));
c.AddCard(ThingGen.Create("bloodpack").SetNum(3));
Thing thing = ThingGen.Create("parchment");
thing.SetStr(53, "letter_vampire");
c.AddCard(thing);
}
}
Thing SetSpellbook(Thing t, int charge)RecipeSource
return row.GetDetail();
}
public bool IsCraftable()
{
if (idFactory.IsEmpty() || idFactory == "x" || idFactory == "none")
{
return false;
}
return true;
}
public Element GetReqSkill()
{
return Element.Create((NeedFactory ? EClass.sources.cards.GetModelCrafter(idFactory) : Trait.SelfFactory).IDReqEle(this), row.LV);Thing
public override void WriteNote(UINote n, Action<UINote> onWriteNote = null, IIns
{
num3 = num3 * (100 + AttackProcess.GetTwoHandEncBonus(root.Chara)) / 100;
}
string text12 = " (" + e.Value + ((e.Value == num3) ? "" : (" → " + num3)) + ")";
string text13 = "_bracketLeft3".lang() + e.Name + "_bracketRight3".lang();
return s + text12 + " " + text13;
string text13 = " (" + e.Value + ((e.Value == num3) ? "" : (" → " + num3)) + ")";
string text14 = "_bracketLeft3".lang() + e.Name + "_bracketRight3".lang();
return s + text13 + " " + text14;
});
}
if (sockets != null)public override void WriteNote(UINote n, Action<UINote> onWriteNote = null, IIns
if (base.c_mixedFoodData != null)
{
n.AddHeader("isMixedFood");
foreach (string text14 in base.c_mixedFoodData.texts)
foreach (string text15 in base.c_mixedFoodData.texts)
{
AddText("_bullet".lang() + text14 + text2, FontColor.Default);
AddText("_bullet".lang() + text15 + text2, FontColor.Default);
}
}
}string GetTextTrait(Element e)
}
int num2 = e.Value / 10;
num2 = ((e.Value < 0) ? (num2 - 1) : (num2 + 1));
text10 = "Lv." + num2 + text11 + " " + text10;
string text12 = num2.ToString() ?? "";
if (EClass.pc.HasElement(1250) && HasElement(710) && e.IsFoodTrait && e.id != 710)
{
text12 = (int)((float)num2 * 0.1f * (float)(Evalue(710) + 10)) + " (" + num2 + ")";
}
text10 = "Lv." + text12 + text11 + " " + text10;
if (infoMode && e.IsFoodTraitMain)
{
text10 += "traitAdditive".lang();ThrowType
Flyer,
MonsterBall,
Explosive,
Ball
Ball,
Dice
}+TraitDice
File Created
public class TraitDice : Trait
{
public override bool IsThrowMainAction => true;
public override ThrowType ThrowType => ThrowType.Dice;
}