Files
Bubberstation/code/modules/surgery/surgery_step.dm
moo 8fcf42eff9 Experimental Cobbisection [150+ Hours and Ready] (#44821)
About The Pull Request & Why
Dissection (Prev Experimental Dissection) Is Now Roundstart

Goal:give medbay a task they can do outside of normal healing on the off chance they're overstaffed and/or are in need of work.
Dissection (Prev Experimental Dissection) Is Now Tiered

Goal: I'm still not seeing competition in the medical tree that I'd like to see. Now that science benefits from going to this tree, I expect it to be a prominent if not the main pick.

Goal: Provide Medical bargaining power with Science. Want you cool gear bros? Better indulge us a bit if you want us to farm corpses.

NOTE: You will NOT be punished for doing low tiered surgeries then unlocking further tiers. It adjusts your rewards depending on if the body has been experimented on before and gives you the difference, it will not block you from doing the surgery entirely.
Repeatability

Goal: Make it less balanced around the all/nothing mechanic and more with rewarding constantly running the surgery.

Failing the surgery will give you a pity amount (1%, something slightly more than none in grand scheme) but more importantly will NOT add the trait that disables you from using that body for the surgery again.
Silicons can now perform dissection

Since It's not All/Nothing I decided to allow silicons to be able to help out. This is the first (and only) surgery that they can potentially fail.
Nerfs (yikes!)

Needed to nerf it to compensate for the fact that it was now roundstart. The hardest one was pointgain. I decided to mega nerf it so tiered would be desired. This was also a result in the shift of balance off the RNG and more on the repeatability.
Dissection Can Now Be Performed on ANY LIVING MOB

Goal: Cooperation between Mining (returning Mobs) and Medbay (turning these mobs into points)

The foundation is really lacking imo since I didn't want to dance around with numbers in this PR. Currently all mobs that aren't human and aren't explicitly listed in check_value are 300 points per surgery.

I hope you guys can add more mobs to the pool with better rewards (imagine dissecting the dragon for science!)
Dissection Surgery Minor Edits
Step Configuration Edit

Needed to change just for repeatability in the dissect step (didn't like the end step being the proceeding step).

I replaced the incision step with a post-dissection clamp step to keep the theme of scalpel > hemo (dissection uses scalpel)
Implement Changes / Probability Effects

Rewards using the researched tools (further integrates medsci coop), lowers standard gear to appropriately balance higher tiers.
MISC
Prices are Define Bound

Everything is relative to a single number via calculating off a define instead of independent values. Balance discussion shifts from "Is X number fair" to a more tangible "Is this mob worth X times the amount of a normal human". If everything is strong/low we can just edit a single number!
Let me know if there's any undoc'd changes!
Changelog

cl Cobby x Medbay
balance: (Experimental) Dissection is now roundstart.
balance: (Experimental) Dissection is now tiered and give higher point outputs than their predecessors.
add: All living mobs with corpses can be dissected.
code: Attention, all ss13 gamers! I need YOUR help adding mobs to the pool so they don't get the lame 60% of normal human pricing! You can dissect DRAGONS FOR CRY IT OUT LOUD!
balance: You are NOT punished for doing the lower tier surgeries then unlocking higher ones!
add: Borgs can perform dissection but they are not 100% successful.
tweak: Shifts balance of dissection surgery towards spammability vs. rng mechanic.
balance: All point rewards are severely nerfed to promote doing this multiple times (since it's now available from the getgo).
tweak: If you fail the dissection step, you get a pity reward (1% credits) and can repeat the step until you successfully dissect the being.
tweak: Lowered probabilty of success on default tools, increased probability for researched tools.
tweak: removed 2nd incision step, added clamp step post dissection (repeatability purposes).
/cl
2019-07-09 11:57:26 +12:00

147 lines
5.8 KiB
Plaintext

/datum/surgery_step
var/name
var/list/implements = list() //format is path = probability of success. alternatively
var/implement_type = null //the current type of implement used. This has to be stored, as the actual typepath of the tool may not match the list type.
var/accept_hand = FALSE //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item.
var/accept_any_item = FALSE //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand.
var/time = 10 //how long does the step take?
var/repeatable = FALSE //can this step be repeated? Make shure it isn't last step, or it used in surgery with `can_cancel = 1`. Or surgion will be stuck in the loop
var/list/chems_needed = list() //list of chems needed to complete the step. Even on success, the step will have no effect if there aren't the chems required in the mob.
var/require_all_chems = TRUE //any on the list or all on the list?
var/silicons_obey_prob = FALSE
/datum/surgery_step/proc/try_op(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
var/success = FALSE
if(accept_hand)
if(!tool)
success = TRUE
if(iscyborg(user))
success = TRUE
if(accept_any_item)
if(tool && tool_check(user, tool))
success = TRUE
else if(tool)
for(var/key in implements)
var/match = FALSE
if(ispath(key) && istype(tool, key))
match = TRUE
else if(tool.tool_behaviour == key)
match = TRUE
if(match)
implement_type = key
if(tool_check(user, tool))
success = TRUE
break
if(success)
if(target_zone == surgery.location)
if(get_location_accessible(target, target_zone) || surgery.ignore_clothes)
initiate(user, target, target_zone, tool, surgery, try_to_fail)
else
to_chat(user, "<span class='warning'>You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!</span>")
return TRUE //returns TRUE so we don't stab the guy in the dick or wherever.
if(repeatable)
var/datum/surgery_step/next_step = surgery.get_surgery_next_step()
if(next_step)
surgery.status++
if(next_step.try_op(user, target, user.zone_selected, user.get_active_held_item(), surgery))
return TRUE
else
surgery.status--
return FALSE
/datum/surgery_step/proc/initiate(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
surgery.step_in_progress = TRUE
var/speed_mod = 1
var/advance = FALSE
if(preop(user, target, target_zone, tool, surgery) == -1)
surgery.step_in_progress = FALSE
return FALSE
if(tool)
speed_mod = tool.toolspeed
if(do_after(user, time * speed_mod, target = target))
var/prob_chance = 100
if(implement_type) //this means it isn't a require hand or any item step.
prob_chance = implements[implement_type]
prob_chance *= surgery.get_propability_multiplier()
if((prob(prob_chance) || (iscyborg(user) && !silicons_obey_prob)) && chem_check(target) && !try_to_fail)
if(success(user, target, target_zone, tool, surgery))
advance = TRUE
else
if(failure(user, target, target_zone, tool, surgery))
advance = TRUE
if(advance && !repeatable)
surgery.status++
if(surgery.status > surgery.steps.len)
surgery.complete()
surgery.step_in_progress = FALSE
return advance
/datum/surgery_step/proc/preop(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You begin to perform surgery on [target]...</span>",
"[user] begins to perform surgery on [target].",
"[user] begins to perform surgery on [target].")
/datum/surgery_step/proc/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You succeed.</span>",
"[user] succeeds!",
"[user] finishes.")
return TRUE
/datum/surgery_step/proc/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='warning'>You screw up!</span>",
"<span class='warning'>[user] screws up!</span>",
"[user] finishes.", TRUE) //By default the patient will notice if the wrong thing has been cut
return FALSE
/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
return TRUE
/datum/surgery_step/proc/chem_check(mob/living/target)
if(!LAZYLEN(chems_needed))
return TRUE
if(require_all_chems)
. = TRUE
for(var/R in chems_needed)
if(!target.reagents.has_reagent(R))
return FALSE
else
. = FALSE
for(var/R in chems_needed)
if(target.reagents.has_reagent(R))
return TRUE
/datum/surgery_step/proc/get_chem_list()
if(!LAZYLEN(chems_needed))
return
var/list/chems = list()
for(var/R in chems_needed)
var/datum/reagent/temp = GLOB.chemical_reagents_list[R]
if(temp)
var/chemname = temp.name
chems += chemname
return english_list(chems, and_text = require_all_chems ? " and " : " or ")
//Replaces visible_message during operations so only people looking over the surgeon can tell what they're doing, allowing for shenanigans.
/datum/surgery_step/proc/display_results(mob/user, mob/living/carbon/target, self_message, detailed_message, vague_message, target_detailed = FALSE)
var/list/detailed_mobs = get_hearers_in_view(1, user) //Only the surgeon and people looking over his shoulder can see the operation clearly
if(!target_detailed)
detailed_mobs -= target //The patient can't see well what's going on, unless it's something like getting cut
user.visible_message(detailed_message, self_message, vision_distance = 1, ignored_mobs = target_detailed ? null : target)
user.visible_message(vague_message, "", ignored_mobs = detailed_mobs)