From 3803d6a8173c81ed777c071dd8950c877c930cdc Mon Sep 17 00:00:00 2001 From: Qustinnus Date: Sun, 10 May 2020 17:16:01 +0200 Subject: [PATCH] Adds hardcore random mode: Earn your way onto a score-board with difficult random characters (#50606) * start * done * done * gold wheelchair * mats * icons * Update code/datums/achievements/hardcore_random.dm Co-Authored-By: ATH1909 <42606352+ATH1909@users.noreply.github.com> * fixes * Update code/controllers/subsystem/processing/quirks.dm Co-Authored-By: spookydonut * proc * Update code/__HELPERS/roundend.dm Co-Authored-By: spookydonut * Update code/__HELPERS/roundend.dm Co-Authored-By: spookydonut * playtime stuff * Update code/__HELPERS/roundend.dm Co-Authored-By: Rohesie * Update code/__HELPERS/roundend.dm Co-Authored-By: Rohesie * Update code/__HELPERS/roundend.dm Co-Authored-By: Rohesie * Update code/datums/traits/_quirk.dm Co-Authored-By: Rohesie * Update code/datums/traits/negative.dm Co-Authored-By: Rohesie * Update code/modules/client/preferences.dm Co-Authored-By: Rohesie * Update code/modules/client/preferences.dm Co-Authored-By: Rohesie * Update code/modules/client/preferences.dm Co-Authored-By: Rohesie * fixes * done * fix * removes u * Update code/modules/client/preferences_savefile.dm Co-Authored-By: Rohesie * overlay * Update code/modules/mob/dead/new_player/preferences_setup.dm Co-Authored-By: Rohesie * Update code/modules/mob/dead/new_player/preferences_setup.dm Co-Authored-By: Rohesie * less braindead code * woops * Update code/__HELPERS/roundend.dm Co-authored-by: Rohesie * Update code/__HELPERS/roundend.dm Co-authored-by: Rohesie * Update code/controllers/subsystem/ticker.dm Co-authored-by: Rohesie * done Co-authored-by: ATH1909 <42606352+ATH1909@users.noreply.github.com> Co-authored-by: spookydonut Co-authored-by: Rohesie --- code/__DEFINES/achievements.dm | 3 + code/__DEFINES/misc.dm | 5 ++ code/__DEFINES/preferences.dm | 1 + code/__HELPERS/roundend.dm | 42 ++++++++++++++ .../subsystem/processing/quirks.dm | 14 ++++- code/controllers/subsystem/ticker.dm | 9 +++ code/datums/achievements/_achievement_data.dm | 6 +- code/datums/achievements/hardcore_random.dm | 4 ++ code/datums/traits/_quirk.dm | 2 + code/datums/traits/negative.dm | 30 +++++++++- code/modules/client/client_procs.dm | 8 ++- code/modules/client/preferences.dm | 31 +++++++++-- .../mob/dead/new_player/preferences_setup.dm | 52 ++++++++++++++++++ .../mob/living/carbon/human/human_defines.dm | 2 + code/modules/vehicles/wheelchair.dm | 16 +++++- icons/obj/vehicles.dmi | Bin 73221 -> 77475 bytes tgstation.dme | 1 + 17 files changed, 213 insertions(+), 13 deletions(-) create mode 100644 code/datums/achievements/hardcore_random.dm diff --git a/code/__DEFINES/achievements.dm b/code/__DEFINES/achievements.dm index 68e033420b1..db0ff4a3501 100644 --- a/code/__DEFINES/achievements.dm +++ b/code/__DEFINES/achievements.dm @@ -63,3 +63,6 @@ #define SWARMER_BEACON_SCORE "Swarmer Beacs Killed" #define KINGGOAT_SCORE "King Goat Killed" #define TENDRIL_CLEAR_SCORE "Tendrils Killed" + +// DB IDs for hardcore random mode +#define HARDCORE_RANDOM_SCORE "Hardcore Random Score" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index ebc0e0b028e..2c09746e5fb 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -487,6 +487,10 @@ GLOBAL_LIST_INIT(pda_styles, sortList(list(MONO, VT, ORBITRON, SHARE))) #define ALIGNMENT_NEUT "neutral" #define ALIGNMENT_EVIL "evil" + +// Play time / EXP +#define PLAYTIME_HARDCORE_RANDOM 120 + // The alpha we give to stuff under tiles, if they want it #define ALPHA_UNDERTILE 128 @@ -495,3 +499,4 @@ GLOBAL_LIST_INIT(pda_styles, sortList(list(MONO, VT, ORBITRON, SHARE))) #define ANON_DISABLED "" //so it's falsey #define ANON_RANDOMNAMES "Random Default" #define ANON_EMPLOYEENAMES "Employees" + diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 91b849bd50e..87f761016d2 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -86,6 +86,7 @@ #define JP_HIGH 3 //randomised elements +#define RANDOM_HARDCORE "random_hardcore" #define RANDOM_NAME "random_name" #define RANDOM_NAME_ANTAG "random_name_antag" #define RANDOM_BODY "random_body" diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index e173231ffdf..121acf332ff 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -177,6 +177,29 @@ file_data["wanted"] = list("author" = "[GLOB.news_network.wanted_issue.scannedUser]", "criminal" = "[GLOB.news_network.wanted_issue.criminal]", "description" = "[GLOB.news_network.wanted_issue.body]", "photo file" = "[GLOB.news_network.wanted_issue.photo_file]") WRITE_FILE(json_file, json_encode(file_data)) +///Handles random hardcore point rewarding if it applies. +/datum/controller/subsystem/ticker/proc/HandleRandomHardcoreScore(client/player_client) + if(!ishuman(player_client.mob)) + return FALSE + var/mob/living/carbon/human/human_mob = player_client.mob + if(!human_mob.hardcore_survival_score) ///no score no glory + return FALSE + + if(human_mob.mind && (human_mob.mind.special_role || length(human_mob.mind.antag_datums) > 0)) + var/didthegamerwin = TRUE + for(var/a in human_mob.mind.antag_datums) + var/datum/antagonist/antag_datum = a + for(var/i in antag_datum.objectives) + var/datum/objective/objective_datum = i + if(!objective_datum.check_completion()) + didthegamerwin = FALSE + if(!didthegamerwin) + return FALSE + player_client.give_award(/datum/award/score/hardcore_random, human_mob, round(human_mob.hardcore_survival_score)) + else if(human_mob.onCentCom()) + player_client.give_award(/datum/award/score/hardcore_random, human_mob, round(human_mob.hardcore_survival_score)) + + /datum/controller/subsystem/ticker/proc/declare_completion() set waitfor = FALSE @@ -198,6 +221,7 @@ C.playtitlemusic(40) if(speed_round) C.give_award(/datum/award/achievement/misc/speed_round, C.mob) + HandleRandomHardcoreScore(C) var/popcount = gather_roundend_feedback() display_report(popcount) @@ -280,6 +304,8 @@ //Antagonists parts += antag_report() + parts += hardcore_random_report() + CHECK_TICK //Medals parts += medal_report() @@ -435,6 +461,22 @@ return "
[parts.Join("
")]
" return "" +///Generate a report for all players who made it out alive with a hardcore random character and prints their final score +/datum/controller/subsystem/ticker/proc/hardcore_random_report() + . = list() + . += "The following people made it out as a random hardcore character:" + . += "
    " + for(var/i in GLOB.player_list) + if(!ishuman(i)) + continue + var/mob/living/carbon/human/human_player = i + if(!human_player.hardcore_survival_score || !human_player.onCentCom() || human_player.stat == DEAD) ///gotta escape nerd + continue + if(!human_player.mind) + continue + . += "
  • [printplayer(human_player.mind)] with a hardcore random score of [round(human_player.hardcore_survival_score)]
  • " + . += "
" + /datum/controller/subsystem/ticker/proc/antag_report() var/list/result = list() var/list/all_teams = list() diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index 365b2320d7e..2b7563c90c9 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -12,7 +12,9 @@ PROCESSING_SUBSYSTEM_DEF(quirks) var/list/quirks = list() //Assoc. list of all roundstart quirk datum types; "name" = /path/ var/list/quirk_points = list() //Assoc. list of quirk names and their "point cost"; positive numbers are good traits, and negative ones are bad var/list/quirk_objects = list() //A list of all quirk objects in the game, since some may process - var/list/quirk_blacklist = list() //A list a list of quirks that can not be used with each other. Format: list(quirk1,quirk2),list(quirk3,quirk4) + var/list/quirk_blacklist = list() //A list of quirks that can not be used with each other. Format: list(quirk1,quirk2),list(quirk3,quirk4) + ///An assoc list of quirks that can be obtained as a hardcore character, and their hardcore value. + var/list/hardcore_quirks = list() /datum/controller/subsystem/processing/quirks/Initialize(timeofday) if(!quirks.len) @@ -30,6 +32,12 @@ PROCESSING_SUBSYSTEM_DEF(quirks) quirks[initial(T.name)] = T quirk_points[initial(T.name)] = initial(T.value) + var/hardcore_value = initial(T.hardcore_value) + + if(!hardcore_value) + continue + hardcore_quirks[T] += hardcore_value + /datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/cli, spawn_effects) var/badquirk = FALSE for(var/V in cli.prefs.all_quirks) @@ -43,6 +51,10 @@ PROCESSING_SUBSYSTEM_DEF(quirks) if(badquirk) cli.prefs.save_character() + if(ishuman(user)) + var/mob/living/carbon/human/human = user + human.hardcore_survival_score = cli.prefs.hardcore_survival_score //Only do this if we actually asign quirks, to prevent sillicons etc from getting the points. + // Assign wayfinding pinpointer granting quirk if they're new if(cli.get_exp_living(TRUE) < EXP_ASSIGN_WAYFINDER && !user.has_quirk(/datum/quirk/needswayfinder)) user.add_quirk(/datum/quirk/needswayfinder, TRUE) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 62a5e7ce287..56f89abdcb9 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -322,6 +322,15 @@ SUBSYSTEM_DEF(ticker) else stack_trace("[S] [S.type] found in start landmarks list, which isn't a start landmark!") + for(var/i in GLOB.player_list) + if(!ishuman(i)) + continue + var/mob/living/carbon/human/hardcore_player = i + if(!hardcore_player.hardcore_survival_score) + continue + if(hardcore_player.mind?.special_role) + hardcore_player.hardcore_survival_score *= 2 //Double for antags + to_chat(hardcore_player, "You will gain [round(hardcore_player.hardcore_survival_score)] hardcore random points if you survive this round!") //These callbacks will fire after roundstart key transfer /datum/controller/subsystem/ticker/proc/OnRoundstart(datum/callback/cb) diff --git a/code/datums/achievements/_achievement_data.dm b/code/datums/achievements/_achievement_data.dm index f353ef03614..52b07472982 100644 --- a/code/datums/achievements/_achievement_data.dm +++ b/code/datums/achievements/_achievement_data.dm @@ -59,8 +59,8 @@ data[achievement_type] = A.load(owner_ckey) original_cached_data[achievement_type] = data[achievement_type] -///Unlocks an achievement of a specific type. -/datum/achievement_data/proc/unlock(achievement_type, mob/user) +///Unlocks an achievement of a specific type. achievement type is a typepath to the award, user is the mob getting the award, and value is an optional value to be used for defining a score to add to the leaderboard +/datum/achievement_data/proc/unlock(achievement_type, mob/user, value = 1) if(!SSachievements.achievements_enabled) return var/datum/award/A = SSachievements.awards[achievement_type] @@ -71,7 +71,7 @@ data[achievement_type] = TRUE A.on_unlock(user) //Only on default achievement, as scores keep going up. else if(istype(A, /datum/award/score)) - data[achievement_type] += 1 + data[achievement_type] += value ///Getter for the status/score of an achievement /datum/achievement_data/proc/get_achievement_status(achievement_type) diff --git a/code/datums/achievements/hardcore_random.dm b/code/datums/achievements/hardcore_random.dm new file mode 100644 index 00000000000..c5e2692552f --- /dev/null +++ b/code/datums/achievements/hardcore_random.dm @@ -0,0 +1,4 @@ +/datum/award/score/hardcore_random + name = "Hardcore random points" + desc = "Well, I might be a blind, deaf, crippled guy, but hey, at least I'm alive." + database_id = HARDCORE_RANDOM_SCORE diff --git a/code/datums/traits/_quirk.dm b/code/datums/traits/_quirk.dm index 7f1a203e2d7..c36e1679135 100644 --- a/code/datums/traits/_quirk.dm +++ b/code/datums/traits/_quirk.dm @@ -10,6 +10,8 @@ var/medical_record_text //This text will appear on medical records for the trait. Not yet implemented var/mood_quirk = FALSE //if true, this quirk affects mood and is unavailable if moodlets are disabled var/mob_trait //if applicable, apply and remove this mob trait + ///Amount of points this trait is worth towards the hardcore character mode; minus points implies a positive quirk, positive means its hard. This is used to pick the quirks assigned to a hardcore character. 0 means its not available to hardcore draws. + var/hardcore_value = 0 var/mob/living/quirk_holder /datum/quirk/New(mob/living/quirk_mob, spawn_effects) diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index d38d8f76bcf..1e9e2187ee1 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -8,6 +8,7 @@ gain_text = "Your back REALLY hurts!" lose_text = "Your back feels better." medical_record_text = "Patient scans indicate severe and chronic back pain." + hardcore_value = 4 /datum/quirk/badback/on_process() var/mob/living/carbon/human/H = quirk_holder @@ -23,6 +24,7 @@ gain_text = "You feel your vigor slowly fading away." lose_text = "You feel vigorous again." medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood." + hardcore_value = 8 /datum/quirk/blooddeficiency/on_process() var/mob/living/carbon/human/H = quirk_holder @@ -39,6 +41,7 @@ gain_text = "You can't see anything." lose_text = "You miraculously gain back your vision." medical_record_text = "Patient has permanent blindness." + hardcore_value = 15 /datum/quirk/blindness/add() quirk_holder.become_blind(ROUNDSTART_TRAIT) @@ -57,6 +60,7 @@ gain_text = "You feel smooth." lose_text = "You feel wrinkled again." medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death." + hardcore_value = 12 /datum/quirk/brainproblems/on_process() quirk_holder.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2) @@ -69,6 +73,7 @@ gain_text = "You can't hear anything." lose_text = "You're able to hear again!" medical_record_text = "Patient's cochlear nerve is incurably damaged." + hardcore_value = 12 /datum/quirk/depression name = "Depression" @@ -79,6 +84,7 @@ lose_text = "You no longer feel depressed." //if only it were that easy! medical_record_text = "Patient has a mild mood disorder causing them to experience acute episodes of depression." mood_quirk = TRUE + hardcore_value = 1 /datum/quirk/depression/on_process() if(prob(0.05)) @@ -92,6 +98,7 @@ var/obj/item/heirloom var/where medical_record_text = "Patient demonstrates an unnatural attachment to a family heirloom." + hardcore_value = 1 /datum/quirk/family_heirloom/on_spawn() var/mob/living/carbon/human/H = quirk_holder @@ -216,6 +223,7 @@ gain_text = "You feel frail." lose_text = "You feel sturdy again." medical_record_text = "Patient has unusually frail bones, recommend calcium-rich diet." + hardcore_value = 4 /datum/quirk/heavy_sleeper name = "Heavy Sleeper" @@ -225,6 +233,7 @@ gain_text = "You feel sleepy." lose_text = "You feel awake again." medical_record_text = "Patient has abnormal sleep study results and is difficult to wake up." + hardcore_value = 2 /datum/quirk/hypersensitive name = "Hypersensitive" @@ -233,6 +242,7 @@ gain_text = "You seem to make a big deal out of everything." lose_text = "You don't seem to make a big deal out of everything anymore." medical_record_text = "Patient demonstrates a high level of emotional volatility." + hardcore_value = 3 /datum/quirk/hypersensitive/add() var/datum/component/mood/mood = quirk_holder.GetComponent(/datum/component/mood) @@ -253,6 +263,7 @@ gain_text = "Just the thought of drinking alcohol makes your head spin." lose_text = "You're no longer severely affected by alcohol." medical_record_text = "Patient demonstrates a low tolerance for alcohol. (Wimp)" + hardcore_value = 3 /datum/quirk/nearsighted //t. errorage name = "Nearsighted" @@ -261,6 +272,7 @@ gain_text = "Things far away from you start looking blurry." lose_text = "You start seeing faraway things normally again." medical_record_text = "Patient requires prescription glasses in order to counteract nearsightedness." + hardcore_value = 5 /datum/quirk/nearsighted/add() quirk_holder.become_nearsighted(ROUNDSTART_TRAIT) @@ -277,6 +289,7 @@ desc = "As far as you can remember, you've always been afraid of the dark. While in the dark without a light source, you instinctually act careful, and constantly feel a sense of dread." value = -1 medical_record_text = "Patient demonstrates a fear of the dark. (Seriously?)" + hardcore_value = 5 /datum/quirk/nyctophobia/on_process() var/mob/living/carbon/human/H = quirk_holder @@ -300,6 +313,7 @@ gain_text = "You feel repulsed by the thought of violence!" lose_text = "You think you can defend yourself again." medical_record_text = "Patient is unusually pacifistic and cannot bring themselves to cause physical harm." + hardcore_value = 6 /datum/quirk/paraplegic name = "Paraplegic" @@ -309,6 +323,7 @@ gain_text = null // Handled by trauma. lose_text = null medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities." + hardcore_value = 15 /datum/quirk/paraplegic/add() var/datum/brain_trauma/severe/paralysis/paraplegic/T = new() @@ -322,7 +337,11 @@ var/turf/T = get_turf(quirk_holder) var/obj/structure/chair/spawn_chair = locate() in T - var/obj/vehicle/ridden/wheelchair/wheels = new(T) + var/obj/vehicle/ridden/wheelchair/wheels + if(quirk_holder.client?.get_award_status(HARDCORE_RANDOM_SCORE) >= 5000) //More than 5k score? you unlock the gamer wheelchair. + wheels = new /obj/vehicle/ridden/wheelchair/gold(T) + else + wheels = new(T) if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking wheels.setDir(spawn_chair.dir) @@ -341,6 +360,7 @@ value = -1 mob_trait = TRAIT_POOR_AIM medical_record_text = "Patient possesses a strong tremor in both hands." + hardcore_value = 3 /datum/quirk/prosopagnosia name = "Prosopagnosia" @@ -348,6 +368,7 @@ value = -1 mob_trait = TRAIT_PROSOPAGNOSIA medical_record_text = "Patient suffers from prosopagnosia and cannot recognize faces." + hardcore_value = 5 /datum/quirk/prosthetic_limb name = "Prosthetic Limb" @@ -355,6 +376,7 @@ value = -1 var/slot_string = "limb" medical_record_text = "During physical examination, patient was found to have a prosthetic limb." + hardcore_value = 3 /datum/quirk/prosthetic_limb/on_spawn() var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) @@ -390,6 +412,7 @@ gain_text = "You feel like a pushover." lose_text = "You feel like standing up for yourself." medical_record_text = "Patient presents a notably unassertive personality and is easy to manipulate." + hardcore_value = 4 /datum/quirk/insanity name = "Reality Dissociation Syndrome" @@ -399,6 +422,7 @@ gain_text = "..." lose_text = "You feel in tune with the world again." medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations." + hardcore_value = 6 /datum/quirk/insanity/on_process() if(quirk_holder.reagents.has_reagent(/datum/reagent/toxin/mindbreaker, needs_metabolizing = TRUE)) @@ -423,6 +447,7 @@ gain_text = "You start worrying about what you're saying." lose_text = "You feel easier about talking again." //if only it were that easy! medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them." + hardcore_value = 4 var/dumb_thing = TRUE /datum/quirk/social_anxiety/on_process() @@ -449,6 +474,7 @@ gain_text = "You suddenly feel the craving for drugs." lose_text = "You feel like you should kick your drug habit." medical_record_text = "Patient has a history of hard drugs." + hardcore_value = 4 var/drug_list = list(/datum/reagent/drug/crank, /datum/reagent/drug/krokodil, /datum/reagent/medicine/morphine, /datum/reagent/drug/happiness, /datum/reagent/drug/methamphetamine) //List of possible IDs var/datum/reagent/reagent_type //!If this is defined, reagent_id will be unused and the defined reagent type will be instead. var/datum/reagent/reagent_instance //! actual instanced version of the reagent @@ -518,6 +544,7 @@ medical_record_text = "Patient is a current smoker." reagent_type = /datum/reagent/drug/nicotine accessory_type = /obj/item/lighter/greyscale + hardcore_value = 1 /datum/quirk/junkie/smoker/on_spawn() drug_container_type = pick(/obj/item/storage/fancy/cigarettes, @@ -551,3 +578,4 @@ gain_text = "There's a lot on your mind right now." lose_text = "Your mind finally feels calm." medical_record_text = "Patient's mind is in a vulnerable state, and cannot recover from traumatic events." + hardcore_value = 9 diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index b2885c31771..b21a91ff759 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -960,6 +960,10 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) qdel(S) char_render_holders = null +///Redirect proc that makes it easier to call the unlock achievement proc. Achievement type is the typepath to the award, user is the mob getting the award, and value is an optional variable used for leaderboard value increments +/client/proc/give_award(achievement_type, mob/user, value = 1) + return player_details.achievements.unlock(achievement_type, user, value) -/client/proc/give_award(achievement_type, mob/user) - return player_details.achievements.unlock(achievement_type, user) +///Redirect proc that makes it easier to get the status of an achievement. Achievement type is the typepath to the award. +/client/proc/get_award_status(achievement_type, mob/user, value = 1) + return player_details.achievements.get_achievement_status(achievement_type) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 7f80f1d74c2..729dbc46bb5 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -112,6 +112,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/action_buttons_screen_locs = list() + ///This var stores the amount of points the owner will get for making it out alive. + var/hardcore_survival_score = 0 + /datum/preferences/New(client/C) parent = C @@ -197,6 +200,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Random Name " dat += "Always Random Name: [(randomise[RANDOM_NAME]) ? "Yes" : "No"]" dat += "When Antagonist: [(randomise[RANDOM_NAME_ANTAG]) ? "Yes" : "No"]" + if(user.client.get_exp_living(TRUE) >= PLAYTIME_HARDCORE_RANDOM) + dat += "Hardcore Random: [(randomise[RANDOM_HARDCORE]) ? "Yes" : "No"]" dat += "
Name: " dat += "[real_name]
" @@ -1098,8 +1103,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) return for(var/V in SSquirks.quirk_blacklist) //V is a list var/list/L = V + if(!(quirk in L)) + continue for(var/Q in all_quirks) - if((quirk in L) && (Q in L) && !(Q == quirk)) //two quirks have lined up in the list of the list of quirks that conflict with each other, so return (see quirks.dm for more details) + if((Q in L) && !(Q == quirk)) //two quirks have lined up in the list of the list of quirks that conflict with each other, so return (see quirks.dm for more details) to_chat(user, "[quirk] is incompatible with [Q].") return var/value = SSquirks.quirk_points[quirk] @@ -1740,17 +1747,24 @@ GLOBAL_LIST_EMPTY(preferences_datums) /datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1, roundstart_checks = TRUE, character_setup = FALSE, antagonist = FALSE) - if(randomise[RANDOM_SPECIES] && !character_setup) + hardcore_survival_score = 0 //Set to 0 to prevent you getting points from last another time. + + if((randomise[RANDOM_SPECIES] || randomise[RANDOM_HARDCORE]) && !character_setup) + random_species() - if((randomise[RANDOM_BODY] || randomise[RANDOM_BODY_ANTAG] && antagonist) && !character_setup) + if((randomise[RANDOM_BODY] || (randomise[RANDOM_BODY_ANTAG] && antagonist) || randomise[RANDOM_HARDCORE]) && !character_setup) slot_randomized = TRUE random_character(gender, antagonist) - if((randomise[RANDOM_NAME] || randomise[RANDOM_NAME_ANTAG] && antagonist) && !character_setup) + if((randomise[RANDOM_NAME] || (randomise[RANDOM_NAME_ANTAG] && antagonist) || randomise[RANDOM_HARDCORE]) && !character_setup) slot_randomized = TRUE real_name = pref_species.random_name(gender) + if(randomise[RANDOM_HARDCORE] && parent.mob.mind && !character_setup) + if(can_be_random_hardcore()) + hardcore_random_setup(character, antagonist) + if(roundstart_checks) if(CONFIG_GET(flag/humans_need_surnames) && (pref_species.id == "human")) var/firstspace = findtext(real_name, " ") @@ -1806,6 +1820,15 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.update_hair() character.update_body_parts() +/datum/preferences/proc/can_be_random_hardcore() + if(parent.mob.mind.assigned_role in GLOB.command_positions) //No command staff + return FALSE + for(var/A in parent.mob.mind.antag_datums) + var/datum/antagonist/antag + if(antag.get_team()) //No team antags + return FALSE + return TRUE + /datum/preferences/proc/get_default_name(name_id) switch(name_id) if("human") diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index 7dd7a596c25..f86527a7776 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -46,6 +46,58 @@ if(randomise[RANDOM_NAME]) real_name = pref_species.random_name(gender,1) +///Setup a hardcore random character and calculate their hardcore random score +/datum/preferences/proc/hardcore_random_setup(mob/living/carbon/human/character, antagonist) + random_character(TRUE, antagonist) + select_hardcore_quirks() + hardcore_survival_score = hardcore_survival_score ** 1.2 //30 points would be about 60 score + +///Go through all quirks that can be used in hardcore mode and select some based on a random budget. +/datum/preferences/proc/select_hardcore_quirks() + + var/quirk_budget = rand(8, 35) + + + all_quirks = list() //empty it out + + var/list/available_hardcore_quirks = SSquirks.hardcore_quirks.Copy() + + while(quirk_budget > 0) + for(var/i in available_hardcore_quirks) //Remove from available quirks if its too expensive. + var/datum/quirk/available_quirk = i + if(available_hardcore_quirks[available_quirk] > quirk_budget) + available_hardcore_quirks -= available_quirk + + if(!available_hardcore_quirks.len) + break + + var/datum/quirk/picked_quirk = pick(available_hardcore_quirks) + + var/picked_quirk_blacklisted = FALSE + for(var/bl in SSquirks.quirk_blacklist) //Check if the quirk is blacklisted with our current quirks. quirk_blacklist is a list of lists. + var/list/blacklist = bl + if(!(picked_quirk in blacklist)) + continue + for(var/iterator_quirk in all_quirks) //Go through all the quirks we've already selected to see if theres a blacklist match + if((iterator_quirk in blacklist) && !(iterator_quirk == picked_quirk)) //two quirks have lined up in the list of the list of quirks that conflict with each other, so return (see quirks.dm for more details) + picked_quirk_blacklisted = TRUE + break + if(picked_quirk_blacklisted) + break + + if(picked_quirk_blacklisted) + available_hardcore_quirks -= picked_quirk + continue + + if(initial(picked_quirk.mood_quirk) && CONFIG_GET(flag/disable_human_mood)) //check for moodlet quirks + available_hardcore_quirks -= picked_quirk + continue + + all_quirks += initial(picked_quirk.name) + quirk_budget -= available_hardcore_quirks[picked_quirk] + hardcore_survival_score += available_hardcore_quirks[picked_quirk] + available_hardcore_quirks -= picked_quirk + /datum/preferences/proc/update_preview_icon() // Determine what job is marked as 'High' priority, and dress them up as such. var/datum/job/previewJob diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index fcc10776a69..dce7417d18e 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -61,3 +61,5 @@ var/lastpuke = 0 var/last_fire_update var/account_id + + var/hardcore_survival_score = 0 diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm index 2eb1a2ad5df..befd00ccfca 100644 --- a/code/modules/vehicles/wheelchair.dm +++ b/code/modules/vehicles/wheelchair.dm @@ -9,8 +9,10 @@ legs_required = 0 //You'll probably be using this if you don't have legs canmove = TRUE density = FALSE //Thought I couldn't fix this one easily, phew - // Run speed delay is multiplied with this for vehicle move delay. + /// Run speed delay is multiplied with this for vehicle move delay. var/delay_multiplier = 6.7 + /// This variable is used to specify which overlay icon is used for the wheelchair, ensures wheelchair can cover your legs + var/overlay_icon = "wheelchair_overlay" /obj/vehicle/ridden/wheelchair/Initialize() . = ..() @@ -91,7 +93,7 @@ /obj/vehicle/ridden/wheelchair/proc/handle_rotation_overlayed() cut_overlays() - var/image/V = image(icon = icon, icon_state = "wheelchair_overlay", layer = FLY_LAYER, dir = src.dir) + var/image/V = image(icon = icon, icon_state = overlay_icon, layer = FLY_LAYER, dir = src.dir) add_overlay(V) @@ -113,3 +115,13 @@ var/datum/component/riding/D = GetComponent(/datum/component/riding) D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * 6.7) / user.get_num_arms() return ..() + + +/obj/vehicle/ridden/wheelchair/gold + material_flags = MATERIAL_ADD_PREFIX | MATERIAL_AFFECT_STATISTICS + desc = "Damn, he's been through a lot." + icon_state = "gold_wheelchair" + overlay_icon = "gold_wheelchair_overlay" + max_integrity = 200 + armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 0, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 40) + custom_materials = list(/datum/material/gold = 10000) diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi index ff49753f22bbcd99a5a018b0a9b6c75b642906f1..6e5f346cc515169532da76fb4982c00a210d28b8 100644 GIT binary patch delta 15288 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 Q0-!&&M^7JCC|kV!U*7M2mjD0& delta 11001 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