Merge branch 'master' into upstream-merge-26140
This commit is contained in:
@@ -94,7 +94,7 @@
|
||||
name = "Head of Personnel"
|
||||
|
||||
/obj/effect/landmark/start/librarian
|
||||
name = "Librarian"
|
||||
name = "Curator"
|
||||
|
||||
/obj/effect/landmark/start/lawyer
|
||||
name = "Lawyer"
|
||||
|
||||
@@ -323,11 +323,30 @@
|
||||
/obj/effect/overlay/temp/ratvar/grille/broken
|
||||
icon_state = "ratvarbrokengrilleglow"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/mending_mantra
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 20
|
||||
alpha = 200
|
||||
icon_state = "mending_mantra"
|
||||
light_range = 1.5
|
||||
light_color = "#1E8CE1"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/mending_mantra/Initialize(mapload)
|
||||
. = ..()
|
||||
transform = matrix()*2
|
||||
var/matrix/M = transform
|
||||
M.Turn(90)
|
||||
animate(src, alpha = 20, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
|
||||
animate(src, transform = M, time = duration, flags = ANIMATION_PARALLEL)
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/volt_hit
|
||||
name = "volt blast"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 5
|
||||
icon_state = "volt_hit"
|
||||
light_range = 1.5
|
||||
light_power = 2
|
||||
light_color = LIGHT_COLOR_ORANGE
|
||||
var/mob/user
|
||||
var/damage = 20
|
||||
|
||||
@@ -336,7 +355,6 @@
|
||||
damage *= multiplier
|
||||
duration = max(round(damage * 0.2), 1)
|
||||
. = ..()
|
||||
set_light(1.5, 2, LIGHT_COLOR_ORANGE)
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/volt_hit/true/Initialize(mapload, caster, multiplier)
|
||||
. = ..()
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
diff a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm (rejected hunks)
|
||||
@@ -31,8 +31,8 @@
|
||||
. = ..()
|
||||
deltimer(timerid)
|
||||
|
||||
-/obj/effect/overlay/temp/New()
|
||||
- ..()
|
||||
+/obj/effect/overlay/temp/Initialize()
|
||||
+ . = ..()
|
||||
if(randomdir)
|
||||
setDir(pick(GLOB.cardinal))
|
||||
flick("[icon_state]", src) //Because we might be pulling it from a pool, flick whatever icon it uses so it starts at the start of the icon's animation.
|
||||
@@ -214,7 +221,7 @@
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "3"
|
||||
duration = 20
|
||||
-
|
||||
+
|
||||
/obj/effect/overlay/temp/cult
|
||||
randomdir = 0
|
||||
duration = 10
|
||||
@@ -9,10 +9,12 @@
|
||||
host = _host
|
||||
last_host_loc = _host.loc
|
||||
ignore_if_not_on_turf = _ignore_if_not_on_turf
|
||||
checkers = list()
|
||||
SetRange(range)
|
||||
|
||||
/datum/proximity_monitor/Destroy()
|
||||
host = null
|
||||
last_host_loc = null
|
||||
QDEL_LIST(checkers)
|
||||
return ..()
|
||||
|
||||
@@ -34,46 +36,47 @@
|
||||
|
||||
current_range = range
|
||||
|
||||
var/list/old_checkers = checkers
|
||||
var/old_checkers_len = LAZYLEN(old_checkers)
|
||||
var/list/checkers_local = checkers
|
||||
var/old_checkers_len = checkers_local.len
|
||||
|
||||
var/atom/host_loc = host.loc
|
||||
var/atom/_host = host
|
||||
|
||||
var/atom/loc_to_use = ignore_if_not_on_turf ? host_loc : get_turf(host)
|
||||
var/atom/loc_to_use = ignore_if_not_on_turf ? _host.loc : get_turf(_host)
|
||||
if(!isturf(loc_to_use)) //only check the host's loc
|
||||
if(range)
|
||||
var/obj/effect/abstract/proximity_checker/pc
|
||||
if(old_checkers_len)
|
||||
pc = old_checkers[old_checkers_len]
|
||||
--old_checkers.len
|
||||
pc = checkers_local[old_checkers_len]
|
||||
--checkers_local.len
|
||||
QDEL_LIST(checkers_local)
|
||||
else
|
||||
pc = new(host_loc, src)
|
||||
pc = new(loc_to_use, src)
|
||||
|
||||
checkers = list(pc) //only check the host's loc
|
||||
checkers_local += pc //only check the host's loc
|
||||
return
|
||||
|
||||
var/list/turfs = RANGE_TURFS(range, loc_to_use)
|
||||
var/old_checkers_used = min(turfs.len, old_checkers_len)
|
||||
var/turfs_len = turfs.len
|
||||
var/old_checkers_used = min(turfs_len, old_checkers_len)
|
||||
|
||||
//reuse what we can
|
||||
for(var/I in 1 to old_checkers_len)
|
||||
if(I <= old_checkers_used)
|
||||
var/obj/effect/abstract/proximity_checker/pc = old_checkers[I]
|
||||
var/obj/effect/abstract/proximity_checker/pc = checkers_local[I]
|
||||
pc.loc = turfs[I]
|
||||
else
|
||||
qdel(old_checkers[I]) //delete the leftovers
|
||||
qdel(checkers_local[I]) //delete the leftovers
|
||||
|
||||
LAZYCLEARLIST(old_checkers)
|
||||
|
||||
//create what we lack
|
||||
var/list/checkers_local = list()
|
||||
for(var/I in (old_checkers_used + 1) to turfs.len)
|
||||
checkers_local += new /obj/effect/abstract/proximity_checker(turfs[I], src)
|
||||
|
||||
checkers = checkers_local
|
||||
if(old_checkers_len < turfs_len)
|
||||
//create what we lack
|
||||
for(var/I in (old_checkers_used + 1) to turfs_len)
|
||||
checkers_local += new /obj/effect/abstract/proximity_checker(turfs[I], src)
|
||||
else
|
||||
checkers_local.Cut(old_checkers_used + 1, old_checkers_len)
|
||||
|
||||
/obj/effect/abstract/proximity_checker
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
anchored = TRUE
|
||||
var/datum/proximity_monitor/monitor
|
||||
|
||||
/obj/effect/abstract/proximity_checker/Initialize(mapload, datum/proximity_monitor/_monitor)
|
||||
@@ -81,8 +84,8 @@
|
||||
if(_monitor)
|
||||
monitor = _monitor
|
||||
else
|
||||
stack_trace("proximity_checker created without proximity_monitor")
|
||||
qdel(src)
|
||||
stack_trace("proximity_checker created without host")
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/effect/abstract/proximity_checker/Destroy()
|
||||
monitor = null
|
||||
@@ -90,9 +93,6 @@
|
||||
|
||||
/obj/effect/abstract/proximity_checker/Crossed(atom/movable/AM)
|
||||
set waitfor = FALSE
|
||||
var/datum/proximity_monitor/M = monitor
|
||||
if(!M.current_range)
|
||||
return
|
||||
var/atom/H = M.host
|
||||
var/atom/H = monitor.host
|
||||
testing("HasProx: [H] -> [AM]")
|
||||
H.HasProximity(AM)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
diff a/code/game/objects/items.dm b/code/game/objects/items.dm (rejected hunks)
|
||||
@@ -102,7 +102,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
|
||||
/obj/item/Initialize()
|
||||
if (!materials)
|
||||
materials = list()
|
||||
- ..()
|
||||
+ . = ..()
|
||||
for(var/path in actions_types)
|
||||
new path(src)
|
||||
actions_types = null
|
||||
@@ -86,7 +86,7 @@
|
||||
name = "station charter for [station_name()]"
|
||||
desc = "An official document entrusting the governance of \
|
||||
[station_name()] and surrounding space to Captain [uname]."
|
||||
feedback_set_details("station_renames","[station_name()]")
|
||||
SSblackbox.set_details("station_renames","[station_name()]")
|
||||
if(!unlimited_uses)
|
||||
used = TRUE
|
||||
|
||||
|
||||
@@ -161,11 +161,11 @@
|
||||
icon_state = "pda-roboticist"
|
||||
default_cartridge = /obj/item/weapon/cartridge/roboticist
|
||||
|
||||
/obj/item/device/pda/librarian
|
||||
name = "librarian PDA"
|
||||
/obj/item/device/pda/curator
|
||||
name = "curator PDA"
|
||||
icon_state = "pda-library"
|
||||
icon_alert = "pda-r-library"
|
||||
default_cartridge = /obj/item/weapon/cartridge/librarian
|
||||
default_cartridge = /obj/item/weapon/cartridge/curator
|
||||
desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a WGW-11 series e-reader."
|
||||
note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!"
|
||||
silent = 1 //Quiet in the library!
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
access_mime = 1
|
||||
var/mime_charges = 5
|
||||
|
||||
/obj/item/weapon/cartridge/librarian
|
||||
/obj/item/weapon/cartridge/curator
|
||||
name = "\improper Lib-Tweet cartridge"
|
||||
icon_state = "cart-s"
|
||||
access_newscaster = 1
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/device/flashlight/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
|
||||
/obj/item/device/flashlight/attack(mob/living/carbon/M, mob/living/carbon/human/user)
|
||||
add_fingerprint(user)
|
||||
if(on && user.zone_selected == "eyes")
|
||||
if(istype(M) && on && user.zone_selected in list("eyes", "mouth"))
|
||||
|
||||
if((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
|
||||
return ..() //just hit them in the head
|
||||
@@ -48,28 +48,101 @@
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = M //mob has protective eyewear
|
||||
if(ishuman(M) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)))
|
||||
to_chat(user, "<span class='notice'>You're going to need to remove that [(H.head && H.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask": "glasses"] first.</span>")
|
||||
if(!M.get_bodypart("head"))
|
||||
to_chat(user, "<span class='warning'>[M] doesn't have a head!</span>")
|
||||
return
|
||||
|
||||
if(M == user) //they're using it on themselves
|
||||
if(M.flash_act(visual = 1))
|
||||
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes! Trippy!</span>")
|
||||
else
|
||||
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes.</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] directs [src] to [M]'s eyes.</span>", \
|
||||
"<span class='danger'>You direct [src] to [M]'s eyes.</span>")
|
||||
var/mob/living/carbon/C = M
|
||||
if(istype(C))
|
||||
if(C.stat == DEAD || (C.disabilities & BLIND)) //mob is dead or fully blind
|
||||
to_chat(user, "<span class='warning'>[C] pupils don't react to the light!</span>")
|
||||
else if(C.dna.check_mutation(XRAY)) //mob has X-RAY vision
|
||||
to_chat(user, "<span class='danger'>[C] pupils give an eerie glow!</span>")
|
||||
else //they're okay!
|
||||
if(C.flash_act(visual = 1))
|
||||
to_chat(user, "<span class='notice'>[C]'s pupils narrow.</span>")
|
||||
switch(user.zone_selected)
|
||||
if("eyes")
|
||||
if((M.head && M.head.flags_cover & HEADCOVERSEYES) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSEYES) || (M.glasses && M.glasses.flags_cover & GLASSESCOVERSEYES))
|
||||
to_chat(user, "<span class='notice'>You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask": "glasses"] first.</span>")
|
||||
return
|
||||
|
||||
var/obj/item/organ/eyes/E = M.getorganslot("eye_sight")
|
||||
if(!E)
|
||||
to_chat(user, "<span class='danger'>[M] doesn't have any eyes!</span>")
|
||||
return
|
||||
|
||||
if(M == user) //they're using it on themselves
|
||||
if(M.flash_act(visual = 1))
|
||||
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes! Trippy!</span>")
|
||||
else
|
||||
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes.</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] directs [src] to [M]'s eyes.</span>", \
|
||||
"<span class='danger'>You direct [src] to [M]'s eyes.</span>")
|
||||
if(M.stat == DEAD || (M.disabilities & BLIND) || !M.flash_act(visual = 1)) //mob is dead or fully blind
|
||||
to_chat(user, "<span class='warning'>[M]'s pupils don't react to the light!</span>")
|
||||
else if(M.dna && M.dna.check_mutation(XRAY)) //mob has X-RAY vision
|
||||
to_chat(user, "<span class='danger'>[M]'s pupils give an eerie glow!</span>")
|
||||
else //they're okay!
|
||||
to_chat(user, "<span class='notice'>[M]'s pupils narrow.</span>")
|
||||
|
||||
if("mouth")
|
||||
|
||||
if((M.head && M.head.flags_cover & HEADCOVERSMOUTH) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
|
||||
to_chat(user, "<span class='notice'>You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSMOUTH) ? "helmet" : "mask"] first.</span>")
|
||||
return
|
||||
|
||||
var/their = M.p_their()
|
||||
|
||||
var/list/mouth_organs = new
|
||||
for(var/obj/item/organ/O in M.internal_organs)
|
||||
if(O.zone == "mouth")
|
||||
mouth_organs.Add(O)
|
||||
var/organ_list = ""
|
||||
var/organ_count = LAZYLEN(mouth_organs)
|
||||
if(organ_count)
|
||||
for(var/I in 1 to organ_count)
|
||||
if(I > 1)
|
||||
if(I == mouth_organs.len)
|
||||
organ_list += ", and "
|
||||
else
|
||||
organ_list += ", "
|
||||
var/obj/item/organ/O = mouth_organs[I]
|
||||
organ_list += (O.gender == "plural" ? O.name : "\an [O.name]")
|
||||
|
||||
var/pill_count = 0
|
||||
for(var/datum/action/item_action/hands_free/activate_pill/AP in M.actions)
|
||||
pill_count++
|
||||
|
||||
if(M == user)
|
||||
var/can_use_mirror = FALSE
|
||||
if(isturf(user.loc))
|
||||
var/obj/structure/mirror/mirror = locate(/obj/structure/mirror, user.loc)
|
||||
if(mirror)
|
||||
switch(user.dir)
|
||||
if(NORTH)
|
||||
can_use_mirror = mirror.pixel_y > 0
|
||||
if(SOUTH)
|
||||
can_use_mirror = mirror.pixel_y < 0
|
||||
if(EAST)
|
||||
can_use_mirror = mirror.pixel_x > 0
|
||||
if(WEST)
|
||||
can_use_mirror = mirror.pixel_x < 0
|
||||
|
||||
M.visible_message("[M] directs [src] to [their] mouth.", \
|
||||
"<span class='notice'>You point [src] into your mouth.</span>")
|
||||
if(!can_use_mirror)
|
||||
to_chat(user, "<span class='notice'>You can't see anything without a mirror.</span>")
|
||||
return
|
||||
if(organ_count)
|
||||
to_chat(user, "<span class='notice'>Inside your mouth [organ_count > 1 ? "are" : "is"] [organ_list].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There's nothing inside your mouth.</span>")
|
||||
if(pill_count)
|
||||
to_chat(user, "<span class='notice'>You have [pill_count] implanted pill[pill_count > 1 ? "s" : ""].</span>")
|
||||
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] directs [src] to [M]'s mouth.</span>",\
|
||||
"<span class='notice'>You direct [src] to [M]'s mouth.</span>")
|
||||
if(organ_count)
|
||||
to_chat(user, "<span class='notice'>Inside [their] mouth [organ_count > 1 ? "are" : "is"] [organ_list].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[M] doesn't have any organs in [their] mouth.</span>")
|
||||
if(pill_count)
|
||||
to_chat(user, "<span class='notice'>[M] has [pill_count] pill[pill_count > 1 ? "s" : ""] implanted in [their] teeth.")
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -280,7 +353,7 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/flashlight/emp/attack(mob/living/M, mob/living/user)
|
||||
if(on && user.zone_selected == "eyes") // call original attack proc only if aiming at the eyes
|
||||
if(on && user.zone_selected in list("eyes", "mouth")) // call original attack when examining organs
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
@@ -7,10 +7,14 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "materials=2;magnets=1;bluespace=2"
|
||||
unique_rename = TRUE
|
||||
var/gpstag = "COM0"
|
||||
var/emped = FALSE
|
||||
var/turf/locked_location
|
||||
var/tracking = TRUE
|
||||
var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user.
|
||||
var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown
|
||||
|
||||
|
||||
/obj/item/device/gps/Initialize()
|
||||
..()
|
||||
@@ -27,6 +31,7 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
cut_overlay("working")
|
||||
add_overlay("emp")
|
||||
addtimer(CALLBACK(src, .proc/reboot), 300, TIMER_OVERRIDE) //if a new EMP happens, remove the old timer so it doesn't reactivate early
|
||||
SStgui.close_uis(src) //Close the UI control if it is open.
|
||||
|
||||
/obj/item/device/gps/proc/reboot()
|
||||
emped = FALSE
|
||||
@@ -34,6 +39,9 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
add_overlay("working")
|
||||
|
||||
/obj/item/device/gps/AltClick(mob/user)
|
||||
toggletracking(user)
|
||||
|
||||
/obj/item/device/gps/proc/toggletracking(mob/user)
|
||||
if(!user.canUseTopic(src, be_close=TRUE))
|
||||
return //user not valid to use gps
|
||||
if(emped)
|
||||
@@ -48,45 +56,89 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
|
||||
tracking = TRUE
|
||||
|
||||
/obj/item/device/gps/attack_self(mob/user)
|
||||
if(!tracking)
|
||||
to_chat(user, "[src] is turned off. Use alt+click to toggle it back on.")
|
||||
return
|
||||
|
||||
var/obj/item/device/gps/t = ""
|
||||
var/gps_window_height = 110 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
|
||||
/obj/item/device/gps/ui_interact(mob/user, ui_key = "gps", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
|
||||
if(emped)
|
||||
t += "ERROR"
|
||||
else
|
||||
t += "<BR><A href='?src=\ref[src];tag=1'>Set Tag</A> "
|
||||
t += "<BR>Tag: [gpstag]"
|
||||
if(locked_location && locked_location.loc)
|
||||
t += "<BR>Bluespace coordinates saved: [locked_location.loc]"
|
||||
gps_window_height += 20
|
||||
|
||||
for(var/obj/item/device/gps/G in GLOB.GPS_list)
|
||||
var/turf/pos = get_turf(G)
|
||||
var/area/gps_area = get_area(G)
|
||||
var/tracked_gpstag = G.gpstag
|
||||
if(G.emped == 1)
|
||||
t += "<BR>[tracked_gpstag]: ERROR"
|
||||
else if(G.tracking)
|
||||
t += "<BR>[tracked_gpstag]: [format_text(gps_area.name)] ([pos.x], [pos.y], [pos.z])"
|
||||
else
|
||||
continue
|
||||
var/datum/browser/popup = new(user, "GPS", name, 360, min(gps_window_height, 800))
|
||||
popup.set_content(t)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
to_chat(user, "[src] fizzles weakly.")
|
||||
return
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
|
||||
ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height
|
||||
ui.open()
|
||||
|
||||
ui.set_autoupdate(state = updating)
|
||||
|
||||
|
||||
/obj/item/device/gps/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["power"] = tracking
|
||||
data["tag"] = gpstag
|
||||
data["updating"] = updating
|
||||
data["globalmode"] = global_mode
|
||||
if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
|
||||
return data
|
||||
|
||||
var/turf/curr = get_turf(src)
|
||||
data["current"] = "[get_area_name(curr)] ([curr.x], [curr.y], [curr.z])"
|
||||
|
||||
var/list/signals = list()
|
||||
data["signals"] = list()
|
||||
|
||||
for(var/gps in GLOB.GPS_list)
|
||||
var/obj/item/device/gps/G = gps
|
||||
if(G.emped || !G.tracking || G == src)
|
||||
continue
|
||||
var/turf/pos = get_turf(G)
|
||||
if(!global_mode && pos.z != curr.z)
|
||||
continue
|
||||
var/area/gps_area = get_area_name(G)
|
||||
var/list/signal = list()
|
||||
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
|
||||
signal["area"] = format_text(gps_area)
|
||||
signal["coord"] = "[pos.x], [pos.y], [pos.z]"
|
||||
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
|
||||
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
|
||||
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
|
||||
var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful.
|
||||
if(!direction)
|
||||
direction = "CENTER"
|
||||
signal["degrees"] = "N/A"
|
||||
signal["direction"] = direction
|
||||
|
||||
signals += list(signal) //Add this signal to the list of signals
|
||||
data["signals"] = signals
|
||||
return data
|
||||
|
||||
|
||||
|
||||
/obj/item/device/gps/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("rename")
|
||||
var/a = input("Please enter desired tag.", name, gpstag) as text
|
||||
a = uppertext(copytext(sanitize(a), 1, 5))
|
||||
gpstag = a
|
||||
name = "global positioning system ([gpstag])"
|
||||
. = TRUE
|
||||
if("power")
|
||||
toggletracking(usr)
|
||||
. = TRUE
|
||||
if("updating")
|
||||
updating = !updating
|
||||
. = TRUE
|
||||
if("globalmode")
|
||||
global_mode = !global_mode
|
||||
. = TRUE
|
||||
|
||||
/obj/item/device/gps/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["tag"] )
|
||||
var/a = input("Please enter desired tag.", name, gpstag) as text
|
||||
a = uppertext(copytext(sanitize(a), 1, 5))
|
||||
a = copytext(sanitize(a), 1, 20)
|
||||
if(in_range(src, usr))
|
||||
gpstag = a
|
||||
name = "global positioning system ([gpstag])"
|
||||
attack_self(usr)
|
||||
|
||||
/obj/item/device/gps/science
|
||||
@@ -157,4 +209,4 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
clear()
|
||||
tagged = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
. = ..()
|
||||
. = ..()
|
||||
@@ -296,6 +296,7 @@
|
||||
// --- Cold, emotionless machines. ---
|
||||
else if(isobj(M))
|
||||
jobname = "Machine"
|
||||
voice = capitalize(voice)
|
||||
|
||||
// --- Unidentifiable mob ---
|
||||
else
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
if(src.l_arm && src.r_arm)
|
||||
if(src.l_leg && src.r_leg)
|
||||
if(src.chest && src.head)
|
||||
feedback_inc("cyborg_frames_built",1)
|
||||
SSblackbox.inc("cyborg_frames_built",1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
O.mmi = W //and give the real mmi to the borg.
|
||||
O.updatename()
|
||||
|
||||
feedback_inc("cyborg_birth",1)
|
||||
SSblackbox.inc("cyborg_birth",1)
|
||||
|
||||
forceMove(O)
|
||||
O.robot_suit = src
|
||||
|
||||
@@ -237,6 +237,7 @@
|
||||
/obj/item/borg/upgrade/selfrepair/proc/check_dropped()
|
||||
if(loc != cyborg)
|
||||
toggle_action.Remove(cyborg)
|
||||
QDEL_NULL(toggle_action)
|
||||
cyborg = null
|
||||
deactivate()
|
||||
|
||||
@@ -399,4 +400,4 @@
|
||||
return
|
||||
|
||||
R.make_shell(src)
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -29,6 +29,7 @@ Mineral Sheets
|
||||
GLOBAL_LIST_INIT(sandstone_recipes, list ( \
|
||||
new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("aesthetic volcanic floor tile", /obj/item/stack/tile/basalt, 2, 2, 4, 20), \
|
||||
new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Breakdown into sand", /obj/item/weapon/ore/glass, 1, one_per_turf = 0, on_floor = 1), \
|
||||
/* new/datum/stack_recipe("sandstone wall", ???), \
|
||||
@@ -334,12 +335,20 @@ GLOBAL_LIST_INIT(snow_recipes, list ( \
|
||||
/*
|
||||
* Adamantine
|
||||
*/
|
||||
GLOBAL_LIST_INIT(adamantine_recipes, list(
|
||||
new /datum/stack_recipe("artificial golem shell", /obj/item/golem_shell/artificial, req_amount=1, res_amount=1),
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/adamantine
|
||||
name = "adamantine"
|
||||
icon_state = "sheet-adamantine"
|
||||
singular_name = "adamantine sheet"
|
||||
origin_tech = "materials=4"
|
||||
|
||||
/obj/item/stack/sheet/mineral/adamantine/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.adamantine_recipes
|
||||
..()
|
||||
|
||||
/*
|
||||
* Mythril
|
||||
*/
|
||||
|
||||
@@ -328,7 +328,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
|
||||
|
||||
/obj/item/stack/tile/brass/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.brass_recipes
|
||||
..()
|
||||
. = ..()
|
||||
pixel_x = 0
|
||||
pixel_y = 0
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
var/turf_type = null
|
||||
var/mineralType = null
|
||||
|
||||
/obj/item/stack/tile/New(loc, amount)
|
||||
..()
|
||||
/obj/item/stack/tile/Initialize(mapload, amount)
|
||||
. = ..()
|
||||
pixel_x = rand(-3, 3)
|
||||
pixel_y = rand(-3, 3) //randomize a little
|
||||
|
||||
@@ -88,6 +88,14 @@
|
||||
turf_type = /turf/open/floor/wood
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
//Basalt
|
||||
/obj/item/stack/tile/basalt
|
||||
name = "basalt tile"
|
||||
singular_name = "basalt floor tile"
|
||||
desc = "Artificially made ashy soil themed on a hostile enviroment."
|
||||
icon_state = "tile_basalt"
|
||||
origin_tech = "materials=1"
|
||||
turf_type = /turf/open/floor/grass/fakebasalt
|
||||
|
||||
//Carpets
|
||||
/obj/item/stack/tile/carpet
|
||||
|
||||
@@ -1218,9 +1218,9 @@
|
||||
icon_state = "lawyer"
|
||||
toysay = "My client is a dirty traitor!"
|
||||
|
||||
/obj/item/toy/figure/librarian
|
||||
name = "Librarian action figure"
|
||||
icon_state = "librarian"
|
||||
/obj/item/toy/figure/curator
|
||||
name = "Curator action figure"
|
||||
icon_state = "curator"
|
||||
toysay = "One day while..."
|
||||
|
||||
/obj/item/toy/figure/md
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
to_chat(user, "<span class='notice'>You start planting the bomb...</span>")
|
||||
|
||||
if(do_after(user, 50, target = AM))
|
||||
if(do_after(user, 50, target = AM))
|
||||
if(!user.temporarilyRemoveItemFromInventory(src))
|
||||
return
|
||||
src.target = AM
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
|
||||
to_chat(user, "<span class='notice'>You start planting the [src]. The timer is set to [det_time]...</span>")
|
||||
|
||||
if(do_after(user, 50, target = AM))
|
||||
if(do_after(user, 30, target = AM))
|
||||
if(!user.temporarilyRemoveItemFromInventory(src))
|
||||
return
|
||||
src.target = AM
|
||||
@@ -165,4 +165,4 @@
|
||||
icon_state = "plasticx40"
|
||||
item_state = "plasticx4"
|
||||
directional = TRUE
|
||||
boom_sizes = list(0, 2, 5)
|
||||
boom_sizes = list(0, 2, 5)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/weapon/grenade/spawnergrenade
|
||||
desc = "It will unleash unleash an unspecified anomaly into the vicinity."
|
||||
desc = "It will unleash an unspecified anomaly into the vicinity."
|
||||
name = "delivery grenade"
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "delivery"
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
if(do_mob(user, C, 30) && (C.get_num_arms() >= 2 || C.get_arm_ignore()))
|
||||
apply_cuffs(C,user)
|
||||
to_chat(user, "<span class='notice'>You handcuff [C].</span>")
|
||||
feedback_add_details("handcuffs","[type]")
|
||||
SSblackbox.add_details("handcuffs","[type]")
|
||||
|
||||
add_logs(user, C, "handcuffed")
|
||||
else
|
||||
@@ -275,7 +275,7 @@
|
||||
C.legcuffed = src
|
||||
src.loc = C
|
||||
C.update_inv_legcuffed()
|
||||
feedback_add_details("handcuffs","[type]")
|
||||
SSblackbox.add_details("handcuffs","[type]")
|
||||
else if(isanimal(L))
|
||||
var/mob/living/simple_animal/SA = L
|
||||
if(SA.mob_size > MOB_SIZE_TINY)
|
||||
@@ -336,7 +336,7 @@
|
||||
C.legcuffed = src
|
||||
src.loc = C
|
||||
C.update_inv_legcuffed()
|
||||
feedback_add_details("handcuffs","[type]")
|
||||
SSblackbox.add_details("handcuffs","[type]")
|
||||
to_chat(C, "<span class='userdanger'>\The [src] ensnares you!</span>")
|
||||
C.Weaken(weaken)
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/weapon/his_grace/CtrlClick(mob/user) //you can't pull his grace
|
||||
attack_hand(user)
|
||||
return
|
||||
|
||||
/obj/item/weapon/his_grace/examine(mob/user)
|
||||
..()
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
SSreligion.holy_weapon_type = holy_weapon.type
|
||||
|
||||
feedback_set_details("chaplain_weapon","[choice]")
|
||||
SSblackbox.set_details("chaplain_weapon","[choice]")
|
||||
|
||||
if(holy_weapon)
|
||||
holy_weapon.reskinned = TRUE
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var/brightness_on = 3
|
||||
|
||||
/obj/item/weapon/melee/energy/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
if(LAZYLEN(possible_colors))
|
||||
item_color = pick(possible_colors)
|
||||
switch(item_color)//Only run this check if the color was picked randomly, so that colors can be manually set for non-random colored energy weapons.
|
||||
@@ -183,8 +183,8 @@
|
||||
light_color = "#40ceff"
|
||||
possible_colors = null
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/cyborg/saw/New()
|
||||
..()
|
||||
/obj/item/weapon/melee/energy/sword/cyborg/saw/Initialize()
|
||||
. = ..()
|
||||
icon_state = "esaw_0"
|
||||
item_color = null
|
||||
|
||||
@@ -207,19 +207,9 @@
|
||||
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/saber/attackby(obj/item/weapon/W, mob/living/user, params)
|
||||
if(istype(W, /obj/item/weapon/melee/energy/sword/saber))
|
||||
to_chat(user, "<span class='notice'>You attach the ends of the two energy swords, making a single double-bladed weapon! You're cool.</span>")
|
||||
var/obj/item/weapon/melee/energy/sword/saber/other_esword = W
|
||||
var/obj/item/weapon/twohanded/dualsaber/newSaber = new(user.loc)
|
||||
if(hacked || other_esword.hacked)
|
||||
newSaber.hacked = TRUE
|
||||
newSaber.item_color = "rainbow"
|
||||
qdel(W)
|
||||
qdel(src)
|
||||
user.put_in_hands(newSaber)
|
||||
else if(istype(W, /obj/item/device/multitool))
|
||||
if(hacked == 0)
|
||||
hacked = 1
|
||||
if(istype(W, /obj/item/device/multitool))
|
||||
if(!hacked)
|
||||
hacked = TRUE
|
||||
item_color = "rainbow"
|
||||
to_chat(user, "<span class='warning'>RNBW_ENGAGE</span>")
|
||||
|
||||
@@ -253,14 +243,12 @@
|
||||
sharpness = IS_SHARP
|
||||
|
||||
//Most of the other special functions are handled in their own files. aka special snowflake code so kewl
|
||||
/obj/item/weapon/melee/energy/blade/New()
|
||||
/obj/item/weapon/melee/energy/blade/Initialize()
|
||||
. = ..()
|
||||
spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
|
||||
/obj/item/weapon/melee/energy/blade/dropped()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/energy/blade/attack_self(mob/user)
|
||||
return
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
SSreligion.bible_icon_state = B.icon_state
|
||||
SSreligion.bible_item_state = B.item_state
|
||||
|
||||
feedback_set_details("religion_book","[biblename]")
|
||||
SSblackbox.set_details("religion_book","[biblename]")
|
||||
usr << browse(null, "window=editicon")
|
||||
|
||||
/obj/item/weapon/storage/book/bible/proc/bless(mob/living/carbon/human/H, mob/living/user)
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
/obj/item/weapon/implanter, /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool/mini,
|
||||
/obj/item/device/firing_pin
|
||||
)
|
||||
//can hold both regular pens and energy daggers. made for your every-day tactical librarians/murderers.
|
||||
//can hold both regular pens and energy daggers. made for your every-day tactical curators/murderers.
|
||||
priority = FALSE
|
||||
quickdraw = TRUE
|
||||
silent = TRUE
|
||||
|
||||
@@ -92,8 +92,7 @@
|
||||
new /obj/item/pizzabox/bomb
|
||||
|
||||
if("darklord") //20 tc + tk + summon item close enough for now
|
||||
new /obj/item/weapon/melee/energy/sword/saber(src)
|
||||
new /obj/item/weapon/melee/energy/sword/saber(src)
|
||||
new /obj/item/weapon/twohanded/dualsaber(src)
|
||||
new /obj/item/weapon/dnainjector/telemut/darkbundle(src)
|
||||
new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
|
||||
new /obj/item/weapon/card/id/syndicate(src)
|
||||
@@ -219,7 +218,8 @@
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/polonium(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/venom(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/neurotoxin2(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/spewium(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/cyanide(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/histamine(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/initropidril(src)
|
||||
|
||||
@@ -262,11 +262,11 @@
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70)
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/hacked = 0
|
||||
var/brightness_on = 6//TWICE AS BRIGHT AS A REGULAR ESWORD
|
||||
var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD
|
||||
var/list/possible_colors = list("red", "blue", "green", "purple")
|
||||
|
||||
/obj/item/weapon/twohanded/dualsaber/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
if(LAZYLEN(possible_colors))
|
||||
item_color = pick(possible_colors)
|
||||
switch(item_color)
|
||||
|
||||
@@ -71,3 +71,9 @@
|
||||
icon_state = "refill_clothes"
|
||||
charges = list(31, 4, 4)// of 101 standard, 12 contraband, 10 premium(?)
|
||||
init_charges = list(31, 4, 4)
|
||||
|
||||
/obj/item/weapon/vending_refill/medical
|
||||
machine_name = "NanoMed"
|
||||
icon_state = "refill_medical"
|
||||
charges = list(26, 5, 3)// of 76 standard, 13 contraband, 8 premium
|
||||
init_charges = list(26, 5, 3)
|
||||
@@ -390,7 +390,7 @@
|
||||
desc = "A chainsaw that has replaced your arm."
|
||||
icon_state = "chainsaw_on"
|
||||
item_state = "mounted_chainsaw"
|
||||
flags = NODROP | ABSTRACT
|
||||
flags = NODROP | ABSTRACT | DROPDEL
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
force = 21
|
||||
throwforce = 0
|
||||
@@ -400,10 +400,17 @@
|
||||
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
|
||||
hitsound = 'sound/weapons/chainsawhit.ogg'
|
||||
|
||||
/obj/item/weapon/mounted_chainsaw/dropped()
|
||||
..()
|
||||
/obj/item/weapon/mounted_chainsaw/Destroy()
|
||||
var/obj/item/bodypart/part
|
||||
new /obj/item/weapon/twohanded/required/chainsaw(get_turf(src))
|
||||
qdel(src)
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/holder = loc
|
||||
var/index = holder.get_held_index_of_item(src)
|
||||
if(index)
|
||||
part = holder.hand_bodyparts[index]
|
||||
. = ..()
|
||||
if(part)
|
||||
part.drop_limb()
|
||||
|
||||
/obj/item/weapon/statuebust
|
||||
name = "bust"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(loc, laws, brain.brainmob)
|
||||
if(brain.force_replace_ai_name)
|
||||
A.fully_replace_character_name(A.name, brain.replacement_ai_name())
|
||||
feedback_inc("cyborg_ais_created",1)
|
||||
SSblackbox.inc("cyborg_ais_created",1)
|
||||
qdel(src)
|
||||
else
|
||||
state = AI_READY_CORE
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
else
|
||||
for(var/mob/M in range(1,src))
|
||||
if(CanHug(M))
|
||||
child.Attach(M)
|
||||
child.Leap(M)
|
||||
break
|
||||
|
||||
/obj/structure/alien/egg/obj_break(damage_flag)
|
||||
|
||||
@@ -11,32 +11,31 @@
|
||||
max_integrity = 200
|
||||
integrity_failure = 50
|
||||
var/obj/item/showpiece = null
|
||||
var/alert = 0
|
||||
var/open = 0
|
||||
var/alert = TRUE
|
||||
var/open = FALSE
|
||||
var/openable = TRUE
|
||||
var/obj/item/weapon/electronics/airlock/electronics
|
||||
var/start_showpiece_type = null //add type for items on display
|
||||
|
||||
/obj/structure/displaycase/New()
|
||||
..()
|
||||
/obj/structure/displaycase/Initialize()
|
||||
. = ..()
|
||||
if(start_showpiece_type)
|
||||
showpiece = new start_showpiece_type (src)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/displaycase/Destroy()
|
||||
if(electronics)
|
||||
qdel(electronics)
|
||||
electronics = null
|
||||
QDEL_NULL(electronics)
|
||||
if(showpiece)
|
||||
qdel(showpiece)
|
||||
showpiece = null
|
||||
QDEL_NULL(showpiece)
|
||||
return ..()
|
||||
|
||||
/obj/structure/displaycase/examine(mob/user)
|
||||
..()
|
||||
if(showpiece)
|
||||
to_chat(user, "<span class='notice'>There's [showpiece] inside.</span>")
|
||||
if(alert)
|
||||
to_chat(user, "<span class='notice'>Hooked up with an anti-theft system.</span>")
|
||||
if(showpiece)
|
||||
to_chat(user, "<span class='notice'>There's [showpiece] inside.</span>")
|
||||
|
||||
|
||||
/obj/structure/displaycase/proc/dump()
|
||||
@@ -83,8 +82,8 @@
|
||||
try
|
||||
getFlatIcon(A,defdir=4)
|
||||
catch
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/displaycase/proc/get_flat_icon_directional(atom/A)
|
||||
//Get flatIcon even if dir is mismatched for directionless icons
|
||||
@@ -115,7 +114,7 @@
|
||||
return
|
||||
|
||||
/obj/structure/displaycase/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(W.GetID() && !broken)
|
||||
if(W.GetID() && !broken && openable)
|
||||
if(allowed(user))
|
||||
to_chat(user, "<span class='notice'>You [open ? "close":"open"] the [src]</span>")
|
||||
toggle_lock(user)
|
||||
@@ -134,7 +133,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] is already in good condition!</span>")
|
||||
return
|
||||
else if(!alert && istype(W,/obj/item/weapon/crowbar)) //Only applies to the lab cage and player made display cases
|
||||
else if(!alert && istype(W,/obj/item/weapon/crowbar) && openable) //Only applies to the lab cage and player made display cases
|
||||
if(broken)
|
||||
if(showpiece)
|
||||
to_chat(user, "<span class='notice'>Remove the displayed object first.</span>")
|
||||
@@ -147,8 +146,7 @@
|
||||
to_chat(user, "<span class='notice'>You [open ? "close":"open"] the [src]</span>")
|
||||
toggle_lock(user)
|
||||
else if(open && !showpiece)
|
||||
if(user.drop_item())
|
||||
W.loc = src
|
||||
if(user.transferItemToLoc(W, src))
|
||||
showpiece = W
|
||||
to_chat(user, "<span class='notice'>You put [W] on display</span>")
|
||||
update_icon()
|
||||
@@ -176,8 +174,8 @@
|
||||
/obj/structure/displaycase/attack_hand(mob/user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if (showpiece && (broken || open))
|
||||
dump()
|
||||
to_chat(user, "<span class='notice'>You deactivate the hover field built into the case.</span>")
|
||||
dump()
|
||||
src.add_fingerprint(user)
|
||||
update_icon()
|
||||
return
|
||||
@@ -249,3 +247,115 @@
|
||||
desc = "A glass lab container for storing interesting creatures."
|
||||
start_showpiece_type = /obj/item/clothing/mask/facehugger/lamarr
|
||||
req_access = list(GLOB.access_rd)
|
||||
|
||||
/obj/structure/displaycase/trophy
|
||||
name = "trophy display case"
|
||||
desc = "Store your trophies of accomplishment in here, and they will stay forever."
|
||||
var/trophy_message = ""
|
||||
var/placer_key = ""
|
||||
var/added_roundstart = TRUE
|
||||
var/is_locked = TRUE
|
||||
|
||||
alert = TRUE
|
||||
integrity_failure = 0
|
||||
openable = FALSE
|
||||
|
||||
/obj/structure/displaycase/trophy/Initialize()
|
||||
. = ..()
|
||||
GLOB.trophy_cases += src
|
||||
|
||||
/obj/structure/displaycase/trophy/Destroy()
|
||||
GLOB.trophy_cases -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/displaycase/trophy/examine(mob/user)
|
||||
..()
|
||||
if(trophy_message)
|
||||
to_chat(user, "The plaque reads:")
|
||||
to_chat(user, trophy_message)
|
||||
|
||||
/obj/structure/displaycase/trophy/attackby(obj/item/weapon/W, mob/user, params)
|
||||
|
||||
if(!user.Adjacent(src)) //no TK museology
|
||||
return
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
if(user.is_holding_item_of_type(/obj/item/key/displaycase))
|
||||
if(added_roundstart)
|
||||
is_locked = !is_locked
|
||||
to_chat(user, "You [!is_locked ? "un" : ""]lock the case.")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>The lock is stuck shut!</span>")
|
||||
return
|
||||
|
||||
if(is_locked)
|
||||
to_chat(user, "<span class='danger'>The case is shut tight with an old fashioned physical lock. Maybe you should ask the curator for the key?</span>")
|
||||
return
|
||||
|
||||
if(!added_roundstart)
|
||||
to_chat(user, "You've already put something new in this case.")
|
||||
return
|
||||
|
||||
if(is_type_in_typecache(W, GLOB.blacklisted_cargo_types))
|
||||
to_chat(user, "<span class='danger'>The case rejects the [W].</span>")
|
||||
return
|
||||
|
||||
for(var/a in W.GetAllContents())
|
||||
if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types))
|
||||
to_chat(user, "<span class='danger'>The case rejects the [W].</span>")
|
||||
return
|
||||
|
||||
if(user.transferItemToLoc(W, src))
|
||||
|
||||
if(showpiece)
|
||||
to_chat(user, "You press a button, and [showpiece] descends into the floor of the case.")
|
||||
QDEL_NULL(showpiece)
|
||||
|
||||
to_chat(user, "You insert [W] into the case.")
|
||||
showpiece = W
|
||||
added_roundstart = FALSE
|
||||
update_icon()
|
||||
|
||||
placer_key = user.ckey
|
||||
|
||||
trophy_message = W.desc //default value
|
||||
|
||||
var/chosen_plaque = stripped_input(user, "What would you like the plaque to say? Default value is item's description.", "Trophy Plaque")
|
||||
if(chosen_plaque)
|
||||
if(user.Adjacent(src))
|
||||
trophy_message = chosen_plaque
|
||||
to_chat(user, "You set the plaque's text.")
|
||||
else
|
||||
to_chat(user, "You are too far to set the plaque's text.")
|
||||
|
||||
SSpersistence.SaveTrophy(src)
|
||||
return TRUE
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [W] is stuck to your hand, you can't put it in the [src.name]!</span>")
|
||||
|
||||
return
|
||||
|
||||
/obj/structure/displaycase/trophy/dump()
|
||||
if (showpiece)
|
||||
if(added_roundstart)
|
||||
visible_message("<span class='danger'>The [showpiece] crumbles to dust!</span>")
|
||||
new /obj/effect/decal/cleanable/ash(loc)
|
||||
QDEL_NULL(showpiece)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/key/displaycase
|
||||
name = "display case key"
|
||||
desc = "The key to the curator's display cases."
|
||||
|
||||
/obj/item/showpiece_dummy
|
||||
name = "Cheap replica"
|
||||
|
||||
/obj/item/showpiece_dummy/Initialize(mapload, path)
|
||||
. = ..()
|
||||
var/obj/item/I = path
|
||||
name = initial(I.name)
|
||||
icon = initial(I.icon)
|
||||
icon_state = initial(I.icon_state)
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
pixel_y = -20
|
||||
|
||||
/obj/structure/flora/tree/jungle/Initialize()
|
||||
icon_state = "[icon_state][rand(1, 3)]"
|
||||
icon_state = "[icon_state][rand(1, 6)]"
|
||||
..()
|
||||
|
||||
//grass
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
death = FALSE
|
||||
anchored = 0
|
||||
density = 0
|
||||
var/can_transfer = TRUE //if golems can switch bodies to this new shell
|
||||
var/mob/living/owner = null //golem's owner if it has one
|
||||
flavour_text = "<font size=3><b>Y</b></font><b>ou are a Free Golem. Your family worships <span class='danger'>The Liberator</span>. In his infinite and divine wisdom, he set your clan free to \
|
||||
travel the stars with a single declaration: \"Yeah go do whatever.\" Though you are bound to the one who created you, it is customary in your society to repeat those same words to newborn \
|
||||
@@ -119,7 +120,7 @@
|
||||
Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost."
|
||||
owner = creator
|
||||
|
||||
/obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn)
|
||||
/obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn, name)
|
||||
var/datum/species/golem/X = mob_species
|
||||
to_chat(new_spawn, "[initial(X.info_text)]")
|
||||
if(!owner)
|
||||
@@ -132,14 +133,29 @@
|
||||
if(ishuman(new_spawn))
|
||||
var/mob/living/carbon/human/H = new_spawn
|
||||
H.set_cloned_appearance()
|
||||
H.real_name = H.dna.species.random_name()
|
||||
if(!name)
|
||||
H.real_name = H.dna.species.random_name()
|
||||
else
|
||||
H.real_name = name
|
||||
|
||||
/obj/effect/mob_spawn/human/golem/attack_hand(mob/user)
|
||||
if(isgolem(user) && can_transfer)
|
||||
var/transfer = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No")
|
||||
if(!transfer)
|
||||
return
|
||||
log_game("[user.ckey] golem-swapped into [src]")
|
||||
user.visible_message("<span class='notice'>A faint light leaves [user], moving to [src] and animating it!</span>","<span class='notice'>You leave your old body behind, and transfer into [src]!</span>")
|
||||
create(ckey = user.ckey, flavour = FALSE, name = user.real_name)
|
||||
user.death()
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/golem/adamantine
|
||||
name = "dust-caked golem shell"
|
||||
desc = "A humanoid shape, empty, lifeless, and full of potential."
|
||||
mob_name = "a free golem"
|
||||
anchored = 1
|
||||
density = 1
|
||||
can_transfer = FALSE
|
||||
mob_species = /datum/species/golem/adamantine
|
||||
|
||||
//Malfunctioning cryostasis sleepers: Spawns in makeshift shelters in lavaland. Ghosts become hermits with knowledge of how they got to where they are now.
|
||||
|
||||
Reference in New Issue
Block a user