Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into station_traits
This commit is contained in:
@@ -69,6 +69,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
|
||||
/client/proc/cmd_admin_man_up, //CIT CHANGE - adds man up verb
|
||||
/client/proc/cmd_admin_man_up_global, //CIT CHANGE - ditto
|
||||
/client/proc/cmd_admin_create_centcom_report,
|
||||
/client/proc/cmd_admin_make_priority_announcement, //CIT CHANGE
|
||||
/client/proc/cmd_change_command_name,
|
||||
/client/proc/cmd_admin_check_player_exp, /* shows players by playtime */
|
||||
/client/proc/toggle_combo_hud, // toggle display of the combination pizza antag and taco sci/med/eng hud
|
||||
|
||||
@@ -150,7 +150,7 @@ GLOBAL_LIST(round_end_notifiees)
|
||||
|
||||
/datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params)
|
||||
var/saltresult = "The wheel of salt [pick("clatters","screams","vibrates","clanks","resonates","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic"," demonic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog","laughing")] noise")] as it spins violently... And it seems the salt of the day is the "
|
||||
var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin removal","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]"
|
||||
var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin removal","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Polly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]"
|
||||
var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP","bikeshedding","crossdressing","sprites","semen keg","argument","theft","nerf","screeching","salt","creampie","lewding","murder","kissing","marriage","replacement","fucking","ship","netflix adaptation","dance","remaster","system","voyeur","decoration","pre-order","bukkake","seduction","worship","gangbang","handholding")]"
|
||||
if(prob(10))
|
||||
saltresult += "@here for your salt, all day every day"
|
||||
@@ -174,12 +174,12 @@ GLOBAL_LIST(round_end_notifiees)
|
||||
/datum/tgs_chat_command/despacito/Run()
|
||||
return "https://www.youtube.com/watch?v=kJQP7kiw5Fk"
|
||||
|
||||
/datum/tgs_chat_command/poly
|
||||
name = "poly"
|
||||
help_text = "The Lewder, more applicable Poly speak for Citadel Station 13."
|
||||
/datum/tgs_chat_command/polly
|
||||
name = "polly"
|
||||
help_text = "The Lewder, more applicable Polly speak for Citadel Station 13."
|
||||
var/list/speech_buffer
|
||||
|
||||
/datum/tgs_chat_command/poly/Run()
|
||||
/datum/tgs_chat_command/polly/Run()
|
||||
LAZYINITLIST(speech_buffer) //I figure this is just safe to do for everything at this point
|
||||
if(length(speech_buffer)) //Let's not look up the whole json EVERY TIME, just the first time.
|
||||
return "[pick(speech_buffer)]"
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
H.dna.features["flavor_text"] = "" //Oh no.
|
||||
H.dna.features["body_model"] = H.gender
|
||||
|
||||
H.set_bark(pick(GLOB.bark_random_list))
|
||||
H.vocal_pitch = BARK_PITCH_RAND(H.gender)
|
||||
H.vocal_pitch_range = BARK_VARIANCE_RAND
|
||||
|
||||
SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE)
|
||||
|
||||
H.update_body(TRUE)
|
||||
|
||||
@@ -489,8 +489,8 @@
|
||||
M.change_mob_type( /mob/living/simple_animal/crab/Coffee , null, null, delmob )
|
||||
if("parrot")
|
||||
M.change_mob_type( /mob/living/simple_animal/parrot , null, null, delmob )
|
||||
if("polyparrot")
|
||||
M.change_mob_type( /mob/living/simple_animal/parrot/Poly , null, null, delmob )
|
||||
if("pollyparrot")
|
||||
M.change_mob_type( /mob/living/simple_animal/parrot/Polly , null, null, delmob )
|
||||
if("constructarmored")
|
||||
M.change_mob_type( /mob/living/simple_animal/hostile/construct/armored , null, null, delmob )
|
||||
if("constructbuilder")
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
factory.spores += src
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!is_zombie && isturf(src.loc))
|
||||
@@ -233,7 +233,7 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
var/list/blobs_in_area = range(2, src)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// * MEZMERIZE
|
||||
// LOVE: Target falls in love with you. Being harmed directly causes them harm if they see it?
|
||||
// STAY: Target will do everything they can to stand in the same place.
|
||||
// FOLLOW: Target follows you, spouting random phrases from their history (or maybe Poly's or NPC's vocab?)
|
||||
// FOLLOW: Target follows you, spouting random phrases from their history (or maybe Polly's or NPC's vocab?)
|
||||
// ATTACK: Target finds a nearby non-Bloodsucker victim to attack.
|
||||
|
||||
/datum/action/bloodsucker/targeted/mesmerize
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD
|
||||
var/always_keep = 0 // important for abilities like revive that screw you if you lose them.
|
||||
var/ignores_fakedeath = FALSE // usable with the FAKEDEATH flag
|
||||
var/loudness = 0 //Determines how much having this ability will affect changeling blood tests. At 4, the blood will react violently and turn to ash, creating a unique message in the process. At 10, the blood will explode when heated.
|
||||
var/loudness = 0.5 //Determines how much having this ability will affect changeling blood tests. This is averaged with other purchased abilities. Above 1, the blood will react violently and turn to ash, creating a unique message in the process. Above 2, the blood will explode when heated.
|
||||
|
||||
|
||||
/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user, is_respec)
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
/mob/living/simple_animal/hostile/clockwork/examine(mob/user)
|
||||
var/t_He = p_they(TRUE)
|
||||
var/t_s = p_s()
|
||||
var/msg = "<span class='brass'>*---------*\nThis is [icon2html(src, user)] \a <b>[src]</b>!\n"
|
||||
var/msg = "<span class='brass'>This is [icon2html(src, user)] \a <b>[src]</b>!\n"
|
||||
msg += "[desc]\n"
|
||||
if(health < maxHealth)
|
||||
msg += "<span class='warning'>"
|
||||
@@ -55,7 +55,7 @@
|
||||
var/addendum = examine_info()
|
||||
if(addendum)
|
||||
msg += "[addendum]\n"
|
||||
msg += "*---------*</span>"
|
||||
msg += "</span>"
|
||||
|
||||
return list(msg)
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
. = ..()
|
||||
true_name = pick(possible_true_names)
|
||||
|
||||
/mob/living/simple_animal/hostile/clockwork/guardian/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/clockwork/guardian/BiologicalLife(delta_time, times_fired)
|
||||
..()
|
||||
if(is_in_host())
|
||||
if(!is_servant_of_ratvar(host))
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
if(!shield_health)
|
||||
return "<span class='warning'>Its shield has been destroyed!</span>"
|
||||
|
||||
/mob/living/simple_animal/hostile/clockwork/marauder/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/hostile/clockwork/marauder/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
..()
|
||||
boost = world.time + 30
|
||||
|
||||
/mob/living/simple_animal/imp/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/imp/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(boost<world.time)
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
|
||||
/mob/living/carbon/true_devil/examine(mob/user)
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] <b>[src]</b>!")
|
||||
. = list("<span class='info'>This is [icon2html(src, user)] <b>[src]</b>!")
|
||||
|
||||
//Left hand items
|
||||
for(var/obj/item/I in held_items)
|
||||
@@ -81,7 +81,7 @@
|
||||
. += "<span class='warning'>You can see hellfire inside its gaping wounds.</span>"
|
||||
else if(health < (maxHealth/2))
|
||||
. += "<span class='warning'>You can see hellfire inside its wounds.</span>"
|
||||
. += "*---------*</span>"
|
||||
. += "</span>"
|
||||
|
||||
/mob/living/carbon/true_devil/IsAdvancedToolUser()
|
||||
return 1
|
||||
|
||||
@@ -67,6 +67,11 @@
|
||||
if(handler) // if we have a handler, the handler should track this gang
|
||||
handler.gangs += my_gang
|
||||
my_gang.current_theme = handler.current_theme
|
||||
else if(GLOB.families_override_theme)
|
||||
my_gang.current_theme = new GLOB.families_override_theme
|
||||
else
|
||||
var/theme_to_use = pick(subtypesof(/datum/gang_theme))
|
||||
my_gang.current_theme = new theme_to_use
|
||||
my_gang.name = gang_name
|
||||
my_gang.gang_id = gang_id
|
||||
my_gang.acceptable_clothes = acceptable_clothes.Copy()
|
||||
|
||||
@@ -66,9 +66,21 @@
|
||||
icon_state = "nuclearbomb_base"
|
||||
anchored = TRUE //stops it being moved
|
||||
|
||||
/obj/machinery/nuclearbomb/selfdestruct/Initialize(mapload)
|
||||
. = ..()
|
||||
if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(10))
|
||||
name = "station-wide gender-reveal terminal"
|
||||
desc = "For when the whole sector deserves to know a gender. But of whom? Don't ask."
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate
|
||||
//ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate/Initialize(mapload)
|
||||
. = ..()
|
||||
if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(50))
|
||||
name = "tactical gender-reveal device"
|
||||
desc = "\"But whose gender is it revealing?\" you ponder. Don't worry. That comes later."
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station)
|
||||
var/datum/game_mode/nuclear/NM = SSticker.mode
|
||||
switch(off_station)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
if(!SSpersistence.IsValidDebrisLocation(C.loc, allowed_turf_typecache, allowed_z_cache, C.type, FALSE))
|
||||
continue
|
||||
weight += 0.03
|
||||
CHECK_TICK
|
||||
return ..()
|
||||
|
||||
/datum/round_event/ghost_role/slaughter
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
linked_organ = null
|
||||
. = ..()
|
||||
|
||||
/obj/item/organ/genital/on_life()
|
||||
return
|
||||
|
||||
/obj/item/organ/genital/proc/set_aroused_state(new_state,cause = "manual toggle")
|
||||
if(!(genital_flags & GENITAL_CAN_AROUSE))
|
||||
return FALSE
|
||||
|
||||
@@ -15,12 +15,6 @@
|
||||
var/prev_size //former size value, to allow update_size() to early return should be there no significant changes.
|
||||
layer_index = BUTT_LAYER_INDEX
|
||||
|
||||
/obj/item/organ/genital/butt/on_life()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
/obj/item/organ/genital/butt/modify_size(modifier, min = -INFINITY, max = BUTT_SIZE_MAX)
|
||||
var/new_value = clamp(size_cached + modifier, min, max)
|
||||
if(new_value == size_cached)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
/obj/item/assembly_holder/IsAssemblyHolder()
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/assembly_holder/proc/assemble(obj/item/assembly/A, obj/item/assembly/A2, mob/user)
|
||||
attach(A,user)
|
||||
attach(A2,user)
|
||||
@@ -32,6 +31,8 @@
|
||||
else
|
||||
A.forceMove(src)
|
||||
A.holder = src
|
||||
// bandaid: please don't try to be picked up while we're still in the assembly
|
||||
A.interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP
|
||||
A.toggle_secure()
|
||||
if(!a_left)
|
||||
a_left = A
|
||||
@@ -103,9 +104,11 @@
|
||||
to_chat(user, "<span class='notice'>You disassemble [src]!</span>")
|
||||
if(a_left)
|
||||
a_left.on_detach()
|
||||
a_left.interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP
|
||||
a_left = null
|
||||
if(a_right)
|
||||
a_right.on_detach()
|
||||
a_right.interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP
|
||||
a_right = null
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
gases = list(
|
||||
GAS_METHANE = 1,
|
||||
GAS_METHYL_BROMIDE = -0.7,
|
||||
GAS_OXYGEN = -0.1,
|
||||
GAS_O2 = -0.1,
|
||||
GAS_PLUOXIUM = -0.8
|
||||
)
|
||||
products = list(
|
||||
|
||||
@@ -69,6 +69,19 @@
|
||||
fire_products = FIRE_PRODUCT_PLASMA
|
||||
enthalpy = FIRE_PLASMA_ENERGY_RELEASED // 3000000, 3 megajoules, 3000 kj
|
||||
|
||||
/datum/gas/nitrous_oxide
|
||||
id = GAS_NITROUS
|
||||
specific_heat = 40
|
||||
name = "Nitrous Oxide"
|
||||
gas_overlay = "nitrous_oxide"
|
||||
moles_visible = MOLES_GAS_VISIBLE * 2
|
||||
flags = GAS_FLAG_DANGEROUS
|
||||
fire_products = list(GAS_N2 = 1)
|
||||
oxidation_rate = 0.5
|
||||
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100
|
||||
enthalpy = 81600
|
||||
heat_resistance = 6
|
||||
|
||||
/datum/gas/water_vapor
|
||||
id = GAS_H2O
|
||||
specific_heat = 40
|
||||
@@ -82,18 +95,23 @@
|
||||
powermix = 1
|
||||
breath_reagent = /datum/reagent/water
|
||||
|
||||
/datum/gas/nitrous_oxide
|
||||
id = GAS_NITROUS
|
||||
specific_heat = 40
|
||||
name = "Nitrous Oxide"
|
||||
gas_overlay = "nitrous_oxide"
|
||||
moles_visible = MOLES_GAS_VISIBLE * 2
|
||||
flags = GAS_FLAG_DANGEROUS
|
||||
fire_products = list(GAS_N2 = 1)
|
||||
oxidation_rate = 0.5
|
||||
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100
|
||||
enthalpy = 81600
|
||||
heat_resistance = 6
|
||||
|
||||
/datum/gas/pluoxium
|
||||
id = GAS_PLUOXIUM
|
||||
specific_heat = 80
|
||||
name = "Pluoxium"
|
||||
fusion_power = 10
|
||||
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 25 // it is VERY stable
|
||||
oxidation_rate = 8 // when it can oxidize, it can oxidize a LOT
|
||||
enthalpy = -2000000 // but it reduces the heat output a great deal (plasma fires add 3000000 per mole)
|
||||
powermix = -1
|
||||
heat_penalty = -1
|
||||
transmit_modifier = -5
|
||||
heat_resistance = 3
|
||||
price = 6
|
||||
|
||||
/datum/gas/pluoxium/generate_TLV()
|
||||
return new/datum/tlv(-1, -1, 5, 6)
|
||||
|
||||
/datum/gas/tritium
|
||||
id = GAS_TRITIUM
|
||||
@@ -111,17 +129,19 @@
|
||||
fire_burn_rate = 2
|
||||
fire_radiation_released = 50 // arbitrary number, basically 60 moles of trit burning will just barely start to harm you
|
||||
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
|
||||
price = 7
|
||||
|
||||
/datum/gas/nitric_oxide
|
||||
id = GAS_NITRIC
|
||||
specific_heat = 20
|
||||
name = "Nitric oxide"
|
||||
flags = GAS_FLAG_DANGEROUS
|
||||
odor = "sharp sweetness"
|
||||
odor_strength = 1
|
||||
fusion_power = 15
|
||||
enthalpy = 91290
|
||||
heat_resistance = 2
|
||||
powermix = -1
|
||||
heat_penalty = -1
|
||||
|
||||
/datum/gas/nitryl
|
||||
id = GAS_NITRYL
|
||||
@@ -134,6 +154,7 @@
|
||||
fire_products = list(GAS_N2 = 0.5)
|
||||
enthalpy = 33200
|
||||
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
|
||||
price = 3
|
||||
|
||||
/datum/gas/hypernoblium
|
||||
id = GAS_HYPERNOB
|
||||
@@ -141,6 +162,7 @@
|
||||
name = "Hyper-noblium"
|
||||
gas_overlay = "freon"
|
||||
moles_visible = MOLES_GAS_VISIBLE
|
||||
price = 50
|
||||
|
||||
/datum/gas/hydrogen
|
||||
id = GAS_HYDROGEN
|
||||
@@ -168,6 +190,7 @@
|
||||
enthalpy = FIRE_CARBON_ENERGY_RELEASED // it is a mystery
|
||||
transmit_modifier = -2
|
||||
radioactivity_modifier = 5
|
||||
price = 3
|
||||
|
||||
/datum/gas/stimulum
|
||||
id = GAS_STIMULUM
|
||||
@@ -176,22 +199,7 @@
|
||||
odor_strength = 10
|
||||
name = "Stimulum"
|
||||
fusion_power = 7
|
||||
|
||||
/datum/gas/pluoxium
|
||||
id = GAS_PLUOXIUM
|
||||
specific_heat = 80
|
||||
name = "Pluoxium"
|
||||
fusion_power = 10
|
||||
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 25 // it is VERY stable
|
||||
oxidation_rate = 8 // when it can oxidize, it can oxidize a LOT
|
||||
enthalpy = -2000000 // but it reduces the heat output a great deal (plasma fires add 3000000 per mole)
|
||||
powermix = -1
|
||||
heat_penalty = -1
|
||||
transmit_modifier = -5
|
||||
heat_resistance = 3
|
||||
|
||||
/datum/gas/pluoxium/generate_TLV()
|
||||
return new/datum/tlv(-1, -1, 5, 6)
|
||||
price = 25
|
||||
|
||||
/datum/gas/miasma
|
||||
id = GAS_MIASMA
|
||||
@@ -201,7 +209,9 @@
|
||||
// snowflaked odor
|
||||
name = "Miasma"
|
||||
gas_overlay = "miasma"
|
||||
color = "#963"
|
||||
moles_visible = MOLES_GAS_VISIBLE * 60
|
||||
price = 2
|
||||
|
||||
/datum/gas/methane
|
||||
id = GAS_METHANE
|
||||
@@ -227,6 +237,7 @@
|
||||
)
|
||||
enthalpy = -74600
|
||||
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
|
||||
price = 1
|
||||
|
||||
/datum/gas/methyl_bromide
|
||||
id = GAS_METHYL_BROMIDE
|
||||
@@ -249,6 +260,7 @@
|
||||
enthalpy = -35400
|
||||
fire_burn_rate = 4 / 7 // oh no
|
||||
fire_temperature = 808 // its autoignition; it apparently doesn't spark readily, so i don't put it lower
|
||||
price = 2
|
||||
|
||||
/datum/gas/bromine
|
||||
id = GAS_BROMINE
|
||||
@@ -285,3 +297,4 @@
|
||||
powermix = -1
|
||||
transmit_modifier = -10
|
||||
heat_penalty = -10
|
||||
price = 5 // IT'S NOT ACTUALLY THAT HARD TO GET INTO A CANISTER LOL
|
||||
|
||||
@@ -43,6 +43,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
var/list/TLVs = list()
|
||||
var/list/odors = list()
|
||||
var/list/odor_strengths = list()
|
||||
var/list/prices = list()
|
||||
|
||||
/datum/gas
|
||||
var/id = ""
|
||||
@@ -60,6 +61,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
var/datum/reagent/breath_reagent = null // what breathing this adds to your reagents
|
||||
var/datum/reagent/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold
|
||||
var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something
|
||||
var/price = 0 // How much this gas is worth when sold, per mole.
|
||||
var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none
|
||||
var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material
|
||||
var/fire_temperature = null // temperature above which gas may catch fire; null for none
|
||||
@@ -135,6 +137,8 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
if(gas.odor)
|
||||
odor_strengths[g] = gas.odor_strength
|
||||
odors[g] = gas.odor
|
||||
if(gas.price)
|
||||
prices[g] = gas.price
|
||||
add_supermatter_properties(gas)
|
||||
_auxtools_register_gas(gas)
|
||||
if(done_initializing)
|
||||
|
||||
@@ -729,11 +729,11 @@
|
||||
/datum/gas_reaction/nitric_oxide/react(datum/gas_mixture/air, datum/holder)
|
||||
var/nitric = air.get_moles(GAS_NITRIC)
|
||||
var/oxygen = air.get_moles(GAS_O2)
|
||||
var/max_amount = max(nitric / 10, MINIMUM_MOLE_COUNT)
|
||||
var/enthalpy = air.return_temperature() * (air.heat_capacity() + R_IDEAL_GAS_EQUATION * air.total_moles());
|
||||
var/max_amount = max(nitric / 8, MINIMUM_MOLE_COUNT)
|
||||
var/enthalpy = air.return_temperature() * (air.heat_capacity() + R_IDEAL_GAS_EQUATION * air.total_moles())
|
||||
var/list/enthalpies = GLOB.gas_data.enthalpies
|
||||
if(oxygen > MINIMUM_MOLE_COUNT)
|
||||
var/reaction_amount = min(max_amount, oxygen)
|
||||
var/reaction_amount = min(max_amount, oxygen)/4
|
||||
air.adjust_moles(GAS_NITRIC, -reaction_amount*2)
|
||||
air.adjust_moles(GAS_O2, -reaction_amount)
|
||||
air.adjust_moles(GAS_NITRYL, reaction_amount*2)
|
||||
@@ -759,7 +759,18 @@
|
||||
var/initial_energy = air.thermal_energy()
|
||||
for(var/g in air.get_gases())
|
||||
air.set_moles(g, 0)
|
||||
air.set_moles(GAS_QCD, initial_energy / (air.return_temperature() * GLOB.gas_data.specific_heats[GAS_QCD]))
|
||||
var/amount = initial_energy / (air.return_temperature() * GLOB.gas_data.specific_heats[GAS_QCD])
|
||||
air.set_moles(GAS_QCD, amount)
|
||||
var/list/largest_values = SSresearch.science_tech.largest_values
|
||||
if(!(GAS_QCD in largest_values))
|
||||
largest_values[GAS_QCD] = 0
|
||||
var/previous_largest = largest_values[GAS_QCD]
|
||||
var/research_amount = amount * QCD_RESEARCH_AMOUNT
|
||||
if(previous_largest < research_amount)
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, research_amount)
|
||||
largest_values[GAS_QCD] = research_amount
|
||||
else
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, research_amount / 100)
|
||||
|
||||
/datum/gas_reaction/dehagedorn
|
||||
priority = 50
|
||||
@@ -781,11 +792,10 @@
|
||||
var/list/gases = GLOB.gas_data.specific_heats.Copy()
|
||||
gases -= GAS_QCD
|
||||
gases -= GAS_TRITIUM // no refusing sorry
|
||||
for(var/g in gases)
|
||||
gases[g] = 10000 / gases[g]
|
||||
gases -= GAS_HYPERNOB // makes it waaay too easy to stabilize it
|
||||
while(energy_remaining > 0)
|
||||
var/G = pick(gases)
|
||||
air.adjust_moles(G, max(0.1, energy_remaining / (gases[G] * new_temp * 20)))
|
||||
energy_remaining = initial_energy - air.thermal_energy()
|
||||
air.adjust_heat(-energy_remaining)
|
||||
air.set_temperature(initial_energy / air.heat_capacity())
|
||||
return REACTING
|
||||
|
||||
@@ -45,9 +45,9 @@
|
||||
if(9)
|
||||
SpeakPeace(list("Alright maybe that's <b>too</b> boring.", "I can't keep manually typing these lines out though.", "It's hard to explain but the code structure I'm using is kind of terrible."))
|
||||
if(10)
|
||||
SpeakPeace(list("Oh I have an idea!", "Lets outsource this endless banter to Poly!", "Then you'll be able to keep listening to this without getting bored!"))
|
||||
SpeakPeace(list("Oh I have an idea!", "Lets outsource this endless banter to Polly!", "Then you'll be able to keep listening to this without getting bored!"))
|
||||
if(isnull(shenanigans) || !shenanigans.len)
|
||||
shenanigans = list("Except the poly file is missing...")
|
||||
shenanigans = list("Except the polly file is missing...")
|
||||
if(11 to 14, 16 to 50, 52 to 99, 103 to 107, 109 to 203, 205 to 249, 252 to 665, 667 to 999, 1001 to 5642)
|
||||
SpeakPeace(list(pick(shenanigans),pick(shenanigans),pick(shenanigans)))
|
||||
if(times_spoken_to % 10 == 0)
|
||||
@@ -55,7 +55,7 @@
|
||||
if(15)
|
||||
SpeakPeace(list("See? Isn't this fun?","Now you can mash this for hours without getting bored.","Anyway I'll leave you it."))
|
||||
if(51)
|
||||
SpeakPeace(list("The fun never ends around here.", "The Poly text files stores up to 500 statements.", "But you've probably heard a few repeats by now."))
|
||||
SpeakPeace(list("The fun never ends around here.", "The Polly text files stores up to 500 statements.", "But you've probably heard a few repeats by now."))
|
||||
if(100)
|
||||
SpeakPeace(list("And that's a solid hundred.", "Good hustle I guess.", "You've probably heard a lot of repeats by now."))
|
||||
if(101)
|
||||
|
||||
@@ -169,13 +169,9 @@
|
||||
/datum/export/large/gas_canister/get_cost(obj/O)
|
||||
var/obj/machinery/portable_atmospherics/canister/C = O
|
||||
var/worth = 10
|
||||
worth += C.air_contents.get_moles(GAS_BZ)*3
|
||||
worth += C.air_contents.get_moles(GAS_STIMULUM)*25
|
||||
worth += C.air_contents.get_moles(GAS_HYPERNOB)*20
|
||||
worth += C.air_contents.get_moles(GAS_MIASMA)*2
|
||||
worth += C.air_contents.get_moles(GAS_TRITIUM)*7
|
||||
worth += C.air_contents.get_moles(GAS_PLUOXIUM)*6
|
||||
worth += C.air_contents.get_moles(GAS_NITRYL)*10
|
||||
var/list/gas_prices = GLOB.gas_data.prices
|
||||
for(var/gas in C.air_contents.get_gases())
|
||||
worth += C.air_contents.get_moles(gas)*gas_prices[gas]
|
||||
return worth
|
||||
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@
|
||||
/datum/export/weapon/l6sawammo
|
||||
cost = 60
|
||||
unit_name = "L6 SAW ammo box"
|
||||
export_types = list(/obj/item/ammo_box/magazine/mm195x129)
|
||||
export_types = list(/obj/item/ammo_box/magazine/mm712x82)
|
||||
include_subtypes = TRUE
|
||||
|
||||
/datum/export/weapon/rocket
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
/datum/supply_pack/engineering/engihardsuit
|
||||
name = "Engineering Hardsuit"
|
||||
desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!"
|
||||
desc = "Polly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!"
|
||||
cost = 2250
|
||||
access = ACCESS_ENGINE
|
||||
contains = list(/obj/item/tank/internals/air,
|
||||
|
||||
@@ -135,10 +135,6 @@
|
||||
///Used in MouseDrag to preserve the last mouse-entered object.
|
||||
var/mouseObject = null
|
||||
var/mouseControlObject = null
|
||||
//Middle-mouse-button click dragtime control for aimbot exploit detection.
|
||||
var/middragtime = 0
|
||||
//Middle-mouse-button clicked object control for aimbot exploit detection.
|
||||
var/atom/middragatom
|
||||
|
||||
/// Messages currently seen by this client
|
||||
var/list/seen_messages
|
||||
|
||||
@@ -422,10 +422,12 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
if( (world.address == address || !address) && !GLOB.host )
|
||||
GLOB.host = key
|
||||
world.update_status()
|
||||
|
||||
|
||||
if(holder)
|
||||
add_admin_verbs()
|
||||
to_chat(src, get_message_output("memo"))
|
||||
var/admin_memo_note = get_message_output("memo")
|
||||
if(admin_memo_note)
|
||||
to_chat(src, admin_memo_note)
|
||||
adminGreet()
|
||||
|
||||
add_verbs_from_config()
|
||||
@@ -468,7 +470,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
|
||||
if(CONFIG_GET(flag/autoconvert_notes))
|
||||
convert_notes_sql(ckey)
|
||||
to_chat(src, get_message_output("message", ckey))
|
||||
var/admin_message_note = get_message_output("message", ckey)
|
||||
if(admin_message_note)
|
||||
to_chat(src, admin_message_note)
|
||||
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
|
||||
to_chat(src, "<span class='warning'>Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.</span>")
|
||||
|
||||
@@ -867,10 +871,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
return
|
||||
last_activity = world.time
|
||||
last_click = world.time
|
||||
var/ab = FALSE
|
||||
var/list/L = params2list(params)
|
||||
if (object && object == middragatom && L["left"])
|
||||
ab = max(0, 5 SECONDS-(world.time-middragtime)*0.1)
|
||||
|
||||
if(L["drag"])
|
||||
return
|
||||
|
||||
var/mcl = CONFIG_GET(number/minute_click_limit)
|
||||
if (!holder && !ignore_spam && mcl)
|
||||
var/minute = round(world.time, 600)
|
||||
@@ -879,20 +884,14 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
if (minute != clicklimiter[CURRENT_MINUTE])
|
||||
clicklimiter[CURRENT_MINUTE] = minute
|
||||
clicklimiter[MINUTE_COUNT] = 0
|
||||
clicklimiter[MINUTE_COUNT] += 1+(ab)
|
||||
clicklimiter[MINUTE_COUNT] += 1
|
||||
if (clicklimiter[MINUTE_COUNT] > mcl)
|
||||
var/msg = "Your previous click was ignored because you've done too many in a minute."
|
||||
if (minute != clicklimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them)
|
||||
clicklimiter[ADMINSWARNED_AT] = minute
|
||||
|
||||
msg += " Administrators have been informed."
|
||||
if (ab)
|
||||
log_game("[key_name(src)] is using the middle click aimbot exploit")
|
||||
message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit</span>")
|
||||
add_system_note("aimbot", "Is using the middle click aimbot exploit")
|
||||
log_click(object, location, control, params, src, "lockout (spam - minute ab c [ab] s [middragtime])", TRUE)
|
||||
else
|
||||
log_click(object, location, control, params, src, "lockout (spam - minute)", TRUE)
|
||||
log_click(object, location, control, params, src, "lockout (spam - minute)", TRUE)
|
||||
log_game("[key_name(src)] Has hit the per-minute click limit of [mcl] clicks in a given game minute")
|
||||
message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute")
|
||||
to_chat(src, "<span class='danger'>[msg]</span>")
|
||||
@@ -906,15 +905,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
if (second != clicklimiter[CURRENT_SECOND])
|
||||
clicklimiter[CURRENT_SECOND] = second
|
||||
clicklimiter[SECOND_COUNT] = 0
|
||||
clicklimiter[SECOND_COUNT] += 1+(!!ab)
|
||||
clicklimiter[SECOND_COUNT] += 1
|
||||
if (clicklimiter[SECOND_COUNT] > scl)
|
||||
to_chat(src, "<span class='danger'>Your previous click was ignored because you've done too many in a second</span>")
|
||||
return
|
||||
|
||||
if(ab) //Citadel edit, things with stuff.
|
||||
log_click(object, location, control, params, src, "dropped (ab c [ab] s [middragtime])", TRUE)
|
||||
return
|
||||
|
||||
if(prefs.log_clicks)
|
||||
log_click(object, location, control, params, src, extra_info? "clicked ([extra_info])" : null)
|
||||
|
||||
|
||||
@@ -140,6 +140,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/modified_limbs = list() //prosthetic/amputated limbs
|
||||
var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded
|
||||
|
||||
// Vocal bark prefs
|
||||
var/bark_id = "mutedc3"
|
||||
var/bark_speed = 4
|
||||
var/bark_pitch = 1
|
||||
var/bark_variance = 0.2
|
||||
COOLDOWN_DECLARE(bark_previewing)
|
||||
|
||||
/// Security record note section
|
||||
var/security_records
|
||||
/// Medical record note section
|
||||
@@ -153,6 +160,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
//Quirk list
|
||||
var/list/all_quirks = list()
|
||||
|
||||
//Quirk category currently selected
|
||||
var/quirk_category = QUIRK_POSITIVE // defaults to positive, the first tab!
|
||||
|
||||
//Job preferences 2.0 - indexed by job title , no key or value implies never
|
||||
var/list/job_preferences = list()
|
||||
|
||||
@@ -223,6 +233,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
var/screenshake = 100
|
||||
var/damagescreenshake = 2
|
||||
var/recoil_screenshake = 100
|
||||
var/arousable = TRUE
|
||||
var/autostand = TRUE
|
||||
var/auto_ooc = FALSE
|
||||
@@ -401,7 +412,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h2>Flavor Text</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=flavor_text;task=input'><b>Set Examine Text</b></a><br>"
|
||||
if(length(features["flavor_text"]) <= 40)
|
||||
if(length(features["flavor_text"]) <= MAX_FLAVOR_PREVIEW_LEN)
|
||||
if(!length(features["flavor_text"]))
|
||||
dat += "\[...\]"
|
||||
else
|
||||
@@ -410,7 +421,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "[TextPreview(features["flavor_text"])]...<BR>"
|
||||
dat += "<h2>Silicon Flavor Text</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=silicon_flavor_text;task=input'><b>Set Silicon Examine Text</b></a><br>"
|
||||
if(length(features["silicon_flavor_text"]) <= 40)
|
||||
if(length(features["silicon_flavor_text"]) <= MAX_FLAVOR_PREVIEW_LEN)
|
||||
if(!length(features["silicon_flavor_text"]))
|
||||
dat += "\[...\]"
|
||||
else
|
||||
@@ -420,7 +431,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<h2>OOC notes</h2>"
|
||||
dat += "<a href='?_src_=prefs;preference=ooc_notes;task=input'><b>Set OOC notes</b></a><br>"
|
||||
var/ooc_notes_len = length(features["ooc_notes"])
|
||||
if(ooc_notes_len <= 40)
|
||||
if(ooc_notes_len <= MAX_FLAVOR_PREVIEW_LEN)
|
||||
if(!ooc_notes_len)
|
||||
dat += "\[...\]"
|
||||
else
|
||||
@@ -792,11 +803,21 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h2>Speech preferences</h2>"
|
||||
dat += "<b>Custom Speech Verb:</b><BR>"
|
||||
dat += "</b><a style='display:block;width:100px' href='?_src_=prefs;preference=speech_verb;task=input'>[custom_speech_verb]</a><BR>"
|
||||
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=speech_verb;task=input'>[custom_speech_verb]</a><BR>"
|
||||
dat += "<b>Custom Tongue:</b><BR>"
|
||||
dat += "</b><a style='display:block;width:100px' href='?_src_=prefs;preference=tongue;task=input'>[custom_tongue]</a><BR>"
|
||||
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=tongue;task=input'>[custom_tongue]</a><BR>"
|
||||
dat += "<b>Additional Language</b><BR>"
|
||||
dat += "</b><a style='display:block;width:100px' href='?_src_=prefs;preference=language;task=input'>[additional_language]</a><BR>"
|
||||
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=language;task=input'>[additional_language]</a><BR>"
|
||||
dat += "</td>"
|
||||
dat += "<td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h2>Vocal Bark preferences</h2>"
|
||||
var/datum/bark/B = GLOB.bark_list[bark_id]
|
||||
dat += "<b>Vocal Bark Sound:</b><BR>"
|
||||
dat += "<a style='display:block;width:200px' href='?_src_=prefs;preference=barksound;task=input'>[B ? initial(B.name) : "INVALID"]</a><BR>"
|
||||
dat += "<b>Vocal Bark Speed:</b> <a href='?_src_=prefs;preference=barkspeed;task=input'>[bark_speed]</a><BR>"
|
||||
dat += "<b>Vocal Bark Pitch:</b> <a href='?_src_=prefs;preference=barkpitch;task=input'>[bark_pitch]</a><BR>"
|
||||
dat += "<b>Vocal Bark Variance:</b> <a href='?_src_=prefs;preference=barkvary;task=input'>[bark_variance]</a><BR>"
|
||||
dat += "<BR><a href='?_src_=prefs;preference=barkpreview'>Preview Bark</a><BR>"
|
||||
dat += "</td>"
|
||||
dat += "</tr></table>"
|
||||
|
||||
@@ -887,6 +908,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>Screen Shake:</b> <a href='?_src_=prefs;preference=screenshake'>[(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]</a><br>"
|
||||
if (user && user.client && !user.client.prefs.screenshake==0)
|
||||
dat += "<b>Damage Screen Shake:</b> <a href='?_src_=prefs;preference=damagescreenshake'>[(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]</a><br>"
|
||||
dat += "<b>Recoil Screen Push:</b> <a href='?_src_=prefs;preference=recoil_screenshake'>[(recoil_screenshake==100) ? "Full" : ((recoil_screenshake==0) ? "None" : "[screenshake]")]</a><br>"
|
||||
var/p_chaos
|
||||
if (!preferred_chaos)
|
||||
p_chaos = "No preference"
|
||||
@@ -1464,9 +1486,17 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<hr>"
|
||||
dat += "<center><b>Current quirks:</b> [all_quirks.len ? all_quirks.Join(", ") : "None"]</center>"
|
||||
dat += "<center>[GetPositiveQuirkCount()] / [MAX_QUIRKS] max positive quirks<br>\
|
||||
<b>Quirk balance remaining:</b> [GetQuirkBalance()]</center><br>"
|
||||
<b>Quirk balance remaining:</b> [GetQuirkBalance()]<br>"
|
||||
dat += " <a href='?_src_=prefs;quirk_category=[QUIRK_POSITIVE]' [quirk_category == QUIRK_POSITIVE ? "class='linkOn'" : ""]>[QUIRK_POSITIVE]</a> "
|
||||
dat += " <a href='?_src_=prefs;quirk_category=[QUIRK_NEUTRAL]' [quirk_category == QUIRK_NEUTRAL ? "class='linkOn'" : ""]>[QUIRK_NEUTRAL]</a> "
|
||||
dat += " <a href='?_src_=prefs;quirk_category=[QUIRK_NEGATIVE]' [quirk_category == QUIRK_NEGATIVE ? "class='linkOn'" : ""]>[QUIRK_NEGATIVE]</a> "
|
||||
dat += "</center><br>"
|
||||
for(var/V in SSquirks.quirks)
|
||||
var/datum/quirk/T = SSquirks.quirks[V]
|
||||
var/value = initial(T.value)
|
||||
if((value > 0 && quirk_category != QUIRK_POSITIVE) || (value < 0 && quirk_category != QUIRK_NEGATIVE) || (value == 0 && quirk_category != QUIRK_NEUTRAL))
|
||||
continue
|
||||
|
||||
var/quirk_name = initial(T.name)
|
||||
var/has_quirk
|
||||
var/quirk_cost = initial(T.value) * -1
|
||||
@@ -1488,7 +1518,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
quirk_cost = "+[quirk_cost]"
|
||||
var/font_color = "#AAAAFF"
|
||||
if(initial(T.value) != 0)
|
||||
font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA"
|
||||
font_color = value > 0 ? "#AAFFAA" : "#FFAAAA"
|
||||
if(quirk_conflict)
|
||||
dat += "<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)] \
|
||||
<font color='red'><b>LOCKED: [lock_reason]</b></font><br>"
|
||||
@@ -1618,6 +1648,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
SetQuirks(user)
|
||||
return TRUE
|
||||
|
||||
else if(href_list["quirk_category"])
|
||||
var/temp_quirk_category = href_list["quirk_category"]
|
||||
if(temp_quirk_category == QUIRK_POSITIVE || temp_quirk_category == QUIRK_NEUTRAL || temp_quirk_category == QUIRK_NEGATIVE)
|
||||
quirk_category = temp_quirk_category
|
||||
SetQuirks(user)
|
||||
|
||||
switch(href_list["task"])
|
||||
if("random")
|
||||
switch(href_list["preference"])
|
||||
@@ -1697,7 +1733,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("name")
|
||||
var/new_name = input(user, "Choose your character's name:", "Character Preference") as text|null
|
||||
if(new_name)
|
||||
new_name = reject_bad_name(new_name)
|
||||
new_name = reject_bad_name(new_name, allow_numbers = TRUE)
|
||||
if(new_name)
|
||||
real_name = new_name
|
||||
else
|
||||
@@ -2538,6 +2574,43 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(selected_language)
|
||||
additional_language = selected_language
|
||||
|
||||
if("barksound")
|
||||
var/list/woof_woof = list()
|
||||
for(var/path in GLOB.bark_list)
|
||||
var/datum/bark/B = GLOB.bark_list[path]
|
||||
if(initial(B.ignore))
|
||||
continue
|
||||
if(initial(B.ckeys_allowed))
|
||||
var/list/allowed = initial(B.ckeys_allowed)
|
||||
if(!allowed.Find(user.client.ckey))
|
||||
continue
|
||||
woof_woof[initial(B.name)] = initial(B.id)
|
||||
var/new_bork = input(user, "Choose your desired vocal bark", "Character Preference") as null|anything in woof_woof
|
||||
if(new_bork)
|
||||
bark_id = woof_woof[new_bork]
|
||||
var/datum/bark/B = GLOB.bark_list[bark_id] //Now we need sanitization to take into account bark-specific min/max values
|
||||
bark_speed = round(clamp(bark_speed, initial(B.minspeed), initial(B.maxspeed)), 1)
|
||||
bark_pitch = clamp(bark_pitch, initial(B.minpitch), initial(B.maxpitch))
|
||||
bark_variance = clamp(bark_variance, initial(B.minvariance), initial(B.maxvariance))
|
||||
|
||||
if("barkspeed")
|
||||
var/datum/bark/B = GLOB.bark_list[bark_id]
|
||||
var/borkset = input(user, "Choose your desired bark speed (Higher is slower, lower is faster). Min: [initial(B.minspeed)]. Max: [initial(B.maxspeed)]", "Character Preference") as null|num
|
||||
if(borkset)
|
||||
bark_speed = round(clamp(borkset, initial(B.minspeed), initial(B.maxspeed)), 1)
|
||||
|
||||
if("barkpitch")
|
||||
var/datum/bark/B = GLOB.bark_list[bark_id]
|
||||
var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minpitch)]. Max: [initial(B.maxpitch)]", "Character Preference") as null|num
|
||||
if(borkset)
|
||||
bark_pitch = clamp(borkset, initial(B.minpitch), initial(B.maxpitch))
|
||||
|
||||
if("barkvary")
|
||||
var/datum/bark/B = GLOB.bark_list[bark_id]
|
||||
var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minvariance)]. Max: [initial(B.maxvariance)]", "Character Preference") as null|num
|
||||
if(borkset)
|
||||
bark_variance = clamp(borkset, initial(B.minvariance), initial(B.maxvariance))
|
||||
|
||||
if("bodysprite")
|
||||
var/selected_body_sprite = input(user, "Choose your desired body sprite", "Character Preference") as null|anything in pref_species.allowed_limb_ids
|
||||
if(selected_body_sprite)
|
||||
@@ -2711,7 +2784,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("no_tetris_storage")
|
||||
no_tetris_storage = !no_tetris_storage
|
||||
if ("screenshake")
|
||||
var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, 200 = maximum.)", "Character Preference", screenshake) as null|num
|
||||
var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num
|
||||
if (!isnull(desiredshake))
|
||||
screenshake = desiredshake
|
||||
if("damagescreenshake")
|
||||
@@ -2724,6 +2797,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
damagescreenshake = 0
|
||||
else
|
||||
damagescreenshake = 1
|
||||
if ("recoil_screenshake")
|
||||
var/desiredshake = input(user, "Set the amount of recoil screenshake/push you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num
|
||||
if (!isnull(desiredshake))
|
||||
recoil_screenshake = desiredshake
|
||||
if("nameless")
|
||||
nameless = !nameless
|
||||
//END CITADEL EDIT
|
||||
@@ -2998,6 +3075,23 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("hud_toggle_flash")
|
||||
hud_toggle_flash = !hud_toggle_flash
|
||||
|
||||
if("barkpreview")
|
||||
if(SSticker.current_state == GAME_STATE_STARTUP) //Timers don't tick at all during game startup, so let's just give an error message
|
||||
to_chat(user, "<span class='warning'>Bark previews can't play during initialization!</span>")
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, bark_previewing))
|
||||
return
|
||||
if(!parent || !parent.mob)
|
||||
return
|
||||
COOLDOWN_START(src, bark_previewing, (5 SECONDS))
|
||||
var/atom/movable/barkbox = new(get_turf(parent.mob))
|
||||
barkbox.set_bark(bark_id)
|
||||
var/total_delay
|
||||
for(var/i in 1 to (round((32 / bark_speed)) + 1))
|
||||
addtimer(CALLBACK(barkbox, /atom/movable/proc/bark, list(parent.mob), 7, 70, BARK_DO_VARY(bark_pitch, bark_variance)), total_delay)
|
||||
total_delay += rand(DS2TICKS(bark_speed/4), DS2TICKS(bark_speed/4) + DS2TICKS(bark_speed/4)) TICKS
|
||||
QDEL_IN(barkbox, total_delay)
|
||||
|
||||
if("save")
|
||||
save_preferences()
|
||||
save_character()
|
||||
@@ -3219,6 +3313,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
character.additional_language = language_entry
|
||||
character.grant_language(language_entry, TRUE, TRUE)
|
||||
|
||||
character.set_bark(bark_id)
|
||||
character.vocal_speed = bark_speed
|
||||
character.vocal_pitch = bark_pitch
|
||||
character.vocal_pitch_range = bark_variance
|
||||
|
||||
//limb stuff, only done when initially spawning in
|
||||
if(initial_spawn)
|
||||
//delete any existing prosthetic limbs to make sure no remnant prosthetics are left over - But DO NOT delete those that are species-related
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// You do not need to raise this if you are adding new values that have sane defaults.
|
||||
// Only raise this value when changing the meaning/format/name/layout of an existing value
|
||||
// where you would want the updater procs below to run
|
||||
#define SAVEFILE_VERSION_MAX 53
|
||||
#define SAVEFILE_VERSION_MAX 55
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
@@ -42,6 +42,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
//if your savefile is 3 months out of date, then 'tough shit'.
|
||||
|
||||
/datum/preferences/proc/update_preferences(current_version, savefile/S)
|
||||
if(current_version < 55) //Bitflag toggles don't set their defaults when they're added, always defaulting to off instead.
|
||||
toggles |= SOUND_BARK
|
||||
if(current_version < 46) //If you remove this, remove force_reset_keybindings() too.
|
||||
force_reset_keybindings_direct(TRUE)
|
||||
addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice.
|
||||
@@ -72,15 +74,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
var/job_engsec_med = 0
|
||||
var/job_engsec_low = 0
|
||||
|
||||
S["job_civilian_high"] >> job_civilian_high
|
||||
S["job_civilian_med"] >> job_civilian_med
|
||||
S["job_civilian_low"] >> job_civilian_low
|
||||
S["job_medsci_high"] >> job_medsci_high
|
||||
S["job_medsci_med"] >> job_medsci_med
|
||||
S["job_medsci_low"] >> job_medsci_low
|
||||
S["job_engsec_high"] >> job_engsec_high
|
||||
S["job_engsec_med"] >> job_engsec_med
|
||||
S["job_engsec_low"] >> job_engsec_low
|
||||
S["job_civilian_high"] >> job_civilian_high
|
||||
S["job_civilian_med"] >> job_civilian_med
|
||||
S["job_civilian_low"] >> job_civilian_low
|
||||
S["job_medsci_high"] >> job_medsci_high
|
||||
S["job_medsci_med"] >> job_medsci_med
|
||||
S["job_medsci_low"] >> job_medsci_low
|
||||
S["job_engsec_high"] >> job_engsec_high
|
||||
S["job_engsec_med"] >> job_engsec_med
|
||||
S["job_engsec_low"] >> job_engsec_low
|
||||
|
||||
//Can't use SSjob here since this happens right away on login
|
||||
for(var/job in subtypesof(/datum/job))
|
||||
@@ -173,10 +175,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
var/devourable
|
||||
var/feeding
|
||||
var/lickable
|
||||
S["digestable"] >> digestable
|
||||
S["devourable"] >> devourable
|
||||
S["feeding"] >> feeding
|
||||
S["lickable"] >> lickable
|
||||
S["digestable"] >> digestable
|
||||
S["devourable"] >> devourable
|
||||
S["feeding"] >> feeding
|
||||
S["lickable"] >> lickable
|
||||
if(digestable)
|
||||
vore_flags |= DIGESTABLE
|
||||
if(devourable)
|
||||
@@ -196,8 +198,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
features["taur"] = "Cow (Spotted)"
|
||||
|
||||
if(current_version < 31)
|
||||
S["wing_color"] >> features["wings_color"]
|
||||
S["horn_color"] >> features["horns_color"]
|
||||
S["wing_color"] >> features["wings_color"]
|
||||
S["horn_color"] >> features["horns_color"]
|
||||
|
||||
if(current_version < 33)
|
||||
features["flavor_text"] = html_encode(features["flavor_text"])
|
||||
@@ -346,6 +348,16 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
if(current_version < 53)
|
||||
parallax = PARALLAX_INSANE
|
||||
|
||||
// Some genius decided to make features update on the loading part, go figure.
|
||||
if(current_version < 54)
|
||||
var/old_silicon_flavor = S["silicon_feature_flavor_text"]
|
||||
if(length(old_silicon_flavor))
|
||||
features["feature_silicon_flavor_text"] = old_silicon_flavor
|
||||
var/old_flavor_text = S["flavor_text"]
|
||||
// If they have the old flavor text but also have the new one, i suppose the new one is more important.
|
||||
if(length(old_flavor_text) && !length(features["feature_flavor_text"]))
|
||||
features["feature_flavor_text"] = old_flavor_text
|
||||
|
||||
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
|
||||
if(!ckey)
|
||||
return
|
||||
@@ -380,70 +392,70 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
. = TRUE
|
||||
|
||||
//general preferences
|
||||
S["ooccolor"] >> ooccolor
|
||||
S["lastchangelog"] >> lastchangelog
|
||||
S["UI_style"] >> UI_style
|
||||
S["outline_color"] >> outline_color
|
||||
S["outline_enabled"] >> outline_enabled
|
||||
S["screentip_pref"] >> screentip_pref
|
||||
S["screentip_color"] >> screentip_color
|
||||
S["hotkeys"] >> hotkeys
|
||||
S["chat_on_map"] >> chat_on_map
|
||||
S["max_chat_length"] >> max_chat_length
|
||||
S["ooccolor"] >> ooccolor
|
||||
S["lastchangelog"] >> lastchangelog
|
||||
S["UI_style"] >> UI_style
|
||||
S["outline_color"] >> outline_color
|
||||
S["outline_enabled"] >> outline_enabled
|
||||
S["screentip_pref"] >> screentip_pref
|
||||
S["screentip_color"] >> screentip_color
|
||||
S["hotkeys"] >> hotkeys
|
||||
S["chat_on_map"] >> chat_on_map
|
||||
S["max_chat_length"] >> max_chat_length
|
||||
S["see_chat_non_mob"] >> see_chat_non_mob
|
||||
S["tgui_fancy"] >> tgui_fancy
|
||||
S["tgui_lock"] >> tgui_lock
|
||||
S["buttons_locked"] >> buttons_locked
|
||||
S["windowflash"] >> windowflashing
|
||||
S["tgui_fancy"] >> tgui_fancy
|
||||
S["tgui_lock"] >> tgui_lock
|
||||
S["buttons_locked"] >> buttons_locked
|
||||
S["windowflash"] >> windowflashing
|
||||
S["be_special"] >> be_special
|
||||
|
||||
|
||||
S["default_slot"] >> default_slot
|
||||
S["chat_toggles"] >> chat_toggles
|
||||
S["toggles"] >> toggles
|
||||
S["deadmin"] >> deadmin
|
||||
S["ghost_form"] >> ghost_form
|
||||
S["ghost_orbit"] >> ghost_orbit
|
||||
S["ghost_accs"] >> ghost_accs
|
||||
S["ghost_others"] >> ghost_others
|
||||
S["preferred_map"] >> preferred_map
|
||||
S["ignoring"] >> ignoring
|
||||
S["ghost_hud"] >> ghost_hud
|
||||
S["inquisitive_ghost"] >> inquisitive_ghost
|
||||
S["default_slot"] >> default_slot
|
||||
S["chat_toggles"] >> chat_toggles
|
||||
S["toggles"] >> toggles
|
||||
S["deadmin"] >> deadmin
|
||||
S["ghost_form"] >> ghost_form
|
||||
S["ghost_orbit"] >> ghost_orbit
|
||||
S["ghost_accs"] >> ghost_accs
|
||||
S["ghost_others"] >> ghost_others
|
||||
S["preferred_map"] >> preferred_map
|
||||
S["ignoring"] >> ignoring
|
||||
S["ghost_hud"] >> ghost_hud
|
||||
S["inquisitive_ghost"] >> inquisitive_ghost
|
||||
S["uses_glasses_colour"]>> uses_glasses_colour
|
||||
S["clientfps"] >> clientfps
|
||||
S["parallax"] >> parallax
|
||||
S["ambientocclusion"] >> ambientocclusion
|
||||
S["auto_fit_viewport"] >> auto_fit_viewport
|
||||
S["widescreenpref"] >> widescreenpref
|
||||
S["long_strip_menu"] >> long_strip_menu
|
||||
S["clientfps"] >> clientfps
|
||||
S["parallax"] >> parallax
|
||||
S["ambientocclusion"] >> ambientocclusion
|
||||
S["auto_fit_viewport"] >> auto_fit_viewport
|
||||
S["widescreenpref"] >> widescreenpref
|
||||
S["long_strip_menu"] >> long_strip_menu
|
||||
S["pixel_size"] >> pixel_size
|
||||
S["scaling_method"] >> scaling_method
|
||||
S["hud_toggle_flash"] >> hud_toggle_flash
|
||||
S["hud_toggle_color"] >> hud_toggle_color
|
||||
S["menuoptions"] >> menuoptions
|
||||
S["enable_tips"] >> enable_tips
|
||||
S["tip_delay"] >> tip_delay
|
||||
S["pda_style"] >> pda_style
|
||||
S["pda_color"] >> pda_color
|
||||
S["pda_skin"] >> pda_skin
|
||||
S["hud_toggle_flash"] >> hud_toggle_flash
|
||||
S["hud_toggle_color"] >> hud_toggle_color
|
||||
S["menuoptions"] >> menuoptions
|
||||
S["enable_tips"] >> enable_tips
|
||||
S["tip_delay"] >> tip_delay
|
||||
S["pda_style"] >> pda_style
|
||||
S["pda_color"] >> pda_color
|
||||
S["pda_skin"] >> pda_skin
|
||||
|
||||
// Custom hotkeys
|
||||
S["key_bindings"] >> key_bindings
|
||||
S["modless_key_bindings"] >> modless_key_bindings
|
||||
S["key_bindings"] >> key_bindings
|
||||
S["modless_key_bindings"] >> modless_key_bindings
|
||||
|
||||
//citadel code
|
||||
S["arousable"] >> arousable
|
||||
S["screenshake"] >> screenshake
|
||||
S["damagescreenshake"] >> damagescreenshake
|
||||
S["autostand"] >> autostand
|
||||
S["cit_toggles"] >> cit_toggles
|
||||
S["preferred_chaos"] >> preferred_chaos
|
||||
S["auto_ooc"] >> auto_ooc
|
||||
S["no_tetris_storage"] >> no_tetris_storage
|
||||
S["arousable"] >> arousable
|
||||
S["screenshake"] >> screenshake
|
||||
S["damagescreenshake"] >> damagescreenshake
|
||||
S["autostand"] >> autostand
|
||||
S["cit_toggles"] >> cit_toggles
|
||||
S["preferred_chaos"] >> preferred_chaos
|
||||
S["auto_ooc"] >> auto_ooc
|
||||
S["no_tetris_storage"] >> no_tetris_storage
|
||||
|
||||
//favorite outfits
|
||||
S["favorite_outfits"] >> favorite_outfits
|
||||
S["favorite_outfits"] >> favorite_outfits
|
||||
|
||||
var/list/parsed_favs = list()
|
||||
for(var/typetext in favorite_outfits)
|
||||
@@ -461,47 +473,47 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer)
|
||||
|
||||
//Sanitize
|
||||
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
|
||||
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
|
||||
UI_style = sanitize_inlist(UI_style, GLOB.available_ui_styles, GLOB.available_ui_styles[1])
|
||||
hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys))
|
||||
chat_on_map = sanitize_integer(chat_on_map, 0, 1, initial(chat_on_map))
|
||||
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
|
||||
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
|
||||
UI_style = sanitize_inlist(UI_style, GLOB.available_ui_styles, GLOB.available_ui_styles[1])
|
||||
hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys))
|
||||
chat_on_map = sanitize_integer(chat_on_map, 0, 1, initial(chat_on_map))
|
||||
max_chat_length = sanitize_integer(max_chat_length, 1, CHAT_MESSAGE_MAX_LENGTH, initial(max_chat_length))
|
||||
see_chat_non_mob = sanitize_integer(see_chat_non_mob, 0, 1, initial(see_chat_non_mob))
|
||||
tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy))
|
||||
tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock))
|
||||
buttons_locked = sanitize_integer(buttons_locked, 0, 1, initial(buttons_locked))
|
||||
windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing))
|
||||
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
|
||||
toggles = sanitize_integer(toggles, 0, 16777215, initial(toggles))
|
||||
deadmin = sanitize_integer(deadmin, 0, 16777215, initial(deadmin))
|
||||
clientfps = sanitize_integer(clientfps, 0, 1000, 0)
|
||||
parallax = sanitize_integer(parallax, PARALLAX_DISABLE, PARALLAX_INSANE, null)
|
||||
ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion))
|
||||
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
|
||||
widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
|
||||
long_strip_menu = sanitize_integer(long_strip_menu, 0, 1, initial(long_strip_menu))
|
||||
pixel_size = sanitize_integer(pixel_size, PIXEL_SCALING_AUTO, PIXEL_SCALING_3X, initial(pixel_size))
|
||||
scaling_method = sanitize_text(scaling_method, initial(scaling_method))
|
||||
see_chat_non_mob = sanitize_integer(see_chat_non_mob, 0, 1, initial(see_chat_non_mob))
|
||||
tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy))
|
||||
tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock))
|
||||
buttons_locked = sanitize_integer(buttons_locked, 0, 1, initial(buttons_locked))
|
||||
windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing))
|
||||
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
|
||||
toggles = sanitize_integer(toggles, 0, 16777215, initial(toggles))
|
||||
deadmin = sanitize_integer(deadmin, 0, 16777215, initial(deadmin))
|
||||
clientfps = sanitize_integer(clientfps, 0, 1000, 0)
|
||||
parallax = sanitize_integer(parallax, PARALLAX_DISABLE, PARALLAX_INSANE, null)
|
||||
ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion))
|
||||
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
|
||||
widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
|
||||
long_strip_menu = sanitize_integer(long_strip_menu, 0, 1, initial(long_strip_menu))
|
||||
pixel_size = sanitize_integer(pixel_size, PIXEL_SCALING_AUTO, PIXEL_SCALING_3X, initial(pixel_size))
|
||||
scaling_method = sanitize_text(scaling_method, initial(scaling_method))
|
||||
hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash))
|
||||
hud_toggle_color = sanitize_hexcolor(hud_toggle_color, 6, 1, initial(hud_toggle_color))
|
||||
ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form))
|
||||
ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit))
|
||||
ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION)
|
||||
ghost_others = sanitize_inlist(ghost_others, GLOB.ghost_others_options, GHOST_OTHERS_DEFAULT_OPTION)
|
||||
menuoptions = SANITIZE_LIST(menuoptions)
|
||||
be_special = SANITIZE_LIST(be_special)
|
||||
pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style))
|
||||
pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color))
|
||||
pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT)
|
||||
screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake))
|
||||
damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake))
|
||||
autostand = sanitize_integer(autostand, 0, 1, initial(autostand))
|
||||
cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles))
|
||||
auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc))
|
||||
no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage))
|
||||
key_bindings = sanitize_islist(key_bindings, list())
|
||||
modless_key_bindings = sanitize_islist(modless_key_bindings, list())
|
||||
ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form))
|
||||
ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit))
|
||||
ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION)
|
||||
ghost_others = sanitize_inlist(ghost_others, GLOB.ghost_others_options, GHOST_OTHERS_DEFAULT_OPTION)
|
||||
menuoptions = SANITIZE_LIST(menuoptions)
|
||||
be_special = SANITIZE_LIST(be_special)
|
||||
pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style))
|
||||
pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color))
|
||||
pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT)
|
||||
screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake))
|
||||
damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake))
|
||||
autostand = sanitize_integer(autostand, 0, 1, initial(autostand))
|
||||
cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles))
|
||||
auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc))
|
||||
no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage))
|
||||
key_bindings = sanitize_islist(key_bindings, list())
|
||||
modless_key_bindings = sanitize_islist(modless_key_bindings, list())
|
||||
favorite_outfits = SANITIZE_LIST(favorite_outfits)
|
||||
|
||||
verify_keybindings_valid() // one of these days this will runtime and you'll be glad that i put it in a different proc so no one gets their saves wiped
|
||||
@@ -663,7 +675,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
//Species
|
||||
var/species_id
|
||||
S["species"] >> species_id
|
||||
S["species"] >> species_id
|
||||
if(species_id)
|
||||
if(species_id == "avian" || species_id == "aquatic")
|
||||
species_id = "mammal"
|
||||
@@ -678,63 +690,63 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
scars_index = rand(1,5) // WHY
|
||||
|
||||
//Character
|
||||
S["real_name"] >> real_name
|
||||
S["nameless"] >> nameless
|
||||
S["custom_species"] >> custom_species
|
||||
S["name_is_always_random"] >> be_random_name
|
||||
S["body_is_always_random"] >> be_random_body
|
||||
S["gender"] >> gender
|
||||
S["body_model"] >> features["body_model"]
|
||||
S["body_size"] >> features["body_size"]
|
||||
S["age"] >> age
|
||||
S["hair_color"] >> hair_color
|
||||
S["facial_hair_color"] >> facial_hair_color
|
||||
S["eye_type"] >> eye_type
|
||||
S["left_eye_color"] >> left_eye_color
|
||||
S["right_eye_color"] >> right_eye_color
|
||||
S["use_custom_skin_tone"] >> use_custom_skin_tone
|
||||
S["skin_tone"] >> skin_tone
|
||||
S["hair_style_name"] >> hair_style
|
||||
S["facial_style_name"] >> facial_hair_style
|
||||
S["grad_style"] >> grad_style
|
||||
S["grad_color"] >> grad_color
|
||||
S["underwear"] >> underwear
|
||||
S["undie_color"] >> undie_color
|
||||
S["undershirt"] >> undershirt
|
||||
S["shirt_color"] >> shirt_color
|
||||
S["socks"] >> socks
|
||||
S["socks_color"] >> socks_color
|
||||
S["backbag"] >> backbag
|
||||
S["jumpsuit_style"] >> jumpsuit_style
|
||||
S["uplink_loc"] >> uplink_spawn_loc
|
||||
S["custom_speech_verb"] >> custom_speech_verb
|
||||
S["custom_tongue"] >> custom_tongue
|
||||
S["additional_language"] >> additional_language
|
||||
S["feature_mcolor"] >> features["mcolor"]
|
||||
S["feature_lizard_tail"] >> features["tail_lizard"]
|
||||
S["feature_lizard_snout"] >> features["snout"]
|
||||
S["feature_lizard_horns"] >> features["horns"]
|
||||
S["feature_lizard_frills"] >> features["frills"]
|
||||
S["feature_lizard_spines"] >> features["spines"]
|
||||
S["feature_lizard_legs"] >> features["legs"]
|
||||
S["feature_human_tail"] >> features["tail_human"]
|
||||
S["feature_human_ears"] >> features["ears"]
|
||||
S["feature_deco_wings"] >> features["deco_wings"]
|
||||
S["feature_insect_wings"] >> features["insect_wings"]
|
||||
S["feature_insect_fluff"] >> features["insect_fluff"]
|
||||
S["feature_insect_markings"] >> features["insect_markings"]
|
||||
S["feature_arachnid_legs"] >> features["arachnid_legs"]
|
||||
S["feature_arachnid_spinneret"] >> features["arachnid_spinneret"]
|
||||
S["feature_arachnid_mandibles"] >> features["arachnid_mandibles"]
|
||||
S["feature_horns_color"] >> features["horns_color"]
|
||||
S["feature_wings_color"] >> features["wings_color"]
|
||||
S["feature_color_scheme"] >> features["color_scheme"]
|
||||
S["real_name"] >> real_name
|
||||
S["nameless"] >> nameless
|
||||
S["custom_species"] >> custom_species
|
||||
S["name_is_always_random"] >> be_random_name
|
||||
S["body_is_always_random"] >> be_random_body
|
||||
S["gender"] >> gender
|
||||
S["body_model"] >> features["body_model"]
|
||||
S["body_size"] >> features["body_size"]
|
||||
S["age"] >> age
|
||||
S["hair_color"] >> hair_color
|
||||
S["facial_hair_color"] >> facial_hair_color
|
||||
S["eye_type"] >> eye_type
|
||||
S["left_eye_color"] >> left_eye_color
|
||||
S["right_eye_color"] >> right_eye_color
|
||||
S["use_custom_skin_tone"] >> use_custom_skin_tone
|
||||
S["skin_tone"] >> skin_tone
|
||||
S["hair_style_name"] >> hair_style
|
||||
S["facial_style_name"] >> facial_hair_style
|
||||
S["grad_style"] >> grad_style
|
||||
S["grad_color"] >> grad_color
|
||||
S["underwear"] >> underwear
|
||||
S["undie_color"] >> undie_color
|
||||
S["undershirt"] >> undershirt
|
||||
S["shirt_color"] >> shirt_color
|
||||
S["socks"] >> socks
|
||||
S["socks_color"] >> socks_color
|
||||
S["backbag"] >> backbag
|
||||
S["jumpsuit_style"] >> jumpsuit_style
|
||||
S["uplink_loc"] >> uplink_spawn_loc
|
||||
S["custom_speech_verb"] >> custom_speech_verb
|
||||
S["custom_tongue"] >> custom_tongue
|
||||
S["additional_language"] >> additional_language
|
||||
S["feature_mcolor"] >> features["mcolor"]
|
||||
S["feature_lizard_tail"] >> features["tail_lizard"]
|
||||
S["feature_lizard_snout"] >> features["snout"]
|
||||
S["feature_lizard_horns"] >> features["horns"]
|
||||
S["feature_lizard_frills"] >> features["frills"]
|
||||
S["feature_lizard_spines"] >> features["spines"]
|
||||
S["feature_lizard_legs"] >> features["legs"]
|
||||
S["feature_human_tail"] >> features["tail_human"]
|
||||
S["feature_human_ears"] >> features["ears"]
|
||||
S["feature_deco_wings"] >> features["deco_wings"]
|
||||
S["feature_insect_wings"] >> features["insect_wings"]
|
||||
S["feature_insect_fluff"] >> features["insect_fluff"]
|
||||
S["feature_insect_markings"] >> features["insect_markings"]
|
||||
S["feature_arachnid_legs"] >> features["arachnid_legs"]
|
||||
S["feature_arachnid_spinneret"] >> features["arachnid_spinneret"]
|
||||
S["feature_arachnid_mandibles"] >> features["arachnid_mandibles"]
|
||||
S["feature_horns_color"] >> features["horns_color"]
|
||||
S["feature_wings_color"] >> features["wings_color"]
|
||||
S["feature_color_scheme"] >> features["color_scheme"]
|
||||
S["persistent_scars"] >> persistent_scars
|
||||
S["scars1"] >> scars_list["1"]
|
||||
S["scars2"] >> scars_list["2"]
|
||||
S["scars3"] >> scars_list["3"]
|
||||
S["scars4"] >> scars_list["4"]
|
||||
S["scars5"] >> scars_list["5"]
|
||||
S["scars1"] >> scars_list["1"]
|
||||
S["scars2"] >> scars_list["2"]
|
||||
S["scars3"] >> scars_list["3"]
|
||||
S["scars4"] >> scars_list["4"]
|
||||
S["scars5"] >> scars_list["5"]
|
||||
var/limbmodstr
|
||||
S["modified_limbs"] >> limbmodstr
|
||||
if(length(limbmodstr))
|
||||
@@ -756,100 +768,94 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
else
|
||||
tcg_decks = list()
|
||||
|
||||
S["chosen_limb_id"] >> chosen_limb_id
|
||||
S["hide_ckey"] >> hide_ckey //saved per-character
|
||||
S["chosen_limb_id"] >> chosen_limb_id
|
||||
S["hide_ckey"] >> hide_ckey //saved per-character
|
||||
|
||||
//Custom names
|
||||
for(var/custom_name_id in GLOB.preferences_custom_names)
|
||||
var/savefile_slot_name = custom_name_id + "_name" //TODO remove this
|
||||
S[savefile_slot_name] >> custom_names[custom_name_id]
|
||||
|
||||
S["preferred_ai_core_display"] >> preferred_ai_core_display
|
||||
S["prefered_security_department"] >> prefered_security_department
|
||||
S["preferred_ai_core_display"] >> preferred_ai_core_display
|
||||
S["prefered_security_department"] >> prefered_security_department
|
||||
|
||||
//Jobs
|
||||
S["joblessrole"] >> joblessrole
|
||||
S["joblessrole"] >> joblessrole
|
||||
|
||||
//Load prefs
|
||||
S["job_preferences"] >> job_preferences
|
||||
S["job_preferences"] >> job_preferences
|
||||
|
||||
//Quirks
|
||||
S["all_quirks"] >> all_quirks
|
||||
S["all_quirks"] >> all_quirks
|
||||
|
||||
//Records
|
||||
S["security_records"] >> security_records
|
||||
S["medical_records"] >> medical_records
|
||||
S["security_records"] >> security_records
|
||||
S["medical_records"] >> medical_records
|
||||
|
||||
//Citadel code
|
||||
S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"]
|
||||
S["feature_mcolor2"] >> features["mcolor2"]
|
||||
S["feature_mcolor3"] >> features["mcolor3"]
|
||||
S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"]
|
||||
S["feature_mcolor2"] >> features["mcolor2"]
|
||||
S["feature_mcolor3"] >> features["mcolor3"]
|
||||
// note safe json decode will runtime the first time it migrates but this is fine and it solves itself don't worry about it if you see it error
|
||||
features["mam_body_markings"] = safe_json_decode(S["feature_mam_body_markings"])
|
||||
S["feature_mam_tail"] >> features["mam_tail"]
|
||||
S["feature_mam_ears"] >> features["mam_ears"]
|
||||
S["feature_mam_tail_animated"] >> features["mam_tail_animated"]
|
||||
S["feature_taur"] >> features["taur"]
|
||||
S["feature_mam_snouts"] >> features["mam_snouts"]
|
||||
S["feature_meat"] >> features["meat_type"]
|
||||
S["feature_mam_tail"] >> features["mam_tail"]
|
||||
S["feature_mam_ears"] >> features["mam_ears"]
|
||||
S["feature_mam_tail_animated"] >> features["mam_tail_animated"]
|
||||
S["feature_taur"] >> features["taur"]
|
||||
S["feature_mam_snouts"] >> features["mam_snouts"]
|
||||
S["feature_meat"] >> features["meat_type"]
|
||||
//Xeno features
|
||||
S["feature_xeno_tail"] >> features["xenotail"]
|
||||
S["feature_xeno_dors"] >> features["xenodorsal"]
|
||||
S["feature_xeno_head"] >> features["xenohead"]
|
||||
S["feature_xeno_tail"] >> features["xenotail"]
|
||||
S["feature_xeno_dors"] >> features["xenodorsal"]
|
||||
S["feature_xeno_head"] >> features["xenohead"]
|
||||
//cock features
|
||||
S["feature_has_cock"] >> features["has_cock"]
|
||||
S["feature_cock_shape"] >> features["cock_shape"]
|
||||
S["feature_cock_color"] >> features["cock_color"]
|
||||
S["feature_cock_length"] >> features["cock_length"]
|
||||
S["feature_cock_diameter"] >> features["cock_diameter"]
|
||||
S["feature_cock_taur"] >> features["cock_taur"]
|
||||
S["feature_cock_visibility"] >> features["cock_visibility"]
|
||||
S["feature_has_cock"] >> features["has_cock"]
|
||||
S["feature_cock_shape"] >> features["cock_shape"]
|
||||
S["feature_cock_color"] >> features["cock_color"]
|
||||
S["feature_cock_length"] >> features["cock_length"]
|
||||
S["feature_cock_diameter"] >> features["cock_diameter"]
|
||||
S["feature_cock_taur"] >> features["cock_taur"]
|
||||
S["feature_cock_visibility"] >> features["cock_visibility"]
|
||||
//balls features
|
||||
S["feature_has_balls"] >> features["has_balls"]
|
||||
S["feature_balls_color"] >> features["balls_color"]
|
||||
S["feature_balls_shape"] >> features["balls_shape"]
|
||||
S["feature_balls_size"] >> features["balls_size"]
|
||||
S["feature_balls_visibility"] >> features["balls_visibility"]
|
||||
S["feature_has_balls"] >> features["has_balls"]
|
||||
S["feature_balls_color"] >> features["balls_color"]
|
||||
S["feature_balls_shape"] >> features["balls_shape"]
|
||||
S["feature_balls_size"] >> features["balls_size"]
|
||||
S["feature_balls_visibility"] >> features["balls_visibility"]
|
||||
//breasts features
|
||||
S["feature_has_breasts"] >> features["has_breasts"]
|
||||
S["feature_breasts_size"] >> features["breasts_size"]
|
||||
S["feature_breasts_shape"] >> features["breasts_shape"]
|
||||
S["feature_breasts_color"] >> features["breasts_color"]
|
||||
S["feature_breasts_producing"] >> features["breasts_producing"]
|
||||
S["feature_breasts_visibility"] >> features["breasts_visibility"]
|
||||
S["feature_has_breasts"] >> features["has_breasts"]
|
||||
S["feature_breasts_size"] >> features["breasts_size"]
|
||||
S["feature_breasts_shape"] >> features["breasts_shape"]
|
||||
S["feature_breasts_color"] >> features["breasts_color"]
|
||||
S["feature_breasts_producing"] >> features["breasts_producing"]
|
||||
S["feature_breasts_visibility"] >> features["breasts_visibility"]
|
||||
//vagina features
|
||||
S["feature_has_vag"] >> features["has_vag"]
|
||||
S["feature_vag_shape"] >> features["vag_shape"]
|
||||
S["feature_vag_color"] >> features["vag_color"]
|
||||
S["feature_vag_visibility"] >> features["vag_visibility"]
|
||||
S["feature_has_vag"] >> features["has_vag"]
|
||||
S["feature_vag_shape"] >> features["vag_shape"]
|
||||
S["feature_vag_color"] >> features["vag_color"]
|
||||
S["feature_vag_visibility"] >> features["vag_visibility"]
|
||||
//womb features
|
||||
S["feature_has_womb"] >> features["has_womb"]
|
||||
S["feature_has_womb"] >> features["has_womb"]
|
||||
//butt features
|
||||
S["feature_has_butt"] >> features["has_butt"]
|
||||
S["feature_butt_color"] >> features["butt_color"]
|
||||
S["feature_butt_size"] >> features["butt_size"]
|
||||
S["feature_butt_visibility"] >> features["butt_visibility"]
|
||||
S["feature_has_butt"] >> features["has_butt"]
|
||||
S["feature_butt_color"] >> features["butt_color"]
|
||||
S["feature_butt_size"] >> features["butt_size"]
|
||||
S["feature_butt_visibility"] >> features["butt_visibility"]
|
||||
|
||||
//flavor text
|
||||
//Let's make our players NOT cry desperately as we wipe their savefiles of their special snowflake texts:
|
||||
if((S["flavor_text"] != "") && (S["flavor_text"] != null) && S["flavor_text"]) //If old text isn't null and isn't "" but still exists.
|
||||
S["flavor_text"] >> features["flavor_text"] //Load old flavortext as current dna-based flavortext
|
||||
// Flavor texts, Made into a standard.
|
||||
S["feature_flavor_text"] >> features["flavor_text"]
|
||||
S["feature_silicon_flavor_text"] >> features["silicon_flavor_text"]
|
||||
S["feature_ooc_notes"] >> features["ooc_notes"]
|
||||
|
||||
WRITE_FILE(S["feature_flavor_text"], features["flavor_text"]) //Save it in our new type of flavor-text
|
||||
WRITE_FILE(S["flavor_text"] , "") //Remove old flavortext, completing the cut-and-paste into the new format.
|
||||
// Barks
|
||||
S["bark_id"] >> bark_id
|
||||
S["bark_speed"] >> bark_speed
|
||||
S["bark_pitch"] >> bark_pitch
|
||||
S["bark_variance"] >> bark_variance
|
||||
|
||||
else //We have no old flavortext, default to new
|
||||
S["feature_flavor_text"] >> features["flavor_text"]
|
||||
|
||||
|
||||
S["silicon_feature_flavor_text"] >> features["silicon_flavor_text"]
|
||||
|
||||
S["feature_ooc_notes"] >> features["ooc_notes"]
|
||||
S["silicon_flavor_text"] >> features["silicon_flavor_text"]
|
||||
|
||||
S["vore_flags"] >> vore_flags
|
||||
S["vore_taste"] >> vore_taste
|
||||
S["vore_smell"] >> vore_smell
|
||||
S["vore_flags"] >> vore_flags
|
||||
S["vore_taste"] >> vore_taste
|
||||
S["vore_smell"] >> vore_smell
|
||||
var/char_vr_path = "[vr_path]/character_[default_slot]_v2.json"
|
||||
if(fexists(char_vr_path))
|
||||
var/list/json_from_file = json_decode(file2text(char_vr_path))
|
||||
@@ -869,69 +875,69 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
//Sanitize
|
||||
|
||||
real_name = reject_bad_name(real_name)
|
||||
gender = sanitize_gender(gender, TRUE, TRUE)
|
||||
real_name = reject_bad_name(real_name)
|
||||
gender = sanitize_gender(gender, TRUE, TRUE)
|
||||
features["body_model"] = sanitize_gender(features["body_model"], FALSE, FALSE, gender == FEMALE ? FEMALE : MALE)
|
||||
if(!real_name)
|
||||
real_name = random_unique_name(gender)
|
||||
custom_species = reject_bad_name(custom_species)
|
||||
real_name = random_unique_name(gender)
|
||||
custom_species = reject_bad_name(custom_species)
|
||||
for(var/custom_name_id in GLOB.preferences_custom_names)
|
||||
var/namedata = GLOB.preferences_custom_names[custom_name_id]
|
||||
custom_names[custom_name_id] = reject_bad_name(custom_names[custom_name_id],namedata["allow_numbers"])
|
||||
if(!custom_names[custom_name_id])
|
||||
custom_names[custom_name_id] = get_default_name(custom_name_id)
|
||||
|
||||
nameless = sanitize_integer(nameless, 0, 1, initial(nameless))
|
||||
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
|
||||
be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body))
|
||||
nameless = sanitize_integer(nameless, 0, 1, initial(nameless))
|
||||
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
|
||||
be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body))
|
||||
|
||||
hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_list)
|
||||
facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_list)
|
||||
underwear = sanitize_inlist(underwear, GLOB.underwear_list)
|
||||
undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list)
|
||||
undie_color = sanitize_hexcolor(undie_color, 6, FALSE, initial(undie_color))
|
||||
shirt_color = sanitize_hexcolor(shirt_color, 6, FALSE, initial(shirt_color))
|
||||
socks = sanitize_inlist(socks, GLOB.socks_list)
|
||||
socks_color = sanitize_hexcolor(socks_color, 6, FALSE, initial(socks_color))
|
||||
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
|
||||
hair_color = sanitize_hexcolor(hair_color, 6, FALSE)
|
||||
facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE)
|
||||
grad_style = sanitize_inlist(grad_style, GLOB.hair_gradients_list, "None")
|
||||
grad_color = sanitize_hexcolor(grad_color, 6, FALSE)
|
||||
eye_type = sanitize_inlist(eye_type, GLOB.eye_types, DEFAULT_EYES_TYPE)
|
||||
left_eye_color = sanitize_hexcolor(left_eye_color, 6, FALSE)
|
||||
right_eye_color = sanitize_hexcolor(right_eye_color, 6, FALSE)
|
||||
hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_list)
|
||||
facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_list)
|
||||
underwear = sanitize_inlist(underwear, GLOB.underwear_list)
|
||||
undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list)
|
||||
undie_color = sanitize_hexcolor(undie_color, 6, FALSE, initial(undie_color))
|
||||
shirt_color = sanitize_hexcolor(shirt_color, 6, FALSE, initial(shirt_color))
|
||||
socks = sanitize_inlist(socks, GLOB.socks_list)
|
||||
socks_color = sanitize_hexcolor(socks_color, 6, FALSE, initial(socks_color))
|
||||
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
|
||||
hair_color = sanitize_hexcolor(hair_color, 6, FALSE)
|
||||
facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE)
|
||||
grad_style = sanitize_inlist(grad_style, GLOB.hair_gradients_list, "None")
|
||||
grad_color = sanitize_hexcolor(grad_color, 6, FALSE)
|
||||
eye_type = sanitize_inlist(eye_type, GLOB.eye_types, DEFAULT_EYES_TYPE)
|
||||
left_eye_color = sanitize_hexcolor(left_eye_color, 6, FALSE)
|
||||
right_eye_color = sanitize_hexcolor(right_eye_color, 6, FALSE)
|
||||
|
||||
var/static/allow_custom_skintones
|
||||
if(isnull(allow_custom_skintones))
|
||||
allow_custom_skintones = CONFIG_GET(flag/allow_custom_skintones)
|
||||
use_custom_skin_tone = allow_custom_skintones ? sanitize_integer(use_custom_skin_tone, FALSE, TRUE, initial(use_custom_skin_tone)) : FALSE
|
||||
use_custom_skin_tone = allow_custom_skintones ? sanitize_integer(use_custom_skin_tone, FALSE, TRUE, initial(use_custom_skin_tone)) : FALSE
|
||||
if(use_custom_skin_tone)
|
||||
skin_tone = sanitize_hexcolor(skin_tone, 6, TRUE, "#FFFFFF")
|
||||
skin_tone = sanitize_hexcolor(skin_tone, 6, TRUE, "#FFFFFF")
|
||||
else
|
||||
skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones - GLOB.nonstandard_skin_tones, initial(skin_tone))
|
||||
skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones - GLOB.nonstandard_skin_tones, initial(skin_tone))
|
||||
|
||||
features["horns_color"] = sanitize_hexcolor(features["horns_color"], 6, FALSE, "85615a")
|
||||
features["wings_color"] = sanitize_hexcolor(features["wings_color"], 6, FALSE, "FFFFFF")
|
||||
backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag))
|
||||
jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style))
|
||||
uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc))
|
||||
features["mcolor"] = sanitize_hexcolor(features["mcolor"], 6, FALSE)
|
||||
features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard)
|
||||
features["tail_human"] = sanitize_inlist(features["tail_human"], GLOB.tails_list_human)
|
||||
features["snout"] = sanitize_inlist(features["snout"], GLOB.snouts_list)
|
||||
features["horns"] = sanitize_inlist(features["horns"], GLOB.horns_list)
|
||||
features["ears"] = sanitize_inlist(features["ears"], GLOB.ears_list)
|
||||
features["frills"] = sanitize_inlist(features["frills"], GLOB.frills_list)
|
||||
features["spines"] = sanitize_inlist(features["spines"], GLOB.spines_list)
|
||||
features["legs"] = sanitize_inlist(features["legs"], GLOB.legs_list, "Plantigrade")
|
||||
features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None")
|
||||
features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list)
|
||||
features["insect_markings"] = sanitize_inlist(features["insect_markings"], GLOB.insect_markings_list, "None")
|
||||
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
|
||||
features["arachnid_legs"] = sanitize_inlist(features["arachnid_legs"], GLOB.arachnid_legs_list, "Plain")
|
||||
features["arachnid_spinneret"] = sanitize_inlist(features["arachnid_spinneret"], GLOB.arachnid_spinneret_list, "Plain")
|
||||
features["arachnid_mandibles"] = sanitize_inlist(features["arachnid_mandibles"], GLOB.arachnid_mandibles_list, "Plain")
|
||||
features["horns_color"] = sanitize_hexcolor(features["horns_color"], 6, FALSE, "85615a")
|
||||
features["wings_color"] = sanitize_hexcolor(features["wings_color"], 6, FALSE, "FFFFFF")
|
||||
backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag))
|
||||
jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style))
|
||||
uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc))
|
||||
features["mcolor"] = sanitize_hexcolor(features["mcolor"], 6, FALSE)
|
||||
features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard)
|
||||
features["tail_human"] = sanitize_inlist(features["tail_human"], GLOB.tails_list_human)
|
||||
features["snout"] = sanitize_inlist(features["snout"], GLOB.snouts_list)
|
||||
features["horns"] = sanitize_inlist(features["horns"], GLOB.horns_list)
|
||||
features["ears"] = sanitize_inlist(features["ears"], GLOB.ears_list)
|
||||
features["frills"] = sanitize_inlist(features["frills"], GLOB.frills_list)
|
||||
features["spines"] = sanitize_inlist(features["spines"], GLOB.spines_list)
|
||||
features["legs"] = sanitize_inlist(features["legs"], GLOB.legs_list, "Plantigrade")
|
||||
features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None")
|
||||
features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list)
|
||||
features["insect_markings"] = sanitize_inlist(features["insect_markings"], GLOB.insect_markings_list, "None")
|
||||
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
|
||||
features["arachnid_legs"] = sanitize_inlist(features["arachnid_legs"], GLOB.arachnid_legs_list, "Plain")
|
||||
features["arachnid_spinneret"] = sanitize_inlist(features["arachnid_spinneret"], GLOB.arachnid_spinneret_list, "Plain")
|
||||
features["arachnid_mandibles"] = sanitize_inlist(features["arachnid_mandibles"], GLOB.arachnid_mandibles_list, "Plain")
|
||||
|
||||
var/static/size_min
|
||||
if(!size_min)
|
||||
@@ -939,7 +945,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
var/static/size_max
|
||||
if(!size_max)
|
||||
size_max = CONFIG_GET(number/body_size_max)
|
||||
features["body_size"] = sanitize_num_clamp(features["body_size"], size_min, size_max, RESIZE_DEFAULT_SIZE, 0.01)
|
||||
features["body_size"] = sanitize_num_clamp(features["body_size"], size_min, size_max, RESIZE_DEFAULT_SIZE, 0.01)
|
||||
|
||||
var/static/list/B_sizes
|
||||
if(!B_sizes)
|
||||
@@ -963,33 +969,33 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
var/list/L = CONFIG_GET(keyed_list/safe_visibility_toggles)
|
||||
safe_visibilities = L.Copy()
|
||||
|
||||
features["breasts_size"] = sanitize_inlist(features["breasts_size"], B_sizes, BREASTS_SIZE_DEF)
|
||||
features["cock_length"] = sanitize_integer(features["cock_length"], min_D, max_D, COCK_SIZE_DEF)
|
||||
features["butt_size"] = sanitize_integer(features["butt_size"], min_B, max_B, BUTT_SIZE_DEF)
|
||||
features["breasts_shape"] = sanitize_inlist(features["breasts_shape"], GLOB.breasts_shapes_list, DEF_BREASTS_SHAPE)
|
||||
features["cock_shape"] = sanitize_inlist(features["cock_shape"], GLOB.cock_shapes_list, DEF_COCK_SHAPE)
|
||||
features["balls_shape"] = sanitize_inlist(features["balls_shape"], GLOB.balls_shapes_list, DEF_BALLS_SHAPE)
|
||||
features["vag_shape"] = sanitize_inlist(features["vag_shape"], GLOB.vagina_shapes_list, DEF_VAGINA_SHAPE)
|
||||
features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 6, FALSE, "FFFFFF")
|
||||
features["cock_color"] = sanitize_hexcolor(features["cock_color"], 6, FALSE, "FFFFFF")
|
||||
features["balls_color"] = sanitize_hexcolor(features["balls_color"], 6, FALSE, "FFFFFF")
|
||||
features["vag_color"] = sanitize_hexcolor(features["vag_color"], 6, FALSE, "FFFFFF")
|
||||
features["breasts_visibility"] = sanitize_inlist(features["breasts_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
features["cock_visibility"] = sanitize_inlist(features["cock_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
features["balls_visibility"] = sanitize_inlist(features["balls_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
features["vag_visibility"] = sanitize_inlist(features["vag_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
features["butt_visibility"] = sanitize_inlist(features["butt_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
features["breasts_size"] = sanitize_inlist(features["breasts_size"], B_sizes, BREASTS_SIZE_DEF)
|
||||
features["cock_length"] = sanitize_integer(features["cock_length"], min_D, max_D, COCK_SIZE_DEF)
|
||||
features["butt_size"] = sanitize_integer(features["butt_size"], min_B, max_B, BUTT_SIZE_DEF)
|
||||
features["breasts_shape"] = sanitize_inlist(features["breasts_shape"], GLOB.breasts_shapes_list, DEF_BREASTS_SHAPE)
|
||||
features["cock_shape"] = sanitize_inlist(features["cock_shape"], GLOB.cock_shapes_list, DEF_COCK_SHAPE)
|
||||
features["balls_shape"] = sanitize_inlist(features["balls_shape"], GLOB.balls_shapes_list, DEF_BALLS_SHAPE)
|
||||
features["vag_shape"] = sanitize_inlist(features["vag_shape"], GLOB.vagina_shapes_list, DEF_VAGINA_SHAPE)
|
||||
features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 6, FALSE, "FFFFFF")
|
||||
features["cock_color"] = sanitize_hexcolor(features["cock_color"], 6, FALSE, "FFFFFF")
|
||||
features["balls_color"] = sanitize_hexcolor(features["balls_color"], 6, FALSE, "FFFFFF")
|
||||
features["vag_color"] = sanitize_hexcolor(features["vag_color"], 6, FALSE, "FFFFFF")
|
||||
features["breasts_visibility"] = sanitize_inlist(features["breasts_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
features["cock_visibility"] = sanitize_inlist(features["cock_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
features["balls_visibility"] = sanitize_inlist(features["balls_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
features["vag_visibility"] = sanitize_inlist(features["vag_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
features["butt_visibility"] = sanitize_inlist(features["butt_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
|
||||
|
||||
custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default")
|
||||
custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default")
|
||||
additional_language = sanitize_inlist(additional_language, GLOB.roundstart_languages, "None")
|
||||
custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default")
|
||||
custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default")
|
||||
additional_language = sanitize_inlist(additional_language, GLOB.roundstart_languages, "None")
|
||||
|
||||
security_records = copytext(security_records, 1, MAX_FLAVOR_LEN)
|
||||
medical_records = copytext(medical_records, 1, MAX_FLAVOR_LEN)
|
||||
security_records = copytext(security_records, 1, MAX_FLAVOR_LEN)
|
||||
medical_records = copytext(medical_records, 1, MAX_FLAVOR_LEN)
|
||||
|
||||
features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN)
|
||||
features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN)
|
||||
features["ooc_notes"] = copytext(features["ooc_notes"], 1, MAX_FLAVOR_LEN)
|
||||
features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN)
|
||||
features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN)
|
||||
features["ooc_notes"] = copytext(features["ooc_notes"], 1, MAX_FLAVOR_LEN)
|
||||
|
||||
//load every advanced coloring mode thing in one go
|
||||
//THIS MUST BE DONE AFTER ALL FEATURE SAVES OR IT WILL NOT WORK
|
||||
@@ -1011,11 +1017,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
message_admins("Sprite Accessory Failure (loading data): Accessory [accessory.type] is a matrixed item without any matrixed sections set!")
|
||||
continue
|
||||
if(S["feature_[primary_string]"])
|
||||
S["feature_[primary_string]"] >> features[primary_string]
|
||||
S["feature_[primary_string]"] >> features[primary_string]
|
||||
if(S["feature_[secondary_string]"])
|
||||
S["feature_[secondary_string]"] >> features[secondary_string]
|
||||
S["feature_[secondary_string]"] >> features[secondary_string]
|
||||
if(S["feature_[tertiary_string]"])
|
||||
S["feature_[tertiary_string]"] >> features[tertiary_string]
|
||||
S["feature_[tertiary_string]"] >> features[tertiary_string]
|
||||
|
||||
persistent_scars = sanitize_integer(persistent_scars)
|
||||
scars_list["1"] = sanitize_text(scars_list["1"])
|
||||
@@ -1024,7 +1030,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
scars_list["4"] = sanitize_text(scars_list["4"])
|
||||
scars_list["5"] = sanitize_text(scars_list["5"])
|
||||
|
||||
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
|
||||
bark_id = sanitize_inlist(bark_id, GLOB.bark_list, pick(GLOB.bark_random_list))
|
||||
var/datum/bark/bark_path = GLOB.bark_list[bark_id]
|
||||
bark_speed = sanitize_num_clamp(bark_speed, initial(bark_path.minspeed), initial(bark_path.maxspeed), initial(bark_speed))
|
||||
bark_pitch = sanitize_num_clamp(bark_pitch, initial(bark_path.minpitch), initial(bark_path.maxpitch), BARK_PITCH_RAND(gender))
|
||||
bark_variance = sanitize_num_clamp(bark_variance, initial(bark_path.minvariance), initial(bark_path.maxvariance), BARK_VARIANCE_RAND)
|
||||
|
||||
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
|
||||
//Validate job prefs
|
||||
for(var/j in job_preferences)
|
||||
if(job_preferences["[j]"] != JP_LOW && job_preferences["[j]"] != JP_MEDIUM && job_preferences["[j]"] != JP_HIGH)
|
||||
@@ -1032,10 +1044,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
all_quirks = SANITIZE_LIST(all_quirks)
|
||||
|
||||
vore_flags = sanitize_integer(vore_flags, 0, MAX_VORE_FLAG, 0)
|
||||
vore_taste = copytext(vore_taste, 1, MAX_TASTE_LEN)
|
||||
vore_smell = copytext(vore_smell, 1, MAX_TASTE_LEN)
|
||||
belly_prefs = SANITIZE_LIST(belly_prefs)
|
||||
vore_flags = sanitize_integer(vore_flags, 0, MAX_VORE_FLAG, 0)
|
||||
vore_taste = copytext(vore_taste, 1, MAX_TASTE_LEN)
|
||||
vore_smell = copytext(vore_smell, 1, MAX_TASTE_LEN)
|
||||
belly_prefs = SANITIZE_LIST(belly_prefs)
|
||||
|
||||
cit_character_pref_load(S)
|
||||
|
||||
@@ -1091,6 +1103,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["custom_speech_verb"] , custom_speech_verb)
|
||||
WRITE_FILE(S["custom_tongue"] , custom_tongue)
|
||||
WRITE_FILE(S["additional_language"] , additional_language)
|
||||
WRITE_FILE(S["bark_id"] , bark_id)
|
||||
WRITE_FILE(S["bark_speed"] , bark_speed)
|
||||
WRITE_FILE(S["bark_pitch"] , bark_pitch)
|
||||
WRITE_FILE(S["bark_variance"] , bark_variance)
|
||||
|
||||
// records
|
||||
WRITE_FILE(S["security_records"] , security_records)
|
||||
|
||||
@@ -227,6 +227,17 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggleprayersounds)()
|
||||
return C.prefs.toggles & SOUND_PRAYERS
|
||||
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggle_bark)()
|
||||
set name = "Hear/Silence Vocal Barks"
|
||||
set category = "Preferences"
|
||||
set desc = "Hear Vocal Barks"
|
||||
usr.client.prefs.toggles ^= SOUND_BARK
|
||||
usr.client.prefs.save_preferences()
|
||||
to_chat(usr, "You will now [(usr.client.prefs.toggles & SOUND_BARK) ? "hear" : "no longer hear"] vocal barks when other people talk.")
|
||||
SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Vocal Barks", "[usr.client.prefs.toggles & SOUND_BARK ? "Enabled" : "Disabled"]"))
|
||||
/datum/verbs/menu/Settings/Sound/toggle_bark/Get_checked(client/C)
|
||||
return C.prefs.toggles & SOUND_BARK
|
||||
|
||||
/datum/verbs/menu/Settings/Sound/verb/stop_client_sounds()
|
||||
set name = "Stop Sounds"
|
||||
set category = "Preferences"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
|
||||
if(blood_DNA)
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color())
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
||||
|
||||
/obj/item/clothing/gloves/update_clothes_damaged_state()
|
||||
..()
|
||||
|
||||
@@ -360,3 +360,12 @@
|
||||
desc = "Thin, pretty gloves intended for use in sexy feminine attire. A tag on the hem claims they pair great with black stockings."
|
||||
icon_state = "eveningblack"
|
||||
item_state = "eveningblack"
|
||||
|
||||
/obj/item/clothing/gloves/polymaid
|
||||
name = "polychromic maid gloves"
|
||||
desc = "Colourable maid gloves!"
|
||||
icon_state = "maid_arms"
|
||||
|
||||
/obj/item/clothing/gloves/polymaid/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2)
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
|
||||
if(blood_DNA)
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color())
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
||||
|
||||
/obj/item/clothing/head/update_clothes_damaged_state()
|
||||
..()
|
||||
|
||||
@@ -477,6 +477,15 @@
|
||||
item_state = "maid"
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
/obj/item/clothing/head/maid/polychromic
|
||||
name = "polychromic maid headband"
|
||||
icon_state = "polymaid"
|
||||
item_state = "polymaid"
|
||||
|
||||
/obj/item/clothing/head/maid/polychromic/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2)
|
||||
|
||||
/obj/item/clothing/head/widered
|
||||
name = "Wide red hat"
|
||||
desc = "It is both wide, and red. Stylish!"
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
|
||||
if(blood_DNA)
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color())
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
||||
|
||||
/obj/item/clothing/mask/update_clothes_damaged_state()
|
||||
..()
|
||||
|
||||
@@ -113,6 +113,50 @@
|
||||
to_chat(user, "<span class='notice'>Your Joy mask now has a [choice] Emotion!</span>")
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/mask/kitsuneblk
|
||||
name = "Black Kitsune Mask"
|
||||
desc = "An oriental styled porcelain mask, this one is black and gold."
|
||||
icon_state = "blackkitsunemask"
|
||||
item_state = "blackkitsunemask"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
flags_cover = MASKCOVERSMOUTH
|
||||
flags_inv = HIDEFACE|HIDEFACIALHAIR
|
||||
visor_flags_inv = HIDEFACE|HIDEFACIALHAIR
|
||||
visor_flags_cover = MASKCOVERSMOUTH
|
||||
slot_flags = ITEM_SLOT_MASK
|
||||
|
||||
/obj/item/clothing/mask/kitsuneblk/attack_self(mob/user)
|
||||
adjustmask(user)
|
||||
|
||||
/obj/item/clothing/mask/kitsuneblk/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
adjustmask(user)
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/mask/kitsunewhi
|
||||
name = "White Kitsune Mask"
|
||||
desc = "An oriental styled porcelain mask, this one is white and red."
|
||||
icon_state = "whitekitsunemask"
|
||||
item_state = "whitekitsunemask"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
flags_cover = MASKCOVERSMOUTH
|
||||
flags_inv = HIDEFACE|HIDEFACIALHAIR
|
||||
visor_flags_inv = HIDEFACE|HIDEFACIALHAIR
|
||||
visor_flags_cover = MASKCOVERSMOUTH
|
||||
slot_flags = ITEM_SLOT_MASK
|
||||
|
||||
/obj/item/clothing/mask/kitsunewhi/attack_self(mob/user)
|
||||
adjustmask(user)
|
||||
|
||||
/obj/item/clothing/mask/kitsunewhi/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return
|
||||
adjustmask(user)
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/mask/pig
|
||||
name = "pig mask"
|
||||
desc = "A rubber pig mask with a builtin voice modulator."
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
|
||||
if(blood_DNA)
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color())
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
||||
|
||||
/obj/item/clothing/neck/tie
|
||||
name = "tie"
|
||||
@@ -259,6 +259,15 @@
|
||||
name = "Collar Key"
|
||||
desc = "A key for a tiny lock on a collar or bag."
|
||||
|
||||
/obj/item/clothing/neck/maid
|
||||
name = "polychromic maid collar"
|
||||
desc = "A collar that goes with the polychromic maid outfit."
|
||||
icon_state = "maid_neck"
|
||||
|
||||
/obj/item/clothing/neck/maid/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2)
|
||||
|
||||
//////////////
|
||||
//DOPE BLING//
|
||||
//////////////
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
var/last_bloodtype = "" //used to track the last bloodtype to have graced these shoes; makes for better performing footprint shenanigans
|
||||
var/last_blood_DNA = "" //same as last one
|
||||
var/last_blood_color = ""
|
||||
var/last_blood_blend = null
|
||||
|
||||
///Whether these shoes have laces that can be tied/untied
|
||||
var/can_be_tied = TRUE
|
||||
@@ -68,6 +69,7 @@
|
||||
last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
|
||||
last_blood_DNA = blood_dna[blood_dna.len]
|
||||
last_blood_color = blood_dna["color"]
|
||||
last_blood_blend = blood_dna["blendmode"]
|
||||
|
||||
/obj/item/clothing/shoes/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
|
||||
. = ..()
|
||||
@@ -82,7 +84,7 @@
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe")
|
||||
if(bloody)
|
||||
var/file2use = style_flags & STYLE_DIGITIGRADE ? 'icons/mob/clothing/feet_digi.dmi' : 'icons/effects/blood.dmi'
|
||||
. += mutable_appearance(file2use, "shoeblood", color = blood_DNA_to_color())
|
||||
. += mutable_appearance(file2use, "shoeblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
||||
|
||||
/obj/item/clothing/shoes/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
|
||||
@@ -213,6 +213,7 @@
|
||||
heat_protection = FEET|LEGS
|
||||
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
|
||||
resistance_flags = FIRE_PROOF
|
||||
lace_time = 10 SECONDS
|
||||
|
||||
/obj/item/clothing/shoes/cult
|
||||
name = "\improper Nar'Sien invoker boots"
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
|
||||
if(blood_DNA)
|
||||
var/file2use = (style_flags & STYLE_ALL_TAURIC) ? 'modular_citadel/icons/mob/64x32_effects.dmi' : 'icons/effects/blood.dmi'
|
||||
. += mutable_appearance(file2use, "[blood_overlay_type]blood", color = blood_DNA_to_color())
|
||||
. += mutable_appearance(file2use, "[blood_overlay_type]blood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
||||
var/mob/living/carbon/human/M = loc
|
||||
if(ishuman(M) && M.w_uniform)
|
||||
var/obj/item/clothing/under/U = M.w_uniform
|
||||
if(istype(U) && U.attached_accessory)
|
||||
var/obj/item/clothing/accessory/A = U.attached_accessory
|
||||
if(A.above_suit)
|
||||
. += U.accessory_overlay
|
||||
. += U.accessory_overlays
|
||||
|
||||
/obj/item/clothing/suit/update_clothes_damaged_state()
|
||||
..()
|
||||
|
||||
@@ -84,6 +84,23 @@
|
||||
"Cloak" = "trenchcloak"
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/hos/platecarrier
|
||||
name = "plate carrier"
|
||||
desc = "An armor vest with attached pockets for holding and sorting equipment or ammo."
|
||||
icon_state = "platecarrier"
|
||||
item_state = "platecarrier"
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
armor = list (MELEE = 30, BULLET = 40, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 70, WOUND = 10)
|
||||
cold_protection = CHEST|ARMS
|
||||
heat_protection = CHEST|ARMS
|
||||
strip_delay = 80
|
||||
mutantrace_variation = STYLE_DIGITIGRADE
|
||||
|
||||
/obj/item/clothing/suit/armor/hos/platecarrier/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/concrete/storage = AddComponent(/datum/component/storage/concrete)
|
||||
storage.max_items = 5
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/warden
|
||||
name = "warden's jacket"
|
||||
desc = "A navy-blue armored jacket with blue shoulder designations and '/Warden/' stitched into one of the chest pockets."
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/alt_covers_chest = FALSE // for adjusted/rolled-down jumpsuits, FALSE = exposes chest and arms, TRUE = exposes arms only
|
||||
var/dummy_thick = FALSE // is able to hold accessories on its item
|
||||
var/obj/item/clothing/accessory/attached_accessory
|
||||
var/mutable_appearance/accessory_overlay
|
||||
var/list/accessory_overlays
|
||||
|
||||
/obj/item/clothing/under/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
|
||||
. = ..()
|
||||
@@ -29,9 +29,9 @@
|
||||
if(damaged_clothes)
|
||||
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
|
||||
if(blood_DNA)
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color())
|
||||
if(accessory_overlay)
|
||||
. += accessory_overlay
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
||||
if(length(accessory_overlays))
|
||||
. += accessory_overlays
|
||||
|
||||
/obj/item/clothing/under/attackby(obj/item/I, mob/user, params)
|
||||
if((sensordamage || (has_sensor < HAS_SENSORS && has_sensor != NO_SENSORS)) && istype(I, /obj/item/stack/cable_coil))
|
||||
@@ -154,9 +154,15 @@
|
||||
if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY))
|
||||
return TRUE
|
||||
|
||||
accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', attached_accessory.icon_state)
|
||||
accessory_overlay.alpha = attached_accessory.alpha
|
||||
accessory_overlay.color = attached_accessory.color
|
||||
var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays")
|
||||
if(!polychromic)
|
||||
var/mutable_appearance/accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', attached_accessory.icon_state)
|
||||
accessory_overlay.alpha = attached_accessory.alpha
|
||||
accessory_overlay.color = attached_accessory.color
|
||||
accessory_overlays = list(accessory_overlay)
|
||||
else
|
||||
accessory_overlays = list()
|
||||
polychromic.apply_worn_overlays(I, FALSE, 'icons/mob/clothing/accessories.dmi', I.item_state || I.icon_state, NONE, accessory_overlays)
|
||||
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
plane = initial(plane)
|
||||
U.cut_overlays()
|
||||
U.attached_accessory = null
|
||||
U.accessory_overlay = null
|
||||
U.accessory_overlays = null
|
||||
|
||||
/obj/item/clothing/accessory/proc/on_uniform_equip(obj/item/clothing/under/U, user)
|
||||
return
|
||||
@@ -255,6 +255,15 @@
|
||||
item_state = "maidapron"
|
||||
minimize_when_attached = FALSE
|
||||
|
||||
/obj/item/clothing/accessory/maidapron/polychromic
|
||||
name = "polychromic maid apron"
|
||||
icon_state = "polymaidapron"
|
||||
item_state = "polymaidapron"
|
||||
|
||||
/obj/item/clothing/accessory/maidapron/polychromic/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2)
|
||||
|
||||
/obj/item/clothing/accessory/sleevecrop
|
||||
name = "one sleeved crop top"
|
||||
desc = "Off the shoulder crop top, for those nights out partying."
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
name = "Anomaly: Hyper-Energetic Flux"
|
||||
typepath = /datum/round_event/anomaly/anomaly_flux
|
||||
|
||||
min_players = 10
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "Anomaly: Pyroclastic"
|
||||
typepath = /datum/round_event/anomaly/anomaly_pyro
|
||||
|
||||
min_players = 5
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/datum/round_event_control/atmos_flux
|
||||
name = "Atmospheric Flux"
|
||||
typepath = /datum/round_event/atmos_flux
|
||||
max_occurrences = 1
|
||||
weight = 5
|
||||
endWhen = 600
|
||||
var/original_speed
|
||||
max_occurrences = 5
|
||||
weight = 10
|
||||
|
||||
/datum/round_event/atmos_flux
|
||||
announceWhen = 1
|
||||
endWhen = 600
|
||||
var/original_speed
|
||||
|
||||
/datum/round_event/atmos_flux/announce(fake)
|
||||
priority_announce("Atmospheric flux in your sector detected. Sensors show that air may move [(SSair.share_max_steps_target > original_speed) ? "faster" : "slower"] than usual for some time.", "Atmos Alert")
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
min_players = 5
|
||||
|
||||
/datum/round_event_control/brain_trauma/canSpawnEvent(var/players_amt, var/gamemode)
|
||||
var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic")
|
||||
if(!..()) return FALSE
|
||||
var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic","AI","Chemist","Virologist","Captain","Head of Personnel","Roboticist")
|
||||
for (var/mob/M in GLOB.alive_mob_list)
|
||||
if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles))
|
||||
return TRUE
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "Cat Surgeon"
|
||||
typepath = /datum/round_event/cat_surgeon
|
||||
max_occurrences = 1
|
||||
weight = 8
|
||||
weight = 5
|
||||
|
||||
/datum/round_event/cat_surgeon/announce(fake)
|
||||
priority_announce("One of our... ahem... 'special' cases has escaped. As it happens their last known location before their tracker went dead is your station so keep an eye out for them. On an unrelated note, has anyone seen our cats?",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "Disease Outbreak"
|
||||
typepath = /datum/round_event/disease_outbreak
|
||||
max_occurrences = 1
|
||||
min_players = 10
|
||||
min_players = 3
|
||||
weight = 5
|
||||
|
||||
/datum/round_event/disease_outbreak
|
||||
@@ -12,6 +12,13 @@
|
||||
|
||||
var/max_severity = 3
|
||||
|
||||
/datum/round_event_control/disease_outbreak/canSpawnEvent(var/players_amt, var/gamemode)
|
||||
if(!..()) return FALSE
|
||||
var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic","AI","Chemist","Virologist","Captain","Head of Personnel", "Geneticist")
|
||||
for (var/mob/M in GLOB.alive_mob_list)
|
||||
if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/round_event/disease_outbreak/announce(fake)
|
||||
priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak7")
|
||||
@@ -22,7 +29,10 @@
|
||||
|
||||
/datum/round_event/disease_outbreak/start()
|
||||
var/advanced_virus = FALSE
|
||||
max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes
|
||||
var/player_count = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)
|
||||
max_severity = 1 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes
|
||||
max_severity += player_count > 5
|
||||
max_severity += player_count > 10
|
||||
if(prob(20 + (10 * max_severity)))
|
||||
advanced_virus = TRUE
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
/datum/round_event_control/sandstorm
|
||||
name = "Sandstorm"
|
||||
typepath = /datum/round_event/sandstorm
|
||||
weight = 0
|
||||
max_occurrences = 0
|
||||
earliest_start = 0 MINUTES
|
||||
weight = 5
|
||||
max_occurrences = 1
|
||||
min_players = 5
|
||||
earliest_start = 20 MINUTES
|
||||
|
||||
/datum/round_event/sandstorm
|
||||
startWhen = 1
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
/datum/round_event_control/heart_attack
|
||||
name = "Random Heart Attack"
|
||||
typepath = /datum/round_event/heart_attack
|
||||
weight = 20
|
||||
weight = 10
|
||||
max_occurrences = 2
|
||||
min_players = 40 // To avoid shafting lowpop
|
||||
min_players = 10 // To avoid shafting lowpop
|
||||
|
||||
/datum/round_event_control/heart_attack/canSpawnEvent(var/players_amt, var/gamemode)
|
||||
if(!..()) return FALSE
|
||||
var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic","Chemist")
|
||||
for (var/mob/M in GLOB.alive_mob_list)
|
||||
if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/round_event/heart_attack/start()
|
||||
var/list/heart_attack_contestants = list()
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list)
|
||||
Ian.place_on_head(new /obj/item/bedsheet(Ian))
|
||||
for(var/mob/living/simple_animal/parrot/Poly/Poly in GLOB.mob_living_list)
|
||||
new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc)
|
||||
qdel(Poly)
|
||||
for(var/mob/living/simple_animal/parrot/Polly/Polly in GLOB.mob_living_list)
|
||||
new /mob/living/simple_animal/parrot/Polly/ghost(Polly.loc)
|
||||
qdel(Polly)
|
||||
|
||||
|
||||
/datum/round_event/spooky/announce(fake)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "Mass Hallucination"
|
||||
typepath = /datum/round_event/mass_hallucination
|
||||
weight = 10
|
||||
max_occurrences = 2
|
||||
max_occurrences = 5
|
||||
min_players = 1
|
||||
var/forced_hallucination
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "Supermatter Surge"
|
||||
typepath = /datum/round_event/supermatter_surge
|
||||
weight = 20
|
||||
max_occurrences = 4
|
||||
max_occurrences = 5
|
||||
earliest_start = 10 MINUTES
|
||||
|
||||
/datum/round_event_control/supermatter_surge/canSpawnEvent()
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
/datum/round_event/supermatter_surge/start()
|
||||
var/obj/machinery/power/supermatter_crystal/supermatter = GLOB.main_supermatter_engine
|
||||
var/power_proportion = supermatter.powerloss_inhibitor/2 // what % of the power goes into matter power, at most 50%
|
||||
var/power_proportion = supermatter.powerloss_inhibitor * 0.75 // what % of the power goes into matter power, at most 50%
|
||||
// we reduce the proportion that goes into actual matter power based on powerloss inhibitor
|
||||
// primarily so the supermatter doesn't tesla the instant these happen
|
||||
supermatter.matter_power += power * power_proportion
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/datum/round_event_control/supernova
|
||||
name = "Supernova"
|
||||
typepath = /datum/round_event/supernova
|
||||
weight = 10
|
||||
max_occurrences = 2
|
||||
weight = 5
|
||||
max_occurrences = 1
|
||||
min_players = 2
|
||||
|
||||
/datum/round_event/supernova
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/datum/round_event_control/untied_shoes
|
||||
name = "Untied Shoes"
|
||||
typepath = /datum/round_event/untied_shoes
|
||||
weight = 100
|
||||
max_occurrences = 20
|
||||
alert_observers = FALSE
|
||||
|
||||
/datum/round_event/untied_shoes
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/untied_shoes/start()
|
||||
var/budget = rand(5 SECONDS,20 SECONDS)
|
||||
for(var/mob/living/carbon/C in shuffle(GLOB.alive_mob_list))
|
||||
if(!C.client)
|
||||
continue
|
||||
if(C.stat == DEAD)
|
||||
continue
|
||||
if (HAS_TRAIT(C,TRAIT_EXEMPT_HEALTH_EVENTS))
|
||||
continue
|
||||
if(!C.shoes || !C.shoes.can_be_tied || C.shoes.tied != SHOES_TIED || C.shoes.lace_time > budget)
|
||||
continue
|
||||
if(!is_station_level(C.z) && prob(50))
|
||||
continue
|
||||
if(prob(5))
|
||||
C.shoes.adjust_laces(SHOES_KNOTTED)
|
||||
budget -= C.shoes.lace_time // doubling up on the budget removal on purpose
|
||||
else
|
||||
C.shoes.adjust_laces(SHOES_UNTIED)
|
||||
budget -= C.shoes.lace_time
|
||||
if(budget < 5 SECONDS)
|
||||
return
|
||||
@@ -3,7 +3,6 @@
|
||||
typepath = /datum/round_event/vent_clog
|
||||
weight = 10
|
||||
max_occurrences = 3
|
||||
min_players = 25
|
||||
|
||||
/datum/round_event/vent_clog
|
||||
announceWhen = 1
|
||||
@@ -11,7 +10,7 @@
|
||||
endWhen = 35
|
||||
var/interval = 2
|
||||
var/list/vents = list()
|
||||
var/randomProbability = 1
|
||||
var/randomProbability = 0
|
||||
var/reagentsAmount = 100
|
||||
var/list/saferChems = list(
|
||||
/datum/reagent/water,
|
||||
@@ -92,7 +91,7 @@
|
||||
|
||||
var/datum/reagents/R = new/datum/reagents(1000)
|
||||
R.my_atom = vent
|
||||
if (prob(randomProbability))
|
||||
if (randomProbability && prob(randomProbability))
|
||||
R.add_reagent(get_random_reagent_id(), reagentsAmount)
|
||||
else
|
||||
R.add_reagent(pick(saferChems), reagentsAmount)
|
||||
@@ -106,7 +105,7 @@
|
||||
name = "Clogged Vents: Threatening"
|
||||
typepath = /datum/round_event/vent_clog/threatening
|
||||
weight = 4
|
||||
min_players = 35
|
||||
min_players = 15
|
||||
max_occurrences = 1
|
||||
earliest_start = 35 MINUTES
|
||||
|
||||
@@ -118,7 +117,7 @@
|
||||
name = "Clogged Vents: Catastrophic"
|
||||
typepath = /datum/round_event/vent_clog/catastrophic
|
||||
weight = 2
|
||||
min_players = 45
|
||||
min_players = 25
|
||||
max_occurrences = 1
|
||||
earliest_start = 45 MINUTES
|
||||
|
||||
|
||||
@@ -311,6 +311,7 @@
|
||||
/obj/item/reagent_containers/food/snacks/pizza/donkpocket = 0.3,
|
||||
/obj/item/reagent_containers/food/snacks/pizza/dank = 0.1) //pizzas here are weighted by chance to be someone's favorite
|
||||
var/static/list/pizza_preferences
|
||||
COOLDOWN_DECLARE(next_pizza_attunement)
|
||||
|
||||
/obj/item/pizzabox/infinite/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -323,11 +324,18 @@
|
||||
. += "<span class='deadsay'>This pizza box is anomalous, and will produce infinite pizza.</span>"
|
||||
|
||||
/obj/item/pizzabox/infinite/attack_self(mob/living/user)
|
||||
QDEL_NULL(pizza)
|
||||
if(ishuman(user))
|
||||
attune_pizza(user)
|
||||
if(COOLDOWN_FINISHED(src, next_pizza_attunement))
|
||||
QDEL_NULL(pizza)
|
||||
if(ishuman(user))
|
||||
attune_pizza(user)
|
||||
. = ..()
|
||||
|
||||
/obj/item/pizzabox/infinite/on_attack_hand(mob/user, act_intent, unarmed_attack_flags)
|
||||
var/had_pizza = (pizza ? TRUE : FALSE)
|
||||
. = ..()
|
||||
if(had_pizza && !pizza)
|
||||
COOLDOWN_START(src, next_pizza_attunement, (3 SECONDS))
|
||||
|
||||
/obj/item/pizzabox/infinite/proc/attune_pizza(mob/living/carbon/human/noms) //tonight on "proc names I never thought I'd type"
|
||||
if(!pizza_preferences[noms.ckey])
|
||||
pizza_preferences[noms.ckey] = pickweight(pizza_types)
|
||||
|
||||
@@ -771,8 +771,8 @@
|
||||
|
||||
/datum/chemical_reaction/pinkmilk
|
||||
name = "Strawberry Milk"
|
||||
id = /datum/reagent/consumable/pinkmilk
|
||||
results = list(/datum/reagent/consumable/pinkmilk = 2)
|
||||
id = /datum/reagent/consumable/milk/pinkmilk
|
||||
results = list(/datum/reagent/consumable/milk/pinkmilk = 2)
|
||||
required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/milk = 1)
|
||||
mix_message = "You feel a sweet aroma drift up your nose as the lactic mixture swirls. It reminds you of... a cafeteria."
|
||||
|
||||
@@ -1016,8 +1016,8 @@
|
||||
|
||||
/datum/chemical_reaction/pinktea
|
||||
name = "Strawberry Tea"
|
||||
id = /datum/reagent/consumable/pinktea
|
||||
results = list(/datum/reagent/consumable/pinktea = 5)
|
||||
id = /datum/reagent/consumable/tea/pinktea
|
||||
results = list(/datum/reagent/consumable/tea/pinktea = 5)
|
||||
required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/tea/arnold_palmer = 1, /datum/reagent/consumable/sugar = 1)
|
||||
|
||||
/datum/chemical_reaction/catnip_tea
|
||||
|
||||
@@ -6,5 +6,4 @@
|
||||
return lowertext(ddd) in days
|
||||
|
||||
/datum/holiday/dynamic/celebrate()
|
||||
GLOB.dynamic_forced_threat_level = rand(90, 100)
|
||||
CONFIG_SET(string/force_gamemode, "dynamic") // prevents the round vote, which prevents extended
|
||||
GLOB.dynamic_forced_threat_level = rand(50, 100)
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
. = ..()
|
||||
AddComponent(/datum/component/stationloving)
|
||||
|
||||
/mob/living/simple_animal/jacq/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/simple_animal/jacq/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!ckey)
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
growthstages = 1
|
||||
instability = 40
|
||||
growing_icon = 'goon/icons/obj/hydroponics.dmi'
|
||||
icon_grow = "cannabis-grow" // Uses one growth icons set for all the subtypes
|
||||
icon_dead = "cannabis-dead" // Same for the dead icon
|
||||
icon_grow = "cannabis-grow"
|
||||
icon_dead = "cannabis-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/cannabis/rainbow,
|
||||
/obj/item/seeds/cannabis/death)
|
||||
@@ -26,6 +26,8 @@
|
||||
species = "megacannabis"
|
||||
plantname = "Rainbow Weed"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/cannabis/rainbow
|
||||
icon_grow = "megacannabis-grow"
|
||||
icon_dead = "megacannabis-dead"
|
||||
mutatelist = list(/obj/item/seeds/cannabis/ultimate)
|
||||
reagents_add = list(/datum/reagent/toxin/mindbreaker = 0.15, /datum/reagent/toxin/lipolicide = 0.35)
|
||||
rarity = 40
|
||||
@@ -37,6 +39,8 @@
|
||||
species = "blackcannabis"
|
||||
plantname = "Deathweed"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/cannabis/death
|
||||
icon_grow = "blackcannabis-grow"
|
||||
icon_dead = "blackcannabis-dead"
|
||||
mutatelist = list(/obj/item/seeds/cannabis/white)
|
||||
reagents_add = list(/datum/reagent/toxin/cyanide = 0.35, /datum/reagent/drug/space_drugs = 0.15, /datum/reagent/toxin/lipolicide = 0.15)
|
||||
rarity = 40
|
||||
@@ -48,6 +52,8 @@
|
||||
species = "whitecannabis"
|
||||
plantname = "Lifeweed"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/cannabis/white
|
||||
icon_grow = "whitecannabis-grow"
|
||||
icon_dead = "whitecannabis-dead"
|
||||
mutatelist = list()
|
||||
reagents_add = list(/datum/reagent/medicine/omnizine = 0.35, /datum/reagent/drug/space_drugs = 0.15, /datum/reagent/toxin/lipolicide = 0.15)
|
||||
rarity = 40
|
||||
@@ -60,6 +66,8 @@
|
||||
species = "ocannabis"
|
||||
plantname = "Omega Weed"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/cannabis/ultimate
|
||||
icon_grow = "ocannabis-grow"
|
||||
icon_dead = "ocannabis-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/glow/green)
|
||||
mutatelist = list()
|
||||
reagents_add = list(/datum/reagent/drug/space_drugs = 0.3,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
|
||||
var/tastes = list("indescribable" = 1) //Stops runtimes. Grown are un-eatable anyways so if you do then its a bug
|
||||
|
||||
/obj/item/grown/Initialize(mapload, newloc, obj/item/seeds/new_seed)
|
||||
/obj/item/grown/Initialize(mapload, obj/item/seeds/new_seed)
|
||||
. = ..()
|
||||
create_reagents(50, NONE, HARVEST_REAGENTS_VALUE)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
if(seed)
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_new(src, newloc)
|
||||
T.on_new(src, loc)
|
||||
|
||||
if(istype(src, seed.product)) // no adding reagents if it is just a trash item
|
||||
seed.prepare_result(src)
|
||||
|
||||
@@ -47,21 +47,43 @@
|
||||
|
||||
var/meta_color = area_to_color[A]
|
||||
if(!meta_color)
|
||||
meta_color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) // technically conflicts could happen but it's like very unlikely and it's not that big of a deal if one happens
|
||||
var/meta_x = LAZYLEN(area_to_color) + 1
|
||||
var/meta_y = (((meta_x + 1) - ((meta_x + 1) % 255)) / 255)
|
||||
var/meta_z = (((meta_y + 1) - ((meta_y + 1) % 255)) / 255)
|
||||
meta_color = rgb(meta_x % 255, meta_y % 255, meta_z % 255) //This supports exactly 16,581,374 areas with no conflicts whatsoever before it just gives up
|
||||
area_to_color[A] = meta_color
|
||||
color_area_names[meta_color] = A.name
|
||||
meta_icon.DrawBox(meta_color, img_x, img_y)
|
||||
|
||||
if(istype(T, /turf/closed/wall))
|
||||
if(A.minimap_show_walls && istype(T, /turf/closed/wall))
|
||||
map_icon.DrawBox("#000000", img_x, img_y)
|
||||
|
||||
else if(!istype(A, /area/space))
|
||||
var/color = A.minimap_color || "#FF00FF"
|
||||
if(locate(/obj/machinery/power/solar) in T)
|
||||
color = "#02026a"
|
||||
var/color = (A.minimap_color2 ? (((img_x + img_y) % 2) ? A.minimap_color2 : A.minimap_color ) : A.minimap_color) || "#FF00FF"
|
||||
if(A.minimap_show_walls)
|
||||
var/overridden
|
||||
for(var/obj/structure/O in T)
|
||||
if(O.minimap_override_color)
|
||||
color = O.minimap_override_color
|
||||
overridden = TRUE
|
||||
break
|
||||
else if(O.density && O.anchored)
|
||||
color = BlendRGB(color, "#000000", 0.5)
|
||||
overridden = TRUE
|
||||
break
|
||||
|
||||
//In an ideal world, we'd be able to get away with just doing for(var/obj/O in T) up there, and calling it a day. However. HOWEVER!
|
||||
//Doing that causes the code to also loop through items. and that uh. Kinda bloats minimap gen time. A LOT. We're talking straight-up doubling the time it takes to gen.
|
||||
//So instead we take our ctrl+c. We copy the above code. And we ctrl+v. It's awful. We hate it. But it works. It's faster. Funny mapgen go vroom
|
||||
if(!overridden)
|
||||
for(var/obj/machinery/O in T)
|
||||
if(O.minimap_override_color)
|
||||
color = O.minimap_override_color
|
||||
break
|
||||
else if(O.density && O.anchored)
|
||||
color = BlendRGB(color, "#000000", 0.25)
|
||||
break
|
||||
|
||||
if((locate(/obj/effect/spawner/structure/window) in T) || (locate(/obj/structure/grille) in T))
|
||||
color = BlendRGB(color, "#000000", 0.5)
|
||||
map_icon.DrawBox(color, img_x, img_y)
|
||||
|
||||
map_icon.Crop(crop_x1, crop_y1, crop_x2, crop_y2)
|
||||
@@ -102,22 +124,48 @@
|
||||
|
||||
var/list/datas = list()
|
||||
var/list/info = list()
|
||||
|
||||
for(var/i in 1 to length(minimaps))// OLD: for(var/i in 1 to length(minimaps))
|
||||
var/buttonfield = ""
|
||||
var/totalmaps = length(minimaps)
|
||||
for(var/i in 1 to totalmaps)// OLD: for(var/i in 1 to length(minimaps))
|
||||
var/datum/minimap/M = minimaps[i]
|
||||
var/map_name = "minimap-[M.id].png"
|
||||
var/meta_name = "minimap-[M.id]-meta.png"
|
||||
M.send(user)
|
||||
info += {"
|
||||
<div class="block">
|
||||
<div class="block" id='layer-[i]' [i == 1 ? "" : "style='display:none'"]>
|
||||
[totalmaps > 1 ? "<h3>Layer [i]</h3>" : ""]
|
||||
<div> <!-- The div is in here to fit it both in the block div -->
|
||||
<img id='map-[i]' src='[SSassets.transport.get_asset_url(map_name)]' />
|
||||
<img id='map-[i]-meta' src='[SSassets.transport.get_asset_url(meta_name)]' style='display: none' />
|
||||
</div>
|
||||
<div class="statusDisplay" id='label-[i]'></div>
|
||||
[totalmaps <= 1 ? "<div class='statusDisplay' id='label-[i]'> </div>" : ""]
|
||||
</div>
|
||||
"}
|
||||
datas += json_encode(M.color_area_names);
|
||||
buttonfield += "<a onclick='switchmap(\"layer-[i]\")'>Layer [i]</a> "
|
||||
|
||||
if(totalmaps > 1)
|
||||
info += "<div class='block'><div class='statusDisplay'>[buttonfield]</div></div>"
|
||||
|
||||
//This is a hacky workaround; the status display is extremely buggy when multiple z-levels are present. We couldn't figure out how to fix this after 7 hours of banging our head against the wall
|
||||
//We're coder
|
||||
var/mousemove_bit = {"
|
||||
canvas.onmousemove = function(e){
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
var x = Math.floor(e.offsetX * img.width / rect.width);
|
||||
var y = Math.floor(e.offsetY * img.height / rect.height);
|
||||
|
||||
var color_idx = x * 4 + (y * 4 * imagedata.width);
|
||||
var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]);
|
||||
|
||||
label.textContent = data\[color];
|
||||
canvas.title = data\[color];
|
||||
}
|
||||
canvas.onmouseout = function(e){
|
||||
label.textContent = " ";
|
||||
canvas.title = "";
|
||||
}
|
||||
"}
|
||||
|
||||
info = info.Join()
|
||||
//this is bad. Too bad!
|
||||
@@ -133,6 +181,14 @@
|
||||
}
|
||||
return num;
|
||||
}
|
||||
function switchmap(mapid) {
|
||||
var targetblock = document.getElementById(mapid);
|
||||
for(var i = 0; i < [length(minimaps)]; i++) {
|
||||
var currentblock = document.getElementById("layer-" + (i + 1));
|
||||
currentblock.style.display = 'none';
|
||||
}
|
||||
targetblock.style.display = '';
|
||||
}
|
||||
window.onload = function() {
|
||||
if(!window.HTMLCanvasElement) {
|
||||
var label = document.getElementById("label-1");
|
||||
@@ -150,6 +206,7 @@
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = img.width * 2;
|
||||
canvas.height = img.height * 2;
|
||||
canvas.id = "canvas-" + (i+1);
|
||||
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.msImageSmoothingEnabled = false;
|
||||
@@ -158,31 +215,23 @@
|
||||
ctx = document.createElement("canvas").getContext('2d');
|
||||
ctx.canvas.width = img.width;
|
||||
ctx.canvas.height = img.height;
|
||||
ctx.id = "ctx-" + (i+1);
|
||||
ctx.drawImage(document.getElementById("map-" + (i+1) + "-meta"), 0, 0);
|
||||
|
||||
var imagedata = ctx.getImageData(0, 0, img.width, img.height);
|
||||
|
||||
canvas.onmousemove = function(e){
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
var x = Math.floor(e.offsetX * img.width / rect.width);
|
||||
var y = Math.floor(e.offsetY * img.height / rect.height);
|
||||
|
||||
var color_idx = x * 4 + (y * 4 * imagedata.width);
|
||||
var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]);
|
||||
var label = document.getElementById("label-" + (i+1)); //label-String(n)
|
||||
|
||||
label.textContent = data\[color];
|
||||
canvas.title = data\[color];
|
||||
}
|
||||
canvas.onmouseout = function(e){
|
||||
canvas.title = "";
|
||||
}
|
||||
var label = document.getElementById("label-" + (i+1)); //label-String(n);
|
||||
[totalmaps <= 1 ? mousemove_bit : ""]
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
img, canvas {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped")
|
||||
sharpness = SHARP_EDGED
|
||||
actions_types = list(/datum/action/item_action/toggle_light)
|
||||
obj_flags = UNIQUE_RENAME
|
||||
var/list/trophies = list()
|
||||
var/charged = TRUE
|
||||
var/charge_time = 15
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
|
||||
..()
|
||||
|
||||
if(!age_verify())
|
||||
return
|
||||
|
||||
if(!client) //client can end up null as a result of age_verify() kicking those who fail
|
||||
return
|
||||
|
||||
var/motd = global.config.motd
|
||||
if(motd)
|
||||
to_chat(src, "<div class=\"motd\">[motd]</div>", handle_whitespace=FALSE)
|
||||
@@ -22,8 +28,11 @@
|
||||
|
||||
sight |= SEE_TURFS
|
||||
|
||||
new_player_panel()
|
||||
client.playtitlemusic()
|
||||
|
||||
var/datum/asset/asset_datum = get_asset_datum(/datum/asset/simple/lobby)
|
||||
asset_datum.send(client)
|
||||
|
||||
if(SSticker.current_state < GAME_STATE_SETTING_UP)
|
||||
var/tl = SSticker.GetTimeLeft()
|
||||
var/postfix
|
||||
@@ -32,3 +41,7 @@
|
||||
else
|
||||
postfix = "soon"
|
||||
to_chat(src, "Please set up your character and select \"Ready\". The game will start [postfix].")
|
||||
|
||||
var/datum/hud/new_player/NH = hud_used
|
||||
if(istype(NH))
|
||||
NH.populate_buttons(src)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define LINKIFY_READY(string, value) "<a href='byond://?src=[REF(src)];ready=[value]'>[string]</a>"
|
||||
|
||||
/mob/dead/new_player
|
||||
var/ready = 0
|
||||
var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
|
||||
@@ -10,6 +8,8 @@
|
||||
|
||||
density = FALSE
|
||||
stat = DEAD
|
||||
hud_type = /datum/hud/new_player
|
||||
hud_possible = list()
|
||||
|
||||
var/mob/living/new_character //for instant transfer once the round is set up
|
||||
|
||||
@@ -43,69 +43,6 @@
|
||||
/mob/dead/new_player/prepare_huds()
|
||||
return
|
||||
|
||||
/mob/dead/new_player/proc/new_player_panel()
|
||||
var/output = "<center><p>Welcome, <b>[client ? client.prefs.real_name : "Unknown User"]</b></p>"
|
||||
output += "<center><p><a href='byond://?src=[REF(src)];show_preferences=1'>Setup Character</a></p>"
|
||||
|
||||
if(SSticker.current_state <= GAME_STATE_PREGAME)
|
||||
switch(ready)
|
||||
if(PLAYER_NOT_READY)
|
||||
output += "<p>\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | <b>Not Ready</b> | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]</p>"
|
||||
if(PLAYER_READY_TO_PLAY)
|
||||
output += "<p>\[ <b>Ready</b> | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]</p>"
|
||||
if(PLAYER_READY_TO_OBSERVE)
|
||||
output += "<p>\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | <b> Observe </b> \]</p>"
|
||||
else
|
||||
output += "<p><a href='byond://?src=[REF(src)];manifest=1'>View the Crew Manifest</a></p>"
|
||||
output += "<p><a href='byond://?src=[REF(src)];late_join=1'>Join Game!</a></p>"
|
||||
output += "<p>[LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)]</p>"
|
||||
|
||||
if(!IsGuestKey(src.key))
|
||||
output += playerpolls()
|
||||
|
||||
output += "</center>"
|
||||
|
||||
//src << browse(output,"window=playersetup;size=210x240;can_close=0")
|
||||
var/datum/browser/popup = new(src, "playersetup", "<div align='center'>New Player Options</div>", 250, 265)
|
||||
popup.set_window_options("can_close=0")
|
||||
popup.set_content(output)
|
||||
popup.open(FALSE)
|
||||
|
||||
/mob/dead/new_player/proc/playerpolls()
|
||||
var/output = "" //hey tg why is this a list?
|
||||
if (SSdbcore.Connect())
|
||||
var/isadmin = FALSE
|
||||
if(client?.holder)
|
||||
isadmin = TRUE
|
||||
var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({"
|
||||
SELECT id FROM [format_table_name("poll_question")]
|
||||
WHERE (adminonly = 0 OR :isadmin = 1)
|
||||
AND Now() BETWEEN starttime AND endtime
|
||||
AND deleted = 0
|
||||
AND id NOT IN (
|
||||
SELECT pollid FROM [format_table_name("poll_vote")]
|
||||
WHERE ckey = :ckey
|
||||
AND deleted = 0
|
||||
)
|
||||
AND id NOT IN (
|
||||
SELECT pollid FROM [format_table_name("poll_textreply")]
|
||||
WHERE ckey = :ckey
|
||||
AND deleted = 0
|
||||
)
|
||||
"}, list("isadmin" = isadmin, "ckey" = ckey))
|
||||
var/rs = REF(src)
|
||||
if(!query_get_new_polls.Execute())
|
||||
qdel(query_get_new_polls)
|
||||
return
|
||||
if(query_get_new_polls.NextRow())
|
||||
output += "<p><b><a href='byond://?src=[rs];showpoll=1'>Show Player Polls</A> (NEW!)</b></p>"
|
||||
else
|
||||
output += "<p><a href='byond://?src=[rs];showpoll=1'>Show Player Polls</A></p>"
|
||||
qdel(query_get_new_polls)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
return output
|
||||
|
||||
/mob/dead/new_player/proc/age_gate()
|
||||
var/list/dat = list("<center>")
|
||||
dat += "Enter your date of birth here, to confirm that you are over 18.<BR>"
|
||||
@@ -152,6 +89,9 @@
|
||||
if(!(client.prefs.db_flags & DB_FLAG_AGE_CONFIRMATION_INCOMPLETE)) //completed? Skip
|
||||
return TRUE
|
||||
|
||||
if(!client)
|
||||
return FALSE
|
||||
|
||||
var/age_verification = age_gate()
|
||||
//ban them and kick them
|
||||
if(age_verification != 1)
|
||||
@@ -269,61 +209,12 @@
|
||||
if(!age_verify())
|
||||
return
|
||||
|
||||
//Determines Relevent Population Cap
|
||||
var/relevant_cap
|
||||
var/hpc = CONFIG_GET(number/hard_popcap)
|
||||
var/epc = CONFIG_GET(number/extreme_popcap)
|
||||
if(hpc && epc)
|
||||
relevant_cap = min(hpc, epc)
|
||||
else
|
||||
relevant_cap = max(hpc, epc)
|
||||
|
||||
if(href_list["show_preferences"])
|
||||
client.prefs.ShowChoices(src)
|
||||
return 1
|
||||
|
||||
if(href_list["ready"])
|
||||
var/tready = text2num(href_list["ready"])
|
||||
//Avoid updating ready if we're after PREGAME (they should use latejoin instead)
|
||||
//This is likely not an actual issue but I don't have time to prove that this
|
||||
//no longer is required
|
||||
if(SSticker.current_state <= GAME_STATE_PREGAME)
|
||||
ready = tready
|
||||
//if it's post initialisation and they're trying to observe we do the needful
|
||||
if(!SSticker.current_state < GAME_STATE_PREGAME && tready == PLAYER_READY_TO_OBSERVE)
|
||||
ready = tready
|
||||
make_me_an_observer()
|
||||
return
|
||||
|
||||
if(href_list["refresh"])
|
||||
src << browse(null, "window=playersetup") //closes the player setup window
|
||||
new_player_panel()
|
||||
|
||||
if(href_list["late_join"])
|
||||
if(!SSticker || !SSticker.IsRoundInProgress())
|
||||
to_chat(usr, "<span class='danger'>The round is either not ready, or has already finished...</span>")
|
||||
return
|
||||
|
||||
if(href_list["late_join"] == "override")
|
||||
LateChoices()
|
||||
return
|
||||
|
||||
if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.admin_datums)))
|
||||
to_chat(usr, "<span class='danger'>[CONFIG_GET(string/hard_popcap_message)]</span>")
|
||||
|
||||
var/queue_position = SSticker.queued_players.Find(usr)
|
||||
if(queue_position == 1)
|
||||
to_chat(usr, "<span class='notice'>You are next in line to join the game. You will be notified when a slot opens up.</span>")
|
||||
else if(queue_position)
|
||||
to_chat(usr, "<span class='notice'>There are [queue_position-1] players in front of you in the queue to join the game.</span>")
|
||||
else
|
||||
SSticker.queued_players += usr
|
||||
to_chat(usr, "<span class='notice'>You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].</span>")
|
||||
return
|
||||
LateChoices()
|
||||
|
||||
if(href_list["manifest"])
|
||||
ViewManifest()
|
||||
return
|
||||
|
||||
if(href_list["SelectedJob"])
|
||||
if(!SSticker || !SSticker.IsRoundInProgress())
|
||||
@@ -337,6 +228,17 @@
|
||||
to_chat(usr, "<span class='notice'>There is an administrative lock on entering the game!</span>")
|
||||
return
|
||||
|
||||
//Determines Relevent Population Cap
|
||||
var/relevant_cap
|
||||
var/hpc = CONFIG_GET(number/hard_popcap)
|
||||
var/epc = CONFIG_GET(number/extreme_popcap)
|
||||
if(hpc && epc)
|
||||
relevant_cap = min(hpc, epc)
|
||||
else
|
||||
relevant_cap = max(hpc, epc)
|
||||
|
||||
|
||||
|
||||
if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums))
|
||||
if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
|
||||
to_chat(usr, "<span class='warning'>Server is full.</span>")
|
||||
@@ -349,6 +251,15 @@
|
||||
if(!GLOB.enter_allowed)
|
||||
to_chat(usr, "<span class='notice'> There is an administrative lock on entering the game!</span>")
|
||||
|
||||
//Determines Relevent Population Cap
|
||||
var/relevant_cap
|
||||
var/hpc = CONFIG_GET(number/hard_popcap)
|
||||
var/epc = CONFIG_GET(number/extreme_popcap)
|
||||
if(hpc && epc)
|
||||
relevant_cap = min(hpc, epc)
|
||||
else
|
||||
relevant_cap = max(hpc, epc)
|
||||
|
||||
if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums))
|
||||
if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
|
||||
to_chat(usr, "<span class='warning'>Server is full.</span>")
|
||||
@@ -360,13 +271,6 @@
|
||||
SSticker.queue_delay = 4
|
||||
qdel(src)
|
||||
|
||||
else if(!href_list["late_join"])
|
||||
new_player_panel()
|
||||
|
||||
if(href_list["showpoll"])
|
||||
handle_player_polling()
|
||||
return
|
||||
|
||||
if(href_list["pollid"])
|
||||
var/pollid = href_list["pollid"]
|
||||
if(istext(pollid))
|
||||
@@ -460,7 +364,6 @@
|
||||
if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
|
||||
ready = PLAYER_NOT_READY
|
||||
src << browse(null, "window=playersetup") //closes the player setup window
|
||||
new_player_panel()
|
||||
return FALSE
|
||||
|
||||
var/mob/dead/observer/observer = new()
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
var/rando_race = pick(GLOB.roundstart_races)
|
||||
pref_species = new rando_race()
|
||||
features = random_features(pref_species?.id, gender)
|
||||
bark_id = pick(GLOB.bark_random_list)
|
||||
bark_pitch = BARK_PITCH_RAND(gender)
|
||||
bark_variance = BARK_VARIANCE_RAND
|
||||
age = rand(AGE_MIN,AGE_MAX)
|
||||
|
||||
/datum/preferences/proc/update_preview_icon(current_tab)
|
||||
|
||||
@@ -121,7 +121,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
remove_verb(src, /mob/dead/observer/verb/boo)
|
||||
remove_verb(src, /mob/dead/observer/verb/possess)
|
||||
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
|
||||
add_to_dead_mob_list()
|
||||
|
||||
@@ -534,8 +535,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/dead/observer/stop_orbit(datum/component/orbiter/orbits)
|
||||
. = ..()
|
||||
//restart our floating animation after orbit is done.
|
||||
pixel_y = 0
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
pixel_z = 0
|
||||
animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
|
||||
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
|
||||
set category = "Ghost"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
|
||||
// Takes care blood loss and regeneration
|
||||
/mob/living/carbon/human/handle_blood()
|
||||
/mob/living/carbon/human/handle_blood(delta_time, times_fired)
|
||||
|
||||
if(NOBLOOD in dna.species.species_traits || bleedsuppress || (HAS_TRAIT(src, TRAIT_FAKEDEATH)))
|
||||
return
|
||||
@@ -39,56 +39,57 @@
|
||||
return
|
||||
|
||||
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
|
||||
if(integrating_blood > 0)
|
||||
var/blood_integrated = max(integrating_blood - 1, 0)
|
||||
var/blood_diff = integrating_blood - blood_integrated
|
||||
integrating_blood = blood_integrated
|
||||
if(blood_volume < BLOOD_VOLUME_MAXIMUM)
|
||||
blood_volume += blood_diff
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
var/nutrition_ratio = 0
|
||||
if(!HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
switch(nutrition)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
nutrition_ratio = 0.2
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
nutrition_ratio = 0.4
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
nutrition_ratio = 0.6
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
nutrition_ratio = 0.8
|
||||
else
|
||||
nutrition_ratio = 1
|
||||
if(satiety > 80)
|
||||
nutrition_ratio *= 1.25
|
||||
adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR)
|
||||
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
|
||||
if(dna.species.handle_blood(src, delta_time, times_fired)) // if this returns TRUE, then the species is not handling blood itself and we can control everything
|
||||
if(integrating_blood > 0)
|
||||
var/blood_integrated = max(integrating_blood - 1, 0)
|
||||
var/blood_diff = integrating_blood - blood_integrated
|
||||
integrating_blood = blood_integrated
|
||||
if(blood_volume < BLOOD_VOLUME_MAXIMUM)
|
||||
blood_volume += blood_diff
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
var/nutrition_ratio = 0
|
||||
if(!HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
switch(nutrition)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
nutrition_ratio = 0.2
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
nutrition_ratio = 0.4
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
nutrition_ratio = 0.6
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
nutrition_ratio = 0.8
|
||||
else
|
||||
nutrition_ratio = 1
|
||||
if(satiety > 80)
|
||||
nutrition_ratio *= 1.25
|
||||
adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR)
|
||||
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
|
||||
|
||||
//Effects of bloodloss
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange.
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
var/blood_effect_volume = blood_volume + integrating_blood
|
||||
switch(blood_effect_volume)
|
||||
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
|
||||
if(prob(10))
|
||||
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
if(prob(5))
|
||||
to_chat(src, "<span class='warning'>You feel [word].</span>")
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
|
||||
if(prob(5))
|
||||
blur_eyes(6)
|
||||
to_chat(src, "<span class='warning'>You feel very [word].</span>")
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
adjustOxyLoss(5)
|
||||
if(prob(15))
|
||||
Unconscious(rand(20,60))
|
||||
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
|
||||
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
|
||||
if(!HAS_TRAIT(src, TRAIT_NODEATH))
|
||||
death()
|
||||
//Effects of bloodloss
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange.
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
var/blood_effect_volume = blood_volume + integrating_blood
|
||||
switch(blood_effect_volume)
|
||||
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
|
||||
if(prob(10))
|
||||
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
if(prob(5))
|
||||
to_chat(src, "<span class='warning'>You feel [word].</span>")
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
|
||||
if(prob(5))
|
||||
blur_eyes(6)
|
||||
to_chat(src, "<span class='warning'>You feel very [word].</span>")
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
adjustOxyLoss(5)
|
||||
if(prob(15))
|
||||
Unconscious(rand(20,60))
|
||||
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
|
||||
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
|
||||
if(!HAS_TRAIT(src, TRAIT_NODEATH))
|
||||
death()
|
||||
|
||||
var/temp_bleed = 0
|
||||
//Bleeding out
|
||||
@@ -193,6 +194,7 @@
|
||||
|
||||
blood_data["blood_DNA"] = dna.unique_enzymes
|
||||
blood_data["bloodcolor"] = dna.species.exotic_blood_color
|
||||
blood_data["bloodblend"] = dna.species.exotic_blood_blend_mode
|
||||
if(disease_resistances && disease_resistances.len)
|
||||
blood_data["resistances"] = disease_resistances.Copy()
|
||||
var/list/temp_chem = list()
|
||||
@@ -264,7 +266,7 @@
|
||||
"O-" = list("O-","SY"),
|
||||
"O+" = list("O-", "O+","SY"),
|
||||
"L" = list("L","SY"),
|
||||
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY"),
|
||||
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY", "BUG"),
|
||||
"HF" = list("HF", "SY"),
|
||||
"X*" = list("X*", "SY"),
|
||||
"SY" = list("SY"),
|
||||
@@ -370,27 +372,6 @@
|
||||
if(!B)
|
||||
B = new(T)
|
||||
|
||||
//This is a terrible way of handling it.
|
||||
/mob/living/proc/ResetBloodVol()
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if (HAS_TRAIT(src, TRAIT_HIGH_BLOOD))
|
||||
blood_ratio = 1.2
|
||||
H.handle_blood()
|
||||
return
|
||||
blood_ratio = 1
|
||||
H.handle_blood()
|
||||
return
|
||||
blood_ratio = 1
|
||||
|
||||
/mob/living/proc/AdjustBloodVol(value)
|
||||
if(blood_ratio == value)
|
||||
return
|
||||
blood_ratio = value
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
H.handle_blood()
|
||||
|
||||
/mob/living/proc/adjust_integration_blood(value, remove_actual_blood, force)
|
||||
if(integrating_blood + value < 0 && remove_actual_blood)
|
||||
blood_volume += value + integrating_blood
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
/mob/living/brain/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/brain/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
handle_emp_damage()
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
// update_icons() //Handled in update_transform(), leaving this here as a reminder
|
||||
update_transform()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that.
|
||||
/mob/living/carbon/alien/humanoid/update_transform(do_animate) //The old method of updating lying/standing was update_icons(). Aliens still expect that.
|
||||
if(lying > 0)
|
||||
lying = 90 //Anything else looks silly
|
||||
..()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/alien/larva/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/alien/larva/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
// GROW!
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
else
|
||||
icon_state = "larva[state]"
|
||||
|
||||
/mob/living/carbon/alien/larva/update_transform() //All this is handled in update_icons()
|
||||
/mob/living/carbon/alien/larva/update_transform(do_animate) //All this is handled in update_icons()
|
||||
..()
|
||||
return update_icons()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/alien/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/alien/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
findQueen()
|
||||
|
||||
@@ -90,10 +90,12 @@
|
||||
/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, toxins_type = TOX_DEFAULT)
|
||||
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER) && toxins_type != TOX_SYSCORRUPT) //damage becomes healing and healing becomes damage
|
||||
amount = -amount
|
||||
// don't allow toxinlover to push blood levels past BLOOD_VOLUME_MAXIMUM, but also don't set it back down to this if it's higher from something else
|
||||
var/blood_cap = blood_volume > BLOOD_VOLUME_MAXIMUM ? blood_volume : BLOOD_VOLUME_MAXIMUM
|
||||
if(amount > 0)
|
||||
blood_volume -= 3 * amount //5x was too much, this is punishing enough.
|
||||
blood_volume = min((blood_volume - (3 * amount)), blood_cap) //5x was too much, this is punishing enough.
|
||||
else
|
||||
blood_volume -= amount
|
||||
blood_volume = min((blood_volume - amount), blood_cap)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/getStaminaLoss()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
var/t_has = p_have()
|
||||
var/t_is = p_are()
|
||||
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>!")
|
||||
. = list("<span class='info'>This is [icon2html(src, user)] \a <EM>[src]</EM>!")
|
||||
|
||||
if (handcuffed)
|
||||
. += "<span class='warning'>[t_He] [t_is] [icon2html(handcuffed, user)] handcuffed!</span>"
|
||||
@@ -152,8 +152,11 @@
|
||||
. += "[t_He] look[p_s()] very happy."
|
||||
if(MOOD_LEVEL_HAPPY4 to INFINITY)
|
||||
. += "[t_He] look[p_s()] ecstatic."
|
||||
|
||||
if(LAZYLEN(.) > 1)
|
||||
.[2] = "<hr>[.[2]]"
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
||||
. += "*---------*</span>"
|
||||
|
||||
/mob/living/carbon/examine_more(mob/user)
|
||||
if(!all_scars)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
if(HAS_TRAIT(L, TRAIT_PROSOPAGNOSIA))
|
||||
obscure_name = TRUE
|
||||
|
||||
. = list("<span class='info'>*---------*\nThis is <EM>[!obscure_name ? name : "Unknown"]</EM>!")
|
||||
. = list("<span class='info'>This is <EM>[!obscure_name ? name : "Unknown"]</EM>!")
|
||||
|
||||
var/vampDesc = ReturnVampExamine(user) // Vamps recognize the names of other vamps.
|
||||
var/vassDesc = ReturnVassalExamine(user) // Vassals recognize each other's marks.
|
||||
@@ -442,9 +442,10 @@
|
||||
else if(isobserver(user) && traitstring)
|
||||
. += "<span class='info'><b>Traits:</b> [traitstring]</span>"
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now
|
||||
if(LAZYLEN(.) > 2) //Want this to appear after species text
|
||||
.[3] = "<hr>[.[3]]"
|
||||
|
||||
. += "*---------*</span>"
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now
|
||||
|
||||
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
|
||||
var/list/dat = list()
|
||||
|
||||
@@ -550,7 +550,7 @@
|
||||
to_chat(src, "<span class='notice'>You succesfuly remove the durathread strand.</span>")
|
||||
remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND)
|
||||
return
|
||||
var/to_send = ""
|
||||
var/to_send = "<blockquote class ='notice'>"
|
||||
visible_message("[src] examines [p_them()]self.", \
|
||||
"<span class='notice'>You check yourself for injuries.</span>")
|
||||
|
||||
@@ -597,27 +597,27 @@
|
||||
var/no_damage
|
||||
if(status == "OK" || status == "no damage")
|
||||
no_damage = TRUE
|
||||
to_send += "\t <span class='[no_damage ? "notice" : "warning"]'>Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].</span>\n"
|
||||
to_send += "<span class='[no_damage ? "notice" : "warning"]'>Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].</span>\n"
|
||||
|
||||
for(var/thing in LB.wounds)
|
||||
var/datum/wound/W = thing
|
||||
var/msg
|
||||
switch(W.severity)
|
||||
if(WOUND_SEVERITY_TRIVIAL)
|
||||
msg = "\t <span class='danger'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)].</span>"
|
||||
msg = "<span class='danger'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)].</span>"
|
||||
if(WOUND_SEVERITY_MODERATE)
|
||||
msg = "\t <span class='warning'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</span>"
|
||||
msg = "<span class='warning'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</span>"
|
||||
if(WOUND_SEVERITY_SEVERE)
|
||||
msg = "\t <span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</b></span>"
|
||||
msg = "<span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</b></span>"
|
||||
if(WOUND_SEVERITY_CRITICAL)
|
||||
msg = "\t <span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!</b></span>"
|
||||
msg = "<span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!</b></span>"
|
||||
to_chat(src, msg)
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
if(I.isEmbedHarmless())
|
||||
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] stuck to your [LB.name]!</a>")
|
||||
to_chat(src, "<a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] stuck to your [LB.name]!</a>")
|
||||
else
|
||||
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
|
||||
to_chat(src, "<a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
|
||||
|
||||
for(var/t in missing)
|
||||
to_send += "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>\n"
|
||||
@@ -724,6 +724,8 @@
|
||||
if(roundstart_quirks.len)
|
||||
to_send += "<span class='notice'>You have these quirks: [get_trait_string()].</span>\n"
|
||||
|
||||
to_send += "</blockquote>"
|
||||
|
||||
to_chat(src, to_send)
|
||||
else
|
||||
if(wear_suit)
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
FP.blood_DNA["color"] = S.last_blood_color
|
||||
else
|
||||
FP.blood_DNA["color"] = BlendRGB(FP.blood_DNA["color"], S.last_blood_color)
|
||||
FP.blood_DNA["blendmode"] = S.last_blood_blend
|
||||
FP.update_icon()
|
||||
update_inv_shoes()
|
||||
//End bloody footprints
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
currently_coiled.pixel_x = 12
|
||||
|
||||
/datum/action/innate/ability/coiling/proc/coil_mob(var/mob/living/carbon/human/H)
|
||||
if(currently_coiling)
|
||||
to_chat(owner, span_warning("You are already coiling someone!"))
|
||||
return
|
||||
|
||||
// begin the coiling action
|
||||
H.visible_message("<span class='warning'>[owner] coils [H] with their tail!</span>", \
|
||||
"<span class='userdanger'>[owner] coils you with their tail!</span>")
|
||||
@@ -58,6 +62,9 @@
|
||||
|
||||
/datum/action/innate/ability/coiling/proc/cancel_coil()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
|
||||
if(!currently_coiling)
|
||||
return
|
||||
|
||||
// cancel the coiling action by removing the overlay
|
||||
currently_coiled.pixel_x = 0
|
||||
|
||||
@@ -25,25 +25,21 @@
|
||||
/datum/action/innate/ability/limb_regrowth/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
var/list/limbs_to_heal = H.get_missing_limbs()
|
||||
if(limbs_to_heal.len < 1)
|
||||
to_chat(H, "<span class='notice'>You feel intact enough as it is.</span>")
|
||||
if(!length(limbs_to_heal))
|
||||
to_chat(H, span_notice("You feel intact enough as it is."))
|
||||
return
|
||||
to_chat(H, "<span class='notice'>You focus intently on your missing [limbs_to_heal.len >= 2 ? "limbs" : "limb"]...</span>")
|
||||
var/mode = H.get_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE)
|
||||
switch(mode)
|
||||
if(REGROWTH_USES_BLOOD)
|
||||
if(H.blood_volume >= 40*limbs_to_heal.len+(BLOOD_VOLUME_OKAY*H.blood_ratio))
|
||||
H.regenerate_limbs()
|
||||
H.blood_volume -= 40*limbs_to_heal.len
|
||||
to_chat(H, "<span class='notice'>...and after a moment you finish reforming!</span>")
|
||||
return
|
||||
else if(H.blood_volume >= 40)//We can partially heal some limbs
|
||||
while(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40)
|
||||
var/healed_limb = pick(limbs_to_heal)
|
||||
H.regenerate_limb(healed_limb)
|
||||
limbs_to_heal -= healed_limb
|
||||
H.blood_volume -= 40
|
||||
to_chat(H, "<span class='warning'>...but there is not enough of you to fix everything! You must attain more mass to heal completely!</span>")
|
||||
return
|
||||
to_chat(H, "<span class='warning'>...but there is not enough of you to go around! You must attain more mass to heal!</span>")
|
||||
|
||||
to_chat(H, span_notice("You focus intently on your missing [length(limbs_to_heal) >= 2 ? "limbs" : "limb"]..."))
|
||||
if(H.blood_volume >= 40*length(limbs_to_heal)+BLOOD_VOLUME_OKAY)
|
||||
H.regenerate_limbs()
|
||||
H.blood_volume -= 40*length(limbs_to_heal)
|
||||
to_chat(H, span_notice("...and after a moment you finish reforming!"))
|
||||
return
|
||||
else if(H.blood_volume >= 40)//We can partially heal some limbs
|
||||
while(H.blood_volume >= BLOOD_VOLUME_OKAY+40)
|
||||
var/healed_limb = pick(limbs_to_heal)
|
||||
H.regenerate_limb(healed_limb)
|
||||
limbs_to_heal -= healed_limb
|
||||
H.blood_volume -= 40
|
||||
to_chat(H, span_warning("...but there is not enough of you to fix everything! You must attain more mass to heal completely!"))
|
||||
return
|
||||
to_chat(H, span_warning("...but there is not enough of you to go around! You must attain more mass to heal!"))
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#define THERMAL_PROTECTION_HAND_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
|
||||
|
||||
/mob/living/carbon/human/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/human/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
handle_active_genes()
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
return
|
||||
|
||||
var/list/print_msg = list()
|
||||
print_msg += "<span class='info'>*---------*</span>"
|
||||
print_msg += "<span class='userdanger'>As you snap back to consciousness, you recall people messing with your stuff...</span>"
|
||||
print_msg += "<blockquote class='warning'>"
|
||||
|
||||
afk_thefts = reverseRange(afk_thefts)
|
||||
|
||||
@@ -22,13 +22,14 @@
|
||||
var/time_since = world.time - iter_theft[AFK_THEFT_TIME]
|
||||
|
||||
if(time_since > AFK_THEFT_FORGET_DETAILS_TIME)
|
||||
print_msg += "\t<span class='danger'><b>Someone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago.</b></span>"
|
||||
print_msg += "<span class='danger'><b>Someone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago.</b></span>"
|
||||
else
|
||||
print_msg += "\t<span class='danger'><b>[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago.</b></span>"
|
||||
print_msg += "<span class='danger'><b>[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago.</b></span>"
|
||||
|
||||
print_msg += "</blockquote>"
|
||||
|
||||
if(LAZYLEN(afk_thefts) >= AFK_THEFT_MAX_MESSAGES)
|
||||
print_msg += "<span class='warning'>There may have been more, but that's all you can remember...</span>"
|
||||
print_msg += "<span class='info'>*---------*</span>"
|
||||
|
||||
to_chat(src, print_msg.Join("\n"))
|
||||
LAZYNULL(afk_thefts)
|
||||
|
||||
@@ -65,6 +65,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/exotic_bloodtype = ""
|
||||
/// Assume human as the default blood colour, override this default by species subtypes
|
||||
var/exotic_blood_color = BLOOD_COLOR_HUMAN
|
||||
/// Which blend mode should this species blood use?
|
||||
var/exotic_blood_blend_mode = BLEND_MULTIPLY
|
||||
///What the species drops when gibbed by a gibber machine.
|
||||
var/meat = /obj/item/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing
|
||||
var/list/gib_types = list(/obj/effect/gibspawner/human, /obj/effect/gibspawner/human/bodypartless)
|
||||
@@ -826,13 +828,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/left_state = DEFAULT_LEFT_EYE_STATE
|
||||
var/right_state = DEFAULT_RIGHT_EYE_STATE
|
||||
if(eye_type in GLOB.eye_types)
|
||||
left_state = eye_type + "_left_eye"
|
||||
right_state = eye_type + "_right_eye"
|
||||
left_state = "[eye_type]_left_eye"
|
||||
right_state = "[eye_type]_right_eye"
|
||||
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER)
|
||||
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER)
|
||||
if((EYECOLOR in species_traits) && has_eyes)
|
||||
left_eye.color = "#" + H.left_eye_color
|
||||
right_eye.color = "#" + H.right_eye_color
|
||||
left_eye.color = "#[H.left_eye_color]"
|
||||
right_eye.color = "#[H.right_eye_color]"
|
||||
if(OFFSET_EYES in offset_features)
|
||||
left_eye.pixel_x += offset_features[OFFSET_EYES][1]
|
||||
left_eye.pixel_y += offset_features[OFFSET_EYES][2]
|
||||
@@ -2450,6 +2452,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
////////////////
|
||||
//Blood Stuff///
|
||||
////////////////
|
||||
// true = handle blood normally, false = do not (and then handle blood in this proc instead please!!)
|
||||
/datum/species/proc/handle_blood(mob/living/carbon/human/H, delta_time, times_fired)
|
||||
return TRUE
|
||||
|
||||
////////////////
|
||||
//Tail Wagging//
|
||||
////////////////
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
exotic_blood = /datum/reagent/blood/jellyblood
|
||||
exotic_bloodtype = "GEL"
|
||||
exotic_blood_color = "BLOOD_COLOR_SLIME"
|
||||
exotic_blood_blend_mode = BLEND_DEFAULT
|
||||
damage_overlay_type = ""
|
||||
liked_food = TOXIC | MEAT
|
||||
disliked_food = null
|
||||
@@ -31,6 +32,7 @@
|
||||
species_category = SPECIES_CATEGORY_JELLY
|
||||
wings_icons = SPECIES_WINGS_JELLY
|
||||
ass_image = 'icons/ass/assslime.png'
|
||||
blacklisted_quirks = list(/datum/quirk/glass_bones)
|
||||
|
||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||
C.faction -= "slime"
|
||||
@@ -53,38 +55,46 @@
|
||||
//update blood color to body color
|
||||
exotic_blood_color = "#" + H.dna.features["mcolor"]
|
||||
|
||||
/datum/species/jelly/spec_life(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD || HAS_TRAIT(H, TRAIT_NOMARROW)) //can't farm slime jelly from a dead slime/jelly person indefinitely, and no regeneration for bloodsuckers
|
||||
return
|
||||
if(!H.blood_volume)
|
||||
H.adjust_integration_blood(5)
|
||||
H.adjustBruteLoss(5)
|
||||
to_chat(H, "<span class='danger'>You feel empty!</span>")
|
||||
/datum/species/jelly/handle_blood(mob/living/carbon/human/H, delta_time, times_fired)
|
||||
if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely
|
||||
return TRUE // we dont handle blood when dead
|
||||
|
||||
if(H.blood_volume < (BLOOD_VOLUME_NORMAL * H.blood_ratio))
|
||||
if(H.blood_volume <= 0)
|
||||
H.blood_volume += 2.5 * delta_time
|
||||
H.adjustBruteLoss(2.5 * delta_time)
|
||||
to_chat(H, span_danger("You feel empty!"))
|
||||
|
||||
if(H.blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
if(H.nutrition >= NUTRITION_LEVEL_STARVING)
|
||||
H.adjust_integration_blood(3)
|
||||
H.nutrition -= 2.5
|
||||
if(H.blood_volume < (BLOOD_VOLUME_OKAY*H.blood_ratio))
|
||||
if(prob(5))
|
||||
to_chat(H, "<span class='danger'>You feel drained!</span>")
|
||||
if(H.blood_volume < (BLOOD_VOLUME_BAD*H.blood_ratio))
|
||||
H.blood_volume += 1.5 * delta_time
|
||||
H.adjust_nutrition(-1.25 * delta_time)
|
||||
|
||||
if(H.blood_volume < BLOOD_VOLUME_OKAY)
|
||||
if(DT_PROB(2.5, delta_time))
|
||||
to_chat(H, span_danger("You feel drained!"))
|
||||
|
||||
if(H.blood_volume < BLOOD_VOLUME_BAD)
|
||||
Cannibalize_Body(H)
|
||||
..()
|
||||
|
||||
var/datum/action/innate/ability/regrowth = H.ability_actions[INNATE_ABILITY_LIMB_REGROWTH]
|
||||
if(regrowth)
|
||||
regrowth.UpdateButtonIcon()
|
||||
|
||||
return FALSE // to let living/handle_blood know that the species is handling blood instead
|
||||
|
||||
/datum/species/jelly/proc/Cannibalize_Body(mob/living/carbon/human/H)
|
||||
var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs()
|
||||
var/obj/item/bodypart/consumed_limb
|
||||
if(!limbs_to_consume.len)
|
||||
if(!length(limbs_to_consume))
|
||||
H.losebreath++
|
||||
return
|
||||
if(H.get_num_legs(FALSE)) //Legs go before arms
|
||||
limbs_to_consume -= list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM)
|
||||
consumed_limb = H.get_bodypart(pick(limbs_to_consume))
|
||||
consumed_limb.drop_limb()
|
||||
to_chat(H, "<span class='userdanger'>Your [consumed_limb] is drawn back into your body, unable to maintain its shape!</span>")
|
||||
to_chat(H, span_userdanger("Your [consumed_limb] is drawn back into your body, unable to maintain its shape!"))
|
||||
qdel(consumed_limb)
|
||||
H.adjust_integration_blood(20)
|
||||
H.blood_volume += 20
|
||||
|
||||
////////////////////////////////////////////////////////SLIMEPEOPLE///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
wings_icons = SPECIES_WINGS_SKELETAL
|
||||
|
||||
ass_image = 'icons/ass/assplasma.png'
|
||||
blacklisted_quirks = list(/datum/quirk/paper_skin)
|
||||
|
||||
/datum/species/plasmaman/spec_life(mob/living/carbon/human/H)
|
||||
var/datum/gas_mixture/environment = H.loc.return_air()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
species_category = SPECIES_CATEGORY_SKELETON //they have their own category that's disassociated from undead, paired with plasmapeople
|
||||
wings_icons = SPECIES_WINGS_SKELETAL
|
||||
blacklisted_quirks = list(/datum/quirk/paper_skin)
|
||||
|
||||
/datum/species/skeleton/New()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) //skeletons are stronger during the spooky season!
|
||||
|
||||
@@ -209,7 +209,7 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(!gloves && bloody_hands)
|
||||
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color())
|
||||
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
||||
if(get_num_arms(FALSE) < 2)
|
||||
if(has_left_hand(FALSE))
|
||||
bloody_overlay.icon_state = "bloodyhands_left"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/carbon/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/BiologicalLife(delta_time, times_fired)
|
||||
//Reagent processing needs to come before breathing, to prevent edge cases.
|
||||
handle_organs(seconds, times_fired)
|
||||
handle_organs(delta_time, times_fired)
|
||||
. = ..() // if . is false, we are dead.
|
||||
if(stat == DEAD)
|
||||
stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
@@ -9,7 +9,7 @@
|
||||
. = FALSE
|
||||
if(!.)
|
||||
return
|
||||
handle_blood()
|
||||
handle_blood(delta_time, times_fired)
|
||||
// handle_blood *could* kill us.
|
||||
// we should probably have a better system for if we need to check for death or something in the future hmw
|
||||
if(stat != DEAD)
|
||||
@@ -23,7 +23,7 @@
|
||||
handle_brain_damage()
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_liver(seconds, times_fired)
|
||||
handle_liver(delta_time, times_fired)
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_corruption()
|
||||
@@ -375,7 +375,7 @@
|
||||
|
||||
miasma_turf.air_update_turf()
|
||||
|
||||
/mob/living/carbon/proc/handle_blood()
|
||||
/mob/living/carbon/proc/handle_blood(delta_time, times_fired)
|
||||
return
|
||||
|
||||
/mob/living/carbon/proc/handle_bodyparts(seconds, times_fired)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/mob/living/carbon/monkey
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/monkey/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(client)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
if(relic_mask)
|
||||
equip_to_slot_or_del(new relic_mask, ITEM_SLOT_MASK)
|
||||
|
||||
/mob/living/carbon/monkey/punpun/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/carbon/monkey/punpun/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
@@ -46,6 +46,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Read_Memory()
|
||||
var/saved_color
|
||||
if(fexists("data/npc_saves/Punpun.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
|
||||
S["ancestor_name"] >> ancestor_name
|
||||
@@ -62,6 +63,9 @@
|
||||
ancestor_chain = json["ancestor_chain"]
|
||||
relic_hat = json["relic_hat"]
|
||||
relic_mask = json["relic_hat"]
|
||||
saved_color = json["color"]
|
||||
if(!isnull(saved_color))
|
||||
add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed)
|
||||
var/json_file = file("data/npc_saves/Punpun.json")
|
||||
@@ -71,10 +75,12 @@
|
||||
file_data["ancestor_chain"] = null
|
||||
file_data["relic_hat"] = null
|
||||
file_data["relic_mask"] = null
|
||||
file_data["color"] = null
|
||||
else
|
||||
file_data["ancestor_name"] = ancestor_name ? ancestor_name : name
|
||||
file_data["ancestor_chain"] = dead ? ancestor_chain + 1 : ancestor_chain
|
||||
file_data["relic_hat"] = head ? head.type : null
|
||||
file_data["relic_mask"] = wear_mask ? wear_mask.type : null
|
||||
file_data["color"] = color ? json_encode(color) : null
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
@@ -518,6 +518,8 @@
|
||||
|
||||
/datum/emote/living/circle/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/obj/item/circlegame/N = new(user)
|
||||
if(user.put_in_hands(N))
|
||||
to_chat(user, "<span class='notice'>You make a circle with your hand.</span>")
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
* Handles biological life processes like chemical metabolism, breathing, etc
|
||||
* Returns TRUE or FALSE based on if we were interrupted. This is used by overridden variants to check if they should stop.
|
||||
*/
|
||||
/mob/living/proc/BiologicalLife(seconds, times_fired)
|
||||
SEND_SIGNAL(src,COMSIG_LIVING_BIOLOGICAL_LIFE, seconds, times_fired)
|
||||
/mob/living/proc/BiologicalLife(delta_time, times_fired)
|
||||
SEND_SIGNAL(src,COMSIG_LIVING_BIOLOGICAL_LIFE, delta_time, times_fired)
|
||||
handle_diseases()// DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not.
|
||||
|
||||
handle_wounds()
|
||||
@@ -67,7 +67,7 @@
|
||||
//stuff in the stomach
|
||||
handle_stomach()
|
||||
|
||||
handle_block_parry(seconds)
|
||||
handle_block_parry(delta_time)
|
||||
|
||||
handle_traits() // eye, ear, brain damages
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
|
||||
//Called when we bump onto a mob
|
||||
/mob/living/proc/MobBump(mob/M)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_MOB_BUMP, M)
|
||||
//Even if we don't push/swap places, we "touched" them, so spread fire
|
||||
spreadFire(M)
|
||||
|
||||
@@ -88,6 +89,7 @@
|
||||
return TRUE
|
||||
|
||||
var/they_can_move = TRUE
|
||||
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
they_can_move = CHECK_MOBILITY(L, MOBILITY_MOVE)
|
||||
@@ -105,16 +107,16 @@
|
||||
//Should stop you pushing a restrained person out of the way
|
||||
if(L.pulledby && L.pulledby != src && L.restrained())
|
||||
if(!(world.time % 5))
|
||||
to_chat(src, "<span class='warning'>[L] is restrained, you cannot push past.</span>")
|
||||
return 1
|
||||
to_chat(src, span_warning("[L] is restrained, you cannot push past."))
|
||||
return TRUE
|
||||
|
||||
if(L.pulling)
|
||||
if(ismob(L.pulling))
|
||||
var/mob/P = L.pulling
|
||||
if(P.restrained())
|
||||
if(!(world.time % 5))
|
||||
to_chat(src, "<span class='warning'>[L] is restraining [P], you cannot push past.</span>")
|
||||
return 1
|
||||
to_chat(src, span_warning("[L] is restraining [P], you cannot push past."))
|
||||
return TRUE
|
||||
|
||||
//CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks or over prone bodies without a short delay
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
@@ -142,7 +144,7 @@
|
||||
//END OF CIT CHANGES
|
||||
|
||||
if(moving_diagonally)//no mob swap during diagonal moves.
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(!M.buckled && !M.has_buckled_mobs())
|
||||
var/mob_swap = FALSE
|
||||
@@ -151,7 +153,8 @@
|
||||
if(!too_strong)
|
||||
mob_swap = TRUE
|
||||
else
|
||||
if(M.pulledby == src && a_intent == INTENT_GRAB)
|
||||
//You can swap with the person you are dragging on grab intent, and restrained people in most cases
|
||||
if(M.pulledby == src && !too_strong)
|
||||
mob_swap = TRUE
|
||||
//restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller
|
||||
else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
|
||||
@@ -159,8 +162,8 @@
|
||||
if(mob_swap)
|
||||
//switch our position with M
|
||||
if(loc && !loc.Adjacent(M.loc))
|
||||
return 1
|
||||
now_pushing = 1
|
||||
return TRUE
|
||||
now_pushing = TRUE
|
||||
var/oldloc = loc
|
||||
var/oldMloc = M.loc
|
||||
|
||||
@@ -180,27 +183,31 @@
|
||||
if(!M_passmob)
|
||||
M.pass_flags &= ~PASSMOB
|
||||
|
||||
now_pushing = 0
|
||||
now_pushing = FALSE
|
||||
|
||||
if(!move_failed)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//okay, so we didn't switch. but should we push?
|
||||
//not if he's not CANPUSH of course
|
||||
if(!(M.status_flags & CANPUSH))
|
||||
return 1
|
||||
return TRUE
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
if(HAS_TRAIT(L, TRAIT_PUSHIMMUNE))
|
||||
return 1
|
||||
//If they're a human, and they're not in help intent, block pushing
|
||||
if(ishuman(M) && (M.a_intent != INTENT_HELP))
|
||||
return TRUE
|
||||
return TRUE
|
||||
if(M.a_intent != INTENT_HELP)
|
||||
//If they're a human, and they're not in help intent, block pushing
|
||||
if(ishuman(M))
|
||||
return TRUE
|
||||
//if they are a cyborg, and they're alive and not in help intent, block pushing
|
||||
if(iscyborg(M) && M.stat != DEAD)
|
||||
return TRUE
|
||||
//anti-riot equipment is also anti-push
|
||||
for(var/obj/item/I in M.held_items)
|
||||
if(!istype(M, /obj/item/clothing))
|
||||
if(prob(I.block_chance*2))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/get_photo_description(obj/item/camera/camera)
|
||||
var/list/mob_details = list()
|
||||
@@ -231,21 +238,40 @@
|
||||
if(!client && (mob_size < MOB_SIZE_SMALL))
|
||||
return
|
||||
now_pushing = TRUE
|
||||
var/t = get_dir(src, AM)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_MOVABLE, AM)
|
||||
var/dir_to_target = get_dir(src, AM)
|
||||
|
||||
// If there's no dir_to_target then the player is on the same turf as the atom they're trying to push.
|
||||
// This can happen when a player is stood on the same turf as a directional window. All attempts to push
|
||||
// the window will fail as get_dir will return 0 and the player will be unable to move the window when
|
||||
// it should be pushable.
|
||||
// In this scenario, we will use the facing direction of the /mob/living attempting to push the atom as
|
||||
// a fallback.
|
||||
if(!dir_to_target)
|
||||
dir_to_target = dir
|
||||
|
||||
var/push_anchored = FALSE
|
||||
if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force)
|
||||
if(move_crush(AM, move_force, t))
|
||||
if(move_crush(AM, move_force, dir_to_target))
|
||||
push_anchored = TRUE
|
||||
if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
|
||||
if(force_push(AM, move_force, t, push_anchored))
|
||||
if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
|
||||
if(force_push(AM, move_force, dir_to_target, push_anchored))
|
||||
push_anchored = TRUE
|
||||
if(ismob(AM))
|
||||
var/mob/mob_to_push = AM
|
||||
var/atom/movable/mob_buckle = mob_to_push.buckled
|
||||
// If we can't pull them because of what they're buckled to, make sure we can push the thing they're buckled to instead.
|
||||
// If neither are true, we're not pushing anymore.
|
||||
if(mob_buckle && (mob_buckle.buckle_prevents_pull || (force < (mob_buckle.move_resist * MOVE_FORCE_PUSH_RATIO))))
|
||||
now_pushing = FALSE
|
||||
return
|
||||
if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO)))
|
||||
now_pushing = FALSE
|
||||
return
|
||||
if (istype(AM, /obj/structure/window))
|
||||
if(istype(AM, /obj/structure/window))
|
||||
var/obj/structure/window/W = AM
|
||||
if(W.fulltile)
|
||||
for(var/obj/structure/window/win in get_step(W,t))
|
||||
for(var/obj/structure/window/win in get_step(W, dir_to_target))
|
||||
now_pushing = FALSE
|
||||
return
|
||||
if(pulling == AM)
|
||||
@@ -253,8 +279,9 @@
|
||||
var/current_dir
|
||||
if(isliving(AM))
|
||||
current_dir = AM.dir
|
||||
if(step(AM, t) && Process_Spacemove(t))
|
||||
step(src, t)
|
||||
if(AM.Move(get_step(AM.loc, dir_to_target), dir_to_target, glide_size))
|
||||
AM.add_fingerprint(src)
|
||||
Move(get_step(loc, dir_to_target), dir_to_target)
|
||||
if(current_dir)
|
||||
AM.setDir(current_dir)
|
||||
now_pushing = FALSE
|
||||
@@ -354,29 +381,33 @@
|
||||
offset = GRAB_PIXEL_SHIFT_NECK
|
||||
if(GRAB_KILL)
|
||||
offset = GRAB_PIXEL_SHIFT_NECK
|
||||
M.setDir(get_dir(M, src))
|
||||
switch(M.dir)
|
||||
if(NORTH)
|
||||
animate(M, pixel_x = 0, pixel_y = offset, 3)
|
||||
if(SOUTH)
|
||||
animate(M, pixel_x = 0, pixel_y = -offset, 3)
|
||||
if(EAST)
|
||||
if(M.lying == 270) //update the dragged dude's direction if we've turned
|
||||
M.lying = 90
|
||||
M.update_transform() //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so
|
||||
M.lying_prev = M.lying
|
||||
animate(M, pixel_x = offset, pixel_y = 0, 3)
|
||||
if(WEST)
|
||||
if(M.lying == 90)
|
||||
M.lying = 270
|
||||
M.update_transform()
|
||||
M.lying_prev = M.lying
|
||||
animate(M, pixel_x = -offset, pixel_y = 0, 3)
|
||||
var/target_dir = get_dir(M, src)
|
||||
M.setDir(target_dir)
|
||||
var/target_x
|
||||
var/target_y
|
||||
if(target_dir & NORTH)
|
||||
target_y += offset
|
||||
if(target_dir & SOUTH)
|
||||
target_y -= offset
|
||||
if(target_dir & EAST)
|
||||
target_x += offset
|
||||
if(target_dir & WEST)
|
||||
target_x -= offset
|
||||
if(target_x || target_y)
|
||||
if(0 < target_x && M.lying == 270)
|
||||
M.lying = 90
|
||||
M.update_transform(FALSE) //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so
|
||||
M.lying_prev = M.lying
|
||||
if(0 > target_x && M.lying == 90)
|
||||
M.lying = 270
|
||||
M.update_transform(FALSE)
|
||||
M.lying_prev = M.lying
|
||||
animate(M, pixel_x = target_x, pixel_y = target_y, time = 3, flags = ANIMATION_PARALLEL)
|
||||
|
||||
/mob/living/proc/reset_pull_offsets(mob/living/M, override)
|
||||
if(!override && M.buckled)
|
||||
return
|
||||
animate(M, pixel_x = 0, pixel_y = 0, 1)
|
||||
animate(M, pixel_x = 0, pixel_y = 0, time = 3, flags = ANIMATION_PARALLEL)
|
||||
|
||||
//mob verbs are a lot faster than object verbs
|
||||
//for more info on why this is not atom/pull, see examinate() in mob.dm
|
||||
@@ -885,12 +916,11 @@
|
||||
if(anchored || (buckled && buckled.anchored))
|
||||
fixed = 1
|
||||
if(on && !(movement_type & FLOATING) && !fixed)
|
||||
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
|
||||
sleep(10)
|
||||
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
|
||||
animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
setMovetype(movement_type | FLOATING)
|
||||
else if(((!on || fixed) && (movement_type & FLOATING)))
|
||||
animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10)
|
||||
animate(src, pixel_z = get_standard_pixel_y_offset(lying), time = 10)
|
||||
setMovetype(movement_type & ~FLOATING)
|
||||
|
||||
// The src mob is trying to strip an item from someone
|
||||
@@ -989,7 +1019,7 @@
|
||||
var/pixel_y_diff = rand(-amplitude/3, amplitude/3)
|
||||
var/final_pixel_x = get_standard_pixel_x_offset(lying)
|
||||
var/final_pixel_y = get_standard_pixel_y_offset(lying)
|
||||
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6)
|
||||
animate(src, pixel_x = pixel_x_diff, pixel_y = pixel_y_diff , time = 2, loop = 6, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE)
|
||||
animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2)
|
||||
floating_need_update = TRUE
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
/mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) //parent calls can't overwrite the current proc args.
|
||||
if(!client)
|
||||
if(!client && !audiovisual_redirect)
|
||||
return
|
||||
var/deaf_message
|
||||
var/deaf_type
|
||||
@@ -297,8 +297,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
AM.Hear(rendered, src, message_language, message, null, spans, message_mode, source)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message)
|
||||
|
||||
if(client && !eavesdrop_range && say_test(message) == "2") // Yell hook
|
||||
process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source)
|
||||
var/is_yell = (say_test(message) == "2")
|
||||
if(client && !eavesdrop_range && is_yell) // Yell hook
|
||||
listening |= process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source)
|
||||
|
||||
//speech bubble
|
||||
var/list/speech_bubble_recipients = list()
|
||||
@@ -309,6 +310,23 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30)
|
||||
|
||||
//Listening gets trimmed here if a vocal bark's present. If anyone ever makes this proc return listening, make sure to instead initialize a copy of listening in here to avoid wonkiness
|
||||
if(SEND_SIGNAL(src, COMSIG_MOVABLE_QUEUE_BARK, listening, args) || vocal_bark || vocal_bark_id)
|
||||
for(var/mob/M in listening)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(!(M.client.prefs.toggles & SOUND_BARK))
|
||||
listening -= M
|
||||
var/barks = min(round((LAZYLEN(message) / vocal_speed)) + 1, BARK_MAX_BARKS)
|
||||
var/total_delay
|
||||
vocal_current_bark = world.time
|
||||
for(var/i in 1 to barks)
|
||||
if(total_delay > BARK_MAX_TIME)
|
||||
break
|
||||
addtimer(CALLBACK(src, /atom/movable/proc/bark, listening, (message_range * (is_yell ? 4 : 1)), (vocal_volume * (is_yell ? 1.5 : 1)), BARK_DO_VARY(vocal_pitch, vocal_pitch_range), vocal_current_bark), total_delay)
|
||||
total_delay += rand(DS2TICKS(vocal_speed / BARK_SPEED_BASELINE), DS2TICKS(vocal_speed / BARK_SPEED_BASELINE) + DS2TICKS((vocal_speed / BARK_SPEED_BASELINE) * (is_yell ? 0.5 : 1))) TICKS
|
||||
|
||||
|
||||
/atom/movable/proc/process_yelling(list/already_heard, rendered, atom/movable/speaker, datum/language/message_language, message, list/spans, message_mode, obj/source)
|
||||
if(last_yell > (world.time - 10))
|
||||
to_chat(src, "<span class='warning'>Your voice doesn't project as far as you try to yell in such quick succession.") // yeah no, no spamming an expensive floodfill.
|
||||
@@ -333,6 +351,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
var/atom/movable/AM = _AM
|
||||
AM.Hear(rendered, speaker, message_language, message, null, spans, message_mode, source)
|
||||
|
||||
return overhearing
|
||||
|
||||
/mob/proc/binarycheck()
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
var/mob/living/simple_animal/bot/Bot
|
||||
var/tracking = FALSE //this is 1 if the AI is currently tracking somebody, but the track has not yet been completed.
|
||||
var/datum/effect_system/spark_spread/spark_system//So they can initialize sparks whenever/N
|
||||
var/obj/machinery/status_display/controlled_display
|
||||
|
||||
//MALFUNCTION
|
||||
var/datum/module_picker/malf_picker
|
||||
@@ -660,7 +661,7 @@
|
||||
"goat" = 'icons/mob/animal.dmi',
|
||||
"cat" = 'icons/mob/pets.dmi',
|
||||
"cat2" = 'icons/mob/pets.dmi',
|
||||
"poly" = 'icons/mob/animal.dmi',
|
||||
"polly" = 'icons/mob/animal.dmi',
|
||||
"pug" = 'icons/mob/pets.dmi',
|
||||
"spider" = 'icons/mob/animal.dmi'
|
||||
)
|
||||
@@ -669,7 +670,7 @@
|
||||
if(input)
|
||||
qdel(holo_icon)
|
||||
switch(input)
|
||||
if("poly")
|
||||
if("polly")
|
||||
holo_icon = getHologramIcon(icon(icon_list[input],"parrot_fly"))
|
||||
if("chicken")
|
||||
holo_icon = getHologramIcon(icon(icon_list[input],"chicken_brown"))
|
||||
@@ -1043,3 +1044,14 @@
|
||||
|
||||
/mob/living/silicon/ai/zMove(dir, feedback = FALSE)
|
||||
. = eyeobj.zMove(dir, feedback)
|
||||
|
||||
/mob/living/silicon/ai/proc/stop_controlling_display()
|
||||
if(!controlled_display)
|
||||
return
|
||||
controlled_display.master = null
|
||||
controlled_display.cut_overlay(controlled_display.ai_vtuber_overlay)
|
||||
controlled_display.ai_vtuber_overlay = null
|
||||
if(current == controlled_display)
|
||||
current = null
|
||||
controlled_display.update_appearance()
|
||||
controlled_display = null
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/silicon/ai/examine(mob/user)
|
||||
. = list("<span class='info'>*---------*\nThis is [icon2html(src, user)] <EM>[src]</EM>!")
|
||||
. = list("<span class='info'>This is [icon2html(src, user)] <EM>[src]</EM>!")
|
||||
if (stat == DEAD)
|
||||
. += "<span class='deadsay'>It appears to be powered-down.</span>"
|
||||
else
|
||||
@@ -17,6 +17,8 @@
|
||||
. += "The wireless networking light is blinking."
|
||||
else if (!shunted && !client)
|
||||
. += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem..."
|
||||
. += "*---------*</span>"
|
||||
|
||||
if(LAZYLEN(.) > 1)
|
||||
.[2] = "<hr>[.[2]]"
|
||||
|
||||
. += ..()
|
||||
|
||||
@@ -92,6 +92,8 @@
|
||||
ai.light_cameras()
|
||||
if(ai.master_multicam)
|
||||
ai.master_multicam.refresh_view()
|
||||
if(ai.controlled_display)
|
||||
ai.stop_controlling_display()
|
||||
|
||||
//it uses setLoc not forceMove, talks to the sillycone and not the camera mob
|
||||
/mob/camera/aiEye/zMove(dir, feedback = FALSE)
|
||||
@@ -168,6 +170,9 @@
|
||||
if(!user.tracking)
|
||||
user.cameraFollow = null
|
||||
|
||||
if(user.controlled_display)
|
||||
user.stop_controlling_display()
|
||||
|
||||
// Return to the Core.
|
||||
/mob/living/silicon/ai/proc/view_core()
|
||||
if(istype(current,/obj/machinery/holopad))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user