Merge branch 'VOREStation:master' into master
@@ -93,6 +93,8 @@ What is the naming convention for planes or layers?
|
||||
#define BELOW_MOB_LAYER 3.9 // Should be converted to plane swaps
|
||||
#define ABOVE_MOB_LAYER 4.1 // Should be converted to plane swaps
|
||||
|
||||
#define ABOVE_MOB_PLANE -24
|
||||
|
||||
// Invisible things plane
|
||||
#define CLOAKED_PLANE -15
|
||||
|
||||
@@ -122,6 +124,7 @@ What is the naming convention for planes or layers?
|
||||
#define PLANE_PLANETLIGHTING 4 //Lighting on planets
|
||||
#define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives
|
||||
#define PLANE_LIGHTING_ABOVE 6 //For glowy eyes etc. that shouldn't be affected by darkness
|
||||
#define PLANE_RUNECHAT 7
|
||||
|
||||
#define PLANE_GHOSTS 10 //Spooooooooky ghooooooosts
|
||||
#define PLANE_AI_EYE 11 //The AI eye lives here
|
||||
|
||||
@@ -62,7 +62,8 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define INIT_ORDER_PLANETS 18
|
||||
#define INIT_ORDER_JOB 17
|
||||
#define INIT_ORDER_ALARM 16 // Must initialize before atoms.
|
||||
#define INIT_ORDER_ATOMS 15
|
||||
#define INIT_ORDER_TRANSCORE 15 // VOREStation Edit
|
||||
#define INIT_ORDER_ATOMS 14 // VOREStation Edit
|
||||
#define INIT_ORDER_MACHINES 10
|
||||
#define INIT_ORDER_SHUTTLES 3
|
||||
#define INIT_ORDER_TIMER 1
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#define TICKS2DS(T) ((T) TICKS) // Convert ticks to deciseconds
|
||||
#define DS2NEARESTTICK(DS) TICKS2DS(-round(-(DS2TICKS(DS))))
|
||||
|
||||
var/world_startup_time
|
||||
|
||||
/proc/get_game_time()
|
||||
var/global/time_offset = 0
|
||||
var/global/last_time = 0
|
||||
|
||||
@@ -66,12 +66,21 @@
|
||||
if(target)
|
||||
user.loc = get_turf(target)
|
||||
|
||||
/obj/machinery/gateway/centerstation/attack_ghost(mob/user as mob)
|
||||
if(awaygate)
|
||||
user.loc = awaygate.loc
|
||||
// VOREStation Edit Begin
|
||||
|
||||
/obj/machinery/gateway/centerstation/attack_ghost(mob/user as mob)
|
||||
if(awaygate)
|
||||
if(user.client.holder)
|
||||
user.loc = awaygate.loc
|
||||
else if(active)
|
||||
user.loc = awaygate.loc
|
||||
else
|
||||
return
|
||||
else
|
||||
to_chat(user, "[src] has no destination.")
|
||||
|
||||
// VOREStation Edit End
|
||||
|
||||
/obj/machinery/gateway/centeraway/attack_ghost(mob/user as mob)
|
||||
if(stationgate)
|
||||
user.loc = stationgate.loc
|
||||
|
||||
@@ -25,13 +25,10 @@ SUBSYSTEM_DEF(mobs)
|
||||
/datum/controller/subsystem/mobs/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = mob_list.Copy()
|
||||
process_z.Cut()
|
||||
process_z.len = GLOB.living_players_by_zlevel.len
|
||||
slept_mobs = 0
|
||||
var/level = 1
|
||||
while(process_z.len < GLOB.living_players_by_zlevel.len)
|
||||
process_z.len++
|
||||
for(var/level in 1 to process_z.len)
|
||||
process_z[level] = GLOB.living_players_by_zlevel[level].len
|
||||
level++
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
@@ -10,25 +10,34 @@ SUBSYSTEM_DEF(transcore)
|
||||
name = "Transcore"
|
||||
priority = 20
|
||||
wait = 3 MINUTES
|
||||
flags = SS_BACKGROUND|SS_NO_INIT
|
||||
flags = SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME
|
||||
init_order = INIT_ORDER_TRANSCORE
|
||||
|
||||
// THINGS
|
||||
var/overdue_time = 15 MINUTES
|
||||
var/core_dumped = FALSE // Core has been dumped! Also set can_fire = 0 when you set this.
|
||||
|
||||
var/current_step = SSTRANSCORE_IMPLANTS
|
||||
|
||||
var/cost_backups = 0
|
||||
var/cost_implants = 0
|
||||
|
||||
var/list/datum/transhuman/mind_record/backed_up = list() // All known mind records, indexed by MR.mindname/mind.name
|
||||
var/list/datum/transhuman/mind_record/has_left = list() // Why do we even have this?
|
||||
var/list/datum/transhuman/body_record/body_scans = list() // All known body records, indexed by BR.mydna.name
|
||||
var/list/obj/item/weapon/implant/backup/implants = list() // All OPERATING implants that are being ticked
|
||||
var/list/datum/transcore_db/databases = list() // Holds instances of each database
|
||||
var/datum/transcore_db/default_db // The default if no specific one is used
|
||||
|
||||
var/list/current_run = list()
|
||||
|
||||
/datum/controller/subsystem/transcore/Initialize()
|
||||
default_db = new()
|
||||
databases["default"] = default_db
|
||||
for(var/t in subtypesof(/datum/transcore_db))
|
||||
var/datum/transcore_db/db = new t()
|
||||
if(!db.key)
|
||||
warning("Instantiated transcore DB without a key: [t]")
|
||||
continue
|
||||
databases[db.key] = db
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/transcore/fire(resumed = 0)
|
||||
var/timer = TICK_USAGE
|
||||
|
||||
@@ -37,30 +46,36 @@ SUBSYSTEM_DEF(transcore)
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/process_implants(resumed = 0)
|
||||
if (!resumed)
|
||||
src.current_run = implants.Copy()
|
||||
// Create a flat list of every implant in every db with a value of the db they're in
|
||||
src.current_run.Cut()
|
||||
for(var/key in databases)
|
||||
var/datum/transcore_db/db = databases[key]
|
||||
for(var/obj/item/weapon/implant/backup/imp as anything in db.implants)
|
||||
src.current_run[imp] = db
|
||||
|
||||
var/list/current_run = src.current_run
|
||||
while(current_run.len)
|
||||
var/obj/item/weapon/implant/backup/imp = current_run[current_run.len]
|
||||
var/datum/transcore_db/db = current_run[imp]
|
||||
current_run.len--
|
||||
|
||||
//Remove if not in a human anymore.
|
||||
if(!imp || !isorgan(imp.loc))
|
||||
implants -= imp
|
||||
db.implants -= imp
|
||||
continue
|
||||
|
||||
//We're in an organ, at least.
|
||||
var/obj/item/organ/external/EO = imp.loc
|
||||
var/mob/living/carbon/human/H = EO.owner
|
||||
if(!H)
|
||||
implants -= imp
|
||||
db.implants -= imp
|
||||
continue
|
||||
|
||||
//In a human
|
||||
BITSET(H.hud_updateflag, BACKUP_HUD)
|
||||
|
||||
if(H == imp.imp_in && H.mind && H.stat < DEAD)
|
||||
SStranscore.m_backup(H.mind,H.nif)
|
||||
db.m_backup(H.mind,H.nif)
|
||||
persist_nif_data(H)
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
@@ -68,18 +83,24 @@ SUBSYSTEM_DEF(transcore)
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/process_backups(resumed = 0)
|
||||
if (!resumed)
|
||||
src.current_run = backed_up.Copy()
|
||||
// Create a flat list of every implant in every db with a value of the db they're in
|
||||
src.current_run.Cut()
|
||||
for(var/key in databases)
|
||||
var/datum/transcore_db/db = databases[key]
|
||||
for(var/name in db.backed_up)
|
||||
var/datum/transhuman/mind_record/mr = db.backed_up[name]
|
||||
src.current_run[mr] = db
|
||||
|
||||
var/list/current_run = src.current_run
|
||||
while(current_run.len)
|
||||
var/name = current_run[current_run.len]
|
||||
var/datum/transhuman/mind_record/curr_MR = current_run[name]
|
||||
current_run -= name
|
||||
var/datum/transhuman/mind_record/curr_MR = current_run[current_run.len]
|
||||
var/datum/transcore_db/db = current_run[curr_MR]
|
||||
current_run.len--
|
||||
|
||||
//Invalid record
|
||||
if(!curr_MR)
|
||||
log_debug("Tried to process [name] in transcore w/o a record!")
|
||||
backed_up -= name
|
||||
db.backed_up -= curr_MR.mindname
|
||||
continue
|
||||
|
||||
//Onetimes do not get processing or notifications
|
||||
@@ -92,7 +113,7 @@ SUBSYSTEM_DEF(transcore)
|
||||
curr_MR.dead_state = MR_NORMAL
|
||||
else
|
||||
if(curr_MR.dead_state != MR_DEAD) //First time switching to dead
|
||||
notify(name)
|
||||
db.notify(curr_MR.mindname)
|
||||
curr_MR.last_notification = world.time
|
||||
curr_MR.dead_state = MR_DEAD
|
||||
|
||||
@@ -101,30 +122,100 @@ SUBSYSTEM_DEF(transcore)
|
||||
|
||||
/datum/controller/subsystem/transcore/stat_entry()
|
||||
var/msg = list()
|
||||
if(core_dumped)
|
||||
msg += "CORE DUMPED | "
|
||||
msg += "$:{"
|
||||
msg += "IM:[round(cost_implants,1)]|"
|
||||
msg += "BK:[round(cost_backups,1)]"
|
||||
msg += "} "
|
||||
msg += "#:{"
|
||||
msg += "IM:[implants.len]|"
|
||||
msg += "BK:[backed_up.len]"
|
||||
msg += "DB:[databases.len]|"
|
||||
if(!default_db)
|
||||
msg += "DEFAULT DB MISSING"
|
||||
else
|
||||
msg += "DFM:[default_db.backed_up.len]|"
|
||||
msg += "DFB:[default_db.body_scans.len]|"
|
||||
msg += "DFI:[default_db.implants.len]"
|
||||
msg += "} "
|
||||
..(jointext(msg, null))
|
||||
|
||||
/datum/controller/subsystem/transcore/Recover()
|
||||
if (istype(SStranscore.body_scans))
|
||||
for(var/N in SStranscore.body_scans)
|
||||
if(N && SStranscore.body_scans[N]) body_scans[N] = SStranscore.body_scans[N]
|
||||
if(SStranscore.core_dumped)
|
||||
core_dumped = TRUE
|
||||
can_fire = FALSE
|
||||
else if (istype(SStranscore.backed_up))
|
||||
for(var/N in SStranscore.backed_up)
|
||||
if(N && SStranscore.backed_up[N]) backed_up[N] = SStranscore.backed_up[N]
|
||||
for(var/key in SStranscore.databases)
|
||||
if(!SStranscore.databases[key])
|
||||
warning("SStranscore recovery found missing database value for key: [key]")
|
||||
continue
|
||||
if(key == "default")
|
||||
default_db = SStranscore.databases[key]
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/m_backup(var/datum/mind/mind, var/obj/item/device/nif/nif, var/one_time = FALSE)
|
||||
databases[key] = SStranscore.databases[key]
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/leave_round(var/mob/M)
|
||||
if(!istype(M))
|
||||
warning("Non-mob asked to be removed from transcore: [M] [M?.type]")
|
||||
return
|
||||
if(!M.mind)
|
||||
warning("No mind mob asked to be removed from transcore: [M] [M?.type]")
|
||||
return
|
||||
|
||||
for(var/key in databases)
|
||||
var/datum/transcore_db/db = databases[key]
|
||||
if(M.mind.name in db.backed_up)
|
||||
var/datum/transhuman/mind_record/MR = db.backed_up[M.mind.name]
|
||||
db.stop_backup(MR)
|
||||
if(M.mind.name in db.body_scans) //This uses mind names to avoid people cryo'ing a printed body to delete body scans.
|
||||
var/datum/transhuman/body_record/BR = db.body_scans[M.mind.name]
|
||||
db.remove_body(BR)
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/db_by_key(var/key)
|
||||
if(isnull(key))
|
||||
return default_db
|
||||
if(!databases[key])
|
||||
warning("Tried to find invalid transcore database: [key]")
|
||||
return default_db
|
||||
return databases[key]
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/db_by_mind_name(var/name)
|
||||
if(isnull(name))
|
||||
return null
|
||||
for(var/key in databases)
|
||||
var/datum/transcore_db/db = databases[key]
|
||||
if(name in db.backed_up)
|
||||
return db
|
||||
|
||||
// These are now just interfaces to databases
|
||||
/datum/controller/subsystem/transcore/proc/m_backup(var/datum/mind/mind, var/obj/item/device/nif/nif, var/one_time = FALSE, var/database_key)
|
||||
var/datum/transcore_db/db = db_by_key(database_key)
|
||||
db.m_backup(mind=mind, nif=nif, one_time=one_time)
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/add_backup(var/datum/transhuman/mind_record/MR, var/database_key)
|
||||
var/datum/transcore_db/db = db_by_key(database_key)
|
||||
db.add_backup(MR=MR)
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/stop_backup(var/datum/transhuman/mind_record/MR, var/database_key)
|
||||
var/datum/transcore_db/db = db_by_key(database_key)
|
||||
db.stop_backup(MR=MR)
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/add_body(var/datum/transhuman/body_record/BR, var/database_key)
|
||||
var/datum/transcore_db/db = db_by_key(database_key)
|
||||
db.add_body(BR=BR)
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/remove_body(var/datum/transhuman/body_record/BR, var/database_key)
|
||||
var/datum/transcore_db/db = db_by_key(database_key)
|
||||
db.remove_body(BR=BR)
|
||||
|
||||
/datum/controller/subsystem/transcore/proc/core_dump(var/obj/item/weapon/disk/transcore/disk, var/database_key)
|
||||
var/datum/transcore_db/db = db_by_key(database_key)
|
||||
db.core_dump(disk=disk)
|
||||
|
||||
|
||||
/datum/transcore_db
|
||||
var/list/datum/transhuman/mind_record/backed_up = list() // All known mind records, indexed by MR.mindname/mind.name
|
||||
var/list/datum/transhuman/mind_record/has_left = list() // Why do we even have this?
|
||||
var/list/datum/transhuman/body_record/body_scans = list() // All known body records, indexed by BR.mydna.name
|
||||
var/list/obj/item/weapon/implant/backup/implants = list() // All OPERATING implants that are being ticked
|
||||
|
||||
var/core_dumped = FALSE
|
||||
var/key // Key for this DB
|
||||
|
||||
/datum/transcore_db/proc/m_backup(var/datum/mind/mind, var/obj/item/device/nif/nif, var/one_time = FALSE)
|
||||
ASSERT(mind)
|
||||
if(!mind.name || core_dumped)
|
||||
return 0
|
||||
@@ -154,12 +245,12 @@ SUBSYSTEM_DEF(transcore)
|
||||
MR.nif_savedata = null
|
||||
|
||||
else
|
||||
MR = new(mind, mind.current, add_to_db = TRUE, one_time = one_time)
|
||||
MR = new(mind, mind.current, add_to_db = TRUE, one_time = one_time, database_key = src.key)
|
||||
|
||||
return 1
|
||||
|
||||
// Send a past-due notification to the medical radio channel.
|
||||
/datum/controller/subsystem/transcore/proc/notify(var/name, var/repeated = FALSE)
|
||||
/datum/transcore_db/proc/notify(var/name, var/repeated = FALSE)
|
||||
ASSERT(name)
|
||||
if(repeated)
|
||||
global_announcer.autosay("This is a repeat notification that [name] is past-due for a mind backup.", "TransCore Oversight", "Medical")
|
||||
@@ -167,14 +258,14 @@ SUBSYSTEM_DEF(transcore)
|
||||
global_announcer.autosay("[name] is past-due for a mind backup.", "TransCore Oversight", "Medical")
|
||||
|
||||
// Called from mind_record to add itself to the transcore.
|
||||
/datum/controller/subsystem/transcore/proc/add_backup(var/datum/transhuman/mind_record/MR)
|
||||
/datum/transcore_db/proc/add_backup(var/datum/transhuman/mind_record/MR)
|
||||
ASSERT(MR)
|
||||
backed_up[MR.mindname] = MR
|
||||
backed_up = sortAssoc(backed_up)
|
||||
log_debug("Added [MR.mindname] to transcore DB.")
|
||||
|
||||
// Remove a mind_record from the backup-checking list. Keeps track of it in has_left // Why do we do that? ~Leshana
|
||||
/datum/controller/subsystem/transcore/proc/stop_backup(var/datum/transhuman/mind_record/MR)
|
||||
/datum/transcore_db/proc/stop_backup(var/datum/transhuman/mind_record/MR)
|
||||
ASSERT(MR)
|
||||
has_left[MR.mindname] = MR
|
||||
backed_up.Remove("[MR.mindname]")
|
||||
@@ -182,20 +273,20 @@ SUBSYSTEM_DEF(transcore)
|
||||
log_debug("Put [MR.mindname] in transcore suspended DB.")
|
||||
|
||||
// Called from body_record to add itself to the transcore.
|
||||
/datum/controller/subsystem/transcore/proc/add_body(var/datum/transhuman/body_record/BR)
|
||||
/datum/transcore_db/proc/add_body(var/datum/transhuman/body_record/BR)
|
||||
ASSERT(BR)
|
||||
body_scans[BR.mydna.name] = BR
|
||||
body_scans = sortAssoc(body_scans)
|
||||
log_debug("Added [BR.mydna.name] to transcore body DB.")
|
||||
|
||||
// Remove a body record from the database (Usually done when someone cryos) // Why? ~Leshana
|
||||
/datum/controller/subsystem/transcore/proc/remove_body(var/datum/transhuman/body_record/BR)
|
||||
/datum/transcore_db/proc/remove_body(var/datum/transhuman/body_record/BR)
|
||||
ASSERT(BR)
|
||||
body_scans.Remove("[BR.mydna.name]")
|
||||
log_debug("Removed [BR.mydna.name] from transcore body DB.")
|
||||
|
||||
// Moves all mind records from the databaes into the disk and shuts down all backup canary processing.
|
||||
/datum/controller/subsystem/transcore/proc/core_dump(var/obj/item/weapon/disk/transcore/disk)
|
||||
/datum/transcore_db/proc/core_dump(var/obj/item/weapon/disk/transcore/disk)
|
||||
ASSERT(disk)
|
||||
global_announcer.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Command")
|
||||
global_announcer.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Medical")
|
||||
@@ -203,7 +294,6 @@ SUBSYSTEM_DEF(transcore)
|
||||
disk.stored += backed_up
|
||||
backed_up.Cut()
|
||||
core_dumped = TRUE
|
||||
can_fire = FALSE
|
||||
return disk.stored.len
|
||||
|
||||
#undef SSTRANSCORE_BACKUPS
|
||||
|
||||
@@ -0,0 +1,334 @@
|
||||
#define CHAT_MESSAGE_SPAWN_TIME 0.2 SECONDS
|
||||
#define CHAT_MESSAGE_LIFESPAN 5 SECONDS
|
||||
#define CHAT_MESSAGE_EOL_FADE 0.7 SECONDS
|
||||
#define CHAT_MESSAGE_EXP_DECAY 0.8 // Messages decay at pow(factor, idx in stack)
|
||||
#define CHAT_MESSAGE_HEIGHT_DECAY 0.7 // Increase message decay based on the height of the message
|
||||
#define CHAT_MESSAGE_APPROX_LHEIGHT 11 // Approximate height in pixels of an 'average' line, used for height decay
|
||||
|
||||
#define CHAT_MESSAGE_WIDTH 96 // pixels
|
||||
#define CHAT_MESSAGE_EXT_WIDTH 128
|
||||
#define CHAT_MESSAGE_LENGTH 68 // characters
|
||||
#define CHAT_MESSAGE_EXT_LENGTH 150
|
||||
|
||||
#define CHAT_MESSAGE_MOB 1
|
||||
#define CHAT_MESSAGE_OBJ 2
|
||||
#define WXH_TO_HEIGHT(x) text2num(copytext((x), findtextEx((x), "x") + 1)) // thanks lummox
|
||||
|
||||
#define CHAT_RUNE_EMOTE 0x1
|
||||
#define CHAT_RUNE_RADIO 0x2
|
||||
|
||||
/**
|
||||
* # Chat Message Overlay
|
||||
*
|
||||
* Datum for generating a message overlay on the map
|
||||
* Ported from TGStation; https://github.com/tgstation/tgstation/pull/50608/, author: bobbahbrown
|
||||
*/
|
||||
|
||||
// Cached runechat icon
|
||||
var/list/runechat_image_cache = list()
|
||||
|
||||
|
||||
/hook/startup/proc/runechat_images()
|
||||
var/image/radio_image = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "radio")
|
||||
runechat_image_cache["radio"] = radio_image
|
||||
|
||||
var/image/emote_image = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "emote")
|
||||
runechat_image_cache["emote"] = emote_image
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/chatmessage
|
||||
/// The visual element of the chat messsage
|
||||
var/image/message
|
||||
/// The location in which the message is appearing
|
||||
var/atom/message_loc
|
||||
/// The client who heard this message
|
||||
var/client/owned_by
|
||||
/// Contains the scheduled destruction time
|
||||
var/scheduled_destruction
|
||||
/// Contains the approximate amount of lines for height decay
|
||||
var/approx_lines
|
||||
/// If we are currently processing animation and cleanup at EOL
|
||||
var/ending_life
|
||||
|
||||
/**
|
||||
* Constructs a chat message overlay
|
||||
*
|
||||
* Arguments:
|
||||
* * text - The text content of the overlay
|
||||
* * target - The target atom to display the overlay at
|
||||
* * owner - The mob that owns this overlay, only this mob will be able to view it
|
||||
* * extra_classes - Extra classes to apply to the span that holds the text
|
||||
* * lifespan - The lifespan of the message in deciseconds
|
||||
*/
|
||||
/datum/chatmessage/New(text, atom/target, mob/owner, list/extra_classes = null, lifespan = CHAT_MESSAGE_LIFESPAN)
|
||||
. = ..()
|
||||
if(!istype(target))
|
||||
CRASH("Invalid target given for chatmessage")
|
||||
if(!istype(owner) || QDELETED(owner) || !owner.client)
|
||||
stack_trace("/datum/chatmessage created with [isnull(owner) ? "null" : "invalid"] mob owner")
|
||||
qdel(src)
|
||||
return
|
||||
generate_image(text, target, owner, extra_classes, lifespan)
|
||||
|
||||
/datum/chatmessage/Destroy()
|
||||
if(owned_by)
|
||||
UnregisterSignal(owned_by, COMSIG_PARENT_QDELETING)
|
||||
LAZYREMOVEASSOC(owned_by.seen_messages, message_loc, src)
|
||||
owned_by.images.Remove(message)
|
||||
if(message_loc)
|
||||
UnregisterSignal(message_loc, COMSIG_PARENT_QDELETING)
|
||||
owned_by = null
|
||||
message_loc = null
|
||||
message = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Generates a chat message image representation
|
||||
*
|
||||
* Arguments:
|
||||
* * text - The text content of the overlay
|
||||
* * target - The target atom to display the overlay at
|
||||
* * owner - The mob that owns this overlay, only this mob will be able to view it
|
||||
* * extra_classes - Extra classes to apply to the span that holds the text
|
||||
* * lifespan - The lifespan of the message in deciseconds
|
||||
*/
|
||||
/datum/chatmessage/proc/generate_image(text, atom/target, mob/owner, list/extra_classes, lifespan)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(!target || !owner)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// Register client who owns this message
|
||||
owned_by = owner.client
|
||||
RegisterSignal(owned_by, COMSIG_PARENT_QDELETING, .proc/qdel_self)
|
||||
|
||||
var/extra_length = owned_by.is_preference_enabled(/datum/client_preference/runechat_long_messages)
|
||||
var/maxlen = extra_length ? CHAT_MESSAGE_EXT_LENGTH : CHAT_MESSAGE_LENGTH
|
||||
var/msgwidth = extra_length ? CHAT_MESSAGE_EXT_WIDTH : CHAT_MESSAGE_WIDTH
|
||||
|
||||
// Clip message
|
||||
if(length_char(text) > maxlen)
|
||||
text = copytext_char(text, 1, maxlen + 1) + "..." // BYOND index moment
|
||||
|
||||
// Calculate target color if not already present
|
||||
if(!target.chat_color || target.chat_color_name != target.name)
|
||||
target.chat_color = colorize_string(target.name)
|
||||
target.chat_color_darkened = colorize_string(target.name, 0.85, 0.85)
|
||||
target.chat_color_name = target.name
|
||||
|
||||
// Get rid of any URL schemes that might cause BYOND to automatically wrap something in an anchor tag
|
||||
var/static/regex/url_scheme = new(@"[A-Za-z][A-Za-z0-9+-\.]*:\/\/", "g")
|
||||
text = replacetext(text, url_scheme, "")
|
||||
|
||||
// Reject whitespace
|
||||
var/static/regex/whitespace = new(@"^\s*$")
|
||||
if(whitespace.Find(text))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// Non mobs speakers can be small
|
||||
if(!ismob(target))
|
||||
extra_classes |= "small"
|
||||
|
||||
// If we heard our name, it's important
|
||||
// Differnt from our own system of name emphasis, maybe unify
|
||||
var/list/names = splittext(owner.name, " ")
|
||||
for (var/word in names)
|
||||
text = replacetext(text, word, "<b>[word]</b>")
|
||||
|
||||
var/list/prefixes
|
||||
|
||||
// Append prefixes
|
||||
if(extra_classes.Find("virtual-speaker"))
|
||||
LAZYADD(prefixes, "\icon[runechat_image_cache["radio"]]")
|
||||
if(extra_classes.Find("emote"))
|
||||
// Icon on both ends?
|
||||
//var/image/I = runechat_image_cache["emote"]
|
||||
//text = "\icon[I][text]\icon[I]"
|
||||
|
||||
// Icon on one end?
|
||||
//LAZYADD(prefixes, "\icon[runechat_image_cache["emote"]]")
|
||||
|
||||
// Asterisks instead?
|
||||
text = "* [text] *"
|
||||
|
||||
text = "[prefixes?.Join(" ")][text]"
|
||||
|
||||
// We dim italicized text to make it more distinguishable from regular text
|
||||
var/tgt_color = extra_classes.Find("italics") ? target.chat_color_darkened : target.chat_color
|
||||
|
||||
// Approximate text height
|
||||
var/complete_text = "<span class='center maptext [extra_classes != null ? extra_classes.Join(" ") : ""]' style='color: [tgt_color];'>[text]</span>"
|
||||
var/mheight = WXH_TO_HEIGHT(owned_by.MeasureText(complete_text, null, msgwidth))
|
||||
approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT)
|
||||
|
||||
// Translate any existing messages upwards, apply exponential decay factors to timers
|
||||
message_loc = target
|
||||
RegisterSignal(message_loc, COMSIG_PARENT_QDELETING, .proc/qdel_self)
|
||||
if(owned_by.seen_messages)
|
||||
var/idx = 1
|
||||
var/combined_height = approx_lines
|
||||
for(var/msg in owned_by.seen_messages[message_loc])
|
||||
var/datum/chatmessage/m = msg
|
||||
animate(m.message, pixel_y = m.message.pixel_y + mheight, time = CHAT_MESSAGE_SPAWN_TIME)
|
||||
combined_height += m.approx_lines
|
||||
|
||||
if(!m.ending_life) // Don't bother!
|
||||
var/sched_remaining = m.scheduled_destruction - world.time
|
||||
if(sched_remaining > CHAT_MESSAGE_SPAWN_TIME)
|
||||
var/remaining_time = (sched_remaining) * (CHAT_MESSAGE_EXP_DECAY ** idx++) * (CHAT_MESSAGE_HEIGHT_DECAY ** combined_height)
|
||||
m.scheduled_destruction = world.time + remaining_time
|
||||
spawn(remaining_time)
|
||||
m.end_of_life()
|
||||
|
||||
// Build message image
|
||||
message = image(loc = message_loc, layer = ABOVE_MOB_LAYER)
|
||||
message.plane = PLANE_RUNECHAT
|
||||
message.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART
|
||||
message.alpha = 0
|
||||
message.pixel_y = (owner.bound_height * 0.95)*owner.size_multiplier
|
||||
message.maptext_width = msgwidth
|
||||
message.maptext_height = mheight
|
||||
message.maptext_x = (msgwidth - owner.bound_width) * -0.5
|
||||
message.maptext = complete_text
|
||||
|
||||
if(owner.contains(target)) // Special case, holding an atom speaking (pAI, recorder...)
|
||||
message.plane = PLANE_PLAYER_HUD_ABOVE
|
||||
|
||||
// View the message
|
||||
LAZYADDASSOCLIST(owned_by.seen_messages, message_loc, src)
|
||||
owned_by.images += message
|
||||
animate(message, alpha = 255, time = CHAT_MESSAGE_SPAWN_TIME)
|
||||
|
||||
// Prepare for destruction
|
||||
scheduled_destruction = world.time + (lifespan - CHAT_MESSAGE_EOL_FADE)
|
||||
spawn(lifespan - CHAT_MESSAGE_EOL_FADE)
|
||||
end_of_life()
|
||||
|
||||
/**
|
||||
* Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion
|
||||
*/
|
||||
/datum/chatmessage/proc/end_of_life(fadetime = CHAT_MESSAGE_EOL_FADE)
|
||||
if(gc_destroyed || ending_life)
|
||||
return
|
||||
ending_life = TRUE
|
||||
animate(message, alpha = 0, time = fadetime, flags = ANIMATION_PARALLEL)
|
||||
spawn(fadetime)
|
||||
qdel(src)
|
||||
|
||||
/**
|
||||
* Creates a message overlay at a defined location for a given speaker
|
||||
*
|
||||
* Arguments:
|
||||
* * speaker - The atom who is saying this message
|
||||
* * message - The text content of the message
|
||||
* * italics - Decides if this should be small or not, as generally italics text are for whisper/radio overhear
|
||||
* * existing_extra_classes - Additional classes to add to the message
|
||||
*/
|
||||
/mob/proc/create_chat_message(atom/movable/speaker, message, italics, list/existing_extra_classes, audible = TRUE)
|
||||
if(!client)
|
||||
return
|
||||
|
||||
// Doesn't want to hear
|
||||
if(ismob(speaker) && !client.is_preference_enabled(/datum/client_preference/runechat_mob))
|
||||
return
|
||||
else if(isobj(speaker) && !client.is_preference_enabled(/datum/client_preference/runechat_obj))
|
||||
return
|
||||
|
||||
// Incapable of receiving
|
||||
if((audible && is_deaf()) || (!audible && is_blind()))
|
||||
return
|
||||
|
||||
// Check for virtual speakers (aka hearing a message through a radio)
|
||||
if(existing_extra_classes.Find("radio"))
|
||||
return
|
||||
|
||||
/* Not currently necessary
|
||||
message = strip_html_properly(message)
|
||||
if(!message)
|
||||
return
|
||||
*/
|
||||
|
||||
var/list/extra_classes = list()
|
||||
extra_classes += existing_extra_classes
|
||||
|
||||
if(italics)
|
||||
extra_classes |= "italics"
|
||||
|
||||
if(client.is_preference_enabled(/datum/client_preference/runechat_border))
|
||||
extra_classes |= "black_outline"
|
||||
|
||||
var/dist = get_dist(src, speaker)
|
||||
switch (dist)
|
||||
if(4 to 5)
|
||||
extra_classes |= "small"
|
||||
if(5 to 16)
|
||||
extra_classes |= "very_small"
|
||||
|
||||
// Display visual above source
|
||||
new /datum/chatmessage(message, speaker, src, extra_classes)
|
||||
|
||||
// Tweak these defines to change the available color ranges
|
||||
#define CM_COLOR_SAT_MIN 0.6
|
||||
#define CM_COLOR_SAT_MAX 0.95
|
||||
#define CM_COLOR_LUM_MIN 0.70
|
||||
#define CM_COLOR_LUM_MAX 0.90
|
||||
|
||||
/**
|
||||
* Gets a color for a name, will return the same color for a given string consistently within a round.atom
|
||||
*
|
||||
* Note that this proc aims to produce pastel-ish colors using the HSL colorspace. These seem to be favorable for displaying on the map.
|
||||
*
|
||||
* Arguments:
|
||||
* * name - The name to generate a color for
|
||||
* * sat_shift - A value between 0 and 1 that will be multiplied against the saturation
|
||||
* * lum_shift - A value between 0 and 1 that will be multiplied against the luminescence
|
||||
*/
|
||||
/datum/chatmessage/proc/colorize_string(name, sat_shift = 1, lum_shift = 1)
|
||||
// seed to help randomness
|
||||
var/static/rseed = rand(1,26)
|
||||
|
||||
// get hsl using the selected 6 characters of the md5 hash
|
||||
var/hash = copytext(md5(name + "[world_startup_time]"), rseed, rseed + 6)
|
||||
var/h = hex2num(copytext(hash, 1, 3)) * (360 / 255)
|
||||
var/s = (hex2num(copytext(hash, 3, 5)) >> 2) * ((CM_COLOR_SAT_MAX - CM_COLOR_SAT_MIN) / 63) + CM_COLOR_SAT_MIN
|
||||
var/l = (hex2num(copytext(hash, 5, 7)) >> 2) * ((CM_COLOR_LUM_MAX - CM_COLOR_LUM_MIN) / 63) + CM_COLOR_LUM_MIN
|
||||
|
||||
// adjust for shifts
|
||||
s *= clamp(sat_shift, 0, 1)
|
||||
l *= clamp(lum_shift, 0, 1)
|
||||
|
||||
// convert to rgba
|
||||
var/h_int = round(h/60) // mapping each section of H to 60 degree sections
|
||||
var/c = (1 - abs(2 * l - 1)) * s
|
||||
var/x = c * (1 - abs((h / 60) % 2 - 1))
|
||||
var/m = l - c * 0.5
|
||||
x = (x + m) * 255
|
||||
c = (c + m) * 255
|
||||
m *= 255
|
||||
switch(h_int)
|
||||
if(0)
|
||||
return rgb(c,x,m)
|
||||
if(1)
|
||||
return rgb(x,c,m)
|
||||
if(2)
|
||||
return rgb(m,c,x)
|
||||
if(3)
|
||||
return rgb(m,x,c)
|
||||
if(4)
|
||||
return rgb(x,m,c)
|
||||
if(5)
|
||||
return rgb(c,m,x)
|
||||
|
||||
/atom/proc/runechat_message(message, range = world.view, italics, list/classes = list(), audible = TRUE)
|
||||
var/list/hear = get_mobs_and_objs_in_view_fast(get_turf(src), range, remote_ghosts = FALSE)
|
||||
|
||||
var/list/hearing_mobs = hear["mobs"]
|
||||
|
||||
for(var/mob in hearing_mobs)
|
||||
var/mob/M = mob
|
||||
if(!M.client)
|
||||
continue
|
||||
M.create_chat_message(src, message, italics, classes, audible)
|
||||
@@ -213,10 +213,10 @@
|
||||
*
|
||||
* Arguments:
|
||||
* * datum/target Datum to stop listening to signals from
|
||||
* * sig_typeor_types Signal string key or list of signal keys to stop listening to specifically
|
||||
* * sig_type_or_types Signal string key or list of signal keys to stop listening to specifically
|
||||
*/
|
||||
/datum/proc/UnregisterSignal(datum/target, sig_type_or_types)
|
||||
var/list/lookup = target.comp_lookup
|
||||
var/list/lookup = target?.comp_lookup
|
||||
if(!signal_procs || !signal_procs[target] || !lookup)
|
||||
return
|
||||
if(!islist(sig_type_or_types))
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
/decl/hierarchy/outfit/job/security/detective/forensic
|
||||
name = OUTFIT_JOB_NAME("Forensic technician")
|
||||
head = null
|
||||
suit = /datum/gear/uniform/detective_alt2
|
||||
suit = /obj/item/clothing/suit/storage/det_trench/alt2
|
||||
uniform = /obj/item/clothing/under/det
|
||||
//VOREStation Edit End
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2,
|
||||
)
|
||||
cost = 40
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure/aether
|
||||
containername = "Atmospheric voidsuit crate"
|
||||
access = access_atmospherics
|
||||
@@ -30,7 +30,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2,
|
||||
)
|
||||
cost = 50
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate/secure/aether
|
||||
containername = "Heavy Duty Atmospheric voidsuit crate"
|
||||
access = access_atmospherics
|
||||
@@ -44,7 +44,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 40
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure/xion
|
||||
containername = "Engineering voidsuit crate"
|
||||
access = access_engine_equip
|
||||
@@ -58,7 +58,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 40
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure/xion
|
||||
containername = "Engineering Construction voidsuit crate"
|
||||
access = access_engine_equip
|
||||
@@ -72,7 +72,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 45
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure/xion
|
||||
containername = "Engineering Hazmat voidsuit crate"
|
||||
access = access_engine_equip
|
||||
@@ -86,7 +86,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 50
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate/secure/xion
|
||||
containername = "Reinforced Engineering voidsuit crate"
|
||||
access = access_engine_equip
|
||||
@@ -100,7 +100,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 40
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure/veymed
|
||||
containername = "Medical voidsuit crate"
|
||||
access = access_medical_equip
|
||||
@@ -114,7 +114,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 40
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure/veymed
|
||||
containername = "Medical EMT voidsuit crate"
|
||||
access = access_medical_equip
|
||||
@@ -128,7 +128,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 45
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure/nanomed
|
||||
containername = "Medical Biohazard voidsuit crate"
|
||||
access = access_medical_equip
|
||||
@@ -167,7 +167,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 40
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure/heph
|
||||
containername = "Security voidsuit crate"
|
||||
|
||||
@@ -207,7 +207,7 @@
|
||||
/obj/item/clothing/mask/breath = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 40
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure/xion
|
||||
containername = "Mining voidsuit crate"
|
||||
access = access_mining
|
||||
@@ -220,7 +220,7 @@
|
||||
/obj/item/clothing/mask/breath = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 50
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate/secure/grayson
|
||||
containername = "Frontier Mining voidsuit crate"
|
||||
access = access_mining
|
||||
|
||||
@@ -1,84 +1,13 @@
|
||||
/datum/supply_pack/voidsuits/atmos
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/space/void/atmos = 3,
|
||||
/obj/item/clothing/head/helmet/space/void/atmos = 3,
|
||||
/obj/item/clothing/mask/breath = 3,
|
||||
/obj/item/clothing/shoes/magboots = 3,
|
||||
/obj/item/weapon/tank/oxygen = 3,
|
||||
)
|
||||
|
||||
/datum/supply_pack/voidsuits/engineering
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/space/void/engineering = 3,
|
||||
/obj/item/clothing/head/helmet/space/void/engineering = 3,
|
||||
/obj/item/clothing/mask/breath = 3,
|
||||
/obj/item/clothing/shoes/magboots = 3,
|
||||
/obj/item/weapon/tank/oxygen = 3
|
||||
)
|
||||
|
||||
/datum/supply_pack/voidsuits/medical
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/space/void/medical = 3,
|
||||
/obj/item/clothing/head/helmet/space/void/medical = 3,
|
||||
/obj/item/clothing/mask/breath = 3,
|
||||
/obj/item/clothing/shoes/magboots = 3,
|
||||
/obj/item/weapon/tank/oxygen = 3
|
||||
)
|
||||
|
||||
/datum/supply_pack/voidsuits/medical/alt
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/space/void/medical/alt = 3,
|
||||
/obj/item/clothing/head/helmet/space/void/medical/alt = 3,
|
||||
/obj/item/clothing/mask/breath = 3,
|
||||
/obj/item/clothing/shoes/magboots = 3,
|
||||
/obj/item/weapon/tank/oxygen = 3
|
||||
)
|
||||
|
||||
/datum/supply_pack/voidsuits/security
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/space/void/security = 3,
|
||||
/obj/item/clothing/head/helmet/space/void/security = 3,
|
||||
/obj/item/clothing/mask/breath = 3,
|
||||
/obj/item/clothing/shoes/magboots = 3,
|
||||
/obj/item/weapon/tank/oxygen = 3
|
||||
)
|
||||
|
||||
/datum/supply_pack/voidsuits/security/crowd
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/space/void/security/riot = 3,
|
||||
/obj/item/clothing/head/helmet/space/void/security/riot = 3,
|
||||
/obj/item/clothing/mask/breath = 3,
|
||||
/obj/item/clothing/shoes/magboots = 3,
|
||||
/obj/item/weapon/tank/oxygen = 3
|
||||
)
|
||||
|
||||
/datum/supply_pack/voidsuits/security/alt
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/space/void/security/alt = 3,
|
||||
/obj/item/clothing/head/helmet/space/void/security/alt = 3,
|
||||
/obj/item/clothing/mask/breath = 3,
|
||||
/obj/item/clothing/shoes/magboots = 3,
|
||||
/obj/item/weapon/tank/oxygen = 3
|
||||
)
|
||||
|
||||
/datum/supply_pack/voidsuits/supply
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/space/void/mining = 3,
|
||||
/obj/item/clothing/head/helmet/space/void/mining = 3,
|
||||
/obj/item/clothing/mask/breath = 3,
|
||||
/obj/item/weapon/tank/oxygen = 3
|
||||
)
|
||||
|
||||
/datum/supply_pack/voidsuits/explorer
|
||||
name = "Exploration voidsuits"
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/space/void/exploration = 3,
|
||||
/obj/item/clothing/head/helmet/space/void/exploration = 3,
|
||||
/obj/item/clothing/mask/breath = 3,
|
||||
/obj/item/clothing/shoes/magboots = 3,
|
||||
/obj/item/weapon/tank/oxygen = 3
|
||||
/obj/item/clothing/suit/space/void/exploration = 2,
|
||||
/obj/item/clothing/head/helmet/space/void/exploration = 2,
|
||||
/obj/item/clothing/mask/breath = 2,
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 50
|
||||
cost = 45
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Exploration voidsuit crate"
|
||||
access = access_explorer
|
||||
@@ -92,7 +21,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 35
|
||||
cost = 45
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Expedition Medic voidsuit crate"
|
||||
access = access_explorer
|
||||
|
||||
@@ -34,6 +34,15 @@
|
||||
// Track if we are already had initialize() called to prevent double-initialization.
|
||||
var/initialized = FALSE
|
||||
|
||||
/// Last name used to calculate a color for the chatmessage overlays
|
||||
var/chat_color_name
|
||||
/// Last color calculated for the the chatmessage overlays
|
||||
var/chat_color
|
||||
/// A luminescence-shifted value of the last color calculated for chatmessage overlays
|
||||
var/chat_color_darkened
|
||||
/// The chat color var, without alpha.
|
||||
var/chat_color_hover
|
||||
|
||||
/atom/New(loc, ...)
|
||||
// Don't call ..() unless /datum/New() ever exists
|
||||
|
||||
@@ -490,7 +499,7 @@
|
||||
// Use for objects performing visible actions
|
||||
// message is output to anyone who can see, e.g. "The [src] does something!"
|
||||
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
|
||||
/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs, var/range = world.view)
|
||||
/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs, var/range = world.view, var/runemessage = "<span style='font-size: 1.5em'>👁</span>")
|
||||
|
||||
//VOREStation Edit
|
||||
var/list/see
|
||||
@@ -513,6 +522,8 @@
|
||||
var/mob/M = mob
|
||||
if(M.see_invisible >= invisibility && MOB_CAN_SEE_PLANE(M, plane))
|
||||
M.show_message(message, VISIBLE_MESSAGE, blind_message, AUDIBLE_MESSAGE)
|
||||
if(runemessage != -1)
|
||||
M.create_chat_message(src, "[runemessage]", FALSE, list("emote"), audible = FALSE)
|
||||
else if(blind_message)
|
||||
M.show_message(blind_message, AUDIBLE_MESSAGE)
|
||||
|
||||
@@ -521,7 +532,7 @@
|
||||
// message is the message output to anyone who can hear.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance, var/radio_message)
|
||||
/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance, var/radio_message, var/runemessage)
|
||||
|
||||
var/range = hearing_distance || world.view
|
||||
var/list/hear = get_mobs_and_objs_in_view_fast(get_turf(src),range,remote_ghosts = FALSE)
|
||||
@@ -542,6 +553,8 @@
|
||||
var/mob/M = mob
|
||||
var/msg = message
|
||||
M.show_message(msg, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE)
|
||||
if(runemessage != -1)
|
||||
M.create_chat_message(src, "[runemessage || message]", FALSE, list("emote"))
|
||||
|
||||
/atom/movable/proc/dropInto(var/atom/destination)
|
||||
while(istype(destination))
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
regulating_temperature = 1
|
||||
audible_message("\The [src] clicks as it starts [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\
|
||||
"You hear a click and a faint electronic hum.")
|
||||
"You hear a click and a faint electronic hum.", runemessage = "* click *")
|
||||
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
||||
else
|
||||
//check for when we should stop adjusting temperature
|
||||
@@ -199,7 +199,7 @@
|
||||
update_use_power(USE_POWER_IDLE)
|
||||
regulating_temperature = 0
|
||||
audible_message("\The [src] clicks quietly as it stops [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\
|
||||
"You hear a click as a faint electronic humming stops.")
|
||||
"You hear a click as a faint electronic humming stops.", runemessage = "* click *")
|
||||
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
||||
|
||||
if(regulating_temperature)
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
|
||||
else if((occupant.health >= heal_level || occupant.health == occupant.getMaxHealth()) && (!eject_wait))
|
||||
playsound(src, 'sound/machines/medbayscanner1.ogg', 50, 1)
|
||||
audible_message("\The [src] signals that the cloning process is complete.")
|
||||
audible_message("\The [src] signals that the cloning process is complete.", runemessage = "* ding *")
|
||||
connected_message("Cloning Process Complete.")
|
||||
locked = 0
|
||||
go_out()
|
||||
|
||||
@@ -519,9 +519,9 @@
|
||||
if(electronics)
|
||||
sleep(10)
|
||||
if(oldfuel > fuel && oldfood > food)
|
||||
src.audible_message("\The [src] lets out a somehow reassuring chime.")
|
||||
src.audible_message("\The [src] lets out a somehow reassuring chime.", runemessage = "* reassuring chime *")
|
||||
else if(oldfuel < fuel || oldfood < food)
|
||||
src.audible_message("\The [src] lets out a somehow ominous chime.")
|
||||
src.audible_message("\The [src] lets out a somehow ominous chime.", runemessage = "* ominous chime *")
|
||||
food = oldfood
|
||||
fuel = oldfuel
|
||||
|
||||
|
||||
@@ -461,12 +461,7 @@
|
||||
|
||||
//VOREStation Edit - Resleeving.
|
||||
if(to_despawn.mind)
|
||||
if(to_despawn.mind.name in SStranscore.backed_up)
|
||||
var/datum/transhuman/mind_record/MR = SStranscore.backed_up[to_despawn.mind.name]
|
||||
SStranscore.stop_backup(MR)
|
||||
if(to_despawn.mind.name in SStranscore.body_scans) //This uses mind names to avoid people cryo'ing a printed body to delete body scans.
|
||||
var/datum/transhuman/body_record/BR = SStranscore.body_scans[to_despawn.mind.name]
|
||||
SStranscore.remove_body(BR)
|
||||
SStranscore.leave_round(to_despawn)
|
||||
//VOREStation Edit End - Resleeving.
|
||||
|
||||
//Handle job slot/tater cleanup.
|
||||
|
||||
@@ -1104,7 +1104,7 @@
|
||||
if("Exploration")
|
||||
parent_helmet = /obj/item/clothing/head/helmet/space/void/exploration
|
||||
parent_suit = /obj/item/clothing/suit/space/void/exploration
|
||||
if("Expedition Medic")
|
||||
if("Field Medic")
|
||||
parent_helmet = /obj/item/clothing/head/helmet/space/void/expedition_medical
|
||||
parent_suit = /obj/item/clothing/suit/space/void/expedition_medical
|
||||
if("Old Exploration")
|
||||
|
||||
@@ -277,7 +277,8 @@ when portals are shortly lived, or when portals are made to be obvious with spec
|
||||
|
||||
for(var/thing in mobs_to_relay)
|
||||
var/mob/mob = thing
|
||||
var/message = mob.combine_message(message_pieces, verb, M)
|
||||
var/list/combined = mob.combine_message(message_pieces, verb, M)
|
||||
var/message = combined["formatted"]
|
||||
var/name_used = M.GetVoice()
|
||||
var/rendered = null
|
||||
rendered = "<span class='game say'><span class='name'>[name_used]</span> [message]</span>"
|
||||
|
||||
@@ -246,7 +246,8 @@
|
||||
//VOREStation Edit End
|
||||
|
||||
for(var/mob/mob in mobs_to_relay)
|
||||
var/message = mob.combine_message(message_pieces, verb, M)
|
||||
var/list/combined = mob.combine_message(message_pieces, verb, M)
|
||||
var/message = combined["formatted"]
|
||||
var/name_used = M.GetVoice()
|
||||
var/rendered = null
|
||||
rendered = "<span class='game say'>[bicon(src)] <span class='name'>[name_used]</span> [message]</span>"
|
||||
|
||||
@@ -460,7 +460,7 @@
|
||||
return
|
||||
|
||||
playsound(src, 'sound/machines/defib_charge.ogg', 50, 0)
|
||||
audible_message("<span class='warning'>\The [src] lets out a steadily rising hum...</span>")
|
||||
audible_message("<span class='warning'>\The [src] lets out a steadily rising hum...</span>", runemessage = "* whines *")
|
||||
|
||||
if(!do_after(user, chargetime, H))
|
||||
return
|
||||
@@ -527,7 +527,7 @@
|
||||
H.setBrainLoss(brain_damage)
|
||||
|
||||
/obj/item/weapon/shockpaddles/proc/make_announcement(var/message, var/msg_class)
|
||||
audible_message("<b>\The [src]</b> [message]", "\The [src] vibrates slightly.")
|
||||
audible_message("<b>\The [src]</b> [message]", "\The [src] vibrates slightly.", runemessage = "* buzz *")
|
||||
|
||||
/obj/item/weapon/shockpaddles/emag_act(mob/user)
|
||||
if(safety)
|
||||
|
||||
@@ -31,12 +31,13 @@
|
||||
/obj/item/device/megaphone/proc/do_broadcast(var/mob/living/user, var/message)
|
||||
if(emagged)
|
||||
if(insults)
|
||||
user.audible_message("<B>[user.GetVoice()]</B>[user.GetAltName()] broadcasts, <FONT size=3>\"[pick(insultmsg)]\"</FONT>")
|
||||
var/insult = pick(insultmsg)
|
||||
user.audible_message("<B>[user.GetVoice()]</B>[user.GetAltName()] broadcasts, <FONT size=3>\"[insult]\"</FONT>", runemessage = insult)
|
||||
insults--
|
||||
else
|
||||
to_chat(user, "<span class='warning'>*BZZZZzzzzzt*</span>")
|
||||
else
|
||||
user.audible_message("<B>[user.GetVoice()]</B>[user.GetAltName()] broadcasts, <FONT size=3>\"[message]\"</FONT>")
|
||||
user.audible_message("<B>[user.GetVoice()]</B>[user.GetAltName()] broadcasts, <FONT size=3>\"[message]\"</FONT>", runemessage = message)
|
||||
|
||||
/obj/item/device/megaphone/attack_self(var/mob/living/user)
|
||||
var/message = sanitize(input(user, "Shout a message?", "Megaphone", null) as text)
|
||||
@@ -131,7 +132,8 @@
|
||||
/obj/item/device/megaphone/super/do_broadcast(var/mob/living/user, var/message)
|
||||
if(emagged)
|
||||
if(insults)
|
||||
user.audible_message("<B>[user.GetVoice()]</B>[user.GetAltName()] broadcasts, <FONT size=[broadcast_size] face='[broadcast_font]' color='[broadcast_color]'>\"[pick(insultmsg)]\"</FONT>")
|
||||
var/insult = pick(insultmsg)
|
||||
user.audible_message("<B>[user.GetVoice()]</B>[user.GetAltName()] broadcasts, <FONT size=[broadcast_size] face='[broadcast_font]' color='[broadcast_color]'>\"[insult]\"</FONT>", runemessage = insult)
|
||||
if(broadcast_size >= 11)
|
||||
var/turf/T = get_turf(user)
|
||||
playsound(src, 'sound/items/AirHorn.ogg', 100, 1)
|
||||
@@ -160,4 +162,4 @@
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
user.audible_message("<B>[user.GetVoice()]</B>[user.GetAltName()] broadcasts, <FONT size=[broadcast_size] face='[broadcast_font]' color='[broadcast_color]'>\"[message]\"</FONT>")
|
||||
user.audible_message("<B>[user.GetVoice()]</B>[user.GetAltName()] broadcasts, <FONT size=[broadcast_size] face='[broadcast_font]' color='[broadcast_color]'>\"[message]\"</FONT>", runemessage = message)
|
||||
|
||||
@@ -19,7 +19,14 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
|
||||
|
||||
var/ooc_notes = null //For holding prefs
|
||||
|
||||
// Resleeving database this machine interacts with. Blank for default database
|
||||
// Needs a matching /datum/transcore_db with key defined in code
|
||||
var/db_key
|
||||
var/datum/transcore_db/our_db // These persist all round and are never destroyed, just keep a hard ref
|
||||
|
||||
/obj/item/device/sleevemate/Initialize()
|
||||
. = ..()
|
||||
our_db = SStranscore.db_by_key(db_key)
|
||||
|
||||
//These don't perform any checks and need to be wrapped by checks
|
||||
/obj/item/device/sleevemate/proc/clear_mind()
|
||||
@@ -77,7 +84,7 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
|
||||
clear_mind()
|
||||
if("Backup")
|
||||
to_chat(user,"<span class='notice'>Internal copy of [stored_mind.name] backed up to database.</span>")
|
||||
SStranscore.m_backup(stored_mind,null,one_time = TRUE)
|
||||
our_db.m_backup(stored_mind,null,one_time = TRUE)
|
||||
if("Cancel")
|
||||
return
|
||||
|
||||
@@ -183,7 +190,7 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
|
||||
|
||||
usr.visible_message("[usr] begins scanning [target]'s mind.","<span class='notice'>You begin scanning [target]'s mind.</span>")
|
||||
if(do_after(usr,8 SECONDS,target))
|
||||
SStranscore.m_backup(target.mind,nif,one_time = TRUE)
|
||||
our_db.m_backup(target.mind,nif,one_time = TRUE)
|
||||
to_chat(usr,"<span class='notice'>Mind backed up!</span>")
|
||||
else
|
||||
to_chat(usr,"<span class='warning'>You must remain close to your target!</span>")
|
||||
@@ -200,7 +207,7 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
|
||||
usr.visible_message("[usr] begins scanning [target]'s body.","<span class='notice'>You begin scanning [target]'s body.</span>")
|
||||
if(do_after(usr,8 SECONDS,target))
|
||||
var/datum/transhuman/body_record/BR = new()
|
||||
BR.init_from_mob(H, TRUE, TRUE)
|
||||
BR.init_from_mob(H, TRUE, TRUE, database_key = db_key)
|
||||
to_chat(usr,"<span class='notice'>Body scanned!</span>")
|
||||
else
|
||||
to_chat(usr,"<span class='warning'>You must remain close to your target!</span>")
|
||||
|
||||
@@ -258,13 +258,13 @@
|
||||
var/playedmessage = mytape.storedinfo[i]
|
||||
if (findtextEx(playedmessage,"*",1,2)) //remove marker for action sounds
|
||||
playedmessage = copytext(playedmessage,2)
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: [playedmessage]</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: [playedmessage]</font>", runemessage = playedmessage)
|
||||
|
||||
if(mytape.storedinfo.len < i+1)
|
||||
playsleepseconds = 1
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: End of recording.</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: End of recording.</font>", runemessage = "* click *")
|
||||
break
|
||||
else
|
||||
playsleepseconds = mytape.timestamp[i+1] - mytape.timestamp[i]
|
||||
@@ -272,7 +272,7 @@
|
||||
if(playsleepseconds > 14)
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: Skipping [playsleepseconds] seconds of silence</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: Skipping [playsleepseconds] seconds of silence</font>", runemessage = "* tape winding *")
|
||||
playsleepseconds = 1
|
||||
sleep(10 * playsleepseconds)
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
|
||||
if(emagged)
|
||||
var/turf/T = get_turf(src)
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: This tape recorder will self-destruct in... Five.</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: This tape recorder will self-destruct in... Five.</font>", runemessage = "* beep beep *")
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: Four.</font>")
|
||||
|
||||
@@ -24,5 +24,6 @@
|
||||
|
||||
var/message = sanitize(input(user,"Choose a message to relay to those around you.") as text|null)
|
||||
if(message)
|
||||
var/obj/item/device/text_to_speech/O = src
|
||||
audible_message("[bicon(O)] \The [O.name] states, \"[message]\"")
|
||||
audible_message("[bicon(src)] \The [src.name] states, \"[message]\"", runemessage = "* synthesized speech *")
|
||||
if(ismob(loc))
|
||||
loc.audible_message("", runemessage = "\[TTS Voice\] [message]")
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
|
||||
if(isnull(insults))
|
||||
playsound(src, 'sound/voice/halt.ogg', 100, 1, vary = 0)
|
||||
user.audible_message("<span class='warning'>[user]'s [name] rasps, \"[use_message]\"</span>", "<span class='warning'>\The [user] holds up \the [name].</span>")
|
||||
user.audible_message("<span class='warning'>[user]'s [name] rasps, \"[use_message]\"</span>", "<span class='warning'>\The [user] holds up \the [name].</span>", runemessage = "\[TTS Voice\] [use_message]")
|
||||
else
|
||||
if(insults > 0)
|
||||
playsound(src, 'sound/voice/binsult.ogg', 100, 1, vary = 0)
|
||||
// Yes, it used to show the transcription of the sound clip. That was a) inaccurate b) immature as shit.
|
||||
user.audible_message("<span class='warning'>[user]'s [name] gurgles something indecipherable and deeply offensive.</span>", "<span class='warning'>\The [user] holds up \the [name].</span>")
|
||||
user.audible_message("<span class='warning'>[user]'s [name] gurgles something indecipherable and deeply offensive.</span>", "<span class='warning'>\The [user] holds up \the [name].</span>", runemessage = "\[TTS Voice\] #&@&^%(*")
|
||||
insults--
|
||||
else
|
||||
to_chat(user, "<span class='danger'>*BZZZZZZZZT*</span>")
|
||||
|
||||
@@ -305,7 +305,8 @@
|
||||
for(var/wr_master in masters)
|
||||
var/weakref/wr = wr_master
|
||||
var/mob/master = wr.resolve()
|
||||
var/message = master.combine_message(message_pieces, verb, M)
|
||||
var/list/combined = master.combine_message(message_pieces, verb, M)
|
||||
var/message = combined["formatted"]
|
||||
var/rendered = "<i><span class='game say'>UAV received: <span class='name'>[name_used]</span> [message]</span></i>"
|
||||
master.show_message(rendered, 2)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/structure/handrail
|
||||
name = "handrail"
|
||||
icon = 'icons/obj/handrail_vr.dmi'
|
||||
icon = 'icons/obj/handrail.dmi'
|
||||
icon_state = "handrail"
|
||||
desc = "A safety railing with buckles to secure yourself to when floor isn't stable enough."
|
||||
density = 0
|
||||
@@ -242,6 +242,7 @@
|
||||
prob(2);/obj/item/weapon/storage/box/syndie_kit/spy,
|
||||
prob(2);/obj/item/weapon/grenade/anti_photon,
|
||||
prob(2);/obj/item/clothing/under/hyperfiber/bluespace,
|
||||
prob(2);/obj/item/weapon/reagent_containers/glass/beaker/vial/amorphorovir,
|
||||
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
|
||||
prob(1);/obj/item/device/nif/bad,
|
||||
prob(1);/obj/item/device/radio_jammer,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define RECOMMENDED_VERSION 501
|
||||
/world/New()
|
||||
world_startup_time = world.timeofday
|
||||
to_world_log("Map Loading Complete")
|
||||
//logs
|
||||
//VOREStation Edit Start
|
||||
|
||||
@@ -324,8 +324,7 @@
|
||||
var/message = sanitize(input("What do you want the message to be?", "Make Sound") as text|null)
|
||||
if(!message)
|
||||
return
|
||||
for (var/mob/V in hearers(O))
|
||||
V.show_message(message, 2)
|
||||
O.audible_message(message)
|
||||
log_admin("[key_name(usr)] made [O] at [O.x], [O.y], [O.z]. make a sound")
|
||||
message_admins("<font color='blue'>[key_name_admin(usr)] made [O] at [O.x], [O.y], [O.z]. make a sound.</font>", 1)
|
||||
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
sleep(1 SECOND)
|
||||
shadekin.dir = SOUTH
|
||||
sleep(1 SECOND)
|
||||
shadekin.audible_message("<b>[shadekin]</b> belches loudly!")
|
||||
shadekin.audible_message("<b>[shadekin]</b> belches loudly!", runemessage = "* URRRRRP *")
|
||||
sleep(2 SECONDS)
|
||||
shadekin.phase_shift()
|
||||
target.transforming = FALSE //Undo cheap hack
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
var/obj/O = find_escape_route()
|
||||
if(istype(O))
|
||||
return give_destination(get_turf(O), 0, TRUE)
|
||||
else
|
||||
return find_target()
|
||||
else
|
||||
return find_target()
|
||||
else
|
||||
@@ -91,4 +93,4 @@
|
||||
return pick(closest_escape)
|
||||
return null
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -76,3 +76,6 @@
|
||||
var/connection_realtime
|
||||
///world.timeofday they connected
|
||||
var/connection_timeofday
|
||||
|
||||
// Runechat messages
|
||||
var/list/seen_messages
|
||||
|
||||
@@ -290,6 +290,32 @@ var/list/_client_preferences_by_type
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/runechat_mob
|
||||
description = "Runechat (Mobs)"
|
||||
key = "RUNECHAT_MOB"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/runechat_obj
|
||||
description = "Runechat (Objs)"
|
||||
key = "RUNECHAT_OBJ"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
|
||||
/datum/client_preference/runechat_border
|
||||
description = "Runechat Message Border"
|
||||
key = "RUNECHAT_BORDER"
|
||||
enabled_description = "Show"
|
||||
disabled_description = "Hide"
|
||||
enabled_by_default = FALSE
|
||||
|
||||
/datum/client_preference/runechat_long_messages
|
||||
description = "Runechat Message Length"
|
||||
key = "RUNECHAT_LONG"
|
||||
enabled_description = "ERP KING"
|
||||
disabled_description = "Normie"
|
||||
enabled_by_default = FALSE
|
||||
|
||||
/datum/client_preference/status_indicators/toggled(mob/preference_mob, enabled)
|
||||
. = ..()
|
||||
if(preference_mob && preference_mob.plane_holder)
|
||||
|
||||
@@ -4,11 +4,16 @@
|
||||
icon_state = "ertsuit"
|
||||
item_state = "ertsuit"
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
|
||||
slowdown = 1
|
||||
slowdown = 0.5
|
||||
siemens_coefficient = 0.5
|
||||
species_restricted = list("exclude",SPECIES_DIONA,SPECIES_VOX,SPECIES_TESHARI) //this thing can autoadapt
|
||||
icon = 'icons/obj/clothing/suits_vr.dmi'
|
||||
w_class = ITEMSIZE_NORMAL //the mark vii packs itself down when not in use, thanks future-materials
|
||||
breach_threshold = 16 //Extra Thicc
|
||||
resilience = 0.05 //Military Armor
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 15* ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE+10000
|
||||
|
||||
/obj/item/clothing/suit/space/void/responseteam/command
|
||||
name = "Mark VII-C Emergency Response Team Commander Suit"
|
||||
@@ -110,6 +115,9 @@
|
||||
plane_slots = list(slot_head)
|
||||
var/hud_active = 1
|
||||
var/activation_sound = 'sound/items/nif_click.ogg'
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 15* ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE+10000
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/responseteam/verb/toggle()
|
||||
set category = "Object"
|
||||
@@ -17,7 +17,6 @@
|
||||
desc = "A refurbished early contact era voidsuit of human design. These things aren't especially good against modern weapons but they're sturdy, incredibly easy to come by, and there are lots of spare parts for repairs. Many old-timer spacers swear by these old things, even if new powered hardsuits have more features and better armor. This one is devoid of any identifying markings or rank indicators."
|
||||
icon_state = "rig-vintagecrew"
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuitTG", slot_l_hand_str = "sec_voidsuitTG")
|
||||
slowdown = 0.5
|
||||
armor = list(melee = 30, bullet = 15, laser = 15,energy = 5, bomb = 20, bio = 100, rad = 50)
|
||||
allowed = list(/obj/item/device/flashlight,
|
||||
/obj/item/weapon/tank,
|
||||
@@ -40,7 +39,7 @@
|
||||
armor = list(melee = 40, bullet = 20, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 100)
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 15 * ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE+10000
|
||||
|
||||
/obj/item/clothing/suit/space/void/refurb/engineering
|
||||
name = "vintage engineering voidsuit"
|
||||
@@ -51,7 +50,8 @@
|
||||
armor = list(melee = 40, bullet = 20, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 100)
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 15 * ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE+10000
|
||||
breach_threshold = 14 //These are kinda thicc
|
||||
allowed = list(/obj/item/device/flashlight,
|
||||
/obj/item/weapon/tank,
|
||||
/obj/item/device/suit_cooling_unit,
|
||||
@@ -93,7 +93,6 @@
|
||||
desc = "A refurbished early contact era voidsuit of human design. These things aren't especially good against modern weapons but they're sturdy, incredibly easy to come by, and there are lots of spare parts for repairs. Many old-timer spacers swear by these old things, even if new powered hardsuits have more features and better armor. The green and white markings indicate this as a medic's suit."
|
||||
icon_state = "rig-vintagemedic"
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuitTG", slot_l_hand_str = "sec_voidsuitTG")
|
||||
slowdown = 0.5
|
||||
armor = list(melee = 30, bullet = 15, laser = 15, energy = 5, bomb = 25, bio = 100, rad = 75)
|
||||
allowed = list(/obj/item/device/flashlight,
|
||||
/obj/item/weapon/tank,
|
||||
@@ -126,6 +125,8 @@
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuitTG", slot_l_hand_str = "sec_voidsuitTG")
|
||||
slowdown = 1
|
||||
armor = list(melee = 40, bullet = 35, laser = 35, energy = 5, bomb = 40, bio = 100, rad = 50)
|
||||
breach_threshold = 14 //These are kinda thicc
|
||||
resilience = 0.15 //Armored
|
||||
siemens_coefficient = 0.8
|
||||
allowed = list(/obj/item/weapon/gun,
|
||||
/obj/item/device/flashlight,
|
||||
@@ -162,6 +163,8 @@
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuitTG", slot_l_hand_str = "sec_voidsuitTG")
|
||||
slowdown = 1
|
||||
armor = list(melee = 50, bullet = 45, laser = 45, energy = 10, bomb = 30, bio = 100, rad = 60)
|
||||
breach_threshold = 16 //Extra Thicc
|
||||
resilience = 0.1 //Heavily Armored
|
||||
siemens_coefficient = 0.7
|
||||
allowed = list(/obj/item/weapon/gun,
|
||||
/obj/item/device/flashlight,
|
||||
@@ -201,7 +204,7 @@
|
||||
desc = "A refurbished early contact era voidsuit of human design. These things aren't especially good against modern weapons but they're sturdy, incredibly easy to come by, and there are lots of spare parts for repairs. Many old-timer spacers swear by these old things, even if new powered hardsuits have more features and better armor. The royal blue markings indicate this is the pilot's variant; low protection but ultra-lightweight."
|
||||
icon_state = "rig-vintagepilot"
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuitTG", slot_l_hand_str = "sec_voidsuitTG")
|
||||
slowdown = 0.25
|
||||
slowdown = 0
|
||||
armor = list(melee = 25, bullet = 20, laser = 20, energy = 5, bomb = 20, bio = 100, rad = 50)
|
||||
siemens_coefficient = 0.9
|
||||
allowed = list(/obj/item/device/flashlight,
|
||||
@@ -232,7 +235,6 @@
|
||||
desc = "A refurbished early contact era voidsuit of human design. These things aren't especially good against modern weapons but they're sturdy, incredibly easy to come by, and there are lots of spare parts for repairs. Many old-timer spacers swear by these old things, even if new powered hardsuits have more features and better armor. The purple markings indicate this as a scientist's suit. Keep your eyes open for ropes."
|
||||
icon_state = "rig-vintagescientist"
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuitTG", slot_l_hand_str = "sec_voidsuitTG")
|
||||
slowdown = 0.5
|
||||
armor = list(melee = 25, bullet = 10, laser = 10, energy = 50, bomb = 10, bio = 100, rad = 100)
|
||||
siemens_coefficient = 0.8
|
||||
allowed = list(/obj/item/device/flashlight,
|
||||
@@ -275,6 +277,8 @@
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuitTG", slot_l_hand_str = "sec_voidsuitTG")
|
||||
slowdown = 1.5 //the tradeoff for being hot shit almost on par with a crimson suit is that it slows you down even more
|
||||
armor = list(melee = 55, bullet = 45, laser = 45, energy = 25, bomb = 50, bio = 100, rad = 50)
|
||||
breach_threshold = 16 //Extra Thicc
|
||||
resilience = 0.05 //Military Armor
|
||||
siemens_coefficient = 0.6
|
||||
allowed = list(/obj/item/weapon/gun,
|
||||
/obj/item/device/flashlight,
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
name = "blood-red voidsuit"
|
||||
desc = "An advanced suit that protects against injuries during special operations. Property of Gorlex Marauders."
|
||||
item_state_slots = list(slot_r_hand_str = "syndie_voidsuit", slot_l_hand_str = "syndie_voidsuit")
|
||||
slowdown = 1
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
|
||||
siemens_coefficient = 0.6
|
||||
breach_threshold = 16 //Extra Thicc
|
||||
resilience = 0.05 //Military Armor
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/merc/fire
|
||||
icon_state = "rig0-firebug"
|
||||
@@ -26,6 +27,8 @@
|
||||
desc = "A blackened helmet that has had many of its protective plates coated in or replaced with high-grade thermal insulation, to protect against incineration. Property of Gorlex Marauders."
|
||||
armor = list(melee = 40, bullet = 40, laser = 60, energy = 20, bomb = 50, bio = 100, rad = 50)
|
||||
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 20* ONE_ATMOSPHERE
|
||||
siemens_coefficient = 0.7
|
||||
light_overlay = "helmet_light_fire"
|
||||
|
||||
@@ -33,7 +36,11 @@
|
||||
icon_state = "rig-firebug"
|
||||
name = "soot-covered voidsuit"
|
||||
desc = "A blackened suit that has had many of its protective plates coated in or replaced with high-grade thermal insulation, to protect against incineration. Property of Gorlex Marauders."
|
||||
armor = list(melee = 40, bullet = 40, laser = 60, energy = 20, bomb = 50, bio = 100, rad = 50)
|
||||
armor = list(melee = 50, bullet = 40, laser = 60, energy = 20, bomb = 50, bio = 100, rad = 50)
|
||||
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 20* ONE_ATMOSPHERE
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/material/twohanded/fireaxe,/obj/item/weapon/flamethrower)
|
||||
siemens_coefficient = 0.7
|
||||
breach_threshold = 18 //Super Extra Thicc
|
||||
slowdown = 1
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuit", slot_l_hand_str = "sec_voidsuit")
|
||||
slowdown = 1.5
|
||||
armor = list(melee = 60, bullet = 35, laser = 35, energy = 15, bomb = 55, bio = 100, rad = 20)
|
||||
breach_threshold = 14 //These are kinda thicc
|
||||
resilience = 0.15 //Armored
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/security/prototype
|
||||
name = "\improper security prototype voidsuit helmet"
|
||||
@@ -51,3 +53,6 @@
|
||||
icon = 'icons/obj/clothing/suits_vr.dmi'
|
||||
icon_override = 'icons/mob/suit_vr.dmi'
|
||||
species_restricted = null
|
||||
breach_threshold = 16 //Extra Thicc
|
||||
resilience = 0.05 //Military Armor
|
||||
|
||||
|
||||
@@ -2,23 +2,26 @@
|
||||
//Engineering
|
||||
/obj/item/clothing/head/helmet/space/void/engineering
|
||||
name = "engineering voidsuit helmet"
|
||||
desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding."
|
||||
desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has moderate radiation and pressure shielding."
|
||||
icon_state = "rig0-engineering"
|
||||
item_state_slots = list(slot_r_hand_str = "eng_helm", slot_l_hand_str = "eng_helm")
|
||||
armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80)
|
||||
armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 70)
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 15 * ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE+5000
|
||||
|
||||
/obj/item/clothing/suit/space/void/engineering
|
||||
name = "engineering voidsuit"
|
||||
desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding."
|
||||
desc = "A special suit that protects against hazardous, low pressure environments. Has moderate radiation and pressure shielding."
|
||||
icon_state = "rig-engineering"
|
||||
item_state_slots = list(slot_r_hand_str = "eng_voidsuit", slot_l_hand_str = "eng_voidsuit")
|
||||
slowdown = 1
|
||||
armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80)
|
||||
armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 70)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 15 * ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE+5000
|
||||
breach_threshold = 14 //These are kinda thicc
|
||||
slowdown = 1
|
||||
|
||||
//Engineering HAZMAT Voidsuit
|
||||
|
||||
@@ -27,26 +30,43 @@
|
||||
desc = "A engineering helmet designed for work in a low-pressure environment. Extra radiation shielding appears to have been installed at the price of comfort."
|
||||
icon_state = "rig0-engineering_rad"
|
||||
item_state_slots = list(slot_r_hand_str = "eng_helm_rad", slot_l_hand_str = "eng_helm_rad")
|
||||
armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 50, bio = 100, rad = 100)
|
||||
armor = list(melee = 25, bullet = 5, laser = 20, energy = 5, bomb = 50, bio = 100, rad = 100)
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 10 * ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
/obj/item/clothing/suit/space/void/engineering/hazmat
|
||||
name = "HAZMAT voidsuit"
|
||||
desc = "A engineering voidsuit that protects against hazardous, low pressure environments. Has enhanced radiation shielding compared to regular engineering voidsuits."
|
||||
icon_state = "rig-engineering_rad"
|
||||
item_state_slots = list(slot_r_hand_str = "eng_voidsuit_rad", slot_l_hand_str = "eng_voidsuit_rad")
|
||||
armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 50, bio = 100, rad = 100)
|
||||
armor = list(melee = 25, bullet = 5, laser = 20, energy = 5, bomb = 50, bio = 100, rad = 100)
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 10 * ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
//Engineering Construction Voidsuit
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/engineering/construction
|
||||
name = "construction voidsuit helmet"
|
||||
desc = "A special helmet designed for work in a hazardous, low-pressure environment. Exchanges radiation shielding for extra armor and maneuverability for field projects."
|
||||
icon_state = "rig0-engineering_con"
|
||||
item_state_slots = list(slot_r_hand_str = "eng_helm_con", slot_l_hand_str = "eng_helm_con")
|
||||
armor = list(melee = 40, bullet = 15, laser = 25, energy = 15, bomb = 35, bio = 100, rad = 50)
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 10 * ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
/obj/item/clothing/suit/space/void/engineering/construction
|
||||
name = "contstruction voidsuit"
|
||||
name = "construction voidsuit"
|
||||
desc = "A special suit that protects against hazardous, low pressure environments. Exchanges radiation shielding for extra armor and maneuverability for field projects."
|
||||
icon_state = "rig-engineering_con"
|
||||
item_state_slots = list(slot_r_hand_str = "eng_voidsuit_con", slot_l_hand_str = "eng_voidsuit_con")
|
||||
armor = list(melee = 40, bullet = 15, laser = 25, energy = 15, bomb = 35, bio = 100, rad = 50)
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 10 * ONE_ATMOSPHERE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
slowdown = 0.5
|
||||
|
||||
//Engineering Surplus Voidsuits
|
||||
|
||||
@@ -54,14 +74,15 @@
|
||||
name = "reinforced engineering voidsuit helmet"
|
||||
desc = "A heavy, radiation-shielded voidsuit helmet with a surprisingly comfortable interior."
|
||||
icon_state = "rig0-engineeringalt"
|
||||
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 45, bio = 100, rad = 100)
|
||||
armor = list(melee = 50, bullet = 15, laser = 25, energy = 5, bomb = 45, bio = 100, rad = 100)
|
||||
light_overlay = "helmet_light_dual"
|
||||
|
||||
/obj/item/clothing/suit/space/void/engineering/alt
|
||||
name = "reinforced engineering voidsuit"
|
||||
desc = "A bulky industrial voidsuit. It's a few generations old, but a reliable design and radiation shielding make up for the lack of climate control."
|
||||
icon_state = "rig-engineeringalt"
|
||||
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 45, bio = 100, rad = 100)
|
||||
armor = list(melee = 50, bullet = 15, laser = 25, energy = 15, bomb = 45, bio = 100, rad = 100)
|
||||
slowdown = 0.5
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/engineering/salvage
|
||||
name = "salvage voidsuit helmet"
|
||||
@@ -71,14 +92,15 @@
|
||||
slot_l_hand_str = "eng_helm",
|
||||
slot_r_hand_str = "eng_helm",
|
||||
)
|
||||
armor = list(melee = 50, bullet = 10, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 80)
|
||||
armor = list(melee = 50, bullet = 15, laser = 25, energy = 15, bomb = 45, bio = 100, rad = 100)
|
||||
|
||||
/obj/item/clothing/suit/space/void/engineering/salvage
|
||||
name = "salvage voidsuit"
|
||||
desc = "A hand-me-down salvage voidsuit. It has obviously had a lot of repair work done to its radiation shielding."
|
||||
icon_state = "rig-engineeringsav"
|
||||
armor = list(melee = 50, bullet = 10, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 80)
|
||||
armor = list(melee = 50, bullet = 15, laser = 25, energy = 15, bomb = 45, bio = 100, rad = 100)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/toolbox,/obj/item/weapon/storage/briefcase/inflatable,/obj/item/device/t_scanner,/obj/item/weapon/rcd)
|
||||
slowdown = 0.5
|
||||
|
||||
//Mining
|
||||
/obj/item/clothing/head/helmet/space/void/mining
|
||||
@@ -86,7 +108,7 @@
|
||||
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has reinforced plating."
|
||||
icon_state = "rig0-mining"
|
||||
item_state_slots = list(slot_r_hand_str = "mining_helm", slot_l_hand_str = "mining_helm")
|
||||
armor = list(melee = 50, bullet = 5, laser = 20, energy = 5, bomb = 55, bio = 100, rad = 20)
|
||||
armor = list(melee = 50, bullet = 15, laser = 25, energy = 15, bomb = 55, bio = 100, rad = 50)
|
||||
light_overlay = "helmet_light_dual"
|
||||
|
||||
/obj/item/clothing/suit/space/void/mining
|
||||
@@ -95,7 +117,10 @@
|
||||
icon_state = "rig-mining"
|
||||
item_state_slots = list(slot_r_hand_str = "mining_voidsuit", slot_l_hand_str = "mining_voidsuit")
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/pickaxe)
|
||||
armor = list(melee = 50, bullet = 5, laser = 20, energy = 5, bomb = 55, bio = 100, rad = 20)
|
||||
armor = list(melee = 50, bullet = 15, laser = 25, energy = 15, bomb = 55, bio = 100, rad = 50)
|
||||
breach_threshold = 14 //These are kinda thicc
|
||||
resilience = 0.15 //Armored
|
||||
slowdown = 1
|
||||
|
||||
//Mining Surplus Voidsuit
|
||||
|
||||
@@ -103,13 +128,12 @@
|
||||
name = "frontier mining voidsuit helmet"
|
||||
desc = "An armored cheap voidsuit helmet. Someone must have through they were pretty cool when they painted a mohawk on it."
|
||||
icon_state = "rig0-miningalt"
|
||||
armor = list(melee = 50, bullet = 15, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 0)
|
||||
|
||||
/obj/item/clothing/suit/space/void/mining/alt
|
||||
icon_state = "rig-miningalt"
|
||||
name = "frontier mining voidsuit"
|
||||
desc = "A cheap prospecting voidsuit. What it lacks in comfort it makes up for in armor plating and street cred."
|
||||
armor = list(melee = 50, bullet = 15, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 0)
|
||||
slowdown = 0.5
|
||||
|
||||
//Medical
|
||||
/obj/item/clothing/head/helmet/space/void/medical
|
||||
@@ -117,7 +141,7 @@
|
||||
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has minor radiation shielding."
|
||||
icon_state = "rig0-medical"
|
||||
item_state_slots = list(slot_r_hand_str = "medical_helm", slot_l_hand_str = "medical_helm")
|
||||
armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50)
|
||||
armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 80)
|
||||
|
||||
/obj/item/clothing/suit/space/void/medical
|
||||
name = "medical voidsuit"
|
||||
@@ -125,35 +149,48 @@
|
||||
icon_state = "rig-medical"
|
||||
item_state_slots = list(slot_r_hand_str = "medical_voidsuit", slot_l_hand_str = "medical_voidsuit")
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
|
||||
armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50)
|
||||
armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 80)
|
||||
|
||||
//Medical EMT Voidsuit
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/medical/emt
|
||||
name = "emergency medical response voidsuit helmet"
|
||||
desc = "A special helmet designed for work in a hazardous, low pressure environment. Exchanges radiation shielding for some additional protection."
|
||||
icon_state = "rig0-medical_emt"
|
||||
item_state_slots = list(slot_r_hand_str = "medical_helm_emt", slot_l_hand_str = "medical_helm_emt")
|
||||
armor = list(melee = 40, bullet = 15, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50)
|
||||
|
||||
/obj/item/clothing/suit/space/void/medical/emt
|
||||
name = "emergency medical response voidsuit"
|
||||
desc = "A special suit that protects against hazardous, low pressure environments. Exchanges radiation shielding for some additional protection."
|
||||
icon_state = "rig-medical_emt"
|
||||
item_state_slots = list(slot_r_hand_str = "medical_voidsuit_emt", slot_l_hand_str = "medical_voidsuit_emt")
|
||||
armor = list(melee = 40, bullet = 15, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50)
|
||||
breach_threshold = 14 //These are kinda thicc
|
||||
|
||||
//Medical Biohazard Voidsuit
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/medical/bio
|
||||
name = "biohazard voidsuit helmet"
|
||||
desc = "A special helmet that protects against hazardous environments. Has minor radiation shielding."
|
||||
desc = "A special suit designed to protect the user in hazardous enviornments on the field. It feels heavier than the standard suit with extra protection around the joints."
|
||||
icon_state = "rig0-medical_bio"
|
||||
item_state_slots = list(slot_r_hand_str = "medical_helm_bio", slot_l_hand_str = "medical_helm_bio")
|
||||
armor = list(melee = 45, bullet = 5, laser = 20, energy = 5, bomb = 15, bio = 100, rad = 75)
|
||||
armor = list(melee = 55, bullet = 15, laser = 20, energy = 15, bomb = 15, bio = 100, rad = 75)
|
||||
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 15 * ONE_ATMOSPHERE
|
||||
|
||||
/obj/item/clothing/suit/space/void/medical/bio
|
||||
name = "biohazard voidsuit"
|
||||
desc = "A special suit that protects against hazardous, environments. It feels heavier than the standard suit with extra protection around the joints."
|
||||
desc = "A special suit designed to protect the user in hazardous enviornments on the field. It feels heavier than the standard suit with extra protection around the joints."
|
||||
icon_state = "rig-medical_bio"
|
||||
item_state_slots = list(slot_r_hand_str = "medical_voidsuit_bio", slot_l_hand_str = "medical_voidsuit_bio")
|
||||
armor = list(melee = 45, bullet = 5, laser = 20, energy = 5, bomb = 15, bio = 100, rad = 75)
|
||||
armor = list(melee = 55, bullet = 15, laser = 20, energy = 15, bomb = 15, bio = 100, rad = 75)
|
||||
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 15 * ONE_ATMOSPHERE
|
||||
breach_threshold = 16 //Extra Thicc
|
||||
slowdown = 1.5
|
||||
|
||||
//Medical Streamlined Voidsuit
|
||||
/obj/item/clothing/head/helmet/space/void/medical/alt
|
||||
@@ -234,7 +271,7 @@
|
||||
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor."
|
||||
icon_state = "rig0-sec"
|
||||
item_state_slots = list(slot_r_hand_str = "sec_helm", slot_l_hand_str = "sec_helm")
|
||||
armor = list(melee = 50, bullet = 25, laser = 25, energy = 5, bomb = 45, bio = 100, rad = 10)
|
||||
armor = list(melee = 50, bullet = 25, laser = 25, energy = 15, bomb = 45, bio = 100, rad = 10)
|
||||
siemens_coefficient = 0.7
|
||||
light_overlay = "helmet_light_dual"
|
||||
|
||||
@@ -243,9 +280,12 @@
|
||||
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
|
||||
icon_state = "rig-sec"
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuit", slot_l_hand_str = "sec_voidsuit")
|
||||
armor = list(melee = 50, bullet = 25, laser = 25, energy = 5, bomb = 45, bio = 100, rad = 10)
|
||||
armor = list(melee = 50, bullet = 25, laser = 25, energy = 15, bomb = 45, bio = 100, rad = 10)
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton)
|
||||
siemens_coefficient = 0.7
|
||||
breach_threshold = 14 //These are kinda thicc
|
||||
resilience = 0.15 //Armored
|
||||
slowdown = 1
|
||||
|
||||
//Security Crowd Control Voidsuit
|
||||
|
||||
@@ -253,28 +293,32 @@
|
||||
name = "crowd control voidsuit helmet"
|
||||
desc = "A heavy-set and ominous looking crowd control suit helmet. Fitted with state of the art shock absorbing materials, to disperse blunt force trauma."
|
||||
icon_state = "rig0-sec_riot"
|
||||
armor = list(melee = 70, bullet = 15, laser = 15, energy = 5, bomb = 40, bio = 100, rad = 10)
|
||||
armor = list(melee = 70, bullet = 15, laser = 15, energy = 15, bomb = 60, bio = 100, rad = 10)
|
||||
item_state_slots = list(slot_r_hand_str = "sec_helm_riot", slot_l_hand_str = "sec_helm_riot")
|
||||
|
||||
/obj/item/clothing/suit/space/void/security/riot
|
||||
name = "crowd control voidsuit"
|
||||
desc = "A heavy-set and ominous looking crowd control suit. Fitted with state of the art shock absorbing materials, to disperse blunt force trauma."
|
||||
icon_state = "rig-sec_riot"
|
||||
armor = list(melee = 70, bullet = 15, laser = 15, energy = 5, bomb = 40, bio = 100, rad = 10)
|
||||
armor = list(melee = 70, bullet = 15, laser = 15, energy = 15, bomb = 60, bio = 100, rad = 10)
|
||||
breach_threshold = 16 //Extra Thicc
|
||||
resilience = 0.1 //Heavily Armored
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuit_riot", slot_l_hand_str = "sec_voidsuit_riot")
|
||||
|
||||
//Security Surplus Voidsuit
|
||||
/obj/item/clothing/head/helmet/space/void/security/alt
|
||||
name = "security EVA voidsuit helmet"
|
||||
desc = "A grey-black voidsuit helmet with red highlights. A little tacky, but it offers better protection against modern firearms and radiation than standard-issue security voidsuit helmets."
|
||||
armor = list(melee = 30, bullet = 40, laser = 40, energy = 25, bomb = 60, bio = 100, rad = 50)
|
||||
armor = list(melee = 40, bullet = 40, laser = 40, energy = 25, bomb = 40, bio = 100, rad = 50)
|
||||
icon_state = "rig0-secalt"
|
||||
item_state_slots = list(slot_r_hand_str = "syndicate-helm-black", slot_l_hand_str = "syndicate-helm-black")
|
||||
|
||||
/obj/item/clothing/suit/space/void/security/alt
|
||||
name = "security EVA voidsuit"
|
||||
desc = "A grey-black voidsuit with red highlights. A little tacky, but it offers better protection against modern firearms and radiation than standard-issue security voidsuits."
|
||||
armor = list(melee = 30, bullet = 40, laser = 40, energy = 25, bomb = 60, bio = 100, rad = 50)
|
||||
armor = list(melee = 40, bullet = 40, laser = 40, energy = 25, bomb = 40, bio = 100, rad = 50)
|
||||
breach_threshold = 16 //Extra Thicc
|
||||
resilience = 0.1 //Heavily Armored
|
||||
icon_state = "rig-secalt"
|
||||
item_state_slots = list(slot_r_hand_str = "sec_voidsuitTG", slot_l_hand_str = "sec_voidsuitTG")
|
||||
|
||||
@@ -299,6 +343,8 @@
|
||||
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 20* ONE_ATMOSPHERE
|
||||
breach_threshold = 16 //Extra Thicc
|
||||
slowdown = 1.5
|
||||
|
||||
//Atmospherics Surplus Voidsuit
|
||||
|
||||
@@ -306,16 +352,15 @@
|
||||
desc = "A special voidsuit helmet designed for work in hazardous, low pressure environments.This one has been plated with an expensive heat and radiation resistant ceramic."
|
||||
name = "heavy duty atmospherics voidsuit helmet"
|
||||
icon_state = "rig0-atmosalt"
|
||||
armor = list(melee = 20, bullet = 5, laser = 20,energy = 15, bomb = 45, bio = 100, rad = 50)
|
||||
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 70)
|
||||
light_overlay = "hardhat_light"
|
||||
|
||||
/obj/item/clothing/suit/space/void/atmos/alt
|
||||
desc = "A special suit that protects against hazardous, low pressure environments. Fits better than the standard atmospheric voidsuit while still rated to withstand extreme heat and even minor radiation."
|
||||
icon_state = "rig-atmosalt"
|
||||
name = "heavy duty atmos voidsuit"
|
||||
armor = list(melee = 20, bullet = 5, laser = 20,energy = 15, bomb = 45, bio = 100, rad = 50)
|
||||
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 70)
|
||||
slowdown = 1
|
||||
|
||||
//Exploration
|
||||
/obj/item/clothing/head/helmet/space/void/exploration
|
||||
@@ -324,7 +369,7 @@
|
||||
icon_state = "helm_explorer"
|
||||
item_state = "helm_explorer"
|
||||
item_state_slots = list(slot_r_hand_str = "syndicate-helm-black", slot_l_hand_str = "syndicate-helm-black")
|
||||
armor = list(melee = 40, bullet = 15, laser = 25,energy = 35, bomb = 30, bio = 100, rad = 70)
|
||||
armor = list(melee = 50, bullet = 15, laser = 35, energy = 25, bomb = 30, bio = 100, rad = 70)
|
||||
light_overlay = "helmet_light_dual" //explorer_light
|
||||
|
||||
/obj/item/clothing/suit/space/void/exploration
|
||||
@@ -332,29 +377,34 @@
|
||||
desc = "A hazard and radiation resistant voidsuit, featuring the Explorer emblem on its chest plate. Designed for exploring unknown planetary environments."
|
||||
icon_state = "void_explorer"
|
||||
item_state_slots = list(slot_r_hand_str = "skrell_suit_black", slot_l_hand_str = "skrell_suit_black")
|
||||
armor = list(melee = 40, bullet = 15, laser = 25,energy = 35, bomb = 30, bio = 100, rad = 70)
|
||||
armor = list(melee = 50, bullet = 15, laser = 35, energy = 25, bomb = 30, bio = 100, rad = 70)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/stack/flag,/obj/item/device/healthanalyzer,/obj/item/device/gps,/obj/item/device/radio/beacon, \
|
||||
/obj/item/weapon/shovel,/obj/item/ammo_magazine,/obj/item/weapon/gun)
|
||||
breach_threshold = 14 //These are kinda thicc
|
||||
resilience = 0.15 //Armored
|
||||
|
||||
//SAR
|
||||
/obj/item/clothing/head/helmet/space/void/expedition_medical
|
||||
name = "exploration medic\'s voidsuit helmet"
|
||||
name = "field medic voidsuit helmet"
|
||||
desc = "A radiation-resistant helmet made especially for exploring unknown planetary environments. Has a reinforced high-vis bubble style visor."
|
||||
icon_state = "helm_exp_medic"
|
||||
item_state = "helm_exp_medic"
|
||||
item_state_slots = list(slot_r_hand_str = "syndicate-helm-black", slot_l_hand_str = "syndicate-helm-black")
|
||||
armor = list(melee = 25, bullet = 10, laser = 20,energy = 30, bomb = 25, bio = 100, rad = 70)
|
||||
armor = list(melee = 50, bullet = 15, laser = 25, energy = 15, bomb = 30, bio = 100, rad = 90)
|
||||
light_overlay = "helmet_light_dual" //explorer_light
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE+5000
|
||||
|
||||
/obj/item/clothing/suit/space/void/expedition_medical
|
||||
name = "exploration medic\'s voidsuit"
|
||||
name = "field medic voidsuit"
|
||||
desc = "A hazard and radiation resistant voidsuit, featuring the Explorer emblem and a green cross on its chest plate. Seems to be a little lighter and more flexible than the regular explorer issue."
|
||||
icon_state = "void_exp_medic"
|
||||
slowdown = 0.75
|
||||
item_state_slots = list(slot_r_hand_str = "skrell_suit_black", slot_l_hand_str = "skrell_suit_black")
|
||||
armor = list(melee = 25, bullet = 10, laser = 20,energy = 30, bomb = 25, bio = 100, rad = 70)
|
||||
armor = list(melee = 50, bullet = 15, laser = 25, energy = 15, bomb = 30, bio = 100, rad = 90)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/stack/flag,/obj/item/device/healthanalyzer,/obj/item/device/gps,/obj/item/device/radio/beacon, \
|
||||
/obj/item/weapon/shovel,/obj/item/ammo_magazine,/obj/item/weapon/gun,/obj/item/weapon/storage/firstaid,/obj/item/stack/medical)
|
||||
breach_threshold = 14 //These are kinda thicc
|
||||
resilience = 0.15 //Armored
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE+5000
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/exploration/alt
|
||||
desc = "A radiation-resistant helmet retrofitted for exploring unknown planetary environments."
|
||||
@@ -374,8 +424,7 @@
|
||||
icon_state = "rig0_pilot"
|
||||
item_state = "pilot_helm"
|
||||
item_state_slots = list(slot_r_hand_str = "atmos_helm", slot_l_hand_str = "atmos_helm")
|
||||
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 15, bio = 100, rad = 50)
|
||||
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
armor = list(melee = 40, bullet = 10, laser = 25, energy = 15, bomb = 25, bio = 100, rad = 60)
|
||||
light_overlay = "helmet_light_dual"
|
||||
|
||||
/obj/item/clothing/suit/space/void/pilot
|
||||
@@ -383,8 +432,7 @@
|
||||
icon_state = "rig-pilot"
|
||||
item_state_slots = list(slot_r_hand_str = "atmos_voidsuit", slot_l_hand_str = "atmos_voidsuit")
|
||||
name = "pilot voidsuit"
|
||||
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 15, bio = 100, rad = 50)
|
||||
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
armor = list(melee = 40, bullet = 10, laser = 25, energy = 15, bomb = 25, bio = 100, rad = 60)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/toolbox,/obj/item/weapon/storage/briefcase/inflatable)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/pilot/alt
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon_state = "void"
|
||||
item_state_slots = list(slot_r_hand_str = "syndicate", slot_l_hand_str = "syndicate")
|
||||
heat_protection = HEAD
|
||||
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
|
||||
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
min_pressure_protection = 0 * ONE_ATMOSPHERE
|
||||
max_pressure_protection = 10 * ONE_ATMOSPHERE
|
||||
@@ -35,8 +35,8 @@
|
||||
icon_state = "void"
|
||||
item_state_slots = list(slot_r_hand_str = "space_suit_syndicate", slot_l_hand_str = "space_suit_syndicate")
|
||||
desc = "A high-tech dark red space suit. Used for AI satellite maintenance."
|
||||
slowdown = 1
|
||||
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
|
||||
slowdown = 0.5
|
||||
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit)
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
name = "gem-encrusted voidsuit"
|
||||
desc = "A bizarre gem-encrusted suit that radiates magical energies."
|
||||
item_state_slots = list(slot_r_hand_str = "wiz_voidsuit", slot_l_hand_str = "wiz_voidsuit")
|
||||
slowdown = 1
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
unacidable = 1
|
||||
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
if(usr.stat) return
|
||||
|
||||
if(!jingled)
|
||||
usr.audible_message("[usr] jingles the [src]'s bell.")
|
||||
usr.audible_message("[usr] jingles the [src]'s bell.", runemessage = "* jingle *")
|
||||
playsound(src, 'sound/items/pickup/ring.ogg', 50, 1)
|
||||
jingled = 1
|
||||
addtimer(CALLBACK(src, .proc/jingledreset), 50)
|
||||
|
||||
@@ -129,3 +129,11 @@
|
||||
key = "cackle"
|
||||
emote_message_3p = "cackles hysterically!"
|
||||
emote_sound = 'sound/voice/YeenCackle.ogg'
|
||||
/decl/emote/audible/spiderchitter
|
||||
key = "spiderchitter"
|
||||
emote_message_3p = "chitters."
|
||||
emote_sound = 'sound/voice/spiderchitter.ogg'
|
||||
/decl/emote/audible/spiderpurr
|
||||
key = "spiderpurr"
|
||||
emote_message_3p = "purrs."
|
||||
emote_sound = 'sound/voice/spiderpurr.ogg'
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
key = "sidestep"
|
||||
check_restraints = TRUE
|
||||
emote_message_3p = "steps rhythmically and moves side to side."
|
||||
emote_delay = 1.2 SECONDS
|
||||
//emote_delay = 1.2 SECONDS //VOREStation Edit - Delay moved to parent
|
||||
|
||||
/decl/emote/visible/sidestep/do_extra(mob/user)
|
||||
if(istype(user))
|
||||
@@ -26,7 +26,7 @@
|
||||
emote_message_1p = "You do a flip!"
|
||||
emote_message_3p = "does a flip!"
|
||||
emote_sound = 'sound/effects/bodyfall4.ogg'
|
||||
emote_delay = 1.2 SECONDS
|
||||
//emote_delay = 1.2 SECONDS //VOREStation Edit - Delay moved to parent
|
||||
|
||||
/decl/emote/visible/flip/do_extra(mob/user)
|
||||
. = ..()
|
||||
@@ -42,7 +42,7 @@
|
||||
key = "floorspin"
|
||||
emote_message_1p = "You spin around on the floor!"
|
||||
emote_message_3p = "spins around on the floor!"
|
||||
emote_delay = 1.2 SECONDS
|
||||
//emote_delay = 1.2 SECONDS //VOREStation Edit - Delay moved to parent
|
||||
var/static/list/spin_dirs = list(
|
||||
NORTH,
|
||||
SOUTH,
|
||||
|
||||
@@ -35,7 +35,7 @@ var/global/list/emotes_by_key
|
||||
var/list/emote_sound_synthetic // As above, but used when check_synthetic() is true.
|
||||
var/emote_volume = 50 // Volume of sound to play.
|
||||
var/emote_volume_synthetic = 50 // As above, but used when check_synthetic() is true.
|
||||
var/emote_delay = 0 // Time in ds that this emote will block further emote use (spam prevention).
|
||||
var/emote_delay = 1.2 SECONDS // Time in ds that this emote will block further emote use (spam prevention). // VOREStation Edit
|
||||
|
||||
var/message_type = VISIBLE_MESSAGE // Audible/visual flag
|
||||
var/check_restraints // Can this emote be used while restrained?
|
||||
@@ -103,11 +103,14 @@ var/global/list/emotes_by_key
|
||||
if(target)
|
||||
use_1p = replace_target_tokens(use_1p, target)
|
||||
use_1p = "<span class='emote'>[capitalize(replace_user_tokens(use_1p, user))]</span>"
|
||||
var/use_3p = get_emote_message_3p(user, target, extra_params)
|
||||
if(use_3p)
|
||||
var/prefinal_3p
|
||||
var/use_3p
|
||||
var/raw_3p = get_emote_message_3p(user, target, extra_params)
|
||||
if(raw_3p)
|
||||
if(target)
|
||||
use_3p = replace_target_tokens(use_3p, target)
|
||||
use_3p = "<span class='emote'><b>\The [user]</b> [replace_user_tokens(use_3p, user)]</span>"
|
||||
raw_3p = replace_target_tokens(raw_3p, target)
|
||||
prefinal_3p = replace_user_tokens(raw_3p, user)
|
||||
use_3p = "<span class='emote'><b>\The [user]</b> [prefinal_3p]</span>"
|
||||
var/use_radio = get_radio_message(user)
|
||||
if(use_radio)
|
||||
if(target)
|
||||
@@ -124,12 +127,12 @@ var/global/list/emotes_by_key
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(L.silent)
|
||||
M.visible_message(message = "[user] opens their mouth silently!", self_message = "You cannot say anything!", blind_message = emote_message_impaired)
|
||||
M.visible_message(message = "[user] opens their mouth silently!", self_message = "You cannot say anything!", blind_message = emote_message_impaired, runemessage = "opens their mouth silently!")
|
||||
return
|
||||
else
|
||||
M.audible_message(message = use_3p, self_message = use_1p, deaf_message = emote_message_impaired, hearing_distance = use_range, radio_message = use_radio)
|
||||
M.audible_message(message = use_3p, self_message = use_1p, deaf_message = emote_message_impaired, hearing_distance = use_range, radio_message = use_radio, runemessage = prefinal_3p)
|
||||
else
|
||||
M.visible_message(message = use_3p, self_message = use_1p, blind_message = emote_message_impaired, range = use_range)
|
||||
M.visible_message(message = use_3p, self_message = use_1p, blind_message = emote_message_impaired, range = use_range, runemessage = prefinal_3p)
|
||||
|
||||
do_extra(user, target)
|
||||
do_sound(user)
|
||||
|
||||
@@ -86,7 +86,8 @@
|
||||
return
|
||||
|
||||
if(use_emote.message_type == AUDIBLE_MESSAGE && is_muzzled())
|
||||
audible_message("<b>\The [src]</b> [use_emote.emote_message_muffled || "makes a muffled sound."]")
|
||||
var/muffle_message = use_emote.emote_message_muffled || "makes a muffled sound."
|
||||
audible_message("<b>\The [src]</b> [muffle_message]", runemessage = "* [muffle_message] *")
|
||||
return
|
||||
|
||||
next_emote = world.time + use_emote.emote_delay
|
||||
@@ -149,7 +150,7 @@
|
||||
subtext = html_encode(subtext)
|
||||
// Store the player's name in a nice bold, naturalement
|
||||
nametext = "<B>[emoter]</B>"
|
||||
return pretext + nametext + subtext
|
||||
return list("pretext" = pretext, "nametext" = nametext, "subtext" = subtext)
|
||||
|
||||
/mob/proc/custom_emote(var/m_type = VISIBLE_MESSAGE, var/message, var/range = world.view)
|
||||
|
||||
@@ -163,8 +164,14 @@
|
||||
else
|
||||
input = message
|
||||
|
||||
var/list/formatted
|
||||
var/runemessage
|
||||
if(input)
|
||||
message = format_emote(src, message)
|
||||
formatted = format_emote(src, message)
|
||||
message = formatted["pretext"] + formatted["nametext"] + formatted["subtext"]
|
||||
runemessage = formatted["subtext"]
|
||||
// This is just personal preference (but I'm objectively right) that custom emotes shouldn't have periods at the end in runechat
|
||||
runemessage = replacetext(runemessage,".","",length(runemessage),length(runemessage)+1)
|
||||
else
|
||||
return
|
||||
|
||||
@@ -192,6 +199,7 @@
|
||||
if(isobserver(M))
|
||||
message = "<span class='emote'><B>[src]</B> ([ghost_follow_link(src, M)]) [input]</span>"
|
||||
M.show_message(message, m_type)
|
||||
M.create_chat_message(src, "[runemessage]", FALSE, list("emote"), (m_type == AUDIBLE_MESSAGE))
|
||||
|
||||
for(var/obj in o_viewers)
|
||||
var/obj/O = obj
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/bugball
|
||||
name = "bugball"
|
||||
desc = "A hard chitin, dont chip a tooth!"
|
||||
desc = "A hard piece of chitin, don't chip a tooth!"
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "pillbugball"
|
||||
slice_path = /obj/item/weapon/reagent_containers/food/snacks/pillbug
|
||||
@@ -250,7 +250,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/lobster
|
||||
name = "raw lobster"
|
||||
desc = "a shifty lobster. You can try eating it, but its shell is extremely tough."
|
||||
desc = "A shifty lobster. You can try eating it, but its shell is extremely tough."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "lobster_raw"
|
||||
nutriment_amt = 5
|
||||
@@ -261,7 +261,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/lobstercooked
|
||||
name = "cooked lobster"
|
||||
desc = "a luxurious plate of cooked lobster, its taste accentuated by lemon juice. Reinvigorating!"
|
||||
desc = "A luxurious plate of cooked lobster, its taste accentuated by lemon juice. Reinvigorating!"
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "lobster_cooked"
|
||||
trash = /obj/item/trash/plate
|
||||
@@ -277,7 +277,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cuttlefish
|
||||
name = "raw cuttlefish"
|
||||
desc = "it's an adorable squid! you can't possible be thinking about eating this right?"
|
||||
desc = "It's an adorable squid! You couldn't possibly be thinking about eating this, right?"
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "cuttlefish_raw"
|
||||
nutriment_amt = 5
|
||||
@@ -288,7 +288,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cuttlefishcooked
|
||||
name = "cooked cuttlefish"
|
||||
desc = "it's a roasted cuttlefish. rubbery, squishy, an acquired taste."
|
||||
desc = "It's a roasted cuttlefish. Rubbery, squishy, an acquired taste."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "cuttlefish_cooked"
|
||||
nutriment_amt = 20
|
||||
@@ -301,7 +301,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sliceable/monkfish
|
||||
name = "extra large monkfish"
|
||||
desc = "it's a huge monkfish. better clean it first, you can't possibly eat it like this."
|
||||
desc = "It's a huge monkfish. Better clean it first, you can't possibly eat it like this."
|
||||
icon = 'icons/obj/food48x48_vr.dmi'
|
||||
icon_state = "monkfish_raw"
|
||||
nutriment_amt = 30
|
||||
@@ -316,7 +316,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkfishfillet
|
||||
name = "monkfish fillet"
|
||||
desc = "it's a fillet sliced from a monkfish."
|
||||
desc = "It's a fillet sliced from a monkfish."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "monkfish_fillet"
|
||||
nutriment_amt = 5
|
||||
@@ -328,7 +328,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkfishcooked
|
||||
name = "seasoned monkfish"
|
||||
desc = "a delicious slice of monkfish prepared with sweet chili and spring onion."
|
||||
desc = "A delicious slice of monkfish prepared with sweet chili and spring onion."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "monkfish_cooked"
|
||||
nutriment_amt = 10
|
||||
@@ -344,7 +344,7 @@
|
||||
name = "monkfish remains"
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "monkfish_remains"
|
||||
desc = "the work of a madman."
|
||||
desc = "The work of a madman."
|
||||
w_class = ITEMSIZE_LARGE
|
||||
nutriment_amt = 10
|
||||
slice_path = /obj/item/clothing/head/fish
|
||||
@@ -357,7 +357,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sliceable/sharkchunk
|
||||
name = "chunk of shark meat"
|
||||
desc = "still rough, needs to be cut into even smaller chunks."
|
||||
desc = "Still rough, needs to be cut into even smaller chunks."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "sharkmeat_chunk"
|
||||
nutriment_amt = 15
|
||||
@@ -371,8 +371,8 @@
|
||||
reagents.add_reagent("protein", 20)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/carpmeat/fish/sharkmeat
|
||||
name = "a slice of sharkmeat"
|
||||
desc = "now it's small enough to cook with."
|
||||
name = "slice of sharkmeat"
|
||||
desc = "Now it's small enough to cook with."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "sharkmeat"
|
||||
nutriment_amt = 2
|
||||
@@ -385,7 +385,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sharkmeatcooked
|
||||
name = "shark steak"
|
||||
desc = "finally, some food for real men."
|
||||
desc = "Finally, some food for real men."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "sharkmeat_cooked"
|
||||
nutriment_amt = 5
|
||||
@@ -399,7 +399,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sharkmeatdip
|
||||
name = "hot shark shank"
|
||||
desc = "a shank of shark meat dipped in hot sauce."
|
||||
desc = "A shank of shark meat dipped in hot sauce."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "sharkmeat_dip"
|
||||
nutriment_amt = 5
|
||||
@@ -414,7 +414,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sharkmeatcubes
|
||||
name = "shark cubes"
|
||||
desc = "foul scented fermented shark cubes, it's said to make men fly, or just make them really fat."
|
||||
desc = "Foul scented fermented shark cubes, it's said to make men fly, or just make them really fat."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "sharkmeat_cubes"
|
||||
nutriment_amt = 8
|
||||
@@ -616,7 +616,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grub
|
||||
name = "grub"
|
||||
desc = "a still writhing grub, soft and squishy."
|
||||
desc = "A still writhing grub, soft and squishy."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "grub"
|
||||
nutriment_amt = 3
|
||||
@@ -629,7 +629,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grub_pink
|
||||
name = "pink candy grub"
|
||||
desc = "a thoroughly candied grub, it smells of raspberry."
|
||||
desc = "A thoroughly candied grub, it smells of raspberry."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "grub_pink"
|
||||
nutriment_amt = 5
|
||||
@@ -641,7 +641,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grub_purple
|
||||
name = "pink candy grub"
|
||||
desc = "a thoroughly candied grub, it smells of grape."
|
||||
desc = "A thoroughly candied grub, it smells of grape."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "grub_purple"
|
||||
nutriment_amt = 5
|
||||
@@ -653,7 +653,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grub_blue
|
||||
name = "pink candy grub"
|
||||
desc = "a thoroughly candied grub, it smells of blueberry."
|
||||
desc = "A thoroughly candied grub, it smells of blueberry."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "grub_blue"
|
||||
nutriment_amt = 5
|
||||
@@ -665,7 +665,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/scorpion
|
||||
name = "scorpion"
|
||||
desc = "a scorpion from the sandy deserts, don't get stung!"
|
||||
desc = "A scorpion from the sandy deserts, don't get stung!"
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "scorpion"
|
||||
nutriment_amt = 8
|
||||
@@ -677,7 +677,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/scorpion_cooked
|
||||
name = "cooked scorpion"
|
||||
desc = "a scorpion baked nice and crispy"
|
||||
desc = "A scorpion. Baked nice and crispy."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "scorpion_cooked"
|
||||
nutriment_amt = 6
|
||||
@@ -691,7 +691,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ant
|
||||
name = "giant honey ant"
|
||||
desc = "a sweetly scented honey ant. it has a huge swollen abdomen full of yummy."
|
||||
desc = "A sweetly scented honey ant. It has a huge swollen abdomen full of yummy."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "honeyant"
|
||||
nutriment_amt = 2
|
||||
@@ -707,7 +707,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/antball
|
||||
name = "giant honey ball"
|
||||
desc = "a sweetly scented honey ball, minus the ant. For those who don't like bug bits between their teeth."
|
||||
desc = "A sweetly scented honey ball, minus the ant. For those who don't like bug bits between their teeth."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "honeyant_clean"
|
||||
nutriment_amt = 4
|
||||
@@ -720,7 +720,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/honey_candy
|
||||
name = "honey candy"
|
||||
desc = "a clever mimicery of a honey ant abdomen, but it's just a piece of candy. Does not contain actual honey"
|
||||
desc = "A clever mimicry of a honey ant abdomen, but it's just a piece of candy. Does not contain actual honey!"
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "candy_honey"
|
||||
nutriment_amt = 4
|
||||
@@ -735,7 +735,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/locust
|
||||
name = "yellow jacket locust"
|
||||
desc = "a vibrant bug that looks like a wasp, but is in fact a locust. Crunchy"
|
||||
desc = "A vibrant bug that looks like a wasp, but is in fact a locust. Crunchy."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "locust"
|
||||
nutriment_amt = 4
|
||||
@@ -748,7 +748,7 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/locust_cooked
|
||||
name = "fried locust"
|
||||
desc = "a fried locust, extremely crunchy"
|
||||
desc = "A fried locust, extremely crunchy."
|
||||
icon = 'icons/obj/food_vr.dmi'
|
||||
icon_state = "locust_cooked"
|
||||
nutriment_amt = 2
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
text = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(text))
|
||||
var/obj/O = assembly ? loc : assembly
|
||||
audible_message("[bicon(O)] \The [O.name] states, \"[text]\"")
|
||||
audible_message("[bicon(O)] \The [O.name] states, \"[text]\"", runemessage = text)
|
||||
|
||||
/obj/item/integrated_circuit/output/text_to_speech/advanced
|
||||
name = "advanced text-to-speech circuit"
|
||||
|
||||
@@ -240,8 +240,10 @@ turf/simulated/mineral/floor/light_corner
|
||||
spawn(1) // Otherwise most of the ore is lost to the explosion, which makes this rather moot.
|
||||
for(var/ore in resources)
|
||||
var/amount_to_give = rand(CEILING(resources[ore]/2, 1), resources[ore]) // Should result in at least one piece of ore.
|
||||
var/oretype = ore_types[ore]
|
||||
if(!oretype)
|
||||
return // this turf can't give that type
|
||||
for(var/i=1, i <= amount_to_give, i++)
|
||||
var/oretype = ore_types[ore]
|
||||
new oretype(src)
|
||||
resources[ore] = 0
|
||||
|
||||
|
||||
@@ -32,12 +32,8 @@ var/global/list/prevent_respawns = list()
|
||||
qdel(O)
|
||||
|
||||
//Resleeving cleanup
|
||||
if(src.mind.name in SStranscore.backed_up)
|
||||
var/datum/transhuman/mind_record/MR = SStranscore.backed_up[src.mind.name]
|
||||
SStranscore.stop_backup(MR)
|
||||
if(src.mind.name in SStranscore.body_scans) //This uses mind names to avoid people cryo'ing a printed body to delete body scans.
|
||||
var/datum/transhuman/body_record/BR = SStranscore.body_scans[src.mind.name]
|
||||
SStranscore.remove_body(BR)
|
||||
if(mind)
|
||||
SStranscore.leave_round(src)
|
||||
|
||||
//Job slot cleanup
|
||||
var/job = src.mind.assigned_role
|
||||
|
||||
@@ -481,6 +481,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/proc/update_following()
|
||||
. = get_turf(src)
|
||||
for(var/mob/observer/dead/M in following_mobs)
|
||||
if(!.)
|
||||
M.stop_following()
|
||||
|
||||
if(M.following != src)
|
||||
following_mobs -= M
|
||||
else
|
||||
|
||||
@@ -62,18 +62,22 @@
|
||||
set name = "Notify Transcore"
|
||||
set desc = "If your past-due backup notification was missed or ignored, you can use this to send a new one."
|
||||
|
||||
if(src.mind && (src.mind.name in SStranscore.backed_up))
|
||||
var/datum/transhuman/mind_record/record = SStranscore.backed_up[src.mind.name]
|
||||
if(!mind)
|
||||
to_chat(src,"<span class='warning'>Your ghost is missing game values that allow this functionality, sorry.</span>")
|
||||
return
|
||||
var/datum/transcore_db/db = SStranscore.db_by_mind_name(mind.name)
|
||||
if(db)
|
||||
var/datum/transhuman/mind_record/record = db.backed_up[src.mind.name]
|
||||
if(!(record.dead_state == MR_DEAD))
|
||||
to_chat(src, "<span class='warning'>Your backup is not past-due yet.</span>")
|
||||
else if((world.time - record.last_notification) < 10 MINUTES)
|
||||
to_chat(src, "<span class='warning'>Too little time has passed since your last notification.</span>")
|
||||
else
|
||||
SStranscore.notify(record.mindname, TRUE)
|
||||
db.notify(record.mindname, TRUE)
|
||||
record.last_notification = world.time
|
||||
to_chat(src, "<span class='notice'>New notification has been sent.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='warning'>No mind record found!</span>")
|
||||
to_chat(src,"<span class='warning'>No backup record could be found, sorry.</span>")
|
||||
|
||||
/mob/observer/dead/verb/findghostpod() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
|
||||
set category = "Ghost"
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
/mob/proc/combine_message(var/list/message_pieces, var/verb, var/mob/speaker, always_stars = FALSE, var/radio = FALSE)
|
||||
var/iteration_count = 0
|
||||
var/msg = "" // This is to make sure that the pieces have actually added something
|
||||
. = "[verb], \""
|
||||
var/raw_msg = ""
|
||||
. = list("formatted" = "[verb], \"", "raw" = "")
|
||||
|
||||
for(var/datum/multilingual_say_piece/SP in message_pieces)
|
||||
iteration_count++
|
||||
var/piece = SP.message
|
||||
@@ -11,9 +13,13 @@
|
||||
|
||||
if(SP.speaking && SP.speaking.flags & INNATE) // Snowflake for noise lang
|
||||
if(radio)
|
||||
return SP.speaking.format_message_radio(piece)
|
||||
.["formatted"] = SP.speaking.format_message_radio(piece)
|
||||
.["raw"] = piece
|
||||
return
|
||||
else
|
||||
return SP.speaking.format_message(piece)
|
||||
.["formatted"] = SP.speaking.format_message(piece)
|
||||
.["raw"] = piece
|
||||
return
|
||||
|
||||
if(iteration_count == 1)
|
||||
piece = capitalize(piece)
|
||||
@@ -27,6 +33,9 @@
|
||||
if(istype(S.say_list) && length(S.say_list.speak))
|
||||
piece = pick(S.say_list.speak)
|
||||
|
||||
raw_msg += (piece + " ")
|
||||
|
||||
//HTML formatting
|
||||
if(!SP.speaking) // Catch the most generic case first
|
||||
piece = "<span class='message body'>[piece]</span>"
|
||||
else if(radio) // SP.speaking == TRUE enforced by previous !SP.speaking
|
||||
@@ -38,10 +47,11 @@
|
||||
|
||||
if(msg == "")
|
||||
// There is literally no content left in this message, we need to shut this shit down
|
||||
. = "" // hear_say will suppress it
|
||||
.["formatted"] = "" // hear_say will suppress it
|
||||
else
|
||||
. = trim(. + trim(msg))
|
||||
. += "\""
|
||||
.["formatted"] = trim(.["formatted"] + trim(msg))
|
||||
.["formatted"] += "\""
|
||||
.["raw"] = trim(raw_msg)
|
||||
|
||||
/mob/proc/saypiece_scramble(datum/multilingual_say_piece/SP)
|
||||
if(SP.speaking)
|
||||
@@ -76,7 +86,8 @@
|
||||
var/mob/living/carbon/human/H = speaker
|
||||
speaker_name = H.GetVoice()
|
||||
|
||||
var/message = combine_message(message_pieces, verb, speaker)
|
||||
var/list/combined = combine_message(message_pieces, verb, speaker)
|
||||
var/message = combined["formatted"]
|
||||
if(message == "")
|
||||
return
|
||||
|
||||
@@ -109,6 +120,7 @@
|
||||
message_to_send = "<font size='3'><b>[message_to_send]</b></font>"
|
||||
|
||||
on_hear_say(message_to_send)
|
||||
create_chat_message(speaker, combined["raw"], italics, list())
|
||||
|
||||
if(speech_sound && (get_dist(speaker, src) <= world.view && z == speaker.z))
|
||||
var/turf/source = speaker ? get_turf(speaker) : get_turf(src)
|
||||
@@ -164,7 +176,8 @@
|
||||
if(!client)
|
||||
return
|
||||
|
||||
var/message = combine_message(message_pieces, verb, speaker, always_stars = hard_to_hear, radio = TRUE)
|
||||
var/list/combined = combine_message(message_pieces, verb, speaker, always_stars = hard_to_hear, radio = TRUE)
|
||||
var/message = combined["formatted"]
|
||||
if(sleeping || stat == UNCONSCIOUS) //If unconscious or sleeping
|
||||
hear_sleep(multilingual_to_message(message_pieces))
|
||||
return
|
||||
@@ -272,7 +285,8 @@
|
||||
return
|
||||
|
||||
/mob/proc/hear_holopad_talk(list/message_pieces, var/verb = "says", var/mob/speaker = null)
|
||||
var/message = combine_message(message_pieces, verb, speaker)
|
||||
var/list/combined = combine_message(message_pieces, verb, speaker)
|
||||
var/message = combined["formatted"]
|
||||
|
||||
var/name = speaker.name
|
||||
if(!say_understands(speaker))
|
||||
|
||||
@@ -38,14 +38,14 @@
|
||||
|
||||
for(var/obj/item/organ/external/E in organs)
|
||||
for(var/obj/item/weapon/implant/I in E.implants)
|
||||
if(I.implanted)
|
||||
if(istype(I,/obj/item/weapon/implant/backup))
|
||||
if(!mind)
|
||||
holder.icon_state = "hud_backup_nomind"
|
||||
else if(!(mind.name in SStranscore.body_scans))
|
||||
holder.icon_state = "hud_backup_nobody"
|
||||
else
|
||||
holder.icon_state = "hud_backup_norm"
|
||||
if(I.implanted && istype(I,/obj/item/weapon/implant/backup))
|
||||
var/obj/item/weapon/implant/backup/B = I
|
||||
if(!mind)
|
||||
holder.icon_state = "hud_backup_nomind"
|
||||
else if(!(mind.name in B.our_db.body_scans))
|
||||
holder.icon_state = "hud_backup_nobody"
|
||||
else
|
||||
holder.icon_state = "hud_backup_norm"
|
||||
|
||||
apply_hud(BACKUP_HUD, holder)
|
||||
|
||||
|
||||
@@ -1,57 +1,63 @@
|
||||
var/list/department_radio_keys = list(
|
||||
":r" = "right ear", ".r" = "right ear",
|
||||
":l" = "left ear", ".l" = "left ear",
|
||||
":i" = "intercom", ".i" = "intercom",
|
||||
":h" = "department", ".h" = "department",
|
||||
":+" = "special", ".+" = "special", //activate radio-specific special functions
|
||||
":c" = "Command", ".c" = "Command",
|
||||
":n" = "Science", ".n" = "Science",
|
||||
":m" = "Medical", ".m" = "Medical",
|
||||
":e" = "Engineering", ".e" = "Engineering",
|
||||
":k" = "Response Team", ".k" = "Response Team",
|
||||
":s" = "Security", ".s" = "Security",
|
||||
":w" = "whisper", ".w" = "whisper",
|
||||
":t" = "Mercenary", ".t" = "Mercenary",
|
||||
":x" = "Raider", ".x" = "Raider",
|
||||
":u" = "Supply", ".u" = "Supply",
|
||||
":v" = "Service", ".v" = "Service",
|
||||
":p" = "AI Private", ".p" = "AI Private",
|
||||
":y" = "Explorer", ".y" = "Explorer",
|
||||
":a" = "Talon", ".a" = "Talon", //VOREStation Add,
|
||||
":r" = "right ear", ".r" = "right ear",
|
||||
":l" = "left ear", ".l" = "left ear",
|
||||
":i" = "intercom", ".i" = "intercom",
|
||||
":h" = "department", ".h" = "department",
|
||||
":+" = "special", ".+" = "special", //activate radio-specific special functions
|
||||
":c" = "Command", ".c" = "Command",
|
||||
":n" = "Science", ".n" = "Science",
|
||||
":m" = "Medical", ".m" = "Medical",
|
||||
":e" = "Engineering", ".e" = "Engineering",
|
||||
":k" = "Response Team", ".k" = "Response Team",
|
||||
":s" = "Security", ".s" = "Security",
|
||||
":w" = "whisper", ".w" = "whisper",
|
||||
":t" = "Mercenary", ".t" = "Mercenary",
|
||||
":x" = "Raider", ".x" = "Raider",
|
||||
":u" = "Supply", ".u" = "Supply",
|
||||
":v" = "Service", ".v" = "Service",
|
||||
":p" = "AI Private", ".p" = "AI Private",
|
||||
":y" = "Explorer", ".y" = "Explorer",
|
||||
":a" = "Talon", ".a" = "Talon", //VOREStation Add,
|
||||
|
||||
":R" = "right ear", ".R" = "right ear",
|
||||
":L" = "left ear", ".L" = "left ear",
|
||||
":I" = "intercom", ".I" = "intercom",
|
||||
":H" = "department", ".H" = "department",
|
||||
":C" = "Command", ".C" = "Command",
|
||||
":N" = "Science", ".N" = "Science",
|
||||
":M" = "Medical", ".M" = "Medical",
|
||||
":E" = "Engineering", ".E" = "Engineering",
|
||||
":k" = "Response Team", ".k" = "Response Team",
|
||||
":S" = "Security", ".S" = "Security",
|
||||
":W" = "whisper", ".W" = "whisper",
|
||||
":T" = "Mercenary", ".T" = "Mercenary",
|
||||
":X" = "Raider", ".X" = "Raider",
|
||||
":U" = "Supply", ".U" = "Supply",
|
||||
":V" = "Service", ".V" = "Service",
|
||||
":P" = "AI Private", ".P" = "AI Private",
|
||||
":Y" = "Explorer", ".Y" = "Explorer",
|
||||
":A" = "Talon", ".A" = "Talon", //VOREStation Add,
|
||||
":R" = "right ear", ".R" = "right ear",
|
||||
":L" = "left ear", ".L" = "left ear",
|
||||
":I" = "intercom", ".I" = "intercom",
|
||||
":H" = "department", ".H" = "department",
|
||||
":C" = "Command", ".C" = "Command",
|
||||
":N" = "Science", ".N" = "Science",
|
||||
":M" = "Medical", ".M" = "Medical",
|
||||
":E" = "Engineering", ".E" = "Engineering",
|
||||
":k" = "Response Team", ".k" = "Response Team",
|
||||
":S" = "Security", ".S" = "Security",
|
||||
":W" = "whisper", ".W" = "whisper",
|
||||
":T" = "Mercenary", ".T" = "Mercenary",
|
||||
":X" = "Raider", ".X" = "Raider",
|
||||
":U" = "Supply", ".U" = "Supply",
|
||||
":V" = "Service", ".V" = "Service",
|
||||
":P" = "AI Private", ".P" = "AI Private",
|
||||
":Y" = "Explorer", ".Y" = "Explorer",
|
||||
":A" = "Talon", ".A" = "Talon", //VOREStation Add,
|
||||
|
||||
//kinda localization -- rastaf0
|
||||
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.
|
||||
":ê" = "right ear", ".ê" = "right ear",
|
||||
":ä" = "left ear", ".ä" = "left ear",
|
||||
":ø" = "intercom", ".ø" = "intercom",
|
||||
":ð" = "department", ".ð" = "department",
|
||||
":ñ" = "Command", ".ñ" = "Command",
|
||||
":ò" = "Science", ".ò" = "Science",
|
||||
":ü" = "Medical", ".ü" = "Medical",
|
||||
":ó" = "Engineering", ".ó" = "Engineering",
|
||||
":û" = "Security", ".û" = "Security",
|
||||
":ö" = "whisper", ".ö" = "whisper",
|
||||
":å" = "Mercenary", ".å" = "Mercenary",
|
||||
":é" = "Supply", ".é" = "Supply",
|
||||
// Cyrillic characters on the same keys on the Russian QWERTY (phonetic) layout
|
||||
":к" = "right ear", ".к" = "right ear",
|
||||
":д" = "left ear", ".д" = "left ear",
|
||||
":ш" = "intercom", ".ш" = "intercom",
|
||||
":р" = "department", ".р" = "department",
|
||||
":+" = "special", ".+" = "special", //activate radio-specific special functions
|
||||
":с" = "Command", ".с" = "Command",
|
||||
":т" = "Science", ".т" = "Science",
|
||||
":ь" = "Medical", ".ь" = "Medical",
|
||||
":у" = "Engineering", ".у" = "Engineering",
|
||||
":л" = "Response Team", ".л" = "Response Team",
|
||||
":ы" = "Security", ".ы" = "Security",
|
||||
":ц" = "whisper", ".ц" = "whisper",
|
||||
":е" = "Mercenary", ".е" = "Mercenary",
|
||||
":ч" = "Raider", ".ч" = "Raider",
|
||||
":г" = "Supply", ".г" = "Supply",
|
||||
":м" = "Service", ".м" = "Service",
|
||||
":з" = "AI Private", ".з" = "AI Private",
|
||||
":н" = "Explorer", ".н" = "Explorer",
|
||||
":ф" = "Talon", ".ф" = "Talon" //VOREStation Add
|
||||
)
|
||||
|
||||
|
||||
@@ -362,16 +368,17 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
//VOREStation Add End
|
||||
|
||||
var/dst = get_dist(get_turf(M),get_turf(src))
|
||||
var/runechat_enabled = M.client?.is_preference_enabled(/datum/client_preference/runechat_mob)
|
||||
|
||||
if(dst <= message_range || (M.stat == DEAD && !forbid_seeing_deadchat)) //Inside normal message range, or dead with ears (handled in the view proc)
|
||||
if(M.client)
|
||||
if(M.client && !runechat_enabled)
|
||||
var/image/I1 = listening[M] || speech_bubble
|
||||
images_to_clients[I1] |= M.client
|
||||
M << I1
|
||||
M.hear_say(message_pieces, verb, italics, src, speech_sound, sound_vol)
|
||||
if(whispering && !isobserver(M)) //Don't even bother with these unless whispering
|
||||
if(dst > message_range && dst <= w_scramble_range) //Inside whisper scramble range
|
||||
if(M.client)
|
||||
if(M.client && !runechat_enabled)
|
||||
var/image/I2 = listening[M] || speech_bubble
|
||||
images_to_clients[I2] |= M.client
|
||||
M << I2
|
||||
|
||||
@@ -1,126 +1,127 @@
|
||||
/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode)
|
||||
if(!is_component_functioning("radio"))
|
||||
to_chat(src, "<span class='warning'>Your radio isn't functional at this time.</span>")
|
||||
return 0
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/speech_bubble_appearance()
|
||||
return "synthetic"
|
||||
|
||||
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode == "department")
|
||||
return holopad_talk(message, verb, speaking)
|
||||
else if(message_mode)
|
||||
if (aiRadio.disabledAi || aiRestorePowerRoutine || stat)
|
||||
to_chat(src, "<span class='danger'>System Error - Transceiver Disabled.</span>")
|
||||
return 0
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return aiRadio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode)
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/say_quote(var/text)
|
||||
var/ending = copytext(text, length(text))
|
||||
|
||||
if (ending == "?")
|
||||
return speak_query
|
||||
else if (ending == "!")
|
||||
return speak_exclamation
|
||||
|
||||
return speak_statement
|
||||
|
||||
#define IS_AI 1
|
||||
#define IS_ROBOT 2
|
||||
#define IS_PAI 3
|
||||
|
||||
/mob/living/silicon/say_understands(var/other, var/datum/language/speaking = null)
|
||||
//These only pertain to common. Languages are handled by mob/say_understands()
|
||||
if(!speaking)
|
||||
if(iscarbon(other))
|
||||
return TRUE
|
||||
if(issilicon(other))
|
||||
return TRUE
|
||||
if(isbrain(other))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
//For holopads only. Usable by AI.
|
||||
/mob/living/silicon/ai/proc/holopad_talk(list/message_pieces, verb)
|
||||
log_say("(HPAD) [multilingual_to_message(message_pieces)]",src)
|
||||
|
||||
var/obj/machinery/hologram/holopad/T = src.holo
|
||||
if(T && T.masters[src])//If there is a hologram and its master is the user.
|
||||
var/list/listeners = get_mobs_and_objs_in_view_fast(get_turf(T), world.view)
|
||||
var/list/listening = listeners["mobs"]
|
||||
var/list/listening_obj = listeners["objs"]
|
||||
for(var/mob/M in listening)
|
||||
M.hear_holopad_talk(message_pieces, verb, src)
|
||||
for(var/obj/O in listening_obj)
|
||||
if(O == T) //Don't recieve your own speech
|
||||
continue
|
||||
O.hear_talk(src, message_pieces, verb)
|
||||
/*Radios "filter out" this conversation channel so we don't need to account for them.
|
||||
This is another way of saying that we won't bother dealing with them.*/
|
||||
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [combine_message(message_pieces, verb, src)]</span></i>")
|
||||
else
|
||||
to_chat(src, "No holopad connected.")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/proc/holopad_emote(var/message) //This is called when the AI uses the 'me' verb while using a holopad.
|
||||
message = trim(message)
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
var/obj/machinery/hologram/holopad/T = src.holo
|
||||
if(T && T.masters[src])
|
||||
var/rendered = "<span class='game say'><span class='name'>[name]</span> <span class='message'>[message]</span></span>"
|
||||
to_chat(src, "<i><span class='game say'>Holopad action relayed, <span class='name'>[real_name]</span> <span class='message'>[message]</span></span></i>")
|
||||
var/obj/effect/overlay/aiholo/hologram = T.masters[src] //VOREStation Add for people in the hologram to hear the messages
|
||||
|
||||
//var/obj/effect/overlay/hologram = T.masters[src] //VOREStation edit. Done above.
|
||||
var/list/in_range = get_mobs_and_objs_in_view_fast(get_turf(hologram), world.view, 2) //Emotes are displayed from the hologram, not the pad
|
||||
var/list/m_viewers = in_range["mobs"]
|
||||
var/list/o_viewers = in_range["objs"]
|
||||
|
||||
for(var/mob/M in m_viewers)
|
||||
spawn(0)
|
||||
if(M)
|
||||
M.show_message(rendered, 2)
|
||||
|
||||
for(var/obj/O in o_viewers)
|
||||
if(O == T)
|
||||
continue
|
||||
spawn(0)
|
||||
if(O)
|
||||
O.see_emote(src, message)
|
||||
|
||||
log_emote("(HPAD) [message]", src)
|
||||
|
||||
else //This shouldn't occur, but better safe then sorry.
|
||||
to_chat(src, "No holopad connected.")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/emote(var/act, var/m_type, var/message)
|
||||
var/obj/machinery/hologram/holopad/T = holo
|
||||
if(T && T.masters[src]) //Is the AI using a holopad?
|
||||
. = holopad_emote(message)
|
||||
else //Emote normally, then.
|
||||
. = ..()
|
||||
|
||||
#undef IS_AI
|
||||
#undef IS_ROBOT
|
||||
#undef IS_PAI
|
||||
/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode)
|
||||
if(!is_component_functioning("radio"))
|
||||
to_chat(src, "<span class='warning'>Your radio isn't functional at this time.</span>")
|
||||
return 0
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/speech_bubble_appearance()
|
||||
return "synthetic"
|
||||
|
||||
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode == "department")
|
||||
return holopad_talk(message, verb, speaking)
|
||||
else if(message_mode)
|
||||
if (aiRadio.disabledAi || aiRestorePowerRoutine || stat)
|
||||
to_chat(src, "<span class='danger'>System Error - Transceiver Disabled.</span>")
|
||||
return 0
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return aiRadio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode)
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/say_quote(var/text)
|
||||
var/ending = copytext(text, length(text))
|
||||
|
||||
if (ending == "?")
|
||||
return speak_query
|
||||
else if (ending == "!")
|
||||
return speak_exclamation
|
||||
|
||||
return speak_statement
|
||||
|
||||
#define IS_AI 1
|
||||
#define IS_ROBOT 2
|
||||
#define IS_PAI 3
|
||||
|
||||
/mob/living/silicon/say_understands(var/other, var/datum/language/speaking = null)
|
||||
//These only pertain to common. Languages are handled by mob/say_understands()
|
||||
if(!speaking)
|
||||
if(iscarbon(other))
|
||||
return TRUE
|
||||
if(issilicon(other))
|
||||
return TRUE
|
||||
if(isbrain(other))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
//For holopads only. Usable by AI.
|
||||
/mob/living/silicon/ai/proc/holopad_talk(list/message_pieces, verb)
|
||||
log_say("(HPAD) [multilingual_to_message(message_pieces)]",src)
|
||||
|
||||
var/obj/machinery/hologram/holopad/T = src.holo
|
||||
if(T && T.masters[src])//If there is a hologram and its master is the user.
|
||||
var/list/listeners = get_mobs_and_objs_in_view_fast(get_turf(T), world.view)
|
||||
var/list/listening = listeners["mobs"]
|
||||
var/list/listening_obj = listeners["objs"]
|
||||
for(var/mob/M in listening)
|
||||
M.hear_holopad_talk(message_pieces, verb, src)
|
||||
for(var/obj/O in listening_obj)
|
||||
if(O == T) //Don't recieve your own speech
|
||||
continue
|
||||
O.hear_talk(src, message_pieces, verb)
|
||||
/*Radios "filter out" this conversation channel so we don't need to account for them.
|
||||
This is another way of saying that we won't bother dealing with them.*/
|
||||
var/list/combined = combine_message(message_pieces, verb, src)
|
||||
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [combined["formatted"]]</span></i>")
|
||||
else
|
||||
to_chat(src, "No holopad connected.")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/proc/holopad_emote(var/message) //This is called when the AI uses the 'me' verb while using a holopad.
|
||||
message = trim(message)
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
var/obj/machinery/hologram/holopad/T = src.holo
|
||||
if(T && T.masters[src])
|
||||
var/rendered = "<span class='game say'><span class='name'>[name]</span> <span class='message'>[message]</span></span>"
|
||||
to_chat(src, "<i><span class='game say'>Holopad action relayed, <span class='name'>[real_name]</span> <span class='message'>[message]</span></span></i>")
|
||||
var/obj/effect/overlay/aiholo/hologram = T.masters[src] //VOREStation Add for people in the hologram to hear the messages
|
||||
|
||||
//var/obj/effect/overlay/hologram = T.masters[src] //VOREStation edit. Done above.
|
||||
var/list/in_range = get_mobs_and_objs_in_view_fast(get_turf(hologram), world.view, 2) //Emotes are displayed from the hologram, not the pad
|
||||
var/list/m_viewers = in_range["mobs"]
|
||||
var/list/o_viewers = in_range["objs"]
|
||||
|
||||
for(var/mob/M in m_viewers)
|
||||
spawn(0)
|
||||
if(M)
|
||||
M.show_message(rendered, 2)
|
||||
|
||||
for(var/obj/O in o_viewers)
|
||||
if(O == T)
|
||||
continue
|
||||
spawn(0)
|
||||
if(O)
|
||||
O.see_emote(src, message)
|
||||
|
||||
log_emote("(HPAD) [message]", src)
|
||||
|
||||
else //This shouldn't occur, but better safe then sorry.
|
||||
to_chat(src, "No holopad connected.")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/emote(var/act, var/m_type, var/message)
|
||||
var/obj/machinery/hologram/holopad/T = holo
|
||||
if(T && T.masters[src]) //Is the AI using a holopad?
|
||||
. = holopad_emote(message)
|
||||
else //Emote normally, then.
|
||||
. = ..()
|
||||
|
||||
#undef IS_AI
|
||||
#undef IS_ROBOT
|
||||
#undef IS_PAI
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
// message is the message output to anyone who can see e.g. "[src] does something!"
|
||||
// self_message (optional) is what the src mob sees e.g. "You do something!"
|
||||
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
|
||||
/mob/visible_message(var/message, var/self_message, var/blind_message, var/list/exclude_mobs = null, var/range = world.view)
|
||||
/mob/visible_message(var/message, var/self_message, var/blind_message, var/list/exclude_mobs = null, var/range = world.view, var/runemessage)
|
||||
if(self_message)
|
||||
if(LAZYLEN(exclude_mobs))
|
||||
exclude_mobs |= src
|
||||
@@ -87,7 +87,9 @@
|
||||
// Transfer messages about what we are doing to upstairs
|
||||
if(shadow)
|
||||
shadow.visible_message(message, self_message, blind_message, exclude_mobs, range)
|
||||
. = ..(message, blind_message, exclude_mobs, range) // Really not ideal that atom/visible_message has different arg numbering :(
|
||||
if(isnull(runemessage))
|
||||
runemessage = -1
|
||||
. = ..(message, blind_message, exclude_mobs, range, runemessage) // Really not ideal that atom/visible_message has different arg numbering :(
|
||||
|
||||
// Returns an amount of power drawn from the object (-1 if it's not viable).
|
||||
// If drain_check is set it will not actually drain power, just return a value.
|
||||
@@ -102,7 +104,7 @@
|
||||
// self_message (optional) is what the src mob hears.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
/mob/audible_message(var/message, var/deaf_message, var/hearing_distance, var/self_message, var/radio_message)
|
||||
/mob/audible_message(var/message, var/deaf_message, var/hearing_distance, var/self_message, var/radio_message, var/runemessage)
|
||||
|
||||
var/range = hearing_distance || world.view
|
||||
var/list/hear = get_mobs_and_objs_in_view_fast(get_turf(src),range,remote_ghosts = FALSE)
|
||||
@@ -110,6 +112,9 @@
|
||||
var/list/hearing_mobs = hear["mobs"]
|
||||
var/list/hearing_objs = hear["objs"]
|
||||
|
||||
if(isnull(runemessage))
|
||||
runemessage = -1 // Symmetry with mob/audible_message, despite the fact this one doesn't call parent. Maybe it should!
|
||||
|
||||
if(radio_message)
|
||||
for(var/obj in hearing_objs)
|
||||
var/obj/O = obj
|
||||
@@ -125,6 +130,8 @@
|
||||
if(self_message && M==src)
|
||||
msg = self_message
|
||||
M.show_message(msg, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE)
|
||||
if(runemessage != -1)
|
||||
M.create_chat_message(src, "[runemessage || message]", FALSE, list("emote"), audible = FALSE)
|
||||
|
||||
/mob/proc/findname(msg)
|
||||
for(var/mob/M in mob_list)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
var/obj/screen/shadekin/shadekin_display = null
|
||||
var/obj/screen/xenochimera/danger_level/xenochimera_danger_display = null
|
||||
|
||||
var/size_multiplier = 1 //multiplier for the mob's icon size
|
||||
|
||||
/mob/drop_location()
|
||||
if(temporary_form)
|
||||
return temporary_form.drop_location()
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
"You begin climbing [direction] \the [src]!",
|
||||
"You hear the grunting and clanging of a metal ladder being used.")
|
||||
|
||||
target_ladder.audible_message("<span class='notice'>You hear something coming [direction] \the [src]</span>")
|
||||
target_ladder.audible_message("<span class='notice'>You hear something coming [direction] \the [src]</span>", runemessage = "* clank clank *")
|
||||
|
||||
if(do_after(M, climb_time, src))
|
||||
var/turf/T = get_turf(target_ladder)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
if(lattice)
|
||||
var/pull_up_time = max(5 SECONDS + (src.movement_delay() * 10), 1)
|
||||
to_chat(src, "<span class='notice'>You grab \the [lattice] and start pulling yourself upward...</span>")
|
||||
destination.audible_message("<span class='notice'>You hear something climbing up \the [lattice].</span>")
|
||||
destination.audible_message("<span class='notice'>You hear something climbing up \the [lattice].</span>", runemessage = "* clank clang *")
|
||||
if(do_after(src, pull_up_time))
|
||||
to_chat(src, "<span class='notice'>You pull yourself up.</span>")
|
||||
else
|
||||
@@ -74,7 +74,7 @@
|
||||
if(!destination?.Enter(src, old_dest))
|
||||
to_chat(src, "<span class='notice'>There's something in the way up above in that direction, try another.</span>")
|
||||
return 0
|
||||
destination.audible_message("<span class='notice'>You hear something climbing up \the [catwalk].</span>")
|
||||
destination.audible_message("<span class='notice'>You hear something climbing up \the [catwalk].</span>", runemessage = "* clank clang *")
|
||||
if(do_after(src, pull_up_time))
|
||||
to_chat(src, "<span class='notice'>You pull yourself up.</span>")
|
||||
else
|
||||
@@ -90,8 +90,8 @@
|
||||
return 0
|
||||
var/fly_time = max(7 SECONDS + (H.movement_delay() * 10), 1) //So it's not too useful for combat. Could make this variable somehow, but that's down the road.
|
||||
to_chat(src, "<span class='notice'>You begin to fly upwards...</span>")
|
||||
destination.audible_message("<span class='notice'>You hear the flapping of wings.</span>")
|
||||
H.audible_message("<span class='notice'>[H] begins to flap \his wings, preparing to move upwards!</span>")
|
||||
destination.audible_message("<span class='notice'>You hear the flapping of wings.</span>", runemessage = "* flap flap *")
|
||||
H.audible_message("<span class='notice'>[H] begins to flap \his wings, preparing to move upwards!</span>", runemessage = "* flap flap *")
|
||||
if(do_after(H, fly_time) && H.flying)
|
||||
to_chat(src, "<span class='notice'>You fly upwards.</span>")
|
||||
else
|
||||
|
||||
@@ -77,7 +77,8 @@
|
||||
mobs_to_relay = in_range["mobs"]
|
||||
|
||||
for(var/mob/mob in mobs_to_relay)
|
||||
var/message = mob.combine_message(message_pieces, verb, M)
|
||||
var/list/combined = mob.combine_message(message_pieces, verb, M)
|
||||
var/message = combined["formatted"]
|
||||
var/name_used = M.GetVoice()
|
||||
var/rendered = null
|
||||
rendered = "<span class='game say'>[bicon(icon_object)] <span class='name'>[name_used]</span> [message]</span>"
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
if(!is_on())
|
||||
return 0
|
||||
if(!check_fuel() || (use_power_oneoff(charge_per_burn) < charge_per_burn) || check_blockage())
|
||||
audible_message(src,"<span class='warning'>[src] coughs once and goes silent!</span>")
|
||||
audible_message(src,"<span class='warning'>[src] coughs once and goes silent!</span>", runemessage = "* sputtercough *")
|
||||
update_use_power(USE_POWER_OFF)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -111,28 +111,28 @@
|
||||
playsound(src, "sound/machines/copier.ogg", 100, 1)
|
||||
sleep(11)
|
||||
copy(copyitem)
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it finishes printing.</span>")
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it finishes printing.</span>", runemessage = "* whirr *")
|
||||
playsound(src, "sound/machines/buzzbeep.ogg", 30)
|
||||
else if (istype(copyitem, /obj/item/weapon/photo))
|
||||
playsound(src, "sound/machines/copier.ogg", 100, 1)
|
||||
sleep(11)
|
||||
photocopy(copyitem)
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it finishes printing.</span>")
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it finishes printing.</span>", runemessage = "* whirr *")
|
||||
playsound(src, "sound/machines/buzzbeep.ogg", 30)
|
||||
else if (istype(copyitem, /obj/item/weapon/paper_bundle))
|
||||
sleep(11)
|
||||
playsound(src, "sound/machines/copier.ogg", 100, 1)
|
||||
var/obj/item/weapon/paper_bundle/B = bundlecopy(copyitem)
|
||||
sleep(11*B.pages.len)
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it finishes printing.</span>")
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it finishes printing.</span>", runemessage = "* whirr *")
|
||||
playsound(src, "sound/machines/buzzbeep.ogg", 30)
|
||||
else if (has_buckled_mobs()) // VOREStation EDIT: For ass-copying.
|
||||
playsound(src, "sound/machines/copier.ogg", 100, 1)
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it attempts to scan.</span>")
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it attempts to scan.</span>", runemessage = "* whirr *")
|
||||
sleep(rand(20,45)) // Sit with your bare ass on the copier for a random time, feel like a fool, get stared at.
|
||||
copyass(user)
|
||||
sleep(15)
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it finishes printing.</span>")
|
||||
audible_message("<span class='notice'>You can hear [src] whirring as it finishes printing.</span>", runemessage = "* whirr *")
|
||||
playsound(src, "sound/machines/buzzbeep.ogg", 30)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [copyitem] can't be copied by [src].</span>")
|
||||
|
||||
@@ -243,6 +243,7 @@
|
||||
desc = "A storage case for a multi-purpose handgun. Variety hour!"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
can_hold = list(/obj/item/weapon/gun/projectile/cell_loaded,/obj/item/ammo_magazine/cell_mag,/obj/item/ammo_casing/microbattery)
|
||||
|
||||
/obj/item/weapon/storage/secure/briefcase/nsfw_pack_hybrid/New()
|
||||
..()
|
||||
@@ -264,6 +265,7 @@
|
||||
desc = "A storage case for a multi-purpose handgun. Variety hour!"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
can_hold = list(/obj/item/weapon/gun/projectile/cell_loaded,/obj/item/ammo_magazine/cell_mag,/obj/item/ammo_casing/microbattery)
|
||||
|
||||
/obj/item/weapon/storage/secure/briefcase/nsfw_pack_hybrid_combat/New()
|
||||
..()
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
desc = "A storage case for a multi-purpose healing gun. Variety hour!"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
can_hold = list(/obj/item/weapon/gun/projectile/cell_loaded/medical,/obj/item/ammo_magazine/cell_mag/medical,/obj/item/ammo_casing/microbattery/medical)
|
||||
|
||||
/obj/item/weapon/storage/secure/briefcase/ml3m_pack_med/New()
|
||||
..()
|
||||
@@ -61,6 +62,7 @@
|
||||
desc = "A storage case for a multi-purpose healing gun. Variety hour!"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
can_hold = list(/obj/item/weapon/gun/projectile/cell_loaded/medical,/obj/item/ammo_magazine/cell_mag/medical,/obj/item/ammo_casing/microbattery/medical)
|
||||
|
||||
/obj/item/weapon/storage/secure/briefcase/ml3m_pack_cmo/New()
|
||||
..()
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
desc = "A storage case for a multi-purpose handgun. Variety hour!"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
can_hold = list(/obj/item/weapon/gun/projectile/cell_loaded/combat,/obj/item/ammo_magazine/cell_mag/combat,/obj/item/ammo_casing/microbattery/combat)
|
||||
|
||||
/obj/item/weapon/storage/secure/briefcase/nsfw_pack/New()
|
||||
..()
|
||||
@@ -61,6 +62,7 @@
|
||||
desc = "A storage case for a multi-purpose handgun. Variety hour!"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_w_class = ITEMSIZE_NORMAL
|
||||
can_hold = list(/obj/item/weapon/gun/projectile/cell_loaded/combat,/obj/item/ammo_magazine/cell_mag/combat,/obj/item/ammo_casing/microbattery/combat)
|
||||
|
||||
/obj/item/weapon/storage/secure/briefcase/nsfw_pack_hos/New()
|
||||
..()
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
|
||||
/obj/item/weapon/gun/magnetic/matfed/phoronbore/process()
|
||||
if(generator_state && !mat_storage)
|
||||
audible_message(SPAN_NOTICE("\The [src] goes quiet."),SPAN_NOTICE("A motor noise cuts out."))
|
||||
audible_message(SPAN_NOTICE("\The [src] goes quiet."),SPAN_NOTICE("A motor noise cuts out."), runemessage = "* goes quiet *")
|
||||
soundloop.stop()
|
||||
generator_state = GEN_OFF
|
||||
|
||||
@@ -258,12 +258,12 @@
|
||||
soundloop.start()
|
||||
time_started = world.time
|
||||
cell?.use(100)
|
||||
audible_message(SPAN_NOTICE("\The [src] starts chugging."),SPAN_NOTICE("A motor noise starts up."))
|
||||
audible_message(SPAN_NOTICE("\The [src] starts chugging."),SPAN_NOTICE("A motor noise starts up."), runemessage = "* whirr *")
|
||||
generator_state = GEN_IDLE
|
||||
|
||||
else if(generator_state > GEN_OFF && time_started + 3 SECONDS < world.time)
|
||||
soundloop.stop()
|
||||
audible_message(SPAN_NOTICE("\The [src] goes quiet."),SPAN_NOTICE("A motor noise cuts out."))
|
||||
audible_message(SPAN_NOTICE("\The [src] goes quiet."),SPAN_NOTICE("A motor noise cuts out."), runemessage = "* goes quiet *")
|
||||
generator_state = GEN_OFF
|
||||
|
||||
/obj/item/weapon/gun/magnetic/matfed/phoronbore/loaded
|
||||
|
||||
@@ -284,7 +284,7 @@
|
||||
visible_message("<span class='danger'>\The [src] begins to rattle, its acceleration chamber collapsing in on itself!</span>")
|
||||
removable_components = FALSE
|
||||
spawn(15)
|
||||
audible_message("<span class='critical'>\The [src]'s power supply begins to overload as the device crumples!</span>") //Why are you still holding this?
|
||||
audible_message("<span class='critical'>\The [src]'s power supply begins to overload as the device crumples!</span>", runemessage = "* VWRRRRRRRR *") //Why are you still holding this?
|
||||
playsound(src, 'sound/effects/grillehit.ogg', 10, 1)
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -47,18 +47,19 @@
|
||||
if(!current_cell)
|
||||
return 0
|
||||
var/turf/simulated/mineral/T = locate((origin_x-1)+x,(origin_y-1)+y,origin_z)
|
||||
if(istype(T) && !T.ignore_mapgen && !T.ignore_cavegen) //VOREStation Edit: ignore cavegen
|
||||
if(map[current_cell] == FLOOR_CHAR)
|
||||
T.make_floor() //VOREStation Edit - Don't make cracked sand on surface map, jerk.
|
||||
//if(prob(90))
|
||||
//T.make_floor()
|
||||
//else
|
||||
//T.ChangeTurf(/turf/space/cracked_asteroid)
|
||||
else
|
||||
T.make_wall()
|
||||
//VOREStation Edit Start
|
||||
if(istype(T) && !T.ignore_mapgen)
|
||||
if(!T.ignore_cavegen)
|
||||
if(map[current_cell] == FLOOR_CHAR)
|
||||
T.make_floor()
|
||||
else
|
||||
T.make_wall()
|
||||
|
||||
if(T.density && !T.ignore_oregen)
|
||||
if(map[current_cell] == DOOR_CHAR)
|
||||
T.make_ore()
|
||||
else if(map[current_cell] == EMPTY_CHAR)
|
||||
T.make_ore(1)
|
||||
get_additional_spawns(map[current_cell],T,get_spawn_dir(x, y))
|
||||
//VOREStation Edit End
|
||||
return T
|
||||
@@ -47,6 +47,58 @@
|
||||
s.start()
|
||||
holder.clear_reagents()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// TF chemicals
|
||||
/decl/chemical_reaction/instant/amorphorovir
|
||||
name = "Amorphorovir"
|
||||
id = "amorphorovir"
|
||||
result = "amorphorovir"
|
||||
required_reagents = list("cryptobiolin" = 30, "biomass" = 30, "hyperzine" = 20)
|
||||
catalysts = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/androrovir
|
||||
name = "Androrovir"
|
||||
id = "androrovir"
|
||||
result = "androrovir"
|
||||
required_reagents = list("amorphorovir" = 1, "bicaridine" = 20, "iron" = 20, "ethanol" = 20)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/gynorovir
|
||||
name = "Gynorovir"
|
||||
id = "gynorovir"
|
||||
result = "gynorovir"
|
||||
required_reagents = list("amorphorovir" = 1, "inaprovaline" = 20, "silicon" = 20, "sugar" = 20)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/androgynorovir
|
||||
name = "Androgynorovir"
|
||||
id = "androgynorovir"
|
||||
result = "androgynorovir"
|
||||
required_reagents = list("amorphorovir" = 1, "anti_toxin" = 20, "fluorine" = 20, "tungsten" = 20)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/androrovir_bootleg
|
||||
name = "Bootleg Androrovir"
|
||||
id = "androrovir_bootleg"
|
||||
result = "androrovir"
|
||||
required_reagents = list("amorphorovir" = 1, "protein" = 10, "capsaicin" = 10)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/gynorovir_bootleg
|
||||
name = "Bootleg Gynorovir"
|
||||
id = "gynorovir_bootleg"
|
||||
result = "gynorovir"
|
||||
required_reagents = list("amorphorovir" = 1, "soymilk" = 10, "sugar" = 10)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/androgynorovir_bootleg
|
||||
name = "Bootleg Androgynorovir"
|
||||
id = "androgynorovir_bootleg"
|
||||
result = "androgynorovir"
|
||||
required_reagents = list("amorphorovir" = 1, "cola" = 10, "berryjuice" = 10)
|
||||
result_amount = 1
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Miscellaneous Reactions
|
||||
|
||||
@@ -85,7 +137,7 @@
|
||||
required_reagents = list("water" = 1)
|
||||
catalysts = list("fluorine" = 10)
|
||||
result_amount = 1
|
||||
|
||||
|
||||
/decl/chemical_reaction/instant/firefightingfoamqol //Please don't abuse this and make us remove it. Seriously.
|
||||
name = "Firefighting Foam EZ"
|
||||
id = "firefighting foam ez"
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
name = "vial (hyronalin)"
|
||||
prefill = list("hyronalin" = 30)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/amorphorovir
|
||||
name = "vial (amorphorovir)"
|
||||
prefill = list("amorphorovir" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/measuring_cup
|
||||
name = "measuring cup"
|
||||
desc = "A measuring cup."
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
color = "#13BC5E"
|
||||
|
||||
/datum/reagent/advmutationtoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
if(!(M.allow_spontaneous_tf))
|
||||
return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.name != "Promethean")
|
||||
@@ -119,3 +121,16 @@
|
||||
if(nif.stat == NIF_TEMPFAIL)
|
||||
nif.stat = NIF_INSTALLING
|
||||
nif.durability = min(nif.durability + removed*0.1, initial(nif.durability))
|
||||
|
||||
//Special toxins for solargrubs
|
||||
/datum/reagent/grubshock
|
||||
name = "200 V" //in other words a painful shock
|
||||
id = "shockchem"
|
||||
description = "A liquid that quickly dissapates to deliver a painful shock."
|
||||
reagent_state = LIQUID
|
||||
color = "#E4EC2F"
|
||||
metabolism = 2.50
|
||||
var/power = 9
|
||||
|
||||
/datum/reagent/grubshock/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
M.take_organ_damage(0, removed * power * 0.2)
|
||||
|
||||
@@ -117,16 +117,74 @@
|
||||
P.absorbed = 0
|
||||
M.visible_message("<font color='green'><b>Something spills into [M]'s [lowertext(B.name)]!</b></font>")
|
||||
|
||||
//Special toxins for solargrubs
|
||||
////////////////////////// TF Drugs //////////////////////////
|
||||
|
||||
/datum/reagent/grubshock
|
||||
name = "200 V" //in other words a painful shock
|
||||
id = "shockchem"
|
||||
description = "A liquid that quickly dissapates to deliver a painful shock."
|
||||
/datum/reagent/amorphorovir
|
||||
name = "Amorphorovir"
|
||||
id = "amorphorovir"
|
||||
description = "A base medical concoction, capable of rapidly altering genetic and physical structure of the body. Requires extra processing to allow for a targeted transformation."
|
||||
reagent_state = LIQUID
|
||||
color = "#E4EC2F"
|
||||
metabolism = 2.50
|
||||
var/power = 9
|
||||
color = "#AAAAAA"
|
||||
|
||||
/datum/reagent/grubshock/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
M.take_organ_damage(0, removed * power * 0.2)
|
||||
/datum/reagent/androrovir
|
||||
name = "Androrovir"
|
||||
id = "androrovir"
|
||||
description = "A medical concoction, capable of rapidly altering genetic and physical structure of the body. This one seems to realign the target's gender to be male."
|
||||
reagent_state = LIQUID
|
||||
color = "#00BBFF"
|
||||
|
||||
/datum/reagent/androrovir/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
if(!(M.allow_spontaneous_tf))
|
||||
return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(M.reagents.has_reagent("gynorovir") || M.reagents.has_reagent("androgynorovir"))
|
||||
H.Confuse(1)
|
||||
else
|
||||
if(!(H.gender == MALE))
|
||||
H.set_gender(MALE)
|
||||
H.change_gender_identity(MALE)
|
||||
H.visible_message("<span class='notice'>[H] suddenly twitches as some of their features seem to contort and reshape, adjusting... In the end, it seems they are now male.</span>",
|
||||
"<span class='warning'>Your body suddenly contorts, feeling very different in various ways... By the time the rushing feeling is over it seems you just became male.</span>")
|
||||
|
||||
/datum/reagent/gynorovir
|
||||
name = "Gynorovir"
|
||||
id = "gynorovir"
|
||||
description = "A medical concoction, capable of rapidly altering genetic and physical structure of the body. This one seems to realign the target's gender to be female."
|
||||
reagent_state = LIQUID
|
||||
color = "#FF00AA"
|
||||
|
||||
/datum/reagent/gynorovir/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
if(!(M.allow_spontaneous_tf))
|
||||
return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(M.reagents.has_reagent("androrovir") || M.reagents.has_reagent("androgynorovir"))
|
||||
H.Confuse(1)
|
||||
else
|
||||
if(!(H.gender == FEMALE))
|
||||
H.set_gender(FEMALE)
|
||||
H.change_gender_identity(FEMALE)
|
||||
H.visible_message("<span class='notice'>[H] suddenly twitches as some of their features seem to contort and reshape, adjusting... In the end, it seems they are now female.</span>",
|
||||
"<span class='warning'>Your body suddenly contorts, feeling very different in various ways... By the time the rushing feeling is over it seems you just became female.</span>")
|
||||
|
||||
/datum/reagent/androgynorovir
|
||||
name = "Androgynorovir"
|
||||
id = "androgynorovir"
|
||||
description = "A medical concoction, capable of rapidly altering genetic and physical structure of the body. This one seems to realign the target's gender to be mixed."
|
||||
reagent_state = LIQUID
|
||||
color = "#6600FF"
|
||||
|
||||
/datum/reagent/androgynorovir/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
if(!(M.allow_spontaneous_tf))
|
||||
return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(M.reagents.has_reagent("gynorovir") || M.reagents.has_reagent("androrovir"))
|
||||
H.Confuse(1)
|
||||
else
|
||||
if(!(H.gender == PLURAL))
|
||||
H.set_gender(PLURAL)
|
||||
H.change_gender_identity(PLURAL)
|
||||
H.visible_message("<span class='notice'>[H] suddenly twitches as some of their features seem to contort and reshape, adjusting... In the end, it seems they are now of mixed gender.</span>",
|
||||
"<span class='warning'>Your body suddenly contorts, feeling very different in various ways... By the time the rushing feeling is over it seems you just became of mixed gender.</span>")
|
||||
@@ -130,12 +130,12 @@ var/global/list/obj/machinery/message_server/message_servers = list()
|
||||
if(2)
|
||||
if(!Console.silent)
|
||||
playsound(Console, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5)
|
||||
Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5, runemessage = "* beep! beep! *")
|
||||
Console.message_log += list(list("High Priority message from [sender]", "[authmsg]"))
|
||||
else
|
||||
if(!Console.silent)
|
||||
playsound(Console, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'Message from [sender]'"),,4)
|
||||
Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'Message from [sender]'"),,4, runemessage = "* beep beep *")
|
||||
Console.message_log += list(list("Message from [sender]", "[authmsg]"))
|
||||
Console.set_light(2)
|
||||
|
||||
|
||||
@@ -25,11 +25,17 @@
|
||||
var/obj/machinery/transhuman/synthprinter/selected_printer
|
||||
var/obj/machinery/transhuman/resleever/selected_sleever
|
||||
|
||||
// Resleeving database this machine interacts with. Blank for default database
|
||||
// Needs a matching /datum/transcore_db with key defined in code
|
||||
var/db_key
|
||||
var/datum/transcore_db/our_db // These persist all round and are never destroyed, just keep a hard ref
|
||||
|
||||
/obj/machinery/computer/transhuman/resleeving/Initialize()
|
||||
. = ..()
|
||||
pods = list()
|
||||
spods = list()
|
||||
sleevers = list()
|
||||
our_db = SStranscore.db_by_key(db_key)
|
||||
updatemodules()
|
||||
|
||||
/obj/machinery/computer/transhuman/resleeving/Destroy()
|
||||
@@ -82,7 +88,7 @@
|
||||
P.connected = src
|
||||
P.name = "[initial(P.name)] #[pods.len]"
|
||||
to_chat(user, "<span class='notice'>You connect [P] to [src].</span>")
|
||||
else if(istype(W, /obj/item/weapon/disk/transcore) && SStranscore && !SStranscore.core_dumped)
|
||||
else if(istype(W, /obj/item/weapon/disk/transcore) && !our_db.core_dumped)
|
||||
user.unEquip(W)
|
||||
disk = W
|
||||
disk.forceMove(src)
|
||||
@@ -172,7 +178,7 @@
|
||||
data["sleevers"] = temppods.Copy()
|
||||
temppods.Cut()
|
||||
|
||||
data["coredumped"] = SStranscore.core_dumped
|
||||
data["coredumped"] = our_db.core_dumped
|
||||
data["emergency"] = disk
|
||||
data["temp"] = temp
|
||||
data["selected_pod"] = "\ref[selected_pod]"
|
||||
@@ -180,14 +186,14 @@
|
||||
data["selected_sleever"] = "\ref[selected_sleever]"
|
||||
|
||||
var/bodyrecords_list_ui[0]
|
||||
for(var/N in SStranscore.body_scans)
|
||||
var/datum/transhuman/body_record/BR = SStranscore.body_scans[N]
|
||||
for(var/N in our_db.body_scans)
|
||||
var/datum/transhuman/body_record/BR = our_db.body_scans[N]
|
||||
bodyrecords_list_ui[++bodyrecords_list_ui.len] = list("name" = N, "recref" = "\ref[BR]")
|
||||
data["bodyrecords"] = bodyrecords_list_ui
|
||||
|
||||
var/mindrecords_list_ui[0]
|
||||
for(var/N in SStranscore.backed_up)
|
||||
var/datum/transhuman/mind_record/MR = SStranscore.backed_up[N]
|
||||
for(var/N in our_db.backed_up)
|
||||
var/datum/transhuman/mind_record/MR = our_db.backed_up[N]
|
||||
mindrecords_list_ui[++mindrecords_list_ui.len] = list("name" = N, "recref" = "\ref[MR]")
|
||||
data["mindrecords"] = mindrecords_list_ui
|
||||
|
||||
@@ -251,7 +257,7 @@
|
||||
set_temp("Error: Record missing.", "danger")
|
||||
if("coredump")
|
||||
if(disk)
|
||||
SStranscore.core_dump(disk)
|
||||
our_db.core_dump(disk)
|
||||
sleep(5)
|
||||
visible_message("<span class='warning'>\The [src] spits out \the [disk].</span>")
|
||||
disk.forceMove(get_turf(src))
|
||||
@@ -407,7 +413,7 @@
|
||||
return TRUE
|
||||
|
||||
//They were dead, or otherwise available.
|
||||
sleever.putmind(active_mr,mode,override)
|
||||
sleever.putmind(active_mr,mode,override,db_key = db_key)
|
||||
set_temp("Initiating resleeving...")
|
||||
tgui_modal_clear(src)
|
||||
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
var/mob/living/carbon/human/dummy/mannequin/mannequin = null
|
||||
var/obj/item/weapon/disk/body_record/disk = null
|
||||
|
||||
// Resleeving database this machine interacts with. Blank for default database
|
||||
// Needs a matching /datum/transcore_db with key defined in code
|
||||
var/db_key
|
||||
var/datum/transcore_db/our_db // These persist all round and are never destroyed, just keep a hard ref
|
||||
|
||||
/obj/machinery/computer/transhuman/designer/Initialize()
|
||||
. = ..()
|
||||
map_name = "transhuman_designer_[REF(src)]_map"
|
||||
@@ -51,6 +56,8 @@
|
||||
west_preview.del_on_map_removal = FALSE
|
||||
west_preview.screen_loc = "[map_name]:0,1"
|
||||
|
||||
our_db = SStranscore.db_by_key(db_key)
|
||||
|
||||
/obj/machinery/computer/transhuman/designer/Destroy()
|
||||
active_br = null
|
||||
mannequin = null
|
||||
@@ -100,8 +107,8 @@
|
||||
|
||||
if(menu == MENU_BODYRECORDS)
|
||||
var/bodyrecords_list_ui[0]
|
||||
for(var/N in SStranscore.body_scans)
|
||||
var/datum/transhuman/body_record/BR = SStranscore.body_scans[N]
|
||||
for(var/N in our_db.body_scans)
|
||||
var/datum/transhuman/body_record/BR = our_db.body_scans[N]
|
||||
bodyrecords_list_ui[++bodyrecords_list_ui.len] = list("name" = N, "recref" = "\ref[BR]")
|
||||
if(bodyrecords_list_ui.len)
|
||||
data["bodyrecords"] = bodyrecords_list_ui
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
icon_state = "backup_implant"
|
||||
known_implant = TRUE
|
||||
|
||||
// Resleeving database this machine interacts with. Blank for default database
|
||||
// Needs a matching /datum/transcore_db with key defined in code
|
||||
var/db_key
|
||||
var/datum/transcore_db/our_db // These persist all round and are never destroyed, just keep a hard ref
|
||||
|
||||
/obj/item/weapon/implant/backup/get_data()
|
||||
var/dat = {"
|
||||
<b>Implant Specifications:</b><BR>
|
||||
@@ -26,14 +31,22 @@
|
||||
<b>Integrity:</b> Generally very survivable. Susceptible to being destroyed by acid."}
|
||||
return dat
|
||||
|
||||
/obj/item/weapon/implant/backup/New(newloc, db_key)
|
||||
. = ..()
|
||||
src.db_key = db_key
|
||||
|
||||
/obj/item/weapon/implant/backup/Initialize()
|
||||
. = ..()
|
||||
our_db = SStranscore.db_by_key(db_key)
|
||||
|
||||
/obj/item/weapon/implant/backup/Destroy()
|
||||
SStranscore.implants -= src
|
||||
our_db.implants -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/implant/backup/post_implant(var/mob/living/carbon/human/H)
|
||||
if(istype(H))
|
||||
BITSET(H.hud_updateflag, BACKUP_HUD)
|
||||
SStranscore.implants |= src
|
||||
our_db.implants |= src
|
||||
|
||||
return 1
|
||||
|
||||
@@ -53,10 +66,12 @@
|
||||
var/list/obj/item/weapon/implant/backup/imps = list()
|
||||
var/max_implants = 4 //Iconstates need to exist due to the update proc!
|
||||
|
||||
var/db_key // To give to the baby implants
|
||||
|
||||
/obj/item/weapon/backup_implanter/New()
|
||||
..()
|
||||
for(var/i = 1 to max_implants)
|
||||
var/obj/item/weapon/implant/backup/imp = new(src)
|
||||
var/obj/item/weapon/implant/backup/imp = new(src, db_key)
|
||||
imps |= imp
|
||||
imp.germ_level = 0
|
||||
update()
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
var/one_time = FALSE
|
||||
|
||||
/datum/transhuman/mind_record/New(var/datum/mind/mind, var/mob/living/carbon/human/M, var/add_to_db = TRUE, var/one_time = FALSE)
|
||||
/datum/transhuman/mind_record/New(var/datum/mind/mind, var/mob/living/carbon/human/M, var/add_to_db = TRUE, var/one_time = FALSE, var/database_key)
|
||||
ASSERT(mind)
|
||||
|
||||
src.one_time = one_time
|
||||
@@ -62,7 +62,7 @@
|
||||
last_update = world.time
|
||||
|
||||
if(add_to_db)
|
||||
SStranscore.add_backup(src)
|
||||
SStranscore.add_backup(src, database_key = database_key)
|
||||
|
||||
/////// Body Record ///////
|
||||
/datum/transhuman/body_record
|
||||
@@ -100,7 +100,7 @@
|
||||
organ_data.Cut()
|
||||
return QDEL_HINT_HARDDEL // For now at least there is no easy way to clear references to this in machines etc.
|
||||
|
||||
/datum/transhuman/body_record/proc/init_from_mob(var/mob/living/carbon/human/M, var/add_to_db = 0, var/ckeylock = 0)
|
||||
/datum/transhuman/body_record/proc/init_from_mob(var/mob/living/carbon/human/M, var/add_to_db = 0, var/ckeylock = 0, var/database_key)
|
||||
ASSERT(!QDELETED(M))
|
||||
ASSERT(istype(M))
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
genetic_modifiers.Add(mod.type)
|
||||
|
||||
if(add_to_db)
|
||||
SStranscore.add_body(src)
|
||||
SStranscore.add_body(src, database_key = database_key)
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -58,6 +58,7 @@ var/list/infomorph_emotions = list(
|
||||
|
||||
var/obj/item/weapon/pai_cable/cable // The cable we produce and use when door or camera jacking
|
||||
var/silence_time // Timestamp when we were silenced (normally via EMP burst), set to null after silence has faded
|
||||
var/db_key
|
||||
|
||||
// Various software-specific vars
|
||||
|
||||
@@ -83,7 +84,7 @@ var/list/infomorph_emotions = list(
|
||||
var/datum/data/record/securityActive1 // Could probably just combine all these into one
|
||||
var/datum/data/record/securityActive2
|
||||
|
||||
/mob/living/silicon/infomorph/New(var/obj/item/device/sleevecard/SC, var/name = "Unknown")
|
||||
/mob/living/silicon/infomorph/New(var/obj/item/device/sleevecard/SC, var/name = "Unknown", var/db_key)
|
||||
ASSERT(SC)
|
||||
name = "[initial(name)] ([name])"
|
||||
src.forceMove(SC)
|
||||
@@ -95,6 +96,8 @@ var/list/infomorph_emotions = list(
|
||||
card.radio = new (card)
|
||||
radio = card.radio
|
||||
|
||||
src.db_key = db_key
|
||||
|
||||
//Default languages without universal translator software
|
||||
add_language(LANGUAGE_EAL, 1)
|
||||
add_language(LANGUAGE_SIGN, 0)
|
||||
@@ -406,9 +409,7 @@ var/list/infomorph_emotions = list(
|
||||
close_up()
|
||||
|
||||
//Resleeving 'cryo'
|
||||
if(mind && (mind.name in SStranscore.backed_up))
|
||||
var/datum/transhuman/mind_record/MR = SStranscore.backed_up[mind.name]
|
||||
SStranscore.stop_backup(MR)
|
||||
SStranscore.leave_round(src)
|
||||
|
||||
card.removePersonality()
|
||||
clear_client()
|
||||
@@ -588,7 +589,7 @@ var/global/list/default_infomorph_software = list()
|
||||
|
||||
//Only every so often
|
||||
if(air_master.current_cycle%30 == 1)
|
||||
SStranscore.m_backup(mind)
|
||||
SStranscore.m_backup(mind, database_key = db_key)
|
||||
|
||||
if(health <= 0)
|
||||
death(null,"gives one shrill beep before falling lifeless.")
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
|
||||
else if(((occupant.health == occupant.maxHealth)) && (!eject_wait))
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, 1)
|
||||
audible_message("\The [src] signals that the growing process is complete.")
|
||||
audible_message("\The [src] signals that the growing process is complete.", runemessage = "* ding *")
|
||||
connected_message("Growing Process Complete.")
|
||||
locked = 0
|
||||
go_out()
|
||||
@@ -536,13 +536,13 @@
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/machinery/transhuman/resleever/proc/putmind(var/datum/transhuman/mind_record/MR, mode = 1, var/mob/living/carbon/human/override = null)
|
||||
/obj/machinery/transhuman/resleever/proc/putmind(var/datum/transhuman/mind_record/MR, mode = 1, var/mob/living/carbon/human/override = null, var/db_key)
|
||||
if((!occupant || !istype(occupant) || occupant.stat >= DEAD) && mode == 1)
|
||||
return 0
|
||||
|
||||
if(mode == 2 && sleevecards) //Card sleeving
|
||||
var/obj/item/device/sleevecard/card = new /obj/item/device/sleevecard(get_turf(src))
|
||||
card.sleeveInto(MR)
|
||||
card.sleeveInto(MR, db_key = db_key)
|
||||
sleevecards--
|
||||
return 1
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
to_chat(user,"<span class='notice'>\The [src] displays the name '[infomorph]'.</span>")
|
||||
|
||||
//This is a 'hard' proc, it does no permission checking, do that on the computer
|
||||
/obj/item/device/sleevecard/proc/sleeveInto(var/datum/transhuman/mind_record/MR)
|
||||
infomorph = new(src,MR.mindname)
|
||||
/obj/item/device/sleevecard/proc/sleeveInto(var/datum/transhuman/mind_record/MR, var/db_key)
|
||||
infomorph = new(src,MR.mindname,db_key=db_key)
|
||||
|
||||
for(var/datum/language/L in MR.languages)
|
||||
infomorph.add_language(L.name)
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
continue
|
||||
if(!H.shuttle_comp || !(get_area(H) in shuttle_area))
|
||||
H.shuttle_comp = null
|
||||
H.audible_message("<span class='warning'>\The [H] pings as it loses it's connection with the ship.</span>")
|
||||
H.audible_message("<span class='warning'>\The [H] pings as it loses it's connection with the ship.</span>", runemessage = "* ping *")
|
||||
H.update_hud("discon")
|
||||
helmets -= H
|
||||
else
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
priority_mode = TRUE
|
||||
cancel_pending_floors()
|
||||
update_ext_panel_icons()
|
||||
control_panel_interior.audible_message("<span class='info'>This turbolift is responding to a priority call. Please exit the lift when it stops and make way.</span>")
|
||||
control_panel_interior.audible_message("<span class='info'>This turbolift is responding to a priority call. Please exit the lift when it stops and make way.</span>", runemessage = "* BUZZ *")
|
||||
spawn(time)
|
||||
priority_mode = FALSE
|
||||
update_ext_panel_icons()
|
||||
@@ -158,7 +158,7 @@
|
||||
doors_closing = 0
|
||||
if(!fire_mode)
|
||||
open_doors()
|
||||
control_panel_interior.audible_message("\The [current_floor.ext_panel] buzzes loudly.")
|
||||
control_panel_interior.audible_message("\The [current_floor.ext_panel] buzzes loudly.", runemessage = "* BUZZ *")
|
||||
playsound(control_panel_interior, "sound/machines/buzz-two.ogg", 50, 1)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -130,10 +130,10 @@
|
||||
return
|
||||
lift.update_fire_mode(!lift.fire_mode)
|
||||
if(lift.fire_mode)
|
||||
audible_message("<span class='danger'>Firefighter Mode Activated. Door safeties disabled. Manual control engaged.</span>")
|
||||
audible_message("<span class='danger'>Firefighter Mode Activated. Door safeties disabled. Manual control engaged.</span>", runemessage = "* SCREECH *")
|
||||
playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4, volume_channel = VOLUME_CHANNEL_ALARMS)
|
||||
else
|
||||
audible_message("<span class='warning'>Firefighter Mode Deactivated. Door safeties enabled. Automatic control engaged.</span>")
|
||||
audible_message("<span class='warning'>Firefighter Mode Deactivated. Door safeties enabled. Automatic control engaged.</span>", runemessage = "* ding *")
|
||||
return
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
if(!moved) // nowhere to go....
|
||||
LM.gib()
|
||||
else // the mob is too big to just move, so we need to give up what we're doing
|
||||
audible_message("\The [src]'s motors grind as they quickly reverse direction, unable to safely close.")
|
||||
audible_message("\The [src]'s motors grind as they quickly reverse direction, unable to safely close.", runemessage = "* WRRRRR *")
|
||||
cur_command = null // the door will just keep trying otherwise
|
||||
return 0
|
||||
return ..()
|
||||
@@ -42,7 +42,16 @@
|
||||
user.client.eye = target_move //if we don't do this, Byond only updates the eye every tick - required for smooth movement
|
||||
if(world.time > user.next_play_vent)
|
||||
user.next_play_vent = world.time+30
|
||||
playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
|
||||
var/turf/T = get_turf(src)
|
||||
playsound(T, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
|
||||
var/message = pick(
|
||||
prob(90);"* clunk *",
|
||||
prob(90);"* thud *",
|
||||
prob(90);"* clatter *",
|
||||
prob(1);"* <span style='font-size:2em'>ඞ</span> *"
|
||||
)
|
||||
T.runechat_message(message)
|
||||
|
||||
else
|
||||
if((direction & initialize_directions) || is_type_in_list(src, ventcrawl_machinery) && src.can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
|
||||
user.remove_ventcrawl()
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
var/permit_healbelly = TRUE
|
||||
var/can_be_drop_prey = FALSE
|
||||
var/can_be_drop_pred = TRUE // Mobs are pred by default.
|
||||
var/allow_spontaneous_tf = FALSE // Obviously.
|
||||
var/next_preyloop // For Fancy sound internal loop
|
||||
var/adminbus_trash = FALSE // For abusing trash eater for event shenanigans.
|
||||
var/adminbus_eat_minerals = FALSE // This creature subsists on a diet of pure adminium.
|
||||
@@ -236,6 +237,7 @@
|
||||
P.show_vore_fx = src.show_vore_fx
|
||||
P.can_be_drop_prey = src.can_be_drop_prey
|
||||
P.can_be_drop_pred = src.can_be_drop_pred
|
||||
P.allow_spontaneous_tf = src.allow_spontaneous_tf
|
||||
P.step_mechanics_pref = src.step_mechanics_pref
|
||||
P.pickup_pref = src.pickup_pref
|
||||
|
||||
@@ -271,6 +273,7 @@
|
||||
show_vore_fx = P.show_vore_fx
|
||||
can_be_drop_prey = P.can_be_drop_prey
|
||||
can_be_drop_pred = P.can_be_drop_pred
|
||||
allow_spontaneous_tf = P.allow_spontaneous_tf
|
||||
step_mechanics_pref = P.step_mechanics_pref
|
||||
pickup_pref = P.pickup_pref
|
||||
|
||||
@@ -857,6 +860,7 @@
|
||||
dispvoreprefs += "<b>Healbelly permission:</b> [permit_healbelly ? "Allowed" : "Disallowed"]<br>"
|
||||
dispvoreprefs += "<b>Spontaneous vore prey:</b> [can_be_drop_prey ? "Enabled" : "Disabled"]<br>"
|
||||
dispvoreprefs += "<b>Spontaneous vore pred:</b> [can_be_drop_pred ? "Enabled" : "Disabled"]<br>"
|
||||
dispvoreprefs += "<b>Spontaneous transformation:</b> [allow_spontaneous_tf ? "Enabled" : "Disabled"]<br>"
|
||||
dispvoreprefs += "<b>Can be stepped on/over:</b> [step_mechanics_pref ? "Allowed" : "Disallowed"]<br>"
|
||||
dispvoreprefs += "<b>Can be picked up:</b> [pickup_pref ? "Allowed" : "Disallowed"]<br>"
|
||||
user << browse("<html><head><title>Vore prefs: [src]</title></head><body><center>[dispvoreprefs]</center></body></html>", "window=[name]mvp;size=200x300;can_resize=0;can_minimize=0")
|
||||
|
||||
@@ -49,6 +49,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
|
||||
var/feeding = TRUE
|
||||
var/can_be_drop_prey = FALSE
|
||||
var/can_be_drop_pred = FALSE
|
||||
var/allow_spontaneous_tf = FALSE
|
||||
var/digest_leave_remains = FALSE
|
||||
var/allowmobvore = TRUE
|
||||
var/permit_healbelly = TRUE
|
||||
@@ -136,6 +137,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
|
||||
show_vore_fx = json_from_file["show_vore_fx"]
|
||||
can_be_drop_prey = json_from_file["can_be_drop_prey"]
|
||||
can_be_drop_pred = json_from_file["can_be_drop_pred"]
|
||||
allow_spontaneous_tf = json_from_file["allow_spontaneous_tf"]
|
||||
step_mechanics_pref = json_from_file["step_mechanics_pref"]
|
||||
pickup_pref = json_from_file["pickup_pref"]
|
||||
belly_prefs = json_from_file["belly_prefs"]
|
||||
@@ -163,6 +165,8 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
|
||||
can_be_drop_prey = FALSE
|
||||
if(isnull(can_be_drop_pred))
|
||||
can_be_drop_pred = FALSE
|
||||
if(isnull(allow_spontaneous_tf))
|
||||
allow_spontaneous_tf = FALSE
|
||||
if(isnull(step_mechanics_pref))
|
||||
step_mechanics_pref = TRUE
|
||||
if(isnull(pickup_pref))
|
||||
@@ -192,6 +196,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
|
||||
"show_vore_fx" = show_vore_fx,
|
||||
"can_be_drop_prey" = can_be_drop_prey,
|
||||
"can_be_drop_pred" = can_be_drop_pred,
|
||||
"allow_spontaneous_tf" = allow_spontaneous_tf,
|
||||
"step_mechanics_pref" = step_mechanics_pref,
|
||||
"pickup_pref" = pickup_pref,
|
||||
"belly_prefs" = belly_prefs,
|
||||
|
||||
@@ -224,6 +224,7 @@
|
||||
"show_vore_fx" = host.show_vore_fx,
|
||||
"can_be_drop_prey" = host.can_be_drop_prey,
|
||||
"can_be_drop_pred" = host.can_be_drop_pred,
|
||||
"allow_spontaneous_tf" = host.allow_spontaneous_tf,
|
||||
"step_mechanics_active" = host.step_mechanics_pref,
|
||||
"pickup_mechanics_active" = host.pickup_pref,
|
||||
"noisy" = host.noisy,
|
||||
@@ -354,6 +355,12 @@
|
||||
host.client.prefs_vr.can_be_drop_prey = host.can_be_drop_prey
|
||||
unsaved_changes = TRUE
|
||||
return TRUE
|
||||
if("toggle_allow_spontaneous_tf")
|
||||
host.allow_spontaneous_tf = !host.allow_spontaneous_tf
|
||||
if(host.client.prefs_vr)
|
||||
host.client.prefs_vr.allow_spontaneous_tf = host.allow_spontaneous_tf
|
||||
unsaved_changes = TRUE
|
||||
return TRUE
|
||||
if("toggle_digest")
|
||||
host.digestable = !host.digestable
|
||||
if(host.client.prefs_vr)
|
||||
|
||||
@@ -551,7 +551,7 @@
|
||||
//He's dead, jim
|
||||
if((state == 1) && owner && (owner.stat == DEAD))
|
||||
update_state(2)
|
||||
audible_message("<span class='warning'>The [name] begins flashing red.</span>")
|
||||
visible_message("<span class='warning'>The [name] begins flashing red.</span>")
|
||||
sleep(30)
|
||||
visible_message("<span class='warning'>The [name] shatters into dust!</span>")
|
||||
if(owner_c)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Adding needed defines to /mob/living
|
||||
// Note: Polaris had this on /mob/living/carbon/human We need it higher up for animals and stuff.
|
||||
/mob/living
|
||||
var/size_multiplier = 1 //multiplier for the mob's icon size
|
||||
var/holder_default
|
||||
var/step_mechanics_pref = TRUE // Allow participation in macro-micro step mechanics
|
||||
var/pickup_pref = TRUE // Allow participation in macro-micro pickup mechanics
|
||||
|
||||
|
Before Width: | Height: | Size: 739 KiB After Width: | Height: | Size: 735 KiB |
|
Before Width: | Height: | Size: 656 KiB After Width: | Height: | Size: 664 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 385 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -1282,7 +1282,7 @@ window "mapwindow"
|
||||
saved-params = "icon-size"
|
||||
on-show = ".winset\"mainwindow.mainvsplit.left=mapwindow\""
|
||||
on-hide = ".winset\"mainwindow.mainvsplit.left=\""
|
||||
style=".center { text-align: center; } .maptext { font-family: 'Small Fonts'; font-size: 7px; -dm-text-outline: 1px black; color: white; line-height: 1.1; } .small { font-size: 6px; } .big { font-size: 8px; } .reallybig { font-size: 8px; } .extremelybig { font-size: 8px; } .clown { color: #FF69Bf;} .tajaran {color: #803B56;} .skrell {color: #00CED1;} .solcom {color: #22228B;} .com_srus {color: #7c4848;} .zombie {color: #ff0000;} .soghun {color: #228B22;} .vox {color: #AA00AA;} .diona {color: #804000; font-weight: bold;} .trinary {color: #727272;} .kidan {color: #664205;} .slime {color: #0077AA;} .drask {color: #a3d4eb;} .vulpkanin {color: #B97A57;} .abductor {color: #800080; font-style: italic;} .his_grace { color: #15D512; } .hypnophrase { color: #0d0d0d; font-weight: bold; } .yell { font-weight: bold; }"
|
||||
style=".center { text-align: center; } .runechatdiv {background-color: #20202070} .black_outline { -dm-text-outline: 1px black } .boldtext { font-weight: bold; } .maptext { font-family: 'Small Fonts'; font-size: 7px; color: white; line-height: 1.1; } .command_headset { font-weight: bold; font-size: 8px; } .small { font-size: 6px; } .very_small { font-size: 5px;} .big { font-size: 8px; } .reallybig { font-size: 8px; } .extremelybig { font-size: 8px; } .greentext { color: #00FF00; font-size: 7px; } .redtext { color: #FF0000; font-size: 7px; } .clown { color: #FF69Bf; font-size: 7px; font-weight: bold; } .his_grace { color: #15D512; } .hypnophrase { color: #0d0d0d; font-weight: bold; } .yell { font-weight: bold; } .italics { font-size: 7px; font-style: italic; }"
|
||||
|
||||
window "outputwindow"
|
||||
elem "outputwindow"
|
||||
|
||||