Merge remote-tracking branch 'refs/remotes/origin/master' into syntheticbloods
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)]->[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)]->[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)] °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)] °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))
|
||||
|
||||
Reference in New Issue
Block a user