EA 23.302 Nightly โ
May 4, 2026
22 files modified. 2 new files created.
Important Changes โ
Possible breaking changes. Click the filename to view the chunk.
ConBaseTransmuteMimic (1) โ
public virtual void RevealMimicry(Card c, bool surprise)
public override void Reveal(Card attacker = null, bool surprise = false) ConPeaky (1) โ
public void OnHit()
public override void OnHit(Card attacker, AttackSource source) AI_Fish โ
public override IEnumerable<Status> Run()
yield return Restart();
}
yield return DoWait(2);
if (owner != null)
if (owner != null && !owner.IsPC)
{
if (!owner.IsPC)
{
owner.TryPickGroundItem((Card t) => t.category.IsChildOf("fish") || t.SelfWeight <= 1000);
}
if (owner.IsPCFaction && !owner.IsPCParty)
{
owner.ClearInventory(ClearInventoryType.Purge);
}
owner.TryPickGroundItem((Card t) => t.category.IsChildOf("fish") || t.SelfWeight <= 1000);
owner.TryClearInventory();
}
yield return Success();
}AI_Idle โ
public override IEnumerable<Status> Run()
}
if (thing != null)
{
if (owner.IsPCParty)
{
owner.TryClearInventory();
}
if (EClass._zone.IsRegion)
{
owner.InstantEat(thing, sound: false);public override IEnumerable<Status> Run()
c.pos.TryWitnessCrime(owner, c);
if (owner.mimicry != null)
{
owner.mimicry.RevealMimicry(c, surprise: true);
owner.mimicry.Reveal(c, surprise: true);
}
});
}
}
if (owner.mimicry != null && owner.HasElement(1429))
{
owner.mimicry.Reveal();
}
Party party = owner.party;
if (party == null || party.leader == owner || !party.leader.IsAliveInCurrentZone || owner.host != null || !EClass._zone.PetFollow)
{AI_OpenLock โ
public class AI_OpenLock : AI_TargetThing
public override bool CanTargetInventory => true;
public override bool IsHostileAct
{
get
{
if (base.target != null)
{
return base.target.isNPCProperty;
}
return false;
}
}
public override AIProgress CreateProgress()
{
return new Progress_Custom+AI_PryOpen โ
File Created
public class AI_PryOpen : AI_TargetThing
{
public override CursorInfo CursorIcon => CursorSystem.Container;
public override bool HasProgress => true;
public override bool IsHostileAct
{
get
{
if (base.target != null)
{
return base.target.isNPCProperty;
}
return false;
}
}
public override bool CanManualCancel()
{
return true;
}
public override AIProgress CreateProgress()
{
return new Progress_Custom
{
canProgress = CanProgress,
onProgressBegin = delegate
{
owner.Say("pry_start", owner, base.target);
},
onProgress = delegate(Progress_Custom p)
{
owner.PlaySound("lock_pry");
if (p.progress >= 3 && base.target.trait.TryPryOpenLock(owner, msgFail: false) == LockOpenState.Success)
{
p.CompleteProgress();
}
},
onProgressComplete = delegate
{
}
}.SetDuration(100, 10);
}
public override void OnCancelOrSuccess()
{
if (owner != null && !base.target.isDestroyed && base.target.c_lockLv != 0)
{
owner.Say("pry_end", owner, base.target);
}
EClass.Sound.Stop("lock_pry");
}
}ActThrow โ
public static EffectIRenderer Throw(Card c, Point p, Card target, Thing t, Throw
}
if (Act.TC?.Chara?.mimicry != null && Act.TC.Chara.mimicry.ShouldRevealOnContact)
{
Act.TC.Chara.mimicry.RevealMimicry(c, surprise: false);
Act.TC.Chara.mimicry.Reveal(c);
}
bool flag = method == ThrowMethod.Reward;
bool flag2 = method == ThrowMethod.Default;BaseCondition โ
public virtual void OnStartOrStack()
{
}
public virtual void OnHit(Card attacker, AttackSource source)
{
}
public virtual void PlayEffect()
{
if (!Condition.ignoreEffect && base.source.effect.Length != 0)Card โ
public void DamageHP(long dmg, int ele, int eleP = 100, AttackSource attackSourc
onEvade?.Invoke();
if (isChara)
{
if (Chara.mimicry != null && Chara.mimicry.ShouldRevealOnDamage)
for (int num15 = Chara.conditions.Count - 1; num15 >= 0; num15--)
{
Chara.mimicry.RevealMimicry(origin, surprise: false);
Chara.conditions[num15].OnHit(origin, attackSource);
}
foreach (Condition condition4 in Chara.conditions)
if (Chara.mimicry == null && HasElement(1429))
{
(condition4 as ConPeaky)?.OnHit();
Chara.AddCondition<ConTransmuteHuman>();
}
if (flag2)
{public void DamageHP(long dmg, int ele, int eleP = 100, AttackSource attackSourc
}
if (attackSource == AttackSource.Melee || attackSource == AttackSource.Range)
{
int num15 = origin.Dist(this);
if (attackSource == AttackSource.Melee && HasElement(1221) && num15 <= Evalue(1221))
int num16 = origin.Dist(this);
if (attackSource == AttackSource.Melee && HasElement(1221) && num16 <= Evalue(1221))
{
int ele2 = ((Chara.MainElement == Element.Void) ? 924 : Chara.MainElement.id);
if (id == "hedgehog_ether")public void DamageHP(long dmg, int ele, int eleP = 100, AttackSource attackSourc
Say("reflect_thorne", origin, this);
origin.DamageHP((int)Mathf.Clamp(dmg / 10, 1f, MaxHP / (origin.IsPowerful ? 200 : 20)), ele2, Power, AttackSource.Condition, this);
}
if (HasElement(1223) && num15 <= Evalue(1223))
if (HasElement(1223) && num16 <= Evalue(1223))
{
int ele3 = ((Chara.MainElement == Element.Void) ? 923 : Chara.MainElement.id);
Say("reflect_acid", this, origin);public void DamageHP(long dmg, int ele, int eleP = 100, AttackSource attackSourc
}
}
}
int num16 = ((EClass.rnd(2) == 0) ? 1 : 0);
int num17 = ((EClass.rnd(2) == 0) ? 1 : 0);
if (attackSource == AttackSource.Condition)
{
num16 = 1 + EClass.rnd(2);
num17 = 1 + EClass.rnd(2);
}
if (num16 > 0)
if (num17 > 0)
{
bool flag3 = Chara.HasCondition<ConPoison>() || ((e.id == 915 || e.id == 923) && ResistLv(Evalue(955)) < 4);
AddBlood(num16, flag3 ? 6 : (-1));
AddBlood(num17, flag3 ? 6 : (-1));
}
if (dmg > 0 || (origin != null && origin.HasElement(1345)))
{public void DamageHP(long dmg, int ele, int eleP = 100, AttackSource attackSourc
}
if (IsPC)
{
float num17 = (float)hp / (float)MaxHP;
float num18 = (float)hp / (float)MaxHP;
if (Evalue(1421) > 0)
{
num17 = (float)Chara.mana.value / (float)Chara.mana.max;
num18 = (float)Chara.mana.value / (float)Chara.mana.max;
}
if (num17 < 0.3f)
if (num18 < 0.3f)
{
PlaySound("heartbeat", 1f - num17 * 2f);
PlaySound("heartbeat", 1f - num18 * 2f);
}
}
if (!IsPC && hp < MaxHP / 5 && Evalue(423) <= 0 && dmg * 100 / MaxHP + 10 > EClass.rnd(IsPowerful ? 400 : 150) && !HasCondition<ConFear>()) {
if (origin != null && origin.isChara && isChara && (weapon == null || !weapon.HasElement(486)))
{
int num18 = origin.Evalue(662) + (weapon?.Evalue(662, ignoreGlobalElement: true) ?? 0);
int num19 = origin.Evalue(661) + (weapon?.Evalue(661, ignoreGlobalElement: true) ?? 0);
if (num18 != 0)
int num19 = origin.Evalue(662) + (weapon?.Evalue(662, ignoreGlobalElement: true) ?? 0);
int num20 = origin.Evalue(661) + (weapon?.Evalue(661, ignoreGlobalElement: true) ?? 0);
if (num19 != 0)
{
Debug.Log(num18);
Debug.Log(num19);
}
if (num18 > 0 && attackSource == AttackSource.Melee && origin.isChara && !origin.Chara.ignoreSPAbsorb && Chara.IsHostile(origin as Chara))
if (num19 > 0 && attackSource == AttackSource.Melee && origin.isChara && !origin.Chara.ignoreSPAbsorb && Chara.IsHostile(origin as Chara))
{
int num20 = EClass.rnd(3 + (int)Mathf.Clamp(dmg / 100, 0f, num18 / 10));
origin.Chara.stamina.Mod(num20);
int num21 = EClass.rnd(3 + (int)Mathf.Clamp(dmg / 100, 0f, num19 / 10));
origin.Chara.stamina.Mod(num21);
if (IsAliveInCurrentZone)
{
Chara.stamina.Mod(-num20);
Chara.stamina.Mod(-num21);
}
}
if (origin.HasElement(1350) && attackSource == AttackSource.Melee)
{
int num21 = EClass.rndHalf(2 + (int)Mathf.Clamp(dmg / 10, 0f, origin.Chara.GetPietyValue() + 10));
origin.Chara.mana.Mod(num21);
int num22 = EClass.rndHalf(2 + (int)Mathf.Clamp(dmg / 10, 0f, origin.Chara.GetPietyValue() + 10));
origin.Chara.mana.Mod(num22);
if (IsAliveInCurrentZone)
{
Chara.mana.Mod(-num21);
Chara.mana.Mod(-num22);
}
}
if (num19 > 0 && attackSource == AttackSource.Melee)
if (num20 > 0 && attackSource == AttackSource.Melee)
{
int num22 = EClass.rnd(2 + (int)Mathf.Clamp(dmg / 10, 0f, num19 + 10));
origin.Chara.mana.Mod(num22);
int num23 = EClass.rnd(2 + (int)Mathf.Clamp(dmg / 10, 0f, num20 + 10));
origin.Chara.mana.Mod(num23);
if (IsAliveInCurrentZone)
{
Chara.mana.Mod(-num22);
Chara.mana.Mod(-num23);
}
}
}public void Kick(Chara t, bool ignoreSelf = false, bool karmaLoss = true, bool s
t.PlayEffect("kick");
if (t.mimicry != null && t.mimicry.ShouldRevealOnContact)
{
t.mimicry.RevealMimicry(this, surprise: false);
t.mimicry.Reveal(this);
}
}Chara โ
public override MoveResult _Move(Point newPoint, MoveType type = MoveType.Walk)
{
if (item.mimicry.ShouldRevealOnPush)
{
item.mimicry.RevealMimicry(this, surprise: true);
item.mimicry.Reveal(this, surprise: true);
}
return MoveResult.Event;
}public void RestockEquip(bool onCreate)
AddThing("bow_vindale");
}
break;
case "unseenhand":
if (onCreate)
{
EQ_ID("martial_ring");
}
break;
case "larnneire":
if (onCreate)
{public void GiveGift(Chara c, Thing t)
c.nextUse = null;
}
}
if (c.IsPCParty)
{
c.TryClearInventory();
}
}
public void OnGiveErohon(Thing t)public bool ShouldThrowAway(Thing t, ClearInventoryType type)
switch (type)
{
case ClearInventoryType.SellAtTown:
if (!t.isGifted && !t.isNPCProperty)
switch (t.category.id)
{
return false;
default:
if (!t.isGifted && !t.isNPCProperty)
{
return false;
}
break;
case "fish":
case "junk":
case "garbage":
break;
}
break;
case ClearInventoryType.Purge:public bool ShouldThrowAway(Thing t, ClearInventoryType type)
return true;
}
public void TryClearInventory()
{
if (IsPC)
{
return;
}
if (IsPCParty)
{
if (!things.IsAlmostFull())
{
return;
}
bool flag = EClass._zone.IsTown;
if (!flag && EClass._zone.IsPCFactionOrTent)
{
foreach (Chara chara in EClass._map.charas)
{
if (chara.IsPCFaction && chara.trait.ShopType != 0)
{
flag = true;
}
}
}
if (flag)
{
ClearInventory(ClearInventoryType.SellAtTown);
}
}
else
{
ClearInventory(ClearInventoryType.Purge);
}
}
public void ClearInventory(ClearInventoryType type)
{
int num = 0;ConBaseTransmuteMimic โ
public class ConBaseTransmuteMimic : ConTransmute
public override bool HasDuration => false;
public virtual bool ShouldRevealOnContact => true;
public virtual bool ShouldRevealOnPush => true;
public virtual bool ShouldRevealOnDamage => true;
public virtual bool IsThing => Card.isThing;
public virtual bool IsChara => Card.isChara;
public override bool ShouldRevealOnDamage => true;
public override void SetOwner(Chara _owner, bool onDeserialize = false)
{
base.SetOwner(_owner);public override void OnRemoved()
base.OnRemoved();
}
public virtual void RevealMimicry(Card c, bool surprise)
public override void Reveal(Card attacker = null, bool surprise = false)
{
if (c != null && owner.IsHostile(c.Chara))
if (attacker is Chara && owner.IsHostile(attacker.Chara))
{
owner.DoHostileAction(c, immediate: true);
owner.DoHostileAction(attacker, immediate: true);
}
if (surprise)
{
owner.AddCondition<ConAmbush>();
}
Kill();
base.Reveal(attacker, surprise);
}
public virtual string GetName(NameStyle style, int num = -1)ConPeaky โ
}
}
public void OnHit()
public override void OnHit(Card attacker, AttackSource source)
{
ec.SetBase(79, ec.Value(79) / 2);
}ConTransmute โ
public class ConTransmute : BaseBuff
public override bool ShouldTryNullify => true;
public virtual bool ShouldRevealOnContact => true;
public virtual bool ShouldRevealOnPush => true;
public virtual bool ShouldRevealOnDamage => false;
public override void Tick()
{
if (HasDuration && owner.host == null && owner.conSleep == null && (EClass.pc.conSleep == null || EClass.pc.conSleep.pcSleep == 0))public override void OnStart()
Change();
}
public override void OnHit(Card attacker, AttackSource source)
{
if (ShouldRevealOnDamage)
{
Reveal(attacker);
}
}
public void Change()
{
if (owner.ai is GoalCombat { abilities: not null } goalCombat)
{
goalCombat.BuildAbilityList();
}
owner._CreateRenderer();
if (owner.IsPCParty)
{public override bool TryNullify(Condition c)
}
return false;
}
public virtual void Reveal(Card attacker = null, bool surprise = false)
{
Kill();
}
}ConTransmuteHuman โ
public class ConTransmuteHuman : ConBaseTransmuteMimic
public bool IsBaby => chara.HasElement(1232);
public bool IsNyaru => owner?.id == "nyaruruga";
public bool IsNyaru => owner.HasElement(1429);
public override bool HasDuration => false;public override void OnBeforeStart()
public void NyaruSpecial()
{
IEnumerable<SourceChara.Row> ie = EClass.sources.charas.rows.Where((SourceChara.Row a) => !a.multisize && !a.actCombat.IsEmpty() && !a.HasTag(CTAG.suicide) && !a.HasTag(CTAG.noRandomProduct));
chara = CharaGen.Create(ie.RandomItem().id);
if (chara != null && chara.id != owner.id)
{
chara = CharaGen.Create(owner.id);
}
else
{
IEnumerable<SourceChara.Row> ie = EClass.sources.charas.rows.Where((SourceChara.Row a) => !a.multisize && !a.actCombat.IsEmpty() && !a.HasTag(CTAG.suicide) && !a.HasTag(CTAG.noRandomProduct));
chara = CharaGen.Create(ie.RandomItem().id);
}
lastHP = owner.hp;
owner.PlayEffect("morph");
owner.PlaySound("vanish");
}
public override void Tick()ConTransmuteMimic โ
public override void TrySetAct(ActPlan p)
{
p.TrySetAct("actContainer", delegate
{
RevealMimicry(EClass.pc, surprise: true);
Reveal(EClass.pc, surprise: true);
return true;
}, owner, CursorSystem.Container);
}CoreConfig โ
public bool extraRace;
public bool allRace;
public bool unsealWidgets;
public bool extraMoveCancel;GoalAutoCombat โ
public void GetAbilities(Func<Element, bool> func)
public override void BuildAbilityList()
{
GetAbilities((Element e) => e.source.abilityType.Length != 0);
base.BuildAbilityList();
GetAbilities((Element e) => e.source.abilityType.Length != 0);
}
public override bool TryAbortCombat()GoalCombat โ
public virtual void BuildAbilityList()
{
abilities.Clear();
foreach (ActList.Item item in owner.ability.list.items)
{
AddAbility(item.act, 0, item.chance, item.pt);HotItemNoItem โ
public static bool _TrySetAct(ActPlan p)
{
if (tg.isChara && tg.Chara.mimicry != null && !tg.IsPCParty)
{
tg.Chara.mimicry.RevealMimicry(EClass.pc, surprise: true);
tg.Chara.mimicry.Reveal(EClass.pc, surprise: true);
return true;
}
if (!EClass.pc.CanLift(tg))SurvivalManager โ
Point pos2 = point.GetNearestPoint(allowBlock: false, allowChara: false, allowInstalled: false, ignoreCenter: true) ?? point;
if (searchWreck2 == 20)
{
Thing container = ThingGen.CreateParcel(null, ThingGen.CreateRecipe("container_shipping"), ThingGen.CreateRecipe("stonecutter"), ThingGen.CreateRecipe("workbench2"));
Thing container = ThingGen.CreateParcel(null, ThingGen.CreateRecipe("container_shipping"), ThingGen.CreateRecipe("stonecutter"), ThingGen.CreateRecipe("workbench2"), ThingGen.Create("crystal_earth").SetNum(3));
Meteor(pos2, delegate
{
EClass._zone.AddCard(container, pos2);ThingContainer โ
}
}
public bool IsAlmostFull(int threshold = 2)
{
return base.Count + threshold >= GridSize;
}
public bool IsFull(int y = 0)
{
if (IsMagicChest)Trait โ
public virtual LockOpenState TryOpenLock(Chara cc, bool msgFail = true)
num3 *= 10;
}
cc.ModExp(280, num3);
owner.c_lockLv = 0;
if (owner.c_lockedHard)
{
owner.c_lockedHard = false;
owner.c_priceAdd = 0;
}
if (cc.IsPC && owner.isLostProperty)
{
EClass.player.ModKarma(-8);
}
owner.isLostProperty = false;
if (owner.GetBool(127))
{
Steam.GetAchievement(ID_Achievement.FIAMA_CHEST);
}
OnLockOpen(cc);
return LockOpenState.Success;
}
cc.PlaySound("lock");public virtual LockOpenState TryOpenLock(Chara cc, bool msgFail = true)
return LockOpenState.Fail;
}
public virtual LockOpenState TryPryOpenLock(Chara cc, bool msgFail = true)
{
Thing tool = cc.Tool;
cc.stamina.Mod(-1);
Point pos = owner.GetRootCard().pos;
SourceMaterial.Row material = owner.material;
material.PlayHitEffect(pos);
material.AddBlood(pos);
if (!cc.IsAliveInCurrentZone || tool == null)
{
return LockOpenState.Fail;
}
cc.ModExp(280, 20);
cc.ModExp(70, 30);
int a2 = Mathf.Clamp(20 * tool.material.hardness / material.hardness, 10, 150);
owner.hp -= EClass.rnd(a2);
int num = (int)Mathf.Clamp(20L * (long)(owner.c_lockLv + 20) / cc.STR, 5f, 50f);
if (owner.c_lockedHard)
{
num = num * 3 / 2;
}
if (EClass.rnd(100) < num)
{
DamageRandomProperty(cc);
}
if (owner.hp < 0)
{
cc.Say("pry_success", cc, owner);
if (owner.trait is TraitChestPractice)
{
cc.PlaySound("lock_open");
}
OnLockOpen(cc);
foreach (Thing item in owner.things.List((Thing a) => a.Num > 10))
{
item.SetNum(item.Num / 10 * 9);
}
if (!(owner.trait is TraitChestPractice))
{
if (owner.isNPCProperty && cc.IsPC)
{
EClass.player.ModKarma(-1);
}
owner.Die();
}
return LockOpenState.Success;
}
return LockOpenState.Fail;
}
public void DamageRandomProperty(Chara cc)
{
Thing thing = owner.things.List((Thing a) => true).RandomItem();
if (thing != null)
{
if (thing.Num > 10)
{
thing.SetNum(thing.Num / 10 * 9);
}
else if (thing.Num > 1)
{
thing.SetNum(thing.Num - 1);
}
else
{
thing.Destroy();
}
cc.Say("pry_damage", cc, thing);
}
}
public virtual void OnLockOpen(Chara cc)
{
owner.c_lockLv = 0;
if (owner.c_lockedHard)
{
owner.c_lockedHard = false;
owner.c_priceAdd = 0;
}
if (cc.IsPC && owner.isLostProperty)
{
EClass.player.ModKarma(-8);
}
owner.isLostProperty = false;
if (owner.GetBool(127))
{
Steam.GetAchievement(ID_Achievement.FIAMA_CHEST);
}
}
public virtual void WriteNote(UINote n, bool identified)
{
}TraitChestPractice โ
public override void OnSimulateHour(VirtualDate date)
}
}
owner.c_lockLv = owner.LV;
owner.hp = 100;
}
}+TraitToolCrowbar โ
File Created
public class TraitToolCrowbar : TraitTool
{
public override void TrySetHeldAct(ActPlan p)
{
p.pos.Things.ForEach(delegate(Thing t)
{
if (!t.isMasked && !t.isHidden && t.IsContainer && (t.c_lockLv > 0 || t.isNPCProperty))
{
p.TrySetAct(new AI_PryOpen
{
target = t
}, t);
}
});
}
}TraitToolHammerStrip โ
public override void TrySetHeldAct(ActPlan p)
t.PlayEffect("buff");
t.SetEncLv(0);
return false;
});
}, t);
}
});
}TraitWhipEgg โ
public override void TrySetHeldAct(ActPlan p)
EClass.player.ModKarma(-1);
if (c.isChara && c.Chara.mimicry != null)
{
c.Chara.mimicry.RevealMimicry(EClass.pc, surprise: false);
c.Chara.mimicry.Reveal(EClass.pc);
}
return true;
}, c);