Elin:Code Analysis/Housing: Difference between revisions

From Ylvapedia
No edit summary
Line 30: Line 30:
|Publicity
|Publicity
|}
|}
<syntaxhighlight lang="c#" line="1" start="0">
Found in FactionBranch.cs on line 374.<syntaxhighlight lang="c#" line="1" start="0">


if (EClass.rnd(5) == 0 && this.policies.IsActive(2810, -1))
if (EClass.rnd(5) == 0 && this.policies.IsActive(2810, -1))
Line 75: Line 75:
             }
             }
         }
         }
</syntaxhighlight>So there's a 80% chance if open for business is active, then
</syntaxhighlight>
 
* 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<sup>^</sup>] *  ((100 + Your Land's Attractiveness + 200<sup>^^</sup>) / 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.
* 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.
 
^<sup>This is if you have a settlement with an Ancient Ruin present</sup>
 
^^<sup>Currently unsure if this is 200 or 20</sup>
 
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 . . .


num8 = 3 + (I'm guessing land lvl) + (attractiveness  / 5) + (If ancient ruin value is active then, it * 2) + publicity / 2
And you had 100 Publicity and 100 Tourist Safety:


num8 = num8 (from above) * (100 + ancient ruin * 20 + attractiveness) / 100
You could expect to find that:


num8 = num8 (from above) * (100 + integer of the sqrt((of a float of tourist safety) * 3) / 100)
* [3 + 7 + (10 + 15) / 5 + 50 + 20] = 85
* 85 * ((100 + 25 + 200<sup>^^</sup>) / 100) = 276.25
* 276.25 * ((100 + sqrt(100 * 3) / 100) = 323 visitors an hour.


Then if Celeb heaven is on AND the sqrt(Celeb heaven / 2) + 5 is greater than or equal to a random number from 1-100
IF you assumed that the ^^ amount was 20, instead of 200, then:


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


wealthy visitors are generated (based on something called content lvl (which may be danger lvl))
=== Let's look at a low end example: ===
If you were just using a maxed level Meadow . . .


add the random visitors somewhere random
And you had 10 Publicity and 10 Tourist Safety:


Then the next lines check to say if its a mother and if you have the anti mother policy
You could expect to find that:


Then they get an allowance of their character level * 100,
* [3 + 7 + 5 + 20] = 35
* 35 * (100/100) = 35
* 35 * ((100 + sqrt(10*3) / 100) = 36 visitors an hour.


and if they're wealthy its * 1000


TLDR; if you want to build a settlement that generates orens through visitors you should use a snowy / ancient ruin tile
Further testing is required.


== Housing: Taxes ==
== Housing: Taxes ==
Line 114: Line 134:
|Resident Tax
|Resident Tax
|}
|}
<syntaxhighlight lang="c#" line="1" start="1">
Found in FactionBranch.cs on line 819.<syntaxhighlight lang="c#" line="1" start="1">
public int GetResidentTax()
public int GetResidentTax()
{
{
Line 169: Line 189:
*** If not wealthy: (10 + 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.
**** 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.
** Now we go to the policies.
Line 188: Line 207:
** 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?
** 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 ==
{| class="wikitable"
|+
!Value#
!Element
|-
|(750)
|Bed Comfort
|-
|(2812)
|Traveler's Inn Policy
|-
|(2813)
|Luxury Suite Policy
|}
Found in FactionBranch.cs on line 865.<syntaxhighlight lang="c#" line="1">
    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);
    }
</syntaxhighlight>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<sup>^^</sup>) / 15) + 5)
The income from your Inn in total is now num4 / 2 rounded down * 2
^<sup>This number is a value currently hidden without the use of mods to detect it.</sup>


^^<sup>It is currently unclear what This.Worth is. Speculation is that it is the value of your entire settlement.</sup>
[[Category:Elin Spoiler]]
[[Category:Elin Spoiler]]
[[Category:EN]]
[[Category:EN]]

Revision as of 21:23, 4 January 2025


Housing: Visitors / Publicity / Attractiveness

This is (TENATIVELY) the code block that determines the amount of visitors that visit a settlement and the type of visitors that visit.

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.
  • 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

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

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

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 from your Inn in total is now num4 / 2 rounded down * 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.