Merge branch 'master' of https://github.com/PolarisSS13/Polaris into clawmachine

Pretend I know what I'm doing.
This commit is contained in:
Schnayy
2020-10-09 19:55:28 -05:00
1416 changed files with 70777 additions and 27688 deletions
@@ -51,6 +51,8 @@ var/list/civilian_cartridges = list(
icon_state = "cart"
item_state = "electronic"
w_class = ITEMSIZE_TINY
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
var/obj/item/radio/integrated/radio = null
var/access_security = 0
@@ -124,14 +124,6 @@
data["latest_news"] = get_recent_news()
if(newsfeed_channel)
data["target_feed"] = data["feeds"][newsfeed_channel]
if(cartridge) // If there's a cartridge, we need to grab the information from it
data["cart_devices"] = cartridge.get_device_status()
data["cart_templates"] = cartridge.ui_templates
for(var/list/L in cartridge.get_data())
data[L["field"]] = L["value"]
// cartridge.get_data() returns a list of tuples:
// The field element is the tag used to access the information by the template
// The value element is the actual data, and can take any form necessary for the template
// update the ui if it exists, returns null if no ui is passed/found
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -278,15 +270,8 @@
fon = !fon
set_light(fon * flum)
if(href_list["toggle_device"])
var/obj/O = cartridge.internal_devices[text2num(href_list["toggle_device"])]
cartridge.active_devices ^= list(O) // Exclusive or, will toggle its presence
if(href_list["newsfeed"])
newsfeed_channel = text2num(href_list["newsfeed"])
if(href_list["cartridge_topic"] && cartridge) // Has to have a cartridge to perform these functions
cartridge.Topic(href, href_list)
SSnanoui.update_uis(src)
add_fingerprint(usr)
@@ -1,952 +0,0 @@
// Communicator peripheral devices
// Internal devices that attack() can be relayed to
// Additional UI menus for added functionality
/obj/item/weapon/commcard
name = "generic commcard"
desc = "A peripheral plug-in for personal communicators."
icon = 'icons/obj/pda.dmi'
icon_state = "cart"
item_state = "electronic"
w_class = ITEMSIZE_TINY
var/list/internal_devices = list() // Devices that can be toggled on to trigger on attack()
var/list/active_devices = list() // Devices that will be triggered on attack()
var/list/ui_templates = list() // List of ui templates the commcard can access
var/list/internal_data = list() // Data that shouldn't be updated every time nanoUI updates, or needs to persist between updates
/obj/item/weapon/commcard/proc/get_device_status()
var/list/L = list()
var/i = 1
for(var/obj/I in internal_devices)
if(I in active_devices)
L[++L.len] = list("name" = "\proper[I.name]", "active" = 1, "index" = i++)
else
L[++L.len] = list("name" = I.name, "active" = 0, "index" = i++)
return L
// cartridge.get_data() returns a list of tuples:
// The field element is the tag used to access the information by the template
// The value element is the actual data, and can take any form necessary for the template
/obj/item/weapon/commcard/proc/get_data()
return list()
// Handles cartridge-specific functions
// The helper.link() MUST HAVE 'cartridge_topic' passed into the href in order for cartridge functions to be processed.
// Doesn't matter what the value of it is for now, it's just a flag to say, "Hey, there's cartridge data to change!"
/obj/item/weapon/commcard/Topic(href, href_list)
// Signalers
if(href_list["signaler_target"])
var/obj/item/device/assembly/signaler/S = locate(href_list["signaler_target"]) // Should locate the correct signaler
if(!istype(S)) // Ref is no longer valid
return
if(S.loc != src) // No longer within the cartridge
return
switch(href_list["signaler_action"])
if("Pulse")
S.activate()
if("Edit")
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Ref no longer valid
return
var/newVal = input(user, "Input a new [href_list["signaler_value"]].", href_list["signaler_value"], (href_list["signaler_value"] == "Code" ? S.code : S.frequency)) as num|null
if(newVal)
switch(href_list["signaler_value"])
if("Code")
S.code = newVal
if("Frequency")
S.frequency = newVal
// Refresh list of powernet sensors
if(href_list["powernet_refresh"])
internal_data["grid_sensors"] = find_powernet_sensors()
// Load apc's on targeted powernet
if(href_list["powernet_target"])
internal_data["powernet_target"] = href_list["powernet_target"]
// GPS units
if(href_list["gps_target"])
var/obj/item/device/gps/G = locate(href_list["gps_target"])
if(!istype(G)) // Ref is no longer valid
return
if(G.loc != src) // No longer within the cartridge
return
switch(href_list["gps_action"])
if("Power")
G.tracking = text2num(href_list["value"])
if("Long_Range")
G.local_mode = text2num(href_list["value"])
if("Hide_Signal")
G.hide_signal = text2num(href_list["value"])
if("Tag")
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Ref no longer valid
return
var/newTag = input(user, "Please enter desired tag.", G.tag) as text|null
if(newTag)
G.tag = newTag
if(href_list["active_category"])
internal_data["supply_category"] = href_list["active_category"]
// Supply topic
// Copied from /obj/machinery/computer/supplycomp/Topic()
// code\game\machinery\computer\supply.dm, line 188
// Unfortunately, in order to support complete functionality, the whole thing is necessary
if(href_list["pack_ref"])
var/datum/supply_pack/S = locate(href_list["pack_ref"])
// Invalid ref
if(!istype(S))
return
// Expand the supply pack's contents
if(href_list["expand"])
internal_data["supply_pack_expanded"] ^= S
// Make a request for the pack
if(href_list["request"])
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Invalid ref
return
if(world.time < internal_data["supply_reqtime"])
visible_message("<span class='warning'>[src] flashes, \"[internal_data["supply_reqtime"] - world.time] seconds remaining until another requisition form may be printed.\"</span>")
return
var/timeout = world.time + 600
var/reason = sanitize(input(user, "Reason:","Why do you require this item?","") as null|text)
if(world.time > timeout)
to_chat(user, "<span class='warning'>Error. Request timed out.</span>")
return
if(!reason)
return
SSsupply.create_order(S, user, reason)
internal_data["supply_reqtime"] = (world.time + 5) % 1e5
if(href_list["order_ref"])
var/datum/supply_order/O = locate(href_list["order_ref"])
// Invalid ref
if(!istype(O))
return
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Invalid ref
return
if(href_list["edit"])
var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text)
if(!new_val)
return
switch(href_list["edit"])
if("Supply Pack")
O.name = new_val
if("Cost")
var/num = text2num(new_val)
if(num)
O.cost = num
if("Index")
var/num = text2num(new_val)
if(num)
O.index = num
if("Reason")
O.comment = new_val
if("Ordered by")
O.ordered_by = new_val
if("Ordered at")
O.ordered_at = new_val
if("Approved by")
O.approved_by = new_val
if("Approved at")
O.approved_at = new_val
if(href_list["approve"])
SSsupply.approve_order(O, user)
if(href_list["deny"])
SSsupply.deny_order(O, user)
if(href_list["delete"])
SSsupply.delete_order(O, user)
if(href_list["clear_all_requests"])
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Invalid ref
return
SSsupply.deny_all_pending(user)
if(href_list["export_ref"])
var/datum/exported_crate/E = locate(href_list["export_ref"])
// Invalid ref
if(!istype(E))
return
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Invalid ref
return
if(href_list["index"])
var/list/L = E.contents[href_list["index"]]
if(href_list["edit"])
var/field = alert(user, "Select which field to edit", , "Name", "Quantity", "Value")
var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text)
if(!new_val)
return
switch(field)
if("Name")
L["object"] = new_val
if("Quantity")
var/num = text2num(new_val)
if(num)
L["quantity"] = num
if("Value")
var/num = text2num(new_val)
if(num)
L["value"] = num
if(href_list["delete"])
E.contents.Cut(href_list["index"], href_list["index"] + 1)
// Else clause means they're editing/deleting the whole export report, rather than a specific item in it
else if(href_list["edit"])
var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text)
if(!new_val)
return
switch(href_list["edit"])
if("Name")
E.name = new_val
if("Value")
var/num = text2num(new_val)
if(num)
E.value = num
else if(href_list["delete"])
SSsupply.delete_export(E, user)
else if(href_list["add_item"])
SSsupply.add_export_item(E, user)
if(SSsupply && SSsupply.shuttle)
switch(href_list["send_shuttle"])
if("send_away")
if(SSsupply.shuttle.forbidden_atoms_check())
to_chat(usr, "<span class='warning'>For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.</span>")
else
SSsupply.shuttle.launch(src)
to_chat(usr, "<span class='notice'>Initiating launch sequence.</span>")
if("send_to_station")
SSsupply.shuttle.launch(src)
to_chat(usr, "<span class='notice'>The supply shuttle has been called and will arrive in approximately [round(SSsupply.movetime/600,1)] minutes.</span>")
if("cancel_shuttle")
SSsupply.shuttle.cancel_launch(src)
if("force_shuttle")
SSsupply.shuttle.force_launch(src)
// Status display
switch(href_list["stat_display"])
if("message")
post_status("message", internal_data["stat_display_line1"], internal_data["stat_display_line2"])
internal_data["stat_display_special"] = "message"
if("alert")
post_status("alert", href_list["alert"])
internal_data["stat_display_special"] = href_list["alert"]
if("setmsg")
internal_data["stat_display_line[href_list["line"]]"] = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", internal_data["stat_display_line[href_list["line"]]"]) as text|null, 40), 40)
else
post_status(href_list["stat_display"])
internal_data["stat_display_special"] = href_list["stat_display"]
// Merc shuttle blast door controls
switch(href_list["all_blast_doors"])
if("open")
for(var/obj/machinery/door/blast/B in internal_data["shuttle_doors"])
B.open()
if("close")
for(var/obj/machinery/door/blast/B in internal_data["shuttle_doors"])
B.close()
if(href_list["scan_blast_doors"])
internal_data["shuttle_doors"] = find_blast_doors()
if(href_list["toggle_blast_door"])
var/obj/machinery/door/blast/B = locate(href_list["toggle_blast_door"])
if(!B)
return
spawn(0)
if(B.density)
B.open()
else
B.close()
// Updates status displays with a new message
// Copied from /obj/item/weapon/cartridge/proc/post_status(),
// code/game/objects/items/devices/PDA/cart.dm, line 251
/obj/item/weapon/commcard/proc/post_status(var/command, var/data1, var/data2)
var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435)
if(!frequency)
return
var/datum/signal/status_signal = new
status_signal.source = src
status_signal.transmission_method = TRANSMISSION_RADIO
status_signal.data["command"] = command
switch(command)
if("message")
status_signal.data["msg1"] = data1
status_signal.data["msg2"] = data2
internal_data["stat_display_active1"] = data1 // Update the internally stored message, we won't get receive_signal if we're the sender
internal_data["stat_display_active2"] = data2
if(loc)
var/obj/item/PDA = loc
var/mob/user = PDA.fingerprintslast
log_admin("STATUS: [user] set status screen with [src]. Message: [data1] [data2]")
message_admins("STATUS: [user] set status screen with [src]. Message: [data1] [data2]")
if("alert")
status_signal.data["picture_state"] = data1
frequency.post_signal(src, status_signal)
// Receives updates by external devices to the status displays
/obj/item/weapon/commcard/receive_signal(var/datum/signal/signal, var/receive_method, var/receive_param)
internal_data["stat_display_special"] = signal.data["command"]
switch(signal.data["command"])
if("message")
internal_data["stat_display_active1"] = signal.data["msg1"]
internal_data["stat_display_active2"] = signal.data["msg2"]
if("alert")
internal_data["stat_display_special"] = signal.data["picture_state"]
///////////////////////////
// SUBTYPES
///////////////////////////
// Engineering Cartridge:
// Devices
// *- Halogen Counter
// Templates
// *- Power Monitor
/obj/item/weapon/commcard/engineering
name = "\improper Power-ON cartridge"
icon_state = "cart-e"
ui_templates = list(list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl"))
/obj/item/weapon/commcard/engineering/New()
..()
internal_devices |= new /obj/item/device/halogen_counter(src)
/obj/item/weapon/commcard/engineering/Initialize()
internal_data["grid_sensors"] = find_powernet_sensors()
internal_data["powernet_target"] = ""
/obj/item/weapon/commcard/engineering/get_data()
return list(
list("field" = "powernet_monitoring", "value" = get_powernet_monitoring_list()),
list("field" = "powernet_target", "value" = get_powernet_target(internal_data["powernet_target"]))
)
// Atmospherics Cartridge:
// Devices
// *- Gas scanner
/obj/item/weapon/commcard/atmos
name = "\improper BreatheDeep cartridge"
icon_state = "cart-a"
/obj/item/weapon/commcard/atmos/New()
..()
internal_devices |= new /obj/item/device/analyzer(src)
// Medical Cartridge:
// Devices
// *- Halogen Counter
// *- Health Analyzer
// Templates
// *- Medical Records
/obj/item/weapon/commcard/medical
name = "\improper Med-U cartridge"
icon_state = "cart-m"
ui_templates = list(list("name" = "Medical Records", "template" = "med_records.tmpl"))
/obj/item/weapon/commcard/medical/New()
..()
internal_devices |= new /obj/item/device/healthanalyzer(src)
internal_devices |= new /obj/item/device/halogen_counter(src)
/obj/item/weapon/commcard/medical/get_data()
return list(list("field" = "med_records", "value" = get_med_records()))
// Chemistry Cartridge:
// Devices
// *- Halogen Counter
// *- Health Analyzer
// *- Reagent Scanner
// Templates
// *- Medical Records
/obj/item/weapon/commcard/medical/chemistry
name = "\improper ChemWhiz cartridge"
icon_state = "cart-chem"
/obj/item/weapon/commcard/medical/chemistry/New()
..()
internal_devices |= new /obj/item/device/reagent_scanner(src)
// Detective Cartridge:
// Devices
// *- Halogen Counter
// *- Health Analyzer
// Templates
// *- Medical Records
// *- Security Records
/obj/item/weapon/commcard/medical/detective
name = "\improper D.E.T.E.C.T. cartridge"
icon_state = "cart-s"
ui_templates = list(
list("name" = "Medical Records", "template" = "med_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl")
)
/obj/item/weapon/commcard/medical/detective/get_data()
var/list/data = ..()
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
return data
// Internal Affairs Cartridge:
// Templates
// *- Security Records
// *- Employment Records
/obj/item/weapon/commcard/int_aff
name = "\improper P.R.O.V.E. cartridge"
icon_state = "cart-s"
ui_templates = list(
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl")
)
/obj/item/weapon/commcard/int_aff/get_data()
return list(
list("field" = "emp_records", "value" = get_emp_records()),
list("field" = "sec_records", "value" = get_sec_records())
)
// Security Cartridge:
// Templates
// *- Security Records
// *- Security Bot Access
/obj/item/weapon/commcard/security
name = "\improper R.O.B.U.S.T. cartridge"
icon_state = "cart-s"
ui_templates = list(
list("name" = "Security Records", "template" = "sec_records.tmpl"),
list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl")
)
/obj/item/weapon/commcard/security/get_data()
return list(
list("field" = "sec_records", "value" = get_sec_records()),
list("field" = "sec_bot_access", "value" = get_sec_bot_access())
)
// Janitor Cartridge:
// Templates
// *- Janitorial Locator Magicbox
/obj/item/weapon/commcard/janitor
name = "\improper CustodiPRO cartridge"
desc = "The ultimate in clean-room design."
ui_templates = list(
list("name" = "Janitorial Supply Locator", "template" = "janitorialLocator.tmpl")
)
/obj/item/weapon/commcard/janitor/get_data()
return list(
list("field" = "janidata", "value" = get_janitorial_locations())
)
// Signal Cartridge:
// Devices
// *- Signaler
// Templates
// *- Signaler Access
/obj/item/weapon/commcard/signal
name = "generic signaler cartridge"
desc = "A data cartridge with an integrated radio signaler module."
ui_templates = list(
list("name" = "Integrated Signaler Control", "template" = "signaler_access.tmpl")
)
/obj/item/weapon/commcard/signal/New()
..()
internal_devices |= new /obj/item/device/assembly/signaler(src)
/obj/item/weapon/commcard/signal/get_data()
return list(
list("field" = "signaler_access", "value" = get_int_signalers())
)
// Science Cartridge:
// Devices
// *- Signaler
// *- Reagent Scanner
// *- Gas Scanner
// Templates
// *- Signaler Access
/obj/item/weapon/commcard/signal/science
name = "\improper Signal Ace 2 cartridge"
desc = "Complete with integrated radio signaler!"
icon_state = "cart-tox"
// UI templates inherited
/obj/item/weapon/commcard/signal/science/New()
..()
internal_devices |= new /obj/item/device/reagent_scanner(src)
internal_devices |= new /obj/item/device/analyzer(src)
// Supply Cartridge:
// Templates
// *- Supply Records
/obj/item/weapon/commcard/supply
name = "\improper Space Parts & Space Vendors cartridge"
desc = "Perfect for the Quartermaster on the go!"
icon_state = "cart-q"
ui_templates = list(
list("name" = "Supply Records", "template" = "supply_records.tmpl")
)
/obj/item/weapon/commcard/supply/New()
..()
internal_data["supply_category"] = null
internal_data["supply_controls"] = FALSE // Cannot control the supply shuttle, cannot accept orders
internal_data["supply_pack_expanded"] = list()
internal_data["supply_reqtime"] = -1
/obj/item/weapon/commcard/supply/get_data()
// Supply records data
var/list/shuttle_status = get_supply_shuttle_status()
var/list/orders = get_supply_orders()
var/list/receipts = get_supply_receipts()
var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge
var/list/pack_list = list() // List of supply packs within the currently selected category
if(internal_data["supply_category"])
pack_list = get_supply_pack_list()
return list(
list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"]),
list("field" = "order_auth", "value" = misc_supply_data["order_auth"]),
list("field" = "supply_points", "value" = misc_supply_data["supply_points"]),
list("field" = "categories", "value" = misc_supply_data["supply_categories"]),
list("field" = "contraband", "value" = misc_supply_data["contraband"]),
list("field" = "active_category", "value" = internal_data["supply_category"]),
list("field" = "shuttle", "value" = shuttle_status),
list("field" = "orders", "value" = orders),
list("field" = "receipts", "value" = receipts),
list("field" = "supply_packs", "value" = pack_list)
)
// Command Cartridge:
// Templates
// *- Status Display Access
// *- Employment Records
/obj/item/weapon/commcard/head
name = "\improper Easy-Record DELUXE"
icon_state = "cart-h"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl")
)
/obj/item/weapon/commcard/head/New()
..()
internal_data["stat_display_line1"] = null
internal_data["stat_display_line2"] = null
internal_data["stat_display_active1"] = null
internal_data["stat_display_active2"] = null
internal_data["stat_display_special"] = null
/obj/item/weapon/commcard/head/Initialize()
// Have to register the commcard with the Radio controller to receive updates to the status displays
radio_controller.add_object(src, 1435)
..()
/obj/item/weapon/commcard/head/Destroy()
// Have to unregister the commcard for proper bookkeeping
radio_controller.remove_object(src, 1435)
..()
/obj/item/weapon/commcard/head/get_data()
return list(
list("field" = "emp_records", "value" = get_emp_records()),
list("field" = "stat_display", "value" = get_status_display())
)
// Head of Personnel Cartridge:
// Templates
// *- Status Display Access
// *- Employment Records
// *- Security Records
// *- Supply Records
// ?- Supply Bot Access
// *- Janitorial Locator Magicbox
/obj/item/weapon/commcard/head/hop
name = "\improper HumanResources9001 cartridge"
icon_state = "cart-h"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl"),
list("name" = "Supply Records", "template" = "supply_records.tmpl"),
list("name" = "Janitorial Supply Locator", "template" = "janitorialLocator.tmpl")
)
/obj/item/weapon/commcard/head/hop/get_data()
var/list/data = ..()
// Sec records
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
// Supply records data
var/list/shuttle_status = get_supply_shuttle_status()
var/list/orders = get_supply_orders()
var/list/receipts = get_supply_receipts()
var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge
var/list/pack_list = list() // List of supply packs within the currently selected category
if(internal_data["supply_category"])
pack_list = get_supply_pack_list()
data[++data.len] = list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"])
data[++data.len] = list("field" = "order_auth", "value" = misc_supply_data["order_auth"])
data[++data.len] = list("field" = "supply_points", "value" = misc_supply_data["supply_points"])
data[++data.len] = list("field" = "categories", "value" = misc_supply_data["supply_categories"])
data[++data.len] = list("field" = "contraband", "value" = misc_supply_data["contraband"])
data[++data.len] = list("field" = "active_category", "value" = internal_data["supply_category"])
data[++data.len] = list("field" = "shuttle", "value" = shuttle_status)
data[++data.len] = list("field" = "orders", "value" = orders)
data[++data.len] = list("field" = "receipts", "value" = receipts)
data[++data.len] = list("field" = "supply_packs", "value" = pack_list)
// Janitorial locator magicbox
data[++data.len] = list("field" = "janidata", "value" = get_janitorial_locations())
return data
// Head of Security Cartridge:
// Templates
// *- Status Display Access
// *- Employment Records
// *- Security Records
// *- Security Bot Access
/obj/item/weapon/commcard/head/hos
name = "\improper R.O.B.U.S.T. DELUXE"
icon_state = "cart-hos"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl"),
list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl")
)
/obj/item/weapon/commcard/head/hos/get_data()
var/list/data = ..()
// Sec records
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
// Sec bot access
data[++data.len] = list("field" = "sec_bot_access", "value" = get_sec_bot_access())
return data
// Research Director Cartridge:
// Devices
// *- Signaler
// *- Gas Scanner
// *- Reagent Scanner
// Templates
// *- Status Display Access
// *- Employment Records
// *- Signaler Access
/obj/item/weapon/commcard/head/rd
name = "\improper Signal Ace DELUXE"
icon_state = "cart-rd"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Integrated Signaler Control", "template" = "signaler_access.tmpl")
)
/obj/item/weapon/commcard/head/rd/New()
..()
internal_devices |= new /obj/item/device/analyzer(src)
internal_devices |= new /obj/item/device/reagent_scanner(src)
internal_devices |= new /obj/item/device/assembly/signaler(src)
/obj/item/weapon/commcard/head/rd/get_data()
var/list/data = ..()
// Signaler access
data[++data.len] = list("field" = "signaler_access", "value" = get_int_signalers())
return data
// Chief Medical Officer Cartridge:
// Devices
// *- Health Analyzer
// *- Reagent Scanner
// *- Halogen Counter
// Templates
// *- Status Display Access
// *- Employment Records
// *- Medical Records
/obj/item/weapon/commcard/head/cmo
name = "\improper Med-U DELUXE"
icon_state = "cart-cmo"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Medical Records", "template" = "med_records.tmpl")
)
/obj/item/weapon/commcard/head/cmo/New()
..()
internal_devices |= new /obj/item/device/healthanalyzer(src)
internal_devices |= new /obj/item/device/reagent_scanner(src)
internal_devices |= new /obj/item/device/halogen_counter(src)
/obj/item/weapon/commcard/head/cmo/get_data()
var/list/data = ..()
// Med records
data[++data.len] = list("field" = "med_records", "value" = get_med_records())
return data
// Chief Engineer Cartridge:
// Devices
// *- Gas Scanner
// *- Halogen Counter
// Templates
// *- Status Display Access
// *- Employment Records
// *- Power Monitoring
/obj/item/weapon/commcard/head/ce
name = "\improper Power-On DELUXE"
icon_state = "cart-ce"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl")
)
/obj/item/weapon/commcard/head/ce/New()
..()
internal_devices |= new /obj.item/device/analyzer(src)
internal_devices |= new /obj/item/device/halogen_counter(src)
/obj/item/weapon/commcard/head/ce/Initialize()
internal_data["grid_sensors"] = find_powernet_sensors()
internal_data["powernet_target"] = ""
/obj/item/weapon/commcard/head/ce/get_data()
var/list/data = ..()
// Add power monitoring data
data[++data.len] = list("field" = "powernet_monitoring", "value" = get_powernet_monitoring_list())
data[++data.len] = list("field" = "powernet_target", "value" = get_powernet_target(internal_data["powernet_target"]))
return data
// Captain Cartridge:
// Devices
// *- Health analyzer
// *- Gas Scanner
// *- Reagent Scanner
// *- Halogen Counter
// X- GPS - Balance
// *- Signaler
// Templates
// *- Status Display Access
// *- Employment Records
// *- Medical Records
// *- Security Records
// *- Power Monitoring
// *- Supply Records
// X- Supply Bot Access - Mulebots usually break when used
// *- Security Bot Access
// *- Janitorial Locator Magicbox
// X- GPS Access - Balance
// *- Signaler Access
/obj/item/weapon/commcard/head/captain
name = "\improper Value-PAK cartridge"
desc = "Now with 200% more value!"
icon_state = "cart-c"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Medical Records", "template" = "med_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl"),
list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl"),
list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl"),
list("name" = "Supply Records", "template" = "supply_records.tmpl"),
list("name" = "Janitorial Supply Locator", "template" = "janitorialLocator.tmpl"),
list("name" = "Integrated Signaler Control", "template" = "signaler_access.tmpl")
)
/obj/item/weapon/commcard/head/captain/New()
..()
internal_devices |= new /obj.item/device/analyzer(src)
internal_devices |= new /obj/item/device/healthanalyzer(src)
internal_devices |= new /obj/item/device/reagent_scanner(src)
internal_devices |= new /obj/item/device/halogen_counter(src)
internal_devices |= new /obj/item/device/assembly/signaler(src)
/obj/item/weapon/commcard/head/captain/get_data()
var/list/data = ..()
//Med records
data[++data.len] = list("field" = "med_records", "value" = get_med_records())
// Sec records
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
// Sec bot access
data[++data.len] = list("field" = "sec_bot_access", "value" = get_sec_bot_access())
// Power Monitoring
data[++data.len] = list("field" = "powernet_monitoring", "value" = get_powernet_monitoring_list())
data[++data.len] = list("field" = "powernet_target", "value" = get_powernet_target(internal_data["powernet_target"]))
// Supply records data
var/list/shuttle_status = get_supply_shuttle_status()
var/list/orders = get_supply_orders()
var/list/receipts = get_supply_receipts()
var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge
var/list/pack_list = list() // List of supply packs within the currently selected category
if(internal_data["supply_category"])
pack_list = get_supply_pack_list()
data[++data.len] = list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"])
data[++data.len] = list("field" = "order_auth", "value" = misc_supply_data["order_auth"])
data[++data.len] = list("field" = "supply_points", "value" = misc_supply_data["supply_points"])
data[++data.len] = list("field" = "categories", "value" = misc_supply_data["supply_categories"])
data[++data.len] = list("field" = "contraband", "value" = misc_supply_data["contraband"])
data[++data.len] = list("field" = "active_category", "value" = internal_data["supply_category"])
data[++data.len] = list("field" = "shuttle", "value" = shuttle_status)
data[++data.len] = list("field" = "orders", "value" = orders)
data[++data.len] = list("field" = "receipts", "value" = receipts)
data[++data.len] = list("field" = "supply_packs", "value" = pack_list)
// Janitorial locator magicbox
data[++data.len] = list("field" = "janidata", "value" = get_janitorial_locations())
// Signaler access
data[++data.len] = list("field" = "signaler_access", "value" = get_int_signalers())
return data
// Mercenary Cartridge
// Templates
// *- Merc Shuttle Door Controller
/obj/item/weapon/commcard/mercenary
name = "\improper Detomatix cartridge"
icon_state = "cart"
ui_templates = list(
list("name" = "Shuttle Blast Door Control", "template" = "merc_blast_door_control.tmpl")
)
/obj/item/weapon/commcard/mercenary/Initialize()
internal_data["shuttle_door_code"] = "smindicate" // Copied from PDA code
internal_data["shuttle_doors"] = find_blast_doors()
/obj/item/weapon/commcard/mercenary/get_data()
var/door_status[0]
for(var/obj/machinery/door/blast/B in internal_data["shuttle_doors"])
door_status[++door_status.len] += list(
"open" = B.density,
"name" = B.name,
"ref" = "\ref[B]"
)
return list(
list("field" = "blast_door", "value" = door_status)
)
// Explorer Cartridge
// Devices
// *- GPS
// Templates
// *- GPS Access
// IMPORTANT: NOT MAPPED IN DUE TO BALANCE CONCERNS RE: FINDING THE VICTIMS OF ANTAGS.
// See suit sensors, specifically ease of turning them off, and variable level of settings which may or may not give location
// A GPS in your phone that is either broadcasting position or totally off, and can be hidden in pockets, coats, bags, boxes, etc, is much harder to disable
/obj/item/weapon/commcard/explorer
name = "\improper Explorator cartridge"
icon_state = "cart-tox"
ui_templates = list(
list("name" = "Integrated GPS", "template" = "gps_access.tmpl")
)
/obj/item/weapon/commcard/explorer/New()
..()
internal_devices |= new /obj/item/device/gps/explorer(src)
/obj/item/weapon/commcard/explorer/get_data()
var/list/GPS = get_GPS_lists()
return list(
list("field" = "gps_access", "value" = GPS[1]),
list("field" = "gps_signal", "value" = GPS[2]),
list("field" = "gps_status", "value" = GPS[3])
)
@@ -43,7 +43,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
var/note = "Thank you for choosing the T-14.2 Communicator, this is your notepad!" //Current note in the notepad function
var/notehtml = ""
var/obj/item/weapon/commcard/cartridge = null //current cartridge
var/fon = 0 // Internal light
var/flum = 2 // Brightness
@@ -203,17 +202,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
if(!get_connection_to_tcomms())
close_connection(reason = "Connection timed out")
// Proc: attack()
// Parameters: 2 (M - what is being attacked. user - the mob that has the communicator)
// Description: When the communicator has an attached commcard with internal devices, relay the attack() through to those devices.
// Contents of the for loop are copied from gripper code, because that does approximately what we want to do.
/obj/item/device/communicator/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(cartridge && cartridge.active_devices)
for(var/obj/item/wrapped in cartridge.active_devices)
if(wrapped) //The force of the wrapped obj gets set to zero during the attack() and afterattack().
wrapped.attack(M,user)
return 0
// Proc: attackby()
// Parameters: 2 (C - what is used on the communicator. user - the mob that has the communicator)
// Description: When an ID is swiped on the communicator, the communicator reads the job and checks it against the Owner name, if success, the occupation is added.
@@ -229,13 +217,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
occupation = idcard.assignment
to_chat(user, "<span class='notice'>Occupation updated.</span>")
if(istype(C, /obj/item/weapon/commcard) && !cartridge)
cartridge = C
user.drop_item()
cartridge.forceMove(src)
to_chat(usr, "<span class='notice'>You slot \the [cartridge] into \the [src].</span>")
modules[++modules.len] = list("module" = "External Device", "icon" = "external64", "number" = EXTRTAB)
SSnanoui.update_uis(src) // update all UIs attached to src
return
// Proc: attack_self()
@@ -358,38 +339,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
client_huds |= global_hud.whitense
client_huds |= global_hud.darkMask
/obj/item/device/communicator/verb/verb_remove_cartridge()
set category = "Object"
set name = "Remove commcard"
set src in usr
// Can't remove what isn't there
if(!cartridge)
to_chat(usr, "<span class='notice'>There isn't a commcard to remove!</span>")
return
// Can't remove if you're physically unable to
if(usr.stat || usr.restrained() || usr.paralysis || usr.stunned || usr.weakened)
to_chat(usr, "<span class='notice'>You cannot do this while restrained.</span>")
return
var/turf/T = get_turf(src)
cartridge.loc = T
// If it's in someone, put the cartridge in their hands
if (ismob(loc))
var/mob/M = loc
M.put_in_hands(cartridge)
// Else just set it on the ground
else
cartridge.loc = get_turf(src)
cartridge = null
// We have to iterate through the modules to find EXTRTAB, because list procs don't play nice with a list of lists
for(var/i = 1, i <= modules.len, i++)
if(modules[i]["number"] == EXTRTAB)
modules.Cut(i, i+1)
break
to_chat(usr, "<span class='notice'>You remove \the [cartridge] from the [name].</span>")
//It's the 26th century. We should have smart watches by now.
/obj/item/device/communicator/watch
name = "communicator watch"
@@ -96,448 +96,3 @@
news.Swap(1, 3) // List is sorted in ascending order of timestamp, we want descending
return news
// Putting the commcard data harvesting helpers here
// Not ideal to put all the procs on the base type
// but it may open options for adminbus,
// And it saves duplicated code
// Medical records
/obj/item/weapon/commcard/proc/get_med_records()
var/med_records[0]
for(var/datum/data/record/M in sortRecord(data_core.medical))
var/record[0]
record[++record.len] = list("tab" = "Name", "val" = M.fields["name"])
record[++record.len] = list("tab" = "ID", "val" = M.fields["id"])
record[++record.len] = list("tab" = "Blood Type", "val" = M.fields["b_type"])
record[++record.len] = list("tab" = "DNA #", "val" = M.fields["b_dna"])
record[++record.len] = list("tab" = "Gender", "val" = M.fields["id_gender"])
record[++record.len] = list("tab" = "Entity Classification", "val" = M.fields["brain_type"])
record[++record.len] = list("tab" = "Minor Disorders", "val" = M.fields["mi_dis"])
record[++record.len] = list("tab" = "Major Disorders", "val" = M.fields["ma_dis"])
record[++record.len] = list("tab" = "Allergies", "val" = M.fields["alg"])
record[++record.len] = list("tab" = "Condition", "val" = M.fields["cdi"])
record[++record.len] = list("tab" = "Notes", "val" = M.fields["notes"])
med_records[++med_records.len] = list("name" = M.fields["name"], "record" = record)
return med_records
// Employment records
/obj/item/weapon/commcard/proc/get_emp_records()
var/emp_records[0]
for(var/datum/data/record/G in sortRecord(data_core.general))
var/record[0]
record[++record.len] = list("tab" = "Name", "val" = G.fields["name"])
record[++record.len] = list("tab" = "ID", "val" = G.fields["id"])
record[++record.len] = list("tab" = "Rank", "val" = G.fields["rank"])
record[++record.len] = list("tab" = "Fingerprint", "val" = G.fields["fingerprint"])
record[++record.len] = list("tab" = "Entity Classification", "val" = G.fields["brain_type"])
record[++record.len] = list("tab" = "Sex", "val" = G.fields["sex"])
record[++record.len] = list("tab" = "Species", "val" = G.fields["species"])
record[++record.len] = list("tab" = "Age", "val" = G.fields["age"])
record[++record.len] = list("tab" = "Notes", "val" = G.fields["notes"])
emp_records[++emp_records.len] = list("name" = G.fields["name"], "record" = record)
return emp_records
// Security records
/obj/item/weapon/commcard/proc/get_sec_records()
var/sec_records[0]
for(var/datum/data/record/G in sortRecord(data_core.general))
var/record[0]
record[++record.len] = list("tab" = "Name", "val" = G.fields[""])
record[++record.len] = list("tab" = "Sex", "val" = G.fields[""])
record[++record.len] = list("tab" = "Species", "val" = G.fields[""])
record[++record.len] = list("tab" = "Age", "val" = G.fields[""])
record[++record.len] = list("tab" = "Rank", "val" = G.fields[""])
record[++record.len] = list("tab" = "Fingerprint", "val" = G.fields[""])
record[++record.len] = list("tab" = "Physical Status", "val" = G.fields[""])
record[++record.len] = list("tab" = "Mental Status", "val" = G.fields[""])
record[++record.len] = list("tab" = "Criminal Status", "val" = G.fields[""])
record[++record.len] = list("tab" = "Major Crimes", "val" = G.fields[""])
record[++record.len] = list("tab" = "Minor Crimes", "val" = G.fields[""])
record[++record.len] = list("tab" = "Notes", "val" = G.fields["notes"])
sec_records[++sec_records.len] = list("name" = G.fields["name"], "record" = record)
return sec_records
// Status of all secbots
// Weaker than what PDAs appear to do, but as of 7/1/2018 PDA secbot access is nonfunctional
/obj/item/weapon/commcard/proc/get_sec_bot_access()
var/sec_bots[0]
for(var/mob/living/bot/secbot/S in mob_list)
// Get new bot
var/status[0]
status[++status.len] = list("tab" = "Name", "val" = sanitize(S.name))
// If it's turned off, then it shouldn't be broadcasting any further info
if(!S.on)
status[++status.len] = list("tab" = "Power", "val" = "<span class='bad'>Off</span>") // Encoding the span classes here so I don't have to do complicated switches in the ui template
continue
status[++status.len] = list("tab" = "Power", "val" = "<span class='good'>On</span>")
// -- What it's doing
// If it's engaged, then say who it thinks it's engaging
if(S.target)
status[++status.len] = list("tab" = "Status", "val" = "<span class='bad'>Apprehending Target</span>")
status[++status.len] = list("tab" = "Target", "val" = S.target_name(S.target))
// Else if it's patrolling
else if(S.will_patrol)
status[++status.len] = list("tab" = "Status", "val" = "<span class='good'>Patrolling</span>")
// Otherwise we don't know what it's doing
else
status[++status.len] = list("tab" = "Status", "val" = "<span class='average'>Idle</span>")
// Where it is
status[++status.len] = list("tab" = "Location", "val" = sanitize("[get_area(S.loc)]"))
// Append bot to the list
sec_bots[++sec_bots.len] = list("bot" = S.name, "status" = status)
return sec_bots
// Code and frequency of stored signalers
// Supports multiple signalers within the device
/obj/item/weapon/commcard/proc/get_int_signalers()
var/signalers[0]
for(var/obj/item/device/assembly/signaler/S in internal_devices)
var/unit[0]
unit[++unit.len] = list("tab" = "Code", "val" = S.code)
unit[++unit.len] = list("tab" = "Frequency", "val" = S.frequency)
signalers[++signalers.len] = list("ref" = "\ref[S]", "status" = unit)
return signalers
// Returns list of all powernet sensors currently visible to the commcard
/obj/item/weapon/commcard/proc/find_powernet_sensors()
var/grid_sensors[0]
// Find all the powernet sensors we need to pull data from
// Copied from /datum/nano_module/power_monitor/proc/refresh_sensors(),
// located in '/code/modules/nano/modules/power_monitor.dm'
// Minor tweaks for efficiency and cleanliness
var/turf/T = get_turf(src)
if(T)
var/list/levels = using_map.get_map_levels(T.z, FALSE)
for(var/obj/machinery/power/sensor/S in machines)
if((S.long_range) || (S.loc.z in levels) || (S.loc.z == T.z)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels.
if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen!
warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z")
else
grid_sensors += S
return grid_sensors
// List of powernets
/obj/item/weapon/commcard/proc/get_powernet_monitoring_list()
// Fetch power monitor data
var/sensors[0]
for(var/obj/machinery/power/sensor/S in internal_data["grid_sensors"])
var/list/focus = S.return_reading_data()
sensors[++sensors.len] = list(
"name" = S.name_tag,
"alarm" = focus["alarm"]
)
return sensors
// Information about the targeted powernet
/obj/item/weapon/commcard/proc/get_powernet_target(var/target_sensor)
if(!target_sensor)
return
var/powernet_target[0]
for(var/obj/machinery/power/sensor/S in internal_data["grid_sensors"])
var/list/focus = S.return_reading_data()
// Packages the span class here so it doesn't need to be interpreted w/in the for loop in the ui template
var/load_stat = "<span class='good'>Optimal</span>"
if(focus["load_percentage"] >= 95)
load_stat = "<span class='bad'>DANGER: Overload</span>"
else if(focus["load_percentage"] >= 85)
load_stat = "<span class='average'>WARNING: High Load</span>"
var/alarm_stat = focus["alarm"] ? "<span class='bad'>WARNING: Abnormal activity detected!</span>" : "<span class='good'>Secure</span>"
if(target_sensor == S.name_tag)
powernet_target = list(
"name" = S.name_tag,
"alarm" = focus["alarm"],
"error" = focus["error"],
"apc_data" = focus["apc_data"],
"status" = list(
list("field" = "Network Load Status", "statval" = load_stat),
list("field" = "Network Security Status", "statval" = alarm_stat),
list("field" = "Load Percentage", "statval" = focus["load_percentage"]),
list("field" = "Available Power", "statval" = focus["total_avail"]),
list("field" = "APC Power Usage", "statval" = focus["total_used_apc"]),
list("field" = "Other Power Usage", "statval" = focus["total_used_other"]),
list("field" = "Total Usage", "statval" = focus["total_used_all"])
)
)
return powernet_target
// Compiles the locations of all janitorial paraphernalia, as used by janitorialLocator.tmpl
/obj/item/weapon/commcard/proc/get_janitorial_locations()
// Fetch janitorial locator
var/janidata[0]
var/list/cleaningList = list()
cleaningList += all_mops + all_mopbuckets + all_janitorial_carts
// User's location
var/turf/userloc = get_turf(src)
if(isturf(userloc))
janidata[++janidata.len] = list("field" = "Current Location", "val" = "<span class='good'>[userloc.x], [userloc.y], [using_map.get_zlevel_name(userloc.z)]</span>")
else
janidata[++janidata.len] = list("field" = "Current Location", "val" = "<span class='bad'>Unknown</span>")
return janidata // If the user isn't on a valid turf, then it shouldn't be able to find anything anyways
// Mops, mop buckets, janitorial carts.
for(var/obj/C in cleaningList)
var/turf/T = get_turf(C)
if(isturf(T) )//&& T.z in using_map.get_map_levels(userloc, FALSE))
if(T.z == userloc.z)
janidata[++janidata.len] = list("field" = apply_text_macros("\proper [C.name]"), "val" = "<span class='good'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>")
else
janidata[++janidata.len] = list("field" = apply_text_macros("\proper [C.name]"), "val" = "<span class='average'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>")
// Cleanbots
for(var/mob/living/bot/cleanbot/B in living_mob_list)
var/turf/T = get_turf(B)
if(isturf(T) )//&& T.z in using_map.get_map_levels(userloc, FALSE))
var/textout = ""
if(B.on)
textout += "Status: <span class='good'>Online</span><br>"
if(T.z == userloc.z)
textout += "<span class='good'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>"
else
textout += "<span class='average'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>"
else
textout += "Status: <span class='bad'>Offline</span>"
janidata[++janidata.len] = list("field" = "[B.name]", "val" = textout)
return janidata
// Compiles the three lists used by GPS_access.tmpl
// The contents of the three lists are inherently related, so separating them into different procs would be largely redundant
/obj/item/weapon/commcard/proc/get_GPS_lists()
// GPS Access
var/intgps[0] // Gps devices within the commcard -- Allow tag edits, turning on/off, etc
var/extgps[0] // Gps devices not inside the commcard -- Print locations if a gps is on
var/stagps[0] // Gps net status, location, whether it's on, if it's got long range
var/obj/item/device/gps/cumulative = new(src)
cumulative.tracking = FALSE
cumulative.local_mode = TRUE // Won't detect long-range signals automatically
cumulative.long_range = FALSE
var/list/toggled_gps = list() // List of GPS units that are turned off before display_list() is called
for(var/obj/item/device/gps/G in internal_devices)
var/gpsdata[0]
if(G.tracking && !G.emped)
cumulative.tracking = TRUE // Turn it on
if(G.long_range)
cumulative.long_range = TRUE // It can detect long-range
if(!G.local_mode)
cumulative.local_mode = FALSE // It is detecting long-range
gpsdata["ref"] = "\ref[G]"
gpsdata["tag"] = G.gps_tag
gpsdata["power"] = G.tracking
gpsdata["local_mode"] = G.local_mode
gpsdata["long_range"] = G.long_range
gpsdata["hide_signal"] = G.hide_signal
gpsdata["can_hide"] = G.can_hide_signal
intgps[++intgps.len] = gpsdata // Add it to the list
if(G.tracking)
G.tracking = FALSE // Disable the internal gps units so they don't show up in the report
toggled_gps += G
var/list/remote_gps = cumulative.display_list() // Fetch information for all units except the ones inside of this device
for(var/obj/item/device/gps/G in toggled_gps) // Reenable any internal GPS units
G.tracking = TRUE
stagps["enabled"] = cumulative.tracking
stagps["long_range_en"] = (cumulative.long_range && !cumulative.local_mode)
stagps["my_area_name"] = remote_gps["my_area_name"]
stagps["curr_x"] = remote_gps["curr_x"]
stagps["curr_y"] = remote_gps["curr_y"]
stagps["curr_z"] = remote_gps["curr_z"]
stagps["curr_z_name"] = remote_gps["curr_z_name"]
extgps = remote_gps["gps_list"] // Compiled by the GPS
qdel(cumulative) // Don't want spare GPS units building up in the contents
return list(
intgps,
extgps,
stagps
)
// Collects the current status of the supply shuttle
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
// code\game\machinery\computer\supply.dm, starting at line 55
/obj/item/weapon/commcard/proc/get_supply_shuttle_status()
var/shuttle_status[0]
var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle
if(shuttle)
if(shuttle.has_arrive_time())
shuttle_status["location"] = "In transit"
shuttle_status["mode"] = SUP_SHUTTLE_TRANSIT
shuttle_status["time"] = shuttle.eta_minutes()
else
shuttle_status["time"] = 0
if(shuttle.at_station())
if(shuttle.shuttle_docking_controller)
switch(shuttle.shuttle_docking_controller.get_docking_status())
if("docked")
shuttle_status["location"] = "Docked"
shuttle_status["mode"] = SUP_SHUTTLE_DOCKED
if("undocked")
shuttle_status["location"] = "Undocked"
shuttle_status["mode"] = SUP_SHUTTLE_UNDOCKED
if("docking")
shuttle_status["location"] = "Docking"
shuttle_status["mode"] = SUP_SHUTTLE_DOCKING
shuttle_status["force"] = shuttle.can_force()
if("undocking")
shuttle_status["location"] = "Undocking"
shuttle_status["mode"] = SUP_SHUTTLE_UNDOCKING
shuttle_status["force"] = shuttle.can_force()
else
shuttle_status["location"] = "Station"
shuttle_status["mode"] = SUP_SHUTTLE_DOCKED
else
shuttle_status["location"] = "Away"
shuttle_status["mode"] = SUP_SHUTTLE_AWAY
if(shuttle.can_launch())
shuttle_status["launch"] = 1
else if(shuttle.can_cancel())
shuttle_status["launch"] = 2
else
shuttle_status["launch"] = 0
switch(shuttle.moving_status)
if(SHUTTLE_IDLE)
shuttle_status["engine"] = "Idle"
if(SHUTTLE_WARMUP)
shuttle_status["engine"] = "Warming up"
if(SHUTTLE_INTRANSIT)
shuttle_status["engine"] = "Engaged"
else
shuttle["mode"] = SUP_SHUTTLE_ERROR
return shuttle_status
// Compiles the list of supply orders
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
// code\game\machinery\computer\supply.dm, starting at line 130
/obj/item/weapon/commcard/proc/get_supply_orders()
var/orders[0]
for(var/datum/supply_order/S in SSsupply.order_history)
orders[++orders.len] = list(
"ref" = "\ref[S]",
"status" = S.status,
"entries" = list(
list("field" = "Supply Pack", "entry" = S.name),
list("field" = "Cost", "entry" = S.cost),
list("field" = "Index", "entry" = S.index),
list("field" = "Reason", "entry" = S.comment),
list("field" = "Ordered by", "entry" = S.ordered_by),
list("field" = "Ordered at", "entry" = S.ordered_at),
list("field" = "Approved by", "entry" = S.approved_by),
list("field" = "Approved at", "entry" = S.approved_at)
)
)
return orders
// Compiles the list of supply export receipts
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
// code\game\machinery\computer\supply.dm, starting at line 147
/obj/item/weapon/commcard/proc/get_supply_receipts()
var/receipts[0]
for(var/datum/exported_crate/E in SSsupply.exported_crates)
receipts[++receipts.len] = list(
"ref" = "\ref[E]",
"contents" = E.contents,
"error" = E.contents["error"],
"title" = list(
list("field" = "Name", "entry" = E.name),
list("field" = "Value", "entry" = E.value)
)
)
return receipts
// Compiles the list of supply packs for the category currently stored in internal_data["supply_category"]
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
// code\game\machinery\computer\supply.dm, starting at line 147
/obj/item/weapon/commcard/proc/get_supply_pack_list()
var/supply_packs[0]
for(var/pack_name in SSsupply.supply_pack)
var/datum/supply_pack/P = SSsupply.supply_pack[pack_name]
if(P.group == internal_data["supply_category"])
var/list/pack = list(
"name" = P.name,
"cost" = P.cost,
"contraband" = P.contraband,
"manifest" = uniquelist(P.manifest),
"random" = P.num_contained,
"expand" = 0,
"ref" = "\ref[P]"
)
if(P in internal_data["supply_pack_expanded"])
pack["expand"] = 1
supply_packs[++supply_packs.len] = pack
return supply_packs
// Compiles miscellaneous data and permissions used by the supply template
/obj/item/weapon/commcard/proc/get_misc_supply_data()
return list(
"shuttle_auth" = (internal_data["supply_controls"] & SUP_SEND_SHUTTLE),
"order_auth" = (internal_data["supply_controls"] & SUP_ACCEPT_ORDERS),
"supply_points" = SSsupply.points,
"supply_categories" = all_supply_groups
)
/obj/item/weapon/commcard/proc/get_status_display()
return list(
"line1" = internal_data["stat_display_line1"],
"line2" = internal_data["stat_display_line2"],
"active_line1" = internal_data["stat_display_active1"],
"active_line2" = internal_data["stat_display_active2"],
"active" = internal_data["stat_display_special"]
)
/obj/item/weapon/commcard/proc/find_blast_doors()
var/target_doors[0]
for(var/obj/machinery/door/blast/B in machines)
if(B.id == internal_data["shuttle_door_code"])
target_doors += B
return target_doors
@@ -239,6 +239,8 @@
desc = "A pen-sized light, used by medical staff."
icon_state = "penlight"
item_state = "pen"
drop_sound = 'sound/items/drop/accessory.ogg'
pickup_sound = 'sound/items/pickup/accessory.ogg'
slot_flags = SLOT_EARS
brightness_on = 2
w_class = ITEMSIZE_TINY
@@ -330,6 +332,8 @@
var/on_damage = 7
var/produce_heat = 1500
power_use = 0
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
/obj/item/device/flashlight/flare/New()
fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds.
+1 -1
View File
@@ -30,7 +30,7 @@
else
..()
/obj/item/device/multitool/hacktool/resolve_attackby(atom/A, mob/user)
/obj/item/device/multitool/hacktool/afterattack(atom/A, mob/user)
sanity_check()
if(!in_hack_mode)
+3 -1
View File
@@ -7,13 +7,15 @@
/obj/item/device/multitool
name = "multitool"
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
description_info = "You can use this on airlocks or APCs to try to hack them without cutting wires."
icon_state = "multitool"
force = 5.0
w_class = ITEMSIZE_SMALL
throwforce = 5.0
throw_range = 15
throw_speed = 3
desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
drop_sound = 'sound/items/drop/multitool.ogg'
pickup_sound = 'sound/items/pickup/multitool.ogg'
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20)
@@ -66,7 +66,7 @@
channels = list("Command" = 1)
/obj/item/device/encryptionkey/heads/captain
name = "colony director's encryption key"
name = "site manager's encryption key"
icon_state = "cap_cypherkey"
channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1)
@@ -16,6 +16,9 @@
var/obj/item/device/encryptionkey/keyslot2 = null
var/ks1type = null
var/ks2type = null
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
/obj/item/device/radio/headset/New()
..()
@@ -170,13 +173,13 @@
/obj/item/device/radio/headset/heads/captain
name = "colony director's headset"
name = "site manager's headset"
desc = "The headset of the boss."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/heads/captain/alt
name = "colony director's bowman headset"
name = "site manager's bowman headset"
desc = "The headset of the boss."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/captain
@@ -252,13 +255,13 @@
/obj/item/device/radio/headset/heads/hop
name = "head of personnel's headset"
desc = "The headset of the guy who will one day be Colony Director."
desc = "The headset of the guy who will one day be Site Manager."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/hop
/obj/item/device/radio/headset/heads/hop/alt
name = "head of personnel's bowman headset"
desc = "The headset of the guy who will one day be Colony Director."
desc = "The headset of the guy who will one day be Site Manager."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/hop
+2
View File
@@ -14,6 +14,8 @@
flags = NOBLUDGEON
var/list/accept_mobs = list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse, /mob/living/simple_mob/animal/sif/leech, /mob/living/simple_mob/animal/sif/frostfly, /mob/living/simple_mob/animal/sif/glitterfly)
var/contains = 0 // 0 = nothing, 1 = money, 2 = animal, 3 = spiderling
drop_sound = 'sound/items/drop/glass.ogg'
pickup_sound = 'sound/items/pickup/glass.ogg'
/obj/item/glass_jar/New()
..()
+5 -1
View File
@@ -10,7 +10,8 @@
var/heal_brute = 0
var/heal_burn = 0
var/apply_sounds
drop_sound = 'sound/items/drop/box.ogg'
drop_sound = 'sound/items/drop/cardboardbox.ogg'
pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
var/upgrade_to // The type path this stack can be upgraded to.
@@ -155,6 +156,7 @@
no_variants = FALSE
apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg')
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
upgrade_to = /obj/item/stack/medical/advanced/bruise_pack
@@ -230,6 +232,7 @@
no_variants = FALSE
apply_sounds = list('sound/effects/ointment.ogg')
drop_sound = 'sound/items/drop/herb.ogg'
pickup_sound = 'sound/items/pickup/herb.ogg'
/obj/item/stack/medical/ointment/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
@@ -377,6 +380,7 @@
amount = 5
max_amount = 5
drop_sound = 'sound/items/drop/hat.ogg'
pickup_sound = 'sound/items/pickup/hat.ogg'
var/list/splintable_organs = list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO) //List of organs you can splint, natch.
+2
View File
@@ -8,6 +8,8 @@
throwforce = 15.0
throw_speed = 5
throw_range = 20
drop_sound = 'sound/items/drop/metalweapon.ogg'
pickup_sound = 'sound/items/pickup/metalweapon.ogg'
matter = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 2)
max_amount = 60
attack_verb = list("hit", "bludgeoned", "whacked")
@@ -17,6 +17,7 @@
var/is_reinforced = 0
default_type = "glass"
drop_sound = 'sound/items/drop/glass.ogg'
pickup_sound = 'sound/items/pickup/glass.ogg'
/obj/item/stack/material/glass/attack_self(mob/user as mob)
construct_window(user)
@@ -4,7 +4,8 @@
singular_name = "human skin piece"
icon_state = "sheet-hide"
no_variants = FALSE
drop_sound = 'sound/items/drop/clothing.ogg'
drop_sound = 'sound/items/drop/leather.ogg'
pickup_sound = 'sound/items/pickup/leather.ogg'
/obj/item/stack/animalhide/human
amount = 50
+1 -1
View File
@@ -169,7 +169,7 @@
if ((pass_color || recipe.pass_color))
if(!color)
if(recipe.use_material)
var/material/MAT = get_material_by_name(recipe.use_material)
var/datum/material/MAT = get_material_by_name(recipe.use_material)
if(MAT.icon_colour)
O.color = MAT.icon_colour
else
@@ -18,6 +18,7 @@
w_class = ITEMSIZE_NORMAL
max_amount = 60
drop_sound = 'sound/items/drop/axe.ogg'
pickup_sound = 'sound/items/pickup/axe.ogg'
/obj/item/stack/tile/New()
..()
@@ -39,6 +40,7 @@
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
drop_sound = 'sound/items/drop/herb.ogg'
pickup_sound = 'sound/items/pickup/herb.ogg'
/*
* Wood
*/
@@ -54,6 +56,7 @@
flags = 0
no_variants = FALSE
drop_sound = 'sound/items/drop/wooden.ogg'
pickup_sound = 'sound/items/pickup/wooden.ogg'
/obj/item/stack/tile/wood/sif
name = "alien wood tile"
@@ -83,7 +86,8 @@
throw_range = 20
flags = 0
no_variants = FALSE
drop_sound = 'sound/items/drop/clothing.ogg'
drop_sound = 'sound/items/drop/cloth.ogg'
pickup_sound = 'sound/items/pickup/cloth.ogg'
/obj/item/stack/tile/carpet/teal
name = "teal carpet"
+643
View File
@@ -0,0 +1,643 @@
/*
* Mech toys (previously labeled prizes, but that's unintuitive)
* Mech toy combat
*/
// Mech battle special attack types.
#define SPECIAL_ATTACK_HEAL 1
#define SPECIAL_ATTACK_DAMAGE 2
#define SPECIAL_ATTACK_UTILITY 3
#define SPECIAL_ATTACK_OTHER 4
// Max length of a mech battle
#define MAX_BATTLE_LENGTH 50
/obj/item/toy/mecha
icon = 'icons/obj/toy.dmi'
icon_state = "ripleytoy"
drop_sound = 'sound/mecha/mechstep.ogg'
description_info = "To engage in mech battles, hold this mech while clicking on another toy mech, or a player who is also holding a toy mech. You must be within 2 tiles (This allows you to battle across a table). Battles are entirely randomized, and mechs with higher health and special abilities have a better chance of winning."
reach = 2 // So you can battle across the table!
// Mech Battle Vars
var/timer = 0 // Timer when it'll be off cooldown
var/cooldown = 1.5 SECONDS // Cooldown between play sessions (and interactions)
var/cooldown_multiplier = 20 // Cooldown multiplier after a battle (by default: battle cooldowns are 30 seconds)
var/quiet = FALSE // If it makes noise when played with
var/wants_to_battle = FALSE // TRUE = Offering battle to someone || FALSE = Not offering battle
var/in_combat = FALSE // TRUE = in combat currently || FALSE = Not in combat
var/combat_health = 0 // The mech's health in battle
var/max_combat_health = 0 // The mech's max combat health
var/special_attack_charged = FALSE // TRUE = the special attack is charged || FALSE = not charged
var/special_attack_type = 0 // What type of special attack they use - SPECIAL_ATTACK_DAMAGE, SPECIAL_ATTACK_HEAL, SPECIAL_ATTACK_UTILITY, SPECIAL_ATTACK_OTHER
var/special_attack_type_message = "" // What message their special move gets on examining
var/special_attack_cry = "*flip" // The battlecry when using the special attack
var/special_attack_cooldown = 0 // Current cooldown of their special attack
var/wins = 0 // This mech's win count in combat
var/losses = 0 // ...And their loss count in combat
/obj/item/toy/mecha/Initialize()
. = ..()
desc = "Mini-Mecha action figure! Collect them all! Attack your friends or another mech with one to initiate epic mech combat! [desc]."
combat_health = max_combat_health
switch(special_attack_type)
if(SPECIAL_ATTACK_DAMAGE)
special_attack_type_message = "an aggressive move, which deals bonus damage."
if(SPECIAL_ATTACK_HEAL)
special_attack_type_message = "a defensive move, which grants bonus healing."
if(SPECIAL_ATTACK_UTILITY)
special_attack_type_message = "a utility move, which heals the user and damages the opponent."
if(SPECIAL_ATTACK_OTHER)
special_attack_type_message = "a special move, which [special_attack_type_message]"
else
special_attack_type_message = "a mystery move, even I don't know."
/obj/item/toy/mecha/proc/in_range(source, user) // Modify our in_range proc specifically for mech battles!
if(get_dist(source, user) <= 2)
return 1
return 0 //not in range and not telekinetic
/**
* this proc combines "sleep" while also checking for if the battle should continue
*
* this goes through some of the checks - the toys need to be next to each other to fight!
* if it's player vs themself: They need to be able to "control" both mechs (either must be adjacent or using TK).
* if it's player vs player: Both players need to be able to "control" their mechs (either must be adjacent or using TK).
* if it's player vs mech (suicide): the mech needs to be in range of the player.
* if all the checks are TRUE, it does the sleeps, and returns TRUE. Otherwise, it returns FALSE.
* Arguments:
* * delay - the amount of time the sleep at the end of the check will sleep for
* * attacker - the attacking toy in the battle.
* * attacker_controller - the controller of the attacking toy. there should ALWAYS be an attacker_controller
* * opponent - (optional) the defender controller in the battle, for PvP
*/
/obj/item/toy/mecha/proc/combat_sleep(var/delay, obj/item/toy/mecha/attacker, mob/living/carbon/attacker_controller, mob/living/carbon/opponent)
if(!attacker_controller) // If the attacker for whatever reason is null, don't continue.
return FALSE
if(!attacker) // If there's no attacker, then attacker_controller IS the attacker.
if(!in_range(src, attacker_controller))
attacker_controller.visible_message("<span class='suicide'>[attacker_controller] is running from [src]! The coward!</span>")
return FALSE
else // If there's an attacker, we can procede as normal.
if(!in_range(src, attacker)) // The two toys aren't next to each other, the battle ends.
attacker_controller.visible_message("<span class='notice'> [attacker] and [src] separate, ending the battle. </span>", \
"<span class='notice'> [attacker] and [src] separate, ending the battle. </span>")
return FALSE
// Dead men tell no tales, incapacitated men fight no fights.
if(attacker_controller.incapacitated())
return FALSE
// If the attacker_controller isn't next to the attacking toy (and doesn't have telekinesis), the battle ends.
if(!in_range(attacker, attacker_controller))
attacker_controller.visible_message("<span class='notice'> [attacker_controller.name] seperates from [attacker], ending the battle.</span>", \
"<span class='notice'> You separate from [attacker], ending the battle. </span>")
return FALSE
// If it's PVP and the opponent is not next to the defending(src) toy (and doesn't have telekinesis), the battle ends.
if(opponent)
if(opponent.incapacitated())
return FALSE
if(!in_range(src, opponent))
opponent.visible_message("<span class='notice'> [opponent.name] seperates from [src], ending the battle.</span>", \
"<span class='notice'> You separate from [src], ending the battle. </span>")
return FALSE
// If it's not PVP and the attacker_controller isn't next to the defending toy (and doesn't have telekinesis), the battle ends.
else
if (!in_range(src, attacker_controller))
attacker_controller.visible_message("<span class='notice'> [attacker_controller.name] seperates from [src] and [attacker], ending the battle.</span>", \
"<span class='notice'> You separate [attacker] and [src], ending the battle. </span>")
return FALSE
// If all that is good, then we can sleep peacefully.
sleep(delay)
return TRUE
//all credit to skasi for toy mech fun ideas
/obj/item/toy/mecha/attack_self(mob/user)
if(timer < world.time)
to_chat(user, "<span class='notice'>You play with [src].</span>")
timer = world.time + cooldown
playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE)
else
. = ..()
/obj/item/toy/mecha/attack_hand(mob/user)
. = ..()
if(.)
return
if(loc == user)
attack_self(user)
/**
* If you attack a mech with a mech, initiate combat between them
*/
/obj/item/toy/mecha/attackby(obj/item/user_toy, mob/living/user)
if(istype(user_toy, /obj/item/toy/mecha))
var/obj/item/toy/mecha/M = user_toy
if(check_battle_start(user, M))
mecha_brawl(M, user)
..()
/**
* Attack is called from the user's toy, aimed at target(another human), checking for target's toy.
*/
/obj/item/toy/mecha/attack(mob/living/carbon/human/target, mob/living/carbon/human/user)
if(target == user)
to_chat(user, "<span class='notice'>Target another toy mech if you want to start a battle with yourself.</span>")
return
else if(user.a_intent != I_HURT)
if(wants_to_battle) //prevent spamming someone with offers
to_chat(user, "<span class='notice'>You already are offering battle to someone!</span>")
return
if(!check_battle_start(user)) //if the user's mech isn't ready, don't bother checking
return
for(var/obj/item/I in target.get_all_held_items())
if(istype(I, /obj/item/toy/mecha)) //if you attack someone with a mech who's also holding a mech, offer to battle them
var/obj/item/toy/mecha/M = I
if(!M.check_battle_start(target, null, user)) //check if the attacker mech is ready
break
//slap them with the metaphorical white glove
if(M.wants_to_battle) //if the target mech wants to battle, initiate the battle from their POV
mecha_brawl(M, target, user) //P = defender's mech / SRC = attacker's mech / target = defender / user = attacker
M.wants_to_battle = FALSE
return
//extend the offer of battle to the other mech
var/datum/gender/T = gender_datums[user.get_visible_gender()]
to_chat(user, "<span class='notice'>You offer battle to [target.name]!</span>")
to_chat(target, "<span class='notice'><b>[user.name] wants to battle with [T.His] [name]!</b> <i>Attack them with a toy mech to initiate combat.</i></span>")
wants_to_battle = TRUE
addtimer(CALLBACK(src, .proc/withdraw_offer, user), 6 SECONDS)
return
..()
/**
* Overrides attack_tk - Sorry, you have to be face to face to initiate a battle, it's good sportsmanship
*/
/obj/item/toy/mecha/attack_tk(mob/user)
if(timer < world.time)
to_chat(user, "<span class='notice'>You telekinetically play with [src].</span>")
timer = world.time + cooldown
playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE)
/**
* Resets the request for battle.
*
* For use in a timer, this proc resets the wants_to_battle variable after a short period.
* Arguments:
* * user - the user wanting to do battle
*/
/obj/item/toy/mecha/proc/withdraw_offer(mob/living/carbon/user)
if(wants_to_battle)
wants_to_battle = FALSE
to_chat(user, "<span class='notice'>You get the feeling they don't want to battle.</span>")
/**
* Starts a battle, toy mech vs player. Player... doesn't win. Commented out for now as suicide_act is not physically doable.
*/
/obj/item/toy/mecha/suicide_act(mob/living/carbon/user)
if(in_combat)
to_chat(user, "<span class='notice'>[src] is in battle, let it finish first.</span>")
return
var/datum/gender/T = gender_datums[user.get_visible_gender()]
user.visible_message("<span class='suicide'>[user] begins a fight [T.His] can't win with [src]! It looks like [T.His] trying to commit suicide!</span>")
in_combat = TRUE
sleep(1.5 SECONDS)
for(var/i in 1 to 4)
switch(i)
if(1, 3)
SpinAnimation(5, 0)
playsound(src, 'sound/mecha/mechstep.ogg', 30, TRUE)
user.adjustBruteLoss(25)
if(2)
user.SpinAnimation(5, 0)
playsound(user, 'sound/weapons/smash.ogg', 20, TRUE)
combat_health-- //we scratched it!
if(4)
visible_message(special_attack_cry + "!!")
if(!combat_sleep(1 SECONDS, null, user))
visible_message("PATHETIC.")
combat_health = max_combat_health
in_combat = FALSE
return (BRUTELOSS)
sleep(0.5 SECONDS)
user.adjustBruteLoss(450)
in_combat = FALSE
visible_message("AN EASY WIN. MY POWER INCREASES.") // steal a soul, become swole
color= "#ff7373"
max_combat_health = round(max_combat_health*1.5 + 0.1)
combat_health = max_combat_health
wins++
return (BRUTELOSS)
/obj/item/toy/mecha/examine()
. = ..()
. += "<span class='notice'>This toy's special attack is [special_attack_cry], [special_attack_type_message] </span>"
if(in_combat)
. += "<span class='notice'>This toy has a maximum health of [max_combat_health]. Currently, it's [combat_health].</span>"
. += "<span class='notice'>Its special move light is [special_attack_cooldown? "flashing red." : "green and is ready!"]</span>"
else
. += "<span class='notice'>This toy has a maximum health of [max_combat_health].</span>"
if(wins || losses)
. += "<span class='notice'>This toy has [wins] wins, and [losses] losses.</span>"
/**
* The 'master' proc of the mech battle. Processes the entire battle's events and makes sure it start and finishes correctly.
*
* src is the defending toy, and the battle proc is called on it to begin the battle.
* After going through a few checks at the beginning to ensure the battle can start properly, the battle begins a loop that lasts
* until either toy has no more health. During this loop, it also ensures the mechs stay in combat range of each other.
* It will then randomly decide attacks for each toy, occasionally making one or the other use their special attack.
* When either mech has no more health, the loop ends, and it displays the victor and the loser while updating their stats and resetting them.
* Arguments:
* * attacker - the attacking toy, the toy in the attacker_controller's hands
* * attacker_controller - the user, the one who is holding the toys / controlling the fight
* * opponent - optional arg used in Mech PvP battles: the other person who is taking part in the fight (controls src)
*/
/obj/item/toy/mecha/proc/mecha_brawl(obj/item/toy/mecha/attacker, mob/living/carbon/attacker_controller, mob/living/carbon/opponent)
//A GOOD DAY FOR A SWELL BATTLE!
attacker_controller.visible_message("<span class='danger'> [attacker_controller.name] collides [attacker] with [src]! Looks like they're preparing for a brawl! </span>", \
"<span class='danger'> You collide [attacker] into [src], sparking a fierce battle! </span>", \
"<span class='hear'> You hear hard plastic smacking into hard plastic.</span>")
/// Who's in control of the defender (src)?
var/mob/living/carbon/src_controller = (opponent)? opponent : attacker_controller
/// How long has the battle been going?
var/battle_length = 0
in_combat = TRUE
attacker.in_combat = TRUE
//1.5 second cooldown * 20 = 30 second cooldown after a fight
timer = world.time + cooldown*cooldown_multiplier
attacker.timer = world.time + attacker.cooldown*attacker.cooldown_multiplier
sleep(1 SECONDS)
//--THE BATTLE BEGINS--
while(combat_health > 0 && attacker.combat_health > 0 && battle_length < MAX_BATTLE_LENGTH)
if(!combat_sleep(0.5 SECONDS, attacker, attacker_controller, opponent)) //combat_sleep checks everything we need to have checked for combat to continue
break
//before we do anything - deal with charged attacks
if(special_attack_charged)
src_controller.visible_message("<span class='danger'> [src] unleashes its special attack!! </span>", \
"<span class='danger'> You unleash [src]'s special attack! </span>")
special_attack_move(attacker)
else if(attacker.special_attack_charged)
attacker_controller.visible_message("<span class='danger'> [attacker] unleashes its special attack!! </span>", \
"<span class='danger'> You unleash [attacker]'s special attack! </span>")
attacker.special_attack_move(src)
else
//process the cooldowns
if(special_attack_cooldown > 0)
special_attack_cooldown--
if(attacker.special_attack_cooldown > 0)
attacker.special_attack_cooldown--
//combat commences
switch(rand(1,8))
if(1 to 3) //attacker wins
if(attacker.special_attack_cooldown == 0 && attacker.combat_health <= round(attacker.max_combat_health/3)) //if health is less than 1/3 and special off CD, use it
attacker.special_attack_charged = TRUE
attacker_controller.visible_message("<span class='danger'> [attacker] begins charging its special attack!! </span>", \
"<span class='danger'> You begin charging [attacker]'s special attack! </span>")
else //just attack
attacker.SpinAnimation(5, 0)
playsound(attacker, 'sound/mecha/mechstep.ogg', 30, TRUE)
combat_health--
attacker_controller.visible_message("<span class='danger'> [attacker] devastates [src]! </span>", \
"<span class='danger'> You ram [attacker] into [src]! </span>", \
"<span class='hear'> You hear hard plastic smacking hard plastic.</span>")
if(prob(5))
combat_health--
playsound(src, 'sound/effects/meteorimpact.ogg', 20, TRUE)
attacker_controller.visible_message("<span class='boldwarning'> ...and lands a CRIPPLING BLOW! </span>", \
"<span class='boldwarning'> ...and you land a CRIPPLING blow on [src]! </span>", null)
if(4) //both lose
attacker.SpinAnimation(5, 0)
SpinAnimation(5, 0)
combat_health--
attacker.combat_health--
// This is sloppy but we don't have do_sparks.
var/datum/effect/effect/system/spark_spread/sparksrc = new(src)
playsound(src, "sparks", 50, 1)
sparksrc.set_up(2, 0, src)
sparksrc.attach(src)
sparksrc.start()
var/datum/effect/effect/system/spark_spread/sparkatk = new(attacker)
playsound(attacker, "sparks", 50, 1)
sparkatk.set_up(2, 0, attacker)
sparkatk.attach(attacker)
sparkatk.start()
if(prob(50))
attacker_controller.visible_message("<span class='danger'> [attacker] and [src] clash dramatically, causing sparks to fly! </span>", \
"<span class='danger'> [attacker] and [src] clash dramatically, causing sparks to fly! </span>", \
"<span class='hear'> You hear hard plastic rubbing against hard plastic.</span>")
else
src_controller.visible_message("<span class='danger'> [src] and [attacker] clash dramatically, causing sparks to fly! </span>", \
"<span class='danger'> [src] and [attacker] clash dramatically, causing sparks to fly! </span>", \
"<span class='hear'> You hear hard plastic rubbing against hard plastic.</span>")
if(5) //both win
playsound(attacker, 'sound/weapons/parry.ogg', 20, TRUE)
if(prob(50))
attacker_controller.visible_message("<span class='danger'> [src]'s attack deflects off of [attacker]. </span>", \
"<span class='danger'> [src]'s attack deflects off of [attacker]. </span>", \
"<span class='hear'> You hear hard plastic bouncing off hard plastic.</span>")
else
src_controller.visible_message("<span class='danger'> [attacker]'s attack deflects off of [src]. </span>", \
"<span class='danger'> [attacker]'s attack deflects off of [src]. </span>", \
"<span class='hear'> You hear hard plastic bouncing off hard plastic.</span>")
if(6 to 8) //defender wins
if(special_attack_cooldown == 0 && combat_health <= round(max_combat_health/3)) //if health is less than 1/3 and special off CD, use it
special_attack_charged = TRUE
src_controller.visible_message("<span class='danger'> [src] begins charging its special attack!! </span>", \
"<span class='danger'> You begin charging [src]'s special attack! </span>")
else //just attack
SpinAnimation(5, 0)
playsound(src, 'sound/mecha/mechstep.ogg', 30, TRUE)
attacker.combat_health--
src_controller.visible_message("<span class='danger'> [src] smashes [attacker]! </span>", \
"<span class='danger'> You smash [src] into [attacker]! </span>", \
"<span class='hear'> You hear hard plastic smashing hard plastic.</span>")
if(prob(5))
attacker.combat_health--
playsound(attacker, 'sound/effects/meteorimpact.ogg', 20, TRUE)
src_controller.visible_message("<span class='boldwarning'> ...and lands a CRIPPLING BLOW! </span>", \
"<span class='boldwarning'> ...and you land a CRIPPLING blow on [attacker]! </span>", null)
else
attacker_controller.visible_message("<span class='notice'> [src] and [attacker] stand around awkwardly.</span>", \
"<span class='notice'> You don't know what to do next.</span>")
battle_length++
sleep(0.5 SECONDS)
/// Lines chosen for the winning mech
var/list/winlines = list("YOU'RE NOTHING BUT SCRAP!", "I'LL YIELD TO NONE!", "GLORY IS MINE!", "AN EASY FIGHT.", "YOU SHOULD HAVE NEVER FACED ME.", "ROCKED AND SOCKED.")
if(attacker.combat_health <= 0 && combat_health <= 0) //both lose
playsound(src, 'sound/machines/warning-buzzer.ogg', 20, TRUE)
attacker_controller.visible_message("<span class='boldnotice'> MUTUALLY ASSURED DESTRUCTION!! [src] and [attacker] both end up destroyed!</span>", \
"<span class='boldnotice'> Both [src] and [attacker] are destroyed!</span>")
else if(attacker.combat_health <= 0) //src wins
wins++
attacker.losses++
playsound(attacker, 'sound/effects/light_flicker.ogg', 20, TRUE)
attacker_controller.visible_message("<span class='notice'> [attacker] falls apart!</span>", \
"<span class='notice'> [attacker] falls apart!</span>", null)
visible_message("[pick(winlines)]")
src_controller.visible_message("<span class='notice'> [src] destroys [attacker] and walks away victorious!</span>", \
"<span class='notice'> You raise up [src] victoriously over [attacker]!</span>")
else if (combat_health <= 0) //attacker wins
attacker.wins++
losses++
playsound(src, 'sound/effects/light_flicker.ogg', 20, TRUE)
src_controller.visible_message("<span class='notice'> [src] collapses!</span>", \
"<span class='notice'> [src] collapses!</span>", null)
attacker.visible_message("[pick(winlines)]")
attacker_controller.visible_message("<span class='notice'> [attacker] demolishes [src] and walks away victorious!</span>", \
"<span class='notice'> You raise up [attacker] proudly over [src]</span>!")
else //both win?
visible_message("NEXT TIME.")
//don't want to make this a one sided conversation
quiet? attacker.visible_message("I WENT EASY ON YOU.") : attacker.visible_message("OF COURSE.")
in_combat = FALSE
attacker.in_combat = FALSE
combat_health = max_combat_health
attacker.combat_health = attacker.max_combat_health
return
/**
* This proc checks if a battle can be initiated between src and attacker.
*
* Both SRC and attacker (if attacker is included) timers are checked if they're on cooldown, and
* both SRC and attacker (if attacker is included) are checked if they are in combat already.
* If any of the above are true, the proc returns FALSE and sends a message to user (and target, if included) otherwise, it returns TRUE
* Arguments:
* * user: the user who is initiating the battle
* * attacker: optional arg for checking two mechs at once
* * target: optional arg used in Mech PvP battles (if used, attacker is target's toy)
*/
/obj/item/toy/mecha/proc/check_battle_start(mob/living/carbon/user, obj/item/toy/mecha/attacker, mob/living/carbon/target)
var/datum/gender/T
if(target)
T = gender_datums[target.get_visible_gender()] // Doing this because Polaris Code has shitty gender datums and it's clunkier than FUCK.
if(attacker && attacker.in_combat)
to_chat(user, "<span class='notice'>[target ? T.His : "Your" ] [attacker.name] is in combat.</span>")
if(target)
to_chat(target, "<span class='notice'>Your [attacker.name] is in combat.</span>")
return FALSE
if(in_combat)
to_chat(user, "<span class='notice'>Your [name] is in combat.</span>")
if(target)
to_chat(target, "<span class='notice'>[T.His] [name] is in combat.</span>")
return FALSE
if(attacker && attacker.timer > world.time)
to_chat(user, "<span class='notice'>[target?T.His : "Your" ] [attacker.name] isn't ready for battle.</span>")
if(target)
to_chat(target, "<span class='notice'>Your [attacker.name] isn't ready for battle.</span>")
return FALSE
if(timer > world.time)
to_chat(user, "<span class='notice'>Your [name] isn't ready for battle.</span>")
if(target)
to_chat(target, "<span class='notice'>[T.His] [name] isn't ready for battle.</span>")
return FALSE
return TRUE
/**
* Processes any special attack moves that happen in the battle (called in the mechaBattle proc).
*
* Makes the toy shout their special attack cry and updates its cooldown. Then, does the special attack.
* Arguments:
* * victim - the toy being hit by the special move
*/
/obj/item/toy/mecha/proc/special_attack_move(obj/item/toy/mecha/victim)
visible_message(special_attack_cry + "!!")
special_attack_charged = FALSE
special_attack_cooldown = 3
switch(special_attack_type)
if(SPECIAL_ATTACK_DAMAGE) //+2 damage
victim.combat_health-=2
playsound(src, 'sound/weapons/marauder.ogg', 20, TRUE)
if(SPECIAL_ATTACK_HEAL) //+2 healing
combat_health+=2
playsound(src, 'sound/mecha/mech_shield_raise.ogg', 20, TRUE)
if(SPECIAL_ATTACK_UTILITY) //+1 heal, +1 damage
victim.combat_health--
combat_health++
playsound(src, 'sound/mecha/mechmove01.ogg', 30, TRUE)
if(SPECIAL_ATTACK_OTHER) //other
super_special_attack(victim)
else
visible_message("I FORGOT MY SPECIAL ATTACK...")
/**
* Base proc for 'other' special attack moves.
*
* This one is only for inheritance, each mech with an 'other' type move has their procs below.
* Arguments:
* * victim - the toy being hit by the super special move (doesn't necessarily need to be used)
*/
/obj/item/toy/mecha/proc/super_special_attack(obj/item/toy/mecha/victim)
visible_message("<span class='notice'> [src] does a cool flip.</span>")
/obj/random/mech_toy
name = "Random Mech Toy"
desc = "This is a random mech toy."
icon = 'icons/obj/toy.dmi'
icon_state = "ripleytoy"
/obj/random/mech_toy/item_to_spawn()
return pick(typesof(/obj/item/toy/mecha))
/obj/item/toy/mecha/ripley
name = "toy ripley"
desc = "Mini-Mecha action figure! Collect them all! 1/11."
max_combat_health = 4 // 200 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "GIGA DRILL BREAK"
/obj/item/toy/mecha/fireripley
name = "toy firefighting ripley"
desc = "Mini-Mecha action figure! Collect them all! 2/11."
icon_state = "fireripleytoy"
max_combat_health = 5 // 250 integrity?
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "FIRE SHIELD"
/obj/item/toy/mecha/deathripley
name = "toy deathsquad ripley"
desc = "Mini-Mecha action figure! Collect them all! 3/11."
icon_state = "deathripleytoy"
max_combat_health = 5 // 250 integrity
special_attack_type = SPECIAL_ATTACK_OTHER
special_attack_type_message = "instantly destroys the opposing mech if its health is less than this mech's health."
special_attack_cry = "KILLER CLAMP"
/obj/item/toy/mecha/deathripley/super_special_attack(obj/item/toy/mecha/victim)
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 20, TRUE)
if(victim.combat_health < combat_health) // Instantly kills the other mech if it's health is below our's.
visible_message("EXECUTE!!")
victim.combat_health = 0
else // Otherwise, just deal one damage.
victim.combat_health--
/obj/item/toy/mecha/gygax
name = "toy gygax"
desc = "Mini-Mecha action figure! Collect them all! 4/11."
icon_state = "gygaxtoy"
max_combat_health = 5 // 250 integrity
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "SUPER SERVOS"
/obj/item/toy/mecha/durand
name = "toy durand"
desc = "Mini-Mecha action figure! Collect them all! 5/11."
icon_state = "durandtoy"
max_combat_health = 6 // 400 integrity
special_attack_type = SPECIAL_ATTACK_HEAL
special_attack_cry = "SHIELD OF PROTECTION"
/obj/item/toy/mecha/honk
name = "toy H.O.N.K."
desc = "Mini-Mecha action figure! Collect them all! 6/11."
icon_state = "honktoy"
max_combat_health = 4 // 140 integrity
special_attack_type = SPECIAL_ATTACK_OTHER
special_attack_type_message = "puts the opposing mech's special move on cooldown and heals this mech."
special_attack_cry = "MEGA HORN"
/obj/item/toy/mecha/honk/super_special_attack(obj/item/toy/mecha/victim)
playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 20, TRUE)
victim.special_attack_cooldown += 3 // Adds cooldown to the other mech and gives a minor self heal
combat_health++
/obj/item/toy/mecha/marauder
name = "toy marauder"
desc = "Mini-Mecha action figure! Collect them all! 7/11."
icon_state = "maraudertoy"
max_combat_health = 7 // 500 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "BEAM BLAST"
/obj/item/toy/mecha/seraph
name = "toy seraph"
desc = "Mini-Mecha action figure! Collect them all! 8/11."
icon_state = "seraphtoy"
max_combat_health = 8 // 550 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "ROCKET BARRAGE"
/obj/item/toy/mecha/mauler
name = "toy mauler"
desc = "Mini-Mecha action figure! Collect them all! 9/11."
icon_state = "maulertoy"
max_combat_health = 7 // 500 integrity
special_attack_type = SPECIAL_ATTACK_DAMAGE
special_attack_cry = "BULLET STORM"
/obj/item/toy/mecha/odysseus
name = "toy odysseus"
desc = "Mini-Mecha action figure! Collect them all! 10/11."
icon_state = "odysseustoy"
max_combat_health = 4 // 120 integrity
special_attack_type = SPECIAL_ATTACK_HEAL
special_attack_cry = "MECHA BEAM"
/obj/item/toy/mecha/phazon
name = "toy phazon"
desc = "Mini-Mecha action figure! Collect them all! 11/11."
icon_state = "phazontoy"
max_combat_health = 6 // 200 integrity
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "NO-CLIP"
/* // TG-Station Added toys, commenting these out until I port 'em later.
/obj/item/toy/mecha/reticence
name = "toy Reticence"
desc = "12/13"
icon_state = "reticencetoy"
quiet = TRUE
max_combat_health = 4 //100 integrity
special_attack_type = SPECIAL_ATTACK_OTHER
special_attack_type_message = "has a lower cooldown than normal special moves, increases the opponent's cooldown, and deals damage."
special_attack_cry = "*wave"
/obj/item/toy/mecha/reticence/super_special_attack(obj/item/toy/mecha/victim)
special_attack_cooldown-- //Has a lower cooldown...
victim.special_attack_cooldown++ //and increases the opponent's cooldown by 1...
victim.combat_health-- //and some free damage.
/obj/item/toy/mecha/clarke
name = "toy Clarke"
desc = "13/13"
icon_state = "clarketoy"
max_combat_health = 4 //200 integrity
special_attack_type = SPECIAL_ATTACK_UTILITY
special_attack_cry = "ROLL OUT"
*/
#undef SPECIAL_ATTACK_HEAL
#undef SPECIAL_ATTACK_DAMAGE
#undef SPECIAL_ATTACK_UTILITY
#undef SPECIAL_ATTACK_OTHER
#undef MAX_BATTLE_LENGTH
File diff suppressed because it is too large Load Diff
+108 -18
View File
@@ -7,6 +7,7 @@
w_class = ITEMSIZE_SMALL
desc = "This is rubbish."
drop_sound = 'sound/items/drop/wrapper.ogg'
pickup_sound = 'sound/items/pickup/wrapper.ogg'
var/age = 0
/obj/item/trash/New(var/newloc, var/_age)
@@ -14,8 +15,9 @@
if(!isnull(_age))
age = _age
/obj/item/trash/Initialize()
SSpersistence.track_value(src, /datum/persistent/filth/trash)
/obj/item/trash/Initialize(mapload)
if(!mapload || !config.persistence_ignore_mapload)
SSpersistence.track_value(src, /datum/persistent/filth/trash)
. = ..()
/obj/item/trash/Destroy()
@@ -27,40 +29,61 @@
icon_state = "4no_raisins"
/obj/item/trash/candy
name = "candy"
name = "hard candy wrapper"
icon_state = "candy"
/obj/item/trash/candy/gums
name = "gummy candy bag"
icon_state = "candy_gums"
/obj/item/trash/candy/proteinbar
name = "protein bar"
name = "protein bar wrapper"
icon_state = "proteinbar"
/obj/item/trash/candy/fruitbar
name = "fruit bar wrapper"
icon_state = "fruitbar"
/obj/item/trash/cheesie
name = "\improper Cheesie Honkers"
name = "\improper Cheesie Honkers bag"
icon_state = "cheesie_honkers"
/obj/item/trash/chips
name = "chips"
name = "chips bag"
icon_state = "chips"
/obj/item/trash/chips/bbq
name = "bbq chips bag"
icon_state = "chips_bbq"
/obj/item/trash/cookiesnack
name = "\improper Carps Ahoy! miniature cookies packet"
icon_state = "cookiesnack"
/obj/item/trash/popcorn
name = "popcorn"
name = "popcorn bag"
icon_state = "popcorn"
/obj/item/trash/tuna
name = "fish flake packet"
icon_state = "tuna"
/obj/item/trash/sosjerky
name = "Scaredy's Private Reserve Beef Jerky"
name = "Scaredy's Private Reserve Beef Jerky wrapper"
icon_state = "sosjerky"
/obj/item/trash/unajerky
name = "Moghes Imported Sissalik Jerky"
name = "Moghes Imported Sissalik Jerky tin"
icon_state = "unathitinred"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/syndi_cakes
name = "syndi cakes"
name = "syndi cakes box"
icon_state = "syndi_cakes"
/obj/item/trash/waffles
name = "waffles"
name = "waffles tray"
icon_state = "waffles"
/obj/item/trash/plate
@@ -72,13 +95,45 @@
icon_state = "snack_bowl"
/obj/item/trash/pistachios
name = "pistachios pack"
name = "pistachios packet"
icon_state = "pistachios_pack"
/obj/item/trash/semki
name = "semki pack"
name = "semki packet"
icon_state = "semki_pack"
/obj/item/trash/koisbar
name = "candy wrapper"
icon_state = "koisbar"
/obj/item/trash/kokobar
name = "candy wrapper"
icon_state = "kokobar"
/obj/item/trash/skrellsnax
name = "skrellsnax packet"
icon_state = "skrellsnacks"
/obj/item/trash/gumpack
name = "gum packet"
icon_state = "gum_pack"
/obj/item/trash/admints
name = "mint wrapper"
icon_state = "admint_pack"
/obj/item/trash/coffee
name = "empty cup"
icon_state = "coffee_vended"
drop_sound = 'sound/items/drop/papercup.ogg'
pickup_sound = 'sound/items/pickup/papercup.ogg'
/obj/item/trash/ramen
name = "cup ramen"
icon_state = "ramen"
drop_sound = 'sound/items/drop/papercup.ogg'
pickup_sound = 'sound/items/pickup/papercup.ogg'
/obj/item/trash/tray
name = "tray"
icon_state = "tray"
@@ -88,39 +143,74 @@
name = "candle"
icon = 'icons/obj/candle.dmi'
icon_state = "candle4"
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
/obj/item/trash/liquidfood
name = "\improper \"LiquidFood\" ration"
name = "\improper \"LiquidFood\" ration packet"
icon_state = "liquidfood"
/obj/item/trash/liquidprotein
name = "\improper \"LiquidProtein\" ration"
name = "\improper \"LiquidProtein\" ration packet"
icon_state = "liquidprotein"
/obj/item/trash/liquidvitamin
name = "\improper \"VitaPaste\" ration"
name = "\improper \"VitaPaste\" ration packet"
icon_state = "liquidvitamin"
/obj/item/trash/tastybread
name = "bread tube"
name = "bread tube wrapper"
icon_state = "tastybread"
// Aurora Food Port
/obj/item/trash/brownies
name = "brownie tray"
icon_state = "brownies"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/snacktray
name = "snacktray"
icon_state = "snacktray"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/dipbowl
name = "dip bowl"
icon_state = "dipbowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/chipbasket
name = "empty basket"
icon_state = "chipbasket_empty"
icon_state = "chipbasket_empty"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/spitgum
name = "old gum"
desc = "A disgusting chewed up wad of gum."
icon = 'icons/obj/clothing/masks.dmi'
icon_state = "spit-gum"
drop_sound = 'sound/items/drop/flesh.ogg'
pickup_sound = 'sound/items/pickup/flesh.ogg'
/obj/item/trash/lollibutt
name = "lollipop stick"
desc = "A lollipop stick devoid of pop."
icon = 'icons/obj/clothing/masks.dmi'
icon_state = "pop-stick"
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
/obj/item/trash/spitwad
name = "spit wad"
desc = "A disgusting spitwad."
icon = 'icons/obj/clothing/masks.dmi'
icon_state = "spit-chew"
drop_sound = 'sound/items/drop/flesh.ogg'
pickup_sound = 'sound/items/pickup/flesh.ogg'
slot_flags = SLOT_EARS | SLOT_MASK
/obj/item/trash/attack(mob/M as mob, mob/living/user as mob)
return
@@ -417,3 +417,75 @@ AI MODULES
desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 4)
laws = new/datum/ai_laws/antimov()
/****************** NT Aggressive *****************/
/obj/item/weapon/aiModule/nanotrasen_aggressive
name = "\improper 'NT Aggressive' core AI module"
desc = "An 'NT Aggressive' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_ILLEGAL = 1)
laws = new/datum/ai_laws/nanotrasen_aggressive()
/******************** Syndicate Directives ********************/
/obj/item/weapon/aiModule/syndicate_override
name = "\improper 'Syndicate Directives' core AI module"
desc = "A 'Syndicate Directives' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 4)
laws = new/datum/ai_laws/syndicate_override()
/******************** Spider Clan Directives ********************/
/obj/item/weapon/aiModule/ninja_override
name = "\improper 'Spider Clan Directives' core AI module"
desc = "A 'Spider Clan Directives' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 4)
laws = new/datum/ai_laws/ninja_override()
/******************** Maintenance ********************/
/obj/item/weapon/aiModule/maintenance
name = "\improper 'Maintenance' core AI module"
desc = "A 'Maintenance' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/maintenance()
/******************** Peacekeeper ********************/
/obj/item/weapon/aiModule/peacekeeper
name = "\improper 'Peacekeeper' core AI module"
desc = "A 'Peacekeeper' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/peacekeeper()
/******************** Reporter ********************/
/obj/item/weapon/aiModule/reporter
name = "\improper 'Reporter' core AI module"
desc = "A 'Reporter' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/reporter()
/******************** Live and Let Live ********************/
/obj/item/weapon/aiModule/live_and_let_live
name = "\improper 'Live and Let Live' core AI module"
desc = "A 'Live and Let Live' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/live_and_let_live()
/******************** Guardian of Balance ********************/
/obj/item/weapon/aiModule/balance
name = "\improper 'Guardian of Balance' core AI module"
desc = "A 'Guardian of Balance' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/balance()
/******************** Gravekeeper ********************/
/obj/item/weapon/aiModule/gravekeeper
name = "\improper 'Gravekeeper' core AI module"
desc = "A 'Gravekeeper' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/gravekeeper()
+2
View File
@@ -5,6 +5,8 @@
icon = 'icons/obj/tools.dmi'
icon_state = "rcd"
item_state = "rcd"
drop_sound = 'sound/items/drop/gun.ogg'
pickup_sound = 'sound/items/pickup/gun.ogg'
flags = NOBLUDGEON
force = 10
throwforce = 10
+1
View File
@@ -19,6 +19,7 @@ RSF
var/list/container_types = list(
"metamorphic glass" = /obj/item/weapon/reagent_containers/food/drinks/metaglass,
"metamorphic pint glass" = /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint,
"half-pint glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/square,
"rocks glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/rocks,
"milkshake glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/shake,
@@ -0,0 +1,37 @@
// **For augment items that aren't subtypes of other things.**
/obj/item/weapon/melee/augment
name = "integrated item"
desc = "A surprisingly non-descript item, integrated into its user. You probably shouldn't be seeing this."
icon = 'icons/obj/surgery.dmi'
icon_state = "augment_box"
/obj/item/weapon/melee/augment/blade
name = "handblade"
desc = "A sleek-looking telescopic blade that fits inside the hand. Favored by infiltration specialists and assassins."
icon_state = "augment_handblade"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
w_class = ITEMSIZE_SMALL
force = 15
armor_penetration = 25
sharp = 1
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
defend_chance = 10
projectile_parry_chance = 5
hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/weapon/melee/augment/blade/arm
name = "armblade"
desc = "A sleek-looking cybernetic blade that cleaves through people like butter. Favored by psychopaths and assassins."
icon_state = "augment_armblade"
w_class = ITEMSIZE_HUGE
force = 30
armor_penetration = 15
edge = 1
pry = 1
defend_chance = 40
projectile_parry_chance = 20
@@ -14,6 +14,8 @@
var/list/datum/autopsy_data_scanner/chemtraces = list()
var/target_name = null
var/timeofdeath = null
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
/datum/autopsy_data_scanner
var/weapon = null // this is the DEFINITE weapon type that was used
@@ -3,6 +3,8 @@
desc = "a red pillar candle. Its specially-formulated fuel-oxidizer wax mixture allows continued combustion in airless environments."
icon = 'icons/obj/candle.dmi'
icon_state = "candle1"
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
w_class = ITEMSIZE_TINY
light_color = "#E09D37"
var/wax = 2000
@@ -0,0 +1,233 @@
/obj/item/clothing/mask/chewable
name = "chewable item master"
desc = "If you are seeing this, ahelp it."
icon = 'icons/obj/clothing/masks.dmi'
drop_sound = 'sound/items/drop/food.ogg'
body_parts_covered = 0
var/type_butt = null
var/chem_volume = 0
var/chewtime = 0
var/brand
var/list/filling = list()
var/wrapped = FALSE
/obj/item/clothing/mask/chewable/attack_self(mob/user)
if(wrapped)
wrapped = FALSE
to_chat(user, span("notice", "You unwrap \the [name]."))
playsound(src.loc, 'sound/items/drop/wrapper.ogg', 50, 1)
slot_flags = SLOT_EARS | SLOT_MASK
update_icon()
/obj/item/clothing/mask/chewable/update_icon()
cut_overlays()
if(wrapped)
add_overlay("[initial(icon_state)]_wrapper")
obj/item/clothing/mask/chewable/Initialize()
. = ..()
flags |= NOREACT // so it doesn't react until you light it
create_reagents(chem_volume) // making the cigarrete a chemical holder with a maximum volume of 15
for(var/R in filling)
reagents.add_reagent(R, filling[R])
if(wrapped)
slot_flags = null
/obj/item/clothing/mask/chewable/equipped(var/mob/living/user, var/slot)
..()
if(slot == slot_wear_mask)
var/mob/living/carbon/human/C = user
if(C.check_has_mouth())
START_PROCESSING(SSprocessing, src)
else
to_chat(user, span("notice", "You don't have a mouth, and can't make much use of \the [src]."))
/obj/item/clothing/mask/chewable/dropped()
STOP_PROCESSING(SSprocessing, src)
..()
obj/item/clothing/mask/chewable/Destroy()
. = ..()
STOP_PROCESSING(SSprocessing, src)
/obj/item/clothing/mask/chewable/proc/chew()
chewtime--
if(reagents && reagents.total_volume)
if(ishuman(loc))
var/mob/living/carbon/human/C = loc
if (src == C.wear_mask && C.check_has_mouth())
reagents.trans_to_mob(C, REM, CHEM_INGEST, 0.2)
else
STOP_PROCESSING(SSprocessing, src)
/obj/item/clothing/mask/chewable/process()
chew()
if(chewtime < 1)
spitout()
/obj/item/clothing/mask/chewable/tobacco
name = "wad"
desc = "A chewy wad of tobacco. Cut in long strands and treated with syrup so it doesn't taste like an ash-tray when you stuff it into your face."
throw_speed = 0.5
icon_state = "chew"
type_butt = /obj/item/trash/spitwad
w_class = 1
slot_flags = SLOT_EARS | SLOT_MASK
chem_volume = 50
chewtime = 300
brand = "tobacco"
/obj/item/clothing/mask/chewable/proc/spitout(var/transfer_color = 1, var/no_message = 0)
if(type_butt)
var/obj/item/butt = new type_butt(src.loc)
transfer_fingerprints_to(butt)
if(transfer_color)
butt.color = color
if(brand)
butt.desc += " This one is \a [brand]."
if(ismob(loc))
var/mob/living/M = loc
if(!no_message)
to_chat(M, SPAN_NOTICE("The [name] runs out of flavor."))
if(M.wear_mask)
M.remove_from_mob(src) //un-equip it so the overlays can update
M.update_inv_wear_mask(0)
if(!M.equip_to_slot_if_possible(butt, slot_wear_mask))
M.update_inv_l_hand(0)
M.update_inv_r_hand(1)
M.put_in_hands(butt)
STOP_PROCESSING(SSprocessing, src)
qdel(src)
/obj/item/clothing/mask/chewable/tobacco/cheap
name = "chewing tobacco"
desc = "A chewy wad of tobacco. Cut in long strands and treated with syrup so it tastes less like an ash-tray when you stuff it into your face."
filling = list("nicotine" = 2)
/obj/item/clothing/mask/chewable/tobacco/fine
name = "deluxe chewing tobacco"
desc = "A chewy wad of fine tobacco. Cut in long strands and treated with syrup so it doesn't taste like an ash-tray when you stuff it into your face."
filling = list("nicotine" = 3)
/obj/item/clothing/mask/chewable/tobacco/nico
name = "nicotine gum"
desc = "A chewy wad of synthetic rubber, laced with nicotine. Possibly the least disgusting method of nicotine delivery."
icon_state = "nic_gum"
type_butt = /obj/item/trash/spitgum
wrapped = TRUE
/obj/item/clothing/mask/chewable/tobacco/nico/Initialize()
. = ..()
reagents.add_reagent("nicotine", 2)
color = reagents.get_color()
/obj/item/weapon/storage/chewables
name = "box of chewing wads master"
desc = "A generic brand of Waffle Co Wads, unflavored chews. Why do these exist?"
icon = 'icons/obj/cigarettes.dmi'
icon_state = "cigpacket"
item_state = "cigpacket"
drop_sound = 'sound/items/drop/shovel.ogg'
use_sound = 'sound/items/storage/pillbottle.ogg'
w_class = 2
throwforce = 2
slot_flags = SLOT_BELT
starts_with = list(/obj/item/clothing/mask/chewable/tobacco = 6)
make_exact_fit()
//Tobacco Tins
/obj/item/weapon/storage/chewables/tobacco
name = "tin of Al Mamun Smooth chewing tobacco"
desc = "Packaged and shipped straight from Kishar, popularised by the biosphere farmers of Kanondaga."
icon_state = "chew_generic"
item_state = "cigpacket"
starts_with = list(/obj/item/clothing/mask/chewable/tobacco/cheap = 6)
storage_slots = 6
/obj/item/weapon/storage/chewables/tobacco/fine
name = "tin of Suamalie chewing tobacco"
desc = "Once reserved for the first-class tourists of Oasis, this premium blend has been released for the public to enjoy."
icon_state = "chew_fine"
item_state = "Dpacket"
starts_with = list(/obj/item/clothing/mask/chewable/tobacco/fine = 6)
/obj/item/weapon/storage/box/fancy/chewables/tobacco/nico
name = "box of Nico-Tine gum"
desc = "A government doctor approved brand of nicotine gum. Cut out the middleman for your addiction fix."
icon = 'icons/obj/cigarettes.dmi'
icon_state = "chew_nico"
item_state = "Epacket"
starts_with = list(/obj/item/clothing/mask/chewable/tobacco/nico = 6)
storage_slots = 6
drop_sound = 'sound/items/drop/box.ogg'
use_sound = 'sound/items/storage/box.ogg'
/obj/item/weapon/storage/box/fancy/chewables/tobacco/update_icon()
icon_state = "[initial(icon_state)][contents.len]"
/obj/item/clothing/mask/chewable/candy
name = "wad"
desc = "A chewy wad of wadding material."
throw_speed = 0.5
icon_state = "chew"
type_butt = /obj/item/trash/spitgum
w_class = 1
slot_flags = SLOT_EARS | SLOT_MASK
chem_volume = 50
chewtime = 300
filling = list("sugar" = 2)
/obj/item/clothing/mask/chewable/candy/gum
name = "chewing gum"
desc = "A chewy wad of fine synthetic rubber and artificial flavoring. Be sure to unwrap it, genius."
icon_state = "gum"
item_state = "gum"
wrapped = TRUE
/obj/item/clothing/mask/chewable/candy/gum/Initialize()
. = ..()
reagents.add_reagent(pick("banana","berryjuice","grapejuice","lemonjuice","limejuice","orangejuice","watermelonjuice"),10)
color = reagents.get_color()
update_icon()
/obj/item/weapon/storage/box/gum
name = "\improper Frooty-Choos flavored gum"
desc = "A small pack of chewing gum in various flavors."
description_fluff = "Frooty-Choos is NanoTrasen's top-selling brand of artificially flavoured fruit-adjacent non-swallowable chew-product. This extremely specific definition places sales figures safely away from competing 'gum' brands."
icon = 'icons/obj/food_snacks.dmi'
icon_state = "gum_pack"
item_state = "candy"
slot_flags = SLOT_EARS
w_class = 1
starts_with = list(/obj/item/clothing/mask/chewable/candy/gum = 5)
can_hold = list(/obj/item/clothing/mask/chewable/candy/gum,
/obj/item/trash/spitgum)
use_sound = 'sound/items/drop/paper.ogg'
drop_sound = 'sound/items/drop/wrapper.ogg'
max_storage_space = 5
foldable = null
trash = /obj/item/trash/gumpack
/obj/item/clothing/mask/chewable/candy/lolli
name = "lollipop"
desc = "A simple artificially flavored sphere of sugar on a handle, colloquially known as a sucker. Allegedly one is born every minute. Make sure to unwrap it, genius."
type_butt = /obj/item/trash/lollibutt
icon_state = "lollipop"
item_state = "lollipop"
wrapped = TRUE
/obj/item/clothing/mask/chewable/candy/lolli/process()
chew()
if(chewtime < 1)
spitout(0)
/obj/item/clothing/mask/chewable/candy/lolli/Initialize()
. = ..()
reagents.add_reagent(pick("banana","berryjuice","grapejuice","lemonjuice","limejuice","orangejuice","watermelonjuice"),20)
color = reagents.get_color()
update_icon()
@@ -34,7 +34,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
origin_tech = list(TECH_MATERIAL = 1)
slot_flags = SLOT_EARS
attack_verb = list("burnt", "singed")
drop_sound = null
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/weapon/flame/match/process()
if(isliving(loc))
@@ -346,6 +347,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/smokable/cigarette/cigar
name = "premium cigar"
desc = "A brown roll of tobacco and... well, you're not quite sure. This thing's huge!"
description_fluff = "While the label does say that this is a 'premium cigar', it really cannot match other types of cigars on the market. Is it a quality cigarette? Perhaps. Was it hand-made with care? No."
icon_state = "cigar2"
type_butt = /obj/item/trash/cigbutt/cigarbutt
throw_speed = 0.5
@@ -363,12 +365,14 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/smokable/cigarette/cigar/cohiba
name = "\improper Cohiba Robusto cigar"
desc = "There's little more you could want from a cigar."
description_fluff = "Cohiba has been a popular cigar company for centuries. They are still based out of Cuba and refuse to expand and therefore have a very limited quantity, making their cigars coveted all through known space. Robusto is one of their most popular shapes of cigars."
icon_state = "cigar2"
nicotine_amt = 7
/obj/item/clothing/mask/smokable/cigarette/cigar/havana
name = "premium Havanian cigar"
desc = "A cigar fit for only the best of the best."
description_fluff = "'Havanian' is an umbrella term for any cigar made in the typical handmade style of Cuba. This particular cigar is from Gilthari's cigar manufacturers and produced galaxy-wide. While this way of making quality cigars has become slightly bastardized over the years, overall quality has remained relatively the same, even if there is a large quantity of 'Havanian' cigars."
icon_state = "cigar2"
max_smoketime = 7200
smoketime = 7200
@@ -408,6 +412,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/smokable/pipe
name = "smoking pipe"
desc = "A pipe, for smoking. Made of fine, stained cherry wood."
description_fluff = "ClassiCo Accessories and Haberdashers, originating out of Mars, claim to produce products 'for the modern gentlefolk'. Most of their items are high-end and expensive, but they pledge to back their prices up with quality, and usually do."
icon_state = "pipe"
item_state = "pipe"
smoketime = 0
@@ -494,6 +499,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/weapon/rollingpaper
name = "rolling paper"
desc = "A small, thin piece of easily flammable paper, commonly used for rolling and smoking various dried plants."
description_fluff = "The legalization of certain substances propelled the sale of rolling papers through the roof. Now almost every Trans-stellar produces a variety, often of questionable quality."
icon = 'icons/obj/cigarettes.dmi'
icon_state = "cig paper"
@@ -519,6 +525,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/weapon/flame/lighter
name = "cheap lighter"
desc = "A cheap-as-free lighter."
description_fluff = "The 'hand-made in Altair' sticker underneath is a charming way of saying 'Made with prison labour'. It's no wonder the company can sell these things so cheap."
icon = 'icons/obj/items.dmi'
icon_state = "lighter-g"
item_state = "lighter-g"
@@ -533,6 +540,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/weapon/flame/lighter/zippo
name = "\improper Zippo lighter"
desc = "The zippo."
description_fluff = "Still going after all these years."
icon = 'icons/obj/zippo.dmi'
icon_state = "zippo"
item_state = "zippo"
@@ -20,6 +20,8 @@
var/board_type = new /datum/frame/frame_types/computer
var/list/req_components = null
var/contain_parts = 1
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
//Called when the circuitboard is used to contruct a new machine.
/obj/item/weapon/circuitboard/proc/construct(var/obj/machinery/M)
@@ -12,7 +12,6 @@
/obj/item/weapon/circuitboard/security/New()
..()
network = using_map.station_networks
/obj/item/weapon/circuitboard/security/tv
name = T_BOARD("security camera monitor - television")
@@ -45,7 +44,7 @@
/obj/item/weapon/circuitboard/security/construct(var/obj/machinery/computer/security/C)
if (..(C))
C.network = network.Copy()
C.set_network(network.Copy())
/obj/item/weapon/circuitboard/security/deconstruct(var/obj/machinery/computer/security/C)
if (..(C))
@@ -0,0 +1,14 @@
#ifndef T_BOARD
#error T_BOARD macro is not defined but we need it!
#endif
/obj/item/weapon/circuitboard/fluidpump
name = T_BOARD("fluid pump")
build_path = /obj/machinery/pump
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_DATA = 1)
req_components = list(
/obj/item/weapon/stock_parts/matter_bin = 2,
/obj/item/weapon/stock_parts/motor = 2,
/obj/item/weapon/stock_parts/manipulator = 1)
+7 -7
View File
@@ -9,6 +9,7 @@
var/colour = "red"
var/open = 0
drop_sound = 'sound/items/drop/glass.ogg'
pickup_sound = 'sound/items/pickup/glass.ogg'
/obj/item/weapon/lipstick/purple
name = "purple lipstick"
@@ -96,17 +97,16 @@
w_class = ITEMSIZE_TINY
icon = 'icons/obj/items.dmi'
icon_state = "trinketbox"
var/list/ui_users = list()
var/datum/tgui_module/appearance_changer/mirror/coskit/M
/obj/item/weapon/makeover/Initialize()
. = ..()
M = new(src, null)
/obj/item/weapon/makeover/attack_self(mob/living/carbon/user as mob)
if(ishuman(user))
to_chat(user, "<span class='notice'>You flip open \the [src] and begin to adjust your appearance.</span>")
var/datum/nano_module/appearance_changer/AC = ui_users[user]
if(!AC)
AC = new(src, user)
AC.name = "SalonPro Porta-Makeover Deluxe&trade;"
ui_users[user] = AC
AC.ui_interact(user)
M.tgui_interact(user)
var/mob/living/carbon/human/H = user
var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES]
if(istype(E))
@@ -67,7 +67,7 @@
if(istype(M,/mob/living))
var/mob/living/L = M
L.apply_effect(rand(5,20), IRRADIATE, check_protection = 0)
L.apply_damage(max(2,L.getCloneLoss()), CLONE)
L.apply_damage(max(2,L.getCloneLoss()), CLONE)
if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed
if (buf.types & DNA2_BUF_UI)
@@ -158,7 +158,7 @@
/obj/item/weapon/dnainjector/xraymut
name = "\improper DNA injector (Xray)"
desc = "Finally you can see what the Colony Director does."
desc = "Finally you can see what the Site Manager does."
datatype = DNA2_BUF_SE
value = 0xFFF
//block = 8
+4 -1
View File
@@ -1,6 +1,6 @@
/obj/item/clothing/mask/smokable/ecig
name = "electronic cigarette"
desc = "Device with modern approach to smoking."
desc = "For the modern approach to smoking."
icon = 'icons/obj/ecig.dmi'
var/active = 0
//var/obj/item/weapon/cell/ec_cell = /obj/item/weapon/cell/device
@@ -24,6 +24,7 @@
/obj/item/clothing/mask/smokable/ecig/simple
name = "simple electronic cigarette"
desc = "A cheap Lucky 1337 electronic cigarette, styled like a traditional cigarette."
description_fluff = "Produced by the Ward-Takahashi Corporation on behalf of the Lucky Stars cigarette brand, the 1337 is the e-cig of choice for teenage wastrels across the core worlds. Due to a total lack of safety features, this model is banned on most interstellar flights."
icon_state = "ccigoff"
icon_off = "ccigoff"
icon_empty = "ccigoff"
@@ -32,6 +33,7 @@
/obj/item/clothing/mask/smokable/ecig/util
name = "electronic cigarette"
desc = "A popular utilitarian model electronic cigarette, the ONI-55. Comes in a variety of colors."
description_fluff = "Ward-Takahashi's flagship brand of e-cig is a popular fashion accessory in certain circles where open flames are prohibited. Custom casings are sold for almost as much as the device itself, and are practically impossible to DIY."
icon_state = "ecigoff1"
icon_off = "ecigoff1"
icon_empty = "ecigoff1"
@@ -43,6 +45,7 @@
/obj/item/clothing/mask/smokable/ecig/deluxe
name = "deluxe electronic cigarette"
desc = "A premium model eGavana MK3 electronic cigarette, shaped like a cigar."
description_fluff = "The eGavana is a product of Morpheus Cyberkinetics, and comes standard with additional jacks that allow cyborgs and positronics to experience a simulation of soothing artificial oil residues entering their lungs. It's a pretty good cig for meatbags, too."
icon_state = "pcigoff1"
icon_off = "pcigoff1"
icon_empty = "pcigoff2"
@@ -13,6 +13,7 @@
matter = list(DEFAULT_WALL_MATERIAL = 90)
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
drop_sound = 'sound/items/drop/gascan.ogg'
pickup_sound = 'sound/items/pickup/gascan.ogg'
var/spray_particles = 3
var/spray_amount = 10 //units of liquid per particle
@@ -110,10 +110,6 @@
update_icon()
return
if(istype(W, /obj/item/device/analyzer))
var/obj/item/device/analyzer/A = W
A.analyze_gases(src, user)
return
..()
return
@@ -13,7 +13,8 @@
icon = 'icons/obj/items.dmi'
icon_state = "gift1"
item_state = "gift1"
drop_sound = 'sound/items/drop/box.ogg'
drop_sound = 'sound/items/drop/cardboardbox.ogg'
pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
/obj/item/weapon/a_gift/New()
..()
@@ -87,17 +88,17 @@
/obj/item/toy/crossbow,
/obj/item/weapon/gun/projectile/revolver/capgun,
/obj/item/toy/katana,
/obj/item/toy/prize/deathripley,
/obj/item/toy/prize/durand,
/obj/item/toy/prize/fireripley,
/obj/item/toy/prize/gygax,
/obj/item/toy/prize/honk,
/obj/item/toy/prize/marauder,
/obj/item/toy/prize/mauler,
/obj/item/toy/prize/odysseus,
/obj/item/toy/prize/phazon,
/obj/item/toy/prize/ripley,
/obj/item/toy/prize/seraph,
/obj/item/toy/mecha/deathripley,
/obj/item/toy/mecha/durand,
/obj/item/toy/mecha/fireripley,
/obj/item/toy/mecha/gygax,
/obj/item/toy/mecha/honk,
/obj/item/toy/mecha/marauder,
/obj/item/toy/mecha/mauler,
/obj/item/toy/mecha/odysseus,
/obj/item/toy/mecha/phazon,
/obj/item/toy/mecha/ripley,
/obj/item/toy/mecha/seraph,
/obj/item/toy/spinningtoy,
/obj/item/toy/sword,
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,
@@ -125,6 +126,8 @@
icon = 'icons/obj/items.dmi'
icon_state = "wrap_paper"
var/amount = 20.0
drop_sound = 'sound/items/drop/wrapper.ogg'
pickup_sound = 'sound/items/pickup/wrapper.ogg'
/obj/item/weapon/wrapping_paper/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
..()
@@ -99,7 +99,7 @@
/obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve
desc = "Use of this weapon may constiute a war crime in your area, consult your local Colony Director."
desc = "Use of this weapon may constiute a war crime in your area, consult your local Site Manager."
name = "clusterbang"
icon = 'icons/obj/grenade.dmi'
icon_state = "clusterbang"
@@ -12,6 +12,7 @@
origin_tech = list(TECH_MATERIAL = 1)
matter = list(DEFAULT_WALL_MATERIAL = 500)
drop_sound = 'sound/items/drop/accessory.ogg'
pickup_sound = 'sound/items/pickup/accessory.ogg'
var/elastic
var/dispenser = 0
var/breakouttime = 1200 //Deciseconds = 120s = 2 minutes
@@ -21,6 +21,7 @@
var/list/files = list( )
drop_sound = 'sound/items/drop/card.ogg'
pickup_sound = 'sound/items/pickup/card.ogg'
/obj/item/weapon/card/data
name = "data disk"
@@ -30,6 +31,8 @@
var/data = "null"
var/special = null
item_state = "card-id"
drop_sound = 'sound/items/drop/disk.ogg'
pickup_sound = 'sound/items/pickup/disk.ogg'
/obj/item/weapon/card/data/verb/label(t as text)
set name = "Label Disk"
@@ -139,13 +139,13 @@
preserve_item = 1
/obj/item/weapon/card/id/gold/captain
assignment = "Colony Director"
rank = "Colony Director"
assignment = "Site Manager"
rank = "Site Manager"
/obj/item/weapon/card/id/gold/captain/spare
name = "\improper Colony Director's spare ID"
name = "\improper Site Manager's spare ID"
desc = "The spare ID of the High Lord himself."
registered_name = "Colony Director"
registered_name = "Site Manager"
/obj/item/weapon/card/id/synthetic
name = "\improper Synthetic ID"
@@ -169,6 +169,10 @@
organ_to_implant = /obj/item/organ/internal/augment/armmounted/hand/sword
organ_display_name = "weapon augment"
/obj/item/weapon/implant/organ/limbaugment/wrist/blade
organ_to_implant = /obj/item/organ/internal/augment/armmounted/hand/blade
organ_display_name = "weapon augment"
// Fore-arm
/obj/item/weapon/implant/organ/limbaugment/laser
organ_to_implant = /obj/item/organ/internal/augment/armmounted
@@ -185,6 +189,10 @@
/obj/item/weapon/implant/organ/limbaugment/upperarm/surge
organ_to_implant = /obj/item/organ/internal/augment/armmounted/shoulder/surge
/obj/item/weapon/implant/organ/limbaugment/upperarm/blade
organ_to_implant = /obj/item/organ/internal/augment/armmounted/shoulder/blade
organ_display_name = "weapon augment"
/*
* Others
*/
@@ -279,3 +279,23 @@
src.imp = new /obj/item/weapon/implant/organ/pelvic( src )
..()
return
/obj/item/weapon/implantcase/armblade
name = "glass case - 'Armblade'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/armblade/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm/blade( src )
..()
return
/obj/item/weapon/implantcase/handblade
name = "glass case - 'Handblade'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/handblade/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/blade( src )
..()
return
+1 -1
View File
@@ -1136,7 +1136,7 @@
Remember the order:<br>
<b>Disk, Code, Safety, Timer, Disk, RUN!</b><br><br>
Intelligence Analysts believe that normal corporate procedure is for the Colony Director to secure the nuclear authentication disk.<br><br>
Intelligence Analysts believe that normal corporate procedure is for the Site Manager to secure the nuclear authentication disk.<br><br>
Good luck!
</body>
@@ -5,6 +5,8 @@
* Utensils
*/
/obj/item/weapon/material/kitchen/utensil
drop_sound = 'sound/items/drop/knife.ogg'
pickup_sound = 'sound/items/pickup/knife.ogg'
w_class = ITEMSIZE_TINY
thrown_force_divisor = 1
origin_tech = list(TECH_MATERIAL = 1)
@@ -104,6 +106,7 @@
dulled_divisor = 0.75 // Still a club
thrown_force_divisor = 1 // as above
drop_sound = 'sound/items/drop/wooden.ogg'
pickup_sound = 'sound/items/pickup/wooden.ogg'
/obj/item/weapon/material/kitchen/rollingpin/attack(mob/living/M as mob, mob/living/user as mob)
if ((CLUMSY in user.mutations) && prob(50))
@@ -10,6 +10,7 @@
force_divisor = 0.25 // 15 when wielded with hardness 60 (steel)
thrown_force_divisor = 0.25 // 5 when thrown with weight 20 (steel)
drop_sound = 'sound/items/drop/knife.ogg'
pickup_sound = 'sound/items/pickup/knife.ogg'
/obj/item/weapon/material/butterfly/update_force()
if(active)
@@ -27,7 +27,7 @@ Protectiveness | Armor %
// Putting these at /clothing/ level saves a lot of code duplication in armor/helmets/gauntlets/etc
/obj/item/clothing
var/material/material = null // Why isn't this a datum?
var/datum/material/material = null // Why isn't this a datum?
var/applies_material_color = TRUE
var/unbreakable = FALSE
var/default_material = null // Set this to something else if you want material attributes on init.
@@ -24,7 +24,7 @@
var/thrown_force_divisor = 0.5
var/dulled_divisor = 0.5 //Just drops the damage by half
var/default_material = DEFAULT_WALL_MATERIAL
var/material/material
var/datum/material/material
var/drops_debris = 1
/obj/item/weapon/material/New(var/newloc, var/material_key)
@@ -22,6 +22,7 @@
attack_verb = list("chopped", "torn", "cut")
applies_material_colour = 0
drop_sound = 'sound/items/drop/axe.ogg'
pickup_sound = 'sound/items/pickup/axe.ogg'
/obj/item/weapon/material/knife/machete/hatchet/unathiknife
name = "duelling knife"
@@ -10,6 +10,7 @@
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
drop_sound = 'sound/items/drop/sword.ogg'
pickup_sound = 'sound/items/pickup/sword.ogg'
/obj/item/weapon/material/sword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(unique_parry_check(user, attacker, damage_source) && prob(50))
@@ -26,6 +26,9 @@
var/base_icon
var/base_name
var/unwielded_force_divisor = 0.25
hitsound = "swing_hit"
drop_sound = 'sound/items/drop/sword.ogg'
pickup_sound = 'sound/items/pickup/sword.ogg'
/obj/item/weapon/material/twohanded/update_held_icon()
var/mob/living/M = loc
@@ -96,6 +99,7 @@
applies_material_colour = 0
can_cleave = TRUE
drop_sound = 'sound/items/drop/axe.ogg'
pickup_sound = 'sound/items/pickup/axe.ogg'
/obj/item/weapon/material/twohanded/fireaxe/update_held_icon()
var/mob/living/M = loc
@@ -152,6 +156,7 @@
edge = 0
sharp = 1
hitsound = 'sound/weapons/bladeslice.ogg'
mob_throw_hit_sound = 'sound/weapons/pierce.ogg'
attack_verb = list("attacked", "poked", "jabbed", "torn", "gored")
default_material = "glass"
applies_material_colour = 0
@@ -279,6 +279,8 @@
sharp = 1
edge = 1
colorable = TRUE
drop_sound = 'sound/items/drop/sword.ogg'
pickup_sound = 'sound/items/pickup/sword.ogg'
projectile_parry_chance = 65
@@ -17,6 +17,7 @@
var/flippable = 0
var/side = 0 //0 = right, 1 = left
drop_sound = 'sound/items/drop/backpack.ogg'
pickup_sound = 'sound/items/pickup/backpack.ogg'
/obj/item/weapon/storage/backpack/equipped(var/mob/user, var/slot)
@@ -92,7 +93,7 @@
icon_state = "securitypack"
/obj/item/weapon/storage/backpack/captain
name = "colony director's backpack"
name = "site manager's backpack"
desc = "It's a special backpack made exclusively for officers."
icon_state = "captainpack"
@@ -154,7 +155,7 @@
icon_state = "duffle_syndieammo"
/obj/item/weapon/storage/backpack/dufflebag/captain
name = "colony director's dufflebag"
name = "site manager's dufflebag"
desc = "A large dufflebag for holding extra captainly goods."
icon_state = "duffle_captain"
@@ -249,7 +250,7 @@
icon_state = "satchel_hyd"
/obj/item/weapon/storage/backpack/satchel/cap
name = "colony director's satchel"
name = "site manager's satchel"
desc = "An exclusive satchel for officers."
icon_state = "satchel-cap"
item_state_slots = list(slot_r_hand_str = "captainpack", slot_l_hand_str = "captainpack")
@@ -24,6 +24,7 @@
use_to_pickup = 1
slot_flags = SLOT_BELT
drop_sound = 'sound/items/drop/backpack.ogg'
pickup_sound = 'sound/items/pickup/backpack.ogg'
// -----------------------------
// Trash bag
@@ -35,6 +36,7 @@
icon_state = "trashbag0"
item_state_slots = list(slot_r_hand_str = "trashbag", slot_l_hand_str = "trashbag")
drop_sound = 'sound/items/drop/wrapper.ogg'
pickup_sound = 'sound/items/pickup/wrapper.ogg'
w_class = ITEMSIZE_LARGE
max_w_class = ITEMSIZE_SMALL
@@ -62,6 +64,7 @@
icon = 'icons/obj/trash.dmi'
icon_state = "plasticbag"
drop_sound = 'sound/items/drop/wrapper.ogg'
pickup_sound = 'sound/items/pickup/wrapper.ogg'
w_class = ITEMSIZE_LARGE
max_w_class = ITEMSIZE_SMALL
@@ -8,8 +8,10 @@
max_w_class = ITEMSIZE_NORMAL
slot_flags = SLOT_BELT
attack_verb = list("whipped", "lashed", "disciplined")
equip_sound = 'sound/items/toolbelt_equip.ogg'
drop_sound = 'sound/items/drop/toolbelt.ogg'
pickup_sound = 'sound/items/pickup/toolbelt.ogg'
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/belt.dmi')
drop_sound = 'sound/items/drop/leather.ogg'
var/show_above_suit = 0
@@ -26,35 +26,48 @@
item_state = "syringe_kit"
center_of_mass = list("x" = 13,"y" = 10)
var/foldable = /obj/item/stack/material/cardboard // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard
var/trash = null // if set, can be crushed into a trash item when empty
max_w_class = ITEMSIZE_SMALL
max_storage_space = INVENTORY_BOX_SPACE
use_sound = 'sound/items/storage/box.ogg'
drop_sound = 'sound/items/drop/box.ogg'
drop_sound = 'sound/items/drop/cardboardbox.ogg'
pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
// BubbleWrap - A box can be folded up to make card
/obj/item/weapon/storage/box/attack_self(mob/user as mob)
if(..()) return
//try to fold it.
if ( contents.len )
return
//try to fold it
if(ispath(foldable))
if (contents.len)
return
var/found = 0
// Close any open UI windows first
for(var/mob/M in range(1))
if (M.s_active == src)
close(M)
if (M == user)
found = 1
if (!found) // User is too far away
return
// Now make the cardboard
to_chat(user, "<span class='notice'>You fold [src] flat.</span>")
playsound(src, 'sound/items/storage/boxfold.ogg', 30, 1)
new foldable(get_turf(src))
qdel(src)
//try to crush it
if(ispath(trash))
if(contents.len && user.a_intent == I_HURT) // only crumple with things inside on harmintent.
user.visible_message(SPAN_DANGER("[user] crushes \the [src], spilling its contents everywhere!"), SPAN_DANGER("You crush \the [src], spilling its contents everywhere!"))
spill()
else
to_chat(user, SPAN_NOTICE("You crumple up \the [src].")) //make trash
playsound(src.loc, 'sound/items/drop/wrapper.ogg', 30, 1)
var/obj/item/trash = new src.trash()
qdel(src)
user.put_in_hands(trash)
if ( !ispath(foldable) )
return
var/found = 0
// Close any open UI windows first
for(var/mob/M in range(1))
if (M.s_active == src)
close(M)
if ( M == user )
found = 1
if ( !found ) // User is too far away
return
// Now make the cardboard
to_chat(user, "<span class='notice'>You fold [src] flat.</span>")
playsound(src, 'sound/items/storage/boxfold.ogg', 30, 1)
new foldable(get_turf(src))
qdel(src)
/obj/item/weapon/storage/box/survival
name = "emergency supply box"
@@ -124,6 +137,8 @@
icon_state = "blankshot_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g/blank = 8)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/blanks/large
starts_with = list(/obj/item/ammo_casing/a12g/blank = 16)
@@ -134,6 +149,8 @@
icon_state = "beanshot_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g/beanbag = 8)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/beanbags/large/New()
starts_with = list(/obj/item/ammo_casing/a12g/beanbag = 16)
@@ -144,6 +161,8 @@
icon_state = "lethalshellshot_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g = 8)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/shotgunammo/large
starts_with = list(/obj/item/ammo_casing/a12g = 16)
@@ -154,6 +173,8 @@
icon_state = "lethalslug_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g/pellet = 8)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/shotgunshells/large
starts_with = list(/obj/item/ammo_casing/a12g/pellet = 16)
@@ -164,6 +185,8 @@
icon_state = "illumshot_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g/flash = 8)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/flashshells/large
starts_with = list(/obj/item/ammo_casing/a12g/flash = 16)
@@ -174,6 +197,8 @@
icon_state = "stunshot_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g/stunshell = 8)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/stunshells/large
starts_with = list(/obj/item/ammo_casing/a12g/stunshell = 16)
@@ -184,6 +209,8 @@
icon_state = "blankshot_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g/practice = 8)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/practiceshells/large
starts_with = list(/obj/item/ammo_casing/a12g/practice = 16)
@@ -194,6 +221,8 @@
icon_state = "empshot_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g/emp = 8)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/empshells/large
starts_with = list(/obj/item/ammo_casing/a12g/emp = 16)
@@ -204,6 +233,8 @@
icon_state = "lethalslug_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g/flechette = 8)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/flechetteshells/large
starts_with = list(/obj/item/ammo_casing/a12g/flechette = 16)
@@ -212,6 +243,8 @@
name = "box of 14.5mm shells"
desc = "It has a picture of a gun and several warning symbols on the front.<br>WARNING: Live ammunition. Misuse may result in serious injury or death."
starts_with = list(/obj/item/ammo_casing/a145 = 7)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/sniperammo/highvel
name = "box of 14.5mm sabot shells"
@@ -223,42 +256,56 @@
desc = "<B>WARNING: These devices are extremely dangerous and can cause blindness or deafness in repeated use.</B>"
icon_state = "flashbang"
starts_with = list(/obj/item/weapon/grenade/flashbang = 7)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/emps
name = "box of emp grenades"
desc = "A box containing 5 military grade EMP grenades.<br> WARNING: Do not use near unshielded electronics or biomechanical augmentations, death or permanent paralysis may occur."
icon_state = "emp"
starts_with = list(/obj/item/weapon/grenade/empgrenade = 7)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/empslite
name = "box of low yield emp grenades"
desc = "A box containing 5 low yield EMP grenades.<br> WARNING: Do not use near unshielded electronics or biomechanical augmentations, death or permanent paralysis may occur."
icon_state = "emp"
starts_with = list(/obj/item/weapon/grenade/empgrenade/low_yield = 7)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/smokes
name = "box of smoke bombs"
desc = "A box containing 7 smoke bombs."
icon_state = "flashbang"
starts_with = list(/obj/item/weapon/grenade/smokebomb = 7)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/anti_photons
name = "box of anti-photon grenades"
desc = "A box containing 7 experimental photon disruption grenades."
icon_state = "flashbang"
starts_with = list(/obj/item/weapon/grenade/anti_photon = 7)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/frags
name = "box of fragmentation grenades (WARNING)"
desc = "A box containing 7 military grade fragmentation grenades.<br> WARNING: These devices are extremely dangerous and can cause limb loss or death in repeated use."
icon_state = "frag"
starts_with = list(/obj/item/weapon/grenade/explosive = 7)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/frags_half_box
name = "box of fragmentation grenades (WARNING)"
desc = "A box containing 4 military grade fragmentation grenades.<br> WARNING: These devices are extremely dangerous and can cause limb loss or death in repeated use."
icon_state = "frag"
starts_with = list(/obj/item/weapon/grenade/explosive = 4)
drop_sound = 'sound/items/drop/ammobox.ogg'
pickup_sound = 'sound/items/pickup/ammobox.ogg'
/obj/item/weapon/storage/box/metalfoam
name = "box of metal foam grenades."
@@ -421,6 +468,8 @@
slot_flags = SLOT_BELT
can_hold = list(/obj/item/weapon/flame/match)
starts_with = list(/obj/item/weapon/flame/match = 10)
drop_sound = 'sound/items/drop/matchbox.ogg'
pickup_sound = 'sound/items/pickup/matchbox.ogg'
/obj/item/weapon/storage/box/matches/attackby(var/obj/item/weapon/flame/match/W, var/mob/user)
if(istype(W) && !W.lit && !W.burnt)
@@ -10,6 +10,7 @@
max_storage_space = ITEMSIZE_COST_NORMAL * 4
use_sound = 'sound/items/storage/briefcase.ogg'
drop_sound = 'sound/items/drop/backpack.ogg'
pickup_sound = 'sound/items/pickup/backpack.ogg'
/obj/item/weapon/storage/briefcase/clutch
name = "clutch purse"
@@ -19,6 +19,8 @@
icon_state = "donutbox6"
name = "donut box"
var/icon_type = "donut"
drop_sound = 'sound/items/drop/cardboardbox.ogg'
pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
/obj/item/weapon/storage/fancy/update_icon(var/itemremoved = 0)
var/total_contents = contents.len - itemremoved
@@ -202,6 +204,7 @@
/obj/item/weapon/storage/fancy/cigarettes
name = "\improper pack of Trans-Stellar Duty-frees"
desc = "A ubiquitous brand of cigarettes, found in every major spacefaring corporation in the universe. As mild and flavorless as it gets."
description_fluff = "The Trans-Stellar Duty-Free Cigarette Company was created as an imprint of NanoTrasen. They are the most boring, tasteless, dry cigarettes on the market, but due to just how unremarkable (not to mention cheap to produce) they are, they sold in vending machines in almost every corner of the galaxy."
icon = 'icons/obj/cigarettes.dmi'
icon_state = "cigpacket"
item_state_slots = list(slot_r_hand_str = "cigpacket", slot_l_hand_str = "cigpacket")
@@ -265,14 +268,16 @@
/obj/item/weapon/storage/fancy/cigarettes/dromedaryco
name = "\improper DromedaryCo packet"
desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\""
desc = "A packet of six Earth-export DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\""
description_fluff = "DromedaryCo is one of Sol's oldest cigarette brands, and takes pride in having sourced tobcacco from the same Indian plantations since 2044. Popular with those willing to pay extra for a little nostalgia."
icon_state = "Dpacket"
brand = "\improper Dromedary Co. cigarette"
/obj/item/weapon/storage/fancy/cigarettes/killthroat
name = "\improper AcmeCo packet"
desc = "A packet of six AcmeCo cigarettes. For those who somehow want to obtain the record for the most amount of cancerous tumors."
icon_state = "Bpacket"
desc = "A packet of six AcmeCo cigarettes. For those who want to obtain a record for the most cancerous tumors on a budget."
description_fluff = "Available anywhere people breathe and want to breathe less, AcmeCo is the cheapest, most widespread cigarette brand in the galaxy. They taste like trash, but when you're keeping them inside your jumpsuit on a 16 hour shift, you're probably not too concerned with flavour."
icon_state = "Apacket"
brand = "\improper Acme Co. cigarette"
// New exciting ways to kill your lungs! - Earthcrusher //
@@ -280,37 +285,42 @@
/obj/item/weapon/storage/fancy/cigarettes/luckystars
name = "\improper pack of Lucky Stars"
desc = "A mellow blend made from synthetic, pod-grown tobacco. The commercial jingle is guaranteed to get stuck in your head."
description_fluff = "Lucky Stars are some of the most prolific advertisers in the business, with Gilthari Exports plastering the name and slogan on everything from workplace safety videos to racing bikes. 'Feel the gentle warmth of your Lucky Star'."
icon_state = "LSpacket"
brand = "\improper Lucky Star"
/obj/item/weapon/storage/fancy/cigarettes/jerichos
name = "\improper pack of Jerichos"
desc = "Typically seen dangling from the lips of Martian soldiers and border world hustlers. Tastes like hickory smoke, feels like warm liquid death down your lungs."
desc = "Typically seen dangling from the lips of Fleet veterans and border world hustlers. Tastes like hickory smoke, feels like warm liquid death down your lungs."
description_fluff = "The Jericho brand has carefully cultivated its 'rugged' image ever since its completely accidental association with the SolGov-Hegemony war due to their sizable corporate presence in the region. Prior to the war, Jerichos were considered the realm of drunks and sad divorcees."
icon_state = "Jpacket"
brand = "\improper Jericho"
/obj/item/weapon/storage/fancy/cigarettes/menthols
name = "\improper pack of Temperamento Menthols"
desc = "With a sharp and natural organic menthol flavor, these Temperamentos are a favorite of NDV crews. Hardly anyone knows they make 'em in non-menthol!"
desc = "With a sharp and natural organic menthol flavor, these Temperamentos are a favorite of science vessel crews. Hardly anyone knows they make 'em in non-menthol!"
description_fluff = "Temperamento Menthols are a product of the Aether Atmospherics and Recycling company, and the 'smooth' menthol taste is rumoured to be the chemical by-product of some far more profitable industrial synthesis."
icon_state = "TMpacket"
brand = "\improper Temperamento Menthol"
starts_with = list(/obj/item/clothing/mask/smokable/cigarette/menthol = 6)
/obj/item/weapon/storage/fancy/cigarettes/carcinomas
name = "\improper pack of Carcinoma Angels"
desc = "This unknown brand was slated for the chopping block, until they were publicly endorsed by an old Earthling gonzo journalist. The rest is history. They sell a variety for cats, too."
icon_state = "CApacket"
desc = "This previously unknown brand was slated for the chopping block, until they were publicly endorsed by an old Earthling gonzo journalist. The rest is history. They sell a variety for cats, too."
description_fluff = "The bitter taste of a Carcinoma Angel is considered desirable by many equally bitter wash-ups who consider themselves to be 'hard-boiled'. The smell is practically inseparable from urban security offices, and old men with exonet radio shows."
brand = "\improper Carcinoma Angel"
/obj/item/weapon/storage/fancy/cigarettes/professionals
name = "\improper pack of Professional 120s"
desc = "Let's face it - if you're smoking these, you're either trying to look upper-class or you're 80 years old. That's the only excuse. They are, however, very good quality."
description_fluff = "Grown and rolled in a meticulously maintained biosphere orbitting Love, P120 tobacco is marketed as 'probably the best in the galaxy'. The premium price point, and the fact that the vast majority of consumers couldn't really tell the difference between this and the next leading brand."
icon_state = "P100packet"
brand = "\improper Professional 120"
/obj/item/weapon/storage/fancy/cigar
name = "cigar case"
desc = "A case for holding your cigars when you are not smoking them."
description_fluff = "The tastefully engraved palm tree tells you that these 'Palma Grande' premium cigars are only sold on the luxury cruises and resorts of Oasis, though ten separate companies produce them for that purpose galaxy-wide. The standard is however very high."
icon_state = "cigarcase"
icon = 'icons/obj/cigarettes.dmi'
w_class = ITEMSIZE_TINY
@@ -15,7 +15,8 @@
throw_range = 8
max_storage_space = ITEMSIZE_COST_SMALL * 7 // 14
var/list/icon_variety
drop_sound = 'sound/items/drop/box.ogg'
drop_sound = 'sound/items/drop/cardboardbox.ogg'
pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
/obj/item/weapon/storage/firstaid/Initialize()
. = ..()
@@ -173,6 +174,7 @@
icon_state = "pill_canister"
icon = 'icons/obj/chemical.dmi'
drop_sound = 'sound/items/drop/pillbottle.ogg'
pickup_sound = 'sound/items/pickup/pillbottle.ogg'
item_state_slots = list(slot_r_hand_str = "contsolid", slot_l_hand_str = "contsolid")
w_class = ITEMSIZE_SMALL
can_hold = list(/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/dice,/obj/item/weapon/paper)
@@ -362,6 +362,8 @@
usr.client.screen -= W
W.dropped(usr)
add_fingerprint(usr)
if (use_sound)
playsound(src, src.use_sound, 50, 0, -5) //Something broke "add item to container" sounds, this is a hacky fix.
if(!prevent_warning)
for(var/mob/M in viewers(usr, null))
@@ -15,7 +15,8 @@
origin_tech = list(TECH_COMBAT = 1)
attack_verb = list("robusted")
use_sound = 'sound/items/storage/toolbox.ogg'
drop_sound = 'sound/items/drop/metalboots.ogg'
drop_sound = 'sound/items/drop/toolbox.ogg'
pickup_sound = 'sound/items/pickup/toolbox.ogg'
/obj/item/weapon/storage/toolbox/emergency
name = "emergency toolbox"
@@ -128,6 +128,12 @@
/obj/item/weapon/storage/box/syndie_kit/imp_aug/sprinter
case_type = /obj/item/weapon/implantcase/sprinter
/obj/item/weapon/storage/box/syndie_kit/imp_aug/armblade
case_type = /obj/item/weapon/implantcase/armblade
/obj/item/weapon/storage/box/syndie_kit/imp_aug/handblade
case_type = /obj/item/weapon/implantcase/handblade
/obj/item/weapon/storage/box/syndie_kit/space
name = "boxed space suit and helmet"
@@ -43,6 +43,9 @@
var/obj/item/weapon/card/id/front_id = null
drop_sound = 'sound/items/drop/leather.ogg'
pickup_sound = 'sound/items/pickup/leather.ogg'
/obj/item/weapon/storage/wallet/remove_from_storage(obj/item/W as obj, atom/new_location)
. = ..(W, new_location)
if(.)
@@ -11,6 +11,8 @@
throwforce = 7
flags = NOCONDUCT
w_class = ITEMSIZE_NORMAL
drop_sound = 'sound/items/drop/metalweapon.ogg'
pickup_sound = 'sound/items/pickup/metalweapon.ogg'
origin_tech = list(TECH_COMBAT = 2)
attack_verb = list("beaten")
var/lightcolor = "#FF6A00"
@@ -13,6 +13,8 @@
desc = "This shouldn't be here, ahelp it."
icon = 'icons/obj/surgery.dmi'
w_class = ITEMSIZE_SMALL
drop_sound = 'sound/items/drop/weldingtool.ogg'
pickup_sound = 'sound/items/pickup/weldingtool.ogg'
var/helpforce = 0 //For help intent things
/obj/item/weapon/surgical/attack(mob/M, mob/user)
@@ -26,6 +26,8 @@
item_state = "classic_baton"
slot_flags = SLOT_BELT
force = 10
drop_sound = 'sound/items/drop/crowbar.ogg'
pickup_sound = 'sound/items/pickup/crowbar.ogg'
/obj/item/weapon/melee/classic_baton/attack(mob/M as mob, mob/living/user as mob)
if ((CLUMSY in user.mutations) && prob(50))
@@ -49,6 +51,8 @@
slot_flags = SLOT_BELT
w_class = ITEMSIZE_SMALL
force = 3
drop_sound = 'sound/items/drop/crowbar.ogg'
pickup_sound = 'sound/items/pickup/crowbar.ogg'
var/on = 0
/obj/item/weapon/melee/telebaton/attack_self(mob/user as mob)
@@ -58,21 +58,27 @@
to_chat(usr, "You toggle the thrusters [on? "on":"off"].")
/obj/item/weapon/tank/jetpack/proc/allow_thrust(num, mob/living/user as mob)
/obj/item/weapon/tank/jetpack/proc/get_gas_supply()
return air_contents
/obj/item/weapon/tank/jetpack/proc/can_thrust(num)
if(!on)
return 0
if((num < 0.005 || air_contents.total_moles < num))
var/datum/gas_mixture/fuel = get_gas_supply()
if(num < 0.005 || !fuel || fuel.total_moles < num)
ion_trail.stop()
return 0
var/datum/gas_mixture/G = air_contents.remove(num)
return 1
var/allgases = G.gas["carbon_dioxide"] + G.gas["nitrogen"] + G.gas["oxygen"] + G.gas["phoron"]
if(allgases >= 0.005)
return 1
/obj/item/weapon/tank/jetpack/proc/do_thrust(num, mob/living/user)
if(!can_thrust(num))
return 0
qdel(G)
return
var/datum/gas_mixture/fuel = get_gas_supply()
fuel.remove(num)
return 1
/obj/item/weapon/tank/jetpack/ui_action_click()
toggle()
@@ -116,24 +122,5 @@
. = ..()
. += "It's a jetpack. If you can see this, report it on the bug tracker."
/obj/item/weapon/tank/jetpack/rig/allow_thrust(num, mob/living/user as mob)
if(!(src.on))
return 0
if(!istype(holder) || !holder.air_supply)
return 0
var/obj/item/weapon/tank/pressure_vessel = holder.air_supply
if((num < 0.005 || pressure_vessel.air_contents.total_moles < num))
src.ion_trail.stop()
return 0
var/datum/gas_mixture/G = pressure_vessel.air_contents.remove(num)
var/allgases = G.gas["carbon_dioxide"] + G.gas["nitrogen"] + G.gas["oxygen"] + G.gas["phoron"]
if(allgases >= 0.005)
return 1
qdel(G)
return
/obj/item/weapon/tank/jetpack/rig/get_gas_supply()
return holder?.air_supply?.air_contents
@@ -45,7 +45,7 @@
. = ..()
air_contents.gas["oxygen"] = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
air_contents.gas["sleeping_agent"] = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
air_contents.gas["nitrous_oxide"] = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
air_contents.update_values()
/*
@@ -11,6 +11,7 @@ var/list/global/tank_gauge_cache = list()
SPECIES_TESHARI = 'icons/mob/species/seromi/back.dmi'
)
drop_sound = 'sound/items/drop/gascan.ogg'
pickup_sound = 'sound/items/pickup/gascan.ogg'
var/gauge_icon = "indicator_tank"
var/last_gauge_pressure
@@ -42,14 +43,14 @@ var/list/global/tank_gauge_cache = list()
description_info = "These tanks are utilised to store any of the various types of gaseous substances. \
They can be attached to various portable atmospheric devices to be filled or emptied. <br>\
<br>\
Each tank is fitted with an emergency relief valve. This relief valve will open if the tank is pressurised to over ~3000kPa or heated to over 173ºC. \
Each tank is fitted with an emergency relief valve. This relief valve will open if the tank is pressurised to over ~3000kPa or heated to over 173ºC. \
The valve itself will close after expending most or all of the contents into the air.<br>\
<br>\
Filling a tank such that experiences ~4000kPa of pressure will cause the tank to rupture, spilling out its contents and destroying the tank. \
Tanks filled over ~5000kPa will rupture rather violently, exploding with significant force."
description_antag = "Each tank may be incited to burn by attaching wires and an igniter assembly, though the igniter can only be used once and the mixture only burn if the igniter pushes a flammable gas mixture above the minimum burn temperature (126ºC). \
Wired and assembled tanks may be disarmed with a set of wirecutters. Any exploding or rupturing tank will generate shrapnel, assuming their relief valves have been welded beforehand. Even if not, they can be incited to expel hot gas on ignition if pushed above 173ºC. \
description_antag = "Each tank may be incited to burn by attaching wires and an igniter assembly, though the igniter can only be used once and the mixture only burn if the igniter pushes a flammable gas mixture above the minimum burn temperature (126ºC). \
Wired and assembled tanks may be disarmed with a set of wirecutters. Any exploding or rupturing tank will generate shrapnel, assuming their relief valves have been welded beforehand. Even if not, they can be incited to expel hot gas on ignition if pushed above 173ºC. \
Relatively easy to make, the single tank bomb requries no tank transfer valve, and is still a fairly formidable weapon that can be manufactured from any tank."
/obj/item/weapon/tank/proc/init_proxy()
@@ -119,9 +120,6 @@ var/list/global/tank_gauge_cache = list()
if (istype(src.loc, /obj/item/assembly))
icon = src.loc
if ((istype(W, /obj/item/device/analyzer)) && get_dist(user, src) <= 1)
var/obj/item/device/analyzer/A = W
A.analyze_gases(src, user)
else if (istype(W,/obj/item/latexballon))
var/obj/item/latexballon/LB = W
LB.blow(src)
@@ -423,7 +421,7 @@ var/list/global/tank_gauge_cache = list()
pressure = air_contents.return_pressure()
var/strength = ((pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE)
var/mult = ((src.air_contents.volume/140)**(1/2)) * (air_contents.total_moles**2/3)/((29*0.64) **2/3) //tanks appear to be experiencing a reduction on scale of about 0.64 total moles
var/mult = ((src.air_contents.volume/140)**(1/2)) * (air_contents.total_moles**(2/3))/((29*0.64) **(2/3)) //tanks appear to be experiencing a reduction on scale of about 0.64 total moles
//tanks appear to be experiencing a reduction on scale of about 0.64 total moles
+16 -40
View File
@@ -4,23 +4,26 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "taperoll"
w_class = ITEMSIZE_TINY
drop_sound = 'sound/items/drop/box.ogg'
drop_sound = 'sound/items/drop/cardboardbox.ogg'
pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
toolspeed = 2 //It is now used in surgery as a not awful, but probably dangerous option, due to speed.
/obj/item/weapon/tape_roll/proc/can_place(var/mob/living/carbon/human/H, var/mob/user)
if(istype(user, /mob/living/silicon/robot) || user == H)
return TRUE
for (var/obj/item/weapon/grab/G in H.grabbed_by)
if (G.loc == user && G.state >= GRAB_AGGRESSIVE)
return TRUE
return FALSE
/obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user)
if(istype(H))
if(user.a_intent == I_HELP)
return
var/can_place = 0
if(istype(user, /mob/living/silicon/robot))
can_place = 1
else
for (var/obj/item/weapon/grab/G in H.grabbed_by)
if (G.loc == user && G.state >= GRAB_AGGRESSIVE)
can_place = 1
break
if(!can_place)
if(!can_place(H, user))
to_chat(user, "<span class='danger'>You need to have a firm grip on [H] before you can use \the [src]!</span>")
return
else
@@ -43,16 +46,7 @@
if(!do_after(user, 30))
return
can_place = 0
if(istype(user, /mob/living/silicon/robot))
can_place = 1
else
for (var/obj/item/weapon/grab/G in H.grabbed_by)
if (G.loc == user && G.state >= GRAB_AGGRESSIVE)
can_place = 1
if(!can_place)
if(!can_place(H, user))
return
if(!H || !src || !H.organs_by_name[BP_HEAD] || !H.has_eyes() || H.glasses || (H.head && (H.head.body_parts_covered & FACE)))
@@ -81,16 +75,7 @@
if(!do_after(user, 30))
return
can_place = 0
if(istype(user, /mob/living/silicon/robot))
can_place = 1
else
for (var/obj/item/weapon/grab/G in H.grabbed_by)
if (G.loc == user && G.state >= GRAB_AGGRESSIVE)
can_place = 1
if(!can_place)
if(!can_place(H, user))
return
if(!H || !src || !H.organs_by_name[BP_HEAD] || !H.check_has_mouth() || (H.head && (H.head.body_parts_covered & FACE)))
@@ -103,16 +88,7 @@
playsound(src, 'sound/effects/tape.ogg',25)
else if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand")
can_place = 0
if(istype(user, /mob/living/silicon/robot))
can_place = 1
else
for (var/obj/item/weapon/grab/G in H.grabbed_by)
if (G.loc == user && G.state >= GRAB_AGGRESSIVE)
can_place = 1
if(!can_place)
if(!can_place(H, user))
return
var/obj/item/weapon/handcuffs/cable/tape/T = new(user)
@@ -10,6 +10,8 @@
icon = 'icons/obj/items.dmi'
icon_state = "combitool"
w_class = ITEMSIZE_SMALL
drop_sound = 'sound/items/drop/multitool.ogg'
pickup_sound = 'sound/items/pickup/multitool.ogg'
var/list/spawn_tools = list(
/obj/item/weapon/tool/screwdriver,
@@ -17,7 +17,8 @@
matter = list(DEFAULT_WALL_MATERIAL = 50)
attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked")
usesound = 'sound/items/crowbar.ogg'
drop_sound = 'sound/items/drop/sword.ogg'
drop_sound = 'sound/items/drop/crowbar.ogg'
pickup_sound = 'sound/items/pickup/crowbar.ogg'
toolspeed = 1
/obj/item/weapon/tool/crowbar/is_crowbar()
@@ -15,7 +15,8 @@
throw_range = 5
hitsound = 'sound/weapons/bladeslice.ogg'
usesound = 'sound/items/screwdriver.ogg'
drop_sound = 'sound/items/drop/scrap.ogg'
drop_sound = 'sound/items/drop/screwdriver.ogg'
pickup_sound = 'sound/items/pickup/screwdriver.ogg'
matter = list(DEFAULT_WALL_MATERIAL = 75)
attack_verb = list("stabbed")
sharp = 1
@@ -37,7 +37,8 @@
var/burned_fuel_for = 0 // Keeps track of how long the welder's been on, used to gradually empty the welder if left one, without RNG.
var/always_process = FALSE // If true, keeps the welder on the process list even if it's off. Used for when it needs to regenerate fuel.
toolspeed = 1
drop_sound = 'sound/items/drop/scrap.ogg'
drop_sound = 'sound/items/drop/weldingtool.ogg'
pickup_sound = 'sound/items/pickup/weldingtool.ogg'
/obj/item/weapon/weldingtool/Initialize()
. = ..()
@@ -17,7 +17,8 @@
attack_verb = list("pinched", "nipped")
hitsound = 'sound/items/wirecutter.ogg'
usesound = 'sound/items/wirecutter.ogg'
drop_sound = 'sound/items/drop/knife.ogg'
drop_sound = 'sound/items/drop/wirecutter.ogg'
pickup_sound = 'sound/items/pickup/wirecutter.ogg'
sharp = 1
edge = 1
toolspeed = 1
@@ -15,7 +15,8 @@
attack_verb = list("bashed", "battered", "bludgeoned", "whacked")
usesound = 'sound/items/ratchet.ogg'
toolspeed = 1
drop_sound = 'sound/items/drop/sword.ogg'
drop_sound = 'sound/items/drop/wrench.ogg'
pickup_sound = 'sound/items/pickup/wrench.ogg'
/obj/item/weapon/tool/wrench/is_wrench()
return TRUE
+12 -1
View File
@@ -8,7 +8,18 @@
attack_verb = list("whipped")
hitsound = 'sound/weapons/towelwhip.ogg'
desc = "A soft cotton towel."
drop_sound = 'sound/items/drop/clothing.ogg'
drop_sound = 'sound/items/drop/cloth.ogg'
pickup_sound = 'sound/items/pickup/cloth.ogg'
/obj/item/weapon/towel/equipped(var/M, var/slot)
..()
switch(slot)
if(slot_head)
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/head.dmi')
if(slot_wear_suit)
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/suit.dmi')
if(slot_belt)
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/belt.dmi')
/obj/item/weapon/towel/attack_self(mob/living/user as mob)
user.visible_message(text("<span class='notice'>[] uses [] to towel themselves off.</span>", user, src))
@@ -10,6 +10,7 @@
throwforce = 10
w_class = ITEMSIZE_SMALL
drop_sound = 'sound/items/drop/sword.ogg'
pickup_sound = 'sound/items/pickup/sword.ogg'
suicide_act(mob/user)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
@@ -10,6 +10,7 @@
var/nozzle_type = /obj/item/weapon/weldingtool/tubefed
var/nozzle_attached = 0
drop_sound = 'sound/items/drop/backpack.ogg'
pickup_sound = 'sound/items/pickup/backpack.ogg'
/obj/item/weapon/weldpack/Initialize()
. = ..()