mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-23 13:18:09 +01:00
Merge branch 'master' into upstream-merge-14976
This commit is contained in:
@@ -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
|
||||
@@ -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,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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
..()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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"
|
||||
*/
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+13
-8
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
|
||||
|
||||
@@ -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) )
|
||||
|
||||
@@ -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")
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user