|
59 | 59 | SKILL_FITNESS = EXP_NONE, |
60 | 60 | ) |
61 | 61 |
|
62 | | - /// Progress towards increasing their skill level |
| 62 | + /// Progress towards increasing their skill level. |
63 | 63 | var/list/exp_progress = list( |
64 | 64 | SKILL_PHYSIOLOGY = 0, |
65 | 65 | SKILL_MECHANICAL = 0, |
|
68 | 68 | SKILL_FITNESS = 0, |
69 | 69 | ) |
70 | 70 |
|
71 | | - /// One-time experience gains that have already been acquired |
72 | | - var/list/unique_exp = list() |
| 71 | + /// One-time experience gains that have already been acquired. |
| 72 | + var/list/exp_sources = list() |
73 | 73 |
|
74 | 74 | /// Free skill points to allocate |
75 | 75 | var/skill_points = 0 |
|
121 | 121 | key = _key |
122 | 122 | soulOwner = src |
123 | 123 | martial_art = default_martial_art |
| 124 | + RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_EXCEPTIONAL_SKILL), PROC_REF(update_skills)) |
124 | 125 |
|
125 | 126 | /datum/mind/Destroy() |
126 | 127 | SSticker.minds -= src |
|
813 | 814 | return FALSE |
814 | 815 | if(!amount) |
815 | 816 | return FALSE |
816 | | - if(source && (source in mind.unique_exp)) |
| 817 | + if(source && (source in mind.exp_sources)) |
817 | 818 | return FALSE |
818 | | - mind.unique_exp.Add(source) |
819 | | - var/exp_required = EXPERIENCE_PER_LEVEL * (2**mind.skills[skill]) // exp required scales exponentially |
820 | | - if(mind.exp_progress[skill] + amount >= exp_required) |
821 | | - var/levels_gained = round(log(2, 1 + (mind.exp_progress[skill] + amount) / exp_required)) // in case you gained so much you go up more than one level |
822 | | - var/levels_allocated = hud_used?.skill_menu ? hud_used.skill_menu.allocated_skills[skill] : 0 |
823 | | - if(levels_allocated > 0) // adjust any already allocated skills to prevent shenanigans (you know who you are) |
824 | | - hud_used.skill_menu.allocated_points -= min(levels_gained, levels_allocated) |
825 | | - hud_used.skill_menu.allocated_skills[skill] -= min(levels_gained, levels_allocated) |
826 | | - mind.exp_progress[skill] += amount - exp_required * (2**(levels_gained - 1)) |
827 | | - mind.skill_points = max(mind.skill_points - levels_gained, 0) // remove an equal amount of unallocated skill points to prevent exploits |
828 | | - adjust_skill(skill, levels_gained) |
829 | | - to_chat(src, span_boldnotice("Your [skill] skill is now level [get_skill(skill)]!")) |
| 819 | + mind.exp_sources.Add(source) |
830 | 820 | mind.exp_progress[skill] += amount |
| 821 | + var/levels_gained = check_exp(skill) |
| 822 | + if(levels_gained) // remove an equal amount of unallocated skill points to prevent exploits |
| 823 | + mind.skill_points = max(mind.skill_points - levels_gained, 0) |
831 | 824 | return TRUE |
832 | 825 |
|
833 | | -/// Returns whether experience has been gained from a given source |
| 826 | +/// Levels up a skill if it has enough experience to do so. |
| 827 | +/mob/proc/check_exp(skill) |
| 828 | + if(!mind) |
| 829 | + return FALSE |
| 830 | + var/current_level = get_skill(skill) |
| 831 | + var/exp_required = EXPERIENCE_PER_LEVEL * (2**current_level) // exp required scales exponentially |
| 832 | + if(mind.exp_progress[skill] < exp_required) |
| 833 | + return FALSE |
| 834 | + var/skill_cap = EXP_MASTER + HAS_MIND_TRAIT(src, TRAIT_EXCEPTIONAL_SKILL) |
| 835 | + var/levels_gained = min(round(log(2, 1 + (mind.exp_progress[skill] / exp_required))), max(skill_cap - current_level)) // in case you gained so much you go up more than one level |
| 836 | + if(levels_gained < 1) |
| 837 | + return FALSE |
| 838 | + var/levels_allocated = hud_used?.skill_menu ? hud_used.skill_menu.allocated_skills[skill] : 0 |
| 839 | + if(levels_allocated > 0) // adjust any already allocated skills to prevent shenanigans (you know who you are) |
| 840 | + hud_used.skill_menu.allocated_points -= min(levels_gained, levels_allocated) |
| 841 | + hud_used.skill_menu.allocated_skills[skill] -= min(levels_gained, levels_allocated) |
| 842 | + mind.exp_progress[skill] -= exp_required * (((2**round(levels_gained + 1)) / 2) - 1) |
| 843 | + adjust_skill(skill, levels_gained, max_skill = skill_cap) |
| 844 | + to_chat(src, span_boldnotice("Your [skill] skill is now level [get_skill(skill)]!")) |
| 845 | + return levels_gained |
| 846 | + |
| 847 | +/// Returns whether experience has been gained from a given source. |
834 | 848 | /mob/proc/has_exp(source) |
835 | 849 | if(!mind) |
836 | 850 | return FALSE |
837 | | - return (source in mind.unique_exp) ? TRUE : FALSE |
| 851 | + return (source in mind.exp_sources) ? TRUE : FALSE |
838 | 852 |
|
839 | 853 | /// Adds skill points to be allocated at will. |
840 | 854 | /mob/proc/add_skill_points(amount) |
|
843 | 857 | mind.skill_points += amount |
844 | 858 | throw_alert("skill points", /atom/movable/screen/alert/skill_up) |
845 | 859 |
|
| 860 | +/// Called when [TRAIT_EXCEPTIONAL_SKILL] is added to the mob. |
| 861 | +/datum/mind/proc/update_skills(datum/source) |
| 862 | + SIGNAL_HANDLER |
| 863 | + if(!current) |
| 864 | + return |
| 865 | + for(var/skill in skills) |
| 866 | + current.check_exp(skill) |
| 867 | + |
846 | 868 | /datum/mind/proc/has_martialart(string) |
847 | 869 | if(martial_art && martial_art.id == string) |
848 | 870 | return martial_art |
|
0 commit comments