-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExperience.cs
More file actions
100 lines (86 loc) · 3.87 KB
/
Experience.cs
File metadata and controls
100 lines (86 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using System;
using UnityEngine;
using UnityEngine.Events;
using Mirror;
namespace uMMORPG
{
[RequireComponent(typeof(Level))]
[DisallowMultipleComponent]
public class Experience : NetworkBehaviour
{
[Header("Components")]
public Level level;
[Header("Experience")] // note: int is not enough (can have > 2 mil. easily)
[SyncVar, SerializeField] long _current = 0;
public long current
{
get { return _current; }
set
{
if (value <= _current)
{
// decrease
_current = Math.Max(value, 0);
}
else
{
// increase with level ups
// set the new value (which might be more than expMax)
_current = value;
// now see if we leveled up (possibly more than once too)
// (can't level up if already max level)
while (_current >= max && level.current < level.max)
{
// subtract current level's required exp, then level up
_current -= max;
++level.current;
// call event
onLevelUp.Invoke();
}
// set to expMax if there is still too much exp remaining
if (_current > max) _current = max;
}
}
}
// required experience grows by 10% each level (like Runescape)
[SerializeField] protected ExponentialLong _max = new ExponentialLong{multiplier=100, baseValue=1.1f};
public long max { get { return _max.Get(level.current); } }
[Header("Death")]
public float deathLossPercent = 0.05f;
[Header("Events")]
public UnityEvent onLevelUp;
// helper functions ////////////////////////////////////////////////////////
public float Percent() =>
(current != 0 && max != 0) ? (float)current / (float)max : 0;
// players gain exp depending on their level. if a player has a lower level
// than the monster, then he gains more exp (up to 100% more) and if he has
// a higher level, then he gains less exp (up to 100% less)
// -> see tests for several commented examples!
public static long BalanceExperienceReward(long reward, int attackerLevel, int victimLevel, int maxLevelDifference = 20)
{
// level difference 10 means 10% extra/less per level.
// level difference 20 means 5% extra/less per level.
// so the percentage step depends on the level difference:
float percentagePerLevel = 1f / maxLevelDifference;
// calculate level difference. it should cap out at +- maxDifference to
// avoid power level exploits where a level 1 player kills a level 100
// monster and immediately gets millions of experience points and levels
// up to level 50 instantly. this would be bad for MMOs.
// instead, we only consider +- maxDifference.
int levelDiff = Mathf.Clamp(victimLevel - attackerLevel, -maxLevelDifference, maxLevelDifference);
// calculate the multiplier. it will be +10%, +20% etc. when killing
// higher level monsters. it will be -10%, -20% etc. when killing lower
// level monsters.
float multiplier = 1 + levelDiff * percentagePerLevel;
// calculate reward
return Convert.ToInt64(reward * multiplier);
}
// events //////////////////////////////////////////////////////////////////
[Server]
public virtual void OnDeath()
{
// lose experience
current -= Convert.ToInt64(max * deathLossPercent);
}
}
}