mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-29 06:58:30 +01:00
Merge remote-tracking branch 'VOREStation/master' into upstream-merge-7919
This commit is contained in:
@@ -40,10 +40,7 @@
|
||||
return TRUE
|
||||
|
||||
/atom/movable/proc/has_buckled_mobs()
|
||||
if(!buckled_mobs)
|
||||
return FALSE
|
||||
if(buckled_mobs.len)
|
||||
return TRUE
|
||||
return LAZYLEN(buckled_mobs)
|
||||
|
||||
/atom/movable/Destroy()
|
||||
unbuckle_all_mobs()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
create_reagents(100)
|
||||
|
||||
/obj/effect/decal/cleanable/chemcoating/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
for(var/obj/O in get_turf(src))
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/obj/effect/decal/warning_stripes
|
||||
icon = 'icons/effects/warning_stripes.dmi'
|
||||
|
||||
/obj/effect/decal/warning_stripes/New()
|
||||
/obj/effect/decal/warning_stripes/Initialize()
|
||||
. = ..()
|
||||
var/turf/T=get_turf(src)
|
||||
var/image/I=image(icon, icon_state = icon_state, dir = dir)
|
||||
I.color=color
|
||||
T.overlays += I
|
||||
qdel(src)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
@@ -10,32 +10,37 @@
|
||||
var/obj/item/weapon/mine/mineitemtype = /obj/item/weapon/mine
|
||||
var/panel_open = 0
|
||||
var/datum/wires/mines/wires = null
|
||||
register_as_dangerous_object = TRUE
|
||||
|
||||
var/camo_net = FALSE // Will the mine 'cloak' on deployment?
|
||||
|
||||
// The trap item will be triggered in some manner when detonating. Default only checks for grenades.
|
||||
var/obj/item/trap = null
|
||||
|
||||
/obj/effect/mine/New()
|
||||
/obj/effect/mine/Initialize()
|
||||
icon_state = "uglyminearmed"
|
||||
wires = new(src)
|
||||
|
||||
. = ..()
|
||||
if(ispath(trap))
|
||||
trap = new trap(src)
|
||||
|
||||
/obj/effect/mine/Initialize()
|
||||
..()
|
||||
|
||||
register_dangerous_to_step()
|
||||
if(camo_net)
|
||||
alpha = 50
|
||||
|
||||
/obj/effect/mine/Destroy()
|
||||
unregister_dangerous_to_step()
|
||||
if(trap)
|
||||
QDEL_NULL(trap)
|
||||
qdel_null(wires)
|
||||
return ..()
|
||||
|
||||
/obj/effect/mine/Moved(atom/oldloc)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/turf/old_turf = get_turf(oldloc)
|
||||
var/turf/new_turf = get_turf(src)
|
||||
if(old_turf != new_turf)
|
||||
old_turf.unregister_dangerous_object(src)
|
||||
new_turf.register_dangerous_object(src)
|
||||
|
||||
/obj/effect/mine/proc/explode(var/mob/living/M)
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
|
||||
triggered = 1
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
..()
|
||||
|
||||
/obj/effect/temporary_effect/eruption/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
flick("[icon_state]_create",src)
|
||||
|
||||
/obj/effect/temporary_effect/eruption/Destroy()
|
||||
|
||||
@@ -159,7 +159,6 @@
|
||||
|
||||
/obj/effect/spawner/newbomb/Initialize(newloc)
|
||||
..(newloc)
|
||||
|
||||
var/obj/item/device/transfer_valve/V = new(src.loc)
|
||||
var/obj/item/weapon/tank/phoron/PT = new(V)
|
||||
var/obj/item/weapon/tank/oxygen/OT = new(V)
|
||||
@@ -183,19 +182,14 @@
|
||||
OT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
|
||||
OT.air_contents.update_values()
|
||||
|
||||
|
||||
var/obj/item/device/assembly/S = new assembly_type(V)
|
||||
|
||||
|
||||
V.attached_device = S
|
||||
|
||||
S.holder = V
|
||||
S.toggle_secure()
|
||||
|
||||
V.update_icon()
|
||||
|
||||
qdel(src)
|
||||
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
|
||||
///////////////////////
|
||||
|
||||
@@ -26,7 +26,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
show_messages = 1
|
||||
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2, TECH_DATA = 2)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10, MAT_COPPER = 10)
|
||||
|
||||
var/video_range = 3
|
||||
var/obj/machinery/camera/communicator/video_source // Their camera
|
||||
@@ -131,7 +131,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
|
||||
for(var/mob/living/voice/voice in contents)
|
||||
. += "<span class='notice'>On the screen, you can see a image feed of [voice].</span>"
|
||||
|
||||
|
||||
if(voice && voice.key)
|
||||
switch(voice.stat)
|
||||
if(CONSCIOUS)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
var/cell_type = /obj/item/weapon/cell/device
|
||||
|
||||
/obj/item/device/flash/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
power_supply = new cell_type(src)
|
||||
|
||||
/obj/item/device/flash/attackby(var/obj/item/W, var/mob/user)
|
||||
|
||||
@@ -9,24 +9,119 @@ var/list/GPS_list = list()
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = list(TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_MAGNET = 1)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 500)
|
||||
|
||||
var/gps_tag = "GEN0"
|
||||
var/emped = FALSE
|
||||
var/updating = TRUE // Lets users lock the UI so they don't have to deal with constantly shifting signals
|
||||
var/tracking = FALSE // Will not show other signals or emit its own signal if false.
|
||||
var/long_range = FALSE // If true, can see farther, depending on get_map_levels().
|
||||
var/local_mode = FALSE // If true, only GPS signals of the same Z level are shown.
|
||||
var/hide_signal = FALSE // If true, signal is not visible to other GPS devices.
|
||||
var/can_hide_signal = FALSE // If it can toggle the above var.
|
||||
|
||||
var/mob/holder
|
||||
var/is_in_processing_list = FALSE
|
||||
var/list/tracking_devices
|
||||
var/list/showing_tracked_names
|
||||
var/obj/compass_holder/compass
|
||||
|
||||
/obj/item/device/gps/Initialize()
|
||||
. = ..()
|
||||
compass = new(src)
|
||||
GPS_list += src
|
||||
name = "global positioning system ([gps_tag])"
|
||||
update_holder()
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/gps/proc/check_visible_to_holder()
|
||||
. = (holder && (holder.get_active_hand() == src || holder.get_inactive_hand() == src))
|
||||
|
||||
/obj/item/device/gps/proc/update_holder()
|
||||
|
||||
if(holder && loc != holder)
|
||||
GLOB.moved_event.unregister(holder, src)
|
||||
GLOB.dir_set_event.unregister(holder, src)
|
||||
holder.client?.screen -= compass
|
||||
holder = null
|
||||
|
||||
if(istype(loc, /mob))
|
||||
holder = loc
|
||||
GLOB.moved_event.register(holder, src, .proc/update_compass)
|
||||
GLOB.dir_set_event.register(holder, src, .proc/update_compass)
|
||||
|
||||
if(holder && tracking)
|
||||
if(!is_in_processing_list)
|
||||
START_PROCESSING(SSobj, src)
|
||||
is_in_processing_list = TRUE
|
||||
if(holder.client)
|
||||
if(check_visible_to_holder())
|
||||
holder.client.screen |= compass
|
||||
else
|
||||
holder.client.screen -= compass
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
is_in_processing_list = FALSE
|
||||
if(holder?.client)
|
||||
holder.client.screen -= compass
|
||||
|
||||
/obj/item/device/gps/pickup()
|
||||
. = ..()
|
||||
update_holder()
|
||||
|
||||
/obj/item/device/gps/equipped()
|
||||
. = ..()
|
||||
update_holder()
|
||||
|
||||
/obj/item/device/gps/dropped()
|
||||
. = ..()
|
||||
update_holder()
|
||||
|
||||
/obj/item/device/gps/process()
|
||||
if(!tracking)
|
||||
is_in_processing_list = FALSE
|
||||
return PROCESS_KILL
|
||||
update_holder()
|
||||
if(holder)
|
||||
update_compass(TRUE)
|
||||
|
||||
/obj/item/device/gps/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
is_in_processing_list = FALSE
|
||||
GPS_list -= src
|
||||
return ..()
|
||||
. = ..()
|
||||
update_holder()
|
||||
QDEL_NULL(compass)
|
||||
|
||||
/obj/item/device/gps/proc/can_track(var/obj/item/device/gps/other, var/reachable_z_levels)
|
||||
if(!other.tracking || other.emped || other.hide_signal)
|
||||
return FALSE
|
||||
var/turf/origin = get_turf(src)
|
||||
var/turf/target = get_turf(other)
|
||||
if(!istype(origin) || !istype(target))
|
||||
return FALSE
|
||||
if(origin.z == target.z)
|
||||
return TRUE
|
||||
if(local_mode)
|
||||
return FALSE
|
||||
reachable_z_levels = reachable_z_levels || using_map.get_map_levels(origin.z, long_range)
|
||||
return (target.z in reachable_z_levels)
|
||||
|
||||
/obj/item/device/gps/proc/update_compass(var/update_compass_icon)
|
||||
compass.hide_waypoints(FALSE)
|
||||
for(var/thing in tracking_devices)
|
||||
var/obj/item/device/gps/gps = locate(thing)
|
||||
if(!istype(gps) || QDELETED(gps))
|
||||
LAZYREMOVE(tracking_devices, thing)
|
||||
LAZYREMOVE(showing_tracked_names, thing)
|
||||
continue
|
||||
var/turf/gps_turf = get_turf(gps)
|
||||
var/gps_tag = LAZYACCESS(showing_tracked_names, thing) ? gps.gps_tag : null
|
||||
if(istype(gps_turf))
|
||||
compass.set_waypoint("\ref[gps]", gps_tag, gps_turf.x, gps_turf.y, gps_turf.z, LAZYACCESS(tracking_devices, "\ref[gps]"))
|
||||
else
|
||||
compass.set_waypoint("\ref[gps]", gps_tag, 0, 0, 0, LAZYACCESS(tracking_devices, "\ref[gps]"))
|
||||
if(can_track(gps))
|
||||
compass.show_waypoint("\ref[gps]")
|
||||
compass.rebuild_overlay_lists(update_compass_icon)
|
||||
|
||||
/obj/item/device/gps/AltClick(mob/user)
|
||||
toggletracking(user)
|
||||
@@ -37,14 +132,25 @@ var/list/GPS_list = list()
|
||||
if(emped)
|
||||
to_chat(user, "It's busted!")
|
||||
return
|
||||
|
||||
toggle_tracking()
|
||||
if(tracking)
|
||||
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
|
||||
tracking = FALSE
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
|
||||
tracking = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/gps/proc/toggle_tracking()
|
||||
tracking = !tracking
|
||||
if(tracking)
|
||||
if(!is_in_processing_list)
|
||||
is_in_processing_list = TRUE
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
is_in_processing_list = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_compass()
|
||||
update_holder()
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/gps/emp_act(severity)
|
||||
if(emped) // Without a fancy callback system, this will have to do.
|
||||
@@ -67,11 +173,7 @@ var/list/GPS_list = list()
|
||||
add_overlay("working")
|
||||
|
||||
/obj/item/device/gps/attack_self(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/device/gps/examine(mob/user)
|
||||
. = ..()
|
||||
. += display()
|
||||
display(user)
|
||||
|
||||
// Compiles all the data not available directly from the GPS
|
||||
// Like the positions and directions to all other GPS units
|
||||
@@ -90,15 +192,8 @@ var/list/GPS_list = list()
|
||||
dat["z_level_detection"] = using_map.get_map_levels(curr.z, long_range)
|
||||
|
||||
for(var/obj/item/device/gps/G in GPS_list - src)
|
||||
if(!G.tracking || G.emped || G.hide_signal)
|
||||
continue
|
||||
|
||||
var/turf/T = get_turf(G)
|
||||
if(!T)
|
||||
continue
|
||||
if(local_mode && curr.z != T.z)
|
||||
continue
|
||||
if(!(T.z in dat["z_level_detection"]))
|
||||
if(!can_track(G, dat["z_level_detection"]))
|
||||
continue
|
||||
|
||||
var/gps_data[0]
|
||||
@@ -108,6 +203,7 @@ var/list/GPS_list = list()
|
||||
var/area/A = get_area(G)
|
||||
gps_data["area_name"] = A.get_name()
|
||||
|
||||
var/turf/T = get_turf(G)
|
||||
gps_data["z_name"] = using_map.get_zlevel_name(T.z)
|
||||
gps_data["direction"] = get_adir(curr, T)
|
||||
gps_data["degrees"] = round(Get_Angle(curr,T))
|
||||
@@ -122,37 +218,102 @@ var/list/GPS_list = list()
|
||||
|
||||
return dat
|
||||
|
||||
/obj/item/device/gps/proc/display()
|
||||
if(!tracking)
|
||||
. = "The device is off. Alt-click it to turn it on."
|
||||
return
|
||||
/obj/item/device/gps/proc/display(mob/user)
|
||||
|
||||
if(emped)
|
||||
. = "It's busted!"
|
||||
to_chat(user, "It's busted!")
|
||||
return
|
||||
|
||||
var/list/dat = list()
|
||||
var/list/gps_data = display_list()
|
||||
|
||||
dat += "Current location: [gps_data["my_area_name"]] <b>([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])</b>"
|
||||
dat += "[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. <a href='?src=\ref[src];tag=1'>\[Change Tag\]</a> \
|
||||
<a href='?src=\ref[src];range=1'>\[Toggle Scan Range\]</a> \
|
||||
[can_hide_signal ? "<a href='?src=\ref[src];hide=1'>\[Toggle Signal Visibility\]</a>":""]"
|
||||
|
||||
if(gps_data["gps_list"].len)
|
||||
dat += "Detected signals;"
|
||||
for(var/gps in gps_data["gps_list"])
|
||||
if(istype(gps_data["ref"], /obj/item/device/gps/internal/poi))
|
||||
dat += " [gps["gps_tag"]]: [gps["area_name"]] - [gps["local"] ? "[gps["direction"]] Dist: [round(gps["distance"], 10)]m" : "in \the [gps["z_name"]]"]"
|
||||
else
|
||||
dat += " [gps["gps_tag"]]: [gps["area_name"]], ([gps["x"]], [gps["y"]]) - [gps["local"] ? "[gps["direction"]] Dist: [gps["distX"] ? "[abs(round(gps["distX"], 1))]m [(gps["distX"] > 0) ? "E" : "W"], " : ""][gps["distY"] ? "[abs(round(gps["distY"], 1))]m [(gps["distY"] > 0) ? "N" : "S"]" : ""]" : "in \the [gps["z_name"]]"]"
|
||||
dat += "<table width = '100%'>"
|
||||
if(!tracking)
|
||||
dat += "<tr><td colspan = 6></td><a href='?src=\ref[src];toggle_power=1'>\[Switch On]\]</a></tr>"
|
||||
else
|
||||
dat += "No other signals detected."
|
||||
dat += "<tr><td colspan = 6></td><a href='?src=\ref[src];toggle_power=1'>\[Switch Off]\]</a></tr>"
|
||||
dat += "<tr><td colspan = 2><b>Current location</b></td><td colspan = 2>[gps_data["my_area_name"]]</td><td colspan = 2><b>([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])</b></td></tr>"
|
||||
dat += "<tr><td colspan = 4>[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'.</td>"
|
||||
dat += "<td><a href='?src=\ref[src];tag=1'>\[Change Tag\]</a><a href='?src=\ref[src];range=1'>\[Toggle Scan Range\]</a>[can_hide_signal ? "<a href='?src=\ref[src];hide=1'>\[Toggle Signal Visibility\]</a>":""]</td></tr>"
|
||||
|
||||
. = dat
|
||||
if(gps_data["gps_list"].len)
|
||||
dat += "<tr><td colspan = 6><b>Detected signals</b></td></tr>"
|
||||
for(var/gps in gps_data["gps_list"])
|
||||
dat += "<tr>"
|
||||
var/gps_ref = "\ref[gps["ref"]]"
|
||||
dat += "<td>[gps["gps_tag"]]</td><td>[gps["area_name"]]</td>"
|
||||
|
||||
if(istype(gps_data["ref"], /obj/item/device/gps/internal/poi))
|
||||
dat += "<td>[gps["local"] ? "[gps["direction"]] Dist: [round(gps["distance"], 10)]m" : "in \the [gps["z_name"]]"]</td>"
|
||||
else
|
||||
dat += "<td>([gps["x"]], [gps["y"]], [gps["z_name"]])</td>"
|
||||
|
||||
if(gps["local"])
|
||||
dat += "<td>[gps["distance"]]m</td>"
|
||||
dat += "<td>[gps["degrees"]]° ([gps["direction"]])</td>"
|
||||
else
|
||||
dat += "<td colspan = 2>Non-local signal.</td>"
|
||||
|
||||
if(LAZYACCESS(tracking_devices, gps_ref))
|
||||
dat += "<td><a href='?src=\ref[src];stop_track=[gps_ref]'>\[Stop Tracking\]</a> <a href='?src=\ref[src];track_color=[gps_ref]'>\[Colour [color_square(hex = LAZYACCESS(tracking_devices, gps_ref))]\]</a> <a href='?src=\ref[src];track_label=[gps_ref]'>Show/Hide Label</a></td>"
|
||||
else
|
||||
dat += "<td><a href='?src=\ref[src];start_track=[gps_ref]'>\[Start Tracking\]</a></td>"
|
||||
dat += "</tr>"
|
||||
else
|
||||
dat += "<tr><td colspan = 5>No other signals detected.</td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
var/datum/browser/popup = new(user, "gps_\ref[src]", "Global Positioning System", 700, 1000)
|
||||
popup.set_content(dat.Join(null))
|
||||
popup.open()
|
||||
|
||||
/obj/item/device/gps/Topic(var/href, var/list/href_list)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(href_list["toggle_power"])
|
||||
toggle_tracking()
|
||||
. = TRUE
|
||||
|
||||
if(href_list["track_label"])
|
||||
var/gps_ref = href_list["track_label"]
|
||||
var/obj/item/device/gps/gps = locate(gps_ref)
|
||||
if(istype(gps) && !QDELETED(gps) && !LAZYACCESS(showing_tracked_names, gps_ref))
|
||||
LAZYSET(showing_tracked_names, gps_ref, TRUE)
|
||||
else
|
||||
LAZYREMOVE(showing_tracked_names, gps_ref)
|
||||
to_chat(usr, SPAN_NOTICE("\The [src] is [LAZYACCESS(showing_tracked_names, gps_ref) ? "now showing" : "no longer showing"] labels for [gps.gps_tag]."))
|
||||
|
||||
if(href_list["stop_track"])
|
||||
var/gps_ref = href_list["stop_track"]
|
||||
var/obj/item/device/gps/gps = locate(gps_ref)
|
||||
compass.clear_waypoint(gps_ref)
|
||||
LAZYREMOVE(tracking_devices, gps_ref)
|
||||
LAZYREMOVE(showing_tracked_names, gps_ref)
|
||||
if(istype(gps) && !QDELETED(gps))
|
||||
to_chat(usr, SPAN_NOTICE("\The [src] is no longer tracking [gps.gps_tag]."))
|
||||
update_compass()
|
||||
. = TRUE
|
||||
|
||||
if(href_list["start_track"])
|
||||
var/gps_ref = href_list["start_track"]
|
||||
var/obj/item/device/gps/gps = locate(gps_ref)
|
||||
if(istype(gps) && !QDELETED(gps))
|
||||
LAZYSET(tracking_devices, gps_ref, "#00ffff")
|
||||
LAZYSET(showing_tracked_names, gps_ref, TRUE)
|
||||
to_chat(usr, SPAN_NOTICE("\The [src] is now tracking [gps.gps_tag]."))
|
||||
update_compass()
|
||||
. = TRUE
|
||||
|
||||
if(href_list["track_color"])
|
||||
var/obj/item/device/gps/gps = locate(href_list["track_color"])
|
||||
if(istype(gps) && !QDELETED(gps))
|
||||
var/new_colour = input("Enter a new tracking color.", "GPS Waypoint Color") as color|null
|
||||
if(new_colour && istype(gps) && !QDELETED(gps) && holder == usr && !usr.incapacitated())
|
||||
to_chat(usr, SPAN_NOTICE("You adjust the colour \the [src] is using to highlight [gps.gps_tag]."))
|
||||
LAZYSET(tracking_devices, href_list["track_color"], new_colour)
|
||||
update_compass()
|
||||
. = TRUE
|
||||
|
||||
if(href_list["tag"])
|
||||
var/a = input("Please enter desired tag.", name, gps_tag) as text
|
||||
@@ -161,95 +322,22 @@ var/list/GPS_list = list()
|
||||
gps_tag = a
|
||||
name = "global positioning system ([gps_tag])"
|
||||
to_chat(usr, "You set your GPS's tag to '[gps_tag]'.")
|
||||
. = TRUE
|
||||
|
||||
if(href_list["range"])
|
||||
local_mode = !local_mode
|
||||
to_chat(usr, "You set the signal receiver to [local_mode ? "'NARROW'" : "'BROAD'"].")
|
||||
. = TRUE
|
||||
|
||||
if(href_list["hide"])
|
||||
if(!can_hide_signal)
|
||||
return
|
||||
hide_signal = !hide_signal
|
||||
to_chat(usr, "You set the device to [hide_signal ? "not " : ""]broadcast a signal while scanning for other signals.")
|
||||
. = TRUE
|
||||
|
||||
/obj/item/device/gps/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(emped)
|
||||
to_chat(user, "<span class='hear'>[src] fizzles weakly.</span>")
|
||||
return
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Gps", name)
|
||||
ui.open()
|
||||
ui.set_autoupdate(updating)
|
||||
|
||||
/obj/item/device/gps/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["power"] = tracking
|
||||
data["tag"] = gps_tag
|
||||
data["updating"] = updating
|
||||
data["globalmode"] = !local_mode
|
||||
if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
|
||||
return data
|
||||
|
||||
var/turf/curr = get_turf(src)
|
||||
data["currentArea"] = "[get_area_name(curr, TRUE)]"
|
||||
data["currentCoords"] = list(curr.x, curr.y, curr.z)
|
||||
data["currentCoordsText"] = "[curr.x], [curr.y], [using_map.get_zlevel_name(curr.z)]"
|
||||
|
||||
data["zLevelDetection"] = using_map.get_map_levels(curr.z, long_range)
|
||||
|
||||
var/list/signals = list()
|
||||
data["signals"] = list()
|
||||
|
||||
for(var/obj/item/device/gps/G in GPS_list - src)
|
||||
if(!G.tracking || G.emped || G.hide_signal)
|
||||
continue
|
||||
|
||||
var/turf/T = get_turf(G)
|
||||
if(!T)
|
||||
continue
|
||||
if(local_mode && curr.z != T.z)
|
||||
continue
|
||||
if(!(T.z in data["zLevelDetection"]))
|
||||
continue
|
||||
|
||||
var/list/signal = list()
|
||||
signal["entrytag"] = G.gps_tag //Name or 'tag' of the GPS
|
||||
signal["coords"] = list(T.x, T.y, T.z)
|
||||
signal["coordsText"] = "[T.x], [T.y], [using_map.get_zlevel_name(T.z)]"
|
||||
if(T.z == curr.z) //Distance/Direction calculations for same z-level only
|
||||
signal["dist"] = max(get_dist(curr, T), 0) //Distance between the src and remote GPS turfs
|
||||
signal["degrees"] = round(Get_Angle(curr, T)) //0-360 degree directional bearing, for more precision.
|
||||
signals += list(signal) //Add this signal to the list of signals
|
||||
data["signals"] = signals
|
||||
return data
|
||||
|
||||
/obj/item/device/gps/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("rename")
|
||||
var/a = stripped_input(usr, "Please enter desired tag.", name, gps_tag, 20)
|
||||
|
||||
if(!a)
|
||||
return
|
||||
|
||||
gps_tag = a
|
||||
name = "global positioning system ([gps_tag])"
|
||||
. = TRUE
|
||||
|
||||
if("power")
|
||||
toggletracking(usr)
|
||||
. = TRUE
|
||||
|
||||
if("updating")
|
||||
updating = !updating
|
||||
. = TRUE
|
||||
|
||||
if("globalmode")
|
||||
local_mode = !local_mode
|
||||
. = TRUE
|
||||
if(. && loc == usr)
|
||||
display(usr)
|
||||
|
||||
/obj/item/device/gps/on // Defaults to off to avoid polluting the signal list with a bunch of GPSes without owners. If you need to spawn active ones, use these.
|
||||
tracking = TRUE
|
||||
@@ -373,26 +461,43 @@ var/list/GPS_list = list()
|
||||
can_hide_signal = TRUE
|
||||
|
||||
/obj/item/device/gps/syndie/display(mob/user)
|
||||
if(!tracking)
|
||||
. = "The device is off. Alt-click it to turn it on."
|
||||
return
|
||||
|
||||
if(emped)
|
||||
. = "It's busted!"
|
||||
to_chat(user, "It's busted!")
|
||||
return
|
||||
|
||||
var/list/dat = list()
|
||||
var/list/gps_data = display_list()
|
||||
|
||||
dat += "Current location: [gps_data["my_area_name"]] <b>([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])</b>"
|
||||
dat += "[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. <a href='?src=\ref[src];tag=1'>\[Change Tag\]</a> \
|
||||
<a href='?src=\ref[src];range=1'>\[Toggle Scan Range\]</a> \
|
||||
[can_hide_signal ? "<a href='?src=\ref[src];hide=1'>\[Toggle Signal Visibility\]</a>":""]"
|
||||
|
||||
if(gps_data["gps_list"].len)
|
||||
dat += "Detected signals;"
|
||||
for(var/gps in gps_data["gps_list"])
|
||||
dat += " [gps["gps_tag"]]: [gps["area_name"]] ([gps["x"]], [gps["y"]], [gps["z_name"]]) [gps["local"] ? "Dist: [gps["distance"]]m Dir: [gps["degrees"]]° ([gps["direction"]])" :""]"
|
||||
dat += "<table width = '100%'>"
|
||||
if(!tracking)
|
||||
dat += "<tr><td colspan = 6></td><a href='?src=\ref[src];toggle_power=1'>\[Switch On]\]</a></tr>"
|
||||
else
|
||||
dat += "No other signals detected."
|
||||
dat += "<tr><td colspan = 6></td><a href='?src=\ref[src];toggle_power=1'>\[Switch Off]\]</a></tr>"
|
||||
dat += "<tr><td colspan = 2><b>Current location</b></td><td colspan = 2>[gps_data["my_area_name"]]</td><td colspan = 2><b>([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])</b></td></tr>"
|
||||
dat += "<tr><td colspan = 4>[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'.</td>"
|
||||
dat += "<td><a href='?src=\ref[src];tag=1'>\[Change Tag\]</a><a href='?src=\ref[src];range=1'>\[Toggle Scan Range\]</a>[can_hide_signal ? "<a href='?src=\ref[src];hide=1'>\[Toggle Signal Visibility\]</a>":""]</td></tr>"
|
||||
|
||||
. = dat
|
||||
if(gps_data["gps_list"].len)
|
||||
dat += "<tr><td colspan = 6><b>Detected signals</b></td></tr>"
|
||||
for(var/gps in gps_data["gps_list"])
|
||||
dat += "<tr>"
|
||||
var/gps_ref = "\ref[gps["ref"]]"
|
||||
dat += "<td>[gps["gps_tag"]]</td><td>[gps["area_name"]] ([gps["x"]], [gps["y"]], [gps["z_name"]])</td>"
|
||||
if(gps["local"])
|
||||
dat += "<td>[gps["distance"]]m</td>"
|
||||
dat += "<td>[gps["degrees"]]° ([gps["direction"]])</td>"
|
||||
else
|
||||
dat += "<td colspan = 2>Non-local signal.</td>"
|
||||
if(LAZYACCESS(tracking_devices, gps_ref))
|
||||
dat += "<td><a href='?src=\ref[src];stop_track=[gps_ref]'>\[Stop Tracking\]</a> <a href='?src=\ref[src];track_color=[gps_ref]'>\[Colour [color_square(hex = LAZYACCESS(tracking_devices, gps_ref))]\]</a> <a href='?src=\ref[src];track_label=[gps_ref]'>Show/Hide Label</a></td>"
|
||||
else
|
||||
dat += "<td><a href='?src=\ref[src];start_track=[gps_ref]'>\[Start Tracking\]</a></td>"
|
||||
dat += "</tr>"
|
||||
else
|
||||
dat += "<tr><td colspan = 6>No other signals detected.</td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
var/datum/browser/popup = new(user, "gps_\ref[src]", "Global Positioning System", 700, 1000)
|
||||
popup.set_content(dat.Join(null))
|
||||
popup.open()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
item_state = "pen"
|
||||
var/pointer_icon_state
|
||||
slot_flags = SLOT_BELT
|
||||
matter = list("glass" = 500,"metal" = 500)
|
||||
matter = list("glass" = 500,"metal" = 500, MAT_COPPER = 10)
|
||||
w_class = 2 //Increased to 2, because diodes are w_class 2. Conservation of matter.
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_COMBAT = 1)
|
||||
var/turf/pointer_loc
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
drop_sound = 'sound/items/drop/multitool.ogg'
|
||||
pickup_sound = 'sound/items/pickup/multitool.ogg'
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20, MAT_COPPER = 10)
|
||||
|
||||
var/mode_index = 1
|
||||
var/toolmode = MULTITOOL_MODE_STANDARD
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = ITEMSIZE_HUGE
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 10000,"glass" = 2500)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 10000,"glass" = 2500, MAT_COPPER = 1550)
|
||||
|
||||
var/code = 2
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
desc = "A headset used by pilots, has access to the explorer channel."
|
||||
icon_state = "pilot_headset"
|
||||
adhoc_fallback = TRUE
|
||||
ks2type = /obj/item/device/encryptionkey/pilot
|
||||
|
||||
/obj/item/device/radio/headset/pilot/alt
|
||||
name = "pilot's bowman headset"
|
||||
@@ -120,7 +119,7 @@
|
||||
desc = "A headset used by volunteers to expedition teams, has access to the exploration channel."
|
||||
icon_state = "pilot_headset"
|
||||
adhoc_fallback = TRUE
|
||||
ks2type = /obj/item/device/encryptionkey/pilot
|
||||
ks2type = /obj/item/device/encryptionkey/explorer
|
||||
|
||||
/obj/item/device/radio/headset/talon
|
||||
name = "talon headset"
|
||||
|
||||
@@ -61,7 +61,7 @@ var/global/list/default_medbay_channels = list(
|
||||
var/bs_tx_preload_id
|
||||
var/bs_rx_preload_id
|
||||
|
||||
matter = list("glass" = 25,DEFAULT_WALL_MATERIAL = 75)
|
||||
matter = list("glass" = 25, DEFAULT_WALL_MATERIAL = 75, MAT_COPPER = 15)
|
||||
var/const/FREQ_LISTENING = 1
|
||||
var/list/internal_channels
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ HALOGEN COUNTER - Radcount on mobs
|
||||
w_class = ITEMSIZE_SMALL
|
||||
throw_speed = 5
|
||||
throw_range = 10
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 200)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 200, MAT_COPPER = 25)
|
||||
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1)
|
||||
var/mode = 1;
|
||||
var/advscan = 0
|
||||
|
||||
@@ -7,15 +7,12 @@
|
||||
var/obj/item/stack/type_to_spawn = null
|
||||
|
||||
/obj/fiftyspawner/Initialize()
|
||||
..() //We're not returning . because we're going to ask to be deleted.
|
||||
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/stack/M = new type_to_spawn(T)
|
||||
var/obj/structure/closet/C = locate() in T
|
||||
var/obj/item/stack/M = new type_to_spawn(C || T)
|
||||
M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty
|
||||
M.update_icon() // Some stacks have different sprites depending on how full they are.
|
||||
var/obj/structure/closet/C = locate() in T
|
||||
if(C)
|
||||
C.contents += M
|
||||
return INITIALIZE_HINT_QDEL //Bye!
|
||||
|
||||
/obj/fiftyspawner/rods
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
max_amount = 60
|
||||
attack_verb = list("hit", "bludgeoned", "whacked")
|
||||
|
||||
color = "#666666"
|
||||
|
||||
/obj/item/stack/rods/cyborg
|
||||
name = "metal rod synthesizer"
|
||||
desc = "A device that makes metal rods."
|
||||
@@ -24,8 +26,8 @@
|
||||
stacktype = /obj/item/stack/rods
|
||||
no_variants = TRUE
|
||||
|
||||
/obj/item/stack/rods/New()
|
||||
..()
|
||||
/obj/item/stack/rods/Initialize()
|
||||
. = ..()
|
||||
recipes = rods_recipes
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -32,19 +32,15 @@
|
||||
|
||||
bag_material = MAT_SYNCLOTH
|
||||
|
||||
/obj/item/stack/sandbags/New(var/newloc, var/amt, var/bag_mat)
|
||||
..()
|
||||
/obj/item/stack/sandbags/Initialize(var/ml, var/amt, var/bag_mat)
|
||||
. = ..(ml, amt)
|
||||
recipes = sandbag_recipes
|
||||
update_icon()
|
||||
|
||||
if(bag_mat)
|
||||
bag_material = bag_mat
|
||||
|
||||
var/datum/material/M = get_material_by_name("[bag_material]")
|
||||
if(!M)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
return INITIALIZE_HINT_QDEL
|
||||
color = M.icon_colour
|
||||
|
||||
/obj/item/stack/sandbags/update_icon()
|
||||
@@ -136,17 +132,13 @@ var/global/list/datum/stack_recipe/sandbag_recipes = list( \
|
||||
|
||||
var/bag_material = "cloth"
|
||||
|
||||
/obj/item/stack/emptysandbag/New(var/newloc, var/amt, var/bag_mat)
|
||||
..(newloc, amt)
|
||||
|
||||
/obj/item/stack/emptysandbag/Initialize(var/ml, var/amt, var/bag_mat)
|
||||
. = ..(ml, amt)
|
||||
if(bag_mat)
|
||||
bag_material = bag_mat
|
||||
|
||||
var/datum/material/M = get_material_by_name("[bag_material]")
|
||||
if(!M)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
return INITIALIZE_HINT_QDEL
|
||||
color = M.icon_colour
|
||||
|
||||
/obj/item/stack/emptysandbag/attack_self(var/mob/user)
|
||||
|
||||
@@ -29,14 +29,13 @@
|
||||
var/pass_color = FALSE // Will the item pass its own color var to the created item? Dyed cloth, wood, etc.
|
||||
var/strict_color_stacking = FALSE // Will the stack merge with other stacks that are different colors? (Dyed cloth, wood, etc)
|
||||
|
||||
/obj/item/stack/New(var/loc, var/amount=null)
|
||||
..()
|
||||
if (!stacktype)
|
||||
/obj/item/stack/Initialize(var/ml, var/amount)
|
||||
. = ..()
|
||||
if(!stacktype)
|
||||
stacktype = type
|
||||
if (amount)
|
||||
if(amount)
|
||||
src.amount = amount
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/stack/Destroy()
|
||||
if(uses_charge)
|
||||
@@ -170,8 +169,37 @@
|
||||
var/atom/O
|
||||
if(recipe.use_material)
|
||||
O = new recipe.result_type(user.loc, recipe.use_material)
|
||||
|
||||
if(istype(O, /obj))
|
||||
var/obj/Ob = O
|
||||
|
||||
if(LAZYLEN(Ob.matter)) // Law of equivalent exchange.
|
||||
Ob.matter.Cut()
|
||||
|
||||
else
|
||||
Ob.matter = list()
|
||||
|
||||
var/mattermult = istype(Ob, /obj/item) ? min(2000, 400 * Ob.w_class) : 2000
|
||||
|
||||
Ob.matter[recipe.use_material] = mattermult / produced * required
|
||||
|
||||
else
|
||||
O = new recipe.result_type(user.loc)
|
||||
|
||||
if(recipe.matter_material)
|
||||
if(istype(O, /obj))
|
||||
var/obj/Ob = O
|
||||
|
||||
if(LAZYLEN(Ob.matter)) // Law of equivalent exchange.
|
||||
Ob.matter.Cut()
|
||||
|
||||
else
|
||||
Ob.matter = list()
|
||||
|
||||
var/mattermult = istype(Ob, /obj/item) ? min(2000, 400 * Ob.w_class) : 2000
|
||||
|
||||
Ob.matter[recipe.use_material] = mattermult / produced * required
|
||||
|
||||
O.set_dir(user.dir)
|
||||
O.add_fingerprint(user)
|
||||
|
||||
@@ -379,8 +407,9 @@
|
||||
var/on_floor = 0
|
||||
var/use_material
|
||||
var/pass_color
|
||||
var/matter_material // Material type used for recycling. Default, uses use_material. For non-material-based objects however, matter_material is needed.
|
||||
|
||||
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0, supplied_material = null, pass_stack_color)
|
||||
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0, supplied_material = null, pass_stack_color, recycle_material = null)
|
||||
src.title = title
|
||||
src.result_type = result_type
|
||||
src.req_amount = req_amount
|
||||
@@ -392,6 +421,12 @@
|
||||
src.use_material = supplied_material
|
||||
src.pass_color = pass_stack_color
|
||||
|
||||
if(!recycle_material && src.use_material)
|
||||
src.matter_material = src.use_material
|
||||
|
||||
else if(recycle_material)
|
||||
src.matter_material = recycle_material
|
||||
|
||||
/*
|
||||
* Recipe list datum
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
w_class = ITEMSIZE_TINY
|
||||
max_amount = 30
|
||||
|
||||
/obj/item/stack/arcadeticket/New(loc, amount = null)
|
||||
/obj/item/stack/arcadeticket/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
drop_sound = 'sound/items/drop/axe.ogg'
|
||||
pickup_sound = 'sound/items/pickup/axe.ogg'
|
||||
|
||||
/obj/item/stack/tile/New()
|
||||
..()
|
||||
/obj/item/stack/tile/Initialize()
|
||||
. = ..()
|
||||
randpixel_xy()
|
||||
|
||||
/*
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
drop_sound = 'sound/items/drop/device.ogg'
|
||||
pickup_sound = 'sound/items/pickup/device.ogg'
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
//Called when the circuitboard is used to contruct a new machine.
|
||||
/obj/item/weapon/circuitboard/proc/construct(var/obj/machinery/M)
|
||||
if(istype(M, build_path))
|
||||
|
||||
@@ -10,37 +10,37 @@
|
||||
name = T_BOARD("guestpass console")
|
||||
build_path = /obj/machinery/computer/guestpass
|
||||
board_type = new /datum/frame/frame_types/guest_pass_console
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/status_display
|
||||
name = T_BOARD("status display")
|
||||
build_path = /obj/machinery/status_display
|
||||
board_type = new /datum/frame/frame_types/display
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/ai_status_display
|
||||
name = T_BOARD("ai status display")
|
||||
build_path = /obj/machinery/ai_status_display
|
||||
board_type = new /datum/frame/frame_types/display
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/newscaster
|
||||
name = T_BOARD("newscaster")
|
||||
build_path = /obj/machinery/newscaster
|
||||
board_type = new /datum/frame/frame_types/newscaster
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/atm
|
||||
name = T_BOARD("atm")
|
||||
build_path = /obj/machinery/atm
|
||||
board_type = new /datum/frame/frame_types/atm
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/request
|
||||
name = T_BOARD("request console")
|
||||
build_path = /obj/machinery/requests_console
|
||||
board_type = new /datum/frame/frame_types/supply_request_console
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
//Alarm
|
||||
|
||||
@@ -48,25 +48,25 @@
|
||||
name = T_BOARD("fire alarm")
|
||||
build_path = /obj/machinery/firealarm
|
||||
board_type = new /datum/frame/frame_types/fire_alarm
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/airalarm
|
||||
name = T_BOARD("air alarm")
|
||||
build_path = /obj/machinery/alarm
|
||||
board_type = new /datum/frame/frame_types/air_alarm
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/intercom
|
||||
name = T_BOARD("intercom")
|
||||
build_path = /obj/item/device/radio/intercom
|
||||
board_type = new /datum/frame/frame_types/intercom
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/keycard_auth
|
||||
name = T_BOARD("keycard authenticator")
|
||||
build_path = /obj/machinery/keycard_auth
|
||||
board_type = new /datum/frame/frame_types/keycard_authenticator
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
//Computer
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
name = T_BOARD("holopad")
|
||||
build_path = /obj/machinery/hologram/holopad
|
||||
board_type = new /datum/frame/frame_types/holopad
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/scanner_console
|
||||
name = T_BOARD("body scanner console")
|
||||
@@ -94,7 +94,7 @@
|
||||
name = T_BOARD("photocopier")
|
||||
build_path = /obj/machinery/photocopier
|
||||
board_type = new /datum/frame/frame_types/photocopier
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/scanning_module = 1,
|
||||
/obj/item/weapon/stock_parts/motor = 1,
|
||||
@@ -105,7 +105,7 @@
|
||||
name = T_BOARD("fax")
|
||||
build_path = /obj/machinery/photocopier/faxmachine
|
||||
board_type = new /datum/frame/frame_types/fax
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/scanning_module = 1,
|
||||
/obj/item/weapon/stock_parts/motor = 1,
|
||||
@@ -116,6 +116,7 @@
|
||||
name = T_BOARD("conveyor")
|
||||
build_path = /obj/machinery/conveyor
|
||||
board_type = new /datum/frame/frame_types/conveyor
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/gear = 2,
|
||||
/obj/item/weapon/stock_parts/motor = 2,
|
||||
@@ -125,6 +126,7 @@
|
||||
name = T_BOARD("recharger")
|
||||
build_path = /obj/machinery/recharger
|
||||
board_type = new /datum/frame/frame_types/recharger
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/capacitor = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
@@ -138,6 +140,7 @@
|
||||
name = T_BOARD("heavy-duty cell charger")
|
||||
build_path = /obj/machinery/cell_charger
|
||||
board_type = new /datum/frame/frame_types/cell_charger
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/capacitor = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
@@ -146,7 +149,7 @@
|
||||
name = T_BOARD("washing machine")
|
||||
build_path = /obj/machinery/washing_machine
|
||||
board_type = new /datum/frame/frame_types/washing_machine
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/motor = 1,
|
||||
/obj/item/weapon/stock_parts/gear = 2)
|
||||
@@ -155,6 +158,7 @@
|
||||
name = T_BOARD("reagent grinder")
|
||||
build_path = /obj/machinery/reagentgrinder
|
||||
board_type = new /datum/frame/frame_types/grinder
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/motor = 1,
|
||||
/obj/item/weapon/stock_parts/gear = 1,
|
||||
@@ -163,6 +167,7 @@
|
||||
/obj/item/weapon/circuitboard/distiller
|
||||
build_path = /obj/machinery/portable_atmospherics/powered/reagent_distillery
|
||||
board_type = new /datum/frame/frame_types/reagent_distillery
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/capacitor = 1,
|
||||
/obj/item/weapon/stock_parts/micro_laser = 1,
|
||||
@@ -173,6 +178,7 @@
|
||||
name = T_BOARD("teleporter hub")
|
||||
build_path = /obj/machinery/teleport/hub
|
||||
board_type = "teleporter_hub"
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
|
||||
// origin_tech = list(TECH_DATA = 2, TECH_BLUESPACE = 4)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/scanning_module = 4,
|
||||
@@ -183,6 +189,7 @@
|
||||
name = T_BOARD("teleporter station")
|
||||
build_path = /obj/machinery/teleport/station
|
||||
board_type = "teleporter_station"
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
|
||||
// origin_tech = list(TECH_DATA = 2, TECH_BLUESPACE = 3)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/console_screen = 1,
|
||||
@@ -194,6 +201,7 @@
|
||||
build_path = /obj/machinery/bodyscanner
|
||||
board_type = new /datum/frame/frame_types/medical_pod
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/scanning_module = 3,
|
||||
/obj/item/stack/material/glass/reinforced = 2)
|
||||
@@ -202,6 +210,7 @@
|
||||
name = T_BOARD("sleeper")
|
||||
build_path = /obj/machinery/sleeper
|
||||
board_type = new /datum/frame/frame_types/medical_pod
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/manipulator = 1,
|
||||
@@ -214,6 +223,7 @@
|
||||
name = T_BOARD("VR sleeper")
|
||||
build_path = /obj/machinery/vr_sleeper
|
||||
board_type = new /datum/frame/frame_types/medical_pod
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/scanning_module = 1,
|
||||
@@ -223,6 +233,7 @@
|
||||
name = T_BOARD("dna analyzer")
|
||||
build_path = /obj/machinery/dnaforensics
|
||||
board_type = new /datum/frame/frame_types/dna_analyzer
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
|
||||
origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2, TECH_DATA = 2)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/scanning_module = 2,
|
||||
@@ -233,6 +244,7 @@
|
||||
name = T_BOARD("mass driver")
|
||||
build_path = /obj/machinery/mass_driver
|
||||
board_type = new /datum/frame/frame_types/mass_driver
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/gear = 2,
|
||||
/obj/item/weapon/stock_parts/motor = 2,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "std_mod"
|
||||
board_type = "other"
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/ripley
|
||||
origin_tech = list(TECH_DATA = 3)
|
||||
|
||||
@@ -299,3 +299,13 @@
|
||||
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/blade( src )
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/weapon/implantcase/restrainingbolt
|
||||
name = "glass case - 'Restraining Bolt'"
|
||||
desc = "A case containing a restraining bolt."
|
||||
icon_state = "implantcase-b"
|
||||
|
||||
/obj/item/weapon/implantcase/restrainingbolt/New()
|
||||
src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -4,18 +4,6 @@
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "implant"
|
||||
initialize_loc = BP_HEAD
|
||||
var/roundstart = TRUE
|
||||
|
||||
/obj/item/weapon/implant/dud/torso
|
||||
name = "unknown implant"
|
||||
desc = "A small device with small connector wires."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "implant"
|
||||
initialize_loc = BP_TORSO
|
||||
|
||||
/obj/item/weapon/implant/dud/old
|
||||
name = "old implant"
|
||||
desc = "A small device with small connector wires."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "implant"
|
||||
roundstart = FALSE
|
||||
|
||||
@@ -150,3 +150,12 @@
|
||||
S.remove_from_storage(A)
|
||||
A.loc.contents.Remove(A)
|
||||
update()
|
||||
|
||||
/obj/item/weapon/implanter/restrainingbolt
|
||||
name = "implanter (bolt)"
|
||||
|
||||
/obj/item/weapon/implanter/restrainingbolt/New()
|
||||
src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
|
||||
..()
|
||||
update()
|
||||
return
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
/obj/item/weapon/implant/restrainingbolt
|
||||
name = "\improper restraining bolt"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "implant"
|
||||
@@ -31,7 +31,9 @@ Protectiveness | Armor %
|
||||
var/applies_material_color = TRUE
|
||||
var/unbreakable = FALSE
|
||||
var/default_material = null // Set this to something else if you want material attributes on init.
|
||||
var/material_armor_modifer = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor)
|
||||
var/material_armor_modifier = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor)
|
||||
var/material_slowdown_modifier = 0
|
||||
var/material_slowdown_multiplier = 1
|
||||
|
||||
/obj/item/clothing/New(var/newloc, var/material_key)
|
||||
..(newloc)
|
||||
@@ -138,7 +140,7 @@ Protectiveness | Armor %
|
||||
return ..()
|
||||
|
||||
var/reflectchance = (40 * material.reflectivity) - round(damage/3)
|
||||
reflectchance *= material_armor_modifer
|
||||
reflectchance *= material_armor_modifier
|
||||
if(!(def_zone in list(BP_TORSO, BP_GROIN)))
|
||||
reflectchance /= 2
|
||||
if(P.starting && prob(reflectchance))
|
||||
@@ -166,17 +168,17 @@ Protectiveness | Armor %
|
||||
if(material)
|
||||
var/melee_armor = 0, bullet_armor = 0, laser_armor = 0, energy_armor = 0, bomb_armor = 0
|
||||
|
||||
melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifer)
|
||||
melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifier)
|
||||
|
||||
bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifer) * 0.7)
|
||||
bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifier) * 0.7)
|
||||
|
||||
laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifer) * 0.7)
|
||||
laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifier) * 0.7)
|
||||
if(material.opacity != 1)
|
||||
laser_armor *= max(material.opacity - 0.3, 0) // Glass and such has an opacity of 0.3, but lasers should go through glass armor entirely.
|
||||
|
||||
energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.4)
|
||||
energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifier) * 0.4)
|
||||
|
||||
bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.5)
|
||||
bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifier) * 0.5)
|
||||
|
||||
// Makes sure the numbers stay capped.
|
||||
for(var/number in list(melee_armor, bullet_armor, laser_armor, energy_armor, bomb_armor))
|
||||
@@ -190,7 +192,12 @@ Protectiveness | Armor %
|
||||
|
||||
if(!isnull(material.conductivity))
|
||||
siemens_coefficient = between(0, material.conductivity / 10, 10)
|
||||
slowdown = between(0, round(material.weight / 10, 0.1), 6)
|
||||
|
||||
var/slowdownModified = between(0, round(material.weight / 10, 0.1), 6)
|
||||
|
||||
var/slowdownUncapped = (material_slowdown_multiplier * slowdownModified) - material_slowdown_modifier
|
||||
|
||||
slowdown = max(slowdownUncapped, 0)
|
||||
|
||||
/obj/item/clothing/suit/armor/material
|
||||
name = "armor"
|
||||
@@ -201,6 +208,67 @@ Protectiveness | Armor %
|
||||
desc = "This appears to be two 'sheets' of a material held together by cable. If the sheets are strong, this could be rather protective."
|
||||
icon_state = "material_armor_makeshift"
|
||||
|
||||
/obj/item/clothing/accessory/material/makeshift/light //Craftable with 4 material sheets, less slowdown, less armour
|
||||
name = "light armor plate"
|
||||
desc = "A thin plate of padded material, designed to fit into a plate carrier. Attaches to a plate carrier."
|
||||
icon = 'icons/obj/clothing/modular_armor.dmi'
|
||||
icon_state = "armor_light"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO
|
||||
slot = ACCESSORY_SLOT_ARMOR_C
|
||||
material_armor_modifier = 0.8
|
||||
material_slowdown_modifier = 0.5 //Subtracted from total slowdown
|
||||
material_slowdown_multiplier = 0.8 //Multiplied by total slowdown
|
||||
|
||||
/obj/item/clothing/accessory/material/makeshift/heavy //Craftable with 8 material sheets, more slowdown, more armour
|
||||
name = "heavy armor plate"
|
||||
desc = "A thick plate of padded material, designed to fit into a plate carrier. Attaches to a plate carrier."
|
||||
icon = 'icons/obj/clothing/modular_armor.dmi'
|
||||
icon_state = "armor_medium"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO
|
||||
slot = ACCESSORY_SLOT_ARMOR_C
|
||||
material_armor_modifier = 1.2
|
||||
material_slowdown_modifier = 0
|
||||
material_slowdown_multiplier = 1
|
||||
|
||||
/obj/item/clothing/accessory/material/custom //Not yet craftable, advanced version made with science!
|
||||
name = "custom armor plate"
|
||||
desc = "A composite plate of custom machined material, designed to fit into a plate carrier. Attaches to a plate carrier."
|
||||
icon = 'icons/obj/clothing/modular_armor.dmi'
|
||||
icon_state = "armor_tactical"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO
|
||||
slot = ACCESSORY_SLOT_ARMOR_C
|
||||
material_armor_modifier = 1.2
|
||||
material_slowdown_modifier = 0.5
|
||||
material_slowdown_multiplier = 0.8
|
||||
|
||||
/obj/item/clothing/accessory/material/makeshift/armguards
|
||||
name = "arm guards"
|
||||
desc = "A pair of arm pads reinforced with material. Attaches to a plate carrier."
|
||||
// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
|
||||
icon = 'icons/obj/clothing/modular_armor.dmi'
|
||||
icon_override = 'icons/mob/modular_armor.dmi'
|
||||
icon_state = "armguards_material"
|
||||
gender = PLURAL
|
||||
body_parts_covered = ARMS
|
||||
slot = ACCESSORY_SLOT_ARMOR_A
|
||||
material_armor_modifier = 0.8
|
||||
material_slowdown_modifier = 0.8
|
||||
material_slowdown_multiplier = 0.8
|
||||
|
||||
/obj/item/clothing/accessory/material/makeshift/legguards
|
||||
name = "leg guards"
|
||||
desc = "A pair of leg guards reinforced with material. Attaches to a plate carrier."
|
||||
// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
|
||||
icon = 'icons/obj/clothing/modular_armor.dmi'
|
||||
icon_override = 'icons/mob/modular_armor.dmi'
|
||||
icon_state = "legguards_material"
|
||||
gender = PLURAL
|
||||
body_parts_covered = LEGS
|
||||
slot = ACCESSORY_SLOT_ARMOR_L
|
||||
material_armor_modifier = 0.8
|
||||
material_slowdown_modifier = 0.8
|
||||
material_slowdown_multiplier = 0.8
|
||||
|
||||
/obj/item/clothing/suit/armor/material/makeshift/durasteel
|
||||
default_material = "durasteel"
|
||||
|
||||
@@ -218,6 +286,9 @@ Protectiveness | Armor %
|
||||
thrown_force_divisor = 0.2
|
||||
var/wired = FALSE
|
||||
|
||||
/obj/item/weapon/material/armor_plating/insert
|
||||
unbreakable = FALSE
|
||||
|
||||
/obj/item/weapon/material/armor_plating/attackby(var/obj/O, mob/user)
|
||||
if(istype(O, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/S = O
|
||||
@@ -249,6 +320,54 @@ Protectiveness | Armor %
|
||||
else
|
||||
..()
|
||||
|
||||
//Make plating inserts for modular armour.
|
||||
/obj/item/weapon/material/armor_plating/insert/attackby(var/obj/O, mob/user)
|
||||
|
||||
. = ..()
|
||||
|
||||
if(istype(O, /obj/item/weapon/weldingtool))
|
||||
var /obj/item/weapon/weldingtool/S = O
|
||||
if(S.remove_fuel(0,user))
|
||||
if(!src || !S.isOn()) return
|
||||
to_chat(user, "<span class='notice'>You trim down the edges to size.</span>")
|
||||
user.drop_from_inventory(src)
|
||||
var/obj/item/clothing/accessory/material/makeshift/light/new_armor = new(null, src.material.name)
|
||||
user.put_in_hands(new_armor)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/weapon/material/armor_plating/insert))
|
||||
var/obj/item/weapon/material/armor_plating/insert/second_plate = O
|
||||
if(second_plate.material != src.material)
|
||||
to_chat(user, "<span class='warning'>Both plates need to be the same type of material.</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You bond the two plates together.</span>")
|
||||
user.drop_from_inventory(src)
|
||||
user.drop_from_inventory(second_plate)
|
||||
var/obj/item/clothing/accessory/material/makeshift/heavy/new_armor = new(null, src.material.name)
|
||||
user.put_in_hands(new_armor)
|
||||
qdel(second_plate)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/weapon/tool/wirecutters))
|
||||
to_chat(user, "<span class='notice'>You split the plate down the middle, and joint it at the elbow.</span>")
|
||||
user.drop_from_inventory(src)
|
||||
var/obj/item/clothing/accessory/material/makeshift/armguards/new_armor = new(null, src.material.name)
|
||||
user.put_in_hands(new_armor)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/stack/material))
|
||||
var/obj/item/stack/material/S = O
|
||||
if(S.material == get_material_by_name("leather"))
|
||||
if(S.use(2))
|
||||
to_chat(user, "<span class='notice'>You curve the plate inwards, and add a strap for adjustment.</span>")
|
||||
user.drop_from_inventory(src)
|
||||
var/obj/item/clothing/accessory/material/makeshift/legguards/new_armor = new(null, src.material.name)
|
||||
user.put_in_hands(new_armor)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// Used to craft the makeshift helmet
|
||||
/obj/item/clothing/head/helmet/bucket
|
||||
|
||||
@@ -77,14 +77,14 @@
|
||||
//visible_message("[user] has smashed the snowball in their hand!", "You smash the snowball in your hand.")
|
||||
to_chat(user, "<span class='notice'>You smash the snowball in your hand.</span>")
|
||||
var/atom/S = new /obj/item/stack/material/snow(user.loc)
|
||||
del(src)
|
||||
qdel(src)
|
||||
user.put_in_hands(S)
|
||||
else
|
||||
//visible_message("[user] starts compacting the snowball.", "You start compacting the snowball.")
|
||||
to_chat(user, "<span class='notice'>You start compacting the snowball.</span>")
|
||||
if(do_after(user, 2 SECONDS))
|
||||
var/atom/S = new /obj/item/weapon/material/snow/snowball/reinforced(user.loc)
|
||||
del(src)
|
||||
qdel(src)
|
||||
user.put_in_hands(S)
|
||||
|
||||
/obj/item/weapon/material/snow/snowball/reinforced
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
item_state = "saddlebag"
|
||||
icon_state = "saddlebag"
|
||||
max_storage_space = INVENTORY_DUFFLEBAG_SPACE //Saddlebags can hold more, like dufflebags
|
||||
slowdown = 1 //And are slower, too...Unless you're a macro, that is.
|
||||
slowdown = 1 //And are slower, too...
|
||||
var/taurtype = /datum/sprite_accessory/tail/taur/horse //Acceptable taur type to be wearing this
|
||||
var/no_message = "You aren't the appropriate taur type to wear this!"
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
icon_state = "saddlebag"
|
||||
var/icon_base = "saddlebag"
|
||||
max_storage_space = INVENTORY_DUFFLEBAG_SPACE //Saddlebags can hold more, like dufflebags
|
||||
slowdown = 1 //And are slower, too...Unless you're a macro, that is.
|
||||
slowdown = 1 //And are slower, too...
|
||||
var/no_message = "You aren't the appropriate taur type to wear this!"
|
||||
|
||||
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
|
||||
@@ -44,11 +44,6 @@
|
||||
log_runtime("[H] was not a valid human!")
|
||||
return
|
||||
|
||||
if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? If yes, they get no slowdown.
|
||||
slowdown = 0
|
||||
else
|
||||
slowdown = initial(slowdown)
|
||||
|
||||
var/datum/sprite_accessory/tail/taur/TT = H.tail_style
|
||||
item_state = "[icon_base]_[TT.icon_sprite_tag]" //icon_sprite_tag is something like "deer"
|
||||
return 1
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
gauge_icon = "indicator_emergency"
|
||||
|
||||
/obj/item/weapon/tank/emergency/nitrogen/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
src.air_contents.adjust_gas("nitrogen", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
|
||||
|
||||
/obj/item/weapon/tank/emergency/nitrogen/double
|
||||
|
||||
@@ -671,7 +671,7 @@
|
||||
always_process = TRUE
|
||||
|
||||
/obj/item/weapon/weldingtool/electric/mounted/exosuit/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
if(istype(loc, /obj/item/mecha_parts/mecha_equipment))
|
||||
equip_mount = loc
|
||||
|
||||
@@ -19,29 +19,11 @@
|
||||
var/can_speak = 0 //For MMIs and admin trickery. If an object has a brainmob in its contents, set this to 1 to allow it to speak.
|
||||
|
||||
var/show_examine = TRUE // Does this pop up on a mob when the mob is examined?
|
||||
var/register_as_dangerous_object = FALSE // Should this tell its turf that it is dangerous automatically?
|
||||
|
||||
/obj/Initialize()
|
||||
if(register_as_dangerous_object)
|
||||
register_dangerous_to_step()
|
||||
return ..()
|
||||
|
||||
/obj/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(register_as_dangerous_object)
|
||||
unregister_dangerous_to_step()
|
||||
return ..()
|
||||
|
||||
/obj/Moved(atom/oldloc)
|
||||
. = ..()
|
||||
if(register_as_dangerous_object)
|
||||
var/turf/old_turf = get_turf(oldloc)
|
||||
var/turf/new_turf = get_turf(src)
|
||||
|
||||
if(old_turf != new_turf)
|
||||
old_turf.unregister_dangerous_object(src)
|
||||
new_turf.register_dangerous_object(src)
|
||||
|
||||
/obj/Topic(href, href_list, var/datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
if(usr && ..())
|
||||
return 1
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
// creates a new object and deletes itself
|
||||
/obj/random/Initialize()
|
||||
. = ..()
|
||||
..()
|
||||
if (!prob(spawn_nothing_percentage))
|
||||
spawn_item()
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
@@ -1,236 +1,252 @@
|
||||
GLOBAL_LIST_EMPTY(cliff_icon_cache)
|
||||
|
||||
/*
|
||||
Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side.
|
||||
|
||||
Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile,
|
||||
where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them.
|
||||
|
||||
Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table.
|
||||
|
||||
Flying mobs can pass over all cliffs with no risk of falling.
|
||||
|
||||
Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff.
|
||||
This makes fighting something that is on top of a cliff more challenging.
|
||||
|
||||
As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'.
|
||||
|
||||
When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to
|
||||
two tiles on initialization, and which way a cliff is facing may change during maploading.
|
||||
*/
|
||||
|
||||
/obj/structure/cliff
|
||||
name = "cliff"
|
||||
desc = "A steep rock ledge. You might be able to climb it if you feel bold enough."
|
||||
description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury.<br>\
|
||||
You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff.<br>\
|
||||
Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \
|
||||
on top."
|
||||
icon = 'icons/obj/flora/rocks.dmi'
|
||||
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
opacity = FALSE
|
||||
climbable = TRUE
|
||||
climb_delay = 10 SECONDS
|
||||
block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge.
|
||||
register_as_dangerous_object = TRUE
|
||||
|
||||
var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display.
|
||||
var/corner = FALSE // Used for icon things.
|
||||
var/ramp = FALSE // Ditto.
|
||||
var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons.
|
||||
|
||||
var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks.
|
||||
var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff.
|
||||
|
||||
// These arrange their sprites at runtime, as opposed to being statically placed in the map file.
|
||||
/obj/structure/cliff/automatic
|
||||
icon_state = "cliffbuilder"
|
||||
dir = NORTH
|
||||
|
||||
/obj/structure/cliff/automatic/corner
|
||||
icon_state = "cliffbuilder-corner"
|
||||
dir = NORTHEAST
|
||||
corner = TRUE
|
||||
|
||||
// Tiny part that doesn't block, used for making 'ramps'.
|
||||
/obj/structure/cliff/automatic/ramp
|
||||
icon_state = "cliffbuilder-ramp"
|
||||
dir = NORTHEAST
|
||||
density = FALSE
|
||||
ramp = TRUE
|
||||
|
||||
// Made automatically as needed by automatic cliffs.
|
||||
/obj/structure/cliff/bottom
|
||||
bottom = TRUE
|
||||
|
||||
/obj/structure/cliff/automatic/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH.
|
||||
/obj/structure/cliff/automatic/LateInitialize()
|
||||
if(dir in GLOB.cardinal)
|
||||
icon_variant = pick("a", "b", "c")
|
||||
|
||||
if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made.
|
||||
make_bottom()
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/structure/cliff/proc/make_bottom()
|
||||
// First, make sure there's room to put the bottom side.
|
||||
var/turf/T = locate(x, y - 1, z)
|
||||
if(!istype(T))
|
||||
return FALSE
|
||||
|
||||
// Now make the bottom cliff have mostly the same variables.
|
||||
var/obj/structure/cliff/bottom/bottom = new(T)
|
||||
is_double_cliff = TRUE
|
||||
climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time.
|
||||
|
||||
bottom.dir = dir
|
||||
bottom.is_double_cliff = TRUE
|
||||
bottom.climb_delay = climb_delay
|
||||
bottom.icon_variant = icon_variant
|
||||
bottom.corner = corner
|
||||
bottom.ramp = ramp
|
||||
bottom.layer = layer - 0.1
|
||||
bottom.density = density
|
||||
bottom.update_icon()
|
||||
|
||||
/obj/structure/cliff/set_dir(new_dir)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/cliff/update_icon()
|
||||
icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]"
|
||||
|
||||
// Now for making the top-side look like a different turf.
|
||||
var/turf/T = get_step(src, dir)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
var/subtraction_icon_state = "[icon_state]-subtract"
|
||||
var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
|
||||
if(T && subtraction_icon_state in cached_icon_states(icon))
|
||||
cut_overlays()
|
||||
// If we've made the same icon before, just recycle it.
|
||||
if(cache_string in GLOB.cliff_icon_cache)
|
||||
add_overlay(GLOB.cliff_icon_cache[cache_string])
|
||||
|
||||
else // Otherwise make a new one, but only once.
|
||||
var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir)
|
||||
var/icon/subtract = icon(icon, subtraction_icon_state)
|
||||
underlying_ground.Blend(subtract, ICON_SUBTRACT)
|
||||
var/image/final = image(underlying_ground)
|
||||
final.layer = src.layer - 0.2
|
||||
GLOB.cliff_icon_cache[cache_string] = final
|
||||
add_overlay(final)
|
||||
|
||||
|
||||
// Movement-related code.
|
||||
|
||||
/obj/structure/cliff/CanPass(atom/movable/mover, turf/target)
|
||||
if(isliving(mover))
|
||||
var/mob/living/L = mover
|
||||
if(L.hovering) // Flying mobs can always pass.
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
// Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot.
|
||||
else if(istype(mover, /obj))
|
||||
var/obj/O = mover
|
||||
if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well.
|
||||
if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved.
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/cliff/Bumped(atom/A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(should_fall(L))
|
||||
fall_off_cliff(L)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/structure/cliff/proc/should_fall(mob/living/L)
|
||||
if(L.hovering)
|
||||
return FALSE
|
||||
|
||||
var/turf/T = get_turf(L)
|
||||
if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it.
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/structure/cliff/proc/fall_off_cliff(mob/living/L)
|
||||
if(!istype(L))
|
||||
return FALSE
|
||||
var/turf/T = get_step(src, reverse_dir[dir])
|
||||
var/displaced = FALSE
|
||||
|
||||
if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth.
|
||||
for(var/i = 1 to 2)
|
||||
var/turf/new_T = locate(T.x, T.y - i, T.z)
|
||||
if(!new_T || locate(/obj/structure/cliff) in new_T)
|
||||
break
|
||||
T = new_T
|
||||
displaced = TRUE
|
||||
|
||||
if(istype(T))
|
||||
visible_message(span("danger", "\The [L] falls off \the [src]!"))
|
||||
L.forceMove(T)
|
||||
|
||||
// Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice.
|
||||
var/harm = !is_double_cliff ? 1 : 0.5
|
||||
if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely.
|
||||
var/obj/vehicle/vehicle = L.buckled
|
||||
vehicle.adjust_health(40 * harm)
|
||||
to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it."))
|
||||
harm /= 2
|
||||
|
||||
playsound(L, 'sound/effects/break_stone.ogg', 70, 1)
|
||||
L.Weaken(5 * harm)
|
||||
var/fall_time = 3
|
||||
if(displaced) // Make the fall look more natural when falling sideways.
|
||||
L.pixel_z = 32 * 2
|
||||
animate(L, pixel_z = 0, time = fall_time)
|
||||
sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect.
|
||||
playsound(L, "punch", 70, 1)
|
||||
shake_camera(L, 1, 1)
|
||||
visible_message(span("danger", "\The [L] hits the ground!"))
|
||||
|
||||
// The bigger they are, the harder they fall.
|
||||
// They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health.
|
||||
// This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health.
|
||||
var/damage = between(20, L.getMaxHealth() * 0.4, 100)
|
||||
var/target_zone = ran_zone()
|
||||
var/blocked = L.run_armor_check(target_zone, "melee") * harm
|
||||
var/soaked = L.get_armor_soak(target_zone, "melee") * harm
|
||||
|
||||
L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src)
|
||||
|
||||
// Now fall off more cliffs below this one if they exist.
|
||||
var/obj/structure/cliff/bottom_cliff = locate() in T
|
||||
if(bottom_cliff)
|
||||
visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!"))
|
||||
sleep(5)
|
||||
bottom_cliff.fall_off_cliff(L)
|
||||
|
||||
/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE)
|
||||
// Cliff climbing requires climbing gear.
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/clothing/shoes/shoes = H.shoes
|
||||
if(shoes && shoes.rock_climbing)
|
||||
return ..() // Do the other checks too.
|
||||
|
||||
to_chat(user, span("warning", "\The [src] is too steep to climb unassisted."))
|
||||
return FALSE
|
||||
|
||||
// This tells AI mobs to not be dumb and step off cliffs willingly.
|
||||
/obj/structure/cliff/is_safe_to_step(mob/living/L)
|
||||
if(should_fall(L))
|
||||
return FALSE
|
||||
return ..()
|
||||
GLOBAL_LIST_EMPTY(cliff_icon_cache)
|
||||
|
||||
/*
|
||||
Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side.
|
||||
|
||||
Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile,
|
||||
where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them.
|
||||
|
||||
Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table.
|
||||
|
||||
Flying mobs can pass over all cliffs with no risk of falling.
|
||||
|
||||
Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff.
|
||||
This makes fighting something that is on top of a cliff more challenging.
|
||||
|
||||
As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'.
|
||||
|
||||
When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to
|
||||
two tiles on initialization, and which way a cliff is facing may change during maploading.
|
||||
*/
|
||||
|
||||
/obj/structure/cliff
|
||||
name = "cliff"
|
||||
desc = "A steep rock ledge. You might be able to climb it if you feel bold enough."
|
||||
description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury.<br>\
|
||||
You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff.<br>\
|
||||
Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \
|
||||
on top."
|
||||
icon = 'icons/obj/flora/rocks.dmi'
|
||||
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
opacity = FALSE
|
||||
climbable = TRUE
|
||||
climb_delay = 10 SECONDS
|
||||
block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge.
|
||||
|
||||
var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display.
|
||||
var/corner = FALSE // Used for icon things.
|
||||
var/ramp = FALSE // Ditto.
|
||||
var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons.
|
||||
|
||||
var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks.
|
||||
var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff.
|
||||
|
||||
/obj/structure/cliff/Initialize()
|
||||
. = ..()
|
||||
register_dangerous_to_step()
|
||||
|
||||
/obj/structure/cliff/Destroy()
|
||||
unregister_dangerous_to_step()
|
||||
. = ..()
|
||||
|
||||
/obj/structure/cliff/Moved(atom/oldloc)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/turf/old_turf = get_turf(oldloc)
|
||||
var/turf/new_turf = get_turf(src)
|
||||
if(old_turf != new_turf)
|
||||
old_turf.unregister_dangerous_object(src)
|
||||
new_turf.register_dangerous_object(src)
|
||||
|
||||
// These arrange their sprites at runtime, as opposed to being statically placed in the map file.
|
||||
/obj/structure/cliff/automatic
|
||||
icon_state = "cliffbuilder"
|
||||
dir = NORTH
|
||||
|
||||
/obj/structure/cliff/automatic/corner
|
||||
icon_state = "cliffbuilder-corner"
|
||||
dir = NORTHEAST
|
||||
corner = TRUE
|
||||
|
||||
// Tiny part that doesn't block, used for making 'ramps'.
|
||||
/obj/structure/cliff/automatic/ramp
|
||||
icon_state = "cliffbuilder-ramp"
|
||||
dir = NORTHEAST
|
||||
density = FALSE
|
||||
ramp = TRUE
|
||||
|
||||
// Made automatically as needed by automatic cliffs.
|
||||
/obj/structure/cliff/bottom
|
||||
bottom = TRUE
|
||||
|
||||
/obj/structure/cliff/automatic/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH.
|
||||
/obj/structure/cliff/automatic/LateInitialize()
|
||||
if(dir in GLOB.cardinal)
|
||||
icon_variant = pick("a", "b", "c")
|
||||
|
||||
if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made.
|
||||
make_bottom()
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/structure/cliff/proc/make_bottom()
|
||||
// First, make sure there's room to put the bottom side.
|
||||
var/turf/T = locate(x, y - 1, z)
|
||||
if(!istype(T))
|
||||
return FALSE
|
||||
|
||||
// Now make the bottom cliff have mostly the same variables.
|
||||
var/obj/structure/cliff/bottom/bottom = new(T)
|
||||
is_double_cliff = TRUE
|
||||
climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time.
|
||||
|
||||
bottom.dir = dir
|
||||
bottom.is_double_cliff = TRUE
|
||||
bottom.climb_delay = climb_delay
|
||||
bottom.icon_variant = icon_variant
|
||||
bottom.corner = corner
|
||||
bottom.ramp = ramp
|
||||
bottom.layer = layer - 0.1
|
||||
bottom.density = density
|
||||
bottom.update_icon()
|
||||
|
||||
/obj/structure/cliff/set_dir(new_dir)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/cliff/update_icon()
|
||||
icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]"
|
||||
|
||||
// Now for making the top-side look like a different turf.
|
||||
var/turf/T = get_step(src, dir)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
var/subtraction_icon_state = "[icon_state]-subtract"
|
||||
var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
|
||||
if(T && subtraction_icon_state in cached_icon_states(icon))
|
||||
cut_overlays()
|
||||
// If we've made the same icon before, just recycle it.
|
||||
if(cache_string in GLOB.cliff_icon_cache)
|
||||
add_overlay(GLOB.cliff_icon_cache[cache_string])
|
||||
|
||||
else // Otherwise make a new one, but only once.
|
||||
var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir)
|
||||
var/icon/subtract = icon(icon, subtraction_icon_state)
|
||||
underlying_ground.Blend(subtract, ICON_SUBTRACT)
|
||||
var/image/final = image(underlying_ground)
|
||||
final.layer = src.layer - 0.2
|
||||
GLOB.cliff_icon_cache[cache_string] = final
|
||||
add_overlay(final)
|
||||
|
||||
|
||||
// Movement-related code.
|
||||
|
||||
/obj/structure/cliff/CanPass(atom/movable/mover, turf/target)
|
||||
if(isliving(mover))
|
||||
var/mob/living/L = mover
|
||||
if(L.hovering) // Flying mobs can always pass.
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
// Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot.
|
||||
else if(istype(mover, /obj))
|
||||
var/obj/O = mover
|
||||
if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well.
|
||||
if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved.
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/cliff/Bumped(atom/A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(should_fall(L))
|
||||
fall_off_cliff(L)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/structure/cliff/proc/should_fall(mob/living/L)
|
||||
if(L.hovering)
|
||||
return FALSE
|
||||
|
||||
var/turf/T = get_turf(L)
|
||||
if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it.
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/structure/cliff/proc/fall_off_cliff(mob/living/L)
|
||||
if(!istype(L))
|
||||
return FALSE
|
||||
var/turf/T = get_step(src, reverse_dir[dir])
|
||||
var/displaced = FALSE
|
||||
|
||||
if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth.
|
||||
for(var/i = 1 to 2)
|
||||
var/turf/new_T = locate(T.x, T.y - i, T.z)
|
||||
if(!new_T || locate(/obj/structure/cliff) in new_T)
|
||||
break
|
||||
T = new_T
|
||||
displaced = TRUE
|
||||
|
||||
if(istype(T))
|
||||
visible_message(span("danger", "\The [L] falls off \the [src]!"))
|
||||
L.forceMove(T)
|
||||
|
||||
// Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice.
|
||||
var/harm = !is_double_cliff ? 1 : 0.5
|
||||
if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely.
|
||||
var/obj/vehicle/vehicle = L.buckled
|
||||
vehicle.adjust_health(40 * harm)
|
||||
to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it."))
|
||||
harm /= 2
|
||||
|
||||
playsound(L, 'sound/effects/break_stone.ogg', 70, 1)
|
||||
L.Weaken(5 * harm)
|
||||
var/fall_time = 3
|
||||
if(displaced) // Make the fall look more natural when falling sideways.
|
||||
L.pixel_z = 32 * 2
|
||||
animate(L, pixel_z = 0, time = fall_time)
|
||||
sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect.
|
||||
playsound(L, "punch", 70, 1)
|
||||
shake_camera(L, 1, 1)
|
||||
visible_message(span("danger", "\The [L] hits the ground!"))
|
||||
|
||||
// The bigger they are, the harder they fall.
|
||||
// They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health.
|
||||
// This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health.
|
||||
var/damage = between(20, L.getMaxHealth() * 0.4, 100)
|
||||
var/target_zone = ran_zone()
|
||||
var/blocked = L.run_armor_check(target_zone, "melee") * harm
|
||||
var/soaked = L.get_armor_soak(target_zone, "melee") * harm
|
||||
|
||||
L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src)
|
||||
|
||||
// Now fall off more cliffs below this one if they exist.
|
||||
var/obj/structure/cliff/bottom_cliff = locate() in T
|
||||
if(bottom_cliff)
|
||||
visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!"))
|
||||
sleep(5)
|
||||
bottom_cliff.fall_off_cliff(L)
|
||||
|
||||
/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE)
|
||||
// Cliff climbing requires climbing gear.
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/clothing/shoes/shoes = H.shoes
|
||||
if(shoes && shoes.rock_climbing)
|
||||
return ..() // Do the other checks too.
|
||||
|
||||
to_chat(user, span("warning", "\The [src] is too steep to climb unassisted."))
|
||||
return FALSE
|
||||
|
||||
// This tells AI mobs to not be dumb and step off cliffs willingly.
|
||||
/obj/structure/cliff/is_safe_to_step(mob/living/L)
|
||||
if(should_fall(L))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
|
||||
/obj/structure/closet/Initialize()
|
||||
..()
|
||||
// Closets need to come later because of spawners potentially creating objects during init.
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/structure/closet/LateInitialize()
|
||||
|
||||
@@ -133,7 +133,6 @@
|
||||
/obj/item/clothing/gloves/fingerless,
|
||||
/obj/item/device/radio/headset/pilot,
|
||||
/obj/item/device/radio/headset/pilot/alt,
|
||||
/obj/item/weapon/cartridge/explorer,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein,
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//Dance pole
|
||||
/obj/structure/dancepole
|
||||
name = "dance pole"
|
||||
desc = "Engineered for your entertainment"
|
||||
icon = 'icons/obj/objects_vr.dmi'
|
||||
icon_state = "dancepole"
|
||||
density = 0
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/dancepole/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(O.is_screwdriver())
|
||||
anchored = !anchored
|
||||
playsound(src, O.usesound, 50, 1)
|
||||
if(anchored)
|
||||
to_chat(user, "<font color='blue'>You secure \the [src].</font>")
|
||||
else
|
||||
to_chat(user, "<font color='blue'>You unsecure \the [src].</font>")
|
||||
if(O.is_wrench())
|
||||
playsound(src, O.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>Now disassembling \the [src]...</span>")
|
||||
if(do_after(user, 30 * O.toolspeed))
|
||||
if(!src) return
|
||||
to_chat(user, "<span class='notice'>You dissasembled \the [src]!</span>")
|
||||
new /obj/item/stack/material/steel(src.loc, 1)
|
||||
qdel(src)
|
||||
@@ -14,7 +14,7 @@
|
||||
var/smashed = 0
|
||||
|
||||
/obj/structure/fireaxecabinet/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
fireaxe = new /obj/item/weapon/material/twohanded/fireaxe()
|
||||
|
||||
/obj/structure/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
var/list/harvest_loot = null // Should be an associative list for things to spawn, and their weights. An example would be a branch from a tree.
|
||||
|
||||
/obj/structure/flora/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
if(randomize_size)
|
||||
icon_scale_x = rand(min_x_scale * 100, max_x_scale * 100) / 100
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
icon_state = icon_state_opened
|
||||
if(needscharger)
|
||||
new /obj/machinery/recharge_station/ghost_pod_recharger(src.loc)
|
||||
del(src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
var/list/clothing_possibilities
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/human/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
handle_clothing_setup()
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
var/list/clothing_possibilities
|
||||
|
||||
/obj/structure/ghost_pod/manual/human/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
handle_clothing_setup()
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
say_dead_object("A <span class='notice'>[drone_class] swarm drone</span> shell is now available in \the [T.loc].", src)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/total_creature_max //If set, it can spawn this many creatures, total, ever.
|
||||
|
||||
/obj/structure/prop/nest/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
den_mobs = list()
|
||||
START_PROCESSING(SSobj, src)
|
||||
last_spawn = world.time
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/cult/pylon/swarm/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
active_beams = list()
|
||||
|
||||
/obj/structure/cult/pylon/swarm/Destroy()
|
||||
|
||||
@@ -1,26 +1,59 @@
|
||||
/obj/structure/bed/chair/wheelchair
|
||||
name = "wheelchair"
|
||||
desc = "You sit in this. Either by will or force."
|
||||
icon = 'icons/obj/wheelchair.dmi'
|
||||
icon_state = "wheelchair"
|
||||
anchored = 0
|
||||
buckle_movable = 1
|
||||
|
||||
var/folded_type = /obj/item/wheelchair
|
||||
var/driving = 0
|
||||
var/mob/living/pulling = null
|
||||
var/bloodiness
|
||||
var/min_mob_buckle_size = MOB_SMALL
|
||||
var/max_mob_buckle_size = MOB_LARGE
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/motor
|
||||
name = "electric wheelchair"
|
||||
desc = "A motorized wheelchair controlled with a joystick on one armrest"
|
||||
icon_state = "motorchair"
|
||||
folded_type = /obj/item/wheelchair/motor
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/smallmotor
|
||||
name = "small electric wheelchair"
|
||||
desc = "A small motorized wheelchair, it looks around the right size for a Teshari"
|
||||
icon_state = "teshchair"
|
||||
min_mob_buckle_size = MOB_SMALL
|
||||
max_mob_buckle_size = MOB_MEDIUM
|
||||
folded_type = /obj/item/wheelchair/motor/small
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/can_buckle_check(mob/living/M, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(M.mob_size < min_mob_buckle_size)
|
||||
to_chat(M, SPAN_WARNING("You are too small to use \the [src]."))
|
||||
. = FALSE
|
||||
else if(M.mob_size >= max_mob_buckle_size)
|
||||
to_chat(M, SPAN_WARNING("You are too large to use \the [src]."))
|
||||
. = FALSE
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/update_icon()
|
||||
return
|
||||
cut_overlays()
|
||||
var/image/O = image(icon = icon, icon_state = "[icon_state]_overlay", layer = ABOVE_MOB_LAYER)
|
||||
O.plane = MOB_PLANE
|
||||
add_overlay(O)
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/set_dir()
|
||||
..()
|
||||
cut_overlays()
|
||||
var/image/O = image(icon = 'icons/obj/furniture.dmi', icon_state = "w_overlay", layer = FLY_LAYER, dir = src.dir)
|
||||
add_overlay(O)
|
||||
if(has_buckled_mobs())
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/L = A
|
||||
L.set_dir(dir)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(has_buckled_mobs())
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/L = A
|
||||
L.set_dir(dir)
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(W.is_wrench() || W.is_wirecutter() || istype(W,/obj/item/stack))
|
||||
@@ -93,8 +126,6 @@
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
|
||||
cut_overlays()
|
||||
playsound(src, 'sound/effects/roll.ogg', 75, 1)
|
||||
if(has_buckled_mobs())
|
||||
for(var/A in buckled_mobs)
|
||||
@@ -203,28 +234,13 @@
|
||||
usr.pulledby = null
|
||||
..()
|
||||
|
||||
/obj/item/wheelchair
|
||||
name = "wheelchair"
|
||||
desc = "A folded wheelchair that can be carried around."
|
||||
icon = 'icons/obj/furniture.dmi'
|
||||
icon_state = "wheelchair_folded"
|
||||
item_state = "wheelchair"
|
||||
w_class = ITEMSIZE_HUGE // Can't be put in backpacks. Oh well.
|
||||
|
||||
/obj/item/wheelchair/attack_self(mob/user)
|
||||
var/obj/structure/bed/chair/wheelchair/R = new /obj/structure/bed/chair/wheelchair(user.loc)
|
||||
R.add_fingerprint(user)
|
||||
R.name = src.name
|
||||
R.color = src.color
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/MouseDrop(over_object, src_location, over_location)
|
||||
..()
|
||||
if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
|
||||
if(!ishuman(usr)) return
|
||||
if(has_buckled_mobs()) return 0
|
||||
visible_message("[usr] collapses \the [src.name].")
|
||||
var/obj/item/wheelchair/R = new/obj/item/wheelchair(get_turf(src))
|
||||
var/obj/item/wheelchair/R = new folded_type(get_turf(src))
|
||||
R.name = src.name
|
||||
R.color = src.color
|
||||
spawn(0)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/obj/item/wheelchair
|
||||
name = "wheelchair"
|
||||
desc = "A folded wheelchair that can be carried around."
|
||||
icon = 'icons/obj/wheelchair.dmi'
|
||||
icon_state = "wheelchair_folded"
|
||||
item_state = "wheelchair"
|
||||
w_class = ITEMSIZE_HUGE // Can't be put in backpacks. Oh well.
|
||||
var/unfolded_type = /obj/structure/bed/chair/wheelchair
|
||||
|
||||
/obj/item/wheelchair/attack_self(mob/user)
|
||||
var/obj/structure/bed/chair/wheelchair/R = new unfolded_type(user.loc)
|
||||
R.add_fingerprint(user)
|
||||
R.name = src.name
|
||||
R.color = src.color
|
||||
qdel(src)
|
||||
|
||||
/obj/item/wheelchair/motor
|
||||
name = "electric wheelchair"
|
||||
desc = "A motorized wheelchair controlled with a joystick on one armrest"
|
||||
icon_state = "motorchair_folded"
|
||||
item_state = "motorchair"
|
||||
unfolded_type = /obj/structure/bed/chair/wheelchair/motor
|
||||
|
||||
/obj/item/wheelchair/motor/small
|
||||
name = "small electric wheelchair"
|
||||
desc = "A small motorized wheelchair, it looks around the right size for a Teshari."
|
||||
icon_state = "teshchair_folded"
|
||||
item_state = "teshchair"
|
||||
unfolded_type = /obj/structure/bed/chair/wheelchair/smallmotor
|
||||
@@ -180,6 +180,7 @@
|
||||
prob(2);/obj/item/clothing/shoes/galoshes,
|
||||
prob(2);/obj/item/clothing/under/pants/camo,
|
||||
prob(2);/obj/item/clothing/under/syndicate/tacticool,
|
||||
prob(2);/obj/item/clothing/under/hyperfiber,
|
||||
prob(2);/obj/item/device/camera,
|
||||
prob(2);/obj/item/device/flashlight/flare,
|
||||
prob(2);/obj/item/device/flashlight/glowstick,
|
||||
@@ -240,6 +241,7 @@
|
||||
prob(2);/obj/item/weapon/handcuffs/legcuffs/fuzzy,
|
||||
prob(2);/obj/item/weapon/storage/box/syndie_kit/spy,
|
||||
prob(2);/obj/item/weapon/grenade/anti_photon,
|
||||
prob(2);/obj/item/clothing/under/hyperfiber/bluespace,
|
||||
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
|
||||
prob(1);/obj/item/device/nif/bad,
|
||||
prob(1);/obj/item/device/radio_jammer,
|
||||
|
||||
@@ -27,11 +27,10 @@
|
||||
return FALSE
|
||||
|
||||
/obj/effect/wingrille_spawn/Initialize()
|
||||
. = ..()
|
||||
if(!win_path)
|
||||
return
|
||||
if(ticker && ticker.current_state < GAME_STATE_PLAYING)
|
||||
if(win_path && ticker && ticker.current_state < GAME_STATE_PLAYING)
|
||||
activate()
|
||||
..()
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/effect/wingrille_spawn/proc/activate()
|
||||
if(activated) return
|
||||
@@ -58,7 +57,8 @@
|
||||
activated = 1
|
||||
for(var/obj/effect/wingrille_spawn/other in neighbours)
|
||||
if(!other.activated) other.activate()
|
||||
qdel(src)
|
||||
if(initialized && !QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/wingrille_spawn/proc/handle_window_spawn(var/obj/structure/window/W)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user