Merge remote-tracking branch 'refs/remotes/origin/master' into syntheticbloods

This commit is contained in:
Poojawa
2019-07-31 19:24:39 -05:00
1257 changed files with 31159 additions and 17321 deletions
@@ -4,7 +4,7 @@
/datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params)
var/saltresult = "The wheel of salt [pick("clatters","screams","vibrates","clanks","resonates","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic"," demonic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog","laughing")] noise")] as it spins violently... And it seems the salt of the day is the "
var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Jecca Qua","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]"
var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]"
var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP","bikeshedding","crossdressing","sprites","semen keg","argument","theft","nerf","screeching","salt","creampie","lewding","murder","kissing","marriage","replacement","fucking","ship","netflix adaptation","dance","remaster","system","voyeur","decoration","pre-order","bukkake","seduction","worship","gangbang","handholding")]"
if(prob(10))
saltresult += "@here for your salt, all day every day"
+54 -28
View File
@@ -14,6 +14,10 @@
var/saved_underwear = ""//saves their underwear so it can be toggled later
var/saved_undershirt = ""
var/saved_socks = ""
var/hidden_underwear = FALSE
var/hidden_undershirt = FALSE
var/hidden_socks = FALSE
/mob/living/carbon/human/New()
..()
@@ -29,6 +33,33 @@
var/list/femcum_fluids = list("femcum")
//Mob procs
/mob/living/carbon/human/proc/underwear_toggle()
set name = "Toggle undergarments"
set category = "Object"
if(ishuman(src))
var/mob/living/carbon/human/humz = src
var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling", "Cancel") in list("Top", "Bottom", "Socks", "All", "Cancel")
if(confirm == "Top")
humz.hidden_undershirt = !humz.hidden_undershirt
if(confirm == "Bottom")
humz.hidden_underwear = !humz.hidden_underwear
if(confirm == "Socks")
humz.hidden_socks = !humz.hidden_socks
if(confirm == "All")
humz.hidden_undershirt = !humz.hidden_undershirt
humz.hidden_underwear = !humz.hidden_underwear
humz.hidden_socks = !humz.hidden_socks
if(confirm == "Cancel")
return
src.update_body()
else
to_chat(src, "Humans only. How the fuck did you get this verb anyway.")
/mob/living/proc/handle_arousal()
@@ -40,7 +71,7 @@
adjustArousalLoss(arousal_rate * S.arousal_gain_rate)
if(dna.features["exhibitionist"] && client)
var/amt_nude = 0
if(is_chest_exposed() && (gender == FEMALE || getorganslot("breasts")))
if(is_chest_exposed() && (getorganslot("breasts")))
amt_nude++
if(is_groin_exposed())
if(getorganslot("penis"))
@@ -64,14 +95,14 @@
/mob/living/proc/adjustArousalLoss(amount, updating_arousal=1)
if(status_flags & GODMODE || !canbearoused)
return 0
return FALSE
arousalloss = CLAMP(arousalloss + amount, min_arousal, max_arousal)
if(updating_arousal)
updatearousal()
/mob/living/proc/setArousalLoss(amount, updating_arousal=1)
if(status_flags & GODMODE || !canbearoused)
return 0
return FALSE
arousalloss = CLAMP(amount, min_arousal, max_arousal)
if(updating_arousal)
updatearousal()
@@ -99,6 +130,8 @@
switch(G.type)
if(/obj/item/organ/genital/penis)
S = GLOB.cock_shapes_list[G.shape]
if(/obj/item/organ/genital/testicles)
S = GLOB.balls_shapes_list[G.shape]
if(/obj/item/organ/genital/vagina)
S = GLOB.vagina_shapes_list[G.shape]
if(/obj/item/organ/genital/breasts)
@@ -112,54 +145,54 @@
G.update_appearance()
/mob/living/proc/update_arousal_hud()
return 0
return FALSE
/datum/species/proc/update_arousal_hud(mob/living/carbon/human/H)
return 0
return FALSE
/mob/living/carbon/human/update_arousal_hud()
if(!client || !hud_used)
return 0
return FALSE
if(dna.species.update_arousal_hud())
return 0
return FALSE
if(!canbearoused)
hud_used.arousal.icon_state = ""
return 0
return FALSE
else
if(hud_used.arousal)
if(stat == DEAD)
hud_used.arousal.icon_state = "arousal0"
return 1
return TRUE
if(getArousalLoss() == max_arousal)
hud_used.arousal.icon_state = "arousal100"
return 1
return TRUE
if(getArousalLoss() >= (max_arousal / 100) * 90)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal90"
return 1
return TRUE
if(getArousalLoss() >= (max_arousal / 100) * 80)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal80"
return 1
return TRUE
if(getArousalLoss() >= (max_arousal / 100) * 70)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal70"
return 1
return TRUE
if(getArousalLoss() >= (max_arousal / 100) * 60)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal60"
return 1
return TRUE
if(getArousalLoss() >= (max_arousal / 100) * 50)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal50"
return 1
return TRUE
if(getArousalLoss() >= (max_arousal / 100) * 40)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal40"
return 1
return TRUE
if(getArousalLoss() >= (max_arousal / 100) * 30)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal30"
return 1
return TRUE
if(getArousalLoss() >= (max_arousal / 100) * 20)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal10"
return 1
return TRUE
if(getArousalLoss() >= (max_arousal / 100) * 10)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal10"
return 1
return TRUE
else
hud_used.arousal.icon_state = "arousal0"
@@ -171,11 +204,11 @@
/obj/screen/arousal/Click()
if(!isliving(usr))
return 0
return FALSE
var/mob/living/M = usr
if(M.canbearoused)
M.mob_climax()
return 1
return TRUE
else
to_chat(M, "<span class='warning'>Arousal is disabled. Feature is unavailable.</span>")
@@ -196,13 +229,6 @@
"<span class='userdanger'>You have relieved yourself.</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
setArousalLoss(min_arousal)
/*
switch(gender)
if(MALE)
PoolOrNew(/obj/effect/decal/cleanable/semen, loc)
if(FEMALE)
PoolOrNew(/obj/effect/decal/cleanable/femcum, loc)
*/
else
to_chat(src, "<span class='notice'>You aren't aroused enough for that.</span>")
@@ -5,7 +5,6 @@
icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
zone = "chest"
slot = "breasts"
w_class = 3
size = BREASTS_SIZE_DEF
fluid_id = "milk"
var/amount = 2
@@ -14,7 +13,7 @@
can_masturbate_with = TRUE
masturbation_verb = "massage"
can_climax = TRUE
fluid_transfer_factor =0.5
fluid_transfer_factor = 0.5
/obj/item/organ/genital/breasts/Initialize()
. = ..()
@@ -40,6 +39,10 @@
switch(lowershape)
if("pair")
desc = "You see a pair of breasts."
if("quad")
desc = "You see two pairs of breast, one just under the other."
if("sextuple")
desc = "You see three sets of breasts, running from their chest to their belly."
else
desc = "You see some breasts, they seem to be quite exotic."
if (size)
@@ -54,13 +57,11 @@
if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow...
var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need.
color = "#[skintone2hex(H.skin_tone)]"
string = "breasts_[lowertext(shape)]_[size]-s"
string = "breasts_[GLOB.breasts_shapes_icons[shape]]_[size]-s"
else
color = "#[owner.dna.features["breasts_color"]]"
string = "breasts_[lowertext(shape)]_[size]"
string = "breasts_[GLOB.breasts_shapes_icons[shape]]_[size]"
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
icon_state = sanitize_text(string)
@@ -6,7 +6,6 @@
zone = "groin"
slot = "testicles"
color = null //don't use the /genital color since it already is colored
w_class = 3
internal = TRUE
var/egg_girth = EGG_GIRTH_DEF
var/cum_mult = CUM_RATE_MULT
@@ -1,25 +1,26 @@
/obj/item/organ/genital
color = "#fcccb3"
var/shape = "human"
var/sensitivity = 1
var/list/genital_flags = list()
var/can_masturbate_with = FALSE
var/masturbation_verb = "masturbate"
var/can_climax = FALSE
var/fluid_transfer_factor = 0.0 //How much would a partner get in them if they climax using this?
var/size = 2 //can vary between num or text, just used in icon_state strings
var/fluid_id = null
var/fluid_max_volume = 50
var/fluid_efficiency = 1
var/fluid_rate = 1
var/fluid_mult = 1
var/producing = FALSE
var/aroused_state = FALSE //Boolean used in icon_state strings
var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons.
w_class = WEIGHT_CLASS_NORMAL
var/shape = "human"
var/sensitivity = AROUSAL_START_VALUE
var/list/genital_flags = list()
var/can_masturbate_with = FALSE
var/masturbation_verb = "masturbate"
var/can_climax = FALSE
var/fluid_transfer_factor = 0.0 //How much would a partner get in them if they climax using this?
var/size = 2 //can vary between num or text, just used in icon_state strings
var/fluid_id = null
var/fluid_max_volume = 50
var/fluid_efficiency = 1
var/fluid_rate = 1
var/fluid_mult = 1
var/producing = FALSE
var/aroused_state = FALSE //Boolean used in icon_state strings
var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons.
var/obj/item/organ/genital/linked_organ
var/through_clothes = FALSE
var/internal = FALSE
var/hidden = FALSE
var/through_clothes = FALSE
var/internal = FALSE
var/hidden = FALSE
/obj/item/organ/genital/Initialize()
. = ..()
@@ -72,7 +73,7 @@
owner.exposed_genitals += src
if("Hidden by clothes")
through_clothes = FALSE
hidden = FALSE
hidden = TRUE
if(src in owner.exposed_genitals)
owner.exposed_genitals -= src
if("Always hidden")
@@ -140,14 +141,14 @@
if (NOGENITALS in dna.species.species_traits)
return
//Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
if(dna.features["has_breasts"])
give_breasts()
if(dna.features["has_vag"])
give_vagina()
if(dna.features["has_womb"])
give_womb()
if(dna.features["has_balls"])
give_balls()
if(dna.features["has_breasts"]) // since we have multi-boobs as a thing, we'll want to at least draw over these. but not over the pingas.
give_breasts()
if(dna.features["has_cock"])
give_penis()
if(dna.features["has_ovi"])
@@ -165,7 +166,7 @@
P.Insert(src)
if(P)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
P.color = skintone2hex(skin_tone)
P.color = "#[skintone2hex(skin_tone)]"
else
P.color = "#[dna.features["cock_color"]]"
P.length = dna.features["cock_length"]
@@ -181,13 +182,18 @@
if(!getorganslot("testicles"))
var/obj/item/organ/genital/testicles/T = new
T.Insert(src)
// if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
// T.color = skintone2hex(skin_tone)
// else
// T.color = "#[dna.features["balls_color"]]"
if(T)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
T.color = "#[skintone2hex(skin_tone)]"
else
T.color = "#[dna.features["balls_color"]]"
T.size = dna.features["balls_size"]
T.sack_size = dna.features["balls_sack_size"]
T.shape = dna.features["balls_shape"]
if(dna.features["balls_shape"] == "Hidden")
T.internal = TRUE
else
T.internal = FALSE
T.fluid_id = dna.features["balls_fluid"]
T.fluid_rate = dna.features["balls_cum_rate"]
T.fluid_mult = dna.features["balls_cum_mult"]
@@ -204,7 +210,7 @@
B.Insert(src)
if(B)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
B.color = skintone2hex(skin_tone)
B.color = "#[skintone2hex(skin_tone)]"
else
B.color = "#[dna.features["breasts_color"]]"
B.size = dna.features["breasts_size"]
@@ -228,7 +234,7 @@
V.Insert(src)
if(V)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
V.color = skintone2hex(skin_tone)
V.color = "#[skintone2hex(skin_tone)]"
else
V.color = "[dna.features["vag_color"]]"
V.shape = "[dna.features["vag_shape"]]"
@@ -280,7 +286,7 @@
return
if(NOGENITALS in species_traits)//golems and such
return
if(H.has_trait(TRAIT_HUSK))
if(HAS_TRAIT(H, TRAIT_HUSK))
return
var/list/genitals_to_add = list()
@@ -297,6 +303,8 @@
for(var/obj/item/organ/O in H.internal_organs)
if(isgenital(O))
var/obj/item/organ/genital/G = O
if(G.hidden)
return //we're gunna just hijack this for updates.
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
genitals_to_add += H.getorganslot(G.slot)
//Now we added all genitals that aren't internal and should be rendered
@@ -311,6 +319,8 @@
switch(G.type)
if(/obj/item/organ/genital/penis)
S = GLOB.cock_shapes_list[G.shape]
if(/obj/item/organ/genital/testicles)
S = GLOB.balls_shapes_list[G.shape]
if(/obj/item/organ/genital/vagina)
S = GLOB.vagina_shapes_list[G.shape]
if(/obj/item/organ/genital/breasts)
@@ -318,6 +328,7 @@
if(!S || S.icon_state == "none")
continue
var/mutable_appearance/genital_overlay = mutable_appearance(S.icon, layer = -layer)
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]_[aroused_state]_[layertext]"
@@ -331,12 +342,15 @@
switch(S.color_src)
if("cock_color")
genital_overlay.color = "#[H.dna.features["cock_color"]]"
if("balls_color")
genital_overlay.color = "#[H.dna.features["balls_color"]]"
if("breasts_color")
genital_overlay.color = "#[H.dna.features["breasts_color"]]"
if("vag_color")
genital_overlay.color = "#[H.dna.features["vag_color"]]"
standing += genital_overlay
if(LAZYLEN(standing))
H.overlays_standing[layer] = standing.Copy()
standing = list()
@@ -55,8 +55,24 @@
center = TRUE //Center the image 'cause 2-tile wide.
dimension_x = 64
//Testicles
//These ones aren't inert
/datum/sprite_accessory/testicles
icon = 'modular_citadel/icons/obj/genitals/testicles_onmob.dmi'
icon_state = "testicle"
name = "testicle" //the preview name of the accessory
color_src = "balls_color"
locked = 0
/datum/sprite_accessory/testicles/hidden
icon_state = "hidden"
name = "Hidden"
alt_aroused = TRUE
/datum/sprite_accessory/testicles/single
icon_state = "single"
name = "Single"
alt_aroused = TRUE
//Vaginas
/datum/sprite_accessory/vagina
@@ -109,6 +125,15 @@
name = "Pair"
alt_aroused = TRUE
/datum/sprite_accessory/breasts/quad
icon_state = "quad"
name = "Quad"
alt_aroused = TRUE
/datum/sprite_accessory/breasts/sextuple
icon_state = "sextuple"
name = "Sextuple"
alt_aroused = TRUE
//OVIPOSITORS BE HERE
/datum/sprite_accessory/ovipositor
@@ -5,14 +5,13 @@
icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
zone = "groin"
slot = ORGAN_SLOT_PENIS
w_class = 3
can_masturbate_with = TRUE
masturbation_verb = "stroke"
can_climax = TRUE
fluid_transfer_factor = 0.5
fluid_transfer_factor = 0.5
size = 2 //arbitrary value derived from length and girth for sprites.
var/length = 6 //inches
var/cached_length //used to detect a change in length
var/cached_length //used to detect a change in length
var/girth = 0
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
@@ -52,15 +51,15 @@
string = "penis_[GLOB.cock_shapes_icons[shape]]_[size]"
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
icon_state = sanitize_text(string)
/obj/item/organ/genital/penis/update_link()
if(owner)
linked_organ = (owner.getorganslot("testicles"))
if(linked_organ)
linked_organ.linked_organ = src
linked_organ.size = size
else
if(linked_organ)
linked_organ.linked_organ = null
@@ -1,17 +1,20 @@
/obj/item/organ/genital/testicles
name = "testicles"
desc = "A male reproductive organ."
icon_state = "testicles"
icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
zone = "groin"
slot = "testicles"
w_class = 3
internal = TRUE
size = BALLS_SIZE_DEF
var/sack_size = BALLS_SACK_SIZE_DEF
fluid_id = "semen"
producing = TRUE
var/sent_full_message = 1 //defaults to 1 since they're full to start
name = "testicles"
desc = "A male reproductive organ."
icon_state = "testicles"
icon = 'modular_citadel/icons/obj/genitals/testicles.dmi'
zone = "groin"
slot = "testicles"
size = BALLS_SIZE_MIN
var/size_name = "average"
shape = "single"
var/sack_size = BALLS_SACK_SIZE_DEF
fluid_id = "semen"
producing = TRUE
can_masturbate_with = FALSE
masturbation_verb = "massage"
can_climax = TRUE
var/sent_full_message = TRUE //defaults to 1 since they're full to start
/obj/item/organ/genital/testicles/Initialize()
. = ..()
@@ -28,9 +31,9 @@
if(reagents.total_volume >= reagents.maximum_volume)
if(!sent_full_message)
send_full_message()
sent_full_message = 1
sent_full_message = TRUE
return FALSE
sent_full_message = 0
sent_full_message = FALSE
update_link()
if(!linked_organ)
return FALSE
@@ -42,6 +45,8 @@
linked_organ = (owner.getorganslot("penis"))
if(linked_organ)
linked_organ.linked_organ = src
size = linked_organ.size
else
if(linked_organ)
linked_organ.linked_organ = null
@@ -49,6 +54,36 @@
/obj/item/organ/genital/testicles/proc/send_full_message(msg = "Your balls finally feel full, again.")
if(owner && istext(msg))
owner << msg
to_chat(owner, msg)
return TRUE
/obj/item/organ/genital/testicles/update_appearance()
switch(size)
if(0.1 to 1)
size_name = "average"
if(1.1 to 2)
size_name = "enlarged"
if(2.1 to INFINITY)
size_name = "engorged"
else
size_name = "nonexistant"
if(!internal)
desc = "You see an [size_name] pair of testicles."
else
desc = "They don't have any testicles you can see."
if(owner)
var/string
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow...
var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need.
color = "#[skintone2hex(H.skin_tone)]"
string = "testicles_[GLOB.balls_shapes_icons[shape]]_[size]-s"
else
color = "#[owner.dna.features["balls_color"]]"
string = "testicles_[GLOB.balls_shapes_icons[shape]]_[size]"
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
@@ -60,10 +60,9 @@
string = "vagina"
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
icon_state = sanitize_text(string)
/obj/item/organ/genital/vagina/update_link()
if(owner)
linked_organ = (owner.getorganslot("womb"))
@@ -5,12 +5,10 @@
icon_state = "womb"
zone = "groin"
slot = "womb"
w_class = 3
internal = TRUE
fluid_id = "femcum"
producing = TRUE
/obj/item/organ/genital/womb/Initialize()
. = ..()
reagents.add_reagent(fluid_id, fluid_max_volume)
@@ -385,4 +385,60 @@ datum/gear/darksabresheath
name = "Black, Red, and Gold Coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/blackredgold
ckeywhitelist = list("ttbnc")
ckeywhitelist = list("ttbnc")
/datum/gear/fritzplush
name = "Fritz Plushie"
category = SLOT_IN_BACKPACK
path = /obj/item/toy/plush/mammal/dog/fritz
ckeywhitelist = list("analwerewolf")
/datum/gear/kimono
name = "Kimono"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/kimono
ckeywhitelist = list("sfox63")
/datum/gear/commjacket
name = "Dusty Commisar's Cloak"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/commjacket
ckeywhitelist = list("sadisticbatter")
/datum/gear/mw2_russian_para
name = "Russian Paratrooper Jumper"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/mw2_russian_para
ckeywhitelist = list("investigator77")
/datum/gear/longblackgloves
name = "Luna's Gauntlets"
category = SLOT_GLOVES
path = /obj/item/clothing/gloves/longblackgloves
ckeywhitelist = list("bigmanclancy")
/datum/gear/trendy_fit
name = "Trendy Fit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/trendy_fit
ckeywhitelist = list("midgetdragon")
/datum/gear/singery
name = "Yellow Performer Outfit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/singery
ckeywhitelist = list("maxlynchy")
/datum/gear/csheet
name = "NT Bedsheet"
category = SLOT_NECK
path = /obj/item/bedsheet/captain
ckeywhitelist = list("tikibomb")
/datum/gear/borgplush
name = "Robot Plush"
category = SLOT_IN_BACKPACK
/obj/item/toy/plush/borgplushie
ckeywhitelist = list("nicholaiavenicci")
@@ -1,5 +1,32 @@
/datum/gear/stethoscope
name = "Medical Briefcase"
category = SLOT_HANDS
path = /obj/item/storage/briefcase/medical
restricted_roles = list("Medical Doctor", "Chief Medical Officer")
/datum/gear/stethoscope
name = "Stethoscope"
category = SLOT_NECK
path = /obj/item/clothing/neck/stethoscope
restricted_roles = list("Medical Doctor", "Chief Medical Officer")
/datum/gear/bluescrubs
name = "Blue Scrubs"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/rank/medical/blue
restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist")
restricted_desc = "Medical"
/datum/gear/greenscrubs
name = "Green Scrubs"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/rank/medical/green
restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist")
restricted_desc = "Medical"
/datum/gear/purplescrubs
name = "Purple Scrubs"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/rank/medical/purple
restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist")
restricted_desc = "Medical"
@@ -1,3 +1,9 @@
/datum/gear/greytidestationwide
name = "Grey jumpsuit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/color/grey
restricted_roles = list("Assistant")
/datum/gear/plushvar
name = "Ratvar Plushie"
category = SLOT_IN_BACKPACK
@@ -79,8 +79,24 @@
path = /obj/item/toy/katana
cost = 3
//datum/gear/lumeyes
// name = "Luminescent eye auto surgeon"
// category = SLOT_IN_BACKPACK
// path = /obj/item/autosurgeon/gloweyes
// cost = 4
/datum/gear/box
name = "Spare box"
category = SLOT_IN_BACKPACK
path = /obj/item/storage/box
cost = 2
/datum/gear/crowbar
name = "Pocket Crowbar"
category = SLOT_IN_BACKPACK
path = /obj/item/crowbar
cost = 2
/datum/gear/tapeplayer
name = "Taperecorder"
category = SLOT_IN_BACKPACK
path = /obj/item/taperecorder
/datum/gear/tape
name = "Spare cassette tape"
category = SLOT_IN_BACKPACK
path = /obj/item/tape/random
@@ -54,6 +54,11 @@
path = /obj/item/clothing/head/flakhelm
cost = 2
/datum/gear/bunnyears
name = "Bunny Ears"
category = SLOT_HEAD
path = /obj/item/clothing/head/rabbitears
//trek fancy Hats!
/datum/gear/trekcap
name = "Federation Officer's Cap (White)"
@@ -73,6 +73,31 @@
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/skirt/purple
/datum/gear/schoolgirlblue
name = "Blue Schoolgirl Uniform"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/schoolgirl
/datum/gear/schoolgirlred
name = "Red Schoolgirl Uniform"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/schoolgirl/red
/datum/gear/schoolgirlgreen
name = "Green Schoolgirl Uniform"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/schoolgirl/green
/datum/gear/schoolgirlorange
name = "Orange Schoolgirl Uniform"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/schoolgirl/orange
/datum/gear/stripeddress
name = "Striped Dress"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/stripeddress
/datum/gear/kilt
name = "Kilt"
category = SLOT_W_UNIFORM
@@ -283,3 +308,9 @@
path = /obj/item/clothing/under/rank/trek/engsec/ent
restricted_desc = "Engineering and Security"
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
//Memes
/datum/gear/gear_harnesses
name = "Gear Harness"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/gear_harness
@@ -56,6 +56,7 @@
WRITE_FILE(S["feature_has_balls"], features["has_balls"])
WRITE_FILE(S["feature_balls_color"], features["balls_color"])
WRITE_FILE(S["feature_balls_size"], features["balls_size"])
WRITE_FILE(S["feature_balls_shape"], features["balls_shape"])
WRITE_FILE(S["feature_balls_sack_size"], features["balls_sack_size"])
WRITE_FILE(S["feature_balls_fluid"], features["balls_fluid"])
//breasts features
@@ -5,7 +5,8 @@
*//////////////////////////////////////////////////////////////////////////////////
// <3 Nienhaus && Joan.
// I made the Voy and DS9 stuff tho. - Poojy
// Armor lists for even Heads of Staff is Nulled out do round start armor as well most armor going onto the suit itself rather then a armor slot - Trilby
///////////////////////////////////////////////////////////////////////////////////
/obj/item/clothing/under/rank/trek
@@ -22,7 +23,7 @@
desc = "The uniform worn by command officers in the mid 2260s."
icon_state = "trek_command"
item_state = "trek_command"
armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 10, "rad" = 10, "fire" = 0, "acid" = 0) // Considering only staff heads get to pick it
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/under/rank/trek/engsec
name = "Operations Uniform"
@@ -104,7 +105,7 @@
/obj/item/reagent_containers/glass/bottle/vial,/obj/item/reagent_containers/glass/beaker,
/obj/item/reagent_containers/pill,/obj/item/storage/pill_bottle, /obj/item/restraints/handcuffs,/obj/item/hypospray
)
armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 5, "rad" = 10, "fire" = 10, "acid" = 0)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/suit/storage/trek/ds9/admiral // Only for adminuz
name = "Admiral Overcoat"
@@ -135,7 +136,6 @@
/obj/item/clothing/suit/storage/fluff/fedcoat
name = "Federation Uniform Jacket"
desc = "A uniform jacket from the United Federation. Set phasers to awesome."
icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi'
alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi'
icon_state = "fedcoat"
@@ -160,7 +160,7 @@
/obj/item/reagent_containers/glass/beaker,
/obj/item/storage/pill_bottle,
/obj/item/taperecorder)
armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 5, "rad" = 10, "fire" = 10, "acid" = 0)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
var/unbuttoned = 0
verb/toggle()
@@ -214,7 +214,7 @@
/obj/item/reagent_containers/glass/bottle/vial,/obj/item/reagent_containers/glass/beaker,
/obj/item/reagent_containers/pill,/obj/item/storage/pill_bottle, /obj/item/restraints/handcuffs,/obj/item/hypospray
)
armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 5, "rad" = 10, "fire" = 10, "acid" = 0)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
//Variants
/obj/item/clothing/suit/storage/fluff/modernfedcoat/medsci
@@ -231,6 +231,7 @@
/obj/item/clothing/head/caphat/formal/fedcover
name = "Federation Officer's Cap"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
desc = "An officer's cap that demands discipline from the one who wears it."
icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi'
icon_state = "fedcapofficer"
@@ -43,8 +43,8 @@
icon_state = "bb_turtle"
item_state = "w_suit"
item_color = "bb_turtle"
body_parts_covered = CHEST|ARMS
can_adjust = 1
body_parts_covered = CHEST|GROIN|ARMS
can_adjust = TRUE
icon = 'modular_citadel/icons/obj/clothing/turtlenecks.dmi'
alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi'
mutantrace_variation = NO_MUTANTRACE_VARIATION
@@ -417,7 +417,6 @@
icon_state = "flagcape"
item_state = "flagcape"
/obj/item/clothing/shoes/lucky
name = "Lucky Jackboots"
icon = 'icons/obj/custom.dmi'
@@ -484,4 +483,48 @@
icon_state = "redgoldjacket"
item_state = "redgoldjacket"
body_parts_covered = CHEST|GROIN|LEGS|ARMS
mutantrace_variation = NO_MUTANTRACE_VARIATION
mutantrace_variation = NO_MUTANTRACE_VARIATION
/obj/item/clothing/suit/kimono
name = "Blue Kimono"
desc = "A traditional kimono, this one is blue with purple flowers."
icon_state = "kimono"
item_state = "kimono"
icon = 'icons/obj/custom.dmi'
alternate_worn_icon = 'icons/mob/custom_w.dmi'
mutantrace_variation = NO_MUTANTRACE_VARIATION
/obj/item/clothing/suit/commjacket
name = "Dusty Commisar's Cloak"
desc = "An Imperial Commisar's Coat, straight from the frontline of battle, filled with dirt, bulletholes, and dozens of little pockets. Alongside a curious golden eagle sitting on it's left breast, the marking '200th Venoland' is clearly visible on the inner workings of the coat. It certainly holds an imposing flair, however."
icon_state = "commjacket"
item_state = "commjacket"
icon = 'icons/obj/custom.dmi'
alternate_worn_icon = 'icons/mob/custom_w.dmi'
mutantrace_variation = NO_MUTANTRACE_VARIATION
/obj/item/clothing/under/mw2_russian_para
name = "Russian Paratrooper Jumper"
desc = "A Russian made old paratrooper jumpsuit, has many pockets for easy storage of gear from a by gone era. As bulky as it looks, its shockingly light!"
icon_state = "mw2_russian_para"
item_state = "mw2_russian_para"
icon = 'icons/obj/custom.dmi'
alternate_worn_icon = 'icons/mob/custom_w.dmi'
mutantrace_variation = NO_MUTANTRACE_VARIATION
/obj/item/clothing/gloves/longblackgloves
name = "Luna's Gauntlets"
desc = "These gloves seem to have a coating of slime fluid on them, you should possibly return them to their rightful owner."
icon_state = "longblackgloves"
item_state = "longblackgloves"
icon = 'icons/obj/custom.dmi'
alternate_worn_icon = 'icons/mob/custom_w.dmi'
/obj/item/clothing/under/trendy_fit
name = "Trendy Fitting Clothing"
desc = "An outfit straight from the boredom of space, its the type of thing only someone trying to entertain themselves on the way to their next destination would wear."
icon_state = "trendy_fit"
item_state = "trendy_fit"
icon = 'icons/obj/custom.dmi'
alternate_worn_icon = 'icons/mob/custom_w.dmi'
mutantrace_variation = NO_MUTANTRACE_VARIATION
+17 -17
View File
@@ -3,7 +3,7 @@
set category = "Mentor"
set name = "Mentor PM"
if(!is_mentor())
to_chat(src, "<font color='red'>Error: Mentor-PM-Panel: Only Mentors and Admins may use this command.</font>")
to_chat(src, "<span class='danger'>Error: Mentor-PM-Panel: Only Mentors and Admins may use this command.</span>")
return
var/list/client/targets[0]
for(var/client/T)
@@ -27,24 +27,24 @@
else if(istype(whom,/client))
C = whom
if(!C)
if(is_mentor()) to_chat(src, "<font color='red'>Error: Mentor-PM: Client not found.</font>")
if(is_mentor()) to_chat(src, "<span class='danger'>Error: Mentor-PM: Client not found.</span>")
else mentorhelp(msg) //Mentor we are replying to left. Mentorhelp instead(check below)
return
if(is_mentor(whom))
to_chat(GLOB.admins | GLOB.mentors, "<font color='purple'>[src] has started replying to [whom]'s mhelp.</font color>")
to_chat(GLOB.admins | GLOB.mentors, "<font color='purple'>[src] has started replying to [whom]'s mhelp.</font>")
//get message text, limit it's length.and clean/escape html
if(!msg)
msg = input(src,"Message:", "Private message") as text|null
if(!msg && is_mentor(whom))
to_chat(GLOB.admins | GLOB.mentors, "<font color='purple'>[src] has stopped their reply to [whom]'s mhelp.</font color>")
to_chat(GLOB.admins | GLOB.mentors, "<span class='purple'>[src] has stopped their reply to [whom]'s mhelp.</span>")
return
if(!C)
if(is_mentor())
to_chat(src, "<font color='red'>Error: Mentor-PM: Client not found.</font>")
to_chat(src, "<span class='danger'>Error: Mentor-PM: Client not found.</span>")
else
mentorhelp(msg) //Mentor we are replying to has vanished, Mentorhelp instead (how the fuck does this work?let's hope it works,shrug)
return
@@ -54,8 +54,8 @@
return
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg && is_mentor(whom))
to_chat(GLOB.admins | GLOB.mentors, "<font color='purple'>[src] has stopped their reply to [whom]'s mhelp.</font color>")
if(!msg && is_mentor(whom))
to_chat(GLOB.admins | GLOB.mentors, "<span class='purple'>[src] has stopped their reply to [whom]'s mhelp.</span>")
return
log_mentor("Mentor PM: [key_name(src)]->[key_name(C)]: [msg]")
@@ -65,21 +65,21 @@
var/show_char = CONFIG_GET(flag/mentors_mobname_only)
if(C.is_mentor())
if(is_mentor())//both are mentors
to_chat(C, "<font color='purple'>Mentor PM from-<b>[key_name_mentor(src, C, 1, 0, 0)]</b>: [msg]</font>")
to_chat(src, "<font color='green'>Mentor PM to-<b>[key_name_mentor(C, C, 1, 0, 0)]</b>: [msg]</font>")
to_chat(C, "<span class='purple'>Mentor PM from-<b>[key_name_mentor(src, C, 1, 0, 0)]</b>: [msg]</span>")
to_chat(src, "<span class='green'>Mentor PM to-<b>[key_name_mentor(C, C, 1, 0, 0)]</b>: [msg]</font>")
else //recipient is an mentor but sender is not
to_chat(C, "<font color='purple'>Reply PM from-<b>[key_name_mentor(src, C, 1, 0, show_char)]</b>: [msg]</font>")
to_chat(src, "<font color='brown'>Mentor PM to-<b>[key_name_mentor(C, C, 1, 0, 0)]</b>: [msg]</font>")
else //recipient is a mentor but sender is not
to_chat(C, "<span class='purple'>Reply PM from-<b>[key_name_mentor(src, C, 1, 0, show_char)]</b>: [msg]</span>")
to_chat(src, "<span class='pink'>Mentor PM to-<b>[key_name_mentor(C, C, 1, 0, 0)]</b>: [msg]</span>")
else
if(is_mentor()) //sender is an mentor but recipient is not.
to_chat(C, "<font color='purple'>Mentor PM from-<b>[key_name_mentor(src, C, 1, 0, 0)]</b>: [msg]</font>")
to_chat(src, "<font color='brown'>Mentor PM to-<b>[key_name_mentor(C, C, 1, 0, show_char)]</b>: [msg]</font>")
if(is_mentor()) //sender is a mentor but recipient is not.
to_chat(C, "<span class='purple'>Mentor PM from-<b>[key_name_mentor(src, C, 1, 0, 0)]</b>: [msg]</span>")
to_chat(src, "<span class='pink'>Mentor PM to-<b>[key_name_mentor(C, C, 1, 0, show_char)]</b>: [msg]</span>")
//we don't use message_Mentors here because the sender/receiver might get it too
var/show_char_sender = !is_mentor() && CONFIG_GET(flag/mentors_mobname_only)
var/show_char_recip = !C.is_mentor() && CONFIG_GET(flag/mentors_mobname_only)
for(var/client/X in GLOB.mentors | GLOB.admins)
if(X.key!=key && X.key!=C.key) //check client/X is an Mentor and isn't the sender or recipient
to_chat(X, "<B><font color='brown'>Mentor PM: [key_name_mentor(src, X, 0, 0, show_char_sender)]-&gt;[key_name_mentor(C, X, 0, 0, show_char_recip)]:</B> <font color ='blue'> [msg]</font>") //inform X
to_chat(X, "<B><span class='pink'>Mentor PM: [key_name_mentor(src, X, 0, 0, show_char_sender)]-&gt;[key_name_mentor(C, X, 0, 0, show_char_recip)]:</span></B> <span class='blue'>[msg]</span>") //inform X
@@ -183,6 +183,7 @@
key_third_person = "suddenly hits a dab"
message = "suddenly hits a dab!"
emote_type = EMOTE_AUDIBLE
restraint_check = TRUE
@@ -191,6 +191,32 @@
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
color_src = MATRIXED
/datum/sprite_accessory/ears/human/bigwolf
name = "Big Wolf"
icon_state = "bigwolf"
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
color_src = MATRIXED
/datum/sprite_accessory/ears/human/bigwolfinner
name = "Big Wolf (ALT)"
icon_state = "bigwolfinner"
hasinner = 1
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
color_src = MATRIXED
/datum/sprite_accessory/ears/human/bigwolfdark
name = "Dark Big Wolf"
icon_state = "bigwolfdark"
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
color_src = MATRIXED
/datum/sprite_accessory/ears/human/bigwolfinnerdark
name = "Dark Big Wolf (ALT)"
icon_state = "bigwolfinnerdark"
hasinner = 1
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
color_src = MATRIXED
/datum/sprite_accessory/ears/human/cow
name = "Cow"
icon_state = "cow"
@@ -959,6 +985,13 @@
name = "Eevee"
icon_state = "eevee"
/datum/sprite_accessory/mam_ears/elf
name = "Elf"
icon_state = "elf"
color_src = MUTCOLORS3
/datum/sprite_accessory/mam_ears/elephant
name = "Elephant"
icon_state = "elephant"
@@ -1497,6 +1530,12 @@ datum/sprite_accessory/mam_tails/insect
icon_state = "cow"
taur_mode = HOOF_TAURIC
/datum/sprite_accessory/taur/deer
name = "Deer"
icon_state = "deer"
taur_mode = HOOF_TAURIC
color_src = MUTCOLORS
/datum/sprite_accessory/taur/drake
name = "Drake"
icon_state = "drake"
@@ -34,7 +34,10 @@
for(var/obj/screen/combattoggle/selector in hud_used.static_inventory)
selector.rebasetointerbay(src)
if(world.time >= combatmessagecooldown && combatmode)
visible_message("<span class='warning'>[src] [resting ? "tenses up" : (prob(95)? "drops into a combative stance" : (prob(95)? "poses aggressively" : "asserts dominance with their pose"))].</span>")
if(a_intent != INTENT_HELP)
visible_message("<span class='warning'>[src] [resting ? "tenses up" : (prob(95)? "drops into a combative stance" : (prob(95)? "poses aggressively" : "asserts dominance with their pose"))].</span>")
else
visible_message("<span class='notice'>[src] [pick("looks","seems","goes")] [pick("alert","attentive","vigilant")].</span>")
combatmessagecooldown = 10 SECONDS + world.time //This is set 100% of the time to make sure squeezing regen out of process cycles doesn't result in the combat mode message getting spammed
SEND_SIGNAL(src, COMSIG_COMBAT_TOGGLED, src, combatmode)
return TRUE
@@ -18,3 +18,21 @@
if(recoveringstam && amount > 20)
incomingstammult = max(0.01, incomingstammult/(amount*0.05))
return amount
/mob/living/carbon/doSprintLossTiles(tiles)
doSprintBufferRegen(FALSE) //first regen.
if(sprint_buffer)
var/use = min(tiles, sprint_buffer)
sprint_buffer -= use
tiles -= use
update_hud_sprint_bar()
if(!tiles) //we had enough, we're done!
return
adjustStaminaLoss(tiles * sprint_stamina_cost) //use stamina to cover deficit.
/mob/living/carbon/proc/doSprintBufferRegen(updating = TRUE)
var/diff = world.time - sprint_buffer_regen_last
sprint_buffer_regen_last = world.time
sprint_buffer = min(sprint_buffer_max, sprint_buffer + sprint_buffer_regen_ds * diff)
if(updating)
update_hud_sprint_bar()
@@ -5,7 +5,7 @@
var/oldpseudoheight = pseudo_z_axis
. = ..()
if(. && sprinting && !(movement_type & FLYING) && canmove && !resting && m_intent == MOVE_INTENT_RUN && has_gravity(loc) && !pulledby)
adjustStaminaLossBuffered(0.3)
doSprintLossTiles(1)
if((oldpseudoheight - pseudo_z_axis) >= 8)
to_chat(src, "<span class='warning'>You trip off of the elevated surface!</span>")
for(var/obj/item/I in held_items)
@@ -80,10 +80,21 @@
else
target.Move(target_shove_turf, shove_dir)
if(get_turf(target) == target_oldturf)
target_table = locate(/obj/structure/table) in target_shove_turf.contents
shove_blocked = TRUE
var/thoushallnotpass = FALSE
for(var/obj/O in target_shove_turf)
if(O.density)
shove_blocked = TRUE
if(istype(O, /obj/structure/table))
target_table = O
else
thoushallnotpass = TRUE
if(thoushallnotpass)
target_table = null
if(shove_blocked && !target.is_shove_knockdown_blocked())
if(target.is_shove_knockdown_blocked())
return
if(shove_blocked)
var/directional_blocked = FALSE
if(shove_dir in GLOB.cardinals) //Directional checks to make sure that we're not shoving through a windoor or something like that
var/target_turf = get_turf(target)
@@ -11,6 +11,7 @@
mutant_bodyparts = list("ipc_screen", "ipc_antenna")
default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
mutanttongue = /obj/item/organ/tongue/robot/ipc
exotic_blood = "oilblood"
exotic_bloodtype = "HF"
@@ -28,9 +29,6 @@
screen.Remove(C)
..()
/datum/species/ipc/get_spans()
return SPAN_ROBOT
/datum/action/innate/monitor_change
name = "Screen Change"
check_flags = AB_CHECK_CONSCIOUS
@@ -15,7 +15,6 @@
say_mod = "says"
hair_color = "mutcolor"
hair_alpha = 160 //a notch brighter so it blends better.
liked_food = MEAT
coldmod = 3
heatmod = 1
burnmod = 1
@@ -69,7 +68,7 @@
/datum/action/innate/slime_change/proc/change_form()
var/mob/living/carbon/human/H = owner
var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Cancel")
var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Cancel")
if(select_alteration == "Hair Style")
if(H.gender == MALE)
var/new_style = input(owner, "Select a facial hair style", "Hair Alterations") as null|anything in GLOB.facial_hair_styles_list
@@ -114,7 +113,7 @@
O.Remove(H)
organ.forceMove(get_turf(H))
qdel(organ)
H.update_body()
H.update_genitals()
else if (select_alteration == "Ears")
var/list/snowflake_ears_list = list("Normal" = null)
@@ -194,5 +193,65 @@
if(new_taur != "None")
H.dna.features["mam_tail"] = "None"
H.update_body()
else if (select_alteration == "Penis")
for(var/obj/item/organ/genital/penis/X in H.internal_organs)
qdel(X)
var/new_shape
new_shape = input(owner, "Choose your character's dong", "Genital Alteration") as null|anything in GLOB.cock_shapes_list
if(new_shape)
H.dna.features["cock_shape"] = new_shape
H.update_genitals()
H.give_balls()
H.give_penis()
H.apply_overlay()
else if (select_alteration == "Vagina")
for(var/obj/item/organ/genital/vagina/X in H.internal_organs)
qdel(X)
var/new_shape
new_shape = input(owner, "Choose your character's pussy", "Genital Alteration") as null|anything in GLOB.vagina_shapes_list
if(new_shape)
H.dna.features["vag_shape"] = new_shape
H.update_genitals()
H.give_womb()
H.give_vagina()
H.apply_overlay()
else if (select_alteration == "Penis Length")
for(var/obj/item/organ/genital/penis/X in H.internal_organs)
qdel(X)
var/new_length
new_length = input(owner, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Genital Alteration") as num|null
if(new_length)
H.dna.features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN)
H.update_genitals()
H.apply_overlay()
H.give_balls()
H.give_penis()
else if (select_alteration == "Breast Size")
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
qdel(X)
var/new_size
new_size = input(owner, "Breast Size", "Genital Alteration") as null|anything in GLOB.breasts_size_list
if(new_size)
H.dna.features["breasts_size"] = new_size
H.update_genitals()
H.apply_overlay()
H.give_breasts()
else if (select_alteration == "Breast Shape")
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
qdel(X)
var/new_shape
new_shape = input(owner, "Breast Shape", "Genital Alteration") as null|anything in GLOB.breasts_shapes_list
if(new_shape)
H.dna.features["breasts_shape"] = new_shape
H.update_genitals()
H.apply_overlay()
H.give_breasts()
else
return
@@ -0,0 +1,3 @@
/mob/living/carbon/Life()
. = ..()
doSprintBufferRegen()
@@ -1,2 +1,5 @@
/mob/living/proc/adjustStaminaLossBuffered(amount, updating_stamina = TRUE, forced = FALSE)
return
/mob/living/proc/doSprintLossTiles(amount)
return
@@ -8,6 +8,14 @@
var/intentionalresting = FALSE
var/attemptingcrawl = FALSE
//Sprint buffer---
var/sprint_buffer = 42 //Tiles
var/sprint_buffer_max = 42
var/sprint_buffer_regen_ds = 0.3 //Tiles per world.time decisecond
var/sprint_buffer_regen_last = 0 //last world.time this was regen'd for math.
var/sprint_stamina_cost = 0.55 //stamina loss per tile while insufficient sprint buffer.
//---End
/mob/living/movement_delay(ignorewalk = 0)
. = ..()
if(resting)
@@ -118,3 +126,7 @@
filters -= CIT_FILTER_STAMINACRIT
update_canmove()
update_health_hud()
/mob/living/proc/update_hud_sprint_bar()
if(hud_used && hud_used.sprint_buffer)
hud_used.sprint_buffer.update_to_mob(src)
@@ -1,390 +1,389 @@
/*
DOG BORG EQUIPMENT HERE
SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
*/
/obj/item/dogborg/jaws
name = "Dogborg jaws"
desc = "The jaws of the debug errors oh god."
icon = 'icons/mob/dogborg.dmi'
flags_1 = CONDUCT_1
force = 1
throwforce = 0
w_class = 3
hitsound = 'sound/weapons/bite.ogg'
sharpness = IS_SHARP
/obj/item/dogborg/jaws/big
name = "combat jaws"
desc = "The jaws of the law. Very sharp."
icon_state = "jaws"
force = 12
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
/obj/item/dogborg/jaws/small
name = "puppy jaws"
desc = "Rubberized teeth designed to protect accidental harm. Sharp enough for specialized tasks however."
icon_state = "smalljaws"
force = 6
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
var/status = 0
/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
..()
user.do_attack_animation(A, ATTACK_EFFECT_BITE)
log_combat(user, A, "bit")
/obj/item/dogborg/jaws/small/attack_self(mob/user)
var/mob/living/silicon/robot.R = user
if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0)
name = "combat jaws"
icon_state = "jaws"
desc = "The jaws of the law."
force = 12
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
status = 1
to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>")
else
name = "puppy jaws"
icon_state = "smalljaws"
desc = "The jaws of a small dog."
force = 5
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
status = 0
if(R.emagged)
to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>")
update_icon()
//Boop
/obj/item/analyzer/nose
name = "boop module"
icon = 'icons/mob/dogborg.dmi'
icon_state = "nose"
desc = "The BOOP module"
flags_1 = CONDUCT_1
force = 0
throwforce = 0
attack_verb = list("nuzzles", "pushes", "boops")
w_class = 1
/obj/item/analyzer/nose/attack_self(mob/user)
user.visible_message("[user] sniffs around the air.", "<span class='warning'>You sniff the air for gas traces.</span>")
var/turf/location = user.loc
if(!istype(location))
return
var/datum/gas_mixture/environment = location.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
to_chat(user, "<span class='info'><B>Results:</B></span>")
if(abs(pressure - ONE_ATMOSPHERE) < 10)
to_chat(user, "<span class='info'>Pressure: [round(pressure,0.1)] kPa</span>")
else
to_chat(user, "<span class='alert'>Pressure: [round(pressure,0.1)] kPa</span>")
if(total_moles)
var/list/env_gases = environment.gases
environment.assert_gases(arglist(GLOB.hardcoded_gases))
var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles
var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles
var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles
environment.garbage_collect()
if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
if(plasma_concentration > 0.005)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
for(var/id in env_gases)
if(id in GLOB.hardcoded_gases)
continue
var/gas_concentration = env_gases[id][MOLES]/total_moles
to_chat(user, "<span class='alert'>[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C)] &deg;C</span>")
/obj/item/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens
. = ..()
/obj/item/analyzer/nose/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity)
return
do_attack_animation(target, null, src)
user.visible_message("<span class='notice'>[user] [pick(attack_verb)] \the [target.name] with their nose!</span>")
//Delivery
/obj/item/storage/bag/borgdelivery
name = "fetching storage"
desc = "Fetch the thing!"
icon = 'icons/mob/dogborg.dmi'
icon_state = "dbag"
w_class = WEIGHT_CLASS_BULKY
/obj/item/storage/bag/borgdelivery/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 5
STR.max_items = 1
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/radio/intercom))
//Tongue stuff
/obj/item/soap/tongue
name = "synthetic tongue"
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
icon = 'icons/mob/dogborg.dmi'
icon_state = "synthtongue"
hitsound = 'sound/effects/attackblob.ogg'
cleanspeed = 80
var/status = 0
/obj/item/soap/tongue/scrubpup
cleanspeed = 25 //slightly faster than a mop.
/obj/item/soap/tongue/New()
..()
item_flags |= NOBLUDGEON //No more attack messages
/obj/item/soap/tongue/attack_self(mob/user)
var/mob/living/silicon/robot.R = user
if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0)
status = !status
name = "energized tongue"
desc = "Your tongue is energized for dangerously maximum efficency."
icon_state = "syndietongue"
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
cleanspeed = 10 //(nerf'd)tator soap stat
else
status = 0
name = "synthetic tongue"
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
icon_state = "synthtongue"
cleanspeed = initial(cleanspeed)
if(R.emagged)
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
update_icon()
/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity)
var/mob/living/silicon/robot.R = user
if(!proximity || !check_allowed_items(target))
return
if(R.client && (target in R.client.screen))
to_chat(R, "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>")
else if(is_cleanable(target))
R.visible_message("[R] begins to lick off \the [target.name].", "<span class='warning'>You begin to lick off \the [target.name]...</span>")
if(do_after(R, src.cleanspeed, target = target))
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
to_chat(R, "<span class='notice'>You finish licking off \the [target.name].</span>")
qdel(target)
R.cell.give(50)
else if(isobj(target)) //hoo boy. danger zone man
if(istype(target,/obj/item/trash))
R.visible_message("[R] nibbles away at \the [target.name].", "<span class='warning'>You begin to nibble away at \the [target.name]...</span>")
if(!do_after(R, src.cleanspeed, target = target))
return //If they moved away, you can't eat them.
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
qdel(target)
R.cell.give(250)
return
if(istype(target,/obj/item/stock_parts/cell))
R.visible_message("[R] begins cramming \the [target.name] down its throat.", "<span class='warning'>You begin cramming \the [target.name] down your throat...</span>")
if(!do_after(R, 50, target = target))
return //If they moved away, you can't eat them.
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
var/obj/item/stock_parts/cell.C = target
R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf
qdel(target)
return
var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT
if(!I.anchored && R.emagged)
R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "<span class='warning'>You begin chewing up \the [target.name]...</span>")
if(!do_after(R, 100, target = I)) //Nerf dat time yo
return //If they moved away, you can't eat them.
visible_message("<span class='warning'>[R] chews up \the [target.name] and cleans off the debris!</span>")
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
qdel(I)
R.cell.give(500)
return
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
else if(ishuman(target))
var/mob/living/L = target
if(status == 0 && check_zone(R.zone_selected) == "head")
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]'s face!</span>", "<span class='notice'>You affectionally lick \the [L]'s face!</span>")
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(istype(L) && L.fire_stacks > 0)
L.adjust_fire_stacks(-10)
return
else if(status == 0)
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]!</span>", "<span class='notice'>You affectionally lick \the [L]!</span>")
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(istype(L) && L.fire_stacks > 0)
L.adjust_fire_stacks(-10)
return
else
if(R.cell.charge <= 800)
to_chat(R, "Insufficent Power!")
return
L.Stun(4) // normal stunbaton is force 7 gimme a break good sir!
L.Knockdown(80)
L.apply_effect(EFFECT_STUTTER, 4)
L.visible_message("<span class='danger'>[R] has shocked [L] with its tongue!</span>", \
"<span class='userdanger'>[R] has shocked you with its tongue!</span>")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
R.cell.use(666)
log_combat(R, L, "tongue stunned")
else if(istype(target, /obj/structure/window))
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
target.set_opacity(initial(target.opacity))
else
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
target.wash_cream()
return
//Dogfood
/obj/item/trash/rkibble
name = "robo kibble"
desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge."
icon = 'icons/mob/dogborg.dmi'
icon_state= "kibble"
//Defibs
/obj/item/twohanded/shockpaddles/cyborg/hound
name = "Paws of Life"
desc = "MediHound specific shock paws."
icon = 'icons/mob/dogborg.dmi'
icon_state = "defibpaddles0"
item_state = "defibpaddles0"
// Pounce stuff for K-9
/obj/item/dogborg/pounce
name = "pounce"
icon = 'icons/mob/dogborg.dmi'
icon_state = "pounce"
desc = "Leap at your target to momentarily stun them."
force = 0
throwforce = 0
/obj/item/dogborg/pounce/New()
..()
item_flags |= NOBLUDGEON
/mob/living/silicon/robot
var/leaping = 0
var/pounce_cooldown = 0
var/pounce_cooldown_time = 50 //Nearly doubled, u happy?
var/pounce_spoolup = 3
var/leap_at
var/disabler
var/laser
var/sleeper_g
var/sleeper_r
var/sleeper_nv
#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance.
/obj/item/dogborg/pounce/afterattack(atom/A, mob/user)
var/mob/living/silicon/robot/R = user
if(R && !R.pounce_cooldown)
R.pounce_cooldown = !R.pounce_cooldown
to_chat(R, "<span class ='warning'>Your targeting systems lock on to [A]...</span>")
addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup)
spawn(R.pounce_cooldown_time)
R.pounce_cooldown = !R.pounce_cooldown
else if(R && R.pounce_cooldown)
to_chat(R, "<span class='danger'>Your leg actuators are still recharging!</span>")
/mob/living/silicon/robot/proc/leap_at(atom/A)
if(leaping || stat || buckled || lying)
return
if(!has_gravity(src) || !has_gravity(A))
to_chat(src,"<span class='danger'>It is unsafe to leap without gravity!</span>")
//It's also extremely buggy visually, so it's balance+bugfix
return
if(cell.charge <= 500)
to_chat(src,"<span class='danger'>Insufficent reserves for jump actuators!</span>")
return
else
leaping = 1
weather_immunities += "lava"
pixel_y = 10
update_icons()
throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1)
cell.use(500) //Doubled the energy consumption
weather_immunities -= "lava"
/mob/living/silicon/robot/throw_impact(atom/A)
if(!leaping)
return ..()
if(A)
if(isliving(A))
var/mob/living/L = A
var/blocked = 0
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
blocked = 1
if(!blocked)
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
L.Knockdown(iscarbon(L) ? 450 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice.
playsound(src, 'sound/weapons/Egloves.ogg', 50, 1)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L)
log_combat(src, L, "borg pounced")
else
Knockdown(45, 1, 1)
pounce_cooldown = !pounce_cooldown
spawn(pounce_cooldown_time) //3s by default
pounce_cooldown = !pounce_cooldown
else if(A.density && !A.CanPass(src))
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='userdanger'>You smash into [A]!</span>")
playsound(src, 'sound/items/trayhit1.ogg', 50, 1)
Knockdown(45, 1, 1)
if(leaping)
leaping = 0
pixel_y = initial(pixel_y)
update_icons()
update_canmove()
/*
DOG BORG EQUIPMENT HERE
SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
*/
/obj/item/dogborg/jaws
name = "Dogborg jaws"
desc = "The jaws of the debug errors oh god."
icon = 'icons/mob/dogborg.dmi'
flags_1 = CONDUCT_1
force = 1
throwforce = 0
w_class = 3
hitsound = 'sound/weapons/bite.ogg'
sharpness = IS_SHARP
/obj/item/dogborg/jaws/big
name = "combat jaws"
desc = "The jaws of the law. Very sharp."
icon_state = "jaws"
force = 12
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
/obj/item/dogborg/jaws/small
name = "puppy jaws"
desc = "Rubberized teeth designed to protect accidental harm. Sharp enough for specialized tasks however."
icon_state = "smalljaws"
force = 6
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
var/status = 0
/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
..()
user.do_attack_animation(A, ATTACK_EFFECT_BITE)
log_combat(user, A, "bit")
/obj/item/dogborg/jaws/small/attack_self(mob/user)
var/mob/living/silicon/robot.R = user
if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0)
name = "combat jaws"
icon_state = "jaws"
desc = "The jaws of the law."
force = 12
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
status = 1
to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>")
else
name = "puppy jaws"
icon_state = "smalljaws"
desc = "The jaws of a small dog."
force = 5
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
status = 0
if(R.emagged)
to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>")
update_icon()
//Boop
/obj/item/analyzer/nose
name = "boop module"
icon = 'icons/mob/dogborg.dmi'
icon_state = "nose"
desc = "The BOOP module"
flags_1 = CONDUCT_1
force = 0
throwforce = 0
attack_verb = list("nuzzles", "pushes", "boops")
w_class = 1
/obj/item/analyzer/nose/attack_self(mob/user)
user.visible_message("[user] sniffs around the air.", "<span class='warning'>You sniff the air for gas traces.</span>")
var/turf/location = user.loc
if(!istype(location))
return
var/datum/gas_mixture/environment = location.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
to_chat(user, "<span class='info'><B>Results:</B></span>")
if(abs(pressure - ONE_ATMOSPHERE) < 10)
to_chat(user, "<span class='info'>Pressure: [round(pressure,0.1)] kPa</span>")
else
to_chat(user, "<span class='alert'>Pressure: [round(pressure,0.1)] kPa</span>")
if(total_moles)
var/list/env_gases = environment.gases
var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles
var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles
var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles
GAS_GARBAGE_COLLECT(environment.gases)
if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
if(plasma_concentration > 0.005)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
for(var/id in env_gases)
if(id in GLOB.hardcoded_gases)
continue
var/gas_concentration = env_gases[id]/total_moles
to_chat(user, "<span class='alert'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] %</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C)] &deg;C</span>")
/obj/item/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens
. = ..()
/obj/item/analyzer/nose/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity)
return
do_attack_animation(target, null, src)
user.visible_message("<span class='notice'>[user] [pick(attack_verb)] \the [target.name] with their nose!</span>")
//Delivery
/obj/item/storage/bag/borgdelivery
name = "fetching storage"
desc = "Fetch the thing!"
icon = 'icons/mob/dogborg.dmi'
icon_state = "dbag"
w_class = WEIGHT_CLASS_BULKY
/obj/item/storage/bag/borgdelivery/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 5
STR.max_items = 1
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/radio/intercom))
//Tongue stuff
/obj/item/soap/tongue
name = "synthetic tongue"
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
icon = 'icons/mob/dogborg.dmi'
icon_state = "synthtongue"
hitsound = 'sound/effects/attackblob.ogg'
cleanspeed = 80
var/status = 0
/obj/item/soap/tongue/scrubpup
cleanspeed = 25 //slightly faster than a mop.
/obj/item/soap/tongue/New()
..()
item_flags |= NOBLUDGEON //No more attack messages
/obj/item/soap/tongue/attack_self(mob/user)
var/mob/living/silicon/robot.R = user
if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0)
status = !status
name = "energized tongue"
desc = "Your tongue is energized for dangerously maximum efficency."
icon_state = "syndietongue"
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
cleanspeed = 10 //(nerf'd)tator soap stat
else
status = 0
name = "synthetic tongue"
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
icon_state = "synthtongue"
cleanspeed = initial(cleanspeed)
if(R.emagged)
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
update_icon()
/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity)
var/mob/living/silicon/robot.R = user
if(!proximity || !check_allowed_items(target))
return
if(R.client && (target in R.client.screen))
to_chat(R, "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>")
else if(is_cleanable(target))
R.visible_message("[R] begins to lick off \the [target.name].", "<span class='warning'>You begin to lick off \the [target.name]...</span>")
if(do_after(R, src.cleanspeed, target = target))
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
to_chat(R, "<span class='notice'>You finish licking off \the [target.name].</span>")
qdel(target)
R.cell.give(50)
else if(isobj(target)) //hoo boy. danger zone man
if(istype(target,/obj/item/trash))
R.visible_message("[R] nibbles away at \the [target.name].", "<span class='warning'>You begin to nibble away at \the [target.name]...</span>")
if(!do_after(R, src.cleanspeed, target = target))
return //If they moved away, you can't eat them.
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
qdel(target)
R.cell.give(250)
return
if(istype(target,/obj/item/stock_parts/cell))
R.visible_message("[R] begins cramming \the [target.name] down its throat.", "<span class='warning'>You begin cramming \the [target.name] down your throat...</span>")
if(!do_after(R, 50, target = target))
return //If they moved away, you can't eat them.
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
var/obj/item/stock_parts/cell.C = target
R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf
qdel(target)
return
var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT
if(!I.anchored && R.emagged)
R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "<span class='warning'>You begin chewing up \the [target.name]...</span>")
if(!do_after(R, 100, target = I)) //Nerf dat time yo
return //If they moved away, you can't eat them.
visible_message("<span class='warning'>[R] chews up \the [target.name] and cleans off the debris!</span>")
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
qdel(I)
R.cell.give(500)
return
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
else if(ishuman(target))
var/mob/living/L = target
if(status == 0 && check_zone(R.zone_selected) == "head")
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]'s face!</span>", "<span class='notice'>You affectionally lick \the [L]'s face!</span>")
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(istype(L) && L.fire_stacks > 0)
L.adjust_fire_stacks(-10)
return
else if(status == 0)
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]!</span>", "<span class='notice'>You affectionally lick \the [L]!</span>")
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(istype(L) && L.fire_stacks > 0)
L.adjust_fire_stacks(-10)
return
else
if(R.cell.charge <= 800)
to_chat(R, "Insufficent Power!")
return
L.Stun(4) // normal stunbaton is force 7 gimme a break good sir!
L.Knockdown(80)
L.apply_effect(EFFECT_STUTTER, 4)
L.visible_message("<span class='danger'>[R] has shocked [L] with its tongue!</span>", \
"<span class='userdanger'>[R] has shocked you with its tongue!</span>")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
R.cell.use(666)
log_combat(R, L, "tongue stunned")
else if(istype(target, /obj/structure/window))
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
target.set_opacity(initial(target.opacity))
else
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
target.wash_cream()
return
//Dogfood
/obj/item/trash/rkibble
name = "robo kibble"
desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge."
icon = 'icons/mob/dogborg.dmi'
icon_state= "kibble"
//Defibs
/obj/item/twohanded/shockpaddles/cyborg/hound
name = "Paws of Life"
desc = "MediHound specific shock paws."
icon = 'icons/mob/dogborg.dmi'
icon_state = "defibpaddles0"
item_state = "defibpaddles0"
// Pounce stuff for K-9
/obj/item/dogborg/pounce
name = "pounce"
icon = 'icons/mob/dogborg.dmi'
icon_state = "pounce"
desc = "Leap at your target to momentarily stun them."
force = 0
throwforce = 0
/obj/item/dogborg/pounce/New()
..()
item_flags |= NOBLUDGEON
/mob/living/silicon/robot
var/leaping = 0
var/pounce_cooldown = 0
var/pounce_cooldown_time = 50 //Nearly doubled, u happy?
var/pounce_spoolup = 3
var/leap_at
var/disabler
var/laser
var/sleeper_g
var/sleeper_r
var/sleeper_nv
#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance.
/obj/item/dogborg/pounce/afterattack(atom/A, mob/user)
var/mob/living/silicon/robot/R = user
if(R && !R.pounce_cooldown)
R.pounce_cooldown = !R.pounce_cooldown
to_chat(R, "<span class ='warning'>Your targeting systems lock on to [A]...</span>")
addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup)
spawn(R.pounce_cooldown_time)
R.pounce_cooldown = !R.pounce_cooldown
else if(R && R.pounce_cooldown)
to_chat(R, "<span class='danger'>Your leg actuators are still recharging!</span>")
/mob/living/silicon/robot/proc/leap_at(atom/A)
if(leaping || stat || buckled || lying)
return
if(!has_gravity(src) || !has_gravity(A))
to_chat(src,"<span class='danger'>It is unsafe to leap without gravity!</span>")
//It's also extremely buggy visually, so it's balance+bugfix
return
if(cell.charge <= 500)
to_chat(src,"<span class='danger'>Insufficent reserves for jump actuators!</span>")
return
else
leaping = 1
weather_immunities += "lava"
pixel_y = 10
update_icons()
throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1)
cell.use(500) //Doubled the energy consumption
weather_immunities -= "lava"
/mob/living/silicon/robot/throw_impact(atom/A)
if(!leaping)
return ..()
if(A)
if(isliving(A))
var/mob/living/L = A
var/blocked = 0
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
blocked = 1
if(!blocked)
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
L.Knockdown(iscarbon(L) ? 450 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice.
playsound(src, 'sound/weapons/Egloves.ogg', 50, 1)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L)
log_combat(src, L, "borg pounced")
else
Knockdown(45, 1, 1)
pounce_cooldown = !pounce_cooldown
spawn(pounce_cooldown_time) //3s by default
pounce_cooldown = !pounce_cooldown
else if(A.density && !A.CanPass(src))
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='userdanger'>You smash into [A]!</span>")
playsound(src, 'sound/items/trayhit1.ogg', 50, 1)
Knockdown(45, 1, 1)
if(leaping)
leaping = 0
pixel_y = initial(pixel_y)
update_icons()
update_canmove()
@@ -4,20 +4,24 @@
/mob/living/silicon/robot/Move(NewLoc, direct)
. = ..()
if(. && sprinting && !(movement_type & FLYING) && canmove && !resting)
if(istype(cell))
cell.charge -= 25
if(!(cell?.use(25)))
togglesprint(TRUE)
/mob/living/silicon/robot/movement_delay()
. = ..()
if(!resting && !sprinting)
. += 1
/mob/living/silicon/robot/proc/togglesprint() //Basically a copypaste of the proc from /mob/living/carbon/human
sprinting = !sprinting
/mob/living/silicon/robot/proc/togglesprint(shutdown = FALSE) //Basically a copypaste of the proc from /mob/living/carbon/human
if(!shutdown && (!cell || cell.charge < 25))
return FALSE
sprinting = shutdown ? FALSE : !sprinting
if(!resting && canmove)
if(sprinting)
playsound_local(src, 'modular_citadel/sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
else
if(shutdown)
playsound_local(src, 'sound/effects/light_flicker.ogg', 50, FALSE, pressure_affected = FALSE)
playsound_local(src, 'modular_citadel/sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
if(hud_used && hud_used.static_inventory)
for(var/obj/screen/sprintbutton/selector in hud_used.static_inventory)
@@ -41,6 +41,10 @@
devourable = TRUE
digestable = TRUE
/mob/living/simple_animal/kiwi
devourable = TRUE
digestable = TRUE
//STATION PETS
/mob/living/simple_animal/pet
devourable = TRUE
@@ -65,7 +69,6 @@
/mob/living/simple_animal/sloth
devourable = TRUE
digestable = TRUE
feeding = TRUE
/mob/living/simple_animal/parrot
devourable = TRUE
@@ -84,57 +87,48 @@
/mob/living/simple_animal/hostile/lizard
devourable = TRUE
digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/alien
devourable = TRUE
digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/bear
devourable = TRUE
digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/poison/giant_spider
devourable = TRUE
digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/retaliate/poison/snake
devourable = TRUE
digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/gorilla
devourable = TRUE
digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/asteroid/goliath
devourable = TRUE
digestable = TRUE
feeding = TRUE
feeding = TRUE //for pet Goliaths I guess or something.
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/carp
devourable = TRUE
digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
@@ -1,10 +0,0 @@
/mob/living/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg) //Can't go below remaining duration
if(((status_flags & CANKNOCKDOWN) && !has_trait(TRAIT_STUNIMMUNE)) || ignore_canknockdown)
if(absorb_stun(isnull(override_hardstun)? amount : override_hardstun, ignore_canknockdown))
return
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
if(K)
K.duration = max(world.time + (isnull(override_hardstun)? amount : override_hardstun), K.duration)
else if((amount || override_hardstun) > 0)
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating, override_hardstun, override_stamdmg)
return K
@@ -9,13 +9,3 @@
return 0
else
return ..()
/obj/item/gun/proc/getinaccuracy(mob/living/user)
if(!iscarbon(user))
return 0
else
var/mob/living/carbon/holdingdude = user
if(istype(holdingdude) && holdingdude.combatmode)
return max((holdingdude.lastdirchange + weapon_weight * 25) - world.time,0)
else
return weapon_weight * 25
@@ -1,117 +0,0 @@
//////Flechette Launcher//////
///projectiles///
/obj/item/projectile/bullet/cflechetteap //shreds armor
name = "flechette (armor piercing)"
damage = 8
armour_penetration = 80
/obj/item/projectile/bullet/cflechettes //shreds flesh and forces bleeding
name = "flechette (serrated)"
damage = 15
dismemberment = 10
armour_penetration = -80
/obj/item/projectile/bullet/cflechettes/on_hit(atom/target, blocked = FALSE)
if((blocked != 100) && iscarbon(target))
var/mob/living/carbon/C = target
C.bleed(10)
return ..()
///ammo casings (CASELESS AMMO CASINGS WOOOOOOOO)///
/obj/item/ammo_casing/caseless/flechetteap
name = "flechette (armor piercing)"
desc = "A flechette made with a tungsten alloy."
projectile_type = /obj/item/projectile/bullet/cflechetteap
caliber = "flechette"
throwforce = 1
throw_speed = 3
/obj/item/ammo_casing/caseless/flechettes
name = "flechette (serrated)"
desc = "A serrated flechette made of a special alloy intended to deform drastically upon penetration of human flesh."
projectile_type = /obj/item/projectile/bullet/cflechettes
caliber = "flechette"
throwforce = 2
throw_speed = 3
embedding = list("embedded_pain_multiplier" = 0, "embed_chance" = 40, "embedded_fall_chance" = 10)
///magazine///
/obj/item/ammo_box/magazine/flechette
name = "flechette magazine (armor piercing)"
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "flechettemag"
ammo_type = /obj/item/ammo_casing/caseless/flechetteap
caliber = "flechette"
max_ammo = 40
multiple_sprites = 2
/obj/item/ammo_box/magazine/flechette/s
name = "flechette magazine (serrated)"
ammo_type = /obj/item/ammo_casing/caseless/flechettes
///the gun itself///
/obj/item/gun/ballistic/automatic/flechette
name = "\improper CX Flechette Launcher"
desc = "A flechette launching machine pistol with an unconventional bullpup frame."
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "flechettegun"
item_state = "gun"
w_class = WEIGHT_CLASS_NORMAL
slot_flags = 0
/obj/item/firing_pin/implant/pindicate
mag_type = /obj/item/ammo_box/magazine/flechette/
fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = 0
burst_size = 5
fire_delay = 1
casing_ejector = 0
spread = 10
recoil = 0.05
/obj/item/gun/ballistic/automatic/flechette/update_icon()
..()
if(magazine)
cut_overlays()
add_overlay("flechettegun-magazine")
else
cut_overlays()
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
///unique variant///
/obj/item/projectile/bullet/cflechetteshredder
name = "flechette (shredder)"
damage = 5
dismemberment = 40
/obj/item/ammo_casing/caseless/flechetteshredder
name = "flechette (shredder)"
desc = "A serrated flechette made of a special alloy that forms a monofilament edge."
projectile_type = /obj/item/projectile/bullet/cflechettes
/obj/item/ammo_box/magazine/flechette/shredder
name = "flechette magazine (shredder)"
icon_state = "shreddermag"
ammo_type = /obj/item/ammo_casing/caseless/flechetteshredder
/obj/item/gun/ballistic/automatic/flechette/shredder
name = "\improper CX Shredder"
desc = "A flechette launching machine pistol made of ultra-light CFRP optimized for firing serrated monofillament flechettes."
w_class = WEIGHT_CLASS_SMALL
mag_type = /obj/item/ammo_box/magazine/flechette/shredder
spread = 15
recoil = 0.1
/obj/item/gun/ballistic/automatic/flechette/shredder/update_icon()
..()
if(magazine)
cut_overlays()
add_overlay("shreddergun-magazine")
else
cut_overlays()
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
@@ -86,7 +86,7 @@
/obj/item/ammo_box/magazine/mmag/small
name = "magpistol magazine (non-lethal disabler)"
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "nlmagmag"
icon_state = "smallmagmag"
ammo_type = /obj/item/ammo_casing/caseless/anlmags
caliber = "mags"
max_ammo = 15
@@ -56,7 +56,7 @@
/obj/item/ammo_box/magazine/mmag_e/small
name = "magpistol magazine (non-lethal disabler)"
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "nlmagmag"
icon_state = "smallmagmag"
ammo_type = /obj/item/ammo_casing/caseless/mag_e/anlmags
caliber = "mag_e"
max_ammo = 16
@@ -123,8 +123,8 @@
item_state = "gun"
w_class = WEIGHT_CLASS_NORMAL
slot_flags = 0
/obj/item/firing_pin/implant/pindicate
mag_type = /obj/item/ammo_box/magazine/flechette/
pin = /obj/item/firing_pin/implant/pindicate
mag_type = /obj/item/ammo_box/magazine/flechette
fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = 0
burst_size = 5
@@ -134,12 +134,9 @@
recoil = 0.05
/obj/item/gun/ballistic/automatic/flechette/update_icon()
..()
cut_overlays()
if(magazine)
cut_overlays()
add_overlay("flechettegun-magazine")
else
cut_overlays()
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
///unique variant///
@@ -163,17 +160,13 @@
name = "\improper CX Shredder"
desc = "A flechette launching machine pistol made of ultra-light CFRP optimized for firing serrated monofillament flechettes."
w_class = WEIGHT_CLASS_SMALL
mag_type = /obj/item/ammo_box/magazine/flechette/shredder
spread = 15
recoil = 0.1
/obj/item/gun/ballistic/automatic/flechette/shredder/update_icon()
..()
cut_overlays()
if(magazine)
cut_overlays()
add_overlay("shreddergun-magazine")
else
cut_overlays()
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
/*/////////////////////////////////////////////////////////////
@@ -17,13 +17,13 @@
M.adjustStaminaLoss(-5*REM)
. = ..()
/datum/reagent/syndicateadrenals/on_mob_add(mob/living/M)
/datum/reagent/syndicateadrenals/on_mob_metabolize(mob/living/M)
. = ..()
if(istype(M))
M.next_move_modifier *= 0.5
to_chat(M, "<span class='notice'>You feel an intense surge of energy rushing through your veins.</span>")
/datum/reagent/syndicateadrenals/on_mob_delete(mob/living/M)
/datum/reagent/syndicateadrenals/on_mob_end_metabolize(mob/living/M)
. = ..()
if(istype(M))
M.next_move_modifier *= 2
@@ -16,6 +16,7 @@
"purple hypovial" = "hypovial-p",
"black hypovial" = "hypovial-t"
)
always_reskinnable = TRUE
/obj/item/reagent_containers/glass/bottle/vial/Initialize()
. = ..()
@@ -29,17 +30,6 @@
/obj/item/reagent_containers/glass/bottle/vial/on_reagent_change()
update_icon()
/obj/item/reagent_containers/glass/bottle/vial/reskin_obj(mob/M) //Makes the vials completely reskinnable, and renames them - overrides /obj/proc/reskin_obj
if(!LAZYLEN(unique_reskin))
return
var/choice = input(M,"Do you wish to recolour your [src]?","Vial Recolour") as null|anything in unique_reskin
if(!QDELETED(src) && choice && !current_skin && !M.incapacitated() && in_range(M,src))
if(!unique_reskin[choice])
return
icon_state = unique_reskin[choice]
name = choice
to_chat(M, "[src] is now skinned as '[choice].'")
/obj/item/reagent_containers/glass/bottle/vial/update_icon()
cut_overlays()
if(reagents.total_volume)
@@ -100,7 +100,7 @@
color = "#FFADFF"//PINK, rgb(255, 173, 255)
/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M)
if(M && M.canbearoused && !M.has_trait(TRAIT_CROCRIN_IMMUNE))
if(M && M.canbearoused && !HAS_TRAIT(M, TRAIT_CROCRIN_IMMUNE))
if(prob(33))
M.adjustArousalLoss(2)
if(prob(5))
@@ -122,7 +122,7 @@
overdose_threshold = 20
/datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M)
if(M && M.canbearoused && !M.has_trait(TRAIT_CROCRIN_IMMUNE))
if(M && M.canbearoused && !HAS_TRAIT(M, TRAIT_CROCRIN_IMMUNE))
if(prob(33))
M.adjustArousalLoss(6)//not quite six times as powerful, but still considerably more powerful.
if(prob(5))
@@ -154,12 +154,10 @@
..()
/datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M)
if(M && M.canbearoused && !M.has_trait(TRAIT_CROCRIN_IMMUNE) && prob(33))
if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna())
var/mob/living/carbon/human/H = M
if(prob(50)) //Less spam
to_chat(H, "<span class='love'>Your libido is going haywire!</span>")
H.mob_climax(forced_climax=TRUE)
if(M && M.canbearoused && !HAS_TRAIT(M, TRAIT_CROCRIN_IMMUNE) && prob(33))
if(prob(5) && M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna())
if(prob(5)) //Less spam
to_chat(M, "<span class='love'>Your libido is going haywire!</span>")
if(M.min_arousal < 50)
M.min_arousal += 1
if(M.min_arousal < M.max_arousal)
@@ -19,7 +19,7 @@
display_name = "Games and Toys"
description = "For the slackers on the station."
prereq_ids = list("comptech")
design_ids = list("arcade_battle", "arcade_orion", "slotmachine", "autoylathe")
design_ids = list("arcade_battle", "arcade_orion", "arcade_minesweeper", "slotmachine", "autoylathe")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000)
export_price = 5000
@@ -1,18 +0,0 @@
/*
// PUT ALL YOUR NEW UPLINK STUFF HERE, OVERRIDES GO IN HERE TOO
*/
/datum/uplink_item/device_tools/emagrecharge
name = "Electromagnet Charging Device"
desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer."
item = /obj/item/emagrecharge
cost = 2
/datum/uplink_item/dangerous/revolver
item = /obj/item/gun/ballistic/revolver/syndie
/datum/uplink_item/dangerous/phantomthief
name = "Syndicate Mask"
desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles"
item = /obj/item/clothing/glasses/phantomthief/syndicate
cost = 2
@@ -49,13 +49,16 @@
var/sound/pred_death = sound(get_sfx("death_pred"))
var/turf/source = get_turf(owner)
///////////////////////////// DM_HOLD /////////////////////////////
if(digest_mode == DM_HOLD)
return SSBELLIES_PROCESSED
//////////////////////////// DM_DIGEST ////////////////////////////
else if(digest_mode == DM_DIGEST)
if(HAS_TRAIT(owner, TRAIT_PACIFISM)) //obvious.
digest_mode = DM_NOISY
return
for (var/mob/living/M in contents)
if(prob(25))
if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
@@ -210,6 +213,10 @@
//////////////////////////DM_DRAGON /////////////////////////////////////
//because dragons need snowflake guts
if(digest_mode == DM_DRAGON)
if(HAS_TRAIT(owner, TRAIT_PACIFISM)) //imagine var editing this when you're a pacifist. smh
digest_mode = DM_NOISY
return
for (var/mob/living/M in contents)
if(prob(55)) //if you're hearing this, you're a vore ho anyway.
if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
@@ -57,6 +57,7 @@
/datum/vore_look/proc/gen_vui(var/mob/living/user)
var/dat
dat += "Remember to toggle the vore mode, it's to the left of your combat toggle. Open mouth means you're voracious!<br>"
dat += "Remember that your prey is blind, use audible mode subtle messages to communicate to them with posts!<br>"
dat += "<HR>"
var/atom/userloc = user.loc
if (isbelly(userloc))