Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Skills #22683

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9ce76d7
skill issue
SapphicOverload Oct 7, 2024
9913ea7
this shouldn't be here
SapphicOverload Oct 7, 2024
dda6cdd
more stuff
SapphicOverload Oct 7, 2024
dac65ea
bit of rebalancing
SapphicOverload Oct 7, 2024
a1c48f6
i hate javascript!!!
SapphicOverload Oct 8, 2024
c1a810a
more balance
SapphicOverload Oct 8, 2024
d510f1c
stuff
SapphicOverload Oct 8, 2024
b3ee2f6
things
SapphicOverload Oct 9, 2024
96ff7f6
fixed some stuff
SapphicOverload Oct 15, 2024
053cef0
Merge remote-tracking branch 'upstream/master' into skill-issue
SapphicOverload Oct 15, 2024
aa9f2f7
hacking
SapphicOverload Oct 17, 2024
4830523
ghost roles
SapphicOverload Oct 17, 2024
97151f7
fix
SapphicOverload Oct 18, 2024
3c777b6
crafting skill requirements
SapphicOverload Oct 18, 2024
4c2d46e
real menu button
SapphicOverload Oct 18, 2024
ad8b347
Merge remote-tracking branch 'upstream/master' into skill-issue
SapphicOverload Oct 18, 2024
aa3c3f7
Merge remote-tracking branch 'upstream/master' into skill-issue
SapphicOverload Oct 18, 2024
e9bfc21
cyborg
SapphicOverload Oct 19, 2024
7cef28c
fixed IPC repair
SapphicOverload Oct 19, 2024
c6fd7d8
new skill icons
SapphicOverload Oct 19, 2024
31490d1
fix + rebalancing
SapphicOverload Oct 19, 2024
64399ef
skill icons 2
SapphicOverload Oct 19, 2024
b95448f
exploit fixed
SapphicOverload Oct 20, 2024
ee3dabf
chem dispenser fix
SapphicOverload Oct 20, 2024
7fa94e6
fix again
SapphicOverload Oct 20, 2024
c7fb868
clockwork style
SapphicOverload Oct 20, 2024
a2e26ea
genetics
SapphicOverload Oct 21, 2024
0eadd5f
science fix
SapphicOverload Oct 21, 2024
219ba71
progress bar indicators
SapphicOverload Oct 31, 2024
845ed80
Merge remote-tracking branch 'upstream/master' into skill-issue
SapphicOverload Oct 31, 2024
589566a
minor refactor + rebalance
SapphicOverload Nov 1, 2024
63cc83b
dna console fix
SapphicOverload Nov 1, 2024
9768a62
Merge remote-tracking branch 'upstream/master' into skill-issue
SapphicOverload Nov 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions code/__DEFINES/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -250,5 +250,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define IGNORE_INCAPACITATED (1<<3)
/// Used to prevent important slowdowns from being abused by drugs like kronkaine
#define IGNORE_SLOWDOWNS (1<<4)
/// Used to keep the skill indicator icon without using the built-in delay modifier
#define IGNORE_SKILL_DELAY (1<<5)

#define IGNORE_ALL (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM|IGNORE_INCAPACITATED|IGNORE_SLOWDOWNS)
1 change: 1 addition & 0 deletions code/__DEFINES/hud.dm
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
#define ui_borg_radio "EAST-1:28,SOUTH+1:7"
#define ui_borg_intents "EAST-2:26,SOUTH:5"
#define ui_language_menu "EAST-5:20,SOUTH:21"
#define ui_skill_menu "EAST-5:20,SOUTH:5"
#define ui_move_up "EAST-4:22, SOUTH:21"
#define ui_move_down "EAST-4:22, SOUTH:5"

Expand Down
27 changes: 27 additions & 0 deletions code/__DEFINES/skills.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

/// Medicine and surgery.
#define SKILL_PHYSIOLOGY "physiology"
/// Construction and repair of structures and machinery.
#define SKILL_MECHANICAL "mechanics"
/// Hacking, piloting, and robotic maintenance.
#define SKILL_TECHNICAL "technical"
/// Chemistry, botany, physics, and other sciences.
#define SKILL_SCIENCE "science"
/// Strength, endurance, accuracy.
#define SKILL_FITNESS "fitness"

/// No experience whatsoever.
#define EXP_NONE 0
/// Some experience, but not much.
#define EXP_LOW 1
/// Enough experience to do a decent job.
#define EXP_MID 2
/// Above average skill level.
#define EXP_HIGH 3
/// Exceptionally skilled.
#define EXP_MASTER 4
/// Uniquely gifted. Not obtainable through normal means.
#define EXP_GENIUS 5

/// Experience required to increase your skills by one level. Increases exponentially the higher your level already is.
#define EXPERIENCE_PER_LEVEL 500
1 change: 1 addition & 0 deletions code/__DEFINES/tools.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define TOOL_MULTITOOL "multitool"
#define TOOL_SCREWDRIVER "screwdriver"
#define TOOL_WIRECUTTER "wirecutter"
#define TOOL_WIRING "wiring"
#define TOOL_WRENCH "wrench"
#define TOOL_WELDER "welder"
#define TOOL_ANALYZER "analyzer"
Expand Down
6 changes: 6 additions & 0 deletions code/__DEFINES/traits/declarations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@
#define TRAIT_IGNOREDAMAGESLOWDOWN "ignoredamageslowdown"
/// Makes the screen go black and white while illuminating all mobs based on their body temperature
#define TRAIT_INFRARED_VISION "infrared_vision"
/// Punches don't stun. Use this instead of setting punchstunchance to zero.
#define TRAIT_NO_PUNCH_STUN "no-punch-stun"

////////////////////////////////////////////////////////////////////////////////////
//-------------------------Species Specific defines-------------------------------//
Expand Down Expand Up @@ -441,6 +443,10 @@
#define TRAIT_PRESENT_VISION "present-vision"
#define TRAIT_DISK_VERIFIER "disk-verifier"
#define TRAIT_NOMOBSWAP "no-mob-swap"
/// Can allocate 5 points into one skill instead of the usual 4
#define TRAIT_EXCEPTIONAL_SKILL "exceptional-skill"
/// Acts as an additional skill point for piloting mechs, up to EXP_MASTER.
#define TRAIT_SKILLED_PILOT "skilled-pilot"
/// Can examine IDs to see if they are roundstart.
#define TRAIT_ID_APPRAISER "id_appraiser"
/// Gives us turf, mob and object vision through walls
Expand Down
10 changes: 8 additions & 2 deletions code/__HELPERS/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ GLOBAL_LIST_EMPTY(species_list)
* given `delay`. Returns `TRUE` on success or `FALSE` on failure.
* Interaction_key is the assoc key under which the do_after is capped, with max_interact_count being the cap. Interaction key will default to target if not set.
*/
/proc/do_after(mob/user, delay, atom/target, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, interaction_key, max_interact_count = 1)
/proc/do_after(mob/user, delay, atom/target, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, interaction_key, max_interact_count = 1, skill_check = null)
if(!user)
return FALSE
if(!isnum(delay))
Expand All @@ -344,10 +344,13 @@ GLOBAL_LIST_EMPTY(species_list)

if(!(timed_action_flags & IGNORE_SLOWDOWNS))
delay *= user.action_speed_modifier * user.do_after_coefficent() //yogs: darkspawn

if(skill_check && user.mind && !(timed_action_flags & IGNORE_SKILL_DELAY))
delay *= (12 - user.get_skill(skill_check)) / 10

var/datum/progressbar/progbar
if(progress)
progbar = new(user, delay, target || user)
progbar = new(user, delay, target || user, skill_check)

SEND_SIGNAL(user, COMSIG_DO_AFTER_BEGAN)

Expand Down Expand Up @@ -378,6 +381,9 @@ GLOBAL_LIST_EMPTY(species_list)
. = FALSE
break

if(skill_check) // get better at things by practicing them
user.add_exp(skill_check, delay)

if(!QDELETED(progbar))
progbar.end_progress()

Expand Down
10 changes: 10 additions & 0 deletions code/_onclick/hud/alert.dm
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,16 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
var/mob/living/carbon/C = mob_viewer
C.take(giver, receiving)

//SKILLS

/atom/movable/screen/alert/skill_up
name = "Allocate Skill Points"
desc = "You have unspent skill points! Click here to allocate them."

/atom/movable/screen/alert/skill_up/Click(location, control, params)
. = ..()
mob_viewer.hud_used?.skill_menu?.ui_interact(mob_viewer)

//ALIENS

/atom/movable/screen/alert/alien_tox
Expand Down
1 change: 1 addition & 0 deletions code/_onclick/hud/hud.dm
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
var/atom/movable/screen/rest_icon
var/atom/movable/screen/throw_icon
var/atom/movable/screen/module_store_icon
var/atom/movable/screen/skill_menu

var/list/static_inventory = list() //the screen objects which are static
var/list/toggleable_inventory = list() //the screen objects which can be hidden
Expand Down
6 changes: 6 additions & 0 deletions code/_onclick/hud/human.dm
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@
using.screen_loc = UI_BOXAREA
static_inventory += using

skill_menu = new /atom/movable/screen/skill_menu(src)
skill_menu.icon = ui_style
if(!widescreen_layout)
skill_menu.screen_loc = UI_BOXAREA
static_inventory += skill_menu

action_intent = new /atom/movable/screen/combattoggle/flashy(src)
action_intent.icon = ui_style
action_intent.screen_loc = ui_combat_toggle
Expand Down
93 changes: 93 additions & 0 deletions code/_onclick/hud/screen_objects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,99 @@
var/datum/language_holder/H = M.get_language_holder()
H.open_language_menu(usr)

/atom/movable/screen/skill_menu
name = "skills menu"
icon = 'icons/mob/screen_midnight.dmi'
icon_state = "skill_menu"
screen_loc = ui_skill_menu
var/list/allocated_skills = list(
SKILL_PHYSIOLOGY = EXP_NONE,
SKILL_MECHANICAL = EXP_NONE,
SKILL_TECHNICAL = EXP_NONE,
SKILL_SCIENCE = EXP_NONE,
SKILL_FITNESS = EXP_NONE,
)
var/allocated_points = EXP_NONE

/atom/movable/screen/skill_menu/Click()
ui_interact(usr)

/atom/movable/screen/skill_menu/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "SkillMenu", "Allocate Skill Points")
ui.open()

/atom/movable/screen/skill_menu/ui_data(mob/user)
var/list/data = list()
var/list/skill_data = list()
for(var/skill in user.mind.skills)
skill_data.Add(list(list(
"base" = user.get_skill(skill),
"allocated" = allocated_skills[skill],
)))
data["skills"] = skill_data
data["skill_points"] = user.mind.skill_points
data["allocated_points"] = allocated_points
data["exceptional_skill"] = HAS_MIND_TRAIT(user, TRAIT_EXCEPTIONAL_SKILL)
return data

/atom/movable/screen/skill_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
var/mob/user = usr
if(!user.mind)
CRASH("User ([user]) without a mind attempted to allocate skill points!")
switch(action)
if("confirm")
if(allocated_points > user.mind.skill_points)
stack_trace("[user] attempted to allocate [allocated_points] skill points when they only had [user.mind.skill_points] available!")
message_admins("[key_name_admin(user)] may have attempted an exploit to gain more skill points than intended!")
qdel(allocated_skills)
allocated_skills = list(
SKILL_PHYSIOLOGY = EXP_NONE,
SKILL_MECHANICAL = EXP_NONE,
SKILL_TECHNICAL = EXP_NONE,
SKILL_SCIENCE = EXP_NONE,
SKILL_FITNESS = EXP_NONE,
)
allocated_points = EXP_NONE
return TRUE
for(var/skill in user.mind.skills)
user.adjust_skill(skill, allocated_skills[skill], max_skill = EXP_GENIUS)
allocated_skills[skill] = EXP_NONE
user.mind.skill_points -= allocated_points
allocated_points = EXP_NONE
if(!user.mind.skill_points)
user.clear_alert("skill points")
return TRUE
if("allocate")
if(allocated_points + params["amount"] > user.mind.skill_points)
return TRUE
if(allocated_points + params["amount"] < 0)
return TRUE
if(allocated_skills[params["skill"]] + params["amount"] + user.get_skill(params["skill"]) > (4 + HAS_MIND_TRAIT(user, TRAIT_EXCEPTIONAL_SKILL)))
return TRUE
if(allocated_skills[params["skill"]] + params["amount"] < 0)
return TRUE
allocated_skills[params["skill"]] += params["amount"]
allocated_points += params["amount"]
return TRUE

/atom/movable/screen/skill_menu/ui_status(mob/user)
if(!user.mind)
return UI_CLOSE
return UI_INTERACTIVE

/atom/movable/screen/skill_menu/ui_state(mob/user)
return GLOB.always_state

/atom/movable/screen/skill_menu/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/crafting),
)

/atom/movable/screen/ghost/pai
name = "pAI Candidate"
icon = 'icons/mob/screen_midnight.dmi'
Expand Down
30 changes: 16 additions & 14 deletions code/_onclick/item_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -160,32 +160,32 @@
* Called from [/mob/living/proc/attackby]
*
* Arguments:
* * mob/living/M - The mob being hit by this item
* * mob/living/target - The mob being hit by this item
* * mob/living/user - The mob hitting with this item
* * params - Click params of this attack
*/
/obj/item/proc/attack(mob/living/M, mob/living/user, params)
var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user, params)
/obj/item/proc/attack(mob/living/target, mob/living/user, params)
var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, target, user, params)
if(signal_return & COMPONENT_CANCEL_ATTACK_CHAIN)
return TRUE
if(signal_return & COMPONENT_SKIP_ATTACK)
return

SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user, params)
SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, target, user, params)
if(item_flags & NOBLUDGEON)
return

if(tool_behaviour && !user.combat_mode) // checks for combat mode with surgery tool
var/list/modifiers = params2list(params)
if(attempt_initiate_surgery(src, M, user, modifiers))
if(attempt_initiate_surgery(src, target, user, modifiers))
return TRUE
if(iscarbon(M))
var/mob/living/carbon/C = M
if(iscarbon(target))
var/mob/living/carbon/C = target
for(var/i in C.all_wounds)
var/datum/wound/W = i
if(W.try_treating(src, user))
return TRUE
to_chat(user, span_warning("You can't perform any surgeries on [M]'s [parse_zone(user.zone_selected)]!")) //yells at you
to_chat(user, span_warning("You can't perform any surgeries on [target]'s [parse_zone(user.zone_selected)]!")) //yells at you
return TRUE

if(force && !synth_check(user, SYNTH_ORGANIC_HARM))
Expand All @@ -199,16 +199,17 @@
else if(hitsound)
playsound(loc, hitsound, get_clamped_volume(), 1, -1)

M.lastattacker = user.real_name
M.lastattackerckey = user.ckey
target.lastattacker = user.real_name
target.lastattackerckey = user.ckey

if(force)
M.last_damage = name
target.last_damage = name

user.do_attack_animation(M)
M.attacked_by(src, user)
user.do_attack_animation(target)
user.add_exp(SKILL_FITNESS, target.stat == CONSCIOUS ? force : force / 5) // attacking things that can't move isn't very good experience
target.attacked_by(src, user)

log_combat(user, M, "attacked", src.name, "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (DAMTYPE: [uppertext(damtype)])")
log_combat(user, target, "attacked", src.name, "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (DAMTYPE: [uppertext(damtype)])")
add_fingerprint(user)
var/force_multiplier = 1
if(ishuman(user))
Expand All @@ -233,6 +234,7 @@
user.changeNext_move(CLICK_CD_MELEE * weapon_stats[SWING_SPEED] * (range_cooldown_mod ? (dist > 0 ? min(dist, weapon_stats[REACH]) * range_cooldown_mod : range_cooldown_mod) : 1)) //range increases attack cooldown by swing speed
user.do_attack_animation(attacked_atom)
attacked_atom.attacked_by(src, user)
user.add_exp(SKILL_FITNESS, force / 5)
user.weapon_slow(src)
var/force_multiplier = 1
if(ishuman(user))
Expand Down
4 changes: 2 additions & 2 deletions code/controllers/subsystem/shuttle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -523,14 +523,14 @@ SUBSYSTEM_DEF(shuttle)
* * dock_id - The ID of the destination (stationary docking port) to move to
* * timed - If true, have the shuttle follow normal spool-up, jump, dock process. If false, immediately move to the new location.
*/
/datum/controller/subsystem/shuttle/proc/moveShuttle(shuttle_id, dock_id, timed)
/datum/controller/subsystem/shuttle/proc/moveShuttle(shuttle_id, dock_id, timed, skill_multiplier = 1)
var/obj/docking_port/mobile/shuttle_port = getShuttle(shuttle_id)
var/obj/docking_port/stationary/docking_target = getDock(dock_id)

if(!shuttle_port)
return DOCKING_NULL_SOURCE
if(timed)
if(shuttle_port.request(docking_target))
if(shuttle_port.request(docking_target, skill_multiplier))
return DOCKING_IMMOBILIZED
else
if(shuttle_port.initiate_docking(docking_target) != DOCKING_SUCCESS)
Expand Down
2 changes: 2 additions & 0 deletions code/datums/components/blocking.dm
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@
if(!blocking_component.can_block(defender, incoming, damage, attack_type))
return 0
force_returned = blocking_component.block_force
if(attack_type & (MELEE_ATTACK|UNARMED_ATTACK|THROWN_PROJECTILE_ATTACK|LEAP_ATTACK)) // being stronger provides a small increase to melee blocking
force_returned += defender.get_skill(SKILL_FITNESS)
if(HAS_TRAIT(weapon, TRAIT_PARRYING))
force_returned *= PARRY_BONUS
return max(force_returned - max(armour_penetration - weapon.armour_penetration, 0) * AP_TO_FORCE, 0)
Expand Down
20 changes: 10 additions & 10 deletions code/datums/components/bloodysoles.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

#define FOOTPRINT_INDEX_FILE 1
#define FOOTPRINT_INDEX_STATE 2

//Component for clothing items that can pick up blood from decals and spread it around everywhere when walking, such as shoes or suits with integrated shoes.

Expand Down Expand Up @@ -254,20 +255,19 @@ Like its parent but can be applied to carbon mobs instead of clothing items

/datum/component/bloodysoles/feet/add_parent_to_footprint(obj/effect/decal/cleanable/blood/footprints/FP)
if(ismonkey(wielder))
FP.species_types |= "monkey"
FP.species_types["monkey"] = list(null, FALSE)
return

if(!ishuman(wielder))
FP.species_types |= "unknown"
FP.species_types["unknown"] = list(null, FALSE)
return

// Find any leg of our human and add that to the footprint, instead of the default which is to just add the human type
for(var/X in wielder.bodyparts)
var/obj/item/bodypart/affecting = X
if(affecting.body_part == LEG_RIGHT || affecting.body_part == LEG_LEFT)
if(!affecting.bodypart_disabled)
FP.species_types |= affecting.limb_id
break
// Our limbs code is horribly out of date and won't work the normal way, so we do it like this
for(var/obj/item/bodypart/affecting as anything in wielder.bodyparts)
if((affecting.body_part & (LEG_LEFT|LEG_RIGHT)) && !affecting.bodypart_disabled)
var/image/limb_icon = affecting.get_limb_icon(FALSE)[1]
FP.species_types[affecting.species_id] = list(limb_icon.icon, limb_icon.icon_state)
break


/datum/component/bloodysoles/feet/is_obscured()
Expand Down
Loading
Loading