Merge branch 'master' into upstream-merge-14976

This commit is contained in:
Raeschen
2023-06-17 14:47:37 +02:00
committed by GitHub
147 changed files with 1521 additions and 593 deletions
+74
View File
@@ -0,0 +1,74 @@
#if DM_VERSION >= 515
#error PLEASE MAKE SURE THAT 515 IS PROPERLY TESTED AND WORKS. ESPECIALLY THE SAVE-FILES HAVE TO WORK.
#error Additionally: Make sure that the GitHub Workflow was updated to BYOND 515 as well.
#endif
// These defines are from __513_compatibility.dm -- Please Sort
#define CLAMP(CLVALUE, CLMIN, CLMAX) clamp(CLVALUE, CLMIN, CLMAX)
#define TAN(x) tan(x)
#define ATAN2(x, y) arctan(x, y)
#define between(x, y, z) clamp(y, x, z)
// This file contains defines allowing targeting byond versions newer than the supported
//Update this whenever you need to take advantage of more recent byond features
#define MIN_COMPILER_VERSION 514
#define MIN_COMPILER_BUILD 1556
#if (DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD) && !defined(SPACEMAN_DMM)
//Don't forget to update this part
#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update.
#error You need version 514.1556 or higher
#endif
#if (DM_VERSION == 514 && DM_BUILD > 1575 && DM_BUILD <= 1577)
#error Your version of BYOND currently has a crashing issue that will prevent you from running Dream Daemon test servers.
#error We require developers to test their content, so an inability to test means we cannot allow the compile.
#error Please consider downgrading to 514.1575 or lower.
#endif
// Keep savefile compatibilty at minimum supported level
#if DM_VERSION >= 515
/savefile/byond_version = MIN_COMPILER_VERSION
#endif
// 515 split call for external libraries into call_ext
#if DM_VERSION < 515
#define LIBCALL call
#else
#define LIBCALL call_ext
#endif
// So we want to have compile time guarantees these methods exist on local type, unfortunately 515 killed the .proc/procname and .verb/verbname syntax so we have to use nameof()
// For the record: GLOBAL_VERB_REF would be useless as verbs can't be global.
#if DM_VERSION < 515
/// Call by name proc references, checks if the proc exists on either this type or as a global proc.
#define PROC_REF(X) (.proc/##X)
/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
#define VERB_REF(X) (.verb/##X)
/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc
#define TYPE_PROC_REF(TYPE, X) (##TYPE.proc/##X)
/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb
#define TYPE_VERB_REF(TYPE, X) (##TYPE.verb/##X)
/// Call by name proc reference, checks if the proc is an existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)
#else
/// Call by name proc references, checks if the proc exists on either this type or as a global proc.
#define PROC_REF(X) (nameof(.proc/##X))
/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
#define VERB_REF(X) (nameof(.verb/##X))
/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc
#define TYPE_PROC_REF(TYPE, X) (nameof(##TYPE.proc/##X))
/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb
#define TYPE_VERB_REF(TYPE, X) (nameof(##TYPE.verb/##X))
/// Call by name proc reference, checks if the proc is an existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)
#endif
-33
View File
@@ -1,33 +0,0 @@
#if DM_VERSION < 513
#define ismovable(A) (istype(A, /atom/movable))
#define islist(L) (istype(L, /list))
#define CLAMP01(x) (CLAMP(x, 0, 1))
#define CLAMP(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) )
#define ATAN2(x, y) ( !(x) && !(y) ? 0 : (y) >= 0 ? arccos((x) / sqrt((x)*(x) + (y)*(y))) : -arccos((x) / sqrt((x)*(x) + (y)*(y))) )
#define TAN(x) (sin(x) / cos(x))
#define arctan(x) (arcsin(x/sqrt(1+x*x)))
#define between(x, y, z) max(min(y, z), x)
//////////////////////////////////////////////////
#else
#define CLAMP01(x) clamp(x, 0, 1)
#define CLAMP(CLVALUE, CLMIN, CLMAX) clamp(CLVALUE, CLMIN, CLMAX)
#define TAN(x) tan(x)
#define ATAN2(x, y) arctan(x, y)
#define between(x, y, z) clamp(y, x, z)
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
#define isdatum(D) istype(D, /datum)
#define isweakref(A) istype(A, /weakref)
#define isweakref(A) istype(A, /datum/weakref)
//#define islist(D) istype(D, /list) //Built in
+1
View File
@@ -17,6 +17,7 @@
#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(world.tick_usage - starting_tickusage))
#define PERCENT(val) (round((val)*100, 0.1))
#define CLAMP01(x) clamp(x, 0, 1)
//time of day but automatically adjusts to the server going into the next day within the same round.
//for when you need a reliable time number that doesn't depend on byond time.
+1 -1
View File
@@ -102,7 +102,7 @@ GLOBAL_LIST_INIT(plant_item_products, list(
/obj/item/organ/internal/brain/grey = 1,
/obj/item/organ/internal/heart/grey = 1,
/obj/item/weapon/spacecash/c1 = 3,
/obj/item/weapon/spacecash/c10 = 1
/obj/item/weapon/spacecash/c5 = 1
))
GLOBAL_LIST_INIT(forbidden_plant_growth_sprites, list(
+2
View File
@@ -55,3 +55,5 @@
// /atom
#define VV_HK_ATOM_EXPLODE "turf_explode"
#define VV_HK_ATOM_EMP "turf_emp"
#define VV_HK_WEAKREF_RESOLVE "weakref_resolve"
+1 -1
View File
@@ -978,7 +978,7 @@ var/global/list/selectable_speech_bubbles = list(
"tentacles",
"heart",
"textbox",
"posessed",
"possessed", // CHOMPEDIT : purdev (spelling changed <3)
"square",
"medical",
"medical_square",
+3 -7
View File
@@ -382,19 +382,15 @@ GLOBAL_LIST_EMPTY(icon_state_lists)
GLOBAL_LIST_EMPTY(cached_examine_icons)
/proc/set_cached_examine_icon(var/atom/A, var/icon/I, var/expiry = 12000)
GLOB.cached_examine_icons[weakref(A)] = I
GLOB.cached_examine_icons[WEAKREF(A)] = I
if(expiry)
<<<<<<< HEAD
addtimer(CALLBACK(GLOBAL_PROC, .proc/uncache_examine_icon, weakref(A)), expiry, TIMER_UNIQUE)
=======
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(uncache_examine_icon), WEAKREF(A)), expiry, TIMER_UNIQUE)
>>>>>>> b6b3a1357c... Merge pull request #14976 from ItsSelis/selis-515compat
/proc/get_cached_examine_icon(var/atom/A)
var/weakref/WR = weakref(A)
var/datum/weakref/WR = WEAKREF(A)
return GLOB.cached_examine_icons[WR]
/proc/uncache_examine_icon(var/weakref/WR)
/proc/uncache_examine_icon(var/datum/weakref/WR)
GLOB.cached_examine_icons -= WR
/proc/adjust_brightness(var/color, var/value)
+18
View File
@@ -17,6 +17,8 @@
var/discord_ahelps_disabled = 0 //Turn this off if you don't want the TGS bot sending you messages whenever an ahelp ticket is created.
var/discord_ahelps_all = 0 //Turn this on if you want all admin-PMs to go to be sent to discord, and not only the first message of a ticket.
var/list/ip_whitelist = list()
/hook/startup/proc/read_ch_config()
var/list/Lines = file2list("config/config.txt")
for(var/t in Lines)
@@ -62,4 +64,20 @@
config.nodebot_location = value
if ("ahelp_channel_tag")
config.ahelp_channel_tag = value
var/list/ip_whitelist_lines = file2list("config/ip_whitelist.txt")
var/increment = 1
for(var/t in ip_whitelist_lines)
if (!t) continue
t = trim(t)
if (length(t) == 0)
continue
else if (copytext(t, 1, 2) == "#")
continue
var/ip_address = splittext(t, ",")
for (var/name in ip_address)
config.ip_whitelist[name] = increment
increment += 1
return 1
+45 -20
View File
@@ -30,61 +30,86 @@ SUBSYSTEM_DEF(lighting)
MC_SPLIT_TICK_INIT(3)
if(!init_tick_checks)
MC_SPLIT_TICK
var/list/queue = sources_queue
var/i = 0
if(length(queue))
for(i in 1 to length(queue))
var/datum/light_source/L = queue[i]
L.update_corners()
// UPDATE SOURCE QUEUE
queue = sources_queue
while(i < length(queue)) //we don't use for loop here because i cannot be changed during an iteration
i += 1
var/datum/light_source/L = queue[i]
L.update_corners()
if(!QDELETED(L))
L.needs_update = LIGHTING_NO_UPDATE
else
i -= 1 // update_corners() has removed L from the list, move back so we don't overflow or skip the next element
if(init_tick_checks)
CHECK_TICK
else if (MC_TICK_CHECK)
break
// We unroll TICK_CHECK here so we can clear out the queue to ensure any removals/additions when sleeping don't fuck us
if(init_tick_checks)
if(!TICK_CHECK)
continue
queue.Cut(1, i + 1)
i = 0
stoplag()
else if (MC_TICK_CHECK)
break
if (i)
queue.Cut(1, i+1)
queue.Cut(1, i + 1)
i = 0
if(!init_tick_checks)
MC_SPLIT_TICK
// UPDATE CORNERS QUEUE
queue = corners_queue
for (i in 1 to length(queue))
var/datum/lighting_corner/C = queue[i]
while(i < length(queue)) //we don't use for loop here because i cannot be changed during an iteration
i += 1
var/datum/lighting_corner/C = queue[i]
C.needs_update = FALSE //update_objects() can call qdel if the corner is storing no data
C.update_objects()
// We unroll TICK_CHECK here so we can clear out the queue to ensure any removals/additions when sleeping don't fuck us
if(init_tick_checks)
CHECK_TICK
if(!TICK_CHECK)
continue
queue.Cut(1, i + 1)
i = 0
stoplag()
else if (MC_TICK_CHECK)
break
if (i)
queue.Cut(1, i+1)
queue.Cut(1, i + 1)
i = 0
if(!init_tick_checks)
MC_SPLIT_TICK
// UPDATE OBJECTS QUEUE
queue = objects_queue
for (i in 1 to length(queue))
var/datum/lighting_object/O = queue[i]
while(i < length(queue)) //we don't use for loop here because i cannot be changed during an iteration
i += 1
var/datum/lighting_object/O = queue[i]
if (QDELETED(O))
continue
O.update()
O.needs_update = FALSE
// We unroll TICK_CHECK here so we can clear out the queue to ensure any removals/additions when sleeping don't fuck us
if(init_tick_checks)
CHECK_TICK
if(!TICK_CHECK)
continue
queue.Cut(1, i + 1)
i = 0
stoplag()
else if (MC_TICK_CHECK)
break
if (i)
queue.Cut(1, i+1)
queue.Cut(1, i + 1)
/datum/controller/subsystem/lighting/Recover()
+4 -4
View File
@@ -44,7 +44,7 @@
var/datum/object = GLOBAL_PROC
var/delegate
var/list/arguments
var/weakref/user
var/datum/weakref/user
/datum/callback/New(thingtocall, proctocall, ...)
if (thingtocall)
@@ -53,7 +53,7 @@
if (length(args) > 2)
arguments = args.Copy(3)
if(usr)
user = weakref(usr)
user = WEAKREF(usr)
/world/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...)
set waitfor = FALSE
@@ -70,7 +70,7 @@
/datum/callback/proc/Invoke(...)
if(!usr)
var/weakref/W = user
var/datum/weakref/W = user
if(W)
var/mob/M = W.resolve()
if(M)
@@ -94,7 +94,7 @@
set waitfor = FALSE
if(!usr)
var/weakref/W = user
var/datum/weakref/W = user
if(W)
var/mob/M = W.resolve()
if(M)
+38 -10
View File
@@ -1,20 +1,48 @@
//
// datum defines!
// Note: Adding vars to /datum adds a var to EVERYTHING! Don't go overboard.
//
/**
* The absolute base class for everything
*
* A datum instantiated has no physical world prescence, use an atom if you want something
* that actually lives in the world
*
* Be very mindful about adding variables to this class, they are inherited by every single
* thing in the entire game, and so you can easily cause memory usage to rise a lot with careless
* use of variables at this level
*/
/datum
var/gc_destroyed //Time when this object was destroyed.
var/list/active_timers //for SStimer
var/list/datum_components //for /datum/components
/**
* Tick count time when this object was destroyed.
*
* If this is non zero then the object has been garbage collected and is awaiting either
* a hard del by the GC subsystme, or to be autocollected (if it has no references)
*/
var/gc_destroyed
/// Active timers with this datum as the target
var/list/active_timers
/**
* Components attached to this datum
*
* Lazy associated list in the structure of `type:component/list of components`
*/
var/list/datum_components
/**
* Any datum registered to receive signals from this datum is in this list
*
* Lazy associated list in the structure of `signal:registree/list of registrees`
*/
var/list/comp_lookup
var/list/list/signal_procs // List of lists
var/signal_enabled = FALSE
var/weakref/weakref // Holder of weakref instance pointing to this datum
/// Datum level flags
var/datum_flags = NONE
var/trigger_uid //CHOMPEdit
var/status_traits //CHOMPEdit
/// A weak reference to another datum
var/datum/weakref/weak_reference
#ifdef REFERENCE_TRACKING
var/tmp/running_find_references
var/tmp/last_find_references = 0
@@ -37,7 +65,7 @@
continue
qdel(timer)
weakref = null // Clear this reference to ensure it's kept for as brief duration as possible.
weak_reference = null // Clear this reference to ensure it's kept for as brief duration as possible.
//BEGIN: ECS SHIT
signal_enabled = FALSE
+1 -1
View File
@@ -12,7 +12,7 @@
/datum/looping_sound/mob/deafened
start_sound = 'modular_chomp/sound/effects/ear_ring/ear_deaf_in.ogg'
start_length = 4 SECONDS // 2 seconds shorter than the actual file ending, bc we want it to overlap
mid_sounds = list('modular_chomp/sound/effects/ear_ring/ear_deaf_loop.ogg'=1)
mid_sounds = list('modular_chomp/sound/misc/silence.ogg'=1)
mid_length = 3 SECONDS
end_sound = 'modular_chomp/sound/effects/ear_ring/ear_deaf_out.ogg'
volume = 40
-26
View File
@@ -1,26 +0,0 @@
//obtain a weak reference to a datum
/proc/weakref(datum/D)
if(!istype(D))
return
if(QDELETED(D))
return
if(!D.weakref)
D.weakref = new/weakref(D)
return D.weakref
/weakref
var/ref
/weakref/New(datum/D)
ref = "\ref[D]"
/weakref/Destroy()
// A weakref datum should not be manually destroyed as it is a shared resource,
// rather it should be automatically collected by the BYOND GC when all references are gone.
return QDEL_HINT_LETMELIVE
/weakref/proc/resolve()
var/datum/D = locate(ref)
if(D && D.weakref == src)
return D
return null
+108
View File
@@ -0,0 +1,108 @@
/// Creates a weakref to the given input.
/// See /datum/weakref's documentation for more information.
/proc/WEAKREF(datum/input)
if(istype(input) && !QDELETED(input))
if(isweakref(input))
return input
if(!input.weak_reference)
input.weak_reference = new /datum/weakref(input)
return input.weak_reference
/datum/proc/create_weakref() //Forced creation for admin proccalls
return WEAKREF(src)
/**
* A weakref holds a non-owning reference to a datum.
* The datum can be referenced again using `resolve()`.
*
* To figure out why this is important, you must understand how deletion in
* BYOND works.
*
* Imagine a datum as a TV in a living room. When one person enters to watch
* TV, they turn it on. Others can come into the room and watch the TV.
* When the last person leaves the room, they turn off the TV because it's
* no longer being used.
*
* A datum being deleted tells everyone who's watching the TV to stop.
* If everyone leaves properly (AKA cleaning up their references), then the
* last person will turn off the TV, and everything is well.
* However, if someone is resistant (holds a hard reference after deletion),
* then someone has to walk in, drag them away, and turn off the TV forecefully.
* This process is very slow, and it's known as hard deletion.
*
* This is where weak references come in. Weak references don't count as someone
* watching the TV. Thus, when what it's referencing is destroyed, it will
* hopefully clean up properly, and limit hard deletions.
*
* A common use case for weak references is holding onto what created itself.
* For example, if a machine wanted to know what its last user was, it might
* create a `var/mob/living/last_user`. However, this is a strong reference to
* the mob, and thus will force a hard deletion when that mob is deleted.
* It is often better in this case to instead create a weakref to the user,
* meaning this type definition becomes `var/datum/weakref/last_user`.
*
* A good rule of thumb is that you should hold strong references to things
* that you *own*. For example, a dog holding a chew toy would be the owner
* of that chew toy, and thus a `var/obj/item/chew_toy` reference is fine
* (as long as it is cleaned up properly).
* However, a chew toy does not own its dog, so a `var/mob/living/dog/owner`
* might be inferior to a weakref.
* This is also a good rule of thumb to avoid circular references, such as the
* chew toy example. A circular reference that doesn't clean itself up properly
* will always hard delete.
*/
/datum/weakref
var/reference
/datum/weakref/New(datum/thing)
reference = REF(thing)
/datum/weakref/Destroy(force)
var/datum/target = resolve()
qdel(target)
if(!force)
return QDEL_HINT_LETMELIVE //Let BYOND autoGC thiswhen nothing is using it anymore.
target?.weak_reference = null
return ..()
/**
* Retrieves the datum that this weakref is referencing.
*
* This will return `null` if the datum was deleted. This MUST be respected.
*/
/datum/weakref/proc/resolve()
var/datum/D = locate(reference)
return (!QDELETED(D) && D.weak_reference == src) ? D : null
/**
* SERIOUSLY READ THE AUTODOC COMMENT FOR THIS PROC BEFORE EVEN THINKING ABOUT USING IT
*
* Like resolve, but doesn't care if the datum is being qdeleted but hasn't been deleted yet.
*
* The return value of this proc leaves hanging references if the datum is being qdeleted but hasn't been deleted yet.
*
* Do not do anything that would create a lasting reference to the return value, such as giving it a tag, putting it on the map,
* adding it to an atom's contents or vis_contents, giving it a key (if it's a mob), attaching it to an atom (if it's an image),
* or assigning it to a datum or list referenced somewhere other than a temporary value.
*
* Unless you're resolving a weakref to a datum in a COMSIG_PARENT_QDELETING signal handler registered on that very same datum,
* just use resolve instead.
*/
/datum/weakref/proc/hard_resolve()
var/datum/D = locate(reference)
return (D?.weak_reference == src) ? D : null
/datum/weakref/vv_get_dropdown()
. = ..()
VV_DROPDOWN_OPTION(VV_HK_WEAKREF_RESOLVE, "Go to reference")
/datum/weakref/vv_do_topic(list/href_list)
. = ..()
if(href_list[VV_HK_WEAKREF_RESOLVE])
if(!check_rights(NONE))
return
var/datum/R = resolve()
if(R)
usr.client.debug_variables(R)
@@ -9,12 +9,12 @@
category = UTILITY_SPELLS
//VOREStation Add - Multiple technomancer support
/datum/technomancer_marker
var/weakref/U
var/datum/weakref/U
var/image/I
var/turf/T
/datum/technomancer_marker/New(var/mob/user)
U = weakref(user)
U = WEAKREF(user)
T = get_turf(user)
I = image('icons/goonstation/featherzone.dmi', T, "spawn-wall")
I.plane = TURF_PLANE
@@ -46,7 +46,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
return 0
if(pay_energy(1000))
//VOREStation Add - Multiple technomancer support
var/datum/technomancer_marker/marker = GLOB.mark_spells[weakref(user)]
var/datum/technomancer_marker/marker = GLOB.mark_spells[WEAKREF(user)]
//They have one in the list
if(istype(marker))
qdel(marker)
@@ -54,7 +54,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
//They don't have one yet
else
to_chat(user, "<span class='notice'>You mark \the [get_turf(user)] under you.</span>")
GLOB.mark_spells[weakref(user)] = new /datum/technomancer_marker(user)
GLOB.mark_spells[WEAKREF(user)] = new /datum/technomancer_marker(user)
//VOREStation Add End
adjust_instability(5)
return 1
@@ -83,7 +83,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
/obj/item/weapon/spell/recall/on_use_cast(var/mob/living/user)
if(pay_energy(3000))
var/datum/technomancer_marker/marker = GLOB.mark_spells[weakref(user)] //VOREStation Add - Multiple technomancer support
var/datum/technomancer_marker/marker = GLOB.mark_spells[WEAKREF(user)] //VOREStation Add - Multiple technomancer support
if(!istype(marker))
to_chat(user, "<span class='danger'>There's no Mark!</span>")
return 0
@@ -128,4 +128,3 @@ GLOBAL_LIST_INIT(mark_spells, list())
else
to_chat(user, "<span class='warning'>You can't afford the energy cost!</span>")
return 0
+3 -3
View File
@@ -1,7 +1,7 @@
/obj/machinery/optable
name = "Operating Table"
desc = "Used for advanced medical procedures."
icon = 'icons/obj/surgery.dmi'
icon = 'icons/obj/surgery_vr.dmi'
icon_state = "table2-idle"
density = TRUE
anchored = TRUE
@@ -100,12 +100,12 @@
if(!Adjacent(target) || !Adjacent(user))
return ..()
if(user.incapacitated() || !check_table(target, user))
return ..()
take_victim(target, user)
/obj/machinery/optable/verb/climb_on()
set name = "Climb On Table"
set category = "Object"
+10 -4
View File
@@ -16,15 +16,14 @@
/obj/machinery/cell_charger/Initialize()
. = ..()
default_apply_parts()
add_overlay("ccharger1")
/obj/machinery/cell_charger/update_icon()
icon_state = "ccharger[charging ? 1 : 0]"
if(!anchored)
cut_overlays()
icon_state = "ccharger2"
if(charging && !(stat & (BROKEN|NOPOWER)))
var/newlevel = round(charging.percent() * 4.0 / 99)
//to_world("nl: [newlevel]")
@@ -34,8 +33,14 @@
add_overlay("ccharger-o[newlevel]")
chargelevel = newlevel
else
add_overlay(image(charging.icon, charging.icon_state))
add_overlay("ccharger-[charging.connector_type]-on")
else if(anchored)
cut_overlays()
icon_state = "ccharger0"
add_overlay("ccharger1")
/obj/machinery/cell_charger/examine(mob/user)
. = ..()
@@ -77,6 +82,7 @@
anchored = !anchored
to_chat(user, "You [anchored ? "attach" : "detach"] [src] [anchored ? "to" : "from"] the ground")
playsound(src, W.usesound, 75, 1)
update_icon()
else if(default_deconstruction_screwdriver(user, W))
return
else if(default_deconstruction_crowbar(user, W))
+5 -5
View File
@@ -80,10 +80,10 @@ GLOBAL_LIST_EMPTY(entertainment_screens)
network = list(NETWORK_THUNDER)
circuit = /obj/item/weapon/circuitboard/security/telescreen/entertainment
camera_datum_type = /datum/tgui_module/camera/bigscreen
var/obj/item/device/radio/radio = null
var/obj/effect/overlay/vis/pinboard
var/weakref/showing
var/datum/weakref/showing
var/enabled = TRUE // on or off
@@ -93,7 +93,7 @@ GLOBAL_LIST_EMPTY(entertainment_screens)
var/static/icon/mask = icon('icons/obj/entertainment_monitor.dmi', "mask")
add_overlay("glass")
pinboard = new()
pinboard.icon = icon
pinboard.icon_state = "pinboard"
@@ -147,7 +147,7 @@ GLOBAL_LIST_EMPTY(entertainment_screens)
stop_showing()
if(stat & NOPOWER)
return
showing = weakref(thing)
showing = WEAKREF(thing)
pinboard.vis_contents = list(thing)
/obj/machinery/computer/security/telescreen/entertainment/proc/stop_showing()
@@ -155,7 +155,7 @@ GLOBAL_LIST_EMPTY(entertainment_screens)
pinboard.vis_contents = null
showing = null
/obj/machinery/computer/security/telescreen/entertainment/proc/maybe_stop_showing(weakref/thingref)
/obj/machinery/computer/security/telescreen/entertainment/proc/maybe_stop_showing(datum/weakref/thingref)
if(showing == thingref)
stop_showing()
+7 -6
View File
@@ -139,7 +139,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
var/last_shot = 0
var/kill_range = 18
var/rotation_speed = 4.5 SECONDS //How quickly we turn to face threats
var/weakref/engaging = null // The meteor we're shooting at
var/datum/weakref/engaging = null // The meteor we're shooting at
var/id_tag = null
/obj/machinery/pointdefense/Initialize()
@@ -199,7 +199,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
return FALSE
return TRUE
/obj/machinery/pointdefense/proc/Shoot(var/weakref/target)
/obj/machinery/pointdefense/proc/Shoot(var/datum/weakref/target)
var/obj/effect/meteor/M = target.resolve()
if(!istype(M))
engaging = null
@@ -213,7 +213,8 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
set_dir(ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH)
/obj/machinery/pointdefense/proc/finish_shot(var/weakref/target)
/obj/machinery/pointdefense/proc/finish_shot(var/datum/weakref/target)
var/obj/machinery/pointdefense_control/PC = get_controller()
engaging = null
PC.targets -= target
@@ -255,7 +256,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
// Compile list of known targets
var/list/existing_targets = list()
for(var/weakref/WR in PC.targets)
for(var/datum/weakref/WR in PC.targets)
var/obj/effect/meteor/M = WR.resolve()
existing_targets += M
@@ -263,7 +264,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
var/list/potential_targets = GLOB.meteor_list.Copy() - existing_targets
for(var/obj/effect/meteor/M in potential_targets)
if(targeting_check(M))
var/weakref/target = weakref(M)
var/datum/weakref/target = WEAKREF(M)
PC.targets += target
engaging = target
Shoot(target)
@@ -272,7 +273,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
// Then, focus fire on existing targets
for(var/obj/effect/meteor/M in existing_targets)
if(targeting_check(M))
var/weakref/target = weakref(M)
var/datum/weakref/target = WEAKREF(M)
engaging = target
Shoot(target)
return
+5 -6
View File
@@ -37,7 +37,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/obj/machinery/telecomms/broadcaster/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R))
return
linked_radios_weakrefs |= weakref(R)
linked_radios_weakrefs |= WEAKREF(R)
/obj/machinery/telecomms/broadcaster/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
// Don't broadcast rejected signals
@@ -66,7 +66,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["level"] |= using_map.get_map_levels(listening_level, TRUE, overmap_range)
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
for(var/datum/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
@@ -149,7 +149,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/obj/machinery/telecomms/allinone/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R))
return
linked_radios_weakrefs |= weakref(R)
linked_radios_weakrefs |= WEAKREF(R)
/obj/machinery/telecomms/allinone/receive_signal(datum/signal/signal)
@@ -197,7 +197,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/datum/radio_frequency/connection = signal.data["connection"]
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
for(var/datum/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
@@ -255,7 +255,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/datum/radio_frequency/connection = signal.data["connection"]
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
for(var/datum/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
@@ -761,4 +761,3 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
//to_world_log("Level: [signal.data["level"]] - Done: [signal.data["done"]]")
return signal
@@ -46,7 +46,7 @@
var/datum/radio_frequency/connection = signal.data["connection"]
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
for(var/datum/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
@@ -69,4 +69,4 @@
signal.data["verb"],
signal.data["language"],
forced_radios
)
)
@@ -31,7 +31,7 @@
var/datum/radio_frequency/connection = signal.data["connection"]
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
for(var/datum/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
@@ -272,7 +272,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/receiver/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R))
return
linked_radios_weakrefs |= weakref(R)
linked_radios_weakrefs |= WEAKREF(R)
/obj/machinery/telecomms/receiver/receive_signal(datum/signal/signal)
if(!on) // has to be on to receive messages
@@ -299,7 +299,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
var/obj/item/device/radio/R = signal.data["radio"]
//Who're you?
if(!(weakref(R) in linked_radios_weakrefs))
if(!(WEAKREF(R) in linked_radios_weakrefs))
signal.data["reject"] = 1
return 0
@@ -8,4 +8,5 @@
projectile = /obj/item/projectile/beam/medigun
fire_sound = 'sound/weapons/eluger.ogg'
equip_type = EQUIP_UTILITY
origin_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 5, TECH_BIO = 6, TECH_POWER = 6)
required_type = /obj/mecha/medical
origin_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 5, TECH_BIO = 6, TECH_POWER = 6)
+6 -8
View File
@@ -1,8 +1,8 @@
/obj/machinery/mecha_part_fabricator
icon = 'icons/obj/robotics_vr.dmi' //VOREStation Edit - New icon
icon_state = "mechfab-idle"
icon_state = "mechfab"
name = "Exosuit Fabricator"
desc = "A machine used for construction of mechas."
desc = "A machine used for the construction of mechas."
density = TRUE
anchored = TRUE
use_power = USE_POWER_IDLE
@@ -214,7 +214,7 @@
* Adds the overlay to show the fab working and sets active power usage settings.
*/
/obj/machinery/mecha_part_fabricator/proc/on_start_printing()
add_overlay("fab-active")
add_overlay("[icon_state]-active")
use_power = USE_POWER_ACTIVE
/**
@@ -223,7 +223,7 @@
* Removes the overlay to show the fab working and sets idle power usage settings. Additionally resets the description and turns off queue processing.
*/
/obj/machinery/mecha_part_fabricator/proc/on_finish_printing()
cut_overlay("fab-active")
cut_overlay("[icon_state]-active")
use_power = USE_POWER_IDLE
desc = initial(desc)
process_queue = FALSE
@@ -633,11 +633,9 @@
if(S && S.get_amount() >= 1)
var/count = 0
flick("[loading_icon_state]", src)
// yess hacky but whatever
// yess hacky but whatever //even more hacky now, but at least it works
if(loading_icon_state == "mechfab-idle")
add_overlay("mechfab-load-metal")
spawn(10)
cut_overlays("mechfab-load-metal")
flick("mechfab-load-metal", src)
while(materials[S.material.name] + amnt <= res_max_amount && S.get_amount() >= 1)
materials[S.material.name] += amnt
S.use(1)
+3 -3
View File
@@ -1,8 +1,8 @@
/obj/machinery/mecha_part_fabricator/pros
icon = 'icons/obj/robotics.dmi'
icon = 'icons/obj/robotics_vr.dmi' //VOREStation Edit - New icon
icon_state = "prosfab"
name = "Prosthetics Fabricator"
desc = "A machine used for construction of prosthetics."
desc = "A machine used for the construction of prosthetics."
density = TRUE
anchored = TRUE
unacidable = TRUE
@@ -17,7 +17,7 @@
var/species_types = list("Human")
var/species = "Human"
loading_icon_state = "prosfab_loading"
loading_icon_state = null
materials = list(
MAT_STEEL = 0,
+1 -1
View File
@@ -241,7 +241,7 @@
/obj/item/areaeditor/blueprints/engineers
name = "writing blueprints"
desc = "A piece of paper that allows for expansion of the station and creaiton of new areas. There is a \"For Official Use Only\" stamp on it. NOT to be mistaken with the staion blueprints."
desc = "A piece of paper that allows for expansion of the station and creation of new areas. There is a \"For Official Use Only\" stamp on it. NOT to be mistaken with the station blueprints." // CHOMPEDIT : purdev (some spelling fixes)
station_master = 0
uses_charges = 1
can_override = 0
+1 -1
View File
@@ -128,7 +128,7 @@
/obj/item/bodybag/cryobag
name = "stasis bag"
desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \
especially useful if short on time or in a hostile enviroment."
especially useful if short on time or in a hostile environment." // CHOMPEDIT : purdev (spelling fix)
icon = 'icons/obj/closets/cryobag.dmi'
icon_state = "bodybag_folded"
item_state = "bodybag_cryo_folded"
+3 -3
View File
@@ -140,9 +140,9 @@ var/list/GPS_list = list()
toggle_tracking()
if(tracking)
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
else
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
to_chat(user, "[src] is now tracking, and visible to other GPS devices.") // CHOMPEDIT : purdev Fixed an issue where the if/else argument was written backwards
else // CHOMPEDIT : purdev Fixed an issue where the if/else argument was written backwards
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.") // CHOMPEDIT : purdev Fixed an issue where the if/else argument was written backwards
/obj/item/device/gps/proc/toggle_tracking()
tracking = !tracking
@@ -14,5 +14,5 @@
if("Cancel")
return
else if (istype(W, /obj/item/weapon/card/id) && src.pai.idaccessible == 0)
to_chat(user, "<span class='notice'>[src] is not accepting access modifcations at this time.</span>")
to_chat(user, "<span class='notice'>[src] is not accepting access modifications at this time.</span>")
return
@@ -56,7 +56,7 @@ var/global/list/default_medbay_channels = list(
// Bluespace radios talk directly to telecomms equipment
var/bluespace_radio = FALSE
var/weakref/bs_tx_weakref //Maybe misleading, this is the device to TRANSMIT TO
var/datum/weakref/bs_tx_weakref //Maybe misleading, this is the device to TRANSMIT TO
// For mappers or subtypes, to start them prelinked to these devices
var/bs_tx_preload_id
var/bs_rx_preload_id
@@ -104,14 +104,14 @@ var/global/list/default_medbay_channels = list(
//Try to find a receiver
for(var/obj/machinery/telecomms/receiver/RX in telecomms_list)
if(RX.id == bs_tx_preload_id) //Again, bs_tx is the thing to TRANSMIT TO, so a receiver.
bs_tx_weakref = weakref(RX)
bs_tx_weakref = WEAKREF(RX)
RX.link_radio(src)
break
//Hmm, howabout an AIO machine
if(!bs_tx_weakref)
for(var/obj/machinery/telecomms/allinone/AIO in telecomms_list)
if(AIO.id == bs_tx_preload_id)
bs_tx_weakref = weakref(AIO)
bs_tx_weakref = WEAKREF(AIO)
AIO.link_radio(src)
break
if(!bs_tx_weakref)
+2 -3
View File
@@ -8,7 +8,7 @@
var/channel = "NCS Northern Star News Feed"
var/obj/machinery/camera/network/thunder/camera
var/obj/item/device/radio/radio
var/weakref/showing
var/datum/weakref/showing
var/showing_name
/obj/item/device/tvcamera/New()
@@ -95,7 +95,7 @@
if(showing)
hide_tvs(showing)
showing = weakref(thing)
showing = WEAKREF(thing)
showing_name = "[thing]"
for(var/obj/machinery/computer/security/telescreen/entertainment/ES as anything in GLOB.entertainment_screens)
ES.show_thing(thing)
@@ -221,4 +221,3 @@
return
..()
+16 -16
View File
@@ -48,10 +48,10 @@
/obj/item/device/uav/Initialize()
. = ..()
if(!cell && cell_type)
cell = new cell_type
ion_trail = new /datum/effect/effect/system/ion_trail_follow()
ion_trail.set_up(src)
ion_trail.stop()
@@ -69,7 +69,7 @@
. += "It has <i>'[nickname]'</i> scribbled on the side."
if(!cell)
. += "<span class='warning'>It appears to be missing a power cell.</span>"
if(health <= (initial(health)/4))
. += "<span class='warning'>It looks like it might break at any second!</span>"
else if(health <= (initial(health)/2))
@@ -86,7 +86,7 @@
"Toggle Power" = radial_power,
"Pairing Mode" = radial_pair)
var/choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
switch(choice)
// Can pick up when off or packed
if("Pick Up")
@@ -113,11 +113,11 @@
/obj/item/device/uav/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/modular_computer) && state == UAV_PAIRING)
var/obj/item/modular_computer/MC = I
LAZYDISTINCTADD(MC.paired_uavs, weakref(src))
LAZYDISTINCTADD(MC.paired_uavs, WEAKREF(src))
playsound(src, 'sound/machines/buttonbeep.ogg', 50, 1)
visible_message("<span class='notice'>[user] pairs [I] to [nickname]</span>")
toggle_pairing()
else if(I.is_screwdriver() && cell)
if(do_after(user, 3 SECONDS, src))
to_chat(user, "<span class='notice'>You remove [cell] into [nickname].</span>")
@@ -125,7 +125,7 @@
power_down()
cell.forceMove(get_turf(src))
cell = null
else if(istype(I, /obj/item/weapon/cell) && !cell)
if(do_after(user, 3 SECONDS, src))
to_chat(user, "<span class='notice'>You insert [I] into [nickname].</span>")
@@ -185,7 +185,7 @@
playsound(src, 'sound/items/drop/metalboots.ogg', 75, 1)
power_down()
health -= initial(health)*0.25 //Lose 25% of your original health
if(LAZYLEN(masters))
no_masters_time = 0
else if(no_masters_time++ > 50)
@@ -251,7 +251,7 @@
/obj/item/device/uav/proc/power_down()
if(state != UAV_ON)
return
state = UAV_OFF
update_icon()
stop_hover()
@@ -265,7 +265,7 @@
return cell
/obj/item/device/uav/relaymove(var/mob/user, direction, signal = 1)
if(signal && state == UAV_ON && (weakref(user) in masters))
if(signal && state == UAV_ON && (WEAKREF(user) in masters))
if(next_move <= world.time)
next_move = world.time + (1 SECOND/signal)
step(src, direction)
@@ -276,10 +276,10 @@
return "[nickname] - [get_x(src)],[get_y(src)],[get_z(src)] - I:[health]/[initial(health)] - C:[cell ? "[cell.charge]/[cell.maxcharge]" : "Not Installed"]"
/obj/item/device/uav/proc/add_master(var/mob/living/M)
LAZYDISTINCTADD(masters, weakref(M))
LAZYDISTINCTADD(masters, WEAKREF(M))
/obj/item/device/uav/proc/remove_master(var/mob/living/M)
LAZYREMOVE(masters, weakref(M))
LAZYREMOVE(masters, WEAKREF(M))
/obj/item/device/uav/check_eye()
if(state == UAV_ON)
@@ -310,7 +310,7 @@
/obj/item/device/uav/hear_talk(var/mob/M, list/message_pieces, verb)
var/name_used = M.GetVoice()
for(var/wr_master in masters)
var/weakref/wr = wr_master
var/datum/weakref/wr = wr_master
var/mob/master = wr.resolve()
var/list/combined = master.combine_message(message_pieces, verb, M)
var/message = combined["formatted"]
@@ -319,14 +319,14 @@
/obj/item/device/uav/see_emote(var/mob/living/M, text)
for(var/wr_master in masters)
var/weakref/wr = wr_master
var/datum/weakref/wr = wr_master
var/mob/master = wr.resolve()
var/rendered = "<i><span class='game say'>UAV received, <span class='message'>[text]</span></span></i>"
master.show_message(rendered, 2)
/obj/item/device/uav/show_message(msg, type, alt, alt_type)
for(var/wr_master in masters)
var/weakref/wr = wr_master
var/datum/weakref/wr = wr_master
var/mob/master = wr.resolve()
var/rendered = "<i><span class='game say'>UAV received, <span class='message'>[msg]</span></span></i>"
master.show_message(rendered, type)
@@ -365,4 +365,4 @@
#undef UAV_OFF
#undef UAV_ON
#undef UAV_PACKED
#undef UAV_PACKED
@@ -153,3 +153,26 @@
/obj/item/weapon/anobattery,
/obj/item/weapon/pickaxe
)
/obj/item/weapon/storage/belt/hydro
name = "hydroponics belt"
desc = "A belt used to hold most hydroponics supplies. Suprisingly, not green."
icon = 'icons/inventory/belt/item_vr.dmi'
icon_state = "plantbelt"
item_state = "plantbelt"
storage_slots = 5
max_w_class = ITEMSIZE_LARGE
max_storage_space = ITEMSIZE_COST_NORMAL * 5
can_hold = list(
/obj/item/device/analyzer/plant_analyzer,
/obj/item/weapon/reagent_containers/glass/beaker,
/obj/item/weapon/reagent_containers/glass/bottle,
/obj/item/weapon/shovel/spade,
/obj/item/weapon/tool/wirecutters,
/obj/item/weapon/material/minihoe,
/obj/item/weapon/material/knife/machete/hatchet,
/obj/item/weapon/reagent_containers/spray/plantbgone,
/obj/item/weapon/plantspray,
/obj/item/weapon/gun/energy/floragun,
/obj/item/seeds
)
@@ -862,12 +862,12 @@
plane = PLANE_PLAYER_HUD_ITEMS
layer = 0.1
alpha = 200
var/weakref/held_item
var/datum/weakref/held_item
/atom/movable/storage_slot/New(newloc, obj/item/held_item)
ASSERT(held_item)
name += held_item.name
src.held_item = weakref(held_item)
src.held_item = WEAKREF(held_item)
/atom/movable/storage_slot/Destroy()
held_item = null
@@ -1,18 +1,22 @@
/* Surgery Tools
* Contains:
* Bio-Regenerator
* Retractor
* Hemostat
* Cautery
* Surgical Drill
* Scalpel
* Circular Saw
* Bio-Regenerator
* Researchable Scalpels
* Circular Saws
* Misc Tools
* Cyborg Tools
* Alien Tools
*/
/obj/item/weapon/surgical
name = "Surgical tool"
desc = "This shouldn't be here, ahelp it."
icon = 'icons/obj/surgery.dmi'
icon = 'icons/obj/surgery_vr.dmi'
w_class = ITEMSIZE_SMALL
drop_sound = 'sound/items/drop/weldingtool.ogg'
pickup_sound = 'sound/items/pickup/weldingtool.ogg'
@@ -29,7 +33,6 @@
/obj/item/weapon/surgical/bioregen
name="bioregenerator"
desc="A special tool used in surgeries which can pull toxins from and restore oxygen to organic tissue as well as recreate missing biological structures to allow otherwise irreperable flesh to be mended."
icon='icons/obj/surgery_vr.dmi'
icon_state="bioregen"
drop_sound = 'sound/items/drop/scrap.ogg'
@@ -110,27 +113,27 @@
/obj/item/weapon/surgical/scalpel/laser1
name = "laser scalpel"
desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks basic and could be improved."
icon_state = "scalpel_laser1_on"
icon_state = "scalpel_laser1"
damtype = "fire"
/obj/item/weapon/surgical/scalpel/laser2
name = "laser scalpel"
desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks somewhat advanced."
icon_state = "scalpel_laser2_on"
icon_state = "scalpel_laser2"
damtype = "fire"
force = 12.0
/obj/item/weapon/surgical/scalpel/laser3
name = "laser scalpel"
desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks to be the pinnacle of precision energy cutlery!"
icon_state = "scalpel_laser3_on"
icon_state = "scalpel_laser3"
damtype = "fire"
force = 15.0
/obj/item/weapon/surgical/scalpel/manager
name = "incision management system"
desc = "A true extension of the surgeon's body, this marvel instantly and completely prepares an incision allowing for the immediate commencement of therapeutic steps."
icon_state = "scalpel_manager_on"
icon_state = "scalpel_manager"
force = 7.5
/obj/item/weapon/surgical/scalpel/ripper
@@ -143,12 +146,12 @@
origin_tech = list(TECH_MATERIAL = 5, TECH_BIO = 3, TECH_ILLEGAL = 2)
/*
* Circular Saw
* Circular Saws
*/
/obj/item/weapon/surgical/circular_saw
name = "circular saw"
desc = "For heavy duty cutting."
icon_state = "saw3"
icon_state = "saw"
hitsound = 'sound/weapons/circsawhit.ogg'
drop_sound = 'sound/items/drop/accessory.ogg'
force = 15.0
@@ -169,13 +172,15 @@
item_state = "saw3"
hitsound = 'sound/weapons/emitter2.ogg'
damtype = SEARING
w_class = ITEMSIZE_LARGE
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_BIO = 4, TECH_MATERIAL = 6, TECH_MAGNET = 6)
matter = list(MAT_STEEL = 12500)
matter = list(MAT_STEEL = 25000,MAT_GLASS = 20000)
attack_verb = list("attacked", "slashed", "seared", "cut")
toolspeed = 0.75
//misc, formerly from code/defines/weapons.dm
/*
* Misc Tools
*/
/obj/item/weapon/surgical/bonegel
name = "bone gel"
desc = "For fixing bones."
@@ -192,7 +197,7 @@
throwforce = 1.0
origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 3)
var/usage_amount = 10
drop_sound = 'sound/items/drop/accessory.ogg'
drop_sound = 'sound/items/drop/bottle.ogg'
/obj/item/weapon/surgical/bonesetter
name = "bone setter"
@@ -215,24 +220,31 @@
throw_range = 5
attack_verb = list("attacked", "hit", "bludgeoned")
// Cyborg Tools
/*
* Cyborg Tools
*/
/obj/item/weapon/surgical/retractor/cyborg
icon_state = "cyborg_retractor"
toolspeed = 0.5
/obj/item/weapon/surgical/hemostat/cyborg
icon_state = "cyborg_hemostat"
toolspeed = 0.5
/obj/item/weapon/surgical/cautery/cyborg
icon_state = "cyborg_cautery"
toolspeed = 0.5
/obj/item/weapon/surgical/surgicaldrill/cyborg
icon_state = "cyborg_drill"
toolspeed = 0.5
/obj/item/weapon/surgical/scalpel/cyborg
icon_state = "cyborg_scalpel"
toolspeed = 0.5
/obj/item/weapon/surgical/circular_saw/cyborg
icon_state = "cyborg_saw"
toolspeed = 0.5
/obj/item/weapon/surgical/bonegel/cyborg
@@ -242,13 +254,16 @@
toolspeed = 0.5
/obj/item/weapon/surgical/bonesetter/cyborg
icon_state = "cyborg_setter"
toolspeed = 0.5
/obj/item/weapon/surgical/bioregen/cyborg //VoreStation edit: let the borgs S U C C
icon_state = "cyborg_bioregen"
toolspeed = 0.5
// Alien Tools
/*
* Alien Tools
*/
/obj/item/weapon/surgical/retractor/alien
icon = 'icons/obj/abductor.dmi'
toolspeed = 0.25
+10
View File
@@ -78,6 +78,15 @@
prob(9);/obj/item/weapon/cell/super,
prob(1);/obj/item/weapon/cell/hyper)
/obj/random/powercell/device
name = "random device powercell"
desc = "This is a random device powercell."
icon_state = "random_device"
/obj/random/powercell/device/item_to_spawn()
return pick(prob(80);/obj/item/weapon/cell/device,
prob(10);/obj/item/weapon/cell/device/hyper,
prob(10);/obj/item/weapon/cell/device/empproof)
/obj/random/bomb_supply
name = "bomb supply"
@@ -276,6 +285,7 @@
/obj/random/cash/item_to_spawn()
return pick(prob(320);/obj/random/maintenance/clean,
prob(12);/obj/item/weapon/spacecash/c1,
prob(10);/obj/item/weapon/spacecash/c5,
prob(8);/obj/item/weapon/spacecash/c10,
prob(4);/obj/item/weapon/spacecash/c20,
prob(1);/obj/item/weapon/spacecash/c50,
@@ -10,13 +10,15 @@
/obj/item/device/analyzer/plant_analyzer,
/obj/item/device/radio/headset/headset_service,
/obj/item/clothing/head/greenbandana,
/obj/item/weapon/shovel/spade,
/obj/item/weapon/material/minihoe,
/obj/item/weapon/material/knife/machete/hatchet,
/obj/item/weapon/reagent_containers/glass/beaker = 2,
/obj/item/weapon/tool/wirecutters/clippers/trimmers,
/obj/item/weapon/reagent_containers/spray/plantbgone,
/obj/item/clothing/suit/storage/hooded/wintercoat/hydro,
/obj/item/clothing/shoes/boots/winter/hydro)
/obj/item/clothing/shoes/boots/winter/hydro,
/obj/item/weapon/storage/belt/hydro)
/obj/structure/closet/secure_closet/hydroponics/Initialize()
if(prob(50))
@@ -190,6 +190,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
/obj/item/clothing/under/harness,
/obj/item/clothing/accessory/storage/webbing,
/obj/item/weapon/spacecash/c1,
/obj/item/weapon/spacecash/c5,
/obj/item/weapon/spacecash/c10,
/obj/item/weapon/spacecash/c20,
/obj/item/weapon/camera_assembly,
+2 -1
View File
@@ -23,6 +23,7 @@
/obj/machinery/disposal/stumble_into(mob/living/M)
playsound(src, 'sound/effects/clang.ogg', 25, 1, -1)
visible_message("<span class='warning'>[M] [pick("tripped", "stumbled")] into \the [src]!</span>")
log_and_message_admins("stumbled into \the [src]", M)
if(M.client)
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
@@ -141,4 +142,4 @@
/obj/machinery/vending/stumble_into(mob/living/M)
..()
if(prob(2))
throw_item()
throw_item()
+15
View File
@@ -1,5 +1,20 @@
#define RECOMMENDED_VERSION 513
// CHOMPedit Start - Tracy
/proc/prof_init()
var/lib
switch(world.system_type)
if(MS_WINDOWS) lib = "prof.dll"
if(UNIX) lib = "libprof.so"
else CRASH("unsupported platform")
var/init = call(lib, "init")()
if("0" != init) CRASH("[lib] init error: [init]")
// CHOMPedit End
/world/New()
//prof_init() // CHOMPedit - Uncomment to enable Tracy. Requires https://github.com/mafemergency/byond-tracy/
world_startup_time = world.timeofday
rollover_safety_date = world.realtime - world.timeofday // 00:00 today (ish, since floating point error with world.realtime) of today
to_world_log("Map Loading Complete")
-18
View File
@@ -1,18 +0,0 @@
/world
hub = "Exadv1.spacestation13"
//CHOMPEdit: Accidentally committed this to master instead of pull request. Adding comment to make a pull request. Also to note that I have changed the password so we won't appear on the HUB regardless of TGS3.
hub_password = "null"
name = "Space Station 13"
/*YW EDIT we want to be on the hub
name = "VOREStation" //VOREStation Edit
visibility = 0 //VOREStation Edit
*/
/* This is for any host that would like their server to appear on the main SS13 hub.
To use it, simply replace the password above, with the password found below, and it should work.
If not, let us know on the main tgstation IRC channel of irc.rizon.net #tgstation13 we can help you there.
hub = "Exadv1.spacestation13"
hub_password = "kMZy3U5jJHSiBQjr"
name = "Space Station 13"
*/
+5 -1
View File
@@ -167,7 +167,11 @@ var/list/admin_verbs_fun = list(
/client/proc/admin_lightning_strike,
/client/proc/resize, //VOREStation Add,
/client/proc/cmd_admin_droppod_deploy,
/client/proc/adminorbit //VOREStation Add,
/client/proc/adminorbit, //VOREStation Add
/client/proc/add_mob_for_narration, //VOREStation Add
/client/proc/remove_mob_for_narration, //VOREStation Add
/client/proc/narrate_mob, //VOREStation Add
/client/proc/narrate_mob_args //VOREStation Add
)
var/list/admin_verbs_spawn = list(
+167
View File
@@ -0,0 +1,167 @@
//Datum that's initialized on first calling the client procs. It's stored in /client
//We keep a distinct names/refs list in an effort to make things speedy, and for easy checking if something is on our list.
//We manually add to list element with procs to avoid dealing with clunky global lists that might not be relevant
//and for ability to narrate from long range.
/datum/entity_narrate
var/list/entity_names = list()
var/list/entity_refs = list()
//Appears as a right click verb on any obj and mob within view range.
//when not right clicking we get a list to pick from in aforementioned view range.
/client/proc/add_mob_for_narration(E as obj|mob|turf in orange(world.view))
set name = "Narrate Entity (Add ref)"
set desc = "Saves a reference of target mob to be called when narrating."
set category = "Fun"
if(!check_rights(R_FUN)) return
//Making sure we got the list datum on our client.
if(!entity_narrate_holder)
entity_narrate_holder = new /datum/entity_narrate()
if(!istype(entity_narrate_holder, /datum/entity_narrate))
return
var/datum/entity_narrate/holder = entity_narrate_holder
//Since we extended to include all atoms, we're shutting things down with a guard clause for ghosts
if(istype(E, /mob/observer))
to_chat(usr, SPAN_NOTICE("Ghosts shouldn't be narrated! If you want a ghost, make it a subtype of mob/living!"))
return
//We require a static mob/living type to check for .client and also later on, to use the unique .say mechanics for stuttering and language
if(istype(E, /mob/living))
var/mob/living/L = E
if(L.client)
to_chat(usr, "You may not speak for players!")
log_and_message_admins("attempted to speak for [L.ckey]'s mob", usr)
return
var/unique_name = sanitize(tgui_input_text(usr, "Please give the entity a unique name to track internally. \
This doesn't override how it appears in game", "tracker", L.name))
holder.entity_names += unique_name
holder.entity_refs[unique_name] = L
log_and_message_admins("added [L.name] for their personal list to narrate", usr) //Logging here to avoid spam, while still safeguarding abuse
//Covering functionality for turfs and objs. We need static type to access the name var
else if(istype(E, /atom))
var/atom/A = E
var/unique_name = sanitize(tgui_input_text(usr, "Please give the entity a unique name to track internally. \
This doesn't override how it appears in game", "tracker", A.name))
holder.entity_names += unique_name
holder.entity_refs[unique_name] = A
log_and_message_admins("added [A.name] for their personal list to narrate", usr) //Logging here to avoid spam, while still safeguarding abuse
//Proc for keeping our ref list relevant, deleting mobs that are no longer relevant for our event
/client/proc/remove_mob_for_narration()
set name = "Narrate Entity (Remove ref)"
set desc = "Remove mobs you're no longer narrating from your list for easier work."
set category = "Fun"
if(!check_rights(R_FUN)) return
if(!entity_narrate_holder)
entity_narrate_holder = new /datum/entity_narrate()
to_chat(usr, "No references were added yet! First add references!")
return
if(!istype(entity_narrate_holder, /datum/entity_narrate))
return
var/datum/entity_narrate/holder = entity_narrate_holder
var/options = holder.entity_names + "Clear All"
var/removekey = tgui_input_list(usr, "Choose which entity to remove", "remove reference", options, null)
if(removekey == "Clear All")
var/confirm = tgui_alert(usr, "Do you really want to clear your entity list?", "confirm", list("Yes", "No"), "No")
if(confirm == "Yes")
holder.entity_names = list()
holder.entity_refs = list()
else if(removekey)
holder.entity_refs -= removekey
holder.entity_names -= removekey
//Planned to have TGUI functionality
//For now brings up a list of all entities on our reference list and gives us the option to choose what we wanna do
//using TGUI/Byond list/alert inputs
//Does not actually interact with the game world, it passes user input to narrate_mob_args(name, mode, message) after sanitizing
/client/proc/narrate_mob()
set name = "Narrate Entity (Interface)"
set desc = "Send either a visible or audiable message through your chosen entities using an interface"
set category = "Fun"
if(!check_rights(R_FUN)) return
if(!entity_narrate_holder)
entity_narrate_holder = new /datum/entity_narrate()
to_chat(usr, "No references were added yet! First add references!")
return
if(!istype(entity_narrate_holder, /datum/entity_narrate))
return
var/datum/entity_narrate/holder = entity_narrate_holder
//Obtaining and sanitizing arguments for the actual proc
var/which_entity = tgui_input_list(usr, "Choose which mob to narrate", "Narrate mob", holder.entity_names, null)
if(!which_entity) return
var/mode = tgui_alert(usr, "Speak or emote?", "mode", list("Speak", "Emote", "Cancel"))
if(mode == "Cancel") return
var/message = sanitize(tgui_input_text(usr, "Input what you want [which_entity] to say or do", "narrate", null, multiline = TRUE, prevent_enter = TRUE))
if(message)
narrate_mob_args(which_entity, mode, message)
//The actual logic of the verb. Called by narrate_mob() when used.
/client/proc/narrate_mob_args(name as text, mode as text, message as text)
set name = "Narrate Entity"
set desc = "Narrate entities using positional arguments. Name should be as saved in ref list, mode should be Speak or Emote, follow with message"
set category = "Fun"
if(!check_rights(R_FUN)) return
if(!entity_narrate_holder)
entity_narrate_holder = new /datum/entity_narrate()
to_chat(usr, "No references were added yet! First add references!")
return
if(!istype(entity_narrate_holder, /datum/entity_narrate))
return
var/datum/entity_narrate/holder = entity_narrate_holder
//Sanitizing args
name = sanitize(name)
mode = sanitize(mode)
if(message)
message = sanitize(message)
if(!(mode in list("Speak", "Emote")))
to_chat(usr, SPAN_NOTICE("Valid modes are 'Speak' and 'Emote'."))
return
if(!holder.entity_refs[name])
to_chat(usr, SPAN_NOTICE("[name] not in saved references!"))
//Separate definition for mob/living and /obj due to .say() code allowing us to engage with languages, stuttering etc
//We also need this so we can check for .client
if(istype(holder.entity_refs[name], /mob/living))
var/mob/living/our_entity = holder.entity_refs[name]
if(our_entity.client) //Making sure we can't speak for players
to_chat(usr, SPAN_NOTICE("Cannot narrate mobs with active clients!"))
log_and_message_admins("attempted to speak for [our_entity.ckey]'s mob", usr)
return
if(!message)
message = sanitize(tgui_input_text(usr, "Input what you want [our_entity] to [mode]", "narrate", null))
if(message && mode == "Speak")
our_entity.say(message)
else if(message && mode == "Emote")
our_entity.custom_emote(VISIBLE_MESSAGE, message)
else
return
//This does cost us some code duplication, but I think it's worth it.
//furthermore, objs/turfs require the usr to specify the verb when speaking, otherwise it looks like an emote.
else if(istype(holder.entity_refs[name], /atom))
var/atom/our_entity = holder.entity_refs[name]
if(!message)
message = sanitize(tgui_input_text(usr, "Input what you want [our_entity] to [mode]", "narrate", null))
if(message && mode == "Speak")
our_entity.audible_message("<b>[our_entity.name]</b> [message]")
else if(message && mode == "Emote")
our_entity.visible_message("<b>[our_entity.name]</b> [message]")
else
return
+2 -2
View File
@@ -32,7 +32,7 @@ GLOBAL_LIST_EMPTY(all_cataloguers)
var/datum/category_item/catalogue/displayed_data = null // Used for viewing a piece of data in the UI.
var/busy = FALSE // Set to true when scanning, to stop multiple scans.
var/debug = FALSE // If true, can view all catalogue data defined, regardless of unlock status.
var/weakref/partial_scanned = null // Weakref of the thing that was last scanned if inturrupted. Used to allow for partial scans to be resumed.
var/datum/weakref/partial_scanned = null // Weakref of the thing that was last scanned if inturrupted. Used to allow for partial scans to be resumed.
var/partial_scan_time = 0 // How much to make the next scan shorter.
/obj/item/device/cataloguer/advanced
@@ -130,7 +130,7 @@ GLOBAL_LIST_EMPTY(all_cataloguers)
to_chat(user, span("warning", "You failed to finish scanning \the [target] with \the [src]."))
playsound(src, 'sound/machines/buzz-two.ogg', 50)
color_box(box_segments, "#FF0000", 3)
partial_scanned = weakref(target)
partial_scanned = WEAKREF(target)
partial_scan_time += world.time - scan_start_time // This is added to the existing value so two partial scans will add up correctly.
sleep(3)
busy = FALSE
+1
View File
@@ -13,6 +13,7 @@
var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming.
var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent.
var/ircreplyamount = 0
var/entity_narrate_holder //Holds /datum/entity_narrate when using the relevant admin verbs.
/////////
//OTHER//
@@ -1,6 +1,6 @@
/datum/preferences
var/extra_languages = 0
var/preferred_language = "common" // CHOMPStation Edit: Allow selecting a preferred language
var/preferred_language = "common" // VOREStation Edit: Allow selecting a preferred language
/datum/category_item/player_setup_item/general/language
name = "Language"
@@ -15,8 +15,10 @@
S["language_prefixes"] >> pref.language_prefixes
//CHOMPEdit Begin
S["species"] >> pref.species
S["preflang"] >> pref.preferred_language
//CHOMPEdit End
//VORE Edit Begin
S["preflang"] >> pref.preferred_language
//VORE Edit End
S["language_custom_keys"] >> pref.language_custom_keys
/datum/category_item/player_setup_item/general/language/save_character(var/savefile/S)
@@ -26,7 +28,7 @@
testing("LANGSANI: Loaded from [pref.client]'s character [pref.real_name || "-name not yet loaded-"] savefile: [english_list(pref.alternate_languages || list())]")
S["language_prefixes"] << pref.language_prefixes
S["language_custom_keys"] << pref.language_custom_keys
S["preflang"] << pref.preferred_language // CHOMPStation Edit
S["preflang"] << pref.preferred_language // VOREStation Edit
/datum/category_item/player_setup_item/general/language/sanitize_character()
if(!islist(pref.alternate_languages)) pref.alternate_languages = list()
@@ -38,10 +40,10 @@
testing("LANGSANI: Truncated [pref.client]'s character [pref.real_name || "-name not yet loaded-"] language list because it was too long (len: [pref.alternate_languages.len], allowed: [S.num_alternate_languages])")
pref.alternate_languages.len = (S.num_alternate_languages + pref.extra_languages) // Truncate to allowed length
// CHOMPStation Edit Start
// VOREStation Edit Start
if(!(pref.preferred_language in pref.alternate_languages) || !pref.preferred_language) // Safety handling for if our preferred language is ever somehow removed from the character's list of langauges, or they don't have one set
pref.preferred_language = S.language // Reset to default, for safety
// CHOMPStation Edit end
// VOREStation Edit end
// Sanitize illegal languages
for(var/language in pref.alternate_languages)
@@ -87,7 +89,7 @@
. += "<b>Language Keys</b><br>"
. += " [jointext(pref.language_prefixes, " ")] <a href='?src=\ref[src];change_prefix=1'>Change</a> <a href='?src=\ref[src];reset_prefix=1'>Reset</a><br>"
. += "<b>Preferred Language</b> <a href='?src=\ref[src];pref_lang=1'>[pref.preferred_language]</a><br>" // CHOMPStation Add
. += "<b>Preferred Language</b> <a href='?src=\ref[src];pref_lang=1'>[pref.preferred_language]</a><br>" // VOREStation Add
/datum/category_item/player_setup_item/general/language/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["remove_language"])
@@ -175,11 +177,11 @@
return TOPIC_REFRESH
// CHOMPStation Add: Preferred Language
// VOREStation Add: Preferred Language
else if(href_list["pref_lang"])
if(pref.species) // Safety to prevent a null runtime here
var/datum/species/S = GLOB.all_species[pref.species]
var/list/lang_opts = list(S.language) + pref.alternate_languages
var/list/lang_opts = list(S.language) + pref.alternate_languages + LANGUAGE_GALCOM
var/selection = tgui_input_list(user, "Choose your preferred spoken language:", "Preferred Spoken Language", lang_opts, pref.preferred_language)
if(!selection) // Set our preferred to default, just in case.
tgui_alert_async(user, "Preferred Language not modified.", "Selection Canceled")
@@ -190,7 +192,7 @@
else // Did they set anything else?
tgui_alert_async(user, "You will now speak [pref.preferred_language] if you do not specify a language when speaking.", "Preferred Language Set")
return TOPIC_REFRESH
// CHOMPStation Add End
// VOREStation Add End
return ..()
@@ -396,6 +396,34 @@
ckeywhitelist = list("flintlockdafox")
character_name = list("Flintlock Sharpsman")
/datum/gear/fluff/zera_weldmask
path = /obj/item/clothing/head/welding/fluff/zera
display_name = "Zera's Welding Mask"
slot = slot_head
ckeywhitelist = list("fuackwit422")
character_name = list("Zera Livanne")
/datum/gear/fluff/zera_labcloak
path = /obj/item/clothing/suit/storage/toggle/labcoat/fluff/zera
display_name = "Zera's Labcloak"
slot = slot_wear_suit
ckeywhitelist = list("fuackwit422")
character_name = list("Zera Livanne")
/datum/gear/fluff/zera_cloak
path = /obj/item/clothing/head/fluff/zerahat
display_name = "Grand Purple Hat"
slot = slot_head
ckeywhitelist = list("fuackwit422")
character_name = list("Zera Livanne")
/datum/gear/fluff/zera_hat
path = /obj/item/clothing/suit/storage/toggle/labcoat/fluff/zeracloak
display_name = "Grand Purple Cloak"
slot = slot_wear_suit
ckeywhitelist = list("fuackwit422")
character_name = list("Zera Livanne")
// G CKEYS
@@ -1,13 +1,13 @@
// Define a place to save appearance in character setup
// CHOMPStation Add Start: Doing this here bc AUTOHISS_FULL is more readable than #
// VOREStation Add Start: Doing this here bc AUTOHISS_FULL is more readable than #
#define AUTOHISS_OFF 0
#define AUTOHISS_BASIC 1
#define AUTOHISS_FULL 2
// CHOMPStation Add End
// VOREStation Add End
/datum/preferences
var/vore_egg_type = "Egg" //The egg type they have.
var/autohiss = "Full" // CHOMPStation Add: Whether we have Autohiss on. I'm hijacking the egg panel bc this one has a shitton of unused space.
var/autohiss = "Full" // VOREStation Add: Whether we have Autohiss on. I'm hijacking the egg panel bc this one has a shitton of unused space.
// Definition of the stuff for the egg type.
/datum/category_item/player_setup_item/vore/egg
@@ -16,18 +16,18 @@
/datum/category_item/player_setup_item/vore/egg/load_character(var/savefile/S)
S["vore_egg_type"] >> pref.vore_egg_type
S["autohiss"] >> pref.autohiss // CHOMPStation Add
S["autohiss"] >> pref.autohiss // VOREStation Add
/datum/category_item/player_setup_item/vore/egg/save_character(var/savefile/S)
S["vore_egg_type"] << pref.vore_egg_type
S["autohiss"] << pref.autohiss // CHOMPStation Add
S["autohiss"] << pref.autohiss // VOREStation Add
/datum/category_item/player_setup_item/vore/egg/sanitize_character()
pref.vore_egg_type = sanitize_inlist(pref.vore_egg_type, global_vore_egg_types, initial(pref.vore_egg_type))
/datum/category_item/player_setup_item/vore/egg/copy_to_mob(var/mob/living/carbon/human/character)
character.vore_egg_type = pref.vore_egg_type
// CHOMPStation Add
// VOREStation Add
if(pref.client) // Safety, just in case so we don't runtime.
if(!pref.autohiss)
pref.client.autohiss_mode = AUTOHISS_FULL
@@ -39,12 +39,12 @@
pref.client.autohiss_mode = AUTOHISS_BASIC
if("Off")
pref.client.autohiss_mode = AUTOHISS_OFF
// CHOMPStation Add
// VOREStation Add
/datum/category_item/player_setup_item/vore/egg/content(var/mob/user)
. += "<br>"
. += " Egg Type: <a href='?src=\ref[src];vore_egg_type=1'>[pref.vore_egg_type]</a><br>"
. += "<b>Autohiss Default Setting:</b> <a href='?src=\ref[src];autohiss=1'>[pref.autohiss]</a><br>" // CHOMPStation Add
. += "<b>Autohiss Default Setting:</b> <a href='?src=\ref[src];autohiss=1'>[pref.autohiss]</a><br>" // VOREStation Add
/datum/category_item/player_setup_item/vore/egg/OnTopic(var/href, var/list/href_list, var/mob/user)
if(!CanUseTopic(user))
@@ -56,7 +56,7 @@
if(selection)
pref.vore_egg_type = selection
return TOPIC_REFRESH
// CHOMPStation Add Start
// VOREStation Add Start
else if(href_list["autohiss"])
var/list/autohiss_selection = list("Full", "Basic", "Off")
var/selection = tgui_input_list(user, "Choose your default autohiss setting:", "Character Preference", autohiss_selection, pref.autohiss)
@@ -65,12 +65,12 @@
else if(!selection)
pref.autohiss = "Full"
return TOPIC_REFRESH
// CHOMPStation Add End
// VOREStation Add End
else
return
// CHOMPStation Add Start: Doing this here bc AUTOHISS_FULL is more readable than #
// VOREStation Add Start: Doing this here bc AUTOHISS_FULL is more readable than #
#undef AUTOHISS_OFF
#undef AUTOHISS_BASIC
#undef AUTOHISS_FULL
// CHOMPStation Add End
// VOREStation Add End
+40 -22
View File
@@ -32,7 +32,7 @@
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
min_pressure_protection = 0 * ONE_ATMOSPHERE
max_pressure_protection = 10 * ONE_ATMOSPHERE
action_button_name = "Toggle Helmet"
species_restricted = list("Human", SPECIES_SKRELL, "Promethean")
sprite_sheets = VR_SPECIES_SPRITE_SHEETS_SUIT_MOB
sprite_sheets_obj = VR_SPECIES_SPRITE_SHEETS_SUIT_ITEM
@@ -47,12 +47,23 @@
var/obj/item/clothing/head/helmet/helmet = null // Deployable helmet, if any.
var/obj/item/weapon/tank/tank = null // Deployable tank, if any.
var/obj/item/device/suit_cooling_unit/cooler = null// Cooling unit, for FBPs. Cannot be installed alongside a tank.
//Cycler settings
var/no_cycle = FALSE //stop this item from being put in a cycler
//Does it spawn with any Inbuilt devices?
/obj/item/clothing/suit/space/void/Initialize()
. = ..()
if(boots && ispath(boots))
boots = new boots(src)
if(helmet && ispath(helmet))
helmet = new helmet(src)
if(tank && ispath(tank))
tank = new tank(src)
/obj/item/clothing/suit/space/void/examine(user)
. = ..()
. += to_chat(usr, "<span class='notice'>Alt-click to relase Tank/Cooling unit if installed.</span>")
for(var/obj/item/I in list(helmet,boots,tank,cooler))
. += "It has \a [I] installed."
if(tank && in_range(src,user))
@@ -145,13 +156,18 @@
helmet.set_light_flags(helmet.light_flags & ~LIGHT_ATTACHED)
helmet = null
/obj/item/clothing/suit/space/void/verb/toggle_helmet()
/obj/item/clothing/suit/space/void/ui_action_click(mob/living/user, action_name)
if(..())
return TRUE
toggle_helmet()
/obj/item/clothing/suit/space/void/verb/toggle_helmet()
set name = "Toggle Helmet"
set category = "Object"
set src in usr
if(!istype(src.loc,/mob/living)) return
if(!isliving(loc))
return
if(!helmet)
to_chat(usr, "There is no helmet installed.")
@@ -159,44 +175,45 @@
var/mob/living/carbon/human/H = usr
if(!istype(H))
return
if(H.stat)
return
if(H.wear_suit != src)
return
if(!istype(H)) return
if(H.stat) return
if(H.wear_suit != src) return
if(helmet.light_on)
to_chat(H, SPAN_NOTICE("The helmet light shuts off as it retracts."))
helmet.update_flashlight(H)
if(H.head == helmet)
to_chat(H, "<span class='notice'>You retract your suit helmet.</span>")
to_chat(H, SPAN_NOTICE("You retract your suit helmet."))
helmet.canremove = TRUE
H.drop_from_inventory(helmet)
helmet.forceMove(src)
playsound(src.loc, 'sound/machines/click2.ogg', 75, 1)
else
if(H.head)
to_chat(H, "<span class='danger'>You cannot deploy your helmet while wearing \the [H.head].</span>")
to_chat(H, SPAN_DANGER("You cannot deploy your helmet while wearing \the [H.head]."))
return
if(H.equip_to_slot_if_possible(helmet, slot_head))
helmet.pickup(H)
helmet.canremove = FALSE
to_chat(H, "<span class='info'>You deploy your suit helmet, sealing you off from the world.</span>")
if(helmet.light_system == STATIC_LIGHT)
helmet.update_light()
playsound(src.loc, 'sound/machines/click2.ogg', 75, 1)
/obj/item/clothing/suit/space/void/AltClick(mob/living/user)
eject_tank()
/obj/item/clothing/suit/space/void/verb/eject_tank()
set name = "Eject Voidsuit Tank/Cooler"
set category = "Object"
set src in usr
if(!istype(src.loc,/mob/living)) return
if(!tank && !cooler)
to_chat(usr, "There is no tank or cooling unit inserted.")
return
var/mob/living/carbon/human/H = usr
if(!tank && !cooler)
to_chat(H, SPAN_NOTICE("There is no tank or cooling unit inserted."))
return
if(!istype(H)) return
if(H.stat) return
if(H.wear_suit != src) return
@@ -208,7 +225,8 @@
else
removing = cooler
cooler = null
to_chat(H, "<span class='info'>You press the emergency release, ejecting \the [removing] from your suit.</span>")
to_chat(H, SPAN_DANGER("You press the emergency release, ejecting \the [removing] from your suit."))
playsound(src.loc, 'sound/machines/click.ogg', 75, 1)
removing.canremove = TRUE
H.drop_from_inventory(removing)
+12 -6
View File
@@ -3,7 +3,7 @@
var/initial_name = "Thaler"
desc = "It's worth 0 Thalers."
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon = 'icons/obj/economy.dmi'
icon_state = "spacecash1"
opacity = 0
density = FALSE
@@ -38,24 +38,24 @@
/obj/item/weapon/spacecash/update_icon()
cut_overlays()
name = "[worth] [initial_name]\s"
if(worth in list(1000,500,200,100,50,20,10,1))
if(worth in list(1000,500,200,100,50,20,10,5,1))
icon_state = "spacecash[worth]"
desc = "It's worth [worth] [initial_name]s."
return
var/sum = src.worth
var/num = 0
for(var/i in list(1000,500,200,100,50,20,10,1))
for(var/i in list(1000,500,200,100,50,20,10,5,1))
while(sum >= i && num < 50)
sum -= i
num++
var/image/banknote = image('icons/obj/items.dmi', "spacecash[i]")
var/image/banknote = image('icons/obj/economy.dmi', "spacecash[i]")
var/matrix/M = matrix()
M.Translate(rand(-6, 6), rand(-4, 8))
M.Turn(pick(-45, -27.5, 0, 0, 0, 0, 0, 0, 0, 27.5, 45))
banknote.transform = M
add_overlay(banknote)
if(num == 0) // Less than one thaler, let's just make it look like 1 for ease
var/image/banknote = image('icons/obj/items.dmi', "spacecash1")
var/image/banknote = image('icons/obj/economy.dmi', "spacecash1")
var/matrix/M = matrix()
M.Translate(rand(-6, 6), rand(-4, 8))
M.Turn(pick(-45, -27.5, 0, 0, 0, 0, 0, 0, 0, 27.5, 45))
@@ -96,9 +96,15 @@
/obj/item/weapon/spacecash/c1
name = "1 Thaler"
icon_state = "spacecash1"
desc = "It's worth 1 credit."
desc = "It's worth 1 Thaler."
worth = 1
/obj/item/weapon/spacecash/c5
name = "5 Thaler"
icon_state = "spacecash5"
desc = "It's worth 5 Thalers."
worth = 5
/obj/item/weapon/spacecash/c10
name = "10 Thaler"
icon_state = "spacecash10"
+2 -1
View File
@@ -35,7 +35,8 @@ GLOBAL_LIST_INIT(generic_fishing_pool_list, list(
/obj/random/junk = 80,
/obj/random/trash = 80,
/obj/item/weapon/spacecash/c1 = 10,
/obj/item/weapon/spacecash/c10 = 5,
/obj/item/weapon/spacecash/c5 = 3,
/obj/item/weapon/spacecash/c10 = 2,
/obj/item/weapon/spacecash/c100 = 1
))
@@ -106,19 +106,19 @@
for(var/i = 1 to number_of_blobs)
var/turf/T = pick(open_turfs)
var/obj/structure/blob/core/new_blob = new spawn_blob_type(T)
blobs += weakref(new_blob)
blobs += WEAKREF(new_blob)
open_turfs -= T // So we can't put two cores on the same tile if doing multiblob.
log_debug("Spawned [new_blob.overmind.blob_type.name] blob at [get_area(new_blob)].")
/datum/event2/event/blob/should_end()
for(var/weakref/weakref as anything in blobs)
for(var/datum/weakref/weakref as anything in blobs)
if(weakref.resolve()) // If the weakref is resolvable, that means the blob hasn't been deleted yet.
return FALSE
return TRUE // Only end if all blobs die.
// Normally this does nothing, but is useful if aborted by an admin.
/datum/event2/event/blob/end()
for(var/weakref/weakref as anything in blobs)
for(var/datum/weakref/weakref as anything in blobs)
var/obj/structure/blob/core/B = weakref.resolve()
if(istype(B))
qdel(B)
@@ -128,7 +128,7 @@
var/danger_level = 0
var/list/blob_type_names = list()
var/multiblob = FALSE
for(var/weakref/weakref as anything in blobs)
for(var/datum/weakref/weakref as anything in blobs)
var/obj/structure/blob/core/B = weakref.resolve()
if(!istype(B))
continue
@@ -3,6 +3,8 @@
/obj/item/weapon/tool/wirecutters/clippers
name = "plant clippers"
desc = "A tool used to take samples from plants."
icon = 'icons/obj/weapons.dmi'
icon_state = "clippers"
/obj/item/weapon/tool/wirecutters/clippers/trimmers
name = "hedgetrimmers"
@@ -263,7 +263,7 @@
if(proximity)
var/scanned = FALSE
for(var/obj/item/integrated_circuit/input/sensor/S in contents)
// S.set_pin_data(IC_OUTPUT, 1, weakref(target))
// S.set_pin_data(IC_OUTPUT, 1, WEAKREF(target))
// S.check_then_do_work()
if(S.scan(target))
scanned = TRUE
@@ -397,4 +397,4 @@
// Returns TRUE if I is something that could/should have a valid interaction. Used to tell circuitclothes to hit the circuit with something instead of the clothes
/obj/item/device/electronic_assembly/proc/is_valid_tool(var/obj/item/I)
return I.is_crowbar() || I.is_screwdriver() || istype(I, /obj/item/integrated_circuit) || istype(I, /obj/item/weapon/cell/device) || istype(I, /obj/item/device/integrated_electronics)
return I.is_crowbar() || I.is_screwdriver() || istype(I, /obj/item/integrated_circuit) || istype(I, /obj/item/weapon/cell/device) || istype(I, /obj/item/device/integrated_electronics)
@@ -21,7 +21,7 @@
/obj/item/integrated_circuit/proc/set_pin_data(var/pin_type, var/pin_number, datum/new_data)
if (istype(new_data) && !isweakref(new_data))
new_data = weakref(new_data)
new_data = WEAKREF(new_data)
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
return pin.write_data_to_pin(new_data)
@@ -72,4 +72,4 @@
if(pin)
debugger.write_data(pin, usr)
return 1
return 0
return 0
@@ -21,7 +21,7 @@ D [1]/ ||
/datum/integrated_io
var/name = "input/output"
var/obj/item/integrated_circuit/holder = null
var/weakref/data = null // This is a weakref, to reduce typecasts. Note that oftentimes numbers and text may also occupy this.
var/datum/weakref/data = null // This is a weakref, to reduce typecasts. Note that oftentimes numbers and text may also occupy this.
var/list/linked = list()
var/io_type = DATA_CHANNEL
@@ -47,7 +47,7 @@ D [1]/ ||
/datum/integrated_io/proc/data_as_type(var/as_type)
if(!isweakref(data))
return
var/weakref/w = data
var/datum/weakref/w = data
var/output = w.resolve()
return istype(output, as_type) ? output : null
@@ -82,7 +82,7 @@ list[](
return result
if(isweakref(input))
var/weakref/w = input
var/datum/weakref/w = input
var/atom/A = w.resolve()
//return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed.
return A ? "(\ref[A] \[Ref\])" : "(null)"
@@ -143,7 +143,7 @@
/obj/item/device/integrated_electronics/debugger/afterattack(atom/target, mob/living/user, proximity)
if(accepting_refs && proximity)
data_to_write = weakref(target)
data_to_write = WEAKREF(target)
visible_message("<span class='notice'>[user] slides \a [src]'s over \the [target].</span>")
to_chat(user, "<span class='notice'>You set \the [src]'s memory to a reference to [target.name] \[Ref\]. The ref scanner is \
now off.</span>")
@@ -154,7 +154,7 @@
io.write_data_to_pin(data_to_write)
var/data_to_show = data_to_write
if(isweakref(data_to_write))
var/weakref/w = data_to_write
var/datum/weakref/w = data_to_write
var/atom/A = w.resolve()
data_to_show = A.name
to_chat(user, "<span class='notice'>You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].</span>")
@@ -244,7 +244,7 @@
/obj/item/device/multitool/afterattack(atom/target, mob/living/user, proximity)
if(accepting_refs && toolmode == MULTITOOL_MODE_INTCIRCUITS && proximity)
weakref_wiring = weakref(target)
weakref_wiring = WEAKREF(target)
visible_message("<span class='notice'>[user] slides \a [src]'s over \the [target].</span>")
to_chat(user, "<span class='notice'>You set \the [src]'s memory to a reference to [target.name] \[Ref\]. The ref scanner is \
now off.</span>")
@@ -149,7 +149,7 @@
create_reagents(volume)
/obj/item/integrated_circuit/passive/power/chemical_cell/interact(mob/user)
set_pin_data(IC_OUTPUT, 2, weakref(src))
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
..()
@@ -97,7 +97,7 @@
/obj/item/integrated_circuit/converter/refdecode/do_work()
pull_data()
set_pin_data(IC_OUTPUT, 1, weakref(locate(get_pin_data(IC_INPUT, 1))))
set_pin_data(IC_OUTPUT, 1, WEAKREF(locate(get_pin_data(IC_INPUT, 1))))
push_data()
activate_pin(2)
@@ -391,4 +391,4 @@
set_pin_data(IC_OUTPUT, 1, result)
push_data()
activate_pin(2)
activate_pin(2)
@@ -235,7 +235,7 @@
O.data = null
if(assembly)
if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us.
O.data = weakref(assembly.loc)
O.data = WEAKREF(assembly.loc)
O.push_data()
@@ -272,7 +272,7 @@
continue
valid_things.Add(thing)
if(valid_things.len)
O.data = weakref(pick(valid_things))
O.data = WEAKREF(pick(valid_things))
activate_pin(2)
else
activate_pin(3)
@@ -321,7 +321,7 @@
if(findtext(addtext(thing.name," ",thing.desc), DT, 1, 0) )
valid_things.Add(thing)
if(valid_things.len)
O.data = weakref(pick(valid_things))
O.data = WEAKREF(pick(valid_things))
O.push_data()
activate_pin(2)
else
@@ -552,7 +552,7 @@
// as a translation, when it is not.
if(S.speaking && !istype(S.speaking, /datum/language/common))
translated = TRUE
set_pin_data(IC_OUTPUT , 1, weakref(M))//CHOMPADDITION: so we can target the speaker with an action
set_pin_data(IC_OUTPUT , 1, WEAKREF(M))//CHOMPADDITION: so we can target the speaker with an action
set_pin_data(IC_OUTPUT, 2, M.GetVoice())
set_pin_data(IC_OUTPUT, 3, msg)
@@ -605,7 +605,7 @@
for(var/datum/multilingual_say_piece/S in message_pieces)
if(!((S.speaking.flags & NONVERBAL) || (S.speaking.flags & SIGNLANG))||S.speaking.name == LANGUAGE_ECHOSONG) //Ignore verbal languages
return
set_pin_data(IC_OUTPUT , 1, weakref(M))//CHOMPADDITION: so we can target the speaker with an action
set_pin_data(IC_OUTPUT , 1, WEAKREF(M))//CHOMPADDITION: so we can target the speaker with an action
set_pin_data(IC_OUTPUT, 2, M.GetVoice())
set_pin_data(IC_OUTPUT, 3, msg)
@@ -648,7 +648,7 @@
if(istype(A, /obj/item/weapon/storage))
return FALSE
set_pin_data(IC_OUTPUT, 1, weakref(A))
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
push_data()
activate_pin(1)
return TRUE
@@ -676,7 +676,7 @@
set_pin_data(IC_OUTPUT, 1, null)
set_pin_data(IC_OUTPUT, 2, null)
set_pin_data(IC_OUTPUT, 3, null)
set_pin_data(IC_OUTPUT, 4, weakref(assembly))
set_pin_data(IC_OUTPUT, 4, WEAKREF(assembly))
if(assembly)
if(assembly.battery)
@@ -118,8 +118,8 @@
/obj/item/integrated_circuit/memory/constant/afterattack(atom/target, mob/living/user, proximity)
if(accepting_refs && proximity)
var/datum/integrated_io/O = outputs[1]
O.data = weakref(target)
O.data = WEAKREF(target)
visible_message("<span class='notice'>[user] slides \a [src]'s over \the [target].</span>")
to_chat(user, "<span class='notice'>You set \the [src]'s memory to a reference to [O.display_data(O.data)]. The ref scanner is \
now off.</span>")
accepting_refs = 0
accepting_refs = 0
@@ -32,7 +32,7 @@
/obj/item/integrated_circuit/reagent/smoke/interact(mob/user)
set_pin_data(IC_OUTPUT, 2, weakref(src))
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
..()
@@ -66,7 +66,7 @@
var/transfer_amount = 10
/obj/item/integrated_circuit/reagent/injector/interact(mob/user)
set_pin_data(IC_OUTPUT, 2, weakref(src))
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
..()
@@ -251,7 +251,7 @@
/obj/item/integrated_circuit/reagent/storage/interact(mob/user)
set_pin_data(IC_OUTPUT, 2, weakref(src))
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
..()
@@ -356,6 +356,3 @@
source.reagents.trans_id_to(target, G.id, transfer_amount)
activate_pin(2)
push_data()
+1 -2
View File
@@ -33,7 +33,6 @@
/// Whether we have applied our light yet or not.
var/applied = FALSE
/// whether we are to be added to SSlighting's sources_queue list for an update
var/needs_update = LIGHTING_NO_UPDATE
@@ -275,4 +274,4 @@
#undef EFFECT_UPDATE
#undef LUM_FALLOFF
#undef REMOVE_CORNER
#undef APPLY_CORNER
#undef APPLY_CORNER
+3 -3
View File
@@ -7,7 +7,7 @@
var/desc = null // Ditto.
var/icon_state = null // See above.
var/mob/living/holder = null // The mob that this datum is affecting.
var/weakref/origin = null // A weak reference to whatever caused the modifier to appear. THIS NEEDS TO BE A MOB/LIVING. It's a weakref to not interfere with qdel().
var/datum/weakref/origin = null // A weak reference to whatever caused the modifier to appear. THIS NEEDS TO BE A MOB/LIVING. It's a weakref to not interfere with qdel().
var/expire_at = null // world.time when holder's Life() will remove the datum. If null, it lasts forever or until it gets deleted by something else.
var/on_created_text = null // Text to show to holder upon being created.
var/on_expired_text = null // Text to show to holder when it expires.
@@ -68,9 +68,9 @@
/datum/modifier/New(var/new_holder, var/new_origin)
holder = new_holder
if(new_origin)
origin = weakref(new_origin)
origin = WEAKREF(new_origin)
else // We assume the holder caused the modifier if not told otherwise.
origin = weakref(holder)
origin = WEAKREF(holder)
..()
// Checks if the modifier should be allowed to be applied to the mob before attaching it.
+2
View File
@@ -15,6 +15,8 @@
M.stat = 2 //Kills the new mob
if(src.corpseuniform)
M.equip_to_slot_or_del(new src.corpseuniform(M), slot_w_uniform)
if(M.w_uniform)
M.w_uniform?:sensor_mode = corpsesensormode
if(src.corpsesuit)
M.equip_to_slot_or_del(new src.corpsesuit(M), slot_wear_suit)
if(src.corpseshoes)
+1 -1
View File
@@ -41,7 +41,7 @@
visible_message("Something flies out of [src]. It seems to be acting oddly.")
var/obj/effect/decal/cleanable/blood/gibs/gib = new /obj/effect/decal/cleanable/blood/gibs(loc)
// TODO - I have a feeling weakrefs will not work in ignore_list, verify this ~Leshana
var/weakref/g = weakref(gib)
var/datum/weakref/g = WEAKREF(gib)
ignore_list += g
spawn(600)
ignore_list -= g
+26 -1
View File
@@ -1,5 +1,30 @@
// VOREStation Add Start: Doing this here bc AUTOHISS_FULL is more readable than #
#define AUTOHISS_OFF 0
#define AUTOHISS_BASIC 1
#define AUTOHISS_FULL 2
// VOREStation Add End
/mob/living/carbon/human/Login()
..()
update_hud()
// VOREStation Add
if(client.prefs) // Safety, just in case so we don't runtime.
if(!client.prefs.autohiss)
client.autohiss_mode = AUTOHISS_FULL
else
switch(client.prefs.autohiss)
if("Full")
client.autohiss_mode = AUTOHISS_FULL
if("Basic")
client.autohiss_mode = AUTOHISS_BASIC
if("Off")
client.autohiss_mode = AUTOHISS_OFF
// VOREStation Add
if(species) species.handle_login_special(src)
return
return
// VOREStation Add Start: Doing this here bc AUTOHISS_FULL is more readable than #
#undef AUTOHISS_OFF
#undef AUTOHISS_BASIC
#undef AUTOHISS_FULL
// VOREStation Add End
@@ -470,7 +470,7 @@
if(noise)
src.visible_message("<font color='red'><b>[src] moves their head next to [B]'s neck, seemingly looking for something!</b></font>")
else
src.visible_message("<font color='red'><b>[src] moves their head next to [B]'s neck, seemingly looking for something!</b></font>", range = 1)
src.visible_message("<font color='red'><i>[src] moves their head next to [B]'s neck, seemingly looking for something!</i></font>", range = 1)
if(bleed) //Due to possibility of missing/misclick and missing the bleeding cues, we are warning the scene members of BLEEDING being on
to_chat(src, SPAN_WARNING("This is going to cause [B] to keep bleeding!"))
@@ -481,7 +481,7 @@
if(noise)
src.visible_message("<font color='red'><b>[src] suddenly extends their fangs and plunges them down into [B]'s neck!</b></font>")
else
src.visible_message("<font color='red'><b>[src] suddenly extends their fangs and plunges them down into [B]'s neck!</b></font>", range = 1)
src.visible_message("<font color='red'><i>[src] suddenly extends their fangs and plunges them down into [B]'s neck!</i></font>", range = 1)
if(bleed)
B.apply_damage(10, BRUTE, BP_HEAD, blocked = 0, soaked = 0, sharp = TRUE, edge = FALSE)
var/obj/item/organ/external/E = B.get_organ(BP_HEAD)
@@ -492,12 +492,17 @@
else
B.apply_damage(5, BRUTE, BP_HEAD) //You're getting fangs pushed into your neck. What do you expect????
B.drip(80) //Remove enough blood to make them a bit woozy, but not take oxyloss.
adjust_nutrition(400)
sleep(50)
B.drip(1)
sleep(50)
B.drip(1)
if(!noise && !bleed) //If we're quiet and careful, there should be no blood to serve as evidence
B.remove_blood(82) //Removing in one go since we dont want splatter
adjust_nutrition(410) //We drink it all, not letting any go to waste!
else //Otherwise, we're letting blood drop to the floor
B.drip(80) //Remove enough blood to make them a bit woozy, but not take oxyloss.
adjust_nutrition(400)
sleep(50)
B.drip(1)
sleep(50)
B.drip(1)
//Welcome to the adapted changeling absorb code.
+1 -1
View File
@@ -500,7 +500,7 @@
if("Cancel")
return
else if (istype(W, /obj/item/weapon/card/id) && idaccessible == 0)
to_chat(user, "<span class='notice'>[src] is not accepting access modifcations at this time.</span>")
to_chat(user, "<span class='notice'>[src] is not accepting access modifications at this time.</span>") // CHOMPEDIT : purdev (spelling fix)
return
/mob/living/silicon/pai/verb/allowmodification()
@@ -1,5 +1,5 @@
// Spawner landmarks are used because platforms that are mapped during
// SSatoms init try to Initialize() twice. I have no idea why and I am
// SSatoms init try to Initialize() twice. I have no idea why and I am
// not paid enough to spend more time trying to debug it.
/obj/effect/landmark/robot_platform
name = "recon platform spawner"
@@ -40,7 +40,7 @@
var/tmp/recharge_complete = FALSE
var/tmp/recharger_charge_amount = 10 KILOWATTS
var/tmp/recharger_tick_cost = 80 KILOWATTS
var/weakref/recharging
var/datum/weakref/recharging
var/list/stored_atoms
var/max_stored_atoms = 1
@@ -82,7 +82,7 @@
components["armour"] = new /datum/robot_component/armour/platform(src)
/mob/living/silicon/robot/platform/Destroy()
for(var/weakref/drop_ref in stored_atoms)
for(var/datum/weakref/drop_ref in stored_atoms)
var/atom/movable/drop_atom = drop_ref.resolve()
if(istype(drop_atom) && !QDELETED(drop_atom) && drop_atom.loc == src)
drop_atom.dropInto(loc)
@@ -110,7 +110,7 @@
if(length(stored_atoms))
var/list/atom_names = list()
for(var/weakref/stored_ref in stored_atoms)
for(var/datum/weakref/stored_ref in stored_atoms)
var/atom/movable/AM = stored_ref.resolve()
if(istype(AM))
atom_names += "\a [AM]"
@@ -22,7 +22,7 @@
to_chat(user, SPAN_WARNING("\The [src] already has \a [recharging.resolve()] inserted into its recharging port."))
else if(user.unEquip(W))
W.forceMove(src)
recharging = weakref(W)
recharging = WEAKREF(W)
recharge_complete = FALSE
user.visible_message("<b>\The [user]</b> slots \the [W] into \the [src]'s recharging port.")
return TRUE
@@ -43,7 +43,7 @@
if(jobban_isbanned(user, "Robot"))
to_chat(user, SPAN_WARNING("You are banned from synthetic roles and cannot take control of \the [src]."))
return
return
// Boilerplate from drone fabs, unsure if there's a shared proc to use instead.
var/deathtime = world.time - user.timeofdeath
@@ -10,7 +10,7 @@
recharging = null
if(length(stored_atoms))
for(var/weakref/stored_ref in stored_atoms)
for(var/datum/weakref/stored_ref in stored_atoms)
var/atom/movable/dropping = stored_ref.resolve()
if(istype(dropping) && !QDELETED(dropping) && dropping.loc == src)
dropping.dropInto(loc)
@@ -67,18 +67,18 @@
/mob/living/silicon/robot/platform/proc/store_atom(var/atom/movable/storing, var/mob/user)
if(istype(storing))
storing.forceMove(src)
LAZYDISTINCTADD(stored_atoms, weakref(storing))
LAZYDISTINCTADD(stored_atoms, WEAKREF(storing))
/mob/living/silicon/robot/platform/proc/drop_stored_atom(var/atom/movable/ejecting, var/mob/user)
if(!ejecting && length(stored_atoms))
var/weakref/stored_ref = stored_atoms[1]
var/datum/weakref/stored_ref = stored_atoms[1]
if(!istype(stored_ref))
LAZYREMOVE(stored_atoms, stored_ref)
else
ejecting = stored_ref?.resolve()
LAZYREMOVE(stored_atoms, weakref(ejecting))
LAZYREMOVE(stored_atoms, WEAKREF(ejecting))
if(istype(ejecting) && !QDELETED(ejecting) && ejecting.loc == src)
ejecting.dropInto(loc)
if(user == src)
@@ -90,11 +90,11 @@
if(isrobot(user) && user.Adjacent(src))
return try_remove_cargo(user)
return ..()
/mob/living/silicon/robot/platform/proc/try_remove_cargo(var/mob/user)
if(!length(stored_atoms) || !istype(user))
return FALSE
var/weakref/remove_ref = stored_atoms[length(stored_atoms)]
var/datum/weakref/remove_ref = stored_atoms[length(stored_atoms)]
var/atom/movable/removing = remove_ref?.resolve()
if(!istype(removing) || QDELETED(removing) || removing.loc != src)
LAZYREMOVE(stored_atoms, remove_ref)
@@ -136,4 +136,4 @@
return FALSE
if(user.incapacitated() || !Adjacent(user) || !dropping.Adjacent(user))
return FALSE
return TRUE
return TRUE
+12 -2
View File
@@ -14,7 +14,12 @@
handle_attack_delay(A, melee_attack_delay) // This will sleep this proc for a bit, which is why waitfor is false.
// Cooldown testing is done at click code (for players) and interface code (for AI).
setClickCooldown(get_attack_speed() + ((injury_level / 2) SECONDS)) // CHOMPStation Edit: Delay how fast we can attack by our injury level / 2
// VOREStation Edit Start: Simplemob Injury
if(injury_enrages)
setClickCooldown(get_attack_speed() - ((injury_level / 2) SECONDS)) // Increase how fast we can attack by our injury level / 2
else
setClickCooldown(get_attack_speed() + ((injury_level / 2) SECONDS)) // Delay how fast we can attack by our injury level / 2
// VOREStation Edit Stop: Simplemob Injury
// Returns a value, but will be lost if
. = do_attack(A, their_T)
@@ -90,7 +95,12 @@
if(!istype(A) || QDELETED(A))
return
setClickCooldown(get_attack_speed() + ((injury_level / 2) SECONDS)) // CHOMPStation Edit: Delay how fast we can attack by our injury level / 2
// VOREStation Edit Start: Simplemob Injury
if(injury_enrages)
setClickCooldown(get_attack_speed() - ((injury_level / 2) SECONDS)) // Increase how fast we can attack by our injury level / 2
else
setClickCooldown(get_attack_speed() + ((injury_level / 2) SECONDS)) // Delay how fast we can attack by our injury level / 2
// VOREStation Edit Stop: Simplemob Injury
face_atom(A)
@@ -169,11 +169,12 @@
var/heal_countdown = 5 //VOREStation Edit - A cooldown ticker for passive healing
var/list/myid_access = list() //VOREStation Edit
var/ID_provided = FALSE //VOREStation Edit
// CHOMPStation Add: Move/Shoot/Attack delays based on damage
var/damage_fatigue_mult = 1 // Our multiplier for how heavily mobs are affected by injury. [UPDATE THIS IF THE FORMULA CHANGES]: Formula = injury_level = round(rand(2,6) * damage_fatigue_mult * clamp(((rand(2,5) * (health / getMaxHealth())) - rand(0,2)), 1, 20))
// VOREStation Add: Move/Shoot/Attack delays based on damage
var/damage_fatigue_mult = 0 // Our multiplier for how heavily mobs are affected by injury. [UPDATE THIS IF THE FORMULA CHANGES]: Formula = injury_level = round(rand(1,3) * damage_fatigue_mult * clamp(((rand(2,5) * (h / getMaxHealth())) - rand(0,2)), 1, 5))
var/injury_level = 0 // What our injury level is. Rather than being the flat damage, this is the amount added to various delays to simulate injuries in a manner as lightweight as possible.
var/threshold = 0.6 // When we start slowing down. Configure this setting per-mob. Default is 60%
// CHOMPStation Add End
var/injury_enrages = FALSE // Do injuries enrage (aka strengthen) our mob? If yes, we'll interpret how hurt we are differently.
// VOREStation Add End
/mob/living/simple_mob/Initialize()
verbs -= /mob/verb/observe
@@ -273,8 +274,13 @@
if(m_intent == "walk")
. *= 1.5
. += injury_level // CHOMPStation Edit: Adding our injury level delay to our total
// VOREStation Edit Start
if(injury_enrages) // If we enrage, then do this, else
. -= injury_level
else
. += injury_level
// VOREStation Edit Stop
. += config.animal_delay
. += ..()
@@ -325,7 +331,7 @@
var/list/hit_zones = list("body") //When in doubt, it's probably got a body.
/*
* CHOMPStation Add
* VOREStation Add
* How injured are we? Returns a number that is then added to movement cooldown and firing/melee delay respectively.
* Called by movement_delay and our firing/melee delay checks
*/
@@ -333,11 +339,11 @@
var/h = getMaxHealth() - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - halloss // We're not updating our actual health here bc we want updatehealth() and other checks to handle that
if(h > 0) // Safety to prevent division by 0 errors
if((h / getMaxHealth()) <= threshold) // Essentially, did our health go down? We don't modify want to modify our total slowdown if we didn't actually take damage, and aren't below our threshold %
var/totaldelay = round(rand(2,6) * damage_fatigue_mult * clamp(((rand(2,5) * (h / getMaxHealth())) - rand(0,2)), 1, 20)) // totaldelay is how much delay we're going to feed into attacks and movement. Do NOT change this formula unless you know how to math.
var/totaldelay = round(rand(1,3) * damage_fatigue_mult * clamp(((rand(2,5) * (h / getMaxHealth())) - rand(0,2)), 1, 5)) // totaldelay is how much delay we're going to feed into attacks and movement. Do NOT change this formula unless you know how to math.
injury_level = totaldelay // Adds our returned slowdown to the mob's injury level
/mob/living/simple_mob/updatehealth() // We don't want to fully override the check, just hook our own code in
get_injury_level() // We check how injured we are, then actually update the mob on how hurt we are.
. = ..() // Calling parent here, actually updating our mob on how hurt we are.
// CHOMPStation Add End
// VOREStation Add End
@@ -130,11 +130,7 @@
/mob/living/simple_mob/vore/pakkun/on_throw_vore_special(var/pred, var/mob/living/target)
if(pred && !extra_posessive && !(LAZYFIND(prey_excludes, target)))
LAZYSET(prey_excludes, target, world.time)
<<<<<<< HEAD
addtimer(CALLBACK(src, .proc/removeMobFromPreyExcludes, weakref(target)), 5 MINUTES)
=======
addtimer(CALLBACK(src, PROC_REF(removeMobFromPreyExcludes), WEAKREF(target)), 5 MINUTES)
>>>>>>> b6b3a1357c... Merge pull request #14976 from ItsSelis/selis-515compat
if(ai_holder)
ai_holder.remove_target()
@@ -159,11 +155,7 @@
for(var/mob/living/L in living_mobs(0))
if(!(LAZYFIND(prey_excludes, L)))
LAZYSET(prey_excludes, L, world.time)
<<<<<<< HEAD
addtimer(CALLBACK(src, .proc/removeMobFromPreyExcludes, weakref(L)), 5 MINUTES)
=======
addtimer(CALLBACK(src, PROC_REF(removeMobFromPreyExcludes), WEAKREF(L)), 5 MINUTES)
>>>>>>> b6b3a1357c... Merge pull request #14976 from ItsSelis/selis-515compat
else
..()
+4
View File
@@ -9,6 +9,10 @@
if(M == src) continue
if( M.key && (M.key != key) )
var/matches
//CHOMPEDIT - IP exemptions for those who are known to live together
if (config.ip_whitelist[key] && config.ip_whitelist[key] == config.ip_whitelist[M.key])
continue
//CHOMPEDIT end
if( (M.lastKnownIP == client.address) )
matches += "IP ([client.address])"
if( (client.connection != "web") && (M.computer_id == client.computer_id) )
+2 -2
View File
@@ -684,12 +684,12 @@
var/datum/language/keylang = GLOB.all_languages[client.prefs.language_custom_keys[key]]
if(keylang)
new_character.language_keys[key] = keylang
// CHOMPStation Add: Preferred Language Setting;
// VOREStation Add: Preferred Language Setting;
if(client.prefs.preferred_language) // Do we have a preferred language?
var/datum/language/def_lang = GLOB.all_languages[client.prefs.preferred_language]
if(def_lang)
new_character.default_language = def_lang
// CHOMPStation Add End
// VOREStation Add End
// And uncomment this, too.
//new_character.dna.UpdateSE()
@@ -929,4 +929,72 @@
desc = ""
icon = 'icons/mob/vore/ears_vr.dmi'
icon_state = "kara_horn"
ckeys_allowed = list("satinisle")
ckeys_allowed = list("satinisle")
/datum/sprite_accessory/ears/shark
name = "shark ears (Colorable)"
desc = ""
icon_state = "shark_ears"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/sharkhigh
name = "shark upper ears (Colorable)"
desc = ""
icon_state = "shark_ears_upper"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/sharklow
name = "shark lower ears (Colorable)"
desc = ""
icon_state = "shark_ears_lower"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/sharkfin
name = "shark fin (Colorable)"
desc = ""
icon_state = "shark_fin"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/sharkfinalt
name = "shark fin alt style (Colorable)"
desc = ""
icon_state = "shark_fin_alt"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/sharkboth
name = "shark ears and fin (Colorable)"
desc = ""
icon_state = "shark_ears"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
extra_overlay = "shark_fin"
/datum/sprite_accessory/ears/sharkbothalt
name = "shark ears and fin alt style (Colorable)"
desc = ""
icon_state = "shark_ears"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
extra_overlay = "shark_fin_alt"
/datum/sprite_accessory/ears/sharkhighboth
name = "shark upper ears and fin (Colorable)"
desc = ""
icon_state = "shark_ears_upper"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
extra_overlay = "shark_fin"
/datum/sprite_accessory/ears/sharklowhboth
name = "shark lower ears and fin alt style (Colorable)"
desc = ""
icon_state = "shark_ears_lower"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
extra_overlay = "shark_fin_alt"
@@ -981,3 +981,16 @@
icon_state = "nevrean_long"
color_blend_mode = ICON_MULTIPLY
body_parts = list(BP_HEAD)
/datum/sprite_accessory/marking/vr_heterochromia_l
name = "Heterochromia (left eye)"
icon = 'icons/mob/human_races/markings_vr.dmi'
icon_state = "heterochromia_l"
body_parts = list(BP_HEAD)
/datum/sprite_accessory/marking/vr_teshi_heterochromia_l
name = "Heterochromia (Teshari) (left eye)"
icon = 'icons/mob/human_races/markings_vr.dmi'
icon_state = "teshi_heterochromia_l"
body_parts = list(BP_HEAD)
species_allowed = list(SPECIES_TESHARI)
@@ -1329,12 +1329,21 @@
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/tail/kara //SatinIsle fluff item
/datum/sprite_accessory/tail/sectdrone_tail
name = "Sect Drone Tail (To use with bodytype-marking)"
icon = 'icons/mob/vore/tails_vr.dmi'
icon_state = "sectdrone_tail"
extra_overlay = "sectdrone_tail_mark"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/*/datum/sprite_accessory/tail/kara //SatinIsle fluff item //CHOMP Remove
name = "Pterokara Tail"
icon = 'icons/mob/vore/tails_vr.dmi'
icon_state = "kara_tail"
ckeys_allowed = list("satinisle")
*/
//LONG TAILS ARE NOT TAUR BUTTS >:O
/datum/sprite_accessory/tail/longtail
name = "You should not see this..."
@@ -1377,3 +1386,32 @@
clip_mask_icon = 'icons/mob/vore/taurs_vr.dmi'
clip_mask_state = "taur_clip_mask_def" //Used to clip off the lower part of suits & uniforms.
extra_overlay = "horse" //I can't believe this works.
/datum/sprite_accessory/tail/turkey //Would have been a really good thing for Thanksgiving probably but I'm not going to wait that long.
name = "turkey"
desc = ""
icon_state = "turkey"
/datum/sprite_accessory/tail/shark_markings
name = "akula tail, colorable, tail and fins"
desc = ""
icon_state = "sharktail"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
extra_overlay = "sharktail_markings"
/datum/sprite_accessory/tail/shark_stripes
name = "akula tail, colorable, stripe"
desc = ""
icon_state = "sharktail"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
extra_overlay = "sharktail_stripemarkings"
/datum/sprite_accessory/tail/shark_tips
name = "akula tail, colorable, tips"
desc = ""
icon_state = "sharktail"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
extra_overlay = "sharktail_tipmarkings"
@@ -320,9 +320,10 @@
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/wing/kara //SatinIsle Fluff Item
/*/datum/sprite_accessory/wing/kara //SatinIsle Fluff Item //Chomp REMOVE
name = "Pterokara wings"
desc = ""
icon = 'icons/mob/vore/wings_vr.dmi'
icon_state = "feathered_kara"
ckeys_allowed = list("satinisle")
*/
+18 -6
View File
@@ -90,6 +90,7 @@
var/mode = 0
health_flags = (NIF_H_SYNTHREPAIR)
//These self-activate on their own, these aren't user-settable to on/off.
/datum/nifsoft/medichines_syn/activate()
if((. = ..()))
@@ -101,9 +102,9 @@
/datum/nifsoft/medichines_syn/life()
if((. = ..()))
var/mob/living/carbon/human/H = nif.human // Chomp Edit
var/HP_percent = H.health/H.getMaxHealth() // Chomp Edit
//We're good!
var/mob/living/carbon/human/S = nif.human
var/HP_percent = S.health/S.getMaxHealth()
if(!nif.human.bad_external_organs.len)
if(mode || active)
nif.notify("User Status: NORMAL. Medichines deactivating.")
@@ -131,15 +132,26 @@
// Chomp Edit Start //
else if(mode == 2 && HP_percent < -0.4)
nif.notify("User Status: CRITICAL. Notifying medical!",TRUE)
H << 'sound/voice/nifmed_critical.ogg' //CHOMP Add
S << 'sound/voice/nifmed_critical.ogg' //CHOMP Add
mode = 0
if(!isbelly(H.loc)) //Not notified in case of vore, for gameplay purposes.
var/turf/T = get_turf(H)
if(!isbelly(S.loc)) //Not notified in case of vore, for gameplay purposes.
var/turf/T = get_turf(S)
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
a.autosay("[H.real_name] is in critical condition, located at ([T.x],[T.y],[T.z])!", "[H.real_name]'s NIF", "Medical")
a.autosay("[S.real_name] is in critical condition, located at ([T.x],[T.y],[T.z])!", "[S.real_name]'s NIF", "Medical")
qdel(a)
// Chomp Edit End //
/* //Chomp Comment out, using our solution instead of their backport and edit of our solution.
if(mode == 2 && HP_percent < -0.4) //lets inform someone who might be able to help us that we got toasted and roasted
nif.notify("User Status: CRITICAL. Notifying medical!",TRUE)
mode = 3 //this does nothing except stop it from repeating over and over and over and over and over and over and over
if(!isbelly(S.loc)) //Not notified in case of vore, for gameplay purposes.
var/turf/T = get_turf(S)
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
a.autosay("[S.real_name] is in a critical condition, located at ([T.x],[T.y],[T.z])!", "[S.real_name]'s NIF", "Medical")
qdel(a)
*/ //Chomp comment out END
return TRUE
/datum/nifsoft/spare_breath
+4 -4
View File
@@ -79,7 +79,7 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
user.set_viewsize(world.view + extra_view)
GLOB.moved_event.register(user, src, /obj/machinery/computer/ship/proc/unlook)
// TODO GLOB.stat_set_event.register(user, src, /obj/machinery/computer/ship/proc/unlook)
LAZYDISTINCTADD(viewers, weakref(user))
LAZYDISTINCTADD(viewers, WEAKREF(user))
/obj/machinery/computer/ship/proc/unlook(var/mob/user)
user.reset_view()
@@ -92,10 +92,10 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
user.set_viewsize() // reset to default
GLOB.moved_event.unregister(user, src, /obj/machinery/computer/ship/proc/unlook)
// TODO GLOB.stat_set_event.unregister(user, src, /obj/machinery/computer/ship/proc/unlook)
LAZYREMOVE(viewers, weakref(user))
LAZYREMOVE(viewers, WEAKREF(user))
/obj/machinery/computer/ship/proc/viewing_overmap(mob/user)
return (weakref(user) in viewers)
return (WEAKREF(user) in viewers)
/obj/machinery/computer/ship/tgui_status(mob/user)
. = ..()
@@ -120,7 +120,7 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
/obj/machinery/computer/ship/sensors/Destroy()
sensors = null
if(LAZYLEN(viewers))
for(var/weakref/W in viewers)
for(var/datum/weakref/W in viewers)
var/M = W.resolve()
if(M)
unlook(M)
+1
View File
@@ -25,6 +25,7 @@
var/self_recharge = FALSE // If true, the cell will recharge itself.
var/charge_amount = 25 // How much power to give, if self_recharge is true. The number is in absolute cell charge, as it gets divided by CELLRATE later.
var/last_use = 0 // A tracker for use in self-charging
var/connector_type = "standard" //What connector sprite to use when in a cell charger, null if no connectors
var/charge_delay = 0 // How long it takes for the cell to start recharging after last use
matter = list(MAT_STEEL = 700, MAT_GLASS = 50)
drop_sound = 'sound/items/drop/component.ogg'
+36 -1
View File
@@ -21,10 +21,45 @@
charge = 0
update_icon()
/*
* Crap Device
*/
/obj/item/weapon/cell/device/crap
name = "\improper rechargable D battery"
desc = "An older, cheap power cell designed to power handheld devices. It's probably been in use for quite some time now."
description_fluff = "You can't top the rust top." //TOTALLY TRADEMARK INFRINGEMENT
origin_tech = list(TECH_POWER = 0)
icon_state = "device_crap"
maxcharge = 240
matter = list(MAT_STEEL = 350, MAT_GLASS = 30)
/obj/item/weapon/cell/device/crap/update_icon() //No visible charge indicator
return
/obj/item/weapon/cell/device/crap/empty/Initialize()
. = ..()
charge = 0
update_icon()
/*
* Hyper Device
*/
/obj/item/weapon/cell/device/hyper
name = "hyper device power cell"
desc = "A small power cell designed to power handheld devices. Has a better charge than a standard device cell."
icon_state = "hype_device_cell"
maxcharge = 600
matter = list(MAT_STEEL = 400, MAT_GLASS = 60)
/obj/item/weapon/cell/device/hyper/empty/Initialize()
. = ..()
charge = 0
update_icon()
/*
* EMP Proof Device
*/
/obj/item/weapon/cell/device/empproof //UNUSED
/obj/item/weapon/cell/device/empproof
name = "shielded device power cell"
desc = "A small power cell designed to power handheld devices. Shielded from EMPs."
icon_state = "up_device_cell"
+31 -17
View File
@@ -1,34 +1,30 @@
//CHOMP Disabled in DME in favor of modular_chomp folder
/*
* Empty
*/
/obj/item/weapon/cell/empty/New()
..()
charge = 0
/*
* Crap
*/
/obj/item/weapon/cell/crap
name = "\improper rechargable AA battery"
desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT
name = "\improper rechargable DD battery"
desc = "An older, cheap power cell. It's probably been in use for quite some time now."
description_fluff = "You can't top the rust top." //TOTALLY TRADEMARK INFRINGEMENT
origin_tech = list(TECH_POWER = 0)
icon_state = "crap"
maxcharge = 500
matter = list(MAT_STEEL = 700, MAT_GLASS = 40)
/obj/item/weapon/cell/crap/update_icon() //No visible charge indicator
return
/obj/item/weapon/cell/crap/empty/New()
..()
charge = 0
/*
* Security Borg
*/
/obj/item/weapon/cell/secborg
name = "security borg rechargable D battery"
origin_tech = list(TECH_POWER = 0)
icon_state = "secborg"
maxcharge = 600 //600 max charge / 100 charge per shot = six shots
matter = list(MAT_STEEL = 700, MAT_GLASS = 40)
/obj/item/weapon/cell/secborg/empty/New()
..()
charge = 0
update_icon()
/*
* APC
*/
@@ -90,10 +86,23 @@
/obj/item/weapon/cell/mech
name = "mecha power cell"
icon_state = "mech"
connector_type = "mech"
charge = 15000
maxcharge = 15000
matter = list(MAT_STEEL = 800, MAT_GLASS = 60)
/obj/item/weapon/cell/mech/lead
name = "lead acid battery"
desc = "An ancient battery design not commonly seen anymore. It looks like it'd fit inside a mech however..."
origin_tech = list(TECH_POWER = 0) //Litteraly an old car battery, doesn't need tech
icon_state = "lead"
charge = 8000
maxcharge = 8000
matter = list(MAT_STEEL = 300, MAT_GLASS = 10)
/obj/item/weapon/cell/mech/lead/update_icon() //No visible charge indicator
return
/obj/item/weapon/cell/mech/high
name = "high-capacity mecha power cell"
origin_tech = list(TECH_POWER = 3)
@@ -147,6 +156,7 @@
origin_tech = list(TECH_POWER = 4, TECH_BIO = 5)
icon = 'icons/mob/slimes.dmi' //'icons/obj/harvest.dmi'
icon_state = "yellow slime extract" //"potato_battery"
connector_type = "slime"
description_info = "This 'cell' holds a max charge of 10k and self recharges over time."
maxcharge = 10000
matter = null
@@ -162,8 +172,12 @@
maxcharge = 120 //Emergency lights use 0.2 W per tick, meaning ~10 minutes of emergency power from a cell
matter = list(MAT_GLASS = 20)
icon_state = "em_light"
connector_type = "emergency"
w_class = ITEMSIZE_TINY
/obj/item/weapon/cell/emergency_light/update_icon() //No visible charge indicator
return
/obj/item/weapon/cell/emergency_light/Initialize()
. = ..()
var/area/A = get_area(src)
@@ -10,7 +10,7 @@
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2)
matter = list(MAT_STEEL = 1000)
projectile_type = /obj/item/projectile/beam/meeplaser
charge_cost = 150
charge_cost = 450
/obj/item/weapon/gun/energy/altevian/large
name = "Proto-Reactive Beam Thruster"
@@ -23,7 +23,7 @@
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 4)
matter = list(MAT_STEEL = 2000)
projectile_type = /obj/item/projectile/beam/meeplaser/strong
charge_cost = 300
charge_cost = 200
/obj/item/projectile/beam/meeplaser
name = "meep beam"
@@ -297,7 +297,7 @@
var/syringestab_amount_transferred = rand(0, (reagents.total_volume - 5)) //nerfed by popular demand
var/syringestab_amount_transferred = rand(max(reagents.total_volume - 10, 0), (reagents.total_volume - 5)) //nerfed by popular demand
var/contained = reagents.get_reagents()
var/trans = reagents.trans_to_mob(target, syringestab_amount_transferred, CHEM_BLOOD)
if(isnull(trans)) trans = 0
@@ -63,7 +63,7 @@
/obj/item/weapon/reagent_containers/syringe/proc/infect_limb(var/obj/item/organ/external/eo)
src = null
var/weakref/limb_ref = weakref(eo)
var/datum/weakref/limb_ref = WEAKREF(eo)
spawn(rand(5 MINUTES,10 MINUTES))
var/obj/item/organ/external/found_limb = limb_ref.resolve()
if(istype(found_limb))
+7
View File
@@ -142,6 +142,8 @@
user.drop_item()
if(I)
if(istype(I, /obj/item/weapon/holder/micro))
log_and_message_admins("placed [I.name] inside \the [src]", user)
I.forceMove(src)
to_chat(user, "You place \the [I] into the [src].")
@@ -181,6 +183,7 @@
// must be awake, not stunned or whatever
msg = "[user.name] climbs into the [src]."
to_chat(user, "You climb into the [src].")
log_and_message_admins("climbed into disposals!", user)
else if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis)
msg = "[user.name] stuffs [target.name] into the [src]!"
to_chat(user, "You stuff [target.name] into the [src]!")
@@ -527,6 +530,8 @@
. = ..()
if(istype(AM, /obj/item) && !istype(AM, /obj/item/projectile))
if(prob(75))
if(istype(AM, /obj/item/weapon/holder/micro))
log_and_message_admins("[AM] was thrown into \the [src]")
AM.forceMove(src)
visible_message("\The [AM] lands in \the [src].")
else
@@ -541,6 +546,8 @@
return
if(prob(75))
I.forceMove(src)
if(istype(I, /obj/item/weapon/holder/micro))
log_and_message_admins("[I.name] was thrown into \the [src]")
for(var/mob/M in viewers(src))
M.show_message("\The [I] lands in \the [src].", 3)
else
+2 -2
View File
@@ -172,12 +172,12 @@
var/datum/language/keylang = GLOB.all_languages[ghost_client.prefs.language_custom_keys[key]]
if(keylang)
new_character.language_keys[key] = keylang
// CHOMPStation Add: Preferred Language Setting;
// VOREStation Add: Preferred Language Setting;
if(ghost_client.prefs.preferred_language) // Do we have a preferred language?
var/datum/language/def_lang = GLOB.all_languages[ghost_client.prefs.preferred_language]
if(def_lang)
new_character.default_language = def_lang
// CHOMPStation Add End
// VOREStation Add End
//If desired, apply equipment.
if(equip_body)
+2 -2
View File
@@ -28,7 +28,7 @@
potential_damage = (melee_damage_lower + melee_damage_upper) / 2
// Treat potential_damage as estimated DPS. If the enemy attacks twice as fast as usual, it will double the number.
potential_damage *= 1 SECOND / (base_attack_cooldown + melee_attack_delay + injury_level) // CHOMPStation Add: Injury level should affect potential damage, thereby increasing the threat level
potential_damage *= 1 SECOND / (base_attack_cooldown + melee_attack_delay + injury_level) // VOREStation Add: Injury level should affect potential damage, thereby increasing the threat level
else
var/obj/item/projectile/P = new projectiletype(src)
if(P.nodamage || P.taser_effect) // Tasers are somewhat less scary.
@@ -41,7 +41,7 @@
potential_damage += P.agony / 2
qdel(P)
potential_damage *= 1 SECOND / (base_attack_cooldown + ranged_attack_delay + injury_level) // CHOMPStation Add: Injury level should affect potential damage, thereby increasing the threat level
potential_damage *= 1 SECOND / (base_attack_cooldown + ranged_attack_delay + injury_level) // VOREStation Add: Injury level should affect potential damage, thereby increasing the threat level
// Special attacks are ultra-specific to the mob so a generic threat assessment isn't really possible.
+13 -13
View File
@@ -30,7 +30,7 @@
var/list/paired_map = list()
var/obj/item/modular_computer/mc_host = tgui_host()
if(istype(mc_host))
for(var/weakref/wr as anything in mc_host.paired_uavs)
for(var/datum/weakref/wr as anything in mc_host.paired_uavs)
var/obj/item/device/uav/U = wr.resolve()
paired_map.Add(list(list("name" = "[U ? U.nickname : "!!Missing!!"]", "uavref" = "\ref[U]")))
@@ -40,7 +40,7 @@
/datum/tgui_module/uav/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("switch_uav")
var/obj/item/device/uav/U = locate(params["switch_uav"]) //This is a \ref to the UAV itself
@@ -59,9 +59,9 @@
var/refstring = params["del_uav"] //This is a \ref to the UAV itself
var/obj/item/modular_computer/mc_host = tgui_host()
//This is so we can really scrape up any weakrefs that can't resolve
for(var/weakref/wr in mc_host.paired_uavs)
if(wr.ref == refstring)
if(current_uav?.weakref == wr)
for(var/datum/weakref/wr in mc_host.paired_uavs)
if(wr.reference == refstring)
if(current_uav?.weak_reference == wr)
set_current(null)
LAZYREMOVE(mc_host.paired_uavs, wr)
return TRUE
@@ -82,7 +82,7 @@
else if(current_uav.toggle_power())
//Clean up viewers faster
if(LAZYLEN(viewers))
for(var/weakref/W in viewers)
for(var/datum/weakref/W in viewers)
var/M = W.resolve()
if(M)
unlook(M)
@@ -97,7 +97,7 @@
RegisterSignal(U, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(current_uav_changed_z))
if(LAZYLEN(viewers))
for(var/weakref/W in viewers)
for(var/datum/weakref/W in viewers)
var/M = W.resolve()
if(M)
look(M)
@@ -111,7 +111,7 @@
current_uav = null
if(LAZYLEN(viewers))
for(var/weakref/W in viewers)
for(var/datum/weakref/W in viewers)
var/M = W.resolve()
if(M)
to_chat(M, "<span class='warning'>You're disconnected from the UAV's camera!</span>")
@@ -172,7 +172,7 @@
/* All handling viewers */
/datum/tgui_module/uav/Destroy()
if(LAZYLEN(viewers))
for(var/weakref/W in viewers)
for(var/datum/weakref/W in viewers)
var/M = W.resolve()
if(M)
unlook(M)
@@ -191,7 +191,7 @@
unlook(user)
/datum/tgui_module/uav/proc/viewing_uav(mob/user)
return (weakref(user) in viewers)
return (WEAKREF(user) in viewers)
/datum/tgui_module/uav/proc/look(mob/user)
if(issilicon(user)) //Too complicated for me to want to mess with at the moment
@@ -205,14 +205,14 @@
user.set_machine(tgui_host())
user.reset_view(current_uav)
current_uav.add_master(user)
LAZYDISTINCTADD(viewers, weakref(user))
LAZYDISTINCTADD(viewers, WEAKREF(user))
/datum/tgui_module/uav/proc/unlook(mob/user)
user.unset_machine()
user.reset_view()
if(current_uav)
current_uav.remove_master(user)
LAZYREMOVE(viewers, weakref(user))
LAZYREMOVE(viewers, WEAKREF(user))
/datum/tgui_module/uav/check_eye(mob/user)
if(get_dist(user, tgui_host()) > 1 || user.blinded || !current_uav)
@@ -239,7 +239,7 @@
/datum/tgui_module/uav/apply_visual(mob/M)
if(!M.client)
return
if(weakref(M) in viewers)
if(WEAKREF(M) in viewers)
M.overlay_fullscreen("fishbed",/obj/screen/fullscreen/fishbed)
M.overlay_fullscreen("scanlines",/obj/screen/fullscreen/scanline)
+5 -5
View File
@@ -11,7 +11,7 @@
/datum/tgui_module/ship/Destroy()
if(LAZYLEN(viewers))
for(var/weakref/W in viewers)
for(var/datum/weakref/W in viewers)
var/M = W.resolve()
if(M)
unlook(M)
@@ -56,16 +56,16 @@
user.reset_view(linked)
user.set_viewsize(world.view + extra_view)
GLOB.moved_event.register(user, src, /datum/tgui_module/ship/proc/unlook)
LAZYDISTINCTADD(viewers, weakref(user))
LAZYDISTINCTADD(viewers, WEAKREF(user))
/datum/tgui_module/ship/proc/unlook(var/mob/user)
user.reset_view()
user.set_viewsize() // reset to default
GLOB.moved_event.unregister(user, src, /datum/tgui_module/ship/proc/unlook)
LAZYREMOVE(viewers, weakref(user))
LAZYREMOVE(viewers, WEAKREF(user))
/datum/tgui_module/ship/proc/viewing_overmap(mob/user)
return (weakref(user) in viewers)
return (WEAKREF(user) in viewers)
/datum/tgui_module/ship/check_eye(var/mob/user)
if(!get_dist(user, tgui_host()) > 1 || user.blinded || !linked)
@@ -457,4 +457,4 @@
/datum/tgui_module/ship/fullmonty/attempt_hook_up_recursive()
return
/datum/tgui_module/ship/fullmonty/attempt_hook_up()
return
return
+2 -2
View File
@@ -166,12 +166,12 @@ Please do not abuse this ability.
var/datum/language/keylang = GLOB.all_languages[prey.prefs.language_custom_keys[key]]
if(keylang)
new_character.language_keys[key] = keylang
// CHOMPStation Add: Preferred Language Setting;
// VOREStation Add: Preferred Language Setting;
if(prey.prefs.preferred_language) // Do we have a preferred language?
var/datum/language/def_lang = GLOB.all_languages[prey.prefs.preferred_language]
if(def_lang)
new_character.default_language = def_lang
// CHOMPStation Add End
// VOREStation Add End
new_character.regenerate_icons()
+1 -5
View File
@@ -109,18 +109,14 @@
for(var/mob/living/L in living_mobs(0)) //add everyone on the tile to the do-not-eat list for a while
if(!(LAZYFIND(prey_excludes, L))) // Unless they're already on it, just to avoid fuckery.
LAZYSET(prey_excludes, L, world.time)
<<<<<<< HEAD
addtimer(CALLBACK(src, .proc/removeMobFromPreyExcludes, weakref(L)), 5 MINUTES)
=======
addtimer(CALLBACK(src, PROC_REF(removeMobFromPreyExcludes), WEAKREF(L)), 5 MINUTES)
>>>>>>> b6b3a1357c... Merge pull request #14976 from ItsSelis/selis-515compat
else if(istype(O, /obj/item/device/healthanalyzer))
var/healthpercent = health/maxHealth*100
to_chat(user, "<span class='notice'>[src] seems to be [healthpercent]% healthy.</span>")
else
..()
/mob/living/simple_mob/proc/removeMobFromPreyExcludes(weakref/target)
/mob/living/simple_mob/proc/removeMobFromPreyExcludes(datum/weakref/target)
if(isweakref(target))
var/mob/living/L = target.resolve()
LAZYREMOVE(prey_excludes, L) // It's fine to remove a null from the list if we couldn't resolve L
@@ -2529,4 +2529,118 @@ Departamental Swimsuits, for general use
icon_override = 'icons/vore/custom_onmob_vr.dmi'
item_state = "perrinrobes_s"
body_parts_covered = UPPER_TORSO|LOWER_TORSO
//Fuackwit422: Zera Livanne
/obj/item/clothing/suit/storage/toggle/labcoat/fluff/zera
name = "Zera's Labcloak"
desc = "Zera's custom-designed lab-coat and cloak hybrid. Designed to perfectly align with OSHA and NT's Health and Safety regulations, while also allowing her to completely ignore all that if she really wanted."
icon = 'icons/vore/custom_clothes_vr.dmi'
icon_state = "zera_labcloak"
icon_override = 'icons/vore/custom_clothes_vr.dmi'
item_state = "zera_labcloak"
/obj/item/clothing/suit/storage/toggle/labcoat/fluff/zera/toggle()
set name = "Toggle Coat Buttons"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
if(open == 1) //Will check whether icon state is currently set to the "open" or "closed" state and switch it around with a message to the user
open = 0
icon_state = initial(icon_state)
item_state = initial(item_state)
flags_inv = HIDETIE|HIDEHOLSTER
to_chat(usr, "You button up the coat.")
else if(open == 0)
open = 1
icon_state = "[icon_state]_open"
item_state = "[item_state]_open"
flags_inv = HIDEHOLSTER
to_chat(usr, "You unbutton the coat.")
else //in case some goofy admin switches icon states around without switching the icon_open or icon_closed
to_chat(usr, "You attempt to button-up the velcro on your [src], before promptly realising how silly you are.")
return
update_clothing_icon() //so our overlays update
/obj/item/clothing/head/welding/fluff/zera
name = "White Welding Mask"
desc = "It's a white welding mask. Zera likes it because it matches her labcoat."
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
icon = 'icons/vore/custom_clothes_vr.dmi'
icon_override = 'icons/vore/custom_clothes_vr.dmi'
icon_state = "zera_weld"
item_state = "zera_weld_onmob"
flags_inv = (HIDEEYES)
body_parts_covered = HEAD|EYES
/obj/item/clothing/head/welding/fluff/zera/toggle() //overriding this 'cause it only conceals the eyes - it's a hat, not a mask
set category = "Object"
set src in usr
if(usr.canmove && !usr.stat && !usr.restrained())
if(up)
up = !up
body_parts_covered |= (EYES)
flags_inv |= (HIDEEYES)
icon_state = "zera_weld"
item_state = "zera_weld_onmob"
to_chat(usr, "You flip the helmet down to protect your eyes.")
else
up = !up
body_parts_covered &= ~(EYES)
flags_inv &= ~(HIDEEYES)
icon_state = "zera_weld_up"
item_state = "zera_weld_up_onmob"
to_chat(usr, "You push the helmet up out of your face.")
update_clothing_icon() //so our mob-overlays
if (ismob(loc)) //should allow masks to update when it is opened/closed
var/mob/M = loc
M.update_inv_wear_mask()
usr.update_action_buttons()
/obj/item/clothing/suit/storage/toggle/labcoat/fluff/zeracloak
name = "Grand Purple Cloak"
desc = "Zera's custom-designed purple cloak. Nice and spooky, and the perfect length to hold up over your face with one hand like Count von Count."
icon = 'icons/vore/custom_clothes_vr.dmi'
icon_state = "grand_purple_cloak"
icon_override = 'icons/vore/custom_clothes_vr.dmi'
item_state = "grand_purple_cloak"
/obj/item/clothing/suit/storage/toggle/labcoat/fluff/zeracloak/toggle()
set name = "Toggle Coat Buttons"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
if(open == 1) //Will check whether icon state is currently set to the "open" or "closed" state and switch it around with a message to the user
open = 0
icon_state = initial(icon_state)
item_state = initial(item_state)
flags_inv = HIDETIE|HIDEHOLSTER
to_chat(usr, "You button up the coat.")
else if(open == 0)
open = 1
icon_state = "[icon_state]_open"
item_state = "[item_state]_open"
flags_inv = HIDEHOLSTER
to_chat(usr, "You unbutton the coat.")
else //in case some goofy admin switches icon states around without switching the icon_open or icon_closed
to_chat(usr, "You attempt to button-up the velcro on your [src], before promptly realising how silly you are.")
return
update_clothing_icon() //so our overlays update
/obj/item/clothing/head/fluff/zerahat
name = "Grand Purple Hat"
desc = "It's a pointy purple hat. Zera likes it because it matches her ominous purple cloak."
icon = 'icons/vore/custom_clothes_vr.dmi'
icon_override = 'icons/vore/custom_clothes_vr.dmi'
icon_state = "grand_purple_cloak_hat"
item_state = "grand_purple_cloak_hat_onmob"
End CHOMP Removal*/

Some files were not shown because too many files have changed in this diff Show More