Merge branch 'master' into upstream-merge-10961

This commit is contained in:
Nadyr
2021-07-08 00:09:21 -04:00
committed by GitHub
49 changed files with 1604 additions and 1237 deletions

View File

@@ -11,6 +11,9 @@
//#define ZASDBG // Uncomment to turn on super detailed ZAS debugging that probably won't even compile. //#define ZASDBG // Uncomment to turn on super detailed ZAS debugging that probably won't even compile.
#define MULTIZAS // Uncomment to turn on Multi-Z ZAS Support! #define MULTIZAS // Uncomment to turn on Multi-Z ZAS Support!
// Movement Compile Options
//#define CARDINAL_INPUT_ONLY // Uncomment to disable diagonal player movement (restore previous cardinal-moves-only behavior)
// Comment/Uncomment this to turn off/on shuttle code debugging logs // Comment/Uncomment this to turn off/on shuttle code debugging logs
#define DEBUG_SHUTTLES #define DEBUG_SHUTTLES

View File

@@ -54,6 +54,9 @@ What is the naming convention for planes or layers?
#define OPENSPACE_LAYER 600 // Above every other layer #define OPENSPACE_LAYER 600 // Above every other layer
#define OPENSPACE_BACKDROP_PLANE -50 // Black square has to be above openspace turfs #define OPENSPACE_BACKDROP_PLANE -50 // Black square has to be above openspace turfs
#define MAP_VIEW_PLANE -48 // Plane for 'embedded' maps in consoles and such
#define MAP_VIEW_LAYER 0
// Turf Planes // Turf Planes
#define PLATING_PLANE -44 // Plating #define PLATING_PLANE -44 // Plating
#define DISPOSAL_LAYER 2.1 // Under objects, even when planeswapped #define DISPOSAL_LAYER 2.1 // Under objects, even when planeswapped

21
code/__defines/input.dm Normal file
View File

@@ -0,0 +1,21 @@
// Bitflags for the move_keys_held bitfield.
#define NORTH_KEY (1<<0)
#define SOUTH_KEY (1<<1)
#define EAST_KEY (1<<2)
#define WEST_KEY (1<<3)
#define W_KEY (1<<4)
#define S_KEY (1<<5)
#define D_KEY (1<<6)
#define A_KEY (1<<7)
// Combine the held WASD and arrow keys together (OR) into byond N/S/E/W dir
#define MOVEMENT_KEYS_TO_DIR(MK) ((((MK)>>4)|(MK))&(ALL_CARDINALS))
// Bitflags for pressed modifier keys.
// Values chosen specifically to not conflict with dir bitfield, in case we want to smoosh them together.
#define CTRL_KEY (1<<8)
#define SHIFT_KEY (1<<9)
#define ALT_KEY (1<<10)
// Uncomment to get a lot of debug logging for movement keys.
// #define DEBUG_INPUT(A) to_world_log(A)
#define DEBUG_INPUT(A)

View File

@@ -56,6 +56,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_DBCORE 41 //CHOMPEdit #define INIT_ORDER_DBCORE 41 //CHOMPEdit
#define INIT_ORDER_SQLITE 40 #define INIT_ORDER_SQLITE 40
#define INIT_ORDER_MEDIA_TRACKS 38 // Gotta get that lobby music up, yo #define INIT_ORDER_MEDIA_TRACKS 38 // Gotta get that lobby music up, yo
#define INIT_ORDER_INPUT 37
#define INIT_ORDER_CHEMISTRY 35 #define INIT_ORDER_CHEMISTRY 35
#define INIT_ORDER_VIS 32 #define INIT_ORDER_VIS 32
#define INIT_ORDER_SKYBOX 30 #define INIT_ORDER_SKYBOX 30
@@ -115,6 +116,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_PROJECTILES 150 #define FIRE_PRIORITY_PROJECTILES 150
#define FIRE_PRIORITY_CHAT 400 #define FIRE_PRIORITY_CHAT 400
#define FIRE_PRIORITY_OVERLAYS 500 #define FIRE_PRIORITY_OVERLAYS 500
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
// Macro defining the actual code applying our overlays lists to the BYOND overlays list. (I guess a macro for speed) // Macro defining the actual code applying our overlays lists to the BYOND overlays list. (I guess a macro for speed)
// TODO - I don't really like the location of this macro define. Consider it. ~Leshana // TODO - I don't really like the location of this macro define. Consider it. ~Leshana

View File

@@ -244,7 +244,7 @@ GLOBAL_LIST_EMPTY(mannequins)
wing_styles_list[path] = instance wing_styles_list[path] = instance
// VOREStation Add - Vore Modes! // VOREStation Add - Vore Modes!
paths = subtypesof(/datum/digest_mode) paths = typesof(/datum/digest_mode)
for(var/T in paths) for(var/T in paths)
var/datum/digest_mode/DM = new T var/datum/digest_mode/DM = new T
GLOB.digest_modes[DM.id] = DM GLOB.digest_modes[DM.id] = DM

View File

@@ -96,6 +96,19 @@
if ("SOUTHEAST") return 6 if ("SOUTHEAST") return 6
if ("SOUTHWEST") return 10 if ("SOUTHWEST") return 10
// Turns a direction into text showing all bits set
/proc/dirs2text(direction)
if(!direction)
return ""
var/list/dirs = list()
if(direction & NORTH) dirs += "NORTH"
if(direction & SOUTH) dirs += "SOUTH"
if(direction & EAST) dirs += "EAST"
if(direction & WEST) dirs += "WEST"
if(direction & UP) dirs += "UP"
if(direction & DOWN) dirs += "DOWN"
return dirs.Join(" ")
// Converts an angle (degrees) into an ss13 direction // Converts an angle (degrees) into an ss13 direction
/proc/angle2dir(var/degree) /proc/angle2dir(var/degree)
degree = (degree + 22.5) % 365 // 22.5 = 45 / 2 degree = (degree + 22.5) % 365 // 22.5 = 45 / 2

View File

@@ -29,8 +29,8 @@
/obj/screen/map_view /obj/screen/map_view
icon_state = "blank" icon_state = "blank"
// Map view has to be on the lowest plane to enable proper lighting // Map view has to be on the lowest plane to enable proper lighting
layer = SPACE_PLANE layer = MAP_VIEW_LAYER
plane = SPACE_PLANE plane = MAP_VIEW_PLANE
/** /**
* A generic background object. * A generic background object.
@@ -41,8 +41,8 @@
name = "background" name = "background"
icon = 'icons/mob/map_backgrounds.dmi' icon = 'icons/mob/map_backgrounds.dmi'
icon_state = "clear" icon_state = "clear"
layer = SPACE_PLANE layer = MAP_VIEW_LAYER
plane = SPACE_PLANE plane = MAP_VIEW_PLANE
/** /**
* Sets screen_loc of this screen object, in form of point coordinates, * Sets screen_loc of this screen object, in form of point coordinates,

View File

@@ -6,12 +6,13 @@
/obj/screen/skybox /obj/screen/skybox
name = "skybox" name = "skybox"
icon = null icon = null
vis_flags = NONE
appearance_flags = TILE_BOUND|PIXEL_SCALE appearance_flags = TILE_BOUND|PIXEL_SCALE
mouse_opacity = 0 mouse_opacity = 0
anchored = TRUE anchored = TRUE
simulated = FALSE simulated = FALSE
screen_loc = "CENTER,CENTER" screen_loc = "CENTER,CENTER"
layer = OBJ_LAYER layer = BACKGROUND_LAYER
plane = SKYBOX_PLANE plane = SKYBOX_PLANE
blend_mode = BLEND_MULTIPLY // You actually need to do it this way or you see it in occlusion. blend_mode = BLEND_MULTIPLY // You actually need to do it this way or you see it in occlusion.

View File

@@ -0,0 +1,13 @@
SUBSYSTEM_DEF(input)
name = "Input"
wait = 1 // SS_TICKER means this runs every tick
init_order = INIT_ORDER_INPUT
flags = SS_TICKER
priority = FIRE_PRIORITY_INPUT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
/datum/controller/subsystem/input/fire()
var/list/clients = GLOB.clients // Let's sing the list cache song
for(var/i in 1 to clients.len)
var/client/C = clients[i]
C?.keyLoop()

View File

@@ -7,7 +7,8 @@ SUBSYSTEM_DEF(persistence)
/// Places our subsystem can spawn paintings (helps with art spawning differently across maps) /// Places our subsystem can spawn paintings (helps with art spawning differently across maps)
var/list/obj/structure/sign/painting/painting_frames = list() var/list/obj/structure/sign/painting/painting_frames = list()
var/list/paintings = list() var/list/all_paintings = list()
var/list/unpicked_paintings = list()
/datum/controller/subsystem/persistence/Initialize() /datum/controller/subsystem/persistence/Initialize()
. = ..() . = ..()

File diff suppressed because it is too large Load Diff

View File

@@ -123,7 +123,7 @@
spawn_positions = 2 spawn_positions = 2
alt_titles = list("Journalist" = /datum/alt_title/journalist, "Reporter" = /datum/alt_title/reporter, "Writer" = /datum/alt_title/writer, alt_titles = list("Journalist" = /datum/alt_title/journalist, "Reporter" = /datum/alt_title/reporter, "Writer" = /datum/alt_title/writer,
"Historian" = /datum/alt_title/historian, "Archivist" = /datum/alt_title/archivist, "Professor" = /datum/alt_title/professor, "Historian" = /datum/alt_title/historian, "Archivist" = /datum/alt_title/archivist, "Professor" = /datum/alt_title/professor,
"Academic" = /datum/alt_title/academic, "Philosopher" = /datum/alt_title/philosopher) "Academic" = /datum/alt_title/academic, "Philosopher" = /datum/alt_title/philosopher, "Curator" = /datum/alt_title/curator)
pto_type = PTO_CIVILIAN pto_type = PTO_CIVILIAN
/datum/alt_title/reporter /datum/alt_title/reporter
@@ -150,6 +150,9 @@
title = "Philosopher" title = "Philosopher"
title_blurb = "The Philosopher uses the Library as a base of operation to ruminate on nature of life and other great questions, and share their opinions with the crew." title_blurb = "The Philosopher uses the Library as a base of operation to ruminate on nature of life and other great questions, and share their opinions with the crew."
/datum/alt_title/curator
title = "Curator"
title_blurb = "The Curator uses the Library as a base of operation to gather the finest of art for display and preservation."
/datum/job/lawyer /datum/job/lawyer
disallow_jobhop = TRUE disallow_jobhop = TRUE

View File

@@ -345,6 +345,7 @@
///Description set when canvas is added. ///Description set when canvas is added.
var/desc_with_canvas var/desc_with_canvas
var/persistence_id var/persistence_id
var/loaded = FALSE
//Presets for art gallery mapping, for paintings to be shared across stations //Presets for art gallery mapping, for paintings to be shared across stations
/obj/structure/sign/painting/public /obj/structure/sign/painting/public
@@ -402,10 +403,18 @@
. = ..() . = ..()
if(persistence_id) if(persistence_id)
. += "<span class='notice'>Any painting placed here will be archived at the end of the shift.</span>" . += "<span class='notice'>Any painting placed here will be archived at the end of the shift.</span>"
if(current_canvas) if(current_canvas)
current_canvas.tgui_interact(user) current_canvas.tgui_interact(user)
. += "<span class='notice'>Use wirecutters to remove the painting.</span>" . += "<span class='notice'>Use wirecutters to remove the painting.</span>"
// Painting loaded and persistent frame, give a hint about removal safety
if(persistence_id)
if(loaded)
. += "<span class='notice'>Don't worry, the currently framed painting has already been entered into the archives and can be safely removed. It will still be used on future shifts.</span>"
else
. += "<span class='warning'>This painting has not been entered into the archives yet. Removing it will prevent that from happening.</span>"
/obj/structure/sign/painting/proc/frame_canvas(mob/user,obj/item/canvas/new_canvas) /obj/structure/sign/painting/proc/frame_canvas(mob/user,obj/item/canvas/new_canvas)
if(!allowed(user)) if(!allowed(user))
to_chat(user, "<span class='warning'>You're not comfortable framing this canvas in such a prestigious spot!</span>") to_chat(user, "<span class='warning'>You're not comfortable framing this canvas in such a prestigious spot!</span>")
@@ -418,9 +427,13 @@
update_appearance() update_appearance()
/obj/structure/sign/painting/proc/unframe_canvas(mob/living/user) /obj/structure/sign/painting/proc/unframe_canvas(mob/living/user)
if(!allowed(user))
to_chat(user, "<span class='warning'>You're not comfortable removing this prestigious canvas!</span>")
return
if(current_canvas) if(current_canvas)
current_canvas.forceMove(drop_location()) current_canvas.forceMove(drop_location())
current_canvas = null current_canvas = null
loaded = FALSE
to_chat(user, "<span class='notice'>You remove the painting from the frame.</span>") to_chat(user, "<span class='notice'>You remove the painting from the frame.</span>")
update_appearance() update_appearance()
@@ -462,12 +475,14 @@
* Deleting paintings leaves their json, so this proc will remove the json and try again if it finds one of those. * Deleting paintings leaves their json, so this proc will remove the json and try again if it finds one of those.
*/ */
/obj/structure/sign/painting/proc/load_persistent() /obj/structure/sign/painting/proc/load_persistent()
if(!persistence_id || !SSpersistence.paintings) if(!persistence_id || !LAZYLEN(SSpersistence.unpicked_paintings))
return return
var/list/painting_category = list() var/list/painting_category = list()
for (var/list/P in SSpersistence.paintings) for (var/list/P in SSpersistence.unpicked_paintings)
if(P["persistence_id"] == persistence_id) if(P["persistence_id"] == persistence_id)
painting_category[++painting_category.len] = P painting_category[++painting_category.len] = P
var/list/painting var/list/painting
while(!painting) while(!painting)
if(!length(painting_category)) if(!length(painting_category))
@@ -475,24 +490,30 @@
var/list/chosen = pick(painting_category) var/list/chosen = pick(painting_category)
if(!fexists("data/persistent/paintings/[persistence_id]/[chosen["md5"]].png")) //shitmin deleted this art, lets remove json entry to avoid errors if(!fexists("data/persistent/paintings/[persistence_id]/[chosen["md5"]].png")) //shitmin deleted this art, lets remove json entry to avoid errors
painting_category -= list(chosen) painting_category -= list(chosen)
SSpersistence.unpicked_paintings -= chosen
continue //and try again continue //and try again
painting = chosen painting = chosen
SSpersistence.unpicked_paintings -= chosen
var/title = painting["title"] var/title = painting["title"]
var/author_name = painting["author"] var/author_name = painting["author"]
var/author_ckey = painting["ckey"] var/author_ckey = painting["ckey"]
var/png = "data/persistent/paintings/[persistence_id]/[painting["md5"]].png" var/png = "data/persistent/paintings/[persistence_id]/[painting["md5"]].png"
if(!title)
title = "Untitled Artwork" //legacy artwork allowed null names which was bad for the json, lets fix that
painting["title"] = title
var/icon/I = new(png) var/icon/I = new(png)
var/obj/item/canvas/new_canvas var/obj/item/canvas/new_canvas
var/w = I.Width() var/w = I.Width()
var/h = I.Height() var/h = I.Height()
for(var/T in typesof(/obj/item/canvas)) for(var/T in typesof(/obj/item/canvas))
new_canvas = T new_canvas = T
if(initial(new_canvas.width) == w && initial(new_canvas.height) == h) if(initial(new_canvas.width) == w && initial(new_canvas.height) == h)
new_canvas = new T(src) new_canvas = new T(src)
break break
if(!new_canvas)
warning("Couldn't find a canvas to match [w]x[h] of painting")
return
new_canvas.fill_grid_from_icon(I) new_canvas.fill_grid_from_icon(I)
new_canvas.generated_icon = I new_canvas.generated_icon = I
new_canvas.icon_generated = TRUE new_canvas.icon_generated = TRUE
@@ -502,6 +523,7 @@
new_canvas.author_ckey = author_ckey new_canvas.author_ckey = author_ckey
new_canvas.name = "painting - [title]" new_canvas.name = "painting - [title]"
current_canvas = new_canvas current_canvas = new_canvas
loaded = TRUE
update_appearance() update_appearance()
/obj/structure/sign/painting/proc/save_persistent() /obj/structure/sign/painting/proc/save_persistent()
@@ -512,18 +534,20 @@
return return
if(!current_canvas.painting_name) if(!current_canvas.painting_name)
current_canvas.painting_name = "Untitled Artwork" current_canvas.painting_name = "Untitled Artwork"
var/data = current_canvas.get_data_string() var/data = current_canvas.get_data_string()
var/md5 = md5(lowertext(data)) var/md5 = md5(lowertext(data))
LAZYINITLIST(SSpersistence.paintings) for(var/list/entry in SSpersistence.all_paintings)
for(var/list/entry in SSpersistence.paintings) if(entry["md5"] == md5 && entry["persistence_id"] == persistence_id)
if(entry["md5"] == md5)
return return
var/png_directory = "data/persistent/paintings/[persistence_id]/" var/png_directory = "data/persistent/paintings/[persistence_id]/"
var/png_path = png_directory + "[md5].png" var/png_path = png_directory + "[md5].png"
var/result = rustg_dmi_create_png(png_path,"[current_canvas.width]","[current_canvas.height]",data) var/result = rustg_dmi_create_png(png_path,"[current_canvas.width]","[current_canvas.height]",data)
if(result) if(result)
CRASH("Error saving persistent painting: [result]") CRASH("Error saving persistent painting: [result]")
SSpersistence.paintings += list(list(
SSpersistence.all_paintings += list(list(
"persistence_id" = persistence_id, "persistence_id" = persistence_id,
"title" = current_canvas.painting_name, "title" = current_canvas.painting_name,
"md5" = md5, "md5" = md5,
@@ -547,10 +571,10 @@
var/md5 = md5(lowertext(current_canvas.get_data_string())) var/md5 = md5(lowertext(current_canvas.get_data_string()))
var/author = current_canvas.author_ckey var/author = current_canvas.author_ckey
var/list/filenames_found = list() var/list/filenames_found = list()
for(var/list/entry in SSpersistence.paintings) for(var/list/entry in SSpersistence.all_paintings)
if(entry["md5"] == md5) if(entry["md5"] == md5)
filenames_found += "data/persistent/paintings/[entry["persistence_id"]]/[entry["md5"]].png" filenames_found += "data/persistent/paintings/[entry["persistence_id"]]/[entry["md5"]].png"
SSpersistence.paintings -= entry SSpersistence.all_paintings -= entry
for(var/png in filenames_found) for(var/png in filenames_found)
if(fexists(png)) if(fexists(png))
fdel(png) fdel(png)
@@ -558,4 +582,5 @@
if(P.current_canvas && md5(P.current_canvas.get_data_string()) == md5) if(P.current_canvas && md5(P.current_canvas.get_data_string()) == md5)
QDEL_NULL(P.current_canvas) QDEL_NULL(P.current_canvas)
P.update_appearance() P.update_appearance()
loaded = FALSE
log_and_message_admins("<span class='notice'>[key_name_admin(user)] has deleted persistent painting made by [author].</span>") log_and_message_admins("<span class='notice'>[key_name_admin(user)] has deleted persistent painting made by [author].</span>")

View File

@@ -31,7 +31,14 @@
for(var/atom/movable/AM in contents) for(var/atom/movable/AM in contents)
if(AM.simulated) if(AM.simulated)
AM.forceMove(T) AM.forceMove(T)
//VOREStation Add Start
if(isanimal(AM))
var/mob/living/simple_mob/AMBLINAL = AM
if(!AMBLINAL.mind)
AMBLINAL.ghostjoin = 1
AMBLINAL.ghostjoin_icon()
active_ghost_pods |= AMBLINAL
//VOREStation Add End
user.visible_message("<span class='notice'>[user] pries \the [src] open.</span>", \ user.visible_message("<span class='notice'>[user] pries \the [src] open.</span>", \
"<span class='notice'>You pry open \the [src].</span>", \ "<span class='notice'>You pry open \the [src].</span>", \
"<span class='notice'>You hear splitting wood.</span>") "<span class='notice'>You hear splitting wood.</span>")

View File

@@ -1570,9 +1570,16 @@
var/mob/M = locate(href_list["sendmob"]) var/mob/M = locate(href_list["sendmob"])
if(!M) if(!M)
return return
var/area/A = tgui_input_list(usr, "Pick an area:", "Send Mob", return_sorted_areas())
var/list/areachoices = return_sorted_areas()
var/choice = tgui_input_list(usr, "Pick an area:", "Send Mob", areachoices)
if(!choice)
return
var/area/A = areachoices[choice]
if(!A) if(!A)
return return
M.on_mob_jump() M.on_mob_jump()
M.forceMove(pick(get_area_turfs(A))) M.forceMove(pick(get_area_turfs(A)))
var/msg = "[key_name_admin(usr)] teleported [ADMIN_LOOKUPFLW(M)]" var/msg = "[key_name_admin(usr)] teleported [ADMIN_LOOKUPFLW(M)]"

View File

@@ -4,25 +4,32 @@
/mob/observer/dead/on_mob_jump() /mob/observer/dead/on_mob_jump()
following = null following = null
/client/proc/Jump() /client/proc/Jump(areaname as null|anything in return_sorted_areas())
set name = "Jump to Area" set name = "Jump to Area"
set desc = "Area to jump to" set desc = "Area to jump to"
set category = "Admin" set category = "Admin"
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG|R_EVENT)) if(!check_rights(R_ADMIN|R_MOD|R_DEBUG|R_EVENT))
return return
if(config.allow_admin_jump) if(!config.allow_admin_jump)
var/area/A = tgui_input_list(usr, "Pick an area:", "Jump to Area", return_sorted_areas())
if(!A)
return
usr.on_mob_jump()
usr.forceMove(pick(get_area_turfs(A)))
log_admin("[key_name(usr)] jumped to [A]")
message_admins("[key_name_admin(usr)] jumped to [A]", 1)
feedback_add_details("admin_verb","JA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
else
tgui_alert_async(usr, "Admin jumping disabled") tgui_alert_async(usr, "Admin jumping disabled")
return
var/area/A
if(areaname)
A = return_sorted_areas()[areaname]
else
A = tgui_input_list(usr, "Pick an area:", "Jump to Area", return_sorted_areas())
if(!A)
return
usr.on_mob_jump()
usr.forceMove(pick(get_area_turfs(A)))
log_admin("[key_name(usr)] jumped to [A]")
message_admins("[key_name_admin(usr)] jumped to [A]", 1)
feedback_add_details("admin_verb","JA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/jumptoturf(var/turf/T in world) /client/proc/jumptoturf(var/turf/T in world)
set name = "Jump to Turf" set name = "Jump to Turf"
@@ -40,7 +47,7 @@
return return
/// Verb wrapper around do_jumptomob() /// Verb wrapper around do_jumptomob()
/client/proc/jumptomob() /client/proc/jumptomob(mob as null|anything in mob_list)
set category = "Admin" set category = "Admin"
set name = "Jump to Mob" set name = "Jump to Mob"
set popup_menu = FALSE //VOREStation Edit - Declutter. set popup_menu = FALSE //VOREStation Edit - Declutter.
@@ -48,16 +55,16 @@
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG|R_EVENT)) if(!check_rights(R_ADMIN|R_MOD|R_DEBUG|R_EVENT))
return return
var/mob/M = tgui_input_list(usr, "Pick a mob:", "Jump to Mob", mob_list) do_jumptomob(mob)
if(!M) // Cancelled
return
do_jumptomob(M)
/// Performs the jumps /// Performs the jumps, also called from admin Topic() for JMP links
/client/proc/do_jumptomob(var/mob/M) /client/proc/do_jumptomob(var/mob/M)
if(!config.allow_admin_jump) if(!config.allow_admin_jump)
tgui_alert_async(usr, "Admin jumping disabled") tgui_alert_async(usr, "Admin jumping disabled")
return return
if(!M)
M = tgui_input_list(usr, "Pick a mob:", "Jump to Mob", mob_list)
if(!M) if(!M)
return return

View File

@@ -80,3 +80,32 @@
// Runechat messages // Runechat messages
var/list/seen_messages var/list/seen_messages
///////////
// INPUT //
///////////
/// Bitfield of modifier keys (Shift, Ctrl, Alt) held currently.
var/mod_keys_held = 0
/// Bitfield of movement keys (WASD/Cursor Keys) held currently.
var/move_keys_held = 0
/// These next two vars are to apply movement for keypresses and releases made while move delayed.
/// Because discarding that input makes the game less responsive.
/// Bitfield of movement dirs that were pressed down *this* cycle (even if not currently held).
/// Note that only dirs that actually are first pressed down during this cycle are included, if it was still held from last cycle it won't be in here.
/// On next move, add this dir to the move that would otherwise be done
var/next_move_dir_add
/// Bitfield of movement dirs that were released *this* cycle (even if currently held).
/// Note that only dirs that were already held at the start of this cycle are included, if it pressed then released it won't be in here.
/// On next move, subtract this dir from the move that would otherwise be done
var/next_move_dir_sub
#ifdef CARDINAL_INPUT_ONLY
/// Movement dir of the most recently pressed movement key. Used in cardinal-only movement mode.
var/last_move_dir_pressed = NONE
#endif

View File

@@ -39,22 +39,25 @@
if(nutriment_amt) if(nutriment_amt)
reagents.add_reagent("nutriment",(nutriment_amt*2),nutriment_desc) //VOREStation Edit: Undoes global nutrition nerf reagents.add_reagent("nutriment",(nutriment_amt*2),nutriment_desc) //VOREStation Edit: Undoes global nutrition nerf
//Placeholder for effect that trigger on eating that aren't tied to reagents. //Placeholder for effect that trigger on eating that aren't tied to reagents.
/obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume(var/mob/M) /obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume(var/mob/living/M)
if(!usr) if(!usr) // what
usr = M usr = M
if(!reagents.total_volume) if(!reagents.total_volume)
M.visible_message("<span class='notice'>[M] finishes eating \the [src].</span>","<span class='notice'>You finish eating \the [src].</span>") M.visible_message("<span class='notice'>[M] finishes eating \the [src].</span>","<span class='notice'>You finish eating \the [src].</span>")
usr.drop_from_inventory(src) //so icons update :[ // Embedded-in-food smol vore
for(var/obj/item/weapon/holder/holder in src)
if(holder.held_mob?.devourable)
holder.held_mob.forceMove(M.vore_selected)
holder.held_mob = null
qdel(holder)
usr.drop_from_inventory(src) // Drop food from inventory so it doesn't end up staying on the hud after qdel, and so inhands go away
if(trash) if(trash)
if(ispath(trash,/obj/item)) var/obj/item/TrashItem = new trash(usr)
var/obj/item/TrashItem = new trash(usr) usr.put_in_hands(TrashItem)
usr.put_in_hands(TrashItem)
else if(istype(trash,/obj/item))
usr.put_in_hands(trash)
qdel(src) qdel(src)
return
/obj/item/weapon/reagent_containers/food/snacks/attack_self(mob/user as mob) /obj/item/weapon/reagent_containers/food/snacks/attack_self(mob/user as mob)
if(package && !user.incapacitated()) if(package && !user.incapacitated())
@@ -4264,7 +4267,7 @@
if (!feeder) if (!feeder)
feeder = eater feeder = eater
feeder.drop_from_inventory(src) //so icons update :[ //what the fuck is this???? feeder.drop_from_inventory(src) // Drop food from inventory so it doesn't end up staying on the hud after qdel, and so inhands go away
if(trash) if(trash)
if(ispath(trash,/obj/item)) if(ispath(trash,/obj/item))
@@ -7114,7 +7117,7 @@
desc = "A burger stored in a plastic wrapping for vending machine distribution. Surely it tastes fine!" desc = "A burger stored in a plastic wrapping for vending machine distribution. Surely it tastes fine!"
package = TRUE package = TRUE
package_trash = /obj/item/trash/vendor_burger package_trash = /obj/item/trash/vendor_burger
package_open_state = "smolburger" package_open_state = "smolcheeseburger"
nutriment_amt = 3 nutriment_amt = 3
nutriment_desc = list("stale burger" = 3) nutriment_desc = list("stale burger" = 3)
starts_with = list("sodiumchloride" = 1) starts_with = list("sodiumchloride" = 1)

View File

@@ -0,0 +1,45 @@
// You might be wondering why this isn't client level. If focus is null, we don't want you to move.
// Only way to do that is to tie the behavior into the focus's keyLoop().
// THE TRADITIONAL STYLE FROM /TG (modified)
/atom/movable/keyLoop(client/user)
// Bail out if the user is holding the "face direction" key (Maybe?)
// TODO - I think this breaks non-hotkeys WASD movement, so maybe adopt the /tg solution)
if(user.mod_keys_held & CTRL_KEY)
return
var/must_call_move = FALSE
var/movement_dir = MOVEMENT_KEYS_TO_DIR(user.move_keys_held)
if(user.next_move_dir_add)
must_call_move = TRUE // So that next_move_dir_add gets cleared if its time.
movement_dir |= user.next_move_dir_add
if(user.next_move_dir_sub)
DEBUG_INPUT("[(user.next_move_dir_sub & movement_dir) ? "Actually" : "Want to"] subtract [dirs2text(user.next_move_dir_sub)] from [dirs2text(movement_dir)]")
must_call_move = TRUE // So that next_move_dir_sub gets cleared if its time.
movement_dir &= ~user.next_move_dir_sub
// Sanity checks in case you hold left and right and up to make sure you only go up
if((movement_dir & (NORTH|SOUTH)) == (NORTH|SOUTH))
movement_dir &= ~(NORTH|SOUTH)
if((movement_dir & (EAST|WEST)) == (EAST|WEST))
movement_dir &= ~(EAST|WEST)
#ifdef CARDINAL_INPUT_ONLY
if(movement_dir & user.last_move_dir_pressed)
movement_dir = user.last_move_dir_pressed
else if (movement_dir == NORTHEAST || movement_dir == NORTHWEST)
DEBUG_INPUT("overriding to NORTH: movement_dir=[dirs2text(movement_dir)] last=[dirs2text(user.last_move_dir_pressed)]")
movement_dir = NORTH
else if (movement_dir == SOUTHEAST || movement_dir == SOUTHWEST)
DEBUG_INPUT("overriding to SOUTH: movement_dir=[dirs2text(movement_dir)] last=[dirs2text(user.last_move_dir_pressed)]")
movement_dir = SOUTH
#endif
// Compensate for client camera spinning (client.dir) so our movement still makes sense I guess.
if(movement_dir) // Only compensate if non-zero, as byond will auto-fill dir otherwise
movement_dir = turn(movement_dir, -dir2angle(user.dir))
// Move, but only if we actually are planing to move, or we need to clear the next move vars
if(movement_dir || must_call_move)
user.Move(get_step(src, movement_dir), movement_dir)

View File

@@ -0,0 +1,77 @@
// TODO - Optimize this into numerics if this ends up working out
var/global/list/MOVE_KEY_MAPPINGS = list(
"North" = NORTH_KEY,
"South" = SOUTH_KEY,
"East" = EAST_KEY,
"West" = WEST_KEY,
"W" = W_KEY,
"A" = A_KEY,
"S" = S_KEY,
"D" = D_KEY,
"Shift" = SHIFT_KEY,
"Ctrl" = CTRL_KEY,
"Alt" = ALT_KEY,
)
// These verbs are called for all movemen key press and release events
/client/verb/moveKeyDown(movekeyName as text)
set instant = TRUE
set hidden = TRUE
// set name = ".movekeydown"
set name = "KeyDown"
// Map text sent by skin.dmf to our numeric codes. (This can be optimized away once we update skin.dmf)
var/movekey = MOVE_KEY_MAPPINGS[movekeyName]
// Validate input. Must be one (and only one) of the key codes)
if(isnull(movekey) || (movekey & ~0xFFF) || (movekey & (movekey - 1)))
log_debug("Client [ckey] sent an illegal movement key down: [movekeyName] ([movekey])")
return
// Record that we are now holding the key!
move_keys_held |= (movekey & 0x0FF)
mod_keys_held |= (movekey & 0xF00)
// If we were NOT holding at the start of this move cycle and pressed it, remember that.
var/movement = MOVEMENT_KEYS_TO_DIR(movekey)
if(movement && !(next_move_dir_sub & movement) && !(mod_keys_held & CTRL_KEY)) // TODO-LESHANA - Possibly not holding Alt either
DEBUG_INPUT("Saving [dirs2text(movement)] into next_move_dir_ADD")
next_move_dir_add |= movement
#ifdef CARDINAL_INPUT_ONLY
if(movement)
DEBUG_INPUT("set last=[dirs2text(movement)]")
last_move_dir_pressed = movement
#endif
mob.focus?.key_down(movekey, src)
/client/verb/moveKeyUp(movekeyName as text)
set instant = TRUE
set hidden = TRUE
// set name = ".movekeyup"
set name = "KeyUp"
// Map text sent by skin.dmf to our numeric codes. (This can be optimized away once we update skin.dmf)
var/movekey = MOVE_KEY_MAPPINGS[movekeyName]
// Validate input. Must be one (and only one) of the key codes)
if(isnull(movekey) || (movekey & ~0xFFF) || (movekey & (movekey - 1)))
log_debug("Client [ckey] sent an illegal movement key up: [movekeyName] ([movekey])")
return
// Clear bit indicating we were holding the key
move_keys_held &= ~movekey
mod_keys_held &= ~movekey
// If we were holding at the start of this move cycle and now relased it, remember that.
var/movement = MOVEMENT_KEYS_TO_DIR(movekey)
if(movement && !(next_move_dir_add & movement))
DEBUG_INPUT("Saving [dirs2text(movement)] into next_move_dir_SUB")
next_move_dir_sub |= movement
mob.focus?.key_up(movekey, src)
// Called every game tick
/client/keyLoop()
mob.focus?.keyLoop(src)

View File

@@ -0,0 +1,42 @@
# In-code keypress handling system
This whole system is heavily based off of forum_account's keyboard library.
Thanks to forum_account for saving the day, the library can be found
[here](https://secure.byond.com/developer/Forum_account/Keyboard)!
.dmf macros have some very serious shortcomings. For example, they do not allow reusing parts
of one macro in another, so giving cyborgs their own shortcuts to swap active module couldn't
inherit the movement that all mobs should have anyways. The webclient only supports one macro,
so having more than one was problematic. Additionally each keybind has to call an actual
verb, which meant a lot of hidden verbs that just call one other proc. Also our existing
macro was really bad and tied unrelated behavior into `Northeast()`, `Southeast()`, `Northwest()`,
and `Southwest()`.
The basic premise of this system is to not screw with .dmf macro setup at all and handle
pressing those keys in the code instead. We have every key call `client.keyDown()`
or `client.keyUp()` with the pressed key as an argument. Certain keys get processed
directly by the client because they should be doable at any time, then we call
`keyDown()` or `keyUp()` on the client's holder and the client's mob's focus.
By default `mob.focus` is the mob itself, but you can set it to any datum to give control of a
client's keypresses to another object. This would be a good way to handle a menu or driving
a mech. You can also set it to null to disregard input from a certain user.
Movement is handled by having each client call `client.keyLoop()` every game tick.
As above, this calls holder and `focus.keyLoop()`. `atom/movable/keyLoop()` handles movement
Try to keep the calculations in this proc light. It runs every tick for every client after all!
You can also tell which keys are being held down now. Each client a list of keys pressed called
`keys_held`. Each entry is a key as a text string associated with the world.time when it was
pressed.
No client-set keybindings at this time, but it shouldn't be too hard if someone wants.
Notes about certain keys:
* `Tab` has client-sided behavior but acts normally
* `T`, `O`, and `M` move focus to the input when pressed. This fires the keyUp macro right away.
* `\` needs to be escaped in the dmf so any usage is `\\`
You cannot `TICK_CHECK` or check `world.tick_usage` inside of procs called by key down and up
events. They happen outside of a byond tick and have no meaning there. Key looping
works correctly since it's part of a subsystem, not direct input.

View File

@@ -0,0 +1,34 @@
// Set a client's focus to an object and override these procs on that object to let it handle keypresses
/datum/proc/key_down(key, client/user) // Called when a key is pressed down initially
return
/datum/proc/key_up(key, client/user) // Called when a key is released
return
/datum/proc/keyLoop(client/user) // Called once every server tick
set waitfor = FALSE
return
/// Set mob's focus
/// TODO - Do we even need this concept?
/mob/proc/set_focus(datum/new_focus)
if(focus == new_focus)
return
focus = new_focus
/// Turns a keys bitfield into text showing all bits set
/proc/keys2text(keys)
if(!keys)
return ""
var/list/out = list()
if(keys & NORTH_KEY) out += "NORTH"
if(keys & SOUTH_KEY) out += "SOUTH"
if(keys & EAST_KEY) out += "EAST"
if(keys & WEST_KEY) out += "WEST"
if(keys & W_KEY) out += "W"
if(keys & A_KEY) out += "A"
if(keys & S_KEY) out += "S"
if(keys & D_KEY) out += "D"
if(keys & CTRL_KEY) out += "CTRL"
if(keys & SHIFT_KEY) out += "SHIFT"
if(keys & ALT_KEY) out += "ALT"
return out.Join(" ")

View File

@@ -179,4 +179,4 @@
"brightness" = 0.1, "brightness" = 0.1,
"color" = "#27024B" "color" = "#27024B"
) )
) )

View File

@@ -139,18 +139,6 @@
. * applied_lum_b \ . * applied_lum_b \
); );
#define APPLY_CORNER_SIMPLE(C) \
. = light_power; \
var/OLD = effect_str[C]; \
\
C.update_lumcount \
( \
(. * lum_r) - (OLD * applied_lum_r), \
(. * lum_g) - (OLD * applied_lum_g), \
(. * lum_b) - (OLD * applied_lum_b) \
); \
/datum/light_source/proc/remove_lum() /datum/light_source/proc/remove_lum()
applied = FALSE applied = FALSE
for (var/datum/lighting_corner/corner as anything in effect_str) for (var/datum/lighting_corner/corner as anything in effect_str)
@@ -284,91 +272,7 @@
UNSETEMPTY(effect_str) UNSETEMPTY(effect_str)
// For planets and fake suns
/datum/light_source/sun
light_range = 1
light_color = "#FFFFFF"
light_power = 2
var/applied_power = 2
/datum/light_source/sun/New()
return
/datum/light_source/sun/force_update()
return
/datum/light_source/sun/vis_update()
return
/datum/light_source/sun/update_corners(var/list/turfs_to_update)
if(!LAZYLEN(turfs_to_update))
stack_trace("Planet sun tried to update with no turfs given")
return
// Update lum_r/g/b from our light_color
PARSE_LIGHT_COLOR(src)
// Noop update
if(lum_r == applied_lum_r && lum_g == applied_lum_g && lum_b == applied_lum_b && light_power == applied_power)
return
// No reason to unapply on the first run or if previous run was 0 power
if(applied)
remove_lum()
// Entirely dark, just stop now that we've remove_lum()'d
if(!light_power)
applied = FALSE
return
LAZYINITLIST(effect_str)
var/list/datum/lighting_corner/corners = list()
for(var/turf/T as anything in turfs_to_update)
if(!IS_OPAQUE_TURF(T))
if(!T.lighting_corners_initialised)
T.generate_missing_corners()
var/datum/lighting_corner/LC = T.lighting_corner_NE
if(!corners[LC])
corners[LC] = 1
APPLY_CORNER_SIMPLE(LC)
LAZYADD(LC.affecting, src)
effect_str[LC] = .
LC = T.lighting_corner_SE
if(!corners[LC])
corners[LC] = 1
APPLY_CORNER_SIMPLE(LC)
LAZYADD(LC.affecting, src)
effect_str[LC] = .
LC = T.lighting_corner_NW
if(!corners[LC])
corners[LC] = 1
APPLY_CORNER_SIMPLE(LC)
LAZYADD(LC.affecting, src)
effect_str[LC] = .
LC = T.lighting_corner_SW
if(!corners[LC])
corners[LC] = 1
APPLY_CORNER_SIMPLE(LC)
LAZYADD(LC.affecting, src)
effect_str[LC] = .
CHECK_TICK
applied_lum_r = lum_r
applied_lum_g = lum_g
applied_lum_b = lum_b
applied_power = light_power
applied = TRUE // remove_lum() now necessary in the future
UNSETEMPTY(effect_str)
#undef EFFECT_UPDATE #undef EFFECT_UPDATE
#undef LUM_FALLOFF #undef LUM_FALLOFF
#undef REMOVE_CORNER #undef REMOVE_CORNER
#undef APPLY_CORNER #undef APPLY_CORNER
#undef APPLY_CORNER_SIMPLE

View File

@@ -98,7 +98,6 @@
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
see_invisible = SEE_INVISIBLE_OBSERVER see_invisible = SEE_INVISIBLE_OBSERVER
see_in_dark = world.view //I mean. I don't even know if byond has occlusion culling... but... see_in_dark = world.view //I mean. I don't even know if byond has occlusion culling... but...
verbs += /mob/observer/dead/proc/dead_tele
var/turf/T var/turf/T
if(ismob(body)) if(ismob(body))
@@ -342,6 +341,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/area/A = areas[key] var/area/A = areas[key]
if(A.z in using_map?.secret_levels) if(A.z in using_map?.secret_levels)
areas -= key areas -= key
return areas return areas
/mob/observer/dead/proc/jumpable_mobs() /mob/observer/dead/proc/jumpable_mobs()
@@ -353,41 +353,62 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/mobz = get_z(mobs[key]) var/mobz = get_z(mobs[key])
if(mobz in using_map?.secret_levels) if(mobz in using_map?.secret_levels)
mobs -= key mobs -= key
return mobs return mobs
/mob/observer/dead/proc/dead_tele() /mob/observer/dead/verb/dead_tele(areaname as null|anything in jumpable_areas())
set category = "Ghost"
set name = "Teleport" set name = "Teleport"
set desc = "Teleport to a location" set category = "Ghost"
set desc = "Teleport to a location."
if(!istype(usr, /mob/observer/dead)) if(!istype(usr, /mob/observer/dead))
to_chat(usr, "Not when you're not dead!") to_chat(usr, "Not when you're not dead!")
return return
var/list/areas = jumpable_areas() var/area/A
var/input = tgui_input_list(usr, "Select an area:", "Ghost Teleport", areas)
if(!input)
return
var/area/A = areas[input] if(!areaname)
if(!A) return var/list/areas = jumpable_areas()
usr.forceMove(pick(get_area_turfs(A))) var/input = tgui_input_list(usr, "Select an area:", "Ghost Teleport", areas)
if(!input)
return
A = areas[input]
if(!A)
return
if(!istype(usr, /mob/observer/dead))
to_chat(usr, "Not when you're not dead!")
return
usr.forceMove(pick(get_area_turfs(A || jumpable_areas()[areaname])))
usr.on_mob_jump() usr.on_mob_jump()
/mob/observer/dead/verb/follow() /mob/observer/dead/verb/follow(mobname as null|anything in jumpable_mobs())
set name = "Follow"
set category = "Ghost" set category = "Ghost"
set name = "Follow" // "Haunt"
set desc = "Follow and haunt a mob." set desc = "Follow and haunt a mob."
var/list/possible_mobs = jumpable_mobs() if(!istype(usr, /mob/observer/dead))
var/input = tgui_input_list(usr, "Select a mob:", "Ghost Follow", possible_mobs) to_chat(usr, "Not when you're not dead!")
if(!input)
return return
var/target = possible_mobs[input]
if(!target) return
ManualFollow(target)
var/mob/M
if(!mobname)
var/list/possible_mobs = jumpable_mobs()
var/input = tgui_input_list(usr, "Select a mob:", "Ghost Follow", possible_mobs)
if(!input)
return
M = possible_mobs[input]
if(!M)
return
if(!istype(usr, /mob/observer/dead))
to_chat(usr, "Not when you're not dead!")
return
ManualFollow(M || jumpable_mobs()[mobname])
/mob/observer/dead/forceMove(atom/destination) /mob/observer/dead/forceMove(atom/destination)
if(client?.holder) if(client?.holder)
return ..() return ..()

View File

@@ -45,6 +45,12 @@
/mob/living/carbon/brain/isSynthetic() /mob/living/carbon/brain/isSynthetic()
return istype(loc, /obj/item/device/mmi) return istype(loc, /obj/item/device/mmi)
/mob/living/carbon/brain/runechat_holder(datum/chatmessage/CM)
if(isturf(loc))
return ..()
return loc
/mob/living/carbon/brain/set_typing_indicator(var/state) /mob/living/carbon/brain/set_typing_indicator(var/state)
if(isturf(loc)) if(isturf(loc))
return ..() return ..()

View File

@@ -135,11 +135,139 @@ var/list/_human_default_emotes = list(
//VOREStation Add End //VOREStation Add End
) )
//VOREStation Add Start
var/list/_simple_mob_default_emotes = list(
/decl/emote/visible/blink,
/decl/emote/visible/nod,
/decl/emote/visible/shake,
/decl/emote/visible/shiver,
/decl/emote/visible/collapse,
/decl/emote/audible/gasp,
/decl/emote/audible/choke,
/decl/emote/audible/sneeze,
/decl/emote/audible/sniff,
/decl/emote/audible/snore,
/decl/emote/audible/whimper,
/decl/emote/audible/whistle,
/decl/emote/audible/whistle/quiet,
/decl/emote/audible/whistle/wolf,
/decl/emote/audible/whistle/summon,
/decl/emote/audible/yawn,
/decl/emote/audible/clap,
/decl/emote/audible/chuckle,
/decl/emote/audible/cough,
/decl/emote/audible/cry,
/decl/emote/audible/sigh,
/decl/emote/audible/laugh,
/decl/emote/audible/mumble,
/decl/emote/audible/grumble,
/decl/emote/audible/groan,
/decl/emote/audible/moan,
/decl/emote/audible/grunt,
/decl/emote/audible/slap,
/decl/emote/audible/crack,
/decl/emote/human/deathgasp,
/decl/emote/audible/giggle,
/decl/emote/audible/scream,
/decl/emote/visible/airguitar,
/decl/emote/visible/blink_r,
/decl/emote/visible/bow,
/decl/emote/visible/salute,
/decl/emote/visible/flap,
/decl/emote/visible/aflap,
/decl/emote/visible/drool,
/decl/emote/visible/eyebrow,
/decl/emote/visible/twitch,
/decl/emote/visible/dance,
/decl/emote/visible/twitch_v,
/decl/emote/visible/faint,
/decl/emote/visible/frown,
/decl/emote/visible/blush,
/decl/emote/visible/wave,
/decl/emote/visible/glare,
/decl/emote/visible/stare,
/decl/emote/visible/look,
/decl/emote/visible/point,
/decl/emote/visible/raise,
/decl/emote/visible/grin,
/decl/emote/visible/shrug,
/decl/emote/visible/smile,
/decl/emote/visible/pale,
/decl/emote/visible/tremble,
/decl/emote/visible/wink,
/decl/emote/visible/hug,
/decl/emote/visible/signal,
/decl/emote/visible/afold,
/decl/emote/visible/alook,
/decl/emote/visible/eroll,
/decl/emote/visible/hbow,
/decl/emote/visible/hip,
/decl/emote/visible/holdup,
/decl/emote/visible/hshrug,
/decl/emote/visible/crub,
/decl/emote/visible/erub,
/decl/emote/visible/fslap,
/decl/emote/visible/ftap,
/decl/emote/visible/hrub,
/decl/emote/visible/hspread,
/decl/emote/visible/rsalute,
/decl/emote/visible/rshoulder,
/decl/emote/visible/squint,
/decl/emote/visible/tfist,
/decl/emote/visible/tilt,
/decl/emote/visible/spin,
/decl/emote/visible/sidestep,
/decl/emote/visible/vomit,
/decl/emote/visible/floorspin,
/decl/emote/visible/flip,
/decl/emote/audible/awoo,
/decl/emote/audible/awoo2,
/decl/emote/audible/growl,
/decl/emote/audible/woof,
/decl/emote/audible/woof2,
/decl/emote/audible/nya,
/decl/emote/audible/mrowl,
/decl/emote/audible/peep,
/decl/emote/audible/chirp,
/decl/emote/audible/hoot,
/decl/emote/audible/weh,
/decl/emote/audible/merp,
/decl/emote/audible/myarp,
/decl/emote/audible/bark,
/decl/emote/audible/bork,
/decl/emote/audible/mrow,
/decl/emote/audible/hypno,
/decl/emote/audible/hiss,
/decl/emote/audible/rattle,
/decl/emote/audible/squeak,
/decl/emote/audible/geck,
/decl/emote/audible/baa,
/decl/emote/audible/baa2,
/decl/emote/audible/mar,
/decl/emote/audible/wurble,
/decl/emote/audible/snort,
/decl/emote/audible/meow,
/decl/emote/audible/moo,
/decl/emote/audible/croak,
/decl/emote/audible/gao,
/decl/emote/audible/cackle,
/decl/emote/audible/squish,
/decl/emote/audible/spiderchitter,
/decl/emote/audible/spiderpurr,
/decl/emote/visible/mlem,
/decl/emote/visible/blep
)
//VOREStation Add End
/mob/living/carbon/human/get_available_emotes() /mob/living/carbon/human/get_available_emotes()
. = global._human_default_emotes . = global._human_default_emotes
if(length(species?.default_emotes)) if(length(species?.default_emotes))
. |= species.default_emotes . |= species.default_emotes
/mob/living/simple_mob/get_available_emotes()
. = global._simple_mob_default_emotes
/mob/living/carbon/human/verb/pose() /mob/living/carbon/human/verb/pose()
set name = "Set Pose" set name = "Set Pose"
set desc = "Sets a description which will be shown when someone examines you." set desc = "Sets a description which will be shown when someone examines you."

View File

@@ -3,7 +3,7 @@
/mob/living /mob/living
var/ooc_notes = null var/ooc_notes = null
appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER|LONG_GLIDE
var/hunger_rate = DEFAULT_HUNGER_FACTOR var/hunger_rate = DEFAULT_HUNGER_FACTOR
//custom say verbs //custom say verbs
var/custom_say = null var/custom_say = null

View File

@@ -197,7 +197,15 @@ default behaviour is:
now_pushing = 0 now_pushing = 0
return return
step(AM, t) var/turf/T = AM.loc
var/turf/T2 = get_step(AM,t)
if(!T2) // Map edge
now_pushing = 0
return
var/move_time = movement_delay(loc, t)
move_time = DS2NEARESTTICK(move_time)
if(AM.Move(T2, t, move_time))
Move(T, t, move_time)
if(ishuman(AM) && AM:grabbed_by) if(ishuman(AM) && AM:grabbed_by)
for(var/obj/item/weapon/grab/G in AM:grabbed_by) for(var/obj/item/weapon/grab/G in AM:grabbed_by)

View File

@@ -141,7 +141,12 @@ GLOBAL_VAR_INIT(chicken_count, 0) // How mant chickens DO we have?
if(!stat) if(!stat)
amount_grown += rand(1,2) amount_grown += rand(1,2)
if(amount_grown >= 100) if(amount_grown >= 100)
new /mob/living/simple_mob/animal/passive/chicken(src.loc) //VOREStation Edit Begin
var/mob/living/simple_mob/animal/passive/chicken/C = new (src.loc)
C.ghostjoin = 1
C.ghostjoin_icon()
active_ghost_pods |= C
//VOREStation Edit End
qdel(src) qdel(src)
// Say Lists // Say Lists

View File

@@ -40,6 +40,7 @@
else else
living_mob_list += src living_mob_list += src
lastarea = get_area(src) lastarea = get_area(src)
set_focus(src) // VOREStation Add - Key Handling
hook_vr("mob_new",list(src)) //VOREStation Code hook_vr("mob_new",list(src)) //VOREStation Code
update_transform() // Some mobs may start bigger or smaller than normal. update_transform() // Some mobs may start bigger or smaller than normal.
return ..() return ..()
@@ -616,7 +617,10 @@
stat("CPU:","[world.cpu]") stat("CPU:","[world.cpu]")
stat("Instances:","[world.contents.len]") stat("Instances:","[world.contents.len]")
stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)") stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)")
stat("Keys Held", keys2text(client.move_keys_held | client.mod_keys_held))
stat("Next Move ADD", dirs2text(client.next_move_dir_add))
stat("Next Move SUB", dirs2text(client.next_move_dir_sub))
if(statpanel("MC")) if(statpanel("MC"))
stat("Location:", "([x], [y], [z]) [loc]") stat("Location:", "([x], [y], [z]) [loc]")
stat("CPU:","[world.cpu]") stat("CPU:","[world.cpu]")
@@ -689,6 +693,7 @@
/mob/proc/facedir(var/ndir) /mob/proc/facedir(var/ndir)
if(!canface() || (client && (client.moving || !checkMoveCooldown()))) if(!canface() || (client && (client.moving || !checkMoveCooldown())))
DEBUG_INPUT("Denying Facedir for [src] (moving=[client?.moving])")
return 0 return 0
set_dir(ndir) set_dir(ndir)
if(buckled && buckled.buckle_movable) if(buckled && buckled.buckle_movable)

View File

@@ -231,3 +231,5 @@
var/in_enclosed_vehicle = 0 //For mechs and fighters ambiance. Can be used in other cases. var/in_enclosed_vehicle = 0 //For mechs and fighters ambiance. Can be used in other cases.
var/list/progressbars = null //VOREStation Edit var/list/progressbars = null //VOREStation Edit
var/datum/focus //What receives our keyboard inputs. src by default // VOREStation Add - Key Handling

View File

@@ -140,22 +140,32 @@
// Used many times below, faster reference. // Used many times below, faster reference.
var/atom/loc = my_mob.loc var/atom/loc = my_mob.loc
// We're controlling an object which is SOMEHOW DIFFERENT FROM AN EYE?? // We're controlling an object which is when admins possess an object.
if(my_mob.control_object) if(my_mob.control_object)
Move_object(direct) Move_object(direct)
// Ghosty mob movement // Ghosty mob movement
if(my_mob.incorporeal_move && isobserver(my_mob)) if(my_mob.incorporeal_move && isobserver(my_mob))
Process_Incorpmove(direct) Process_Incorpmove(direct)
DEBUG_INPUT("--------")
next_move_dir_add = 0 // This one I *think* exists so you can tap move and it will move even if delay isn't quite up.
next_move_dir_sub = 0 // I'm not really sure why next_move_dir_sub even exists.
return return
// We're in the middle of another move we've already decided to do // We're in the middle of another move we've already decided to do
if(moving) if(moving)
log_debug("Client [src] attempted to move while moving=[moving]")
return 0 return 0
// We're still cooling down from the last move // We're still cooling down from the last move
if(!my_mob.checkMoveCooldown()) if(!my_mob.checkMoveCooldown())
return return
DEBUG_INPUT("--------")
next_move_dir_add = 0 // This one I *think* exists so you can tap move and it will move even if delay isn't quite up.
next_move_dir_sub = 0 // I'm not really sure why next_move_dir_sub even exists.
if(!n || !direct)
return
// If dead and we try to move in our mob, it leaves our body // If dead and we try to move in our mob, it leaves our body
if(my_mob.stat == DEAD && isliving(my_mob) && !my_mob.forbid_seeing_deadchat) if(my_mob.stat == DEAD && isliving(my_mob) && !my_mob.forbid_seeing_deadchat)
@@ -287,6 +297,10 @@
else else
. = my_mob.SelfMove(n, direct, total_delay) . = my_mob.SelfMove(n, direct, total_delay)
// If we ended up moving diagonally, increase delay.
if((direct & (direct - 1)) && mob.loc == n)
my_mob.setMoveCooldown(total_delay * 2)
// If we have a grab // If we have a grab
var/list/grablist = my_mob.ret_grab() var/list/grablist = my_mob.ret_grab()
if(LAZYLEN(grablist)) if(LAZYLEN(grablist))

View File

@@ -122,6 +122,7 @@
screen_loc = "CENTER" screen_loc = "CENTER"
plane = -100 //Dodge just in case someone instantiates one of these accidentally, don't end up on 0 with plane_master plane = -100 //Dodge just in case someone instantiates one of these accidentally, don't end up on 0 with plane_master
appearance_flags = PLANE_MASTER appearance_flags = PLANE_MASTER
vis_flags = NONE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT //Normally unclickable mouse_opacity = MOUSE_OPACITY_TRANSPARENT //Normally unclickable
alpha = 0 //Hidden from view alpha = 0 //Hidden from view
var/desired_alpha = 255 //What we go to when we're enabled var/desired_alpha = 255 //What we go to when we're enabled

View File

@@ -95,7 +95,7 @@
if(stored_mmi) if(stored_mmi)
. = stored_mmi //VOREStation Code . = stored_mmi //VOREStation Code
stored_mmi.loc = get_turf(src) stored_mmi.forceMove(drop_location())
if(owner.mind) if(owner.mind)
owner.mind.transfer_to(stored_mmi.brainmob) owner.mind.transfer_to(stored_mmi.brainmob)
..() ..()

View File

@@ -32,7 +32,7 @@
/obj/effect/overmap/bluespace_rift/attack_ghost(var/mob/observer/dead/user) /obj/effect/overmap/bluespace_rift/attack_ghost(var/mob/observer/dead/user)
if(!partner && user?.client?.holder) if(!partner && user?.client?.holder)
var/response = tgui_alert(user, "You appear to be staff. This rift has no exit point. If you want to make one, move to where you want it to go, and click 'Make Here', otherwise click 'Cancel'",list("Rift Exit","Cancel","Make Here")) var/response = tgui_alert(user, "You appear to be staff. This rift has no exit point. If you want to make one, move to where you want it to go, and click 'Make Here', otherwise click 'Cancel'", "Bluespace Rift", list("Cancel","Make Here"))
if(response == "Make Here") if(response == "Make Here")
new type(get_turf(user), src) new type(get_turf(user), src)
else if(partner) else if(partner)

View File

@@ -8,16 +8,17 @@
/datum/persistent/paintings/Initialize() /datum/persistent/paintings/Initialize()
. = ..() . = ..()
if(fexists(filename)) if(fexists(filename))
SSpersistence.paintings = json_decode(file2text(filename)) SSpersistence.all_paintings = json_decode(file2text(filename))
var/list/tokens = SSpersistence.paintings var/list/tokens = SSpersistence.all_paintings
for(var/list/token in tokens) for(var/list/token in tokens)
token["age"]++ // Increment age! token["age"]++ // Increment age!
if(!CheckTokenSanity(token)) if(!CheckTokenSanity(token))
tokens -= token tokens -= token
SSpersistence.unpicked_paintings = SSpersistence.all_paintings.Copy()
for(var/obj/structure/sign/painting/P in SSpersistence.painting_frames) for(var/obj/structure/sign/painting/P in SSpersistence.painting_frames)
P.load_persistent() P.load_persistent()
return
/datum/persistent/paintings/CheckTokenSanity(var/list/token) /datum/persistent/paintings/CheckTokenSanity(var/list/token)
var/png_filename = "data/paintings/[token["persistence_id"]]/[token["md5"]].png" var/png_filename = "data/paintings/[token["persistence_id"]]/[token["md5"]].png"
@@ -33,4 +34,4 @@
if(fexists(filename)) if(fexists(filename))
fdel(filename) fdel(filename)
to_file(file(filename), json_encode(SSpersistence.paintings)) to_file(file(filename), json_encode(SSpersistence.all_paintings))

View File

@@ -67,8 +67,8 @@
/obj/machinery/conveyor/proc/update_dir() /obj/machinery/conveyor/proc/update_dir()
if(!(dir in cardinal)) // Diagonal. Forwards is *away* from dir, curving to the right. if(!(dir in cardinal)) // Diagonal. Forwards is *away* from dir, curving to the right.
forwards = turn(dir, 135) forwards = turn(dir, 45)
backwards = turn(dir, 45) backwards = turn(dir, 135)
else else
forwards = dir forwards = dir
backwards = turn(dir, 180) backwards = turn(dir, 180)

View File

@@ -580,11 +580,9 @@
for(var/obj/item/W in M) for(var/obj/item/W in M)
if(istype(W, /obj/item/organ/internal/mmi_holder/posibrain)) if(istype(W, /obj/item/organ/internal/mmi_holder/posibrain))
var/obj/item/organ/internal/mmi_holder/MMI = W var/obj/item/organ/internal/mmi_holder/MMI = W
var/atom/movable/brain = MMI.removed() var/obj/item/device/mmi/brainbox = MMI.removed()
if(brain) if(brainbox)
M.remove_from_mob(brain,owner) items_preserved += brainbox
brain.forceMove(src)
items_preserved += brain
for(var/slot in slots) for(var/slot in slots)
var/obj/item/I = M.get_equipped_item(slot = slot) var/obj/item/I = M.get_equipped_item(slot = slot)
if(I) if(I)

View File

@@ -10,6 +10,10 @@
return return
HandleBellyReagents() //CHOMP reagent belly stuff, here to jam it into subsystems and avoid too much cpu usage HandleBellyReagents() //CHOMP reagent belly stuff, here to jam it into subsystems and avoid too much cpu usage
// VERY early exit
if(!contents.len)
return
var/play_sound //Potential sound to play at the end to avoid code duplication. var/play_sound //Potential sound to play at the end to avoid code duplication.
var/to_update = FALSE //Did anything update worthy happen? var/to_update = FALSE //Did anything update worthy happen?
@@ -51,28 +55,29 @@
if(hta_returns["to_update"]) if(hta_returns["to_update"])
to_update = hta_returns["to_update"] to_update = hta_returns["to_update"]
if(!islist(touchable_mobs)) if(!LAZYLEN(touchable_mobs))
return return
///////////////////// Early Non-Mode Handling ///////////////////// ///////////////////// Early Non-Mode Handling /////////////////////
var/list/EL = emote_lists[digest_mode] if(emote_active)
if(LAZYLEN(EL) && touchable_mobs && next_emote <= world.time && emote_active) var/list/EL = emote_lists[digest_mode]
next_emote = world.time + (emote_time SECONDS) if(LAZYLEN(EL) && next_emote <= world.time)
for(var/mob/living/M in contents)
if(digest_mode == DM_DIGEST && !M.digestable)
continue // don't give digesty messages to indigestible people
var/living_count = 0 var/living_count = 0
for(var/mob/living/L in contents) for(var/mob/living/L in contents)
living_count++ living_count++
next_emote = world.time + (emote_time SECONDS)
for(var/mob/living/M in contents)
if(digest_mode == DM_DIGEST && !M.digestable)
continue // don't give digesty messages to indigestible people
var/raw_message = pick(EL) var/raw_message = pick(EL)
var/formatted_message var/formatted_message
formatted_message = replacetext(raw_message, "%belly", lowertext(name)) formatted_message = replacetext(raw_message, "%belly", lowertext(name))
formatted_message = replacetext(formatted_message, "%pred", owner) formatted_message = replacetext(formatted_message, "%pred", owner)
formatted_message = replacetext(formatted_message, "%prey", english_list(contents)) formatted_message = replacetext(formatted_message, "%prey", english_list(contents))
formatted_message = replacetext(formatted_message, "%count", contents.len) formatted_message = replacetext(formatted_message, "%count", contents.len)
formatted_message = replacetext(formatted_message, "%countprey", living_count) formatted_message = replacetext(formatted_message, "%countprey", living_count)
to_chat(M, "<span class='notice'>[formatted_message]</span>") to_chat(M, "<span class='notice'>[formatted_message]</span>")
if(!digestion_noise_chance) if(!digestion_noise_chance)
digestion_noise_chance = DM.noise_chance digestion_noise_chance = DM.noise_chance

View File

@@ -542,8 +542,11 @@
else else
swallow_time = istype(prey, /mob/living/carbon/human) ? belly.human_prey_swallow_time : belly.nonhuman_prey_swallow_time swallow_time = istype(prey, /mob/living/carbon/human) ? belly.human_prey_swallow_time : belly.nonhuman_prey_swallow_time
// Their AI should get notified so they can stab us
prey.ai_holder?.react_to_attack(user)
//Timer and progress bar //Timer and progress bar
if(!do_after(user, swallow_time, prey)) if(!do_after(user, swallow_time, prey, exclusive = TRUE))
return FALSE // Prey escpaed (or user disabled) before timer expired. return FALSE // Prey escpaed (or user disabled) before timer expired.
// If we got this far, nom successful! Announce it! // If we got this far, nom successful! Announce it!

View File

@@ -61,7 +61,7 @@
if(!ui) if(!ui)
update_preview_icon() //CHOMPEdit update_preview_icon() //CHOMPEdit
give_client_previews(user.client) //CHOMPEdit give_client_previews(user.client) //CHOMPEdit
ui = new(user, src, "VorePanel", "Inside!") ui = new(user, src, "VorePanel", "Vore Panel")
ui.open() ui.open()
// This looks weird, but all tgui_host is used for is state checking // This looks weird, but all tgui_host is used for is state checking

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -2,9 +2,24 @@ macro "borghotkeymode"
elem elem
name = "TAB" name = "TAB"
command = ".winset \"mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5\"" command = ".winset \"mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5\""
elem elem
name = "CENTER+REP" name = "Shift"
command = ".center" command = "KeyDown Shift"
elem
name = "Shift+UP"
command = "KeyUp Shift"
elem
name = "Ctrl"
command = "KeyDown Ctrl"
elem
name = "Ctrl+UP"
command = "KeyUp Ctrl"
elem
name = "Alt"
command = "KeyDown Alt"
elem
name = "Alt+UP"
command = "KeyUp Alt"
elem elem
name = "NORTHEAST" name = "NORTHEAST"
command = ".northeast" command = ".northeast"
@@ -24,8 +39,11 @@ macro "borghotkeymode"
name = "CTRL+WEST" name = "CTRL+WEST"
command = "westface" command = "westface"
elem elem
name = "WEST+REP" name = "West"
command = ".west" command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
elem elem
name = "ALT+NORTH" name = "ALT+NORTH"
command = "northfaceperm" command = "northfaceperm"
@@ -33,8 +51,11 @@ macro "borghotkeymode"
name = "CTRL+NORTH" name = "CTRL+NORTH"
command = "northface" command = "northface"
elem elem
name = "NORTH+REP" name = "North"
command = ".moveup" command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
elem elem
name = "ALT+EAST" name = "ALT+EAST"
command = "eastfaceperm" command = "eastfaceperm"
@@ -42,18 +63,18 @@ macro "borghotkeymode"
name = "CTRL+EAST" name = "CTRL+EAST"
command = "eastface" command = "eastface"
elem elem
name = "EAST+REP" name = "East"
command = ".moveright" command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
elem elem
name = "ALT+SOUTH" name = "ALT+SOUTH"
command = "southfaceperm" command = "southfaceperm"
elem elem
name = "CTRL+SOUTH" name = "CTRL+SOUTH"
command = "southface" command = "southface"
elem elem
name = "SOUTH+REP"
command = ".movedown"
elem
name = "CTRL+SHIFT+NORTH" name = "CTRL+SHIFT+NORTH"
command = "shiftnorth" command = "shiftnorth"
elem elem
@@ -65,6 +86,11 @@ macro "borghotkeymode"
elem elem
name = "CTRL+SHIFT+EAST" name = "CTRL+SHIFT+EAST"
command = "shifteast" command = "shifteast"
name = "South"
command = "KeyDown South"
elem
name = "South+UP"
command = "KeyUp South"
elem elem
name = "INSERT" name = "INSERT"
command = "a-intent right" command = "a-intent right"
@@ -99,17 +125,17 @@ macro "borghotkeymode"
name = "5" name = "5"
command = ".me" command = ".me"
elem elem
name = "A+REP" name = "A"
command = ".moveleft" command = "KeyDown A"
elem
name = "A+UP"
command = "KeyUp A"
elem elem
name = "CTRL+A+REP" name = "D"
command = ".moveleft" command = "KeyDown D"
elem elem
name = "D+REP" name = "D+UP"
command = ".moveright" command = "KeyUp D"
elem
name = "CTRL+D+REP"
command = ".moveright"
elem elem
name = "F" name = "F"
command = "a-intent left" command = "a-intent left"
@@ -141,20 +167,20 @@ macro "borghotkeymode"
name = "CTRL+R" name = "CTRL+R"
command = ".southwest" command = ".southwest"
elem "s_key" elem "s_key"
name = "S+REP" name = "S"
command = ".movedown" command = "KeyDown S"
elem elem
name = "CTRL+S+REP" name = "S+UP"
command = ".movedown" command = "KeyUp S"
elem elem
name = "T" name = "T"
command = ".say" command = ".say"
elem "w_key" elem "w_key"
name = "W+REP" name = "W"
command = ".moveup" command = "KeyDown W"
elem elem
name = "CTRL+W+REP" name = "W+UP"
command = ".moveup" command = "KeyUp W"
elem elem
name = "X" name = "X"
command = ".northeast" command = ".northeast"
@@ -235,9 +261,24 @@ macro "macro"
elem elem
name = "TAB" name = "TAB"
command = ".winset \"mainwindow.macro=hotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true\"" command = ".winset \"mainwindow.macro=hotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true\""
elem elem
name = "CENTER+REP" name = "Shift"
command = ".center" command = "KeyDown Shift"
elem
name = "Shift+UP"
command = "KeyUp Shift"
elem
name = "Ctrl"
command = "KeyDown Ctrl"
elem
name = "Ctrl+UP"
command = "KeyUp Ctrl"
elem
name = "Alt"
command = "KeyDown Alt"
elem
name = "Alt+UP"
command = "KeyUp Alt"
elem elem
name = "NORTHEAST" name = "NORTHEAST"
command = ".northeast" command = ".northeast"
@@ -257,8 +298,11 @@ macro "macro"
name = "CTRL+WEST" name = "CTRL+WEST"
command = "westface" command = "westface"
elem elem
name = "WEST+REP" name = "West"
command = ".moveleft" command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
elem elem
name = "ALT+NORTH" name = "ALT+NORTH"
command = "northfaceperm" command = "northfaceperm"
@@ -266,8 +310,11 @@ macro "macro"
name = "CTRL+NORTH" name = "CTRL+NORTH"
command = "northface" command = "northface"
elem elem
name = "NORTH+REP" name = "North"
command = ".moveup" command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
elem elem
name = "ALT+EAST" name = "ALT+EAST"
command = "eastfaceperm" command = "eastfaceperm"
@@ -275,18 +322,18 @@ macro "macro"
name = "CTRL+EAST" name = "CTRL+EAST"
command = "eastface" command = "eastface"
elem elem
name = "EAST+REP" name = "East"
command = ".moveright" command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
elem elem
name = "ALT+SOUTH" name = "ALT+SOUTH"
command = "southfaceperm" command = "southfaceperm"
elem elem
name = "CTRL+SOUTH" name = "CTRL+SOUTH"
command = "southface" command = "southface"
elem elem
name = "SOUTH+REP"
command = ".movedown"
elem
name = "CTRL+SHIFT+NORTH" name = "CTRL+SHIFT+NORTH"
command = "shiftnorth" command = "shiftnorth"
elem elem
@@ -298,6 +345,11 @@ macro "macro"
elem elem
name = "CTRL+SHIFT+EAST" name = "CTRL+SHIFT+EAST"
command = "shifteast" command = "shifteast"
name = "South"
command = "KeyDown South"
elem
name = "South+UP"
command = "KeyUp South"
elem elem
name = "INSERT" name = "INSERT"
command = "a-intent right" command = "a-intent right"
@@ -317,11 +369,17 @@ macro "macro"
name = "CTRL+4" name = "CTRL+4"
command = "a-intent harm" command = "a-intent harm"
elem elem
name = "CTRL+A+REP" name = "CTRL+A"
command = ".moveleft" command = "KeyDown A"
elem
name = "CTRL+A+UP"
command = "KeyUp A"
elem elem
name = "CTRL+D+REP" name = "CTRL+D"
command = ".moveright" command = "KeyDown D"
elem
name = "CTRL+D+UP"
command = "KeyUp D"
elem elem
name = "CTRL+E" name = "CTRL+E"
command = "quick-equip" command = "quick-equip"
@@ -338,11 +396,17 @@ macro "macro"
name = "CTRL+R" name = "CTRL+R"
command = ".southwest" command = ".southwest"
elem elem
name = "CTRL+S+REP" name = "CTRL+S"
command = ".movedown" command = "KeyDown S"
elem
name = "CTRL+S+UP"
command = "KeyUp S"
elem elem
name = "CTRL+W+REP" name = "CTRL+W"
command = ".moveup" command = "KeyDown W"
elem
name = "CTRL+W+UP"
command = "KeyUp W"
elem elem
name = "CTRL+X" name = "CTRL+X"
command = ".northeast" command = ".northeast"
@@ -420,9 +484,24 @@ macro "hotkeymode"
elem elem
name = "TAB" name = "TAB"
command = ".winset \"mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true\"" command = ".winset \"mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true\""
elem elem
name = "CENTER+REP" name = "Shift"
command = ".center" command = "KeyDown Shift"
elem
name = "Shift+UP"
command = "KeyUp Shift"
elem
name = "Ctrl"
command = "KeyDown Ctrl"
elem
name = "Ctrl+UP"
command = "KeyUp Ctrl"
elem
name = "Alt"
command = "KeyDown Alt"
elem
name = "Alt+UP"
command = "KeyUp Alt"
elem elem
name = "NORTHEAST" name = "NORTHEAST"
command = ".northeast" command = ".northeast"
@@ -442,8 +521,11 @@ macro "hotkeymode"
name = "CTRL+WEST" name = "CTRL+WEST"
command = "westface" command = "westface"
elem elem
name = "WEST+REP" name = "West"
command = ".moveleft" command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
elem elem
name = "ALT+NORTH" name = "ALT+NORTH"
command = "northfaceperm" command = "northfaceperm"
@@ -451,8 +533,11 @@ macro "hotkeymode"
name = "CTRL+NORTH" name = "CTRL+NORTH"
command = "northface" command = "northface"
elem elem
name = "NORTH+REP" name = "North"
command = ".moveup" command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
elem elem
name = "ALT+EAST" name = "ALT+EAST"
command = "eastfaceperm" command = "eastfaceperm"
@@ -460,18 +545,18 @@ macro "hotkeymode"
name = "CTRL+EAST" name = "CTRL+EAST"
command = "eastface" command = "eastface"
elem elem
name = "EAST+REP" name = "East"
command = ".moveright" command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
elem elem
name = "ALT+SOUTH" name = "ALT+SOUTH"
command = "southfaceperm" command = "southfaceperm"
elem elem
name = "CTRL+SOUTH" name = "CTRL+SOUTH"
command = "southface" command = "southface"
elem elem
name = "SOUTH+REP"
command = ".movedown"
elem
name = "CTRL+SHIFT+NORTH" name = "CTRL+SHIFT+NORTH"
command = "shiftnorth" command = "shiftnorth"
elem elem
@@ -483,6 +568,11 @@ macro "hotkeymode"
elem elem
name = "CTRL+SHIFT+EAST" name = "CTRL+SHIFT+EAST"
command = "shifteast" command = "shifteast"
name = "South"
command = "KeyDown South"
elem
name = "South+UP"
command = "KeyUp South"
elem elem
name = "INSERT" name = "INSERT"
command = "a-intent right" command = "a-intent right"
@@ -520,17 +610,17 @@ macro "hotkeymode"
name = "6" name = "6"
command = ".Subtle" command = ".Subtle"
elem elem
name = "A+REP" name = "A"
command = ".moveleft" command = "KeyDown A"
elem
name = "A+UP"
command = "KeyUp A"
elem elem
name = "CTRL+A+REP" name = "D"
command = ".moveleft" command = "KeyDown D"
elem elem
name = "D+REP" name = "D+UP"
command = ".moveright" command = "KeyUp D"
elem
name = "CTRL+D+REP"
command = ".moveright"
elem elem
name = "E" name = "E"
command = "quick-equip" command = "quick-equip"
@@ -574,20 +664,20 @@ macro "hotkeymode"
name = "CTRL+R" name = "CTRL+R"
command = ".southwest" command = ".southwest"
elem "s_key" elem "s_key"
name = "S+REP" name = "S"
command = ".movedown" command = "KeyDown S"
elem elem
name = "CTRL+S+REP" name = "S+UP"
command = ".movedown" command = "KeyUp S"
elem elem
name = "T" name = "T"
command = ".say" command = ".say"
elem "w_key" elem "w_key"
name = "W+REP" name = "W"
command = ".moveup" command = "KeyDown W"
elem elem
name = "CTRL+W+REP" name = "W+UP"
command = ".moveup" command = "KeyUp W"
elem elem
name = "X" name = "X"
command = ".northeast" command = ".northeast"
@@ -674,9 +764,24 @@ macro "borgmacro"
elem elem
name = "TAB" name = "TAB"
command = ".winset \"mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0\"" command = ".winset \"mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0\""
elem elem
name = "CENTER+REP" name = "Shift"
command = ".center" command = "KeyDown Shift"
elem
name = "Shift+UP"
command = "KeyUp Shift"
elem
name = "Ctrl"
command = "KeyDown Ctrl"
elem
name = "Ctrl+UP"
command = "KeyUp Ctrl"
elem
name = "Alt"
command = "KeyDown Alt"
elem
name = "Alt+UP"
command = "KeyUp Alt"
elem elem
name = "NORTHEAST" name = "NORTHEAST"
command = ".northeast" command = ".northeast"
@@ -696,8 +801,11 @@ macro "borgmacro"
name = "CTRL+WEST" name = "CTRL+WEST"
command = "westface" command = "westface"
elem elem
name = "WEST+REP" name = "West"
command = ".moveleft" command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
elem elem
name = "ALT+NORTH" name = "ALT+NORTH"
command = "northfaceperm" command = "northfaceperm"
@@ -705,8 +813,11 @@ macro "borgmacro"
name = "CTRL+NORTH" name = "CTRL+NORTH"
command = "northface" command = "northface"
elem elem
name = "NORTH+REP" name = "North"
command = ".moveup" command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
elem elem
name = "ALT+EAST" name = "ALT+EAST"
command = "eastfaceperm" command = "eastfaceperm"
@@ -714,18 +825,18 @@ macro "borgmacro"
name = "CTRL+EAST" name = "CTRL+EAST"
command = "eastface" command = "eastface"
elem elem
name = "EAST+REP" name = "East"
command = ".moveright" command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
elem elem
name = "ALT+SOUTH" name = "ALT+SOUTH"
command = "southfaceperm" command = "southfaceperm"
elem elem
name = "CTRL+SOUTH" name = "CTRL+SOUTH"
command = "southface" command = "southface"
elem elem
name = "SOUTH+REP"
command = ".movedown"
elem
name = "CTRL+SHIFT+NORTH" name = "CTRL+SHIFT+NORTH"
command = "shiftnorth" command = "shiftnorth"
elem elem
@@ -737,6 +848,11 @@ macro "borgmacro"
elem elem
name = "CTRL+SHIFT+EAST" name = "CTRL+SHIFT+EAST"
command = "shifteast" command = "shifteast"
name = "South"
command = "KeyDown South"
elem
name = "South+UP"
command = "KeyUp South"
elem elem
name = "INSERT" name = "INSERT"
command = "a-intent right" command = "a-intent right"
@@ -756,11 +872,17 @@ macro "borgmacro"
name = "CTRL+4" name = "CTRL+4"
command = "a-intent left" command = "a-intent left"
elem elem
name = "CTRL+A+REP" name = "CTRL+A"
command = ".moveleft" command = "KeyDown A"
elem
name = "CTRL+A+UP"
command = "KeyUp A"
elem elem
name = "CTRL+D+REP" name = "CTRL+D"
command = ".moveright" command = "KeyDown D"
elem
name = "CTRL+D+UP"
command = "KeyUp D"
elem elem
name = "CTRL+F" name = "CTRL+F"
command = "a-intent left" command = "a-intent left"
@@ -774,11 +896,17 @@ macro "borgmacro"
name = "CTRL+R" name = "CTRL+R"
command = ".southwest" command = ".southwest"
elem elem
name = "CTRL+S+REP" name = "CTRL+S"
command = ".movedown" command = "KeyDown S"
elem
name = "CTRL+S+UP"
command = "KeyUp S"
elem elem
name = "CTRL+W+REP" name = "CTRL+W"
command = ".moveup" command = "KeyDown W"
elem
name = "CTRL+W+UP"
command = "KeyUp W"
elem elem
name = "CTRL+X" name = "CTRL+X"
command = ".northeast" command = ".northeast"
@@ -980,210 +1108,6 @@ menu "menu"
category = "&Help" category = "&Help"
saved-params = "is-checked" saved-params = "is-checked"
window "Telecomms IDE"
elem "Telecomms IDE"
type = MAIN
pos = 281,0
size = 569x582
anchor1 = -1,-1
anchor2 = -1,-1
background-color = #ffffff
is-visible = false
saved-params = "pos;size;is-minimized;is-maximized"
title = "TCS IDE"
statusbar = false
on-close = "exittcs"
elem "button5"
type = BUTTON
pos = 209,464
size = 70x20
anchor1 = 37,80
anchor2 = 49,83
saved-params = "is-checked"
text = "Clear Memory"
command = "tcsclearmem"
elem "button4"
type = BUTTON
pos = 157,464
size = 52x20
anchor1 = 28,80
anchor2 = 37,83
saved-params = "is-checked"
text = "Revert"
command = "tcsrevert"
elem "button3"
type = BUTTON
pos = 105,464
size = 52x20
anchor1 = 18,80
anchor2 = 28,83
saved-params = "is-checked"
text = "Execute"
command = "tcsrun"
elem "tcserror"
type = OUTPUT
pos = 0,488
size = 566x94
anchor1 = 0,84
anchor2 = 99,100
font-family = "sans-serif"
font-size = 9
saved-params = "max-lines"
elem "button2"
type = BUTTON
pos = 53,464
size = 52x20
anchor1 = 9,80
anchor2 = 18,83
saved-params = "is-checked"
text = "Compile"
command = "tcscompile"
elem "button1"
type = BUTTON
pos = 0,464
size = 53x20
anchor1 = 0,80
anchor2 = 9,83
saved-params = "is-checked"
text = "Apply"
command = "tcssave"
elem "tcscode"
type = INPUT
pos = 0,0
size = 569x464
anchor1 = 0,0
anchor2 = 100,80
font-family = "Courier"
font-size = 10
saved-params = ""
command = "cancel"
multi-line = true
no-command = true
window "chemdispenser"
elem "chemdispenser"
type = MAIN
pos = 281,0
size = 340x480
anchor1 = -1,-1
anchor2 = -1,-1
is-visible = false
saved-params = "pos;size;is-minimized;is-maximized"
title = "Chem Dispenser"
statusbar = false
elem "energy"
type = LABEL
pos = 8,24
size = 56x16
anchor1 = -1,-1
anchor2 = -1,-1
saved-params = ""
text = "Energy: 25"
elem "eject"
type = BUTTON
pos = 264,4
size = 72x20
anchor1 = -1,-1
anchor2 = -1,-1
saved-params = "is-checked"
text = "[Insert beaker]"
command = "skincmd \"chemdispenser;eject\""
elem "amountc"
type = BUTTON
pos = 208,4
size = 48x20
anchor1 = -1,-1
anchor2 = -1,-1
saved-params = "is-checked"
text = "[Other]"
command = "skincmd \"chemdispenser;amountc\""
elem "amount3"
type = BUTTON
pos = 176,4
size = 24x20
anchor1 = -1,-1
anchor2 = -1,-1
saved-params = "is-checked"
text = "[30]"
command = "skincmd \"chemdispenser;amount30\""
elem "amount2"
type = BUTTON
pos = 144,4
size = 24x20
anchor1 = -1,-1
anchor2 = -1,-1
saved-params = "is-checked"
text = "[20]"
command = "skincmd \"chemdispenser;amount20\""
elem "amount1"
type = BUTTON
pos = 112,4
size = 24x20
anchor1 = -1,-1
anchor2 = -1,-1
saved-params = "is-checked"
text = "[10]"
command = "skincmd \"chemdispenser;amount10\""
elem "amount"
type = LABEL
pos = 4,4
size = 100x20
anchor1 = -1,-1
anchor2 = -1,-1
font-size = 12
saved-params = ""
text = "Amount: 30"
elem "child1"
type = CHILD
pos = 0,40
size = 340x440
anchor1 = -1,-1
anchor2 = -1,-1
saved-params = "splitter"
left = "chemdispenser_reagents"
is-vert = false
window "chemdispenser_reagents"
elem "chemdispenser_reagents"
type = MAIN
pos = 281,0
size = 340x448
anchor1 = -1,-1
anchor2 = -1,-1
saved-params = "pos;size;is-minimized;is-maximized"
titlebar = false
statusbar = false
can-close = false
can-minimize = false
can-resize = false
is-pane = true
can-scroll = vertical
elem "template_dispense"
type = BUTTON
pos = 256,8
size = 64x32
anchor1 = -1,-1
anchor2 = -1,-1
is-visible = false
saved-params = "is-checked"
text = "Dispense"
image = 'icons\\dispensebutton_bg.png'
command = ""
is-flat = true
elem "template_name"
type = LABEL
pos = 18,8
size = 230x32
anchor1 = -1,-1
anchor2 = -1,-1
font-size = 15
is-visible = false
saved-params = ""
text = "Chloral Hydrate"
image = 'icons\\reagentname_bg.png'
image-mode = stretch
window "mainwindow" window "mainwindow"
elem "mainwindow" elem "mainwindow"
type = MAIN type = MAIN

View File

@@ -249,7 +249,7 @@
var/mob/living/carbon/human/user = AM var/mob/living/carbon/human/user = AM
var/choice = tgui_alert(usr, "Do you want to depart via the tram? Your character will leave the round.","Departure",list("Yes","No")) var/choice = tgui_alert(user, "Do you want to depart via the tram? Your character will leave the round.","Departure",list("Yes","No"))
if(user && Adjacent(user) && choice == "Yes") if(user && Adjacent(user) && choice == "Yes")
var/mob/observer/dead/newghost = user.ghostize() var/mob/observer/dead/newghost = user.ghostize()
newghost.timeofdeath = world.time newghost.timeofdeath = world.time

View File

@@ -132,7 +132,7 @@ export const releaseHeldKeys = () => {
if (keyState[byondKeyCode]) { if (keyState[byondKeyCode]) {
keyState[byondKeyCode] = false; keyState[byondKeyCode] = false;
logger.log(`releasing key "${byondKeyCode}"`); logger.log(`releasing key "${byondKeyCode}"`);
Byond.command(`KeyUp "${byondKeyCode}"`); Byond.command(`TguiKeyUp "${byondKeyCode}"`);
} }
} }
}; };

View File

@@ -172,7 +172,7 @@ const digestModeToPreyMode = {
export const VorePanel = (props, context) => { export const VorePanel = (props, context) => {
const { act, data } = useBackend(context); const { act, data } = useBackend(context);
return ( return (
<Window width={700} height={800} resizable> <Window width={700} height={660} theme="abstract" resizable>
<Window.Content scrollable> <Window.Content scrollable>
{data.unsaved_changes && ( {data.unsaved_changes && (
<NoticeBox danger> <NoticeBox danger>
@@ -1108,7 +1108,7 @@ const VoreUserPreferences = (props, context) => {
selected={step_mechanics_active} selected={step_mechanics_active}
fluid fluid
tooltipPosition="top" tooltipPosition="top"
tooltip={step_mechanics_active tooltip={step_mechanics_active
? "This setting controls whether or not you participate in size-based step mechanics." ? "This setting controls whether or not you participate in size-based step mechanics."
+ "Includes both stepping on others, as well as getting stepped on. Click to disable step mechanics." + "Includes both stepping on others, as well as getting stepped on. Click to disable step mechanics."
: ("You will not participate in step mechanics." : ("You will not participate in step mechanics."
@@ -1122,7 +1122,7 @@ const VoreUserPreferences = (props, context) => {
selected={show_vore_fx} selected={show_vore_fx}
fluid fluid
tooltipPosition="top" tooltipPosition="top"
tooltip={show_vore_fx tooltip={show_vore_fx
? "This setting controls whether or not a pred is allowed to mess with your HUD and fullscreen overlays." ? "This setting controls whether or not a pred is allowed to mess with your HUD and fullscreen overlays."
+ "Click to disable all FX." + "Click to disable all FX."
: ("Regardless of Predator Setting, you will not see their FX settings." : ("Regardless of Predator Setting, you will not see their FX settings."
@@ -1136,7 +1136,7 @@ const VoreUserPreferences = (props, context) => {
selected={digest_leave_remains} selected={digest_leave_remains}
fluid fluid
tooltipPosition="top" tooltipPosition="top"
tooltip={digest_leave_remains tooltip={digest_leave_remains
? "Your Predator must have this setting enabled in their belly modes to allow remains to show up," ? "Your Predator must have this setting enabled in their belly modes to allow remains to show up,"
+ "if they do not, they will not leave your remains behind, even with this on. Click to disable remains" + "if they do not, they will not leave your remains behind, even with this on. Click to disable remains"
: ("Regardless of Predator Setting, you will not leave remains behind." : ("Regardless of Predator Setting, you will not leave remains behind."
@@ -1150,7 +1150,7 @@ const VoreUserPreferences = (props, context) => {
selected={pickup_mechanics_active} selected={pickup_mechanics_active}
fluid fluid
tooltipPosition="top" tooltipPosition="top"
tooltip={pickup_mechanics_active tooltip={pickup_mechanics_active
? "Allows macros to pick you up into their hands, and you to pick up micros." ? "Allows macros to pick you up into their hands, and you to pick up micros."
+ "Click to disable pick-up mechanics" + "Click to disable pick-up mechanics"
: ("You will not participate in pick-up mechanics." : ("You will not participate in pick-up mechanics."

File diff suppressed because one or more lines are too long

View File

@@ -51,6 +51,7 @@
#include "code\__defines\gamemode.dm" #include "code\__defines\gamemode.dm"
#include "code\__defines\holomap.dm" #include "code\__defines\holomap.dm"
#include "code\__defines\hoses.dm" #include "code\__defines\hoses.dm"
#include "code\__defines\input.dm"
#include "code\__defines\instruments.dm" #include "code\__defines\instruments.dm"
#include "code\__defines\integrated_circuits.dm" #include "code\__defines\integrated_circuits.dm"
#include "code\__defines\inventory_sizes.dm" #include "code\__defines\inventory_sizes.dm"
@@ -281,6 +282,7 @@
#include "code\controllers\subsystems\garbage.dm" #include "code\controllers\subsystems\garbage.dm"
#include "code\controllers\subsystems\holomaps.dm" #include "code\controllers\subsystems\holomaps.dm"
#include "code\controllers\subsystems\inactivity.dm" #include "code\controllers\subsystems\inactivity.dm"
#include "code\controllers\subsystems\input.dm"
#include "code\controllers\subsystems\job.dm" #include "code\controllers\subsystems\job.dm"
#include "code\controllers\subsystems\lighting.dm" #include "code\controllers\subsystems\lighting.dm"
#include "code\controllers\subsystems\machines.dm" #include "code\controllers\subsystems\machines.dm"
@@ -2602,6 +2604,9 @@
#include "code\modules\integrated_electronics\subtypes\trig.dm" #include "code\modules\integrated_electronics\subtypes\trig.dm"
#include "code\modules\integrated_electronics\subtypes\z_mixed_ch.dm" #include "code\modules\integrated_electronics\subtypes\z_mixed_ch.dm"
#include "code\modules\integrated_electronics\~defines\~defines.dm" #include "code\modules\integrated_electronics\~defines\~defines.dm"
#include "code\modules\keybindings\bindings_atom.dm"
#include "code\modules\keybindings\bindings_movekeys.dm"
#include "code\modules\keybindings\setup.dm"
#include "code\modules\library\lib_items.dm" #include "code\modules\library\lib_items.dm"
#include "code\modules\library\lib_machines.dm" #include "code\modules\library\lib_machines.dm"
#include "code\modules\library\lib_readme.dm" #include "code\modules\library\lib_readme.dm"