EA 23.121 Nightly
April 7, 2025
18 files modified. 4 new files created.
Important Changes
Possible breaking changes. Click the filename to view the chunk.
CharaAbility (1)
public void BuildRandomAbilityList()
TraitPotionRandom (1)
public override void OnCreate(int lv)
AM_FlagCell
@@ -111,13 +111,14 @@ public override void OnClickSubMenu(int a)
public override string OnSetSubMenuButton(int a, UIButton b)
{
if (a >= 3 && !EClass.debug.enable)
{
return null;
}
if (a < 5)
{
return a.ToEnum<Mode>().ToString();
Mode mode = a.ToEnum<Mode>();
if (a >= 3 && mode != Mode.flagShadow)
{
return null;
}
return mode.ToString();
}
return null;
}
ActEffect
break;
}
Thing thing6 = null;
bool flag8 = actRef.n1 == "food";
bool flag7 = actRef.n1 == "food";
if (actRef.n1 == "money")
{
int currency = TC.GetCurrency();
else
{
Func<Thing, bool> func = (Thing t) => true;
if (flag8)
if (flag7)
{
func = (Thing t) => t.IsFood;
}
{
EClass.game.religions.Trickery.Talk("ability");
bool hex2 = CC.IsHostile(TC);
List<SourceStat.Row> list5 = EClass.sources.stats.rows.Where((SourceStat.Row con) => con.tag.Contains("random") && con.group == (hex2 ? "Debuff" : "Buff")).ToList();
List<SourceStat.Row> list4 = EClass.sources.stats.rows.Where((SourceStat.Row con) => con.tag.Contains("random") && con.group == (hex2 ? "Debuff" : "Buff")).ToList();
int power2 = power;
for (int k = 0; k < 4 + EClass.rnd(2); k++)
{
SourceStat.Row row2 = list5.RandomItem();
list5.Remove(row2);
SourceStat.Row row2 = list4.RandomItem();
list4.Remove(row2);
Proc(hex2 ? EffectId.Debuff : EffectId.Buff, CC, TC, power2, new ActRef
{
n1 = row2.alias
power = power * 2 / 3;
}
int a2 = power;
int num9 = TC.WIL * (isPowerful ? 20 : 5);
int num8 = TC.WIL * (isPowerful ? 20 : 5);
ConHolyVeil condition3 = TC.GetCondition<ConHolyVeil>();
if (condition3 != null)
{
num9 += condition3.power * 5;
num8 += condition3.power * 5;
}
if (EClass.rnd(a2) < num9 / EClass.sources.stats.alias[n].hexPower && EClass.rnd(10) != 0)
if (EClass.rnd(a2) < num8 / EClass.sources.stats.alias[n].hexPower && EClass.rnd(10) != 0)
{
TC.Say("debuff_resist", TC);
CC.DoHostileAction(TC);
case EffectId.DamageMindGreat:
case EffectId.Weaken:
{
bool flag7 = id == EffectId.DamageBody || id == EffectId.DamageBodyGreat;
bool flag8 = id == EffectId.DamageBody || id == EffectId.DamageBodyGreat;
bool mind = id == EffectId.DamageMind || id == EffectId.DamageMindGreat;
int num6 = ((id == EffectId.DamageBody || id == EffectId.DamageMind) ? 1 : (4 + EClass.rnd(4)));
if (id == EffectId.Weaken)
{
flag7 = EClass.rnd(2) == 0;
mind = !flag7;
flag8 = EClass.rnd(2) == 0;
mind = !flag8;
num6 = 1;
}
else
TC.PlayEffect("debuff");
TC.PlaySound("debuff");
}
TC.Say(flag7 ? "damageBody" : "damageMind", TC);
TC.Say(flag8 ? "damageBody" : "damageMind", TC);
for (int l = 0; l < num6; l++)
{
TC.DamageTempElements(power, flag7, mind);
TC.DamageTempElements(power, flag8, mind);
}
if (TC.IsPC)
{
break;
}
case EffectId.HealComplete:
Dice.Create("SpHealLight", power, CC, (actRef.refThing != null) ? null : actRef.act);
TC.HealHPHost(9999, (actRef.refThing == null) ? HealSource.Magic : HealSource.Item);
TC.CureHost(CureType.HealComplete, power, state);
TC.Say("heal_heavy", TC);
{
Debug.Log(actRef.act.id);
}
int num8 = Dice.Create((actRef.act != null && EClass.sources.calc.map.ContainsKey(actRef.act.ID)) ? actRef.act.ID : "SpHealLight", power, CC, (actRef.refThing != null) ? null : actRef.act).Roll();
int num9 = Dice.Create((actRef.act != null && EClass.sources.calc.map.ContainsKey(actRef.act.ID)) ? actRef.act.ID : "SpHealLight", power, CC, (actRef.refThing != null) ? null : actRef.act).Roll();
if (actRef.refThing != null)
{
num9 = num9 * (100 + actRef.refThing.Evalue(7500)) / 100;
}
if (flag)
{
TC.DamageHP(num8 / 2, 919, power);
TC.DamageHP(num9 / 2, 919, power);
break;
}
TC.HealHPHost(num8, (actRef.refThing == null) ? HealSource.Magic : HealSource.Item);
TC.HealHPHost(num9, (actRef.refThing == null) ? HealSource.Magic : HealSource.Item);
TC.CureHost(CureType.Heal, power, state);
TC.Say((power >= 300) ? "heal_heavy" : "heal_light", TC);
break;
{
power /= 4;
}
List<Thing> list4 = TC.things.List((Thing t) => (t.Num <= 1 && t.IsEquipmentOrRanged && !t.IsToolbelt && !t.IsLightsource && t.isEquipped) ? true : false);
if (list4.Count != 0)
List<Thing> list5 = TC.things.List((Thing t) => (t.Num <= 1 && t.IsEquipmentOrRanged && !t.IsToolbelt && !t.IsLightsource && t.isEquipped) ? true : false);
if (list5.Count != 0)
{
Thing thing5 = list4.RandomItem();
Thing thing5 = list5.RandomItem();
TC.Say("acid_hit", TC);
if (thing5.isAcidproof)
{
ActPlan
@@ -96,6 +96,7 @@ public bool Perform(bool repeated = false)
AIAct aIAct = act as AIAct;
if (act.IsAct)
{
Act.CC = EClass.pc;
if (act.PerformDistance != -1 && (num > act.PerformDistance || (num == 1 && !flag)))
{
cc.SetAIImmediate(new DynamicAIAct(act.GetText(), () => act.Perform(cc, tc, pos))
ActPray
@@ -26,25 +26,26 @@ public static bool TryPray(Chara c, bool passive = false)
if (c.faith.IsEyth)
{
c.Say("pray", c);
if (passive)
if (passive && c.Evalue(1655) >= 2 && EClass.pc.party.members.Count > 1)
{
if (c.Evalue(1655) >= 2 && EClass.pc.party.members.Count > 1)
foreach (Chara member in EClass.pc.party.members)
{
foreach (Chara member in EClass.pc.party.members)
if (member != EClass.pc)
{
if (member != EClass.pc)
{
member.Say("pray2", member, member.faith.Name);
member.ModExp(306, 200);
}
member.Say("pray2", member, member.faith.Name);
member.ModExp(306, 200);
}
}
}
else
if (EClass.player.prayed)
{
c.PlaySound("pray_ignore");
}
c.ModExp(306, 100);
else
{
EClass.player.prayed = true;
c.ModExp(306, 100);
}
return true;
}
foreach (Chara member2 in EClass.pc.party.members)
ActRanged
@@ -293,6 +293,7 @@ void Shoot(Card _tc, Point _tp)
CellEffect effect = Act.TP.cell.effect;
if (effect != null && effect.id == 6 && EClass.rnd(2) == 0)
{
Prepare();
AttackProcess.Current.PlayRangedAnime(numFire);
Act.CC.PlaySound(missSound);
Act.CC.Say("abMistOfDarkness_miss", Act.CC);
AttackProcess
public void PlayRangedAnime(int numFire)
{
if (weapon == null)
{
return;
}
bool isGun = toolRange is TraitToolRangeGun;
bool isCane = toolRange is TraitToolRangeCane;
GameSetting.EffectData data = EClass.setting.effect.guns.TryGetValue(weapon.id) ?? EClass.setting.effect.guns[isCane ? "cane" : (isGun ? "gun" : "bow")];
Biography
@@ -409,6 +409,10 @@ public void GenerateAppearance(Chara c)
{
SourceRace.Row race = c.race;
height = race.height + EClass.rnd(race.height / 5 + 1) - EClass.rnd(race.height / 5 + 1);
if (c.source.tag.Contains("mini"))
{
height /= 10;
}
weight = height * height * (EClass.rnd(6) + 18) / 10000;
}
Card
c.PlayEffect("blood").SetParticleColor(EClass.Colors.matColors[material.alias].main).Emit(20 + (int)(30f * ratio));
if (EClass.core.config.test.showNumbers || isThing)
{
Popper popper = EClass.scene.popper.Pop(renderer.PositionCenter(), "DamageNum");
Color c2 = (c.IsPC ? EClass.Colors.textColors.damagePC : (c.IsPCFaction ? EClass.Colors.textColors.damagePCParty : EClass.Colors.textColors.damage));
if (e != Element.Void)
{
c2 = EClass.Colors.elementColors.TryGetValue(e.source.alias);
float num16 = (c2.r + c2.g + c2.b) / 3f;
num16 = ((num16 > 0.5f) ? 0f : (0.6f - num16));
c2 = new Color(c2.r + num16, c2.g + num16, c2.b + num16, 1f);
}
popper.SetText(dmg.ToString() ?? "", c2);
EClass.scene.damageTextRenderer.Add(this, c, dmg, e);
}
});
}
if (!isDestroyed)
{
Die(e, origin, attackSource);
if (trait.CanBeSmashedToDeath)
if (trait.CanBeSmashedToDeath && !EClass._zone.IsUserZone)
{
Rand.SetSeed(uid);
if (EClass.rnd(3) == 0 && !isCrafted && !isCopy)
@@ -6006,7 +5997,7 @@ public void Decay(int a = 10)
}
if (IsFood)
{
elements.SetBase(73, -10);
elements.ModBase(73, -10);
}
}
}
CharaAbility
@@ -43,7 +43,10 @@ public class CharaAbility : EClass
continue;
}
}
list.Add(row);
if (!row.tag.Contains("noRandomAbility"))
{
list.Add(row);
}
}
return list;
}
@@ -125,44 +128,6 @@ string ConvertID(string s)
}
}
public void BuildRandomAbilityList()
{
foreach (SourceElement.Row row in EClass.sources.elements.rows)
{
if (row.abilityType.Length == 0 || row.aliasRef == "mold")
{
continue;
}
switch (row.id)
{
case 5000:
case 5001:
case 5005:
case 5040:
case 5048:
case 6400:
case 6410:
case 8200:
continue;
}
if (row.idMold != 0 && !(owner.trait is TraitAdventurer))
{
switch (row.aliasRef)
{
case "eleEther":
case "eleAcid":
case "eleCut":
case "eleImpact":
continue;
}
}
if (!row.tag.Contains("noRandomAbility"))
{
randomAbilities.Add(row);
}
}
}
public void Add(int id, int chance, bool pt)
{
if (owner._listAbility == null)
ContentConfigTest
@@ -13,6 +13,8 @@ public class ContentConfigTest : ContentConfig
public UIButton toggleShowNumber;
public UIButton toggleStackNumber;
public UIButton toggleAAPortrait;
public UIButton toggleExTurn;
@@ -68,6 +70,10 @@ public override void OnInstantiate()
{
base.config.test.showNumbers = on;
});
toggleStackNumber.SetToggle(base.config.test.stackNumbers, delegate(bool on)
{
base.config.test.stackNumbers = on;
});
toggleToolNoPick.SetToggle(base.config.test.toolNoPick, delegate(bool on)
{
base.config.test.toolNoPick = on;
CoreConfig
@@ -526,6 +526,8 @@ public class Test
public bool showNumbers;
public bool stackNumbers;
public bool aaPortrait;
public bool extraTurnaround;
+DamageTextRenderer
File Created
using UnityEngine;
public class DamageTextRenderer : EClass
{
public Card lastTarget;
public Card lastAttacker;
public Element lastElement = Element.Void;
public int sum;
public int num;
public void Add(Card target, Card attacker, int dmg, Element e = null)
{
if (e == null)
{
e = Element.Void;
}
if (lastTarget != target || lastAttacker != attacker || lastElement.id != e.id)
{
Flush();
lastTarget = target;
lastAttacker = attacker;
lastElement = e;
}
sum += dmg;
num++;
if (!EClass.core.config.test.stackNumbers)
{
Flush();
}
}
public void Flush()
{
if (this.num != 0)
{
Card card = lastTarget;
Card card2 = lastAttacker;
Element element = lastElement;
Popper popper = EClass.scene.popper.Pop(card.renderer.PositionCenter(), "DamageNum");
Color c = EClass.Colors.textColors.damage;
if (card2 != null)
{
c = (card2.IsPC ? EClass.Colors.textColors.damagePC : (card2.IsPCFaction ? EClass.Colors.textColors.damagePCParty : EClass.Colors.textColors.damage));
}
if (element != Element.Void)
{
c = EClass.Colors.elementColors.TryGetValue(element.source.alias);
float num = (c.r + c.g + c.b) / 3f;
num = ((num > 0.5f) ? 0f : (0.6f - num));
c = new Color(c.r + num, c.g + num, c.b + num, 1f);
}
popper.SetText((this.num == 1) ? (sum.ToString() ?? "") : (sum + "<size=18> (x" + this.num + ")</size>"), c);
sum = (this.num = 0);
}
}
}
HitSummary
@@ -93,9 +93,13 @@ public bool CanExecute()
}
}
}
else if (recipe.ingredients[0].thing == null || recipe.ingredients[0].thing.Num < countValid)
else
{
return false;
Thing thing = recipe.ingredients[0].thing;
if (thing == null || recipe.ingredients[0].thing.Num < countValid / (thing.W * thing.H))
{
return false;
}
}
}
return true;
RecipeCard
rarity = (flag ? Rarity.Crude : Rarity.Normal)
});
Thing thing = (flag3 ? ThingGen.Create(key) : ThingGen.Create(key, num, num4));
if (thing.trait.CraftNum > 1)
{
thing.SetNum(thing.trait.CraftNum);
}
thing.idSkin = idSkin;
if (thing.IsEquipment && ings != null)
{
thing.SetNum(1);
return thing;
}
int num5 = thing.trait.CraftNum;
if (crafter != null && EClass.pc.Evalue(1417) > 0 && crafter.WitchDoubleCraftChance(thing) > EClass.rnd(100))
{
num5 *= 2;
}
if (num5 > 1)
{
thing.SetNum(num5);
}
if (EClass.pc.held == null || !thing.TryStackTo(EClass.pc.held.Thing))
{
EClass.pc.HoldCard(thing);
Scene
@@ -102,6 +102,8 @@ public enum Mode
public Material matFloorEx;
public DamageTextRenderer damageTextRenderer = new DamageTextRenderer();
public ParticleSystem psFoot;
public ParticleSystem psSmoke;
@@ -675,6 +677,7 @@ public void OnUpdate()
EMono.ui.mouseInfo.SetText();
}
EMono.screen.Draw();
damageTextRenderer.Flush();
actionMode.OnAfterUpdate();
if (EMono.player.lastTransition == null || EMono.player.simulatingZone)
{
Thing
@@ -856,7 +856,7 @@ public override void WriteNote(UINote n, Action<UINote> onWriteNote = null, IIns
text2 = array[0] + Environment.NewLine + text3 + array[1];
}
}
if (flag)
if (flag && !(trait is TraitPotionAlchemy))
{
text2 = recipe.GetName();
}
+TraitAlchemyBench
File Created
public class TraitAlchemyBench : TraitWorkbench
{
public override int WitchDoubleCraftChance(Thing t)
{
return 100;
}
public override bool Contains(RecipeSource r)
{
return r.idFactory == "tool_alchemy";
}
}
TraitCrafter
@@ -64,6 +64,11 @@ public enum AnimeType
public virtual int CostSP => 1;
public virtual int WitchDoubleCraftChance(Thing t)
{
return 0;
}
public virtual string IDReqEle(RecipeSource r)
{
return GetParam(1) ?? "handicraft";
TraitDrink
@@ -173,7 +173,7 @@ public override void OnDrink(Chara c)
n1 = N1,
isPerfume = (this is TraitPerfume),
refThing = owner.Thing,
act = ((source != null) ? ACT.Create(source) : null)
act = ((source != null && source.id != 0) ? ACT.Create(source) : null)
});
FoodEffect.ProcTrait(c, owner);
}
+TraitPotionAlchemy
File Created
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class TraitPotionAlchemy : TraitPotionRandom
{
public override int Power => owner.Power;
public override void OnCrafted(Recipe recipe)
{
owner.refVal = 0;
List<Element> list = owner.elements.dict.Values.Where((Element e) => e.IsTrait).ToList();
list.Sort((Element a, Element b) => Mathf.Abs(b.Value) - Mathf.Abs(a.Value));
int num = 0;
foreach (Element item in list)
{
int num2 = item.Value / 10;
switch (item.id)
{
case 750:
case 753:
num = ((num2 >= 6) ? 8402 : ((num2 >= 4) ? 8401 : 8400));
break;
case 754:
num = 8471;
break;
case 755:
num = 8470;
break;
case 751:
num = 8501;
break;
case 752:
num = 8791;
break;
case 760:
num = 8704;
break;
case 756:
num = 8506;
break;
}
if (num != 0)
{
break;
}
}
owner.refVal = num;
}
}
TraitPotionRandom
@@ -12,12 +12,27 @@ public class TraitPotionRandom : TraitPotion
public override int Power => 200;
public override EffectId IdEffect => source.proc[0].ToEnum<EffectId>();
public override EffectId IdEffect
{
get
{
if (!source.proc.IsEmpty())
{
return source.proc[0].ToEnum<EffectId>();
}
return EffectId.DrinkWaterDirty;
}
}
public override string N1 => source.proc.TryGet(1, returnNull: true);
public override bool IsNeg => source.tag.Contains("neg");
public override void OnCreate(int lv)
{
TraitPotion.Create(owner, selecter.Select(lv));
}
public override SourceElement.Row GetRefElement()
{
return source;
@@ -28,13 +43,21 @@ public override int GetValue()
return source.value * 120 / 100;
}
public override void OnCreate(int lv)
{
TraitPotion.Create(owner, selecter.Select(lv));
}
public override string GetName()
{
return Lang.TryGet("potion_" + source.alias) ?? "potion_".lang(source.GetName().ToLower());
string text;
if (owner.refVal != 0)
{
text = Lang.TryGet("potion_" + source.alias);
if (text == null)
{
return "potion_".lang(source.GetName().ToLower());
}
}
else
{
text = base.GetName();
}
return text;
}
}
+TraitToolAlchemy
File Created
public class TraitToolAlchemy : TraitWorkbench
{
public override int WitchDoubleCraftChance(Thing t)
{
return 100;
}
}