Merge branch 'master' into Ghommie-cit367

This commit is contained in:
Lin
2019-12-31 22:37:59 +00:00
committed by GitHub
244 changed files with 3041 additions and 1886 deletions
+1 -1
View File
@@ -492,7 +492,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] assumed direct control of [M].</span>")
log_admin("[key_name(usr)] assumed direct control of [M].")
var/mob/adminmob = src.mob
M.ckey = src.ckey
adminmob.transfer_ckey(M, send_signal = FALSE)
if( isobserver(adminmob) )
qdel(adminmob)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Assume Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -3,6 +3,7 @@
icon = 'icons/mob/blob.dmi'
icon_state = "blob_shield"
desc = "A solid wall of slightly twitching tendrils."
var/damaged_desc = "A wall of twitching tendrils."
max_integrity = 150
brute_resist = 0.25
explosion_block = 3
@@ -21,10 +22,10 @@
/obj/structure/blob/shield/update_icon()
..()
if(obj_integrity <= 70)
icon_state = "blob_shield_damaged"
name = "weakened strong blob"
desc = "A wall of twitching tendrils."
if(obj_integrity < max_integrity * 0.5)
icon_state = "[initial(icon_state)]_damaged"
name = "weakened [initial(name)]"
desc = "[damaged_desc]"
atmosblock = FALSE
if(!weakened)
armor = armor.setRating("melee" = 15, "bullet" = 15, "laser" = 5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
@@ -37,4 +38,27 @@
if(weakened)
armor = armor.setRating("melee" = 25, "bullet" = 25, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
weakened = FALSE
air_update_turf(1)
air_update_turf(1)
/obj/structure/blob/shield/reflective
name = "reflective blob"
desc = "A solid wall of slightly twitching tendrils with a reflective glow."
damaged_desc = "A wall of twitching tendrils with a reflective glow."
icon_state = "blob_glow"
flags_1 = CHECK_RICOCHET_1
point_return = 8
max_integrity = 50
brute_resist = 1
explosion_block = 2
/obj/structure/blob/shield/reflective/handle_ricochet(obj/item/projectile/P)
var/turf/p_turf = get_turf(P)
var/face_direction = get_dir(src, p_turf)
var/face_angle = dir2angle(face_direction)
var/incidence_s = GET_ANGLE_OF_INCIDENCE(face_angle, (P.Angle + 180))
if(abs(incidence_s) > 90 && abs(incidence_s) < 270)
return FALSE
var/new_angle_s = SIMPLIFY_DEGREES(face_angle + incidence_s)
P.setAngle(new_angle_s)
visible_message("<span class='warning'>[P] reflects off [src]!</span>")
return TRUE
+14 -4
View File
@@ -113,12 +113,22 @@
/mob/camera/blob/verb/create_shield_power()
set category = "Blob"
set name = "Create Shield Blob (15)"
set desc = "Create a shield blob, which will block fire and is hard to kill."
set name = "Create/Upgrade Shield Blob (15)"
set desc = "Create a shield blob, which will block fire and is hard to kill. Using this on an existing shield blob turns it into a reflective blob, capable of reflecting most projectiles but making it much weaker than usual to brute attacks."
create_shield()
/mob/camera/blob/proc/create_shield(turf/T)
createSpecial(15, /obj/structure/blob/shield, 0, 0, T)
var/obj/structure/blob/shield/S = locate(/obj/structure/blob/shield) in T
if(S)
if(!can_buy(15))
return
if(S.obj_integrity < S.max_integrity * 0.5)
to_chat(src, "<span class='warning'>This shield blob is too damaged to be modified properly!</span>")
return
to_chat(src, "<span class='warning'>You secrete a reflective ooze over the shield blob, allowing it to reflect projectiles at the cost of reduced intregrity.</span>")
S.change_to(/obj/structure/blob/shield/reflective, src)
else
createSpecial(15, /obj/structure/blob/shield, 0, 0, T)
/mob/camera/blob/verb/create_resource()
set category = "Blob"
@@ -359,7 +369,7 @@
to_chat(src, "<b>You can expand, which will attack people, damage objects, or place a Normal Blob if the tile is clear.</b>")
to_chat(src, "<i>Normal Blobs</i> will expand your reach and can be upgraded into special blobs that perform certain functions.")
to_chat(src, "<b>You can upgrade normal blobs into the following types of blob:</b>")
to_chat(src, "<i>Shield Blobs</i> are strong and expensive blobs which take more damage. In additon, they are fireproof and can block air, use these to protect yourself from station fires.")
to_chat(src, "<i>Shield Blobs</i> are strong and expensive blobs which take more damage. In additon, they are fireproof and can block air, use these to protect yourself from station fires. Upgrading them again will result in a reflective blob, capable of reflecting most projectiles at the cost of the strong blob's extra health.")
to_chat(src, "<i>Resource Blobs</i> are blobs which produce more resources for you, build as many of these as possible to consume the station. This type of blob must be placed near node blobs or your core to work.")
to_chat(src, "<i>Factory Blobs</i> are blobs that spawn blob spores which will attack nearby enemies. This type of blob must be placed near node blobs or your core to work.")
to_chat(src, "<i>Blobbernauts</i> can be produced from factories for a cost, and are hard to kill, powerful, and moderately smart. The factory used to create one will become fragile and briefly unable to produce spores.")
@@ -183,7 +183,7 @@
BuyPower(new /datum/action/bloodsucker/masquerade)
BuyPower(new /datum/action/bloodsucker/veil)
// Traits
for (var/T in defaultTraits)
for(var/T in defaultTraits)
ADD_TRAIT(owner.current, T, "bloodsucker")
if(HAS_TRAIT(owner.current, TRAIT_TOXINLOVER)) //No slime bonuses here, no thank you
had_toxlover = TRUE
@@ -200,10 +200,10 @@
var/mob/living/carbon/human/H = owner.current
var/datum/species/S = H.dna.species
// Make Changes
S.brutemod *= 0.5 // <-------------------- Start small, but burn mod increases based on rank!
S.coldmod = 0
S.stunmod *= 0.25
S.siemens_coeff *= 0.75 //base electrocution coefficient 1
H.physiology.brute_mod *= 0.8 // <-------------------- Start small, but burn mod increases based on rank!
H.physiology.cold_mod = 0
H.physiology.stun_mod *= 0.35
H.physiology.siemens_coeff *= 0.75 //base electrocution coefficient 1
//S.heatmod += 0.5 // Heat shouldn't affect. Only Fire.
//S.punchstunthreshold = 8 //damage at which punches from this race will stun 9
S.punchdamagelow += 1 //lowest possible punch damage 0
@@ -319,12 +319,10 @@ datum/antagonist/bloodsucker/proc/SpendRank()
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
var/datum/species/S = H.dna.species
S.burnmod *= 0.025 // Slightly more burn damage
S.stunmod *= 0.95 // Slightly less stun time.
S.punchdamagelow += 0.5
S.punchdamagehigh += 0.5 // NOTE: This affects the hitting power of Brawn.
// More Health
owner.current.setMaxHealth(owner.current.maxHealth + 5)
owner.current.setMaxHealth(owner.current.maxHealth + 10)
// Vamp Stats
regenRate += 0.05 // Points of brute healed (starts at 0.3)
feedAmount += 2 // Increase how quickly I munch down vics (15)
@@ -275,7 +275,7 @@
// All done!
if(convert_progress <= 0)
// FAIL: Can't be Vassal
if(!SSticker.mode.can_make_vassal(target, user, display_warning=FALSE) && HAS_TRAIT(target, TRAIT_MINDSHIELD)) // If I'm an unconvertable Antag ONLY
if(!SSticker.mode.can_make_vassal(target, user, display_warning=FALSE) || HAS_TRAIT(target, TRAIT_MINDSHIELD)) // If I'm an unconvertable Antag ONLY
to_chat(user, "<span class='danger'>[target] doesn't respond to your persuasion. It doesn't appear they can be converted to follow you, they either have a mindshield or their external loyalties are too difficult for you to break.<i>\[ALT+click to release\]</span>")
convert_progress ++ // Pop it back up some. Avoids wasting Blood on a lost cause.
// SUCCESS: All done!
@@ -5,6 +5,14 @@
antagpanel_category = "ClownOp"
nukeop_outfit = /datum/outfit/syndicate/clownop
/datum/antagonist/nukeop/clownop/on_gain()
. = ..()
ADD_TRAIT(owner, TRAIT_CLOWN_MENTALITY, NUKEOP_ANTAGONIST)
/datum/antagonist/nukeop/clownop/on_removal()
REMOVE_TRAIT(owner, TRAIT_CLOWN_MENTALITY, NUKEOP_ANTAGONIST)
return ..()
/datum/antagonist/nukeop/leader/clownop
name = "Clown Operative Leader"
roundend_category = "clown operatives"
@@ -154,11 +154,6 @@
var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume)
var/target_temperature
var/target_heat_capacity
// first calculate heat from radiation. there's an implied "* 1 tick" here.
// 0.05 magic multiplicand is, first, 0.1 deciseconds; second, half of the radiation's going right back into the gas.
var/share_constant = STEFANBOLTZMANN*(share_volume**(2/3))*0.05
// Minimizing temp to 4 billion is mostly to prevent -infinity temperatures.
var/heat = share_constant*(min(air.temperature,4000000000)**4)
if(isopenturf(target))
@@ -170,8 +165,8 @@
if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
var/delta_temperature = air.temperature - target_temperature
heat -= share_constant*(min(target_temperature,4000000000)**4)
heat += thermal_conductivity*delta_temperature* \
var/heat = thermal_conductivity*delta_temperature* \
(partial_heat_capacity*target_heat_capacity/(partial_heat_capacity+target_heat_capacity))
air.temperature -= heat/total_heat_capacity
@@ -188,8 +183,7 @@
var/sharer_temperature_delta = 0
if((sharer_heat_capacity>0) && (partial_heat_capacity>0))
heat -= share_constant*(min(target_temperature,4000000000)**4)
heat += thermal_conductivity*delta_temperature* \
var/heat = thermal_conductivity*delta_temperature* \
(partial_heat_capacity*sharer_heat_capacity/(partial_heat_capacity+sharer_heat_capacity))
self_temperature_delta = -heat/total_heat_capacity
@@ -205,12 +199,10 @@
if((target.heat_capacity>0) && (partial_heat_capacity>0))
var/delta_temperature = air.temperature - target.temperature
heat -= share_constant*(min(target.temperature,4000000000)**4)
heat += thermal_conductivity*delta_temperature* \
var/heat = thermal_conductivity*delta_temperature* \
(partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
air.temperature -= heat/total_heat_capacity
air.temperature = CLAMP(air.temperature,TCMB,INFINITY) // i have no idea why TCMB needs to be the min but i ain't changing it
update = TRUE
/datum/pipeline/proc/return_air()
@@ -26,7 +26,9 @@
var/turf/T = loc
if(istype(T))
if(T.blocks_air)
if(islava(T))
environment_temperature = 5000
else if(T.blocks_air)
environment_temperature = T.temperature
else
var/turf/open/OT = T
+5 -1
View File
@@ -79,4 +79,8 @@
var/client_keysend_amount = 0
var/next_keysend_reset = 0
var/next_keysend_trip_reset = 0
var/keysend_tripped = FALSE
var/keysend_tripped = FALSE
// stops players from coming back through ghost/midround roles after suicide/cryo
// for a duration set by CONFIG_GET(number/suicide_reenter_round_timer) and CONFIG_GET(number/roundstart_suicide_time_limit)
var/reenter_round_timeout = 0
+52 -10
View File
@@ -245,6 +245,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<a href='?_src_=prefs;preference=tab;tab=2' [current_tab == 2 ? "class='linkOn'" : ""]>Character Appearance</a>"
dat += "<a href='?_src_=prefs;preference=tab;tab=3' [current_tab == 3 ? "class='linkOn'" : ""]>Loadout</a>"
dat += "<a href='?_src_=prefs;preference=tab;tab=1' [current_tab == 1 ? "class='linkOn'" : ""]>Game Preferences</a>"
dat += "<a href='?_src_=prefs;preference=tab;tab=4' [current_tab == 4 ? "class='linkOn'" : ""]>Content Preferences</a>"
if(!path)
dat += "<div class='notice'>Please create an account to save your preferences</div>"
@@ -721,13 +722,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
dat += "<h2>Clothing & Equipment</h2>"
dat += "<b>Underwear:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=underwear;task=input'>[underwear]</a>"
if(UNDIE_COLORABLE(GLOB.underwear_list[underwear]))
if(GLOB.underwear_list[underwear]?.has_color)
dat += "<b>Underwear Color:</b> <span style='border:1px solid #161616; background-color: #[undie_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=undie_color;task=input'>Change</a><BR>"
dat += "<b>Undershirt:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=undershirt;task=input'>[undershirt]</a>"
if(UNDIE_COLORABLE(GLOB.undershirt_list[undershirt]))
if(GLOB.undershirt_list[undershirt]?.has_color)
dat += "<b>Undershirt Color:</b> <span style='border:1px solid #161616; background-color: #[shirt_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=shirt_color;task=input'>Change</a><BR>"
dat += "<b>Socks:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=socks;task=input'>[socks]</a>"
if(UNDIE_COLORABLE(GLOB.socks_list[socks]))
if(GLOB.socks_list[socks]?.has_color)
dat += "<b>Socks Color:</b> <span style='border:1px solid #161616; background-color: #[socks_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=socks_color;task=input'>Change</a><BR>"
dat += "<b>Backpack:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a>"
dat += "<b>Jumpsuit:</b><BR><a href ='?_src_=prefs;preference=suit;task=input'>[jumpsuit_style]</a><BR>"
@@ -834,13 +835,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat +="<td width='300px' height='300px' valign='top'>"
dat += "<h2>Citadel Preferences</h2>" //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe.
dat += "<b>Arousal:</b><a href='?_src_=prefs;preference=arousable'>[arousable == TRUE ? "Enabled" : "Disabled"]</a><BR>"
dat += "<b>Voracious MediHound sleepers:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(cit_toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Lewdchem:</b><a href='?_src_=prefs;preference=lewdchem'>[lewdchem == TRUE ? "Enabled" : "Disabled"]</a><BR>"
dat += "<b>Widescreen:</b> <a href='?_src_=prefs;preference=widescreenpref'>[widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]</a><br>"
dat += "<b>Auto stand:</b> <a href='?_src_=prefs;preference=autostand'>[autostand ? "Enabled" : "Disabled"]</a><br>"
dat += "<b>Auto OOC:</b> <a href='?_src_=prefs;preference=auto_ooc'>[auto_ooc ? "Enabled" : "Disabled"]</a><br>"
dat += "<b>Screen Shake:</b> <a href='?_src_=prefs;preference=screenshake'>[(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]</a><br>"
if (user && user.client && !user.client.prefs.screenshake==0)
dat += "<b>Damage Screen Shake:</b> <a href='?_src_=prefs;preference=damagescreenshake'>[(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]</a><br>"
@@ -991,6 +988,26 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</font>"
dat += "</td><td><font size=2><i>[gear.description]</i></font></td></tr>"
dat += "</table>"
if(4) // Content preferences
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
dat += "<h2>Fetish content prefs</h2>"
dat += "<b>Arousal:</b><a href='?_src_=prefs;preference=arousable'>[arousable == TRUE ? "Enabled" : "Disabled"]</a><BR>"
dat += "<b>Voracious MediHound sleepers:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(cit_toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
dat += "<b>Forced Feminization:</b> <a href='?_src_=prefs;preference=feminization'>[(cit_toggles & FORCED_FEM) ? "Allowed" : "Disallowed"]</a><br>"
dat += "<b>Forced Masculinization:</b> <a href='?_src_=prefs;preference=masculinization'>[(cit_toggles & FORCED_MASC) ? "Allowed" : "Disallowed"]</a><br>"
dat += "<b>Lewd Hypno:</b> <a href='?_src_=prefs;preference=hypno'>[(cit_toggles & HYPNO) ? "Allowed" : "Disallowed"]</a><br>"
dat += "</td>"
dat +="<td width='300px' height='300px' valign='top'>"
dat += "<h2>Other content prefs</h2>"
dat += "<b>Breast Enlargement:</b> <a href='?_src_=prefs;preference=breast_enlargement'>[(cit_toggles & BREAST_ENLARGEMENT) ? "Allowed" : "Disallowed"]</a><br>"
dat += "<b>Penis Enlargement:</b> <a href='?_src_=prefs;preference=penis_enlargement'>[(cit_toggles & PENIS_ENLARGEMENT) ? "Allowed" : "Disallowed"]</a><br>"
dat += "<b>Hypno:</b> <a href='?_src_=prefs;preference=never_hypno'>[(cit_toggles & NEVER_HYPNO) ? "Disallowed" : "Allowed"]</a><br>"
dat += "<b>Aphrodisiacs:</b> <a href='?_src_=prefs;preference=aphro'>[(cit_toggles & NO_APHRO) ? "Disallowed" : "Allowed"]</a><br>"
dat += "<b>Ass Slapping:</b> <a href='?_src_=prefs;preference=ass_slap'>[(cit_toggles & NO_ASS_SLAP) ? "Disallowed" : "Allowed"]</a><br>"
dat += "<br>"
dat += "<hr><center>"
@@ -2036,8 +2053,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["genitals_use_skintone"] = !features["genitals_use_skintone"]
if("arousable")
arousable = !arousable
if("lewdchem")
lewdchem = !lewdchem
if("has_cock")
features["has_cock"] = !features["has_cock"]
if(features["has_cock"] == FALSE)
@@ -2069,6 +2084,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
user.client.change_view(CONFIG_GET(string/default_view))
if("autostand")
autostand = !autostand
if("auto_ooc")
auto_ooc = !auto_ooc
if ("screenshake")
var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, 200 = maximum.)", "Character Preference", screenshake) as null|num
if (!isnull(desiredshake))
@@ -2184,6 +2201,31 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("toggledigestionnoise")
cit_toggles ^= DIGESTION_NOISES
if("breast_enlargement")
cit_toggles ^= BREAST_ENLARGEMENT
if("penis_enlargement")
cit_toggles ^= PENIS_ENLARGEMENT
if("feminization")
cit_toggles ^= FORCED_FEM
if("masculinization")
cit_toggles ^= FORCED_MASC
if("hypno")
cit_toggles ^= HYPNO
if("never_hypno")
cit_toggles ^= NEVER_HYPNO
if("aphro")
cit_toggles ^= NO_APHRO
if("ass_slap")
cit_toggles ^= NO_ASS_SLAP
//END CITADEL EDIT
if("ambientocclusion")
+18 -3
View File
@@ -181,8 +181,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["widescreenpref"] >> widescreenpref
S["autostand"] >> autostand
S["cit_toggles"] >> cit_toggles
S["lewdchem"] >> lewdchem
S["preferred_chaos"] >> preferred_chaos
S["auto_ooc"] >> auto_ooc
//try to fix any outdated data if necessary
@@ -219,7 +219,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
autostand = sanitize_integer(autostand, 0, 1, initial(autostand))
cit_toggles = sanitize_integer(cit_toggles, 0, 65535, initial(cit_toggles))
auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc))
return 1
@@ -278,8 +278,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["widescreenpref"], widescreenpref)
WRITE_FILE(S["autostand"], autostand)
WRITE_FILE(S["cit_toggles"], cit_toggles)
WRITE_FILE(S["lewdchem"], lewdchem)
WRITE_FILE(S["preferred_chaos"], preferred_chaos)
WRITE_FILE(S["auto_ooc"], auto_ooc)
return 1
@@ -517,6 +517,21 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
all_quirks = SANITIZE_LIST(all_quirks)
for(var/V in all_quirks) // quirk migration
switch(V)
if("Acute hepatic pharmacokinesis")
DISABLE_BITFIELD(cit_toggles, PENIS_ENLARGEMENT)
DISABLE_BITFIELD(cit_toggles, BREAST_ENLARGEMENT)
ENABLE_BITFIELD(cit_toggles,FORCED_FEM)
ENABLE_BITFIELD(cit_toggles,FORCED_MASC)
all_quirks -= V
if("Crocin Immunity")
ENABLE_BITFIELD(cit_toggles,NO_APHRO)
all_quirks -= V
if("Buns of Steel")
ENABLE_BITFIELD(cit_toggles,NO_ASS_SLAP)
all_quirks -= V
cit_character_pref_load(S)
return 1
+27
View File
@@ -298,6 +298,33 @@ BLIND // can't see anything
user.regenerate_icons()
return TRUE
/obj/item/clothing/neck/AltClick(mob/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
// Polychrome stuff:
if(hasprimary | hassecondary | hastertiary)
var/choice = input(user,"polychromic thread options", "Clothing Recolor") as null|anything in list("[hasprimary ? "Primary Color" : ""]", "[hassecondary ? "Secondary Color" : ""]", "[hastertiary ? "Tertiary Color" : ""]") //generates a list depending on the enabled overlays
switch(choice) //Lets the list's options actually lead to something
if("Primary Color")
var/primary_color_input = input(usr,"","Choose Primary Color",primary_color) as color|null //color input menu, the "|null" adds a cancel button to it.
if(primary_color_input) //Checks if the color selected is NULL, rejects it if it is NULL.
primary_color = sanitize_hexcolor(primary_color_input, desired_format=6, include_crunch=1) //formats the selected color properly
update_icon() //updates the item icon
user.regenerate_icons() //updates the worn icon. Probably a bad idea, but it works.
if("Secondary Color")
var/secondary_color_input = input(usr,"","Choose Secondary Color",secondary_color) as color|null
if(secondary_color_input)
secondary_color = sanitize_hexcolor(secondary_color_input, desired_format=6, include_crunch=1)
update_icon()
user.regenerate_icons()
if("Tertiary Color")
var/tertiary_color_input = input(usr,"","Choose Tertiary Color",tertiary_color) as color|null
if(tertiary_color_input)
tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1)
update_icon()
user.regenerate_icons()
return TRUE
/obj/item/clothing/under/verb/jumpsuit_adjust()
set name = "Adjust Jumpsuit Style"
@@ -54,6 +54,9 @@
H.blur_eyes(5)
eyes.applyOrganDamage(5)
/obj/item/clothing/glasses/proc/ranged_attack(mob/living/carbon/human/user,atom/A, params)
return FALSE
/obj/item/clothing/glasses/meson
name = "optical meson scanner"
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions."
@@ -0,0 +1,15 @@
/obj/item/clothing/glasses/hud/security/sunglasses/disablers
name = "true stunglasses"
desc = "Made for only the best of shitsec. Wear 'em like you're gonna robust all of those fuckers."
var/beamtype = /obj/item/projectile/beam/disabler //change for adminbus
/obj/item/clothing/glasses/hud/security/sunglasses/disablers/ranged_attack(mob/living/carbon/human/user,atom/A, params)
user.changeNext_move(CLICK_CD_RANGE)
var/obj/item/projectile/beam/disabler/LE = new beamtype( loc )
playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1)
LE.firer = src
LE.def_zone = user.get_organ_target()
LE.preparePixelProjectile(A, src, params)
LE.fire()
return TRUE
//shamelessly copied
@@ -90,7 +90,7 @@
for(var/i in rad_places)
var/turf/place = i
if(get_dist(user, place) >= range*2) //Rads are easier to see than wires under the floor
if(get_dist(user, place) >= range*8) //Rads are easier to see than wires under the floor
continue
var/strength = round(rad_places[i] / 1000, 0.1)
var/image/pic = new(loc = place)
@@ -139,7 +139,6 @@
item_state = "trayson-t-ray"
desc = "Used by engineering staff to see underfloor objects such as cables and pipes."
range = 2
modes = list(MODE_NONE = MODE_TRAY, MODE_TRAY = MODE_NONE)
/obj/item/clothing/glasses/meson/engine/tray/prescription
@@ -152,7 +151,6 @@
icon_state = "trayson-shuttle"
item_state = "trayson-shuttle"
desc = "Used to see the boundaries of shuttle regions."
modes = list(MODE_NONE = MODE_SHUTTLE, MODE_SHUTTLE = MODE_NONE)
#undef MODE_NONE
+2 -2
View File
@@ -89,12 +89,12 @@
/obj/item/clothing/shoes/clown_shoes/equipped(mob/user, slot)
. = ..()
if(user.mind && user.mind.assigned_role == "Clown")
if(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY))
SEND_SIGNAL(user, COMSIG_CLEAR_MOOD_EVENT, "noshoes")
/obj/item/clothing/shoes/clown_shoes/dropped(mob/user)
. = ..()
if(user.mind && user.mind.assigned_role == "Clown")
if(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY))
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "noshoes", /datum/mood_event/noshoes)
/obj/item/clothing/shoes/clown_shoes/jester
+1 -1
View File
@@ -13,7 +13,7 @@
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(!(HAS_TRAIT(H, TRAIT_CLUMSY)) && !(H.mind && H.mind.assigned_role == "Clown"))
if(!(HAS_TRAIT(H, TRAIT_CLUMSY)) && !(H.mind && HAS_TRAIT(H.mind, TRAIT_CLOWN_MENTALITY)))
return
if(slot == SLOT_SHOES)
spells = new
+1 -2
View File
@@ -590,8 +590,7 @@
/obj/item/clothing/suit/space/hardsuit/clown/mob_can_equip(mob/M, slot)
if(!..() || !ishuman(M))
return FALSE
var/mob/living/carbon/human/H = M
if(H.mind.assigned_role == "Clown")
if(M.mind && HAS_TRAIT(M.mind, TRAIT_CLOWN_MENTALITY))
return TRUE
else
return FALSE
@@ -467,6 +467,33 @@
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/sundresswhite
name = "white sundress"
desc = "Makes you want to frolic in a field of lillies."
icon_state = "sundress_white"
item_color = "sundress_white"
body_parts_covered = CHEST|GROIN
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/greendress
name = "green dress"
desc = "A tight green dress"
icon_state = "dress_green"
item_color = "dress_green"
body_parts_covered = CHEST|GROIN
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/pinkdress
name = "pink dress"
desc = "A tight pink dress"
icon_state = "dress_pink"
item_color = "dress_pink"
body_parts_covered = CHEST|GROIN
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/captainparade
name = "captain's parade uniform"
desc = "A captain's luxury-wear, for special occasions."
@@ -509,6 +536,24 @@
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/westernbustle
name = "western bustle dress"
desc = "Filled with Western fire."
icon_state = "western_bustle"
item_state = "wcoat"
item_color = "western_bustle"
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/flamenco
name = "flamenco dress"
desc = "Filled with Latin fire."
icon_state = "flamenco"
item_state = "wcoat"
item_color = "flamenco"
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/stripeddress
name = "striped dress"
desc = "Fashion in space."
@@ -529,6 +574,44 @@
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/flowerdress
name = "flower dress"
desc = "Lovely dress"
icon_state = "flower_dress"
item_state = "sailordress"
item_color = "flower_dress"
body_parts_covered = CHEST|GROIN
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/sweptskirt
name = "swept skirt"
desc = "Formal skirt"
icon_state = "skirt_swept"
item_color = "skirt_swept"
body_parts_covered = GROIN
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/corset
name = "black corset"
desc = "Nanotrasen is not resposible for any organ damage"
icon_state = "corset"
item_color = "corset"
body_parts_covered = CHEST|GROIN
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/croptop
name = "crop top"
desc = "We've saved money by giving you half a shirt!"
icon_state = "sailor_dress"
item_state = "sailordress"
item_color = "sailor_dress"
body_parts_covered = CHEST|GROIN|ARMS
fitted = FEMALE_UNIFORM_TOP
can_adjust = FALSE
/obj/item/clothing/under/redeveninggown
name = "red evening gown"
desc = "Fancy dress for space bar singers."
+31
View File
@@ -75,3 +75,34 @@
desc = "A pair of woodland camouflage pants. Probably not the best choice for a space station."
icon_state = "camopants"
item_color = "camopants"
/obj/item/clothing/under/pants/jeanripped
name = "ripped jeans"
desc = "If you're wearing this you're poor or a rebel"
icon_state = "jean_ripped"
item_color = "jean_ripped"
/obj/item/clothing/under/pants/jeanshort
name = "jean shorts"
desc = "These are really just jeans cut in half"
icon_state = "jean_shorts"
item_color = "jean_shorts"
/obj/item/clothing/under/pants/denimskirt
name = "denim skirt"
desc = "These are really just a jean leg hole cut from a pair"
icon_state = "denim_skirt"
item_color = "denim_skirt"
/obj/item/clothing/under/pants/chaps
name = "black chaps"
body_parts_covered = LEGS
desc = "Yeehaw"
icon_state = "chaps"
item_color = "chaps"
/obj/item/clothing/under/pants/yoga
name = "yoga pants"
desc = "Comfy!"
icon_state = "yoga_pants"
item_color = "yoga_pants"
@@ -358,3 +358,11 @@
time = 100
category = CAT_MISC
always_availible = FALSE // Disabled til learned
/datum/crafting_recipe/coconut_bong
name = "Coconut Bong"
result = /obj/item/bong/coconut
reqs = list(/obj/item/stack/sheet/mineral/bamboo = 2,
/obj/item/reagent_containers/food/snacks/grown/coconut = 1)
time = 70
category = CAT_MISC
+2
View File
@@ -37,6 +37,8 @@
continue
if(!H.client)
continue
if(HAS_TRAIT(H,TRAIT_EXEMPT_HEALTH_EVENTS))
continue
if(H.stat == DEAD)
continue
if(HAS_TRAIT(H, TRAIT_VIRUSIMMUNE)) //Don't pick someone who's virus immune, only for it to not do anything.
+1 -1
View File
@@ -9,7 +9,7 @@
/datum/round_event/heart_attack/start()
var/list/heart_attack_contestants = list()
for(var/mob/living/carbon/human/H in shuffle(GLOB.player_list))
if(!H.client || H.stat == DEAD || H.InCritical() || !H.can_heartattack() || H.has_status_effect(STATUS_EFFECT_EXERCISED) || (/datum/disease/heart_failure in H.diseases) || H.undergoing_cardiac_arrest())
if(!H.client || H.stat == DEAD || H.InCritical() || !H.can_heartattack() || H.has_status_effect(STATUS_EFFECT_EXERCISED) || (/datum/disease/heart_failure in H.diseases) || H.undergoing_cardiac_arrest() || HAS_TRAIT(H,TRAIT_EXEMPT_HEALTH_EVENTS))
continue
if(H.satiety <= -60) //Multiple junk food items recently
heart_attack_contestants[H] = 3
@@ -35,4 +35,6 @@
/datum/hallucination/delusion,
/datum/hallucination/oh_yeah)
for(var/mob/living/carbon/C in GLOB.alive_mob_list)
if (HAS_TRAIT(C,TRAIT_EXEMPT_HEALTH_EVENTS))
continue
new picked_hallucination(C, TRUE)
@@ -15,6 +15,8 @@
continue
if(H.stat == DEAD)
continue
if (HAS_TRAIT(H,TRAIT_EXEMPT_HEALTH_EVENTS))
continue
if(!H.getorgan(/obj/item/organ/appendix)) //Don't give the disease to some who lacks it, only for it to be auto-cured
continue
if(!(MOB_ORGANIC in H.mob_biotypes)) //biotype sleeper bugs strike again, once again making appendicitis pick a target that can't take it
@@ -609,4 +609,68 @@
filling_color = "#ECA735"
tastes = list("fried corn" = 1)
foodtype = JUNKFOOD | FRIED
dunkable = TRUE
dunkable = TRUE
/obj/item/reagent_containers/food/snacks/marshmallow
name = "marshmallow"
desc = "A marshmallow filled with fluffy marshmallow fluff."
icon_state = "marshmallow"
list_reagents = list("sugar" = 5, "nutriment" = 2)
filling_color = "#fafafa"
w_class = WEIGHT_CLASS_TINY
tastes = list("marshmallow" = 2)
foodtype = SUGAR | JUNKFOOD
var/burned = 0
/obj/item/reagent_containers/food/snacks/marshmallow/attackby(obj/item/I, mob/user)
switch (I.get_temperature())
if (355 to 1500)
if (prob(30))
burnmallow()
if (1500 to 2000)
if (prob(50))
burnmallow()
else
burnmallow(TRUE)
if (2000 to 3000)
if (prob(10))
burnmallow()
else
burnmallow(TRUE)
if (3000 to INFINITY)
burnmallow(TRUE)
return ..()
/obj/item/reagent_containers/food/snacks/marshmallow/proc/burnmallow(reallyburned = FALSE)
if (reallyburned && burned == 1)
icon_state = "marshmallowrburned"
else if (burned == 0)
icon_state = "marshmallowburned"
/obj/item/reagent_containers/food/snacks/marshmallow/examine(mob/user)
. = ..()
if (burned == 2)
. += "It looks very burned."
if (burned == 1)
. += "It looks just right for eating!"
/obj/item/reagent_containers/food/snacks/marshmallow/fire_act(temp,volume)
switch (temp)
if (355 to 1500)
if (prob(30))
burnmallow()
if (1500 to 2000)
if (prob(50))
burnmallow()
else
burnmallow(TRUE)
if (2000 to 3000)
if (prob(10))
burnmallow()
else
burnmallow(TRUE)
if (3000 to 7000)
burnmallow(TRUE)
if (7000 to INFINITY)
burn()
..()
+1 -1
View File
@@ -240,7 +240,7 @@
dat += "</table>"
else
dat += "No trait-related genes detected in sample.<br>"
if(can_insert && istype(disk.gene, /datum/plant_gene/trait))
if(can_insert && istype(disk.gene, /datum/plant_gene/trait) && !seed.is_gene_forbidden(disk.gene.type))
dat += "<a href='?src=[REF(src)];op=insert'>Insert: [disk.gene.get_name()]</a>"
dat += "</div>"
else
@@ -27,7 +27,7 @@
bitesize_mod = 2
var/stacktype = /obj/item/stack/tile/grass
var/tile_coefficient = 0.02 // 1/50
wine_power = 15
distill_reagent = /datum/reagent/consumable/ethanol/beer/light
/obj/item/reagent_containers/food/snacks/grown/grass/attack_self(mob/user)
to_chat(user, "<span class='notice'>You prepare the astroturf.</span>")
+277 -1
View File
@@ -232,7 +232,7 @@
/obj/item/reagent_containers/food/snacks/grown/cherry_bomb/proc/detonate()
reagents.chem_temp = 1000 //Sets off the black powder
reagents.handle_reactions()
// Lavaland cactus
/obj/item/seeds/lavaland/cactus
@@ -244,3 +244,279 @@
product = /obj/item/reagent_containers/food/snacks/grown/ash_flora/cactus_fruit
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
growthstages = 2
// Coconut
/obj/item/seeds/coconut
name = "pack of coconut seeds"
desc = "They're seeds that grow into coconut palm trees."
icon_state = "seed-coconut"
species = "coconut"
plantname = "Coconut Palm Tree"
product = /obj/item/reagent_containers/food/snacks/grown/coconut
lifespan = 50
endurance = 30
potency = 35
growing_icon = 'icons/obj/hydroponics/growing.dmi'
icon_dead = "coconut-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest)
forbiddengenes = list(/datum/plant_gene/trait/squash, /datum/plant_gene/trait/stinging)
reagents_add = list("coconutmilk" = 0.3)
/obj/item/reagent_containers/food/snacks/grown/coconut
seed = /obj/item/seeds/coconut
name = "coconut"
desc = "Hard shell of a nut containing delicious milk inside. Perhaps try using something sharp?"
icon_state = "coconut"
item_state = "coconut"
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
spillable = FALSE
resistance_flags = ACID_PROOF
volume = 150 //so it won't cut reagents despite having the capacity for them
w_class = WEIGHT_CLASS_SMALL
force = 5
throwforce = 5
hitsound = 'sound/weapons/klonk.ogg'
attack_verb = list("klonked", "donked", "bonked")
var/opened = FALSE
var/carved = FALSE
var/chopped = FALSE
var/straw = FALSE
var/fused = FALSE
var/fusedactive = FALSE
var/defused = FALSE
/obj/item/reagent_containers/food/snacks/grown/coconut/Initialize(mapload, obj/item/seeds/new_seed)
. = ..()
var/newvolume = 50 + round(seed.potency,10)
if (seed.get_gene(/datum/plant_gene/trait/maxchem))
newvolume = newvolume + 50
volume = newvolume
reagents.maximum_volume = newvolume
reagents.update_total()
transform *= TRANSFORM_USING_VARIABLE(40, 100) + 0.5 //temporary fix for size?
/obj/item/reagent_containers/food/snacks/grown/coconut/attack_self(mob/user)
if (!opened)
return
if(!possible_transfer_amounts.len)
return
var/i=0
for(var/A in possible_transfer_amounts)
i++
if(A != amount_per_transfer_from_this)
continue
if(i<possible_transfer_amounts.len)
amount_per_transfer_from_this = possible_transfer_amounts[i+1]
else
amount_per_transfer_from_this = possible_transfer_amounts[1]
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
return
/obj/item/reagent_containers/food/snacks/grown/coconut/attackby(obj/item/W, mob/user, params)
//DEFUSING NADE LOGIC
if (W.tool_behaviour == TOOL_WIRECUTTER && fused)
user.show_message("<span class='notice'>You cut the fuse!</span>", MSG_VISUAL)
playsound(user, W.hitsound, 50, 1, -1)
icon_state = "coconut_carved"
desc = "A coconut. This one's got a hole in it."
name = "coconut"
defused = TRUE
fused = FALSE
fusedactive = FALSE
if(!seed.get_gene(/datum/plant_gene/trait/glow))
set_light(0, 0.0)
return
//IGNITING NADE LOGIC
if(!fusedactive && fused)
var/lighting_text = W.ignition_effect(src, user)
if(lighting_text)
user.visible_message("<span class='warning'>[user] ignites [src]'s fuse!</span>", "<span class='userdanger'>You ignite the [src]'s fuse!</span>")
fusedactive = TRUE
defused = FALSE
playsound(src, 'sound/effects/fuse.ogg', 100, 0)
message_admins("[ADMIN_LOOKUPFLW(user)] ignited a coconut bomb for detonation at [ADMIN_VERBOSEJMP(user)] [pretty_string_from_reagent_list(reagents.reagent_list)]")
log_game("[key_name(user)] primed a coconut grenade for detonation at [AREACOORD(user)].")
addtimer(CALLBACK(src, .proc/prime), 5 SECONDS)
icon_state = "coconut_grenade_active"
desc = "RUN!"
if(!seed.get_gene(/datum/plant_gene/trait/glow))
light_color = "#FFCC66" //for the fuse
set_light(3, 0.8)
return
//ADDING A FUSE, NADE LOGIC
if (istype(W,/obj/item/stack/sheet/cloth) || istype(W,/obj/item/stack/sheet/durathread))
if (carved && !straw && !fused)
user.show_message("<span class='notice'>You add a fuse to the coconut!</span>", 1)
W.use(1)
fused = TRUE
icon_state = "coconut_grenade"
desc = "A makeshift bomb made out of a coconut. You estimate the fuse is long enough for 5 seconds."
name = "coconut bomb"
return
//ADDING STRAW LOGIC
if (istype(W,/obj/item/stack/sheet/mineral/bamboo) && opened && !straw && fused)
user.show_message("<span class='notice'>You add a bamboo straw to the coconut!</span>", 1)
straw = TRUE
W.use(1)
icon_state += "_straw"
desc = "You can already feel like you're on a tropical vacation."
return
//OPENING THE NUT LOGIC
if (!carved && !chopped)
var/screwdrivered = W.tool_behaviour == TOOL_SCREWDRIVER
if(screwdrivered || W.sharpness)
user.show_message("<span class='notice'>You [screwdrivered ? "make a hole in the coconut" : "slice the coconut open"]!</span>", 1)
carved = TRUE
opened = TRUE
spillable = !screwdrivered
reagent_flags = OPENCONTAINER
ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
icon_state = screwdrivered ? "coconut_carved" : "coconut_chopped"
desc = "A coconut. [screwdrivered ? "This one's got a hole in it" : "This one's sliced open, with all its delicious contents for your eyes to savour"]."
playsound(user, W.hitsound, 50, 1, -1)
return
return ..()
/obj/item/reagent_containers/food/snacks/grown/coconut/attack(mob/living/M, mob/user, obj/target)
if(M && user.a_intent == INTENT_HARM && !spillable)
var/obj/item/bodypart/affecting = user.zone_selected //Find what the player is aiming at
if (affecting == BODY_ZONE_HEAD && prob(15))
//smash the nut open
var/armor_block = min(90, M.run_armor_check(affecting, "melee", null, null,armour_penetration)) // For normal attack damage
M.apply_damage(force, BRUTE, affecting, armor_block)
//Sound
playsound(user, hitsound, 100, 1, -1)
//Attack logs
log_combat(user, M, "attacked", src)
//Display an attack message.
if(M != user)
M.visible_message("<span class='danger'>[user] has cracked open a [name] on [M]'s head!</span>", \
"<span class='userdanger'>[user] has cracked open a [name] on [M]'s head!</span>")
else
user.visible_message("<span class='danger'>[M] cracks open a [name] on their [M.p_them()] head!</span>", \
"<span class='userdanger'>[M] cracks open a [name] on [M.p_their()] head!</span>")
//The coconut breaks open so splash its reagents
spillable = TRUE
SplashReagents(M)
//Lastly we remove the nut
qdel(src)
else
. = ..()
return
if(fusedactive)
return
if(!opened)
return
if(!canconsume(M, user))
return
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
if(user.a_intent == INTENT_HARM && spillable)
var/R
M.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [M]!</span>", \
"<span class='userdanger'>[user] splashes the contents of [src] onto [M]!</span>")
if(reagents)
for(var/datum/reagent/A in reagents.reagent_list)
R += A.id + " ("
R += num2text(A.volume) + "),"
if(isturf(target) && reagents.reagent_list.len && thrownby)
log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]")
message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].")
reagents.reaction(M, TOUCH)
log_combat(user, M, "splashed", R)
reagents.clear_reagents()
else
if(M != user)
M.visible_message("<span class='danger'>[user] attempts to feed something to [M].</span>", \
"<span class='userdanger'>[user] attempts to feed something to you.</span>")
if(!do_mob(user, M))
return
if(!reagents || !reagents.total_volume)
return // The drink might be empty after the delay, such as by spam-feeding
M.visible_message("<span class='danger'>[user] feeds something to [M].</span>", "<span class='userdanger'>[user] feeds something to you.</span>")
log_combat(user, M, "fed", reagents.log_list())
else
to_chat(user, "<span class='notice'>You swallow a gulp of [src].</span>")
var/fraction = min(5/reagents.total_volume, 1)
reagents.reaction(M, INGEST, fraction)
addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5), 5)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
/obj/item/reagent_containers/food/snacks/grown/coconut/afterattack(obj/target, mob/user, proximity)
. = ..()
if(fusedactive)
return
if((!proximity) || !check_allowed_items(target,target_self=1))
return
if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
if(target.reagents.holder_full())
to_chat(user, "<span class='warning'>[target] is full.</span>")
return
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>")
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty and can't be refilled!</span>")
return
if(reagents.holder_full())
to_chat(user, "<span class='warning'>[src] is full.</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] unit\s of the contents of [target].</span>")
else if(reagents.total_volume)
if(user.a_intent == INTENT_HARM && spillable == TRUE)
user.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [target]!</span>", \
"<span class='notice'>You splash the contents of [src] onto [target].</span>")
reagents.reaction(target, TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/food/snacks/grown/coconut/dropped(mob/user)
. = ..()
transform *= TRANSFORM_USING_VARIABLE(40, 100) + 0.5 //temporary fix for size?
/obj/item/reagent_containers/food/snacks/grown/coconut/proc/prime()
if (defused)
return
var/turf/T = get_turf(src)
reagents.chem_temp = 1000
//Disable seperated contents when the grenade primes
if (seed.get_gene(/datum/plant_gene/trait/noreact))
DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
reagents.handle_reactions()
log_game("Coconut bomb detonation at [AREACOORD(T)], location [loc]")
qdel(src)
/obj/item/reagent_containers/food/snacks/grown/coconut/ex_act(severity)
qdel(src)
/obj/item/reagent_containers/food/snacks/grown/coconut/deconstruct(disassembled = TRUE)
if(!disassembled && fused)
prime()
if(!QDELETED(src))
qdel(src)
+6 -1
View File
@@ -27,6 +27,7 @@
var/rarity = 0 // How rare the plant is. Used for giving points to cargo when shipping off to CentCom.
var/list/mutatelist = list() // The type of plants that this plant can mutate into.
var/list/genes = list() // Plant genes are stored here, see plant_genes.dm for more info.
var/list/forbiddengenes = list()
var/list/reagents_add = list()
// A list of reagents to add to product.
// Format: "reagent_id" = potency multiplier
@@ -96,6 +97,10 @@
S.reagents_add = reagents_add.Copy() // Faster than grabbing the list from genes.
return S
obj/item/seeds/proc/is_gene_forbidden(typepath)
return (typepath in forbiddengenes)
/obj/item/seeds/proc/get_gene(typepath)
return (locate(typepath) in genes)
@@ -448,7 +453,7 @@
for(var/i in 1 to amount_random_traits)
var/random_trait = pick((subtypesof(/datum/plant_gene/trait)-typesof(/datum/plant_gene/trait/plant_type)))
var/datum/plant_gene/trait/T = new random_trait
if(T.can_add(src))
if(T.can_add(src) && !is_gene_forbidden(random_trait))
genes += T
else
qdel(T)
+2
View File
@@ -14,6 +14,8 @@
access = list(ACCESS_THEATRE)
minimal_access = list(ACCESS_THEATRE)
mind_traits = list(TRAIT_CLOWN_MENTALITY)
display_order = JOB_DISPLAY_ORDER_CLOWN
/datum/outfit/job/clown
@@ -74,4 +74,5 @@
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
var/has_color = FALSE
var/has_color = FALSE
var/has_digitigrade = FALSE
@@ -2,6 +2,9 @@
// Socks Definitions //
///////////////////////
/datum/sprite_accessory/underwear/socks
has_digitigrade = TRUE
/datum/sprite_accessory/underwear/socks/nude
name = "Nude"
icon_state = null
@@ -28,41 +28,49 @@
name = "Boxers"
icon_state = "boxers"
has_color = TRUE
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_bee
name = "Boxers - Bee"
icon_state = "bee_shorts"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_hearts
name = "Boxers - Heart"
icon_state = "boxers_heart"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_stripe
name = "Boxers - Striped"
icon_state = "boxers_striped"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_commie
name = "Boxers - Striped Communist"
icon_state = "boxers_commie"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_usastripe
name = "Boxers - Striped Freedom"
icon_state = "boxers_assblastusa"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/male_uk
name = "Boxers - Striped UK"
icon_state = "boxers_uk"
has_digitigrade = TRUE
gender = MALE
/datum/sprite_accessory/underwear/bottom/boxer_briefs
name = "Boxer Briefs"
icon_state = "boxer_briefs"
has_digitigrade = TRUE
has_color = TRUE
/datum/sprite_accessory/underwear/bottom/panties
@@ -140,6 +148,7 @@
/datum/sprite_accessory/underwear/bottom/longjon
name = "Long John Bottoms"
icon_state = "ljonb"
has_digitigrade = TRUE
has_color = TRUE
/datum/sprite_accessory/underwear/bottom/swimsuit_red
+3
View File
@@ -18,3 +18,6 @@
update_icon(preferred_form)
updateghostimages()
client.reenter_round_timeout = max(client.reenter_round_timeout, clientless_round_timeout)
clientless_round_timeout = client.reenter_round_timeout
+17 -11
View File
@@ -3,8 +3,6 @@ GLOBAL_LIST_EMPTY(ghost_images_simple) //this is a list of all ghost images as t
GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
#define CANT_REENTER_ROUND -1
/mob/dead/observer
name = "ghost"
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
@@ -21,7 +19,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
hud_type = /datum/hud/ghost
movement_type = GROUND | FLYING
var/can_reenter_corpse
var/reenter_round_timeout = 0 // used to prevent people from coming back through ghost roles/midround antags as they suicide/cryo for a duration set by CONFIG_GET(number/suicide_reenter_round_timer) and CONFIG_GET(number/roundstart_suicide_time_limit)
var/clientless_round_timeout = 0 //mobs will lack a client as long as their player is disconnected. See client_defines.dm "reenter_round_timeout"
var/datum/hud/living/carbon/hud = null // hud
var/bootime = 0
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
@@ -278,9 +276,16 @@ Works together with spawning an observer, noted above.
if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
penalty += roundstart_quit_limit - world.time
if(penalty)
ghost.reenter_round_timeout = world.realtime + penalty
if(ghost.reenter_round_timeout - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
ghost.reenter_round_timeout = CANT_REENTER_ROUND
penalty += world.realtime
if(penalty - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
if(client)
client.reenter_round_timeout = penalty
else //A disconnected player (quite likely for cryopods)
ghost.clientless_round_timeout = penalty
if (client && client.prefs && client.prefs.auto_ooc)
if (!(client.prefs.chat_toggles & CHAT_OOC))
client.prefs.chat_toggles ^= CHAT_OOC
transfer_ckey(ghost, FALSE)
return ghost
@@ -339,10 +344,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
ghostize(0, penalize = TRUE)
/mob/dead/observer/proc/can_reenter_round(silent = FALSE)
if(reenter_round_timeout != CANT_REENTER_ROUND && reenter_round_timeout <= world.realtime)
var/timeout = clientless_round_timeout
if(client)
timeout = client.reenter_round_timeout
if(timeout != CANT_REENTER_ROUND && timeout <= world.realtime)
return TRUE
if(!silent)
to_chat(src, "<span class='warning'>You are unable to reenter the round[reenter_round_timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(reenter_round_timeout - world.realtime)]" : ""].</span>")
if(!silent && client)
to_chat(src, "<span class='warning'>You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].</span>")
return FALSE
/mob/dead/observer/Move(NewLoc, direct)
@@ -898,5 +906,3 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
spawners_menu = new(src)
spawners_menu.ui_interact(src)
#undef CANT_REENTER_ROUND
@@ -103,15 +103,17 @@
new_xeno.notransform = 0
new_xeno.invisibility = 0
var/mob/living/carbon/old_owner = owner
if(kill_on_sucess) //ITS TOO LATE
new_xeno.visible_message("<span class='danger'>[new_xeno] bursts out of [owner]!</span>", "<span class='userdanger'>You exit [owner], your previous host.</span>", "<span class='italics'>You hear organic matter ripping and tearing!</span>")
owner.apply_damage(rand(100,300),BRUTE,zone,FALSE) //Random high damage to torso so health sensors don't metagame.
owner.spill_organs(TRUE,FALSE,TRUE) //Lets still make the death gruesome and impossible to just simply defib someone.
var/obj/item/bodypart/B = owner.get_bodypart(zone)
B.drop_organs(owner) //Lets still make the death gruesome and impossible to just simply defib someone.
owner.death(FALSE) //Just in case some freak occurance occurs where you somehow survive all your organs being removed from you and the 100-300 brute damage.
else //When it is removed via surgery at a late stage, rather than forced.
new_xeno.visible_message("<span class='danger'>[new_xeno] wriggles out of [owner]!</span>", "<span class='userdanger'>You exit [owner], your previous host.</span>")
owner.adjustBruteLoss(40)
owner.cut_overlay(overlay)
old_owner.cut_overlay(overlay)
qdel(src)
File diff suppressed because it is too large Load Diff
@@ -308,7 +308,7 @@
var/obj/item/organ/vocal_cords/Vc = user.getorganslot(ORGAN_SLOT_VOICE)
if(Vc)
if(istype(Vc, /obj/item/organ/vocal_cords/velvet))
if(client?.prefs.lewdchem)
if(client.prefs.cit_toggles & HYPNO)
msg += "<span class='velvet'><i>You feel your chords resonate looking at them.</i></span>\n"
@@ -580,7 +580,7 @@
if(mind)
if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") )
gain = 100
if(mind.assigned_role == "Clown")
if(HAS_TRAIT(mind, TRAIT_CLOWN_MENTALITY))
gain = rand(-300, 300)
investigate_log("([key_name(src)]) has been consumed by the singularity.", INVESTIGATE_SINGULO) //Oh that's where the clown ended up!
gib()
+24 -30
View File
@@ -545,6 +545,20 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//Underwear, Undershirts & Socks
if(!(NO_UNDERWEAR in species_traits))
if(H.socks && H.get_num_legs(FALSE) >= 2)
if(H.hidden_socks)
H.socks = "Nude"
else
H.socks = H.saved_socks
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
if(S)
var/digilegs = ((DIGITIGRADE in species_traits) && S.has_digitigrade) ? "_d" : ""
var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
if(S.has_color)
MA.color = "#[H.socks_color]"
standing += MA
if(H.underwear)
if(H.hidden_underwear)
H.underwear = "Nude"
@@ -552,8 +566,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.underwear = H.saved_underwear
var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
if(B)
var/mutable_appearance/MA = mutable_appearance(B.icon, B.icon_state, -BODY_LAYER)
if(UNDIE_COLORABLE(B))
var/digilegs = ((DIGITIGRADE in species_traits) && B.has_digitigrade) ? "_d" : ""
var/mutable_appearance/MA = mutable_appearance(B.icon, "[B.icon_state][digilegs]", -BODY_LAYER)
if(B.has_color)
MA.color = "#[H.undie_color]"
standing += MA
@@ -564,28 +579,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.undershirt = H.saved_undershirt
var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
if(T)
var/state = "[T.icon_state][((DIGITIGRADE in species_traits) && T.has_digitigrade) ? "_d" : ""]"
var/mutable_appearance/MA
if(H.dna.species.sexes && H.gender == FEMALE)
MA = wear_female_version(T.icon_state, T.icon, BODY_LAYER)
MA = wear_female_version(state, T.icon, BODY_LAYER)
else
MA = mutable_appearance(T.icon, T.icon_state, -BODY_LAYER)
if(UNDIE_COLORABLE(T))
MA = mutable_appearance(T.icon, state, -BODY_LAYER)
if(T.has_color)
MA.color = "#[H.shirt_color]"
standing += MA
if(H.socks && H.get_num_legs(FALSE) >= 2)
if(H.hidden_socks)
H.socks = "Nude"
else
H.socks = H.saved_socks
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
if(S)
var/digilegs = (DIGITIGRADE in species_traits) ? "_d" : ""
var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
if(UNDIE_COLORABLE(S))
MA.color = "#[H.socks_color]"
standing += MA
if(standing.len)
H.overlays_standing[BODY_LAYER] = standing
@@ -1589,20 +1592,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
user.adjustStaminaLossBuffered(3)
return FALSE
else if(aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin))
if(target.client?.prefs.cit_toggles & NO_ASS_SLAP)
to_chat(user,"A force stays your hand, preventing you from slapping \the [target]'s ass!")
return FALSE
user.do_attack_animation(target, ATTACK_EFFECT_ASS_SLAP)
user.adjustStaminaLossBuffered(3)
if(HAS_TRAIT(target, TRAIT_ASSBLASTUSA))
var/hit_zone = (user.held_index_to_dir(user.active_hand_index) == "l" ? "l_":"r_") + "arm"
user.adjustStaminaLoss(20, affected_zone = hit_zone)
user.visible_message(\
"<span class='danger'>\The [user] slaps \the [target]'s ass, but their hand bounces off like they hit metal!</span>",\
"<span class='danger'>You slap [user == target ? "your" : "\the [target]'s"] ass, but feel an intense amount of pain as you realise their buns are harder than steel!</span>",\
"You hear a slap."
)
playsound(target.loc, 'sound/weapons/tap.ogg', 50, 1, -1)
user.emote("scream")
return FALSE
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
user.visible_message(\
"<span class='danger'>\The [user] slaps \the [target]'s ass!</span>",\
@@ -51,11 +51,7 @@
. = ..()
to_chat(C, "[info_text]")
C.real_name = "[pick(GLOB.nightmare_names)]"
C.name = C.real_name
if(C.mind)
C.mind.name = C.real_name
C.dna.real_name = C.real_name
C.fully_replace_character_name("[pick(GLOB.nightmare_names)]")
/datum/species/shadow/nightmare/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
var/turf/T = H.loc
@@ -127,8 +123,8 @@
/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
respawn_progress = 0
if(blade && special != HEART_SPECIAL_SHADOWIFY)
QDEL_NULL(blade)
M.visible_message("<span class='warning'>\The [blade] disintegrates!</span>")
QDEL_NULL(blade)
..()
/obj/item/organ/heart/nightmare/Stop()
@@ -183,15 +179,21 @@
. = ..()
if(!proximity)
return
if(isopenturf(AM)) //So you can actually melee with it
return
if(isliving(AM))
if(isopenturf(AM))
var/turf/open/T = AM
if(T.light_range && !isspaceturf(T)) //no fairy grass or light tile can escape the fury of the darkness.
to_chat(user, "<span class='notice'>You scrape away [T] with your [name] and snuff out its lights.</span>")
T.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
else if(isliving(AM))
var/mob/living/L = AM
if(iscyborg(AM))
var/mob/living/silicon/robot/borg = AM
if(!borg.lamp_cooldown)
if(borg.lamp_intensity)
borg.update_headlamp(TRUE, INFINITY)
to_chat(borg, "<span class='danger'>Your headlamp is fried! You'll need a human to help replace it.</span>")
for(var/obj/item/assembly/flash/cyborg/F in borg.held_items)
if(!F.crit_fail)
F.burn_out()
else
for(var/obj/item/O in AM)
if(O.light_range && O.light_power)
+3 -1
View File
@@ -91,7 +91,9 @@
if(mind && mind.name && mind.active && !istype(T.loc, /area/ctf) && !(signal & COMPONENT_BLOCK_DEATH_BROADCAST))
var/rendered = "<span class='deadsay'><b>[mind.name]</b> has died at <b>[get_area_name(T)]</b>.</span>"
deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
if (client && client.prefs && client.prefs.auto_ooc)
if (!(client.prefs.chat_toggles & CHAT_OOC))
client.prefs.chat_toggles ^= CHAT_OOC
if (client)
client.move_delay = initial(client.move_delay)
+5
View File
@@ -459,6 +459,11 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
if(!ckey || !new_mob)
CRASH("transfer_ckey() called [ckey ? "" : "on a ckey-less mob[new_mob ? "" : " and "]"][new_mob ? "" : "without a valid mob target"]!")
SEND_SIGNAL(new_mob, COMSIG_MOB_PRE_PLAYER_CHANGE, new_mob, src)
if (client && client.prefs && client.prefs.auto_ooc)
if (client.prefs.chat_toggles & CHAT_OOC && isliving(new_mob))
client.prefs.chat_toggles ^= CHAT_OOC
if (!(client.prefs.chat_toggles & CHAT_OOC) && isdead(new_mob))
client.prefs.chat_toggles ^= CHAT_OOC
new_mob.ckey = ckey
if(send_signal)
SEND_SIGNAL(src, COMSIG_MOB_KEY_CHANGE, new_mob, src)
@@ -352,7 +352,7 @@
clumsy_check = 0
/obj/item/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user)
if((HAS_TRAIT(user, TRAIT_CLUMSY)) || (user.mind && user.mind.assigned_role == "Clown"))
if((HAS_TRAIT(user, TRAIT_CLUMSY)) || (user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY)))
return ..()
if(process_fire(user, user, FALSE, null, BODY_ZONE_HEAD))
user.visible_message("<span class='warning'>[user] somehow manages to shoot [user.p_them()]self in the face!</span>", "<span class='userdanger'>You somehow shoot yourself in the face! How the hell?!</span>")
+1 -1
View File
@@ -135,7 +135,7 @@
// A gun with ultra-honk pin is useful for clown and useless for everyone else.
/obj/item/firing_pin/clown/ultra/pin_auth(mob/living/user)
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
if(user && (!(HAS_TRAIT(user, TRAIT_CLUMSY)) && !(user.mind && user.mind.assigned_role == "Clown")))
if(user && (!(HAS_TRAIT(user, TRAIT_CLUMSY)) && !(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY))))
return FALSE
return TRUE
@@ -260,7 +260,7 @@
if(!amount)
return
vol_each = min(reagents.total_volume / amount, 50)
var/name = stripped_input(usr,"Name:","Name your pill!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
var/name = html_decode(stripped_input(usr,"Name:","Name your pill!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
var/obj/item/reagent_containers/pill/P
@@ -287,7 +287,7 @@
adjust_item_drop_location(P)
reagents.trans_to(P,vol_each)
else
var/name = stripped_input(usr, "Name:", "Name your pack!", reagents.get_master_reagent_name(), MAX_NAME_LEN)
var/name = html_decode(stripped_input(usr, "Name:", "Name your pack!", reagents.get_master_reagent_name(), MAX_NAME_LEN))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
var/obj/item/reagent_containers/food/condiment/pack/P = new/obj/item/reagent_containers/food/condiment/pack(drop_location())
@@ -313,7 +313,7 @@
if(!amount)
return
vol_each = min(reagents.total_volume / amount, 40)
var/name = stripped_input(usr,"Name:","Name your patch!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
var/name = html_decode(stripped_input(usr,"Name:","Name your patch!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
var/obj/item/reagent_containers/pill/P
@@ -331,7 +331,7 @@
return
if(condi)
var/name = stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN)
var/name = html_decode(stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
var/obj/item/reagent_containers/food/condiment/P = new(drop_location())
@@ -344,7 +344,7 @@
if(text2num(many))
amount_full = round(reagents.total_volume / 30)
vol_part = ((reagents.total_volume*1000) % 30000) / 1000 //% operator doesn't support decimals.
var/name = stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN)
var/name = html_decode(stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
@@ -372,7 +372,7 @@
if(text2num(many))
amount_full = round(reagents.total_volume / 60)
vol_part = reagents.total_volume % 60
var/name = stripped_input(usr, "Name:","Name your hypovial!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN)
var/name = html_decode(stripped_input(usr, "Name:","Name your hypovial!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
@@ -407,7 +407,7 @@
return
vol_each = min(reagents.total_volume / amount, 20)
var/name = stripped_input(usr,"Name:","Name your SmartDart!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
var/name = html_decode(stripped_input(usr,"Name:","Name your SmartDart!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN))
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
@@ -247,6 +247,23 @@
. = 1
..()
/datum/reagent/consumable/coconutmilk
name = "Coconut Milk"
id = "coconutmilk"
description = "A transparent white liquid extracted from coconuts. Rich in taste."
color = "#DFDFDF" // rgb: 223, 223, 223
taste_description = "sweet milk"
quality = DRINK_GOOD
glass_icon_state = "glass_white"
glass_name = "glass of coconut milk"
glass_desc = "White and nutritious goodness!"
/datum/reagent/consumable/coconutmilk/on_mob_life(mob/living/carbon/M)
if(M.getBruteLoss() && prob(20))
M.heal_bodypart_damage(2,0, 0)
. = 1
..()
/datum/reagent/consumable/cream
name = "Cream"
id = "cream"
@@ -26,12 +26,11 @@ Borg Hypospray
var/bypass_protection = 0 //If the hypospray can go through armor or thick material
var/list/datum/reagents/reagent_list = list()
var/list/reagent_ids = list("dexalin", "kelotane", "bicaridine", "antitoxin", "epinephrine", "spaceacillin", "salglu_solution")
var/list/reagent_ids = list("dexalin", "kelotane", "bicaridine", "antitoxin", "epinephrine", "spaceacillin", "salglu_solution", "insulin")
var/accepts_reagent_upgrades = TRUE //If upgrades can increase number of reagents dispensed.
var/list/modes = list() //Basically the inverse of reagent_ids. Instead of having numbers as "keys" and strings as values it has strings as keys and numbers as values.
//Used as list for input() in shakers.
/obj/item/reagent_containers/borghypo/Initialize()
. = ..()
@@ -40,12 +39,10 @@ Borg Hypospray
START_PROCESSING(SSobj, src)
/obj/item/reagent_containers/borghypo/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg
charge_tick++
if(charge_tick >= recharge_time)
@@ -162,7 +159,7 @@ Borg Hypospray
icon_state = "borghypo_s"
charge_cost = 20
recharge_time = 2
reagent_ids = list("syndicate_nanites", "potass_iodide", "morphine")
reagent_ids = list("syndicate_nanites", "potass_iodide", "morphine", "insulin")
bypass_protection = 1
accepts_reagent_upgrades = FALSE
@@ -178,7 +175,6 @@ Borg Shaker
charge_cost = 20 //Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
recharge_time = 3
accepts_reagent_upgrades = FALSE
reagent_ids = list("beer", "orangejuice", "grenadine", "limejuice", "tomatojuice", "cola", "tonic", "sodawater", "ice", "cream", "whiskey", "vodka", "rum", "gin", "tequila", "vermouth", "wine", "kahlua", "cognac", "ale", "milk", "coffee", "banana", "lemonjuice")
/obj/item/reagent_containers/borghypo/borgshaker/attack(mob/M, mob/user)
@@ -234,23 +230,21 @@ Borg Shaker
charge_cost = 20 //Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
recharge_time = 3
accepts_reagent_upgrades = FALSE
reagent_ids = list("fakebeer", "fernet")
/obj/item/reagent_containers/borghypo/peace
name = "Peace Hypospray"
reagent_ids = list("dizzysolution","tiresolution","synthpax")
reagent_ids = list("dizzysolution", "tiresolution", "synthpax", "insulin")
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/peace/hacked
desc = "Everything's peaceful in death!"
icon_state = "borghypo_s"
reagent_ids = list("dizzysolution","tiresolution","synthpax","tirizene","sulfonal","sodium_thiopental","cyanide","fentanyl")
reagent_ids = list("dizzysolution", "tiresolution", "synthpax", "tirizene", "sulfonal", "sodium_thiopental", "cyanide", "fentanyl")
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/epi
name = "epinephrine injector"
name = "Stabilizer injector"
desc = "An advanced chemical synthesizer and injection system, designed to stabilize patients."
reagent_ids = list("epinephrine")
reagent_ids = list("epinephrine", "insulin")
accepts_reagent_upgrades = FALSE
@@ -152,6 +152,16 @@
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/telescopiciv
name = "Telescopic IV Drip"
desc = "An IV drip with an advanced infusion pump that can both drain blood into and inject liquids from attached containers. Blood packs are processed at an accelerated rate. This one is telescopic, and can be picked up and put down."
id = "telescopiciv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 5000, MAT_GLASS = 3500, MAT_SILVER = 1000)
build_path = /obj/item/tele_iv
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/holobarrier_med
name = "PENLITE holobarrier projector"
desc = "PENLITE holobarriers, a device that halts individuals with malicious diseases."
+1 -1
View File
@@ -71,7 +71,7 @@
display_name = "Biological Technology"
description = "What makes us tick." //the MC, silly!
prereq_ids = list("base")
design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen")
design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen", "telescopiciv")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
+28 -29
View File
@@ -560,7 +560,7 @@
else if((findtext(message, honk_words)))
cooldown = COOLDOWN_MEME
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, get_turf(user), 'sound/items/bikehorn.ogg', 300, 1), 25)
if(user.mind && user.mind.assigned_role == "Clown")
if(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY))
for(var/mob/living/carbon/C in listeners)
C.slip(140 * power_multiplier)
cooldown = COOLDOWN_MEME
@@ -807,9 +807,8 @@
E.enthrallTally += (power_multiplier*(((length(message))/200) + 1)) //encourage players to say more than one word.
else
E.enthrallTally += power_multiplier*1.25 //thinking about it, I don't know how this can proc
if(L.canbearoused)
if(L.client?.prefs.lewdchem)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='nicegreen'><i><b>[E.enthrallGender] is so nice to listen to.</b></i></span>"), 5)
if(L.canbearoused && E.lewd)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='nicegreen'><i><b>[E.enthrallGender] is so nice to listen to.</b></i></span>"), 5)
E.cooldown += 1
//REWARD mixable works
@@ -820,7 +819,7 @@
power_multiplier *= distancelist[get_dist(user, V)+1]
if(L == user)
continue
if (L.client?.prefs.lewdchem)
if (E.lewd)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='love'>[E.enthrallGender] has praised me!!</span>"), 5)
if(HAS_TRAIT(L, TRAIT_NYMPHO))
L.adjustArousalLoss(2*power_multiplier)
@@ -832,7 +831,7 @@
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='nicegreen'><b><i>I've been praised for doing a good job!</b></i></span>"), 5)
E.resistanceTally -= power_multiplier
E.enthrallTally += power_multiplier
var/descmessage = "<span class='love'><i>[(L.client?.prefs.lewdchem?"I feel so happy! I'm a good pet who [E.enthrallGender] loves!":"I did a good job!")]</i></span>"
var/descmessage = "<span class='love'><i>[(E.lewd?"I feel so happy! I'm a good pet who [E.enthrallGender] loves!":"I did a good job!")]</i></span>"
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "enthrallpraise", /datum/mood_event/enthrallpraise, descmessage)
E.cooldown += 1
@@ -841,10 +840,10 @@
for(var/V in listeners)
var/mob/living/L = V
var/datum/status_effect/chem/enthrall/E = L.has_status_effect(/datum/status_effect/chem/enthrall)
var/descmessage = "[(L.client?.prefs.lewdchem?"I've failed [E.enthrallGender]... What a bad, bad pet!":"I did a bad job...")]"
var/descmessage = "[(E.lewd?"I've failed [E.enthrallGender]... What a bad, bad pet!":"I did a bad job...")]"
if(L == user)
continue
if (L.client?.prefs.lewdchem)
if (E.lewd)
if(HAS_TRAIT(L, TRAIT_MASO))
L.adjustArousalLoss(3*power_multiplier)
descmessage += "And yet, it feels so good..!</span>" //I don't really understand masco, is this the right sort of thing they like?
@@ -871,7 +870,7 @@
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
REMOVE_TRAIT(C, TRAIT_MUTE, "enthrall")
C.silent = 0
if(C.client?.prefs.lewdchem)
if(E.lewd)
addtimer(CALLBACK(C, /atom/movable/proc/say, "[E.enthrallGender]"), 5)
else
addtimer(CALLBACK(C, /atom/movable/proc/say, "[E.master]"), 5)
@@ -887,7 +886,7 @@
E.phase = 3
E.status = null
user.emote("snap")
if(L.client?.prefs.lewdchem)
if(E.lewd)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='big warning'>The snapping of your [E.enthrallGender]'s fingers brings you back to your enthralled state, obedient and ready to serve.</b></span>"), 5)
else
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='big warning'>The snapping of [E.master]'s fingers brings you back to being under their influence.</b></span>"), 5)
@@ -910,11 +909,11 @@
addtimer(CALLBACK(H, /atom/movable/proc/say, "I feel happy being with you."), 5)
continue
if(2)
speaktrigger += "[(H.client?.prefs.lewdchem?"I think I'm in love with you... ":"I find you really inspirational, ")]" //'
speaktrigger += "[(E.lewd?"I think I'm in love with you... ":"I find you really inspirational, ")]" //'
if(3)
speaktrigger += "[(H.client?.prefs.lewdchem?"I'm devoted to being your pet":"I'm commited to following your cause!")]! "
speaktrigger += "[(E.lewd?"I'm devoted to being your pet":"I'm commited to following your cause!")]! "
if(4)
speaktrigger += "[(H.client?.prefs.lewdchem?"You are my whole world and all of my being belongs to you, ":"I cannot think of anything else but aiding your cause, ")] "//Redflags!!
speaktrigger += "[(E.lewd?"You are my whole world and all of my being belongs to you, ":"I cannot think of anything else but aiding your cause, ")] "//Redflags!!
//mood
var/datum/component/mood/mood = H.GetComponent(/datum/component/mood)
@@ -1003,7 +1002,7 @@
speaktrigger += "I feel like I'm on the brink of losing my mind, "
//horny
if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && H.client?.prefs.lewdchem)
if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && E.lewd)
switch(H.getArousalLoss())
if(40 to 60)
speaktrigger += "I'm feeling a little horny, "
@@ -1013,10 +1012,10 @@
speaktrigger += "I'm really, really horny, "
//collar
if(istype(H.wear_neck, /obj/item/clothing/neck/petcollar) && H.client?.prefs.lewdchem)
if(istype(H.wear_neck, /obj/item/clothing/neck/petcollar) && E.lewd)
speaktrigger += "I love the collar you gave me, "
//End
if(H.client?.prefs.lewdchem)
if(E.lewd)
speaktrigger += "[E.enthrallGender]!"
else
speaktrigger += "[user.first_name()]!"
@@ -1044,7 +1043,7 @@
REMOVE_TRAIT(C, TRAIT_MUTE, "enthrall")
C.silent = 0
E.cooldown += 3
to_chat(user, "<span class='notice'><i>You [(C.client?.prefs.lewdchem?"allow [C] to speak again":"encourage [C] to speak again")].</i></span>")
to_chat(user, "<span class='notice'><i>You [(E.lewd?"allow [C] to speak again":"encourage [C] to speak again")].</i></span>")
//Antiresist
@@ -1074,7 +1073,7 @@
for(var/mob/living/carbon/C in listeners)
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase == 4)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='warning'>You're unable to forget about [(C.client?.prefs.lewdchem?"the dominating presence of [E.enthrallGender]":"[E.master]")]!</b></span>"), 5)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='warning'>You're unable to forget about [(E.lewd?"the dominating presence of [E.enthrallGender]":"[E.master]")]!</b></span>"), 5)
continue
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='warning'>You wake up, forgetting everything that just happened. You must've dozed off..? How embarassing!</b></span>"), 5)
C.Sleeping(50)
@@ -1086,7 +1085,7 @@
if(3)
E.phase = 0
E.cooldown = 0
if(C.client?.prefs.lewdchem)
if(E.lewd)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='big warning'>You revert to yourself before being enthralled by your [E.enthrallGender], with no memory of what happened.</b></span>"), 5)
else
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='big warning'>You revert to who you were before, with no memory of what happened with [E.master].</b></span>"), 5)
@@ -1112,7 +1111,7 @@
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase > 1)
if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && H.client?.prefs.lewdchem) // probably a redundant check but for good measure
if(HAS_TRAIT(H, TRAIT_NYMPHO) && H.canbearoused && E.lewd) // probably a redundant check but for good measure
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='love'>Your [E.enthrallGender] pushes you over the limit, overwhelming your body with pleasure.</b></span>"), 5)
H.mob_climax(forced_climax=TRUE)
H.SetStun(20)
@@ -1168,7 +1167,7 @@
for(var/obj/item/W in items)
if(W == H.wear_suit)
H.dropItemToGround(W, TRUE)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='[(H.client?.prefs.lewdchem?"love":"warning")]'>Before you can even think about it, you quickly remove your clothes in response to [(H.client?.prefs.lewdchem?"your [E.enthrallGender]'s command'":"[E.master]'s directive'")].</b></span>"), 5)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='[(E.lewd?"love":"warning")]'>Before you can even think about it, you quickly remove your clothes in response to [(E.lewd?"your [E.enthrallGender]'s command'":"[E.master]'s directive'")].</b></span>"), 5)
E.cooldown += 10
//WALK
@@ -1206,7 +1205,7 @@
if(2 to INFINITY)
L.lay_down()
E.cooldown += 10
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "[(L.client?.prefs.lewdchem?"<span class='love'>You eagerly lie down!":"<span class='notice'>You suddenly lie down!")]</b></span>"), 5)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "[(E.lewd?"<span class='love'>You eagerly lie down!":"<span class='notice'>You suddenly lie down!")]</b></span>"), 5)
to_chat(user, "<span class='notice'><i>You encourage [L] to lie down.</i></span>")
//KNOCKDOWN
@@ -1237,7 +1236,7 @@
for (var/trigger in E.customTriggers)
speaktrigger += "[trigger], "
to_chat(user, "<b>[C]</b> whispers, \"<i>[speaktrigger] are my triggers.</i>\"")//So they don't trigger themselves!
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='notice'>You whisper your triggers to [(C.client?.prefs.lewdchem?"Your [E.enthrallGender]":"[E.master]")].</span>"), 5)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, C, "<span class='notice'>You whisper your triggers to [(E.lewd?"Your [E.enthrallGender]":"[E.master]")].</span>"), 5)
//CUSTOM TRIGGERS
@@ -1249,7 +1248,7 @@
if (get_dist(user, H) > 1)//Requires user to be next to their pet.
to_chat(user, "<span class='warning'>You need to be next to your pet to give them a new trigger!</b></span>")
continue
if(!H.client?.prefs.lewdchem)
if(!E.lewd)
to_chat(user, "<span class='warning'>[H] seems incapable of being implanted with triggers.</b></span>")
continue
else
@@ -1272,7 +1271,7 @@
E.customTriggers[trigger] = trigger2
log_game("FERMICHEM: [H] has been implanted by [user] with [trigger], triggering [trigger2].")
E.mental_capacity -= 5
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='notice'>[(H.client?.prefs.lewdchem?"your [E.enthrallGender]":"[E.master]")] whispers you a new trigger.</span>"), 5)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='notice'>[(E.lewd?"your [E.enthrallGender]":"[E.master]")] whispers you a new trigger.</span>"), 5)
to_chat(user, "<span class='notice'><i>You sucessfully set the trigger word [trigger] in [H]</i></span>")
else
to_chat(user, "<span class='warning'>Your pet looks at you confused, it seems they don't understand that effect!</b></span>")
@@ -1290,7 +1289,7 @@
if (get_dist(user, H) > 1)//Requires user to be next to their pet.
to_chat(user, "<span class='warning'>You need to be next to your pet to give them a new echophrase!</b></span>")
continue
if(!H.client?.prefs.lewdchem)
if(!E.lewd)
to_chat(user, "<span class='warning'>[H] seems incapable of being implanted with an echoing phrase.</b></span>")
continue
else
@@ -1334,7 +1333,7 @@
objective = replacetext(lowertext(objective), "suicide", "self-love")
message_admins("[H] has been implanted by [user] with the objective [objective].")
log_game("FERMICHEM: [H] has been implanted by [user] with the objective [objective] via MKUltra.")
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='notice'>[(H.client?.prefs.lewdchem?"Your [E.enthrallGender]":"[E.master]")] whispers you a new objective.</span>"), 5)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='notice'>[(E.lewd?"Your [E.enthrallGender]":"[E.master]")] whispers you a new objective.</span>"), 5)
brainwash(H, objective)
E.mental_capacity -= 200
to_chat(user, "<span class='notice'><i>You sucessfully give an objective to [H]</i></span>")
@@ -1348,7 +1347,7 @@
for(var/V in listeners)
var/mob/living/carbon/human/H = V
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
if(E.phase >= 3 && H.client?.prefs.lewdchem)
if(E.phase >= 3 && E.lewd)
var/instill = stripped_input(user, "Instill an emotion in [H].", MAX_MESSAGE_LEN)
to_chat(H, "<i>[instill]</i>")
to_chat(user, "<span class='notice'><i>You sucessfully instill a feeling in [H]</i></span>")
@@ -1363,7 +1362,7 @@
if(E.phase > 1)
if(user.ckey == E.enthrallID && user.real_name == E.master.real_name)
E.master = user
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='nicegreen'>[(H.client?.prefs.lewdchem?"You hear the words of your [E.enthrallGender] again!! They're back!!":"You recognise the voice of [E.master].")]</b></span>"), 5)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='nicegreen'>[(E.lewd?"You hear the words of your [E.enthrallGender] again!! They're back!!":"You recognise the voice of [E.master].")]</b></span>"), 5)
to_chat(user, "<span class='notice'><i>[H] looks at you with sparkling eyes, recognising you!</i></span>")
//I dunno how to do state objectives without them revealing they're an antag
+1 -1
View File
@@ -21,7 +21,7 @@
/obj/vehicle/sealed/car/clowncar/auto_assign_occupant_flags(mob/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.mind && H.mind.assigned_role == "Clown") //Ensures only clowns can drive the car. (Including more at once)
if(H.mind && HAS_TRAIT(H.mind, TRAIT_CLOWN_MENTALITY)) //Ensures only clowns can drive the car. (Including more at once)
add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_PERMISSION)
return
add_control_flags(M, VEHICLE_CONTROL_KIDNAPPED)
+8
View File
@@ -70,14 +70,22 @@
/obj/item/clothing/under/skirt/red = 3,
/obj/item/clothing/under/skirt/purple = 3,
/obj/item/clothing/under/sundress = 4,
/obj/item/clothing/under/sundresswhite = 4,
/obj/item/clothing/under/stripeddress = 3,
/obj/item/clothing/under/sailordress = 3,
/obj/item/clothing/under/sweptskirt = 3,
/obj/item/clothing/under/greendress = 3,
/obj/item/clothing/under/pinkdress = 3,
/obj/item/clothing/under/redeveninggown = 3,
/obj/item/clothing/under/blacktango = 3,
/obj/item/clothing/under/westernbustle = 3,
/obj/item/clothing/under/flamenco = 3,
/obj/item/clothing/under/flowerdress = 3,
/obj/item/clothing/under/plaid_skirt = 3,
/obj/item/clothing/under/plaid_skirt/blue = 3,
/obj/item/clothing/under/plaid_skirt/purple = 3,
/obj/item/clothing/under/plaid_skirt/green = 3,
/obj/item/clothing/under/croptop = 3,
/obj/item/clothing/glasses/regular = 2,
/obj/item/clothing/glasses/regular/jamjar = 2,
/obj/item/clothing/head/sombrero = 3,
+1
View File
@@ -14,6 +14,7 @@
/obj/item/seeds/chanter = 3,
/obj/item/seeds/chili = 3,
/obj/item/seeds/cocoapod = 3,
/obj/item/seeds/coconut = 3,
/obj/item/seeds/coffee = 3,
/obj/item/seeds/cotton = 3,
/obj/item/seeds/corn = 3,