Merge branch 'master' into master

This commit is contained in:
Thalpy
2019-06-29 15:48:25 +01:00
committed by GitHub
158 changed files with 3775 additions and 2492 deletions
+2 -2
View File
@@ -25,8 +25,8 @@
cross.icon_state = "kingyellow"
font_color = "blue"
prayer_type = "CHAPLAIN PRAYER"
if(SSreligion.deity)
deity = SSreligion.deity
if(GLOB.deity)
deity = GLOB.deity
else if(iscultist(usr))
cross.icon_state = "tome"
font_color = "red"
@@ -1,8 +1,9 @@
/obj/effect/proc_holder/changeling/adrenaline
name = "Adrenaline Sacs"
desc = "We evolve additional sacs of adrenaline throughout our body."
helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body."
helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body. This ability is loud, and might cause our blood to react violently to heat."
chemical_cost = 30
loudness = 2
dna_cost = 2
req_human = 1
req_stat = UNCONSCIOUS
@@ -13,4 +14,4 @@
//Recover from stuns.
/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user)
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list("epinephrine" = 3, "changelingmeth" = 10, "mannitol" = 10, "regen_jelly" = 10, "changelingadrenaline" = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
return TRUE
return TRUE
@@ -95,7 +95,7 @@
cached_gases[/datum/gas/oxygen] -= cached_gases[/datum/gas/tritium]
if(burned_fuel)
energy_released += FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel
energy_released += (FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel)
if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
@@ -285,6 +285,7 @@
if(do_explosion)
explosion(location, 0, 0, 5, power_ratio, TRUE, TRUE) //large shockwave, the actual radius is quite small - people will recognize that you're doing fusion
radiation_pulse(location, radiation_power) //You mean causing a super-tier fusion reaction in the halls is a bad idea?
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, 30000)//The science is cool though.
playsound(location, 'sound/effects/supermatter.ogg', 100, 0)
else
playsound(location, 'sound/effects/phasein.ogg', 75, 0)
@@ -350,12 +351,20 @@
var/old_heat_capacity = air.heat_capacity()
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma]/cached_gases[/datum/gas/nitrous_oxide],1))),cached_gases[/datum/gas/nitrous_oxide],cached_gases[/datum/gas/plasma]/2)
var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
if(cached_gases[/datum/gas/miasma] && cached_gases[/datum/gas/miasma] > 0)
energy_released /= cached_gases[/datum/gas/miasma]*0.1
if(cached_gases[/datum/gas/bz] && cached_gases[/datum/gas/bz] > 0)
energy_released *= cached_gases[/datum/gas/bz]*0.1
if ((cached_gases[/datum/gas/nitrous_oxide] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma] - (2*reaction_efficency) < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
cached_gases[/datum/gas/bz] += reaction_efficency
if(reaction_efficency == cached_gases[/datum/gas/nitrous_oxide])
cached_gases[/datum/gas/bz] -= min(pressure,1)
cached_gases[/datum/gas/oxygen] += min(pressure,1)
cached_gases[/datum/gas/nitrous_oxide] -= reaction_efficency
cached_gases[/datum/gas/plasma] -= 2*reaction_efficency
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, (reaction_efficency**0.5)*BZ_RESEARCH_AMOUNT)
if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity()
@@ -390,6 +399,7 @@
cached_gases[/datum/gas/plasma] -= heat_scale
cached_gases[/datum/gas/nitryl] -= heat_scale
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0))
if(stim_energy_change)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
@@ -418,6 +428,7 @@
cached_gases[/datum/gas/nitrogen] -= 20*nob_formed
cached_gases[/datum/gas/hypernoblium]+= nob_formed
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT)
if (nob_formed)
var/new_heat_capacity = air.heat_capacity()
@@ -449,3 +460,4 @@
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
air.temperature += cleaned_air * 0.002
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists
+4
View File
@@ -68,6 +68,7 @@
GLOB.poi_list |= src
LAZYADD(GLOB.mob_spawners[job_description ? job_description : name], src)
/obj/effect/mob_spawn/Destroy()
GLOB.poi_list -= src
LAZYREMOVE(GLOB.mob_spawners[job_description ? job_description : name], src)
@@ -75,6 +76,9 @@
GLOB.mob_spawners -= job_description ? job_description : name
return ..()
/obj/effect/mob_spawn/proc/can_latejoin() //If it can be taken from the lobby.
return TRUE
/obj/effect/mob_spawn/proc/special(mob/M)
return
@@ -131,6 +131,24 @@
unit_name = "security barrier"
export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security)
/datum/export/large/gas_canister
cost = 10 //Base cost of canister. You get more for nice gases inside.
unit_name = "Gas Canister"
export_types = list(/obj/machinery/portable_atmospherics/canister)
/datum/export/large/gas_canister/get_cost(obj/O)
var/obj/machinery/portable_atmospherics/canister/C = O
var/worth = 10
var/gases = C.air_contents.gases
worth += gases[/datum/gas/bz]*4
worth += gases[/datum/gas/stimulum]*25
worth += gases[/datum/gas/hypernoblium]*1000
worth += gases[/datum/gas/miasma]*15
worth += gases[/datum/gas/tritium]*7
worth += gases[/datum/gas/pluoxium]*6
worth += gases[/datum/gas/nitryl]*30
return worth
/datum/export/large/odysseus
cost = 5500
unit_name = "working odysseus"
+26 -3
View File
@@ -755,13 +755,24 @@
/datum/supply_pack/engineering/engihardsuit
name = "Engineering Hardsuit"
desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and maks!"
desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!"
cost = 2500
contains = list(/obj/item/tank/internals/air,
/obj/item/clothing/mask/gas,
/obj/item/clothing/suit/space/hardsuit/engine)
crate_name = "engineering hardsuit"
/datum/supply_pack/engineering/atmoshardsuit
name = "Atmospherics Hardsuit"
desc = "Too many techs and not enough hardsuits? Time to buy some more! Comes with gas mask and air tank. Ask the CE to open."
cost = 5000
access = ACCESS_CE
contains = list(/obj/item/tank/internals/air,
/obj/item/clothing/mask/gas,
/obj/item/clothing/suit/space/hardsuit/engine/atmos)
crate_name = "atmospherics hardsuit"
crate_type = /obj/structure/closet/crate/secure/engineering
/datum/supply_pack/engineering/industrialrcd
name = "Industrial RCD"
desc = "A industrial RCD in case the station has gone through more then one meteor storm and the CE needs to bring out the somthing a bit more reliable. Dose not contain spare ammo for the industrial RCD or any other RCD modles."
@@ -1146,7 +1157,7 @@
/datum/supply_pack/materials/bz
name = "BZ Canister Crate"
desc = "Contains a canister of BZ. Requires Toxins access to open."
cost = 5000
cost = 7500 // Costs 3 credits more than what you can get for selling it.
access = ACCESS_TOX_STORAGE
contains = list(/obj/machinery/portable_atmospherics/canister/bz)
crate_name = "BZ canister crate"
@@ -1949,6 +1960,17 @@
crate_name = "hydroponics backpack crate"
crate_type = /obj/structure/closet/crate/secure
/datum/supply_pack/organic/mre
name = "MRE supply kit (emergency rations)"
desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank."
cost = 2000
contains = list(/obj/item/storage/box/mre/menu1/safe,
/obj/item/storage/box/mre/menu1/safe,
/obj/item/storage/box/mre/menu2/safe,
/obj/item/storage/box/mre/menu2/safe,
/obj/item/storage/box/mre/menu3)
crate_name = "MRE crate (emergency rations)"
/datum/supply_pack/organic/pizza
name = "Pizza Crate"
desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!"
@@ -2241,7 +2263,8 @@
/obj/item/storage/fancy/cigarettes/cigpack_shadyjims,
/obj/item/clothing/mask/gas/syndicate,
/obj/item/clothing/neck/necklace/dope,
/obj/item/vending_refill/donksoft)
/obj/item/vending_refill/donksoft,
/obj/item/circuitboard/computer/arcade/amputation)
crate_name = "crate"
/datum/supply_pack/costumes_toys/foamforce
+18
View File
@@ -467,6 +467,24 @@ GLOBAL_LIST_EMPTY(asset_datums)
"stamp-law" = 'icons/stamp_icons/large_stamp-law.png'
)
/datum/asset/spritesheet/simple/minesweeper
name = "minesweeper"
assets = list(
"1" = 'icons/misc/minesweeper_tiles/one.png',
"2" = 'icons/misc/minesweeper_tiles/two.png',
"3" = 'icons/misc/minesweeper_tiles/three.png',
"4" = 'icons/misc/minesweeper_tiles/four.png',
"5" = 'icons/misc/minesweeper_tiles/five.png',
"6" = 'icons/misc/minesweeper_tiles/six.png',
"7" = 'icons/misc/minesweeper_tiles/seven.png',
"8" = 'icons/misc/minesweeper_tiles/eight.png',
"empty" = 'icons/misc/minesweeper_tiles/empty.png',
"flag" = 'icons/misc/minesweeper_tiles/flag.png',
"hidden" = 'icons/misc/minesweeper_tiles/hidden.png',
"mine" = 'icons/misc/minesweeper_tiles/mine.png',
"minehit" = 'icons/misc/minesweeper_tiles/minehit.png'
)
/datum/asset/simple/IRV
assets = list(
"jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js',
+24 -14
View File
@@ -59,6 +59,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/preferred_map = null
var/pda_style = MONO
var/pda_color = "#808000"
var/pda_skin = PDA_SKIN_ALT
var/uses_glasses_colour = 0
@@ -685,48 +686,48 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
if(pref_species.use_skintones)
dat += "<b>Genitals use skintone:</b><a href='?_src_=prefs;preference=genital_colour'>[features["genitals_use_skintone"] == TRUE ? "Yes" : "No"]</a>"
dat += "<b>Has Penis:</b>"
dat += "<h3>Penis</h3>"
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_cock'>[features["has_cock"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_cock"] == TRUE)
if(features["has_cock"])
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
dat += "<b>Penis Color:</b>"
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<br>"
dat += "<b>Penis Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)</a><br>"
else
dat += "<b>Penis Color:</b>"
dat += "<b>Penis Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["cock_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=cock_color;task=input'>Change</a><br>"
dat += "<b>Penis Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]]</a>"
dat += "<b>Penis Length:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_length;task=input'>[features["cock_length"]] inch(es)</a>"
dat += "<b>Has Testicles:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_balls'>[features["has_balls"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_balls"] == TRUE)
if(features["has_balls"])
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
dat += "<b>Testicles Color:</b>"
dat += "<b>Testicles Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<br>"
else
dat += "<b>Testicles Color:</b>"
dat += "<b>Testicles Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["balls_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=balls_color;task=input'>Change</a><br>"
dat += "<b>Testicles showing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=balls_shape;task=input'>[features["balls_shape"]]</a>"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<b>Has Vagina:</b>"
dat += "<h3>Vagina</h3>"
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_vag'>[features["has_vag"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_vag"])
dat += "<b>Vagina Type:</b> <a style='display:block;width:100px' href='?_src_=prefs;preference=vag_shape;task=input'>[features["vag_shape"]]</a>"
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
dat += "<b>Vagina Color:</b>"
dat += "<b>Vagina Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<br>"
else
dat += "<b>Vagina Color:</b>"
dat += "<b>Vagina Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["vag_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=vag_color;task=input'>Change</a><br>"
dat += "<b>Has Womb:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_womb'>[features["has_womb"] == TRUE ? "Yes" : "No"]</a>"
dat += "</td>"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<b>Has Breasts:</b>"
dat += "<h3>Breasts</h3>"
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_breasts'>[features["has_breasts"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_breasts"])
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
dat += "<b>Color:</b>"
dat += "<b>Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'>&nbsp;&nbsp;&nbsp;</span>(Skin tone overriding)<br>"
else
dat += "<b>Color:</b>"
dat += "<b>Color:</b></a><BR>"
dat += "<span style='border: 1px solid #161616; background-color: #[features["breasts_color"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=breasts_color;task=input'>Change</a><br>"
dat += "<b>Cup Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_size;task=input'>[features["breasts_size"]]</a>"
dat += "<b>Breast Shape:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_shape;task=input'>[features["breasts_shape"]]</a>"
@@ -746,6 +747,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<br>"
dat += "<b>PDA Color:</b> <span style='border:1px solid #161616; background-color: [pda_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=pda_color;task=input'>Change</a><BR>"
dat += "<b>PDA Style:</b> <a href='?_src_=prefs;task=input;preference=pda_style'>[pda_style]</a><br>"
dat += "<b>PDA Reskin:</b> <a href='?_src_=prefs;task=input;preference=pda_skin'>[pda_skin]</a><br>"
dat += "<br>"
dat += "<b>Ghost Ears:</b> <a href='?_src_=prefs;preference=ghost_ears'>[(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</a><br>"
dat += "<b>Ghost Radio:</b> <a href='?_src_=prefs;preference=ghost_radio'>[(chat_toggles & CHAT_GHOSTRADIO) ? "All Messages":"No Messages"]</a><br>"
@@ -1986,6 +1988,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/pickedPDAColor = input(user, "Choose your PDA Interface color.", "Character Preference",pda_color) as color|null
if(pickedPDAColor)
pda_color = pickedPDAColor
if("pda_skin")
var/pickedPDASkin = input(user, "Choose your PDA reskin.", "Character Preference", pda_skin) as null|anything in GLOB.pda_reskins
if(pickedPDASkin)
pda_skin = pickedPDASkin
else
switch(href_list["preference"])
@@ -1996,6 +2002,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
arousable = !arousable
if("has_cock")
features["has_cock"] = !features["has_cock"]
if(features["has_cock"] == FALSE)
features["has_balls"] = FALSE
if("has_balls")
features["has_balls"] = !features["has_balls"]
if("has_ovi")
@@ -2010,6 +2018,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["has_breasts"] = !features["has_breasts"]
if("has_vag")
features["has_vag"] = !features["has_vag"]
if(features["has_vag"] == FALSE)
features["has_womb"] = FALSE
if("has_womb")
features["has_womb"] = !features["has_womb"]
if("exhibitionist")
@@ -108,6 +108,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["tip_delay"] >> tip_delay
S["pda_style"] >> pda_style
S["pda_color"] >> pda_color
S["pda_skin"] >> pda_skin
//citadel code
S["arousable"] >> arousable
@@ -144,6 +145,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
be_special = SANITIZE_LIST(be_special)
pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style))
pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color))
pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT)
screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake))
damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake))
+14 -1
View File
@@ -226,6 +226,19 @@
CL.flags_cover = initial(PCL.flags_cover)
target.icon = initial(picked_item.icon)
/datum/action/item_action/chameleon/change/pda/update_item(obj/item/pda/picked_item)
if(!istype(target, /obj/item/pda))
return ..()
var/obj/item/pda/P = target
P.name = initial(picked_item.name)
P.desc = initial(picked_item.desc)
P.icon_state = initial(picked_item.icon_state)
P.item_state = initial(picked_item.item_state)
P.item_color = initial(picked_item.item_color)
P.overlays_offsets = initial(picked_item.overlays_offsets)
P.set_new_overlays()
P.update_icon()
/datum/action/item_action/chameleon/change/Trigger()
if(!IsAvailable())
return
@@ -584,7 +597,7 @@
/obj/item/pda/chameleon
name = "PDA"
var/datum/action/item_action/chameleon/change/chameleon_action
var/datum/action/item_action/chameleon/change/pda/chameleon_action
/obj/item/pda/chameleon/Initialize()
. = ..()
+3 -3
View File
@@ -98,7 +98,7 @@
desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents."
icon_state = "purple"
item_state = "glasses"
scan_reagents = 1 //You can see reagents while wearing science goggles
scan_reagents = TRUE //You can see reagents while wearing science goggles
actions_types = list(/datum/action/item_action/toggle_research_scanner)
glass_colour_type = /datum/client_colour/glass_colour/purple
resistance_flags = ACID_PROOF
@@ -202,7 +202,7 @@
/obj/item/clothing/glasses/sunglasses/reagent
name = "beer goggles"
desc = "A pair of sunglasses outfitted with apparatus to scan reagents."
scan_reagents = 1
scan_reagents = TRUE
/obj/item/clothing/glasses/sunglasses/garb
name = "black gar glasses"
@@ -377,7 +377,7 @@
item_state = "godeye"
vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS
darkness_view = 8
scan_reagents = 1
scan_reagents = TRUE
item_flags = NODROP
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
resistance_flags = LAVA_PROOF | FIRE_PROOF
+4 -4
View File
@@ -445,7 +445,7 @@
flash_protect = 0
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
scan_reagents = 1
scan_reagents = TRUE
/obj/item/clothing/suit/space/hardsuit/medical
icon_state = "hardsuit-medical"
@@ -467,7 +467,7 @@
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80)
var/obj/machinery/doppler_array/integrated/bomb_radar
scan_reagents = 1
scan_reagents = TRUE
actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_research_scanner)
/obj/item/clothing/head/helmet/space/hardsuit/rd/Initialize()
@@ -626,7 +626,7 @@
item_state = "anc_hardsuit"
armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500)
slowdown = 6 //Slow
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
@@ -639,7 +639,7 @@
armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500)
item_color = "ancient"
brightness_on = 16
scan_reagents = 1
scan_reagents = TRUE
flash_protect = 5 //We will not be flash by bombs
tint = 1
var/obj/machinery/doppler_array/integrated/bomb_radar
+2 -1
View File
@@ -58,7 +58,8 @@
item_state = "hostrench"
flags_inv = 0
strip_delay = 80
unique_reskin = list("Coat" = "hostrench", "Cloak" = "trenchcloak")
/obj/item/clothing/suit/armor/vest/warden
name = "warden's jacket"
desc = "A navy-blue armored jacket with blue shoulder designations and '/Warden/' stitched into one of the chest pockets."
File diff suppressed because it is too large Load Diff
@@ -204,6 +204,14 @@
resistance_flags = FREEZE_PROOF
isGlass = FALSE
//Used by MREs
/obj/item/reagent_containers/food/drinks/coffee/type2
name = "\improper Coffee, instant (type 2)"
desc = "Coffee that's been blow dried into a granulated powder. This packet includes self heating water for your nutritional pleasure."
icon = 'icons/obj/food/containers.dmi'
icon_state = "condi_cornoil"
/obj/item/reagent_containers/food/drinks/ice
name = "ice cup"
desc = "Careful, cold ice, do not chew."
+11 -7
View File
@@ -291,19 +291,23 @@ All foods are distributed among various categories. Use common sense.
S.reagents.add_reagent(r_id, amount)
/obj/item/reagent_containers/food/snacks/microwave_act(obj/machinery/microwave/M)
var/turf/T = get_turf(src)
var/obj/item/result
if(cooked_type)
var/obj/item/reagent_containers/food/snacks/S = new cooked_type(get_turf(src))
if(M)
initialize_cooked_food(S, M.efficiency)
result = new cooked_type(T)
if(istype(M))
initialize_cooked_food(result, M.efficiency)
else
initialize_cooked_food(S, 1)
SSblackbox.record_feedback("tally", "food_made", 1, type)
initialize_cooked_food(result, 1)
SSblackbox.record_feedback("tally", "food_made", 1, result.type)
else
new /obj/item/reagent_containers/food/snacks/badrecipe(src)
if(M && M.dirty < 100)
result = new /obj/item/reagent_containers/food/snacks/badrecipe(T)
if(istype(M) && M.dirty < 100)
M.dirty++
qdel(src)
return result
/obj/item/reagent_containers/food/snacks/Destroy()
if(contents)
for(var/atom/movable/something in contents)
@@ -225,3 +225,12 @@
filling_color = "#FFFFFF"
foodtype = GRAIN | VEGETABLES
// Used by MREs
/obj/item/reagent_containers/food/snacks/pizzaslice/pepperoni
name = "\improper MRE pepperoni pizza slice"
desc = "A freeze dried, dehydrated slice of bread with tomato sauce, pepperoni and cheese."
icon_state = "meatpizzaslice"
filling_color = "#A52A2A"
tastes = list("cardboard" = 1, "tomato" = 1, "cheese" = 1, "pepperoni" = 2)
foodtype = GRAIN | VEGETABLES | DAIRY | MEAT
@@ -12,322 +12,343 @@
pass_flags = PASSTABLE
light_color = LIGHT_COLOR_YELLOW
light_power = 0.9
var/wire_disabled = FALSE // is its internal wire cut?
var/operating = FALSE // Is it on?
var/dirty = 0 // = {0..100} Does it need cleaning?
var/broken = 0 // ={0,1,2} How broken is it???
var/max_n_of_items = 10 // whatever fat fuck made this a global var needs to look at themselves in the mirror sometime
var/dirty = 0 // 0 to 100 // Does it need cleaning?
var/dirty_anim_playing = FALSE
var/broken = 0 // 0, 1 or 2 // How broken is it???
var/max_n_of_items = 10
var/efficiency = 0
var/datum/looping_sound/microwave/soundloop
var/list/ingredients = list() // may only contain /atom/movables
//Microwaving doesn't use recipes, instead it calls the microwave_act of the objects. For food, this creates something based on the food's cooked_type
var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject")
var/static/radial_use = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_use")
/*******************
* Initialising
********************/
// we show the button even if the proc will not work
var/static/list/radial_options = list("eject" = radial_eject, "use" = radial_use)
var/static/list/ai_radial_options = list("eject" = radial_eject, "use" = radial_use, "examine" = radial_examine)
/obj/machinery/microwave/Initialize()
. = ..()
wires = new /datum/wires/microwave(src)
create_reagents(100)
soundloop = new(list(src), FALSE)
/obj/machinery/microwave/Destroy()
eject()
if(wires)
QDEL_NULL(wires)
. = ..()
/obj/machinery/microwave/RefreshParts()
var/E
var/max_items = 10
efficiency = 0
for(var/obj/item/stock_parts/micro_laser/M in component_parts)
E += M.rating
efficiency += M.rating
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
max_items = 10 * M.rating
efficiency = E
max_n_of_items = max_items
max_n_of_items = 10 * M.rating
break
/obj/machinery/microwave/examine(mob/user)
..()
. = ..()
if(!operating)
to_chat(user, "<span class='notice'>Alt-click [src] to turn it on.</span>")
/*******************
* Item Adding
********************/
if(!in_range(user, src) && !issilicon(user) && !isobserver(user))
to_chat(user, "<span class='warning'>You're too far away to examine [src]'s contents and display!</span>")
return
if(operating)
to_chat(user, "<span class='notice'>\The [src] is operating.</span>")
return
if(length(ingredients))
if(issilicon(user))
to_chat(user, "<span class='notice'>\The [src] camera shows:</span>")
else
to_chat(user, "<span class='notice'>\The [src] contains:</span>")
var/list/items_counts = new
for(var/i in ingredients)
if(istype(i, /obj/item/stack))
var/obj/item/stack/S = i
items_counts[S.name] += S.amount
else
var/atom/movable/AM = i
items_counts[AM.name]++
for(var/O in items_counts)
to_chat(user, "<span class='notice'>- [items_counts[O]]x [O].</span>")
else
to_chat(user, "<span class='notice'>\The [src] is empty.</span>")
if(!(stat & (NOPOWER|BROKEN)))
to_chat(user, "<span class='notice'>The status display reads:</span>")
to_chat(user, "<span class='notice'>- Capacity: <b>[max_n_of_items]</b> items.<span>")
to_chat(user, "<span class='notice'>- Cook time reduced by <b>[(efficiency - 1) * 25]%</b>.<span>")
/obj/machinery/microwave/update_icon()
if(broken)
icon_state = "mwb"
else if(dirty_anim_playing)
icon_state = "mwbloody1"
else if(dirty == 100)
icon_state = "mwbloody"
else if(operating)
icon_state = "mw1"
else if(panel_open)
icon_state = "mw-o"
else
icon_state = "mw"
/obj/machinery/microwave/attackby(obj/item/O, mob/user, params)
if(operating)
return
if(!broken && dirty<100)
if(default_deconstruction_screwdriver(user, "mw-o", "mw", O))
return
if(default_unfasten_wrench(user, O))
return
if(default_deconstruction_crowbar(O))
return
if(src.broken > 0)
if(src.broken == 2 && istype(O, /obj/item/wirecutters)) // If it's broken and they're using a screwdriver
user.visible_message( \
"[user] starts to fix part of the microwave.", \
"<span class='notice'>You start to fix part of the microwave...</span>" \
)
if (O.use_tool(src, user, 20))
user.visible_message( \
"[user] fixes part of the microwave.", \
"<span class='notice'>You fix part of the microwave.</span>" \
)
src.broken = 1 // Fix it a bit
else if(src.broken == 1 && istype(O, /obj/item/weldingtool)) // If it's broken and they're doing the wrench
user.visible_message( \
"[user] starts to fix part of the microwave.", \
"<span class='notice'>You start to fix part of the microwave...</span>" \
)
if (O.use_tool(src, user, 20))
user.visible_message( \
"[user] fixes the microwave.", \
"<span class='notice'>You fix the microwave.</span>" \
)
src.icon_state = "mw"
src.broken = 0 // Fix it!
src.dirty = 0 // just to be sure
return 0 //to use some fuel
if(dirty < 100)
if(default_deconstruction_screwdriver(user, icon_state, icon_state, O) || default_unfasten_wrench(user, O))
update_icon()
return
if(panel_open && is_wire_tool(O))
wires.interact(user)
return TRUE
if(broken > 0)
if(broken == 2 && O.tool_behaviour == TOOL_WIRECUTTER) // If it's broken and they're using a screwdriver
user.visible_message("[user] starts to fix part of \the [src].", "<span class='notice'>You start to fix part of \the [src]...</span>")
if(O.use_tool(src, user, 20))
user.visible_message("[user] fixes part of \the [src].", "<span class='notice'>You fix part of \the [src].</span>")
broken = 1 // Fix it a bit
else if(broken == 1 && O.tool_behaviour == TOOL_WELDER) // If it's broken and they're doing the wrench
user.visible_message("[user] starts to fix part of \the [src].", "<span class='notice'>You start to fix part of \the [src]...</span>")
if(O.use_tool(src, user, 20))
user.visible_message("[user] fixes \the [src].", "<span class='notice'>You fix \the [src].</span>")
broken = 0
update_icon()
return FALSE //to use some fuel
else
to_chat(user, "<span class='warning'>It's broken!</span>")
return 1
else if(istype(O, /obj/item/reagent_containers/spray/))
return TRUE
return
if(istype(O, /obj/item/reagent_containers/spray))
var/obj/item/reagent_containers/spray/clean_spray = O
if(clean_spray.reagents.has_reagent("cleaner",clean_spray.amount_per_transfer_from_this))
clean_spray.reagents.remove_reagent("cleaner",clean_spray.amount_per_transfer_from_this,1)
if(clean_spray.reagents.has_reagent("cleaner", clean_spray.amount_per_transfer_from_this))
clean_spray.reagents.remove_reagent("cleaner", clean_spray.amount_per_transfer_from_this,1)
playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6)
user.visible_message( \
"[user] has cleaned the microwave.", \
"<span class='notice'>You clean the microwave.</span>" \
)
src.dirty = 0 // It's clean!
src.broken = 0 // just to be sure
src.icon_state = "mw"
src.updateUsrDialog()
return 1 // Disables the after-attack so we don't spray the floor/user.
user.visible_message("[user] has cleaned \the [src].", "<span class='notice'>You clean \the [src].</span>")
dirty = 0
update_icon()
else
to_chat(user, "<span class='warning'>You need more space cleaner!</span>")
return 1
return TRUE
else if(istype(O, /obj/item/soap/)) // If they're trying to clean it then let them
if(istype(O, /obj/item/soap))
var/obj/item/soap/P = O
user.visible_message( \
"[user] starts to clean the microwave.", \
"<span class='notice'>You start to clean the microwave...</span>" \
)
if (do_after(user, P.cleanspeed, target = src))
user.visible_message( \
"[user] has cleaned the microwave.", \
"<span class='notice'>You clean the microwave.</span>" \
)
src.dirty = 0 // It's clean!
src.broken = 0 // just to be sure
src.icon_state = "mw"
user.visible_message("[user] starts to clean \the [src].", "<span class='notice'>You start to clean \the [src]...</span>")
if(do_after(user, P.cleanspeed, target = src))
user.visible_message("[user] has cleaned \the [src].", "<span class='notice'>You clean \the [src].</span>")
dirty = 0
update_icon()
return TRUE
else if(src.dirty==100) // The microwave is all dirty so can't be used!
to_chat(user, "<span class='warning'>It's dirty!</span>")
return 1
if(dirty == 100) // The microwave is all dirty so can't be used!
to_chat(user, "<span class='warning'>\The [src] is dirty!</span>")
return TRUE
else if(istype(O, /obj/item/storage/bag/tray))
if(istype(O, /obj/item/storage/bag/tray))
var/obj/item/storage/T = O
var/loaded = 0
for(var/obj/item/reagent_containers/food/snacks/S in T.contents)
if (contents.len>=max_n_of_items)
to_chat(user, "<span class='warning'>[src] is full, you can't put anything in!</span>")
return 1
if(ingredients.len >= max_n_of_items)
to_chat(user, "<span class='warning'>\The [src] is full, you can't put anything in!</span>")
return TRUE
if(SEND_SIGNAL(T, COMSIG_TRY_STORAGE_TAKE, S, src))
loaded++
ingredients += S
if(loaded)
to_chat(user, "<span class='notice'>You insert [loaded] items into [src].</span>")
to_chat(user, "<span class='notice'>You insert [loaded] items into \the [src].</span>")
return
if(O.w_class <= WEIGHT_CLASS_NORMAL && !istype(O, /obj/item/storage) && user.a_intent == INTENT_HELP)
if(ingredients.len >= max_n_of_items)
to_chat(user, "<span class='warning'>\The [src] is full, you can't put anything in!</span>")
return TRUE
if(!user.transferItemToLoc(O, src))
to_chat(user, "<span class='warning'>\The [O] is stuck to your hand!</span>")
return FALSE
else if(O.w_class <= WEIGHT_CLASS_NORMAL && !istype(O, /obj/item/storage) && user.a_intent == INTENT_HELP)
if (contents.len>=max_n_of_items)
to_chat(user, "<span class='warning'>[src] is full, you can't put anything in!</span>")
return 1
else
if(!user.transferItemToLoc(O, src))
to_chat(user, "<span class='warning'>\the [O] is stuck to your hand, you cannot put it in \the [src]!</span>")
return 0
ingredients += O
user.visible_message("[user] has added \a [O] to \the [src].", "<span class='notice'>You add [O] to \the [src].</span>")
return
user.visible_message( \
"[user] has added \the [O] to \the [src].", \
"<span class='notice'>You add \the [O] to \the [src].</span>")
else
..()
updateUsrDialog()
..()
/obj/machinery/microwave/AltClick(mob/user)
if(user.canUseTopic(src, BE_CLOSE) && !(operating || broken > 0 || panel_open || !anchored || dirty == 100))
if(user.canUseTopic(src, !issilicon(usr)))
cook()
/*******************
* Microwave Menu
********************/
/obj/machinery/microwave/ui_interact(mob/user) // The microwave Menu
/obj/machinery/microwave/ui_interact(mob/user)
. = ..()
if(panel_open || !anchored)
if(operating || panel_open || !anchored || !user.canUseTopic(src, !issilicon(user)))
return
if(isAI(user) && (stat & NOPOWER))
return
var/dat = "<div class='statusDisplay'>"
if(broken > 0)
dat += "ERROR: 09734014-A2379-D18746 --Bad memory<BR>Contact your operator or use command line to rebase memory ///git checkout {HEAD} -a commit pull --rebase push {*NEW HEAD*}</div>" //Thats how all the git fiddling looks to me
else if(operating)
dat += "Microwaving in progress!<BR>Please wait...!</div>"
else if(dirty==100)
dat += "ERROR: >> 0 --Response input zero<BR>Contact your operator of the device manifactor support.</div>"
else
var/list/items_counts = new
for (var/obj/O in contents)
if(istype(O, /obj/item/stack/))
var/obj/item/stack/S = O
items_counts[O.name] += S.amount
else
items_counts[O.name]++
for (var/O in items_counts)
var/N = items_counts[O]
dat += "[capitalize(O)]: [N]<BR>"
if (items_counts.len==0)
dat += "The microwave is empty.</div>"
if(!length(ingredients))
if(isAI(user))
examine(user)
else
dat = "<h3>Ingredients:</h3>[dat]</div>"
dat += "<A href='?src=[REF(src)];action=cook'>Turn on</A>"
dat += "<A href='?src=[REF(src)];action=dispose'>Eject ingredients</A><BR>"
to_chat(user, "<span class='warning'>\The [src] is empty.</span>")
return
var/datum/browser/popup = new(user, "microwave", name, 300, 300)
popup.set_content(dat)
popup.open()
var/choice = show_radial_menu(user, src, isAI(user) ? ai_radial_options : radial_options, require_near = !issilicon(user))
/***********************************
* Microwave Menu Handling/Cooking
************************************/
// post choice verification
if(operating || panel_open || !anchored || !user.canUseTopic(src, !issilicon(user)))
return
if(isAI(user) && (stat & NOPOWER))
return
usr.set_machine(src)
switch(choice)
if("eject")
eject()
if("use")
cook()
if("examine")
examine(user)
/obj/machinery/microwave/proc/eject()
for(var/i in ingredients)
var/atom/movable/AM = i
AM.forceMove(drop_location())
ingredients.Cut()
/obj/machinery/microwave/proc/cook()
if(stat & (NOPOWER|BROKEN))
return
if(operating || broken > 0 || panel_open || !anchored || dirty == 100)
return
if(wire_disabled)
audible_message("[src] buzzes.")
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
return
if(prob(max((5 / efficiency) - 5, dirty * 5))) //a clean unupgraded microwave has no risk of failure
muck()
return
for(var/obj/O in ingredients)
if(istype(O, /obj/item/reagent_containers/food) || istype(O, /obj/item/grown))
continue
if(prob(min(dirty * 5, 100)))
start_can_fail()
return
break
start()
if (prob(max(5/efficiency-5,dirty*5))) //a clean unupgraded microwave has no risk of failure
muck_start()
if (!microwaving(4))
muck_finish()
return
muck_finish()
return
/obj/machinery/microwave/proc/turn_on()
visible_message("\The [src] turns on.", "<span class='italics'>You hear a microwave humming.</span>")
operating = TRUE
else
if(has_extra_item() && prob(min(dirty*5,100)) && !microwaving(4))
broke()
return
set_light(1.5)
soundloop.start()
update_icon()
if(!microwaving(10))
abort()
return
stop()
/obj/machinery/microwave/proc/spark()
visible_message("<span class='warning'>Sparks fly around [src]!</span>")
var/datum/effect_system/spark_spread/s = new
s.set_up(2, 1, src)
s.start()
var/metal = 0
for(var/obj/item/O in contents)
O.microwave_act(src)
if(O.materials[MAT_METAL])
metal += O.materials[MAT_METAL]
if(metal)
visible_message("<span class='warning'>Sparks fly around [src]!</span>")
if(prob(max(metal/2, 33)))
explosion(loc,0,1,2)
broke()
return
dropContents()
return
/obj/machinery/microwave/proc/microwaving(seconds as num)
for (var/i=1 to seconds)
if (stat & (NOPOWER|BROKEN))
return 0
use_power(500)
sleep(max(12-2*efficiency,2)) // standard microwave means sleep(10). The better the efficiency, the faster the cooking
return 1
/obj/machinery/microwave/proc/has_extra_item()
for (var/obj/O in contents)
if ( \
!istype(O, /obj/item/reagent_containers/food) && \
!istype(O, /obj/item/grown) \
)
return 1
return 0
#define MICROWAVE_NORMAL 0
#define MICROWAVE_MUCK 1
#define MICROWAVE_PRE 2
/obj/machinery/microwave/proc/start()
visible_message("The microwave turns on.", "<span class='italics'>You hear a microwave humming.</span>")
soundloop.start()
operating = TRUE
icon_state = "mw1"
set_light(1.5)
updateUsrDialog()
turn_on()
loop(MICROWAVE_NORMAL, 10)
/obj/machinery/microwave/proc/abort()
operating = FALSE // Turn it off again aferwards
icon_state = "mw"
updateUsrDialog()
set_light(0)
soundloop.stop()
/obj/machinery/microwave/proc/start_can_fail()
turn_on()
loop(MICROWAVE_PRE, 4)
/obj/machinery/microwave/proc/stop()
abort()
/obj/machinery/microwave/proc/muck()
turn_on()
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
dirty_anim_playing = TRUE
update_icon()
loop(MICROWAVE_MUCK, 4)
/obj/machinery/microwave/proc/dispose()
for (var/obj/O in contents)
O.forceMove(drop_location())
to_chat(usr, "<span class='notice'>You dispose of the microwave contents.</span>")
updateUsrDialog()
/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * efficiency, 2)) // standard wait is 10
if(stat & (NOPOWER|BROKEN))
if(MICROWAVE_PRE)
pre_fail()
return
if(!time)
switch(type)
if(MICROWAVE_NORMAL)
loop_finish()
if(MICROWAVE_MUCK)
muck_finish()
if(MICROWAVE_PRE)
pre_success()
return
time--
use_power(500)
addtimer(CALLBACK(src, .proc/loop, type, time, wait), wait)
/obj/machinery/microwave/proc/muck_start()
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) // Play a splat sound
icon_state = "mwbloody1" // Make it look dirty!!
/obj/machinery/microwave/proc/loop_finish()
operating = FALSE
var/metal = 0
for(var/obj/item/O in ingredients)
O.microwave_act(src)
if(O.materials[MAT_METAL])
metal += O.materials[MAT_METAL]
if(metal)
spark()
broken = 2
if(prob(max(metal / 2, 33)))
explosion(loc, 0, 1, 2)
else
dropContents(ingredients)
ingredients.Cut()
after_finish_loop()
/obj/machinery/microwave/proc/pre_fail()
broken = 2
operating = FALSE
spark()
after_finish_loop()
/obj/machinery/microwave/proc/pre_success()
loop(MICROWAVE_NORMAL, 10)
/obj/machinery/microwave/proc/muck_finish()
visible_message("<span class='warning'>The microwave gets covered in muck!</span>")
dirty = 100 // Make it dirty so it can't be used util cleaned
icon_state = "mwbloody" // Make it look dirty too
operating = FALSE // Turn it off again aferwards
updateUsrDialog()
visible_message("<span class='warning'>\The [src] gets covered in muck!</span>")
dirty = 100
dirty_anim_playing = FALSE
operating = FALSE
for(var/obj/item/reagent_containers/food/snacks/S in src)
if(prob(50))
new /obj/item/reagent_containers/food/snacks/badrecipe(src)
qdel(S)
after_finish_loop()
/obj/machinery/microwave/proc/after_finish_loop()
set_light(0)
soundloop.stop()
update_icon()
/obj/machinery/microwave/proc/broke()
var/datum/effect_system/spark_spread/s = new
s.set_up(2, 1, src)
s.start()
icon_state = "mwb" // Make it look all busted up and shit
visible_message("<span class='warning'>The microwave breaks!</span>") //Let them know they're stupid
broken = 2 // Make it broken so it can't be used util fixed
flags_1 = null //So you can't add condiments
operating = FALSE // Turn it off again aferwards
updateUsrDialog()
set_light(0)
soundloop.stop()
/obj/machinery/microwave/Topic(href, href_list)
if(..() || panel_open)
return
usr.set_machine(src)
if(operating)
updateUsrDialog()
return
switch(href_list["action"])
if ("cook")
cook()
if ("dispose")
dispose()
updateUsrDialog()
#undef MICROWAVE_NORMAL
#undef MICROWAVE_MUCK
#undef MICROWAVE_PRE
+6
View File
@@ -332,6 +332,12 @@
/obj/item/pizzabox/infinite/proc/attune_pizza(mob/living/carbon/human/noms) //tonight on "proc names I never thought I'd type"
if(!pizza_preferences[noms.ckey])
pizza_preferences[noms.ckey] = pickweight(pizza_types)
if(noms.has_quirk(/datum/quirk/pineapple_liker))
pizza_preferences[noms.ckey] = /obj/item/reagent_containers/food/snacks/pizza/pineapple
else if(noms.has_quirk(/datum/quirk/pineapple_hater))
var/list/pineapple_pizza_liker = pizza_types.Copy()
pineapple_pizza_liker -= /obj/item/reagent_containers/food/snacks/pizza/pineapple
pizza_preferences[noms.ckey] = pickweight(pineapple_pizza_liker)
if(noms.mind && noms.mind.assigned_role == "Botanist")
pizza_preferences[noms.ckey] = /obj/item/reagent_containers/food/snacks/pizza/dank
+6 -10
View File
@@ -31,18 +31,17 @@
decksize = 50
card_text_file = "strings/cas_black.txt"
/obj/item/toy/cards/deck/cas/Initialize()
. = ..()
/obj/item/toy/cards/deck/cas/populate_deck()
var/static/list/cards_against_space = list("cas_white" = world.file2list("strings/cas_white.txt"),"cas_black" = world.file2list("strings/cas_black.txt"))
allcards = cards_against_space[card_face]
var/list/possiblecards = allcards.Copy()
if(possiblecards.len < decksize) // sanity check
decksize = (possiblecards.len - 1)
var/list/randomcards = list()
while (randomcards.len < decksize)
for(var/x in 1 to decksize)
randomcards += pick_n_take(possiblecards)
for(var/i=1 to randomcards.len)
var/cardtext = randomcards[i]
for(var/x in 1 to randomcards.len)
var/cardtext = randomcards[x]
var/datum/playingcard/P
P = new()
P.name = "[cardtext]"
@@ -50,7 +49,7 @@
cards += P
if(!blanks)
return
for(var/x=1 to blanks)
for(var/x in 1 to blanks)
var/datum/playingcard/P
P = new()
P.name = "Blank Card"
@@ -58,10 +57,7 @@
cards += P
shuffle_inplace(cards) // distribute blank cards throughout deck
/obj/item/toy/cards/deck/cas/attack_hand(mob/user)
. = ..()
if(.)
return
/obj/item/toy/cards/deck/cas/draw_card(mob/user)
if(user.lying)
return
if(cards.len == 0)
@@ -24,14 +24,14 @@ Chaplain
var/obj/item/storage/book/bible/booze/B = new
if(SSreligion.religion)
B.deity_name = SSreligion.deity
B.name = SSreligion.bible_name
B.icon_state = SSreligion.bible_icon_state
B.item_state = SSreligion.bible_item_state
to_chat(H, "There is already an established religion onboard the station. You are an acolyte of [SSreligion.deity]. Defer to the Chaplain.")
if(GLOB.religion)
B.deity_name = GLOB.deity
B.name = GLOB.bible_name
B.icon_state = GLOB.bible_icon_state
B.item_state = GLOB.bible_item_state
to_chat(H, "There is already an established religion onboard the station. You are an acolyte of [GLOB.deity]. Defer to the Chaplain.")
H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK)
var/nrt = SSreligion.holy_weapon_type || /obj/item/nullrod
var/nrt = GLOB.holy_weapon_type || /obj/item/nullrod
var/obj/item/nullrod/N = new nrt(H)
H.put_in_hands(N)
return
@@ -74,9 +74,9 @@ Chaplain
else
B.name = "The Holy Book of [new_religion]"
SSreligion.religion = new_religion
SSreligion.bible_name = B.name
SSreligion.deity = B.deity_name
GLOB.religion = new_religion
GLOB.bible_name = B.name
GLOB.deity = B.deity_name
H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK)
+5 -5
View File
@@ -485,11 +485,11 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
if(href_list["printbible"])
if(cooldown < world.time)
var/obj/item/storage/book/bible/B = new /obj/item/storage/book/bible(src.loc)
if(SSreligion.bible_icon_state && SSreligion.bible_item_state)
B.icon_state = SSreligion.bible_icon_state
B.item_state = SSreligion.bible_item_state
B.name = SSreligion.bible_name
B.deity_name = SSreligion.deity
if(GLOB.bible_icon_state && GLOB.bible_item_state)
B.icon_state = GLOB.bible_icon_state
B.item_state = GLOB.bible_item_state
B.name = GLOB.bible_name
B.deity_name = GLOB.deity
cooldown = world.time + PRINTER_COOLDOWN
else
say("Printer currently unavailable, please wait a moment.")
@@ -164,7 +164,7 @@
return
var/obj/effect/mob_spawn/MS = pick(GLOB.mob_spawners[href_list["JoinAsGhostRole"]])
if(istype(MS) && MS.attack_ghost(src, latejoinercalling = TRUE))
if(MS?.attack_ghost(src, latejoinercalling = TRUE))
SSticker.queued_players -= src
SSticker.queue_delay = 4
qdel(src)
@@ -443,9 +443,10 @@
for(var/datum/job/job in SSjob.occupations)
if(job && IsJobUnavailable(job.title, TRUE) == JOB_AVAILABLE)
available_job_count++
for(var/spawner in GLOB.mob_spawners)
available_job_count++
break
for(var/obj/effect/mob_spawn/spawner in GLOB.mob_spawners)
if(spawner.can_latejoin())
available_job_count++
break
if(!available_job_count)
dat += "<div class='notice red'>There are currently no open positions!</div>"
@@ -464,8 +465,9 @@
"Science" = list(jobs = list(), titles = GLOB.science_positions, color = "#e6b3e6"),
"Security" = list(jobs = list(), titles = GLOB.security_positions, color = "#ff9999"),
)
for(var/spawner in GLOB.mob_spawners)
categorizedJobs["Ghost Role"]["jobs"] += spawner
for(var/obj/effect/mob_spawn/spawner in GLOB.mob_spawners)
if(spawner.can_latejoin())
categorizedJobs["Ghost Role"]["jobs"] += spawner
for(var/datum/job/job in SSjob.occupations)
if(job && IsJobUnavailable(job.title, TRUE) == JOB_AVAILABLE)
@@ -67,6 +67,38 @@
name = "Short (White)"
icon_state = "white_short"
/datum/sprite_accessory/socks/stockings_blue
name = "Stockings (Blue)"
icon_state = "stockings_blue"
/datum/sprite_accessory/socks/stockings_cyan
name = "Stockings (Cyan)"
icon_state = "stockings_cyan"
/datum/sprite_accessory/socks/stockings_dpink
name = "Stockings (Dark Pink)"
icon_state = "stockings_dpink"
/datum/sprite_accessory/socks/stockings_green
name = "Stockings (Green)"
icon_state = "stockings_black"
/datum/sprite_accessory/socks/stockings_orange
name = "Stockings (Orange)"
icon_state = "stockings_orange"
/datum/sprite_accessory/socks/stockings_programmer
name = "Stockings (Programmer)"
icon_state = "stockings_lpink"
/datum/sprite_accessory/socks/stockings_purple
name = "Stockings (Purple)"
icon_state = "stockings_purple"
/datum/sprite_accessory/socks/stockings_yellow
name = "Stockings (Yellow)"
icon_state = "stockings_yellow"
/datum/sprite_accessory/socks/bee_thigh
name = "Thigh-high (Bee)"
icon_state = "bee_thigh"
@@ -44,6 +44,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/siemens_coeff = 1 //base electrocution coefficient
var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded?
var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"]
var/list/special_step_sounds //Sounds to override barefeet walkng
var/grab_sound //Special sound for grabbing
// species-only traits. Can be found in DNA.dm
var/list/species_traits = list()
@@ -30,6 +30,7 @@
var/list/special_names = list("Tarkus")
var/human_surname_chance = 3
var/special_name_chance = 5
var/owner //dobby is a free golem
/datum/species/golem/random_name(gender,unique,lastname)
var/golem_surname = pick(GLOB.golem_names)
@@ -807,3 +808,196 @@
/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C)
. = ..()
C.ventcrawler = initial(C.ventcrawler)
/datum/species/golem/bronze
name = "Bronze Golem"
id = "bronze golem"
prefix = "Bronze"
special_names = list("Bell")
fixed_mut_color = "cd7f32"
info_text = "As a <span class='danger'>Bronze Golem</span>, you are very resistant to loud noises, and make loud noises if something hard hits you, however this ability does hurt your hearing."
special_step_sounds = list('sound/machines/clockcult/integration_cog_install.ogg', 'sound/magic/clockwork/fellowship_armory.ogg' )
attack_verb = "bonk"
mutantears = /obj/item/organ/ears/bronze
var/last_gong_time = 0
var/gong_cooldown = 150
/datum/species/golem/bronze/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
if(!(world.time > last_gong_time + gong_cooldown))
return ..()
if(P.flag == "bullet" || P.flag == "bomb")
gong(H)
return ..()
/datum/species/golem/bronze/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
..()
if(world.time > last_gong_time + gong_cooldown)
gong(H)
/datum/species/golem/bronze/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
..()
if(world.time > last_gong_time + gong_cooldown && M.a_intent != INTENT_HELP)
gong(H)
/datum/species/golem/bronze/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
..()
if(world.time > last_gong_time + gong_cooldown)
gong(H)
/datum/species/golem/bronze/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
..()
if(world.time > last_gong_time + gong_cooldown)
gong(H)
/datum/species/golem/bronze/proc/gong(mob/living/carbon/human/H)
last_gong_time = world.time
for(var/mob/living/M in get_hearers_in_view(7,H))
if(M.stat == DEAD) //F
return
if(M == H)
H.show_message("<span class='narsiesmall'>You cringe with pain as your body rings around you!</span>", 2)
H.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE)
H.soundbang_act(2, 0, 100, 1)
H.jitteriness += 7
var/distance = max(0,get_dist(get_turf(H),get_turf(M)))
switch(distance)
if(0 to 1)
M.show_message("<span class='narsiesmall'>GONG!</span>", 2)
M.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE)
M.soundbang_act(1, 0, 30, 3)
M.confused += 10
M.jitteriness += 4
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong)
if(2 to 3)
M.show_message("<span class='cult'>GONG!</span>", 2)
M.playsound_local(H, 'sound/effects/gong.ogg', 75, TRUE)
M.soundbang_act(1, 0, 15, 2)
M.jitteriness += 3
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong)
else
M.show_message("<span class='warning'>GONG!</span>", 2)
M.playsound_local(H, 'sound/effects/gong.ogg', 50, TRUE)
/datum/species/golem/cardboard //Faster but weaker, can also make new shells on its own
name = "Cardboard Golem"
id = "cardboard golem"
prefix = "Cardboard"
special_names = list("Box")
info_text = "As a <span class='danger'>Cardboard Golem</span>, you aren't very strong, but you are a bit quicker and can easily create more brethren by using cardboard on yourself."
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS)
inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
fixed_mut_color = "ffffff"
limbs_id = "c_golem" //special sprites
attack_verb = "bash"
armor = 25
burnmod = 1.25
heatmod = 2
speedmod = 1.5
punchdamagelow = 4
punchstunthreshold = 7
punchdamagehigh = 8
var/last_creation = 0
var/brother_creation_cooldown = 300
/datum/species/golem/cardboard/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
. = ..()
if(user != H)
return FALSE //forced reproduction is rape.
if(istype(I, /obj/item/stack/sheet/cardboard))
var/obj/item/stack/sheet/cardboard/C = I
if(last_creation + brother_creation_cooldown > world.time) //no cheesing dork
return
if(C.amount < 10)
to_chat(H, "<span class='warning'>You do not have enough cardboard!</span>")
return FALSE
to_chat(H, "<span class='notice'>You attempt to create a new cardboard brother.</span>")
if(do_after(user, 30, target = user))
if(last_creation + brother_creation_cooldown > world.time) //no cheesing dork
return
if(!C.use(10))
to_chat(H, "<span class='warning'>You do not have enough cardboard!</span>")
return FALSE
to_chat(H, "<span class='notice'>You create a new cardboard golem shell.</span>")
create_brother(H.loc)
/datum/species/golem/cardboard/proc/create_brother(var/location)
new /obj/effect/mob_spawn/human/golem/servant(location, /datum/species/golem/cardboard, owner)
last_creation = world.time
/datum/species/golem/leather
name = "Leather Golem"
id = "leather golem"
special_names = list("Face", "Man", "Belt") //Ah dude 4 strength 4 stam leather belt AHHH
inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER, TRAIT_STRONG_GRABBER)
prefix = "Leather"
fixed_mut_color = "624a2e"
info_text = "As a <span class='danger'>Leather Golem</span>, you are flammable, but you can grab things with incredible ease, allowing all your grabs to start at a strong level."
attack_verb = "whipp"
grab_sound = 'sound/weapons/whipgrab.ogg'
attack_sound = 'sound/weapons/whip.ogg'
/datum/species/golem/bone
name = "Bone Golem"
id = "bone golem"
say_mod = "rattles"
prefix = "Bone"
limbs_id = "b_golem"
special_names = list("Head", "Broth", "Fracture", "Rattler", "Appetit")
liked_food = GROSS | MEAT | RAW
toxic_food = null
inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
mutanttongue = /obj/item/organ/tongue/bone
sexes = FALSE
fixed_mut_color = "ffffff"
attack_verb = "rattl"
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH,TRAIT_CALCIUM_HEALER)
info_text = "As a <span class='danger'>Bone Golem</span>, You have a powerful spell that lets you chill your enemies with fear, and milk heals you! Just make sure to watch our for bone-hurting juice."
var/datum/action/innate/bonechill/bonechill
/datum/species/golem/bone/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
if(ishuman(C))
bonechill = new
bonechill.Grant(C)
/datum/species/golem/bone/on_species_loss(mob/living/carbon/C)
if(bonechill)
bonechill.Remove(C)
..()
/datum/action/innate/bonechill
name = "Bone Chill"
desc = "Rattle your bones and strike fear into your enemies!"
check_flags = AB_CHECK_CONSCIOUS
icon_icon = 'icons/mob/actions/actions_spells.dmi'
button_icon_state = "bonechill"
var/cooldown = 600
var/last_use
var/snas_chance = 3
/datum/action/innate/bonechill/Activate()
if(world.time < last_use + cooldown)
to_chat("<span class='notice'>You aren't ready yet to rattle your bones again</span>")
return
owner.visible_message("<span class='warning'>[owner] rattles [owner.p_their()] bones harrowingly.</span>", "<span class='notice'>You rattle your bones</span>")
last_use = world.time
if(prob(snas_chance))
playsound(get_turf(owner),'sound/magic/RATTLEMEBONES2.ogg', 100)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
var/mutable_appearance/badtime = mutable_appearance('icons/mob/human_parts.dmi', "b_golem_eyes", -FIRE_LAYER-0.5)
badtime.appearance_flags = RESET_COLOR
H.overlays_standing[FIRE_LAYER+0.5] = badtime
H.apply_overlay(FIRE_LAYER+0.5)
addtimer(CALLBACK(H, /mob/living/carbon/.proc/remove_overlay, FIRE_LAYER+0.5), 25)
else
playsound(get_turf(owner),'sound/magic/RATTLEMEBONES.ogg', 100)
for(var/mob/living/L in orange(7, get_turf(owner)))
if((MOB_UNDEAD in L.mob_biotypes) || isgolem(L) || HAS_TRAIT(L, TRAIT_RESISTCOLD))
return //Do not affect our brothers
to_chat(L, "<span class='cultlarge'>A spine-chilling sound chills you to the bone!</span>")
L.apply_status_effect(/datum/status_effect/bonechill)
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "spooked", /datum/mood_event/spooked)
@@ -5,7 +5,7 @@
sexes = 0
meat = /obj/item/stack/sheet/mineral/plasma
species_traits = list(NOBLOOD,NOTRANSSTING,NOGENITALS)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER,TRAIT_CALCIUM_HEALER)
inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
mutantlungs = /obj/item/organ/lungs/plasmaman
mutanttongue = /obj/item/organ/tongue/bone/plasmaman
@@ -7,7 +7,7 @@
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
mutanttongue = /obj/item/organ/tongue/bone
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
@@ -21,4 +21,4 @@
/datum/species/skeleton/pirate
name = "Space Queen's Skeleton"
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
+11 -28
View File
@@ -73,39 +73,21 @@
if(I.loc == src)
return TRUE
if(I.anchored)
if(I.anchored || !put_in_hands(I))
blacklistItems[I] ++
return FALSE
// WEAPONS
if(istype(I, /obj/item))
var/obj/item/W = I
if(W.force >= best_force)
put_in_hands(W)
best_force = W.force
return TRUE
// CLOTHING
else if(istype(I, /obj/item/clothing))
var/obj/item/clothing/C = I
monkeyDrop(C)
addtimer(CALLBACK(src, .proc/pickup_and_wear, C), 5)
return TRUE
// EVERYTHING ELSE
if(I.force >= best_force)
best_force = I.force
else
if(!get_item_for_held_index(1) || !get_item_for_held_index(2))
put_in_hands(I)
return TRUE
addtimer(CALLBACK(src, .proc/pickup_and_wear, I), 5)
blacklistItems[I] ++
return FALSE
return TRUE
/mob/living/carbon/monkey/proc/pickup_and_wear(var/obj/item/clothing/C)
if(!equip_to_appropriate_slot(C))
monkeyDrop(get_item_by_slot(C)) // remove the existing item if worn
sleep(5)
equip_to_appropriate_slot(C)
/mob/living/carbon/monkey/proc/pickup_and_wear(obj/item/I)
if(QDELETED(I) || I.loc != src)
return
equip_to_appropriate_slot(I)
/mob/living/carbon/monkey/resist_restraints()
var/obj/item/I = null
@@ -311,7 +293,8 @@
if(I == pickupTarget)
M.visible_message("<span class='danger'>[src] snatches [pickupTarget] from [M].</span>", "<span class='userdanger'>[src] snatched [pickupTarget]!</span>")
if(M.temporarilyRemoveItemFromInventory(pickupTarget) && !QDELETED(pickupTarget))
equip_item(pickupTarget)
if(!equip_item(pickupTarget))
dropItemToGround(pickupTarget)
else
M.visible_message("<span class='danger'>[src] tried to snatch [pickupTarget] from [M], but failed!</span>", "<span class='userdanger'>[src] tried to grab [pickupTarget]!</span>")
pickpocketing = FALSE
+6 -1
View File
@@ -263,7 +263,7 @@
var/mob/M = AM
log_combat(src, M, "grabbed", addition="passive grab")
if(!supress_message)
if(!supress_message && !(iscarbon(AM) && HAS_TRAIT(src, TRAIT_STRONG_GRABBER)))
visible_message("<span class='warning'>[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by their hands":" passively"]!</span>") //Cit change - And they thought ERP was bad.
if(!iscarbon(src))
M.LAssailant = null
@@ -281,6 +281,11 @@
var/datum/disease/D = thing
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
ContactContractDisease(D)
if(iscarbon(L))
var/mob/living/carbon/C = L
if(HAS_TRAIT(src, TRAIT_STRONG_GRABBER))
C.grippedby(src)
//mob verbs are a lot faster than object verbs
//for more info on why this is not atom/pull, see examinate() in mob.dm
+9
View File
@@ -288,8 +288,17 @@
/mob/living/silicon/ai/can_interact_with(atom/A)
. = ..()
var/turf/ai = get_turf(src)
var/turf/target = get_turf(A)
if (.)
return
if(!target)
return
if ((ai.z != target.z) && !is_station_level(ai.z))
return FALSE
if (istype(loc, /obj/item/aicard))
var/turf/T0 = get_turf(src)
var/turf/T1 = get_turf(A)
+2 -2
View File
@@ -1,4 +1,4 @@
/obj/item/paperplane
name = "paper plane"
desc = "Paper, folded in the shape of a plane."
@@ -122,7 +122,7 @@
to_chat(user, "<span class='notice'>Alt-click [src] to fold it into a paper plane.</span>")
/obj/item/paper/AltClick(mob/living/carbon/user, obj/item/I)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user), NO_TK))
return
to_chat(user, "<span class='notice'>You fold [src] into the shape of a plane!</span>")
user.temporarilyRemoveItemFromInventory(src)
@@ -51,7 +51,8 @@
//these become available once upgraded.
var/list/upgrade_reagents = list(
"oil",
"ammonia"
"ammonia",
"ash"
)
var/list/upgrade_reagents2 = list(
@@ -248,13 +249,8 @@
work_animation()
. = TRUE
if("eject")
if(beaker)
beaker.forceMove(drop_location())
if(Adjacent(usr) && !issilicon(usr))
usr.put_in_hands(beaker)
beaker = null
update_icon()
. = TRUE
replace_beaker(usr)
. = TRUE //no afterattack
if("dispense_recipe")
if(!is_operational() || QDELETED(cell))
return
@@ -267,7 +263,7 @@
if(beaker && dispensable_reagents.Find(r_id)) // but since we verify we have the reagent, it'll be fine
var/datum/reagents/R = beaker.reagents
var/free = R.maximum_volume - R.total_volume
var/actual = min(round(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free)
var/actual = min(max(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free)
if(actual)
if(!cell.use(actual / powerefficiency))
say("Not enough energy to complete operation!")
@@ -320,14 +316,12 @@
return
if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
var/obj/item/reagent_containers/B = I
. = 1 //no afterattack
if(beaker)
to_chat(user, "<span class='warning'>A container is already loaded into [src]!</span>")
return
. = TRUE //no afterattack
if(!user.transferItemToLoc(B, src))
return
beaker = B
replace_beaker(user, B)
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
updateUsrDialog()
update_icon()
else if(user.a_intent != INTENT_HARM && !istype(I, /obj/item/card/emag))
to_chat(user, "<span class='warning'>You can't load [I] into [src]!</span>")
@@ -379,7 +373,17 @@
dispensable_reagents |= upgrade_reagents3
powerefficiency = round(newpowereff, 0.01)
/obj/machinery/chem_dispenser/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/chem_dispenser/on_deconstruction()
cell = null
@@ -415,6 +419,12 @@
final_list += list(avoid_assoc_duplicate_keys(fuck[1],key_list) = text2num(fuck[2]))
return final_list
/obj/machinery/chem_dispenser/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
/obj/machinery/chem_dispenser/drinks/Initialize()
. = ..()
AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE)
@@ -478,9 +488,16 @@
"tomatojuice",
"lemonjuice",
"menthol"
) //prevents the soda machine from obtaining chemical upgrades. .
upgrade_reagents = null
upgrade_reagents2 = null
)
upgrade_reagents = list(
"mushroomhallucinogen",
"nothing",
"cryoxadone"
)
upgrade_reagents2 = list(
"banana",
"berryjuice"
)
upgrade_reagents3 = null
emagged_reagents = list(
"thirteenloko",
@@ -533,18 +550,19 @@
"creme_de_cacao",
"triple_sec",
"sake"
)//prevents the booze machine from obtaining chemical upgrades.
upgrade_reagents = null
)
upgrade_reagents = list(
"ethanol",
"fernet"
)
upgrade_reagents2 = null
upgrade_reagents3 = null
emagged_reagents = list(
"ethanol",
"iron",
"alexander",
"clownstears",
"minttoxin",
"atomicbomb",
"fernet",
"aphro",
"aphro+"
)
@@ -28,13 +28,23 @@
else
icon_state = "mixer0b"
/obj/machinery/chem_heater/proc/eject_beaker(mob/user)
/obj/machinery/chem_heater/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
/obj/machinery/chem_heater/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/chem_heater/RefreshParts()
heater_coefficient = 0.1
@@ -58,21 +68,19 @@
return
if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
. = 1 //no afterattack
if(beaker)
to_chat(user, "<span class='warning'>A container is already loaded into [src]!</span>")
. = TRUE //no afterattack
var/obj/item/reagent_containers/B = I
if(!user.transferItemToLoc(B, src))
return
if(!user.transferItemToLoc(I, src))
return
beaker = I
to_chat(user, "<span class='notice'>You add [I] to [src].</span>")
replace_beaker(user, B)
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
updateUsrDialog()
update_icon()
return
return ..()
/obj/machinery/chem_heater/on_deconstruction()
eject_beaker()
replace_beaker()
return ..()
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
@@ -122,5 +130,5 @@
target_temperature = CLAMP(target, 0, 1000)
if("eject")
on = FALSE
eject_beaker(usr)
replace_beaker(usr)
. = TRUE
@@ -60,16 +60,6 @@
else
icon_state = "mixer0"
/obj/machinery/chem_master/proc/eject_beaker(mob/user)
if(beaker)
beaker.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(beaker)
else
adjust_item_drop_location(beaker)
beaker = null
update_icon()
/obj/machinery/chem_master/blob_act(obj/structure/blob/B)
if (prob(50))
qdel(src)
@@ -85,36 +75,49 @@
return
if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
. = 1 // no afterattack
. = TRUE // no afterattack
if(panel_open)
to_chat(user, "<span class='warning'>You can't use the [src.name] while its panel is opened!</span>")
return
if(beaker)
to_chat(user, "<span class='warning'>A container is already loaded into [src]!</span>")
var/obj/item/reagent_containers/B = I
if(!user.transferItemToLoc(B, src))
return
if(!user.transferItemToLoc(I, src))
return
beaker = I
to_chat(user, "<span class='notice'>You add [I] to [src].</span>")
src.updateUsrDialog()
replace_beaker(user, B)
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
updateUsrDialog()
update_icon()
else if(!condi && istype(I, /obj/item/storage/pill_bottle))
if(bottle)
to_chat(user, "<span class='warning'>A pill bottle is already loaded into [src]!</span>")
return
if(!user.transferItemToLoc(I, src))
return
bottle = I
to_chat(user, "<span class='notice'>You add [I] into the dispenser slot.</span>")
src.updateUsrDialog()
updateUsrDialog()
else
return ..()
/obj/machinery/chem_master/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
/obj/machinery/chem_master/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/chem_master/on_deconstruction()
eject_beaker()
replace_beaker(usr)
if(bottle)
bottle.forceMove(drop_location())
adjust_item_drop_location(bottle)
@@ -164,7 +167,7 @@
return
switch(action)
if("eject")
eject_beaker(usr)
replace_beaker(usr)
. = TRUE
if("ejectp")
@@ -19,6 +19,12 @@
var/speed = 1
var/list/holdingitems
var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject")
var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind")
var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice")
var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix")
/obj/machinery/reagentgrinder/Initialize()
. = ..()
holdingitems = list()
@@ -51,7 +57,6 @@
if(A == beaker)
beaker = null
update_icon()
updateUsrDialog()
if(holdingitems[A])
holdingitems -= A
@@ -67,6 +72,18 @@
else
icon_state = "juicer0"
/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params)
//You can only screw open empty grinder
if(!beaker && !length(holdingitems) && default_deconstruction_screwdriver(user, icon_state, icon_state, I))
@@ -82,17 +99,14 @@
return TRUE
if (istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
if (!beaker)
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
return TRUE
to_chat(user, "<span class='notice'>You slide [I] into [src].</span>")
beaker = I
update_icon()
updateUsrDialog()
else
to_chat(user, "<span class='warning'>There's already a container inside [src].</span>")
return TRUE //no afterattack
var/obj/item/reagent_containers/B = I
. = TRUE
if(!user.transferItemToLoc(B, src))
return
replace_beaker(user, B)
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
update_icon()
return
if(holdingitems.len >= limit)
to_chat(user, "<span class='warning'>[src] is filled to capacity!</span>")
@@ -108,8 +122,6 @@
to_chat(user, "<span class='notice'>You empty [I] into [src].</span>")
else
to_chat(user, "<span class='notice'>You fill [src] to the brim.</span>")
updateUsrDialog()
return TRUE
if(!I.grind_results && !I.juice_results)
@@ -125,104 +137,89 @@
if(user.transferItemToLoc(I, src))
to_chat(user, "<span class='notice'>You add [I] to [src].</span>")
holdingitems[I] = TRUE
updateUsrDialog()
return FALSE
/obj/machinery/reagentgrinder/ui_interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave
. = ..()
var/is_chamber_empty = FALSE
var/is_beaker_ready = FALSE
var/processing_chamber = ""
var/beaker_contents = ""
var/dat = ""
if(!operating)
for (var/i in holdingitems)
var/obj/item/O = i
processing_chamber += "\A [O.name]<BR>"
if(operating || !user.canUseTopic(src, !issilicon(user)))
return
if (!processing_chamber)
is_chamber_empty = TRUE
processing_chamber = "Nothing."
if (!beaker)
beaker_contents = "<B>No beaker attached.</B><br>"
else
is_beaker_ready = TRUE
beaker_contents = "<B>The beaker contains:</B><br>"
var/anything = FALSE
for(var/datum/reagent/R in beaker.reagents.reagent_list)
anything = TRUE
beaker_contents += "[R.volume] - [R.name]<br>"
if(!anything)
beaker_contents += "Nothing<br>"
var/list/options = list()
dat = {"
<b>Processing chamber contains:</b><br>
[processing_chamber]<br>
[beaker_contents]<hr>
"}
if (is_beaker_ready)
if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN)))
dat += "<A href='?src=[REF(src)];action=grind'>Grind the reagents</a><BR>"
dat += "<A href='?src=[REF(src)];action=juice'>Juice the reagents</a><BR><BR>"
else if (beaker.reagents.total_volume)
dat += "<A href='?src=[REF(src)];action=mix'>Mix the reagents</a><BR><BR>"
if(length(holdingitems))
dat += "<A href='?src=[REF(src)];action=eject'>Eject the reagents</a><BR>"
if(beaker)
dat += "<A href='?src=[REF(src)];action=detach'>Detach the beaker</a><BR>"
if(beaker || length(holdingitems))
options["eject"] = radial_eject
if(isAI(user))
if(stat & NOPOWER)
return
options["examine"] = radial_examine
// if there is no power or it's broken, the procs will fail but the buttons will still show
if(length(holdingitems))
options["grind"] = radial_grind
options["juice"] = radial_juice
else if(beaker?.reagents.total_volume)
options["mix"] = radial_mix
var/choice
if(length(options) < 1)
return
if(length(options) == 1)
for(var/key in options)
choice = key
else
dat += "Please wait..."
choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open(1)
return
// post choice verification
if(operating || (isAI(user) && stat & NOPOWER) || !user.canUseTopic(src, !issilicon(user)))
return
/obj/machinery/reagentgrinder/Topic(href, href_list)
if(..())
return
var/mob/user = usr
if(!user.canUseTopic(src))
return
if(stat & (NOPOWER|BROKEN))
return
user.set_machine(src)
if(operating)
updateUsrDialog()
return
switch(href_list["action"])
if ("grind")
switch(choice)
if("eject")
eject(user)
if("grind")
grind(user)
if("juice")
juice(user)
if("mix")
mix(user)
if("eject")
eject(user)
if("detach")
detach(user)
updateUsrDialog()
if("examine")
examine(user)
/obj/machinery/reagentgrinder/proc/detach(mob/user)
if(!beaker)
/obj/machinery/reagentgrinder/examine(mob/user)
. = ..()
if(!in_range(user, src) && !issilicon(user) && !isobserver(user))
to_chat(user, "<span class='warning'>You're too far away to examine [src]'s contents and display!</span>")
return
beaker.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(beaker)
beaker = null
update_icon()
updateUsrDialog()
if(operating)
to_chat(user, "<span class='warning'>\The [src] is operating.</span>")
return
if(beaker || length(holdingitems))
to_chat(user, "<span class='notice'>\The [src] contains:</span>")
if(beaker)
to_chat(user, "<span class='notice'>- \A [beaker].</span>")
for(var/i in holdingitems)
var/obj/item/O = i
to_chat(user, "<span class='notice'>- \A [O.name].</span>")
if(!(stat & (NOPOWER|BROKEN)))
to_chat(user, "<span class='notice'>The status display reads:</span>")
to_chat(user, "<span class='notice'>- Grinding reagents at <b>[speed*100]%</b>.<span>")
if(beaker)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
to_chat(user, "<span class='notice'>- [R.volume] units of [R.name].</span>")
/obj/machinery/reagentgrinder/proc/eject(mob/user)
if(!length(holdingitems))
return
for(var/i in holdingitems)
var/obj/item/O = i
O.forceMove(drop_location())
holdingitems -= O
updateUsrDialog()
if(beaker)
replace_beaker(user)
/obj/machinery/reagentgrinder/proc/remove_object(obj/item/O)
holdingitems -= O
@@ -240,7 +237,6 @@
/obj/machinery/reagentgrinder/proc/operate_for(time, silent = FALSE, juicing = FALSE)
shake_for(time / speed)
updateUsrDialog()
operating = TRUE
if(!silent)
if(!juicing)
@@ -251,11 +247,10 @@
/obj/machinery/reagentgrinder/proc/stop_operating()
operating = FALSE
updateUsrDialog()
/obj/machinery/reagentgrinder/proc/juice()
power_change()
if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)))
if(!beaker || stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
return
operate_for(50, juicing = TRUE)
for(var/obj/item/i in holdingitems)
@@ -274,7 +269,7 @@
/obj/machinery/reagentgrinder/proc/grind()
power_change()
if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
if(!beaker || stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
return
operate_for(60)
for(var/i in holdingitems)
@@ -296,13 +291,13 @@
/obj/machinery/reagentgrinder/proc/mix(mob/user)
//For butter and other things that would change upon shaking or mixing
power_change()
if(!beaker)
if(!beaker || stat & (NOPOWER|BROKEN))
return
operate_for(50, juicing = TRUE)
addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50)
/obj/machinery/reagentgrinder/proc/mix_complete()
if(beaker && beaker.reagents.total_volume)
if(beaker?.reagents.total_volume)
//Recipe to make Butter
var/butter_amt = FLOOR(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF, 1)
beaker.reagents.remove_reagent("milk", MILK_TO_BUTTER_COEFF * butter_amt)
@@ -215,15 +215,15 @@
glass_desc = "White and nutritious goodness!"
/datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/M)
if(M.getBruteLoss() && prob(20))
M.heal_bodypart_damage(1,0, 0)
if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER))
M.heal_bodypart_damage(1.5,0, 0)
. = 1
else
if(M.getBruteLoss() && prob(20))
M.heal_bodypart_damage(1,0, 0)
. = 1
if(holder.has_reagent("capsaicin"))
holder.remove_reagent("capsaicin", 2)
var/datum/dna/Mdna = M.has_dna()
if(Mdna && Mdna.species && (Mdna.species.id == "plasmaman" || Mdna.species.id == "skeleton"))
M.heal_bodypart_damage(1,0, 0)
. = 1
..()
/datum/reagent/consumable/soymilk
@@ -908,3 +908,64 @@
/datum/reagent/toxin/mimesbane/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_EMOTEMUTE, id)
/datum/reagent/toxin/bonehurtingjuice //oof ouch
name = "Bone Hurting Juice"
id = "bonehurtingjuice"
description = "A strange substance that looks a lot like water. Drinking it is oddly tempting. Oof ouch."
color = "#AAAAAA77" //RGBA: 170, 170, 170, 77
toxpwr = 0
taste_description = "bone hurting"
overdose_threshold = 20
/datum/reagent/toxin/bonehurtingjuice/on_mob_add(mob/living/carbon/M)
M.say("oof ouch my bones", forced = /datum/reagent/toxin/bonehurtingjuice)
/datum/reagent/toxin/bonehurtingjuice/on_mob_life(mob/living/carbon/M)
M.adjustStaminaLoss(7.5, 0)
if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER))
M.adjustBruteLoss(3.5, 0)
if(prob(12))
switch(rand(1, 3))
if(1)
var/list/possible_says = list("oof.", "ouch!", "my bones.", "oof ouch.", "oof ouch my bones.")
M.say(pick(possible_says), forced = /datum/reagent/toxin/bonehurtingjuice)
if(2)
var/list/possible_mes = list("oofs softly.", "looks like their bones hurt.", "grimaces, as though their bones hurt.")
M.say("*custom " + pick(possible_mes), forced = /datum/reagent/toxin/bonehurtingjuice)
if(3)
to_chat(M, "<span class='warning'>Your bones hurt!</span>")
return ..()
/datum/reagent/toxin/bonehurtingjuice/overdose_process(mob/living/carbon/M)
if(prob(6) && iscarbon(M)) //big oof
var/selected_part
switch(rand(1, 4)) //God help you if the same limb gets picked twice quickly.
if(1)
selected_part = BODY_ZONE_L_ARM
if(2)
selected_part = BODY_ZONE_R_ARM
if(3)
selected_part = BODY_ZONE_L_LEG
if(4)
selected_part = BODY_ZONE_R_LEG
var/obj/item/bodypart/bp = M.get_bodypart(selected_part)
if(M.dna.species.type != /datum/species/skeleton || M.dna.species.type != /datum/species/plasmaman || M.dna.species.type != /datum/species/golem/bone) //We're so sorry skeletons, you're so misunderstood
if(bp)
bp.receive_damage(0, 0, 200)
playsound(M, get_sfx("desceration"), 50, TRUE, -1)
M.visible_message("<span class='warning'>[M]'s bones hurt too much!!</span>", "<span class='danger'>Your bones hurt too much!!</span>")
M.say("OOF!!", forced = /datum/reagent/toxin/bonehurtingjuice)
else //SUCH A LUST FOR REVENGE!!!
to_chat(M, "<span class='warning'>A phantom limb hurts!</span>")
M.say("Why are we still here, just to suffer?", forced = /datum/reagent/toxin/bonehurtingjuice)
else //you just want to socialize
if(bp)
playsound(M, get_sfx("desceration"), 50, TRUE, -1)
M.visible_message("<span class='warning'>[M] rattles loudly and flails around!!</span>", "<span class='danger'>Your bones hurt so much that your missing muscles spasm!!</span>")
M.say("OOF!!", forced=/datum/reagent/toxin/bonehurtingjuice)
bp.receive_damage(200, 0, 0) //But I don't think we should
else
to_chat(M, "<span class='warning'>Your missing arm aches from wherever you left it.</span>")
M.emote("sigh")
return ..()
@@ -64,8 +64,8 @@
strengthdiv = 8
for(var/mob/living/simple_animal/revenant/R in get_hearers_in_view(7,get_turf(holder.my_atom)))
var/deity
if(SSreligion.deity)
deity = SSreligion.deity
if(GLOB.deity)
deity = GLOB.deity
else
deity = "Christ"
to_chat(R, "<span class='userdanger'>The power of [deity] compels you!</span>")
@@ -119,3 +119,10 @@
id = "mimesbane"
results = list("mimesbane" = 3)
required_reagents = list("radium" = 1, "mutetoxin" = 1, "nothing" = 1)
/datum/chemical_reaction/bonehurtingjuice
name = "Bone Hurting Juice"
id = "bonehurtingjuice"
results = list("bonehurtingjuice" = 5)
required_reagents = list("mutagen" = 1, "itching_powder" = 3, "milk" = 1)
mix_message = "<span class='danger'>The mixture suddenly becomes clear and looks a lot like water. You feel a strong urge to drink it.</span>"
@@ -21,6 +21,14 @@
category = list("Computer Boards")
departmental_flags = DEPARTMENTAL_FLAG_ALL
/datum/design/board/minesweeper
name = "Computer Design (Minesweeper Arcade Machine)"
desc = "Allows for the construction of circuit boards used to build a new Minesweeper machine."
id = "arcade_minesweeper"
build_path = /obj/item/circuitboard/computer/arcade/minesweeper
category = list("Computer Boards")
departmental_flags = DEPARTMENTAL_FLAG_ALL
/datum/design/board/slot_machine
name = "Computer Design (Slot Machine)"
desc = "Allows for the construction of circuit boards used to build a new slot machine."
+5 -1
View File
@@ -81,7 +81,11 @@
/obj/item/stack/sheet/cloth = /datum/species/golem/cloth,
/obj/item/stack/sheet/mineral/adamantine = /datum/species/golem/adamantine,
/obj/item/stack/sheet/plastic = /datum/species/golem/plastic,
/obj/item/stack/tile/brass = /datum/species/golem/clockwork)
/obj/item/stack/tile/brass = /datum/species/golem/clockwork,
/obj/item/stack/tile/bronze = /datum/species/golem/bronze,
/obj/item/stack/sheet/cardboard = /datum/species/golem/cardboard,
/obj/item/stack/sheet/leather = /datum/species/golem/leather,
/obj/item/stack/sheet/bone = /datum/species/golem/bone)
if(istype(I, /obj/item/stack))
var/obj/item/stack/O = I
+6
View File
@@ -94,3 +94,9 @@
H.dna.features["ears"] = "None"
H.dna.species.mutant_bodyparts -= "ears"
H.update_body()
/obj/item/organ/ears/bronze
name = "tin ears"
desc = "The robust ears of a bronze golem. "
damage_multiplier = 0.1 //STRONK
bang_protect = 1 //Fear me weaklings.
+3 -3
View File
@@ -1795,10 +1795,10 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
desc = "Nothing is more terrifying than clowns with fully automatic weaponry."
item = /obj/item/storage/backpack/duffelbag/clown/syndie
/datum/uplink_item/badass/durasteel_toolbox
name = "Durasteel Toolbox"
/datum/uplink_item/badass/plastitanium_toolbox
name = "Plastitanium Toolbox"
desc = "A very high impact toolbox. Excels at destroying stationary structures."
item = /obj/item/storage/toolbox/durasteel
item = /obj/item/storage/toolbox/plastitanium
cost = 2 //18 damage on mobs, 50 on objects, 4.5 stam/hit
/datum/uplink_item/badass/balloon