[READY] Adds a basic skill framework to Physiology. (Only applied to mining) (#46913)

* levels

* mining

* ore exp

* fixes

* epic

* Update code/game/turfs/simulated/minerals.dm

Co-Authored-By: moo <11748095+ExcessiveUseOfCobblestone@users.noreply.github.com>

* fixes message

* dumb

* shreet

* epic

* fix

* ass

* scrape

* fixes bugs

* fixes

* reset

* test

* ??

* ok bye

* fix

* Adds skills

* skill
This commit is contained in:
Qustinnus
2019-10-19 01:59:35 +02:00
committed by moo
parent 91c5494382
commit b021210a2f
22 changed files with 283 additions and 15 deletions

View File

@@ -0,0 +1,23 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/template_noop)
"b" = (
/turf/closed/mineral/strong,
/area/template_noop)
(1,1,1) = {"
a
a
a
"}
(2,1,1) = {"
a
b
a
"}
(3,1,1) = {"
a
a
a
"}

19
code/__DEFINES/skills.dm Normal file
View File

@@ -0,0 +1,19 @@
// Skills
#define SKILL_LEVEL_NONE 0
#define SKILL_LEVEL_NOVICE 1
#define SKILL_LEVEL_APPRENTICE 2
#define SKILL_LEVEL_JOURNEYMAN 3
#define SKILL_LEVEL_EXPERT 4
#define SKILL_LEVEL_MASTER 5
#define SKILL_LEVEL_LEGENDARY 6
#define SKILL_EXP_NOVICE 100
#define SKILL_EXP_APPRENTICE 250
#define SKILL_EXP_JOURNEYMAN 500
#define SKILL_EXP_EXPERT 900
#define SKILL_EXP_MASTER 1500
#define SKILL_EXP_LEGENDARY 2500
// Gets the reference for the skill type that was given
#define GetSkillRef(A) (SSskills.all_skills[A])

View File

@@ -118,7 +118,7 @@
#define INIT_ORDER_ATOMS 30
#define INIT_ORDER_LANGUAGE 25
#define INIT_ORDER_MACHINES 20
#define INIT_ORDER_CIRCUIT 15
#define INIT_ORDER_SKILLS 15
#define INIT_ORDER_TIMER 1
#define INIT_ORDER_DEFAULT 0
#define INIT_ORDER_AIR -1

View File

@@ -86,6 +86,7 @@
#define ui_crafting "EAST-4:22,SOUTH:5"
#define ui_building "EAST-4:22,SOUTH:21"
#define ui_language_menu "EAST-4:6,SOUTH:21"
#define ui_skill_menu "EAST-4:22,SOUTH:5"
#define ui_borg_pull "EAST-2:26,SOUTH+1:7"
#define ui_borg_radio "EAST-1:28,SOUTH+1:7"

View File

@@ -98,6 +98,12 @@
using.hud = src
static_inventory += using
using = new/obj/screen/skills
using.icon = ui_style
if(!widescreen_layout)
using.screen_loc = UI_BOXLANG
static_inventory += using
using = new /obj/screen/area_creator
using.icon = ui_style
if(!widescreen_layout)

View File

@@ -59,6 +59,17 @@
var/mob/M = usr
M.swap_hand()
return 1
/obj/screen/skills
name = "skills"
icon = 'icons/mob/screen_midnight.dmi'
icon_state = "skills"
screen_loc = ui_skill_menu
/obj/screen/skills/Click()
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
H.mind.print_levels(H)
/obj/screen/craft
name = "crafting menu"

View File

@@ -0,0 +1,23 @@
/*!
This subsystem mostly exists to populate and manage the skill singletons.
*/
SUBSYSTEM_DEF(skills)
name = "Skills"
flags = SS_NO_FIRE
init_order = INIT_ORDER_SKILLS
///Dictionary of skill.type || skill ref
var/list/all_skills = list()
///Static assoc list of levels (ints) - strings
var/list/level_names = list("Novice", "Apprentice", "Journeyman", "Expert", "Master", "Legendary")//This list is already in the right order, due to indexing
/datum/controller/subsystem/skills/Initialize(timeofday)
InitializeSkills()
return ..()
///Ran on initialize, populates the skills dictionary
/datum/controller/subsystem/skills/proc/InitializeSkills(timeofday)
for(var/type in subtypesof(/datum/skill))
var/datum/skill/ref = new type
all_skills[type] = ref

View File

@@ -196,7 +196,7 @@
beauty_modifier = 0.4
armor_modifiers = list("melee" = 1.5, "bullet" = 1.5, "laser" = 1.3, "energy" = 1.3, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 2.5, "acid" = 1)
///RPG Magic. (Admin only)
///RPG Magic.
/datum/material/mythril
name = "mythril"
id = "mythril"
@@ -205,8 +205,9 @@
categories = list(MAT_CATEGORY_RIGID = TRUE)
sheet_type = /obj/item/stack/sheet/mineral/mythril
value_per_unit = 0.75
strength_modifier = 1.2
armor_modifiers = list("melee" = 1.5, "bullet" = 1.5, "laser" = 1.5, "energy" = 1.5, "bomb" = 1.5, "bio" = 1.5, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5)
beauty_modifier = 0.5
armor_modifiers = list("melee" = 2, "bullet" = 2, "laser" = 2, "energy" = 2, "bomb" = 2, "bio" = 2, "rad" = 2, "fire" = 2, "acid" = 2)
/datum/material/mythril/on_applied_obj(atom/source, amount, material_flags)
. = ..()

View File

@@ -66,6 +66,11 @@
var/list/learned_recipes //List of learned recipe TYPES.
///Assoc list of skills - level
var/list/known_skills = list()
///Assoc list of skills - exp
var/list/skill_experience = list()
/datum/mind/New(key)
src.key = key
soulOwner = src
@@ -122,6 +127,63 @@
if(active || force_key_move)
new_character.key = key //now transfer the key to link the client to our new body
///Adjust experience of a specific skill
/datum/mind/proc/adjust_experience(skill, amt, silent = FALSE)
var/datum/skill/S = GetSkillRef(skill)
skill_experience[S] = max(0, skill_experience[S] + amt) //Prevent going below 0
var/old_level = known_skills[S]
switch(skill_experience[S])
if(SKILL_EXP_LEGENDARY to INFINITY)
known_skills[S] = SKILL_LEVEL_LEGENDARY
if(SKILL_EXP_MASTER to SKILL_EXP_LEGENDARY)
known_skills[S] = SKILL_LEVEL_MASTER
if(SKILL_EXP_EXPERT to SKILL_EXP_MASTER)
known_skills[S] = SKILL_LEVEL_EXPERT
if(SKILL_EXP_JOURNEYMAN to SKILL_EXP_EXPERT)
known_skills[S] = SKILL_LEVEL_JOURNEYMAN
if(SKILL_EXP_APPRENTICE to SKILL_EXP_JOURNEYMAN)
known_skills[S] = SKILL_LEVEL_APPRENTICE
if(SKILL_EXP_NOVICE to SKILL_EXP_APPRENTICE)
known_skills[S] = SKILL_LEVEL_NOVICE
if(0 to SKILL_EXP_NOVICE)
known_skills[S] = SKILL_LEVEL_NONE
if(known_skills[S] == old_level)
return //same level
if(silent)
return
if(known_skills[S] >= old_level)
to_chat(current, "<span class='nicegreen'>I feel like I've become more proficient at [S.name]!</span>")
else
to_chat(current, "<span class='warning'>I feel like I've become worse at [S.name]!</span>")
///Gets the skill's singleton and returns the result of its get_skill_speed_modifier
/datum/mind/proc/get_skill_speed_modifier(skill)
var/datum/skill/S = GetSkillRef(skill)
return S.get_skill_speed_modifier(known_skills[S])
/datum/mind/proc/get_skill_level(skill)
var/datum/skill/S = GetSkillRef(skill)
return known_skills[S]
/datum/mind/proc/print_levels(user)
var/msg
var/list/shown_skills = list()
for(var/i in known_skills)
if(known_skills[i])
shown_skills += i
if(!shown_skills.len)
msg += "<span class='notice'>You don't seem to have any particularly outstanding skills.</span>"
to_chat(user, msg)
msg += "<span class='info'>*---------*\n<EM>Your skills</EM>\n"
for(var/i in shown_skills)
var/datum/skill/S
msg += "<span class='notice'>[i] - [SSskills.level_names[known_skills[S.name]]]</span>"
to_chat(user, msg)
/datum/mind/proc/set_death_time()
last_death = world.time
@@ -317,6 +379,7 @@
else
traitor_mob.mind.store_memory(U.unlock_note)
//Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does.
/datum/mind/proc/enslave_mind_to_creator(mob/living/creator)

View File

@@ -223,9 +223,17 @@
suffix = "lavaland_surface_wizard.dmm"
cost = 5
/datum/map_template/ruin/lavaland/strong_stone
name = "Strong Stone"
id = "strong_stone"
description = "A stone that seems particularly powerful."
suffix = "lavaland_strong_rock.dmm"
allow_duplicates = FALSE
cost = 2
/datum/map_template/ruin/lavaland/puzzle
name = "Ancient Puzzle"
id = "puzzle"
description = "Mystery to be solved."
suffix = "lavaland_surface_puzzle.dmm"
cost = 5
cost = 5

View File

@@ -0,0 +1,6 @@
/datum/skill
var/name = "skill"
var/desc = "the art of doing things"
/datum/skill/proc/get_skill_speed_modifier(level)
return

View File

@@ -0,0 +1,20 @@
/datum/skill/mining
name = "mining"
desc = "A dwarf's biggest skill, after drinking."
/datum/skill/mining/get_skill_speed_modifier(level)
switch(level)
if(SKILL_LEVEL_NONE)
return 1.3
if(SKILL_LEVEL_NOVICE)
return 1.2
if(SKILL_LEVEL_APPRENTICE)
return 1.1
if(SKILL_LEVEL_JOURNEYMAN)
return 1
if(SKILL_LEVEL_EXPERT)
return 0.9
if(SKILL_LEVEL_MASTER)
return 0.75
if(SKILL_LEVEL_LEGENDARY)
return 0.5

View File

@@ -758,7 +758,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if(!delay && !tool_start_check(user, amount))
return
delay *= toolspeed
var/skill_modifier = 1
if(tool_behaviour == TOOL_MINING && ishuman(user))
var/mob/living/carbon/human/H = user
skill_modifier = H.mind.get_skill_speed_modifier(/datum/skill/mining)
delay *= toolspeed * skill_modifier
// Play tool sound at the beginning of tool usage.
play_tool_sound(target, volume)

View File

@@ -138,7 +138,7 @@
icons = list("bananium","bananium_dam")
var/spam_flag = 0
/turf/open/floor/mineral/bananium/Entered(var/mob/living/L)
/turf/open/floor/mineral/bananium/Entered(mob/living/L)
.=..()
if(!.)
if(istype(L))
@@ -191,7 +191,7 @@
var/last_event = 0
var/active = null
/turf/open/floor/mineral/uranium/Entered(var/mob/AM)
/turf/open/floor/mineral/uranium/Entered(mob/AM)
.=..()
if(!.)
if(istype(AM))

View File

@@ -15,7 +15,7 @@
temperature = TCMB
var/environment_type = "asteroid"
var/turf/open/floor/plating/turf_type = /turf/open/floor/plating/asteroid/airless
var/mineralType = null
var/obj/item/stack/ore/mineralType = null
var/mineralAmt = 3
var/spread = 0 //will the seam spread?
var/spreadChance = 0 //the percentual chance of an ore spreading to the neighbouring tiles
@@ -69,10 +69,18 @@
else
return attack_hand(user)
/turf/closed/mineral/proc/gets_drilled()
/turf/closed/mineral/proc/gets_drilled(user, give_exp = TRUE)
if (mineralType && (mineralAmt > 0))
new mineralType(src, mineralAmt)
SSblackbox.record_feedback("tally", "ore_mined", mineralAmt, mineralType)
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(give_exp)
if (mineralType && (mineralAmt > 0))
H.mind.adjust_experience(/datum/skill/mining, initial(mineralType.mine_experience) * mineralAmt)
else
H.mind.adjust_experience(/datum/skill/mining, 4)
for(var/obj/effect/temp_visual/mining_overlay/M in src)
qdel(M)
var/flags = NONE
@@ -84,7 +92,7 @@
/turf/closed/mineral/attack_animal(mob/living/simple_animal/user)
if((user.environment_smash & ENVIRONMENT_SMASH_WALLS) || (user.environment_smash & ENVIRONMENT_SMASH_RWALLS))
gets_drilled()
gets_drilled(user)
..()
/turf/closed/mineral/attack_alien(mob/living/carbon/alien/M)
@@ -521,3 +529,42 @@
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
/turf/closed/mineral/strong
name = "Very strong rock"
desc = "Seems to be stronger than the other rocks in the area. Only a master of mining techniques could destroy this."
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
smooth_icon = 'icons/turf/walls/rock_wall.dmi'
/turf/closed/mineral/strong/attackby(obj/item/I, mob/user, params)
if(!ishuman(user))
to_chat(usr, "<span class='warning'>Only a more advanced species could break a rock such as this one!</span>")
return FALSE
var/mob/living/carbon/human/H = user
if(H.mind.get_skill_level(/datum/skill/mining) >= SKILL_LEVEL_LEGENDARY)
. = ..()
else
to_chat(usr, "<span class='warning'>The rock seems to be too strong to destroy. Maybe I can break it once I become a master miner.</span>")
/turf/closed/mineral/strong/gets_drilled(user)
if(prob(10))
new /obj/item/stack/sheet/mineral/mythril(src, 5)
else
new /obj/item/stack/sheet/mineral/adamantine(src, 5)
var/flags = NONE
if(defer_change) // TODO: make the defer change var a var for any changeturf flag
flags = CHANGETURF_DEFER_CHANGE
ScrapeAway(flags=flags)
addtimer(CALLBACK(src, .proc/AfterChange), 1, TIMER_UNIQUE)
playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) //beautiful destruction
/turf/closed/mineral/strong/acid_melt()
return
/turf/closed/mineral/strong/ex_act(severity, target)
return

View File

@@ -60,6 +60,10 @@
var/display_order = JOB_DISPLAY_ORDER_DEFAULT
///Levels unlocked at roundstart in physiology
var/list/roundstart_experience
//Only override this proc
//H is usually a human unless an /equip override transformed it
/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
@@ -67,6 +71,11 @@
if(mind_traits)
for(var/t in mind_traits)
ADD_TRAIT(H.mind, t, JOB_TRAIT)
if(roundstart_experience && ishuman(H))
var/mob/living/carbon/human/experiencer = H
for(var/i in roundstart_experience)
experiencer.mind.adjust_experience(i, roundstart_experience[i], TRUE)
/datum/job/proc/announce(mob/living/carbon/human/H)
if(head_announce)

View File

@@ -16,6 +16,7 @@
singular_name = "ore chunk"
var/points = 0 //How many points this ore gets you from the ore redemption machine
var/refined_type = null //What this ore defaults to being refined into
var/mine_experience = 5 //How much experience do you get for mining this ore?
novariants = TRUE // Ore stacks handle their icon updates themselves to keep the illusion that there's more going
mats_per_stack = MINERAL_MATERIAL_AMOUNT
var/list/stack_overlays
@@ -74,6 +75,7 @@
material_flags = MATERIAL_NO_EFFECTS
custom_materials = list(/datum/material/uranium=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/uranium
mine_experience = 6
/obj/item/stack/ore/iron
name = "iron ore"
@@ -83,6 +85,7 @@
points = 1
custom_materials = list(/datum/material/iron=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/metal
mine_experience = 1
/obj/item/stack/ore/glass
name = "sand pile"
@@ -93,6 +96,7 @@
custom_materials = list(/datum/material/glass=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/glass
w_class = WEIGHT_CLASS_TINY
mine_experience = 0 //its sand
GLOBAL_LIST_INIT(sand_recipes, list(\
new /datum/stack_recipe("sandstone", /obj/item/stack/sheet/mineral/sandstone, 1, 1, 50),\
@@ -126,6 +130,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
icon_state = "volcanic_sand"
item_state = "volcanic_sand"
singular_name = "volcanic ash pile"
mine_experience = 0
/obj/item/stack/ore/plasma
name = "plasma ore"
@@ -135,6 +140,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
points = 15
custom_materials = list(/datum/material/plasma=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/plasma
mine_experience = 5
/obj/item/stack/ore/plasma/welder_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='warning'>You can't hit a high enough temperature to smelt [src] properly!</span>")
@@ -147,6 +153,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
item_state = "Silver ore"
singular_name = "silver ore chunk"
points = 16
mine_experience = 3
custom_materials = list(/datum/material/silver=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/silver
@@ -156,6 +163,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
item_state = "Gold ore"
singular_name = "gold ore chunk"
points = 18
mine_experience = 5
custom_materials = list(/datum/material/gold=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/gold
@@ -167,6 +175,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
points = 50
custom_materials = list(/datum/material/diamond=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/diamond
mine_experience = 10
/obj/item/stack/ore/bananium
name = "bananium ore"
@@ -176,6 +185,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
points = 60
custom_materials = list(/datum/material/bananium=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/bananium
mine_experience = 15
/obj/item/stack/ore/titanium
name = "titanium ore"
@@ -185,6 +195,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
points = 50
custom_materials = list(/datum/material/titanium=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/titanium
mine_experience = 3
/obj/item/stack/ore/slag
name = "slag"

View File

@@ -12,13 +12,15 @@
flight_x_offset = 15
flight_y_offset = 9
automatic_charge_overlays = FALSE
can_bayonet = TRUE
knife_x_offset = 20
knife_y_offset = 12
var/overheat_time = 16
var/holds_charge = FALSE
var/unique_frequency = FALSE // modified by KA modkits
var/overheat = FALSE
can_bayonet = TRUE
knife_x_offset = 20
knife_y_offset = 12
var/mob/holder
var/max_mod_capacity = 100
var/list/modkits = list()
@@ -91,11 +93,13 @@
/obj/item/gun/energy/kinetic_accelerator/equipped(mob/user)
. = ..()
holder = user
if(!can_shoot())
attempt_reload()
/obj/item/gun/energy/kinetic_accelerator/dropped()
. = ..()
holder = null
if(!QDELING(src) && !holds_charge)
// Put it on a delay because moving item from slot to hand
// calls dropped().
@@ -130,7 +134,13 @@
carried = 1
deltimer(recharge_timerid)
recharge_timerid = addtimer(CALLBACK(src, .proc/reload), recharge_time * carried, TIMER_STOPPABLE)
var/skill_modifier
if(ishuman(holder))
var/mob/living/carbon/human/H = holder
skill_modifier = H.mind.get_skill_speed_modifier(/datum/skill/mining)
recharge_timerid = addtimer(CALLBACK(src, .proc/reload), recharge_time * carried * skill_modifier, TIMER_STOPPABLE)
/obj/item/gun/energy/kinetic_accelerator/emp_act(severity)
return

View File

@@ -15,7 +15,7 @@
. = ..()
if(ismineralturf(target))
var/turf/closed/mineral/M = target
M.gets_drilled(firer)
M.gets_drilled(firer, FALSE)
if(mine_range)
mine_range--
range++

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -94,6 +94,7 @@
#include "code\__DEFINES\say.dm"
#include "code\__DEFINES\shuttles.dm"
#include "code\__DEFINES\sight.dm"
#include "code\__DEFINES\skills.dm"
#include "code\__DEFINES\sound.dm"
#include "code\__DEFINES\spaceman_dmm.dm"
#include "code\__DEFINES\stat.dm"
@@ -272,6 +273,7 @@
#include "code\controllers\subsystem\research.dm"
#include "code\controllers\subsystem\server_maint.dm"
#include "code\controllers\subsystem\shuttle.dm"
#include "code\controllers\subsystem\skills.dm"
#include "code\controllers\subsystem\spacedrift.dm"
#include "code\controllers\subsystem\stickyban.dm"
#include "code\controllers\subsystem\sun.dm"
@@ -540,6 +542,8 @@
#include "code\datums\mutations\touch.dm"
#include "code\datums\ruins\lavaland.dm"
#include "code\datums\ruins\space.dm"
#include "code\datums\skills\_skill.dm"
#include "code\datums\skills\mining.dm"
#include "code\datums\status_effects\buffs.dm"
#include "code\datums\status_effects\debuffs.dm"
#include "code\datums\status_effects\gas.dm"