Elin:Code Analysis/Housing

From Ylvapedia
Version EA23.74: This article is up to date for the latest stable release of Elin.

Housing: Visitors / Publicity / Attractiveness

This is the section dedicated to understanding the amount of visitors that come to visit your settlement.

Value# Element
(2206) Attraction
(2811) Tourist Safety
(3702) Ancient Ruin
(2822) Celebrity's Heaven
(2810) Open for Buisness
(2710) Motherless Zone
(2202) Publicity

Found in FactionBranch.cs on line 374.

if (EClass.rnd(5) == 0 && this.policies.IsActive(2810, -1))
        {
            int num8 = 3 + this.lv + this.Evalue(2206) / 5 + this.Evalue(3702) * 2 + this.Evalue(2202) / 2;
            num8 = num8 * (100 + this.Evalue(3702) * 20 + this.Evalue(2206)) / 100;
            num8 = num8 * (100 + (int)Mathf.Sqrt((float)this.Evalue(2811)) * 3) / 100;
            if (EClass._map.CountGuest() < num8)
            {
                Chara chara;
                if (this.policies.IsActive(2822, -1) && Mathf.Sqrt((float)(this.Evalue(2822) / 2)) + 5f >= (float)EClass.rnd(100))
                {
                    chara = CharaGen.CreateWealthy(this.ContentLV);
                    EClass._zone.AddCard(chara, EClass._zone.GetSpawnPos(SpawnPosition.Random, 100) ?? EClass._map.GetRandomSurface(false, true, false));
                }
                else
                {
                    chara = EClass._zone.SpawnMob(null, SpawnSetting.HomeGuest(this.ContentLV));
                }
                if (chara != null && (chara.id == "nun_mother" || chara.id == "prostitute") && this.policies.IsActive(2710, -1))
                {
                    chara.Destroy();
                    chara = null;
                }
                if (chara != null)
                {
                    this.statistics.visitor++;
                    chara.memberType = FactionMemberType.Guest;
                    chara.SetInt(34, EClass.world.date.GetRaw(0));
                    chara.c_allowance = chara.LV * 100;
                    if (chara.IsWealthy)
                    {
                        chara.c_allowance *= 10;
                    }
                    if (date.IsRealTime)
                    {
                        Msg.Say("guestArrive", chara.Name, null, null, null);
                    }
                    else
                    {
                        chara.TryAssignBed();
                    }
                }
            }
        }
  • So there's a 80% chance per hour that if the policy: "Open for Business" is active, then:
    • A number of visitors will arrive. This number is: [3 + Land lvl + Your Land's Attractiveness / 5 + Publicity / 2 + 20^] * ((100 + Your Land's Attractiveness + 200^^) / 100) * (100 + sqrt(Tourist Safety lvl * 3) / 100)
    • Then if the policy of Celebrity's Heaven is active and the sqrt(Celebrity's Heaven lvl / 2) + 5 is greater than or equal to a random number from 1-100 THEN
    • Wealthy visitors are generated based on the Danger Level of the zone. The higher the Danger Level of the zone, the higher the level of the tourists, ergo the more money they bring with them. Therefore it is actually beneficial to turn on the "Demonic Invocation" policy to maximize gains. On another note: It may be beneficial to turn on Nocturnal Life, as it is believed that the visitors and therefore the profit from visitors are generated hourly.^^^
  • If you do not have the Mother Prohibited Zone policy active, mothers can spawn.
    • Each visitor gets an allowance of their Character Level * 100. If they are wealthy its: Character Level * 1000.

^This is if you have a settlement with an Ancient Ruin present

^^Currently unsure if this is 200 or 20

^^^Not tested yet.

It is highly advisable to make a settlement for Inns / Tourism in a Snowy Biome with an Ancient Ruin.

Let's look at a high end example:

If you had a maxed level Snowy Biome settlement with an Ancient Ruin preset as a feature, then . . .

And you had 100 Publicity and 100 Tourist Safety:

You could expect to find that:

  • [3 + 7 + (10 + 15) / 5 + 50 + 20] = 85
  • 85 * ((100 + 25 + 200^^) / 100) = 276.25
  • 276.25 * ((100 + sqrt(100 * 3) / 100) = 323 visitors an hour.

IF you assumed that the ^^ amount was 20, instead of 200, then:

The amount of visitors you would expect = 144 visitors an hour.

Let's look at a low end example:

If you were just using a maxed level Meadow . . .

And you had 10 Publicity and 10 Tourist Safety:

You could expect to find that:

  • [3 + 7 + 5 + 20] = 35
  • 35 * (100/100) = 35
  • 35 * ((100 + sqrt(10*3) / 100) = 36 visitors an hour.


Further testing is required.

Housing: Taxes

This is the section dedicated to understanding the amount of profit generated when assigning taxes to your own residents.

Value# Element
(2500) Wealth Tax
(2501) Faith Tax
(2512) Resident Tax

Found in FactionBranch.cs on line 819.

	public int GetResidentTax()
	{
		if (!policies.IsActive(2512, 30))
		{
			return 0;
		}
		int num = 0;
		int num2 = (policies.IsActive(2500, 30) ? Evalue(2500) : 0);
		int num3 = (policies.IsActive(2501, 30) ? Evalue(2501) : 0);
		int num4 = 50 + (int)Mathf.Sqrt(Evalue(2512)) * 5;
		foreach (Chara member in members)
		{
			if (member.IsPC || member.memberType != 0)
			{
				continue;
			}
			bool isWealthy = member.IsWealthy;
			int num5 = 0;
			foreach (Hobby item in member.ListWorks().Concat(member.ListHobbies()))
			{
				int num6 = item.source.tax * 100 / 100;
				if (num6 > num5)
				{
					num5 = num6;
				}
			}
			int num7 = ((isWealthy ? 50 : 10) + member.LV * 2) * num5 / 100 * num4 / 100;
			if (isWealthy && num2 > 0)
			{
				num7 = num7 * (150 + (int)Mathf.Sqrt(num2) * 5) / 100;
			}
			if (num3 > 0)
			{
				num7 += (80 + (int)Mathf.Sqrt(num3) * 5) * member.faith.source.tax / 100;
			}
			num7 = num7 * efficiency / (IsTaxFree ? 100 : 1000);
			num += num7;
			if (num7 > 0)
			{
				Log("bTax", num7.ToString() ?? "", member.Name);
			}
		}
		statistics.tax += num;
		return num;
	}
  • The policy of wealth tax, faith tax, and resident tax must already have been enabled for 30 days, for these policies to count.
    • The base tax percentage for each resident is calculated with (50 + Square root of resident tax lvl * 5).
    • Each hobby of resident have a different tax base, this we call "hobby tax standard", we take the maximum among all hobbies of that resident.
      • For example, Reading is 120, Lottery is 140, Gacha is 160 (don't play gacha games guys), Smoking is 300, Extravagance is 400, Rambo is 30, and Supervisor is 0.
    • The overall tax for a resident is calculated as:
      • If wealthy: (50 + resident level * 2) * base tax percentage% * hobby tax standard%.
      • If not wealthy: (10 + resident level * 2) * base tax percentage% * hobby tax standard%.
        • For example, a wealthy citizen of lv 5, whose hobby is reading and the resident tax policy level is 9, his tax is (50 + 2 * 5)* 120% * 65% = 46.8.
    • Now we go to the policies.
      • If wealthy & wealthy tax activated:
        • the overall tax is modified by (150 + sqrt of wealthy tax policy lvl * 5)%.
      • If faith tax is activated:
        • the overall tax is modified by +(80 + sqrt of faith tax policy lvl) * Faith tax rate%.
          • The faith tax rate is different for each religion. Eyth of void: 500%. Ehekatl of luck: 300%, The lowest is Yakasha of Oblivion: 0%, and Lulwy of Wind: 25%.
    • Finally, this tax rate is penalized for lack of efficiency or not in tax free land.
      • If your land is not tax free, all resident tax will be penalized by 90%!


  • Let's look at an example.
    • Here is a wealthy citizen, who has a hobby of Gacha, and is lvl 50, and he is worshiping Eyth of void. All your tax policies is at lvl 100, but the land is not tax free.
      • The overall tax before policies is : (50 + 50 * 2) * 160% * (50+50)% = 240 orens.
      • We then have wealthy tax, modified to 240 * (150 + 50)% = 480 orens
      • Then the faith tax modified to 480 + (80 + 50) * 500% = 1230 orens.
    • But your land is not tax free, so the final tax is 123 orens. Making your blood boil already? Wanna buy a nuke for Mysilia?

Housing: Innkeeping

This is the section dedicated to understanding the amount of profit generated when assigning beds to guests.

Value# Element
(750) Bed Comfort
(2812) Traveler's Inn Policy
(2813) Luxury Suite Policy

Found in FactionBranch.cs on line 865.

    public void CalcInnIncome()
    {
        int num = this.CountGuests();
        if (num == 0)
        {
            return;
        }
        int num2 = 0;
        int num3 = 0;
        foreach (Thing thing in EClass._map.things)
        {
            if (thing.IsInstalled)
            {
                TraitBed traitBed = thing.trait as TraitBed;
                if (traitBed != null && traitBed.owner.c_bedType == BedType.guest)
                {
                    int maxHolders = traitBed.MaxHolders;
                    num2 += maxHolders;
                    num3 += traitBed.owner.LV * (100 + traitBed.owner.Quality / 2 + traitBed.owner.Evalue(750) / 2) / 100 * maxHolders;
                }
            }
        }
        num = Mathf.Min(num, num2);
        if (num == 0)
        {
            return;
        }
        num3 /= num2;
        num3 = num3 * (100 + 5 * (int)Mathf.Sqrt((float)this.Evalue(2812))) / 100;
        float num4 = 10f + Mathf.Sqrt((float)num) * 10f;
        if (this.policies.IsActive(2813, -1))
        {
            num4 += Mathf.Sqrt((float)this.CountWealthyGuests()) * 50f * (80f + 5f * Mathf.Sqrt((float)this.Evalue(2813))) / 100f;
        }
        if (this.policies.IsActive(2812, -1))
        {
            num4 = num4 * (float)(100 + num3) / 100f;
        }
        num4 = Mathf.Min(num4, Mathf.Sqrt((float)this.Worth) / 15f + 5f);
        this.incomeInn += EClass.rndHalf((int)num4) + EClass.rndHalf((int)num4);
    }

Num is the count of all guests in your base.

If there's a single bed assigned to guests then:

  • Num2 is now max holders Num3 = Guest Bed Value^ * ( 100 + bed quality / 2 + bed comfort value / 2 ) / 100 * max holders.
  • The new Num is the min of the count of guests or the max holders of beds.
  • Num3 is now Num3 / Num2
  • Num3 = num3 * ( 100 + ( 5 * sqrt (Traveler's Inn policy lvl ) ) ) / 100. Num4 = 10 + 10 * sqrt ( Num )

IF the Luxury Suite policy is active, then Num4 = Num4 + sqrt (Wealthy Guest Count * 50 * ( 80 + 5 * sqrt ( Luxury Suite policy lvl ) ) ) / 100

IF the Traveler's Inn policy is active, then Num4 = Num4 * ( 100 + Num3 ) / 100

Num4 = the min of ( num4 or ( sqrt (This.Worth^^) / 15) + 5)

The income is equal to: Num4 + a random number between (1 - Num4 / 2) + a random number between (1 - Num4 / 2)

^This number is a value currently hidden without the use of mods to detect it.

^^It is currently unclear what This.Worth is. Speculation is that it is the value of your entire settlement.