Skip to content

EA 23.68 Nightly

December 29, 2024

29 files modified. 4 new files created.

Important Changes

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

FactionBranch (1)

cs
public void BanishMember(Chara c, bool sell = false) 
public void BanishMember(Chara c, bool skipMsg = false) 

AI_Shear

@@ -24,7 +24,7 @@ public override bool Perform()

cs
public override IEnumerable<Status> Run()
{
	yield return DoGoto(target);
	int furLv = Mathf.Clamp(target.c_fur / 10 + 1, 1, 5); 
	int furLv = GetFurLv(target.Chara); 
	Progress_Custom seq = new Progress_Custom
	{
		canProgress = () => IsValidTC(target),

@@ -43,61 +43,73 @@ public override IEnumerable<Status> Run()

cs
				target.renderer.PlayAnime(AnimeID.Shiver);
				if (owner.Dist(target) > 1)
				{
					EClass.pc.TryMoveTowards(target.pos); 
					owner.TryMoveTowards(target.pos); 
					if (owner == null)
					{
						p.Cancel();
					}
					else if (owner.Dist(target) > 1)
					{
						EClass.pc.Say("targetTooFar"); 
						owner.Say("targetTooFar"); 
						p.Cancel();
					}
				}
			},
			onProgressComplete = delegate
			{
				string text = "fiber"; 
				string idMat = "wool"; 
				string text2 = target.id; 
				if (!(text2 == "putty_snow")) 
				{ 
					if (text2 == "putty_snow_gold") 
					{ 
						idMat = "gold"; 
					} 
					else if (!target.Chara.race.fur.IsEmpty()) 
					{ 
						string[] array = target.Chara.race.fur.Split('/'); 
						text = array[0]; 
						idMat = array[1]; 
					} 
				} 
				else
				{ 
					idMat = "cashmere"; 
				} 
				Thing thing = ThingGen.Create(text, idMat); 
				int num = 100 * furLv + furLv * furLv * 10; 
				int num2 = target.LV; 
				if (target.Chara.IsInCombat || target.Chara.IsMinion) 
				{ 
					owner.Say("shear_penalty"); 
					num /= 2; 
					num2 /= 2; 
				} 
				int num3 = 20 + thing.material.tier * 20; 
				thing.SetNum(Mathf.Max(num / num3, 1) + EClass.rnd(furLv + 1)); 
				thing.SetEncLv(EClass.curve(num2, 30, 10) / 10); 
				thing.elements.ModBase(2, EClass.curve(num2 / 10 * 10, 30, 10)); 
				target.c_fur = -5; 
				owner.Say("shear_end", owner, target, thing.Name); 
				owner.Pick(thing, msg: false); 
				Thing fur = GetFur(target.Chara); 
				owner.Say("shear_end", owner, target, fur.Name); 
				owner.Pick(fur, msg: false); 
				owner.elements.ModExp(237, 50 * furLv);
				EClass.pc.stamina.Mod(-1); 
				owner.stamina.Mod(-1); 
				target.Chara.ModAffinity(owner, 1);
			}
		}.SetDuration((6 + furLv * 6) * 100 / (100 + owner.Tool.material.hardness * 2), 3);
		yield return Do(seq);
	}

	public static int GetFurLv(Chara c) 
	{ 
		return Mathf.Clamp(c.c_fur / 10 + 1, 1, 5); 
	} 

	public static Thing GetFur(Chara c, int mod = 100) 
	{ 
		int furLv = GetFurLv(c); 
		string text = "fiber"; 
		string idMat = "wool"; 
		string text2 = c.id; 
		if (!(text2 == "putty_snow")) 
		{ 
			if (text2 == "putty_snow_gold") 
			{ 
				idMat = "gold"; 
			} 
			else if (!c.Chara.race.fur.IsEmpty()) 
			{ 
				string[] array = c.Chara.race.fur.Split('/'); 
				text = array[0]; 
				idMat = array[1]; 
			} 
		} 
		else
		{ 
			idMat = "cashmere"; 
		} 
		Thing thing = ThingGen.Create(text, idMat); 
		int num = mod * furLv + furLv * furLv * 10; 
		int num2 = c.LV; 
		if (c.IsInCombat || c.IsMinion) 
		{ 
			Msg.Say("shear_penalty"); 
			num /= 2; 
			num2 /= 2; 
		} 
		int num3 = 20 + thing.material.tier * 20; 
		thing.SetNum(Mathf.Max(num / num3, 1) + EClass.rnd(furLv + 1)); 
		thing.SetEncLv(EClass.curve(num2, 30, 10) / 10); 
		thing.elements.ModBase(2, EClass.curve(num2 / 10 * 10, 30, 10)); 
		c.c_fur = -5; 
		return thing; 
	} 
}

AI_Shopping

@@ -142,7 +142,7 @@ public override IEnumerable<Status> Run()

cs
	public static void SellChara(Chara c)
	{
		Msg.Say("sell_resident", c);
		c.homeBranch.BanishMember(c, sell: true); 
		c.homeBranch.BanishMember(c, skipMsg: true); 
		EClass.player.ModKarma(-1);
	}

+AI_Slaughter

File Created
cs
using System.Collections.Generic;
using UnityEngine;

public class AI_Slaughter : AI_TargetCard
{
	public static bool slaughtering;

	public override bool CanManualCancel()
	{
		return true;
	}

	public override string GetText(string str = "")
	{
		string[] list = Lang.GetList("fur");
		string text = list[Mathf.Clamp(target.c_fur / 10, 0, list.Length - 1)];
		return "AI_Shear".lang() + "(" + text + ")";
	}

	public override bool IsValidTC(Card c)
	{
		return c?.ExistsOnMap ?? false;
	}

	public override bool Perform()
	{
		target = Act.TC;
		return base.Perform();
	}

	public override IEnumerable<Status> Run()
	{
		yield return DoGoto(target);
		target.Chara.AddCondition<ConWait>(1000, force: true);
		Progress_Custom seq = new Progress_Custom
		{
			canProgress = () => IsValidTC(target),
			onProgressBegin = delegate
			{
				target.PlaySound("slaughter");
				target.SetCensored(enable: true);
				owner.Say("disassemble_start", owner, target);
			},
			onProgress = delegate(Progress_Custom p)
			{
				owner.LookAt(target);
				target.renderer.PlayAnime(AnimeID.Shiver);
				target.Chara.AddCondition<ConWait>(1000, force: true);
				if (owner.Dist(target) > 1)
				{
					owner.TryMoveTowards(target.pos);
					if (owner == null)
					{
						p.Cancel();
					}
					else if (owner.Dist(target) > 1)
					{
						owner.Say("targetTooFar");
						p.Cancel();
					}
				}
			},
			onProgressComplete = delegate
			{
				target.Chara.ModAffinity(owner, 1);
				target.SetCensored(enable: false);
				if (target.HaveFur())
				{
					Thing fur = AI_Shear.GetFur(target.Chara, 500);
					EClass._zone.AddCard(fur, target.pos);
				}
				slaughtering = true;
				target.Die();
				slaughtering = false;
				if (target.Chara.trait.IsUnique)
				{
					target.c_dateDeathLock = EClass.world.date.GetRaw() + 86400;
				}
				else
				{
					target.Chara.homeBranch.BanishMember(target.Chara, skipMsg: true);
				}
				owner.elements.ModExp(237, 250);
				owner.elements.ModExp(290, 100);
				EClass.pc.stamina.Mod(-3);
			}
		}.SetDuration(5000 / (100 + owner.Tool.material.hardness * 2), 3);
		yield return Do(seq);
	}

	public override void OnCancelOrSuccess()
	{
		if (target.ExistsOnMap)
		{
			target.Chara.RemoveCondition<ConWait>();
			target.SetCensored(enable: false);
		}
	}
}

ActEffect

@@ -1679,7 +1679,7 @@ public static bool DamageEle(Card CC, EffectId id, int power, Element e, List<Po

cs
		{
			if (TC.IsPC && list3.Count == 0)
			{
				list3 = EClass.game.cards.globalCharas.Where((KeyValuePair<int, Chara> a) => a.Value.isDead && a.Value.faction == EClass.pc.faction && !a.Value.isSummon).ToList(); 
				list3 = EClass.game.cards.globalCharas.Where((KeyValuePair<int, Chara> a) => a.Value.CanRevive() && a.Value.isDead && a.Value.faction == EClass.pc.faction && !a.Value.isSummon).ToList(); 
			}
			if (list3.Count > 0)
			{

ActPlan

@@ -515,7 +515,7 @@ public void _Update(PointTarget target)

cs
						}
						if (flag5 || altAction)
						{
							if (EClass.pc.HasElement(1216) && (c2.HasCondition<ConSleep>() || EClass.debug.enable)) 
							if (EClass.pc.HasElement(1216) && c2.HasCondition<ConSleep>()) 
							{
								TrySetAct(new AI_Fuck
								{

CINT

@@ -145,4 +145,6 @@ public class CINT

cs
	public const int isDisableStockUse = 122;

	public const int isSleepBeside = 123;

	public const int dateDeathLock = 130; 
}

Card

@@ -1153,6 +1153,18 @@ public int c_dateStockExpire

cs
		}
	}

	public int c_dateDeathLock 
	{ 
		get 
		{ 
			return GetInt(130); 
		} 
		set 
		{ 
			SetInt(130, value); 
		} 
	} 

	public int c_IDTState
	{
		get

@@ -2693,7 +2705,7 @@ public void AddExp(int a)

cs
		a *= 2;
		if (IsPCFaction)
		{
			a = a * Mathf.Clamp(100 + Chara.affinity.value / 10, 50, 100) / 100; 
			a = a * Mathf.Clamp(100 + Chara.affinity.value / 10, 50, 200) / 100; 
		}
	}
	a = a * (100 + Evalue(1237) * 30) / 100;

@@ -3314,7 +3326,14 @@ public void SetPlaceState(PlaceState newState, bool byPlayer = false)

cs
		{
			if (isThing)
			{
				pos.detail.MoveThingToTop(Thing); 
				if (trait.InstallBottomPriority != -1) 
				{ 
					pos.detail.MoveThingToBottom(Thing); 
				} 
				else
				{ 
					pos.detail.MoveThingToTop(Thing); 
				} 
			}
			area?.OnInstallCard(this);
			isRoofItem = false;

@@ -4381,10 +4400,16 @@ public void SpawnLoot(Card origin)

cs
		}
	}
	bool flag2 = Chara.race.corpse[1].ToInt() > EClass.rnd(1500) || (Chara.IsPowerful && !IsPCFaction) || EClass.debug.godFood;
	int num = 1; 
	if (Chara.race.IsAnimal && EClass.rnd(EClass._zone.IsPCFaction ? 3 : 5) == 0)
	{
		flag2 = true;
	}
	if (AI_Slaughter.slaughtering) 
	{ 
		flag2 = true; 
		num = EClass.rndHalf(4 + 5 * Chara.race.food[0].ToInt() / 100); 
	} 
	if (origin != null && origin.HasElement(290))
	{
		if (!flag2 && Chara.race.corpse[1].ToInt() > EClass.rnd(150000 / (100 + (int)Mathf.Sqrt(origin.Evalue(290)) * 5)))

@@ -4404,7 +4429,7 @@ public void SpawnLoot(Card origin)

cs
		{
			text = "meat_marble";
		}
		Thing thing3 = ThingGen.Create(text); 
		Thing thing3 = ThingGen.Create(text).SetNum(num); 
		if (thing3.source._origin == "meat")
		{
			thing3.MakeFoodFrom(this);

@@ -4424,10 +4449,10 @@ public void SpawnLoot(Card origin)

cs
		foreach (string item2 in sourceCard.loot.Concat(Chara.race.loot).ToList())
		{
			string[] array = item2.Split('/');
			int num = array[1].ToInt(); 
			if (num >= 1000 || num > EClass.rnd(1000) || EClass.debug.godMode) 
			int num2 = array[1].ToInt(); 
			if (num2 >= 1000 || num2 > EClass.rnd(1000) || EClass.debug.godMode) 
			{
				list.Add(ThingGen.Create(array[0]).SetNum((num < 1000) ? 1 : (num / 1000 + ((EClass.rnd(1000) > num % 1000) ? 1 : 0)))); 
				list.Add(ThingGen.Create(array[0]).SetNum((num2 < 1000) ? 1 : (num2 / 1000 + ((EClass.rnd(1000) > num2 % 1000) ? 1 : 0)))); 
			}
		}
		if (race.IsMachine)

@@ -4465,19 +4490,19 @@ public void SpawnLoot(Card origin)

cs
		}
		if (!isBackerContent && !flag)
		{
			int num2 = ((EClass._zone.Boss == this) ? 2 : ((this.rarity >= Rarity.Legendary) ? 1 : 0)); 
			int num3 = ((EClass._zone.Boss == this) ? 2 : ((this.rarity >= Rarity.Legendary) ? 1 : 0)); 
			if (EClass._zone is Zone_Void)
			{
				num2++; 
				num3++; 
			}
			if (EClass.rnd(5) == 0)
			{
				num2++; 
				num3++; 
			}
			string text2 = id;
			if (text2 == "big_daddy" || text2 == "santa")
			{
				num2 += 2; 
				num3 += 2; 
			}
			List<Thing> list2 = new List<Thing>();
			foreach (Thing thing4 in things)

@@ -4506,33 +4531,33 @@ public void SpawnLoot(Card origin)

cs
					list.Add(thing4);
				}
			}
			if (num2 > 0 && list2.Count > 0) 
			if (num3 > 0 && list2.Count > 0) 
			{
				list2.Shuffle();
				for (int j = 0; j < list2.Count && j < num2; j++) 
				for (int j = 0; j < list2.Count && j < num3; j++) 
				{
					list.Add(list2[j]);
					num2--; 
					num3--; 
				}
			}
			if (this.rarity >= Rarity.Legendary && !IsUnique && c_bossType != BossType.Evolved)
			{
				int num3 = 0; 
				int num4 = 0; 
				foreach (Card item3 in list)
				{
					if (item3.rarity >= Rarity.Legendary || item3.IsContainer)
					{
						num3++; 
						num4++; 
					}
				}
				if (num3 == 0) 
				if (num4 == 0) 
				{
					int num4 = ((!(EClass._zone is Zone_Void)) ? 1 : 2); 
					if (num2 < num4) 
					int num5 = ((!(EClass._zone is Zone_Void)) ? 1 : 2); 
					if (num3 < num5) 
					{
						num2 = num4; 
						num3 = num5; 
					}
					for (int k = 0; k < num2; k++) 
					for (int k = 0; k < num3; k++) 
					{
						Rand.SetSeed(uid + k);
						if (EClass.rnd((EClass._zone.events.GetEvent<ZoneEventDefenseGame>() != null) ? 3 : 2) == 0)

CellDetail

@@ -1,4 +1,5 @@

cs
using System.Collections.Generic;
using UnityEngine; 

public class CellDetail
{

@@ -48,9 +49,10 @@ public void MoveThingToBottom(Thing t)

cs
	{
		things.Remove(t);
		things.Insert(0, t);
		for (int i = 0; i < things.Count - 1 && things[i].IsInstalled; i++) 
		for (int i = 0; i < things.Count && things[i].IsInstalled; i++) 
		{
			t.stackOrder = i; 
			things[i].stackOrder = i; 
			Debug.Log(things[i].Name + "/" + things[i].stackOrder); 
		}
	}
}

@@ -60,7 +62,7 @@ public void MoveThingToTop(Thing t)

cs
	if (things.Count != 1)
	{
		int num = 0;
		for (int i = 0; i < things.Count - 1 && things[i].IsInstalled; i++) 
		for (int i = 0; i < things.Count && things[i].IsInstalled; i++) 
		{
			num = i + 1;
		}

Chara

@@ -864,7 +864,7 @@ public bool IsWealthy

cs

	public FactionBranch homeBranch => homeZone?.branch;

	public int MaxGeneSlot => race.geneCap; 
	public int MaxGeneSlot => race.geneCap - (HasElement(1237) ? 2 : 0); 

	public int CurrentGeneSlot
	{

@@ -4467,6 +4467,11 @@ public void Drink(Card t)

cs
		_ = IsPC;
	}

	public bool CanRevive() 
	{ 
		return EClass.world.date.IsExpired(base.c_dateDeathLock); 
	} 

	public void GetRevived()
	{
		Revive(EClass.pc.pos.GetNearestPoint(allowBlock: false, allowChara: false), msg: true);

@@ -4673,7 +4678,7 @@ public override void Die(Element e = null, Card origin = null, AttackSource atta

cs
		{
			Effect.Get("blood").Play((parent is Chara) ? (parent as Chara).pos : pos).SetParticleColor(EClass.Colors.matColors[base.material.alias].main)
				.Emit(50);
			AddBlood(2 + EClass.rnd(2)); 
			AddBlood(AI_Slaughter.slaughtering ? 12 : (2 + EClass.rnd(2))); 
			PlaySound(base.material.GetSoundDead(source));
		}
		renderer.RefreshSprite();

CoreConfig

@@ -205,6 +205,10 @@ public class GameConfig

cs
		[NonSerialized]
		[JsonIgnore]
		public bool ignoreWarnDisassemble;

		[NonSerialized] 
		[JsonIgnore] 
		public bool ignoreWarnSlaughter; 
	}

	[Serializable]

Dialog

@@ -318,6 +318,9 @@ public static void TryWarn(string lang, Action action, bool yes = true)

cs
			case "warn_disassemble":
				ELayer.core.config.game.ignoreWarnDisassemble = true;
				break;
			case "warn_slaughter":
				ELayer.core.config.game.ignoreWarnSlaughter = true; 
				break; 
			}
			d.Close();
			Commit();

@@ -355,6 +358,21 @@ void Commit()

cs
		}
	}

	public static void TryWarnSlaughter(Action action) 
	{ 
		if (ELayer.core.config.game.ignoreWarnSlaughter) 
		{ 
			warned = true; 
			action(); 
			warned = false; 
			ActPlan.warning = false; 
		} 
		else
		{ 
			TryWarn("warn_slaughter", action); 
		} 
	} 

	public static void TryWarnCrime(Action action)
	{
		if (!ELayer.core.config.game.warnCrime || ELayer.core.config.game.ignoreWarnCrime)

DramaManager

@@ -1024,7 +1024,7 @@ public bool CheckIF(string IF)

cs
		{
			foreach (Chara member in EMono.pc.homeBranch.members)
			{
				if (member.isDead && member.GetInt(100) != 0) 
				if (member.isDead && member.CanRevive() && member.GetInt(100) != 0) 
				{
					return true;
				}

@@ -115,7 +115,7 @@ public void BuildIngredients(Recipe _recipe, Image _icon, Action _onValueChange,

cs
					if (uid != 0)
					{
						Thing thing = EMono.pc.things.Find((Thing t) => t.uid == uid) ?? EMono._map.Stocked.Find(uid);
						if (thing != null) 
						if (thing != null && (!(thing.parent is Card card) || card.GetWindowSaveData() == null || !card.GetWindowSaveData().excludeCraft)) 
						{
							ingredient.SetThing(thing);
							flag = true;

FactionBranch

@@ -406,15 +406,20 @@ public void OnSimulateHour(VirtualDate date)

cs
	}
	foreach (Chara chara3 in EClass._map.charas)
	{
		if (chara3.memberType == FactionMemberType.Guest && ((chara3.c_allowance <= 0 && EClass.rnd(2) == 0) || chara3.GetInt(34) + 10080 < EClass.world.date.GetRaw())) 
		if (chara3.memberType != FactionMemberType.Guest || ((chara3.c_allowance > 0 || EClass.rnd(2) != 0) && chara3.GetInt(34) + 10080 >= EClass.world.date.GetRaw())) 
		{
			if (!chara3.IsGlobal) 
			{ 
				chara3.Destroy(); 
			} 
			chara3.ClearBed(); 
			break; 
			continue; 
		} 
		foreach (Chara item in EClass._zone.ListMinions(chara3)) 
		{ 
			item.Destroy(); 
		} 
		if (!chara3.IsGlobal) 
		{ 
			chara3.Destroy(); 
		}
		chara3.ClearBed(); 
		break; 
	}
	if (date.hour == 5)
	{

@@ -437,11 +442,11 @@ public void OnSimulateHour(VirtualDate date)

cs
	}
	if (!date.IsRealTime && date.hour % 8 == 0)
	{
		foreach (Chara item in EClass._map.charas.Where((Chara c) => c.memberType == FactionMemberType.Guest).ToList()) 
		foreach (Chara item2 in EClass._map.charas.Where((Chara c) => c.memberType == FactionMemberType.Guest).ToList()) 
		{
			for (int j = 0; j < 3; j++)
			{
				AI_Shopping.TryShop(item, realtime: false); 
				AI_Shopping.TryShop(item2, realtime: false); 
			}
		}
		AI_Shopping.TryRestock(EClass.pc, realtime: false);

@@ -823,7 +828,7 @@ void GetOutcome(Hobby h)

cs
				{
					if (!member2.IsPCParty)
					{
						if (member2.isDead && EClass.rnd(num3) > EClass.rnd(100)) 
						if (member2.isDead && member2.CanRevive() && EClass.rnd(num3) > EClass.rnd(100)) 
						{
							Log("bNurse", i, member2);
							member2.Revive(member2.pos, msg: true);

@@ -1366,10 +1371,10 @@ public void ChangeMemberType(Chara c, FactionMemberType type)

cs
		policies.Validate();
	}

	public void BanishMember(Chara c, bool sell = false) 
	public void BanishMember(Chara c, bool skipMsg = false) 
	{
		RemoveMemeber(c);
		if (!sell) 
		if (!skipMsg) 
		{
			Msg.Say("banish", c, EClass._zone.Name);
		}

Game

@@ -253,7 +253,7 @@ private void _OnDeserialized(StreamingContext context)

cs

	public Prologue Prologue => EClass.setting.start.prologues[idPrologue];

	public GameDifficulty Difficulty => EClass.setting.start.difficulties[idDifficulty]; 
	public GameDifficultySetting Difficulty => EClass.setting.start.difficulties[idDifficulty]; 

	public bool UseGrid => EClass.core.config.game.useGrid;

GameDifficulty

@@ -1,17 +1,41 @@

cs
using System; 
using Newtonsoft.Json; 

[Serializable] 
public class GameDifficulty : EClass
{
	public int tier; 
	[JsonProperty] 
	public int socre; 

	public bool allowManualSave; 
	[JsonProperty] 
	public int minScore; 

	public bool allowRevive; 
	[JsonProperty] 
	public int bonusLoot; 

	public bool deleteGameOnDeath; 
	[JsonProperty] 
	public bool deathPenalty; 

	public int ID => EClass.setting.start.difficulties.IndexOf(this); 
	[JsonProperty] 
	public bool economy; 

	public string Name => Lang.GetList("difficulties")[ID]; 
	[JsonProperty] 
	public bool manualSave; 

	[JsonProperty] 
	public bool ironMode; 

	[JsonProperty] 
	public bool moreFood; 

	[JsonProperty] 
	public bool moreReward; 

	public int GetGrade(int v) 
	{ 
		return 0; 
	} 

	public int CalculateScore() 
	{ 
		return 0; 
	} 
}

+GameDifficultySetting

File Created
cs
using System;

[Serializable]
public class GameDifficultySetting : EClass
{
	public int tier;

	public bool allowManualSave;

	public bool allowRevive;

	public bool deleteGameOnDeath;

	public int ID => EClass.setting.start.difficulties.IndexOf(this);

	public string Name => Lang.GetList("difficulties")[ID];
}

GameSetting

@@ -239,7 +239,7 @@ public class StartSetting

cs
	{
		public List<Prologue> prologues;

		public List<GameDifficulty> difficulties; 
		public List<GameDifficultySetting> difficulties; 
	}

	[Serializable]

GoalCombat

@@ -834,7 +834,6 @@ int HealFactor(Chara c)

cs
			continue;
		}
		Chara chara = owner;
		Debug.Log(ability2.act.Name + ":" + ability2.act.CanPerform(owner, ability2.tg ?? tc)); 
		if (ability2.act.CanPerform(owner, ability2.tg ?? tc) && owner.UseAbility(ability2.act, ability2.tg ?? tc, null, (ability2.act.HaveLongPressAction && ability2.pt) || ability2.aiPt))
		{
			if (EClass.debug.logCombat)

ListPeopleRevive

@@ -26,7 +26,7 @@ public override void OnClick(Chara c, ItemGeneral i)

cs

	public override void OnList()
	{
		foreach (KeyValuePair<int, Chara> item in EClass.game.cards.globalCharas.Where((KeyValuePair<int, Chara> a) => a.Value.isDead && a.Value.faction == EClass.pc.faction && !a.Value.isSummon)) 
		foreach (KeyValuePair<int, Chara> item in EClass.game.cards.globalCharas.Where((KeyValuePair<int, Chara> a) => a.Value.CanRevive() && a.Value.isDead && a.Value.faction == EClass.pc.faction && !a.Value.isSummon)) 
		{
			list.Add(item.Value);
		}

Map

@@ -2002,7 +2002,7 @@ public void AddDecal(int x, int z, int id, int amount = 1, bool refresh = true)

cs

	public void SetDecal(int x, int z, int id = 0, int amount = 1, bool refresh = true)
	{
		cells[x, z].decal = (byte)(id * 8 + ((id != 0) ? amount : 0)); 
		cells[x, z].decal = (byte)((id != 0 && amount != 0) ? ((uint)(id * 8 + amount)) : 0u); 
		if (refresh)
		{
			RefreshNeighborTiles(x, z);

Props

@@ -214,6 +214,7 @@ public ThingStack ListThingStack(Recipe.Ingredient ing, StockSearchMode searchMo

cs
		{
			FindCat(item);
		}
		stack.list.Sort((Thing a, Thing b) => b.Num - a.Num); 
		return stack;
	}
	Find(id2);

@@ -221,6 +222,7 @@ public ThingStack ListThingStack(Recipe.Ingredient ing, StockSearchMode searchMo

cs
	{
		Find(item2);
	}
	stack.list.Sort((Thing a, Thing b) => b.Num - a.Num); 
	return stack;
	void Find(string id)
	{

Recipe

@@ -857,9 +857,13 @@ public bool IsCraftable()

cs
{
	foreach (Ingredient ingredient in ingredients)
	{
		if (!ingredient.optional && EClass._map.Stocked.ListThingStack(ingredient, StockSearchMode.AroundPC).max < ingredient.req) 
		if (!ingredient.optional) 
		{
			return false; 
			ThingStack thingStack = EClass._map.Stocked.ListThingStack(ingredient, StockSearchMode.AroundPC); 
			if (thingStack.list.Count == 0 || thingStack.list[0].Num < ingredient.req) 
			{ 
				return false; 
			} 
		}
	}
	return true;

Scene

@@ -217,7 +217,7 @@ public void Init(Mode newMode)

cs
			Zone zone = (EMono.pc.currentZone = EMono.pc.homeZone);
			obj.zone = zone;
		}
		EMono.core.config.game.ignoreWarnCrime = (EMono.core.config.game.ignoreWarnMana = (EMono.core.config.game.ignoreWarnDisassemble = false)); 
		EMono.core.config.game.ignoreWarnCrime = (EMono.core.config.game.ignoreWarnMana = (EMono.core.config.game.ignoreWarnDisassemble = (EMono.core.config.game.ignoreWarnSlaughter = false))); 
		EMono.game.updater.Reset();
		CellDetail.count = 0;
		skipAnime = true;

TaskClean

@@ -46,29 +46,25 @@ public override IEnumerable<Status> Run()

cs
			{
				yield return Success();
			}
			bool fail = false; 
			yield return DoGoto(dest, 0, ignoreConnection: false, delegate
			yield return DoGoto(dest, 1); 
			for (int i = 0; i < ((!dest.cell.HasLiquid) ? 1 : 5); i++) 
			{
				fail = true; 
				return Status.Running; 
			}); 
			yield return KeepRunning(); 
			if (!fail && CanClean(dest)) 
			{ 
				if (owner.Dist(dest) > 1) 
				{ 
					yield return Cancel(); 
				} 
				Point point = dest; 
				EClass._map.SetDecal(point.x, point.z); 
				EClass._map.SetLiquid(point.x, point.z, 0, 0); 
				point.PlayEffect("vanish"); 
				EClass.pc.Say("clean", owner); 
				EClass.pc.PlaySound("clean_floor"); 
				EClass.pc.stamina.Mod(-1); 
				EClass.pc.ModExp(293, 30); 
				owner.LookAt(dest); 
				owner.renderer.NextFrame(); 
				yield return KeepRunning();
			}
			if (!CanClean(dest) || owner.Dist(dest) > 1) 
			{ 
				yield return Cancel(); 
			} 
			EClass._map.SetDecal(dest.x, dest.z); 
			EClass._map.SetLiquid(dest.x, dest.z, 0, 0); 
			dest.PlayEffect("vanish"); 
			EClass.pc.Say("clean", owner); 
			EClass.pc.PlaySound("clean_floor"); 
			EClass.pc.stamina.Mod(-1); 
			EClass.pc.ModExp(293, 30); 
			yield return KeepRunning(); 
		}
	}

Trait

@@ -81,6 +81,8 @@ public virtual bool ShouldRefreshTile

cs

	public virtual bool ShouldTryRefreshRoom => IsDoor;

	public virtual int InstallBottomPriority => -1; 

	public virtual bool CanHarvest => true;

	public virtual int radius => 0;

@@ -1115,7 +1117,14 @@ public virtual void Toggle(bool on, bool silent = false)

cs
			}
		}
		owner.isOn = on;
		PlayToggleEffect(silent); 
		OnToggle(); 
	} 

	public virtual void PlayToggleEffect(bool silent) 
	{ 
		bool flag = ToggleType == ToggleType.Fire;
		bool isOn = owner.isOn; 
		switch (ToggleType)
		{
		case ToggleType.Lever:

@@ -1124,49 +1133,46 @@ public virtual void Toggle(bool on, bool silent = false)

cs
				owner.Say("lever", EClass.pc, owner);
				owner.PlaySound("switch_lever");
			}
			break; 
			return; 
		case ToggleType.Curtain:
			if (!silent)
			{
				owner.Say(on ? "close" : "open", EClass.pc, owner); 
				owner.Say(isOn ? "close" : "open", EClass.pc, owner); 
				owner.PlaySound("Material/leather_drop");
			}
			owner.pos.RefreshNeighborTiles();
			EClass.pc.RecalculateFOV();
			break; 
		default: 
			if (on) 
			{ 
				if (!silent) 
				{ 
					owner.Say(flag ? "toggle_fire" : "toggle_ele", EClass.pc, owner); 
					string id = ((Electricity < 0) ? "switch_on_electricity" : (flag ? "torch_lit" : "switch_on")); 
					if (this is TraitMusicBox) 
					{ 
						id = "switch_on_musicbox"; 
					} 
					owner.PlaySound(id); 
				} 
				RefreshRenderer(); 
				owner.RecalculateFOV(); 
				break; 
			} 
			return; 
		case ToggleType.None:
			return; 
		} 
		if (isOn) 
		{ 
			if (!silent)
			{
				string id2 = ((Electricity < 0) ? "switch_off_electricity" : (flag ? "torch_unlit" : "switch_off")); 
				owner.Say(flag ? "toggle_fire" : "toggle_ele", EClass.pc, owner); 
				string id = ((Electricity < 0) ? "switch_on_electricity" : (flag ? "torch_lit" : "switch_on")); 
				if (this is TraitMusicBox)
				{
					id2 = "switch_off_musicbox"; 
					id = "switch_on_musicbox"; 
				}
				owner.PlaySound(id2); 
				owner.PlaySound(id); 
			}
			RefreshRenderer();
			owner.RecalculateFOV();
			break; 
		case ToggleType.None:
			break; 
			return; 
		}
		OnToggle(); 
		if (!silent) 
		{ 
			string id2 = ((Electricity < 0) ? "switch_off_electricity" : (flag ? "torch_unlit" : "switch_off")); 
			if (this is TraitMusicBox) 
			{ 
				id2 = "switch_off_musicbox"; 
			} 
			owner.PlaySound(id2); 
		} 
		RefreshRenderer(); 
		owner.RecalculateFOV(); 
	}

	public virtual void OnToggle()

@@ -1907,7 +1913,7 @@ public void OnBarter()

cs
				{
					thing9.isStolen = true;
				}
				if (CurrencyType == CurrencyType.Money || !thing9.IsUnique) 
				if (!(thing9.trait is TraitErohon)) 
				{
					thing9.c_IDTState = 0;
				}

TraitBed

@@ -91,7 +91,7 @@ public void ValidateOwners()

cs
	data.list.ForeachReverse(delegate(int i)
	{
		Chara chara = EClass._map.FindChara(i) ?? EClass.game.cards.globalCharas.Find(i);
		if (chara == null || (chara.IsPCFaction && chara.homeBranch != EClass._zone.branch)) 
		if (chara == null || (chara.IsPCFaction && !chara.IsPCParty && chara.homeBranch != EClass._zone.branch)) 
		{
			data.list.Remove(i);
		}

TraitSeed

@@ -8,6 +8,8 @@ public class TraitSeed : Trait

cs

	public SourceObj.Row row => EClass.sources.objs.map[owner.refVal];

	public override int InstallBottomPriority => 10000; 

	public override bool CanExtendBuild => true;

	public override bool CanChangeHeight => false;

+TraitToolButcher

File Created
cs
public class TraitToolButcher : TraitTool
{
	public override bool DisableAutoCombat => true;

	public override void TrySetHeldAct(ActPlan p)
	{
		foreach (Chara chara in p.pos.Charas)
		{
			if (chara.IsPCParty || !chara.IsPCFaction)
			{
				continue;
			}
			Chara _c = chara;
			p.TrySetAct("AI_Slaughter", delegate
			{
				Dialog.TryWarnSlaughter(delegate
				{
					EClass.pc.SetAIImmediate(new AI_Slaughter
					{
						target = _c
					});
				});
				return false;
			}, chara);
		}
	}
}

+TraitWoodMill

File Created
cs
public class TraitWoodMill : TraitCrafter
{
	public override string IdSource => "WoodMill";

	public override int numIng => 2;

	public override string CrafterTitle => "invWoodMill";

	public override AnimeID IdAnimeProgress => AnimeID.Shiver;

	public override string idSoundProgress => "cook_pound";

	public override ToggleType ToggleType => ToggleType.Custom;

	public override AnimeType animeType => AnimeType.Microwave;

	public override bool AutoTurnOff => true;

	public override bool AutoToggle => false;

	public override void PlayToggleEffect(bool silent)
	{
	}
}

UICharaMaker

@@ -215,12 +215,12 @@ public void ListDifficulties()

cs
	TooltipManager.Instance.disableHide = "note";
	bool first = true;
	EMono.ui.AddLayer<LayerList>().SetPivot(0.5f, 0.2f).SetSize(260f)
		.SetList2(EMono.setting.start.difficulties, (GameDifficulty a) => a.Name, delegate(GameDifficulty a, ItemGeneral b) 
		.SetList2(EMono.setting.start.difficulties, (GameDifficultySetting a) => a.Name, delegate(GameDifficultySetting a, ItemGeneral b) 
		{
			EMono.game.idDifficulty = a.ID;
			textDifficulty.SetText(listDifficulties[EMono.game.idDifficulty]);
			Refresh();
		}, delegate(GameDifficulty a, ItemGeneral item) 
		}, delegate(GameDifficultySetting a, ItemGeneral item) 
		{
			UIButton b2 = item.button1;
			b2.SetTooltip(delegate(UITooltip t)

WidgetStatsBar

@@ -273,17 +273,14 @@ public void Refresh()

cs
			{
				text2 = text2 + " (" + ele.ValueWithoutLink + ")";
			}
			if (ele.DisplayValue < ele.ValueWithoutLink) 
			int num = ((EMono.pc.tempElements != null) ? EMono.pc.tempElements.Value(ele.id) : 0); 
			if (ele.DisplayValue < ele.ValueWithoutLink || num < 0) 
			{
				fontColor = FontColor.Bad;
			}
			else if (EMono.pc.tempElements != null) 
			else if (num > 0) 
			{
				Element element = EMono.pc.tempElements.GetElement(ele.id); 
				if (element != null && element.vBase > 0) 
				{ 
					fontColor = FontColor.Good; 
				} 
				fontColor = FontColor.Good; 
			}
		}
		if (text2 != text || item.lastColor != fontColor)

Zone

@@ -111,7 +111,7 @@ public override int DangerLv

cs
			{
				return GetTopZone().DangerLv + Mathf.Abs(base.lv) - 1;
			}
			return (int)Mathf.Max(1f, (float)base._dangerLv + MathF.Abs(base.lv) + (float)DangerLvFix); 
			return (int)Mathf.Max(1f, (branch != null) ? ((float)branch.DangerLV) : ((float)base._dangerLv + MathF.Abs(base.lv) + (float)DangerLvFix)); 
		}
	}

@@ -1024,7 +1024,7 @@ public void Revive()

cs
	{
		foreach (Chara deadChara in map.deadCharas)
		{
			if (deadChara.trait.CanAutoRevive) 
			if (deadChara.trait.CanAutoRevive && deadChara.CanRevive()) 
			{
				deadChara.Revive();
				if (deadChara.isBackerContent && EClass.player.doneBackers.Contains(deadChara.c_idBacker) && !EClass.core.config.test.ignoreBackerDestoryFlag)

@@ -1037,7 +1037,7 @@ public void Revive()

cs
	}
	foreach (Chara value in EClass.game.cards.globalCharas.Values)
	{
		if (value.isDead && value.homeZone == this) 
		if (value.isDead && value.CanRevive() && value.homeZone == this) 
		{
			value.Revive();
			Point point = GetSpawnPos(value);

@@ -2021,7 +2021,7 @@ Thing SearchDest()

cs
			{
				thing = EClass.game.cards.container_shipping;
			}
			if (!sharedOnly || thing.IsSharedContainer) 
			if ((!sharedOnly || thing.IsSharedContainer) && thing.c_lockLv <= 0) 
			{
				if (add)
				{

@@ -3348,6 +3348,19 @@ public void UpdateQuests(bool force = false)

cs
		}
	}

	public List<Chara> ListMinions(Chara c) 
	{ 
		List<Chara> list = new List<Chara>(); 
		foreach (Chara chara in EClass._map.charas) 
		{ 
			if (chara.c_uidMaster == c.uid && chara.c_minionType == MinionType.Default) 
			{ 
				list.Add(chara); 
			} 
		} 
		return list; 
	} 

	public int CountMinions(Chara c)
	{
		int num = 0;