Merge branch 'master' into FERMICHEMCurTweaks

This commit is contained in:
Fermi
2019-11-23 00:10:33 +00:00
3018 changed files with 65365 additions and 157564 deletions
@@ -1,2 +0,0 @@
GLOBAL_LIST_EMPTY(mentors) //all clients whom are admins
GLOBAL_PROTECT(mentors)
@@ -1,4 +0,0 @@
/datum/config_entry/flag/mentors_mobname_only
/datum/config_entry/flag/mentor_legacy_system //Defines whether the server uses the legacy mentor system with mentors.txt or the SQL system
protection = CONFIG_ENTRY_LOCKED
@@ -1,40 +0,0 @@
/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, equipbackpackstuff)
var/mob/the_mob = N
if(!the_mob)
the_mob = M // cause this doesn't get assigned if player is a latejoiner
if(the_mob.client && the_mob.client.prefs && (the_mob.client.prefs.chosen_gear && the_mob.client.prefs.chosen_gear.len))
if(!ishuman(M))//no silicons allowed
return
for(var/i in the_mob.client.prefs.chosen_gear)
var/datum/gear/G = i
G = GLOB.loadout_items[slot_to_string(initial(G.category))][initial(G.name)]
if(!G)
continue
var/permitted = TRUE
if(G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles))
permitted = FALSE
if(G.donoritem && !G.donator_ckey_check(the_mob.client.ckey))
permitted = FALSE
if(!equipbackpackstuff && G.category == SLOT_IN_BACKPACK)//snowflake check since plopping stuff in the backpack doesnt work for pre-job equip loadout stuffs
permitted = FALSE
if(equipbackpackstuff && G.category != SLOT_IN_BACKPACK)//ditto
permitted = FALSE
if(!permitted)
continue
var/obj/item/I = new G.path
if(!M.equip_to_slot_if_possible(I, G.category, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // If the job's dresscode compliant, try to put it in its slot, first
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/storage/backpack/B = C.back
if(!B || !SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, I, null, TRUE, TRUE)) // Otherwise, try to put it in the backpack, for carbons.
I.forceMove(get_turf(C))
else if(!M.equip_to_slot_if_possible(I, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // Otherwise, try to put it in the backpack
I.forceMove(get_turf(M)) // If everything fails, just put it on the floor under the mob.
/datum/controller/subsystem/job/proc/FreeRole(rank)
if(!rank)
return
var/datum/job/job = GetJob(rank)
if(!job)
return FALSE
job.current_positions = max(0, job.current_positions - 1)
@@ -1,7 +0,0 @@
/datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end after 2 hours have passed.
if((world.realtime - SSshuttle.realtimeofstart) > auto_call && EMERGENCY_IDLE_OR_RECALLED) //2 hours
SSshuttle.emergency.request(silent = TRUE)
priority_announce("The shift has come to an end and the shuttle called. [seclevel2num(get_security_level()) == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, 'sound/ai/shuttlecalled.ogg', "Priority")
log_game("Round time limit reached. Shuttle has been auto-called.")
message_admins("Round time limit reached. Shuttle called.")
emergencyNoRecall = TRUE
@@ -1,49 +0,0 @@
//This component applies a customizable drop_shadow filter to its wearer when they toggle combat mode on or off. This can stack.
/datum/component/phantomthief
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
var/filter_x
var/filter_y
var/filter_size
var/filter_border
var/filter_color
var/datum/component/redirect/combattoggle_redir
/datum/component/phantomthief/Initialize(_x = -2, _y = 0, _size = 0, _border = 0, _color = "#E62111")
filter_x = _x
filter_y = _y
filter_size = _size
filter_border = _border
filter_color = _color
RegisterSignal(parent, COMSIG_COMBAT_TOGGLED, .proc/handlefilterstuff)
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/OnEquipped)
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/OnDropped)
/datum/component/phantomthief/proc/handlefilterstuff(mob/user, combatmodestate)
if(istype(user))
var/thefilter = filter(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, border = filter_border, color = filter_color)
if(!combatmodestate)
user.filters -= thefilter
else
user.filters += thefilter
/datum/component/phantomthief/proc/stripdesiredfilter(mob/user)
if(istype(user))
var/thefilter = filter(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, border = filter_border, color = filter_color)
user.filters -= thefilter
/datum/component/phantomthief/proc/OnEquipped(mob/user, slot)
if(!istype(user))
return
if(!combattoggle_redir)
combattoggle_redir = user.AddComponent(/datum/component/redirect, list(COMSIG_COMBAT_TOGGLED = CALLBACK(src, .proc/handlefilterstuff)))
/datum/component/phantomthief/proc/OnDropped(mob/user)
if(!istype(user))
return
if(combattoggle_redir)
QDEL_NULL(combattoggle_redir)
stripdesiredfilter(user)
@@ -29,7 +29,7 @@
if(!wearer)
return //idfk
new/obj/effect/temp_visual/souldeath(wearer.loc, wearer)
playsound(wearer, 'modular_citadel/sound/misc/souldeath.ogg', 100, FALSE)
playsound(wearer, 'sound/misc/souldeath.ogg', 100, FALSE)
/datum/component/souldeath/neck
equip_slot = SLOT_NECK
@@ -1,59 +1,59 @@
/datum/mood_event/eigenstate
mood_change = -3
description = "<span class='warning'>Where the hell am I? Is this an alternative dimension ?</span>\n"
mood_change = -3
description = "<span class='warning'>Where the hell am I? Is this an alternative dimension ?</span>\n"
/datum/mood_event/enthrall
mood_change = 5
mood_change = 5
/datum/mood_event/enthrall/add_effects(message)
description = "<span class='nicegreen'>[message]</span>\n"
description = "<span class='nicegreen'>[message]</span>\n"
/datum/mood_event/enthrallpraise
mood_change = 10
timeout = 1 MINUTES
/datum/mood_event/enthrallpraise/add_effects(message)
description = "<span class='nicegreen'>[message]</span>\n"
description = "<span class='nicegreen'>[message]</span>\n"
/datum/mood_event/enthrallscold
mood_change = -10
timeout = 1 MINUTES
mood_change = -10
timeout = 1 MINUTES
/datum/mood_event/enthrallscold/add_effects(message)
description = "<span class='warning'>[message]</span>\n"//aaa I'm not kinky enough for this
/datum/mood_event/enthrallmissing1
mood_change = -5
mood_change = -5
/datum/mood_event/enthrallmissing1/add_effects(message)
description = "<span class='warning'>[message]</span>\n"
description = "<span class='warning'>[message]</span>\n"
/datum/mood_event/enthrallmissing2
mood_change = -10
mood_change = -10
/datum/mood_event/enthrallmissing2/add_effects(message)
description = "<span class='warning'>[message]</span>\n"
/datum/mood_event/enthrallmissing3
mood_change = -15
mood_change = -15
/datum/mood_event/enthrallmissing3/add_effects(message)
description = "<span class='warning'>[message]</span>\n"
/datum/mood_event/enthrallmissing4
mood_change = -25
mood_change = -25
/datum/mood_event/enthrallmissing4/add_effects(message)
description = "<span class='warning'>[message]</span>\n"
/datum/mood_event/InLove
mood_change = 10
mood_change = 10
/datum/mood_event/InLove/add_effects(message)
description = "<span class='nicegreen'>[message]</span>\n"
description = "<span class='nicegreen'>[message]</span>\n"
/datum/mood_event/MissingLove
mood_change = -10
mood_change = -10
/datum/mood_event/MissingLove/add_effects(message)
description = "<span class='warning'>[message]</span>\n"
description = "<span class='warning'>[message]</span>\n"
@@ -18,7 +18,7 @@
// Jack the Ripper starring plush
/obj/item/toy/plush/attackby(obj/item/I, mob/living/user, params)
. = ..()
if(I.is_sharp())
if(I.get_sharpness())
if(!grenade)
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plushjack", /datum/mood_event/plushjack)
@@ -37,64 +37,62 @@
alert_type = null
var/moveCalc = 1
var/cachedmoveCalc = 1
var/last_checked_size //used to prevent potential cpu waste from happening every tick.
/datum/status_effect/chem/breast_enlarger/on_apply(mob/living/carbon/human/H)//Removes clothes, they're too small to contain you. You belong to space now.
/datum/status_effect/chem/breast_enlarger/on_apply()//Removes clothes, they're too small to contain you. You belong to space now.
log_game("FERMICHEM: [owner]'s breasts has reached comical sizes. ID: [owner.key]")
var/mob/living/carbon/human/o = owner
var/items = o.get_contents()
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W, TRUE)
playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
to_chat(o, "<span class='warning'>Your clothes give, ripping into peices under the strain of your swelling breasts! Unless you manage to reduce the size of your breasts, there's no way you're going to be able to put anything on over these melons..!</b></span>")
o.visible_message("<span class='boldnotice'>[o]'s chest suddenly bursts forth, ripping their clothes off!'</span>")
else
to_chat(o, "<span class='notice'>Your bountiful bosom is so rich with mass, you seriously doubt you'll be able to fit any clothes over it.</b></span>")
return ..()
var/mob/living/carbon/human/H = owner
var/message = FALSE
if(H.w_uniform)
H.dropItemToGround(H.w_uniform, TRUE)
message = TRUE
if(H.wear_suit)
H.dropItemToGround(H.wear_suit, TRUE)
message = TRUE
if(message)
playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1)
H.visible_message("<span class='boldnotice'>[H]'s chest suddenly bursts forth, ripping their clothes off!'</span>", \
"<span class='warning'>Your clothes give, ripping into peices under the strain of your swelling breasts! Unless you manage to reduce the size of your breasts, there's no way you're going to be able to put anything on over these melons..!</b></span>")
else
to_chat(H, "<span class='notice'>Your bountiful bosom is so rich with mass, you seriously doubt you'll be able to fit any clothes over it.</b></span>")
return ..()
/datum/status_effect/chem/breast_enlarger/tick(mob/living/carbon/human/H)//If you try to wear clothes, you fail. Slows you down if you're comically huge
var/mob/living/carbon/human/o = owner
var/obj/item/organ/genital/breasts/B = o.getorganslot("breasts")
moveCalc = 1+((round(B.cached_size) - 9)/3) //Afffects how fast you move, and how often you can click.
/datum/status_effect/chem/breast_enlarger/tick()//If you try to wear clothes, you fail. Slows you down if you're comically huge
var/mob/living/carbon/human/H = owner
var/obj/item/organ/genital/breasts/B = H.getorganslot(ORGAN_SLOT_BREASTS)
if(!B)
o.remove_movespeed_modifier(BREAST_MOVEMENT_SPEED)
sizeMoveMod(1)
owner.remove_status_effect(src)
var/items = o.get_contents()
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W, TRUE)
playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
to_chat(owner, "<span class='warning'>Your enormous breasts are way too large to fit anything over them!</b></span>")
H.remove_status_effect(src)
return
moveCalc = 1+((round(B.cached_size) - 9)/3) //Afffects how fast you move, and how often you can click.
var/message = FALSE
if(H.w_uniform)
H.dropItemToGround(H.w_uniform, TRUE)
message = TRUE
if(H.wear_suit)
H.dropItemToGround(H.wear_suit, TRUE)
message = TRUE
if(message)
playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1)
to_chat(H, "<span class='warning'>Your enormous breasts are way too large to fit anything over them!</b></span>")
if(last_checked_size != B.cached_size)
H.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
sizeMoveMod(moveCalc)
if (B.size == "huge")
if(prob(1))
to_chat(owner, "<span class='notice'>Your back is feeling sore.</span>")
var/target = o.get_bodypart(BODY_ZONE_CHEST)
o.apply_damage(0.1, BRUTE, target)
if(!B.cached_size == B.breast_values[B.prev_size])
o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
sizeMoveMod(moveCalc)
return ..()
else if (B.breast_values[B.size] > B.breast_values[B.prev_size])
o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
sizeMoveMod(moveCalc)
else if (B.breast_values[B.size] < B.breast_values[B.prev_size])
o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
sizeMoveMod(moveCalc)
if((B.cached_size) < 16)
switch(round(B.cached_size))
if(9)
if (B.breast_values[B.prev_size] != B.breast_values[B.size])
to_chat(o, "<span class='notice'>Your expansive chest has become a more managable size, liberating your movements.</b></span>")
if(10 to INFINITY)
if (B.breast_values[B.prev_size] != B.breast_values[B.size])
to_chat(H, "<span class='warning'>Your indulgent busom is so substantial, it's affecting your movements!</b></span>")
var/target = H.get_bodypart(BODY_ZONE_CHEST)
H.apply_damage(0.1, BRUTE, target)
else
if(prob(1))
to_chat(owner, "<span class='notice'>Your back is feeling a little sore.</span>")
..()
to_chat(H, "<span class='notice'>Your back is feeling a little sore.</span>")
last_checked_size = B.cached_size
..()
/datum/status_effect/chem/breast_enlarger/on_remove(mob/living/carbon/M)
/datum/status_effect/chem/breast_enlarger/on_remove()
log_game("FERMICHEM: [owner]'s breasts has reduced to an acceptable size. ID: [owner.key]")
to_chat(owner, "<span class='notice'>Your expansive chest has become a more managable size, liberating your movements.</b></span>")
owner.remove_movespeed_modifier(BREAST_MOVEMENT_SPEED)
sizeMoveMod(1)
@@ -112,51 +110,57 @@
alert_type = null
var/bloodCalc
var/moveCalc
var/last_checked_size //used to prevent potential cpu waste, just like the above.
/datum/status_effect/chem/penis_enlarger/on_apply(mob/living/carbon/human/H)//Removes clothes, they're too small to contain you. You belong to space now.
/datum/status_effect/chem/penis_enlarger/on_apply()//Removes clothes, they're too small to contain you. You belong to space now.
log_game("FERMICHEM: [owner]'s dick has reached comical sizes. ID: [owner.key]")
var/mob/living/carbon/human/o = owner
var/items = o.get_contents()
if(o.w_uniform || o.wear_suit)
to_chat(o, "<span class='warning'>Your clothes give, ripping into peices under the strain of your swelling pecker! Unless you manage to reduce the size of your emancipated trouser snake, there's no way you're going to be able to put anything on over this girth..!</b></span>")
owner.visible_message("<span class='boldnotice'>[o]'s schlong suddenly bursts forth, ripping their clothes off!'</span>")
var/mob/living/carbon/human/H = owner
var/message = FALSE
if(H.w_uniform)
H.dropItemToGround(H.w_uniform, TRUE)
message = TRUE
if(H.wear_suit)
H.dropItemToGround(H.wear_suit, TRUE)
message = TRUE
if(message)
playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1)
H.visible_message("<span class='boldnotice'>[H]'s schlong suddenly bursts forth, ripping their clothes off!'</span>", \
"<span class='warning'>Your clothes give, ripping into peices under the strain of your swelling pecker! Unless you manage to reduce the size of your emancipated trouser snake, there's no way you're going to be able to put anything on over this girth..!</b></span>")
else
to_chat(o, "<span class='notice'>Your emancipated trouser snake is so ripe with girth, you seriously doubt you'll be able to fit any clothes over it.</b></span>")
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W, TRUE)
playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
to_chat(H, "<span class='notice'>Your emancipated trouser snake is so ripe with girth, you seriously doubt you'll be able to fit any clothes over it.</b></span>")
return ..()
/datum/status_effect/chem/penis_enlarger/tick(mob/living/carbon/M)
var/mob/living/carbon/human/o = owner
var/obj/item/organ/genital/penis/P = o.getorganslot("penis")
/datum/status_effect/chem/penis_enlarger/tick()
var/mob/living/carbon/human/H = owner
var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
if(!P)
owner.remove_status_effect(src)
return
moveCalc = 1+((round(P.length) - 21)/3) //effects how fast you can move
bloodCalc = 1+((round(P.length) - 21)/15) //effects how much blood you need (I didn' bother adding an arousal check because I'm spending too much time on this organ already.)
if(!P)
o.remove_movespeed_modifier(DICK_MOVEMENT_SPEED)
o.ResetBloodVol()
owner.remove_status_effect(src)
var/items = o.get_contents()
for(var/obj/item/W in items)
if(W == o.w_uniform || W == o.wear_suit)
o.dropItemToGround(W, TRUE)
playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
to_chat(owner, "<span class='warning'>Your enormous package is way to large to fit anything over!</b></span>")
switch(round(P.cached_length))
if(21)
to_chat(o, "<span class='notice'>Your rascally willy has become a more managable size, liberating your movements.</b></span>")
o.remove_movespeed_modifier(DICK_MOVEMENT_SPEED)
o.AdjustBloodVol(bloodCalc)
if(22 to INFINITY)
if(prob(2))
to_chat(o, "<span class='warning'>Your indulgent johnson is so substantial, it's taking all your blood and affecting your movements!</b></span>")
o.add_movespeed_modifier(DICK_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
o.AdjustBloodVol(bloodCalc)
var/message = FALSE
if(H.w_uniform)
H.dropItemToGround(H.w_uniform, TRUE)
message = TRUE
if(H.wear_suit)
H.dropItemToGround(H.wear_suit, TRUE)
message = TRUE
if(message)
playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1)
to_chat(H, "<span class='warning'>Your enormous package is way to large to fit anything over!</b></span>")
if(P.length < 22 && H.has_movespeed_modifier(DICK_MOVEMENT_SPEED))
to_chat(owner, "<span class='notice'>Your rascally willy has become a more managable size, liberating your movements.</b></span>")
H.remove_movespeed_modifier(DICK_MOVEMENT_SPEED)
else if(P.length >= 22 && !H.has_movespeed_modifier(DICK_MOVEMENT_SPEED))
to_chat(H, "<span class='warning'>Your indulgent johnson is so substantial, it's taking all your blood and affecting your movements!</b></span>")
H.add_movespeed_modifier(DICK_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
H.AdjustBloodVol(bloodCalc)
..()
/datum/status_effect/chem/penis_enlarger/on_remove(mob/living/carbon/human/o)
/datum/status_effect/chem/penis_enlarger/on_remove()
log_game("FERMICHEM: [owner]'s dick has reduced to an acceptable size. ID: [owner.key]")
owner.remove_movespeed_modifier(DICK_MOVEMENT_SPEED)
owner.ResetBloodVol()
@@ -230,7 +234,6 @@
var/enthrallGender //Use master or mistress
var/mental_capacity //Higher it is, lower the cooldown on commands, capacity reduces with resistance.
var/datum/weakref/redirect_component //resistance
var/distancelist = list(2,1.5,1,0.8,0.6,0.5,0.4,0.3,0.2) //Distance multipliers
@@ -260,7 +263,7 @@
master = get_mob_by_key(enthrallID)
//if(M.ckey == enthrallID)
// owner.remove_status_effect(src)//At the moment, a user can enthrall themselves, toggle this back in if that should be removed.
redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/owner_resist)))) //Do resistance calc if resist is pressed#
RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/owner_resist) //Do resistance calc if resist is pressed#
RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/owner_hear)
mental_capacity = 500 - M.getOrganLoss(ORGAN_SLOT_BRAIN)//It's their brain!
var/mob/living/carbon/human/H = owner
@@ -532,7 +535,7 @@
cooldown += 1 //Cooldown doesn't process till status is done
else if(status == "charge")
ADD_TRAIT(owner, TRAIT_GOTTAGOFAST, "MKUltra")
owner.add_movespeed_modifier(MOVESPEED_ID_MKULTRA, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING))
status = "charged"
if(master.client?.prefs.lewdchem)
to_chat(owner, "<span class='notice'><i>Your [enthrallGender]'s order fills you with a burst of speed!</i></span>")
@@ -542,7 +545,7 @@
else if (status == "charged")
if (statusStrength < 0)
status = null
REMOVE_TRAIT(owner, TRAIT_GOTTAGOFAST, "MKUltra")
owner.remove_movespeed_modifier(MOVESPEED_ID_MKULTRA)
owner.Knockdown(50)
to_chat(owner, "<span class='notice'><i>Your body gives out as the adrenaline in your system runs out.</i></span>")
else
@@ -598,8 +601,7 @@
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing2")
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing3")
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing4")
qdel(redirect_component.resolve())
redirect_component = null
UnregisterSignal(M, COMSIG_LIVING_RESIST)
UnregisterSignal(owner, COMSIG_MOVABLE_HEAR)
REMOVE_TRAIT(owner, TRAIT_PACIFISM, "MKUltra")
to_chat(owner, "<span class='big redtext'><i>You're now free of [master]'s influence, and fully independent!'</i></span>")
@@ -1 +0,0 @@
// Citadel-specific Negative Traits
@@ -1,43 +0,0 @@
// Citadel-specific Neutral Traits
/datum/quirk/libido
name = "Nymphomania"
desc = "You're always feeling a bit in heat. Also, you get aroused faster than usual."
value = 0
mob_trait = TRAIT_NYMPHO
gain_text = "<span class='notice'>You are feeling extra wild.</span>"
lose_text = "<span class='notice'>You don't feel that burning sensation anymore.</span>"
/datum/quirk/libido/add()
var/mob/living/M = quirk_holder
M.min_arousal = 16
M.arousal_rate = 3
/datum/quirk/libido/remove()
var/mob/living/M = quirk_holder
M.min_arousal = initial(M.min_arousal)
M.arousal_rate = initial(M.arousal_rate)
/datum/quirk/libido/on_process()
var/mob/living/M = quirk_holder
if(M.canbearoused == FALSE)
to_chat(quirk_holder, "<span class='notice'>Having high libido is useless when you can't feel arousal at all!</span>")
qdel(src)
/datum/quirk/maso
name = "Masochism"
desc = "You are aroused by pain."
value = 0
mob_trait = TRAIT_MASO
gain_text = "<span class='notice'>You desire to be hurt.</span>"
lose_text = "<span class='notice'>Pain has become less exciting for you.</span>"
/datum/quirk/pharmacokinesis //Prevents unwanted organ additions.
name = "Acute hepatic pharmacokinesis"
desc = "You've a rare genetic disorder that causes Incubus draft and Sucubus milk to be absorbed by your liver instead."
value = 0
mob_trait = TRAIT_PHARMA
lose_text = "<span class='notice'>Your liver feels different.</span>"
var/active = FALSE
var/power = 0
var/cachedmoveCalc = 1
@@ -1,40 +0,0 @@
/datum/wires/airlock
proper_name = "Generic Airlock"
var/wiretype
/datum/wires/airlock/command
proper_name = "Command Airlock"
wiretype = "commandairlock"
/datum/wires/airlock/security
proper_name = "Security Airlock"
wiretype = "securityairlock"
/datum/wires/airlock/engineering
proper_name = "Engineering Airlock"
wiretype = "engineeringairlock"
/datum/wires/airlock/science
proper_name = "Science Airlock"
wiretype = "scienceairlock"
/datum/wires/airlock/medical
proper_name = "Medical Airlock"
wiretype = "medicalairlock"
/datum/wires/airlock/cargo
proper_name = "Cargo Airlock"
wiretype = "cargoairlock"
/datum/wires/airlock/New(atom/holder)
. = ..()
if(randomize)
return
if(wiretype)
if(!GLOB.wire_color_directory[wiretype])
colors = list()
randomize()
GLOB.wire_color_directory[wiretype] = colors
GLOB.wire_name_directory[wiretype] = proper_name
else
colors = GLOB.wire_color_directory[wiretype]
Binary file not shown.

Before

Width:  |  Height:  |  Size: 559 B

@@ -1,18 +0,0 @@
/area/maintenance/bar
name = "Maintenance Bar"
icon = 'modular_citadel/code/game/area/areas.dmi'
icon_state = "maintbar"
/area/maintenance/bar/cafe
name = "Abandoned Cafe"
/area/crew_quarters/theatre/clown
name = "Clown's Office"
/area/crew_quarters/theatre/mime
name = "Mime's Office"
/area/crew_quarters/cryopod
name = "Cryogenics"
icon = 'modular_citadel/code/game/area/areas.dmi'
icon_state = "cryo"
@@ -53,19 +53,17 @@
/obj/machinery/dominator/update_icon()
cut_overlays()
if(!(stat & BROKEN))
icon_state = "dominator-active"
if(operating)
var/mutable_appearance/dominator_overlay = mutable_appearance('icons/obj/machines/dominator.dmi', "dominator-overlay")
if(gang)
dominator_overlay.color = gang.color
add_overlay(dominator_overlay)
else
icon_state = "dominator"
if(obj_integrity/max_integrity < 0.66)
add_overlay("damage")
else
if(stat & BROKEN)
icon_state = "dominator-broken"
return
icon_state = "dominator"
if(operating)
var/mutable_appearance/dominator_overlay = mutable_appearance('icons/obj/machines/dominator.dmi', "dominator-overlay")
if(gang)
dominator_overlay.color = gang.color
add_overlay(dominator_overlay)
if(obj_integrity/max_integrity < 0.66)
add_overlay("damage")
/obj/machinery/dominator/examine(mob/user)
..()
@@ -168,7 +166,7 @@
examine(user)
return
if(tempgang.domination_time != NOT_DOMINATING)
if(tempgang.domination_time != NOT_DOMINATING)
to_chat(user, "<span class='warning'>Error: Hostile Takeover is already in progress.</span>")
return
@@ -130,7 +130,7 @@
/obj/item/device/gangtool/proc/ping_gang(mob/user)
if(!can_use(user))
return
var/message = stripped_input(user,"Discreetly send a gang-wide message.","Send Message") as null|text
var/message = stripped_input(user,"Discreetly send a gang-wide message.","Send Message")
if(!message || !can_use(user))
return
if(!is_station_level(user.z))
@@ -1,3 +0,0 @@
/obj/machinery/computer/card
list/blacklisted = list(
"Quartermaster")
@@ -1,2 +0,0 @@
/obj/machinery/door/airlock
var/wiretypepath = /datum/wires/airlock
@@ -1,29 +0,0 @@
/obj/machinery/door/airlock/command
wiretypepath = /datum/wires/airlock/command
/obj/machinery/door/airlock/security
wiretypepath = /datum/wires/airlock/security
/obj/machinery/door/airlock/engineering
wiretypepath = /datum/wires/airlock/engineering
/obj/machinery/door/airlock/medical
wiretypepath = /datum/wires/airlock/medical
/obj/machinery/door/airlock/mining
wiretypepath = /datum/wires/airlock/cargo
/obj/machinery/door/airlock/atmos
wiretypepath = /datum/wires/airlock/engineering
/obj/machinery/door/airlock/research
wiretypepath = /datum/wires/airlock/science
/obj/machinery/door/airlock/science
wiretypepath = /datum/wires/airlock/science
/obj/machinery/door/airlock/virology
wiretypepath = /datum/wires/airlock/medical
/obj/machinery/door/airlock/vault
wiretypepath = /datum/wires/airlock/secure
+29 -19
View File
@@ -4,24 +4,34 @@
/obj/machinery/autoylathe
name = "autoylathe"
desc = "It produces items using plastic, metal and glass."
desc = "It produces toys using plastic, metal and glass."
icon_state = "autolathe"
density = TRUE
anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 10
active_power_usage = 100
circuit = /obj/item/circuitboard/machine/autoylathe
layer = BELOW_OBJ_LAYER
var/operating = FALSE
var/list/L = list()
var/list/LL = list()
var/hacked = FALSE
var/disabled = FALSE
var/disabled = 0
var/shocked = FALSE
var/hack_wire
var/disable_wire
var/shock_wire
var/busy = FALSE
var/prod_coeff = 1
var/datum/design/being_built
var/datum/techweb/stored_research
var/list/datum/design/matching_designs
var/selected_category
var/screen = 1
var/list/categories = list(
"Toys",
"Figurines",
@@ -36,8 +46,8 @@
)
/obj/machinery/autoylathe/Initialize()
. = ..()
AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASTIC), 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
. = ..()
wires = new /datum/wires/autoylathe(src)
stored_research = new /datum/techweb/specialized/autounlocking/autoylathe
@@ -47,7 +57,8 @@
QDEL_NULL(wires)
return ..()
/obj/machinery/autoylathe/interact(mob/user)
/obj/machinery/autoylathe/ui_interact(mob/user)
. = ..()
if(!is_operational())
return
@@ -69,7 +80,7 @@
popup.open()
/obj/machinery/autoylathe/on_deconstruction()
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
/obj/machinery/autoylathe/attackby(obj/item/O, mob/user, params)
@@ -81,9 +92,6 @@
updateUsrDialog()
return TRUE
if(exchange_parts(user, O))
return TRUE
if(default_deconstruction_crowbar(O))
return TRUE
@@ -148,6 +156,7 @@
var/multiplier = text2num(href_list["multiplier"])
var/is_stack = ispath(being_built.build_path, /obj/item/stack)
multiplier = CLAMP(multiplier,1,50)
/////////////////
@@ -157,7 +166,7 @@
var/plastic_cost = being_built.materials[MAT_PLASTIC]
var/power = max(2000, (metal_cost+glass_cost+plastic_cost)*multiplier/5)
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if((materials.amount(MAT_METAL) >= metal_cost*multiplier*coeff) && (materials.amount(MAT_GLASS) >= glass_cost*multiplier*coeff) && (materials.amount(MAT_PLASTIC) >= plastic_cost*multiplier*coeff))
busy = TRUE
use_power(power)
@@ -169,7 +178,7 @@
matching_designs.Cut()
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(findtext(D.name,href_list["to_search"]))
matching_designs.Add(D)
updateUsrDialog()
@@ -181,7 +190,7 @@
return
/obj/machinery/autoylathe/proc/make_item(power, metal_cost, glass_cost, plastic_cost, multiplier, coeff, is_stack)
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/atom/A = drop_location()
use_power(power)
var/list/materials_used = list(MAT_METAL=metal_cost*coeff*multiplier, MAT_GLASS=glass_cost*coeff*multiplier, MAT_PLASTIC=plastic_cost*coeff*multiplier)
@@ -194,6 +203,7 @@
else
for(var/i=1, i<=multiplier, i++)
var/obj/item/new_item = new being_built.build_path(A)
new_item.materials = new_item.materials.Copy()
for(var/mat in materials_used)
new_item.materials[mat] = materials_used[mat] / multiplier
new_item.autoylathe_crafted(src)
@@ -205,7 +215,7 @@
var/T = 0
for(var/obj/item/stock_parts/matter_bin/MB in component_parts)
T += MB.rating*75000
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.max_amount = T
T=1.2
for(var/obj/item/stock_parts/manipulator/M in component_parts)
@@ -244,7 +254,7 @@
dat += materials_printout()
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(!(selected_category in D.category))
continue
@@ -254,7 +264,7 @@
dat += "<a href='?src=[REF(src)];make=[D.id];multiplier=1'>[D.name]</a>"
if(ispath(D.build_path, /obj/item/stack))
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS] ?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY,D.materials[MAT_PLASTIC] ?round(materials.amount(MAT_PLASTIC)/D.materials[MAT_PLASTIC]):INFINITY)
if (max_multiplier>10 && !disabled)
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
@@ -286,7 +296,7 @@
dat += "<a href='?src=[REF(src)];make=[D.id];multiplier=1'>[D.name]</a>"
if(ispath(D.build_path, /obj/item/stack))
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS] ?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY,D.materials[MAT_PLASTIC] ?round(materials.amount(MAT_PLASTIC)/D.materials[MAT_PLASTIC]):INFINITY)
if (max_multiplier>10 && !disabled)
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
@@ -301,7 +311,7 @@
return dat
/obj/machinery/autoylathe/proc/materials_printout()
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/dat = "<b>Total amount:</b> [materials.total_amount] / [materials.max_amount] cm<sup>3</sup><br>"
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
@@ -314,7 +324,7 @@
var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff)
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(D.materials[MAT_METAL] && (materials.amount(MAT_METAL) < (D.materials[MAT_METAL] * coeff * amount)))
return FALSE
if(D.materials[MAT_GLASS] && (materials.amount(MAT_GLASS) < (D.materials[MAT_GLASS] * coeff * amount)))
@@ -347,7 +357,7 @@
disabled = FALSE
/obj/machinery/autoylathe/proc/shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return FALSE
if(!prob(prb))
return FALSE
@@ -72,32 +72,7 @@
/obj/item/reagent_containers/glass/bottle/hexacrocin = 10
)
refill_canister = /obj/item/vending_refill/kink
/*
/obj/machinery/vending/nazivend
name = "Nazivend"
desc = "A vending machine containing Nazi German supplies. A label reads: \"Remember the gorrilions lost.\""
icon = 'icons/obj/citvending.dmi'
icon_state = "nazi"
vend_reply = "SIEG HEIL!"
product_slogans = "Das Vierte Reich wird zuruckkehren!;ENTFERNEN JUDEN!;Billiger als die Juden jemals geben!;Rader auf dem adminbus geht rund und rund.;Warten Sie, warum wir wieder hassen Juden?- *BZZT*"
products = list(
/obj/item/clothing/head/stalhelm = 20,
/obj/item/clothing/head/panzer = 20,
/obj/item/clothing/suit/soldiercoat = 20,
// /obj/item/clothing/under/soldieruniform = 20,
/obj/item/clothing/shoes/jackboots = 20
)
contraband = list(
/obj/item/clothing/head/naziofficer = 10,
// /obj/item/clothing/suit/officercoat = 10,
// /obj/item/clothing/under/officeruniform = 10,
/obj/item/clothing/suit/space/hardsuit/nazi = 3,
/obj/item/gun/energy/plasma/MP40k = 4
)
premium = list()
refill_canister = /obj/item/vending_refill/nazi
*/
/obj/machinery/vending/sovietvend
name = "KomradeVendtink"
desc = "Rodina-mat' zovyot!"
@@ -137,10 +112,6 @@
icon = 'modular_citadel/icons/vending_restock.dmi'
icon_state = "refill_kink"
/obj/item/vending_refill/nazi
machine_name = "nazivend"
icon_state = "refill_nazi"
/obj/item/vending_refill/soviet
machine_name = "sovietvend"
icon_state = "refill_soviet"
-83
View File
@@ -1,83 +0,0 @@
//Polychromatic Knight Badge
/obj/item/card/id/knight
var/id_color = "#00FF00" //defaults to green
name = "knight badge"
icon = 'modular_citadel/icons/obj/id.dmi'
icon_state = "knight"
desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID"
/obj/item/card/id/knight/update_label(newname, newjob)
. = ..()
if(newname || newjob)
name = "[(!newname) ? "identification card" : "[newname]'s Knight Badge"][(!newjob) ? "" : " ([newjob])"]"
return
name = "[(!registered_name) ? "identification card" : "[registered_name]'s Knight Badge"][(!assignment) ? "" : " ([assignment])"]"
/obj/item/card/id/knight/update_icon()
var/mutable_appearance/id_overlay = mutable_appearance('modular_citadel/icons/obj/id.dmi', "knight_overlay")
if(id_color)
id_overlay.color = id_color
cut_overlays()
add_overlay(id_overlay)
/obj/item/card/id/knight/AltClick(mob/living/user)
if(!in_range(src, user)) //Basic checks to prevent abuse
return
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(alert("Are you sure you want to recolor your id?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"","Choose Energy Color",id_color) as color|null
if(energy_color_input)
id_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
/obj/item/card/id/knight/Initialize()
. = ..()
update_icon()
/obj/item/card/id/knight/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
//=================================================
/obj/item/emagrecharge
name = "electromagnet charging device"
desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices, sadly this can't be recharged like a normal cell."
icon = 'icons/obj/module.dmi'
icon_state = "cell_mini"
item_flags = NOBLUDGEON
var/uses = 5 //Dictates how many charges the device adds to compatible items
/obj/item/emagrecharge/examine(mob/user)
. = ..()
if(uses)
to_chat(user, "<span class='notice'>It can add up to [uses] charges to compatible devices</span>")
else
to_chat(user, "<span class='warning'>It has a small, red, blinking light coming from inside of it. It's spent.</span>")
/obj/item/card/emag
var/uses = 15
/obj/item/card/emag/examine(mob/user)
. = ..()
to_chat(user, "<span class='notice'>It has <b>[uses ? uses : "no"]</b> charges left.</span>")
/obj/item/card/emag/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/emagrecharge))
var/obj/item/emagrecharge/ER = W
if(ER.uses)
uses += ER.uses
to_chat(user, "<span class='notice'>You have added [ER.uses] charges to [src]. It now has [uses] charges.</span>")
playsound(src, "sparks", 100, 1)
ER.uses = 0
else
to_chat(user, "<span class='warning'>[ER] has no charges left.</span>")
return
. = ..()
+1 -1
View File
@@ -9,7 +9,7 @@
alternate_screams = list('modular_citadel/sound/voice/scream_silicon.ogg')
/obj/item/clothing/head/ushanka
alternate_screams = list('modular_citadel/sound/misc/cyka1.ogg', 'modular_citadel/sound/misc/cheekibreeki.ogg')
alternate_screams = list('sound/voice/human/cyka1.ogg', 'sound/voice/human/cheekibreeki.ogg')
/obj/item/proc/grenade_prime_react(obj/item/grenade/nade)
return
@@ -1,4 +0,0 @@
/obj/item/aicard/potato
name = "Potat-OS"
desc = "A storage device for possibly malfunctioning AIs. Go on. Get a big fat eyeful. With your big fat eyes."
icon = 'modular_citadel/icons/aicards.dmi'
@@ -1,45 +0,0 @@
/obj/item/nullrod/rosary
icon = 'modular_citadel/icons/obj/items_and_weapons.dmi'
icon_state = "rosary"
item_state = null
name = "prayer beads"
desc = "A set of prayer beads used by many of the more traditional religions in space"
force = 0
throwforce = 0
var/praying = FALSE
var/deity_name = "Coderbus" //This is the default, hopefully won't actually appear if the religion subsystem is running properly
/obj/item/nullrod/rosary/Initialize()
.=..()
if(GLOB.religion)
deity_name = GLOB.deity
/obj/item/nullrod/rosary/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M))
return ..()
if(!user.mind || user.mind.assigned_role != "Chaplain")
to_chat(user, "<span class='notice'>You are not close enough with [deity_name] to use [src].</span>")
return
if(praying)
to_chat(user, "<span class='notice'>You are already using [src].</span>")
return
user.visible_message("<span class='info'>[user] kneels[M == user ? null : " next to [M]"] and begins to utter a prayer to [deity_name].</span>", \
"<span class='info'>You kneel[M == user ? null : " next to [M]"] and begin a prayer to [deity_name].</span>")
praying = TRUE
if(do_after(user, 20, target = M))
if(istype(M, /mob/living/carbon/human)) // This probably should not work on catpeople. They're unholy abominations.
var/mob/living/carbon/human/target = M
M.reagents.add_reagent("holywater", 5)
to_chat(target, "<span class='notice'>[user]'s prayer to [deity_name] has eased your pain!</span>")
target.adjustToxLoss(-5, TRUE, TRUE)
target.adjustOxyLoss(-5)
target.adjustBruteLoss(-5)
target.adjustFireLoss(-5)
praying = FALSE
else
to_chat(user, "<span class='notice'>Your prayer to [deity_name] was interrupted.</span>")
praying = FALSE
@@ -1,17 +0,0 @@
/obj/item/bikehorn/silver
name = "silver bike horn"
desc = "A shiny bike horn handcrafted in the artisan workshops of Mars, with superior kevlar-reinforced rubber bulb attached to a polished plasteel reed horn."
attack_verb = list("elegantly HONKED")
icon = 'modular_citadel/icons/obj/honk.dmi'
icon_state = "silverhorn"
/obj/item/bikehorn/bluespacehonker
name = "bluespace bike horn"
desc = "A normal bike horn colored blue and has bluespace dust held in to reed horn allowing for silly honks through space and time, into your in childhood."
attack_verb = list("HONKED in bluespace", "HONKED", "quantumly HONKED")
icon = 'modular_citadel/icons/obj/honk.dmi'
icon_state = "bluespacehonker"
/obj/item/bikehorn/bluespacehonker/attack(mob/living/carbon/M, mob/living/carbon/user)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "bshonk", /datum/mood_event/bshonk)
return ..()
@@ -1,392 +0,0 @@
/*/////////////////////////////////////////////////////////////////////////
///////////// The TRUE Energy Sword ///////////////////////////
*//////////////////////////////////////////////////////////////////////////
/obj/item/melee/transforming/energy/sword/cx
name = "non-eutactic blade"
desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable."
icon_state = "cxsword_hilt"
icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi'
item_state = "cxsword"
lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi'
righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi'
force = 3
force_on = 21
throwforce = 5
throwforce_on = 20
hitsound = "swing_hit" //it starts deactivated
hitsound_on = 'sound/weapons/nebhit.ogg'
attack_verb_off = list("tapped", "poked")
throw_speed = 3
throw_range = 5
sharpness = IS_SHARP
embedding = list("embedded_pain_multiplier" = 6, "embed_chance" = 20, "embedded_fall_chance" = 60)
armour_penetration = 10
block_chance = 35
light_color = "#37FFF7"
actions_types = list()
/obj/item/melee/transforming/energy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
altafterattack(A, user, TRUE, params)
return TRUE
/obj/item/melee/transforming/energy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
if(istype(user))
user.visible_message("<span class='notice'>[user] points the tip of [src] at [target].</span>", "<span class='notice'>You point the tip of [src] at [target].</span>")
return TRUE
/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text)
active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE
if(active) //also I'd need to rip out the iconstate changing bits
force = force_on
throwforce = throwforce_on
hitsound = hitsound_on
throw_speed = 4
if(attack_verb_on.len)
attack_verb = attack_verb_on
w_class = w_class_on
START_PROCESSING(SSobj, src)
set_light(brightness_on)
update_icon()
else
force = initial(force)
throwforce = initial(throwforce)
hitsound = initial(hitsound)
throw_speed = initial(throw_speed)
if(attack_verb_off.len)
attack_verb = attack_verb_off
w_class = initial(w_class)
STOP_PROCESSING(SSobj, src)
set_light(0)
update_icon()
transform_messages(user, supress_message_text)
add_fingerprint(user)
return TRUE
/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1)
if(!supress_message_text)
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
/obj/item/melee/transforming/energy/sword/cx/update_icon()
var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade")
var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem")
if(light_color)
blade_overlay.color = light_color
gem_overlay.color = light_color
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(gem_overlay)
if(active)
add_overlay(blade_overlay)
if(ismob(loc))
var/mob/M = loc
M.update_inv_hands()
/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user)
if(!in_range(src, user)) //Basic checks to prevent abuse
return
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
if(energy_color_input)
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
update_light()
/obj/item/melee/transforming/energy/sword/cx/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file)
. = ..()
if(active)
if(isinhands)
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
blade_inhand.color = light_color
. += blade_inhand
//Broken version. Not a toy, but not as strong.
/obj/item/melee/transforming/energy/sword/cx/broken
name = "misaligned non-eutactic blade"
desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. This one seems to have a damaged handle and misaligned components, causing the blade to be unstable at best"
force_on = 15 //As strong a survival knife/bone dagger
/obj/item/melee/transforming/energy/sword/cx/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/melee/transforming/energy/sword/cx))
if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
to_chat(user, "<span class='warning'>\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!</span>")
return
else
to_chat(user, "<span class='notice'>You combine the two light swords, making a single supermassive blade! You're cool.</span>")
new /obj/item/twohanded/dualsaber/hypereutactic(user.drop_location())
qdel(W)
qdel(src)
else
return ..()
//OBLIGATORY TOY MEMES /////////////////////////////////////
/obj/item/toy/sword/cx
name = "\improper DX Non-Euplastic LightSword"
desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up."
icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi'
icon_state = "cxsword_hilt"
item_state = "cxsword"
lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi'
righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi'
active = FALSE
w_class = WEIGHT_CLASS_SMALL
attack_verb = list("poked", "jabbed", "hit")
light_color = "#37FFF7"
var/light_brightness = 3
actions_types = list()
/obj/item/toy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
altafterattack(A, user, TRUE, params)
return TRUE
/obj/item/toy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
if(istype(user))
user.visible_message("<span class='notice'>[user] points the tip of [src] at [target].</span>", "<span class='notice'>You point the tip of [src] at [target].</span>")
return TRUE
/obj/item/toy/sword/cx/attack_self(mob/user)
active = !( active )
if (active)
to_chat(user, "<span class='notice'>You activate the holographic blade with a press of a button.</span>")
playsound(user, 'sound/weapons/nebon.ogg', 50, 1)
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("slashed", "stabbed", "ravaged")
set_light(light_brightness)
update_icon()
else
to_chat(user, "<span class='notice'>You deactivate the holographic blade with a press of a button.</span>")
playsound(user, 'sound/weapons/neboff.ogg', 50, 1)
w_class = WEIGHT_CLASS_SMALL
attack_verb = list("poked", "jabbed", "hit")
set_light(0)
update_icon()
add_fingerprint(user)
/obj/item/toy/sword/cx/update_icon()
var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade")
var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem")
if(light_color)
blade_overlay.color = light_color
gem_overlay.color = light_color
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(gem_overlay)
if(active)
add_overlay(blade_overlay)
if(ismob(loc))
var/mob/M = loc
M.update_inv_hands()
/obj/item/toy/sword/cx/AltClick(mob/living/user)
if(!in_range(src, user)) //Basic checks to prevent abuse
return
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
if(energy_color_input)
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
update_light()
/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file)
. = ..()
if(active)
if(isinhands)
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
blade_inhand.color = light_color
. += blade_inhand
/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/toy/sword/cx))
if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
to_chat(user, "<span class='warning'>\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!</span>")
return
else
to_chat(user, "<span class='notice'>You combine the two plastic swords, making a single supermassive toy! You're fake-cool.</span>")
new /obj/item/twohanded/dualsaber/hypereutactic/toy(user.loc)
qdel(W)
qdel(src)
else
return ..()
/obj/item/toy/sword/cx/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
/////////////////////////////////////////////////////
// HYPEREUTACTIC Blades /////////////////////////
/////////////////////////////////////////////////////
/obj/item/twohanded/dualsaber/hypereutactic
icon = 'modular_citadel/icons/eutactic/item/hypereutactic.dmi'
icon_state = "hypereutactic"
lefthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi'
righthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi'
item_state = "hypereutactic"
inhand_x_dimension = 64
inhand_y_dimension = 64
name = "hypereutactic blade"
desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter."
force = 7
force_unwielded = 7
force_wielded = 40
wieldsound = 'sound/weapons/nebon.ogg'
unwieldsound = 'sound/weapons/neboff.ogg'
hitsound_on = 'sound/weapons/nebhit.ogg'
slowdown_wielded = 1
armour_penetration = 60
light_color = "#37FFF7"
rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00")
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded")
spinnable = FALSE
total_mass_on = 4
/obj/item/twohanded/dualsaber/hypereutactic/chaplain
name = "\improper divine lightblade"
desc = "A giant blade of bright and holy light, said to cut down the wicked with ease."
force = 5
force_unwielded = 5
force_wielded = 20
block_chance = 50
armour_penetration = 0
var/chaplain_spawnable = TRUE
obj_flags = UNIQUE_RENAME
/obj/item/twohanded/dualsaber/hypereutactic/chaplain/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE)
/obj/item/twohanded/dualsaber/hypereutactic/chaplain/IsReflect()
return FALSE
/obj/item/twohanded/dualsaber/hypereutactic/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
altafterattack(A, user, TRUE, params)
return TRUE
/obj/item/twohanded/dualsaber/hypereutactic/altafterattack(atom/target, mob/living/user, proximity_flag, click_parameters) //does right click memes
if(istype(user))
user.visible_message("<span class='notice'>[user] points the tip of [src] at [target].</span>", "<span class='notice'>You point the tip of [src] at [target].</span>")
return TRUE
/obj/item/twohanded/dualsaber/hypereutactic/update_icon()
var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_blade")
var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_gem")
if(light_color)
blade_overlay.color = light_color
gem_overlay.color = light_color
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(gem_overlay)
if(wielded)
add_overlay(blade_overlay)
if(ismob(loc))
var/mob/M = loc
M.update_inv_hands()
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)//blood overlays get weird otherwise, because the sprite changes. (retained from original desword because I have no idea what this is)
/obj/item/twohanded/dualsaber/hypereutactic/AltClick(mob/living/user)
if(!user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
return
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
if(!energy_color_input || !user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
return
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
update_light()
/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file)
. = ..()
if(isinhands)
var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
gem_inhand.color = light_color
. += gem_inhand
if(wielded)
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade")
blade_inhand.color = light_color
. += blade_inhand
/obj/item/twohanded/dualsaber/hypereutactic/examine(mob/user)
..()
if(!hacked)
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
/obj/item/twohanded/dualsaber/hypereutactic/rainbow_process()
. = ..()
update_icon()
update_light()
////////////////// TOY VERSION /////////////////////////////
/obj/item/twohanded/dualsaber/hypereutactic/toy
name = "\improper DX Hyper-Euplastic LightSword"
desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up."
force = 0
throwforce = 0
throw_speed = 3
throw_range = 5
force_unwielded = 0
force_wielded = 0
attack_verb = list("attacked", "struck", "hit")
total_mass_on = TOTAL_MASS_TOY_SWORD
slowdown_wielded = 0
/obj/item/twohanded/dualsaber/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return FALSE
/obj/item/twohanded/dualsaber/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles
return FALSE
//////// Tatortot NEB /////////////// (same stats as regular esword)
/obj/item/melee/transforming/energy/sword/cx/traitor
name = "\improper Dragon's Tooth Sword"
desc = "The Dragon's Tooth sword is a blackmarket modification of a Non-Eutactic Blade, \
which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \
It appears to have a wooden grip and a shaved down guard."
icon_state = "cxsword_hilt_traitor"
force_on = 30
armour_penetration = 50
embedding = list("embedded_pain_multiplier" = 10, "embed_chance" = 75, "embedded_fall_chance" = 0, "embedded_impact_pain_multiplier" = 10)
block_chance = 50
hitsound_on = 'sound/weapons/blade1.ogg'
light_color = "#37F0FF"
/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text)
playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1)
if(!supress_message_text)
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
//RAINBOW MEMES
/obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow
name = "\improper Hyper-Euclidean Reciprocating Trigonometric Zweihander"
desc = "A custom-built toy with fancy rainbow lights built-in."
hacked = TRUE
@@ -28,8 +28,8 @@
icon_state = "rad"
/obj/item/storage/firstaid/radbgone/Initialize(mapload)
. = ..()
icon_state = pick("[initial(icon_state)]","[initial(icon_state)]2","[initial(icon_state)]3","[initial(icon_state)]4")
. = ..()
icon_state = pick("[initial(icon_state)]","[initial(icon_state)]2","[initial(icon_state)]3","[initial(icon_state)]4")
/obj/item/storage/firstaid/tactical
icon_state = "tactical"
@@ -49,7 +49,7 @@
/obj/item/storage/hypospraykit/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 12
STR.can_hold = typecacheof(list(
/obj/item/hypospray/mkii,
@@ -151,7 +151,7 @@
/obj/item/storage/hypospraykit/cmo/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(
/obj/item/hypospray/mkii,
@@ -1,3 +0,0 @@
/obj/item/vending_refill/medical
machine_name = "NanoMed"
icon_state = "refill_medical"
@@ -1,6 +1,6 @@
/obj/structure/closet/secure_closet/quartermaster/PopulateContents()
..()
new /obj/item/radio/headset/heads/qm(src)
..()
new /obj/item/radio/headset/heads/qm(src)
/obj/structure/closet/secure_closet/CMO/PopulateContents()
..()
@@ -1,24 +0,0 @@
//Yes, hi. This is the file that handles Citadel's turf modifications.
/*
/turf/open/floor/Entered(atom/obj, atom/oldloc)
. = ..()
CitDirtify(obj, oldloc)*/
//Baystation-styled tile dirtification.
/turf/open/floor/proc/CitDirtify(atom/obj, atom/oldloc)
if(prob(50))
if(has_gravity(src) && !isobserver(obj))
var/dirtamount
var/obj/effect/decal/cleanable/dirt/dirt = locate(/obj/effect/decal/cleanable/dirt, src)
if(!dirt)
dirt = new/obj/effect/decal/cleanable/dirt(src)
dirt.alpha = 0
dirtamount = 0
dirtamount = dirt.alpha + 1
if(oldloc && istype(oldloc, /turf/open/floor))
var/obj/effect/decal/cleanable/dirt/spreadindirt = locate(/obj/effect/decal/cleanable/dirt, oldloc)
if(spreadindirt && spreadindirt.alpha)
dirtamount += round(spreadindirt.alpha * 0.05)
dirt.alpha = min(dirtamount,255)
return TRUE
+2 -2
View File
@@ -15,7 +15,7 @@
return
to_chat(M, "<span class='warning bold reallybig'>Man up, and deal with it.</span><br><span class='warning big'>Move on.</span>")
M.playsound_local(M, 'modular_citadel/sound/misc/manup.ogg', 50, FALSE, pressure_affected = FALSE)
M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE)
log_admin("Man up: [key_name(usr)] told [key_name(M)] to man up")
var/message = "<span class='adminnotice'>[key_name_admin(usr)] told [key_name_admin(M)] to man up.</span>"
@@ -32,7 +32,7 @@
to_chat(world, "<span class='warning bold reallybig'>Man up, and deal with it.</span><br><span class='warning big'>Move on.</span>")
for(var/mob/M in GLOB.player_list)
M.playsound_local(M, 'modular_citadel/sound/misc/manup.ogg', 50, FALSE, pressure_affected = FALSE)
M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE)
log_admin("Man up global: [key_name(usr)] told everybody to man up")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] told everybody to man up.</span>")
+261 -413
View File
@@ -19,11 +19,6 @@
var/hidden_undershirt = FALSE
var/hidden_socks = FALSE
/mob/living/carbon/human/New()
..()
saved_underwear = underwear
saved_undershirt = undershirt
//Species vars
/datum/species
var/arousal_gain_rate = AROUSAL_START_VALUE //Rate at which this species becomes aroused
@@ -35,60 +30,51 @@
//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
set category = "IC"
if(confirm == "Bottom")
humz.hidden_underwear = !humz.hidden_underwear
var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling") as null|anything in list("Top", "Bottom", "Socks", "All")
if(!confirm)
return
if(confirm == "Top")
hidden_undershirt = !hidden_undershirt
if(confirm == "Socks")
humz.hidden_socks = !humz.hidden_socks
if(confirm == "Bottom")
hidden_underwear = !hidden_underwear
if(confirm == "All")
humz.hidden_undershirt = !humz.hidden_undershirt
humz.hidden_underwear = !humz.hidden_underwear
humz.hidden_socks = !humz.hidden_socks
if(confirm == "Socks")
hidden_socks = !hidden_socks
if(confirm == "Cancel")
return
src.update_body()
if(confirm == "All")
var/on_off = (hidden_undershirt || hidden_underwear || hidden_socks) ? FALSE : TRUE
hidden_undershirt = on_off
hidden_underwear = on_off
hidden_socks = on_off
else
to_chat(src, "Humans only. How the fuck did you get this verb anyway.")
update_body()
/mob/living/proc/handle_arousal()
/mob/living/carbon/handle_arousal()
if(canbearoused && dna)
var/datum/species/S
S = dna.species
if(S && !(SSmobs.times_fired % 36) && getArousalLoss() < max_arousal)//Totally stolen from breathing code. Do this every 36 ticks.
adjustArousalLoss(arousal_rate * S.arousal_gain_rate)
if(dna.features["exhibitionist"] && client)
var/amt_nude = 0
if(is_chest_exposed() && (getorganslot("breasts")))
amt_nude++
if(is_groin_exposed())
if(getorganslot("penis"))
amt_nude++
if(getorganslot("vagina"))
amt_nude++
if(amt_nude)
var/watchers = 0
for(var/mob/_M in view(world.view, src))
var/mob/living/M = _M
if(!istype(M))
continue
if(M.client && !M.stat && !M.eye_blind && (locate(src) in viewers(world.view,M)))
watchers++
if(watchers)
adjustArousalLoss((amt_nude * watchers) + S.arousal_gain_rate)
/mob/living/proc/handle_arousal(times_fired)
return
/mob/living/carbon/handle_arousal(times_fired)
if(!canbearoused || !dna)
return
var/datum/species/S = dna.species
if(!S || (times_fired % 36) || !getArousalLoss() >= max_arousal)//Totally stolen from breathing code. Do this every 36 ticks.
return
var/our_loss = arousal_rate * S.arousal_gain_rate
if(HAS_TRAIT(src, TRAIT_EXHIBITIONIST) && client)
var/amt_nude = 0
for(var/obj/item/organ/genital/G in internal_organs)
if(G.is_exposed())
amt_nude++
if(amt_nude)
var/watchers = 0
for(var/mob/living/L in view(src))
if(L.client && !L.stat && !L.eye_blind && (src in view(L)))
watchers++
if(watchers)
our_loss += (amt_nude * watchers) + S.arousal_gain_rate
adjustArousalLoss(our_loss)
/mob/living/proc/getArousalLoss()
return arousalloss
@@ -138,8 +124,6 @@
S = GLOB.breasts_shapes_list[G.shape]
if(S?.alt_aroused)
G.aroused_state = isPercentAroused(G.aroused_amount)
if(getArousalLoss() >= ((max_arousal / 100) * 33))
G.aroused_state = TRUE
else
G.aroused_state = FALSE
G.update_appearance()
@@ -147,54 +131,16 @@
/mob/living/proc/update_arousal_hud()
return FALSE
/datum/species/proc/update_arousal_hud(mob/living/carbon/human/H)
return FALSE
/mob/living/carbon/human/update_arousal_hud()
if(!client || !hud_used)
return FALSE
if(dna.species.update_arousal_hud())
if(!client || !(hud_used?.arousal))
return FALSE
if(!canbearoused)
hud_used.arousal.icon_state = ""
return FALSE
else
if(hud_used.arousal)
if(stat == DEAD)
hud_used.arousal.icon_state = "arousal0"
return TRUE
if(getArousalLoss() == max_arousal)
hud_used.arousal.icon_state = "arousal100"
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 TRUE
if(getArousalLoss() >= (max_arousal / 100) * 80)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal80"
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 TRUE
if(getArousalLoss() >= (max_arousal / 100) * 60)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal60"
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 TRUE
if(getArousalLoss() >= (max_arousal / 100) * 40)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal40"
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 TRUE
if(getArousalLoss() >= (max_arousal / 100) * 20)//M O D U L A R , W O W
hud_used.arousal.icon_state = "arousal10"
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 TRUE
else
hud_used.arousal.icon_state = "arousal0"
var/value = FLOOR(getPercentAroused(), 10)
hud_used.arousal.icon_state = "arousal[value]"
return TRUE
/obj/screen/arousal
name = "arousal"
@@ -213,7 +159,6 @@
to_chat(M, "<span class='warning'>Arousal is disabled. Feature is unavailable.</span>")
/mob/living/proc/mob_climax()//This is just so I can test this shit without being forced to add actual content to get rid of arousal. Will be a very basic proc for a while.
set name = "Masturbate"
set category = "IC"
@@ -221,225 +166,187 @@
if(mb_cd_timer <= world.time)
//start the cooldown even if it fails
mb_cd_timer = world.time + mb_cd_length
if(getArousalLoss() >= ((max_arousal / 100) * 33))//33% arousal or greater required
src.visible_message("<span class='danger'>[src] starts masturbating!</span>", \
if(getArousalLoss() >= 33)//one third of average max_arousal or greater required
visible_message("<span class='danger'>[src] starts masturbating!</span>", \
"<span class='userdanger'>You start masturbating.</span>")
if(do_after(src, 30, target = src))
src.visible_message("<span class='danger'>[src] relieves [p_them()]self!</span>", \
visible_message("<span class='danger'>[src] relieves [p_them()]self!</span>", \
"<span class='userdanger'>You have relieved yourself.</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
setArousalLoss(min_arousal)
else
to_chat(src, "<span class='notice'>You aren't aroused enough for that.</span>")
/obj/item/organ/genital/proc/climaxable(mob/living/carbon/human/H, silent = FALSE) //returns the fluid source (ergo reagents holder) if found.
if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
. = reagents
else
if(linked_organ)
. = linked_organ.reagents
if(!. && !silent)
to_chat(H, "<span class='warning'>Your [name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
/mob/living/carbon/human/proc/do_climax(datum/reagents/R, atom/target, obj/item/organ/genital/G, spill = TRUE)
if(!G)
return
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
setArousalLoss(min_arousal)
if(!target || !R)
return
var/turfing = isturf(target)
if(spill & R.total_volume >= 5)
R.reaction(turfing ? target : target.loc, TOUCH, 1, 0)
if(!turfing)
R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1))
R.clear_reagents()
//These are various procs that we'll use later, split up for readability instead of having one, huge proc.
//For all of these, we assume the arguments given are proper and have been checked beforehand.
/mob/living/carbon/human/proc/mob_masturbate(obj/item/organ/genital/G, mb_time = 30) //Masturbation, keep it gender-neutral
var/total_fluids = 0
var/datum/reagents/fluid_source = null
if(G.producing) //Can it produce its own fluids, such as breasts?
fluid_source = G.reagents
else
if(!G.linked_organ)
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
return
fluid_source = G.linked_organ.reagents
total_fluids = fluid_source.total_volume
var/datum/reagents/fluid_source = G.climaxable(src)
if(!fluid_source)
return
var/obj/item/organ/genital/PP = CHECK_BITFIELD(G.genital_flags, MASTURBATE_LINKED_ORGAN) ? G.linked_organ : G
if(!PP)
to_chat(src, "<span class='warning'>You shudder, unable to cum with your [name].</span>")
if(mb_time)
src.visible_message("<span class='love'>[src] starts to [G.masturbation_verb] [p_their()] [G.name].</span>", \
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name].</span>", \
visible_message("<span class='love'>[src] starts to [G.masturbation_verb] [p_their()] [G.name].</span>", \
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name].</span>")
if(do_after(src, mb_time, target = src))
if(total_fluids > 5)
fluid_source.reaction(src.loc, TOUCH, 1, 0)
fluid_source.clear_reagents()
src.visible_message("<span class='love'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
"<span class='userlove'>You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].</span>", \
"<span class='userlove'>You have relieved yourself.</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
if(G.can_climax)
setArousalLoss(min_arousal)
if(!do_after(src, mb_time, target = src) || !G.climaxable(src, TRUE))
return
visible_message("<span class='love'>[src] orgasms, [PP.orgasm_verb][isturf(loc) ? " onto [loc]" : ""] with [p_their()] [PP.name]!</span>", \
"<span class='userlove'>You orgasm, [PP.orgasm_verb][isturf(loc) ? " onto [loc]" : ""] with your [PP.name].</span>")
do_climax(fluid_source, loc, G)
/mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30) //This is used for forced orgasms and other hands-free climaxes
var/total_fluids = 0
var/datum/reagents/fluid_source = null
var/unable_to_come = FALSE
if(G.producing) //Can it produce its own fluids, such as breasts?
fluid_source = G.reagents
total_fluids = fluid_source.total_volume
else
if(!G.linked_organ)
unable_to_come = TRUE
else
fluid_source = G.linked_organ.reagents
total_fluids = fluid_source.total_volume
if(unable_to_come)
src.visible_message("<span class='danger'>[src] shudders, their [G.name] unable to cum.</span>", \
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>", \
var/datum/reagents/fluid_source = G.climaxable(src, TRUE)
if(!fluid_source)
visible_message("<span class='danger'>[src] shudders, their [G.name] unable to cum.</span>", \
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>")
else
total_fluids = fluid_source.total_volume
if(mb_time) //as long as it's not instant, give a warning
src.visible_message("<span class='love'>[src] looks like they're about to cum.</span>", \
"<span class='userlove'>You feel yourself about to orgasm.</span>", \
"<span class='userlove'>You feel yourself about to orgasm.</span>")
if(do_after(src, mb_time, target = src))
if(total_fluids > 5)
fluid_source.reaction(src.loc, TOUCH, 1, 0)
fluid_source.clear_reagents()
src.visible_message("<span class='love'>[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], using [p_their()] [G.name]!</span>", \
"<span class='userlove'>You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name].</span>", \
"<span class='userlove'>You climax using your [G.name].</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
if(G.can_climax)
setArousalLoss(min_arousal)
return
if(mb_time) //as long as it's not instant, give a warning
visible_message("<span class='love'>[src] looks like they're about to cum.</span>", \
"<span class='userlove'>You feel yourself about to orgasm.</span>")
if(!do_after(src, mb_time, target = src) || !G.climaxable(src, TRUE))
return
visible_message("<span class='love'>[src] orgasms[isturf(loc) ? " onto [loc]" : ""], using [p_their()] [G.name]!</span>", \
"<span class='userlove'>You climax[isturf(loc) ? " onto [loc]" : ""] with your [G.name].</span>")
do_climax(fluid_source, loc, G)
/mob/living/carbon/human/proc/mob_climax_partner(obj/item/organ/genital/G, mob/living/L, spillage = TRUE, mb_time = 30) //Used for climaxing with any living thing
var/total_fluids = 0
var/datum/reagents/fluid_source = null
if(G.producing) //Can it produce its own fluids, such as breasts?
fluid_source = G.reagents
else
if(!G.linked_organ)
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
return
fluid_source = G.linked_organ.reagents
total_fluids = fluid_source.total_volume
var/datum/reagents/fluid_source = G.climaxable(src)
if(!fluid_source)
return
if(mb_time) //Skip warning if this is an instant climax.
src.visible_message("<span class='love'>[src] is about to climax with [L]!</span>", \
"<span class='userlove'>You're about to climax with [L]!</span>", \
"<span class='userlove'>You're preparing to climax with someone!</span>")
visible_message("<span class='love'>[src] is about to climax with [L]!</span>", \
"<span class='userlove'>You're about to climax with [L]!</span>")
if(!do_after(src, mb_time, target = src) || !in_range(src, L) || !G.climaxable(src, TRUE))
return
if(spillage)
if(do_after(src, mb_time, target = src) && in_range(src, L))
fluid_source.trans_to(L, total_fluids*G.fluid_transfer_factor)
total_fluids -= total_fluids*G.fluid_transfer_factor
if(total_fluids > 5)
fluid_source.reaction(L.loc, TOUCH, 1, 0)
fluid_source.clear_reagents()
src.visible_message("<span class='love'>[src] climaxes with [L][spillage ? ", overflowing and spilling":""], using [p_their()] [G.name]!</span>", \
"<span class='userlove'>You orgasm with [L][spillage ? ", spilling out of them":""], using your [G.name].</span>", \
"<span class='userlove'>You have climaxed with someone[spillage ? ", spilling out of them":""], using your [G.name].</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
if(G.can_climax)
setArousalLoss(min_arousal)
visible_message("<span class='love'>[src] climaxes with [L], overflowing and spilling, using [p_their()] [G.name]!</span>", \
"<span class='userlove'>You orgasm with [L], spilling out of them, using your [G.name].</span>")
else //knots and other non-spilling orgasms
if(do_after(src, mb_time, target = src) && in_range(src, L))
fluid_source.trans_to(L, total_fluids)
total_fluids = 0
src.visible_message("<span class='love'>[src] climaxes with [L], [p_their()] [G.name] spilling nothing!</span>", \
"<span class='userlove'>You ejaculate with [L], your [G.name] spilling nothing.</span>", \
"<span class='userlove'>You have climaxed inside someone, your [G.name] spilling nothing.</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
if(G.can_climax)
setArousalLoss(min_arousal)
visible_message("<span class='love'>[src] climaxes with [L], [p_their()] [G.name] spilling nothing!</span>", \
"<span class='userlove'>You ejaculate with [L], your [G.name] spilling nothing.</span>")
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
do_climax(fluid_source, spillage ? loc : L, G, spillage)
/mob/living/carbon/human/proc/mob_fill_container(obj/item/organ/genital/G, obj/item/reagent_containers/container, mb_time = 30) //For beaker-filling, beware the bartender
var/total_fluids = 0
var/datum/reagents/fluid_source = null
if(G.producing) //Can it produce its own fluids, such as breasts?
fluid_source = G.reagents
else
if(!G.linked_organ)
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
var/datum/reagents/fluid_source = G.climaxable(src)
if(!fluid_source)
return
if(mb_time)
visible_message("<span class='love'>[src] starts to [G.masturbation_verb] their [G.name] over [container].</span>", \
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name] over [container].</span>")
if(!do_after(src, mb_time, target = src) || !in_range(src, container) || !G.climaxable(src, TRUE))
return
fluid_source = G.linked_organ.reagents
total_fluids = fluid_source.total_volume
visible_message("<span class='love'>[src] uses [p_their()] [G.name] to fill [container]!</span>", \
"<span class='userlove'>You used your [G.name] to fill [container].</span>")
do_climax(fluid_source, container, G, FALSE)
//if(!container) //Something weird happened
// to_chat(src, "<span class='warning'>You need a container to do this!</span>")
// return
src.visible_message("<span class='love'>[src] starts to [G.masturbation_verb] their [G.name] over [container].</span>", \
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name] over [container].</span>", \
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name] over something.</span>")
if(do_after(src, mb_time, target = src) && in_range(src, container))
fluid_source.trans_to(container, total_fluids)
src.visible_message("<span class='love'>[src] uses [p_their()] [G.name] to fill [container]!</span>", \
"<span class='userlove'>You used your [G.name] to fill [container].</span>", \
"<span class='userlove'>You have relieved some pressure.</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
if(G.can_climax)
setArousalLoss(min_arousal)
/mob/living/carbon/human/proc/pick_masturbate_genitals()
var/obj/item/organ/genital/ret_organ
var/list/genitals_list = list()
/mob/living/carbon/human/proc/pick_masturbate_genitals(silent = FALSE)
var/list/genitals_list
var/list/worn_stuff = get_equipped_items()
for(var/obj/item/organ/genital/G in internal_organs)
if(G.can_masturbate_with) //filter out what you can't masturbate with
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
genitals_list += G
if(genitals_list.len)
ret_organ = input(src, "with what?", "Masturbate", null) as null|obj in genitals_list
if(CHECK_BITFIELD(G.genital_flags, CAN_MASTURBATE_WITH) && G.is_exposed(worn_stuff)) //filter out what you can't masturbate with
if(CHECK_BITFIELD(G.genital_flags, MASTURBATE_LINKED_ORGAN) && !G.linked_organ)
continue
LAZYADD(genitals_list, G)
if(LAZYLEN(genitals_list))
var/obj/item/organ/genital/ret_organ = input(src, "with what?", "Masturbate", null) as null|obj in genitals_list
return ret_organ
return null //error stuff
else if(!silent)
to_chat(src, "<span class='warning'>You cannot masturbate without available genitals.</span>")
/mob/living/carbon/human/proc/pick_climax_genitals()
var/obj/item/organ/genital/ret_organ
var/list/genitals_list = list()
/mob/living/carbon/human/proc/pick_climax_genitals(silent = FALSE)
var/list/genitals_list
var/list/worn_stuff = get_equipped_items()
for(var/obj/item/organ/genital/G in internal_organs)
if(G.can_climax) //filter out what you can't masturbate with
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
genitals_list += G
if(genitals_list.len)
ret_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list
if(CHECK_BITFIELD(G.genital_flags, CAN_CLIMAX_WITH) && G.is_exposed(worn_stuff)) //filter out what you can't masturbate with
LAZYADD(genitals_list, G)
if(LAZYLEN(genitals_list))
var/obj/item/organ/genital/ret_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list
return ret_organ
return null //error stuff
else if(!silent)
to_chat(src, "<span class='warning'>You cannot climax without available genitals.</span>")
/mob/living/carbon/human/proc/pick_partner()
/mob/living/carbon/human/proc/pick_partner(silent = FALSE)
var/list/partners = list()
if(src.pulling)
partners += src.pulling //Yes, even objects for now
if(src.pulledby)
partners += src.pulledby
if(pulling)
partners += pulling
if(pulledby)
partners += pulledby
//Now we got both of them, let's check if they're proper
for(var/I in partners)
if(isliving(I))
if(iscarbon(I))
var/mob/living/carbon/C = I
if(!C.exposed_genitals.len) //Nothing through_clothing
if(!C.is_groin_exposed()) //No pants undone
if(!C.is_chest_exposed()) //No chest exposed
partners -= I //Then not proper, remove them
else
partners -= I //No fucking objects
for(var/mob/living/L in partners)
if(iscarbon(L))
var/mob/living/carbon/C = L
if(!C.exposed_genitals.len && !C.is_groin_exposed() && !C.is_chest_exposed()) //Nothing through_clothing, no proper partner.
partners -= C
//NOW the list should only contain correct partners
if(!partners.len)
return null //No one left.
return input(src, "With whom?", "Sexual partner", null) in partners //pick one, default to null
if(!silent)
to_chat(src, "<span class='warning'>You cannot do this alone.</span>")
return //No one left.
var/mob/living/target = input(src, "With whom?", "Sexual partner", null) as null|anything in partners //pick one, default to null
if(target && in_range(src, target))
return target
/mob/living/carbon/human/proc/pick_climax_container()
var/obj/item/reagent_containers/SC = null
/mob/living/carbon/human/proc/pick_climax_container(silent = FALSE)
var/list/containers_list = list()
for(var/obj/item/reagent_containers/container in held_items)
if(container.is_open_container() || istype(container, /obj/item/reagent_containers/food/snacks))
containers_list += container
for(var/obj/item/reagent_containers/C in held_items)
if(C.is_open_container() || istype(C, /obj/item/reagent_containers/food/snacks))
containers_list += C
for(var/obj/item/reagent_containers/C in range(1, src))
if((C.is_open_container() || istype(C, /obj/item/reagent_containers/food/snacks)) && CanReach(C))
containers_list += C
if(containers_list.len)
SC = input(src, "Into or onto what?(Cancel for nowhere)", null) as null|obj in containers_list
if(SC)
if(in_range(src, SC))
return SC
return null //If nothing correct, give null.
var/obj/item/reagent_containers/SC = input(src, "Into or onto what?(Cancel for nowhere)", null) as null|obj in containers_list
if(SC && CanReach(SC))
return SC
else if(!silent)
to_chat(src, "<span class='warning'>You cannot do this without an appropriate container.</span>")
/mob/living/carbon/human/proc/available_rosie_palms(silent = FALSE, list/whitelist_typepaths = list(/obj/item/dildo))
if(restrained(TRUE)) //TRUE ignores grabs
if(!silent)
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
return FALSE
if(!get_num_arms() || !get_empty_held_indexes())
if(whitelist_typepaths)
if(!islist(whitelist_typepaths))
whitelist_typepaths = list(whitelist_typepaths)
for(var/path in whitelist_typepaths)
if(is_holding_item_of_type(path))
return TRUE
if(!silent)
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
return FALSE
return TRUE
//Here's the main proc itself
/mob/living/carbon/human/mob_climax(forced_climax=FALSE) //Forced is instead of the other proc, makes you cum if you have the tools for it, ignoring restraints
@@ -447,156 +354,97 @@
if(!forced_climax) //Don't spam the message to the victim if forced to come too fast
to_chat(src, "<span class='warning'>You need to wait [DisplayTimeText((mb_cd_timer - world.time), TRUE)] before you can do that again!</span>")
return
mb_cd_timer = (world.time + mb_cd_length)
if(canbearoused && has_dna())
if(stat==2)
if(!canbearoused || !has_dna())
return
if(stat == DEAD)
if(!forced_climax)
to_chat(src, "<span class='warning'>You can't do that while dead!</span>")
return
if(forced_climax) //Something forced us to cum, this is not a masturbation thing and does not progress to the other checks
for(var/obj/item/organ/O in internal_organs)
if(istype(O, /obj/item/organ/genital))
var/obj/item/organ/genital/G = O
if(!G.can_climax) //Skip things like wombs and testicles
continue
var/mob/living/partner
var/check_target
var/list/worn_stuff = get_equipped_items()
return
if(forced_climax) //Something forced us to cum, this is not a masturbation thing and does not progress to the other checks
for(var/obj/item/organ/genital/G in internal_organs)
if(!CHECK_BITFIELD(G.genital_flags, CAN_CLIMAX_WITH)) //Skip things like wombs and testicles
continue
var/mob/living/partner
var/check_target
var/list/worn_stuff = get_equipped_items()
if(G.is_exposed(worn_stuff))
if(src.pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick
if(isliving(src.pulling)) //Don't fuck objects
check_target = src.pulling
if(src.pulledby && !check_target) //prioritise pulled over pulledby
if(isliving(src.pulledby))
check_target = src.pulledby
//Now we should have a partner, or else we have to come alone
if(check_target)
if(iscarbon(check_target)) //carbons can have clothes
var/mob/living/carbon/C = check_target
if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) //Are they naked enough?
partner = C
else //A cat is fine too
partner = check_target
if(partner) //Did they pass the clothing checks?
mob_climax_partner(G, partner, mb_time = 0) //Instant climax due to forced
continue //You've climaxed once with this organ, continue on
//not exposed OR if no partner was found while exposed, climax alone
mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms
//Now all genitals that could climax, have.
//Since this was a forced climax, we do not need to continue with the other stuff
return
//If we get here, then this is not a forced climax and we gotta check a few things.
if(G.is_exposed(worn_stuff))
if(pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick
if(isliving(pulling)) //Don't fuck objects
check_target = pulling
if(pulledby && !check_target) //prioritise pulled over pulledby
if(isliving(pulledby))
check_target = pulledby
//Now we should have a partner, or else we have to come alone
if(check_target)
if(iscarbon(check_target)) //carbons can have clothes
var/mob/living/carbon/C = check_target
if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) //Are they naked enough?
partner = C
else //A cat is fine too
partner = check_target
if(partner) //Did they pass the clothing checks?
mob_climax_partner(G, partner, mb_time = 0) //Instant climax due to forced
continue //You've climaxed once with this organ, continue on
//not exposed OR if no partner was found while exposed, climax alone
mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms
//Now all genitals that could climax, have.
//Since this was a forced climax, we do not need to continue with the other stuff
mb_cd_timer = world.time + mb_cd_length
return
//If we get here, then this is not a forced climax and we gotta check a few things.
if(stat==1) //No sleep-masturbation, you're unconscious.
to_chat(src, "<span class='warning'>You must be conscious to do that!</span>")
return
if(getArousalLoss() < 33) //flat number instead of percentage
to_chat(src, "<span class='warning'>You aren't aroused enough for that!</span>")
return
if(stat == UNCONSCIOUS) //No sleep-masturbation, you're unconscious.
to_chat(src, "<span class='warning'>You must be conscious to do that!</span>")
return
if(getArousalLoss() < 33) //flat number instead of percentage
to_chat(src, "<span class='warning'>You aren't aroused enough for that!</span>")
return
//Ok, now we check what they want to do.
var/choice = input(src, "Select sexual activity", "Sexual activity:") in list("Masturbate", "Climax alone", "Climax with partner", "Fill container")
//Ok, now we check what they want to do.
var/choice = input(src, "Select sexual activity", "Sexual activity:") as null|anything in list("Masturbate", "Climax alone", "Climax with partner", "Fill container")
if(!choice)
return
switch(choice)
if("Masturbate")
if(restrained(TRUE)) //TRUE ignores grabs
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
return
var/free_hands = get_num_arms()
if(!free_hands)
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
return
for(var/helditem in held_items)//how many hands are free
if(isobj(helditem))
free_hands--
if(free_hands <= 0)
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
return
//We got hands, let's pick an organ
var/obj/item/organ/genital/picked_organ
picked_organ = pick_masturbate_genitals()
if(picked_organ)
mob_masturbate(picked_organ)
return
else //They either lack organs that can masturbate, or they didn't pick one.
to_chat(src, "<span class='warning'>You cannot masturbate without choosing genitals.</span>")
return
switch(choice)
if("Masturbate")
if(!available_rosie_palms())
return
//We got hands, let's pick an organ
var/obj/item/organ/genital/picked_organ = pick_masturbate_genitals()
if(picked_organ && available_rosie_palms(TRUE))
mob_masturbate(picked_organ)
return
if("Climax alone")
if(restrained(TRUE)) //TRUE ignores grabs
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
return
var/free_hands = get_num_arms()
if(!free_hands)
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
return
for(var/helditem in held_items)//how many hands are free
if(isobj(helditem))
free_hands--
if(free_hands <= 0)
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
return
//We got hands, let's pick an organ
var/obj/item/organ/genital/picked_organ
picked_organ = pick_climax_genitals()
if(picked_organ)
mob_climax_outside(picked_organ)
return
else //They either lack organs that can masturbate, or they didn't pick one.
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
return
if("Climax alone")
if(!available_rosie_palms())
return
var/obj/item/organ/genital/picked_organ = pick_climax_genitals()
if(picked_organ && available_rosie_palms(TRUE))
mob_climax_outside(picked_organ)
if("Climax with partner")
//We need no hands, we can be restrained and so on, so let's pick an organ
var/obj/item/organ/genital/picked_organ
picked_organ = pick_climax_genitals()
if(picked_organ)
var/mob/living/partner = pick_partner() //Get someone
if(partner)
var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as anything in list("Yes", "No")
if(spillage == "Yes")
mob_climax_partner(picked_organ, partner, TRUE)
else
mob_climax_partner(picked_organ, partner, FALSE)
return
else
to_chat(src, "<span class='warning'>You cannot do this alone.</span>")
return
else //They either lack organs that can masturbate, or they didn't pick one.
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
return
if("Climax with partner")
//We need no hands, we can be restrained and so on, so let's pick an organ
var/obj/item/organ/genital/picked_organ = pick_climax_genitals()
if(picked_organ)
var/mob/living/partner = pick_partner() //Get someone
if(partner)
var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as null|anything in list("Yes", "No")
if(spillage && in_range(src, partner))
mob_climax_partner(picked_organ, partner, spillage == "Yes" ? TRUE : FALSE)
if("Fill container")
//We'll need hands and no restraints.
if(restrained(TRUE)) //TRUE ignores grabs
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
return
var/free_hands = get_num_arms()
if(!free_hands)
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
return
for(var/helditem in held_items)//how many hands are free
if(isobj(helditem))
free_hands--
if(free_hands <= 0)
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
return
//We got hands, let's pick an organ
var/obj/item/organ/genital/picked_organ
picked_organ = pick_climax_genitals() //Gotta be climaxable, not just masturbation, to fill with fluids.
if(picked_organ)
//Good, got an organ, time to pick a container
var/obj/item/reagent_containers/fluid_container = pick_climax_container()
if(fluid_container)
mob_fill_container(picked_organ, fluid_container)
return
else
to_chat(src, "<span class='warning'>You cannot do this without anything to fill.</span>")
return
else //They either lack organs that can climax, or they didn't pick one.
to_chat(src, "<span class='warning'>You cannot fill anything without choosing genitals.</span>")
return
else //Somehow another option was taken, maybe something interrupted the selection or it was cancelled
return //Just end it in that case.
if("Fill container")
//We'll need hands and no restraints.
if(!available_rosie_palms(FALSE, /obj/item/reagent_containers))
return
//We got hands, let's pick an organ
var/obj/item/organ/genital/picked_organ
picked_organ = pick_climax_genitals() //Gotta be climaxable, not just masturbation, to fill with fluids.
if(picked_organ)
//Good, got an organ, time to pick a container
var/obj/item/reagent_containers/fluid_container = pick_climax_container()
if(fluid_container && available_rosie_palms(TRUE, /obj/item/reagent_containers))
mob_fill_container(picked_organ, fluid_container)
mb_cd_timer = world.time + mb_cd_length
@@ -0,0 +1,339 @@
/obj/item/organ/genital
color = "#fcccb3"
w_class = WEIGHT_CLASS_NORMAL
var/shape = "human"
var/sensitivity = AROUSAL_START_VALUE
var/genital_flags //see citadel_defines.dm
var/masturbation_verb = "masturbate"
var/orgasm_verb = "cumming" //present continous
var/fluid_transfer_factor = 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 = CUM_RATE
var/fluid_mult = 1
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/linked_organ_slot //used for linking an apparatus' organ to its other half on update_link().
var/layer_index = GENITAL_LAYER_INDEX //Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
/obj/item/organ/genital/Initialize(mapload, mob/living/carbon/human/H)
. = ..()
if(fluid_id)
create_reagents(fluid_max_volume)
if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
reagents.add_reagent(fluid_id, fluid_max_volume)
if(H)
get_features(H)
Insert(H)
else
update()
/obj/item/organ/genital/Destroy()
if(linked_organ)
update_link(TRUE)//this should remove any other links it has
if(owner)
Remove(owner, TRUE)//this should remove references to it, so it can be GCd correctly
return ..()
/obj/item/organ/genital/proc/update(removing = FALSE)
if(QDELETED(src))
return
update_size()
update_appearance()
if(linked_organ_slot || (linked_organ && removing))
update_link(removing)
//exposure and through-clothing code
/mob/living/carbon
var/list/exposed_genitals = list() //Keeping track of them so we don't have to iterate through every genitalia and see if exposed
/obj/item/organ/genital/proc/is_exposed()
if(!owner || CHECK_BITFIELD(genital_flags, GENITAL_INTERNAL) || CHECK_BITFIELD(genital_flags, GENITAL_HIDDEN))
return FALSE
if(CHECK_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES))
return TRUE
switch(zone) //update as more genitals are added
if(BODY_ZONE_CHEST)
return owner.is_chest_exposed()
if(BODY_ZONE_PRECISE_GROIN)
return owner.is_groin_exposed()
/obj/item/organ/genital/proc/toggle_visibility(visibility)
switch(visibility)
if("Always visible")
ENABLE_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES)
DISABLE_BITFIELD(genital_flags, GENITAL_HIDDEN)
if(!(src in owner.exposed_genitals))
owner.exposed_genitals += src
if("Hidden by clothes")
DISABLE_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES)
DISABLE_BITFIELD(genital_flags, GENITAL_HIDDEN)
if(src in owner.exposed_genitals)
owner.exposed_genitals -= src
if("Always hidden")
DISABLE_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES)
ENABLE_BITFIELD(genital_flags, GENITAL_HIDDEN)
if(src in owner.exposed_genitals)
owner.exposed_genitals -= src
if(ishuman(owner)) //recast to use update genitals proc
var/mob/living/carbon/human/H = owner
H.update_genitals()
/mob/living/carbon/verb/toggle_genitals()
set category = "IC"
set name = "Expose/Hide genitals"
set desc = "Allows you to toggle which genitals should show through clothes or not."
var/list/genital_list = list()
for(var/obj/item/organ/O in internal_organs)
if(isgenital(O))
var/obj/item/organ/genital/G = O
if(!CHECK_BITFIELD(G.genital_flags, GENITAL_INTERNAL))
genital_list += G
if(!genital_list.len) //There is nothing to expose
return
//Full list of exposable genitals created
var/obj/item/organ/genital/picked_organ
picked_organ = input(src, "Choose which genitalia to expose/hide", "Expose/Hide genitals", null) in genital_list
if(picked_organ)
var/picked_visibility = input(src, "Choose visibility setting", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
picked_organ.toggle_visibility(picked_visibility)
return
/obj/item/organ/genital/proc/modify_size(modifier, min = -INFINITY, max = INFINITY)
return
/obj/item/organ/genital/proc/update_size()
return
/obj/item/organ/genital/proc/update_appearance()
if(!owner || owner.stat == DEAD)
aroused_state = FALSE
/obj/item/organ/genital/on_life()
if(!reagents || !owner)
return
reagents.maximum_volume = fluid_max_volume
if(fluid_id && CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
generate_fluid()
/obj/item/organ/genital/proc/generate_fluid()
var/amount = fluid_rate
if(!reagents.total_volume && amount < 0.1) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
amount += 0.1
var/multiplier = fluid_mult
if(reagents.total_volume >= 5)
multiplier *= 0.5
if(reagents.total_volume < reagents.maximum_volume)
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
reagents.add_reagent(fluid_id, (amount * multiplier))//generate the cum
return TRUE
return FALSE
/obj/item/organ/genital/proc/update_link(removing = FALSE)
if(!removing && owner)
if(linked_organ)
return
linked_organ = owner.getorganslot(linked_organ_slot)
if(linked_organ)
linked_organ.linked_organ = src
linked_organ.upon_link()
upon_link()
return TRUE
else
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
return FALSE
//post organ duo making arrangements.
/obj/item/organ/genital/proc/upon_link()
return
/obj/item/organ/genital/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
. = ..()
if(.)
update()
RegisterSignal(owner, COMSIG_MOB_DEATH, .proc/update_appearance)
/obj/item/organ/genital/Remove(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
. = ..()
if(.)
update(TRUE)
UnregisterSignal(M, COMSIG_MOB_DEATH)
//proc to give a player their genitals and stuff when they log in
/mob/living/carbon/human/proc/give_genitals(clean = FALSE)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA
if(clean)
for(var/obj/item/organ/genital/G in internal_organs)
qdel(G)
if (NOGENITALS in dna.species.species_traits)
return
if(dna.features["has_vag"])
give_genital(/obj/item/organ/genital/vagina)
if(dna.features["has_womb"])
give_genital(/obj/item/organ/genital/womb)
if(dna.features["has_balls"])
give_genital(/obj/item/organ/genital/testicles)
if(dna.features["has_breasts"])
give_genital(/obj/item/organ/genital/breasts)
if(dna.features["has_cock"])
give_genital(/obj/item/organ/genital/penis)
/*
if(dna.features["has_ovi"])
give_genital(/obj/item/organ/genital/ovipositor)
if(dna.features["has_eggsack"])
give_genital(/obj/item/organ/genital/eggsack)
*/
/mob/living/carbon/human/proc/give_genital(obj/item/organ/genital/G)
if(!dna || (NOGENITALS in dna.species.species_traits) || getorganslot(initial(G.slot)))
return FALSE
G = new G(null, src)
return G
/obj/item/organ/genital/proc/get_features(mob/living/carbon/human/H)
return
/datum/species/proc/genitals_layertext(layer)
switch(layer)
if(GENITALS_BEHIND_LAYER)
return "BEHIND"
if(GENITALS_FRONT_LAYER)
return "FRONT"
//procs to handle sprite overlays being applied to humans
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
. = ..()
if(!. && I && slot && !(slot in GLOB.no_genitals_update_slots)) //the item was successfully equipped, and the chosen slot wasn't merely storage, hands or cuffs.
update_genitals()
/mob/living/carbon/human/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE)
var/no_update = FALSE
if(!I || I == l_store || I == r_store || I == s_store || I == handcuffed || I == legcuffed || get_held_index_of_item(I)) //stops storages, cuffs and held items from triggering it.
no_update = TRUE
. = ..()
if(!. || no_update)
return
update_genitals()
/mob/living/carbon/human/proc/update_genitals()
if(!QDELETED(src))
dna.species.handle_genitals(src)
//Checks to see if organs are new on the mob, and changes their colours so that they don't get crazy colours.
/mob/living/carbon/human/proc/emergent_genital_call()
if(!canbearoused)
return FALSE
var/organCheck = locate(/obj/item/organ/genital) in internal_organs
var/breastCheck = getorganslot(ORGAN_SLOT_BREASTS)
var/willyCheck = getorganslot(ORGAN_SLOT_PENIS)
if(organCheck == FALSE)
if(ishuman(src) && dna.species.id == "human")
dna.features["genitals_use_skintone"] = TRUE
dna.species.use_skintones = TRUE
if(MUTCOLORS)
if(src.dna.species.fixed_mut_color)
dna.features["cock_color"] = "[dna.species.fixed_mut_color]"
dna.features["breasts_color"] = "[dna.species.fixed_mut_color]"
return
//So people who haven't set stuff up don't get rainbow surprises.
dna.features["cock_color"] = "[dna.features["mcolor"]]"
dna.features["breasts_color"] = "[dna.features["mcolor"]]"
else //If there's a new organ, make it the same colour.
if(breastCheck == FALSE)
dna.features["breasts_color"] = dna.features["cock_color"]
else if (willyCheck == FALSE)
dna.features["cock_color"] = dna.features["breasts_color"]
return TRUE
/datum/species/proc/handle_genitals(mob/living/carbon/human/H)//more like handle sadness
if(!H)//no args
CRASH("H = null")
if(!LAZYLEN(H.internal_organs) || ((NOGENITALS in species_traits) && !H.genital_override) || HAS_TRAIT(H, TRAIT_HUSK))
return
var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_FRONT_LAYER)
for(var/L in relevant_layers) //Less hardcode
H.remove_overlay(L)
H.remove_overlay(GENITALS_EXPOSED_LAYER)
//start scanning for genitals
var/list/gen_index[GENITAL_LAYER_INDEX_LENGTH]
var/list/genitals_to_add
var/list/fully_exposed
for(var/obj/item/organ/genital/G in H.internal_organs)
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
LAZYADD(gen_index[G.layer_index], G)
for(var/L in gen_index)
if(L) //skip nulls
LAZYADD(genitals_to_add, L)
if(!genitals_to_add)
return
//Now we added all genitals that aren't internal and should be rendered
//start applying overlays
for(var/layer in relevant_layers)
var/list/standing = list()
var/layertext = genitals_layertext(layer)
for(var/A in genitals_to_add)
var/obj/item/organ/genital/G = A
var/datum/sprite_accessory/S
var/size = G.size
var/aroused_state = G.aroused_state
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)
S = GLOB.breasts_shapes_list[G.shape]
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]"
if(S.center)
genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y)
if(use_skintones && H.dna.features["genitals_use_skintone"])
genital_overlay.color = "#[skintone2hex(H.skin_tone)]"
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]"
else
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"]]"
if(layer == GENITALS_FRONT_LAYER && CHECK_BITFIELD(G.genital_flags, GENITAL_THROUGH_CLOTHES))
genital_overlay.layer = -GENITALS_EXPOSED_LAYER
LAZYADD(fully_exposed, genital_overlay) // to be added to a layer with higher priority than clothes, hence the name of the bitflag.
else
standing += genital_overlay
if(LAZYLEN(standing))
H.overlays_standing[layer] = standing
if(LAZYLEN(fully_exposed))
H.overlays_standing[GENITALS_EXPOSED_LAYER] = fully_exposed
H.apply_overlay(GENITALS_EXPOSED_LAYER)
for(var/L in relevant_layers)
H.apply_overlay(L)
@@ -5,11 +5,9 @@
//DICKS,COCKS,PENISES,WHATEVER YOU WANT TO CALL THEM
/datum/sprite_accessory/penis
icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi'
icon_state = null
name = "penis" //the preview name of the accessory
gender_specific = 0 //Might be needed somewhere down the list.
color_src = "cock_color"
locked = 0
alt_aroused = TRUE
/datum/sprite_accessory/penis/human
icon_state = "human"
@@ -32,16 +30,16 @@
name = "Tapered"
/datum/sprite_accessory/penis/tentacle
icon_state = "tentacle"
name = "Tentacled"
icon_state = "tentacle"
name = "Tentacled"
/datum/sprite_accessory/penis/hemi
icon_state = "hemi"
name = "Hemi"
icon_state = "hemi"
name = "Hemi"
/datum/sprite_accessory/penis/hemiknot
icon_state = "hemiknot"
name = "Knotted Hemi"
icon_state = "hemiknot"
name = "Knotted Hemi"
////////////////////////
@@ -75,27 +73,21 @@
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"
icon_state = "none"
name = "Hidden"
alt_aroused = TRUE
/datum/sprite_accessory/testicles/single
icon_state = "single"
name = "Single"
alt_aroused = TRUE
//Vaginas
/datum/sprite_accessory/vagina
icon = 'modular_citadel/icons/obj/genitals/vagina_onmob.dmi'
icon_state = null
name = "vagina"
gender_specific = 0
color_src = "vag_color"
locked = 0
alt_aroused = FALSE //if this is TRUE, then the genitals will use an alternate sprite for aroused states
/datum/sprite_accessory/vagina/human
icon_state = "human"
@@ -125,41 +117,34 @@
name = "Furred"
/datum/sprite_accessory/vagina/gaping
icon_state = "gaping"
name = "Gaping"
icon_state = "gaping"
name = "Gaping"
//BREASTS BE HERE
/datum/sprite_accessory/breasts
icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi'
icon_state = null
name = "breasts"
gender_specific = 0
color_src = "breasts_color"
locked = 0
alt_aroused = TRUE
/datum/sprite_accessory/breasts/pair
icon_state = "pair"
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
icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi'
icon_state = null
name = "Ovipositor" //the preview name of the accessory
gender_specific = 0 //Might be needed somewhere down the list.
color_src = "cock_color"
locked = 0
/datum/sprite_accessory/ovipositor/knotted
icon_state = "knotted"
@@ -1,49 +1,26 @@
/obj/item/organ/genital/breasts
name = "breasts"
desc = "Female milk producing organs."
icon_state = "breasts"
icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
zone = "chest"
slot = "breasts"
w_class = 3
size = BREASTS_SIZE_DEF //SHOULD BE A LETTER, starts as a number...???
var/cached_size = null //for enlargement SHOULD BE A NUMBER
var/prev_size //For flavour texts SHOULD BE A LETTER
//var/breast_sizes = list ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "huge", "flat")
var/breast_values = list ("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "flat" = 0)
var/statuscheck = FALSE
fluid_id = "milk"
var/amount = 2
producing = TRUE
shape = "Pair"
can_masturbate_with = TRUE
masturbation_verb = "massage"
can_climax = TRUE
fluid_transfer_factor = 0.5
name = "breasts"
desc = "Female milk producing organs."
icon_state = "breasts"
icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_BREASTS
size = "c" //refer to the breast_values static list below for the cups associated number values
fluid_id = "milk"
shape = "pair"
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_FUID_PRODUCTION
masturbation_verb = "massage"
orgasm_verb = "leaking"
fluid_transfer_factor = 0.5
var/static/list/breast_values = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "flat" = 0)
var/cached_size //these two vars pertain size modifications and so should be expressed in NUMBERS.
var/prev_size //former cached_size value, to allow update_size() to early return should be there no significant changes.
/obj/item/organ/genital/breasts/on_life()
if(QDELETED(src))
return
if(!reagents || !owner)
return
reagents.maximum_volume = fluid_max_volume
if(fluid_id && producing)
if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
fluid_rate = 0.1
else
fluid_rate = CUM_RATE
if(reagents.total_volume >= 5)
fluid_mult = 0.5
else
fluid_mult = 1
generate_milk()
/obj/item/organ/genital/breasts/proc/generate_milk()
if(owner.stat == DEAD)
return FALSE
consider_size()
reagents.isolate_reagent(fluid_id)
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))
/obj/item/organ/genital/breasts/Initialize(mapload, mob/living/carbon/human/H)
if(!H)
cached_size = breast_values[size]
prev_size = cached_size
return ..()
/obj/item/organ/genital/breasts/proc/consider_size()
if(!cached_size || cached_size < 1)
@@ -53,6 +30,7 @@
reagents.maximum_volume = fluid_max_volume
/obj/item/organ/genital/breasts/update_appearance()
. = ..()
var/lowershape = lowertext(shape)
switch(lowershape)
if("pair")
@@ -63,16 +41,15 @@
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(cached_size > 16)
if(size == "huge")
desc = "You see [pick("some serious honkers", "a real set of badonkers", "some dobonhonkeros", "massive dohoonkabhankoloos", "two big old tonhongerekoogers", "a couple of giant bonkhonagahoogs", "a pair of humongous hungolomghnonoloughongous")]. Their volume is way beyond cupsize now, measuring in about [round(cached_size)]cm in diameter."
else if (!isnum(size))
else
if (size == "flat")
desc += " They're very small and flatchested, however."
else
desc += " You estimate that they're [uppertext(size)]-cups."
//string = "breasts_[lowertext(shape)]_[size]-s"
if(producing && aroused_state)
if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION) && aroused_state)
desc += " They're leaking [fluid_id]."
var/string
if(owner)
@@ -88,57 +65,71 @@
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
icon_state = sanitize_text(string)
//Allows breasts to grow and change size, with sprite changes too.
//maximum wah
//Comical sizes slow you down in movement and actions.
//Rediculous sizes makes you more cumbersome.
//this is far too lewd wah
/obj/item/organ/genital/breasts/update_size()//wah
if(!ishuman(owner) || !owner)
/obj/item/organ/genital/breasts/modify_size(modifier, min = -INFINITY, max = INFINITY)
var/new_value = CLAMP(cached_size + modifier, min, max)
if(new_value == cached_size)
return
if(cached_size < 0)//I don't actually know what round() does to negative numbers, so to be safe!!fixed
to_chat(owner, "<span class='warning'>You feel your breasts shrinking away from your body as your chest flattens out.</b></span>")
src.Remove(owner)
switch(round(cached_size))
if(0) //If flatchested
size = "flat"
if(owner.has_status_effect(/datum/status_effect/chem/breast_enlarger))
owner.remove_status_effect(/datum/status_effect/chem/breast_enlarger)
statuscheck = FALSE
if(1 to 8) //If modest size
size = breast_values[round(cached_size)]
if(owner.has_status_effect(/datum/status_effect/chem/breast_enlarger))
owner.remove_status_effect(/datum/status_effect/chem/breast_enlarger)
statuscheck = FALSE
if(9 to 15) //If massive
size = breast_values[round(cached_size)]
if(!owner.has_status_effect(/datum/status_effect/chem/breast_enlarger))
owner.apply_status_effect(/datum/status_effect/chem/breast_enlarger)
statuscheck = TRUE
if(16 to INFINITY) //if Rediculous
size = cached_size
prev_size = cached_size
cached_size = new_value
update()
..()
if(round(cached_size) < 16)//Because byond doesn't count from 0, I have to do this.
if (prev_size == 0)
prev_size = "flat"
if(size == 0)//Bloody byond with it's counting from 1
/obj/item/organ/genital/breasts/update_size()//wah
var/rounded_cached = round(cached_size)
if(cached_size < 0)//I don't actually know what round() does to negative numbers, so to be safe!!fixed
if(owner)
to_chat(owner, "<span class='warning'>You feel your breasts shrinking away from your body as your chest flattens out.</span>")
QDEL_IN(src, 1)
return
var/enlargement = FALSE
switch(rounded_cached)
if(0) //flatchested
size = "flat"
if(isnum(prev_size))
prev_size = breast_values[prev_size]
if (breast_values[size] > breast_values[prev_size])
to_chat(owner, "<span class='warning'>Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [uppertext(size)]-cup.</b></span>")
var/mob/living/carbon/human/H = owner
H.Force_update_genitals()
else if ((breast_values[size] < breast_values[prev_size]) && (breast_values[size] > 0.5))
to_chat(owner, "<span class='warning'>Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [uppertext(size)]-cup.</b></span>")
var/mob/living/carbon/human/H = owner
H.Force_update_genitals()
prev_size = size
else if (cached_size >= 16)
size = "huge"
if(1 to 8) //modest
size = breast_values[rounded_cached]
if(9 to 15) //massive
size = breast_values[rounded_cached]
enlargement = TRUE
if(16 to INFINITY) //rediculous
size = "huge"
enlargement = TRUE
if(owner)
var/status_effect = owner.has_status_effect(STATUS_EFFECT_BREASTS_ENLARGEMENT)
if(enlargement && !status_effect)
owner.apply_status_effect(STATUS_EFFECT_BREASTS_ENLARGEMENT)
else if(!enlargement && status_effect)
owner.remove_status_effect(STATUS_EFFECT_BREASTS_ENLARGEMENT)
if(rounded_cached < 16 && owner)//Because byond doesn't count from 0, I have to do this.
var/mob/living/carbon/human/H = owner
var/r_prev_size = round(prev_size)
if (rounded_cached > r_prev_size)
to_chat(H, "<span class='warning'>Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [uppertext(size)]-cup.</span>")
else if (rounded_cached < r_prev_size)
to_chat(H, "<span class='warning'>Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [uppertext(size)]-cup.</span>")
/obj/item/organ/genital/breasts/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
if(D.species.use_skintones && D.features["genitals_use_skintone"])
color = "#[skintone2hex(H.skin_tone)]"
else
color = "#[D.features["breasts_color"]]"
size = D.features["breasts_size"]
shape = D.features["breasts_shape"]
fluid_id = D.features["breasts_fluid"]
if(!D.features["breasts_producing"])
DISABLE_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION)
if(!isnum(size))
cached_size = breast_values[size]
else
cached_size = size
size = breast_values[size]
prev_size = cached_size
@@ -1,14 +1,14 @@
/obj/item/organ/genital/eggsack
name = "Egg sack"
desc = "An egg producing reproductive organ."
icon_state = "egg_sack"
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
zone = "groin"
slot = "testicles"
color = null //don't use the /genital color since it already is colored
internal = TRUE
name = "Egg sack"
desc = "An egg producing reproductive organ."
icon_state = "egg_sack"
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_TESTICLES
genital_flags = GENITAL_INTERNAL|GENITAL_BLACKLISTED //unimplemented
linked_organ_slot = ORGAN_SLOT_PENIS
color = null //don't use the /genital color since it already is colored
var/egg_girth = EGG_GIRTH_DEF
var/cum_mult = CUM_RATE_MULT
var/cum_rate = CUM_RATE
var/cum_efficiency = CUM_EFFICIENCY
var/obj/item/organ/ovipositor/linked_ovi
@@ -1,414 +0,0 @@
/obj/item/organ/genital
color = "#fcccb3"
w_class = WEIGHT_CLASS_NORMAL
var/shape = "Human" //Changed to be uppercase, let me know if this breaks everything..!!
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 = 15
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
/obj/item/organ/genital/Initialize()
. = ..()
if(!reagents)
create_reagents(fluid_max_volume)
update()
/obj/item/organ/genital/Destroy()
remove_ref()
if(owner)
Remove(owner, 1)//this should remove references to it, so it can be GCd correctly
update_link()//this should remove any other links it has
return ..()
/obj/item/organ/genital/proc/update()
if(QDELETED(src))
return
update_size()
update_appearance()
update_link()
//exposure and through-clothing code
/mob/living/carbon
var/list/exposed_genitals = list() //Keeping track of them so we don't have to iterate through every genitalia and see if exposed
/obj/item/organ/genital/proc/is_exposed()
if(!owner)
return FALSE
if(hidden)
return FALSE
if(internal)
return FALSE
if(through_clothes)
return TRUE
switch(zone) //update as more genitals are added
if("chest")
return owner.is_chest_exposed()
if("groin")
return owner.is_groin_exposed()
return FALSE
/obj/item/organ/genital/proc/toggle_visibility(visibility)
switch(visibility)
if("Always visible")
through_clothes = TRUE
hidden = FALSE
if(!(src in owner.exposed_genitals))
owner.exposed_genitals += src
if("Hidden by clothes")
through_clothes = FALSE
hidden = TRUE
if(src in owner.exposed_genitals)
owner.exposed_genitals -= src
if("Always hidden")
through_clothes = FALSE
hidden = TRUE
if(src in owner.exposed_genitals)
owner.exposed_genitals -= src
if(ishuman(owner)) //recast to use update genitals proc
var/mob/living/carbon/human/H = owner
H.update_genitals()
/mob/living/carbon/verb/toggle_genitals()
set category = "IC"
set name = "Expose/Hide genitals"
set desc = "Allows you to toggle which genitals should show through clothes or not."
var/list/genital_list = list()
for(var/obj/item/organ/O in internal_organs)
if(isgenital(O))
var/obj/item/organ/genital/G = O
if(!G.internal)
genital_list += G
if(!genital_list.len) //There is nothing to expose
return
//Full list of exposable genitals created
var/obj/item/organ/genital/picked_organ
picked_organ = input(src, "Choose which genitalia to expose/hide", "Expose/Hide genitals", null) in genital_list
if(picked_organ)
var/picked_visibility = input(src, "Choose visibility setting", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
picked_organ.toggle_visibility(picked_visibility)
return
/obj/item/organ/genital/proc/update_size()
return
/obj/item/organ/genital/proc/update_appearance()
return
/obj/item/organ/genital/proc/update_link()
return
/obj/item/organ/genital/proc/remove_ref()
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
/obj/item/organ/genital/Insert(mob/living/carbon/M, special = 0)
..()
update()
/obj/item/organ/genital/Remove(mob/living/carbon/M, special = 0)
..()
update()
//proc to give a player their genitals and stuff when they log in
/mob/living/carbon/human/proc/give_genitals(clean=0)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA
if(clean)
var/obj/item/organ/genital/GtoClean
for(GtoClean in internal_organs)
qdel(GtoClean)
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_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"])
give_ovipositor()
if(dna.features["has_eggsack"])
give_eggsack()
/mob/living/carbon/human/proc/give_penis()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("penis"))
var/obj/item/organ/genital/penis/P = new
P.Insert(src)
if(P)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
P.color = "#[skintone2hex(skin_tone)]"
else
P.color = "#[dna.features["cock_color"]]"
P.length = dna.features["cock_length"]
P.girth_ratio = dna.features["cock_girth_ratio"]
P.shape = dna.features["cock_shape"]
P.prev_length = P.length
P.cached_length = P.length
P.update()
/mob/living/carbon/human/proc/give_balls()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("testicles"))
var/obj/item/organ/genital/testicles/T = new
T.Insert(src)
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"]
T.fluid_efficiency = dna.features["balls_efficiency"]
T.update()
/mob/living/carbon/human/proc/give_breasts()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("breasts"))
var/obj/item/organ/genital/breasts/B = new
B.Insert(src)
if(B)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
B.color = "#[skintone2hex(skin_tone)]"
else
B.color = "#[dna.features["breasts_color"]]"
B.size = dna.features["breasts_size"]
if(!isnum(B.size))
if(B.size == "flat")
B.cached_size = 0
B.prev_size = 0
else if (B.cached_size == "huge")
B.prev_size = "huge"
else
B.cached_size = B.breast_values[B.size]
B.prev_size = B.size
else
B.cached_size = B.size
B.prev_size = B.size
B.shape = dna.features["breasts_shape"]
B.fluid_id = dna.features["breasts_fluid"]
B.producing = dna.features["breasts_producing"]
B.update()
/mob/living/carbon/human/proc/give_ovipositor()
return
/mob/living/carbon/human/proc/give_eggsack()
return
/mob/living/carbon/human/proc/give_vagina()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("vagina"))
var/obj/item/organ/genital/vagina/V = new
V.Insert(src)
if(V)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
V.color = "#[skintone2hex(skin_tone)]"
else
V.color = "[dna.features["vag_color"]]"
V.shape = "[dna.features["vag_shape"]]"
V.update()
/mob/living/carbon/human/proc/give_womb()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("womb"))
var/obj/item/organ/genital/womb/W = new
W.Insert(src)
if(W)
W.update()
/datum/species/proc/genitals_layertext(layer)
switch(layer)
if(GENITALS_BEHIND_LAYER)
return "BEHIND"
/*if(GENITALS_ADJ_LAYER)
return "ADJ"*/
if(GENITALS_FRONT_LAYER)
return "FRONT"
//procs to handle sprite overlays being applied to humans
/obj/item/equipped(mob/user, slot)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.update_genitals()
..()
/mob/living/carbon/human/doUnEquip(obj/item/I, force)
. = ..()
if(!.)
return
update_genitals()
/mob/living/carbon/human/proc/update_genitals()
if(src && !QDELETED(src))
dna.species.handle_genitals(src)
//fermichem procs
/mob/living/carbon/human/proc/Force_update_genitals(mob/living/carbon/human/H) //called in fermiChem
dna.species.handle_genitals(src)//should work.
//dna.species.handle_breasts(src)
//Checks to see if organs are new on the mob, and changes their colours so that they don't get crazy colours.
/mob/living/carbon/human/proc/emergent_genital_call()
var/organCheck = FALSE
var/breastCheck = FALSE
var/willyCheck = FALSE
if(!canbearoused)
ADD_TRAIT(src, TRAIT_PHARMA, "pharma")//Prefs prevent unwanted organs.
return
for(var/obj/item/organ/O in internal_organs)
if(istype(O, /obj/item/organ/genital))
organCheck = TRUE
if(/obj/item/organ/genital/penis)
//dna.features["has_cock"] = TRUE
willyCheck = TRUE
if(/obj/item/organ/genital/breasts)
//dna.features["has_breasts"] = TRUE//Goddamnit get in there.
breastCheck = TRUE
if(organCheck == FALSE)
if(ishuman(src) && dna.species.id == "human")
dna.features["genitals_use_skintone"] = TRUE
dna.species.use_skintones = TRUE
if(MUTCOLORS)
if(src.dna.species.fixed_mut_color)
dna.features["cock_color"] = "[src.dna.species.fixed_mut_color]"
dna.features["breasts_color"] = "[src.dna.species.fixed_mut_color]"
return
//So people who haven't set stuff up don't get rainbow surprises.
dna.features["cock_color"] = "[dna.features["mcolor"]]"
dna.features["breasts_color"] = "[dna.features["mcolor"]]"
else //If there's a new organ, make it the same colour.
if(breastCheck == FALSE)
dna.features["breasts_color"] = dna.features["cock_color"]
else if (willyCheck == FALSE)
dna.features["cock_color"] = dna.features["breasts_color"]
return
/datum/species/proc/handle_genitals(mob/living/carbon/human/H)//more like handle sadness
if(!H)//no args
CRASH("H = null")
if(!LAZYLEN(H.internal_organs))//if they have no organs, we're done
return
if((NOGENITALS in species_traits) && (H.genital_override = FALSE))//golems and such - things that shouldn't
return
if(HAS_TRAIT(H, TRAIT_HUSK))
return
var/list/genitals_to_add = list()
var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_FRONT_LAYER) //GENITALS_ADJ_LAYER removed
var/list/standing = list()
var/size
var/aroused_state
for(var/L in relevant_layers) //Less hardcode
H.remove_overlay(L)
//start scanning for genitals
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
//start applying overlays
for(var/layer in relevant_layers)
var/layertext = genitals_layertext(layer)
for(var/obj/item/organ/genital/G in genitals_to_add)
var/datum/sprite_accessory/S
size = G.size
aroused_state = G.aroused_state
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)
S = GLOB.breasts_shapes_list[G.shape]
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]"
if(S.center)
genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y)
if(use_skintones && H.dna.features["genitals_use_skintone"])
genital_overlay.color = "#[skintone2hex(H.skin_tone)]"
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]"
else
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()
for(var/L in relevant_layers)
H.apply_overlay(L)
@@ -3,14 +3,14 @@
desc = "An egg laying reproductive organ."
icon_state = "ovi_knotted_2"
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
zone = "groin"
slot = "penis"
w_class = 3
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_PENIS
genital_flags = GENITAL_BLACKLISTED //unimplemented
shape = "knotted"
size = 3
layer_index = PENIS_LAYER_INDEX
var/length = 6 //inches
var/girth = 0
var/girth_ratio = COCK_GIRTH_RATIO_DEF //citadel_defines.dm for these defines
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
var/list/oviflags = list()
var/obj/item/organ/eggsack/linked_eggsack
@@ -1,77 +1,78 @@
/obj/item/organ/genital/penis
name = "penis"
desc = "A male reproductive organ."
icon_state = "penis"
icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
zone = "groin"
slot = ORGAN_SLOT_PENIS
can_masturbate_with = TRUE
masturbation_verb = "stroke"
can_climax = TRUE
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/girth = 4.38
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
var/list/dickflags = list()
var/list/knotted_types = list("knotted", "barbed, knotted")
var/prev_length = 6 //really should be renamed to prev_length
name = "penis"
desc = "A male reproductive organ."
icon_state = "penis"
icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_PENIS
masturbation_verb = "stroke"
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
linked_organ_slot = ORGAN_SLOT_TESTICLES
fluid_transfer_factor = 0.5
size = 2 //arbitrary value derived from length and girth for sprites.
layer_index = PENIS_LAYER_INDEX
var/length = 6 //inches
var/prev_length = 6 //really should be renamed to prev_length
var/girth = 4.38
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
/obj/item/organ/genital/penis/Initialize()
. = ..()
/* I hate genitals.*/
/obj/item/organ/genital/penis/update_size()
var/mob/living/carbon/human/o = owner
if(!ishuman(o) || !o)
/obj/item/organ/genital/penis/modify_size(modifier, min = -INFINITY, max = INFINITY)
var/new_value = CLAMP(length + modifier, min, max)
if(new_value == length)
return
if(cached_length < 0)//I don't actually know what round() does to negative numbers, so to be safe!!
var/obj/item/organ/genital/penis/P = o.getorganslot("penis")
to_chat(o, "<span class='warning'>You feel your tallywacker shrinking away from your body as your groin flattens out!</b></span>")
P.Remove(o)
switch(round(cached_length))
if(0 to 4) //If modest size
length = cached_length
size = 1
if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.remove_status_effect(/datum/status_effect/chem/penis_enlarger)
if(5 to 10) //If modest size
length = cached_length
size = 2
if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.remove_status_effect(/datum/status_effect/chem/penis_enlarger)
if(11 to 20) //If massive
length = cached_length
size = 3
if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.remove_status_effect(/datum/status_effect/chem/penis_enlarger)
if(21 to 35) //If massive and due for large effects
length = cached_length
size = 3
if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.apply_status_effect(/datum/status_effect/chem/penis_enlarger)
if(36 to INFINITY) //If comical
length = cached_length
size = 4 //no new sprites for anything larger yet
if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
o.apply_status_effect(/datum/status_effect/chem/penis_enlarger)
if (round(length) > round(prev_length))
to_chat(o, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(round(length))] inch penis.</b></span>")
else if ((round(length) < round(prev_length)) && (length > 0.5))
to_chat(o, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(round(length))] inch penis.</b></span>")
prev_length = length
length = CLAMP(length + modifier, min, max)
update()
/obj/item/organ/genital/penis/update_size(modified = FALSE)
if(length < 0)//I don't actually know what round() does to negative numbers, so to be safe!!
if(owner)
to_chat(owner, "<span class='warning'>You feel your tallywacker shrinking away from your body as your groin flattens out!</b></span>")
QDEL_IN(src, 1)
if(linked_organ)
QDEL_IN(linked_organ, 1)
return
var/rounded_length = round(length)
var/new_size
var/enlargement = FALSE
switch(rounded_length)
if(0 to 6) //If modest size
new_size = 1
if(7 to 11) //If large
new_size = 2
if(12 to 20) //If massive
new_size = 3
if(21 to 34) //If massive and due for large effects
new_size = 3
enlargement = TRUE
if(35 to INFINITY) //If comical
new_size = 4 //no new sprites for anything larger yet
enlargement = TRUE
if(owner)
var/status_effect = owner.has_status_effect(STATUS_EFFECT_PENIS_ENLARGEMENT)
if(enlargement && !status_effect)
owner.apply_status_effect(STATUS_EFFECT_PENIS_ENLARGEMENT)
else if(!enlargement && status_effect)
owner.remove_status_effect(STATUS_EFFECT_PENIS_ENLARGEMENT)
if(linked_organ)
linked_organ.size = CLAMP(size + new_size, BALLS_SIZE_MIN, BALLS_SIZE_MAX)
linked_organ.update()
size = new_size
if(owner)
if (round(length) > round(prev_length))
to_chat(owner, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(round(length))] inch penis.</b></span>")
else if ((round(length) < round(prev_length)) && (length > 0.5))
to_chat(owner, "<span class='warning'>Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(round(length))] inch penis.</b></span>")
icon_state = sanitize_text("penis_[shape]_[size]")
girth = (length * girth_ratio)//Is it just me or is this ludicous, why not make it exponentially decay?
//I have no idea on how to update sprites and I hate it
/obj/item/organ/genital/penis/update_appearance()
. = ..()
var/string
var/lowershape = lowertext(shape)
desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] penis. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth."
desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] [name]. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth."
if(owner)
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
@@ -87,13 +88,13 @@
icon_state = sanitize_text(string)
H.update_genitals()
/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
/obj/item/organ/genital/penis/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
if(D.species.use_skintones && D.features["genitals_use_skintone"])
color = "#[skintone2hex(H.skin_tone)]"
else
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
color = "#[D.features["cock_color"]]"
length = D.features["cock_length"]
girth_ratio = D.features["cock_girth_ratio"]
shape = D.features["cock_shape"]
prev_length = length
@@ -1,82 +1,46 @@
/obj/item/organ/genital/testicles
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
name = "testicles"
desc = "A male reproductive organ."
icon_state = "testicles"
icon = 'modular_citadel/icons/obj/genitals/testicles.dmi'
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_TESTICLES
size = BALLS_SIZE_MIN
linked_organ_slot = ORGAN_SLOT_PENIS
genital_flags = CAN_MASTURBATE_WITH|MASTURBATE_LINKED_ORGAN|GENITAL_FUID_PRODUCTION
var/size_name = "average"
shape = "Single"
var/sack_size = BALLS_SACK_SIZE_DEF
fluid_id = "semen"
masturbation_verb = "massage"
layer_index = TESTICLES_LAYER_INDEX
/obj/item/organ/genital/testicles/on_life()
if(QDELETED(src))
return
if(reagents && producing)
if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
fluid_rate = 0.1
else
fluid_rate = CUM_RATE
if(reagents.total_volume >= 5)
fluid_mult = 0.5
else
fluid_mult = 1
generate_cum()
/obj/item/organ/genital/testicles/proc/generate_cum()
reagents.maximum_volume = fluid_max_volume
if(reagents.total_volume >= reagents.maximum_volume)
if(!sent_full_message)
send_full_message()
sent_full_message = TRUE
/obj/item/organ/genital/testicles/generate_fluid()
if(!linked_organ && !update_link())
return FALSE
sent_full_message = FALSE
update_link()
if(!linked_organ)
return FALSE
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
. = ..()
if(. && reagents.holder_full())
to_chat(owner, "Your balls finally feel full, again.")
/obj/item/organ/genital/testicles/update_link()
if(owner && !QDELETED(src))
linked_organ = (owner.getorganslot("penis"))
if(linked_organ)
linked_organ.linked_organ = src
size = linked_organ.size
/obj/item/organ/genital/testicles/upon_link()
size = linked_organ.size
update_size()
update_appearance()
else
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
/obj/item/organ/genital/testicles/proc/send_full_message(msg = "Your balls finally feel full, again.")
if(owner && istext(msg))
to_chat(owner, msg)
return TRUE
/obj/item/organ/genital/testicles/update_appearance()
/obj/item/organ/genital/testicles/update_size(modified = FALSE)
switch(size)
if(0.1 to 1)
if(BALLS_SIZE_MIN)
size_name = "average"
if(1.1 to 2)
if(BALLS_SIZE_DEF)
size_name = "enlarged"
if(2.1 to INFINITY)
if(BALLS_SIZE_MAX)
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."
/obj/item/organ/genital/testicles/update_appearance()
. = ..()
desc = "You see an [size_name] pair of testicles."
if(owner)
var/string
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
@@ -91,3 +55,18 @@
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
/obj/item/organ/genital/testicles/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
if(D.species.use_skintones && D.features["genitals_use_skintone"])
color = "#[skintone2hex(H.skin_tone)]"
else
color = "#[D.features["balls_color"]]"
sack_size = D.features["balls_sack_size"]
shape = D.features["balls_shape"]
if(D.features["balls_shape"] == "Hidden")
ENABLE_BITFIELD(genital_flags, GENITAL_INTERNAL)
fluid_id = D.features["balls_fluid"]
fluid_rate = D.features["balls_cum_rate"]
fluid_mult = D.features["balls_cum_mult"]
fluid_efficiency = D.features["balls_efficiency"]
@@ -1,26 +1,25 @@
/obj/item/organ/genital/vagina
name = "vagina"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon_state = "vagina"
zone = "groin"
slot = "vagina"
size = 1 //There is only 1 size right now
can_masturbate_with = TRUE
masturbation_verb = "finger"
can_climax = TRUE
name = "vagina"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon_state = ORGAN_SLOT_VAGINA
zone = BODY_ZONE_PRECISE_GROIN
slot = "vagina"
size = 1 //There is only 1 size right now
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
masturbation_verb = "finger"
fluid_transfer_factor = 0.1 //Yes, some amount is exposed to you, go get your AIDS
w_class = 3
var/cap_length = 8//D E P T H (cap = capacity)
var/cap_girth = 12
layer_index = VAGINA_LAYER_INDEX
var/cap_length = 8//D E P T H (cap = capacity)
var/cap_girth = 12
var/cap_girth_ratio = 1.5
var/clits = 1
var/clit_diam = 0.25
var/clit_len = 0.25
var/clits = 1
var/clit_diam = 0.25
var/clit_len = 0.25
var/list/vag_types = list("tentacle", "dentata", "hairy", "spade", "furred")
/obj/item/organ/genital/vagina/update_appearance()
. = ..()
var/string //Keeping this code here, so making multiple sprites for the different kinds is easier.
var/lowershape = lowertext(shape)
var/details
@@ -63,12 +62,10 @@
icon_state = sanitize_text(string)
H.update_genitals()
/obj/item/organ/genital/vagina/update_link()
if(owner)
linked_organ = (owner.getorganslot("womb"))
if(linked_organ)
linked_organ.linked_organ = src
/obj/item/organ/genital/vagina/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
if(D.species.use_skintones && D.features["genitals_use_skintone"])
color = "#[skintone2hex(H.skin_tone)]"
else
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
color = "[D.features["vag_color"]]"
shape = "[D.features["vag_shape"]]"
@@ -1,45 +1,10 @@
/obj/item/organ/genital/womb
name = "womb"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon_state = "womb"
zone = "groin"
slot = "womb"
internal = TRUE
fluid_id = "femcum"
producing = TRUE
/obj/item/organ/genital/womb/on_life()
if(QDELETED(src))
return
if(reagents && producing)
if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
fluid_rate = 0.1
else
fluid_rate = CUM_RATE
if(reagents.total_volume >= 5)
fluid_mult = 0.5
else
fluid_mult = 1
generate_femcum()
/obj/item/organ/genital/womb/proc/generate_femcum()
reagents.maximum_volume = fluid_max_volume
update_link()
if(!linked_organ)
return FALSE
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
/obj/item/organ/genital/womb/update_link()
if(owner)
linked_organ = (owner.getorganslot("vagina"))
if(linked_organ)
linked_organ.linked_organ = src
else
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
/obj/item/organ/genital/womb/Destroy()
return ..()
name = "womb"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon_state = "womb"
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_WOMB
genital_flags = GENITAL_INTERNAL|GENITAL_FUID_PRODUCTION
fluid_id = "femcum"
linked_organ_slot = ORGAN_SLOT_VAGINA
@@ -1,73 +0,0 @@
/obj/effect/mob_spawn/human/lavaknight
name = "odd cryogenics pod"
desc = "A humming cryo pod. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant."
mob_name = "a displaced knight from another dimension"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
roundstart = FALSE
job_description = "Cydonian Knight"
death = FALSE
random = TRUE
outfit = /datum/outfit/lavaknight
mob_species = /datum/species/human
flavour_text = "<font size=3><b>Y</b></font><b>ou are a knight who conveniently has some form of retrograde amnesia. \
You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \
Remember: hostile creatures and such are fair game for attacking, but <span class='danger'>under no circumstances are you to attack anything capable of thought and/or speech</span> unless it has made it its life's calling to chase you to the ends of the earth."
assignedrole = "Cydonian Knight"
/obj/effect/mob_spawn/human/lavaknight/special(mob/living/new_spawn)
if(ishuman(new_spawn))
var/mob/living/carbon/human/H = new_spawn
H.dna.features["mam_ears"] = "Cat, Big" //cat people
H.dna.features["mcolor"] = H.hair_color
H.update_body()
/obj/effect/mob_spawn/human/lavaknight/Destroy()
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
return ..()
/datum/outfit/lavaknight
name = "Cydonian Knight"
uniform = /obj/item/clothing/under/assistantformal
mask = /obj/item/clothing/mask/breath
shoes = /obj/item/clothing/shoes/sneakers/black
r_pocket = /obj/item/melee/transforming/energy/sword/cx
suit = /obj/item/clothing/suit/space/hardsuit/lavaknight
suit_store = /obj/item/tank/internals/oxygen
id = /obj/item/card/id/knight
/datum/outfit/lavaknight/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
if(visualsOnly)
return
var/obj/item/card/id/knight/W = H.wear_id
W.assignment = "Knight"
W.registered_name = H.real_name
W.id_color = "#0000FF" //Regular knights get simple blue. Doesn't matter much because it's variable anyway
W.update_label(H.real_name)
W.update_icon()
/datum/outfit/lavaknight/captain
name ="Cydonian Knight Captain"
l_pocket = /obj/item/twohanded/dualsaber/hypereutactic
/datum/outfit/lavaknight/captain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
if(visualsOnly)
return
var/obj/item/card/id/knight/W = H.wear_id
W.assignment = "Knight Captain"
W.registered_name = H.real_name
W.id_color = "#FFD700" //Captains get gold, duh. Doesn't matter because it's variable anyway
W.update_label(H.real_name)
W.update_icon()
/obj/effect/mob_spawn/human/lavaknight/captain
name = "odd gilded cryogenics pod"
desc = "A humming cryo pod that appears to be gilded. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant."
flavour_text = "<font size=3><b>Y</b></font><b>ou are a knight who conveniently has some form of retrograde amnesia. \
You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \
Remember: hostile creatures and such are fair game for attacking, but <span class='danger'>under no circumstances are you to attack anything capable of thought and/or speech</span> unless it has made it its life's calling to chase you to the ends of the earth. \
You feel a natural instict to lead, and as such, you should strive to lead your comrades to safety, and hopefully home. You also feel a burning determination to uphold your vow, as well as your fellow comrade's."
outfit = /datum/outfit/lavaknight/captain
@@ -1,11 +0,0 @@
/obj/machinery/computer/cargo
req_access = list(ACCESS_CARGO)
/obj/machinery/computer/cargo/request
req_access = list()
/obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui)
if(!allowed(usr))
to_chat(usr, "<span class='notice'>Access denied.</span>")
return
. = ..()
@@ -194,28 +194,28 @@
ckeywhitelist = list("technicalmagi")
/datum/gear/gladiator
name = "Gladiator Armor"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/under/gladiator
ckeywhitelist = list("aroche")
name = "Gladiator Armor"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/under/gladiator
ckeywhitelist = list("aroche")
/datum/gear/bloodredtie
name = "Blood Red Tie"
category = SLOT_NECK
path = /obj/item/clothing/neck/tie/bloodred
ckeywhitelist = list("kyutness")
name = "Blood Red Tie"
category = SLOT_NECK
path = /obj/item/clothing/neck/tie/bloodred
ckeywhitelist = list("kyutness")
/datum/gear/puffydress
name = "Puffy Dress"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/puffydress
ckeywhitelist = list("stallingratt")
name = "Puffy Dress"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/puffydress
ckeywhitelist = list("stallingratt")
/datum/gear/labredblack
name = "Black and Red Coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/toggle/labcoat/labredblack
ckeywhitelist = list("blakeryan", "durandalphor")
name = "Black and Red Coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/toggle/labcoat/labredblack
ckeywhitelist = list("blakeryan", "durandalphor")
/datum/gear/torisword
name = "Rainbow Zweihander"
@@ -452,3 +452,9 @@ datum/gear/darksabresheath
category = SLOT_HEAD
path = /obj/item/clothing/head/flight
ckeywhitelist = list("maxlynchy")
/datum/gear/onionneck
name = "Onion Necklace"
category = SLOT_NECK
path = /obj/item/clothing/neck/necklace/onion
ckeywhitelist = list("cdrcross")
@@ -4,6 +4,20 @@
path = /obj/item/clothing/under/color/grey
restricted_roles = list("Assistant")
/datum/gear/neetsuit
name = "D.A.B. suit"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/assu_suit
restricted_roles = list("Assistant")
cost = 2
/datum/gear/neethelm
name = "D.A.B. helmet"
category = SLOT_HEAD
path = /obj/item/clothing/head/assu_helmet
restricted_roles = list("Assistant")
cost = 2
/datum/gear/plushvar
name = "Ratvar Plushie"
category = SLOT_IN_BACKPACK
@@ -16,4 +30,4 @@
category = SLOT_IN_BACKPACK
path = /obj/item/toy/plush/narplush
cost = 5
restricted_roles = list("Chaplain")
restricted_roles = list("Chaplain")
@@ -37,3 +37,23 @@
name = "White shoes"
category = SLOT_SHOES
path = /obj/item/clothing/shoes/sneakers/white
/datum/gear/gildedcuffs
name = "Gilded leg wraps"
category = SLOT_SHOES
path= /obj/item/clothing/shoes/wraps
/datum/gear/silvercuffs
name = "Silver leg wraps"
category = SLOT_SHOES
path= /obj/item/clothing/shoes/wraps/silver
/datum/gear/redcuffs
name = "Red leg wraps"
category = SLOT_SHOES
path= /obj/item/clothing/shoes/wraps/red
/datum/gear/bluecuffs
name = "Blue leg wraps"
category = SLOT_SHOES
path= /obj/item/clothing/shoes/wraps/blue
@@ -64,6 +64,64 @@
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat
/* Commented out until it is "balanced"
/datum/gear/coat/sec
name = "Security winter coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/security
restricted_roles = list("Head of Security", "Warden", "Detective", "Security Officer") // Reserve it to the Security Departement
*/
/datum/gear/coat/med
name = "Medical winter coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/medical
restricted_roles = list("Chief Medical Officer", "Medical Doctor") // Reserve it to Medical Doctors and their boss, the Chief Medical Officer
/* Commented out until there is a Chemistry Winter Coat
/datum/gear/coat/med/chem
name = "Chemistry winter coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/medical/chemistry
restricted_roles = list("Chief Medical Officer", "Chemist") // Reserve it to Chemists and their boss, the Chief Medical Officer
*/
/datum/gear/coat/sci
name = "Science winter coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/science
restricted_roles = list("Research Director", "Scientist", "Roboticist") // Reserve it to the Science Departement
/datum/gear/coat/eng
name = "Engineering winter coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/engineering
restricted_roles = list("Chief Engineer", "Station Engineer") // Reserve it to Station Engineers and their boss, the Chief Engineer
/datum/gear/coat/eng/atmos
name = "Atmospherics winter coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos
restricted_roles = list("Chief Engineer", "Atmospheric Technician") // Reserve it to Atmos Techs and their boss, the Chief Engineer
/datum/gear/coat/hydro
name = "Hydroponics winter coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/hydro
restricted_roles = list("Head of Personnel", "Botanist") // Reserve it to Botanists and their boss, the Head of Personnel
/datum/gear/coat/cargo
name = "Cargo winter coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/cargo
restricted_roles = list("Quartermaster", "Cargo Technician") // Reserve it to Cargo Techs and their boss, the Quartermaster
/datum/gear/coat/miner
name = "Mining winter coat"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat/miner
restricted_roles = list("Quartermaster", "Shaft Miner") // Reserve it to Miners and their boss, the Quartermaster
/datum/gear/militaryjacket
name = "Military Jacket"
category = SLOT_WEAR_SUIT
@@ -32,7 +32,6 @@
WRITE_FILE(S["feature_ipc_antenna"], features["ipc_antenna"])
//Citadel
WRITE_FILE(S["feature_genitals_use_skintone"], features["genitals_use_skintone"])
WRITE_FILE(S["feature_exhibitionist"], features["exhibitionist"])
WRITE_FILE(S["feature_mcolor2"], features["mcolor2"])
WRITE_FILE(S["feature_mcolor3"], features["mcolor3"])
WRITE_FILE(S["feature_mam_body_markings"], features["mam_body_markings"])
@@ -6,41 +6,39 @@
icon_state = "s-ninja"
item_state = "s-ninja"
/obj/item/clothing/glasses/phantomthief/Initialize()
/obj/item/clothing/glasses/phantomthief/ComponentInitialize()
. = ..()
AddComponent(/datum/component/phantomthief)
AddComponent(/datum/component/wearertargeting/phantomthief)
/obj/item/clothing/glasses/phantomthief/syndicate
name = "suspicious plastic mask"
desc = "A cheap, bulky, Syndicate-branded plastic face mask. You have to break in to break out."
var/nextadrenalinepop
var/datum/component/redirect/combattoggle_redir
/obj/item/clothing/glasses/phantomthief/syndicate/examine(user)
/obj/item/clothing/glasses/phantomthief/syndicate/examine(mob/user)
. = ..()
if(combattoggle_redir)
if(user.get_item_by_slot(SLOT_GLASSES) == src)
if(world.time >= nextadrenalinepop)
to_chat(user, "<span class='notice'>The built-in adrenaline injector is ready for use.</span>")
else
to_chat(user, "<span class='notice'>[DisplayTimeText(nextadrenalinepop - world.time)] left before the adrenaline injector can be used again.")
/obj/item/clothing/glasses/phantomthief/syndicate/proc/injectadrenaline(mob/user, combatmodestate)
if(istype(user))
if(combatmodestate && world.time >= nextadrenalinepop)
nextadrenalinepop = world.time + 5 MINUTES
user.reagents.add_reagent("syndicateadrenals", 5)
user.playsound_local(user, 'modular_citadel/sound/misc/adrenalinject.ogg', 100, 0, pressure_affected = FALSE)
if(istype(user) && combatmodestate && world.time >= nextadrenalinepop)
nextadrenalinepop = world.time + 5 MINUTES
user.reagents.add_reagent("syndicateadrenals", 5)
user.playsound_local(user, 'sound/misc/adrenalinject.ogg', 100, 0, pressure_affected = FALSE)
/obj/item/clothing/glasses/phantomthief/syndicate/equipped(mob/user, slot)
. = ..()
if(!istype(user))
return
if(!combattoggle_redir)
combattoggle_redir = user.AddComponent(/datum/component/redirect, list(COMSIG_COMBAT_TOGGLED = CALLBACK(src, .proc/injectadrenaline)))
if(slot != SLOT_GLASSES)
return
RegisterSignal(user, COMSIG_COMBAT_TOGGLED, .proc/injectadrenaline)
/obj/item/clothing/glasses/phantomthief/syndicate/dropped(mob/user)
. = ..()
if(!istype(user))
return
if(combattoggle_redir)
QDEL_NULL(combattoggle_redir)
UnregisterSignal(user, COMSIG_COMBAT_TOGGLED)
@@ -15,7 +15,7 @@
/datum/action/item_action/zanderlocket/Trigger()
new/obj/effect/temp_visual/souldeath(owner.loc, owner)
playsound(owner, 'modular_citadel/sound/misc/souldeath.ogg', 100, FALSE)
playsound(owner, 'sound/misc/souldeath.ogg', 100, FALSE)
/obj/item/clothing/neck/undertale/Initialize()
@@ -1,176 +0,0 @@
/*
CYDONIAN ARMOR THAT IS RGB AND STUFF WOOOOOOOOOO
*/
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight
name = "cydonian helmet"
desc = "A helmet designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
icon = 'modular_citadel/icons/lavaknight/item/head.dmi'
icon_state = "knight_cydonia"
item_state = "knight_yellow"
item_color = null
alternate_worn_icon = 'modular_citadel/icons/lavaknight/mob/head.dmi'
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | LAVA_PROOF
heat_protection = HEAD
armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
brightness_on = 7
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator)
var/energy_color = "#35FFF0"
var/obj/item/clothing/suit/space/hardsuit/lavaknight/linkedsuit = null
mutantrace_variation = NO_MUTANTRACE_VARIATION
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/New()
..()
if(istype(loc, /obj/item/clothing/suit/space/hardsuit/lavaknight))
linkedsuit = loc
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/attack_self(mob/user)
on = !on
if(on)
set_light(brightness_on)
else
set_light(0)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/update_icon()
var/mutable_appearance/helm_overlay = mutable_appearance('modular_citadel/icons/lavaknight/item/head.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
if(energy_color)
helm_overlay.color = energy_color
helm_overlay.plane = LIGHTING_PLANE + 1 //Magic number is used here because we have no ABOVE_LIGHTING_PLANE plane defined. Lighting plane is 15, HUD is 18
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(helm_overlay)
emissivelights()
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/equipped(mob/user, slot)
..()
if(slot == SLOT_HEAD)
emissivelights()
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/dropped(mob/user)
..()
emissivelightsoff()
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/proc/emissivelights(mob/user = usr)
var/mutable_appearance/energy_overlay = mutable_appearance('modular_citadel/icons/lavaknight/mob/head.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
energy_overlay.color = energy_color
energy_overlay.plane = LIGHTING_PLANE + 1
user.cut_overlay(energy_overlay) //honk
user.add_overlay(energy_overlay) //honk
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/proc/emissivelightsoff(mob/user = usr)
user.cut_overlay()
linkedsuit.emissivelights() //HONK HONK HONK MAXIMUM SPAGHETTI
user.regenerate_icons() //honk
/obj/item/clothing/suit/space/hardsuit/lavaknight
icon = 'modular_citadel/icons/lavaknight/item/suit.dmi'
icon_state = "knight_cydonia"
name = "cydonian armor"
desc = "A suit designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
item_state = "swat_suit"
alternate_worn_icon = 'modular_citadel/icons/lavaknight/mob/suit.dmi'
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | LAVA_PROOF
armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/lavaknight
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
actions_types = list(/datum/action/item_action/toggle_helmet)
var/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/linkedhelm
tauric = TRUE //Citadel Add for tauric hardsuits
var/energy_color = "#35FFF0"
/obj/item/clothing/suit/space/hardsuit/lavaknight/New()
..()
if(helmet)
linkedhelm = helmet
light_color = energy_color
set_light(1)
/obj/item/clothing/suit/space/hardsuit/lavaknight/Initialize()
..()
update_icon()
/obj/item/clothing/suit/space/hardsuit/lavaknight/update_icon()
var/mutable_appearance/suit_overlay
if(taurmode == SNEK_TAURIC)
suit_overlay = mutable_appearance('modular_citadel/icons/mob/taur_naga.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
else if(taurmode == PAW_TAURIC)
suit_overlay = mutable_appearance('modular_citadel/icons/mob/taur_canine.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
else
suit_overlay = mutable_appearance('modular_citadel/icons/lavaknight/item/suit.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
if(energy_color)
suit_overlay.color = energy_color
suit_overlay.plane = LIGHTING_PLANE + 1 //Magic number is used here because we have no ABOVE_LIGHTING_PLANE plane defined. Lighting plane is 15.
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(suit_overlay)
/obj/item/clothing/suit/space/hardsuit/lavaknight/equipped(mob/user, slot)
..()
if(slot == SLOT_WEAR_SUIT)
emissivelights()
/obj/item/clothing/suit/space/hardsuit/lavaknight/dropped(mob/user)
..()
emissivelightsoff()
/obj/item/clothing/suit/space/hardsuit/lavaknight/proc/emissivelights(mob/user = usr)
var/mutable_appearance/energy_overlay
if(taurmode == SNEK_TAURIC)
energy_overlay = mutable_appearance('modular_citadel/icons/mob/taur_naga.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
else if(taurmode == PAW_TAURIC)
energy_overlay = mutable_appearance('modular_citadel/icons/mob/taur_canine.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
else
energy_overlay = mutable_appearance('modular_citadel/icons/lavaknight/mob/suit.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
energy_overlay.color = energy_color
energy_overlay.plane = LIGHTING_PLANE + 1
user.cut_overlay(energy_overlay) //honk
user.add_overlay(energy_overlay) //honk
/obj/item/clothing/suit/space/hardsuit/lavaknight/proc/emissivelightsoff(mob/user = usr)
user.cut_overlays()
user.regenerate_icons() //honk
/obj/item/clothing/suit/space/hardsuit/lavaknight/AltClick(mob/living/user)
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(!in_range(src, user))
return
if(user.incapacitated() || !istype(user) || !in_range(src, user))
return
if(alert("Are you sure you want to recolor your armor stripes?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"","Choose Energy Color",energy_color) as color|null
if(energy_color_input)
energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
user.update_inv_wear_suit()
if(linkedhelm)
linkedhelm.energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
user.update_inv_head()
linkedhelm.update_icon()
update_icon()
user.update_inv_wear_suit()
light_color = energy_color
emissivelights()
update_light()
/obj/item/clothing/suit/space/hardsuit/lavaknight/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
@@ -501,3 +501,11 @@
item_state = "flight-g"
icon = 'icons/obj/custom.dmi'
alternate_worn_icon = 'icons/mob/custom_w.dmi'
/obj/item/clothing/neck/necklace/onion
name = "Onion Necklace"
desc = "A string of onions sequenced together to form a necklace."
icon = 'icons/obj/custom.dmi'
icon_state = "onion"
item_state = "onion"
alternate_worn_icon = 'icons/mob/custom_w.dmi'
@@ -1,2 +0,0 @@
/datum/round_event_control/blob
earliest_start = 60 MINUTES
@@ -1,2 +0,0 @@
/mob/living/simple_animal/hostile/carp/ranged
gold_core_spawnable = NO_SPAWN
@@ -1,8 +0,0 @@
//This file controls whether or not a job complies with dresscodes.
//If a job complies with dresscodes, loadout items will not be equipped instead of the job's outfit, instead placing the items into the player's backpack.
/datum/job
var/dresscodecompliant = TRUE
/datum/job/assistant
dresscodecompliant = FALSE
@@ -1,21 +0,0 @@
/datum/job/captain
minimal_player_age = 20
exp_type = EXP_TYPE_COMMAND
/datum/job/hop
minimal_player_age = 20
exp_type_department = EXP_TYPE_SERVICE
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER,
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER,
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM)
@@ -1,31 +0,0 @@
/datum/job/bartender
access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_BAR, ACCESS_MINERAL_STOREROOM)
/datum/job/qm
department_head = list("Captain")
supervisors = "the captain"
req_admin_notify = 1
minimal_player_age = 10
exp_requirements = 180
exp_type_department = EXP_TYPE_SUPPLY
access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE, ACCESS_SEC_DOORS, ACCESS_HEADS)
minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE, ACCESS_SEC_DOORS, ACCESS_HEADS)
/datum/outfit/job/quartermaster
id = /obj/item/card/id/silver
ears = /obj/item/radio/headset/heads/qm
backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/modular_computer/tablet/preset/advanced = 1)
/datum/job/cargo_tech
department_head = list("Quartermaster")
supervisors = "the quartermaster"
access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
/datum/job/mining
department_head = list("Quartermaster")
supervisors = "the quartermaster"
access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
@@ -1,14 +0,0 @@
/datum/job/chief_engineer
minimal_player_age = 10
/datum/job/engineer
access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS,
ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS,
ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM)
/datum/job/atmos
access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS,
ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_ENGINE,
ACCESS_ENGINE_EQUIP, ACCESS_EMERGENCY_STORAGE, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM)
@@ -1,8 +0,0 @@
/datum/job/cmo
minimal_player_age = 10
/datum/outfit/job/doctor
backpack_contents = list(/obj/item/storage/hypospraykit/regular)
/datum/outfit/job/chemist
backpack_contents = list(/obj/item/storage/hypospraykit/regular)
@@ -1,2 +0,0 @@
/datum/job/rd
minimal_player_age = 10
@@ -1,5 +0,0 @@
/datum/job/hos
minimal_player_age = 10
/datum/outfit/job/warden
suit_store = /obj/item/gun/energy/pumpaction/defender
@@ -1,6 +0,0 @@
/mob/living/carbon/key_down(_key, client/user)
switch(_key)
if("C")
toggle_combat_mode()
return
return ..()
@@ -1,13 +0,0 @@
/mob/living/carbon/human/key_down(_key, client/user)
switch(_key)
if("Shift")
sprint_hotkey(TRUE)
return
return ..()
/mob/living/carbon/human/key_up(_key, client/user)
switch(_key)
if("Shift")
sprint_hotkey(FALSE)
return
return ..()
@@ -1,13 +0,0 @@
/mob/living/silicon/robot/key_down(_key, client/user)
switch(_key)
if("Shift")
sprint_hotkey(TRUE)
return
return ..()
/mob/living/silicon/robot/key_up(_key, client/user)
switch(_key)
if("Shift")
sprint_hotkey(FALSE)
return
return ..()
@@ -1,8 +1,8 @@
GLOBAL_PROTECT(mentor_verbs)
GLOBAL_LIST_INIT(mentor_verbs, list(
/client/proc/cmd_mentor_say,
/client/proc/show_mentor_memo
))
GLOBAL_PROTECT(mentor_verbs)
/client/proc/add_mentor_verbs()
if(mentor_datum)
@@ -1,26 +0,0 @@
/datum/map_template/ruin/lavaland/alien_nest
name = "Alien Nest"
id = "alien-nest"
description = "Not even Necropolis is safe from alien infestation. The competition for hosts has locked the legion and aliens in an endless conflict that can only be resolved by a PKA."
suffix = "lavaland_surface_alien_nest.dmm"
cost = 20
//Aliens for the alien nest space ruin.
/obj/effect/mob_spawn/alien/corpse/humanoid/drone
mob_type = /mob/living/carbon/alien/humanoid/drone
death = TRUE
name = "alien drone"
mob_name = "alien drone"
/obj/effect/mob_spawn/alien/corpse/humanoid/queen
mob_type = /mob/living/carbon/alien/humanoid/royal/queen
death = TRUE
name = "alien queen"
mob_name = "alien queen"
/obj/item/reagent_containers/syringe/alien
name = "Hive's Blessing"
desc = "A syringe filled with a strange viscous liquid. It might be best to leave it alone."
amount_per_transfer_from_this = 1
volume = 1
list_reagents = list("xenomicrobes" = 1)
@@ -18,16 +18,20 @@
return FALSE
return .
/mob/living/carbon/proc/toggle_combat_mode()
/mob/living/carbon/proc/toggle_combat_mode(forced)
if(recoveringstam)
return TRUE
if(!forced)
for(var/datum/status_effect/S in status_effects)
if(S.blocks_combatmode)
return TRUE
combatmode = !combatmode
if(voremode)
toggle_vore_mode()
if(combatmode)
playsound_local(src, 'modular_citadel/sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
playsound_local(src, 'sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
else
playsound_local(src, 'modular_citadel/sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
playsound_local(src, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
if(client)
client.show_popup_menus = !combatmode // So we can right-click for alternate actions and all that other good shit. Also moves examine to shift+rightclick to make it possible to attack while sprinting
if(hud_used && hud_used.static_inventory)
@@ -1,12 +1,3 @@
/mob/living/carbon/human/species/mammal
race = /datum/species/mammal
/mob/living/carbon/human/species/insect
race = /datum/species/insect
/mob/living/carbon/human/species/xeno
race = /datum/species/xeno
/mob/living/proc/resist_embedded()
return
@@ -24,9 +24,9 @@
sprinting = !sprinting
if(!resting && m_intent == MOVE_INTENT_RUN && canmove)
if(sprinting)
playsound_local(src, 'modular_citadel/sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
playsound_local(src, 'sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
else
playsound_local(src, 'modular_citadel/sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
playsound_local(src, '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)
selector.insert_witty_toggle_joke_here(src)
@@ -13,7 +13,7 @@
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.
var/sprint_stamina_cost = 0.70 //stamina loss per tile while insufficient sprint buffer.
//---End
/mob/living/movement_delay(ignorewalk = 0)
@@ -116,7 +116,7 @@
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
resting = TRUE
if(combatmode)
toggle_combat_mode()
toggle_combat_mode(TRUE)
recoveringstam = TRUE
filters += CIT_FILTER_STAMINACRIT
update_canmove()
@@ -1,633 +0,0 @@
// List is required to compile the resources into the game when it loads.
// Dynamically loading it has bad results with sounds overtaking each other, even with the wait variable.
#ifdef AI_VOX
GLOBAL_LIST_INIT(vox_sounds_male, list("," = 'modular_citadel/sound/vox/_comma.ogg',
"." = 'modular_citadel/sound/vox/_period.ogg',
"a" = 'modular_citadel/sound/vox/a.ogg',
"accelerating" = 'modular_citadel/sound/vox/accelerating.ogg',
"accelerator" = 'modular_citadel/sound/vox/accelerator.ogg',
"accepted" = 'modular_citadel/sound/vox/accepted.ogg',
"access" = 'modular_citadel/sound/vox/access.ogg',
"acknowledge" = 'modular_citadel/sound/vox/acknowledge.ogg',
"acknowledged" = 'modular_citadel/sound/vox/acknowledged.ogg',
"acquired" = 'modular_citadel/sound/vox/acquired.ogg',
"acquisition" = 'modular_citadel/sound/vox/acquisition.ogg',
"across" = 'modular_citadel/sound/vox/across.ogg',
"activate" = 'modular_citadel/sound/vox/activate.ogg',
"activated" = 'modular_citadel/sound/vox/activated.ogg',
"activity" = 'modular_citadel/sound/vox/activity.ogg',
"adios" = 'modular_citadel/sound/vox/adios.ogg',
"administration" = 'modular_citadel/sound/vox/administration.ogg',
"advanced" = 'modular_citadel/sound/vox/advanced.ogg',
"after" = 'modular_citadel/sound/vox/after.ogg',
"agent" = 'modular_citadel/sound/vox/agent.ogg',
"alarm" = 'modular_citadel/sound/vox/alarm.ogg',
"alert" = 'modular_citadel/sound/vox/alert.ogg',
"alien" = 'modular_citadel/sound/vox/alien.ogg',
"aligned" = 'modular_citadel/sound/vox/aligned.ogg',
"all" = 'modular_citadel/sound/vox/all.ogg',
"alpha" = 'modular_citadel/sound/vox/alpha.ogg',
"am" = 'modular_citadel/sound/vox/am.ogg',
"amigo" = 'modular_citadel/sound/vox/amigo.ogg',
"ammunition" = 'modular_citadel/sound/vox/ammunition.ogg',
"an" = 'modular_citadel/sound/vox/an.ogg',
"and" = 'modular_citadel/sound/vox/and.ogg',
"announcement" = 'modular_citadel/sound/vox/announcement.ogg',
"anomalous" = 'modular_citadel/sound/vox/anomalous.ogg',
"antenna" = 'modular_citadel/sound/vox/antenna.ogg',
"any" = 'modular_citadel/sound/vox/any.ogg',
"apprehend" = 'modular_citadel/sound/vox/apprehend.ogg',
"approach" = 'modular_citadel/sound/vox/approach.ogg',
"are" = 'modular_citadel/sound/vox/are.ogg',
"area" = 'modular_citadel/sound/vox/area.ogg',
"arm" = 'modular_citadel/sound/vox/arm.ogg',
"armed" = 'modular_citadel/sound/vox/armed.ogg',
"armor" = 'modular_citadel/sound/vox/armor.ogg',
"armory" = 'modular_citadel/sound/vox/armory.ogg',
"arrest" = 'modular_citadel/sound/vox/arrest.ogg',
"ass" = 'modular_citadel/sound/vox/ass.ogg',
"at" = 'modular_citadel/sound/vox/at.ogg',
"atomic" = 'modular_citadel/sound/vox/atomic.ogg',
"attention" = 'modular_citadel/sound/vox/attention.ogg',
"authorize" = 'modular_citadel/sound/vox/authorize.ogg',
"authorized" = 'modular_citadel/sound/vox/authorized.ogg',
"automatic" = 'modular_citadel/sound/vox/automatic.ogg',
"away" = 'modular_citadel/sound/vox/away.ogg',
"b" = 'modular_citadel/sound/vox/b.ogg',
"back" = 'modular_citadel/sound/vox/back.ogg',
"backman" = 'modular_citadel/sound/vox/backman.ogg',
"bad" = 'modular_citadel/sound/vox/bad.ogg',
"bag" = 'modular_citadel/sound/vox/bag.ogg',
"bailey" = 'modular_citadel/sound/vox/bailey.ogg',
"barracks" = 'modular_citadel/sound/vox/barracks.ogg',
"base" = 'modular_citadel/sound/vox/base.ogg',
"bay" = 'modular_citadel/sound/vox/bay.ogg',
"be" = 'modular_citadel/sound/vox/be.ogg',
"been" = 'modular_citadel/sound/vox/been.ogg',
"before" = 'modular_citadel/sound/vox/before.ogg',
"beyond" = 'modular_citadel/sound/vox/beyond.ogg',
"biohazard" = 'modular_citadel/sound/vox/biohazard.ogg',
"biological" = 'modular_citadel/sound/vox/biological.ogg',
"birdwell" = 'modular_citadel/sound/vox/birdwell.ogg',
"bizwarn" = 'modular_citadel/sound/vox/bizwarn.ogg',
"black" = 'modular_citadel/sound/vox/black.ogg',
"blast" = 'modular_citadel/sound/vox/blast.ogg',
"blocked" = 'modular_citadel/sound/vox/blocked.ogg',
"bloop" = 'modular_citadel/sound/vox/bloop.ogg',
"blue" = 'modular_citadel/sound/vox/blue.ogg',
"bottom" = 'modular_citadel/sound/vox/bottom.ogg',
"bravo" = 'modular_citadel/sound/vox/bravo.ogg',
"breach" = 'modular_citadel/sound/vox/breach.ogg',
"breached" = 'modular_citadel/sound/vox/breached.ogg',
"break" = 'modular_citadel/sound/vox/break.ogg',
"bridge" = 'modular_citadel/sound/vox/bridge.ogg',
"bust" = 'modular_citadel/sound/vox/bust.ogg',
"but" = 'modular_citadel/sound/vox/but.ogg',
"button" = 'modular_citadel/sound/vox/button.ogg',
"buzwarn" = 'modular_citadel/sound/vox/buzwarn.ogg',
"bypass" = 'modular_citadel/sound/vox/bypass.ogg',
"c" = 'modular_citadel/sound/vox/c.ogg',
"cable" = 'modular_citadel/sound/vox/cable.ogg',
"call" = 'modular_citadel/sound/vox/call.ogg',
"called" = 'modular_citadel/sound/vox/called.ogg',
"canal" = 'modular_citadel/sound/vox/canal.ogg',
"cap" = 'modular_citadel/sound/vox/cap.ogg',
"captain" = 'modular_citadel/sound/vox/captain.ogg',
"capture" = 'modular_citadel/sound/vox/capture.ogg',
"captured" = 'modular_citadel/sound/vox/captured.ogg',
"ceiling" = 'modular_citadel/sound/vox/ceiling.ogg',
"celsius" = 'modular_citadel/sound/vox/celsius.ogg',
"center" = 'modular_citadel/sound/vox/center.ogg',
"centi" = 'modular_citadel/sound/vox/centi.ogg',
"central" = 'modular_citadel/sound/vox/central.ogg',
"chamber" = 'modular_citadel/sound/vox/chamber.ogg',
"charlie" = 'modular_citadel/sound/vox/charlie.ogg',
"check" = 'modular_citadel/sound/vox/check.ogg',
"checkpoint" = 'modular_citadel/sound/vox/checkpoint.ogg',
"chemical" = 'modular_citadel/sound/vox/chemical.ogg',
"cleanup" = 'modular_citadel/sound/vox/cleanup.ogg',
"clear" = 'modular_citadel/sound/vox/clear.ogg',
"clearance" = 'modular_citadel/sound/vox/clearance.ogg',
"close" = 'modular_citadel/sound/vox/close.ogg',
"clown" = 'modular_citadel/sound/vox/clown.ogg',
"code" = 'modular_citadel/sound/vox/code.ogg',
"coded" = 'modular_citadel/sound/vox/coded.ogg',
"collider" = 'modular_citadel/sound/vox/collider.ogg',
"command" = 'modular_citadel/sound/vox/command.ogg',
"communication" = 'modular_citadel/sound/vox/communication.ogg',
"complex" = 'modular_citadel/sound/vox/complex.ogg',
"computer" = 'modular_citadel/sound/vox/computer.ogg',
"condition" = 'modular_citadel/sound/vox/condition.ogg',
"containment" = 'modular_citadel/sound/vox/containment.ogg',
"contamination" = 'modular_citadel/sound/vox/contamination.ogg',
"control" = 'modular_citadel/sound/vox/control.ogg',
"coolant" = 'modular_citadel/sound/vox/coolant.ogg',
"coomer" = 'modular_citadel/sound/vox/coomer.ogg',
"core" = 'modular_citadel/sound/vox/core.ogg',
"correct" = 'modular_citadel/sound/vox/correct.ogg',
"corridor" = 'modular_citadel/sound/vox/corridor.ogg',
"crew" = 'modular_citadel/sound/vox/crew.ogg',
"cross" = 'modular_citadel/sound/vox/cross.ogg',
"cryogenic" = 'modular_citadel/sound/vox/cryogenic.ogg',
"d" = 'modular_citadel/sound/vox/d.ogg',
"dadeda" = 'modular_citadel/sound/vox/dadeda.ogg',
"damage" = 'modular_citadel/sound/vox/damage.ogg',
"damaged" = 'modular_citadel/sound/vox/damaged.ogg',
"danger" = 'modular_citadel/sound/vox/danger.ogg',
"day" = 'modular_citadel/sound/vox/day.ogg',
"deactivated" = 'modular_citadel/sound/vox/deactivated.ogg',
"decompression" = 'modular_citadel/sound/vox/decompression.ogg',
"decontamination" = 'modular_citadel/sound/vox/decontamination.ogg',
"deeoo" = 'modular_citadel/sound/vox/deeoo.ogg',
"defense" = 'modular_citadel/sound/vox/defense.ogg',
"degrees" = 'modular_citadel/sound/vox/degrees.ogg',
"delta" = 'modular_citadel/sound/vox/delta.ogg',
"denied" = 'modular_citadel/sound/vox/denied.ogg',
"deploy" = 'modular_citadel/sound/vox/deploy.ogg',
"deployed" = 'modular_citadel/sound/vox/deployed.ogg',
"destroy" = 'modular_citadel/sound/vox/destroy.ogg',
"destroyed" = 'modular_citadel/sound/vox/destroyed.ogg',
"detain" = 'modular_citadel/sound/vox/detain.ogg',
"detected" = 'modular_citadel/sound/vox/detected.ogg',
"detonation" = 'modular_citadel/sound/vox/detonation.ogg',
"device" = 'modular_citadel/sound/vox/device.ogg',
"did" = 'modular_citadel/sound/vox/did.ogg',
"die" = 'modular_citadel/sound/vox/die.ogg',
"dimensional" = 'modular_citadel/sound/vox/dimensional.ogg',
"dirt" = 'modular_citadel/sound/vox/dirt.ogg',
"disengaged" = 'modular_citadel/sound/vox/disengaged.ogg',
"dish" = 'modular_citadel/sound/vox/dish.ogg',
"disposal" = 'modular_citadel/sound/vox/disposal.ogg',
"distance" = 'modular_citadel/sound/vox/distance.ogg',
"distortion" = 'modular_citadel/sound/vox/distortion.ogg',
"do" = 'modular_citadel/sound/vox/do.ogg',
"doctor" = 'modular_citadel/sound/vox/doctor.ogg',
"doop" = 'modular_citadel/sound/vox/doop.ogg',
"door" = 'modular_citadel/sound/vox/door.ogg',
"down" = 'modular_citadel/sound/vox/down.ogg',
"dual" = 'modular_citadel/sound/vox/dual.ogg',
"duct" = 'modular_citadel/sound/vox/duct.ogg',
"e" = 'modular_citadel/sound/vox/e.ogg',
"east" = 'modular_citadel/sound/vox/east.ogg',
"echo" = 'modular_citadel/sound/vox/echo.ogg',
"ed" = 'modular_citadel/sound/vox/ed.ogg',
"effect" = 'modular_citadel/sound/vox/effect.ogg',
"egress" = 'modular_citadel/sound/vox/egress.ogg',
"eight" = 'modular_citadel/sound/vox/eight.ogg',
"eighteen" = 'modular_citadel/sound/vox/eighteen.ogg',
"eighty" = 'modular_citadel/sound/vox/eighty.ogg',
"electric" = 'modular_citadel/sound/vox/electric.ogg',
"electromagnetic" = 'modular_citadel/sound/vox/electromagnetic.ogg',
"elevator" = 'modular_citadel/sound/vox/elevator.ogg',
"eleven" = 'modular_citadel/sound/vox/eleven.ogg',
"eliminate" = 'modular_citadel/sound/vox/eliminate.ogg',
"emergency" = 'modular_citadel/sound/vox/emergency.ogg',
"enemy" = 'modular_citadel/sound/vox/enemy.ogg',
"energy" = 'modular_citadel/sound/vox/energy.ogg',
"engage" = 'modular_citadel/sound/vox/engage.ogg',
"engaged" = 'modular_citadel/sound/vox/engaged.ogg',
"engine" = 'modular_citadel/sound/vox/engine.ogg',
"enter" = 'modular_citadel/sound/vox/enter.ogg',
"entry" = 'modular_citadel/sound/vox/entry.ogg',
"environment" = 'modular_citadel/sound/vox/environment.ogg',
"error" = 'modular_citadel/sound/vox/error.ogg',
"escape" = 'modular_citadel/sound/vox/escape.ogg',
"evacuate" = 'modular_citadel/sound/vox/evacuate.ogg',
"exchange" = 'modular_citadel/sound/vox/exchange.ogg',
"exit" = 'modular_citadel/sound/vox/exit.ogg',
"expect" = 'modular_citadel/sound/vox/expect.ogg',
"experiment" = 'modular_citadel/sound/vox/experiment.ogg',
"experimental" = 'modular_citadel/sound/vox/experimental.ogg',
"explode" = 'modular_citadel/sound/vox/explode.ogg',
"explosion" = 'modular_citadel/sound/vox/explosion.ogg',
"exposure" = 'modular_citadel/sound/vox/exposure.ogg',
"exterminate" = 'modular_citadel/sound/vox/exterminate.ogg',
"extinguish" = 'modular_citadel/sound/vox/extinguish.ogg',
"extinguisher" = 'modular_citadel/sound/vox/extinguisher.ogg',
"extreme" = 'modular_citadel/sound/vox/extreme.ogg',
"f" = 'modular_citadel/sound/vox/f.ogg',
"face" = 'modular_citadel/sound/vox/face.ogg',
"facility" = 'modular_citadel/sound/vox/facility.ogg',
"fahrenheit" = 'modular_citadel/sound/vox/fahrenheit.ogg',
"failed" = 'modular_citadel/sound/vox/failed.ogg',
"failure" = 'modular_citadel/sound/vox/failure.ogg',
"farthest" = 'modular_citadel/sound/vox/farthest.ogg',
"fast" = 'modular_citadel/sound/vox/fast.ogg',
"feet" = 'modular_citadel/sound/vox/feet.ogg',
"field" = 'modular_citadel/sound/vox/field.ogg',
"fifteen" = 'modular_citadel/sound/vox/fifteen.ogg',
"fifth" = 'modular_citadel/sound/vox/fifth.ogg',
"fifty" = 'modular_citadel/sound/vox/fifty.ogg',
"final" = 'modular_citadel/sound/vox/final.ogg',
"fine" = 'modular_citadel/sound/vox/fine.ogg',
"fire" = 'modular_citadel/sound/vox/fire.ogg',
"first" = 'modular_citadel/sound/vox/first.ogg',
"five" = 'modular_citadel/sound/vox/five.ogg',
"flag" = 'modular_citadel/sound/vox/flag.ogg',
"flooding" = 'modular_citadel/sound/vox/flooding.ogg',
"floor" = 'modular_citadel/sound/vox/floor.ogg',
"fool" = 'modular_citadel/sound/vox/fool.ogg',
"for" = 'modular_citadel/sound/vox/for.ogg',
"forbidden" = 'modular_citadel/sound/vox/forbidden.ogg',
"force" = 'modular_citadel/sound/vox/force.ogg',
"forms" = 'modular_citadel/sound/vox/forms.ogg',
"found" = 'modular_citadel/sound/vox/found.ogg',
"four" = 'modular_citadel/sound/vox/four.ogg',
"fourteen" = 'modular_citadel/sound/vox/fourteen.ogg',
"fourth" = 'modular_citadel/sound/vox/fourth.ogg',
"fourty" = 'modular_citadel/sound/vox/fourty.ogg',
"foxtrot" = 'modular_citadel/sound/vox/foxtrot.ogg',
"freeman" = 'modular_citadel/sound/vox/freeman.ogg',
"freezer" = 'modular_citadel/sound/vox/freezer.ogg',
"from" = 'modular_citadel/sound/vox/from.ogg',
"front" = 'modular_citadel/sound/vox/front.ogg',
"fuel" = 'modular_citadel/sound/vox/fuel.ogg',
"g" = 'modular_citadel/sound/vox/g.ogg',
"gay" = 'modular_citadel/sound/vox/gay.ogg',
"get" = 'modular_citadel/sound/vox/get.ogg',
"go" = 'modular_citadel/sound/vox/go.ogg',
"going" = 'modular_citadel/sound/vox/going.ogg',
"good" = 'modular_citadel/sound/vox/good.ogg',
"goodbye" = 'modular_citadel/sound/vox/goodbye.ogg',
"gordon" = 'modular_citadel/sound/vox/gordon.ogg',
"got" = 'modular_citadel/sound/vox/got.ogg',
"government" = 'modular_citadel/sound/vox/government.ogg',
"granted" = 'modular_citadel/sound/vox/granted.ogg',
"great" = 'modular_citadel/sound/vox/great.ogg',
"green" = 'modular_citadel/sound/vox/green.ogg',
"grenade" = 'modular_citadel/sound/vox/grenade.ogg',
"guard" = 'modular_citadel/sound/vox/guard.ogg',
"gulf" = 'modular_citadel/sound/vox/gulf.ogg',
"gun" = 'modular_citadel/sound/vox/gun.ogg',
"guthrie" = 'modular_citadel/sound/vox/guthrie.ogg',
"handling" = 'modular_citadel/sound/vox/handling.ogg',
"hangar" = 'modular_citadel/sound/vox/hangar.ogg',
"has" = 'modular_citadel/sound/vox/has.ogg',
"have" = 'modular_citadel/sound/vox/have.ogg',
"hazard" = 'modular_citadel/sound/vox/hazard.ogg',
"head" = 'modular_citadel/sound/vox/head.ogg',
"health" = 'modular_citadel/sound/vox/health.ogg',
"heat" = 'modular_citadel/sound/vox/heat.ogg',
"helicopter" = 'modular_citadel/sound/vox/helicopter.ogg',
"helium" = 'modular_citadel/sound/vox/helium.ogg',
"hello" = 'modular_citadel/sound/vox/hello.ogg',
"help" = 'modular_citadel/sound/vox/help.ogg',
"here" = 'modular_citadel/sound/vox/here.ogg',
"hide" = 'modular_citadel/sound/vox/hide.ogg',
"high" = 'modular_citadel/sound/vox/high.ogg',
"highest" = 'modular_citadel/sound/vox/highest.ogg',
"hit" = 'modular_citadel/sound/vox/hit.ogg',
"holds" = 'modular_citadel/sound/vox/holds.ogg',
"hole" = 'modular_citadel/sound/vox/hole.ogg',
"hostile" = 'modular_citadel/sound/vox/hostile.ogg',
"hot" = 'modular_citadel/sound/vox/hot.ogg',
"hotel" = 'modular_citadel/sound/vox/hotel.ogg',
"hour" = 'modular_citadel/sound/vox/hour.ogg',
"hours" = 'modular_citadel/sound/vox/hours.ogg',
"hundred" = 'modular_citadel/sound/vox/hundred.ogg',
"hydro" = 'modular_citadel/sound/vox/hydro.ogg',
"i" = 'modular_citadel/sound/vox/i.ogg',
"idiot" = 'modular_citadel/sound/vox/idiot.ogg',
"illegal" = 'modular_citadel/sound/vox/illegal.ogg',
"immediate" = 'modular_citadel/sound/vox/immediate.ogg',
"immediately" = 'modular_citadel/sound/vox/immediately.ogg',
"in" = 'modular_citadel/sound/vox/in.ogg',
"inches" = 'modular_citadel/sound/vox/inches.ogg',
"india" = 'modular_citadel/sound/vox/india.ogg',
"ing" = 'modular_citadel/sound/vox/ing.ogg',
"inoperative" = 'modular_citadel/sound/vox/inoperative.ogg',
"inside" = 'modular_citadel/sound/vox/inside.ogg',
"inspection" = 'modular_citadel/sound/vox/inspection.ogg',
"inspector" = 'modular_citadel/sound/vox/inspector.ogg',
"interchange" = 'modular_citadel/sound/vox/interchange.ogg',
"intruder" = 'modular_citadel/sound/vox/intruder.ogg',
"invallid" = 'modular_citadel/sound/vox/invallid.ogg',
"invasion" = 'modular_citadel/sound/vox/invasion.ogg',
"is" = 'modular_citadel/sound/vox/is.ogg',
"it" = 'modular_citadel/sound/vox/it.ogg',
"johnson" = 'modular_citadel/sound/vox/johnson.ogg',
"juliet" = 'modular_citadel/sound/vox/juliet.ogg',
"key" = 'modular_citadel/sound/vox/key.ogg',
"kill" = 'modular_citadel/sound/vox/kill.ogg',
"kilo" = 'modular_citadel/sound/vox/kilo.ogg',
"kit" = 'modular_citadel/sound/vox/kit.ogg',
"lab" = 'modular_citadel/sound/vox/lab.ogg',
"lambda" = 'modular_citadel/sound/vox/lambda.ogg',
"laser" = 'modular_citadel/sound/vox/laser.ogg',
"last" = 'modular_citadel/sound/vox/last.ogg',
"launch" = 'modular_citadel/sound/vox/launch.ogg',
"leak" = 'modular_citadel/sound/vox/leak.ogg',
"leave" = 'modular_citadel/sound/vox/leave.ogg',
"left" = 'modular_citadel/sound/vox/left.ogg',
"legal" = 'modular_citadel/sound/vox/legal.ogg',
"level" = 'modular_citadel/sound/vox/level.ogg',
"lever" = 'modular_citadel/sound/vox/lever.ogg',
"lie" = 'modular_citadel/sound/vox/lie.ogg',
"lieutenant" = 'modular_citadel/sound/vox/lieutenant.ogg',
"life" = 'modular_citadel/sound/vox/life.ogg',
"light" = 'modular_citadel/sound/vox/light.ogg',
"lima" = 'modular_citadel/sound/vox/lima.ogg',
"liquid" = 'modular_citadel/sound/vox/liquid.ogg',
"loading" = 'modular_citadel/sound/vox/loading.ogg',
"locate" = 'modular_citadel/sound/vox/locate.ogg',
"located" = 'modular_citadel/sound/vox/located.ogg',
"location" = 'modular_citadel/sound/vox/location.ogg',
"lock" = 'modular_citadel/sound/vox/lock.ogg',
"locked" = 'modular_citadel/sound/vox/locked.ogg',
"locker" = 'modular_citadel/sound/vox/locker.ogg',
"lockout" = 'modular_citadel/sound/vox/lockout.ogg',
"lower" = 'modular_citadel/sound/vox/lower.ogg',
"lowest" = 'modular_citadel/sound/vox/lowest.ogg',
"magnetic" = 'modular_citadel/sound/vox/magnetic.ogg',
"main" = 'modular_citadel/sound/vox/main.ogg',
"maintenance" = 'modular_citadel/sound/vox/maintenance.ogg',
"malfunction" = 'modular_citadel/sound/vox/malfunction.ogg',
"man" = 'modular_citadel/sound/vox/man.ogg',
"mass" = 'modular_citadel/sound/vox/mass.ogg',
"materials" = 'modular_citadel/sound/vox/materials.ogg',
"maximum" = 'modular_citadel/sound/vox/maximum.ogg',
"may" = 'modular_citadel/sound/vox/may.ogg',
"med" = 'modular_citadel/sound/vox/med.ogg',
"medical" = 'modular_citadel/sound/vox/medical.ogg',
"men" = 'modular_citadel/sound/vox/men.ogg',
"mercy" = 'modular_citadel/sound/vox/mercy.ogg',
"mesa" = 'modular_citadel/sound/vox/mesa.ogg',
"message" = 'modular_citadel/sound/vox/message.ogg',
"meter" = 'modular_citadel/sound/vox/meter.ogg',
"micro" = 'modular_citadel/sound/vox/micro.ogg',
"middle" = 'modular_citadel/sound/vox/middle.ogg',
"mike" = 'modular_citadel/sound/vox/mike.ogg',
"miles" = 'modular_citadel/sound/vox/miles.ogg',
"military" = 'modular_citadel/sound/vox/military.ogg',
"milli" = 'modular_citadel/sound/vox/milli.ogg',
"million" = 'modular_citadel/sound/vox/million.ogg',
"minefield" = 'modular_citadel/sound/vox/minefield.ogg',
"minimum" = 'modular_citadel/sound/vox/minimum.ogg',
"minutes" = 'modular_citadel/sound/vox/minutes.ogg',
"mister" = 'modular_citadel/sound/vox/mister.ogg',
"mode" = 'modular_citadel/sound/vox/mode.ogg',
"motor" = 'modular_citadel/sound/vox/motor.ogg',
"motorpool" = 'modular_citadel/sound/vox/motorpool.ogg',
"move" = 'modular_citadel/sound/vox/move.ogg',
"must" = 'modular_citadel/sound/vox/must.ogg',
"nearest" = 'modular_citadel/sound/vox/nearest.ogg',
"nice" = 'modular_citadel/sound/vox/nice.ogg',
"nine" = 'modular_citadel/sound/vox/nine.ogg',
"nineteen" = 'modular_citadel/sound/vox/nineteen.ogg',
"ninety" = 'modular_citadel/sound/vox/ninety.ogg',
"no" = 'modular_citadel/sound/vox/no.ogg',
"nominal" = 'modular_citadel/sound/vox/nominal.ogg',
"north" = 'modular_citadel/sound/vox/north.ogg',
"not" = 'modular_citadel/sound/vox/not.ogg',
"november" = 'modular_citadel/sound/vox/november.ogg',
"now" = 'modular_citadel/sound/vox/now.ogg',
"number" = 'modular_citadel/sound/vox/number.ogg',
"objective" = 'modular_citadel/sound/vox/objective.ogg',
"observation" = 'modular_citadel/sound/vox/observation.ogg',
"of" = 'modular_citadel/sound/vox/of.ogg',
"officer" = 'modular_citadel/sound/vox/officer.ogg',
"ok" = 'modular_citadel/sound/vox/ok.ogg',
"on" = 'modular_citadel/sound/vox/on.ogg',
"one" = 'modular_citadel/sound/vox/one.ogg',
"open" = 'modular_citadel/sound/vox/open.ogg',
"operating" = 'modular_citadel/sound/vox/operating.ogg',
"operations" = 'modular_citadel/sound/vox/operations.ogg',
"operative" = 'modular_citadel/sound/vox/operative.ogg',
"option" = 'modular_citadel/sound/vox/option.ogg',
"order" = 'modular_citadel/sound/vox/order.ogg',
"organic" = 'modular_citadel/sound/vox/organic.ogg',
"oscar" = 'modular_citadel/sound/vox/oscar.ogg',
"out" = 'modular_citadel/sound/vox/out.ogg',
"outside" = 'modular_citadel/sound/vox/outside.ogg',
"over" = 'modular_citadel/sound/vox/over.ogg',
"overload" = 'modular_citadel/sound/vox/overload.ogg',
"override" = 'modular_citadel/sound/vox/override.ogg',
"pacify" = 'modular_citadel/sound/vox/pacify.ogg',
"pain" = 'modular_citadel/sound/vox/pain.ogg',
"pal" = 'modular_citadel/sound/vox/pal.ogg',
"panel" = 'modular_citadel/sound/vox/panel.ogg',
"percent" = 'modular_citadel/sound/vox/percent.ogg',
"perimeter" = 'modular_citadel/sound/vox/perimeter.ogg',
"permitted" = 'modular_citadel/sound/vox/permitted.ogg',
"personnel" = 'modular_citadel/sound/vox/personnel.ogg',
"pipe" = 'modular_citadel/sound/vox/pipe.ogg',
"plant" = 'modular_citadel/sound/vox/plant.ogg',
"platform" = 'modular_citadel/sound/vox/platform.ogg',
"please" = 'modular_citadel/sound/vox/please.ogg',
"point" = 'modular_citadel/sound/vox/point.ogg',
"portal" = 'modular_citadel/sound/vox/portal.ogg',
"power" = 'modular_citadel/sound/vox/power.ogg',
"presence" = 'modular_citadel/sound/vox/presence.ogg',
"press" = 'modular_citadel/sound/vox/press.ogg',
"primary" = 'modular_citadel/sound/vox/primary.ogg',
"proceed" = 'modular_citadel/sound/vox/proceed.ogg',
"processing" = 'modular_citadel/sound/vox/processing.ogg',
"progress" = 'modular_citadel/sound/vox/progress.ogg',
"proper" = 'modular_citadel/sound/vox/proper.ogg',
"propulsion" = 'modular_citadel/sound/vox/propulsion.ogg',
"prosecute" = 'modular_citadel/sound/vox/prosecute.ogg',
"protective" = 'modular_citadel/sound/vox/protective.ogg',
"push" = 'modular_citadel/sound/vox/push.ogg',
"quantum" = 'modular_citadel/sound/vox/quantum.ogg',
"quebec" = 'modular_citadel/sound/vox/quebec.ogg',
"question" = 'modular_citadel/sound/vox/question.ogg',
"questioning" = 'modular_citadel/sound/vox/questioning.ogg',
"quick" = 'modular_citadel/sound/vox/quick.ogg',
"quit" = 'modular_citadel/sound/vox/quit.ogg',
"radiation" = 'modular_citadel/sound/vox/radiation.ogg',
"radioactive" = 'modular_citadel/sound/vox/radioactive.ogg',
"rads" = 'modular_citadel/sound/vox/rads.ogg',
"rapid" = 'modular_citadel/sound/vox/rapid.ogg',
"reach" = 'modular_citadel/sound/vox/reach.ogg',
"reached" = 'modular_citadel/sound/vox/reached.ogg',
"reactor" = 'modular_citadel/sound/vox/reactor.ogg',
"red" = 'modular_citadel/sound/vox/red.ogg',
"relay" = 'modular_citadel/sound/vox/relay.ogg',
"released" = 'modular_citadel/sound/vox/released.ogg',
"remaining" = 'modular_citadel/sound/vox/remaining.ogg',
"renegade" = 'modular_citadel/sound/vox/renegade.ogg',
"repair" = 'modular_citadel/sound/vox/repair.ogg',
"report" = 'modular_citadel/sound/vox/report.ogg',
"reports" = 'modular_citadel/sound/vox/reports.ogg',
"required" = 'modular_citadel/sound/vox/required.ogg',
"research" = 'modular_citadel/sound/vox/research.ogg',
"reset" = 'modular_citadel/sound/vox/reset.ogg',
"resevoir" = 'modular_citadel/sound/vox/resevoir.ogg',
"resistance" = 'modular_citadel/sound/vox/resistance.ogg',
"returned" = 'modular_citadel/sound/vox/returned.ogg',
"right" = 'modular_citadel/sound/vox/right.ogg',
"rocket" = 'modular_citadel/sound/vox/rocket.ogg',
"roger" = 'modular_citadel/sound/vox/roger.ogg',
"romeo" = 'modular_citadel/sound/vox/romeo.ogg',
"room" = 'modular_citadel/sound/vox/room.ogg',
"round" = 'modular_citadel/sound/vox/round.ogg',
"run" = 'modular_citadel/sound/vox/run.ogg',
"safe" = 'modular_citadel/sound/vox/safe.ogg',
"safety" = 'modular_citadel/sound/vox/safety.ogg',
"sargeant" = 'modular_citadel/sound/vox/sargeant.ogg',
"satellite" = 'modular_citadel/sound/vox/satellite.ogg',
"save" = 'modular_citadel/sound/vox/save.ogg',
"science" = 'modular_citadel/sound/vox/science.ogg',
"scores" = 'modular_citadel/sound/vox/scores.ogg',
"scream" = 'modular_citadel/sound/vox/scream.ogg',
"screen" = 'modular_citadel/sound/vox/screen.ogg',
"search" = 'modular_citadel/sound/vox/search.ogg',
"second" = 'modular_citadel/sound/vox/second.ogg',
"secondary" = 'modular_citadel/sound/vox/secondary.ogg',
"seconds" = 'modular_citadel/sound/vox/seconds.ogg',
"sector" = 'modular_citadel/sound/vox/sector.ogg',
"secure" = 'modular_citadel/sound/vox/secure.ogg',
"secured" = 'modular_citadel/sound/vox/secured.ogg',
"security" = 'modular_citadel/sound/vox/security.ogg',
"select" = 'modular_citadel/sound/vox/select.ogg',
"selected" = 'modular_citadel/sound/vox/selected.ogg',
"service" = 'modular_citadel/sound/vox/service.ogg',
"seven" = 'modular_citadel/sound/vox/seven.ogg',
"seventeen" = 'modular_citadel/sound/vox/seventeen.ogg',
"seventy" = 'modular_citadel/sound/vox/seventy.ogg',
"severe" = 'modular_citadel/sound/vox/severe.ogg',
"sewage" = 'modular_citadel/sound/vox/sewage.ogg',
"sewer" = 'modular_citadel/sound/vox/sewer.ogg',
"shield" = 'modular_citadel/sound/vox/shield.ogg',
"shipment" = 'modular_citadel/sound/vox/shipment.ogg',
"shock" = 'modular_citadel/sound/vox/shock.ogg',
"shoot" = 'modular_citadel/sound/vox/shoot.ogg',
"shower" = 'modular_citadel/sound/vox/shower.ogg',
"shut" = 'modular_citadel/sound/vox/shut.ogg',
"side" = 'modular_citadel/sound/vox/side.ogg',
"sierra" = 'modular_citadel/sound/vox/sierra.ogg',
"sight" = 'modular_citadel/sound/vox/sight.ogg',
"silo" = 'modular_citadel/sound/vox/silo.ogg',
"six" = 'modular_citadel/sound/vox/six.ogg',
"sixteen" = 'modular_citadel/sound/vox/sixteen.ogg',
"sixty" = 'modular_citadel/sound/vox/sixty.ogg',
"slime" = 'modular_citadel/sound/vox/slime.ogg',
"slow" = 'modular_citadel/sound/vox/slow.ogg',
"soldier" = 'modular_citadel/sound/vox/soldier.ogg',
"some" = 'modular_citadel/sound/vox/some.ogg',
"someone" = 'modular_citadel/sound/vox/someone.ogg',
"something" = 'modular_citadel/sound/vox/something.ogg',
"son" = 'modular_citadel/sound/vox/son.ogg',
"sorry" = 'modular_citadel/sound/vox/sorry.ogg',
"south" = 'modular_citadel/sound/vox/south.ogg',
"squad" = 'modular_citadel/sound/vox/squad.ogg',
"square" = 'modular_citadel/sound/vox/square.ogg',
"stairway" = 'modular_citadel/sound/vox/stairway.ogg',
"status" = 'modular_citadel/sound/vox/status.ogg',
"sterile" = 'modular_citadel/sound/vox/sterile.ogg',
"sterilization" = 'modular_citadel/sound/vox/sterilization.ogg',
"stolen" = 'modular_citadel/sound/vox/stolen.ogg',
"storage" = 'modular_citadel/sound/vox/storage.ogg',
"sub" = 'modular_citadel/sound/vox/sub.ogg',
"subsurface" = 'modular_citadel/sound/vox/subsurface.ogg',
"sudden" = 'modular_citadel/sound/vox/sudden.ogg',
"suit" = 'modular_citadel/sound/vox/suit.ogg',
"superconducting" = 'modular_citadel/sound/vox/superconducting.ogg',
"supercooled" = 'modular_citadel/sound/vox/supercooled.ogg',
"supply" = 'modular_citadel/sound/vox/supply.ogg',
"surface" = 'modular_citadel/sound/vox/surface.ogg',
"surrender" = 'modular_citadel/sound/vox/surrender.ogg',
"surround" = 'modular_citadel/sound/vox/surround.ogg',
"surrounded" = 'modular_citadel/sound/vox/surrounded.ogg',
"switch" = 'modular_citadel/sound/vox/switch.ogg',
"system" = 'modular_citadel/sound/vox/system.ogg',
"systems" = 'modular_citadel/sound/vox/systems.ogg',
"tactical" = 'modular_citadel/sound/vox/tactical.ogg',
"take" = 'modular_citadel/sound/vox/take.ogg',
"talk" = 'modular_citadel/sound/vox/talk.ogg',
"tango" = 'modular_citadel/sound/vox/tango.ogg',
"tank" = 'modular_citadel/sound/vox/tank.ogg',
"target" = 'modular_citadel/sound/vox/target.ogg',
"team" = 'modular_citadel/sound/vox/team.ogg',
"temperature" = 'modular_citadel/sound/vox/temperature.ogg',
"temporal" = 'modular_citadel/sound/vox/temporal.ogg',
"ten" = 'modular_citadel/sound/vox/ten.ogg',
"terminal" = 'modular_citadel/sound/vox/terminal.ogg',
"terminated" = 'modular_citadel/sound/vox/terminated.ogg',
"termination" = 'modular_citadel/sound/vox/termination.ogg',
"test" = 'modular_citadel/sound/vox/test.ogg',
"that" = 'modular_citadel/sound/vox/that.ogg',
"the" = 'modular_citadel/sound/vox/the.ogg',
"then" = 'modular_citadel/sound/vox/then.ogg',
"there" = 'modular_citadel/sound/vox/there.ogg',
"third" = 'modular_citadel/sound/vox/third.ogg',
"thirteen" = 'modular_citadel/sound/vox/thirteen.ogg',
"thirty" = 'modular_citadel/sound/vox/thirty.ogg',
"this" = 'modular_citadel/sound/vox/this.ogg',
"those" = 'modular_citadel/sound/vox/those.ogg',
"thousand" = 'modular_citadel/sound/vox/thousand.ogg',
"threat" = 'modular_citadel/sound/vox/threat.ogg',
"three" = 'modular_citadel/sound/vox/three.ogg',
"through" = 'modular_citadel/sound/vox/through.ogg',
"time" = 'modular_citadel/sound/vox/time.ogg',
"to" = 'modular_citadel/sound/vox/to.ogg',
"top" = 'modular_citadel/sound/vox/top.ogg',
"topside" = 'modular_citadel/sound/vox/topside.ogg',
"touch" = 'modular_citadel/sound/vox/touch.ogg',
"towards" = 'modular_citadel/sound/vox/towards.ogg',
"track" = 'modular_citadel/sound/vox/track.ogg',
"train" = 'modular_citadel/sound/vox/train.ogg',
"transportation" = 'modular_citadel/sound/vox/transportation.ogg',
"truck" = 'modular_citadel/sound/vox/truck.ogg',
"tunnel" = 'modular_citadel/sound/vox/tunnel.ogg',
"turn" = 'modular_citadel/sound/vox/turn.ogg',
"turret" = 'modular_citadel/sound/vox/turret.ogg',
"twelve" = 'modular_citadel/sound/vox/twelve.ogg',
"twenty" = 'modular_citadel/sound/vox/twenty.ogg',
"two" = 'modular_citadel/sound/vox/two.ogg',
"unauthorized" = 'modular_citadel/sound/vox/unauthorized.ogg',
"under" = 'modular_citadel/sound/vox/under.ogg',
"uniform" = 'modular_citadel/sound/vox/uniform.ogg',
"unlocked" = 'modular_citadel/sound/vox/unlocked.ogg',
"until" = 'modular_citadel/sound/vox/until.ogg',
"up" = 'modular_citadel/sound/vox/up.ogg',
"upper" = 'modular_citadel/sound/vox/upper.ogg',
"uranium" = 'modular_citadel/sound/vox/uranium.ogg',
"us" = 'modular_citadel/sound/vox/us.ogg',
"usa" = 'modular_citadel/sound/vox/usa.ogg',
"use" = 'modular_citadel/sound/vox/use.ogg',
"used" = 'modular_citadel/sound/vox/used.ogg',
"user" = 'modular_citadel/sound/vox/user.ogg',
"vacate" = 'modular_citadel/sound/vox/vacate.ogg',
"valid" = 'modular_citadel/sound/vox/valid.ogg',
"vapor" = 'modular_citadel/sound/vox/vapor.ogg',
"vent" = 'modular_citadel/sound/vox/vent.ogg',
"ventillation" = 'modular_citadel/sound/vox/ventillation.ogg',
"victor" = 'modular_citadel/sound/vox/victor.ogg',
"violated" = 'modular_citadel/sound/vox/violated.ogg',
"violation" = 'modular_citadel/sound/vox/violation.ogg',
"voltage" = 'modular_citadel/sound/vox/voltage.ogg',
"vox_login" = 'modular_citadel/sound/vox/vox_login.ogg',
"walk" = 'modular_citadel/sound/vox/walk.ogg',
"wall" = 'modular_citadel/sound/vox/wall.ogg',
"want" = 'modular_citadel/sound/vox/want.ogg',
"wanted" = 'modular_citadel/sound/vox/wanted.ogg',
"warm" = 'modular_citadel/sound/vox/warm.ogg',
"warn" = 'modular_citadel/sound/vox/warn.ogg',
"warning" = 'modular_citadel/sound/vox/warning.ogg',
"waste" = 'modular_citadel/sound/vox/waste.ogg',
"water" = 'modular_citadel/sound/vox/water.ogg',
"we" = 'modular_citadel/sound/vox/we.ogg',
"weapon" = 'modular_citadel/sound/vox/weapon.ogg',
"west" = 'modular_citadel/sound/vox/west.ogg',
"whiskey" = 'modular_citadel/sound/vox/whiskey.ogg',
"white" = 'modular_citadel/sound/vox/white.ogg',
"wilco" = 'modular_citadel/sound/vox/wilco.ogg',
"will" = 'modular_citadel/sound/vox/will.ogg',
"with" = 'modular_citadel/sound/vox/with.ogg',
"without" = 'modular_citadel/sound/vox/without.ogg',
"woop" = 'modular_citadel/sound/vox/woop.ogg',
"xeno" = 'modular_citadel/sound/vox/xeno.ogg',
"yankee" = 'modular_citadel/sound/vox/yankee.ogg',
"yards" = 'modular_citadel/sound/vox/yards.ogg',
"year" = 'modular_citadel/sound/vox/year.ogg',
"yellow" = 'modular_citadel/sound/vox/yellow.ogg',
"yes" = 'modular_citadel/sound/vox/yes.ogg',
"you" = 'modular_citadel/sound/vox/you.ogg',
"your" = 'modular_citadel/sound/vox/your.ogg',
"yourself" = 'modular_citadel/sound/vox/yourself.ogg',
"zero" = 'modular_citadel/sound/vox/zero.ogg',
"zone" = 'modular_citadel/sound/vox/zone.ogg',
"zulu" = 'modular_citadel/sound/vox/zulu.ogg',))
#endif
@@ -13,13 +13,23 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
w_class = 3
hitsound = 'sound/weapons/bite.ogg'
sharpness = IS_SHARP
var/stamtostunconversion = 0.1 //Total stamloss gets multiplied by this value for the help intent hard stun. Resting adds an additional 2x multiplier on top. Keep this low or so help me god.
var/stuncooldown = 4 SECONDS //How long it takes before you're able to attempt to stun a target again
var/nextstuntime
/obj/item/dogborg/jaws/examine(mob/user)
. = ..()
if(!CONFIG_GET(flag/weaken_secborg))
to_chat(user, "<span class='notice'>Use help intent to attempt to non-lethally incapacitate the target by latching on with your maw. This is more effective against exhausted and resting targets.</span>")
/obj/item/dogborg/jaws/big
name = "combat jaws"
desc = "The jaws of the law. Very sharp."
icon_state = "jaws"
force = 10 //Lowered to match secborg. No reason it should be more than a secborg's baton.
force = 15 //Chomp chomp. Crew harm.
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
stamtostunconversion = 0.2 // 100*0.2*2=40. Stun's just long enough to slap on cuffs with click delay if the target is near hard stamcrit.
stuncooldown = 6 SECONDS
/obj/item/dogborg/jaws/small
@@ -31,11 +41,36 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
var/status = 0
/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
..()
user.do_attack_animation(A, ATTACK_EFFECT_BITE)
if(!istype(user))
return
if(!CONFIG_GET(flag/weaken_secborg) && user.a_intent != INTENT_HARM && istype(A, /mob/living))
if(A == user.pulling)
to_chat(user, "<span class='warning'>You already have [A] in your jaws.</span>")
return
if(nextstuntime >= world.time)
to_chat(user, "<span class='warning'>Your jaw servos are still recharging.</span>")
return
nextstuntime = world.time + stuncooldown
var/mob/living/M = A
var/cachedstam = M.getStaminaLoss()
var/totalstuntime = cachedstam * stamtostunconversion * (M.lying ? 2 : 1)
if(!M.resting)
M.Knockdown(cachedstam*2) //BORK BORK. GET DOWN.
M.Stun(totalstuntime)
user.do_attack_animation(A, ATTACK_EFFECT_BITE)
user.start_pulling(M, TRUE) //Yip yip. Come with.
user.changeNext_move(CLICK_CD_MELEE)
M.visible_message("<span class='danger'>[user] clamps [user.p_their()] [src] onto [M] and latches on!</span>", "<span class='userdanger'>[user] clamps [user.p_their()] [src] onto you and latches on!</span>")
if(totalstuntime >= 4 SECONDS)
playsound(usr, 'sound/effects/k9_jaw_strong.ogg', 75, FALSE, 2) //Wuff wuff. Big stun.
else
playsound(usr, 'sound/effects/k9_jaw_weak.ogg', 50, TRUE, -1) //Arf arf. Pls buff.
else
. = ..()
user.do_attack_animation(A, ATTACK_EFFECT_BITE)
/obj/item/dogborg/jaws/small/attack_self(mob/user)
var/mob/living/silicon/robot.R = user
var/mob/living/silicon/robot/R = user
if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0)
name = "combat jaws"
@@ -43,14 +78,18 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
desc = "The jaws of the law."
force = 12
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
stamtostunconversion = 0.15
stuncooldown = 5 SECONDS
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
force = initial(force)
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
stamtostunconversion = initial(stamtostunconversion)
stuncooldown = initial(stuncooldown)
status = 0
if(R.emagged)
to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>")
@@ -143,7 +182,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
/obj/item/storage/bag/borgdelivery/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 5
STR.max_items = 1
@@ -167,7 +206,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
item_flags |= NOBLUDGEON //No more attack messages
/obj/item/soap/tongue/attack_self(mob/user)
var/mob/living/silicon/robot.R = user
var/mob/living/silicon/robot/R = user
if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0)
status = !status
@@ -187,7 +226,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
update_icon()
/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity)
var/mob/living/silicon/robot.R = user
var/mob/living/silicon/robot/R = user
if(!proximity || !check_allowed_items(target))
return
if(R.client && (target in R.client.screen))
@@ -273,6 +312,42 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
target.wash_cream()
return
//Nerfed tongue for flavour reasons (haha geddit?). Used for aux skins for regular borgs
/obj/item/soap/tongue/flavour
desc = "For giving affectionate kisses."
/obj/item/soap/tongue/flavour/attack_self(mob/user)
return
/obj/item/soap/tongue/flavour/afterattack(atom/target, mob/user, proximity)
if(!proximity)
return
var/mob/living/silicon/robot.R = user
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)
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)
return
//Same as above but for noses
/obj/item/analyzer/nose/flavour/AltClick(mob/user)
return
/obj/item/analyzer/nose/flavour/attack_self(mob/user)
return
/obj/item/analyzer/nose/flavour/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>")
//Dogfood
/obj/item/trash/rkibble
@@ -307,8 +382,10 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
/mob/living/silicon/robot
var/leaping = 0
var/pounce_cooldown = 0
var/pounce_cooldown_time = 20 //Buffed to counter balance changes
var/pounce_spoolup = 1
var/pounce_cooldown_time = 30 //Time in deciseconds between pounces
var/pounce_spoolup = 5 //Time in deciseconds for the pounce to happen after clicking
var/pounce_stamloss_cap = 120 //How much staminaloss pounces alone are capable of bringing a spaceman to
var/pounce_stamloss = 80 //Base staminaloss value of the pounce
var/leap_at
var/disabler
var/laser
@@ -320,13 +397,12 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
/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
if(R && (world.time >= R.pounce_cooldown))
R.pounce_cooldown = world.time + R.pounce_cooldown_time
to_chat(R, "<span class ='warning'>Your targeting systems lock on to [A]...</span>")
playsound(R, 'sound/effects/servostep.ogg', 100, TRUE)
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)
else if(R && (world.time < 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)
@@ -349,6 +425,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
update_icons()
throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1)
cell.use(750) //Less than a stunbaton since stunbatons hit everytime.
playsound(src, 'sound/effects/stealthoff.ogg', 25, TRUE, -1)
weather_immunities -= "lava"
/mob/living/silicon/robot/throw_impact(atom/A)
@@ -366,7 +443,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
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) ? 225 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice.
L.Knockdown(iscarbon(L) ? 60 : 45, override_stamdmg = CLAMP(pounce_stamloss, 0, pounce_stamloss_cap-L.getStaminaLoss())) // 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)
@@ -1,26 +0,0 @@
mob/living/silicon
no_vore = TRUE
/mob/living/silicon/robot
var/dogborg = FALSE
/mob/living/silicon/robot/lay_down()
..()
update_canmove()
/mob/living/silicon/robot/update_canmove()
..()
if(client && stat != DEAD && dogborg == FALSE)
if(resting)
cut_overlays()
icon_state = "[module.cyborg_base_icon]-rest"
else
icon_state = "[module.cyborg_base_icon]"
update_icons()
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_stamina = 1)
if(istype(cell))
cell.charge -= amount*5
@@ -1,465 +0,0 @@
/mob/living/silicon/robot/modules/medihound
set_module = /obj/item/robot_module/medihound
/mob/living/silicon/robot/modules/k9
set_module = /obj/item/robot_module/k9
/mob/living/silicon/robot/modules/scrubpup
set_module = /obj/item/robot_module/scrubpup
/mob/living/silicon/robot/modules/borgi
set_module = /obj/item/robot_module/borgi
/mob/living/silicon/robot/proc/get_cit_modules()
var/list/modulelist = list()
modulelist["MediHound"] = /obj/item/robot_module/medihound
if(!CONFIG_GET(flag/disable_secborg))
modulelist["Security K-9"] = /obj/item/robot_module/k9
modulelist["Scrub Puppy"] = /obj/item/robot_module/scrubpup
modulelist["Borgi"] = /obj/item/robot_module/borgi
return modulelist
/obj/item/robot_module
var/sleeper_overlay
var/icon/cyborg_icon_override
var/has_snowflake_deadsprite
var/cyborg_pixel_offset
var/moduleselect_alternate_icon
var/dogborg = FALSE
/obj/item/robot_module/k9
name = "Security K-9 Unit"
basic_modules = list(
/obj/item/restraints/handcuffs/cable/zipties,
/obj/item/storage/bag/borgdelivery,
/obj/item/dogborg/jaws/big,
/obj/item/dogborg/pounce,
/obj/item/clothing/mask/gas/sechailer/cyborg,
/obj/item/soap/tongue,
/obj/item/analyzer/nose,
/obj/item/dogborg/sleeper/K9,
/obj/item/gun/energy/disabler/cyborg,
/obj/item/pinpointer/crew)
emag_modules = list(/obj/item/gun/energy/laser/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
/obj/item/clockwork/weapon/ratvarian_spear)
cyborg_base_icon = "k9"
moduleselect_icon = "k9"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
can_be_pushed = FALSE
hat_offset = INFINITY
sleeper_overlay = "ksleeper"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
/obj/item/robot_module/k9/do_transform_animation()
..()
to_chat(loc,"<span class='userdanger'>While you have picked the Security K-9 module, you still have to follow your laws, NOT Space Law. \
For Crewsimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
/obj/item/robot_module/k9/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/sechoundmodels = list("Default", "Dark", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
sechoundmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in sechoundmodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "k9"
if("Alina")
cyborg_base_icon = "alina-sec"
special_light_key = "alina"
sleeper_overlay = "alinasleeper"
if("Dark")
cyborg_base_icon = "k9dark"
if("Vale")
cyborg_base_icon = "valesec"
return ..()
/obj/item/robot_module/medihound
name = "MediHound"
basic_modules = list(
/obj/item/dogborg/jaws/small,
/obj/item/storage/bag/borgdelivery,
/obj/item/analyzer/nose,
/obj/item/soap/tongue,
/obj/item/extinguisher/mini,
/obj/item/healthanalyzer,
/obj/item/dogborg/sleeper/medihound,
/obj/item/roller/robo,
/obj/item/reagent_containers/borghypo,
/obj/item/twohanded/shockpaddles/cyborg/hound,
/obj/item/stack/medical/gauze/cyborg,
/obj/item/pinpointer/crew,
/obj/item/sensor_device)
emag_modules = list(/obj/item/dogborg/pounce)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical,
/obj/item/clockwork/weapon/ratvarian_spear)
cyborg_base_icon = "medihound"
moduleselect_icon = "medihound"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
can_be_pushed = FALSE
hat_offset = INFINITY
sleeper_overlay = "msleeper"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
/obj/item/robot_module/medihound/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/medhoundmodels = list("Default", "Dark", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
medhoundmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medhoundmodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "medihound"
if("Dark")
cyborg_base_icon = "medihounddark"
sleeper_overlay = "mdsleeper"
if("Vale")
cyborg_base_icon = "valemed"
sleeper_overlay = "valemedsleeper"
if("Alina")
cyborg_base_icon = "alina-med"
special_light_key = "alina"
sleeper_overlay = "alinasleeper"
return ..()
/obj/item/robot_module/scrubpup
name = "Scrub Pup"
basic_modules = list(
/obj/item/dogborg/jaws/small,
/obj/item/analyzer/nose,
/obj/item/soap/tongue/scrubpup,
/obj/item/lightreplacer/cyborg,
/obj/item/extinguisher/mini,
/obj/item/dogborg/sleeper/compactor)
emag_modules = list(/obj/item/dogborg/pounce)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/janitor,
/obj/item/clockwork/replica_fabricator/cyborg)
cyborg_base_icon = "scrubpup"
moduleselect_icon = "janitor"
hat_offset = INFINITY
clean_on_move = TRUE
sleeper_overlay = "jsleeper"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
cyborg_pixel_offset = -16
dogborg = TRUE
/obj/item/robot_module/scrubpup/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/lightreplacer/LR = locate(/obj/item/lightreplacer) in basic_modules
if(LR)
for(var/i in 1 to coeff)
LR.Charge(R)
/obj/item/robot_module/scrubpup/do_transform_animation()
..()
to_chat(loc,"<span class='userdanger'>As tempting as it might be, do not begin binging on important items. Eat your garbage responsibly. People are not included under Garbage.</span>")
/obj/item/robot_module/borgi
name = "Borgi"
basic_modules = list(
/obj/item/dogborg/jaws/small,
/obj/item/storage/bag/borgdelivery,
/obj/item/analyzer/nose,
/obj/item/soap/tongue,
/obj/item/healthanalyzer,
/obj/item/extinguisher/mini,
/obj/item/borg/cyborghug)
emag_modules = list(/obj/item/dogborg/pounce)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg,
/obj/item/clockwork/weapon/ratvarian_spear,
/obj/item/clockwork/replica_fabricator/cyborg)
cyborg_base_icon = "borgi"
moduleselect_icon = "borgi"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
has_snowflake_deadsprite = TRUE
/*
/obj/item/robot_module/orepup
name = "Ore Pup"
basic_modules = list(
/obj/item/storage/bag/ore/cyborg,
/obj/item/analyzer/nose,
/obj/item/storage/bag/borgdelivery,
/obj/item/dogborg/sleeper/ore,
/obj/item/pickaxe/drill/cyborg,
/obj/item/shovel,
/obj/item/crowbar/cyborg,
/obj/item/weldingtool/mini,
/obj/item/extinguisher/mini,
/obj/item/t_scanner/adv_mining_scanner,
/obj/item/gun/energy/kinetic_accelerator/cyborg,
/obj/item/gps/cyborg)
emag_modules = list(/obj/item/dogborg/pounce)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/miner,
/obj/item/clockwork/weapon/ratvarian_spear,
/obj/item/borg/sight/xray/truesight_lens)
cyborg_base_icon = "orepup"
moduleselect_icon = "orepup"
sleeper_overlay = "osleeper"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
cyborg_pixel_offset = -16
/obj/item/robot_module/miner/do_transform_animation()
var/mob/living/silicon/robot/R = loc
R.cut_overlays()
R.setDir(SOUTH)
flick("orepup_transform", R)
do_transform_delay()
R.update_headlamp()
*/
/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "medical"
if("Droid")
cyborg_base_icon = "medical"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
hat_offset = 4
if("Sleek")
cyborg_base_icon = "sleekmed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinamed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Eyebot")
cyborg_base_icon = "eyebotmed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavymed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/janitor/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/janimodels = list("Default", "Sleek", "Marina", "Can", "Heavy")
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in janimodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "janitor"
if("Marina")
cyborg_base_icon = "marinajan"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Sleek")
cyborg_base_icon = "sleekjan"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "canjan"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavyres"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Spider")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "peace"
if("Spider")
cyborg_base_icon = "whitespider"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "sec"
if("Default - Treads")
cyborg_base_icon = "sec-tread"
special_light_key = "sec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Sleek")
cyborg_base_icon = "sleeksec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinasec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "cansec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
cyborg_base_icon = "spidersec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavysec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/butler/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Waitress", "Heavy", "Sleek", "Butler", "Tophat", "Kent", "Bro", "DarkK9", "Vale", "ValeDark")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Waitress")
cyborg_base_icon = "service_f"
if("Butler")
cyborg_base_icon = "service_m"
if("Bro")
cyborg_base_icon = "brobot"
if("Kent")
cyborg_base_icon = "kent"
special_light_key = "medical"
hat_offset = 3
if("Tophat")
cyborg_base_icon = "tophat"
special_light_key = null
hat_offset = INFINITY //He is already wearing a hat
if("Sleek")
cyborg_base_icon = "sleekserv"
special_light_key = "sleekserv"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavyserv"
special_light_key = "heavyserv"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("DarkK9")
cyborg_base_icon = "k50"
special_light_key = "k50"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
if("Vale")
cyborg_base_icon = "valeserv"
special_light_key = "valeserv"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
if("ValeDark")
cyborg_base_icon = "valeservdark"
special_light_key = "valeservdark"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
return ..()
/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
engymodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "engineer"
if("Default - Treads")
cyborg_base_icon = "engi-tread"
special_light_key = "engineer"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Loader")
cyborg_base_icon = "loaderborg"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
has_snowflake_deadsprite = TRUE
if("Handy")
cyborg_base_icon = "handyeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Sleek")
cyborg_base_icon = "sleekeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "caneng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinaeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
cyborg_base_icon = "spidereng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavyeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Pup Dozer")
cyborg_base_icon = "pupdozer"
can_be_pushed = FALSE
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
if("Vale")
cyborg_base_icon = "valeeng"
can_be_pushed = FALSE
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
if("Alina")
cyborg_base_icon = "alina-eng"
special_light_key = "alina"
can_be_pushed = FALSE
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
return ..()
/obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Lavaland")
cyborg_base_icon = "miner"
if("Asteroid")
cyborg_base_icon = "minerOLD"
special_light_key = "miner"
if("Droid")
cyborg_base_icon = "miner"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
hat_offset = 4
if("Sleek")
cyborg_base_icon = "sleekmin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "canmin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinamin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
cyborg_base_icon = "spidermin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavymin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
@@ -11,6 +11,7 @@
. = ..()
if(!resting && !sprinting)
. += 1
. += speed
/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))
@@ -18,11 +19,11 @@
sprinting = shutdown ? FALSE : !sprinting
if(!resting && canmove)
if(sprinting)
playsound_local(src, 'modular_citadel/sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
playsound_local(src, '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)
playsound_local(src, '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)
selector.insert_witty_toggle_joke_here(src)
@@ -1,151 +0,0 @@
/obj/item/seeds/banana/Initialize()
. = ..()
mutatelist += /obj/item/seeds/banana/exotic_banana
/obj/item/seeds/banana/exotic_banana
name = "pack of exotic banana seeds"
desc = "They're seeds that grow into banana trees. However, those bananas might be alive."
icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
icon_state = "seed_ExoticBanana"
species = "banana"
plantname = "Exotic Banana Tree"
product = /obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable
growing_icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
icon_dead = "banana-dead"
mutatelist = list()
genes = list(/datum/plant_gene/trait/slip)
reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02)
/obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable
seed = /obj/item/seeds/banana/exotic_banana
name = "banana spider"
desc = "You do not know what it is, but you can bet the clown would love it."
icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
icon_state = "banana"
item_state = "banana"
filling_color = "#FFFF00"
list_reagents = list("nutriment" = 3, "vitamin" = 2)
foodtype = GROSS | MEAT | RAW | FRUIT
grind_results = list("blood" = 20, "liquidgibs" = 5)
juice_results = list("banana" = 0)
var/awakening = 0
/obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable/attack_self(mob/user)
if(awakening || isspaceturf(user.loc))
return
to_chat(user, "<span class='notice'>You decide to wake up the banana spider...</span>")
awakening = 1
spawn(30)
if(!QDELETED(src))
var/mob/living/simple_animal/banana_spider/S = new /mob/living/simple_animal/banana_spider(get_turf(src.loc))
S.speed += round(10 / seed.potency)
S.visible_message("<span class='notice'>The banana spider chitters as it stretches its legs.</span>")
qdel(src)
/mob/living/simple_animal/banana_spider
icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
name = "banana spider"
desc = "What the fuck is this abomination?"
icon_state = "banana"
icon_dead = "banana_peel"
health = 1
maxHealth = 1
turns_per_move = 5 //this isn't player speed =|
speed = 2 //this is player speed
loot = list(/obj/item/reagent_containers/food/snacks/deadbanana_spider)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 270
maxbodytemp = INFINITY
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
response_help = "pokes"
response_disarm = "shoos"
response_harm = "splats"
speak_emote = list("chitters")
mouse_opacity = 2
density = TRUE
ventcrawler = VENTCRAWLER_ALWAYS
gold_core_spawnable = FRIENDLY_SPAWN
verb_say = "chitters"
verb_ask = "chitters inquisitively"
verb_exclaim = "chitters loudly"
verb_yell = "chitters loudly"
var/squish_chance = 50
var/projectile_density = TRUE //griffons get shot
del_on_death = TRUE
/mob/living/simple_animal/banana_spider/Initialize()
. = ..()
var/area/A = get_area(src)
if(A)
notify_ghosts("A banana spider has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
/mob/living/simple_animal/banana_spider/attack_ghost(mob/user)
if(key) //please stop using src. without a good reason.
return
if(CONFIG_GET(flag/use_age_restriction_for_jobs))
if(!isnum(user.client.player_age))
return
if(!SSticker.mode)
to_chat(user, "Can't become a banana spider before the game has started.")
return
var/be_spider = alert("Become a banana spider? (Warning, You can no longer be cloned!)",,"Yes","No")
if(be_spider == "No" || QDELETED(src) || !isobserver(user))
return
sentience_act()
user.transfer_ckey(src, FALSE)
density = TRUE
/mob/living/simple_animal/banana_spider/ComponentInitialize()
. = ..()
AddComponent(/datum/component/slippery, 40)
/mob/living/simple_animal/banana_spider/Crossed(atom/movable/AM) //no /var in proc headers
. = ..()
if(istype(AM, /obj/item/projectile) && projectile_density) //forced projectile density
var/obj/item/projectile/P = AM
P.Bump(src)
if(ismob(AM))
if(isliving(AM))
var/mob/living/A = AM
if(A.mob_size > MOB_SIZE_SMALL && !(A.movement_type & FLYING))
if(prob(squish_chance))
A.visible_message("<span class='notice'>[A] squashed [src].</span>", "<span class='notice'>You squashed [src] under your weight as you fell.</span>")
adjustBruteLoss(1)
else
visible_message("<span class='notice'>[src] avoids getting crushed.</span>")
else
if(isstructure(AM))
if(prob(squish_chance))
AM.visible_message("<span class='notice'>[src] was crushed under [AM]'s weight as they fell.</span>")
adjustBruteLoss(1)
else
visible_message("<span class='notice'>[src] avoids getting crushed.</span>")
/mob/living/simple_animal/banana_spider/ex_act()
return
/mob/living/simple_animal/banana_spider/start_pulling()
return FALSE //No.
/obj/item/reagent_containers/food/snacks/deadbanana_spider
name = "dead banana spider"
desc = "Thank god it's gone...but it does look slippery."
icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
icon_state = "banana_peel"
bitesize = 3
eatverb = "devours"
list_reagents = list("nutriment" = 3, "vitamin" = 2)
foodtype = GROSS | MEAT | RAW
grind_results = list("blood" = 20, "liquidgibs" = 5)
juice_results = list("banana" = 0)
/obj/item/reagent_containers/food/snacks/deadbanana_spider/Initialize()
. = ..()
AddComponent(/datum/component/slippery, 20)
@@ -1,134 +0,0 @@
/mob/living/simple_animal/kiwi
name = "space kiwi"
desc = "Exposure to low gravity made them grow larger."
gender = FEMALE
icon = 'modular_citadel/icons/mob/kiwi.dmi'
icon_state = "kiwi"
icon_living = "kiwi"
icon_dead = "dead"
speak = list("Chirp!","Cheep cheep chirp!!","Cheep.")
speak_emote = list("chirps","trills")
emote_hear = list("chirps.")
emote_see = list("pecks at the ground.","jumps in place.")
density = FALSE
speak_chance = 2
turns_per_move = 3
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
var/egg_type = /obj/item/reagent_containers/food/snacks/egg/kiwiEgg
var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
health = 25
maxHealth = 25
ventcrawler = VENTCRAWLER_ALWAYS
var/eggsleft = 0
var/eggsFertile = TRUE
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
var/list/feedMessages = list("It chirps happily.","It chirps happily.")
var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins chirping raucously.")
gold_core_spawnable = FRIENDLY_SPAWN
var/static/kiwi_count = 0
/mob/living/simple_animal/kiwi/Destroy()
--kiwi_count
return ..()
/mob/living/simple_animal/kiwi/Initialize()
. = ..()
++kiwi_count
/mob/living/simple_animal/kiwi/Life()
. =..()
if(!.)
return
if((!stat && prob(3) && eggsleft > 0) && egg_type)
visible_message("[src] [pick(layMessage)]")
eggsleft--
var/obj/item/E = new egg_type(get_turf(src))
E.pixel_x = rand(-6,6)
E.pixel_y = rand(-6,6)
if(eggsFertile)
if(kiwi_count < MAX_CHICKENS && prob(25))
START_PROCESSING(SSobj, E)
/obj/item/reagent_containers/food/snacks/egg/kiwiEgg/process()
if(isturf(loc))
amount_grown += rand(1,2)
if(amount_grown >= 100)
visible_message("[src] hatches with a quiet cracking sound.")
new /mob/living/simple_animal/babyKiwi(get_turf(src))
STOP_PROCESSING(SSobj, src)
qdel(src)
else
STOP_PROCESSING(SSobj, src)
/mob/living/simple_animal/kiwi/attackby(obj/item/O, mob/user, params)
if(istype(O, food_type)) //feedin' dem kiwis
if(!stat && eggsleft < 8)
var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]"
user.visible_message(feedmsg)
qdel(O)
eggsleft += rand(1, 4)
else
to_chat(user, "<span class='warning'>[name] doesn't seem hungry!</span>")
else
..()
/mob/living/simple_animal/babyKiwi
name = "baby space kiwi"
desc = "So huggable."
icon = 'modular_citadel/icons/mob/kiwi.dmi'
icon_state = "babyKiwi"
icon_living = "babyKiwi"
icon_dead = "deadBaby"
icon_gib = "chick_gib"
gender = FEMALE
speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
speak_emote = list("chirps")
emote_hear = list("chirps.")
emote_see = list("pecks at the ground.","Happily bounces in place.")
density = FALSE
speak_chance = 2
turns_per_move = 2
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
health = 10
maxHealth = 10
ventcrawler = VENTCRAWLER_ALWAYS
var/amount_grown = 0
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
gold_core_spawnable = FRIENDLY_SPAWN
/mob/living/simple_animal/babyKiwi/Initialize()
. = ..()
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
/mob/living/simple_animal/babyKiwi/Life()
. =..()
if(!.)
return
if(!stat && !ckey)
amount_grown += rand(1,2)
if(amount_grown >= 100)
new /mob/living/simple_animal/kiwi(src.loc)
qdel(src)
/obj/item/reagent_containers/food/snacks/egg/kiwiEgg
name = "kiwi egg"
icon = 'modular_citadel/icons/mob/kiwi.dmi'
desc = "A slightly bigger egg!"
icon_state = "egg"
@@ -1,135 +0,0 @@
//CARBON MOBS
/mob/living/carbon/alien
devourable = TRUE
digestable = TRUE
feeding = TRUE
/mob/living/carbon/monkey
devourable = TRUE
digestable = TRUE
feeding = TRUE
/*
REFER TO code/modules/mob/living/simple_animal/simple_animal_vr.dm for Var information!
*/
//NUETRAL MOBS
/mob/living/simple_animal/crab
devourable = TRUE
digestable = TRUE
feeding = TRUE
/mob/living/simple_animal/cow
devourable = TRUE
digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_HOLD
/mob/living/simple_animal/chick
devourable = TRUE
digestable = TRUE
/mob/living/simple_animal/chicken
devourable = TRUE
digestable = TRUE
/mob/living/simple_animal/mouse
devourable = TRUE
digestable = TRUE
/mob/living/simple_animal/kiwi
devourable = TRUE
digestable = TRUE
//STATION PETS
/mob/living/simple_animal/pet
devourable = TRUE
digestable = TRUE
feeding = TRUE
/mob/living/simple_animal/pet/fox
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_HOLD
/mob/living/simple_animal/pet/cat
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_HOLD
/mob/living/simple_animal/pet/dog
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_HOLD
/mob/living/simple_animal/sloth
devourable = TRUE
digestable = TRUE
/mob/living/simple_animal/parrot
devourable = TRUE
digestable = TRUE
//HOSTILE MOBS
/mob/living/simple_animal/hostile/retaliate/goat
devourable = TRUE
digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_stomach_flavor = "You find yourself squeezed into the hollow of the goat, the smell of oats and hay thick in the tight space, all of which grinds in on you. Harmless for now..."
vore_default_mode = DM_HOLD
/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
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/bear
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/poison/giant_spider
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/retaliate/poison/snake
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/gorilla
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/asteroid/goliath
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
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
vore_default_mode = DM_DIGEST
+4 -2
View File
@@ -3,9 +3,11 @@
/mob/say_mod(input, message_mode)
var/customsayverb = findtext(input, "*")
if(customsayverb)
if(customsayverb && message_mode != MODE_WHISPER_CRIT)
message_mode = MODE_CUSTOM_SAY
return lowertext(copytext(input, 1, customsayverb))
. = ..()
else
return ..()
/atom/movable/proc/attach_spans(input, list/spans)
var/customsayverb = findtext(input, "*")
@@ -1,7 +0,0 @@
/obj/machinery/light
bulb_colour = "#FFEEDD"
bulb_power = 0.75
/obj/machinery/light/small
bulb_colour = "#FFDDBB"
bulb_power = 0.75
@@ -29,27 +29,27 @@
build_path = /obj/item/ammo_box/magazine/m10mm/hp
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
/datum/design/m10mm/ap
name = "pistol magazine (10mm AP)"
desc = "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets."
id = "10mmap"
build_type = PROTOLATHE
materials = list(MAT_METAL = 40000, MAT_TITANIUM = 60000)
build_path = /obj/item/ammo_box/magazine/m10mm/ap
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
/datum/design/m10mm/ap
name = "pistol magazine (10mm AP)"
desc = "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets."
id = "10mmap"
build_type = PROTOLATHE
materials = list(MAT_METAL = 40000, MAT_TITANIUM = 60000)
build_path = /obj/item/ammo_box/magazine/m10mm/ap
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
/datum/design/bolt_clip
name = "Surplus Rifle Clip"
desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds."
id = "bolt_clip"
build_type = PROTOLATHE
materials = list(MAT_METAL = 8000)
build_path = /obj/item/ammo_box/a762
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
name = "Surplus Rifle Clip"
desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds."
id = "bolt_clip"
build_type = PROTOLATHE
materials = list(MAT_METAL = 8000)
build_path = /obj/item/ammo_box/a762
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
/datum/design/m45 //Kinda NT in throey
name = "handgun magazine (.45)"
id = "m45"
@@ -1,4 +1,4 @@
/obj/item/projectile/bullet/c46x30mm_tx
name = "toxin tipped 4.6x30mm bullet"
damage = 15
damage = 10
damage_type = TOX
@@ -57,10 +57,9 @@
icon_state = "magjectile-nl"
damage = 2
knockdown = 0
stamina = 25
armour_penetration = -10
stamina = 20
light_range = 2
speed = 0.7
speed = 0.6
range = 25
light_color = LIGHT_COLOR_BLUE
@@ -109,9 +108,10 @@
fire_sound = 'sound/weapons/magpistol.ogg'
mag_type = /obj/item/ammo_box/magazine/mmag/small
can_suppress = 0
casing_ejector = 0
casing_ejector = FALSE
fire_delay = 2
recoil = 0.2
recoil = 0.1
inaccuracy_modifier = 0.25
/obj/item/gun/ballistic/automatic/pistol/mag/update_icon()
..()
@@ -123,7 +123,6 @@
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
///research memes///
/*
/obj/item/gun/ballistic/automatic/pistol/mag/nopin
pin = null
spawnwithmagazine = FALSE
@@ -155,7 +154,7 @@
materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250)
build_path = /obj/item/ammo_box/magazine/mmag/small
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
*/
//////toy memes/////
/obj/item/projectile/bullet/reusable/foam_dart/mag
@@ -201,9 +200,9 @@
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "magjectile-large"
damage = 20
armour_penetration = 25
armour_penetration = 20
light_range = 3
speed = 0.7
speed = 0.6
range = 35
light_color = LIGHT_COLOR_RED
@@ -212,10 +211,10 @@
icon_state = "magjectile-large-nl"
damage = 2
knockdown = 0
stamina = 25
armour_penetration = -10
stamina = 20
armour_penetration = 10
light_range = 3
speed = 0.65
speed = 0.6
range = 35
light_color = LIGHT_COLOR_BLUE
@@ -227,6 +226,8 @@
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "mag-casing-live"
projectile_type = /obj/item/projectile/bullet/magrifle
click_cooldown_override = 2.5
delay = 3
/obj/item/ammo_casing/caseless/anlmagm
desc = "A large, specialized ferromagnetic slug designed with a less-than-lethal payload."
@@ -234,10 +235,12 @@
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "mag-casing-live"
projectile_type = /obj/item/projectile/bullet/nlmagrifle
click_cooldown_override = 2.5
delay = 3
///magazines///
/obj/item/ammo_box/magazine/mmag/
/obj/item/ammo_box/magazine/mmag
name = "magrifle magazine (non-lethal disabler)"
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "mediummagmag"
@@ -261,17 +264,20 @@
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "magrifle"
item_state = "arg"
slot_flags = 0
slot_flags = NONE
mag_type = /obj/item/ammo_box/magazine/mmag
fire_sound = 'sound/weapons/magrifle.ogg'
can_suppress = 0
burst_size = 3
fire_delay = 2
spread = 5
recoil = 0.15
casing_ejector = 0
burst_size = 1
actions_types = null
fire_delay = 3
spread = 0
recoil = 0.1
casing_ejector = FALSE
inaccuracy_modifier = 0.5
weapon_weight = WEAPON_MEDIUM
dualwield_spread_mult = 1.4
/*
//research///
/obj/item/gun/ballistic/automatic/magrifle/nopin
@@ -305,7 +311,7 @@
materials = list(MAT_METAL = 6000, MAT_SILVER = 500, MAT_TITANIUM = 500)
build_path = /obj/item/ammo_box/magazine/mmag
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
*/
///foamagrifle///
/obj/item/ammo_box/magazine/toy/foamag
@@ -327,7 +333,6 @@
spread = 60
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_HEAVY
/*
// TECHWEBS IMPLEMENTATION
//
@@ -339,7 +344,6 @@
design_ids = list("magrifle", "magpisol", "mag_magrifle", "mag_magrifle_nl", "mag_magpistol", "mag_magpistol_nl")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
*/
//////Hyper-Burst Rifle//////
@@ -143,6 +143,7 @@
// TECHWEBS IMPLEMENTATION
*/
/*
/datum/techweb_node/magnetic_weapons
id = "magnetic_weapons"
display_name = "Magnetic Weapons"
@@ -151,6 +152,7 @@
design_ids = list("magrifle_e", "magpistol_e", "mag_magrifle_e", "mag_magrifle_e_nl", "mag_magpistol_e", "mag_magpistol_e_nl")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
*/
///magrifle///
@@ -1,11 +0,0 @@
/*
// REVOLVER THINGS GO HERE
*/
/obj/item/gun/ballistic/revolver //regular, classic sprite
name = "\improper .357 revolver"
desc = "A typical revolver. Uses .357 ammo."
/obj/item/gun/ballistic/revolver/syndie //New and improved 100% syndicate technology!
desc = "A suspicious revolver. Uses .357 ammo."
icon = 'modular_citadel/icons/obj/guns/revolver.dmi'
@@ -1,13 +1,6 @@
/obj/item/gun/energy/e_gun
name = "blaster carbine"
desc = "A high powered particle blaster carbine with varitable setting for stunning or lethal applications."
icon = 'modular_citadel/icons/obj/guns/OVERRIDE_energy.dmi'
lefthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi'
righthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi'
ammo_x_offset = 2
flight_x_offset = 17
flight_y_offset = 11
/*/////////////////////////////////////////////////////////////////////////////////////////////
The Recolourable Energy Gun
@@ -1,19 +1,11 @@
/obj/item/gun/energy/laser
name = "blaster rifle"
desc = "a high energy particle blaster, efficient and deadly."
icon = 'modular_citadel/icons/obj/guns/OVERRIDE_energy.dmi'
ammo_x_offset = 1
shaded_charge = 1
lefthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi'
righthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi'
/obj/item/gun/energy/laser/practice
icon = 'modular_citadel/icons/obj/guns/energy.dmi'
icon_state = "laser-p"
/obj/item/gun/energy/laser/bluetag
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
/obj/item/gun/energy/laser/redtag
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
lefthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi'
righthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi'
ammo_x_offset = 1
shaded_charge = 1
@@ -75,9 +75,9 @@
/obj/item/gun/energy/pumpaction/proc/pump(mob/M) //pumping proc. Checks if the gun is empty and plays a different sound if it is.
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
if(cell.charge < shot.e_cost)
playsound(M, 'modular_citadel/sound/weapons/laserPumpEmpty.ogg', 100, 1) //Ends with three beeps made from highly processed knife honing noises
playsound(M, 'sound/weapons/laserPumpEmpty.ogg', 100, 1) //Ends with three beeps made from highly processed knife honing noises
else
playsound(M, 'modular_citadel/sound/weapons/laserPump.ogg', 100, 1) //Ends with high pitched charging noise
playsound(M, 'sound/weapons/laserPump.ogg', 100, 1) //Ends with high pitched charging noise
recharge_newshot() //try to charge a new shot
update_icon()
return 1
@@ -152,14 +152,14 @@
e_cost = 150
pellets = 4
variance = 30
fire_sound = 'modular_citadel/sound/weapons/ParticleBlaster.ogg'
fire_sound = 'sound/weapons/ParticleBlaster.ogg'
select_name = "disable"
/obj/item/ammo_casing/energy/disabler/slug
projectile_type = /obj/item/projectile/beam/disabler/slug
select_name = "overdrive"
e_cost = 200
fire_sound = 'modular_citadel/sound/weapons/LaserSlugv3.ogg'
fire_sound = 'sound/weapons/LaserSlugv3.ogg'
/obj/item/ammo_casing/energy/laser/pump
projectile_type = /obj/item/projectile/beam/weak
@@ -167,12 +167,12 @@
select_name = "kill"
pellets = 3
variance = 15
fire_sound = 'modular_citadel/sound/weapons/ParticleBlaster.ogg'
fire_sound = 'sound/weapons/ParticleBlaster.ogg'
/obj/item/ammo_casing/energy/electrode/pump
projectile_type = /obj/item/projectile/energy/electrode/pump
select_name = "stun"
fire_sound = 'modular_citadel/sound/weapons/LaserSlugv3.ogg'
fire_sound = 'sound/weapons/LaserSlugv3.ogg'
e_cost = 300
pellets = 3
variance = 20
@@ -39,7 +39,7 @@
projectile_type = /obj/item/projectile/beam/lasertag/wavemotion
select_name = "overdrive"
e_cost = 300
fire_sound = 'modular_citadel/sound/weapons/LaserSlugv3.ogg'
fire_sound = 'sound/weapons/LaserSlugv3.ogg'
/obj/item/ammo_casing/energy/laser/dispersal
projectile_type = /obj/item/projectile/beam/lasertag/dispersal
@@ -47,7 +47,7 @@
pellets = 5
variance = 25
e_cost = 200
fire_sound = 'modular_citadel/sound/weapons/ParticleBlaster.ogg'
fire_sound = 'sound/weapons/ParticleBlaster.ogg'
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TOY REVOLVER
@@ -1,2 +0,0 @@
/obj/item/projectile/energy/electrode
stamina = 36
@@ -1,6 +1,6 @@
/obj/item/projectile/bullet/reusable/foam_dart/tag
name = "lastag foam dart"
var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag)
name = "lastag foam dart"
var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag)
/obj/item/projectile/bullet/reusable/foam_dart/tag/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -89,6 +89,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
if(!SM.mind) //Something went wrong, use alt mechanics
return ..()
SM.mind.enslave_mind_to_creator(M)
SM.mind.store_memory(M.mind.memory)
//If they're a zombie, they can try to negate it with this.
//I seriously wonder if anyone will ever use this function.
@@ -30,17 +30,15 @@
inverse_chem_val = 0.35
inverse_chem = "BEsmaller" //At really impure vols, it just becomes 100% inverse
can_synth = FALSE
var/message_spam = FALSE
/datum/reagent/fermi/breast_enlarger/on_mob_add(mob/living/carbon/M)
/datum/reagent/fermi/breast_enlarger/on_mob_metabolize(mob/living/M)
. = ..()
if(!ishuman(M)) //The monkey clause
if(volume >= 15) //To prevent monkey breast farms
var/turf/T = get_turf(M)
var/obj/item/organ/genital/breasts/B = new /obj/item/organ/genital/breasts(T)
var/list/seen = viewers(8, T)
for(var/mob/S in seen)
to_chat(S, "<span class='warning'>A pair of breasts suddenly fly out of the [M]!</b></span>")
//var/turf/T2 = pick(turf in view(5, M))
M.visible_message("<span class='warning'>A pair of breasts suddenly fly out of the [M]!</b></span>")
var/T2 = get_random_station_turf()
M.adjustBruteLoss(25)
M.Knockdown(50)
@@ -48,94 +46,82 @@
B.throw_at(T2, 8, 1)
M.reagents.remove_reagent(id, volume)
return
log_game("FERMICHEM: [M] ckey: [M.key] has ingested Sucubus milk")
var/mob/living/carbon/human/H = M
H.genital_override = TRUE
var/obj/item/organ/genital/breasts/B = H.getorganslot("breasts")
if(!B)
H.emergent_genital_call()
return
if(!B.size == "huge")
var/sizeConv = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5)
B.prev_size = B.size
B.cached_size = sizeConv[B.size]
if(!H.getorganslot(ORGAN_SLOT_BREASTS) && H.emergent_genital_call())
H.genital_override = TRUE
/datum/reagent/fermi/breast_enlarger/on_mob_life(mob/living/carbon/M) //Increases breast size
if(!ishuman(M))//Just in case
return..()
var/mob/living/carbon/human/H = M
var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
if(!B) //If they don't have breasts, give them breasts.
//If they have Acute hepatic pharmacokinesis, then route processing though liver.
if(HAS_TRAIT(M, TRAIT_PHARMA))
var/obj/item/organ/liver/L = M.getorganslot("liver")
if(HAS_TRAIT(H, TRAIT_PHARMA) || !H.canbearoused)
var/obj/item/organ/liver/L = H.getorganslot(ORGAN_SLOT_LIVER)
if(L)
L.swelling+= 0.05
return..()
L.swelling += 0.05
else
M.adjustToxLoss(1)
return..()
H.adjustToxLoss(1)
return..()
//otherwise proceed as normal
var/obj/item/organ/genital/breasts/nB = new
nB.Insert(M)
if(nB)
if(M.dna.species.use_skintones && M.dna.features["genitals_use_skintone"])
nB.color = skintone2hex(H.skin_tone)
else if(M.dna.features["breasts_color"])
nB.color = "#[M.dna.features["breasts_color"]]"
else
nB.color = skintone2hex(H.skin_tone)
nB.size = "flat"
nB.cached_size = 0
nB.prev_size = 0
to_chat(M, "<span class='warning'>Your chest feels warm, tingling with newfound sensitivity.</b></span>")
M.reagents.remove_reagent(id, 5)
B = nB
B = new
if(H.dna.species.use_skintones && H.dna.features["genitals_use_skintone"])
B.color = skintone2hex(H.skin_tone)
else if(M.dna.features["breasts_color"])
B.color = "#[M.dna.features["breasts_color"]]"
else
B.color = skintone2hex(H.skin_tone)
B.size = "flat"
B.cached_size = 0
B.prev_size = 0
to_chat(H, "<span class='warning'>Your chest feels warm, tingling with newfound sensitivity.</b></span>")
H.reagents.remove_reagent(id, 5)
B.Insert(H)
//If they have them, increase size. If size is comically big, limit movement and rip clothes.
B.cached_size = B.cached_size + 0.05
if (B.cached_size >= 8.5 && B.cached_size < 9)
if(H.w_uniform || H.wear_suit)
var/target = M.get_bodypart(BODY_ZONE_CHEST)
to_chat(M, "<span class='warning'>Your breasts begin to strain against your clothes tightly!</b></span>")
M.adjustOxyLoss(5, 0)
M.apply_damage(1, BRUTE, target)
B.update()
..()
B.modify_size(0.05)
if (ISINRANGE_EX(B.cached_size, 8.5, 9) && (H.w_uniform || H.wear_suit))
var/target = H.get_bodypart(BODY_ZONE_CHEST)
if(!message_spam)
to_chat(H, "<span class='danger'>Your breasts begin to strain against your clothes tightly!</b></span>")
message_spam = TRUE
H.adjustOxyLoss(5, 0)
H.apply_damage(1, BRUTE, target)
return ..()
/datum/reagent/fermi/breast_enlarger/overdose_process(mob/living/carbon/M) //Turns you into a female if male and ODing, doesn't touch nonbinary and object genders.
//Acute hepatic pharmacokinesis.
if(HAS_TRAIT(M, TRAIT_PHARMA))
var/obj/item/organ/liver/L = M.getorganslot("liver")
if(HAS_TRAIT(M, TRAIT_PHARMA) || !M.canbearoused)
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
L.swelling+= 0.05
return ..()
var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
var/obj/item/organ/genital/testicles/T = M.getorganslot("testicles")
var/obj/item/organ/genital/vagina/V = M.getorganslot("vagina")
var/obj/item/organ/genital/womb/W = M.getorganslot("womb")
var/obj/item/organ/genital/penis/P = M.getorganslot(ORGAN_SLOT_PENIS)
var/obj/item/organ/genital/testicles/T = M.getorganslot(ORGAN_SLOT_TESTICLES)
var/obj/item/organ/genital/vagina/V = M.getorganslot(ORGAN_SLOT_VAGINA)
var/obj/item/organ/genital/womb/W = M.getorganslot(ORGAN_SLOT_WOMB)
if(M.gender == MALE)
M.gender = FEMALE
M.visible_message("<span class='boldnotice'>[M] suddenly looks more feminine!</span>", "<span class='boldwarning'>You suddenly feel more feminine!</span>")
if(P)
P.cached_length = P.cached_length - 0.05
P.update()
P.modify_size(-0.05)
if(T)
T.Remove(M)
qdel(T)
if(!V)
var/obj/item/organ/genital/vagina/nV = new
nV.Insert(M)
V = nV
V = new
V.Insert(M)
if(!W)
var/obj/item/organ/genital/womb/nW = new
nW.Insert(M)
W = nW
..()
W = new
W.Insert(M)
return ..()
/datum/reagent/fermi/BEsmaller
name = "Modesty milk"
@@ -147,19 +133,18 @@
can_synth = FALSE
/datum/reagent/fermi/BEsmaller/on_mob_life(mob/living/carbon/M)
var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
if(!B)
//Acute hepatic pharmacokinesis.
if(HAS_TRAIT(M, TRAIT_PHARMA))
var/obj/item/organ/liver/L = M.getorganslot("liver")
if(HAS_TRAIT(M, TRAIT_PHARMA) || !M.canbearoused)
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
L.swelling-= 0.05
return ..()
//otherwise proceed as normal
return..()
B.cached_size = B.cached_size - 0.05
B.update()
..()
B.modify_size(-0.05)
return ..()
/datum/reagent/fermi/BEsmaller_hypo
name = "Rectify milk" //Rectify
@@ -171,31 +156,28 @@
var/sizeConv = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5)
can_synth = TRUE
/datum/reagent/fermi/BEsmaller_hypo/on_mob_add(mob/living/carbon/M)
/datum/reagent/fermi/BEsmaller_hypo/on_mob_metabolize(mob/living/M)
. = ..()
if(!M.getorganslot("vagina"))
if(M.dna.features["has_vag"])
var/obj/item/organ/genital/vagina/nV = new
nV.Insert(M)
if(!M.getorganslot("womb"))
if(M.dna.features["has_womb"])
var/obj/item/organ/genital/womb/nW = new
nW.Insert(M)
if(!ishuman(M))
return
var/mob/living/carbon/human/H = M
if(!H.getorganslot(ORGAN_SLOT_VAGINA) && H.dna.features["has_vag"])
H.give_genital(/obj/item/organ/genital/vagina)
if(!H.getorganslot(ORGAN_SLOT_WOMB) && H.dna.features["has_womb"])
H.give_genital(/obj/item/organ/genital/womb)
/datum/reagent/fermi/BEsmaller_hypo/on_mob_life(mob/living/carbon/M)
var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
if(!B)
return..()
if(!M.dna.features["has_breasts"])//Fast fix for those who don't want it.
B.cached_size = B.cached_size - 0.1
B.update()
else if(B.cached_size > (sizeConv[M.dna.features["breasts_size"]]+0.1))
B.cached_size = B.cached_size - 0.05
B.update()
else if(B.cached_size < (sizeConv[M.dna.features["breasts_size"]])+0.1)
B.cached_size = B.cached_size + 0.05
B.update()
..()
var/optimal_size = B.breast_values[M.dna.features["breasts_size"]]
if(!optimal_size)//Fast fix for those who don't want it.
B.modify_size(-0.1)
else if(B.cached_size > optimal_size)
B.modify_size(-0.05, optimal_size)
else if(B.cached_size < optimal_size)
B.modify_size(0.05, 0, optimal_size)
return ..()
////////////////////////////////////////////////////////////////////////////////////////////////////
// PENIS ENLARGE
@@ -215,16 +197,15 @@
inverse_chem_val = 0.35
inverse_chem = "PEsmaller" //At really impure vols, it just becomes 100% inverse and shrinks instead.
can_synth = FALSE
var/message_spam = FALSE
/datum/reagent/fermi/penis_enlarger/on_mob_add(mob/living/carbon/M)
/datum/reagent/fermi/penis_enlarger/on_mob_metabolize(mob/living/M)
. = ..()
if(!ishuman(M)) //Just monkeying around.
if(volume >= 15) //to prevent monkey penis farms
var/turf/T = get_turf(M)
var/obj/item/organ/genital/penis/P = new /obj/item/organ/genital/penis(T)
var/list/seen = viewers(8, T)
for(var/mob/S in seen)
to_chat(S, "<span class='warning'>A penis suddenly flies out of the [M]!</b></span>")
M.visible_message("<span class='warning'>A penis suddenly flies out of the [M]!</b></span>")
var/T2 = get_random_station_turf()
M.adjustBruteLoss(25)
M.Knockdown(50)
@@ -233,80 +214,71 @@
M.reagents.remove_reagent(id, volume)
return
var/mob/living/carbon/human/H = M
H.genital_override = TRUE
var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
if(!P)
H.emergent_genital_call()
return
P.prev_length = P.length
P.cached_length = P.length
if(!H.getorganslot(ORGAN_SLOT_PENIS) && H.emergent_genital_call())
H.genital_override = TRUE
/datum/reagent/fermi/penis_enlarger/on_mob_life(mob/living/carbon/M) //Increases penis size, 5u = +1 inch.
if(!ishuman(M))
return
return ..()
var/mob/living/carbon/human/H = M
var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
if(!P)//They do have a preponderance for escapism, or so I've heard.
//If they have Acute hepatic pharmacokinesis, then route processing though liver.
if(HAS_TRAIT(M, TRAIT_PHARMA))
var/obj/item/organ/liver/L = M.getorganslot("liver")
if(HAS_TRAIT(H, TRAIT_PHARMA) || !H.canbearoused)
var/obj/item/organ/liver/L = H.getorganslot(ORGAN_SLOT_LIVER)
if(L)
L.swelling+= 0.05
return..()
L.swelling += 0.05
else
M.adjustToxLoss(1)
return..()
H.adjustToxLoss(1)
return ..()
//otherwise proceed as normal
var/obj/item/organ/genital/penis/nP = new
nP.Insert(M)
if(nP)
nP.length = 1
to_chat(M, "<span class='warning'>Your groin feels warm, as you feel a newly forming bulge down below.</b></span>")
nP.cached_length = 1
nP.prev_length = 1
M.reagents.remove_reagent(id, 5)
P = nP
P = new
P.length = 1
to_chat(H, "<span class='warning'>Your groin feels warm, as you feel a newly forming bulge down below.</b></span>")
P.prev_length = 1
H.reagents.remove_reagent(id, 5)
P.Insert(H)
P.cached_length = P.cached_length + 0.1
if (P.cached_length >= 20.5 && P.cached_length < 21)
if(H.w_uniform || H.wear_suit)
var/target = M.get_bodypart(BODY_ZONE_CHEST)
to_chat(M, "<span class='warning'>Your cock begin to strain against your clothes tightly!</b></span>")
M.apply_damage(2.5, BRUTE, target)
P.modify_size(0.1)
if (ISINRANGE_EX(P.length, 20.5, 21) && (H.w_uniform || H.wear_suit))
var/target = H.get_bodypart(BODY_ZONE_CHEST)
if(!message_spam)
to_chat(H, "<span class='danger'>Your cock begin to strain against your clothes tightly!</b></span>")
message_spam = TRUE
H.apply_damage(2.5, BRUTE, target)
P.update()
..()
return ..()
/datum/reagent/fermi/penis_enlarger/overdose_process(mob/living/carbon/M) //Turns you into a male if female and ODing, doesn't touch nonbinary and object genders.
/datum/reagent/fermi/penis_enlarger/overdose_process(mob/living/carbon/human/M) //Turns you into a male if female and ODing, doesn't touch nonbinary and object genders.
if(!istype(M))
return ..()
//Acute hepatic pharmacokinesis.
if(HAS_TRAIT(M, TRAIT_PHARMA))
var/obj/item/organ/liver/L = M.getorganslot("liver")
if(HAS_TRAIT(M, TRAIT_PHARMA) || !M.canbearoused)
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
L.swelling+= 0.05
return..()
var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
var/obj/item/organ/genital/testicles/T = M.getorganslot("testicles")
var/obj/item/organ/genital/vagina/V = M.getorganslot("vagina")
var/obj/item/organ/genital/womb/W = M.getorganslot("womb")
var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
var/obj/item/organ/genital/testicles/T = M.getorganslot(ORGAN_SLOT_TESTICLES)
var/obj/item/organ/genital/vagina/V = M.getorganslot(ORGAN_SLOT_VAGINA)
var/obj/item/organ/genital/womb/W = M.getorganslot(ORGAN_SLOT_WOMB)
if(M.gender == FEMALE)
M.gender = MALE
M.visible_message("<span class='boldnotice'>[M] suddenly looks more masculine!</span>", "<span class='boldwarning'>You suddenly feel more masculine!</span>")
if(B)
B.cached_size = B.cached_size - 0.05
B.update()
if(V)
V.Remove(M)
B.modify_size(-0.05)
if(M.getorganslot(ORGAN_SLOT_VAGINA))
qdel(V)
if(W)
W.Remove(M)
qdel(W)
if(!T)
var/obj/item/organ/genital/testicles/nT = new
nT.Insert(M)
T = nT
..()
T = new
T.Insert(M)
return ..()
/datum/reagent/fermi/PEsmaller // Due to cozmo's request...!
name = "Chastity draft"
@@ -318,19 +290,18 @@
can_synth = FALSE
/datum/reagent/fermi/PEsmaller/on_mob_life(mob/living/carbon/M)
if(!ishuman(M))
return ..()
var/mob/living/carbon/human/H = M
var/obj/item/organ/genital/penis/P = H.getorganslot("penis")
var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
if(!P)
//Acute hepatic pharmacokinesis.
if(HAS_TRAIT(M, TRAIT_PHARMA))
var/obj/item/organ/liver/L = M.getorganslot("liver")
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
L.swelling-= 0.05
return..()
//otherwise proceed as normal
return..()
P.cached_length = P.cached_length - 0.1
P.update()
P.modify_size(-0.1)
..()
/datum/reagent/fermi/PEsmaller_hypo
@@ -342,24 +313,25 @@
metabolization_rate = 0.5
can_synth = TRUE
/datum/reagent/fermi/PEsmaller_hypo/on_mob_add(mob/living/carbon/M)
/datum/reagent/fermi/PEsmaller_hypo/on_mob_metabolize(mob/living/M)
. = ..()
if(!M.getorganslot("testicles"))
if(M.dna.features["has_balls"])
var/obj/item/organ/genital/testicles/nT = new
nT.Insert(M)
if(!ishuman(M))
return
var/mob/living/carbon/human/H = M
if(!H.getorganslot(ORGAN_SLOT_PENIS) && H.dna.features["has_cock"])
H.give_genital(/obj/item/organ/genital/penis)
if(!H.getorganslot(ORGAN_SLOT_TESTICLES) && H.dna.features["has_balls"])
H.give_genital(/obj/item/organ/genital/testicles)
/datum/reagent/fermi/PEsmaller_hypo/on_mob_life(mob/living/carbon/M)
var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
var/obj/item/organ/genital/penis/P = M.getorganslot(ORGAN_SLOT_PENIS)
if(!P)
return ..()
if(!M.dna.features["has_cock"])//Fast fix for those who don't want it.
P.cached_length = P.cached_length - 0.2
P.update()
else if(P.cached_length > (M.dna.features["cock_length"]+0.1))
P.cached_length = P.cached_length - 0.1
P.update()
else if(P.cached_length < (M.dna.features["cock_length"]+0.1))
P.cached_length = P.cached_length + 0.1
P.update()
..()
var/optimal_size = M.dna.features["cock_length"]
if(!optimal_size)//Fast fix for those who don't want it.
P.modify_size(-0.2)
else if(P.length > optimal_size)
P.modify_size(-0.1, optimal_size)
else if(P.length < optimal_size)
P.modify_size(0.1, 0, optimal_size)
return ..()
@@ -6,6 +6,7 @@
id = "fermi"
taste_description = "affection and love!"
can_synth = FALSE
value = 20
impure_chem = "fermiTox"// What chemical is metabolised with an inpure reaction
inverse_chem_val = 0.25 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising
inverse_chem = "fermiTox"
@@ -178,18 +179,20 @@
inverse_chem = "nanite_b_goneTox" //At really impure vols, it just becomes 100% inverse
taste_description = "what can only be described as licking a battery."
pH = 9
value = 90
can_synth = FALSE
var/react_objs = list()
/datum/reagent/fermi/nanite_b_gone/on_mob_life(mob/living/carbon/C)
GET_COMPONENT_FROM(N, /datum/component/nanites, C)
var/datum/component/nanites/N = C.GetComponent(/datum/component/nanites)
if(isnull(N))
return ..()
N.nanite_volume += -cached_purity*5//0.5 seems to be the default to me, so it'll neuter them.
..()
/datum/reagent/fermi/nanite_b_gone/overdose_process(mob/living/carbon/C)
GET_COMPONENT_FROM(N, /datum/component/nanites, C)
//var/component/nanites/N = M.GetComponent(/datum/component/nanites)
var/datum/component/nanites/N = C.GetComponent(/datum/component/nanites)
if(prob(5))
to_chat(C, "<span class='warning'>The residual voltage from the nanites causes you to seize up!</b></span>")
C.electrocute_act(10, (get_turf(C)), 1, FALSE, FALSE, FALSE, TRUE)
@@ -1,11 +1,3 @@
/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
if(istype(O, /obj/effect/decal/cleanable) || istype(O, /obj/item/projectile/bullet/reusable/foam_dart) || istype(O, /obj/item/ammo_casing/caseless/foam_dart))
qdel(O)
else
if(O)
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/datum/reagent/syndicateadrenals
name = "Syndicate Adrenaline"
id = "syndicateadrenals"
@@ -325,10 +325,10 @@
//So slimes can play too.
/datum/chemical_reaction/fermi/enthrall/slime
required_catalysts = list("slimejelly" = 1)
required_catalysts = list("jellyblood" = 1)
/datum/chemical_reaction/fermi/enthrall/slime/FermiFinish(datum/reagents/holder, var/atom/my_atom)
var/datum/reagent/toxin/slimejelly/B = locate(/datum/reagent/toxin/slimejelly) in my_atom.reagents.reagent_list//The one line change.
var/datum/reagent/blood/jellyblood/B = locate(/datum/reagent/blood/jellyblood) in my_atom.reagents.reagent_list//The one line change.
var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in my_atom.reagents.reagent_list
if(!B.data)
var/list/seen = viewers(5, get_turf(my_atom))
@@ -1,12 +1,12 @@
/obj/item/fermichem/pHbooklet
name = "pH indicator booklet"
desc = "A booklet containing paper soaked in universal indicator."
icon_state = "pHbooklet"
icon = 'modular_citadel/icons/obj/FermiChem.dmi'
item_flags = NOBLUDGEON
var/numberOfPages = 50
resistance_flags = FLAMMABLE
w_class = WEIGHT_CLASS_TINY
name = "pH indicator booklet"
desc = "A booklet containing paper soaked in universal indicator."
icon_state = "pHbooklet"
icon = 'icons/obj/chemical.dmi'
item_flags = NOBLUDGEON
var/numberOfPages = 50
resistance_flags = FLAMMABLE
w_class = WEIGHT_CLASS_TINY
//A little janky with pockets
/obj/item/fermichem/pHbooklet/attack_hand(mob/user)
@@ -29,7 +29,7 @@
to_chat(user, "<span class='warning'>[src] is empty!</span>")
add_fingerprint(user)
return
. = ..()
. = ..()
if(. & COMPONENT_NO_INTERACT)
return
var/I = user.get_active_held_item()
@@ -37,86 +37,86 @@
user.put_in_active_hand(src)
/obj/item/fermichem/pHbooklet/MouseDrop()
var/mob/living/user = usr
if(numberOfPages >= 1)
var/obj/item/fermichem/pHpaper/P = new /obj/item/fermichem/pHpaper
P.add_fingerprint(user)
P.forceMove(user)
user.put_in_active_hand(P)
to_chat(user, "<span class='notice'>You take [P] out of \the [src].</span>")
numberOfPages--
playsound(user.loc, 'sound/items/poster_ripped.ogg', 50, 1)
add_fingerprint(user)
if(numberOfPages == 0)
icon_state = "pHbookletEmpty"
return
else
to_chat(user, "<span class='warning'>[src] is empty!</span>")
add_fingerprint(user)
return
..()
var/mob/living/user = usr
if(numberOfPages >= 1)
var/obj/item/fermichem/pHpaper/P = new /obj/item/fermichem/pHpaper
P.add_fingerprint(user)
P.forceMove(user)
user.put_in_active_hand(P)
to_chat(user, "<span class='notice'>You take [P] out of \the [src].</span>")
numberOfPages--
playsound(user.loc, 'sound/items/poster_ripped.ogg', 50, 1)
add_fingerprint(user)
if(numberOfPages == 0)
icon_state = "pHbookletEmpty"
return
else
to_chat(user, "<span class='warning'>[src] is empty!</span>")
add_fingerprint(user)
return
..()
/obj/item/fermichem/pHpaper
name = "pH indicator strip"
desc = "A piece of paper that will change colour depending on the pH of a solution."
icon_state = "pHpaper"
icon = 'modular_citadel/icons/obj/FermiChem.dmi'
item_flags = NOBLUDGEON
color = "#f5c352"
var/used = FALSE
resistance_flags = FLAMMABLE
w_class = WEIGHT_CLASS_TINY
name = "pH indicator strip"
desc = "A piece of paper that will change colour depending on the pH of a solution."
icon_state = "pHpaper"
icon = 'icons/obj/chemical.dmi'
item_flags = NOBLUDGEON
color = "#f5c352"
var/used = FALSE
resistance_flags = FLAMMABLE
w_class = WEIGHT_CLASS_TINY
/obj/item/fermichem/pHpaper/afterattack(obj/item/reagent_containers/cont, mob/user, proximity)
if(!istype(cont))
return
if(used == TRUE)
to_chat(user, "<span class='warning'>[user] has already been used!</span>")
return
if(!LAZYLEN(cont.reagents.reagent_list))
return
switch(round(cont.reagents.pH, 1))
if(14 to INFINITY)
color = "#462c83"
if(13 to 14)
color = "#63459b"
if(12 to 13)
color = "#5a51a2"
if(11 to 12)
color = "#3853a4"
if(10 to 11)
color = "#3f93cf"
if(9 to 10)
color = "#0bb9b7"
if(8 to 9)
color = "#23b36e"
if(7 to 8)
color = "#3aa651"
if(6 to 7)
color = "#4cb849"
if(5 to 6)
color = "#b5d335"
if(4 to 5)
color = "#f7ec1e"
if(3 to 4)
color = "#fbc314"
if(2 to 3)
color = "#f26724"
if(1 to 2)
color = "#ef1d26"
if(-INFINITY to 1)
color = "#c6040c"
desc += " The paper looks to be around a pH of [round(cont.reagents.pH, 1)]"
used = TRUE
if(!istype(cont))
return
if(used == TRUE)
to_chat(user, "<span class='warning'>[user] has already been used!</span>")
return
if(!LAZYLEN(cont.reagents.reagent_list))
return
switch(round(cont.reagents.pH, 1))
if(14 to INFINITY)
color = "#462c83"
if(13 to 14)
color = "#63459b"
if(12 to 13)
color = "#5a51a2"
if(11 to 12)
color = "#3853a4"
if(10 to 11)
color = "#3f93cf"
if(9 to 10)
color = "#0bb9b7"
if(8 to 9)
color = "#23b36e"
if(7 to 8)
color = "#3aa651"
if(6 to 7)
color = "#4cb849"
if(5 to 6)
color = "#b5d335"
if(4 to 5)
color = "#f7ec1e"
if(3 to 4)
color = "#fbc314"
if(2 to 3)
color = "#f26724"
if(1 to 2)
color = "#ef1d26"
if(-INFINITY to 1)
color = "#c6040c"
desc += " The paper looks to be around a pH of [round(cont.reagents.pH, 1)]"
used = TRUE
/obj/item/fermichem/pHmeter
name = "Chemistry Analyser"
desc = "A a electrode attached to a small circuit box that will tell you the pH of a solution. The screen currently displays nothing."
icon_state = "pHmeter"
icon = 'modular_citadel/icons/obj/FermiChem.dmi'
resistance_flags = FLAMMABLE
w_class = WEIGHT_CLASS_TINY
var/scanmode = 1
name = "Chemistry Analyser"
desc = "A a electrode attached to a small circuit box that will tell you the pH of a solution. The screen currently displays nothing."
icon_state = "pHmeter"
icon = 'icons/obj/chemical.dmi'
resistance_flags = FLAMMABLE
w_class = WEIGHT_CLASS_TINY
var/scanmode = 1
/obj/item/fermichem/pHmeter/attack_self(mob/user)
if(!scanmode)
@@ -127,21 +127,21 @@
scanmode = 0
/obj/item/fermichem/pHmeter/afterattack(atom/A, mob/user, proximity)
. = ..()
if(!istype(A, /obj/item/reagent_containers))
return
var/obj/item/reagent_containers/cont = A
if(LAZYLEN(cont.reagents.reagent_list) == null)
return
var/out_message
to_chat(user, "<i>The chemistry meter beeps and displays:</i>")
out_message += "<span class='notice'><b>Total volume: [round(cont.volume, 0.01)] Total pH: [round(cont.reagents.pH, 0.1)]\n"
if(cont.reagents.fermiIsReacting)
out_message += "<span class='warning'>A reaction appears to be occuring currently.<span class='notice'>\n"
out_message += "Chemicals found in the beaker:</b>\n"
for(var/datum/reagent/R in cont.reagents.reagent_list)
out_message += "<b>[R.volume]u of [R.name]</b>, <b>Purity:</b> [R.purity], [(scanmode?"[(R.overdose_threshold?"<b>Overdose:</b> [R.overdose_threshold]u, ":"")][(R.addiction_threshold?"<b>Addiction:</b> [R.addiction_threshold]u, ":"")]<b>Base pH:</b> [R.pH].":".")]\n"
if(scanmode)
out_message += "<b>Analysis:</b> [R.description]\n"
to_chat(user, "[out_message]</span>")
desc = "An electrode attached to a small circuit box that will analyse a beaker. It can be toggled to give a reduced or extended report. The screen currently displays [round(cont.reagents.pH, 0.1)]."
. = ..()
if(!istype(A, /obj/item/reagent_containers))
return
var/obj/item/reagent_containers/cont = A
if(LAZYLEN(cont.reagents.reagent_list) == null)
return
var/out_message
to_chat(user, "<i>The chemistry meter beeps and displays:</i>")
out_message += "<span class='notice'><b>Total volume: [round(cont.volume, 0.01)] Total pH: [round(cont.reagents.pH, 0.1)]\n"
if(cont.reagents.fermiIsReacting)
out_message += "<span class='warning'>A reaction appears to be occuring currently.<span class='notice'>\n"
out_message += "Chemicals found in the beaker:</b>\n"
for(var/datum/reagent/R in cont.reagents.reagent_list)
out_message += "<b>[R.volume]u of [R.name]</b>, <b>Purity:</b> [R.purity], [(scanmode?"[(R.overdose_threshold?"<b>Overdose:</b> [R.overdose_threshold]u, ":"")][(R.addiction_threshold?"<b>Addiction:</b> [R.addiction_threshold]u, ":"")]<b>Base pH:</b> [R.pH].":".")]\n"
if(scanmode)
out_message += "<b>Analysis:</b> [R.description]\n"
to_chat(user, "[out_message]</span>")
desc = "An electrode attached to a small circuit box that will analyse a beaker. It can be toggled to give a reduced or extended report. The screen currently displays [round(cont.reagents.pH, 0.1)]."
@@ -1,41 +0,0 @@
/obj/structure/reagent_dispensers/keg
name = "keg"
desc = "A keg."
icon = 'modular_citadel/icons/obj/objects.dmi'
icon_state = "keg"
reagent_id = "water"
/obj/structure/reagent_dispensers/keg/mead
name = "keg of mead"
desc = "A keg of mead."
icon_state = "orangekeg"
reagent_id = "mead"
/obj/structure/reagent_dispensers/keg/aphro
name = "keg of aphrodisiac"
desc = "A keg of aphrodisiac."
icon_state = "pinkkeg"
reagent_id = "aphro"
/obj/structure/reagent_dispensers/keg/aphro/strong
name = "keg of strong aphrodisiac"
desc = "A keg of strong and addictive aphrodisiac."
reagent_id = "aphro+"
/obj/structure/reagent_dispensers/keg/milk
name = "keg of milk"
desc = "It's not quite what you were hoping for."
icon_state = "whitekeg"
reagent_id = "milk"
/obj/structure/reagent_dispensers/keg/semen
name = "keg of semen"
desc = "Dear lord, where did this even come from?"
icon_state = "whitekeg"
reagent_id = "semen"
/obj/structure/reagent_dispensers/keg/gargle
name = "keg of pan galactic gargleblaster"
desc = "A keg of... wow that's a long name."
icon_state = "bluekeg"
reagent_id = "gargleblaster"

Some files were not shown because too many files have changed in this diff Show More