Merge remote-tracking branch 'citadel/master' into clickcd_experimental
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -52,4 +52,4 @@
|
||||
#define ORGAN_VITAL (1<<4) //Currently only the brain
|
||||
#define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances
|
||||
#define ORGAN_NO_DISMEMBERMENT (1<<6) //Immune to disembowelment.
|
||||
#define ORGAN_EDIBLE (1<<5) //is a snack? :D
|
||||
#define ORGAN_EDIBLE (1<<7) //is a snack? :D
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Defines for managed input/keybinding system.
|
||||
/// Max length of a keypress command before it's considered to be a forged packet/bogus command
|
||||
#define MAX_KEYPRESS_COMMANDLENGTH 16
|
||||
#define MAX_KEYPRESS_COMMANDLENGTH 32
|
||||
/// Maximum keys that can be bound to one button
|
||||
#define MAX_COMMANDS_PER_KEY 5
|
||||
/// Maximum keys per keybind
|
||||
|
||||
@@ -153,14 +153,17 @@
|
||||
var/list/po = A.priority_overlays;\
|
||||
if(LAZYLEN(rm)){\
|
||||
A.overlays -= rm;\
|
||||
rm.Cut();\
|
||||
A.remove_overlays = null;\
|
||||
}\
|
||||
if(LAZYLEN(ad)){\
|
||||
A.overlays |= ad;\
|
||||
ad.Cut();\
|
||||
A.add_overlays = null;\
|
||||
}\
|
||||
if(LAZYLEN(po)){\
|
||||
A.overlays |= po;\
|
||||
}\
|
||||
else{\
|
||||
A.priority_overlays = null;\
|
||||
}\
|
||||
A.flags_1 &= ~OVERLAY_QUEUED_1;\
|
||||
}
|
||||
|
||||
@@ -145,9 +145,9 @@
|
||||
continue
|
||||
if(!S.ckeys_allowed)
|
||||
snowflake_ipc_antenna_list[S.name] = mspath
|
||||
var/color1 = random_short_color()
|
||||
var/color2 = random_short_color()
|
||||
var/color3 = random_short_color()
|
||||
var/color1 = random_color()
|
||||
var/color2 = random_color()
|
||||
var/color3 = random_color()
|
||||
|
||||
var/body_model = MALE
|
||||
switch(intended_gender)
|
||||
|
||||
@@ -51,40 +51,111 @@
|
||||
return default
|
||||
return default
|
||||
|
||||
/proc/sanitize_hexcolor(color, desired_format=3, include_crunch=0, default)
|
||||
#define RGB_FORMAT_INVALID 0
|
||||
#define RGB_FORMAT_SHORT 1
|
||||
#define RGB_FORMAT_LONG 2
|
||||
|
||||
/**
|
||||
* Sanitizes a hexadecimal color. Always outputs lowercase.
|
||||
*
|
||||
* @params
|
||||
* * color - input color, 3 or 6 characters without the #.
|
||||
* * desired_format - 3 or 6 characters without the potential #. can only put in 3 or 6 here.
|
||||
* * include_crunch - do we put a # at the start
|
||||
* * default - default color. must be 3 or 6 characters with or without #.
|
||||
* * default_replacement - what we replace broken letters with.
|
||||
*/
|
||||
/proc/sanitize_hexcolor(color, desired_format = 3, include_crunch = 0, default = rgb(218, 72, 255), default_replacement = "f")
|
||||
if(!istext(default) || (length(default) < 3))
|
||||
CRASH("Default should be a text string of RGB format, with or without the crunch, 3 or 6 characters. Default was instead [default]")
|
||||
if(!istext(default_replacement) || (length(default_replacement) != 1))
|
||||
CRASH("Invalid default_replacement: [default_replacement]")
|
||||
default_replacement = lowertext(default_replacement)
|
||||
switch(text2ascii(default_replacement))
|
||||
if(48 to 57)
|
||||
if(97 to 102)
|
||||
if(65 to 70)
|
||||
else // yeah yeah i know 3 empty if's..
|
||||
CRASH("Invalid default_replacement: [default_replacement]")
|
||||
var/crunch = include_crunch ? "#" : ""
|
||||
if(!istext(color))
|
||||
color = ""
|
||||
color = default
|
||||
|
||||
var/start = 1 + (text2ascii(color, 1) == 35)
|
||||
var/len = length(color)
|
||||
var/char = ""
|
||||
// RRGGBB -> RGB but awful
|
||||
var/convert_to_shorthand = desired_format == 3 && length_char(color) > 3
|
||||
// get rid of crunch
|
||||
if(len && color[1] == "#")
|
||||
if(len >= 2)
|
||||
color = copytext(color, 2)
|
||||
else
|
||||
color = ""
|
||||
len = length(color)
|
||||
|
||||
. = ""
|
||||
var/i = start
|
||||
while(i <= len)
|
||||
switch(desired_format)
|
||||
if(3)
|
||||
desired_format = RGB_FORMAT_SHORT
|
||||
if(6)
|
||||
desired_format = RGB_FORMAT_LONG
|
||||
else
|
||||
CRASH("Invalid desired_format: [desired_format]. Must be 3 or 6.")
|
||||
var/current_format = RGB_FORMAT_INVALID
|
||||
switch(length(color))
|
||||
if(3)
|
||||
current_format = RGB_FORMAT_SHORT
|
||||
if(6)
|
||||
current_format = RGB_FORMAT_LONG
|
||||
else
|
||||
current_format = RGB_FORMAT_INVALID
|
||||
|
||||
if(current_format == RGB_FORMAT_INVALID) // nah
|
||||
color = default // process default
|
||||
if(color[1] == "#") // we checked default was at least 3 chars long earlier
|
||||
color = copytext(color, 2)
|
||||
len = length(color)
|
||||
switch(len)
|
||||
if(3)
|
||||
current_format = RGB_FORMAT_SHORT
|
||||
if(6)
|
||||
current_format = RGB_FORMAT_LONG
|
||||
else
|
||||
CRASH("Default was not 3 or 6 RGB hexadecimal characters: [default]")
|
||||
|
||||
var/sanitized = ""
|
||||
var/char = ""
|
||||
// first, sanitize hex
|
||||
for(var/i in 1 to len)
|
||||
char = color[i]
|
||||
switch(text2ascii(char))
|
||||
if(48 to 57) //numbers 0 to 9
|
||||
. += char
|
||||
if(97 to 102) //letters a to f
|
||||
. += char
|
||||
if(65 to 70) //letters A to F
|
||||
. += lowertext(char)
|
||||
if(48 to 57) // 0 to 9
|
||||
sanitized += char
|
||||
if(97 to 102) // a to f
|
||||
sanitized += char
|
||||
if(65 to 70) // A to F (capitalized!)
|
||||
sanitized += lowertext(char)
|
||||
else
|
||||
break
|
||||
i += length(char)
|
||||
if(convert_to_shorthand && i <= len) //skip next one
|
||||
i += length(color[i])
|
||||
sanitized += default_replacement
|
||||
// do we need to convert?
|
||||
if(desired_format == current_format)
|
||||
return crunch + sanitized // no
|
||||
// yes
|
||||
if((desired_format == RGB_FORMAT_SHORT) && (current_format == RGB_FORMAT_LONG)) // downconvert
|
||||
var/temp = ""
|
||||
// we could do some math but we're lazy and in practice floor()ing this.
|
||||
for(var/i in 1 to 6 step 2)
|
||||
temp += sanitized[i]
|
||||
sanitized = temp
|
||||
else if((desired_format == RGB_FORMAT_LONG) && (current_format == RGB_FORMAT_SHORT)) // upconvert
|
||||
var/temp = ""
|
||||
for(var/i in 1 to 3)
|
||||
temp += sanitized[i]
|
||||
temp += sanitized[i]
|
||||
sanitized = temp
|
||||
else
|
||||
CRASH("Invalid desired_format and current_format pair: [desired_format], [current_format]. Could not determine which way to convert.")
|
||||
return crunch + sanitized
|
||||
|
||||
if(length_char(.) != desired_format)
|
||||
if(default)
|
||||
return default
|
||||
return crunch + repeat_string(desired_format, "0")
|
||||
|
||||
return crunch + .
|
||||
#undef RGB_FORMAT_INVALID
|
||||
#undef RGB_FORMAT_SHORT
|
||||
#undef RGB_FORMAT_LONG
|
||||
|
||||
/proc/sanitize_ooccolor(color)
|
||||
if(length(color) != length_char(color))
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
deltimer(C.parallax_animate_timer)
|
||||
var/datum/callback/CB = CALLBACK(src, .proc/update_parallax_motionblur, C, animatedir, new_parallax_movedir, newtransform)
|
||||
if(skip_windups)
|
||||
CB.Invoke()
|
||||
CB.InvokeAsync()
|
||||
else
|
||||
C.parallax_animate_timer = addtimer(CB, min(shortesttimer, PARALLAX_LOOP_TIME), TIMER_CLIENT_TIME|TIMER_STOPPABLE)
|
||||
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
//similar to dog_fashion, but for beepsky, who has far more refined fashion tastes
|
||||
/datum/beepsky_fashion
|
||||
var/name //not setting the name and desc makes them go to the default
|
||||
var/desc
|
||||
|
||||
var/icon_file = 'icons/mob/secbot_accessories.dmi' //we sell secbots and secbot accessories
|
||||
var/obj_icon_state
|
||||
var/obj_alpha
|
||||
var/obj_color
|
||||
|
||||
var/list/stun_sounds //sound that replaces the stun attack when set
|
||||
var/ignore_sound = FALSE //whether to ignore sounds entirely or not
|
||||
|
||||
//emotes (don't set them if you want the default value)
|
||||
var/death_emote //what is said when beepsky dies
|
||||
var/capture_one //what is said when cuffing someone
|
||||
var/capture_two //what is said when cuffing someone, directly to the person being cuffed
|
||||
var/infraction //the level of threat detected
|
||||
var/taunt // beepsky pointing at a criminal
|
||||
var/attack_one //text when attacking criminal
|
||||
var/attack_two //text when attacking criminal, but directly to the criminal
|
||||
var/patrol_emote //engaging patrol text
|
||||
var/patrol_fail_emote //failing to engage patrol text
|
||||
var/list/arrest_texts //first is for not-cuffing, second is for cuffing
|
||||
var/arrest_emote //text stating that you're cuffing some criminal C with a threat of level X in location Y
|
||||
|
||||
//for reference, the following words are replaced when processed before speech:
|
||||
//LOCATION = the location passed, if any (this is only used by arrest_emote)
|
||||
//CRIMINAL = the name of the criminal (this is used by everything but patrol_emote and infraction)
|
||||
//BOT = the name of the bot (this can be used on any of the emotes)
|
||||
//THREAT_LEVEL = the level of the threat detected (can be used on arrest_emote and infraction)
|
||||
|
||||
/datum/beepsky_fashion/proc/get_overlay(var/dir)
|
||||
if(icon_file && obj_icon_state)
|
||||
var/image/beepsky_overlay = image(icon_file, obj_icon_state, dir = dir)
|
||||
beepsky_overlay.alpha = obj_alpha
|
||||
beepsky_overlay.color = obj_color
|
||||
return beepsky_overlay
|
||||
|
||||
/datum/beepsky_fashion/proc/stun_attack(mob/living/carbon/C) //fired when beepsky does a stun attack with the fashion worn, for sounds/overlays/etc
|
||||
return
|
||||
|
||||
//actual fashions from here on out
|
||||
/datum/beepsky_fashion/wizard
|
||||
obj_icon_state = "wizard"
|
||||
name = "Archmage Beepsky"
|
||||
desc = "A secbot stolen from the wizard federation."
|
||||
death_emote = "BOT casts EI NATH on themselves!"
|
||||
capture_one = "BOT is casting cable ties on CRIMINAL!"
|
||||
capture_two = "BOT is casting cable ties on you!"
|
||||
infraction = "Magical disturbance of magnitude THREAT_LEVEL detected!"
|
||||
taunt = "BOT points his staff towards CRIMINAL!"
|
||||
attack_one = "BOT casts magic missile on CRIMINAL!"
|
||||
attack_two = "BOT casts magic missile on you!"
|
||||
patrol_emote = "Beginning search for magical disturbances."
|
||||
patrol_fail_emote = "Failure to find magical disturbances. Recallibrating."
|
||||
arrest_emote = "ARREST_TYPE level THREAT_LEVEL magical practitioner CRIMINAL in LOCATION."
|
||||
stun_sounds = list('sound/magic/lightningbolt.ogg',
|
||||
'sound/magic/fireball.ogg',
|
||||
'sound/weapons/zapbang.ogg',
|
||||
'sound/magic/knock.ogg',
|
||||
'sound/magic/fleshtostone.ogg',
|
||||
'sound/effects/magic.ogg',
|
||||
'sound/magic/disintegrate.ogg')
|
||||
|
||||
/datum/beepsky_fashion/cowboy
|
||||
obj_icon_state = "cowboy"
|
||||
name = "Sheriff Beepsky"
|
||||
desc = "The sheriff of this here station."
|
||||
capture_one = "BOT is tying CRIMINAL up!"
|
||||
capture_two = "BOT is tying you up!"
|
||||
infraction = "Outlaws with a bounty of THREAT_LEVEL000 space dollars detected!"
|
||||
taunt = "BOT aims his revolver towards CRIMINAL!"
|
||||
attack_one = "BOT unloads his revolver onto CRIMINAL!"
|
||||
attack_two = "BOT unloads his revolver onto you!"
|
||||
patrol_emote = "Engaging bounty hunting protocols."
|
||||
patrol_fail_emote = "Unable to find any bounties due to error. Rebooting."
|
||||
arrest_emote = "ARREST_TYPE outlaw CRIMINAL with a bounty of THREAT_LEVEL000 in LOCATION."
|
||||
stun_sounds = list('sound/weapons/Gunshot.ogg',
|
||||
'sound/weapons/Gunshot2.ogg',
|
||||
'sound/weapons/Gunshot3.ogg',
|
||||
'sound/weapons/Gunshot4.ogg')
|
||||
|
||||
/datum/beepsky_fashion/chef
|
||||
obj_icon_state = "chef"
|
||||
name = "Chef Beepsky"
|
||||
desc = "Cooking up the finest foods the station has ever seen."
|
||||
death_emote = "Mamma-mia!"
|
||||
infraction = "Grade THREAT_LEVEL prosciutto detected!"
|
||||
taunt = "BOT glares at CRIMINAL."
|
||||
attack_one = "BOT CQCs CRIMINAL!"
|
||||
attack_two = "BOT CQCs you!"
|
||||
patrol_emote = "Beginning search for the bad prosciutto."
|
||||
patrol_fail_emote = "All prosciutto is stale. Rebooting."
|
||||
arrest_texts = list("Frying", "Grilling") //any good secoff knows the difference
|
||||
arrest_emote = "ARREST_TYPE grade THREAT_LEVEL prosciutto CRIMINAL in LOCATION."
|
||||
stun_sounds = list('sound/weapons/cqchit1.ogg',
|
||||
'sound/weapons/cqchit2.ogg')
|
||||
|
||||
/datum/beepsky_fashion/cat
|
||||
obj_icon_state = "cat"
|
||||
name = "OwOfficer Bweepskwee"
|
||||
desc = "A beepsky unit with cat ears. Catgirl science has gone too far."
|
||||
death_emote = "Nya!"
|
||||
capture_one = "BOT is tying CRIMINAL up!!"
|
||||
capture_two = "BOT is tying you up!"
|
||||
infraction = "Wevel THREAT_LEVEL infwactwion awert!!!"
|
||||
taunt = "BOT points at CRIMINAL and nyas!"
|
||||
attack_one = "BOT shoves CRIMINAL onto a table!"
|
||||
attack_two = "BOT shoves you onto a table!"
|
||||
patrol_emote = "Enwgagwing patwol mwodies.."
|
||||
patrol_fail_emote = "Unawbwle two stwawt patwollies. Nya."
|
||||
arrest_texts = list("Dwetwaining", "Awwesting")
|
||||
arrest_emote = "ARREST_TYPE wevel THREAT_LEVEL scwumbwag CRIMINAL in LOCATION. Nya."
|
||||
ignore_sound = TRUE //we instead make the stunned person fire the nya emote
|
||||
|
||||
/datum/beepsky_fashion/cat/stun_attack(var/mob/living/carbon/C) //makes a fake table under you on hit, makes cat people nya when hit
|
||||
if(iscatperson(C))
|
||||
C.emote("nya")
|
||||
var/turf/target_turf = get_turf(C)
|
||||
if(target_turf) //slams you on a fake table
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
|
||||
var/obj/effect/overlay_holder = new(target_turf)
|
||||
overlay_holder.name = "Catboy Table"
|
||||
overlay_holder.desc = "Where bad catboys go."
|
||||
var/image/table_overlay = image('icons/obj/smooth_structures/table.dmi', "table")
|
||||
overlay_holder.add_overlay(table_overlay)
|
||||
QDEL_IN(overlay_holder, 10)
|
||||
|
||||
/datum/beepsky_fashion/cake //nothing else. it's just beepsky. with a cake on his head.
|
||||
obj_icon_state = "cake"
|
||||
name = "Cakesky"
|
||||
desc = "It's a secbot, wearing a cake on his head!"
|
||||
|
||||
/datum/beepsky_fashion/captain
|
||||
obj_icon_state = "captain"
|
||||
name = "Captainsky"
|
||||
desc = "The real captain of this station."
|
||||
capture_one = "BOT is lecturing CRIMINAL on why he is the captain!"
|
||||
capture_two = "BOT is lecturing you on why he is the captain!"
|
||||
infraction = "Level THREAT_LEVEL greytider detected."
|
||||
attack_one = "BOT beats CRIMINAL with the chain of command!"
|
||||
attack_two = "BOT beats you with the chain of command!"
|
||||
patrol_emote = "Uselessness protocols engaged."
|
||||
patrol_fail_emote = "Unit has been found as useless. Rebooting."
|
||||
arrest_texts = list("Demoting", "Firing")
|
||||
arrest_emote = "ARREST_TYPE level THREAT_LEVEL lesser crewmember CRIMINAL in LOCATION."
|
||||
stun_sounds = list('sound/weapons/chainhit.ogg')
|
||||
|
||||
/datum/beepsky_fashion/king
|
||||
obj_icon_state = "king"
|
||||
name = "King Beepsky"
|
||||
desc = "He who has ascended to bare the right of king, sits atop the throne."
|
||||
capture_one = "BOT is calling the guards onto CRIMINAL!"
|
||||
capture_two = "BOT is calling the guards onto you!"
|
||||
infraction = "Treason of level THREAT_LEVEL detected!"
|
||||
attack_one = "BOT strikes CRIMINAL with his kingly authority!"
|
||||
attack_two = "BOT strikes you with his kingly authority!"
|
||||
patrol_emote = "Searching for peasants to beat up."
|
||||
patrol_fail_emote = "Peasants are using dark magic. Recallibrating."
|
||||
arrest_texts = list("Knighting", "Executing")
|
||||
arrest_emote = "ARREST_TYPE level THREAT_LEVEL peasant CRIMINAL in LOCATION."
|
||||
stun_sounds = list('sound/weapons/punch1.ogg',
|
||||
'sound/weapons/punch2.ogg',
|
||||
'sound/weapons/punch3.ogg',
|
||||
'sound/weapons/punch4.ogg')
|
||||
|
||||
/datum/beepsky_fashion/pirate
|
||||
obj_icon_state = "pirate"
|
||||
name = "Beepsbeard the Pirate"
|
||||
desc = "Sailor of the seven seas, all sea-faring bots fear the one known as Beepsbeard."
|
||||
capture_one = "BOT is making CRIMINAL walk the plank!"
|
||||
capture_two = "BOT is making you walk the plank!"
|
||||
infraction = "Enemy vessel spotted with threat level THREAT_LEVEL!"
|
||||
attack_one = "BOT strikes CRIMINAL with his cutlass!"
|
||||
attack_two = "BOT strikes you with his cutlass!"
|
||||
patrol_emote = "Searching for enemy vessels to board."
|
||||
patrol_fail_emote = "No way to engage enemy vessels. Rebooting."
|
||||
arrest_texts = list("Boarding", "Sinking")
|
||||
arrest_emote = "ARREST_TYPE level THREAT_LEVEL vessel CRIMINAL in LOCATION."
|
||||
stun_sounds = list('sound/weapons/bladeslice.ogg')
|
||||
|
||||
/datum/beepsky_fashion/engineer
|
||||
obj_icon_state = "engineer"
|
||||
name = "Chief Engineer Beepsky"
|
||||
desc = "He fixes criminals with a wrench to the face."
|
||||
capture_one = "BOT is tying CRIMINAL up!"
|
||||
capture_two = "BOT is tying you up!"
|
||||
infraction = "Structural integrity issue spotted with threat level THREAT_LEVEL"
|
||||
attack_one = "BOT strikes CRIMINAL with his wrench!"
|
||||
attack_two = "BOT strikes you with his wrench!"
|
||||
arrest_texts = list("Fixing", "Repairing")
|
||||
arrest_emote = "ARREST_TYPE level THREAT_LEVEL structural issue in LOCATION"
|
||||
stun_sounds = list('sound/weapons/genhit.ogg')
|
||||
|
||||
/datum/beepsky_fashion/tophat
|
||||
obj_icon_state = "tophat"
|
||||
name = "Fancy Beepsky"
|
||||
desc = "It's a secbot, wearing a top hat! How fancy."
|
||||
|
||||
/datum/beepsky_fashion/fedora
|
||||
obj_icon_state = "fedora"
|
||||
name = "Fedorasky"
|
||||
desc = "It's a secbot, wearing a fedora!"
|
||||
|
||||
/datum/beepsky_fashion/sombrero
|
||||
obj_icon_state = "sombrero"
|
||||
name = "Sombrerosky"
|
||||
desc = "A secbot wearing a sombrero. Truly, a hombre to all."
|
||||
|
||||
/datum/beepsky_fashion/santa
|
||||
obj_icon_state = "santa"
|
||||
name = "Saint Beepsky"
|
||||
desc = "Have you been a level 7 infraction this holiday season?"
|
||||
capture_one = "BOT is tying CRIMINAL up with fairy lights!"
|
||||
capture_two = "BOT is tying you up with fairy lights!"
|
||||
infraction = "Level THREAT_LEVEL threat to holiday cheer spotted!"
|
||||
attack_one = "BOT crushes CRIMINAL with their holiday spirit!"
|
||||
attack_two = "BOT crushes you with their holiday spirit!"
|
||||
arrest_emote = "ARREST_TYPE level THREAT_LEVEL threat to holiday cheer in LOCATION"
|
||||
|
||||
@@ -324,6 +324,13 @@
|
||||
result = /obj/item/toy/sword/cx
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/catgirlplushie
|
||||
name = "Catgirl Plushie"
|
||||
reqs = list(/obj/item/toy/plush/hairball = 3)
|
||||
result = /obj/item/toy/plush/catgirl
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
////////////
|
||||
//Unsorted//
|
||||
|
||||
@@ -78,6 +78,8 @@
|
||||
|
||||
/datum/datacore/proc/manifest()
|
||||
for(var/mob/dead/new_player/N in GLOB.player_list)
|
||||
if(!N?.client)
|
||||
continue
|
||||
if(N.new_character)
|
||||
log_manifest(N.ckey,N.new_character.mind,N.new_character)
|
||||
if(ishuman(N.new_character))
|
||||
|
||||
+6
-6
@@ -131,9 +131,9 @@
|
||||
L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color)
|
||||
L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)
|
||||
L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color)
|
||||
L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"])
|
||||
L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"])
|
||||
L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"])
|
||||
L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"], 6)
|
||||
L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"], 6)
|
||||
L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"], 6)
|
||||
if(!GLOB.mam_tails_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list)
|
||||
L[DNA_MUTANTTAIL_BLOCK] = construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len)
|
||||
@@ -239,11 +239,11 @@
|
||||
if(DNA_HAIR_STYLE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len))
|
||||
if(DNA_COLOR_ONE_BLOCK)
|
||||
sanitize_hexcolor(features["mcolor"])
|
||||
sanitize_hexcolor(features["mcolor"], 6)
|
||||
if(DNA_COLOR_TWO_BLOCK)
|
||||
sanitize_hexcolor(features["mcolor2"])
|
||||
sanitize_hexcolor(features["mcolor2"], 6)
|
||||
if(DNA_COLOR_THREE_BLOCK)
|
||||
sanitize_hexcolor(features["mcolor3"])
|
||||
sanitize_hexcolor(features["mcolor3"], 6)
|
||||
if(DNA_MUTANTTAIL_BLOCK)
|
||||
construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len)
|
||||
if(DNA_MUTANTEAR_BLOCK)
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
corgI.color = obj_color
|
||||
return corgI
|
||||
|
||||
|
||||
/datum/dog_fashion/head
|
||||
icon_file = 'icons/mob/corgi_head.dmi'
|
||||
|
||||
@@ -53,7 +52,6 @@
|
||||
name = "Sous chef REAL_NAME"
|
||||
desc = "Your food will be taste-tested. All of it."
|
||||
|
||||
|
||||
/datum/dog_fashion/head/captain
|
||||
name = "Captain REAL_NAME"
|
||||
desc = "Probably better than the last captain."
|
||||
|
||||
@@ -196,3 +196,7 @@
|
||||
description = "<span class='nicegreen'>That work of art was so great it made me believe in the goodness of humanity. Says a lot in a place like this.</span>\n"
|
||||
mood_change = 4
|
||||
timeout = 4 MINUTES
|
||||
|
||||
/datum/mood_event/cleared_stomach
|
||||
description = "<span class='nicegreen'>Feels nice to get that out of the way!</span>\n"
|
||||
mood_change = 3
|
||||
|
||||
@@ -152,6 +152,11 @@
|
||||
user.visible_message("<span class='notice'>[user] licks the wounds on [victim]'s [limb.name].</span>", "<span class='notice'>You lick some of the wounds on [victim]'s [limb.name]</span>", ignored_mobs=victim)
|
||||
to_chat(victim, "<span class='green'>[user] licks the wounds on your [limb.name]!</span")
|
||||
blood_flow -= 0.5
|
||||
if(isinsect(victim) || iscatperson(victim) || ismammal(victim) || isdwarf(victim) || ismonkey(victim)) // Yep you can lick monkeys.
|
||||
user.reagents.add_reagent(/datum/reagent/hairball, 2)
|
||||
|
||||
else if(ishumanbasic(victim) || isflyperson(victim) || islizard(victim) || isdullahan(victim))
|
||||
user.reagents.add_reagent(/datum/reagent/hairball, 1)
|
||||
|
||||
if(blood_flow > minimum_flow)
|
||||
try_handling(user)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// To be removed on step_ conversion
|
||||
// All this work to prevent a second bump
|
||||
/atom/movable/Move(atom/newloc, direct=0)
|
||||
set waitfor = FALSE //n o
|
||||
. = FALSE
|
||||
if(!newloc || newloc == loc)
|
||||
return
|
||||
@@ -52,6 +53,7 @@
|
||||
////////////////////////////////////////
|
||||
|
||||
/atom/movable/Move(atom/newloc, direct)
|
||||
set waitfor = FALSE //n o
|
||||
var/atom/movable/pullee = pulling
|
||||
var/turf/T = loc
|
||||
if(!moving_from_pull)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
var/list/squeak_override //Weighted list; If you want your plush to have different squeak sounds use this
|
||||
var/stuffed = TRUE //If the plushie has stuffing in it
|
||||
var/unstuffable = FALSE //for plushies that can't be stuffed
|
||||
var/obj/item/grenade/grenade //You can remove the stuffing from a plushie and add a grenade to it for *nefarious uses*
|
||||
//--love ~<3--
|
||||
gender = NEUTER
|
||||
@@ -174,6 +175,9 @@
|
||||
/obj/item/toy/plush/attackby(obj/item/I, mob/living/user, params)
|
||||
if(I.get_sharpness())
|
||||
if(!grenade)
|
||||
if(unstuffable)
|
||||
to_chat(user, "<span class='notice'>Nothing to do here.</span>")
|
||||
return
|
||||
if(!stuffed)
|
||||
to_chat(user, "<span class='warning'>You already murdered it!</span>")
|
||||
return
|
||||
@@ -187,6 +191,13 @@
|
||||
grenade = null
|
||||
return
|
||||
if(istype(I, /obj/item/grenade))
|
||||
if(unstuffable)
|
||||
to_chat(user, "<span class='warning'>No... you should destroy it now!</span>")
|
||||
sleep(10)
|
||||
if(QDELETED(user) || QDELETED(src))
|
||||
return
|
||||
SEND_SOUND(user, 'sound/weapons/armbomb.ogg')
|
||||
return
|
||||
if(stuffed)
|
||||
to_chat(user, "<span class='warning'>You need to remove some stuffing first!</span>")
|
||||
return
|
||||
@@ -743,3 +754,14 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
attack_verb = list("headbutt", "scritched", "bit")
|
||||
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
|
||||
/obj/item/toy/plush/hairball
|
||||
name = "Hairball"
|
||||
desc = "A bundle of undigested fibers and scales. Yuck."
|
||||
icon_state = "Hairball"
|
||||
unstuffable = TRUE
|
||||
young = TRUE // Your own mouth-baby.
|
||||
squeak_override = list('sound/misc/splort.ogg'=1)
|
||||
attack_verb = list("sploshed", "splorted", "slushed")
|
||||
can_random_spawn = FALSE
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
linked_minds |= user.mind
|
||||
|
||||
update_icon()
|
||||
float(linked_minds.len)
|
||||
INVOKE_ASYNC(src, /atom/movable.proc/float, linked_minds.len)
|
||||
if(linked_minds.len)
|
||||
START_PROCESSING(SSobj, src)
|
||||
set_light(lit_luminosity)
|
||||
|
||||
@@ -863,7 +863,7 @@
|
||||
if(jobban_isbanned(M, ROLE_TRAITOR) || isbanned_dept)
|
||||
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=traitor;jobban4=[REF(M)]'><font color=red>Traitor</font></a></td>"
|
||||
else
|
||||
dat += "<td width='20%'><a href='?src=[REF(src)];jobban3=traitor;jobban4=[REF(M)]'>Traitor</a></td>"
|
||||
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=traitor;jobban4=[REF(M)]'>Traitor</a></td>"
|
||||
|
||||
//Changeling
|
||||
if(jobban_isbanned(M, ROLE_CHANGELING) || isbanned_dept)
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
var/datum/changelingprofile/first_prof = null
|
||||
var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation.
|
||||
var/absorbedcount = 0
|
||||
/// did we get succed by another changeling
|
||||
var/hostile_absorbed = FALSE
|
||||
var/trueabsorbs = 0//dna gained using absorb, not dna sting
|
||||
var/chem_charges = 20
|
||||
var/chem_storage = 75
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
|
||||
|
||||
var/datum/antagonist/changeling/target_ling = target.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(target_ling)//If the target was a changeling, suck out their extra juice and objective points!
|
||||
if(target_ling && !target_ling.hostile_absorbed)//If the target was a changeling, suck out their extra juice and objective points!
|
||||
to_chat(user, "<span class='boldnotice'>[target] was one of us. We have absorbed their power.</span>")
|
||||
target_ling.remove_changeling_powers()
|
||||
changeling.geneticpoints += round(target_ling.geneticpoints/2)
|
||||
@@ -102,6 +102,7 @@
|
||||
changeling.chem_storage += round(target_ling.chem_storage/2)
|
||||
changeling.chem_charges += min(target_ling.chem_charges, changeling.chem_storage)
|
||||
target_ling.chem_charges = 0
|
||||
target_ling.hostile_absorbed = TRUE
|
||||
target_ling.chem_storage = 0
|
||||
changeling.absorbedcount += (target_ling.absorbedcount)
|
||||
target_ling.stored_profiles.len = 1
|
||||
|
||||
@@ -36,9 +36,10 @@
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(HAS_TRAIT(user, CHANGELING_DRAIN) || ((user.stat != DEAD) && !(HAS_TRAIT(user, TRAIT_DEATHCOMA))))
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!changeling)
|
||||
return FALSE
|
||||
if(changeling.hostile_absorbed || ((user.stat != DEAD) && !(HAS_TRAIT(user, TRAIT_DEATHCOMA))))
|
||||
changeling.purchasedpowers -= src
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
if(stasis)
|
||||
return
|
||||
if(revealed && essence <= 0)
|
||||
death()
|
||||
INVOKE_ASYNC(src, .proc/death)
|
||||
if(unreveal_time && world.time >= unreveal_time)
|
||||
unreveal_time = 0
|
||||
revealed = FALSE
|
||||
|
||||
@@ -43,6 +43,12 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
|
||||
var/list/dummy = get_gases()
|
||||
for(var/gas in dummy)
|
||||
dummy[gas] = get_moles(gas)
|
||||
dummy["TEMP"] = return_temperature()
|
||||
dummy["PRESSURE"] = return_pressure()
|
||||
dummy["HEAT CAPACITY"] = heat_capacity()
|
||||
dummy["TOTAL MOLES"] = total_moles()
|
||||
dummy["VOLUME"] = return_volume()
|
||||
dummy["THERMAL ENERGY"] = thermal_energy()
|
||||
return debug_variable("gases (READ ONLY)", dummy, 0, src)
|
||||
|
||||
/datum/gas_mixture/vv_get_dropdown()
|
||||
|
||||
@@ -83,24 +83,24 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/gender = MALE //gender of character (well duh)
|
||||
var/age = 30 //age of character
|
||||
var/underwear = "Nude" //underwear type
|
||||
var/undie_color = "FFF"
|
||||
var/undie_color = "FFFFFF"
|
||||
var/undershirt = "Nude" //undershirt type
|
||||
var/shirt_color = "FFF"
|
||||
var/shirt_color = "FFFFFF"
|
||||
var/socks = "Nude" //socks type
|
||||
var/socks_color = "FFF"
|
||||
var/socks_color = "FFFFFF"
|
||||
var/backbag = DBACKPACK //backpack type
|
||||
var/jumpsuit_style = PREF_SUIT //suit/skirt
|
||||
var/hair_style = "Bald" //Hair type
|
||||
var/hair_color = "000" //Hair color
|
||||
var/hair_color = "000000" //Hair color
|
||||
var/facial_hair_style = "Shaved" //Face hair type
|
||||
var/facial_hair_color = "000" //Facial hair color
|
||||
var/facial_hair_color = "000000" //Facial hair color
|
||||
var/skin_tone = "caucasian1" //Skin color
|
||||
var/use_custom_skin_tone = FALSE
|
||||
var/eye_color = "000" //Eye color
|
||||
var/eye_color = "000000" //Eye color
|
||||
var/datum/species/pref_species = new /datum/species/human() //Mutant race
|
||||
var/list/features = list("mcolor" = "FFF",
|
||||
"mcolor2" = "FFF",
|
||||
"mcolor3" = "FFF",
|
||||
var/list/features = list("mcolor" = "FFFFFF",
|
||||
"mcolor2" = "FFFFFF",
|
||||
"mcolor3" = "FFFFFF",
|
||||
"tail_lizard" = "Smooth",
|
||||
"tail_human" = "None",
|
||||
"snout" = "Round",
|
||||
@@ -131,23 +131,23 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"cock_shape" = DEF_COCK_SHAPE,
|
||||
"cock_length" = COCK_SIZE_DEF,
|
||||
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
|
||||
"cock_color" = "fff",
|
||||
"cock_color" = "ffffff",
|
||||
"cock_taur" = FALSE,
|
||||
"has_balls" = FALSE,
|
||||
"balls_color" = "fff",
|
||||
"balls_color" = "ffffff",
|
||||
"balls_shape" = DEF_BALLS_SHAPE,
|
||||
"balls_size" = BALLS_SIZE_DEF,
|
||||
"balls_cum_rate" = CUM_RATE,
|
||||
"balls_cum_mult" = CUM_RATE_MULT,
|
||||
"balls_efficiency" = CUM_EFFICIENCY,
|
||||
"has_breasts" = FALSE,
|
||||
"breasts_color" = "fff",
|
||||
"breasts_color" = "ffffff",
|
||||
"breasts_size" = BREASTS_SIZE_DEF,
|
||||
"breasts_shape" = DEF_BREASTS_SHAPE,
|
||||
"breasts_producing" = FALSE,
|
||||
"has_vag" = FALSE,
|
||||
"vag_shape" = DEF_VAGINA_SHAPE,
|
||||
"vag_color" = "fff",
|
||||
"vag_color" = "ffffff",
|
||||
"has_womb" = FALSE,
|
||||
"balls_visibility" = GEN_VISIBLE_NO_UNDIES,
|
||||
"breasts_visibility"= GEN_VISIBLE_NO_UNDIES,
|
||||
@@ -1707,7 +1707,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("hair")
|
||||
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null
|
||||
if(new_hair)
|
||||
hair_color = sanitize_hexcolor(new_hair)
|
||||
hair_color = sanitize_hexcolor(new_hair, 6)
|
||||
|
||||
if("hair_style")
|
||||
var/new_hair_style
|
||||
@@ -1724,7 +1724,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("facial")
|
||||
var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference","#"+facial_hair_color) as color|null
|
||||
if(new_facial)
|
||||
facial_hair_color = sanitize_hexcolor(new_facial)
|
||||
facial_hair_color = sanitize_hexcolor(new_facial, 6)
|
||||
|
||||
if("facial_hair_style")
|
||||
var/new_facial_hair_style
|
||||
@@ -1749,7 +1749,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("undie_color")
|
||||
var/n_undie_color = input(user, "Choose your underwear's color.", "Character Preference", "#[undie_color]") as color|null
|
||||
if(n_undie_color)
|
||||
undie_color = sanitize_hexcolor(n_undie_color)
|
||||
undie_color = sanitize_hexcolor(n_undie_color, 6)
|
||||
|
||||
if("undershirt")
|
||||
var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_list
|
||||
@@ -1759,7 +1759,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("shirt_color")
|
||||
var/n_shirt_color = input(user, "Choose your undershirt's color.", "Character Preference", "#[shirt_color]") as color|null
|
||||
if(n_shirt_color)
|
||||
shirt_color = sanitize_hexcolor(n_shirt_color)
|
||||
shirt_color = sanitize_hexcolor(n_shirt_color, 6)
|
||||
|
||||
if("socks")
|
||||
var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list
|
||||
@@ -1769,12 +1769,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("socks_color")
|
||||
var/n_socks_color = input(user, "Choose your socks' color.", "Character Preference", "#[socks_color]") as color|null
|
||||
if(n_socks_color)
|
||||
socks_color = sanitize_hexcolor(n_socks_color)
|
||||
socks_color = sanitize_hexcolor(n_socks_color, 6)
|
||||
|
||||
if("eyes")
|
||||
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+eye_color) as color|null
|
||||
if(new_eyes)
|
||||
eye_color = sanitize_hexcolor(new_eyes)
|
||||
eye_color = sanitize_hexcolor(new_eyes, 6)
|
||||
|
||||
if("species")
|
||||
var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_race_names
|
||||
@@ -1798,11 +1798,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
//Now that we changed our species, we must verify that the mutant colour is still allowed.
|
||||
var/temp_hsv = RGBtoHSV(features["mcolor"])
|
||||
if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
||||
if(features["mcolor"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
||||
features["mcolor"] = pref_species.default_color
|
||||
if(features["mcolor2"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
||||
if(features["mcolor2"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
||||
features["mcolor2"] = pref_species.default_color
|
||||
if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
||||
if(features["mcolor3"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
||||
features["mcolor3"] = pref_species.default_color
|
||||
|
||||
if("custom_species")
|
||||
@@ -1819,7 +1819,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_mutantcolor == "#000000")
|
||||
features["mcolor"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
|
||||
features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
|
||||
features["mcolor"] = sanitize_hexcolor(new_mutantcolor, 6)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
@@ -1830,7 +1830,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_mutantcolor == "#000000")
|
||||
features["mcolor2"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
|
||||
features["mcolor2"] = sanitize_hexcolor(new_mutantcolor)
|
||||
features["mcolor2"] = sanitize_hexcolor(new_mutantcolor, 6)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
@@ -1841,7 +1841,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_mutantcolor == "#000000")
|
||||
features["mcolor3"] = pref_species.default_color
|
||||
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
|
||||
features["mcolor3"] = sanitize_hexcolor(new_mutantcolor)
|
||||
features["mcolor3"] = sanitize_hexcolor(new_mutantcolor, 6)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
@@ -1969,7 +1969,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if (new_horn_color == "#000000")
|
||||
features["horns_color"] = "85615A"
|
||||
else
|
||||
features["horns_color"] = sanitize_hexcolor(new_horn_color)
|
||||
features["horns_color"] = sanitize_hexcolor(new_horn_color, 6)
|
||||
|
||||
if("wings")
|
||||
var/new_wings
|
||||
@@ -1983,7 +1983,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if (new_wing_color == "#000000")
|
||||
features["wings_color"] = "#FFFFFF"
|
||||
else
|
||||
features["wings_color"] = sanitize_hexcolor(new_wing_color)
|
||||
features["wings_color"] = sanitize_hexcolor(new_wing_color, 6)
|
||||
|
||||
if("frills")
|
||||
var/new_frills
|
||||
@@ -2157,7 +2157,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_cockcolor == "#000000")
|
||||
features["cock_color"] = pref_species.default_color
|
||||
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["cock_color"] = sanitize_hexcolor(new_cockcolor)
|
||||
features["cock_color"] = sanitize_hexcolor(new_cockcolor, 6)
|
||||
else
|
||||
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
@@ -2197,7 +2197,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_ballscolor == "#000000")
|
||||
features["balls_color"] = pref_species.default_color
|
||||
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["balls_color"] = sanitize_hexcolor(new_ballscolor)
|
||||
features["balls_color"] = sanitize_hexcolor(new_ballscolor, 6)
|
||||
else
|
||||
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
@@ -2224,7 +2224,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_breasts_color == "#000000")
|
||||
features["breasts_color"] = pref_species.default_color
|
||||
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["breasts_color"] = sanitize_hexcolor(new_breasts_color)
|
||||
features["breasts_color"] = sanitize_hexcolor(new_breasts_color, 6)
|
||||
else
|
||||
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
@@ -2246,7 +2246,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_vagcolor == "#000000")
|
||||
features["vag_color"] = pref_species.default_color
|
||||
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
||||
features["vag_color"] = sanitize_hexcolor(new_vagcolor)
|
||||
features["vag_color"] = sanitize_hexcolor(new_vagcolor, 6)
|
||||
else
|
||||
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
|
||||
@@ -224,6 +224,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
var/needs_update = savefile_needs_update(S)
|
||||
if(needs_update == -2) //fatal, can't load any data
|
||||
return 0
|
||||
|
||||
. = TRUE
|
||||
|
||||
//general preferences
|
||||
S["ooccolor"] >> ooccolor
|
||||
@@ -440,6 +442,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
if(needs_update == -2) //fatal, can't load any data
|
||||
return 0
|
||||
|
||||
. = TRUE
|
||||
|
||||
//Species
|
||||
var/species_id
|
||||
S["species"] >> species_id
|
||||
@@ -632,14 +636,14 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
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, 3, FALSE, initial(undie_color))
|
||||
shirt_color = sanitize_hexcolor(shirt_color, 3, FALSE, initial(shirt_color))
|
||||
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, 3, FALSE, initial(socks_color))
|
||||
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, 3, 0)
|
||||
facial_hair_color = sanitize_hexcolor(facial_hair_color, 3, 0)
|
||||
eye_color = sanitize_hexcolor(eye_color, 3, 0)
|
||||
hair_color = sanitize_hexcolor(hair_color, 6, FALSE)
|
||||
facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE)
|
||||
eye_color = sanitize_hexcolor(eye_color, 6, FALSE)
|
||||
|
||||
var/static/allow_custom_skintones
|
||||
if(isnull(allow_custom_skintones))
|
||||
@@ -650,12 +654,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
else
|
||||
skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones - GLOB.nonstandard_skin_tones, initial(skin_tone))
|
||||
|
||||
features["horns_color"] = sanitize_hexcolor(features["horns_color"], 3, FALSE, "85615a")
|
||||
features["wings_color"] = sanitize_hexcolor(features["wings_color"], 3, FALSE, "FFFFFF")
|
||||
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"], 3, 0)
|
||||
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)
|
||||
@@ -699,10 +703,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
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"], 3, FALSE, "FFF")
|
||||
features["cock_color"] = sanitize_hexcolor(features["cock_color"], 3, FALSE, "FFF")
|
||||
features["balls_color"] = sanitize_hexcolor(features["balls_color"], 3, FALSE, "FFF")
|
||||
features["vag_color"] = sanitize_hexcolor(features["vag_color"], 3, FALSE, "FFF")
|
||||
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)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/blockTracking = 0 //For AI tracking
|
||||
var/can_toggle = null
|
||||
dynamic_hair_suffix = "+generic"
|
||||
var/datum/beepsky_fashion/beepsky_fashion //the associated datum for applying this to a secbot
|
||||
|
||||
/obj/item/clothing/head/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
icon_state = "chef"
|
||||
item_state = "chef"
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/chef
|
||||
beepsky_fashion = /datum/beepsky_fashion/chef
|
||||
|
||||
/obj/item/clothing/head/collectable/paper
|
||||
name = "collectable paper hat"
|
||||
@@ -42,6 +44,8 @@
|
||||
icon_state = "tophat"
|
||||
item_state = "that"
|
||||
|
||||
beepsky_fashion = /datum/beepsky_fashion/tophat
|
||||
|
||||
/obj/item/clothing/head/collectable/captain
|
||||
name = "collectable captain's hat"
|
||||
desc = "A collectable hat that'll make you look just like a real comdom!"
|
||||
@@ -49,6 +53,7 @@
|
||||
item_state = "caphat"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/captain
|
||||
beepsky_fashion = /datum/beepsky_fashion/captain
|
||||
|
||||
/obj/item/clothing/head/collectable/police
|
||||
name = "collectable police officer's hat"
|
||||
@@ -91,6 +96,7 @@
|
||||
item_state = "pirate"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/pirate
|
||||
beepsky_fashion = /datum/beepsky_fashion/pirate
|
||||
|
||||
/obj/item/clothing/head/collectable/kitty
|
||||
name = "collectable kitty ears"
|
||||
@@ -100,6 +106,7 @@
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/kitty
|
||||
beepsky_fashion = /datum/beepsky_fashion/cat
|
||||
|
||||
/obj/item/clothing/head/collectable/rabbitears
|
||||
name = "collectable rabbit ears"
|
||||
@@ -116,6 +123,7 @@
|
||||
icon_state = "wizard"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/blue_wizard
|
||||
beepsky_fashion = /datum/beepsky_fashion/wizard
|
||||
|
||||
/obj/item/clothing/head/collectable/hardhat
|
||||
name = "collectable hard hat"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
dynamic_hair_suffix = "+generic"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
beepsky_fashion = /datum/beepsky_fashion/engineer
|
||||
|
||||
|
||||
/obj/item/clothing/head/hardhat/ComponentInitialize()
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
strip_delay = 10
|
||||
equip_delay_other = 10
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/chef
|
||||
beepsky_fashion = /datum/beepsky_fashion/chef
|
||||
|
||||
/obj/item/clothing/head/chefhat/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is donning [src]! It looks like [user.p_theyre()] trying to become a chef.</span>")
|
||||
@@ -33,7 +35,9 @@
|
||||
flags_inv = 0
|
||||
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
strip_delay = 60
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/captain
|
||||
beepsky_fashion = /datum/beepsky_fashion/captain
|
||||
|
||||
//Captain: This is no longer space-worthy
|
||||
/obj/item/clothing/head/caphat/parade
|
||||
|
||||
@@ -20,9 +20,11 @@
|
||||
desc = "It's an amish looking hat."
|
||||
icon_state = "tophat"
|
||||
item_state = "that"
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
throwforce = 1
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
beepsky_fashion = /datum/beepsky_fashion/tophat
|
||||
|
||||
/obj/item/clothing/head/canada
|
||||
name = "striped red tophat"
|
||||
desc = "It smells like fresh donut holes. / <i>Il sent comme des trous de beignets frais.</i>"
|
||||
@@ -126,7 +128,9 @@
|
||||
desc = "Yarr."
|
||||
icon_state = "pirate"
|
||||
item_state = "pirate"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/pirate
|
||||
beepsky_fashion = /datum/beepsky_fashion/pirate
|
||||
|
||||
/obj/item/clothing/head/pirate/captain
|
||||
name = "pirate captain hat"
|
||||
@@ -189,6 +193,8 @@
|
||||
desc = "A really cool hat if you're a mobster. A really lame hat if you're not."
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small
|
||||
|
||||
beepsky_fashion = /datum/beepsky_fashion/fedora
|
||||
|
||||
/obj/item/clothing/head/fedora/suicide_act(mob/user)
|
||||
if(user.gender == FEMALE)
|
||||
return 0
|
||||
@@ -205,7 +211,9 @@
|
||||
item_state = "sombrero"
|
||||
desc = "You can practically taste the fiesta."
|
||||
flags_inv = HIDEHAIR
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/sombrero
|
||||
beepsky_fashion = /datum/beepsky_fashion/sombrero
|
||||
|
||||
/obj/item/clothing/head/sombrero/green
|
||||
name = "green sombrero"
|
||||
@@ -213,6 +221,7 @@
|
||||
item_state = "greensombrero"
|
||||
desc = "As elegant as a dancing cactus."
|
||||
flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
|
||||
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/sombrero/shamebrero
|
||||
@@ -220,6 +229,7 @@
|
||||
icon_state = "shamebrero"
|
||||
item_state = "shamebrero"
|
||||
desc = "Once it's on, it never comes off."
|
||||
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/sombrero/shamebrero/Initialize()
|
||||
@@ -248,7 +258,9 @@
|
||||
item_state = "that"
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/santa
|
||||
beepsky_fashion = /datum/beepsky_fashion/santa
|
||||
|
||||
/obj/item/clothing/head/jester
|
||||
name = "jester hat"
|
||||
@@ -286,6 +298,8 @@
|
||||
resistance_flags = FIRE_PROOF
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
beepsky_fashion = /datum/beepsky_fashion/king
|
||||
|
||||
/obj/item/clothing/head/crown/fancy
|
||||
name = "magnificent crown"
|
||||
desc = "A crown worn by only the highest emperors of the <s>land</s> space."
|
||||
@@ -391,7 +405,9 @@
|
||||
name = "cowboy hat"
|
||||
desc = "A standard brown cowboy hat, yeehaw."
|
||||
icon_state = "cowboyhat"
|
||||
item_state= "cowboyhat"
|
||||
item_state = "cowboyhat"
|
||||
|
||||
beepsky_fashion = /datum/beepsky_fashion/cowboy
|
||||
|
||||
/obj/item/clothing/head/cowboyhat/black
|
||||
name = "black cowboy hat"
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
flags_cover = HEADCOVERSEYES
|
||||
heat = 1000
|
||||
|
||||
beepsky_fashion = /datum/beepsky_fashion/cake
|
||||
|
||||
/obj/item/clothing/head/hardhat/cakehat/process()
|
||||
var/turf/location = src.loc
|
||||
if(ishuman(location))
|
||||
@@ -131,6 +133,7 @@
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/kitty
|
||||
beepsky_fashion = /datum/beepsky_fashion/cat
|
||||
|
||||
/obj/item/clothing/head/kitty/equipped(mob/living/carbon/human/user, slot)
|
||||
if(ishuman(user) && slot == SLOT_HEAD)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/modifies_speech = FALSE
|
||||
var/mask_adjusted = 0
|
||||
var/adjusted_flags = null
|
||||
var/datum/beepsky_fashion/beepsky_fashion //the associated datum for applying this to a secbot
|
||||
|
||||
/obj/item/clothing/mask/attack_self(mob/user)
|
||||
if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE))
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
equip_delay_other = 50
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
dog_fashion = /datum/dog_fashion/head/blue_wizard
|
||||
beepsky_fashion = /datum/beepsky_fashion/wizard
|
||||
var/magic_flags = SPELL_WIZARD_HAT
|
||||
|
||||
/obj/item/clothing/head/wizard/ComponentInitialize()
|
||||
|
||||
@@ -163,8 +163,8 @@
|
||||
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!</B>\n"
|
||||
else
|
||||
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!</B>\n"
|
||||
for(var/datum/wound/W in BP.wounds)
|
||||
msg += "[W.get_examine_description(user)]\n"
|
||||
for(var/datum/wound/W in BP.wounds)
|
||||
msg += "[W.get_examine_description(user)]\n"
|
||||
|
||||
for(var/X in disabled)
|
||||
var/obj/item/bodypart/BP = X
|
||||
|
||||
@@ -7,7 +7,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/id // if the game needs to manually check your race to do something not included in a proc here, it will use this
|
||||
var/limbs_id //this is used if you want to use a different species limb sprites. Mainly used for angels as they look like humans.
|
||||
var/name // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
|
||||
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
|
||||
var/default_color = "#FFFFFF" // if alien colors are disabled, this is the color that will be used by that race
|
||||
|
||||
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
|
||||
var/has_field_of_vision = TRUE
|
||||
@@ -854,10 +854,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/g = (H.dna.features["body_model"] == FEMALE) ? "f" : "m"
|
||||
var/list/colorlist = list()
|
||||
var/husk = HAS_TRAIT(H, TRAIT_HUSK)
|
||||
colorlist += husk ? ReadRGB("#a3a3a3") :ReadRGB("[H.dna.features["mcolor"]]0")
|
||||
colorlist += husk ? ReadRGB("#a3a3a3") :ReadRGB("[H.dna.features["mcolor2"]]0")
|
||||
colorlist += husk ? ReadRGB("#a3a3a3") : ReadRGB("[H.dna.features["mcolor3"]]0")
|
||||
colorlist += list(0,0,0, hair_alpha)
|
||||
colorlist += husk ? ReadRGB("#a3a3a3") : ReadRGB("[H.dna.features["mcolor"]]00")
|
||||
colorlist += husk ? ReadRGB("#a3a3a3") : ReadRGB("[H.dna.features["mcolor2"]]00")
|
||||
colorlist += husk ? ReadRGB("#a3a3a3") : ReadRGB("[H.dna.features["mcolor3"]]00")
|
||||
colorlist += husk ? list(0, 0, 0) : list(0, 0, 0, hair_alpha)
|
||||
for(var/index in 1 to colorlist.len)
|
||||
colorlist[index] /= 255
|
||||
|
||||
@@ -1031,7 +1031,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.apply_overlay(BODY_FRONT_LAYER)
|
||||
H.apply_overlay(HORNS_LAYER)
|
||||
|
||||
|
||||
/*
|
||||
* Equip the outfit required for life. Replaces items currently worn.
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
default_color = "00FF00"
|
||||
species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR,CAN_SCAR)
|
||||
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
|
||||
mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None",
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None",
|
||||
"insect_wings" = "None", "insect_fluff" = "None", "mam_snouts" = "None", "taur" = "None", "insect_markings" = "None")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR,CAN_SCAR)
|
||||
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BEAST
|
||||
mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
|
||||
"mam_body_markings" = "Husky", "taur" = "None", "horns" = "None", "legs" = "Plantigrade", "meat_type" = "Mammalian")
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
default_color = "FFFFFF"
|
||||
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR,CAN_SCAR)
|
||||
mutant_bodyparts = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF","tail_human" = "None", "ears" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
disliked_food = GROSS | RAW
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR)
|
||||
mutantlungs = /obj/item/organ/lungs/slime
|
||||
mutant_heart = /obj/item/organ/heart/slime
|
||||
mutant_bodyparts = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
gib_types = list(/obj/effect/gibspawner/slime, /obj/effect/gibspawner/slime/bodypartless)
|
||||
@@ -443,7 +443,7 @@
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
|
||||
say_mod = "says"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 160 //a notch brighter so it blends better.
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
name = "Anthromorphic Plant"
|
||||
id = "podweak"
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS)
|
||||
mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs")
|
||||
limbs_id = "pod"
|
||||
light_nutrition_gain_factor = 3
|
||||
light_bruteheal = -0.2
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD)
|
||||
inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
|
||||
mutant_bodyparts = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "deco_wings" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "tail_human" = "None", "ears" = "None", "deco_wings" = "None")
|
||||
exotic_bloodtype = "U"
|
||||
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
|
||||
mutant_heart = /obj/item/organ/heart/vampire
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Splits off into PhysicalLife() and BiologicalLife(). Override those instead of this.
|
||||
*/
|
||||
/mob/living/proc/Life(seconds, times_fired)
|
||||
set waitfor = FALSE // yeah hey we're kind of on a subsystem, no sleeping will be tolerated here!
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
if(mob_transforming)
|
||||
return
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
handle_diginvis() //AI becomes unable to see mob
|
||||
|
||||
if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating
|
||||
float(on = TRUE)
|
||||
INVOKE_ASYNC(src, /atom/movable.proc/float, TRUE)
|
||||
|
||||
if(!loc)
|
||||
return FALSE
|
||||
|
||||
@@ -803,7 +803,7 @@
|
||||
else
|
||||
throw_alert("gravity", /obj/screen/alert/weightless)
|
||||
if(!override && !is_flying())
|
||||
float(!has_gravity)
|
||||
INVOKE_ASYNC(src, /atom/movable.proc/float, !has_gravity)
|
||||
|
||||
/mob/living/float(on)
|
||||
if(throwing)
|
||||
|
||||
@@ -102,6 +102,10 @@
|
||||
var/can_salute = TRUE
|
||||
var/salute_delay = 60 SECONDS
|
||||
|
||||
//emotes/speech stuff
|
||||
var/patrol_emote = "Engaging patrol mode."
|
||||
var/patrol_fail_emote = "Unable to start patrol."
|
||||
|
||||
/mob/living/simple_animal/bot/proc/get_mode()
|
||||
if(client) //Player bots do not have modes, thus the override. Also an easy way for PDA users/AI to know when a bot is a player.
|
||||
if(paicard)
|
||||
@@ -611,7 +615,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
if(tries >= BOT_STEP_MAX_RETRIES) //Bot is trapped, so stop trying to patrol.
|
||||
auto_patrol = 0
|
||||
tries = 0
|
||||
speak("Unable to start patrol.")
|
||||
speak(patrol_fail_emote)
|
||||
|
||||
return
|
||||
|
||||
@@ -627,7 +631,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
return
|
||||
mode = BOT_PATROL
|
||||
else // no patrol target, so need a new one
|
||||
speak("Engaging patrol mode.")
|
||||
speak(patrol_emote)
|
||||
find_patrol_target()
|
||||
tries++
|
||||
return
|
||||
|
||||
@@ -33,6 +33,20 @@
|
||||
var/check_records = TRUE //Does it check security records?
|
||||
var/arrest_type = FALSE //If true, don't handcuff
|
||||
|
||||
var/obj/item/clothing/head/bot_accessory
|
||||
var/datum/beepsky_fashion/stored_fashion
|
||||
|
||||
//emotes (BOT is replaced with bot name, CRIMINAL with criminal name, THREAT_LEVEL with threat level)
|
||||
var/death_emote = "BOT blows apart!"
|
||||
var/capture_one = "BOT is trying to put zipties on CRIMINAL!"
|
||||
var/capture_two = "BOT is trying to put zipties on you!"
|
||||
var/infraction = "Level THREAT_LEVEL infraction alert!"
|
||||
var/taunt = "<b>BOT</b> points at CRIMINAL!"
|
||||
var/attack_one = "BOT has stunned CRIMINAL!"
|
||||
var/attack_two = "BOT has stunned you!"
|
||||
var/list/arrest_texts = list("Detaining", "Arresting")
|
||||
var/arrest_emote = "ARREST_TYPE level THREAT_LEVEL scumbag CRIMINAL in LOCATION."
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky
|
||||
name = "Officer Beep O'sky"
|
||||
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
|
||||
@@ -49,6 +63,103 @@
|
||||
resize = 0.8
|
||||
update_transform()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/process_emote(var/emote_type, var/atom/criminal, var/threat, var/arrest = -1, var/location)
|
||||
var/emote = "The continuity of space itself collapses around [src]. You should probably report that to someone higher up."
|
||||
switch(emote_type)
|
||||
if("DEATH")
|
||||
emote = death_emote
|
||||
if("CAPTURE_ONE")
|
||||
emote = capture_one
|
||||
if("CAPTURE_TWO")
|
||||
emote = capture_two
|
||||
if("INFRACTION")
|
||||
emote = infraction
|
||||
if("TAUNT")
|
||||
emote = taunt
|
||||
if("ATTACK_ONE")
|
||||
emote = attack_one
|
||||
if("ATTACK_TWO")
|
||||
emote = attack_two
|
||||
if("ARREST")
|
||||
emote = arrest_emote
|
||||
|
||||
//now replace pieces of the text with the information we have
|
||||
if(emote_type != "TAUNT" && emote_type != "ARREST")
|
||||
emote = replacetext(emote, "BOT", name)
|
||||
else
|
||||
emote = replacetext(emote, "BOT", "<b>[name]</b>") //needs to be bold if its a taunt or an arrest text
|
||||
if(criminal)
|
||||
emote = replacetext(emote, "CRIMINAL", criminal.name)
|
||||
if(num2text(threat)) //because a threat of 0 will be false
|
||||
emote = replacetext(emote, "THREAT_LEVEL", threat)
|
||||
if(arrest > -1)
|
||||
emote = replacetext(emote, "ARREST_TYPE", arrest_texts[arrest + 1])
|
||||
if(location)
|
||||
emote = replacetext(emote, "LOCATION", location)
|
||||
return emote
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/apply_fashion(var/datum/beepsky_fashion/fashion)
|
||||
stored_fashion = new fashion
|
||||
if(stored_fashion.name)
|
||||
name = stored_fashion.name
|
||||
|
||||
if(stored_fashion.desc)
|
||||
desc = stored_fashion.desc
|
||||
|
||||
if(stored_fashion.death_emote)
|
||||
death_emote = stored_fashion.death_emote
|
||||
|
||||
if(stored_fashion.capture_one)
|
||||
capture_one = stored_fashion.capture_one
|
||||
|
||||
if(stored_fashion.capture_two)
|
||||
capture_two = stored_fashion.capture_two
|
||||
|
||||
if(stored_fashion.infraction)
|
||||
infraction = stored_fashion.infraction
|
||||
|
||||
if(stored_fashion.taunt)
|
||||
taunt = stored_fashion.taunt
|
||||
|
||||
if(stored_fashion.attack_one)
|
||||
attack_one = stored_fashion.attack_one
|
||||
|
||||
if(stored_fashion.attack_two)
|
||||
attack_two = stored_fashion.attack_two
|
||||
|
||||
if(stored_fashion.patrol_emote)
|
||||
patrol_emote = stored_fashion.patrol_emote
|
||||
|
||||
if(stored_fashion.patrol_fail_emote)
|
||||
patrol_fail_emote = stored_fashion.patrol_fail_emote
|
||||
|
||||
if(stored_fashion.arrest_texts)
|
||||
arrest_texts = stored_fashion.arrest_texts
|
||||
|
||||
if(stored_fashion.arrest_emote)
|
||||
arrest_emote = stored_fashion.arrest_emote
|
||||
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/reset_fashion()
|
||||
bot_accessory.forceMove(get_turf(src))
|
||||
//reset all emotes/sounds and name/desc
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
death_emote = initial(death_emote)
|
||||
capture_one = initial(capture_one)
|
||||
capture_two = initial(capture_two)
|
||||
infraction = initial(infraction)
|
||||
taunt = initial(taunt)
|
||||
attack_one = initial(attack_one)
|
||||
attack_two = initial(attack_two)
|
||||
arrest_texts = initial(arrest_texts)
|
||||
arrest_emote = initial(arrest_emote)
|
||||
patrol_emote = initial(patrol_emote)
|
||||
arrest_texts = initial(arrest_texts)
|
||||
arrest_emote = initial(arrest_emote)
|
||||
bot_accessory = null
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/explode()
|
||||
var/atom/Tsec = drop_location()
|
||||
@@ -178,6 +289,11 @@ Auto Patrol: []"},
|
||||
retaliate(H)
|
||||
if(special_retaliate_after_attack(H))
|
||||
return
|
||||
if(H.a_intent == INTENT_HELP && bot_accessory)
|
||||
|
||||
to_chat(H, "<span class='warning'>You knock [bot_accessory] off of [src]'s head!</span>")
|
||||
reset_fashion()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -185,11 +301,48 @@ Auto Patrol: []"},
|
||||
..()
|
||||
if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
|
||||
return
|
||||
if(istype(W, /obj/item/clothing/head))
|
||||
attempt_place_on_head(user, W)
|
||||
return
|
||||
if(!istype(W, /obj/item/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
|
||||
retaliate(user)
|
||||
if(special_retaliate_after_attack(user))
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/attempt_place_on_head(mob/user, obj/item/clothing/head/H)
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(H))
|
||||
to_chat(user, "<span class='warning'>\The [H] is stuck to your hand, you cannot put it on [src]'s head!</span>")
|
||||
return
|
||||
if(bot_accessory)
|
||||
to_chat("<span class='warning'>\[src] already has an accessory, and the laws of physics disallow him from wearing a second!</span>")
|
||||
return
|
||||
|
||||
if(H.beepsky_fashion)
|
||||
to_chat(user, "<span class='warning'>You set [H] on [src].</span>")
|
||||
bot_accessory = H
|
||||
H.forceMove(src)
|
||||
apply_fashion(H.beepsky_fashion)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You set [H] on [src]'s head, but it falls off!</span>")
|
||||
H.forceMove(drop_location())
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/regenerate_icons()
|
||||
..()
|
||||
if(bot_accessory)
|
||||
if(!stored_fashion)
|
||||
stored_fashion = new bot_accessory.beepsky_fashion
|
||||
if(!stored_fashion.obj_icon_state)
|
||||
stored_fashion.obj_icon_state = bot_accessory.icon_state
|
||||
if(!stored_fashion.obj_alpha)
|
||||
stored_fashion.obj_alpha = bot_accessory.alpha
|
||||
if(!stored_fashion.obj_color)
|
||||
stored_fashion.obj_color = bot_accessory.color
|
||||
add_overlay(stored_fashion.get_overlay())
|
||||
else
|
||||
if(stored_fashion)
|
||||
cut_overlay(stored_fashion.get_overlay())
|
||||
stored_fashion = null
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(emagged == 2)
|
||||
@@ -233,8 +386,8 @@ Auto Patrol: []"},
|
||||
/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
|
||||
mode = BOT_ARREST
|
||||
playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
C.visible_message("<span class='danger'>[process_emote("CAPTURE_ONE", C)]</span>",\
|
||||
"<span class='userdanger'>[process_emote("CAPTURE_TWO", C)]</span>")
|
||||
if(do_after(src, 60, FALSE, C))
|
||||
attempt_handcuff(C)
|
||||
|
||||
@@ -249,16 +402,22 @@ Auto Patrol: []"},
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
|
||||
var/judgement_criteria = judgement_criteria()
|
||||
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
|
||||
icon_state = "secbot-c"
|
||||
addtimer(CALLBACK(src, /atom/.proc/update_icon), 2)
|
||||
var/threat = 5
|
||||
if(ishuman(C))
|
||||
if(stored_fashion)
|
||||
stored_fashion.stun_attack(C)
|
||||
if(stored_fashion.stun_sounds && !stored_fashion.ignore_sound)
|
||||
playsound(src, pick(stored_fashion.stun_sounds), 50, TRUE, -1)
|
||||
else
|
||||
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
|
||||
C.stuttering = 5
|
||||
C.DefaultCombatKnockdown(100)
|
||||
var/mob/living/carbon/human/H = C
|
||||
threat = H.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
else
|
||||
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
|
||||
C.DefaultCombatKnockdown(100)
|
||||
C.stuttering = 5
|
||||
threat = C.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
@@ -266,9 +425,9 @@ Auto Patrol: []"},
|
||||
log_combat(src,C,"stunned")
|
||||
if(declare_arrests)
|
||||
var/area/location = get_area(src)
|
||||
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
|
||||
C.visible_message("<span class='danger'>[src] has stunned [C]!</span>",\
|
||||
"<span class='userdanger'>[src] has stunned you!</span>")
|
||||
speak(process_emote("ARREST", C, threat, arrest_type, location), radio_channel)
|
||||
C.visible_message("<span class='danger'>[process_emote("ATTACK_ONE", C)]</span>",\
|
||||
"<span class='userdanger'>[process_emote("ATTACK_TWO", C)]</span>")
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/handle_automated_action()
|
||||
if(!..())
|
||||
@@ -355,7 +514,6 @@ Auto Patrol: []"},
|
||||
look_for_perp()
|
||||
bot_patrol()
|
||||
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
|
||||
@@ -391,9 +549,9 @@ Auto Patrol: []"},
|
||||
else if(threatlevel >= 4)
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
speak(process_emote("INFRACTION", target, threatlevel))
|
||||
playsound(loc, pick('sound/voice/beepsky/criminal.ogg', 'sound/voice/beepsky/justice.ogg', 'sound/voice/beepsky/freeze.ogg'), 50, FALSE)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
visible_message(process_emote("TAUNT", target, threatlevel))
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
break
|
||||
@@ -408,7 +566,7 @@ Auto Patrol: []"},
|
||||
/mob/living/simple_animal/bot/secbot/explode()
|
||||
|
||||
walk_to(src,0)
|
||||
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
|
||||
visible_message("<span class='boldannounce'>[process_emote("DEATH")]</span>")
|
||||
var/atom/Tsec = drop_location()
|
||||
|
||||
var/obj/item/bot_assembly/secbot/Sa = new (Tsec)
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
/obj/structure/leaper_bubble/Initialize()
|
||||
. = ..()
|
||||
float(on = TRUE)
|
||||
INVOKE_ASYNC(src, /atom/movable.proc/float, TRUE)
|
||||
QDEL_IN(src, 100)
|
||||
|
||||
/obj/structure/leaper_bubble/Destroy()
|
||||
|
||||
@@ -932,6 +932,9 @@
|
||||
return "[area.name] : [equipment]/[lighting]/[environ] ([lastused_equip+lastused_light+lastused_environ]) : [cell? cell.percent() : "N/C"] ([charging])"
|
||||
|
||||
/obj/machinery/power/apc/proc/update()
|
||||
var/old_light = area.power_light
|
||||
var/old_equip = area.power_equip
|
||||
var/old_environ = area.power_environ
|
||||
if(operating && !shorted && !failure_timer)
|
||||
area.power_light = (lighting > 1)
|
||||
area.power_equip = (equipment > 1)
|
||||
@@ -940,7 +943,8 @@
|
||||
area.power_light = FALSE
|
||||
area.power_equip = FALSE
|
||||
area.power_environ = FALSE
|
||||
area.power_change()
|
||||
if(old_light != area.power_light || old_equip != area.power_equip || old_environ != area.power_environ)
|
||||
area.power_change()
|
||||
|
||||
/obj/machinery/power/apc/proc/can_use(mob/user, loud = 0) //used by attack_hand() and Topic()
|
||||
if(IsAdminGhost(user))
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
var/pixel_move_interrupted = FALSE
|
||||
|
||||
/// Pixels moved per second.
|
||||
var/pixels_per_second = TILES_TO_PIXELS(12.5)
|
||||
var/pixels_per_second = TILES_TO_PIXELS(17.5)
|
||||
/// The number of pixels we increment by. THIS IS NOT SPEED, DO NOT TOUCH THIS UNLESS YOU KNOW WHAT YOU ARE DOING. In general, lower values means more linetrace accuracy up to a point at cost of performance.
|
||||
var/pixel_increment_amount
|
||||
|
||||
|
||||
@@ -2336,3 +2336,53 @@
|
||||
reagent_state = SOLID
|
||||
color = "#E6E6DA"
|
||||
taste_mult = 0
|
||||
|
||||
|
||||
/datum/reagent/hairball
|
||||
name = "Hairball"
|
||||
description = "A bundle of keratinous bits and fibers, not easily digestible."
|
||||
reagent_state = SOLID
|
||||
can_synth = FALSE
|
||||
metabolization_rate = 0.05 * REAGENTS_METABOLISM
|
||||
taste_description = "wet hair"
|
||||
var/amount = 0
|
||||
var/knotted = FALSE
|
||||
|
||||
/datum/reagent/hairball/on_mob_life(mob/living/carbon/M)
|
||||
amount = M.reagents.get_reagent_amount(/datum/reagent/hairball)
|
||||
|
||||
if(amount < 10)
|
||||
if(prob(10))
|
||||
M.losebreath += 1
|
||||
M.emote("cough")
|
||||
to_chat(M, "<span class='notice'>You clear your throat.</span>")
|
||||
else
|
||||
if(!knotted)
|
||||
to_chat(M, "<span class='notice'>You feel a knot in your stomach.</span>")
|
||||
knotted = TRUE
|
||||
|
||||
if(prob(5 + amount * 0.5)) // don't want this to cause too much damage
|
||||
M.losebreath += 2
|
||||
to_chat(M, "<span class='notice'>You feel a knot in your throat.</span>")
|
||||
M.emote("cough")
|
||||
|
||||
else if(prob(amount - 4))
|
||||
to_chat(M, "<span class='warning'>Your stomach feels awfully bloated.</span>")
|
||||
playsound(M,'sound/voice/catpeople/distressed.ogg', 50, FALSE)
|
||||
M.visible_message("<span class='warning'>[M] seems distressed!.</span>", ignored_mobs=M)
|
||||
|
||||
else if(prob(amount - 8))
|
||||
knotted = FALSE
|
||||
playsound(M,'sound/voice/catpeople/puking.ogg', 110, FALSE)
|
||||
M.Immobilize(30)
|
||||
sleep(30) //snowflake but it works, don't wanna proc this
|
||||
if(QDELETED(M) || QDELETED(src)) //this handles race conditions about m or src not existing.
|
||||
return
|
||||
M.visible_message("<span class='warning'>[M] throws up a hairball! Disgusting!</span>", ignored_mobs=M)
|
||||
new /obj/item/toy/plush/hairball(get_turf(M))
|
||||
to_chat(M, "<span class='notice'>Aaaah that's better!</span>")
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "cleared_stomach", /datum/mood_event/cleared_stomach, name)
|
||||
M.reagents.del_reagent(/datum/reagent/hairball)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
@@ -490,9 +490,9 @@
|
||||
//body marking memes
|
||||
var/list/colorlist = list()
|
||||
colorlist.Cut()
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor"]]0")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor2"]]0")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor3"]]0")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor"]]00")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor2"]]00")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor3"]]00")
|
||||
colorlist += list(0,0,0, S.hair_alpha)
|
||||
for(var/index=1, index<=colorlist.len, index++)
|
||||
colorlist[index] = colorlist[index]/255
|
||||
|
||||
@@ -50,6 +50,81 @@
|
||||
-->
|
||||
<div class="commit sansserif">
|
||||
|
||||
<h2 class="date">26 July 2020</h2>
|
||||
<h3 class="author">DeltaFire15 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Organs now decay again.</li>
|
||||
</ul>
|
||||
<h3 class="author">Iatots updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Licking wounds now may cause you to spit out a hairball once in a while!</li>
|
||||
<li class="rscadd">You can now craft a catgirl plushie with 3 of a new ingredient occasionally found in medbay!</li>
|
||||
</ul>
|
||||
<h3 class="author">dapnee updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">removed legacy public mining shuttle area and remade lounge</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">25 July 2020</h2>
|
||||
<h3 class="author">CameronWoof updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Aloe now has an icon.</li>
|
||||
</ul>
|
||||
<h3 class="author">timothyteakettle updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">beepsky replaces the word THREAT_LEVEL with the actual threat level</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">24 July 2020</h2>
|
||||
<h3 class="author">EmeraldSundisk updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Adds a CMO office, along with Virology and Genetics labs to Omega Station</li>
|
||||
<li class="rscadd">Adds a second chemistry station to the chemistry lab</li>
|
||||
<li class="tweak">Adjusts the locations of some objects in medical to accommodate these new additions</li>
|
||||
<li class="tweak">Relocates the morgue</li>
|
||||
<li class="tweak">Relocates items in impacted areas of maintenance as well as the library</li>
|
||||
<li class="bugfix">Fixes an air line Bartholomew somehow knocked out</li>
|
||||
</ul>
|
||||
<h3 class="author">Linzolle updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">wounds now have a description on examine</li>
|
||||
</ul>
|
||||
<h3 class="author">Owai-Seek updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Meatball Sub, Meatloaf + Meatloaf Slices, Bear Chili, Mashed Potatoes</li>
|
||||
<li class="rscadd">Buttered Potatoes, Fancy Cracker Pack, Spiral Soup, Sweet and Sour Chicken</li>
|
||||
<li class="tweak">Organised the Food DMI a bit.</li>
|
||||
<li class="tweak">Deleted some stray pixels on some sprites.</li>
|
||||
<li class="tweak">Nuggie boxes are now centered correctly.</li>
|
||||
<li class="imageadd">Icons for the the food items in this PR.</li>
|
||||
</ul>
|
||||
<h3 class="author">Sneakyrat6 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Fixes dressers not giving you undies</li>
|
||||
<li class="bugfix">Fixes Snaxi not loading properly because of typos</li>
|
||||
<li class="rscadd">You can now burn photos</li>
|
||||
</ul>
|
||||
<h3 class="author">Zandario updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="spellcheck">Murdered **tipes** and gave birth to **is**.</li>
|
||||
</ul>
|
||||
<h3 class="author">silicons updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">sanitization now doesn't cut off 15.7 or something million possible colors from character preferences (instead of only allowing 16 values for R G and B, it now allows 256 each)</li>
|
||||
<li class="balance">projectiles are by default 17.5 tiles per second instead of 12.5</li>
|
||||
</ul>
|
||||
<h3 class="author">timothyteakettle updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">due to recent innovative research in the medical field, you now have bones</li>
|
||||
<li class="tweak">zombie claws are now sharp and do less damage, but can destroy non-lifeforms far faster</li>
|
||||
<li class="tweak">zombies now take less stamina damage</li>
|
||||
<li class="rscadd">beepsky can now wear hats</li>
|
||||
</ul>
|
||||
<h3 class="author">zeroisthebiggay updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="imageadd">rad and kravglove sprites</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">23 July 2020</h2>
|
||||
<h3 class="author">DeltaFire15 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
|
||||
@@ -26476,3 +26476,54 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
|
||||
- bugfix: tendril chests being empty
|
||||
zeroisthebiggay:
|
||||
- rscadd: fetish content
|
||||
2020-07-24:
|
||||
EmeraldSundisk:
|
||||
- rscadd: Adds a CMO office, along with Virology and Genetics labs to Omega Station
|
||||
- rscadd: Adds a second chemistry station to the chemistry lab
|
||||
- tweak: Adjusts the locations of some objects in medical to accommodate these new
|
||||
additions
|
||||
- tweak: Relocates the morgue
|
||||
- tweak: Relocates items in impacted areas of maintenance as well as the library
|
||||
- bugfix: Fixes an air line Bartholomew somehow knocked out
|
||||
Linzolle:
|
||||
- bugfix: wounds now have a description on examine
|
||||
Owai-Seek:
|
||||
- rscadd: Meatball Sub, Meatloaf + Meatloaf Slices, Bear Chili, Mashed Potatoes
|
||||
- rscadd: Buttered Potatoes, Fancy Cracker Pack, Spiral Soup, Sweet and Sour Chicken
|
||||
- tweak: Organised the Food DMI a bit.
|
||||
- tweak: Deleted some stray pixels on some sprites.
|
||||
- tweak: Nuggie boxes are now centered correctly.
|
||||
- imageadd: Icons for the the food items in this PR.
|
||||
Sneakyrat6:
|
||||
- bugfix: Fixes dressers not giving you undies
|
||||
- bugfix: Fixes Snaxi not loading properly because of typos
|
||||
- rscadd: You can now burn photos
|
||||
Zandario:
|
||||
- spellcheck: Murdered **tipes** and gave birth to **is**.
|
||||
silicons:
|
||||
- tweak: sanitization now doesn't cut off 15.7 or something million possible colors
|
||||
from character preferences (instead of only allowing 16 values for R G and B,
|
||||
it now allows 256 each)
|
||||
- balance: projectiles are by default 17.5 tiles per second instead of 12.5
|
||||
timothyteakettle:
|
||||
- rscadd: due to recent innovative research in the medical field, you now have bones
|
||||
- tweak: zombie claws are now sharp and do less damage, but can destroy non-lifeforms
|
||||
far faster
|
||||
- tweak: zombies now take less stamina damage
|
||||
- rscadd: beepsky can now wear hats
|
||||
zeroisthebiggay:
|
||||
- imageadd: rad and kravglove sprites
|
||||
2020-07-25:
|
||||
CameronWoof:
|
||||
- bugfix: Aloe now has an icon.
|
||||
timothyteakettle:
|
||||
- bugfix: beepsky replaces the word THREAT_LEVEL with the actual threat level
|
||||
2020-07-26:
|
||||
DeltaFire15:
|
||||
- bugfix: Organs now decay again.
|
||||
Iatots:
|
||||
- tweak: Licking wounds now may cause you to spit out a hairball once in a while!
|
||||
- rscadd: You can now craft a catgirl plushie with 3 of a new ingredient occasionally
|
||||
found in medbay!
|
||||
dapnee:
|
||||
- tweak: removed legacy public mining shuttle area and remade lounge
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "timothyteakettle"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "due to recent innovative research in the medical field, you now have bones"
|
||||
@@ -1,9 +0,0 @@
|
||||
author: "Owai-Seek"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Meatball Sub, Meatloaf + Meatloaf Slices, Bear Chili, Mashed Potatoes"
|
||||
- rscadd: "Buttered Potatoes, Fancy Cracker Pack, Spiral Soup, Sweet and Sour Chicken"
|
||||
- tweak: "Organised the Food DMI a bit."
|
||||
- tweak: "Deleted some stray pixels on some sprites."
|
||||
- tweak: "Nuggie boxes are now centered correctly."
|
||||
- imageadd: "Icons for the the food items in this PR."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "Zandario"
|
||||
delete-after: True
|
||||
changes:
|
||||
- spellcheck: "Murdered **tipes** and gave birth to **is**."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "zeroisthebiggay"
|
||||
delete-after: True
|
||||
changes:
|
||||
- imageadd: "rad and kravglove sprites"
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "Sneakyrat6"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "You can now burn photos"
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "Sneakyrat6"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Fixes dressers not giving you undies"
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "Sneakyrat6"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Fixes Snaxi not loading properly because of typos"
|
||||
@@ -1,9 +0,0 @@
|
||||
author: "EmeraldSundisk"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Adds a CMO office, along with Virology and Genetics labs to Omega Station"
|
||||
- rscadd: "Adds a second chemistry station to the chemistry lab"
|
||||
- tweak: "Adjusts the locations of some objects in medical to accommodate these new additions"
|
||||
- tweak: "Relocates the morgue"
|
||||
- tweak: "Relocates items in impacted areas of maintenance as well as the library"
|
||||
- bugfix: "Fixes an air line Bartholomew somehow knocked out"
|
||||
@@ -1,5 +0,0 @@
|
||||
author: "timothyteakettle"
|
||||
delete-after: True
|
||||
changes:
|
||||
- tweak: "zombie claws are now sharp and do less damage, but can destroy non-lifeforms far faster"
|
||||
- tweak: "zombies now take less stamina damage"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
@@ -7,12 +7,12 @@
|
||||
features["ipc_antenna"] = sanitize_inlist(features["ipc_antenna"], GLOB.ipc_antennas_list)
|
||||
//Citadel
|
||||
features["flavor_text"] = sanitize_text(features["flavor_text"], initial(features["flavor_text"]))
|
||||
if(!features["mcolor2"] || features["mcolor"] == "#000")
|
||||
if(!features["mcolor2"] || features["mcolor"] == "#000000")
|
||||
features["mcolor2"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
|
||||
if(!features["mcolor3"] || features["mcolor"] == "#000")
|
||||
if(!features["mcolor3"] || features["mcolor"] == "#000000")
|
||||
features["mcolor3"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
|
||||
features["mcolor2"] = sanitize_hexcolor(features["mcolor2"], 3, 0)
|
||||
features["mcolor3"] = sanitize_hexcolor(features["mcolor3"], 3, 0)
|
||||
features["mcolor2"] = sanitize_hexcolor(features["mcolor2"], 6, FALSE)
|
||||
features["mcolor3"] = sanitize_hexcolor(features["mcolor3"], 6, FALSE)
|
||||
|
||||
|
||||
/datum/preferences/proc/cit_character_pref_save(savefile/S)
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
distressed_cat.ogg from Cat annoyed meow / wail by jbierfeldt at https://freesound.org/people/jbierfeldt/sounds/440735/, chopped up and ogged
|
||||
cat_puking.ogg from catpuking mp3 by NoiseCollector and Mocha the cat at https://freesound.org/people/NoiseCollector/sounds/80778/, chopped up, volume altered and ogged
|
||||
Binary file not shown.
@@ -361,6 +361,7 @@
|
||||
#include "code\datums\ai_laws.dm"
|
||||
#include "code\datums\armor.dm"
|
||||
#include "code\datums\beam.dm"
|
||||
#include "code\datums\beepsky_fashion.dm"
|
||||
#include "code\datums\browser.dm"
|
||||
#include "code\datums\callback.dm"
|
||||
#include "code\datums\chatmessage.dm"
|
||||
|
||||
Reference in New Issue
Block a user