Merge remote-tracking branch 'citadel/master' into clickcd_experimental

This commit is contained in:
silicons
2020-07-25 23:46:27 -07:00
68 changed files with 1463 additions and 815 deletions
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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 -1
View File
@@ -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
+5 -2
View File
@@ -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;\
}
+3 -3
View File
@@ -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)
+96 -25
View File
@@ -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))
+1 -1
View File
@@ -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)
+221
View File
@@ -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//
+2
View File
@@ -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
View File
@@ -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)
-2
View File
@@ -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
+5
View File
@@ -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)
+2
View File
@@ -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)
+22
View File
@@ -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
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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()
+31 -31
View File
@@ -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>")
+17 -13
View File
@@ -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)
+1
View File
@@ -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"
+1
View File
@@ -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()
+4
View File
@@ -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
+18 -2
View File
@@ -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)
+1
View File
@@ -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))
+1
View File
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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()
+5 -1
View File
@@ -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))
+1 -1
View File
@@ -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
..()
+3 -3
View File
@@ -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
+75
View File
@@ -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">
+51
View File
@@ -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.
+2
View File
@@ -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.
+1
View File
@@ -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"