Elin:Code Analysis/Faith


Piety and Gift

Gift at which piety level?

    int num = EClass.pc.Evalue(85);
	if (giftRank == 0 && (num >= 15 || EClass.debug.enable))
		{
			Talk("pet");
			Chara chara = CharaGen.Create(source.rewards[0]);
			EClass._zone.AddCard(chara, point);
			chara.MakeAlly();
			chara.PlayEffect("aura_heaven");
			giftRank = 1;
			return true;
		}
	if (source.rewards.Length >= 2 && giftRank == 1 && (num >= 30 || EClass.debug.enable))
		{
			Talk("gift");
			string[] array = source.rewards[1].Split('|');
			string[] array2 = array;
			foreach (string text in array2)
			{
				Reforge(text, point, text == array[0]);
			}
			giftRank = 2;
			return true;
		}
  • As of EA23.61, there are two Gift ranks for each god, and each of them is hardcoded at piety level 15 and 30. You will recieve a gift after reach each of these levels then manually pray to the god.

What messages are shown at which threshold?

    int num = Mathf.Max(c.Evalue(306), 1);
    int num2 = 4;
	if (orCreateElement.vBase >= num)
		{
			c.elements.SetBase(orCreateElement.id, num);
		}
    else
		{
			num2 = Mathf.Clamp(orCreateElement.vBase * 100 / num / 25, 0, 3);
		}
	if (num2 == 4 || orCreateElement.Value != value)
		{
			Msg.Say("piety" + num2, c, c.faith.TextGodGender);
		}
  • The above code controls the faith message when your piety levels up.
  • There are 5 messages in all, determined by num2, ranging from (0~4).
  • num2 will be calculated using your (Piety level / Faith level) * 4,rounded down to the nearest integer.
    • So if <25%, num2 = 0; 25%~50%, num2 = 1, 50%~75%, num2 = 2, >75%, num2 = 3.
  • If you are already at the maximum piety level, num2 = 4
  • Then depend on num2, different message will be played.
  • If you are at maximum piety (num2 = 4), then a message will always be shown.

What message is shown at which offer value?

public int GetOfferingValue(Thing t, int num = -1)
	{
		if (num == -1)
		{
			num = t.Num;
		}
		int num2 = 0;
		if (t.source._origin == "meat")
		{
			num2 = Mathf.Clamp(t.SelfWeight / 10, 1, 1000);
			if (t.refCard == null)
			{
				num2 /= 10;
			}
		}
		else
		{
			string[] cat_offer = source.cat_offer;
			foreach (string key in cat_offer)
			{
				if (t.category.IsChildOf(key))
				{
					num2 = Mathf.Clamp(t.SelfWeight / 10, 50, 1000);
					num2 *= EClass.sources.categories.map[key].offer / 100;
					break;
				}
			}
		}
		if (num2 == 0)
		{
			return 0;
		}
		if (t.IsDecayed)
		{
			num2 /= 10;
		}
		num2 = num2 * (100 + Mathf.Min(t.LV * 2, 100) + (t.HasElement(757) ? 50 : 0)) / 100; 
		return Mathf.Max(num2, 1) * num;
	}
  • The offer value is calculated with the following
  • num is the number of items you offered.
  • num2 will be the offering value per item, with minimum value of "1".
  • If the item is meat, then;
    • The weight of meat is divided by 10 (to know that 1000 weight = 1.0s), with minimum value of 1 and maximum value of 1000.
    • If this meat is unlabelled (i.e. not being a meat drop by entity) the value is further divided by 10.
    • Because the divide operator is rounding down to nearest int, this means it is possible to obtain 0 offer value if you are offering unlabelled meat lower than 0.1s.
  • If the item is of category a god will take (not meat), then:
    • The weight of item is divided by 10, but with a minimum value of 50 and maximum value of 1000.
      • Therefore, the weight of item will still count, but anything less than 0.5s will count as 0.5s.
    • The number is then multiplied by the category value.
      • As of EA23.61, the multipler apply to instrument(*5), rod (*3), catalyst (*3), ancient book (*5), spell book (*4), skill book (*10), map (*4).
  • If the item is decayed (rotten), the offer value is further divided by 10.
    • Because the decayed check is done after the 0 offer value check, you won't get 0 offer value if your item is only rotten, but lablled.
    • For example a labelled, 0.7s non-rotten meat will generate a offer value of 70.
  • The final value is modified by the following:
    • The offer value will increase by 2% per each level of the item, at most 100% (for LV 50). (See in resource/things/LV. Meat and most items are LV 1, most equipments range from 10-20, rarest at lv 60)
      • ...At least that is what SUPPOSED TO HAPPEN! Because C# treat divide operator between two integers as round down to an int, instead of creating a float number, this code basically does ABSOLUTELY NOTHING when LV < 50.
      • This is confirmed to be a bug, and was fixed in EA23.62 Nightly Hotfix 1.
    • A further 50% additive modifier is applied if "Just cooked" state is on the offering item.
public void _OnOffer(Chara c, Thing t, int takeoverMod = 0)
	{
		bool @bool = t.GetBool(115);
		int offeringValue = Deity.GetOfferingValue(t, t.Num);
		offeringValue = offeringValue * (c.HasElement(1228) ? 130 : 100) / 100;
		if (takeoverMod == 0)
		{
			if (offeringValue >= 200)
			{
				Msg.Say("god_offer1", t);
				EClass.pc.faith.Talk("offer");
			}
			else if (offeringValue >= 100)
			{
				Msg.Say("god_offer2", t);
			}
			else if (offeringValue >= 50)
			{
				Msg.Say("god_offer3", t);
			}
			else
			{
				Msg.Say("god_offer4", t);
			}
		}
		else
		{
			Msg.Say("god_offer1", t);
			offeringValue += Deity.GetOfferingValue(t, 1) * takeoverMod;
		}
        int num = Mathf.Max(c.Evalue(306), 1);
		Element orCreateElement = c.elements.GetOrCreateElement(85);
		int value = orCreateElement.Value;
		c.elements.ModExp(orCreateElement.id, offeringValue * 2 / 3);
  • The previously calculated offeringValue will return to this function, then the message displayed will be determined.
  • But first, if the character is demigod, the offeringValue will be further offset by 30%.
  • The offering value threshold for each message is 200, 100, 50.
    • So a piece of meat of 2.2s should generate the best possible message...but a 1.7s meat will not (tested).
  • HOWEVER, the experience gained towards Piety is only calculated at two-thirds of the offering value.
    • The "the 30 piety" mentioned in the previous wiki was estimated when the code of piety was not known, and was calculated using the minimum value of God's favorite (excluding corpses) as one point of the base value.
    • The 30 piety value in wiki is, in fact, the level up experience requirement for piety level, which is 1000.
      • 1 piety value = 33 piety experience = 33 * 3 / 2 = 50 offer value.
      • Thus to increase piety level by 1, you need to offer items with 1500 offer value, thus gaining 1000 piety experiences.

Piety level up

if (element.vExp >= element.ExpToNext)
		{
			int num = element.vExp - element.ExpToNext;
			int vBase = element.vBase;
			ModBase(ele, 1);
			OnLevelUp(element, vBase);
			element.vExp = Mathf.Clamp(num / 2, 0, element.ExpToNext / 2);
			if (element.vTempPotential > 0)
			{
				element.vTempPotential -= element.vTempPotential / 4 + EClass.rnd(5) + 5;
				if (element.vTempPotential < 0)
				{
					element.vTempPotential = 0;
				}
			}
			else if (element.vTempPotential < 0)
			{
				element.vTempPotential += -element.vTempPotential / 4 + EClass.rnd(5) + 5;
				if (element.vTempPotential > 0)
				{
					element.vTempPotential = 0;
				}
			}
		}
  • This, in fact, apply to all level ups.
    • If you increased your piety level, the remaining experiences will be cut in half, then at most half to the next level can be retained.
      • So if you gained 3000 piety exp, you leveled up from empty, remaining is 2000 exp, but you can only retain 500 exp (half to the next level)
      • This is the reason for the "45 piety value max" in early version of this wiki.

Ehekatl's School of Magic

The relevant code relating to the randomized mana and stamina costs is as such:

    if (a < 0 && BaseStats.CC.HasElement(1330, 1))        
    {            
        a = -EClass.rnd(-a * 130 / 100 + 2);       
    }

This means that if there is a mana or stamina cost, the new cost is determined by taking a random number between 0 and 1.3 times the original cost plus 2. So in a case where a spell has a cost of 40, it would be randomised between 0 and 54.