Elin:Code Analysis/Basics

Revision as of 13:54, 25 December 2024 by Inno (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Version EA23.65: This article is behind the latest stable release of Elin, but maybe close enough to be reliable.

This page contains code analysis on the basic stats of characters (PC and non-PC). This page is updated to EA23.65.

Maximum HP

public override int MaxHP => Mathf.Max(1, ((base.END * 2 + base.STR + base.WIL / 2) * Mathf.Min(base.LV, 25) / 25 + base.END + 10) 
                             * Evalue(60) / 100 * ((IsPCFaction ? 100 : (100 + (int)base.rarity * 300)) + (IsPC ? (EClass.player.lastEmptyAlly * Evalue(1646)) : 0)) / 100);

The Maximum HP is determined by the following factors:

  • Level-based HP: Until level 25, the HP Maximum will be modified by the base number of level. After level 25, this value becomes constant. (4% per level)
    • For example, a character grow from lvl 1 to 2, its HP will increase by base of *2.
    • This level-base will apply to (2 * END + 1 * STR + 0.5 * WIL) * (4% * level)
  • Another 1 * END base HP and 10 HP will be awarded independent of level.
    • This means, at the start of the game (lvl 1), Endurance is the biggest factor (1.04) of HP Maximum far greater than STR (0.04) and WIL (0.02).
    • For character higher than level 25, Each point of END increase HP base by 3, STR by 1, and WIL by 0.5.
  • The HP base is further modified by Character Life (Evalue(60) / 100
  • Character Faction modifier:
    • If character is in PC faction, the HP is modified by 100%
    • If character is not in PC faction, HP is further amplified by the rarity of character.
      • If normal, 100%; if superior, 400%; if legendary, 700%, if mythical, 1000%, if artifact, 1300%.
    • The rarity of character is bosses and evolved monsters are legendary.
    • All unique characters, such as Fiama, Gwen, even Innos Turas, have the rarity of artifact, which possibly mean that this HP buff will apply to them if they are not in PC faction. (Need Confirmation)
  • This value is finally modified by the Lonelysoul feat if the character is PC.

Maximum MP

public override int max => Mathf.Max(1, ((BaseStats.CC.MAG * 2 + BaseStats.CC.WIL + BaseStats.CC.LER / 2) * Mathf.Min(BaseStats.CC.LV, 25) / 25 + BaseStats.CC.MAG + 10) 
                           * BaseStats.CC.Evalue(61) / 100 * ((BaseStats.CC.IsPCFaction ? 100 : (100 + (int)BaseStats.CC.rarity * 250)) 
                           + (BaseStats.CC.IsPC ? (EClass.player.lastEmptyAlly * BaseStats.CC.Evalue(1646)) : 0)) / 100);

The Maximum MP is determined by the following factors:

  • Level-based HP: Until level 25, the MP Maximum will be modified by the base number of level. After level 25, this value becomes constant. (4% per level)
    • For example, a character grow from lvl 1 to 2, its HP will increase by base of *2.
    • This level-base will apply to (2 * MAG + 1 * WIL + 0.5 * LER) * (4% * level)
  • Another 1 * MAG base MP and 10 MP will be awarded independent of level.
    • This means, at the start of the game (lvl 1), Magic is the biggest factor (1.04) of HP Maximum far greater than WIL (0.04) and LER (0.02).
    • For character higher than level 25, Each point of MAG increase MP base by 3, WIL by 1, and LER by 0.5.
  • The MP base is further modified by Character Mana (Evalue(61) / 100
    • If character is not in PC faction, HP is further amplified by the rarity of character.
      • If normal, 100%; if superior, 350%; if legendary, 600%, if mythical, 850%, if artifact, 1100%.
    • The rarity of character is bosses and evolved monsters are legendary.
    • All unique characters, such as Fiama, Gwen, even Innos Turas, have the rarity of artifact, which possibly mean that this MP buff will apply to them if they are not in PC faction. (Need Confirmation)
  • This value is finally modified by the Lonelysoul feat if the character is PC.

Base ability of Nefia bosses & Evolved

    public Rarity rarity = Rarity.Random;
	public static SpawnSetting Evolved(int fixedLv = -1)
	{
		return new SpawnSetting
		{
			fixedLv = fixedLv,
			rarity = Rarity.Legendary,
			forcedHostility = Hostility.Neutral,
			isEvolved = true,
			tries = 10000
		};
	}

	public static SpawnSetting Boss(int filterLv, int fixedLv = -1)
	{
		return new SpawnSetting
		{
			filterLv = filterLv - 2,
			fixedLv = fixedLv,
			rarity = Rarity.Legendary,
			isBoss = true,
			tries = 10000,
			levelRange = 5,
			forcedHostility = Hostility.Enemy
		};
	}
  • Nefia bosses and Evolved Monsters are generated at the rarity of Rarity.Legendary. Refering to the result from above analysis, the generated monster will have 700% Maximum HP and 600% Maximum MP of the normal version of the monster. This is probably not the only buff to Nefia boss abilities.
  • The Nefia boss will always be selected from monsters at most -7 to +3 levels from the depth of the nefia difficulty (Need confirmation).

Maximum Stamina

	public void CalculateMaxStamina()
	{
		int num = base.END;
		int num2 = 0;
		foreach (Element value in elements.dict.Values)
		{
			if (value.source.category == "skill")
			{
				num = ((!IsPC) ? (num + Mathf.Max(value.ValueWithoutLink, 0)) : (num + Mathf.Max(value.vBase, 0)));
			}
		}
		num2 = EClass.curve(num, 30, 10, 60);
		if (num2 < 10)
		{
			num2 = 10;
		}
		_maxStamina = num2 + 15;
	}
    ....
    public override int max => BaseStats.CC._maxStamina * BaseStats.CC.Evalue(62) / 100;

The maximum stamina of chracters is determined by the following:

  • Each point of base endurance increase the base number by 1.
  • For each skill a chracter have, increase this base number by the level of that skill.
    • For example, two handed lvl 50, then num += 50, cooking lvl 50, then additional += 50, and so on.
    • The main defining factor of Stamina maximum is the total level of skills you have, not END.
  • The base number go through a CURVE function with (base, 30, 10, 60).
    • This means, if the base number is less than 30, return that value.
    • For each point of additional base num, the return is diminished.
    • Base num 60, output is 44.8
    • Base num 90, output is 53.36
    • Base num 300, output is 77.9
    • Base num 1500, output is 110.0
    • Base num 15000, output is 195.6
    • There is no maximum stamina, however it becomes much harder to raise after about 120.
  • The output number is increased by 15, then modified by the vigor(Evalue(62))% of player.
    • So a player with 1500 of total skill levels will have a base stamina about 125, modified by the vigor of said character.
    • A new player with 20 END and 40 total skill level will only have 60 maximum stamina.

Carryweight Limit

public override int WeightLimit => (base.STR * 500 + base.END * 250 + Evalue(207) * 2000) * ((!HasElement(1411)) ? 1 : 5) + 45000;

The carryweight limit of characters is determined by the following factors:

  • Base limit is 0.5 * STR + 0.25 * END + 2 * Weightlifting skill. (Each "s" in game is 1000 in code.)
  • If the character is golden knight, then this is further modified by 500%.
  • A 45s base carry weight is added to the final result.

Sanity

There are many factors influencing the sanity of players. We pick the main ones in the code for analysis:

	public void Cure(CureType type, int p = 100, BlessedState state = BlessedState.Normal)
	{
		bool flag = state == BlessedState.Blessed;
		switch (type)
		{
		case CureType.Heal:
		case CureType.Prayer:
			CureCondition<ConFear>();
			CureCondition<ConBlind>(2 * p / 100 + 5);
			CureCondition<ConPoison>(5 * p / 100 + 5);
			CureCondition<ConConfuse>(10 * p / 100 + 10);
			CureCondition<ConDim>(p / 100 + 5);
			CureCondition<ConBleed>(2 * p / 100 + 10);
			if (flag)
			{
				SAN.Mod(-5);
			}
			break;
  • This is utilized when a player pray to god, and if the state of item used is "blessed", the character will have -5 Sanity value.
    • This is pretty strange, considering that the action of praying to god is never an item and can never be assigned the "blessed" state, thus the code is unused.
	case EffectId.RemedyJure:
		TC.HealHP(1000000, HealSource.Magic);
		TC.CureHost(CureType.Jure, power, state);
		TC.Say("heal_jure", TC);
		break;
    if (type == CureType.Jure)
			{
				SAN.Mod(-999);
  • This effect happens when you use the Healing feather (or Jure's pillow?) (Lay hand would be EffectId.JureHeal), and modify you Sanity by -999.
		case Type.Dojin:
			c.PlaySound("wow");
			c.Say("book_decode", c, owner);
			if (!c.IsPC)
			{
				c.Talk("wow");
			}
			switch (BookType)
			{
			case Type.Ero:
				if (c.IsPC)
				{
					EClass.pc.SAN.Mod(-(EClass.rnd(5) + 1));
				}
  • This effect happens when a PC reads strange book that is in the "Ero" type. The Sanity is modded with a random value from -1 to -5.
		case 914:
			flag2 = false;
			if (EClass.rnd(3) != 0)
			{
				if (Chance(30 + eleP / 5, 100))
				{
					Chara.AddCondition<ConConfuse>(eleP);
				}
			}
			else if (Chance(30 + eleP / 5, 100))
			{
				Chara.AddCondition<ConSleep>(eleP);
			}
			if (Chance(50, 100))
			{
				Chara.SAN.Mod(EClass.rnd(2));
			}
			break;
            ...
		case 920:
			flag2 = false;
			if (Chance(5 + eleP / 25, 40))
			{
				Chara.AddCondition<ConBlind>(eleP / 2);
			}
			if (Chance(5 + eleP / 25, 40))
			{
				Chara.AddCondition<ConParalyze>(eleP / 2);
			}
			if (Chance(5 + eleP / 25, 40))
			{
				Chara.AddCondition<ConConfuse>(eleP / 2);
			}
			if (Chance(5 + eleP / 25, 40))
			{
				Chara.AddCondition<ConPoison>(eleP / 2);
			}
			if (Chance(5 + eleP / 25, 40))
			{
				Chara.AddCondition<ConSleep>(eleP / 2);
			}
			if (Chance(5 + eleP / 25, 40))
			{
				Chara.AddCondition<ConDim>(eleP / 2);
			}
			if (Chance(30 + eleP / 10, 100))
			{
				Chara.SAN.Mod(EClass.rnd(2));
			}
			break;
            ...
        bool Chance(int a, int max)
		{
			if (dmg > 0 || (origin != null && origin.HasElement(1345)))
			{
				return Mathf.Min(a, max) > EClass.rnd(100);
			}
			return false;
		}
  • There are two types of attacks that specifically increase the Sanity value, this is observed to be the main way people get Sanity value in daily life.
  • Element ID 914 or Mind Attack will have a 50% chance of increase your Sanity value by 0 - 1 for every attack received.
  • Element ID 920 or Chaos Attack will have a chance of increase your Sanity value by 0 - 1 for every attack received. The chance depend on the Element power of the attack, and will range from 30% to 100%.
  • A few other effects exist as a fixed increase in Sanity value. Doing the f thing will give Sanity value +10. Eating Human flesh (canniblism) gives a fixed Sanity value +15.

Relationship of Sanity and Sleepiness (<EA23.63)

    public class StatsSleepiness : Stats
    {
	    public const int Sleepy = 1;
 
    	public const int VerySleepy = 2;

    	public const int VeryVerySleepy = 3;

    	public override bool TrackPhaseChange => BaseStats.CC.IsPC;
    }
    ...
    public Stats sleepiness => Stats.Sleepiness.Set(_cints, 17, this);
    public Stats SAN => Stats.SAN.Set(_cints, 17, this);

    public bool CanSleep()
	{
		if (EClass._zone.events.GetEvent<ZoneEventQuest>() != null)
		{
			return false;
		}
		if (!EClass.debug.godMode && sleepiness.GetPhase() == 0)
		{
			return stamina.GetPhase() <= 1;
		}
		return true;
	}
    public override int GetPhase()
	{
		return base.source.phase[(int)Mathf.Clamp(10f * (float)value / (float)max, 0f, 9f)];
	}

	public virtual void Set(int a)
	{
		value = a;
		if (value < min)
		{
			value = min;
		}
		else if (value > max)
		{
			value = max;
		}
	}

BEFORE EA23.63

  • Interestingly, the character's sanity and sleepiness value are determined by the same parameter (ID: 17).
  • In actual gameplay, the first stage of sleepiness always activates the moment the sanity value reaches 40. In other words, it seems reasonable to think that the sleep value (sleepiness) and sanity level are always linked.
    • I have confirmed that even if the PC just woke up, if it continuously use "Hand of Madness" on itself, the PC will still enter a sleepiness state the moment sanity value reaches 40.
    • I believe it is correct that the madness level does not gradually increase from the state of "very sleepy," butt rather gradually increases over time from the start, and when it reaches a certain level, it enters a state of "sleepiness" or "very sleepy."
    • The phenomenon of the sanity value increasing from 0 over time has also been confirmed.
  • This is speculation, but I think that the madness level and sleep value should originally be designed as different values, but at the current stage of EA23.54, there is a bug where these two values become one.
    • In fact, no matter how much I searched in Elin Decompiled, I did not find any code that increases SAN value over time.
    • However, there is code that increases Sleepiness over time. Since SAN = Sleepiness, the SAN value is also increasing over time because of this.

EA23.63

  • This is confirmed to be a bug. In this version, SAN and sleepiness are separated into two values.
  • SAN will not increase over time automatically. However, we expect the sleepiness value might not be so obvious now. Furthermore, SAN might become harder to decrease (previously you just need to sleep it off).

DV&PV

    public override int DV
	{
		get
		{
			if (IsPCFaction)
			{
				return elements.Value(64) / ((!HasCondition<ConWeakness>()) ? 1 : 2);
			}
			int num = base.LV;
			if (num > 50)
			{
				num = 50 + (num - 50) / 10;
			}
			return (num + elements.Value(64) * (100 + num + race.DV * 5) / 100) / ((!HasCondition<ConWeakness>()) ? 1 : 2);
		}
	}

	public override int PV
	{
		get
		{
			if (IsPCFaction)
			{
				return elements.Value(65) / ((!HasCondition<ConWeakness>()) ? 1 : 2);
			}
			int num = base.LV;
			if (num > 50)
			{
				num = 50 + (num - 50) / 10;
			}
			return (num + elements.Value(65) * (100 + num + race.PV * 5) / 100) / ((!HasCondition<ConWeakness>()) ? 1 : 2);
		}
	}
  • For DV and PV, the calculation is as the following:
    • If character is in player faction, then the DV and PV is calculated using the base DV and PV or equipments, etc.
    • If the character is debuffed with weakness, the DV and PV is halved.
    • If chracter is not in player faction, we first record the level of character.
    • If level is greater than 50, the base number is recorded to 50 + (num - 50) / 10.
    • This number is not affected by weakness.
    • The equipment DV and PV is modified by (100 + num + racePV * 5) / 100, then calculated with the weakness condition.
    • For example, for a fairy (race DV of 25), not in player faction, with LVL of 80, and equipment DV of 200, PV of 50:
    • The actual DV is (53 + 200 * (100 + 53 + 25 * 5) / 100 = 53 + 556 = 609.
    • The actual PV is (53 + 50 * (100 + 53 + 0 * 5) / 100 = 53 + 78.5 = 131.5.
  • As you could see, the DV and PV of monsters are heavily buffed based on their level, at least 50 + base value * 150% for each value at level 50.
  • Although the scaling above lvl 50 is reduced to 1/10, this must be considered combined with the damage reduction with increase of lvl beyond 50.