Skip to content

EA 23.193 Nightly

September 4, 2025

12 files modified.

Important Changes

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

Msg (1)

cs
public static string GetGameText(string idLang) 
public static string GetGameText(string idLang, Card card = null) 

ActEffect

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

cs
	}
	case EffectId.Draw:
	{
		Point point = CC.pos.GetRandomPoint(1)?.GetNearestPoint(allowBlock: false, allowChara: false); 
		if (point == null || !CC.CanSeeLos(point) || (CC.IsPCFactionOrMinion && TC.IsPCFactionOrMinion && TC.isRestrained)) 
		if (CC.Dist(TC) <= 1 || (CC.IsPCFactionOrMinion && TC.IsPCFactionOrMinion && TC.isRestrained)) 
		{ 
			break; 
		} 
		Point point = CC.GetFirstStep(TC.pos, PathManager.MoveType.Combat); 
		if (!point.IsValid) 
		{ 
			point = CC.pos.GetRandomPoint(1)?.GetNearestPoint(allowBlock: false, allowChara: false); 
		} 
		if (point == null || !CC.CanSeeLos(point)) 
		{
			break;
		}

ActMelee

public bool Attack(float dmgMulti = 1f)

cs
		}
		else if (AllowCounter && hasMissed && !cC.HasElement(439) && orgTC.HasElement(380))
		{
			orgTC.Say("counter"); 
			orgTC.Say((orgTC.isChara && orgTC.Chara.IsHostile()) ? "counter_enemy" : "counter"); 
			new ActMeleeCounter().Perform(orgTC.Chara, cC);
		}
	}

void Attack(Card _tc, Point _tp, float mtp, bool subAttack)

cs
					num6 = num6 * 100 / (int)Mathf.Clamp((float)AttackProcess.Current.weaponSkill.Value / (float)num7 * 100f, 50f, 150f);
					if (EClass.rnd(100) < num6)
					{
						Act.TC.Say("parry"); 
						Act.TC.Say((Act.TC.isChara && Act.TC.Chara.IsHostile()) ? "parry_enemy" : "parry"); 
						Act.TC.PlaySound("parry");
						parried = true;
						return;

void Attack(Card _tc, Point _tp, float mtp, bool subAttack)

cs
					flag = AttackProcess.Current.Perform(count, hasHit, dmgMulti * mtp, maxRoll, subAttack);
					AttackProcess.Current.critFury = false;
				}
				if (flag) 
				{ 
					hasHit = true; 
				} 
				else
				{ 
					hasMissed = true; 
				} 
				if (flag || !Act.CC.IsAliveInCurrentZone || !Act.TC.IsAliveInCurrentZone)
				{
					break;
				}
			}
			if (flag) 
			{ 
				hasHit = true; 
			} 
			else
			{ 
				hasMissed = true; 
			} 
			Act.TC = _tc;
			Act.TP = _tp;
			if (w != null && w.c_ammo > 0 && !Act.CC.HasCondition<ConReload>() && !safety)

void AttackWithFlurry(Card _tc, Point _tp, float mtp, bool subAttack)

cs
				}
				if (m > 0)
				{
					Act.CC.Say("attack_flurry"); 
					Act.CC.Say(Act.CC.IsHostile() ? "attack_flurry_enemy" : "attack_flurry"); 
				}
				Attack(_tc, _tp, mtp, subAttack);
				if (parried)

ActRanged

void Shoot(Card _tc, Point _tp)

cs
					{
						if (chaser > EClass.rnd(4 + (int)Mathf.Pow(4f, k + 2 + j)))
						{
							Act.CC.Say("attack_chaser"); 
							Act.CC.Say(Act.CC.IsHostile() ? "attack_chaser_enemy" : "attack_chaser"); 
							if (AttackProcess.Current.Perform(j, hasHit, dmgMulti))
							{
								hasHit = true;

AttackProcess

public bool IsCane

cs
	public static int GetWeaponEnc(Chara CC, Thing w, int ele, bool addSelfEnc = false)
	{
		int num = w?.Evalue(ele) ?? 0;
		if (CC.body.GetAttackStyle() == AttackStyle.TwoHand) 
		if (CC.IsPCFactionOrMinion) 
		{
			num = num * (100 + Mathf.Clamp(CC.Evalue(130) / 15, 0, 2) * 25) / 100; 
			num += EClass.pc.faction.charaElements.Value(ele); 
		}
		num = num * (100 + GetTwoHandEncBonus(CC)) / 100; 
		if (addSelfEnc)
		{
			num += CC.Evalue(ele);
		}
		if (CC.IsPCFactionOrMinion) 
		return num; 
	} 
	public static int GetTwoHandEncBonus(Chara CC) 
	{ 
		if (CC == null || CC.body.GetAttackStyle() != AttackStyle.TwoHand) 
		{
			num += EClass.pc.faction.charaElements.Value(ele); 
			return 0; 
		}
		return num; 
		return Mathf.Clamp(CC.Evalue(130) / 15, 0, 2) * 25; 
	}

	public string GetText()

public void Prepare(Chara _CC, Thing _weapon, Card _TC = null, Point _TP = null,

cs
	{
		toHit += 25 + (int)Mathf.Sqrt(Mathf.Max(0, CC.Evalue(130)) * 2);
	}
	else if (attackStyle == AttackStyle.TwoWield && toHit > 0) 
	else if (attackStyle == AttackStyle.TwoWield) 
	{
		toHit = toHit * 100 / (115 + attackIndex * 15 + attackIndex * Mathf.Clamp(2000 / (20 + CC.EvalueMax(131, -10)), 0, 100)); 
		int num4 = CC.EvalueMax(131, -10); 
		int num5 = ((num4 >= 25) ? 12 : 15); 
		int max = 100 + ((num4 >= 50) ? ((int)Mathf.Sqrt(num4)) : 0); 
		if (toHit > 0) 
		{ 
			toHit = toHit * 100 / (100 + (attackIndex + 1) * num5 + attackIndex * Mathf.Clamp(2000 / (20 + num4), 0, max)); 
		} 
	}
	if (CC.isBlind)
	{

public static void ProcAbility(Element e, Chara CC, Card TC, int bonus, bool sub

cs
	}
	int num = (10 + e.Value / 5) * mtpChance / 100;
	int power = EClass.curve((100 + e.Value * 10) * (100 + bonus) / 100, 400, 100);
	if (e.id == 6602) 
	{ 
		num = 100; 
	} 
	if (num <= EClass.rnd(100))
	{
		return;

public bool Perform(int count, bool hasHit, float dmgMulti = 1f, bool maxRoll =

cs
			ModExpDef(150, 90);
			ModExpDef(151, 90);
		}
		ProcAbility(list, CC, TC, weaponSkill.Value, subAttack); 
		ProcAbility(list, CC, TC, weaponSkill.Value + GetTwoHandEncBonus(CC), subAttack); 
		return false;
	}
	if (TC.IsPC)

public bool Perform(int count, bool hasHit, float dmgMulti = 1f, bool maxRoll =

cs
			if (item.IsActive(weapon) && item.source.categorySub == "eleAttack")
			{
				int num10 = 25;
				int dmg = EClass.rnd(num * (100 + item.Value * 10) / 500 + 5); 
				int num11 = EClass.rnd(num * (100 + item.Value * 10) / 500 + 5); 
				num11 = num11 * (100 + GetTwoHandEncBonus(CC)) / 100; 
				if (conWeapon == null && weapon != null && weapon.trait is TraitToolRangeCane)
				{
					num10 = 0;
				}
				if (num10 > EClass.rnd(100))
				{
					TC.DamageHP(dmg, item.id, isThrow ? (100 + item.Value * 5) : (30 + item.Value), AttackSource.WeaponEnchant, CC); 
					TC.DamageHP(num11, item.id, isThrow ? (100 + item.Value * 5) : (30 + item.Value), AttackSource.WeaponEnchant, CC); 
				}
			}
		}
		ProcAbility(list, CC, TC, weaponSkill.Value, subAttack); 
		ProcAbility(list, CC, TC, weaponSkill.Value + GetTwoHandEncBonus(CC), subAttack); 
	}
	if (!CC.IsAliveInCurrentZone || !TC.IsAliveInCurrentZone)
	{

public bool Perform(int count, bool hasHit, float dmgMulti = 1f, bool maxRoll =

cs
	}
	if (!IsRanged && !flag2 && attackStyle == AttackStyle.Shield)
	{
		int num11 = CC.Evalue(123); 
		int num12 = CC.Evalue(381); 
		if (CC.elements.ValueWithoutLink(123) >= 10 && Mathf.Clamp(Mathf.Sqrt(num11) - 2f, 8f, 15f) + Mathf.Min(Mathf.Sqrt(num12), 25f) > (float)EClass.rnd(100)) 
		int num12 = CC.Evalue(123); 
		int num13 = CC.Evalue(381); 
		if (CC.elements.ValueWithoutLink(123) >= 10 && Mathf.Clamp(Mathf.Sqrt(num12) - 2f, 8f, 15f) + Mathf.Min(Mathf.Sqrt(num13), 25f) > (float)EClass.rnd(100)) 
		{
			num = num7 * (Mathf.Min(50 + num11 + num12, 200) + (int)Mathf.Min(Mathf.Sqrt(num12), 100f)) / 100; 
			penetration = (int)Mathf.Sqrt(num12); 
			num = num7 * (Mathf.Min(50 + num12 + num13, 200) + (int)Mathf.Min(Mathf.Sqrt(num13), 100f)) / 100; 
			penetration = (int)Mathf.Sqrt(num13) + ((num13 != 0) ? 20 : 0); 
			if (penetration > 100)
			{
				penetration = 100;

public bool Perform(int count, bool hasHit, float dmgMulti = 1f, bool maxRoll =

cs
			{
				if (EClass.rnd(2) == 0)
				{
					TC.Chara.AddCondition<ConDim>(50 + (int)Mathf.Sqrt(num11) * 10); 
					TC.Chara.AddCondition<ConDim>(50 + (int)Mathf.Sqrt(num12) * 10); 
				}
				TC.Chara.AddCondition<ConParalyze>(EClass.rnd(2), force: true);
			}
			ProcShieldEncs(CC, TC, 500 + num12); 
			ProcShieldEncs(CC, TC, 500 + num13); 
		}
	}
	if (!CC.IsAliveInCurrentZone || !TC.IsAliveInCurrentZone)

Card

public void DamageHP(int dmg, int ele, int eleP = 100, AttackSource attackSource

cs
	{
		Chara.AddCondition<ConFear>(100 + EClass.rnd(100));
	}
	if (Chara.ai.Current.CancelWhenDamaged && attackSource != AttackSource.Hunger && attackSource != AttackSource.Fatigue) 
	if (Chara.ai.Current.CancelWhenDamaged && attackSource != AttackSource.Hunger && attackSource != AttackSource.Fatigue && (!EClass.core.config.test.dontCancelIfZeroDamage || dmg != 0 || !IsPC)) 
	{
		Chara.ai.Current.TryCancel(origin);
	}

ContentConfigTest

public class ContentConfigTest : ContentConfig

cs

	public UIButton toggleCompressSave;

	public UIButton toggledDntCancelIfZeroDamage; 
	public Slider sliderBrightness;

	public override void OnInstantiate()

public override void OnInstantiate()

cs
	{
		base.config.test.compressSave = on;
	});
	toggledDntCancelIfZeroDamage.SetToggle(base.config.test.dontCancelIfZeroDamage, delegate(bool on) 
	{ 
		base.config.test.dontCancelIfZeroDamage = on; 
	}); 
	toggleAlwaysRun.SetToggle(base.config.test.alwaysRun, delegate(bool on)
	{
		base.config.test.alwaysRun = on;

CoreConfig

public class Test

cs

		public bool allowBlockOnItem;

		public bool dontCancelIfZeroDamage; 
		public bool alwaysFixCamera;

		public bool ignoreBackerDestoryFlag;

Msg

public static PopItem TalkMaid(string id)

cs
		return TalkHomeMemeber(id);
	}

	public static string GetGameText(string idLang) 
	public static string GetGameText(string idLang, Card card = null) 
	{
		LangGame.Row row = EClass.core.sources.langGame.map.TryGetValue(idLang);
		if (row == null)

Recipe

public bool HasSameTile(Point point, int dir, int altitude, int bridgeHeight)

cs
			return true;
		}
	}
	else if (IsBlock && point.matBlock == GetColorMaterial() && point.sourceBlock == tileRow) 
	else if (IsBlock && point.matBlock == GetColorMaterial() && (point.sourceBlock == tileRow || (tileRow.tileType == point.sourceBlock.tileType && tileRow.tileType == TileType.Slope))) 
	{
		if (point.sourceBlock.tileType.AltitudeAsDir && dir != point.cell.objDir)
		{

Thing

public override void OnCreate(int genLv)

cs
			{
				num2 = EClass.rnd(2) + 1;
			}
			if (id == "bow_vindale") 
			{ 
				num2 = 4; 
			} 
			if (num2 > 0)
			{
				for (int j = 0; j < num2; j++)

public override void WriteNote(UINote n, Action<UINote> onWriteNote = null, IIns

cs
	{
		n.AddText("(id:" + id + " tile:" + (source.tiles.IsEmpty() ? "-" : ((object)source.tiles[0]))?.ToString() + ") lv:" + base.LV + " price:" + GetPrice());
	}
	Card rootCard = GetRootCard(); 
	if (rootCard != null && rootCard != EClass.pc && rootCard != this && rootCard.ExistsOnMap && !((parent as Thing)?.trait is TraitChestMerchant)) 
	Card root = GetRootCard(); 
	if (root != null && root != EClass.pc && root != this && root.ExistsOnMap && !((parent as Thing)?.trait is TraitChestMerchant)) 
	{
		n.AddText("isChildOf".lang(GetRootCard().Name), FontColor.ItemName);
	}

public override void WriteNote(UINote n, Action<UINote> onWriteNote = null, IIns

cs
					return false;
				}
				return (!showEQStats || (e.id != 64 && e.id != 65 && e.id != 66 && e.id != 67)) ? true : false;
			}, null, ElementContainer.NoteMode.Default, addRaceFeat: false, (Element e, string s) => (mode != IInspect.NoteMode.Info) ? s : (s + " (" + e.Value + ")")); 
			}, null, ElementContainer.NoteMode.Default, addRaceFeat: false, delegate(Element e, string s) 
			{ 
				if (mode != IInspect.NoteMode.Info) 
				{ 
					return s; 
				} 
				int num4 = e.Value; 
				if (e.source.IsWeaponEnc && !e.source.tag.Contains("modRanged") && isEquipped && root.isChara) 
				{ 
					num4 = num4 * (100 + AttackProcess.GetTwoHandEncBonus(root.Chara)) / 100; 
				} 
				return s + " (" + e.Value + ((e.Value == num4) ? "" : (" → " + num4)) + ")"; 
			}); 
		}
		if (sockets != null)
		{

TraitSpellbook

public static void Create(Card owner, int ele)

cs
	switch (row.id)
	{
	case 8430:
		owner.elements.SetBase(765, 50); 
		owner.elements.SetBase(765, 40); 
		break;
	case 9155:
		owner.elements.SetBase(765, 90); 
		owner.elements.SetBase(765, 70); 
		break;
	case 8390:
	case 8550:

WindowChara

public void RefreshSkill(int idTab)

cs
					{
						return true;
					}
					if (a.source.category == "enchant") 
					{ 
						return true; 
					} 
				}
				if ((a.owner == chara.elements && a.vLink == 0 && !a.IsFactionElement(chara)) || a.source.category == "resist")
				{