Merge branch 'master' into update-smooth-movement

This commit is contained in:
deathride58
2022-06-05 00:45:45 -04:00
committed by GitHub
118 changed files with 1620 additions and 816 deletions
+3
View File
@@ -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
-6
View File
@@ -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)
+39 -28
View File
@@ -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,6 +129,7 @@
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
@@ -134,6 +153,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 +161,7 @@
name = "Hyper-noblium"
gas_overlay = "freon"
moles_visible = MOLES_GAS_VISIBLE
price = 50
/datum/gas/hydrogen
id = GAS_HYDROGEN
@@ -168,6 +189,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 +198,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
@@ -202,6 +209,7 @@
name = "Miasma"
gas_overlay = "miasma"
moles_visible = MOLES_GAS_VISIBLE * 60
price = 2
/datum/gas/methane
id = GAS_METHANE
@@ -227,6 +235,7 @@
)
enthalpy = -74600
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
price = 1
/datum/gas/methyl_bromide
id = GAS_METHYL_BROMIDE
@@ -249,6 +258,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 +295,4 @@
powermix = -1
transmit_modifier = -10
heat_penalty = -10
price = 10
@@ -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)
+3 -7
View File
@@ -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
-4
View File
@@ -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
+7 -16
View File
@@ -867,10 +867,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 +880,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 +901,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)
+4 -4
View File
@@ -404,7 +404,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
@@ -413,7 +413,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
@@ -423,7 +423,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
@@ -1714,7 +1714,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
+307 -309
View File
@@ -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 54
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -72,15 +72,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 +173,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 +196,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 +346,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 +390,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 +471,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 +673,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 +688,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 +766,88 @@ 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.
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 +867,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 +937,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 +961,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 +1009,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 +1022,7 @@ 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))
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 +1030,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)
+1 -1
View File
@@ -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()
..()
+1 -1
View File
@@ -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()
..()
+1 -1
View File
@@ -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."
+1 -1
View File
@@ -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"
+3 -1
View File
@@ -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)
. = ..()
+1 -1
View File
@@ -20,7 +20,7 @@
. += 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
+1 -1
View File
@@ -29,7 +29,7 @@
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())
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
if(accessory_overlay)
. += accessory_overlay
+11 -3
View File
@@ -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)
+14 -1
View File
@@ -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)
+26 -123
View File
@@ -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()
+2 -1
View File
@@ -193,6 +193,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 +265,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"),
@@ -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
@@ -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)
@@ -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"
@@ -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"
@@ -925,8 +925,8 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
/mob/living/simple_animal/parrot/Poly/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
. = ..()
if(. && !client && prob(1) && prob(1)) //Only the one true bird may speak across dimensions.
world.TgsTargetedChatBroadcast("A stray squawk is heard... \"[message]\"", FALSE)
if(. && !client && prob(1) && prob(1) && CONFIG_GET(string/chat_squawk_tag)) //Only the one true bird may speak across dimensions.
send2chat("A stray squawk is heard... \"[message]\"", CONFIG_GET(string/chat_squawk_tag))
/mob/living/simple_animal/parrot/Poly/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
@@ -1,5 +1,5 @@
/datum/reagent/blood
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null,"quirks"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "bloodblend" = BLEND_MULTIPLY, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null,"quirks"=null)
name = "Blood"
chemical_flags = REAGENT_ALL_PROCESS
value = REAGENT_VALUE_UNCOMMON // $$$ blood ""donations"" $$$
@@ -81,6 +81,7 @@
B.blood_DNA["color"] = data["bloodcolor"]
else
B.blood_DNA["color"] = BlendRGB(B.blood_DNA["color"], data["bloodcolor"])
B.blood_DNA["blendmode"] = data["bloodblend"]
if(B.reagents)
B.reagents.add_reagent(type, reac_volume)
B.update_icon()
@@ -148,7 +149,7 @@
. += D
/datum/reagent/blood/synthetics
data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "bloodblend" = BLEND_MULTIPLY, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Synthetic Blood"
description = "A synthetically produced imitation of blood."
taste_description = "oil"
@@ -156,7 +157,7 @@
value = REAGENT_VALUE_NONE
/datum/reagent/blood/jellyblood
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "bloodblend" = BLEND_DEFAULT, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Slime Jelly Blood"
description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL."
color = BLOOD_COLOR_SLIME
@@ -165,7 +166,7 @@
pH = 4
/datum/reagent/blood/tomato
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "bloodblend" = BLEND_MULTIPLY, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Tomato Blood"
description = "This highly resembles blood, but it doesnt actually function like it, resembling more ketchup, with a more blood-like consistency."
taste_description = "sap" //Like tree sap?
@@ -189,7 +190,7 @@
description = "You don't even want to think about what's in here."
taste_description = "gross iron"
shot_glass_icon_state = "shotglassred"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "bloodblend" = BLEND_MULTIPLY, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 7.45
/datum/reagent/liquidgibs/xeno
@@ -197,7 +198,7 @@
color = BLOOD_COLOR_XENO
taste_description = "blended heresy"
shot_glass_icon_state = "shotglassgreen"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "bloodblend" = BLEND_MULTIPLY, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 2.5
/datum/reagent/liquidgibs/slime
@@ -205,20 +206,20 @@
color = BLOOD_COLOR_SLIME
taste_description = "slime"
shot_glass_icon_state = "shotglassgreen"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "bloodblend" = BLEND_DEFAULT, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 4
/datum/reagent/liquidgibs/synth
name = "Synthetic sludge"
color = BLOOD_COLOR_SYNTHETIC
taste_description = "jellied plastic"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "bloodblend" = BLEND_MULTIPLY, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
/datum/reagent/liquidgibs/oil
name = "Hydraulic sludge"
color = BLOOD_COLOR_OIL
taste_description = "chunky burnt oil"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "bloodblend" = BLEND_MULTIPLY, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 9.75
/datum/reagent/vaccine
@@ -13,7 +13,7 @@
/obj/item/reagent_containers/blood/Initialize(mapload)
. = ..()
if(blood_type != null)
reagents.add_reagent(/datum/reagent/blood, 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"bloodcolor"=bloodtype_to_color(blood_type), "blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
reagents.add_reagent(/datum/reagent/blood, 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"bloodcolor"=bloodtype_to_color(blood_type), "bloodblend" = BLEND_MULTIPLY, "blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
update_icon()
/obj/item/reagent_containers/blood/on_reagent_change(changetype)
+1 -1
View File
@@ -103,7 +103,7 @@
return
account.adjust_money(-deposit_value) //The money vanishes, not paid to any accounts.
SSblackbox.record_feedback("amount", "BEPIS_credits_spent", deposit_value)
//log_econ("[deposit_value] credits were inserted into [src] by [account.account_holder]")
log_econ("[deposit_value] credits were inserted into [src] by [key_name(usr)] (account: [account.account_holder])")
banked_cash += deposit_value
use_power(1000 * power_saver)
say("Cash deposit successful. There is [banked_cash] in the chamber.")
+10 -1
View File
@@ -228,6 +228,8 @@
var/mangled_state = get_mangled_state()
var/bio_state = owner.get_biological_state()
var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%)
var/glass_bones = HAS_TRAIT(owner, TRAIT_GLASS_BONES)
var/paper_skin = HAS_TRAIT(owner, TRAIT_PAPER_SKIN)
if(wounding_type == WOUND_BLUNT)
if(sharpness == SHARP_EDGED)
@@ -242,22 +244,29 @@
if(wounding_type == WOUND_SLASH)
wounding_type = WOUND_BLUNT
wounding_dmg *= (easy_dismember ? 1 : 0.5)
wounding_dmg *= (glass_bones ? 1.5 : 1)
else if(wounding_type == WOUND_PIERCE)
wounding_type = WOUND_BLUNT
wounding_dmg *= (easy_dismember ? 1 : 0.75)
wounding_dmg *= (glass_bones ? 1.5 : 1)
if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
return
// if we're flesh only, all blunt attacks become weakened slashes in terms of wound damage
if(BIO_JUST_FLESH)
if(wounding_type == WOUND_BLUNT)
wounding_type = WOUND_SLASH
wounding_dmg *= (easy_dismember ? 1 : 0.3)
wounding_dmg *= (easy_dismember ? 1 : 0.5)
wounding_dmg *= (paper_skin ? 1.5 : 1)
if((mangled_state & BODYPART_MANGLED_FLESH) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
return
// standard humanoids
if(BIO_FLESH_BONE)
// if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate
// So a big sharp weapon is still all you need to destroy a limb
if(wounding_type == WOUND_SLASH || wounding_type == WOUND_PIERCE)
wounding_dmg *= (paper_skin ? 1.5 : 1)
else
wounding_dmg *= (glass_bones ? 1.5 : 1)
if(mangled_state == BODYPART_MANGLED_FLESH && sharpness)
playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
if(wounding_type == WOUND_SLASH && !easy_dismember)
+9 -4
View File
@@ -18,10 +18,9 @@
// to hear anything.
var/deaf = 0
// `ear_damage` measures long term damage to the ears, if too high,
// `damage` in this case measures long term damage to the ears, if too high,
// the person will not have either `deaf` or `ear_damage` decrease
// without external aid (earmuffs, drugs)
var/ear_damage = 0
//Resistance against loud noises
var/bang_protect = 0
@@ -44,16 +43,22 @@
/obj/item/organ/ears/proc/restoreEars()
deaf = 0
ear_damage = 0
damage = 0
prev_damage = 0
organ_flags &= ~ORGAN_FAILING
var/mob/living/carbon/C = owner
if(iscarbon(owner) && HAS_TRAIT(C, TRAIT_DEAF))
deaf = 1
var/mess = check_damage_thresholds()
if(mess && owner)
to_chat(owner, mess)
/obj/item/organ/ears/proc/adjustEarDamage(ddmg, ddeaf)
ear_damage = max(ear_damage + (ddmg*damage_multiplier), 0)
if(owner.status_flags & GODMODE)
return
setOrganDamage(max(damage + (ddmg*damage_multiplier), 0))
deaf = max(deaf + (ddeaf*damage_multiplier), 0)
/obj/item/organ/ears/proc/minimumDeafTicks(value)
+1 -1
View File
@@ -300,7 +300,7 @@
to_chat(H, "<span class='alert'>Your throat closes up!</span>")
H.silent = max(H.silent, 3)
else
H.adjustFireLoss(nitryl_pp/4)
H.adjustFireLoss(nitryl_pp/2)
gas_breathed = breath.get_moles(GAS_NITRYL)
if (gas_breathed > gas_stimulation_min)
H.reagents.add_reagent(/datum/reagent/nitryl,1)
+3
View File
@@ -13,6 +13,9 @@
owner.dna.species.stop_wagging_tail(owner)
return ..()
/obj/item/organ/tail/on_life()
return
/obj/item/organ/tail/cat
name = "cat tail"
desc = "A severed cat tail. Who's wagging now?"
+16 -5
View File
@@ -1,18 +1,29 @@
#define UNIT_TEST_SAVING_FLAVOR_TEXT "Space"
#define UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT "Station"
#define UNIT_TEST_SAVING_OOC_NOTES "Thirteen"
/datum/unit_test/character_saving/Run()
try
var/datum/preferences/P = new
P.load_path("test")
P.features["flavor_text"] = "Foo"
P.features["ooc_notes"] = "Bar"
P.features["flavor_text"] = UNIT_TEST_SAVING_FLAVOR_TEXT
P.features["silicon_flavor_text"] = UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT
P.features["ooc_notes"] = UNIT_TEST_SAVING_OOC_NOTES
P.save_character()
P.load_character()
if(P.features["flavor_text"] != "Foo")
if(P.features["flavor_text"] != UNIT_TEST_SAVING_FLAVOR_TEXT)
Fail("Flavor text is failing to save.")
if(P.features["ooc_notes"] != "Bar")
if(P.features["silicon_flavor_text"] != UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT)
Fail("Silicon flavor text is failing to save.")
if(P.features["ooc_notes"] != UNIT_TEST_SAVING_OOC_NOTES)
Fail("OOC text is failing to save.")
P.save_character()
P.load_character()
if(P.features["flavor_text"] != "Foo")
if((P.features["flavor_text"] != UNIT_TEST_SAVING_FLAVOR_TEXT) || (P.features["silicon_flavor_text"] != UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT) || (P.features["ooc_notes"] != UNIT_TEST_SAVING_OOC_NOTES))
Fail("Repeated saving and loading possibly causing save deletion.")
catch(var/exception/e)
Fail("Failed to save and load character due to exception [e.file]:[e.line], [e.name]")
#undef UNIT_TEST_SAVING_FLAVOR_TEXT
#undef UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT
#undef UNIT_TEST_SAVING_OOC_NOTES
+6 -2
View File
@@ -272,7 +272,7 @@
/obj/vehicle/sealed/mecha/proc/update_part_values() ///Updates the values given by scanning module and capacitor tier, called when a part is removed or inserted.
if(scanmod)
normal_step_energy_drain = 20 - (5 * scanmod.rating) //10 is normal, so on lowest part its worse, on second its ok and on higher its real good up to 0 on best
normal_step_energy_drain = initial(normal_step_energy_drain) * (1.5 / (scanmod.rating - 0.5)) //movement power cost is 3x of default at T1, 1x at T2, 0.6x at T3 and 0.4x at T4
step_energy_drain = normal_step_energy_drain
else
normal_step_energy_drain = 500
@@ -641,6 +641,9 @@
if(!Process_Spacemove(direction))
return FALSE
if(!has_charge(step_energy_drain))
if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MESSAGE))
to_chat(occupants, "[icon2html(src, occupants)]<span class='warning'>Insufficient power to move!</span>")
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
return FALSE
if(zoom_mode)
to_chat(occupants, "[icon2html(src, occupants)]<span class='warning'>Unable to move while in zoom mode!</span>")
@@ -651,7 +654,7 @@
if(!scanmod || !capacitor)
to_chat(occupants, "[icon2html(src, occupants)]<span class='warning'>Missing [scanmod? "capacitor" : "scanning module"].</span>")
return FALSE
if(lavaland_only && is_mining_level(z))
if(lavaland_only && !is_mining_level(z))
to_chat(occupants, "[icon2html(src, occupants)]<span class='warning'>Invalid Environment.</span>")
return FALSE
@@ -683,6 +686,7 @@
return TRUE
set_glide_size(DELAY_TO_GLIDE_SIZE(movedelay))
use_power(step_energy_drain)
//Otherwise just walk normally
. = step(src,direction, dir)
+5 -3
View File
@@ -9,12 +9,13 @@
deflect_chance = 5
armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100)
max_temperature = 25000
leg_overload_coeff = 80
leg_overload_coeff = 300
overload_step_energy_drain_min = 300
force = 25
wreckage = /obj/structure/mecha_wreckage/gygax
internal_damage_threshold = 35
max_equip = 3
step_energy_drain = 3
normal_step_energy_drain = 3
/obj/vehicle/sealed/mecha/combat/gygax/dark
desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications."
@@ -24,7 +25,8 @@
deflect_chance = 20
armor = list(MELEE = 40, BULLET = 40, LASER = 50, ENERGY = 35, BOMB = 20, BIO = 0, RAD =20, FIRE = 100, ACID = 100)
max_temperature = 35000
leg_overload_coeff = 70
leg_overload_coeff = 100
overload_step_energy_drain_min = 100
force = 30
operation_req_access = list(ACCESS_SYNDICATE)
internals_req_access = list(ACCESS_SYNDICATE)
@@ -11,7 +11,7 @@
max_temperature = 25000
wreckage = /obj/structure/mecha_wreckage/odysseus
internal_damage_threshold = 35
step_energy_drain = 6
normal_step_energy_drain = 6
infra_luminosity = 6
internals_req_access = list(ACCESS_ROBOTICS, ACCESS_MEDICAL)
+1 -1
View File
@@ -4,7 +4,7 @@
icon_state = "phazon"
movedelay = 2
dir_in = 2 //Facing South.
step_energy_drain = 3
normal_step_energy_drain = 3
max_integrity = 200
deflect_chance = 30
armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 50, FIRE = 100, ACID = 100)
@@ -14,7 +14,7 @@
mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS
internal_damage_threshold = 25
max_equip = 2
step_energy_drain = 3
normal_step_energy_drain = 3
color = "#87878715"
stepsound = null
turnsound = null
@@ -118,7 +118,12 @@
return ..()
/obj/item/mecha_parts/mecha_tracking/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M)
if(!..())
for(var/obj/item/I in M.contents)
if(istype(I, src))
to_chat(user, "<span class='warning'>[M] already has a tracking beacon!</span>")
return
. = ..()
if(!.)
return
M.trackers += src
M.diag_hud_set_mechtracking()
@@ -9,7 +9,7 @@
wreckage = /obj/structure/mecha_wreckage/odysseus
internal_damage_threshold = 35
deflect_chance = 15
step_energy_drain = 6
normal_step_energy_drain = 6
internals_req_access = list(ACCESS_ROBOTICS, ACCESS_MEDICAL)
/obj/vehicle/sealed/mecha/medical/odysseus/moved_inside(mob/living/carbon/human/H)
@@ -96,7 +96,7 @@
movedelay = 4
lights_power = 7
wreckage = /obj/structure/mecha_wreckage/ripley/deathripley
step_energy_drain = 0
normal_step_energy_drain = 0
enclosed = TRUE
enter_delay = 40
silicon_icon_state = null
+5 -19
View File
@@ -864,21 +864,10 @@ GLOBAL_LIST_EMPTY(vending_products)
if(isliving(usr))
var/mob/living/L = usr
C = L.get_idcard(TRUE)
if(!C)
say("No card found.")
if(!can_transact(C))
flick(icon_deny,src)
vend_ready = TRUE
return
else if (!C.registered_account)
say("No account found.")
flick(icon_deny,src)
vend_ready = TRUE
return
else if(!C.registered_account.account_job)
say("Departmental accounts have been blacklisted from personal expenses due to embezzlement.")
flick(icon_deny, src)
vend_ready = TRUE
return
// else if(age_restrictions && R.age_restricted && (!C.registered_age || C.registered_age < AGE_MINOR))
// say("You are not of legal age to purchase [R.name].")
// if(!(usr in GLOB.narcd_underages))
@@ -901,16 +890,13 @@ GLOBAL_LIST_EMPTY(vending_products)
price_to_use = 0 // it's free shut up
if(coin_records.Find(R) || hidden_records.Find(R))
price_to_use = R.custom_premium_price ? R.custom_premium_price : extra_price
if(price_to_use && !account.adjust_money(-price_to_use))
if(price_to_use && !attempt_transact(C, price_to_use))
say("You do not possess the funds to purchase [R.name].")
flick(icon_deny,src)
vend_ready = TRUE
return
var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department)
if(D)
D.adjust_money(price_to_use)
SSblackbox.record_feedback("amount", "vending_spent", price_to_use)
// log_econ("[price_to_use] credits were inserted into [src] by [D.account_holder] to buy [R].")
SSblackbox.record_feedback("amount", "vending_spent", price_to_use)
log_econ("[price_to_use] credits were inserted into [src] by [key_name(usr)] (account: [account.account_holder]) to buy [R].")
if(last_shopper != REF(usr) || purchase_message_cooldown < world.time)
say("Thank you for shopping with [src]!")
purchase_message_cooldown = world.time + 5 SECONDS
@@ -1169,7 +1155,7 @@ GLOBAL_LIST_EMPTY(vending_products)
if(owner)
owner.adjust_money(S.custom_price)
SSblackbox.record_feedback("amount", "vending_spent", S.custom_price)
// log_econ("[S.custom_price] credits were spent on [src] buying a [S] by [owner.account_holder], owned by [private_a.account_holder].")
log_econ("[S.custom_price] credits were spent on [src] buying a [S] by [key_name(usr)] (account: [owner.account_holder]), owned by [private_a.account_holder].")
vending_machine_input[N] = max(vending_machine_input[N] - 1, 0)
S.forceMove(drop_location())
loaded_items--