From 83f7e90b8e807c0e507a3b26b1c517afa67fa5a2 Mon Sep 17 00:00:00 2001 From: Runa Dacino Date: Thu, 8 Jun 2023 00:44:27 +0200 Subject: [PATCH] Implements Wall Climbing * Adds new turf/simulated proc: climb_wall * * Anyone can attempt this by standing next to wall * * Untrained have chance to fall * * Trained dont fall unless interrupted * * Speed varies wildly depending on gear & skills * * * Takes lowest climb_delay, multiplies 5 by it * * * Depending on tresholds, may add 10/5 seconds on top (>1.25, >1.0) * * Gear can enable even rookies to climb. Simplemobs cant use gear * * Except scugs. They can specifically use their spears to climb, leaving it behind * Adds new turf/simulated var: climbable * * solidrock, /mineral/cave have climbable set to true * Adds new turf/simulated logic for init, examine() and a yet-unused proc * * proc toggle_climbability allows turning walls climbable. Useful for GMs! * * Could also later implement a tool to turn walls climbable when used using it. * Adds new mob/living vars, can_climb and climbing_delay * * These are for handling silicons and simple mobs * Adds new species vars, can_climb and climbing_delay * * These are for human mobs * climbing_delay defaults to 1.5 * * Tajara have it at 1.25 * * Vassalian have it at 1 * * Scugs got it at 2.0, reduced to 0.75 when using spear * New traits: climber; climber, professional; climber, master * * Cost 0, 1, 2 pts as positive trait respectively * * Enable safe climbing, reduce delay to 1.25, 1.0 respectively * moves rock_climber from shoes to items define * Adds new item var, climbing_delay set at 1 --- code/game/objects/items.dm | 3 + code/game/turfs/simulated.dm | 11 +- .../turfs/simulated/outdoors/atmoscaves_vr.dm | 2 + code/game/turfs/simulated/wall_types_vr.dm | 1 + code/game/turfs/simulated_vr.dm | 12 ++- code/modules/clothing/clothing.dm | 1 - code/modules/clothing/shoes/boots.dm | 1 + .../living/carbon/human/species/species_vr.dm | 2 + .../species/station/station_special_vr.dm | 3 +- .../human/species/station/station_vr.dm | 4 +- .../species/station/traits_vr/positive.dm | 32 ++++++ code/modules/mob/living/living_defines_vr.dm | 2 + .../subtypes/animal/alien animals/catslug.dm | 2 + code/modules/multiz/movement_vr.dm | 100 ++++++++++++++++++ 14 files changed, 171 insertions(+), 5 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 8c0309563a6..7947aafaea3 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -112,6 +112,9 @@ var/protean_drop_whitelist = FALSE + var/rock_climbing = FALSE //If true, allows climbing cliffs using click drag for single Z, walls if multiZ + var/climbing_delay = 1 //If rock_climbing, lower better. + /obj/item/New() ..() if(embed_chance < 0) diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index e7293865e3f..57c1d22832d 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -17,6 +17,7 @@ var/dirty_prob = 2 // Chance of being dirty roundstart var/dirt = 0 var/special_temperature //Used for turf HE-Pipe interaction + var/climbable = FALSE //Adds proc to wall if set to TRUE on its initialization, defined here since not all walls are subtypes of wall var/icon_edge = 'icons/turf/outdoors_edge.dmi' //VOREStation Addition - Allows for alternative edge icon files @@ -63,6 +64,14 @@ if(istype(loc, /area/chapel)) holy = 1 levelupdate() + if(climbable) + verbs += /turf/simulated/proc/climb_wall + +/turf/simulated/examine(mob/user) + . = ..() + if(climbable) + . += "This [src] looks climbable." + /turf/simulated/proc/AddTracks(var/typepath,var/bloodDNA,var/comingdir,var/goingdir,var/bloodcolor="#A10808") var/obj/effect/decal/cleanable/blood/tracks/tracks = locate(typepath) in src @@ -177,4 +186,4 @@ else if( istype(M, /mob/living/silicon/robot )) new /obj/effect/decal/cleanable/blood/oil(src) else if(ishuman(M)) - add_blood(M) \ No newline at end of file + add_blood(M) diff --git a/code/game/turfs/simulated/outdoors/atmoscaves_vr.dm b/code/game/turfs/simulated/outdoors/atmoscaves_vr.dm index 8ac5dc08e5e..7c96f35143f 100644 --- a/code/game/turfs/simulated/outdoors/atmoscaves_vr.dm +++ b/code/game/turfs/simulated/outdoors/atmoscaves_vr.dm @@ -2,11 +2,13 @@ oxygen = MOLES_O2STANDARD nitrogen = MOLES_N2STANDARD temperature = T20C + climbable = TRUE /turf/simulated/mineral/ignore_mapgen/cave oxygen = MOLES_O2STANDARD nitrogen = MOLES_N2STANDARD temperature = T20C + climbable = TRUE /turf/simulated/mineral/floor/cave oxygen = MOLES_O2STANDARD diff --git a/code/game/turfs/simulated/wall_types_vr.dm b/code/game/turfs/simulated/wall_types_vr.dm index b4bb8a5c042..b25e6d6f9d8 100644 --- a/code/game/turfs/simulated/wall_types_vr.dm +++ b/code/game/turfs/simulated/wall_types_vr.dm @@ -206,6 +206,7 @@ var/list/flesh_overlay_cache = list() /turf/simulated/wall/solidrock icon_state = "solidrock" icon = 'icons/turf/wall_masks_vr.dmi' + climbable = TRUE /turf/simulated/wall/titanium icon_state = "titanium" diff --git a/code/game/turfs/simulated_vr.dm b/code/game/turfs/simulated_vr.dm index 6c7325305fe..dc74fd9aba7 100644 --- a/code/game/turfs/simulated_vr.dm +++ b/code/game/turfs/simulated_vr.dm @@ -1,5 +1,15 @@ /turf/simulated can_start_dirty = FALSE // We have enough premapped dirt where needed + + /turf/simulated/floor/plating - can_start_dirty = TRUE // But let maints and decrepit areas have some randomness \ No newline at end of file + can_start_dirty = TRUE // But let maints and decrepit areas have some randomness + + +/turf/simulated/proc/toggle_climbability() //Again, b + if(climbable) + verbs -= /turf/simulated/proc/climb_wall + else + verbs += /turf/simulated/proc/climb_wall + climbable = !climbable diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index d347881b409..0b914a6a8c6 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -604,7 +604,6 @@ var/water_speed = 0 //Speed boost/decrease in water, lower/negative values mean more speed var/snow_speed = 0 //Speed boost/decrease on snow, lower/negative values mean more speed - var/rock_climbing = FALSE // If true, allows climbing cliffs with clickdrag. var/step_volume_mod = 1 //How quiet or loud footsteps in this shoe are diff --git a/code/modules/clothing/shoes/boots.dm b/code/modules/clothing/shoes/boots.dm index 78949fee1ff..69ea46a5f25 100644 --- a/code/modules/clothing/shoes/boots.dm +++ b/code/modules/clothing/shoes/boots.dm @@ -190,6 +190,7 @@ desc = "A pair of winter boots, with metal bracing attached to assist in climbing rocky terrain." icon_state = "climbing_boots" rock_climbing = TRUE + //Climbing delay with boots is 1 /obj/item/clothing/shoes/boots/tactical name = "tactical boots" diff --git a/code/modules/mob/living/carbon/human/species/species_vr.dm b/code/modules/mob/living/carbon/human/species/species_vr.dm index 49962ef351c..4199dba6f32 100644 --- a/code/modules/mob/living/carbon/human/species/species_vr.dm +++ b/code/modules/mob/living/carbon/human/species/species_vr.dm @@ -38,6 +38,8 @@ var/micro_size_mod = 0 // How different is our size for interactions that involve us being small? var/macro_size_mod = 0 // How different is our size for interactions that involve us being big? var/digestion_nutrition_modifier = 1 + var/can_climb = FALSE + var/climbing_delay = 1.5 // We climb with a quarter delay /datum/species/proc/give_numbing_bite() //Holy SHIT this is hacky, but it works. Updating a mob's attacks mid game is insane. diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm index 15a5fcabea6..67c9ca9322a 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm @@ -423,6 +423,8 @@ primitive_form = "Wolpin" color_mult = 1 icon_height = 64 + can_climb = TRUE + climbing_delay = 1 min_age = 18 max_age = 200 @@ -460,4 +462,3 @@ BP_L_FOOT = list("path" = /obj/item/organ/external/foot), BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) ) - diff --git a/code/modules/mob/living/carbon/human/species/station/station_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_vr.dm index 20b5b0bf5db..7cfe689b120 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_vr.dm @@ -319,6 +319,8 @@ genders = list(MALE, FEMALE, PLURAL, NEUTER) wikilink="https://wiki.vore-station.net/Tajaran" agility = 90 + can_climb = TRUE + climbing_delay = 1.25 //No vassilian, but faster than a human who learned to climb! /datum/species/skrell spawn_flags = SPECIES_CAN_JOIN @@ -387,7 +389,7 @@ tail_animation = 'icons/mob/species/vox/tail.dmi' deform = 'icons/mob/human_races/r_def_vox_old.dmi' color_mult = 1 - + descriptors = list( /datum/mob_descriptor/vox_markings = 0 ) diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm index 2a350374bce..317e9952e24 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm @@ -218,3 +218,35 @@ cost = 1 var_changes = list("throwforce_absorb_threshold" = 10) + + + +/datum/trait/positive/wall_climber + name = "Climber" + desc = "You can climb certain walls without tools!" + tutorial = "You must approach a wall and right click it and select the \ + 'climb wall' verb to climb it. You suffer from a movement delay of 1.5 with this trait.\n \ + Your total climb time is expected to be 17.5 seconds. Tools may reduce this." + cost = 0 + custom_only = FALSE + var_changes = list("can_climb" = TRUE) + +/datum/trait/positive/wall_climber_pro + name = "Climber, Master" + desc = "You can climb certain walls without tools! You are a professional rock climber at this, letting you climb as fast as a tajara!" + tutorial = "You must approach a wall and right click it and select the \ + 'climb wall' verb to climb it. Your movement delay is just 1.25 with this trait.\n \ + Your climb time is expected to be 9 seconds. Tools may reduce this. " + cost = 1 + custom_only = FALSE + var_changes = list("can_climb" = TRUE, "climbing_delay" = 1.25) + +/datum/trait/positive/wall_climber_master + name = "Climber, Master" + desc = "You can climb certain walls without tools! You are a true master at this, letting you climb as a vassilian!" + tutorial = "You must approach a wall and right click it and select the \ + 'climb wall' verb to climb it. Your movement delay is just 1.0 with this trait. \n \ + Your climb time is expected to be 5 seconds." + cost = 2 + custom_only = FALSE + var_changes = list("can_climb" = TRUE, "climbing_delay" = 1.0) diff --git a/code/modules/mob/living/living_defines_vr.dm b/code/modules/mob/living/living_defines_vr.dm index 2a547811c2f..d20b8555fc5 100644 --- a/code/modules/mob/living/living_defines_vr.dm +++ b/code/modules/mob/living/living_defines_vr.dm @@ -14,3 +14,5 @@ //custom temperature discomfort vars var/list/custom_heat = list() var/list/custom_cold = list() + var/can_climb = FALSE //Checked by turfs when using climb_wall(). Defined here for silicons and simple mobs + var/climbing_delay = 1.5 //By default, mobs climb at quarter speed. To be overriden by specific simple mobs or species speed diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm b/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm index 6b4b514e283..4f087411f32 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm @@ -43,6 +43,8 @@ mob_size = MOB_SMALL friendly = list("hugs") see_in_dark = 8 + can_climb = TRUE + climbing_delay = 2.0 ID_provided = TRUE diff --git a/code/modules/multiz/movement_vr.dm b/code/modules/multiz/movement_vr.dm index a8dde43ee9f..e35c6d8c19f 100644 --- a/code/modules/multiz/movement_vr.dm +++ b/code/modules/multiz/movement_vr.dm @@ -82,3 +82,103 @@ return 0 if(direction == DOWN) //on a turf above, trying to enter return 1 + +/turf/simulated/proc/climb_wall() + set name = "Climb Wall" + set desc = "Using nature's gifts or technology, scale that wall!" + set category = "Object" + set src in oview(1) + + if(!istype(usr, /mob/living)) return + var/mob/living/L = usr + var/climbing_delay_min = L.climbing_delay + var/fall_chance = 0 + var/drop_our_held = FALSE + + if(ishuman(L)) + var/permit_human = FALSE + var/mob/living/carbon/human/H = L + if(H.species.climbing_delay < H.climbing_delay) + climbing_delay_min = H.species.climbing_delay + var/list/gear = list(H.head, H.wear_mask, H.wear_suit, H.w_uniform, + H.gloves, H.shoes, H.belt, H.get_active_hand(), H.get_inactive_hand()) + if(H.can_climb || H.species.can_climb) + permit_human = TRUE + for(var/obj/item/I in gear) + if(I.rock_climbing) + permit_human = TRUE + if(I.climbing_delay > climbing_delay_min) + climbing_delay_min = I.climbing_delay //We get the maximum possible speedup out of worn equipment + if(!permit_human) + var/sure = tgui_alert(H,"Are you sure you want to try without tools? It's VERY LIKELY \ + you will fall and get hurt. More agile species might have better luck", "Second Thoughts", list("Bring it!", "Stay grounded")) + if(sure == "Stay grounded") return + fall_chance = clamp(100 - H.species.agility, 40, 90) //This should be 80 for most species. Traceur would reduce to 10%, so clamping higher + else if(!L.can_climb) + var/sure = tgui_alert(L,"Are you sure you want to try without tools? It's VERY LIKELY \ + you will fall and get hurt. More agile species might have better luck", "Second Thoughts", list("Bring it!", "Stay grounded")) + if(sure == "Stay grounded") return + if(isrobot(L)) + fall_chance = 80 // Robots get no mercy + else + fall_chance = 55 //Simple mobs do. + climbing_delay_min = 2 + if(istype(L, /mob/living/simple_mob/vore/alienanimals/catslug)) + var/obj/O = L.get_active_hand() + if(istype(O, /obj/item/weapon/material/twohanded/spear)) + var/choice = tgui_alert(L, "Use your spear to climb faster? This will drop and break it!", "Scug Tactics", list("Yes!", "No")) + if(choice == "Yes!") + drop_our_held = TRUE + climbing_delay_min = 0.75 + + + + var/turf/above_wall = GetAbove(src) + if(!above_wall) //Should we even bother? + to_chat(L, SPAN_NOTICE("There's nothing interesting over this cliff!")) + return + //Making sure we got headroom + var/turf/above_mob = GetAbove(L) + if(!above_mob.CanZPass(L, UP)) + to_chat(L, SPAN_WARNING("\The [above_mob] blocks your way.")) + return + if(above_wall.density) //We check density rather than type since some walls dont have a floor on top. + to_chat(L, SPAN_WARNING("\The [above_wall] blocks your way.")) + return + if(LAZYLEN(above_wall.contents) > 30) //We avoid checking the contents if it's too cluttered to avoid issues + to_chat(L, SPAN_WARNING("\The [above_wall] is too cluttered to climb onto!")) + return + for(var/atom/A in above_wall.contents) + if(A.density) + to_chat(L, SPAN_WARNING("\The [A.name] blocks your way!")) + return + + // Climb time is 3.75 for scugs with spears (spear is dropped) + // Climb time is 5 for Master climbers, Vassilians, Well-geared humans + // Climb time is 9 for Tajara and Professional Climbers + // Climb time is 17.5 Seconds for amateur climbers + // Climb time is 20 seconds for scugs without a spear + // Climb time is 30 for gearless untrained people + var/climb_time = (5 * climbing_delay_min) SECONDS + if(fall_chance) + to_chat(L, SPAN_WARNING("You begin climbing over \The [src]. Getting a grip is exceedingly difficult...")) + climb_time += 20 SECONDS + else + to_chat(L, SPAN_NOTICE("You begin climbing above \The [src]! ")) + if(climbing_delay_min > 1.25) + climb_time += 10 SECONDS + if(climbing_delay_min > 1.0) + climb_time += 2.5 SECONDS + L.custom_emote(VISIBLE_MESSAGE, "begins to climb up on \The [src]") + var/oops_time = world.time + to_chat(L, SPAN_WARNING("If you get interrupted after 4 seconds of climbing, you will fall and hurt yourself, beware!")) + if(do_after(L,climb_time)) + if(prob(fall_chance)) + to_chat(L, SPAN_DANGER("You slipped and fell!")) + L.forceMove(above_mob) + if(drop_our_held) + L.drop_item(get_turf(L)) + L.forceMove(above_wall) + to_chat(L, SPAN_NOTICE("You clambered up successfully!")) + else if(world.time > (oops_time + 4 SECONDS)) + L.forceMove(above_mob)