Skip to content

EA 23.89 Nightly Patch 1

February 9, 2025

10 files modified.

Important Changes

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

Card (1)

cs
public void DamageHP(int dmg, int ele, int eleP = 100, AttackSource attackSource = AttackSource.None, Card origin = null, bool showEffect = true) 
public void DamageHP(int dmg, int ele, int eleP = 100, AttackSource attackSource = AttackSource.None, Card origin = null, bool showEffect = true, Thing weapon = null) 

AttackProcess

@@ -604,7 +604,7 @@ public bool Perform(int count, bool hasHit, float dmgMulti = 1f, bool maxRoll =

cs
	int num9 = num * penetration / 100;
	num -= num9;
	num = TC.ApplyProtection(num) + num9 + num8;
	TC.DamageHP(num, num4, num5, (!IsRanged && !isThrow) ? AttackSource.Melee : AttackSource.Range, CC, showEffect); 
	TC.DamageHP(num, num4, num5, (!IsRanged && !isThrow) ? AttackSource.Melee : AttackSource.Range, CC, showEffect, weapon); 
	conWeapon?.Mod(-1);
	bool flag2 = IsCane || (weapon != null && weapon.Evalue(482) > 0);
	int attackStyleElement = CC.body.GetAttackStyleElement(attackStyle);

Card

@@ -3708,7 +3708,7 @@ public void DamageHP(int dmg, AttackSource attackSource = AttackSource.None, Car

cs
		DamageHP(dmg, 0, 0, attackSource, origin);
	}

	public void DamageHP(int dmg, int ele, int eleP = 100, AttackSource attackSource = AttackSource.None, Card origin = null, bool showEffect = true) 
	public void DamageHP(int dmg, int ele, int eleP = 100, AttackSource attackSource = AttackSource.None, Card origin = null, bool showEffect = true, Thing weapon = null) 
	{
		if (hp < 0)
		{

@@ -3966,7 +3966,7 @@ public void DamageHP(int dmg, int ele, int eleP = 100, AttackSource attackSource

cs
					if (EClass.player.invlunerable)
					{
						EvadeDeath();
						goto IL_0a86; 
						goto IL_0a8e; 
					}
				}
				if (IsPC && Evalue(1220) > 0 && Chara.stamina.value >= Chara.stamina.max / 2)

@@ -3978,8 +3978,8 @@ public void DamageHP(int dmg, int ele, int eleP = 100, AttackSource attackSource

cs
			}
		}
	}
	goto IL_0a86; 
	IL_0a86: 
	goto IL_0a8e; 
	IL_0a8e: 
	if (trait.CanBeAttacked)
	{
		renderer.PlayAnime(AnimeID.HitObj);

@@ -4404,9 +4404,11 @@ void ProcAbsorb()

cs
	{
		if (origin != null && origin.isChara && isChara)
		{
			if (origin.HasElement(662) && attackSource == AttackSource.Melee && origin.isChara && Chara.IsHostile(origin as Chara)) 
			int valueOrDefault = (origin.Evalue(662) + weapon?.Evalue(662, ignoreGlobalElement: true)).GetValueOrDefault(); 
			int valueOrDefault2 = (origin.Evalue(661) + weapon?.Evalue(661, ignoreGlobalElement: true)).GetValueOrDefault(); 
			if (valueOrDefault > 0 && attackSource == AttackSource.Melee && origin.isChara && Chara.IsHostile(origin as Chara)) 
			{
				int num11 = EClass.rnd(3 + Mathf.Clamp(dmg / 100, 0, origin.Evalue(662) / 10)); 
				int num11 = EClass.rnd(3 + Mathf.Clamp(dmg / 100, 0, valueOrDefault / 10)); 
				origin.Chara.stamina.Mod(num11);
				if (IsAliveInCurrentZone)
				{

@@ -4422,9 +4424,9 @@ void ProcAbsorb()

cs
					Chara.mana.Mod(-num12);
				}
			}
			if (origin.HasElement(661) && attackSource == AttackSource.Melee) 
			if (valueOrDefault2 > 0 && attackSource == AttackSource.Melee) 
			{
				int num13 = EClass.rnd(2 + Mathf.Clamp(dmg / 10, 0, origin.Evalue(661) + 10)); 
				int num13 = EClass.rnd(2 + Mathf.Clamp(dmg / 10, 0, valueOrDefault2 + 10)); 
				origin.Chara.mana.Mod(num13);
				if (IsAliveInCurrentZone)
				{

Chara

@@ -5431,7 +5431,6 @@ void ForeachEnemy(Action<Chara> action)

cs
		{
			action(_pts[num9]);
		}
		Debug.Log(_pts.Count); 
	}
	void ForeachParty(Action<Chara> action)
	{

CharaBody

@@ -409,10 +409,6 @@ public int GetAttackIndex(Thing t)

cs

	public int GetMeleeDistance()
	{
		if (owner.Evalue(666) == 0) 
		{ 
			return 1; 
		} 
		int num = 0;
		foreach (BodySlot slot in slots)
		{

GoalCombat

@@ -845,7 +845,29 @@ int HealFactor(Chara c)

cs
			continue;
		}
		Cost cost = ability2.act.GetCost(owner);
		if ((owner.IsPCParty && ability2.pt && !ability2.act.IsTargetHostileParty() && !ability2.act.TargetType.ForceParty && cost.cost * EClass.pc.party.members.Count > owner.mana.value) || (cost.cost > 0 && EClass.rnd(100) > tactics.AbilityChance)) 
		if (owner.IsPCParty && ability2.pt && !ability2.act.IsTargetHostileParty() && !ability2.act.TargetType.ForceParty && cost.cost * EClass.pc.party.members.Count > owner.mana.value) 
		{ 
			continue; 
		} 
		if (isPCFaction && cost.cost > 0) 
		{ 
			switch (cost.type) 
			{ 
			case CostType.MP: 
				if (cost.cost > owner.mana.value) 
				{ 
					continue; 
				} 
				break; 
			case CostType.SP: 
				if (cost.cost > owner.stamina.value) 
				{ 
					continue; 
				} 
				break; 
			} 
		} 
		if (cost.cost > 0 && EClass.rnd(100) > tactics.AbilityChance) 
		{
			continue;
		}

LayerCraft

@@ -433,38 +433,10 @@ public void RefreshRecipe(bool first)

cs

	public void RefreshTrackButton()
	{
		QuestTrackCraft quest = null; 
		foreach (Quest item in ELayer.game.quests.list) 
		{ 
			if (item is QuestTrackCraft) 
			{ 
				quest = item as QuestTrackCraft; 
				break; 
			} 
		} 
		QuestTrackCraft quest = recipe.GetQuestTrack(); 
		buttonTrack.SetOnClick(delegate
		{
			if (quest != null && quest.idRecipe == recipe.id) 
			{ 
				ELayer.game.quests.Remove(quest); 
			} 
			else
			{ 
				if (quest != null) 
				{ 
					ELayer.game.quests.Remove(quest); 
				} 
				QuestTrackCraft questTrackCraft = Quest.Create("track_craft") as QuestTrackCraft; 
				questTrackCraft.SetRecipe(recipe); 
				ELayer.game.quests.Start(questTrackCraft); 
			} 
			if (!WidgetQuestTracker.Instance) 
			{ 
				ELayer.player.questTracker = true; 
				ELayer.ui.widgets.ActivateWidget("QuestTracker"); 
				WidgetHotbar.RefreshButtons(); 
			} 
			WidgetQuestTracker.Instance.Refresh(); 
			recipe.ToggleTrack(quest); 
			RefreshTrackButton();
		});
		buttonTrack.icon.SetActive(quest != null && quest.idRecipe == recipe.id);

QuestTrackCraft

@@ -17,7 +17,7 @@ public class QuestTrackCraft : Quest

cs

	public override string GetTitle()
	{
		return "trackCraft_title".lang(recipe.Name); 
		return "trackCraft_title".lang(recipe.Name, recipe.NameFactory); 
	}

	public void SetRecipe(Recipe r)

Recipe

@@ -982,4 +982,43 @@ public void SaveLastIngredients()

cs
		}
		EClass.player.recipes.lastIngredients[id] = list;
	}

	public QuestTrackCraft GetQuestTrack() 
	{ 
		QuestTrackCraft result = null; 
		foreach (Quest item in EClass.game.quests.list) 
		{ 
			if (item is QuestTrackCraft) 
			{ 
				result = item as QuestTrackCraft; 
				break; 
			} 
		} 
		return result; 
	} 

	public void ToggleTrack(QuestTrackCraft quest) 
	{ 
		if (quest != null && quest.idRecipe == id) 
		{ 
			EClass.game.quests.Remove(quest); 
		} 
		else
		{ 
			if (quest != null) 
			{ 
				EClass.game.quests.Remove(quest); 
			} 
			QuestTrackCraft questTrackCraft = Quest.Create("track_craft") as QuestTrackCraft; 
			questTrackCraft.SetRecipe(this); 
			EClass.game.quests.Start(questTrackCraft); 
		} 
		if (!WidgetQuestTracker.Instance) 
		{ 
			EClass.player.questTracker = true; 
			EClass.ui.widgets.ActivateWidget("QuestTracker"); 
			WidgetHotbar.RefreshButtons(); 
		} 
		WidgetQuestTracker.Instance.Refresh(); 
	} 
}

RecipeSource

@@ -69,7 +69,17 @@ public bool NeedFactory

cs
		}
	}

	public string NameFactory => EClass.sources.cards.map[idFactory].GetName(); 
	public string NameFactory 
	{ 
		get 
		{ 
			if (!NeedFactory) 
			{ 
				return EClass.sources.elements.map[6012].GetName(); 
			} 
			return EClass.sources.cards.map[idFactory].GetName(); 
		} 
	} 

	public string idFactory
	{

WidgetCodex

@@ -87,8 +87,10 @@ public virtual void RefreshList()

cs
{
	list.callbacks = new UIList.Callback<Recipe, ButtonGrid>
	{
		onClick = delegate
		onClick = delegate(Recipe a, ButtonGrid b) 
		{
			SE.ClickGeneral(); 
			a.ToggleTrack(a.GetQuestTrack()); 
		},
		onRedraw = delegate(Recipe a, ButtonGrid b, int i)
		{