Skip to content

EA 23.335 Stable Patch 2 โ€‹

August 24, 2026

15 files modified.

Important Changes โ€‹

Possible breaking changes. Click the filename to view the chunk.

Dice (6) โ€‹

cs
public static int Roll_Normal(long num, long sides, int bonus = 0) 
public static long Roll_Normal(long num, long sides, int bonus = 0) 
cs
public static int Roll_Precise(int num, int sides, int bonus = 0) 
public static long Roll_Precise(int num, int sides, int bonus = 0) 
cs
public static int Roll(int num, int sides, int bonus = 0, Card card = null) 
public static long Roll(int num, int sides, int bonus = 0, Card card = null) 
cs
public static int RollMax(int num, int sides, int bonus = 0) 
public static long RollMax(int num, int sides, int bonus = 0) 
cs
public int Roll() 
public long Roll() 
cs
public int RollMax() 
public long RollMax() 

StanceSongPebble (1) โ€‹

cs
public override void TickSong() 

StanceSongValor (1) โ€‹

cs
public override void TickSong() 

ActEffect โ€‹

public static bool DamageEle(Card CC, EffectId id, int power, Element e, List<Poโ€ฆ)

cs
	num4 = num4 * 100 / (100 + RapidCount * 50);
}
num4 = num4 * Act.powerMod / 100;
if (num4 > 99999999) 
{ 
	num4 = 99999999L; 
} 
c.DamageHP(num4, e.id, power * num / 100, attackSource, chara ?? CC);
if (c.IsAliveInCurrentZone)
{

void AddCon<T>(int rate, int power) where T : Condition

cs
	EClass.game.religions.Element.Talk("ability");
}
Dice dice = Dice.Create("ActManaAbsorb", power, CC, (actRef.refThing != null) ? null : actRef.act);
TC.mana.Mod(dice.Roll() + TC.mana.max / 5); 
TC.mana.Mod(MathEx.ClampToInt(dice.Roll() + TC.mana.max / 5)); 
TC.PlaySound("heal");
TC.PlayEffect("heal");
if (TC == CC)

void AddCon<T>(int rate, int power) where T : Condition

cs
EClass.ui.AddLayer<LayerList>().SetStringList(delegate
{
	List<string> list12 = new List<string>();
	for (int num21 = 0; num21 < 10; num21++) 
	for (int num20 = 0; num20 < 10; num20++) 
	{
		list12.Add(AliasGen.GetRandomAlias());
	}

void AddCon<T>(int rate, int power) where T : Condition

cs
			{
				effect.Play(center, 0f, pos);
			});
			int num16 = Dice.Create("SpShutterHex", power, CC, (actRef.refThing != null) ? null : actRef.act).Roll(); 
			item6.DamageHP(num16, 919, power, AttackSource.None, CC, showEffect: false); 
			long dmg = Dice.Create("SpShutterHex", power, CC, (actRef.refThing != null) ? null : actRef.act).Roll(); 
			item6.DamageHP(dmg, 919, power, AttackSource.None, CC, showEffect: false); 
		}
	}
}

void AddCon<T>(int rate, int power) where T : Condition

cs
List<Thing> list = new List<Thing>();
TC.things.Foreach(delegate(Thing t)
{
	int num20 = 0; 
	int num19 = 0; 
	if ((t.isEquipped || t.IsRangedWeapon || blessed) && t.blessedState < BlessedState.Normal)
	{
		if (t.blessedState == BlessedState.Cursed)
		{
			num20 = EClass.rnd(200); 
			num19 = EClass.rnd(200); 
		}
		if (t.blessedState == BlessedState.Doomed)
		{
			num20 = EClass.rnd(1000); 
			num19 = EClass.rnd(1000); 
		}
		if (blessed)
		{
			num20 /= 2; 
			num19 /= 2; 
		}
		if (id == EffectId.UncurseEQGreater)
		{
			num20 /= 10; 
			num19 /= 10; 
		}
		if (power >= num20) 
		if (power >= num19) 
		{
			TC.Say("uncurseEQ_success", t);
			t.SetBlessedState(BlessedState.Normal);

void AddCon<T>(int rate, int power) where T : Condition

cs
if (TC.HasElement(1211))
{
	TC.Say("drinkSaltWater_snail", TC);
	int num19 = ((TC.hp > 10) ? (TC.hp - EClass.rnd(10)) : 10000); 
	TC.DamageHP(num19, AttackSource.None, CC); 
	int num18 = ((TC.hp > 10) ? (TC.hp - EClass.rnd(10)) : 10000); 
	TC.DamageHP(num18, AttackSource.None, CC); 
}
else if (TC.IsPC)
{

void AddCon<T>(int rate, int power) where T : Condition

cs
{
	TC.PlayEffect("buff");
	TC.PlaySound("offering");
	int num17 = TC.Evalue(1423); 
	if (num17 > 0) 
	int num16 = TC.Evalue(1423); 
	if (num16 > 0) 
	{
		int num18 = 0; 
		if (flag && num17 > 1) 
		int num17 = 0; 
		if (flag && num16 > 1) 
		{
			num18 = -1; 
			num17 = -1; 
		}
		else if (num17 < 15) 
		else if (num16 < 15) 
		{
			num18 = ((!blessed) ? 1 : 2); 
			if (num18 + num17 > 15) 
			num17 = ((!blessed) ? 1 : 2); 
			if (num17 + num16 > 15) 
			{
				num18 = 1; 
				num17 = 1; 
			}
		}
		if (num18 != 0) 
		if (num17 != 0) 
		{
			TC.SetFeat(1423, num17 + num18, msg: true); 
			TC.SetInt(134, TC.GetInt(134) + num18); 
			TC.SetFeat(1423, num16 + num17, msg: true); 
			TC.SetInt(134, TC.GetInt(134) + num17); 
		}
	}
}

BaseCondition โ€‹

public virtual void SetOwner(Chara _owner, bool onDeserialize = false)

cs
	owner = _owner;
	phase = GetPhase();
	RefreshEmoIcon();
	if (UseElements) 
	{ 
		elements = new ElementContainerCondition(); 
		if (base.source.elements.Length != 0) 
		{ 
			for (int i = 0; i < base.source.elements.Length; i += 2) 
			{ 
				elements.SetBase(GetElementSource(i).id, base.source.elements[i + 1].Calc(power, 0, P2)); 
			} 
		} 
		elements.SetParent(owner); 
	} 
	RefreshElements(); 
	if (onDeserialize)
	{
		OnChangePhase(phase, phase);
	}
}

public void RefreshElements() 
{ 
	if (!UseElements) 
	{ 
		return; 
	} 
	if (elements != null) 
	{ 
		elements.SetParent(); 
	} 
	elements = new ElementContainerCondition(); 
	if (base.source.elements.Length != 0) 
	{ 
		for (int i = 0; i < base.source.elements.Length; i += 2) 
		{ 
			elements.SetBase(GetElementSource(i).id, base.source.elements[i + 1].Calc(power, 0, P2)); 
		} 
	} 
	elements.SetParent(owner); 
} 
public void RefreshEmoIcon()
{
	if (EmoIcon > owner.emoIcon)

BaseSong โ€‹

public virtual void TickSong()

cs
	{
	}
}
public class BaseSong<T> : BaseSong where T : Condition
{ 
	public virtual int BaseDuration => 10; 
	public override void TickSong() 
	{ 
		foreach (Chara item in owner.pos.ListCharasInRadius(owner, 4, (Chara c) => !c.IsDeadOrSleeping && ((!owner.IsPCFactionOrMinion) ? (!c.IsHostile(owner)) : c.IsPCFactionOrMinion))) 
		{ 
			T condition = item.GetCondition<T>(); 
			if (condition == null) 
			{ 
				item.AddCondition<T>(base.power); 
				continue; 
			} 
			if (condition.power != base.power) 
			{ 
				condition.power = base.power; 
				condition.RefreshElements(); 
			} 
			condition.SetValue(BaseDuration + owner.Evalue(1294) * 2, owner.Evalue(1294)); 
		} 
	} 
} 

Card โ€‹

public virtual long ApplyProtection(long dmg, int mod = 100)

cs
	bonus = 0;
	dmg = dmg * 100 / Mathf.Max(100 + num, 1);
}
int num4 = Dice.Roll(num2, sides, bonus, this); 
long num4 = Dice.Roll(num2, sides, bonus, this); 
dmg -= num4 * mod / 100;
if (dmg < 0)
{

Chara โ€‹

void ForeachEnemy(Action<Chara> action)

cs
{
	if (_pts.Count == 0)
	{
		for (int num10 = EClass._map.charas.Count - 1; num10 >= 0; num10--) 
		for (int num11 = EClass._map.charas.Count - 1; num11 >= 0; num11--) 
		{
			Chara chara3 = EClass._map.charas[num10]; 
			Chara chara3 = EClass._map.charas[num11]; 
			if (chara3 != this && CanSeeLos(chara3) && chara3.IsHostile(this))
			{
				_pts.Add(chara3);
			}
		}
	}
	for (int num11 = _pts.Count - 1; num11 >= 0; num11--) 
	for (int num12 = _pts.Count - 1; num12 >= 0; num12--) 
	{
		action(_pts[num11]); 
		action(_pts[num12]); 
	}
}
void ForeachParty(Action<Chara> action)

void ForeachParty(Action<Chara> action)

cs
				}
			}
		}
		for (int num9 = _pts.Count - 1; num9 >= 0; num9--) 
		int num9 = _pts.IndexOf(this); 
		if (num9 != -1) 
		{
			action(_pts[num9]); 
			_pts.RemoveAt(num9); 
			_pts.Insert(0, this); 
		} 
		for (int num10 = _pts.Count - 1; num10 >= 0; num10--) 
		{ 
			action(_pts[num10]); 
		}
	}
}

public void Cuddle(Chara c, bool headpat = false)

cs
}
if (faith == EClass.game.religions.MoonShadow && c.IsPCParty)
{
	foreach (Chara member in party.members) 
	foreach (Chara member in c.party.members) 
	{
		if (!member.IsPC && CanSeeLos(member))
		{

Check โ€‹

public int GetFinalDC(Chara p, Card tg = null)

cs
public Result Perform(Chara p, Card tg = null)
{
	int finalDC = GetFinalDC(p, tg);
	int num = Dice.Roll(1, 20); 
	long num = Dice.Roll(1, 20); 
	if (EClass.debug.logDice)
	{
		string text = "Check:" + source.id + " dc=" + finalDC + " roll=" + num + "  ";
		Debug.Log(num switch
		{
			20 => text + "CriticalPass",  
			1 => text + "CriticalFail",  
			20L => text + "CriticalPass",  
			1L => text + "CriticalFail",  
			_ => (num < finalDC) ? (text + "Fail") : (text + "Pass"), 
		});
	}
	switch (num)
	{
	case 20: 
	case 20L: 
		return Result.CriticalPass;
	case 1: 
	case 1L: 
		return Result.CriticalFail;
	default:
		if (num >= finalDC)

DNA โ€‹

public void Apply(Chara c, bool reverse)

cs
	num3 = 0;
}
c.SetFeat(num, num3, !reverse);
if (reverse && num == 1423) 
if (reverse && num == 1423 && c.GetInt(134) > 0) 
{
	int @int = c.GetInt(134); 
	if (@int > 0) 
	int num4 = c.elements.ValueWithoutLink(num) - c.GetInt(134); 
	if (num4 < 0) 
	{
		c.SetFeat(num, -@int); 
		num4 = 0; 
	}
	c.SetFeat(num, num4); 
	c.SetInt(134);
}
break;

Dice โ€‹

public class Dice

cs
public static int MaxValue => 214748364;

public static int Roll_Normal(long num, long sides, int bonus = 0) 
public static long Roll_Normal(long num, long sides, int bonus = 0) 
{
	double num2 = (double)(num * (sides + 1)) / 2.0; 
	double num3 = Math.Sqrt((double)(num * (sides * sides - 1)) / 12.0); 
	double num2 = num; 
	double num3 = sides; 
	double num4 = num2 * (num3 + 1.0) / 2.0; 
	double num5 = Math.Sqrt(num2 * (num3 * num3 - 1.0) / 12.0); 
	double d = (double)(rnd(1000000) + 1) / 1000001.0;
	double num4 = (double)(rnd(1000000) + 1) / 1000001.0; 
	double num5 = Math.Sqrt(-2.0 * Math.Log(d)) * Math.Cos(Math.PI * 2.0 * num4); 
	long num6 = (long)Math.Floor(num2 + num3 * num5 + 0.5); 
	long num7 = num * sides; 
	if (num6 < num) 
	double num6 = (double)(rnd(1000000) + 1) / 1000001.0; 
	double num7 = Math.Sqrt(-2.0 * Math.Log(d)) * Math.Cos(Math.PI * 2.0 * num6); 
	double num8 = Math.Floor(num4 + num5 * num7 + 0.5); 
	long num9 = ((sides != 0L && num > long.MaxValue / sides) ? long.MaxValue : (num * sides)); 
	if (num8 < (double)num) 
	{
		num6 = num; 
		num8 = num; 
	}
	if (num6 > num7) 
	if (num8 > (double)num9) 
	{
		num6 = num7; 
		num8 = num9; 
	}
	return (int)Mathf.Clamp(num6 + bonus, -MaxValue, MaxValue); 
	long num10 = (long)num8; 
	if (bonus > 0 && num10 > long.MaxValue - bonus) 
	{ 
		return long.MaxValue; 
	} 
	if (bonus < 0 && num10 < long.MinValue - bonus) 
	{ 
		return long.MinValue; 
	} 
	return num10 + bonus; 
}

public static int Roll_Precise(int num, int sides, int bonus = 0) 
public static long Roll_Precise(int num, int sides, int bonus = 0) 
{
	long num2 = 0L;
	for (int i = 0; i < num; i++)
	{
		num2 += rnd(sides) + 1;
	}
	return (int)Mathf.Clamp(num2 + bonus, -MaxValue, MaxValue); 
	return num2 + bonus; 
}

public static int Roll(int num, int sides, int bonus = 0, Card card = null) 
public static long Roll(int num, int sides, int bonus = 0, Card card = null) 
{
	int a = 1;
	bool flag = true;
	int num2 = 0; 
	long num2 = 0L; 
	if (card != null)
	{
		int num3 = card.Evalue(78);

public static int Roll(int num, int sides, int bonus = 0, Card card = null)

cs
}
for (int i = 0; i < Mathf.Min(a, 20); i++)
{
	int num4 = ((num >= 10) ? Roll_Normal(num, sides, bonus) : Roll_Precise(num, sides, bonus)); 
	long num4 = ((num >= 10) ? Roll_Normal(num, sides, bonus) : Roll_Precise(num, sides, bonus)); 
	if (i == 0 || (flag && num4 > num2) || (!flag && num4 < num2))
	{
		num2 = num4;

public static int Roll(int num, int sides, int bonus = 0, Card card = null)

cs
	return num2;
}

public static int RollMax(int num, int sides, int bonus = 0) 
public static long RollMax(int num, int sides, int bonus = 0) 
{
	return (int)Mathf.Clamp((long)num * (long)sides + bonus, -MaxValue, MaxValue); 
	return (long)num * (long)sides + bonus; 
}

public static int rnd(int a)

public static Dice Parse(string raw)

cs
	return dice;
}

public int Roll() 
public long Roll() 
{
	return Roll(num, sides, bonus, card);
}

public int RollMax() 
public long RollMax() 
{
	return RollMax(num, sides, bonus);
}

Party โ€‹

public List<Chara> SetMembers()

cs
{
	if (!hashSet.Contains(uidMember))
	{
		hashSet.Add(uidMember); 
		members.Add(RefChara.Get(uidMember)); 
		Chara chara = RefChara.Get(uidMember); 
		if (chara != null) 
		{ 
			hashSet.Add(uidMember); 
			members.Add(chara); 
		} 
	}
}
return _members;

SerializedCards โ€‹

public void Restore(Map map, Map orgMap, bool addToZone, PartialMap partial = nuโ€ฆ)

cs
}
if (source.isOrigin)
{
	text = SpawnListThing.Get("origin_" + text, (SourceThing.Row a) => a.origin == source).GetFirst().id; 
	SpawnList spawnList = SpawnListThing.Get("origin_" + text, (SourceThing.Row a) => a.origin == source); 
	if (spawnList.rows.Count == 0) 
	{ 
		continue; 
	} 
	text = spawnList.GetFirst().id; 
}
card2 = ThingGen.Create(text, -1, EClass._zone.DangerLv);
card2.ChangeMaterial((card4.idMat == -1) ? card2.DefaultMaterial.id : card4.idMat);

StanceSongPebble โ€‹

public class StanceSongPebble : BaseSong

cs
public class StanceSongPebble : BaseSong
public class StanceSongPebble : BaseSong<ConSongPebble> 
{
	public override int IdAbility => 6754;
	public override void TickSong() 
	{ 
		foreach (Chara item in owner.pos.ListCharasInRadius(owner, 4, (Chara c) => !c.IsDeadOrSleeping && ((!owner.IsPCFactionOrMinion) ? (!c.IsHostile(owner)) : c.IsPCFactionOrMinion))) 
		{ 
			if (!item.HasCondition<ConSongPebble>()) 
			{ 
				item.AddCondition<ConSongPebble>(base.power, owner.Evalue(1294)); 
			} 
			else
			{ 
				item.GetCondition<ConSongPebble>()?.SetValue(10 + owner.Evalue(1294) * 2, owner.Evalue(1294)); 
			} 
		} 
	} 
}

StanceSongValor โ€‹

public class StanceSongValor : BaseSong

cs
public class StanceSongValor : BaseSong
public class StanceSongValor : BaseSong<ConSongValor> 
{
	public override int IdAbility => 6752;
	public override void TickSong() 
	{ 
		foreach (Chara item in owner.pos.ListCharasInRadius(owner, 4, (Chara c) => !c.IsDeadOrSleeping && ((!owner.IsPCFactionOrMinion) ? (!c.IsHostile(owner)) : c.IsPCFactionOrMinion))) 
		{ 
			if (!item.HasCondition<ConSongValor>()) 
			{ 
				item.AddCondition<ConSongValor>(base.power); 
			} 
			else
			{ 
				item.GetCondition<ConSongValor>()?.SetValue(10 + owner.Evalue(1294) * 2, owner.Evalue(1294)); 
			} 
		} 
	} 
}

TraitCrafter โ€‹

public bool IsIngredient(int idx, SourceRecipe.Row r, Card c)

cs
}
if (text == "any")
{
	if (this is TraitDyeMaker && !c.category.GetRoot().tag.Contains("dye") && !c.category.tag.Contains("dye")) 
	if (this is TraitDyeMaker) 
	{
		return false; 
		if (c.id == "dye") 
		{ 
			return false; 
		} 
		if (!c.category.GetRoot().tag.Contains("dye") && !c.category.tag.Contains("dye")) 
		{ 
			return false; 
		} 
	}
	if (!c.IsUnique && !c.IsImportant && !c.trait.CanOnlyCarry)
	{

Widget โ€‹

public void Reactivate()

cs
public virtual void OnManagerActivate()
{
	goCover = Util.Instantiate("UI/Widget/CoverWidget", base.transform).gameObject; 
	RectTransform rectTransform = goCover.transform.Rect(); 
	RectTransform rectTransform2 = dragPanel.Rect(); 
	if ((bool)rectTransform && (bool)rectTransform2) 
	{ 
		rectTransform.pivot = rectTransform2.pivot; 
		rectTransform.anchorMin = rectTransform2.anchorMin; 
		rectTransform.anchorMax = rectTransform2.anchorMax; 
		rectTransform.anchoredPosition = rectTransform2.anchoredPosition; 
		rectTransform.sizeDelta = rectTransform2.sizeDelta; 
	} 
	UIDragPanel componentInChildren = goCover.GetComponentInChildren<UIDragPanel>(); 
	componentInChildren.autoAnchor = config.userAnchor == RectPosition.Auto; 
	componentInChildren.onDrag = OnChangePosition; 
	componentInChildren.container = dragPanel.container; 
	componentInChildren.target = dragPanel.target; 
	componentInChildren.bound = dragPanel.bound; 
	if (this is WidgetSideScreen) 
	{ 
		componentInChildren.enable = false; 
	if (!(this == null) && (bool)this) 
	{ 
		goCover = Util.Instantiate("UI/Widget/CoverWidget", base.transform).gameObject; 
		RectTransform rectTransform = goCover.transform.Rect(); 
		RectTransform rectTransform2 = dragPanel.Rect(); 
		if ((bool)rectTransform && (bool)rectTransform2) 
		{ 
			rectTransform.pivot = rectTransform2.pivot; 
			rectTransform.anchorMin = rectTransform2.anchorMin; 
			rectTransform.anchorMax = rectTransform2.anchorMax; 
			rectTransform.anchoredPosition = rectTransform2.anchoredPosition; 
			rectTransform.sizeDelta = rectTransform2.sizeDelta; 
		} 
		UIDragPanel componentInChildren = goCover.GetComponentInChildren<UIDragPanel>(); 
		componentInChildren.autoAnchor = config.userAnchor == RectPosition.Auto; 
		componentInChildren.onDrag = OnChangePosition; 
		componentInChildren.container = dragPanel.container; 
		componentInChildren.target = dragPanel.target; 
		componentInChildren.bound = dragPanel.bound; 
		if (this is WidgetSideScreen) 
		{ 
			componentInChildren.enable = false; 
		} 
		goCover.GetComponentInChildren<UIText>().SetText(("Widget" + ID).lang()); 
	}
	goCover.GetComponentInChildren<UIText>().SetText(("Widget" + ID).lang()); 
}

public virtual void OnManagerDeactivate()

Zone_WindRest โ€‹

public override void OnAfterSimulate()

cs
	TryRevive("eureka", 60, 61);
	TryRevive("billy", 35, 64);
}
List<Thing> list = EClass._map.ListThing<TraitDaggerGrave>(); 
foreach (Thing item in list) 
{ 
	if (item.pos.x != 52 || item.pos.z != 46) 
	{ 
		continue; 
	} 
	{ 
		foreach (Thing item2 in list) 
		{ 
			if (item2.c_idBacker == 1239) 
			{ 
				item.MoveImmediate(item2.pos); 
				item2.MoveImmediate(new Point(52, 46)); 
				break; 
			} 
		} 
		break; 
	} 
} 
static void TryRevive(string id, int x, int y)
{
	if (EClass.game.cards.globalCharas.Find(id) == null)