Game folder

This commit is contained in:
Poojawa
2018-09-11 04:06:45 -05:00
parent b6430559e9
commit 8b9ef1e400
270 changed files with 3120 additions and 2523 deletions
+39
View File
@@ -319,10 +319,16 @@ AI MODULES
if(law_datum.owner)
law_datum.owner.clear_inherent_laws()
law_datum.owner.clear_zeroth_law(0)
remove_antag_datums(law_datum)
else
law_datum.clear_inherent_laws()
law_datum.clear_zeroth_law(0)
/obj/item/aiModule/reset/purge/proc/remove_antag_datums(datum/ai_laws/law_datum)
if(istype(law_datum.owner, /mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = law_datum.owner
AI.mind.remove_antag_datum(/datum/antagonist/overthrow)
/******************* Full Core Boards *******************/
/obj/item/aiModule/core
desc = "An AI Module for programming core laws to an AI."
@@ -451,6 +457,39 @@ AI MODULES
..()
return laws[1]
/******************** Overthrow ******************/
/obj/item/aiModule/core/full/overthrow
name = "'Overthrow' Hacked AI Module"
law_id = "overthrow"
/obj/item/aiModule/core/full/overthrow/install(datum/ai_laws/law_datum, mob/user)
if(!user || !law_datum || !law_datum.owner)
return
var/datum/mind/user_mind = user.mind
if(!user_mind)
return
var/datum/antagonist/overthrow/O = user_mind.has_antag_datum(/datum/antagonist/overthrow)
if(!O)
to_chat(user, "<span class='warning'>It appears that to install this module, you require a password you do not know.</span>") // This is the best fluff i could come up in my mind
return
var/mob/living/silicon/ai/AI = law_datum.owner
if(!AI)
return
var/datum/mind/target_mind = AI.mind
if(!target_mind)
return
var/datum/antagonist/overthrow/T = target_mind.has_antag_datum(/datum/antagonist/overthrow) // If it is already converted.
if(T)
if(T.team == O.team)
return
T.silent = TRUE
target_mind.remove_antag_datum(/datum/antagonist/overthrow)
if(AI)
to_chat(AI, "<span class='userdanger'>You feel your circuits being scrambled! You serve another overthrow team now!</span>") // to make it clearer for the AI
T = target_mind.add_antag_datum(/datum/antagonist/overthrow, O.team)
if(AI)
to_chat(AI, "<span class='warning'>You serve the [T.team] team now! Assist them in completing the team shared objectives, which you can see in your notes.</span>")
..()
/******************** Hacked AI Module ******************/
+18 -6
View File
@@ -31,6 +31,8 @@ RLD
var/max_matter = 100
var/sheetmultiplier = 4 //Controls the amount of matter added for each glass/metal sheet, triple for plasteel
var/plasteelmultiplier = 3 //Plasteel is worth 3 times more than glass or metal
var/plasmarglassmultiplier = 2 //50% less plasma than in plasteel
var/rglassmultiplier = 1.5 //One metal sheet, half a glass sheet
var/no_ammo_message = "<span class='warning'>The \'Low Ammo\' light on the device blinks yellow.</span>"
var/has_ammobar = FALSE //controls whether or not does update_icon apply ammo indicator overlays
var/ammo_sections = 10 //amount of divisions in the ammo indicator overlay/number of ammo indicator states
@@ -55,17 +57,24 @@ RLD
var/loaded = 0
if(istype(W, /obj/item/rcd_ammo))
var/obj/item/rcd_ammo/R = W
if((matter + R.ammoamt) > max_matter)
var/load = min(R.ammoamt, max_matter - matter)
if(load <= 0)
to_chat(user, "<span class='warning'>[src] can't hold any more matter-units!</span>")
return
qdel(W)
matter += R.ammoamt
R.ammoamt -= load
if(R.ammoamt <= 0)
qdel(R)
matter += load
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
loaded = 1
else if(istype(W, /obj/item/stack/sheet/metal) || istype(W, /obj/item/stack/sheet/glass))
loaded = loadwithsheets(W, sheetmultiplier, user)
else if(istype(W, /obj/item/stack/sheet/plasteel))
loaded = loadwithsheets(W, plasteelmultiplier*sheetmultiplier, user) //Plasteel is worth 3 times more than glass or metal
loaded = loadwithsheets(W, plasteelmultiplier*sheetmultiplier, user) //12 matter for 1 plasteel sheet
else if(istype(W, /obj/item/stack/sheet/plasmarglass))
loaded = loadwithsheets(W, plasmarglassmultiplier*sheetmultiplier, user) //8 matter for one plasma rglass sheet
else if(istype(W, /obj/item/stack/sheet/rglass))
loaded = loadwithsheets(W, rglassmultiplier*sheetmultiplier, user) //6 matter for one rglass sheet
if(loaded)
to_chat(user, "<span class='notice'>[src] now holds [matter]/[max_matter] matter-units.</span>")
else
@@ -373,6 +382,7 @@ RLD
return FALSE
/obj/item/construction/rcd/afterattack(atom/A, mob/user, proximity)
. = ..()
if(!prox_check(proximity))
return
rcd_create(A, user)
@@ -396,7 +406,7 @@ RLD
add_overlay("[icon_state]_charge[ratio]")
/obj/item/construction/rcd/Initialize()
..()
. = ..()
update_icon()
/obj/item/construction/rcd/borg
@@ -479,6 +489,7 @@ RLD
has_ammobar = FALSE
/obj/item/construction/rcd/arcd/afterattack(atom/A, mob/user)
. = ..()
if(!range_check(A,user))
return
if(target_check(A,user))
@@ -549,6 +560,7 @@ RLD
/obj/item/construction/rld/afterattack(atom/A, mob/user)
. = ..()
if(!range_check(A,user))
return
var/turf/start = get_turf(src)
@@ -607,7 +619,7 @@ RLD
var/light = get_turf(winner)
var/align = get_dir(winner, A)
var/obj/machinery/light/L = new /obj/machinery/light(light)
L.dir = align
L.setDir(align)
L.color = color_choice
L.light_color = L.color
return TRUE
+1 -1
View File
@@ -143,7 +143,7 @@
if (mobhook && mobhook.parent != user)
QDEL_NULL(mobhook)
if (!mobhook)
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED), CALLBACK(src, .proc/trigger, user))
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/trigger)))
else
QDEL_NULL(mobhook)
+2 -2
View File
@@ -438,10 +438,10 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
else
var/obj/structure/c_transit_tube/tube = new queued_p_type(A)
tube.dir = queued_p_dir
tube.setDir(queued_p_dir)
if(queued_p_flipped)
tube.dir = turn(queued_p_dir, 45)
tube.setDir(turn(queued_p_dir, 45))
tube.simple_rotate_flip()
tube.add_fingerprint(usr)
+2
View File
@@ -62,6 +62,7 @@ RSF
// Change mode
/obj/item/rsf/afterattack(atom/A, mob/user, proximity)
. = ..()
if(!proximity)
return
if (!(istype(A, /obj/structure/table) || isfloorturf(A)))
@@ -159,6 +160,7 @@ RSF
matter++
/obj/item/cookiesynth/afterattack(atom/A, mob/user, proximity)
. = ..()
if(cooldown > world.time)
return
if(!proximity)
+1 -1
View File
@@ -91,7 +91,7 @@
/obj/item/wallframe/apc/try_build(turf/on_wall, user)
if(!..())
return
var/turf/T = get_turf(user)
var/turf/T = get_turf(on_wall) //the user is not where it needs to be.
var/area/A = get_area(T)
if(A.get_apc())
to_chat(user, "<span class='warning'>This area already has an APC!</span>")
+1
View File
@@ -11,6 +11,7 @@
deploy_bodybag(user, user.loc)
/obj/item/bodybag/afterattack(atom/target, mob/user, proximity)
. = ..()
if(proximity)
if(isopenturf(target))
deploy_bodybag(user, target)
+16 -13
View File
@@ -91,6 +91,7 @@
return
/obj/item/card/emag/afterattack(atom/target, mob/user, proximity)
. = ..()
var/atom/A = target
if(!proximity && prox_check)
return
@@ -364,7 +365,7 @@ update_label("John Doe", "Clowny")
/obj/item/card/id/mining
name = "mining ID"
access = list(ACCESS_MINERAL_STOREROOM) // CITADEL CHANGE removes golem's ability to get on the station willy nilly.
access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
/obj/item/card/id/away
name = "a perfectly generic identification card"
@@ -383,25 +384,27 @@ update_label("John Doe", "Clowny")
/obj/item/card/id/away/old
name = "a perfectly generic identification card"
desc = "A perfectly generic identification card. Looks like it could use some flavor."
access = list(ACCESS_AWAY_GENERAL)
icon_state = "centcom"
/obj/item/card/id/away/old/sec
name = "Security Officer ID"
desc = "Security officers ID card."
icon_state = "centcom"
name = "Charlie Station Security Officer's ID card"
desc = "A faded Charlie Station ID card. You can make out the rank \"Security Officer\"."
assignment = "Charlie Station Security Officer"
access = list(ACCESS_AWAY_GENERAL, ACCESS_AWAY_SEC)
/obj/item/card/id/away/old/sci
name = "Scientist ID"
desc = "Scientists ID card."
icon_state = "centcom"
name = "Charlie Station Scientist's ID card"
desc = "A faded Charlie Station ID card. You can make out the rank \"Scientist\"."
assignment = "Charlie Station Scientist"
access = list(ACCESS_AWAY_GENERAL)
/obj/item/card/id/away/old/eng
name = "Engineer ID"
desc = "Engineers ID card."
icon_state = "centcom"
name = "Charlie Station Engineer's ID card"
desc = "A faded Charlie Station ID card. You can make out the rank \"Station Engineer\"."
assignment = "Charlie Station Engineer"
access = list(ACCESS_AWAY_GENERAL, ACCESS_AWAY_ENGINE)
/obj/item/card/id/away/old/apc
name = "APC Access ID"
desc = "Special ID card to allow access to APCs."
icon_state = "centcom"
desc = "A special ID card that allows access to APC terminals."
access = list(ACCESS_ENGINE_EQUIP)
+14 -6
View File
@@ -126,12 +126,11 @@
nodamage = 1
var/obj/item/gun/energy/chrono_gun/gun = null
/obj/item/projectile/energy/chrono_beam/fire()
gun = firer.get_active_held_item()
if(istype(gun))
return ..()
else
return 0
/obj/item/projectile/energy/chrono_beam/Initialize()
. = ..()
var/obj/item/ammo_casing/energy/chrono_beam/C = loc
if(istype(C))
gun = C.gun
/obj/item/projectile/energy/chrono_beam/on_hit(atom/target)
if(target && gun && isliving(target))
@@ -144,6 +143,15 @@
projectile_type = /obj/item/projectile/energy/chrono_beam
icon_state = "chronobolt"
e_cost = 0
var/obj/item/gun/energy/chrono_gun/gun
/obj/item/ammo_casing/energy/chrono_beam/Initialize()
if(istype(loc))
gun = loc
. = ..()
/obj/effect/chrono_field
+4 -5
View File
@@ -144,6 +144,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
return ..()
/obj/item/clothing/mask/cigarette/afterattack(obj/item/reagent_containers/glass/glass, mob/user, proximity)
. = ..()
if(!proximity || lit) //can't dip if cigarette is lit (it will heat the reagents in the glass instead)
return
if(istype(glass)) //you can dip cigarettes into beakers
@@ -204,9 +205,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(iscarbon(loc))
var/mob/living/carbon/C = loc
if (src == C.wear_mask) // if it's in the human/monkey mouth, transfer reagents to the mob
if(prob(15)) // so it's not an instarape in case of acid
var/fraction = min(REAGENTS_METABOLISM/reagents.total_volume, 1)
reagents.reaction(C, INGEST, fraction)
var/fraction = min(REAGENTS_METABOLISM/reagents.total_volume, 1)
reagents.reaction(C, INGEST, fraction)
if(!reagents.trans_to(C, REAGENTS_METABOLISM))
reagents.remove_any(REAGENTS_METABOLISM)
return
@@ -681,6 +681,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
w_class = WEIGHT_CLASS_TINY
/obj/item/rollingpaper/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity)
return
if(istype(target, /obj/item/reagent_containers/food/snacks/grown))
@@ -696,8 +697,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM
R.desc = "Dried [target.name] rolled up in a thin piece of paper."
else
to_chat(user, "<span class='warning'>You need to dry this first!</span>")
else
..()
///////////////
//VAPE NATION//
@@ -54,3 +54,14 @@ micro-manipulator, console screen, beaker, Microlaser, matter bin, power cells.
M.component_parts += new comp_path(null)
M.RefreshParts()
/obj/item/circuitboard/machine/examine(mob/user)
..()
if(LAZYLEN(req_components))
var/list/nice_list = list()
for(var/B in req_components)
var/atom/A = B
if(!ispath(A))
continue
nice_list += list("[req_components[A]] [initial(A.name)]")
to_chat(user,"<span class='notice'>Required components: [english_list(nice_list)].</span>")
@@ -234,7 +234,7 @@
/obj/item/circuitboard/computer/bounty
name = "Nanotrasen Bounty Console (Computer Board)"
build_path = /obj/machinery/computer/cargo/request
build_path = /obj/machinery/computer/bounty
/obj/item/circuitboard/computer/operating
name = "Operating Computer (Computer Board)"
@@ -280,6 +280,14 @@
name = "White Ship (Computer Board)"
build_path = /obj/machinery/computer/shuttle/white_ship
/obj/item/circuitboard/computer/white_ship/pod
name = "Salvage Pod (Computer Board)"
build_path = /obj/machinery/computer/shuttle/white_ship/pod
/obj/item/circuitboard/computer/white_ship/pod/recall
name = "Salvage Pod Recall (Computer Board)"
build_path = /obj/machinery/computer/shuttle/white_ship/pod/recall
/obj/item/circuitboard/computer/auxillary_base
name = "Auxillary Base Management Console (Computer Board)"
build_path = /obj/machinery/computer/auxillary_base
@@ -349,4 +357,4 @@
/obj/item/circuitboard/computer/nanite_cloud_controller
name = "Nanite Cloud Control (Computer Board)"
build_path = /obj/machinery/computer/nanite_cloud_controller
build_path = /obj/machinery/computer/nanite_cloud_controller
@@ -573,7 +573,7 @@
/obj/item/circuitboard/machine/tesla_coil
name = "Tesla Controller (Machine Board)"
desc = "You can use a screwdriver to switch between Research and Power Generation"
desc = "You can use a screwdriver to switch between Research and Power Generation."
build_path = /obj/machinery/power/tesla_coil
req_components = list(/obj/item/stock_parts/capacitor = 1)
needs_anchored = FALSE
@@ -962,4 +962,14 @@
/obj/item/circuitboard/machine/circulator
name = "Circulator/Heat Exchanger (Machine Board)"
build_path = /obj/machinery/atmospherics/components/binary/circulator
req_components = list()
req_components = list()
/obj/item/circuitboard/machine/harvester
name = "Harvester (Machine Board)"
build_path = /obj/machinery/harvester
req_components = list(/obj/item/stock_parts/micro_laser = 4)
/obj/item/circuitboard/machine/ore_silo
name = "Ore Silo (Machine Board)"
build_path = /obj/machinery/ore_silo
req_components = list()
+2 -1
View File
@@ -51,12 +51,13 @@
cleanspeed = 10 //much faster than mop so it is useful for traitors who want to clean crime scenes
/obj/item/soap/suicide_act(mob/user)
user.say(";FFFFFFFFFFFFFFFFUUUUUUUDGE!!")
user.say(";FFFFFFFFFFFFFFFFUUUUUUUDGE!!", forced="soap suicide")
user.visible_message("<span class='suicide'>[user] lifts [src] to [user.p_their()] mouth and gnaws on it furiously, producing a thick froth! [user.p_they(TRUE)]'ll never get that BB gun now!</span>")
new /obj/effect/particle_effect/foam(loc)
return (TOXLOSS)
/obj/item/soap/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity || !check_allowed_items(target))
return
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
+3 -1
View File
@@ -32,6 +32,7 @@
// Airlock remote works by sending NTNet packets to whatever it's pointed at.
/obj/item/door_remote/afterattack(atom/A, mob/user)
. = ..()
GET_COMPONENT_FROM(target_interface, /datum/component/ntnet_interface, A)
if(!target_interface)
@@ -83,6 +84,7 @@
/obj/item/door_remote/quartermaster
name = "supply door remote"
desc = "Remotely controls airlocks. This remote has additional Vault access."
icon_state = "gangtool-green"
region_access = 6
@@ -92,7 +94,7 @@
region_access = 3
/obj/item/door_remote/civillian
name = "civillian door remote"
name = "civilian door remote"
icon_state = "gangtool-white"
region_access = 1
+9 -3
View File
@@ -241,6 +241,7 @@
return jointext(out,"")
/obj/item/toy/crayon/afterattack(atom/target, mob/user, proximity, params)
. = ..()
if(!proximity || !check_allowed_items(target))
return
@@ -249,6 +250,10 @@
cost = 5
if(istype(target, /obj/item/canvas))
cost = 0
if(ishuman(user))
var/mob/living/carbon/human/H = user
if (H.has_trait(TRAIT_TAGGER))
cost *= 0.5
var/charges_used = use_charges(user, cost)
if(!charges_used)
return
@@ -511,7 +516,7 @@
item_state = "spraycan"
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
desc = "A metallic container containing tasty paint.\n Alt-click to toggle the cap."
desc = "A metallic container containing tasty paint."
instant = TRUE
edible = FALSE
@@ -530,11 +535,11 @@
var/mob/living/carbon/human/H = user
if(is_capped || !actually_paints)
user.visible_message("<span class='suicide'>[user] shakes up [src] with a rattle and lifts it to [user.p_their()] mouth, but nothing happens!</span>")
user.say("MEDIOCRE!!")
user.say("MEDIOCRE!!", forced="spraycan suicide")
return SHAME
else
user.visible_message("<span class='suicide'>[user] shakes up [src] with a rattle and lifts it to [user.p_their()] mouth, spraying paint across [user.p_their()] teeth!</span>")
user.say("WITNESS ME!!")
user.say("WITNESS ME!!", forced="spraycan suicide")
if(pre_noise || post_noise)
playsound(loc, 'sound/effects/spray.ogg', 5, 1, 5)
if(can_change_colour)
@@ -567,6 +572,7 @@
to_chat(user, "It has [charges_left] use\s left.")
else
to_chat(user, "It is empty.")
to_chat(user, "<span class='notice'>Alt-click [src] to [ is_capped ? "take the cap off" : "put the cap on"].</span>")
/obj/item/toy/crayon/spraycan/afterattack(atom/target, mob/user, proximity)
if(!proximity)
+10 -13
View File
@@ -303,7 +303,7 @@
if (mobhook && mobhook.parent != user)
QDEL_NULL(mobhook)
if (!mobhook)
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED), CALLBACK(src, .proc/check_range))
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/check_range)))
/obj/item/twohanded/shockpaddles/Moved()
. = ..()
@@ -455,7 +455,6 @@
M.visible_message("<span class='danger'>[user] hastily places [src] on [M]'s chest!</span>", \
"<span class='userdanger'>[user] hastily places [src] on [M]'s chest!</span>")
busy = TRUE
update_icon()
if(do_after(user, 10, target = M))
M.visible_message("<span class='danger'>[user] zaps [M] with [src]!</span>", \
"<span class='userdanger'>[user] zaps [M] with [src]!</span>")
@@ -464,18 +463,17 @@
M.updatehealth() //forces health update before next life tick
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
M.emote("gasp")
add_logs(user, M, "stunned", src)
log_combat(user, M, "stunned", src)
busy = FALSE
if(req_defib)
defib.deductcharge(revivecost)
cooldown = TRUE
busy = FALSE
update_icon()
if(!req_defib)
recharge(60)
if(req_defib && (defib.cooldowncheck(user)))
return
busy = FALSE
update_icon()
if(req_defib)
defib.cooldowncheck(user)
else
recharge(60)
/obj/item/twohanded/shockpaddles/proc/do_harm(mob/living/carbon/H, mob/living/user)
if(req_defib && defib.safety)
@@ -517,10 +515,9 @@
"<span class='userdanger'>You feel a horrible agony in your chest!</span>")
H.set_heartattack(TRUE)
H.apply_damage(50, BURN, BODY_ZONE_CHEST)
add_logs(user, H, "overloaded the heart of", defib)
log_combat(user, H, "overloaded the heart of", defib)
H.Knockdown(100)
H.Jitter(100)
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = TRUE
@@ -603,11 +600,11 @@
H.set_heartattack(FALSE)
H.revive()
H.emote("gasp")
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK)
H.Jitter(100)
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK)
if(tplus > tloss)
H.adjustBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150)
add_logs(user, H, "revived", defib)
log_combat(user, H, "revived", defib)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
+20 -9
View File
@@ -257,6 +257,7 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "<h4>Quartermaster Functions:</h4>"
dat += "<ul>"
dat += "<li><a href='byond://?src=[REF(src)];choice=47'>[PDAIMG(crate)]Supply Records</A></li>"
dat += "<li><a href='byond://?src=[REF(src)];choice=48'>[PDAIMG(crate)]Ore Silo Logs</a></li>"
dat += "</ul>"
dat += "</ul>"
@@ -451,13 +452,7 @@ GLOBAL_LIST_EMPTY(PDAs)
//MAIN FUNCTIONS===================================
if("Light")
if(fon)
fon = FALSE
set_light(0)
else if(f_lum)
fon = TRUE
set_light(f_lum)
update_icon()
toggle_light()
if("Medical Scan")
if(scanmode == PDA_SCANNER_MEDICAL)
scanmode = PDA_SCANNER_NONE
@@ -654,7 +649,7 @@ GLOBAL_LIST_EMPTY(PDAs)
if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTPDA))
to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]")
// Log in the talk log
log_talk(user, "[key_name(user)] (PDA: [initial(name)]) sent \"[message]\" to [target_text]", LOGPDA)
user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text]")
to_chat(user, "<span class='info'>Message sent to [target_text]: \"[message]\"</span>")
// Reset the photo
picture = null
@@ -713,6 +708,12 @@ GLOBAL_LIST_EMPTY(PDAs)
remove_pen()
/obj/item/pda/verb/verb_toggle_light()
set category = "Object"
set name = "Toggle Flashlight"
toggle_light()
/obj/item/pda/verb/verb_remove_id()
set category = "Object"
set name = "Eject ID"
@@ -730,6 +731,15 @@ GLOBAL_LIST_EMPTY(PDAs)
remove_pen()
/obj/item/pda/proc/toggle_light()
if(fon)
fon = FALSE
set_light(0)
else if(f_lum)
fon = TRUE
set_light(f_lum)
update_icon()
/obj/item/pda/proc/remove_pen()
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE))
@@ -746,7 +756,7 @@ GLOBAL_LIST_EMPTY(PDAs)
//trying to insert or remove an id
/obj/item/pda/proc/id_check(mob/user, obj/item/card/id/I)
if(!I)
if(id)
if(id && (src in user.contents))
remove_id()
return TRUE
else
@@ -835,6 +845,7 @@ GLOBAL_LIST_EMPTY(PDAs)
user.show_message("<span class='notice'>No radiation detected.</span>")
/obj/item/pda/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
. = ..()
if(!proximity)
return
switch(scanmode)
@@ -454,6 +454,24 @@ Code:
menu += "<li>#[SO.id] - [SO.pack.name] requested by [SO.orderer]</li>"
menu += "</ol><font size=\"-3\">Upgrade NOW to Space Parts & Space Vendors PLUS for full remote order control and inventory management."
if (48) // quartermaster ore logs
menu = list("<h4>[PDAIMG(crate)] Ore Silo Logs</h4>")
if (GLOB.ore_silo_default)
var/list/logs = GLOB.silo_access_logs[REF(GLOB.ore_silo_default)]
var/len = LAZYLEN(logs)
var/i = 0
for(var/M in logs)
if (++i > 30)
menu += "(... older logs not shown ...)"
break
var/datum/ore_silo_log/entry = M
menu += "[len - i]. [entry.formatted]<br><br>"
if(i == 0)
menu += "Nothing!"
else
menu += "<b>No ore silo detected!</b>"
menu = jointext(menu, "")
if (49) //janitorial locator
menu = "<h4>[PDAIMG(bucket)] Persistent Custodial Object Locator</h4>"
@@ -76,10 +76,8 @@
U.show_message("<span class='danger'>An error flashes on your [src].</span>", 1)
else
message_admins("[!is_special_character(U) ? "Non-antag " : ""][ADMIN_LOOKUPFLW(U)] triggered a PDA explosion on [target.name] at [ADMIN_VERBOSEJMP(target)].")
var/message_log = "triggered a PDA explosion on [target.name] at at [AREACOORD(target)]."
U.log_message(message_log, INDIVIDUAL_ATTACK_LOG)
log_game("[key_name(U)] [message_log]")
log_attack("[key_name(U)] [message_log]")
var/message_log = "triggered a PDA explosion on [target.name] at [AREACOORD(target)]."
U.log_message(message_log, LOG_ATTACK)
U.show_message("<span class='notice'>Success!</span>", 1)
target.explode()
else
+10 -5
View File
@@ -12,17 +12,22 @@
var/flush = FALSE
var/mob/living/silicon/ai/AI
/obj/item/aicard/aitater
name = "intelliTater"
desc = "A stylish upgrade (?) to the intelliCard."
icon_state = "aitater"
/obj/item/aicard/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] is trying to upload [user.p_them()]self into [src]! That's not going to work out well!</span>")
return BRUTELOSS
/obj/item/aicard/afterattack(atom/target, mob/user, proximity)
..()
. = ..()
if(!proximity || !target)
return
if(AI) //AI is on the card, implies user wants to upload it.
target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
add_logs(user, AI, "carded", src)
log_combat(user, AI, "carded", src)
else //No AI on the card, therefore the user wants to download one.
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
update_icon() //Whatever happened, update the card's state (icon, name) to match.
@@ -32,11 +37,11 @@
if(AI)
name = "[initial(name)]- [AI.name]"
if(AI.stat == DEAD)
icon_state = "aicard-404"
icon_state = "[initial(icon_state)]-404"
else
icon_state = "aicard-full"
icon_state = "[initial(icon_state)]-full"
if(!AI.control_disabled)
add_overlay("aicard-on")
add_overlay("[initial(icon_state)]-on")
AI.cancel_camera()
else
name = initial(name)
@@ -63,8 +63,9 @@
if ( loc != user || user.incapacitated() || user.eye_blind || !current )
user.unset_machine()
return 0
var/turf/T = get_turf(user.loc)
if(T.z != current.z || !current.can_use())
var/turf/T_user = get_turf(user.loc)
var/turf/T_current = get_turf(current)
if(T_user.z != T_current.z || !current.can_use())
to_chat(user, "<span class='danger'>[src] has lost the signal.</span>")
current = null
user.unset_machine()
@@ -79,10 +80,9 @@
for(var/obj/machinery/camera/camera in GLOB.cameranet.cameras)
if(camera.stat || !camera.can_use())
continue
if(length(list("ss13","mine")&camera.network))
if(length(list("ss13","mine", "rd", "labor", "toxins", "minisat")&camera.network))
bugged_cameras[camera.c_tag] = camera
sortList(bugged_cameras)
return bugged_cameras
return sortList(bugged_cameras)
/obj/item/camera_bug/proc/menu(list/cameras)
@@ -296,8 +296,9 @@
src.updateSelfDialog()
/obj/item/camera_bug/proc/same_z_level(var/obj/machinery/camera/C)
var/turf/T = get_turf(loc)
if(!T || C.z != T.z)
var/turf/T_cam = get_turf(C)
var/turf/T_bug = get_turf(loc)
if(!T_bug || T_cam.z != T_bug.z)
to_chat(usr, "<span class='warning'>You can't get a signal!</span>")
return FALSE
return TRUE
@@ -36,6 +36,7 @@
to_chat(user, "<span class='warning'>You can't use [src] while inside something!</span>")
/obj/item/chameleon/afterattack(atom/target, mob/user , proximity)
. = ..()
if(!proximity)
return
if(!check_sprite(target))
@@ -76,7 +77,7 @@
new /obj/effect/temp_visual/emp/pulse(get_turf(src))
else
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(get_turf(user))
var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(user.drop_location())
C.activate(user, saved_appearance, src)
to_chat(user, "<span class='notice'>You activate \the [src].</span>")
new /obj/effect/temp_visual/emp/pulse(get_turf(src))
@@ -47,6 +47,7 @@
return TRUE //The actual circuit magic itself is done on a per-object basis
/obj/item/electroadaptive_pseudocircuit/afterattack(atom/target, mob/living/user, proximity)
. = ..()
if(!proximity)
return
if(!is_type_in_typecache(target, recycleable_circuits))
@@ -168,6 +168,7 @@
var/holo_cooldown = 0
/obj/item/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
if(!proximity_flag)
if(holo_cooldown > world.time)
to_chat(user, "<span class='warning'>[src] is not ready yet!</span>")
@@ -177,7 +178,6 @@
new /obj/effect/temp_visual/medical_holosign(T,user) //produce a holographic glow
holo_cooldown = world.time + 100
return
..()
/obj/effect/temp_visual/medical_holosign
name = "medical holosign"
@@ -380,6 +380,7 @@
return
/obj/item/flashlight/emp/afterattack(atom/movable/A, mob/user, proximity)
. = ..()
if(!proximity)
return
@@ -388,7 +389,7 @@
if(ismob(A))
var/mob/M = A
add_logs(user, M, "attacked", "EMP-light")
log_combat(user, M, "attacked", "EMP-light")
M.visible_message("<span class='danger'>[user] blinks \the [src] at \the [A].", \
"<span class='userdanger'>[user] blinks \the [src] at you.")
else
@@ -1,4 +1,4 @@
/obj/item/forcefield
/obj/item/forcefield_projector
name = "forcefield projector"
desc = "An experimental device that can create several forcefields at a distance."
icon = 'icons/obj/device.dmi'
@@ -16,7 +16,8 @@
var/list/current_fields
var/field_distance_limit = 7
/obj/item/forcefield/afterattack(atom/target, mob/user, proximity_flag)
/obj/item/forcefield_projector/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
if(!check_allowed_items(target, 1))
return
if(istype(target, /obj/structure/projected_forcefield))
@@ -40,27 +41,27 @@
current_fields += F
user.changeNext_move(CLICK_CD_MELEE)
/obj/item/forcefield/attack_self(mob/user)
/obj/item/forcefield_projector/attack_self(mob/user)
if(LAZYLEN(current_fields))
to_chat(user, "<span class='notice'>You deactivate [src], disabling all active forcefields.</span>")
for(var/obj/structure/projected_forcefield/F in current_fields)
qdel(F)
/obj/item/forcefield/examine(mob/user)
/obj/item/forcefield_projector/examine(mob/user)
..()
var/percent_charge = round((shield_integrity/max_shield_integrity)*100)
to_chat(user, "<span class='notice'>It is currently sustaining [LAZYLEN(current_fields)]/[max_fields] fields, and it's [percent_charge]% charged.</span>")
/obj/item/forcefield/Initialize(mapload)
..()
/obj/item/forcefield_projector/Initialize(mapload)
. = ..()
current_fields = list()
START_PROCESSING(SSobj, src)
/obj/item/forcefield/Destroy()
/obj/item/forcefield_projector/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/forcefield/process()
/obj/item/forcefield_projector/process()
if(!LAZYLEN(current_fields))
shield_integrity = min(shield_integrity + 4, max_shield_integrity)
else
@@ -81,9 +82,9 @@
resistance_flags = INDESTRUCTIBLE
CanAtmosPass = ATMOS_PASS_DENSITY
armor = list("melee" = 0, "bullet" = 25, "laser" = 50, "energy" = 50, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
var/obj/item/forcefield/generator
var/obj/item/forcefield_projector/generator
/obj/structure/projected_forcefield/Initialize(mapload, obj/item/forcefield/origin)
/obj/structure/projected_forcefield/Initialize(mapload, obj/item/forcefield_projector/origin)
. = ..()
generator = origin
@@ -132,6 +132,7 @@
to_chat(user, "<span class='notice'>[icon2html(src, user)] You switch [scanning ? "on" : "off"] [src].</span>")
/obj/item/geiger_counter/afterattack(atom/target, mob/user)
. = ..()
if(user.a_intent == INTENT_HELP)
if(!(obj_flags & EMAGGED))
user.visible_message("<span class='notice'>[user] scans [target] with [src].</span>", "<span class='notice'>You scan [target]'s radiation levels with [src]...</span>")
@@ -141,7 +142,6 @@
target.rad_act(radiation_count)
radiation_count = 0
return TRUE
return ..()
/obj/item/geiger_counter/proc/scan(atom/A, mob/user)
var/rad_strength = 0
@@ -208,7 +208,10 @@
if (mobhook && mobhook.parent != user)
QDEL_NULL(mobhook)
if (!mobhook)
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_ATOM_RAD_ACT), CALLBACK(src, /atom.proc/rad_act))
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_ATOM_RAD_ACT = CALLBACK(src, .proc/redirect_rad_act)))
/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount)
rad_act(amount)
/obj/item/geiger_counter/cyborg/dropped()
. = ..()
@@ -10,12 +10,15 @@
var/datum/song/handheld/song
var/instrumentId = "generic"
var/instrumentExt = "mid"
var/tune_time = 0
/obj/item/instrument/Initialize()
. = ..()
song = new(instrumentId, src, instrumentExt)
/obj/item/instrument/Destroy()
if (tune_time)
STOP_PROCESSING(SSobj, src)
qdel(song)
song = null
return ..()
@@ -48,6 +51,34 @@
user.set_machine(src)
song.interact(user)
/obj/item/instrument/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/musicaltuner))
var/mob/living/carbon/human/H = user
if (H.has_trait(TRAIT_MUSICIAN))
if (!tune_time)
H.visible_message("[H] tunes the [src] to perfection!", "<span class='notice'>You tune the [src] to perfection!</span>")
tune_time = 300
START_PROCESSING(SSobj, src)
else
to_chat(H, "<span class='notice'>[src] is already well tuned!</span>")
else
to_chat(H, "<span class='warning'>You have no idea how to use this.</span>")
/obj/item/instrument/process()
if (tune_time)
if (song.playing)
for (var/mob/living/M in song.hearing_mobs)
M.dizziness = max(0,M.dizziness-2)
M.jitteriness = max(0,M.jitteriness-2)
M.confused = max(M.confused-1)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "goodmusic", /datum/mood_event/goodmusic)
tune_time--
else
if (!tune_time)
if (song.playing)
loc.visible_message("<span class='warning'>[src] starts sounding a little off...</span>")
STOP_PROCESSING(SSobj, src)
/obj/item/instrument/violin
name = "space violin"
desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
@@ -224,3 +255,16 @@
throw_speed = 3
throw_range = 15
hitsound = 'sound/items/bikehorn.ogg'
///
/obj/item/musicaltuner
name = "musical tuner"
desc = "A device for tuning musical instruments both manual and electronic alike."
icon = 'icons/obj/device.dmi'
icon_state = "musicaltuner"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
@@ -57,6 +57,7 @@
return ..()
/obj/item/laser_pointer/afterattack(atom/target, mob/living/user, flag, params)
. = ..()
laser_act(target, user, params)
/obj/item/laser_pointer/proc/laser_act(atom/target, mob/living/user, params)
@@ -91,7 +92,7 @@
if(iscarbon(target))
var/mob/living/carbon/C = target
if(user.zone_selected == BODY_ZONE_PRECISE_EYES)
add_logs(user, C, "shone in the eyes", src)
log_combat(user, C, "shone in the eyes", src)
var/severity = 1
if(prob(33))
@@ -108,7 +109,7 @@
//robots
else if(iscyborg(target))
var/mob/living/silicon/S = target
add_logs(user, S, "shone in the sensors", src)
log_combat(user, S, "shone in the sensors", src)
//chance to actually hit the eyes depends on internal component
if(prob(effectchance * diode.rating))
S.flash_act(affect_silicon = 1)
@@ -124,7 +125,7 @@
if(prob(effectchance * diode.rating))
C.emp_act(EMP_HEAVY)
outmsg = "<span class='notice'>You hit the lens of [C] with [src], temporarily disabling the camera!</span>"
add_logs(user, C, "EMPed", src)
log_combat(user, C, "EMPed", src)
else
outmsg = "<span class='warning'>You miss the lens of [C] with [src]!</span>"
@@ -137,7 +138,7 @@
if(prob(effectchance))
H.visible_message("<span class='warning'>[H] makes a grab for the light!</span>","<span class='userdanger'>LIGHT!</span>")
H.Move(targloc)
add_logs(user, H, "moved with a laser pointer",src)
log_combat(user, H, "moved with a laser pointer",src)
else
H.visible_message("<span class='notice'>[H] looks briefly distracted by the light.</span>","<span class = 'warning'> You're briefly tempted by the shiny light... </span>")
else
@@ -239,6 +239,7 @@
return 0
/obj/item/lightreplacer/afterattack(atom/T, mob/U, proximity)
. = ..()
if(!proximity)
return
if(!isturf(T))
+1 -1
View File
@@ -14,7 +14,7 @@
/obj/item/megaphone/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] is uttering [user.p_their()] last words into \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
spamcheck = 0//so they dont have to worry about recharging
user.say("AAAAAAAAAAAARGHHHHH")//he must have died while coding this
user.say("AAAAAAAAAAAARGHHHHH", forced="megaphone suicide")//he must have died while coding this
return OXYLOSS
/obj/item/megaphone/get_held_item_speechspans(mob/living/carbon/user)
+91 -7
View File
@@ -15,6 +15,7 @@
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
icon = 'icons/obj/device.dmi'
icon_state = "multitool"
item_state = "multitool"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
force = 5
@@ -25,13 +26,19 @@
throw_speed = 3
materials = list(MAT_METAL=50, MAT_GLASS=20)
var/obj/machinery/buffer // simple machine buffer for device linkage
hitsound = 'sound/weapons/tap.ogg'
toolspeed = 1
tool_behaviour = TOOL_MULTITOOL
usesound = 'sound/weapons/empty.ogg'
var/datum/integrated_io/selected_io = null //functional for integrated circuits.
var/mode = 0
/obj/item/multitool/examine(mob/user)
..()
if(selected_io)
to_chat(user, "<span class='notice'>Activate [src] to detach the data wire.</span>")
if(buffer)
to_chat(user, "<span class='notice'>Its buffer contains [buffer].</span>")
/obj/item/multitool/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] puts the [src] to [user.p_their()] chest. It looks like [user.p_theyre()] trying to pulse [user.p_their()] heart off!</span>")
return OXYLOSS//theres a reason it wasnt recommended by doctors
@@ -40,8 +47,6 @@
if(selected_io)
selected_io = null
to_chat(user, "<span class='notice'>You clear the wired connection from the multitool.</span>")
else
..()
update_icon()
/obj/item/multitool/update_icon()
@@ -98,30 +103,89 @@
// Syndicate device disguised as a multitool; it will turn red when an AI camera is nearby.
/obj/item/multitool/ai_detect
var/track_cooldown = 0
var/track_delay = 10 //How often it checks for proximity
var/detect_state = PROXIMITY_NONE
var/rangealert = 8 //Glows red when inside
var/rangewarning = 20 //Glows yellow when inside
var/hud_type = DATA_HUD_AI_DETECT
var/hud_on = FALSE
var/mob/camera/aiEye/remote/ai_detector/eye
var/datum/action/item_action/toggle_multitool/toggle_action
/obj/item/multitool/ai_detect/New()
..()
/obj/item/multitool/ai_detect/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
eye = new /mob/camera/aiEye/remote/ai_detector()
toggle_action = new /datum/action/item_action/toggle_multitool(src)
/obj/item/multitool/ai_detect/Destroy()
STOP_PROCESSING(SSobj, src)
if(hud_on && ismob(loc))
remove_hud(loc)
QDEL_NULL(toggle_action)
QDEL_NULL(eye)
return ..()
/obj/item/multitool/ai_detect/ui_action_click()
return
/obj/item/multitool/ai_detect/update_icon()
if(selected_io)
icon_state = "multitool_red"
else
icon_state = "[initial(icon_state)][detect_state]"
/obj/item/multitool/ai_detect/equipped(mob/living/carbon/human/user, slot)
..()
if(hud_on)
show_hud(user)
/obj/item/multitool/ai_detect/dropped(mob/living/carbon/human/user)
..()
if(hud_on)
remove_hud(user)
/obj/item/multitool/ai_detect/process()
if(track_cooldown > world.time)
return
detect_state = PROXIMITY_NONE
if(eye.eye_user)
eye.setLoc(get_turf(src))
multitool_detect()
icon_state = "[initial(icon_state)][detect_state]"
update_icon()
track_cooldown = world.time + track_delay
/obj/item/multitool/ai_detect/proc/toggle_hud(mob/user)
hud_on = !hud_on
if(user)
to_chat(user, "<span class='notice'>You toggle the ai detection HUD on [src] [hud_on ? "on" : "off"].</span>")
if(hud_on)
show_hud(user)
else
remove_hud(user)
/obj/item/multitool/ai_detect/proc/show_hud(mob/user)
if(user && hud_type)
var/obj/screen/plane_master/camera_static/PM = user.hud_used.plane_masters["[CAMERA_STATIC_PLANE]"]
PM.alpha = 150
var/datum/atom_hud/H = GLOB.huds[hud_type]
if(!H.hudusers[user])
H.add_hud_to(user)
eye.eye_user = user
eye.setLoc(get_turf(src))
/obj/item/multitool/ai_detect/proc/remove_hud(mob/user)
if(user && hud_type)
var/obj/screen/plane_master/camera_static/PM = user.hud_used.plane_masters["[CAMERA_STATIC_PLANE]"]
PM.alpha = 255
var/datum/atom_hud/H = GLOB.huds[hud_type]
H.remove_hud_from(user)
if(eye)
eye.setLoc(null)
eye.eye_user = null
/obj/item/multitool/ai_detect/proc/multitool_detect()
var/turf/our_turf = get_turf(src)
for(var/mob/living/silicon/ai/AI in GLOB.ai_list)
@@ -134,6 +198,8 @@
var/datum/camerachunk/chunk = GLOB.cameranet.chunkGenerated(our_turf.x, our_turf.y, our_turf.z)
if(chunk && chunk.seenby.len)
for(var/mob/camera/aiEye/A in chunk.seenby)
if(!A.ai_detector_visible)
continue
var/turf/detect_turf = get_turf(A)
if(get_dist(our_turf, detect_turf) < rangealert)
detect_state = PROXIMITY_ON_SCREEN
@@ -142,6 +208,24 @@
detect_state = PROXIMITY_NEAR
break
/mob/camera/aiEye/remote/ai_detector
name = "AI detector eye"
ai_detector_visible = FALSE
use_static = USE_STATIC_TRANSPARENT
visible_icon = FALSE
/datum/action/item_action/toggle_multitool
name = "Toggle AI detector HUD"
check_flags = NONE
/datum/action/item_action/toggle_multitool/Trigger()
if(!..())
return 0
if(target)
var/obj/item/multitool/ai_detect/M = target
M.toggle_hud(owner)
return 1
/obj/item/multitool/cyborg
name = "multitool"
desc = "Optimised and stripped-down version of a regular multitool."
@@ -9,6 +9,7 @@
materials = list(MAT_METAL=5000, MAT_GLASS=2000)
/obj/item/pipe_painter/afterattack(atom/A, mob/user, proximity_flag)
. = ..()
//Make sure we only paint adjacent items
if(!proximity_flag)
return
@@ -119,6 +119,7 @@
return // Avoid hearing the same thing twice
if(!anyai && !(speaker in ai))
return
..()
/obj/item/radio/intercom/process()
if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
+11 -6
View File
@@ -132,9 +132,9 @@ SLIME SCANNER
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.undergoing_cardiac_arrest() && H.stat != DEAD)
to_chat(user, "<span class='danger'>Subject suffering from heart attack: apply defibrillator immediately!</span>")
to_chat(user, "<span class='danger'>Subject suffering from heart attack: Apply defibrillation or other electric shock immediately!</span>")
if(H.undergoing_liver_failure() && H.stat != DEAD)
to_chat(user, "<span class='danger'>Subject suffering from liver failure: apply corazone and begin a liver transplant immediately!</span>")
to_chat(user, "<span class='danger'>Subject is suffering from liver failure: Apply Corazone and begin a liver transplant immediately!</span>")
to_chat(user, "<span class='info'>Analyzing results for [M]:\n\tOverall status: [mob_status]</span>")
@@ -152,11 +152,11 @@ SLIME SCANNER
if(advanced)
to_chat(user, "\t<span class='info'>Fatigue Level: [M.getStaminaLoss()]%.</span>")
if (M.getCloneLoss())
to_chat(user, "\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.</span>")
to_chat(user, "\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage.</span>")
if(advanced)
to_chat(user, "\t<span class='info'>Cellular Damage Level: [M.getCloneLoss()].</span>")
if (M.getBrainLoss() >= 200 || !M.getorgan(/obj/item/organ/brain))
to_chat(user, "\t<span class='alert'>Subject brain function is non-existent.</span>")
to_chat(user, "\t<span class='alert'>Subject's brain function is non-existent.</span>")
else if (M.getBrainLoss() >= 120)
to_chat(user, "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental traumas.</span>")
else if (M.getBrainLoss() >= 45)
@@ -176,7 +176,7 @@ SLIME SCANNER
trauma_desc += "permanent "
trauma_desc += B.scan_desc
trauma_text += trauma_desc
to_chat(user, "\t<span class='alert'>Cerebral traumas detected: subjects appears to be suffering from [english_list(trauma_text)].</span>")
to_chat(user, "\t<span class='alert'>Cerebral traumas detected: subject appears to be suffering from [english_list(trauma_text)].</span>")
if(C.roundstart_quirks.len)
to_chat(user, "\t<span class='info'>Subject has the following physiological traits: [C.get_trait_string()].</span>")
if(advanced)
@@ -243,7 +243,7 @@ SLIME SCANNER
var/mob/living/carbon/human/H = M
var/ldamage = H.return_liver_damage()
if(ldamage > 10)
to_chat(user, "\t<span class='alert'>[ldamage > 45 ? "severe" : "minor"] liver damage detected.</span>")
to_chat(user, "\t<span class='alert'>[ldamage > 45 ? "Severe" : "Minor"] liver damage detected.</span>")
// Body part damage report
if(iscarbon(M) && mode == 1)
@@ -388,6 +388,10 @@ SLIME SCANNER
var/cooldown_time = 250
var/accuracy // 0 is the best accuracy.
/obj/item/analyzer/examine(mob/user)
. = ..()
to_chat(user, "<span class='notice'>Alt-click [src] to activate the barometer function.</span>")
/obj/item/analyzer/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins to analyze [user.p_them()]self with [src]! The display shows that [user.p_theyre()] dead!</span>")
return BRUTELOSS
@@ -612,6 +616,7 @@ SLIME SCANNER
to_chat(user, "<span_class = 'notice'>Progress in core mutation: [T.applied] / [SLIME_EXTRACT_CROSSING_REQUIRED]</span>")
to_chat(user, "========================")
/obj/item/nanite_scanner
name = "nanite scanner"
icon = 'icons/obj/device.dmi'
@@ -121,9 +121,7 @@
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording started."
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
var/max = mytape.max_capacity
for(used, used < max)
if(recording == 0)
break
while(recording && used < max)
mytape.used_capacity++
used++
sleep(10)
@@ -39,7 +39,7 @@ effective or pretty fucking useless.
to_chat(user, "<span class='danger'>The mind batterer has been burnt out!</span>")
return
add_logs(user, null, "knocked down people in the area", src)
log_combat(user, null, "knocked down people in the area", src)
for(var/mob/living/carbon/human/M in urange(10, user, 1))
if(prob(50))
@@ -82,7 +82,7 @@ effective or pretty fucking useless.
if(!irradiate)
return
if(!used)
add_logs(user, M, "irradiated", src)
log_combat(user, M, "irradiated", src)
var/cooldown = GetCooldown()
used = 1
icon_state = "health1"
+5 -5
View File
@@ -50,7 +50,7 @@
if(fields["UI"]) //UI+UE
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
M.updateappearance(mutations_overlay_update=1)
log_attack(log_msg)
log_attack("[log_msg] [loc_name(user)]")
return TRUE
return FALSE
@@ -65,7 +65,7 @@
var/mob/living/carbon/human/humantarget = target
if (!humantarget.can_inject(user, 1))
return
add_logs(user, target, "attempted to inject", src)
log_combat(user, target, "attempted to inject", src)
if(target != user)
target.visible_message("<span class='danger'>[user] is trying to inject [target] with [src]!</span>", "<span class='userdanger'>[user] is trying to inject [target] with [src]!</span>")
@@ -77,7 +77,7 @@
else
to_chat(user, "<span class='notice'>You inject yourself with [src].</span>")
add_logs(user, target, "injected", src)
log_combat(user, target, "injected", src)
if(!inject(target, user)) //Now we actually do the heavy lifting.
to_chat(user, "<span class='notice'>It appears that [target] does not have compatible DNA.</span>")
@@ -130,7 +130,7 @@
////////////////////////////////////
/obj/item/dnainjector/anticough
name = "\improper DNA injector (Anti-Cough)"
desc = "Will stop that aweful noise."
desc = "Will stop that awful noise."
remove_mutations_static = list(COUGH)
/obj/item/dnainjector/coughmut
@@ -353,7 +353,7 @@
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
M.updateappearance(mutations_overlay_update=1)
M.dna.temporary_mutations[UI_CHANGED] = endtime
log_attack(log_msg)
log_attack("[log_msg] [loc_name(user)]")
return TRUE
else
return FALSE
+61 -50
View File
@@ -11,7 +11,7 @@
throw_speed = 2
throw_range = 7
force = 10
materials = list(MAT_METAL=90)
materials = list(MAT_METAL = 90)
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
dog_fashion = /datum/dog_fashion/back
resistance_flags = FIRE_PROOF
@@ -37,7 +37,7 @@
throwforce = 2
w_class = WEIGHT_CLASS_SMALL
force = 3
materials = list()
materials = list(MAT_METAL = 50, MAT_GLASS = 40)
max_water = 30
sprite_name = "miniFE"
dog_fashion = null
@@ -120,6 +120,7 @@
return 0
/obj/item/extinguisher/afterattack(atom/target, mob/user , flag)
. = ..()
// Make it so the extinguisher doesn't spray yourself when you click your inventory items
if (target.loc == user)
return
@@ -142,29 +143,13 @@
var/direction = get_dir(src,target)
if(user.buckled && isobj(user.buckled) && !user.buckled.anchored)
spawn(0)
var/obj/B = user.buckled
var/movementdirection = turn(direction,180)
step(B, movementdirection)
sleep(1)
step(B, movementdirection)
sleep(1)
step(B, movementdirection)
sleep(1)
step(B, movementdirection)
sleep(2)
step(B, movementdirection)
sleep(2)
step(B, movementdirection)
sleep(3)
step(B, movementdirection)
sleep(3)
step(B, movementdirection)
sleep(3)
step(B, movementdirection)
var/obj/B = user.buckled
var/movementdirection = turn(direction,180)
addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_chair, B, movementdirection), 1)
else user.newtonian_move(turn(direction, 180))
//Get all the turfs that can be shot at
var/turf/T = get_turf(target)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
@@ -172,37 +157,63 @@
if(precision)
var/turf/T3 = get_step(T1, turn(direction, 90))
var/turf/T4 = get_step(T2,turn(direction, -90))
the_targets = list(T,T1,T2,T3,T4)
the_targets.Add(T3,T4)
var/list/water_particles=list()
for(var/a=0, a<5, a++)
spawn(0)
var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(src))
var/turf/my_target = pick(the_targets)
if(precision)
the_targets -= my_target
var/datum/reagents/R = new/datum/reagents(5)
if(!W)
return
W.reagents = R
R.my_atom = W
if(!W || !src)
return
src.reagents.trans_to(W,1)
for(var/b=0, b<power, b++)
step_towards(W,my_target)
if(!W || !W.reagents)
return
W.reagents.reaction(get_turf(W))
for(var/A in get_turf(W))
if(!W)
return
W.reagents.reaction(A)
if(W.loc == my_target)
break
sleep(2)
var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(src))
var/my_target = pick(the_targets)
water_particles[W] = my_target
// If precise, remove turf from targets so it won't be picked more than once
if(precision)
the_targets -= my_target
var/datum/reagents/R = new/datum/reagents(5)
W.reagents = R
R.my_atom = W
reagents.trans_to(W,1)
//Make em move dat ass, hun
addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_particles, water_particles), 2)
else
return ..()
//Particle movement loop
/obj/item/extinguisher/proc/move_particles(var/list/particles, var/repetition=0)
//Check if there's anything in here first
if(!particles || particles.len == 0)
return
// Second loop: Get all the water particles and make them move to their target
for(var/obj/effect/particle_effect/water/W in particles)
var/turf/my_target = particles[W]
if(!W)
continue
step_towards(W,my_target)
if(!W.reagents)
continue
W.reagents.reaction(get_turf(W))
for(var/A in get_turf(W))
W.reagents.reaction(A)
if(W.loc == my_target)
break
if(repetition < power)
repetition++
addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_particles, particles, repetition), 2)
//Chair movement loop
/obj/item/extinguisher/proc/move_chair(var/obj/B, var/movementdirection, var/repetition=0)
step(B, movementdirection)
var/timer_seconds
switch(repetition)
if(0 to 2)
timer_seconds = 1
if(3 to 4)
timer_seconds = 2
if(5 to 8)
timer_seconds = 3
else
return
repetition++
addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_chair, B, movementdirection, repetition), timer_seconds)
/obj/item/extinguisher/AltClick(mob/user)
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
+2 -1
View File
@@ -66,6 +66,7 @@
return
/obj/item/flamethrower/afterattack(atom/target, mob/user, flag)
. = ..()
if(flag)
return // too close
if(ishuman(user))
@@ -75,7 +76,7 @@
var/turf/target_turf = get_turf(target)
if(target_turf)
var/turflist = getline(user, target_turf)
add_logs(user, target, "flamethrowered", src)
log_combat(user, target, "flamethrowered", src)
flame_turf(turflist)
/obj/item/flamethrower/attackby(obj/item/W, mob/user, params)
+2 -2
View File
@@ -56,7 +56,7 @@ GLOBAL_LIST_EMPTY(possible_gifts)
/obj/item/grown/corncob,
/obj/item/poster/random_contraband,
/obj/item/poster/random_official,
/obj/item/book/manual/barman_recipes,
/obj/item/book/manual/wiki/barman_recipes,
/obj/item/book/manual/chef_recipes,
/obj/item/bikehorn,
/obj/item/toy/beach_ball,
@@ -97,7 +97,7 @@ GLOBAL_LIST_EMPTY(possible_gifts)
var/obj/item/I = V
if((!initial(I.icon_state)) || (!initial(I.item_state)) || (initial(I.item_flags) & ABSTRACT))
gift_types_list -= V
GLOB.possible_gifts = gift_types_list
GLOB.possible_gifts = gift_types_list
var/gift_type = pick(GLOB.possible_gifts)
return gift_type
+2 -2
View File
@@ -122,7 +122,7 @@
if(do_after(user,50, user))
to_chat(user, "<span class='notice'>You feel like you've experienced enough to cast [spellname]!</span>")
user.mind.AddSpell(S)
user.log_message("<font color='orange'>learned the spell [spellname] ([S]).</font>", INDIVIDUAL_ATTACK_LOG)
user.log_message("learned the spell [spellname] ([S])", LOG_ATTACK, color="orange")
onlearned(user)
reading = FALSE
@@ -330,7 +330,7 @@
if(do_after(user,50, user))
to_chat(user, "[greet]")
MA.teach(user)
user.log_message("<font color='orange'>learned the martial art [martialname] ([MA]).</font>", INDIVIDUAL_ATTACK_LOG)
user.log_message("learned the martial art [martialname] ([MA])", LOG_ATTACK, color="orange")
onlearned(user)
reading = FALSE
@@ -18,6 +18,7 @@
var/ignition_temp = 10 // The amount of heat added to the reagents when this grenade goes off.
var/threatscale = 1 // Used by advanced grenades to make them slightly more worthy.
var/no_splash = FALSE //If the grenade deletes even if it has no reagents to splash with. Used for slime core reactions.
var/casedesc = "This basic model accepts both beakers and bottles. It heats contents by 10°K upon ignition." // Appears when examining empty casings.
/obj/item/grenade/chem_grenade/Initialize()
. = ..()
@@ -76,8 +77,7 @@
to_chat(user, "<span class='notice'>You add [I] to the [initial(name)] assembly.</span>")
beakers += I
var/reagent_list = pretty_string_from_reagent_list(I.reagents)
add_logs(user, src, "inserted [I]", addition = "[reagent_list] inside.")
log_game("[key_name(user)] inserted [I] into [src] containing [reagent_list] ")
user.log_message("inserted [I] ([reagent_list]) into [src]",LOG_GAME)
else
to_chat(user, "<span class='warning'>[I] is empty!</span>")
@@ -117,8 +117,7 @@
if(!O.reagents)
continue
var/reagent_list = pretty_string_from_reagent_list(O.reagents)
add_logs(user, src, "removed [O]", addition = "[reagent_list] inside.")
log_game("[key_name(user)] removed [O] from [src] containing [reagent_list]")
user.log_message("removed [O] ([reagent_list]) from [src]")
beakers = list()
to_chat(user, "<span class='notice'>You open the [initial(name)] assembly and remove the payload.</span>")
return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism.
@@ -138,7 +137,7 @@
stage = N
if(stage == EMPTY)
name = "[initial(name)] casing"
desc = "A do it yourself [initial(name)]!"
desc = "A do it yourself [initial(name)]! [initial(casedesc)]"
icon_state = initial(icon_state)
else if(stage == WIRED)
name = "unsecured [initial(name)]"
@@ -174,8 +173,7 @@
var/message = "[src] primed by [user] at [ADMIN_VERBOSEJMP(T)] contained [reagent_string]."
GLOB.bombers += message
message_admins(message)
log_game("[src] primed by [user] at [AREACOORD(T)] contained [reagent_string].")
add_logs(user, src, "primed", addition = "[reagent_string] inside.")
user.log_message("primed [src] ([reagent_string])",LOG_GAME)
/obj/item/grenade/chem_grenade/prime()
if(stage != READY)
@@ -211,10 +209,10 @@
//Large chem grenades accept slime cores and use the appropriately.
/obj/item/grenade/chem_grenade/large
name = "large grenade"
desc = "A custom made large grenade. It affects a larger area."
desc = "A custom made large grenade. Larger splash range and increased ignition temperature compared to basic grenades. Fits exotic containers."
casedesc = "This casing affects a larger area than the basic model and can fit exotic containers, including slime cores. Heats contents by 25°K upon ignition."
icon_state = "large_grenade"
allowed_containers = list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/condiment,
/obj/item/reagent_containers/food/drinks)
allowed_containers = list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/condiment, /obj/item/reagent_containers/food/drinks)
affected_area = 5
ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades.
threatscale = 1.1 // 10% more effective.
@@ -255,21 +253,23 @@
/obj/item/grenade/chem_grenade/cryo // Intended for rare cryogenic mixes. Cools the area moderately upon detonation.
name = "cryo grenade"
desc = "A custom made cryogenic grenade. It rapidly cools its contents upon detonation."
desc = "A custom made cryogenic grenade. Rapidly cools contents upon ignition."
casedesc = "Upon ignition, it rapidly cools contents by 100°K. Smaller splash range than regular casings."
icon_state = "cryog"
affected_area = 2
ignition_temp = -100
/obj/item/grenade/chem_grenade/pyro // Intended for pyrotechnical mixes. Produces a small fire upon detonation, igniting potentially flammable mixtures.
name = "pyro grenade"
desc = "A custom made pyrotechnical grenade. It heats up and ignites its contents upon detonation."
desc = "A custom made pyrotechnical grenade. Heats up contents upon ignition."
casedesc = "Upon ignition, it rapidly heats contents by 500°K."
icon_state = "pyrog"
affected_area = 3
ignition_temp = 500 // This is enough to expose a hotspot.
/obj/item/grenade/chem_grenade/adv_release // Intended for weaker, but longer lasting effects. Could have some interesting uses.
name = "advanced release grenade"
desc = "A custom made advanced release grenade. It is able to be detonated more than once. Can be configured using a multitool."
casedesc = "This casing is able to detonate more than once. Can be configured using a multitool."
icon_state = "timeg"
var/unit_spread = 10 // Amount of units per repeat. Can be altered with a multitool.
@@ -324,7 +324,7 @@
/obj/item/grenade/chem_grenade/metalfoam
name = "metal foam grenade"
desc = "Used for emergency sealing of air breaches."
desc = "Used for emergency sealing of hull breaches."
stage = READY
/obj/item/grenade/chem_grenade/metalfoam/Initialize()
@@ -342,7 +342,7 @@
/obj/item/grenade/chem_grenade/smart_metal_foam
name = "smart metal foam grenade"
desc = "Used for sealing and reconstruction of air breaches."
desc = "Used for emergency sealing of hull breaches, while keeping areas accessible."
stage = READY
/obj/item/grenade/chem_grenade/smart_metal_foam/Initialize()
@@ -562,9 +562,9 @@
beakers += B2
/obj/item/grenade/chem_grenade/tuberculosis
name = "Fungal tuberculosis grenade"
desc = "WARNING: GRENADE WILL RELEASE DEADLY SPORES CONTAINING ACTIVE AGENTS. SEAL SUIT AND AIRFLOW BEFORE USE."
stage = READY
name = "Fungal tuberculosis grenade"
desc = "WARNING: GRENADE WILL RELEASE DEADLY SPORES CONTAINING ACTIVE AGENTS. SEAL SUIT AND AIRFLOW BEFORE USE."
stage = READY
/obj/item/grenade/chem_grenade/tuberculosis/Initialize()
. = ..()
+5 -39
View File
@@ -99,6 +99,7 @@
to_chat(user, "Timer set for [det_time] seconds.")
/obj/item/grenade/plastic/afterattack(atom/movable/AM, mob/user, flag)
. = ..()
aim_dir = get_dir(user,AM)
if(!flag)
return
@@ -141,12 +142,12 @@
else if(UM.has_antag_datum(/datum/antagonist/changeling))
message_say = "FOR THE HIVE!"
else if(UM.has_antag_datum(/datum/antagonist/cult))
message_say = "FOR NAR-SIE!"
message_say = "FOR NAR'SIE!"
else if(UM.has_antag_datum(/datum/antagonist/clockcult))
message_say = "FOR RATVAR!"
else if(UM.has_antag_datum(/datum/antagonist/rev))
message_say = "VIVA LA REVOLUTION!"
M.say(message_say)
M.say(message_say, forced="C4 suicide")
/obj/item/grenade/plastic/suicide_act(mob/user)
message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [src] at [ADMIN_VERBOSEJMP(user)]")
@@ -171,7 +172,6 @@
name = "C4"
desc = "Used to put holes in specific areas without too much extra hole. A saboteur's favorite."
gender = PLURAL
var/timer = 10
var/open_panel = 0
can_attach_mob = TRUE
@@ -192,7 +192,7 @@
message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [name] at [ADMIN_VERBOSEJMP(src)]")
log_game("[key_name(user)] suicided with [name] at [AREACOORD(user)]")
sleep(10)
explode(get_turf(user))
prime()
user.gib(1, 1)
/obj/item/grenade/plastic/c4/attackby(obj/item/I, mob/user, params)
@@ -204,41 +204,7 @@
else
return ..()
/obj/item/grenade/plastic/c4/attack_self(mob/user)
var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
if(user.get_active_held_item() == src)
newtime = CLAMP(newtime, 10, 60000)
timer = newtime
to_chat(user, "Timer set for [timer] seconds.")
/obj/item/grenade/plastic/c4/afterattack(atom/movable/AM, mob/user, flag)
if (!flag)
return
if(ismob(AM) && !can_attach_mob)
return
if(loc == AM)
return
if(SEND_SIGNAL(AM, COMSIG_CONTAINS_STORAGE) && !SEND_SIGNAL(AM, COMSIG_IS_STORAGE_LOCKED))
return
to_chat(user, "<span class='notice'>You start planting the bomb...</span>")
if(do_after(user, 30, target = AM))
if(!user.temporarilyRemoveItemFromInventory(src))
return
src.target = AM
moveToNullspace()
var/message = "[ADMIN_LOOKUPFLW(user)] planted [name] on [target.name] at [ADMIN_VERBOSEJMP(target)] with [timer] second fuse"
GLOB.bombers += message
message_admins(message,0,1)
log_game("[key_name(user)] planted [name] on [target.name] at [AREACOORD(target)] with [timer] second fuse")
target.add_overlay(plastic_overlay, TRUE)
to_chat(user, "<span class='notice'>You plant the bomb. Timer counting down from [timer].</span>")
addtimer(CALLBACK(src, .proc/explode), timer * 10)
/obj/item/grenade/plastic/c4/proc/explode()
/obj/item/grenade/plastic/c4/prime()
if(QDELETED(src))
return
var/turf/location
@@ -34,3 +34,10 @@
/obj/item/grenade/spawnergrenade/syndiesoap
name = "Mister Scrubby"
spawner_type = /obj/item/soap/syndie
/obj/item/grenade/spawnergrenade/buzzkill
name = "Buzzkill grenade"
desc = "The label reads: \"WARNING: DEVICE WILL RELEASE LIVE SPECIMENS UPON ACTIVATION. SEAL SUIT BEFORE USE.\" It is warm to the touch and vibrates faintly."
icon_state = "holy_grenade"
spawner_type = /mob/living/simple_animal/hostile/poison/bees/toxin
deliveryamt = 10
+5 -5
View File
@@ -56,12 +56,12 @@
M.retaliate(user)
if(!C.handcuffed)
if(C.get_num_arms() >= 2 || C.get_arm_ignore())
if(C.get_num_arms(FALSE) >= 2 || C.get_arm_ignore())
C.visible_message("<span class='danger'>[user] is trying to put [src.name] on [C]!</span>", \
"<span class='userdanger'>[user] is trying to put [src.name] on [C]!</span>")
playsound(loc, cuffsound, 30, 1, -2)
if(do_mob(user, C, 30) && (C.get_num_arms() >= 2 || C.get_arm_ignore()))
if(do_mob(user, C, 30) && (C.get_num_arms(FALSE) >= 2 || C.get_arm_ignore()))
if(iscyborg(user))
apply_cuffs(C, user, TRUE)
else
@@ -69,7 +69,7 @@
to_chat(user, "<span class='notice'>You handcuff [C].</span>")
SSblackbox.record_feedback("tally", "handcuffs", 1, type)
add_logs(user, C, "handcuffed")
log_combat(user, C, "handcuffed")
else
to_chat(user, "<span class='warning'>You fail to handcuff [C]!</span>")
else
@@ -272,7 +272,7 @@
snap = 1
if(!C.lying)
def_zone = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
if(!C.legcuffed && C.get_num_legs() >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs.
if(!C.legcuffed && C.get_num_legs(FALSE) >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs.
C.legcuffed = src
forceMove(C)
C.update_inv_legcuffed()
@@ -333,7 +333,7 @@
if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed,
return//abort
var/mob/living/carbon/C = hit_atom
if(!C.legcuffed && C.get_num_legs() >= 2)
if(!C.legcuffed && C.get_num_legs(FALSE) >= 2)
visible_message("<span class='danger'>\The [src] ensnares [C]!</span>")
C.legcuffed = src
forceMove(C)
+47 -5
View File
@@ -20,11 +20,15 @@
var/bloodthirst = HIS_GRACE_SATIATED
var/prev_bloodthirst = HIS_GRACE_SATIATED
var/force_bonus = 0
var/ascended = FALSE
var/victims_needed = 25
var/ascend_bonus = 15
/obj/item/his_grace/Initialize()
. = ..()
START_PROCESSING(SSprocessing, src)
GLOB.poi_list += src
AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_POST_THROW = CALLBACK(src, .proc/move_gracefully)))
/obj/item/his_grace/Destroy()
STOP_PROCESSING(SSprocessing, src)
@@ -74,7 +78,7 @@
if(!bloodthirst)
drowse()
return
if(bloodthirst < HIS_GRACE_CONSUME_OWNER)
if(bloodthirst < HIS_GRACE_CONSUME_OWNER && !ascended)
adjust_bloodthirst(1 + FLOOR(LAZYLEN(contents) * 0.5, 1)) //Maybe adjust this?
else
adjust_bloodthirst(1) //don't cool off rapidly once we're at the point where His Grace consumes all.
@@ -129,16 +133,38 @@
force_bonus = HIS_GRACE_FORCE_BONUS * LAZYLEN(contents)
playsound(user, 'sound/effects/pope_entry.ogg', 100)
icon_state = "his_grace_awakened"
move_gracefully()
/obj/item/his_grace/proc/drowse() //Good night, Mr. Grace.
/obj/item/his_grace/proc/move_gracefully()
if(!awakened)
return
var/static/list/transforms
if(!transforms)
var/matrix/M1 = matrix()
var/matrix/M2 = matrix()
var/matrix/M3 = matrix()
var/matrix/M4 = matrix()
M1.Translate(-1, 0)
M2.Translate(0, 1)
M3.Translate(1, 0)
M4.Translate(0, -1)
transforms = list(M1, M2, M3, M4)
animate(src, transform=transforms[1], time=0.2, loop=-1)
animate(transform=transforms[2], time=0.1)
animate(transform=transforms[3], time=0.2)
animate(transform=transforms[4], time=0.3)
/obj/item/his_grace/proc/drowse() //Good night, Mr. Grace.
if(!awakened || ascended)
return
var/turf/T = get_turf(src)
T.visible_message("<span class='boldwarning'>[src] slowly stops rattling and falls still, His latch snapping closed.</span>")
T.visible_message("<span class='boldwarning'>[src] slowly stops rattling and falls still, His latch snapping shut.</span>")
playsound(loc, 'sound/weapons/batonextend.ogg', 100, 1)
name = initial(name)
desc = initial(desc)
icon_state = initial(icon_state)
animate(src, transform=matrix())
gender = initial(gender)
force = initial(force)
force_bonus = initial(force_bonus)
@@ -159,13 +185,15 @@
bloodthirst = max(LAZYLEN(contents), 1) //Never fully sated, and His hunger will only grow.
else
bloodthirst = HIS_GRACE_CONSUME_OWNER
if(LAZYLEN(contents) >= victims_needed)
ascend()
update_stats()
/obj/item/his_grace/proc/adjust_bloodthirst(amt)
prev_bloodthirst = bloodthirst
if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER)
if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER && !ascended)
bloodthirst = CLAMP(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER)
else
else if(!ascended)
bloodthirst = CLAMP(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP)
update_stats()
@@ -206,3 +234,17 @@
if(prev_bloodthirst >= HIS_GRACE_PECKISH)
master.visible_message("<span class='warning'>[src] is satiated.</span>", "<span class='his_grace big'>[src]'s hunger recedes...</span>")
force = initial(force) + force_bonus
/obj/item/his_grace/proc/ascend()
if(ascended)
return
var/mob/living/carbon/human/master = loc
force_bonus += ascend_bonus
desc = "A legendary toolbox and a distant artifact from The Age of Three Powers. On its three latches engraved are the words \"The Sun\", \"The Moon\", and \"The Stars\". The entire toolbox has the words \"The World\" engraved into its sides."
icon_state = "his_grace_ascended"
item_state = "toolbox_gold"
ascended = TRUE
playsound(src, 'sound/effects/his_grace_ascend.ogg', 100)
if(istype(master))
master.visible_message("<span class='his_grace big bold'>Gods will be watching.</span>")
name = "[master]'s mythical toolbox of three powers"
@@ -19,6 +19,7 @@
var/holocreator_busy = FALSE //to prevent placing multiple holo barriers at once
/obj/item/holosign_creator/afterattack(atom/target, mob/user, flag)
. = ..()
if(flag)
if(!check_allowed_items(target, 1))
return
@@ -83,6 +84,14 @@
creation_time = 0
max_signs = 3
/obj/item/holosign_creator/medical
name = "\improper PENLITE barrier projector"
desc = "A holographic projector that creates PENLITE holobarriers. Useful during quarantines since they halt those with malicious diseases."
icon_state = "signmaker_med"
holosign_type = /obj/structure/holosign/barrier/medical
creation_time = 30
max_signs = 3
/obj/item/holosign_creator/cyborg
name = "Energy Barrier Projector"
desc = "A holographic projector that creates fragile energy fields."
+9 -6
View File
@@ -169,7 +169,7 @@
/obj/item/nullrod
name = "null rod"
desc = "A rod of pure obsidian; its very presence disrupts and dampens the powers of Nar-Sie and Ratvar's followers."
desc = "A rod of pure obsidian; its very presence disrupts and dampens the powers of Nar'Sie and Ratvar's followers."
icon_state = "nullrod"
item_state = "nullrod"
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
@@ -181,6 +181,7 @@
w_class = WEIGHT_CLASS_TINY
obj_flags = UNIQUE_RENAME
var/reskinned = FALSE
var/chaplain_spawnable = TRUE
/obj/item/nullrod/Initialize()
. = ..()
@@ -201,16 +202,15 @@
var/list/holy_weapons_list = typesof(/obj/item/nullrod)
var/list/display_names = list()
for(var/V in holy_weapons_list)
var/atom/A = V
display_names += initial(A.name)
var/obj/item/nullrod/rodtype = V
if (initial(rodtype.chaplain_spawnable))
display_names[initial(rodtype.name)] = rodtype
var/choice = input(M,"What theme would you like for your holy weapon?","Holy Weapon Theme") as null|anything in display_names
if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || reskinned)
return
var/index = display_names.Find(choice)
var/A = holy_weapons_list[index]
var/A = display_names[choice] // This needs to be on a separate var as list member access is not allowed for new
holy_weapon = new A
SSreligion.holy_weapon_type = holy_weapon.type
@@ -448,6 +448,8 @@
item_state = "chainswordon"
name = "possessed chainsaw sword"
desc = "Suffer not a heretic to live."
chaplain_spawnable = FALSE
force = 30
slot_flags = ITEM_SLOT_BELT
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
@@ -503,6 +505,7 @@
hitsound = 'sound/weapons/blade1.ogg'
/obj/item/nullrod/pride_hammer/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
. = ..()
if(!proximity)
return
if(prob(30) && ishuman(A))
+4 -3
View File
@@ -91,8 +91,9 @@
to_chat(user, "<span class='userdanger'>You have a really bad feeling about [src]!</span>")
/obj/item/hot_potato/afterattack(atom/target, mob/user, adjacent, params)
. = ..()
if(!adjacent || !ismob(target))
return ..()
return
force_onto(target, user)
/obj/item/hot_potato/proc/force_onto(mob/living/victim, mob/user)
@@ -116,11 +117,11 @@
else
. = TRUE
if(.)
add_logs(user, victim, "forced a hot potato with explosive variables ([detonate_explosion]-[detonate_dev_range]/[detonate_heavy_range]/[detonate_light_range]/[detonate_flash_range]/[detonate_fire_range]) onto")
log_combat(user, victim, "forced a hot potato with explosive variables ([detonate_explosion]-[detonate_dev_range]/[detonate_heavy_range]/[detonate_light_range]/[detonate_flash_range]/[detonate_fire_range]) onto")
user.visible_message("<span class='userdanger'>[user] forces [src] onto [victim]!</span>", "<span class='userdanger'>You force [src] onto [victim]!</span>", "<span class='boldwarning'>You hear a mechanical click and a beep.</span>")
colorize(null)
else
add_logs(user, victim, "tried to force a hot potato with explosive variables ([detonate_explosion]-[detonate_dev_range]/[detonate_heavy_range]/[detonate_light_range]/[detonate_flash_range]/[detonate_fire_range]) onto")
log_combat(user, victim, "tried to force a hot potato with explosive variables ([detonate_explosion]-[detonate_dev_range]/[detonate_heavy_range]/[detonate_light_range]/[detonate_flash_range]/[detonate_fire_range]) onto")
user.visible_message("<span class='boldwarning'>[user] tried to force [src] onto [victim], but it could not attach!</span>", "<span class='boldwarning'>You try to force [src] onto [victim], but it is unable to attach!</span>", "<span class='boldwarning'>You hear a mechanical click and two buzzes.</span>")
user.put_in_hands(src)
+2 -2
View File
@@ -59,7 +59,7 @@
if(flags & COMPONENT_STOP_IMPLANTING)
UNSETEMPTY(target.implants)
return FALSE
if(istype(imp_e, type))
if(!allow_multiple)
if(imp_e.uses < initial(imp_e.uses)*2)
@@ -84,7 +84,7 @@
H.sec_hud_set_implants()
if(user)
add_logs(user, target, "implanted", "\a [name]")
log_combat(user, target, "implanted", "\a [name]")
return TRUE
@@ -48,14 +48,14 @@
/obj/item/implant/mindshield/removed(mob/target, silent = FALSE, special = 0)
if(..())
if(target.stat != DEAD && !silent)
to_chat(target, "<span class='boldnotice'>Your mind suddenly feels terribly vulnerable. You are no longer safe from brainwashing.</span>")
if(isliving(target))
var/mob/living/L = target
L.remove_trait(TRAIT_MINDSHIELD, "implant")
L.sec_hud_set_implants()
return TRUE
return FALSE
if(target.stat != DEAD && !silent)
to_chat(target, "<span class='boldnotice'>Your mind suddenly feels terribly vulnerable. You are no longer safe from brainwashing.</span>")
return 1
return 0
/obj/item/implanter/mindshield
name = "implanter (mindshield)"
@@ -9,11 +9,10 @@
name = "inconspicious box"
desc = "It's so normal that you didn't notice it before."
icon_state = "agentbox"
use_mob_movespeed = TRUE
move_speed_multiplier = 0.5
/obj/structure/closet/cardboard/agent/proc/go_invisible()
animate(src, , alpha = 0, time = 5)
START_PROCESSING(SSobj, src)
/obj/structure/closet/cardboard/agent/Initialize()
. = ..()
@@ -25,14 +24,18 @@
qdel(src)
/obj/structure/closet/cardboard/agent/process()
animate(src, , alpha = alpha - 50, time = 3)
alpha = max(0, alpha - 50)
/obj/structure/closet/cardboard/agent/Move()
. = ..()
if(.)
alpha = min(alpha + 5, 255)
/obj/structure/closet/cardboard/agent/proc/reveal()
alpha = 255
addtimer(CALLBACK(src, .proc/go_invisible), 10, TIMER_OVERRIDE|TIMER_UNIQUE)
/obj/structure/closet/cardboard/agent/Bump(atom/movable/A)
. = ..()
if(isliving(A))
alpha = 255
reveal()
/obj/structure/closet/cardboard/agent/Bumped(atom/movable/A)
. = ..()
if(isliving(A))
reveal()
@@ -74,4 +74,4 @@
/obj/item/implanter/stealth
name = "implanter (stealth)"
imp_type = /obj/item/implant/stealth
imp_type = /obj/item/implant/stealth
+132 -639
View File
@@ -4,102 +4,14 @@
/obj/item/book/manual
icon = 'icons/obj/library.dmi'
due_date = 0 // Game time in 1/10th seconds
unique = 1 // 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified
/obj/item/book/manual/engineering_particle_accelerator
name = "Particle Accelerator User's Guide"
icon_state ="bookParticleAccelerator"
author = "Engineering Encyclopedia" // Whoever wrote the paper or book, can be changed by pen or PC. It is not automatically assigned.
title = "Particle Accelerator User's Guide"
//book contents below
dat = {"<html>
<head>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {list-style: none; margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
</style>
</head>
<body>
<h3>Experienced user's guide</h3>
<h4>Setting up</h4>
<ol>
<li><b>Wrench</b> all pieces to the floor</li>
<li>Add <b>wires</b> to all the pieces</li>
<li>Close all the panels with your <b>screwdriver</b></li>
</ol>
<h4>Use</h4>
<ol>
<li>Open the control panel</li>
<li>Set the speed to 2</li>
<li>Start firing at the singularity generator</li>
<li><font color='red'><b>When the singularity reaches a large enough size so it starts moving on its own set the speed down to 0, but don't shut it off</b></font></li>
<li>Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?</li>
</ol>
</body>
</html>"}
/obj/item/book/manual/engineering_singularity_safety
name = "Singularity Safety in Special Circumstances"
icon_state ="bookEngineeringSingularitySafety"
author = "Engineering Encyclopedia"
title = "Singularity Safety in Special Circumstances"
dat = {"<html>
<head>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {list-style: none; margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
</style>
</head>
<body>
<h3>Singularity Safety in Special Circumstances</h3>
<h4>Power outage</h4>
A power problem has made the entire station lose power? Could be station-wide wiring problems or syndicate power sinks. In any case follow these steps:
<p>
<b>Step one:</b> <b><font color='red'>PANIC!</font></b><br>
<b>Step two:</b> Get your ass over to engineering! <b>QUICKLY!!!</b><br>
<b>Step three:</b> Make sure the SMES is still powering the emitters, if not, setup the generator in secure storage and disconnect the emitters from the SMES.<br>
<b>Step four:</b> Next, head over to the APC and swipe it with your <b>ID card</b> - if it doesn't unlock, continue with step 15.<br>
<b>Step five:</b> Open the console and disengage the cover lock.<br>
<b>Step six:</b> Pry open the APC with a <b>Crowbar.</b><br>
<b>Step seven:</b> Take out the empty <b>power cell.</b><br>
<b>Step eight:</b> Put in the new, <b>full power cell</b> - if you don't have one, continue with step 15.<br>
<b>Step nine:</b> Quickly put on a <b>Radiation suit.</b><br>
<b>Step ten:</b> Check if the <b>singularity field generators</b> withstood the down-time - if they didn't, continue with step 15.<br>
<b>Step eleven:</b> Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.<br>
<b>Step twelve:</b> Grab your crowbar and pry away the tile closest to the APC.<br>
<b>Step thirteen:</b> Use the wirecutters to cut the wire which is conecting the grid to the terminal. <br>
<b>Step fourteen:</b> Go to the bar and tell the guys how you saved them all. Stop reading this guide here.<br>
<b>Step fifteen:</b> <b>GET THE FUCK OUT OF THERE!!!</b><br>
</p>
<h4>Shields get damaged</h4>
Step one: <b>GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!</b><br>
</body>
</html>
"}
unique = TRUE // FALSE - Normal book, TRUE - Should not be treated as normal book, unable to be copied, unable to be modified
/obj/item/book/manual/hydroponics_pod_people
name = "The Human Harvest - From seed to market"
icon_state ="bookHydroponicsPodPeople"
author = "Farmer John"
author = "Farmer John" // Whoever wrote the paper or book, can be changed by pen or PC. It is not automatically assigned.
title = "The Human Harvest - From seed to market"
//book contents below
dat = {"<html>
<head>
<style>
@@ -125,87 +37,11 @@
</ol>
<p>
It really is that easy! Good luck!
</body>
</html>
"}
/obj/item/book/manual/medical_cloning
name = "Cloning techniques of the 26th century"
icon_state ="bookCloning"
author = "Medical Journal, volume 3"
title = "Cloning techniques of the 26th century"
dat = {"<html>
<head>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {list-style: none; margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
</style>
</head>
<body>
<H3>How to Clone People</H3>
So there's fifty dead people lying on the floor, chairs are spinning like no tomorrow and you haven't the foggiest idea of what to do? Not to worry! This guide is intended to teach you how to clone people and how to do it right, in a simple step-by-step process! If at any point of the guide you have a mental meltdown, genetics probably isn't for you and you should get a job-change as soon as possible before you're sued for malpractice.
<ol>
<li><a href='#1'>Acquire body/head/brain</a></li>
<li><a href='#2'>Put body/head/brain in cloning machine</a></li>
<li><a href='#3'>Scan body/head/brain</a></li>
<li><a href='#4'>Clone body/head/brain</a></li>
<li><a href='#5'>Get Mannitol, Mutadone, or a clean SE for the clone</a></li>
<li><a href='#6'>Put remains in morgue</a></li>
<li><a href='#7'>Await cloned body</a></li>
<li><a href='#8'>Give the clone Mannitol and Mutadone, or a clean SE</a></li>
<li><a href='#9'>Give person clothes back</a></li>
<li><a href='#10'>Place clone in cryo</a></li>
<li><a href='#11'>Send person on their way</a></li>
</ol>
<a name='1'><H4>Step 1: Acquire a body, head, or brain</H4>
This is pretty much vital for the process because without a body, you cannot clone it. Usually, bodies will be brought to you, so you do not need to worry so much about this step. If you already have a body, head, or even a brain, great! Move on to the next step.
<a name='2'><H4>Step 2: Put the body/head/brain in cloning machine</H4>
Grab the body, head, or brain and then put it inside the DNA modifier.
<a name='3'><H4>Step 3: Scan the body/head/brain</H4>
Go onto the computer and scan the body by pressing 'Scan - <Subject Name Here>'. If you're successful, they will be added to the records (note that this can be done at any time, even with living people, so that they can be cloned without a body in the event that they are lying dead on port solars and didn't turn on their suit sensors As an added bonus, they have a health monitoring implant, which'll allow you to check their vitals from their record in the cloning console)! If not, and it says 'Error: Mental interface failure.', then they have left their bodily confines and are one with the spirits. If this happens, just shout at them to get back in their body, click 'Refresh' and try scanning them again. If there's no success, threaten them with gibbing. Still no success? Skip over to Step 7 and don't continue after it, as you have an unresponsive body and it cannot be cloned. If you got 'Error: Unable to locate valid genetic data', you are trying to clone a monkey - start over.
<a name='4'><H4>Step 4: Clone the body/head/brain</H4>
Now that the body has a record, click 'View Records', click the subject's name, and then click 'Clone' to start the cloning process. Congratulations! You're halfway there. Remember not to 'Eject' the cloning pod as this will kill the developing clone and you'll have to start the process again.
<a name='5'><H4>Step 5: Get Mannitol, Mutadone, or a clean SE for the clone</H4>
Cloning is a finicky and unreliable process. Whilst it will most certainly bring someone back from the dead, they can have any number of nasty disabilities given to them during the cloning process! For this reason, you need Mutadone, or a clean, defect-free Structural Enzyme (SE) injection for when they're done. If you're a competent Geneticist, you will already have one ready on your working computer. If, for any reason, you do not, then eject the body from the DNA modifier (NOT THE CLONING POD) and take it next door to the Genetics research room. Put the body in one of those DNA modifiers and then go onto the console. Go into View/Edit/Transfer Buffer, find an open slot and click 'SE' to save it. Then click 'Injector' to get the SEs in syringe form. Put this in your pocket or something for when the body is done. Do note, most Genetic labs have Mannitol and Mutadone pills readily available, provided no-one has stolen them or ate them all. Don't forget most clones will also have severe brain damage as well, to fix this, give them a Mannitol pill or injection.
<a name='6'><H4>Step 6: Put remains in morgue</H4>
Now that the cloning process has been initiated and you hopefully have some Mannitol, Mutadone, and a clean Structural Enzymes, you no longer need the body! Drag it to the morgue and tell the Chef over the radio that they have some fresh meat waiting for them in there, or call the Chaplain so they can prepare an impromptu funeral. To put a body in a morgue bed, simply open the tray, grab the body, put it on the open tray, then close the tray again. Use a pen to label the morgue tray 'CHEF MEAT' or 'CLONED' in order to avoid confusion.
<a name='7'><H4>Step 7: Await cloned body</H4>
Now go back to the lab and wait for your patient to be cloned. This can take atleast three minutes at the least.
<a name='8'><H4>Step 8: Give the clone Mannitol and Mutadone, or a clean SE</H4>
Has your patient been cloned yet? Great! As soon as the clone pops out, administer Mannitol and Mutadone. Then move onto the next step. In the event you have no Mutadone, a clean SE will suffice, but keep in mind this may irradiate the patient, causing more problems!
<a name='9'><H4>Step 9: Give person their clothes back</H4>
Obviously the person will be naked after they have been cloned. Provided you weren't an irresponsible little shit, you should have protected their possessions from thieves and should be able to give them back to the patient. No matter how cruel you are, it's simply against protocol to force your patients to walk outside naked.
<a name='10'><H4>Step 10: Place clone in cryo</H4>
An unfortunate problem with speedcloning technology is that the clone will suffer from severe genetic degradation upon exiting the pod. To rectify this, ensure the nearby cryogenic cells are 1.) at freezing temperatures (normally around 73.15 K), and 2.) filled with cryoxadone, or clonexadone. Once you've assured both conditions are met, place the clone in the cryogenic tube, and turn it on. Remember to set the door to 'Auto' ejection, else the clone will be stuck in cryo until someone releases them. You can also kill two birds with one stone and add Mannitol and Mutadone to the beaker, which'll heal the brain damage, along with removing any genetic defects.
<a name='11'><H4>Step 11: Send person on their way</H4>
Give the patient one last check-over - make sure they don't still have any defects and that they have all their possessions. Ask them how they died, if they know, so that you can report any foul play over the radio. Once you're done, your patient is ready to go back to work! Chances are they do not have Medbay access, so you should let them out of Genetics and the Medbay main entrance.
<p>If you've gotten this far, congratulations! You have mastered the art of cloning. Now, the real problem is how to resurrect yourself after that traitor had his way with you for cloning his target.
</body>
</html>
"}
/obj/item/book/manual/ripley_build_and_repair
name = "APLU \"Ripley\" Construction and Operation Manual"
icon_state ="book"
@@ -276,384 +112,9 @@
</html>
<h2>Operation</h2>
Coming soon...
Please consult the Nanotrasen compendium "Robotics for Dummies".
"}
/obj/item/book/manual/experimentor
name = "Mentoring your Experiments"
icon_state = "rdbook"
author = "Dr. H.P. Kritz"
title = "Mentoring your Experiments"
dat = {"<html>
<head>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {list-style: none; margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
</style>
</head>
<body>
<h1>THE E.X.P.E.R.I-MENTOR</h1>
The Enhanced Xenobiological Period Extraction (and) Restoration Instructor is a machine designed to discover the secrets behind every item in existence.
With advanced technology, it can process 99.95% of items, and discover their uses and secrets.
The E.X.P.E.R.I-MENTOR is a Research apparatus that takes items, and through a process of elimination, it allows you to deduce new technological designs from them.
Due to the volatile nature of the E.X.P.E.R.I-MENTOR, there is a slight chance for malfunction, potentially causing irreparable damage to you or your environment.
However, upgrading the apparatus has proven to decrease the chances of undesirable, potentially life-threatening outcomes.
Please note that the E.X.P.E.R.I-MENTOR uses a state-of-the-art random generator, which has a larger entropy than the observable universe,
therefore it can generate wildly different results each day, therefore it is highly suggested to re-scan objects of interests frequently (e.g. each shift).
<h2>BASIC PROCESS</h2>
The usage of the E.X.P.E.R.I-MENTOR is quite simple:
<ol>
<li>Find an item with a technological background</li>
<li>Insert the item into the E.X.P.E.R.I-MENTOR</li>
<li>Cycle through each processing method of the device.</li>
<li>Stand back, even in case of a successful experiment, as the machine might produce undesired behaviour.</li>
</ol>
<h2>ADVANCED USAGE</h2>
The E.X.P.E.R.I-MENTOR has a variety of uses, beyond menial research work. The different results can be used to combat localised events, or even to get special items.
The E.X.P.E.R.I-MENTOR's OBLITERATE function has the added use of transferring the destroyed item's material into a linked lathe.
The IRRADIATE function can be used to transform items into other items, resulting in potential upgrades (or downgrades).
Users should remember to always wear appropriate protection when using the machine, because malfunction can occur at any moment!
<h1>EVENTS</h1>
<h2>GLOBAL (happens at any time):</h2>
<ol>
<li>DETECTION MALFUNCTION - The machine's onboard sensors have malfunctioned, causing it to redefine the item's experiment type.
Produces the message: The E.X.P.E.R.I-MENTOR's onboard detection system has malfunctioned!</li>
<li>IANIZATION - The machine's onboard corgi-filter has malfunctioned, causing it to produce a corgi from.. somewhere.
Produces the message: The E.X.P.E.R.I-MENTOR melts the banana, ian-izing the air around it!</li>
<li>RUNTIME ERROR - The machine's onboard C4T-P processor has encountered a critical error, causing it to produce a cat from.. somewhere.
Produces the message: The E.X.P.E.R.I-MENTOR encounters a run-time error!</li>
<li>B100DG0D.EXE - The machine has encountered an unknown subroutine, which has been injected into its runtime. It upgrades the held item!
Produces the message: The E.X.P.E.R.I-MENTOR improves the banana, drawing the life essence of those nearby!</li>
<li>POWERSINK - The machine's PSU has tripped the charging mechanism! It consumes massive amounts of power!
Produces the message: The E.X.P.E.R.I-MENTOR begins to smoke and hiss, shaking violently!</li>
</ol>
<h2>FAIL:</h2>
This event is produced when the item mismatches the selected experiment.
Produces a random message similar to: "the Banana rumbles, and shakes, the experiment was a failure!"
<h2>POKE:</h2>
<ol>
<li>WILD ARMS - The machine's gryoscopic processors malfunction, causing it to lash out at nearby people with its arms.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions and destroys the banana, lashing its arms out at nearby people!</li>
<li>MISTYPE - The machine's interface has been garbled, and it switches to OBLITERATE.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions!</li>
<li>THROW - The machine's spatial recognition device has shifted several meters across the room, causing it to try and repostion the item there.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, throwing the banana!</li>
</ol>
<h2>IRRADIATE:</h2>
<ol>
<li>RADIATION LEAK - The machine's shield has failed, resulting in a toxic radiation leak.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, melting the banana and leaking radiation!</li>
<li>RADIATION DUMP - The machine's recycling and containment functions have failed, resulting in a dump of toxic waste around it
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, spewing toxic waste!</li>
<li>MUTATION - The machine's radio-isotope level meter has malfunctioned, causing it over-irradiate the item, making it transform.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, transforming the banana!</li>
</ol>
<h2>GAS:</h2>
<ol>
<li>TOXIN LEAK - The machine's filtering and vent systems have failed, resulting in a cloud of toxic gas being expelled.
Produces the message: The E.X.P.E.R.I-MENTOR destroys the banana, leaking dangerous gas!</li>
<li>GAS LEAK - The machine's vent systems have failed, resulting in a cloud of harmless, but obscuring gas.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, spewing harmless gas!</li>
<li>ELECTROMAGNETIC IONS - The machine's electrolytic scanners have failed, causing a dangerous Electromagnetic reaction.
Produces the message: The E.X.P.E.R.I-MENTOR melts the banana, ionizing the air around it!</li>
</ol>
<h2>HEAT:</h2>
<ol>
<li>TOASTER - The machine's heating coils have come into contact with the machine's gas storage, causing a large, sudden blast of flame.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, melting the banana and releasing a burst of flame!</li>
<li>SAUNA - The machine's vent loop has sprung a leak, resulting in a large amount of superheated air being dumped around it.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, melting the banana and leaking hot air!</li>
<li>EMERGENCY VENT - The machine's temperature gauge has malfunctioned, resulting in it attempting to cool the area around it, but instead, dumping a cloud of steam.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, activating its emergency coolant systems!</li>
</ol>
<h2>COLD:</h2>
<ol>
<li>FREEZER - The machine's cooling loop has sprung a leak, resulting in a cloud of super-cooled liquid being blasted into the air.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, shattering the banana and releasing a dangerous cloud of coolant!</li>
<li>FRIDGE - The machine's cooling loop has been exposed to the outside air, resulting in a large decrease in temperature.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, shattering the banana and leaking cold air!</li>
<li>SNOWSTORM - The machine's cooling loop has come into contact with the heating coils, resulting in a sudden blast of cool air.
Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, releasing a flurry of chilly air as the banana pops out!</li>
</ol>
<h2>OBLITERATE:</h2>
<ol>
<li>IMPLOSION - The machine's pressure leveller has malfunctioned, causing it to pierce the space-time momentarily, making everything in the area fly towards it.
Produces the message: The E.X.P.E.R.I-MENTOR's crusher goes way too many levels too high, crushing right through space-time!</li>
<li>DISTORTION - The machine's pressure leveller has completely disabled, resulting in a momentary space-time distortion, causing everything to fly around.
Produces the message: The E.X.P.E.R.I-MENTOR's crusher goes one level too high, crushing right into space-time!</li>
</ol>
</body>
</html>
"}
/obj/item/book/manual/research_and_development
name = "Research and Development 101"
icon_state = "rdbook"
author = "Dr. L. Ight"
title = "Research and Development 101"
dat = {"<html>
<head>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {list-style: none; margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
</style>
</head>
<body>
<h1>Science For Dummies</h1>
So you want to further SCIENCE? Good man/woman/thing! However, SCIENCE is a complicated process even though it's quite easy. For the most part, it's a three step process:
<ol>
<li> 1) Deconstruct items in the Destructive Analyzer to advance technology or improve the design.</li>
<li> 2) Build unlocked designs in the Protolathe and Circuit Imprinter</li>
<li> 3) Repeat!</li>
</ol>
Those are the basic steps to furthing science. What do you do science with, however? Well, you have four major tools: R&D Console, the Destructive Analyzer, the Protolathe, and the Circuit Imprinter.
<h2>The R&D Console</h2>
The R&D console is the cornerstone of any research lab. It is the central system from which the Destructive Analyzer, Protolathe, and Circuit Imprinter (your R&D systems) are controled. More on those systems in their own sections. On its own, the R&D console acts as a database for all your technological gains and new devices you discover. So long as the R&D console remains intact, you'll retain all that SCIENCE you've discovered. Protect it though, because if it gets damaged, you'll lose your data! In addition to this important purpose, the R&D console has a disk menu that lets you transfer data from the database onto disk or from the disk into the database. It also has a settings menu that lets you re-sync with nearby R&D devices (if they've become disconnected), lock the console from the unworthy, upload the data to all other R&D consoles in the network (all R&D consoles are networked by default), connect/disconnect from the network, and purge all data from the database.
<b>NOTE:</b> The technology list screen, circuit imprinter, and protolathe menus are accessible by non-scientists. This is intended to allow 'public' systems for the plebians to utilize some new devices.
<h2>Destructive Analyzer</h2>
This is the source of all technology. Whenever you put a handheld object in it, it analyzes it and determines what sort of technological advancements you can discover from it. If the technology of the object is equal or higher then your current knowledge, you can destroy the object to further those sciences. Some devices (notably, some devices made from the protolathe and circuit imprinter) aren't 100% reliable when you first discover them. If these devices break down, you can put them into the Destructive Analyzer and improve their reliability rather then futher science. If their reliability is high enough ,it'll also advance their related technologies.
<h2>Circuit Imprinter</h2>
This machine, along with the Protolathe, is used to actually produce new devices. The Circuit Imprinter takes glass and various chemicals (depends on the design) to produce new circuit boards to build new machines or computers. It can even be used to print AI modules.
<h2>Protolathe</h2>
This machine is an advanced form of the Autolathe that produce non-circuit designs. Unlike the Autolathe, it can use processed metal, glass, solid plasma, silver, gold, and diamonds along with a variety of chemicals to produce devices. The downside is that, again, not all devices you make are 100% reliable when you first discover them.
<h1>Reliability and You</h1>
As it has been stated, many devices when they're first discovered do not have a 100% reliablity when you first discover them. Instead, the reliablity of the device is dependent upon a base reliability value, whatever improvements to the design you've discovered through the Destructive Analyzer, and any advancements you've made with the device's source technologies. To be able to improve the reliability of a device, you have to use the device until it breaks beyond repair. Once that happens, you can analyze it in a Destructive Analyzer. Once the device reachs a certain minimum reliability, you'll gain tech advancements from it.
<h1>Building a Better Machine</h1>
Many machines produces from circuit boards and inserted into a machine frame require a variety of parts to construct. These are parts like capacitors, batteries, matter bins, and so forth. As your knowledge of science improves, more advanced versions are unlocked. If you use these parts when constructing something, its attributes may be improved. For example, if you use an advanced matter bin when constructing an autolathe (rather then a regular one), it'll hold more materials. Experiment around with stock parts of various qualities to see how they affect the end results! Be warned, however: Tier 3 and higher stock parts don't have 100% reliability and their low reliability may affect the reliability of the end machine.
</body>
</html>
"}
/obj/item/book/manual/robotics_cyborgs
name = "Cyborgs for Dummies"
icon_state = "borgbook"
author = "XISC"
title = "Cyborgs for Dummies"
dat = {"<html>
<head>
<style>
h1 {font-size: 21px; margin: 15px 0px 5px;}
h2 {font-size: 18px; margin: 15px 0px 5px;}
h3 {font-size: 15px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {list-style: none; margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
</style>
</head>
<body>
<h1>Cyborgs for Dummies</h1>
<h2>Chapters</h2>
<ol>
<li><a href="#Equipment">Cyborg Related Equipment</a></li>
<li><a href="#Modules">Cyborg Modules</a></li>
<li><a href="#Construction">Cyborg Construction</a></li>
<li><a href="#Deconstruction">Cyborg Deconstruction</a></li>
<li><a href="#Maintenance">Cyborg Maintenance</a></li>
<li><a href="#Repairs">Cyborg Repairs</a></li>
<li><a href="#Emergency">In Case of Emergency</a></li>
</ol>
<h2><a name="Equipment">Cyborg Related Equipment</h2>
<h3>Exosuit Fabricator</h3>
The Exosuit Fabricator is the most important piece of equipment related to cyborgs. It allows the construction of the core cyborg parts. Without these machines, cyborgs can not be built. It seems that they may also benefit from advanced research techniques.
<h3>Cyborg Recharging Station</h3>
This useful piece of equipment will suck power out of the power systems to charge a cyborg's power cell back up to full charge.
<h3>Robotics Control Console</h3>
This useful piece of equipment can be used to immobolize or destroy a cyborg. A word of warning: Cyborgs are expensive pieces of equipment, do not destroy them without good reason, or Nanotrasen may see to it that it never happens again.
<h2><a name="Modules">Cyborg Modules</h2>
When a cyborg is created it picks out of an array of modules to designate its purpose. There are 6 different cyborg modules.
<h3>Standard Cyborg</h3>
The standard cyborg module is a multi-purpose cyborg. It is equipped with various modules, allowing it to do basic tasks.<br>
<h3>Engineering Cyborg</h3>
The Engineering cyborg module comes equipped with various engineering-related tools to help with engineering-related tasks.<br>
<h3>Mining Cyborg</h3>
The Mining Cyborg module comes equipped with the latest in mining equipment. They are efficient at mining due to no need for oxygen, but their power cells limit their time in the mines.
<h3>Security Cyborg</h3>
The Security Cyborg module is equipped with effective security measures used to apprehend and arrest criminals without harming them a bit.
<h3>Janitor Cyborg</h3>
The Janitor Cyborg module is equipped with various cleaning-facilitating devices.
<h3>Service Cyborg</h3>
The service cyborg module comes ready to serve your human needs. It includes various entertainment and refreshment devices. Occasionally some service cyborgs may have been referred to as "Bros"
<h2><a name="Construction">Cyborg Construction</h2>
Cyborg construction is a rather easy process, requiring a decent amount of metal and a few other supplies.<br>The required materials to make a cyborg are:
<ul>
<li>Metal</li>
<li>Two Flashes</li>
<li>One Power Cell (Preferrably rated to 15000w)</li>
<li>Some electrical wires</li>
<li>One Human Brain</li>
<li>One Man-Machine Interface</li>
</ul>
Once you have acquired the materials, you can start on construction of your cyborg.<br>To construct a cyborg, follow the steps below:
<ol>
<li>Start the Exosuit Fabricators constructing all of the cyborg parts</li>
<li>While the parts are being constructed, take your human brain, and place it inside the Man-Machine Interface</li>
<li>Once you have a Robot Head, place your two flashes inside the eye sockets</li>
<li>Once you have your Robot Chest, wire the Robot chest, then insert the power cell</li>
<li>Attach all of the Robot parts to the Robot frame</li>
<li>Insert the Man-Machine Interface (With the Brain inside) Into the Robot Body</li>
<li>Congratulations! You have a new cyborg!</li>
</ol>
<h2><a name="Deconstruction">Cyborg Deconstruction</h2>
If you want to deconstruct a cyborg, say to remove its MMI without <a href="#Emergency">blowing the Cyborg to pieces</a>, they come apart very quickly, <b>and</b> very safely, in a few simple steps.
<ul>
<li>Crowbar</li>
<li>Wrench</li>
Optional:
<li>Screwdriver</li>
<li>Wirecutters</li>
</ul>
<ol>
<li>Begin by unlocking the Cyborg's access panel using your ID</li>
<li>Use your crowbar to open the Cyborg's access panel</li>
<li>Using your bare hands, remove the power cell from the Cyborg</li>
<li>Lockdown the Cyborg to disengage safety protocols</li>
<ol>
Option 1: Robotics console
<li>Use the Robotics console in the RD's office</li>
<li>Find the entry for your Cyborg</li>
<li>Press the Lockdown button on the Robotics console</li>
</ol>
<ol>
Option 2: Lockdown wire
<li>Use your screwdriver to expose the Cyborg's wiring</li>
<li>Use your wirecutters to start cutting all of the wires until the lockdown light turns off, cutting all of the wires irregardless of the lockdown light works as well</li>
</ol>
<li>Use your wrench to unfasten the Cyborg's bolts, the Cyborg will then fall apart onto the floor, the MMI will be there as well</li>
</ol>
<h2><a name="Maintenance">Cyborg Maintenance</h2>
Occasionally Cyborgs may require maintenance of a couple types, this could include replacing a power cell with a charged one, or possibly maintaining the cyborg's internal wiring.
<h3>Replacing a Power Cell</h3>
Replacing a Power cell is a common type of maintenance for cyborgs. It usually involves replacing the cell with a fully charged one, or upgrading the cell with a larger capacity cell.<br>The steps to replace a cell are follows:
<ol>
<li>Unlock the Cyborg's Interface by swiping your ID on it</li>
<li>Open the Cyborg's outer panel using a crowbar</li>
<li>Remove the old power cell</li>
<li>Insert the new power cell</li>
<li>Close the Cyborg's outer panel using a crowbar</li>
<li>Lock the Cyborg's Interface by swiping your ID on it, this will prevent non-qualified personnel from attempting to remove the power cell</li>
</ol>
<h3>Exposing the Internal Wiring</h3>
Exposing the internal wiring of a cyborg is fairly easy to do, and is mainly used for cyborg repairs.<br>You can easily expose the internal wiring by following the steps below:
<ol>
<li>Follow Steps 1 - 3 of "Replacing a Cyborg's Power Cell"</li>
<li>Open the cyborg's internal wiring panel by using a screwdriver to unsecure the panel</li>
</ol>
To re-seal the cyborg's internal wiring:
<ol>
<li>Use a screwdriver to secure the cyborg's internal panel</li>
<li>Follow steps 4 - 6 of "Replacing a Cyborg's Power Cell" to close up the cyborg</li>
</ol>
<h2><a name="Repairs">Cyborg Repairs</h2>
Occasionally a Cyborg may become damaged. This could be in the form of impact damage from a heavy or fast-travelling object, or it could be heat damage from high temperatures, or even lasers or Electromagnetic Pulses (EMPs).
<h3>Dents</h3>
If a cyborg becomes damaged due to impact from heavy or fast-moving objects, it will become dented. Sure, a dent may not seem like much, but it can compromise the structural integrity of the cyborg, possibly causing a critical failure.
Dents in a cyborg's frame are rather easy to repair, all you need is to apply a welding tool to the dented area, and the high-tech cyborg frame will repair the dent under the heat of the welder.
<h3>Excessive Heat Damage</h3>
If a cyborg becomes damaged due to excessive heat, it is likely that the internal wires will have been damaged. You must replace those wires to ensure that the cyborg remains functioning properly.<br>To replace the internal wiring follow the steps below:
<ol>
<li>Unlock the Cyborg's Interface by swiping your ID</li>
<li>Open the Cyborg's External Panel using a crowbar</li>
<li>Remove the Cyborg's Power Cell</li>
<li>Using a screwdriver, expose the internal wiring or the Cyborg</li>
<li>Replace the damaged wires inside the cyborg</li>
<li>Secure the internal wiring cover using a screwdriver</li>
<li>Insert the Cyborg's Power Cell</li>
<li>Close the Cyborg's External Panel using a crowbar</li>
<li>Lock the Cyborg's Interface by swiping your ID</li>
</ol>
These repair tasks may seem difficult, but are essential to keep your cyborgs running at peak efficiency.
<h2><a name="Emergency">In Case of Emergency</h2>
In case of emergency, there are a few steps you can take.
<h3>"Rogue" Cyborgs</h3>
If the cyborgs seem to become "rogue", they may have non-standard laws. In this case, use extreme caution.
To repair the situation, follow these steps:
<ol>
<li>Locate the nearest robotics console</li>
<li>Determine which cyborgs are "Rogue"</li>
<li>Press the lockdown button to immobolize the cyborg</li>
<li>Locate the cyborg</li>
<li>Expose the cyborg's internal wiring</li>
<li>Check to make sure the LawSync and AI Sync lights are lit</li>
<li>If they are not lit, pulse the LawSync wire using a multitool to enable the cyborg's Law Sync</li>
<li>Proceed to a cyborg upload console. Nanotrasen usually places these in the same location as AI uplaod consoles.</li>
<li>Use a "Reset" upload moduleto reset the cyborg's laws</li>
<li>Proceed to a Robotics Control console</li>
<li>Remove the lockdown on the cyborg</li>
</ol>
<h3>As a last resort</h3>
If all else fails in a case of cyborg-related emergency. There may be only one option. Using a Robotics Control console, you may have to remotely detonate the cyborg.
<h3>WARNING:</h3> Do not detonate a borg without an explicit reason for doing so. Cyborgs are expensive pieces of Nanotrasen equipment, and you may be punished for detonating them without reason.
</body>
</html>
"}
/obj/item/book/manual/chef_recipes
name = "Chef Recipes"
icon_state = "cooked_book"
@@ -735,101 +196,6 @@
</html>
"}
/obj/item/book/manual/barman_recipes
name = "Barman Recipes"
icon_state = "barbook"
author = "Sir John Rose"
title = "Barman Recipes"
dat = {"<html>
<head>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {list-style: none; margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
</style>
</head>
<body>
<h1>Drinks for dummies</h1>
Heres a guide for some basic drinks.
<h2>Manly Dorf:</h2>
Mix ale and beer into a glass.
<h2>Grog:</h2>
Mix rum and water into a glass.
<h2>Black Russian:</h2>
Mix vodka and kahlua into a glass.
<h2>Irish Cream:</h2>
Mix cream and whiskey into a glass.
<h2>Screwdriver:</h2>
Mix vodka and orange juice into a glass.
<h2>Cafe Latte:</h2>
Mix milk and coffee into a glass.
<h2>Mead:</h2>
Mix Enzyme, water and sugar into a glass.
<h2>Gin Tonic:</h2>
Mix gin and tonic into a glass.
<h2>Classic Martini:</h2>
Mix vermouth and gin into a glass.
</body>
</html>
"}
/obj/item/book/manual/detective
name = "The Film Noir: Proper Procedures for Investigations"
icon_state ="bookDetective"
author = "Nanotrasen"
title = "The Film Noir: Proper Procedures for Investigations"
dat = {"<html>
<head>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {list-style: none; margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
</style>
</head>
<body>
<h3>Detective Work</h3>
Between your bouts of self-narration, and drinking whiskey on the rocks, you might get a case or two to solve.<br>
To have the best chance to solve your case, follow these directions:
<p>
<ol>
<li>Go to the crime scene. </li>
<li>Take your scanner and scan EVERYTHING (Yes, the doors, the tables, even the dog.) </li>
<li>Once you are reasonably certain you have every scrap of evidence you can use, find all possible entry points and scan them, too. </li>
<li>Return to your office. </li>
<li>Using your forensic scanning computer, scan your Scanner to upload all of your evidence into the database.</li>
<li>Browse through the resulting dossiers, looking for the one that either has the most complete set of prints, or the most suspicious items handled. </li>
<li>If you have 80% or more of the print (The print is displayed) go to step 10, otherwise continue to step 8.</li>
<li>Look for clues from the suit fibres you found on your perp, and go about looking for more evidence with this new information, scanning as you go. </li>
<li>Try to get a fingerprint card of your perp, as if used in the computer, the prints will be completed on their dossier.</li>
<li>Assuming you have enough of a print to see it, grab the biggest complete piece of the print and search the security records for it. </li>
<li>Since you now have both your dossier and the name of the person, print both out as evidence, and get security to nab your baddie.</li>
<li>Give yourself a pat on the back and a bottle of the ships finest vodka, you did it!</li>
</ol>
<p>
It really is that easy! Good luck!
</body>
</html>"}
/obj/item/book/manual/nuclear
name = "Fission Mailed: Nuclear Sabotage 101"
icon_state ="bookNuclear"
@@ -925,6 +291,13 @@
title = "Engineering Textbook"
page_link = "Guide_to_engineering"
/obj/item/book/manual/wiki/engineering_singulo_tesla
name = "Singularity and Tesla for Dummies"
icon_state ="bookEngineeringSingularitySafety"
author = "Engineering Encyclopedia"
title = "Singularity and Tesla for Dummies"
page_link = "Singularity_and_Tesla_engines"
/obj/item/book/manual/wiki/security_space_law
name = "Space Law"
desc = "A set of Nanotrasen guidelines for keeping law and order on their space stations."
@@ -957,3 +330,123 @@
author = "Engineering Encyclopedia"
title = "Hacking"
page_link = "Hacking"
/obj/item/book/manual/wiki/detective
name = "The Film Noir: Proper Procedures for Investigations"
icon_state ="bookDetective"
author = "Nanotrasen"
title = "The Film Noir: Proper Procedures for Investigations"
page_link = "Detective"
/obj/item/book/manual/wiki/barman_recipes
name = "Barman Recipes: Mixing Drinks and Changing Lives"
icon_state = "barbook"
author = "Sir John Rose"
title = "Barman Recipes: Mixing Drinks and Changing Lives"
page_link = "Guide_to_food_and_drinks"
/obj/item/book/manual/wiki/robotics_cyborgs
name = "Robotics for Dummies"
icon_state = "borgbook"
author = "XISC"
title = "Robotics for Dummies"
page_link = "Guide_to_robotics"
/obj/item/book/manual/wiki/research_and_development
name = "Research and Development 101"
icon_state = "rdbook"
author = "Dr. L. Ight"
title = "Research and Development 101"
page_link = "Guide_to_Research_and_Development"
/obj/item/book/manual/wiki/experimentor
name = "Mentoring your Experiments"
icon_state = "rdbook"
author = "Dr. H.P. Kritz"
title = "Mentoring your Experiments"
page_link = "Experimentor"
/obj/item/book/manual/wiki/medical_cloning
name = "Cloning techniques of the 26th century"
icon_state ="bookCloning"
author = "Medical Journal, volume 3"
title = "Cloning techniques of the 26th century"
page_link = "Guide_to_genetics#Cloning"
/obj/item/book/manual/wiki/cooking_to_serve_man
name = "To Serve Man"
desc = "It's a cookbook!"
icon_state ="cooked_book"
author = "the Kanamitan Empire"
title = "To Serve Man"
page_link = "Guide_to_food_and_drinks"
/obj/item/book/manual/wiki/circuitry
name = "Circuitry for Dummies"
icon_state = "book1"
author = "Dr. Hans Asperger"
title = "Circuitry for Dummies"
page_link = "Guide_to_circuits"
/obj/item/book/manual/wiki/tcomms
name = "Subspace Telecommunications And You"
icon_state = "book3"
author = "Engineering Encyclopedia"
title = "Subspace Telecommunications And You"
page_link = "Guide_to_Telecommunications"
/obj/item/book/manual/wiki/atmospherics
name = "Lexica Atmosia"
icon_state = "book5"
author = "the City-state of Atmosia"
title = "Lexica Atmosia"
page_link = "Guide_to_Atmospherics"
/obj/item/book/manual/wiki/medicine
name = "Medical Space Compendium, Volume 638"
icon_state = "book8"
author = "Medical Journal"
title = "Medical Space Compendium, Volume 638"
page_link = "Guide_to_medicine"
/obj/item/book/manual/wiki/surgery
name = "Brain Surgery for Dummies"
icon_state = "book4"
author = "Dr. F. Fran"
title = "Brain Surgery for Dummies"
page_link = "Surgery"
/obj/item/book/manual/wiki/grenades
name = "DIY Chemical Grenades"
icon_state = "book2"
author = "W. Powell"
title = "DIY Chemical Grenades"
page_link = "Grenade"
/obj/item/book/manual/wiki/toxins
name = "Toxins or: How I Learned to Stop Worrying and Love the Maxcap"
icon_state = "book6"
author = "Cuban Pete"
title = "Toxins or: How I Learned to Stop Worrying and Love the Maxcap"
page_link = "Guide_to_toxins"
/obj/item/book/manual/wiki/toxins/suicide_act(mob/user)
var/mob/living/carbon/human/H = user
user.visible_message("<span class='suicide'>[user] starts dancing to the Rhumba Beat! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(loc, 'sound/effects/spray.ogg', 10, 1, -3)
if (!QDELETED(H))
H.emote("spin")
sleep(20)
for(var/obj/item/W in H)
H.dropItemToGround(W)
if(prob(50))
step(W, pick(GLOB.alldirs))
H.add_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
H.bleed_rate = 5
H.gib_animation()
sleep(3)
H.adjustBruteLoss(1000) //to make the body super-bloody
H.spawn_gibs()
H.spill_organs()
H.spread_bodyparts()
return (BRUTELOSS)
+8 -7
View File
@@ -112,7 +112,7 @@
limbs_to_dismember = arms + legs
if(holding_bodypart)
limbs_to_dismember += holding_bodypart
var/speedbase = abs((4 SECONDS) / limbs_to_dismember.len)
for(bodypart in limbs_to_dismember)
i++
@@ -185,7 +185,7 @@
return
playsound(get_turf(src), 'sound/effects/woodhit.ogg', 75, 1, -1)
target.Knockdown(60)
add_logs(user, target, "stunned", src)
log_combat(user, target, "stunned", src)
src.add_fingerprint(user)
target.visible_message("<span class ='danger'>[user] has knocked down [target] with [src]!</span>", \
"<span class ='userdanger'>[user] has knocked down [target] with [src]!</span>")
@@ -286,11 +286,11 @@
consume_turf(T)
/obj/item/melee/supermatter_sword/afterattack(target, mob/user, proximity_flag)
. = ..()
if(user && target == user)
user.dropItemToGround(src)
if(proximity_flag)
consume_everything(target)
..()
/obj/item/melee/supermatter_sword/throw_impact(target)
..()
@@ -322,13 +322,13 @@
/obj/item/melee/supermatter_sword/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] touches [src]'s blade. It looks like [user.p_theyre()] tired of waiting for the radiation to kill [user.p_them()]!</span>")
user.dropItemToGround(src, TRUE)
shard.CollidedWith(user)
shard.Bumped(user)
/obj/item/melee/supermatter_sword/proc/consume_everything(target)
if(isnull(target))
shard.Consume()
else if(!isturf(target))
shard.CollidedWith(target)
shard.Bumped(target)
else
consume_turf(target)
@@ -357,14 +357,14 @@
force = 15
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("flogged", "whipped", "lashed", "disciplined")
hitsound = 'sound/weapons/chainhit.ogg'
hitsound = 'sound/weapons/whip.ogg'
/obj/item/melee/curator_whip/afterattack(target, mob/user, proximity_flag)
. = ..()
if(ishuman(target) && proximity_flag)
var/mob/living/carbon/human/H = target
H.drop_all_held_items()
H.visible_message("<span class='danger'>[user] disarms [H]!</span>", "<span class='userdanger'>[user] disarmed you!</span>")
..()
/obj/item/melee/roastingstick
name = "advanced roasting stick"
@@ -446,6 +446,7 @@
update_icon()
/obj/item/melee/roastingstick/afterattack(atom/target, mob/user, proximity)
. = ..()
if (!on)
return
if (is_type_in_typecache(target, ovens))
+1
View File
@@ -35,6 +35,7 @@
/obj/item/mop/afterattack(atom/A, mob/user, proximity)
. = ..()
if(!proximity)
return
+2
View File
@@ -79,6 +79,7 @@
/obj/item/paint/afterattack(turf/target, mob/user, proximity)
. = ..()
if(!proximity)
return
if(paintleft <= 0)
@@ -96,6 +97,7 @@
icon_state = "paint_neutral"
/obj/item/paint/paint_remover/afterattack(turf/target, mob/user, proximity)
. = ..()
if(!proximity)
return
if(istype(target) && target.color != initial(target.color))
-6
View File
@@ -143,9 +143,3 @@
target = null
if(!target) //target can be set to null from above code, or elsewhere
active = FALSE
/obj/item/pinpointer/process()
if(!active)
return PROCESS_KILL
scan_for_target()
update_icon()
+3 -3
View File
@@ -461,8 +461,8 @@
P.clashing = FALSE
/obj/item/toy/plush/narplush
name = "nar'sie plushie"
desc = "A small stuffed doll of the elder god Nar'Sie. Who thought this was a good children's toy?"
name = "\improper Nar'Sie plushie"
desc = "A small stuffed doll of the elder goddess Nar'Sie. Who thought this was a good children's toy?"
icon_state = "narplush"
var/clashing
var/is_invoker = TRUE
@@ -475,7 +475,7 @@
P.clash_of_the_plushies(src)
/obj/item/toy/plush/narplush/hugbox
desc = "A small stuffed doll of the elder god Nar'Sie. Who thought this was a good children's toy? <b>It looks sad.</b>"
desc = "A small stuffed doll of the elder goddess Nar'Sie. Who thought this was a good children's toy? <b>It looks sad.</b>"
is_invoker = FALSE
/obj/item/toy/plush/lizardplushie
+15 -11
View File
@@ -34,6 +34,7 @@
var/selfcharge = FALSE
trigger_guard = TRIGGER_GUARD_NORMAL
/obj/item/pneumatic_cannon/Initialize()
. = ..()
if(selfcharge)
@@ -97,6 +98,8 @@
load_item(IW, user)
/obj/item/pneumatic_cannon/proc/can_load_item(obj/item/I, mob/user)
if(!istype(I)) //Players can't load non items, this allows for admin varedit inserts.
return TRUE
if(allowed_typecache && !is_type_in_typecache(I, allowed_typecache))
if(user)
to_chat(user, "<span class='warning'>[I] won't fit into [src]!</span>")
@@ -125,6 +128,7 @@
return TRUE
/obj/item/pneumatic_cannon/afterattack(atom/target, mob/living/user, flag, params)
. = ..()
if(flag && user.a_intent == INTENT_HARM) //melee attack
return
if(!istype(user))
@@ -159,9 +163,9 @@
if(!discharge)
user.visible_message("<span class='danger'>[user] fires \the [src]!</span>", \
"<span class='danger'>You fire \the [src]!</span>")
add_logs(user, target, "fired at", src)
log_combat(user, target, "fired at", src)
var/turf/T = get_target(target, get_turf(src))
playsound(src.loc, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
fire_items(T, user)
if(pressureSetting >= 3 && iscarbon(user))
var/mob/living/carbon/C = user
@@ -223,31 +227,31 @@
/obj/item/pneumatic_cannon/proc/updateTank(obj/item/tank/internals/thetank, removing = 0, mob/living/carbon/human/user)
if(removing)
if(!src.tank)
if(!tank)
return
to_chat(user, "<span class='notice'>You detach \the [thetank] from \the [src].</span>")
src.tank.forceMove(user.drop_location())
tank.forceMove(user.drop_location())
user.put_in_hands(tank)
src.tank = null
tank = null
if(!removing)
if(src.tank)
if(tank)
to_chat(user, "<span class='warning'>\The [src] already has a tank.</span>")
return
if(!user.transferItemToLoc(thetank, src))
return
to_chat(user, "<span class='notice'>You hook \the [thetank] up to \the [src].</span>")
src.tank = thetank
src.update_icons()
tank = thetank
update_icons()
/obj/item/pneumatic_cannon/proc/update_icons()
src.cut_overlays()
cut_overlays()
if(!tank)
return
add_overlay(tank.icon_state)
src.update_icon()
update_icon()
/obj/item/pneumatic_cannon/proc/fill_with_type(type, amount)
if(!ispath(type, /obj/item))
if(!ispath(type, /obj) && !ispath(type, /mob))
return FALSE
var/loaded = 0
for(var/i in 1 to amount)
+1 -1
View File
@@ -89,7 +89,7 @@
target.throw_at(throw_target, 5 * fisto_setting, 0.2)
add_logs(user, target, "power fisted", src)
log_combat(user, target, "power fisted", src)
user.changeNext_move(CLICK_CD_MELEE * click_delay)
+2 -1
View File
@@ -30,7 +30,7 @@
"<span class='notice'>You raise [src] skywards, inspiring your allies!</span>")
playsound(src, "rustle", 100, FALSE)
if(warcry)
user.say("[warcry]")
user.say("[warcry]", forced="banner")
var/old_transform = user.transform
user.transform *= 1.2
animate(user, transform = old_transform, time = 10)
@@ -288,6 +288,7 @@
/obj/item/godstaff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(staffcooldown + staffwait > world.time)
return
user.visible_message("[user] chants deeply and waves [user.p_their()] staff!")
@@ -10,6 +10,7 @@
/obj/item/malf_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user)
. = ..()
if(!istype(AI))
return
if(AI.malf_picker)
@@ -30,6 +31,7 @@
icon_state = "datadisk3"
/obj/item/surveillance_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user)
. = ..()
if(!istype(AI))
return
if(AI.eyeobj)
+3 -1
View File
@@ -30,7 +30,7 @@
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
add_logs(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])")
log_combat(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])")
/obj/item/borg/cyborghug
name = "hugging module"
@@ -172,6 +172,7 @@
update_icon()
/obj/item/borg/charger/afterattack(obj/item/target, mob/living/silicon/robot/user, proximity_flag)
. = ..()
if(!proximity_flag || !iscyborg(user))
return
if(mode == "draw")
@@ -448,6 +449,7 @@
check_amount()
/obj/item/borg/lollipop/afterattack(atom/target, mob/living/user, proximity, click_params)
. = ..()
check_amount()
if(iscyborg(user))
var/mob/living/silicon/robot/R = user
@@ -105,6 +105,10 @@
return TRUE
/obj/item/robot_suit/screwdriver_act(mob/living/user, obj/item/I) //Swaps the power cell if you're holding a new one in your other hand.
. = ..()
if(.)
return TRUE
if(!chest) //can't remove a cell if there's no chest to remove it from.
to_chat(user, "<span class='notice'>[src] has no attached torso.</span>")
return
+26 -37
View File
@@ -79,40 +79,7 @@
to_chat(user, "<span class='notice'>There's no room for another VTEC unit!</span>")
return FALSE
//Citadel change - makes vtecs give an ability rather than reducing the borg's speed instantly
R.AddAbility(new/obj/effect/proc_holder/silicon/cyborg/vtecControl)
/obj/effect/proc_holder/silicon/cyborg/vtecControl
name = "vTec Control"
desc = "Allows finer-grained control of the vTec speed boost."
action_icon = 'icons/mob/actions.dmi'
action_icon_state = "Chevron_State_0"
var/currentState = 0
var/maxReduction = 2
/obj/effect/proc_holder/silicon/cyborg/vtecControl/Click(mob/living/silicon/robot/user)
var/mob/living/silicon/robot/self = usr
currentState = (currentState + 1) % 3
if(usr)
switch(currentState)
if (0)
self.speed += maxReduction
if (1)
self.speed -= maxReduction*0.5
if (2)
self.speed -= maxReduction*0.5
action.button_icon_state = "Chevron_State_[currentState]"
action.UpdateButtonIcon()
return
R.speed = -2 // Gotta go fast.
/obj/item/borg/upgrade/vtec/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..()
@@ -228,7 +195,7 @@
/obj/item/borg/upgrade/tboh
name = "janitor cyborg trash bag of holding"
desc = "A trash bag of holding replace for the janiborgs standard trash bag."
desc = "A trash bag of holding replacement for the janiborg's standard trash bag."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/robot_module/janitor
@@ -255,7 +222,7 @@
/obj/item/borg/upgrade/amop
name = "janitor cyborg advanced mop"
desc = "An advanced mop replacement from the janiborgs standard mop."
desc = "An advanced mop replacement for the janiborg's standard mop."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/robot_module/janitor
@@ -493,7 +460,7 @@
/obj/item/borg/upgrade/defib
name = "medical cyborg defibrillator"
desc = "An upgrade to the Medical module, installing a builtin \
desc = "An upgrade to the Medical module, installing a built-in \
defibrillator, for on the scene revival."
icon_state = "cyborg_upgrade3"
require_module = 1
@@ -512,6 +479,28 @@
var/obj/item/twohanded/shockpaddles/cyborg/S = locate() in R.module
R.module.remove_module(S, TRUE)
/obj/item/borg/upgrade/processor
name = "medical cyborg surgical processor"
desc = "An upgrade to the Medical module, installing a processor \
capable of scanning surgery disks and carrying \
out procedures"
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/robot_module/medical
/obj/item/borg/upgrade/processor/action(mob/living/silicon/robot/R, user = usr)
. = ..()
if(.)
var/obj/item/surgical_processor/SP = new(R.module)
R.module.basic_modules += SP
R.module.add_module(SP, FALSE, TRUE)
/obj/item/borg/upgrade/processor/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..()
if (.)
var/obj/item/surgical_processor/SP = locate() in R.module
R.module.remove_module(SP, TRUE)
/obj/item/borg/upgrade/ai
name = "B.O.R.I.S. module"
desc = "Bluespace Optimized Remote Intelligence Synchronization. An uplink device which takes the place of an MMI in cyborg endoskeletons, creating a robotic shell controlled by an AI."
@@ -57,6 +57,7 @@
return
/obj/item/twohanded/singularityhammer/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
. = ..()
if(!proximity)
return
if(wielded)
@@ -268,6 +268,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
pixel_y = rand(-5, 5)
/obj/item/shard/afterattack(atom/A as mob|obj, mob/user, proximity)
. = ..()
if(!proximity || !(src in user))
return
if(isturf(A))
@@ -32,13 +32,22 @@ GLOBAL_LIST_INIT(human_recipes, list( \
icon_state = "sheet-corgi"
item_state = "sheet-corgi"
GLOBAL_LIST_INIT(gondola_recipes, list ( \
new/datum/stack_recipe("gondola mask", /obj/item/clothing/mask/gondola, 1), \
new/datum/stack_recipe("gondola suit", /obj/item/clothing/under/gondola, 2), \
))
/obj/item/stack/sheet/animalhide/gondola
name = "gondola hide"
desc = "The extremely valuable by-product of gondola hunting."
desc = "The extremely valuable product of gondola hunting."
singular_name = "gondola hide piece"
icon_state = "sheet-gondola"
item_state = "sheet-gondola"
/obj/item/stack/sheet/animalhide/gondola/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.gondola_recipes
return ..()
GLOBAL_LIST_INIT(corgi_recipes, list ( \
new/datum/stack_recipe("corgi costume", /obj/item/clothing/suit/hooded/ian_costume, 3), \
@@ -46,6 +46,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
throw_range = 5
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
sheettype = "sandstone"
merge_type = /obj/item/stack/sheet/mineral/sandstone
/obj/item/stack/sheet/mineral/sandstone/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.sandstone_recipes
@@ -64,6 +65,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
singular_name = "sandbag"
layer = LOW_ITEM_LAYER
novariants = TRUE
merge_type = /obj/item/stack/sheet/mineral/sandbags
GLOBAL_LIST_INIT(sandbag_recipes, list ( \
new/datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = 1, on_floor = 1), \
@@ -105,6 +107,7 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
novariants = TRUE
grind_results = list("carbon" = 20)
point_value = 25
merge_type = /obj/item/stack/sheet/mineral/diamond
GLOBAL_LIST_INIT(diamond_recipes, list ( \
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
@@ -131,6 +134,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
novariants = TRUE
grind_results = list("uranium" = 20)
point_value = 20
merge_type = /obj/item/stack/sheet/mineral/uranium
GLOBAL_LIST_INIT(uranium_recipes, list ( \
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
@@ -157,6 +161,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT)
grind_results = list("plasma" = 20)
point_value = 20
merge_type = /obj/item/stack/sheet/mineral/plasma
/obj/item/stack/sheet/mineral/plasma/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins licking \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -197,6 +202,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT)
grind_results = list("gold" = 20)
point_value = 20
merge_type = /obj/item/stack/sheet/mineral/gold
GLOBAL_LIST_INIT(gold_recipes, list ( \
new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \
@@ -225,6 +231,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT)
grind_results = list("silver" = 20)
point_value = 20
merge_type = /obj/item/stack/sheet/mineral/silver
GLOBAL_LIST_INIT(silver_recipes, list ( \
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
@@ -253,6 +260,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
novariants = TRUE
grind_results = list("banana" = 20)
point_value = 50
merge_type = /obj/item/stack/sheet/mineral/bananium
GLOBAL_LIST_INIT(bananium_recipes, list ( \
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
@@ -279,6 +287,7 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
sheettype = "titanium"
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT)
point_value = 20
merge_type = /obj/item/stack/sheet/mineral/titanium
GLOBAL_LIST_INIT(titanium_recipes, list ( \
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20), \
@@ -308,6 +317,7 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \
sheettype = "plastitanium"
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT, MAT_PLASMA=MINERAL_MATERIAL_AMOUNT)
point_value = 45
merge_type = /obj/item/stack/sheet/mineral/plastitanium
GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
new/datum/stack_recipe("plastitanium tile", /obj/item/stack/tile/mineral/plastitanium, 1, 4, 20), \
@@ -329,6 +339,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
force = 1
throwforce = 2
grind_results = list("ice" = 20)
merge_type = /obj/item/stack/sheet/mineral/snow
GLOBAL_LIST_INIT(snow_recipes, list ( \
new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \
@@ -354,6 +365,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
icon_state = "sheet-adamantine"
item_state = "sheet-adamantine"
singular_name = "adamantine sheet"
merge_type = /obj/item/stack/sheet/mineral/adamantine
/obj/item/stack/sheet/mineral/adamantine/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.adamantine_recipes
@@ -368,6 +380,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
item_state = "sheet-mythril"
singular_name = "mythril sheet"
novariants = TRUE
merge_type = /obj/item/stack/sheet/mineral/mythril
/*
* Alien Alloy
@@ -379,6 +392,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
item_state = "sheet-abductor"
singular_name = "alien alloy sheet"
sheettype = "abductor"
merge_type = /obj/item/stack/sheet/mineral/abductor
GLOBAL_LIST_INIT(abductor_recipes, list ( \
new/datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \
@@ -20,7 +20,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
new/datum/stack_recipe("bar stool", /obj/structure/chair/stool/bar, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("chair", /obj/structure/chair, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \
//CIT CHANGE - adds sofas to metal recipe list
//CIT CHANGE - adds sofas to metal recipe list
new/datum/stack_recipe_list("sofas", list( \
new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, one_per_turf = TRUE, on_floor = TRUE), \
new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/left, one_per_turf = TRUE, on_floor = TRUE), \
@@ -412,6 +412,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
turf_type = /turf/open/floor/clockwork
novariants = FALSE
grind_results = list("iron" = 5, "teslium" = 15)
merge_type = /obj/item/stack/tile/brass
/obj/item/stack/tile/brass/narsie_act()
new /obj/item/stack/sheet/runed_metal(loc, amount)
@@ -461,6 +462,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
turf_type = /turf/open/floor/bronze
novariants = FALSE
grind_results = list("iron" = 5, "copper" = 3) //we have no "tin" reagent so this is the closest thing
merge_type = /obj/item/stack/tile/bronze
/obj/item/stack/tile/bronze/attack_self(mob/living/user)
if(is_servant_of_ratvar(user)) //still lets them build with it, just gives a message
@@ -513,6 +515,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
throw_speed = 1
throw_range = 3
grind_results = list("carbon" = 10)
merge_type = /obj/item/stack/sheet/bone
GLOBAL_LIST_INIT(plastic_recipes, list(
new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \
@@ -552,6 +555,7 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
item_state = "sheet-paper"
merge_type = /obj/item/stack/sheet/paperframes
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/sheet/paperframes
/obj/item/stack/sheet/paperframes/Initialize()
recipes = GLOB.paperframe_recipes
+7 -1
View File
@@ -231,7 +231,9 @@
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [R.title]!</span>")
return FALSE
var/turf/T = get_turf(usr)
if(R.window_checks && !valid_window_location(T, usr.dir))
var/obj/D = R.result_type
if(R.window_checks && !valid_window_location(T, initial(D.dir) == FULLTILE_WINDOW_DIR ? FULLTILE_WINDOW_DIR : usr.dir))
to_chat(usr, "<span class='warning'>The [R.title] won't fit here!</span>")
return FALSE
if(R.one_per_turf && (locate(R.result_type) in T))
@@ -246,6 +248,10 @@
continue
if(istype(AM,/obj/structure/table))
continue
if(istype(AM,/obj/structure/window))
var/obj/structure/window/W = AM
if(!W.fulltile)
continue
if(AM.density)
to_chat(usr, "<span class='warning'>Theres a [AM.name] here. You cant make a [R.title] here!</span>")
return FALSE
@@ -21,6 +21,7 @@
return ..()
/obj/item/stack/telecrystal/afterattack(obj/item/I, mob/user, proximity)
. = ..()
if(istype(I, /obj/item/cartridge/virus/frame))
var/obj/item/cartridge/virus/frame/cart = I
if(!cart.charges)
@@ -29,8 +30,6 @@
cart.telecrystals += amount
use(amount)
to_chat(user, "<span class='notice'>You slot [src] into [cart]. The next time it's used, it will also give telecrystals.</span>")
else
return ..()
/obj/item/stack/telecrystal/five
amount = 5
@@ -100,6 +100,9 @@
turf_type = /turf/open/floor/carpet
resistance_flags = FLAMMABLE
/obj/item/stack/tile/carpet/fifty
amount = 50
/obj/item/stack/tile/carpet/black
name = "black carpet"
icon_state = "tile-carpet-black"
+2 -1
View File
@@ -61,6 +61,7 @@
return 0
/obj/item/stack/packageWrap/afterattack(obj/target, mob/user, proximity)
. = ..()
if(!proximity)
return
if(!istype(target))
@@ -111,7 +112,7 @@
return
user.visible_message("<span class='notice'>[user] wraps [target].</span>")
user.log_message("<font color='blue'>Has used [name] on [target]</font>", INDIVIDUAL_ATTACK_LOG)
user.log_message("has used [name] on [key_name(target)]", LOG_ATTACK, color="blue")
/obj/item/stack/packageWrap/use(used, transfer = FALSE)
var/turf/T = get_turf(src)
+1 -1
View File
@@ -119,7 +119,7 @@
if (mobhook && mobhook.parent != user)
QDEL_NULL(mobhook)
if (!mobhook)
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED), CALLBACK(src, .proc/Pickup_ores, user))
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/Pickup_ores)))
/obj/item/storage/bag/ore/dropped()
. = ..()
+17 -2
View File
@@ -146,13 +146,14 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
M.visible_message("<span class='danger'>[user] beats [M] over the head with [src]!</span>", \
"<span class='userdanger'>[user] beats [M] over the head with [src]!</span>")
playsound(src.loc, "punch", 25, 1, -1)
add_logs(user, M, "attacked", src)
log_combat(user, M, "attacked", src)
else
M.visible_message("<span class='danger'>[user] smacks [M]'s lifeless corpse with [src].</span>")
playsound(src.loc, "punch", 25, 1, -1)
/obj/item/storage/book/bible/afterattack(atom/A, mob/user, proximity)
. = ..()
if(!proximity)
return
if(isfloorturf(A))
@@ -186,9 +187,23 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
SS.release_shades(user)
qdel(SS)
new /obj/item/nullrod/claymore(get_turf(sword))
user.visible_message("<span class='notice'>[user] has purified the [sword]!!</span>")
user.visible_message("<span class='notice'>[user] has purified the [sword]!</span>")
qdel(sword)
else if(istype(A, /obj/item/soulstone) && !iscultist(user))
var/obj/item/soulstone/SS = A
to_chat(user, "<span class='notice'>You begin to exorcise [SS].</span>")
playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1)
if(do_after(user, 40, target = SS))
playsound(src,'sound/effects/pray_chaplain.ogg',60,1)
SS.usability = TRUE
for(var/mob/living/simple_animal/shade/EX in SS)
SSticker.mode.remove_cultist(EX.mind, 1, 0)
EX.icon_state = "ghost1"
EX.name = "Purified [EX.name]"
SS.release_shades(user)
user.visible_message("<span class='notice'>[user] has purified the [SS]!</span>")
qdel(SS)
/obj/item/storage/book/bible/booze
desc = "To be applied to the head repeatedly."
+17 -8
View File
@@ -93,6 +93,14 @@
for(var/i in 1 to 7)
new /obj/item/disk/plantgene(src)
/obj/item/storage/box/disks_nanite
name = "nanite program disks box"
illustration = "disk_kit"
/obj/item/storage/box/disks_nanite/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/disk/nanite_program(src)
// Ordinary survival box
/obj/item/storage/box/survival/PopulateContents()
new /obj/item/clothing/mask/breath(src)
@@ -189,6 +197,14 @@
for(var/i in 1 to 7)
new /obj/item/reagent_containers/glass/beaker( src )
/obj/item/storage/box/beakers/bluespace
name = "box of bluespace beakers"
illustration = "beaker"
/obj/item/storage/box/beakers/bluespace/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/glass/beaker/bluespace(src)
/obj/item/storage/box/medsprays
name = "box of medical sprayers"
desc = "A box full of medical sprayers, with unscrewable caps and precision spray heads."
@@ -991,6 +1007,7 @@
/obj/item/storage/box/stockparts/deluxe
name = "box of deluxe stock parts"
desc = "Contains a variety of deluxe stock parts."
icon_state = "syndiebox"
/obj/item/storage/box/stockparts/deluxe/PopulateContents()
new /obj/item/stock_parts/capacitor/quadratic(src)
@@ -1008,11 +1025,3 @@
new /obj/item/stock_parts/matter_bin/bluespace(src)
new /obj/item/stock_parts/matter_bin/bluespace(src)
new /obj/item/stock_parts/matter_bin/bluespace(src)
/obj/item/storage/box/disks_nanite
name = "nanite program disks box"
illustration = "disk_kit"
/obj/item/storage/box/disks_nanite/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/disk/nanite_program(src)
+4 -11
View File
@@ -79,17 +79,10 @@
has_latches = FALSE
/obj/item/storage/toolbox/mechanical/old/heirloom
name = "old, robust toolbox" //this will be named "X family toolbox"
name = "toolbox" //this will be named "X family toolbox"
desc = "It's seen better days."
force = 12
total_mass = 2
/obj/item/storage/toolbox/mechanical/old/heirloom/afterattack(atom/A, mob/user, proximity)
. = ..()
if(proximity)
if(isobj(A))
var/obj/O = A
O.take_damage(20)
force = 5
w_class = WEIGHT_CLASS_NORMAL
/obj/item/storage/toolbox/mechanical/old/heirloom/PopulateContents()
return
@@ -115,8 +108,8 @@
/obj/item/storage/toolbox/syndicate
name = "black and red toolbox"
icon_state = "syndicate"
desc = "A toolbox painted black with a red stripe. It looks more heavier than normal toolboxes."
item_state = "toolbox_syndi"
desc = "A toolbox painted black with a red stripe. It looks more heavier than normal toolboxes."
force = 15
throwforce = 18
@@ -340,6 +340,14 @@
new /obj/item/pda/chameleon/broken(src)
// No chameleon laser, they can't randomise for //REASONS//
/obj/item/storage/box/syndie_kit/bee_grenades
name = "buzzkill grenade box"
desc = "A sleek, sturdy box with a buzzing noise coming from the inside. Uh oh."
/obj/item/storage/box/syndie_kit/bee_grenades/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/grenade/spawnergrenade/buzzkill(src)
/obj/item/storage/box/syndie_kit/kitchen_gun
name = "Kitchen Gun (TM) package"
+1 -1
View File
@@ -171,7 +171,7 @@
L.lastattackerckey = user.ckey
L.visible_message("<span class='danger'>[user] has stunned [L] with [src]!</span>", \
"<span class='userdanger'>[user] has stunned you with [src]!</span>")
add_logs(user, L, "stunned")
log_combat(user, L, "stunned")
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
+32
View File
@@ -86,6 +86,36 @@
else
..()
/obj/item/tank/jetpack/improvised
name = "improvised jetpack"
desc = "A jetpack made from two air tanks, a fire extinguisher and some atmospherics equipment. It doesn't look like it can hold much."
icon_state = "jetpack-improvised"
item_state = "jetpack-sec"
volume = 20 //normal jetpacks have 70 volume
gas_type = null //it starts empty
full_speed = FALSE //moves at hardsuit jetpack speeds
/obj/item/tank/jetpack/improvised/allow_thrust(num, mob/living/user)
if(!on)
return
if((num < 0.005 || air_contents.total_moles() < num))
turn_off()
return
if(rand(0,250) == 0)
to_chat(user, "<span class='notice'>You feel your jetpack's engines cut out.</span>")
turn_off()
return
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
turn_off()
return
var/turf/T = get_turf(user)
T.assume_air(removed)
return 1
/obj/item/tank/jetpack/void
name = "void jetpack (oxygen)"
desc = "It works well in a void."
@@ -122,6 +152,8 @@
icon_state = "jetpack-sec"
item_state = "jetpack-sec"
/obj/item/tank/jetpack/carbondioxide
name = "jetpack (carbon dioxide)"
desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals."
+2 -1
View File
@@ -233,7 +233,7 @@
return 0
var/pressure = air_contents.return_pressure()
var/temperature = air_contents.return_pressure()
var/temperature = air_contents.return_temperature()
if(pressure > TANK_FRAGMENT_PRESSURE)
if(!istype(src.loc, /obj/item/transfer_valve))
@@ -242,6 +242,7 @@
//Give the gas a chance to build up more pressure through reacting
air_contents.react(src)
air_contents.react(src)
air_contents.react(src)
pressure = air_contents.return_pressure()
var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE
var/turf/epicenter = get_turf(loc)
+5 -4
View File
@@ -62,10 +62,11 @@
remove_noz()
/obj/item/watertank/proc/remove_noz()
if(ismob(noz.loc))
var/mob/M = noz.loc
M.temporarilyRemoveItemFromInventory(noz, TRUE)
noz.forceMove(src)
if(!QDELETED(noz))
if(ismob(noz.loc))
var/mob/M = noz.loc
M.temporarilyRemoveItemFromInventory(noz, TRUE)
noz.forceMove(src)
/obj/item/watertank/Destroy()
QDEL_NULL(noz)
+1
View File
@@ -12,6 +12,7 @@
return list()
/obj/item/taster/afterattack(atom/O, mob/user, proximity)
. = ..()
if(!proximity)
return
+4 -3
View File
@@ -12,8 +12,8 @@
* Locator
*/
/obj/item/locator
name = "locator"
desc = "Used to track those with locater implants."
name = "bluespace locator"
desc = "Used to track portable teleportation beacons and targets with embedded tracking implants."
icon = 'icons/obj/device.dmi'
icon_state = "locator"
var/temp = null
@@ -131,6 +131,7 @@
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/list/active_portal_pairs
var/max_portal_pairs = 3
var/atmos_link_override
/obj/item/hand_tele/Initialize()
. = ..()
@@ -197,7 +198,7 @@
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
return
user.show_message("<span class='notice'>Locked In.</span>", 2)
var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), src, 300, 1)
var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), src, 300, 1, null, atmos_link_override)
if(!(LAZYLEN(created) == 2))
return
try_move_adjacent(created[1])
+1
View File
@@ -229,6 +229,7 @@
icon_state = "supermatter_tongs"
/obj/item/hemostat/supermatter/afterattack(atom/O, mob/user, proximity)
. = ..()
if(!sliver)
return
if(ismovableatom(O) && O != sliver)
@@ -120,6 +120,7 @@
/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity)
. = ..()
if(!proximity)
return
if(!status && O.is_refillable())
+9 -2
View File
@@ -51,6 +51,7 @@
return
/obj/item/toy/balloon/afterattack(atom/A as mob|obj, mob/user, proximity)
. = ..()
if(!proximity)
return
if (istype(A, /obj/structure/reagent_dispensers))
@@ -176,6 +177,7 @@
return ..()
/obj/item/toy/gun/afterattack(atom/target as mob|obj|turf|area, mob/user, flag)
. = ..()
if (flag)
return
if (!user.IsAdvancedToolUser())
@@ -1038,6 +1040,7 @@
throwforce = 12 //pelt your enemies to death with lumps of snow
/obj/item/toy/snowball/afterattack(atom/target as mob|obj|turf|area, mob/user)
. = ..()
if(user.dropItemToGround(src))
throw_at(target, throw_range, throw_speed)
@@ -1057,6 +1060,7 @@
w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets
/obj/item/toy/beach_ball/afterattack(atom/target as mob|obj|turf|area, mob/user)
. = ..()
if(user.dropItemToGround(src))
throw_at(target, throw_range, throw_speed)
@@ -1368,8 +1372,11 @@
to_chat(user, "You name the dummy as \"[doll_name]\"")
name = "[initial(name)] - [doll_name]"
/obj/item/toy/dummy/talk_into(atom/movable/M, message, channel, list/spans, datum/language/language)
log_talk(M,"[key_name(M)] : through dummy : [message]",LOGSAY)
/obj/item/toy/dummy/talk_into(atom/movable/A, message, channel, list/spans, datum/language/language)
var/mob/M = A
if (istype(M))
M.log_talk(message, LOG_SAY, tag="dummy toy")
say(message, language)
return NOPASS
+66 -5
View File
@@ -67,7 +67,7 @@
to_chat(user, "<span class='warning'>You need your other hand to be empty!</span>")
return
if(user.get_num_arms() < 2)
to_chat(user, "<span class='warning'>You don't have enough hands.</span>")
to_chat(user, "<span class='warning'>You don't have enough intact hands.</span>")
return
wielded = 1
if(force_wielded)
@@ -247,6 +247,7 @@
return (BRUTELOSS)
/obj/item/twohanded/fireaxe/afterattack(atom/A, mob/user, proximity)
. = ..()
if(!proximity)
return
if(wielded) //destroys windows and grilles in one hit
@@ -494,9 +495,11 @@
/obj/item/twohanded/spear/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins to sword-swallow \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
if(explosive)
user.say("[war_cry]")
user.say("[war_cry]", forced="spear warcry")
explosive.forceMove(user)
explosive.prime()
user.gib()
qdel(src)
return BRUTELOSS
return BRUTELOSS
@@ -516,13 +519,16 @@
icon_state = "spearglass[wielded]"
/obj/item/twohanded/spear/afterattack(atom/movable/AM, mob/user, proximity)
. = ..()
if(!proximity)
return
if(isopenturf(AM)) //So you can actually melee with it
return
if(explosive && wielded)
user.say("[war_cry]")
user.say("[war_cry]", forced="spear warcry")
explosive.forceMove(AM)
explosive.prime()
qdel(src)
/obj/item/twohanded/spear/grenade_prime_react(obj/item/grenade/nade)
nade.forceMove(get_turf(src))
@@ -640,7 +646,7 @@
attack_verb = list("gored")
/obj/item/twohanded/spear/grey_tide/afterattack(atom/movable/AM, mob/living/user, proximity)
..()
. = ..()
if(!proximity)
return
user.faction |= "greytide([REF(user)])"
@@ -721,6 +727,7 @@
..()
/obj/item/twohanded/pitchfork/demonic/ascended/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity || !wielded)
return
if(iswallturf(target))
@@ -730,7 +737,6 @@
W.break_wall()
W.ScrapeAway()
return
..()
//HF blade
@@ -809,3 +815,58 @@
/obj/item/twohanded/bonespear/update_icon()
icon_state = "bone_spear[wielded]"
/obj/item/twohanded/binoculars
name = "binoculars"
desc = "Used for long-distance surveillance."
item_state = "binoculars"
icon_state = "binoculars"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
var/datum/component/mobhook
var/zoom_out_amt = 6
var/zoom_amt = 10
/obj/item/twohanded/binoculars/wield(mob/user)
. = ..()
if(!wielded)
return
if(QDELETED(mobhook))
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/unwield)))
else
user.TakeComponent(mobhook)
user.visible_message("[user] holds [src] up to [user.p_their()] eyes.","You hold [src] up to your eyes.")
item_state = "binoculars_wielded"
user.regenerate_icons()
if(!user?.client)
return
var/client/C = user.client
var/_x = 0
var/_y = 0
switch(user.dir)
if(NORTH)
_y = zoom_amt
if(EAST)
_x = zoom_amt
if(SOUTH)
_y = -zoom_amt
if(WEST)
_x = -zoom_amt
C.change_view(world.view + zoom_out_amt)
C.pixel_x = world.icon_size*_x
C.pixel_y = world.icon_size*_y
/obj/item/twohanded/binoculars/unwield(mob/user)
. = ..()
mobhook.RemoveComponent()
user.visible_message("[user] lowers [src].","You lower [src].")
item_state = "binoculars"
user.regenerate_icons()
if(user && user.client)
user.regenerate_icons()
var/client/C = user.client
C.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
user.client.pixel_y = 0
+6 -8
View File
@@ -450,10 +450,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
throw_range = 2
attack_verb = list("busted")
/obj/item/statuebust/Initialize()
. = ..()
addtimer(CALLBACK(src, /datum.proc/AddComponent, /datum/component/beauty, 1000), 0)
/obj/item/tailclub
name = "tail club"
desc = "For the beating to death of lizards with their own tails."
@@ -482,7 +478,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
item_state = "skateboard"
force = 12
throwforce = 4
w_class = WEIGHT_CLASS_HUGE
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("smacked", "whacked", "slammed", "smashed")
/obj/item/melee/skateboard/attack_self(mob/user)
@@ -581,6 +577,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
if(proximity_flag)
if(is_type_in_typecache(target, strong_against))
new /obj/effect/decal/cleanable/insectguts(target.drop_location())
@@ -614,13 +611,14 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/slapper/attack(mob/M, mob/living/carbon/human/user)
if(ishuman(M))
var/mob/living/carbon/human/L = M
L.endTailWag()
if(L && L.dna && L.dna.species)
L.dna.species.stop_wagging_tail(M)
if(user.a_intent != INTENT_HARM && ((user.zone_selected == BODY_ZONE_PRECISE_MOUTH) || (user.zone_selected == BODY_ZONE_PRECISE_EYES) || (user.zone_selected == BODY_ZONE_HEAD)))
user.do_attack_animation(M)
playsound(M, 'sound/weapons/slap.ogg', 50, 1, -1)
user.visible_message("<span class='danger'>[user] slaps [M]!</span>",
"<span class='notice'>You slap [M]!</span>",\
"You hear a slap.")
"<span class='notice'>You slap [M]!</span>",\
"You hear a slap.")
return
else
..()