diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 9d5b7d3447..a78d771155 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -279,6 +279,8 @@ default behaviour is: is_shifted = FALSE pixel_x = default_pixel_x pixel_y = default_pixel_y + layer = MOB_LAYER + plane = MOB_PLANE // End VOREstation edit if(pulling) // we were pulling a thing and didn't lose it during our move. diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c80e67b3c3..b91399e538 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1,1286 +1,1312 @@ -/mob/Destroy()//This makes sure that mobs withGLOB.clients/keys are not just deleted from the game. - mob_list -= src - dead_mob_list -= src - living_mob_list -= src - unset_machine() - qdel(hud_used) - clear_fullscreen() - if(client) - for(var/obj/screen/movable/spell_master/spell_master in spell_masters) - qdel(spell_master) - remove_screen_obj_references() - client.screen = list() - if(mind && mind.current == src) - spellremove(src) - ghostize() - QDEL_NULL(plane_holder) - ..() - return QDEL_HINT_HARDDEL_NOW - -/mob/proc/remove_screen_obj_references() - hands = null - pullin = null - purged = null - internals = null - i_select = null - m_select = null - healths = null - throw_icon = null - pain = null - item_use_icon = null - gun_move_icon = null - gun_setting_icon = null - spell_masters = null - zone_sel = null - -/mob/Initialize() - mob_list += src - if(stat == DEAD) - dead_mob_list += src - else - living_mob_list += src - lastarea = get_area(src) - set_focus(src) // VOREStation Add - Key Handling - hook_vr("mob_new",list(src)) //VOREStation Code - update_transform() // Some mobs may start bigger or smaller than normal. - return ..() - -/mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) - - if(!client && !teleop) return - - if (type) - if((type & VISIBLE_MESSAGE) && (is_blind() || paralysis) )//Vision related - if (!( alt )) - return - else - msg = alt - type = alt_type - if ((type & AUDIBLE_MESSAGE) && is_deaf())//Hearing related - if (!( alt )) - return - else - msg = alt - type = alt_type - if ((type & VISIBLE_MESSAGE) && (sdisabilities & BLIND)) - return - // Added voice muffling for Issue 41. - if(stat == UNCONSCIOUS || sleeping > 0) - to_chat(src, "... You can almost hear someone talking ...") - else - to_chat(src,msg) - if(teleop) - to_chat(teleop, create_text_tag("body", "BODY:", teleop.client) + "[msg]") - return - -// Show a message to all mobs and objects in sight of this one -// This would be for visible actions by the src mob -// 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, var/runemessage) - if(self_message) - if(LAZYLEN(exclude_mobs)) - exclude_mobs |= src - else - exclude_mobs = list(src) - src.show_message(self_message, 1, blind_message, 2) - 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. -// If surge is set, it will destroy/damage the recipient and not return any power. -// Not sure where to define this, so it can sit here for the rest of time. -/atom/proc/drain_power(var/drain_check,var/surge, var/amount = 0) - return -1 - -// Show a message to all mobs and objects in earshot of this one -// This would be for audible actions by the src mob -// message is the message output to anyone who can hear. -// 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, 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) - - 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/O as anything in hearing_objs) - O.hear_talk(src, list(new /datum/multilingual_say_piece(GLOB.all_languages["Noise"], radio_message)), null) - else - for(var/obj/O as anything in hearing_objs) - O.show_message(message, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE) - - for(var/mob/M as anything in hearing_mobs) - var/msg = message - 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) - if (M.real_name == text("[]", msg)) - return M - return 0 - -/mob/proc/Life() -// if(organStructure) -// organStructure.ProcessOrgans() - return - -#define UNBUCKLED 0 -#define PARTIALLY_BUCKLED 1 -#define FULLY_BUCKLED 2 -/mob/proc/buckled() - // Preliminary work for a future buckle rewrite, - // where one might be fully restrained (like an elecrical chair), or merely secured (shuttle chair, keeping you safe but not otherwise restrained from acting) - if(!buckled) - return UNBUCKLED - return restrained() ? FULLY_BUCKLED : PARTIALLY_BUCKLED - -/mob/proc/is_blind() - return ((sdisabilities & BLIND) || blinded || incapacitated(INCAPACITATION_KNOCKOUT)) - -/mob/proc/is_deaf() - return ((sdisabilities & DEAF) || ear_deaf || incapacitated(INCAPACITATION_KNOCKOUT)) - -/mob/proc/is_physically_disabled() - return incapacitated(INCAPACITATION_DISABLED) - -/mob/proc/cannot_stand() - return incapacitated(INCAPACITATION_KNOCKDOWN) - -/mob/proc/incapacitated(var/incapacitation_flags = INCAPACITATION_DEFAULT) - if ((incapacitation_flags & INCAPACITATION_STUNNED) && stunned) - return 1 - - if ((incapacitation_flags & INCAPACITATION_FORCELYING) && (weakened || resting)) - return 1 - - if ((incapacitation_flags & INCAPACITATION_KNOCKOUT) && (stat || paralysis || sleeping || (status_flags & FAKEDEATH))) - return 1 - - if((incapacitation_flags & INCAPACITATION_RESTRAINED) && restrained()) - return 1 - - if((incapacitation_flags & (INCAPACITATION_BUCKLED_PARTIALLY|INCAPACITATION_BUCKLED_FULLY))) - var/buckling = buckled() - if(buckling >= PARTIALLY_BUCKLED && (incapacitation_flags & INCAPACITATION_BUCKLED_PARTIALLY)) - return 1 - if(buckling == FULLY_BUCKLED && (incapacitation_flags & INCAPACITATION_BUCKLED_FULLY)) - return 1 - - return 0 - -#undef UNBUCKLED -#undef PARTIALLY_BUCKLED -#undef FULLY_BUCKLED - -/mob/proc/restrained() - return - -/mob/proc/reset_view(atom/A) - if (client) - if (istype(A, /atom/movable)) - client.perspective = EYE_PERSPECTIVE - client.eye = A - else - if (isturf(loc)) - client.eye = client.mob - client.perspective = MOB_PERSPECTIVE - else - client.perspective = EYE_PERSPECTIVE - client.eye = loc - return TRUE - -/mob/verb/pointed(atom/A as mob|obj|turf in view()) - set name = "Point To" - set category = "Object" - - if(!src || !isturf(src.loc) || !(A in view(src.loc))) - return 0 - if(istype(A, /obj/effect/decal/point)) - return 0 - - var/turf/tile = get_turf(A) - if (!tile) - return 0 - - var/turf/our_tile = get_turf(src) - var/obj/visual = new /obj/effect/decal/point(our_tile) - visual.invisibility = invisibility - visual.plane = ABOVE_PLANE - visual.layer = FLY_LAYER - - animate(visual, - pixel_x = (tile.x - our_tile.x) * world.icon_size + A.pixel_x, - pixel_y = (tile.y - our_tile.y) * world.icon_size + A.pixel_y, - time = 1.7, - easing = EASE_OUT) - - QDEL_IN(visual, 2 SECONDS) //Better qdel - - face_atom(A) - return 1 - - -/mob/proc/ret_grab(list/L, flag) - return - -/mob/verb/mode() - set name = "Activate Held Object" - set category = "Object" - set src = usr - - return - -/* -/mob/verb/dump_source() - - var/master = "
"
- for(var/t in typesof(/area))
- master += text("[]\n", t)
- //Foreach goto(26)
- src << browse(master)
- return
-*/
-
-/mob/verb/memory()
- set name = "Notes"
- set category = "IC"
- if(mind)
- mind.show_memory(src)
- else
- to_chat(src, "The game appears to have misplaced your mind datum, so we can't show you your notes.")
-
-/mob/verb/add_memory(msg as message)
- set name = "Add Note"
- set category = "IC"
-
- msg = sanitize(msg)
-
- if(mind)
- mind.store_memory(msg)
- else
- to_chat(src, "The game appears to have misplaced your mind datum, so we can't show you your notes.")
-
-/mob/proc/store_memory(msg as message, popup, sane = 1)
- msg = copytext(msg, 1, MAX_MESSAGE_LEN)
-
- if (sane)
- msg = sanitize(msg)
-
- if (length(memory) == 0)
- memory += msg
- else
- memory += "
[msg]"
-
- if (popup)
- memory()
-
-/mob/proc/update_flavor_text()
- set src in usr
- if(usr != src)
- to_chat(usr, "No.")
- var/msg = sanitize(tgui_input_text(usr,"Set the flavor text in your 'examine' verb.","Flavor Text",html_decode(flavor_text), multiline = TRUE, prevent_enter = TRUE), extra = 0) //VOREStation Edit: separating out OOC notes
-
- if(msg != null)
- flavor_text = msg
-
-/mob/proc/warn_flavor_changed()
- if(flavor_text && flavor_text != "") // don't spam people that don't use it!
- to_chat(src, "OOC Warning:
")
- to_chat(src, "Your flavor text is likely out of date! Change")
-
-/mob/proc/print_flavor_text()
- if (flavor_text && flavor_text != "")
- var/msg = replacetext(flavor_text, "\n", " ")
- if(length(msg) <= 40)
- return "[msg]"
- else
- return "[copytext_preserve_html(msg, 1, 37)]... More..."
-
-/*
-/mob/verb/help()
- set name = "Help"
- src << browse('html/help.html', "window=help")
- return
-*/
-
-/mob/proc/set_respawn_timer(var/time)
- // Try to figure out what time to use
-
- // Special cases, can never respawn
- if(ticker?.mode?.deny_respawn)
- time = -1
- else if(!config.abandon_allowed)
- time = -1
- else if(!config.respawn)
- time = -1
-
- // Special case for observing before game start
- else if(ticker?.current_state <= GAME_STATE_SETTING_UP)
- time = 1 MINUTE
-
- // Wasn't given a time, use the config time
- else if(!time)
- time = config.respawn_time
-
- var/keytouse = ckey
- // Try harder to find a key to use
- if(!keytouse && key)
- keytouse = ckey(key)
- else if(!keytouse && mind?.key)
- keytouse = ckey(mind.key)
-
- GLOB.respawn_timers[keytouse] = world.time + time
-
-/mob/observer/dead/set_respawn_timer()
- if(config.antag_hud_restricted && has_enabled_antagHUD)
- ..(-1)
- else
- return // Don't set it, no need
-
-/mob/verb/abandon_mob()
- set name = "Return to Menu"
- set category = "OOC"
-
- if(stat != DEAD || !ticker)
- to_chat(usr, "You must be dead to use this!")
- return
-
- // Final chance to abort "respawning"
- if(mind && timeofdeath) // They had spawned before
- var/choice = tgui_alert(usr, "Returning to the menu will prevent your character from being revived in-round. Are you sure?", "Confirmation", list("No, wait", "Yes, leave"))
- if(choice == "No, wait")
- return
- else if(mind.assigned_role)
- var/extra_check = tgui_alert(usr, "Do you want to Quit This Round before you return to lobby? This will properly remove you from manifest, as well as prevent resleeving.","Quit This Round",list("Quit Round","Cancel"))
- if(extra_check == "Quit Round")
- //Update any existing objectives involving this mob.
- for(var/datum/objective/O in all_objectives)
- if(O.target == src.mind)
- if(O.owner && O.owner.current)
- to_chat(O.owner.current,"You get the feeling your target is no longer within your reach...")
- qdel(O)
-
- //Resleeving cleanup
- if(mind)
- SStranscore.leave_round(src)
-
- //Job slot cleanup
- var/job = src.mind.assigned_role
- job_master.FreeRole(job)
-
- //Their objectives cleanup
- if(src.mind.objectives.len)
- qdel(src.mind.objectives)
- src.mind.special_role = null
-
- //Cut the PDA manifest (ugh)
- if(PDA_Manifest.len)
- PDA_Manifest.Cut()
- for(var/datum/data/record/R in data_core.medical)
- if((R.fields["name"] == src.real_name))
- qdel(R)
- for(var/datum/data/record/T in data_core.security)
- if((T.fields["name"] == src.real_name))
- qdel(T)
- for(var/datum/data/record/G in data_core.general)
- if((G.fields["name"] == src.real_name))
- qdel(G)
-
- //This removes them from being 'active' list on join screen
- src.mind.assigned_role = null
- to_chat(src,"Your job has been free'd up, and you can rejoin as another character or quit. Thanks for properly quitting round, it helps the server!")
-
- // Beyond this point, you're going to respawn
- to_chat(usr, config.respawn_message)
-
- if(!client)
- log_game("[usr.key] AM failed due to disconnect.")
- return
- client.screen.Cut()
- client.screen += client.void
- if(!client)
- log_game("[usr.key] AM failed due to disconnect.")
- return
-
- announce_ghost_joinleave(client, 0)
-
- var/mob/new_player/M = new /mob/new_player()
- if(!client)
- log_game("[usr.key] AM failed due to disconnect.")
- qdel(M)
- return
-
- M.key = key
- if(M.mind)
- M.mind.reset()
- return
-
-/client/verb/changes()
- set name = "Changelog"
- set category = "OOC"
- // CHOMPedit Start - Better Changelog
- //src << browse('html/changelog.html', "window=changes;size=675x650")
- //return
-
- if(!GLOB.changelog_tgui)
- GLOB.changelog_tgui = new /datum/changelog()
- GLOB.changelog_tgui.tgui_interact(usr)
- // CHOMPedit END
- if(prefs.lastchangelog != changelog_hash)
- prefs.lastchangelog = changelog_hash
- SScharacter_setup.queue_preferences_save(prefs)
- // winset(src, "rpane.changelog", "background-color=none;font-style=;") //ChompREMOVE
-
-/mob/verb/observe()
- set name = "Observe"
- set category = "OOC"
- var/is_admin = 0
-
- if(client.holder && (client.holder.rights & R_ADMIN|R_EVENT))
- is_admin = 1
- else if(stat != DEAD || istype(src, /mob/new_player))
- to_chat(usr, "You must be observing to use this!")
- return
-
- if(is_admin && stat == DEAD)
- is_admin = 0
-
- var/list/targets = list()
-
-
- targets += observe_list_format(nuke_disks)
- targets += observe_list_format(GLOB.all_singularities) //CHOMP Edit
- targets += getmobs()
- targets += observe_list_format(sortAtom(mechas_list))
- targets += observe_list_format(SSshuttles.ships)
-
- client.perspective = EYE_PERSPECTIVE
-
- var/eye_name = null
-
- var/ok = "[is_admin ? "Admin Observe" : "Observe"]"
- eye_name = tgui_input_list(usr, "Select something to [ok]:", "Select Target", targets)
-
- if (!eye_name)
- return
-
- var/mob/mob_eye = targets[eye_name]
-
- if(client && mob_eye)
- client.eye = mob_eye
- if (is_admin)
- client.adminobs = 1
- if(mob_eye == client.mob || client.eye == client.mob)
- client.adminobs = 0
-
-/mob/verb/cancel_camera()
- set name = "Cancel Camera View"
- set category = "OOC"
- unset_machine()
- reset_view(null)
-
-/mob/Topic(href, href_list)
- if(href_list["mach_close"])
- var/t1 = text("window=[href_list["mach_close"]]")
- unset_machine()
- src << browse(null, t1)
-
- if(href_list["flavor_more"])
- usr << browse(text("[] []", name, replacetext(flavor_text, "\n", "
")), text("window=[];size=500x200", name))
- onclose(usr, "[name]")
- if(href_list["flavor_change"])
- update_flavor_text()
-// ..()
- return
-
-
-/mob/proc/pull_damage()
- return 0
-
-/mob/verb/stop_pulling()
-
- set name = "Stop Pulling"
- set category = "IC"
-
- if(pulling)
- if(ishuman(pulling))
- var/mob/living/carbon/human/H = pulling
- visible_message(SPAN_WARNING("\The [src] lets go of \the [H]."), SPAN_NOTICE("You let go of \the [H]."), exclude_mobs = list(H))
- if(!H.stat)
- to_chat(H, SPAN_WARNING("\The [src] lets go of you."))
- pulling.pulledby = null
- pulling = null
- if(pullin)
- pullin.icon_state = "pull0"
-
-/mob/proc/start_pulling(var/atom/movable/AM)
-
- if ( !AM || !usr || src==AM || !isturf(src.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort!
- return
-
- if (AM.anchored)
- to_chat(src, "It won't budge!")
- return
-
- var/mob/M = AM
- if(ismob(AM))
-
- if(!can_pull_mobs || !can_pull_size)
- to_chat(src, "They won't budge!")
- return
-
- if((mob_size < M.mob_size) && (can_pull_mobs != MOB_PULL_LARGER))
- to_chat(src, "[M] is too large for you to move!")
- return
-
- if((mob_size == M.mob_size) && (can_pull_mobs == MOB_PULL_SMALLER))
- to_chat(src, "[M] is too heavy for you to move!")
- return
-
- // If your size is larger than theirs and you have some
- // kind of mob pull value AT ALL, you will be able to pull
- // them, so don't bother checking that explicitly.
-
- if(M.grabbed_by.len)
- // Only start pulling when nobody else has a grab on them
- . = 1
- for(var/obj/item/weapon/grab/G in M.grabbed_by)
- if(G.assailant != usr)
- . = 0
- else
- qdel(G)
- if(!.)
- to_chat(src, "Somebody has a grip on them!")
- return
-
- if(!iscarbon(src))
- M.LAssailant = null
- else
- M.LAssailant = usr
-
- else if(isobj(AM))
- var/obj/I = AM
- if(!can_pull_size || can_pull_size < I.w_class)
- to_chat(src, "It won't budge!")
- return
-
- if(pulling)
- var/pulling_old = pulling
- stop_pulling()
- // Are we pulling the same thing twice? Just stop pulling.
- if(pulling_old == AM)
- return
-
- src.pulling = AM
- AM.pulledby = src
-
- if(pullin)
- pullin.icon_state = "pull1"
-
- if(ishuman(AM))
- var/mob/living/carbon/human/H = AM
- if(H.lying) // If they're on the ground we're probably dragging their arms to move them
- visible_message(SPAN_WARNING("\The [src] leans down and grips \the [H]'s arms."), SPAN_NOTICE("You lean down and grip \the [H]'s arms."), exclude_mobs = list(H))
- if(!H.stat)
- to_chat(H, SPAN_WARNING("\The [src] leans down and grips your arms."))
- else //Otherwise we're probably just holding their arm to lead them somewhere
- visible_message(SPAN_WARNING("\The [src] grips \the [H]'s arm."), SPAN_NOTICE("You grip \the [H]'s arm."), exclude_mobs = list(H))
- if(!H.stat)
- to_chat(H, SPAN_WARNING("\The [src] grips your arm."))
- playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 25) //Quieter than hugging/grabbing but we still want some audio feedback
-
- if(H.pull_damage())
- to_chat(src, "Pulling \the [H] in their current condition would probably be a bad idea.")
-
- //Attempted fix for people flying away through space when cuffed and dragged.
- if(ismob(AM))
- var/mob/pulled = AM
- pulled.inertia_dir = 0
-
-/mob/proc/can_use_hands()
- return
-
-/mob/proc/is_active()
- return (0 >= usr.stat)
-
-/mob/proc/is_dead()
- return stat == DEAD
-
-/mob/proc/is_mechanical()
- if(mind && (mind.assigned_role == "Cyborg" || mind.assigned_role == "AI"))
- return 1
- return istype(src, /mob/living/silicon) || get_species() == "Machine"
-
-/mob/proc/is_ready()
- return client && !!mind
-
-/mob/proc/get_gender()
- return gender
-
-/mob/proc/name_gender()
- return gender
-
-/mob/proc/see(message)
- if(!is_active())
- return 0
- to_chat(src,message)
- return 1
-
-/mob/proc/show_viewers(message)
- for(var/mob/M in viewers())
- M.see(message)
-
-/mob/Stat()
- ..()
- . = (is_client_active(10 MINUTES))
-
- if(.)
- if(statpanel("Status"))
- 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)]%)")
- if(ticker && ticker.current_state != GAME_STATE_PREGAME)
- stat("Station Time", stationtime2text())
- var/date = "[stationdate2text()], [capitalize(world_time_season)]"
- stat("Station Date", date)
- stat("Round Duration", roundduration2text())
-
- if(client.holder)
- if(statpanel("Status"))
- stat("Location:", "([x], [y], [z]) [loc]")
- stat("CPU:","[world.cpu]")
- 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("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"))
- stat("Location:", "([x], [y], [z]) [loc]")
- stat("CPU:","[world.cpu]")
- stat("Instances:","[world.contents.len]")
- stat("World Time:", world.time)
- stat("Real time of day:", REALTIMEOFDAY)
- stat(null)
- if(GLOB)
- GLOB.stat_entry()
- else
- stat("Globals:", "ERROR")
- if(Master)
- Master.stat_entry()
- else
- stat("Master Controller:", "ERROR")
- if(Failsafe)
- Failsafe.stat_entry()
- else
- stat("Failsafe Controller:", "ERROR")
- if(Master)
- stat(null)
- for(var/datum/controller/subsystem/SS in Master.subsystems)
- SS.stat_entry()
-
- // CHOMPedit - Ticket System
- //if(statpanel("Tickets"))
- //GLOB.ahelp_tickets.stat_entry()
-
-
- if(length(GLOB.sdql2_queries))
- if(statpanel("SDQL2"))
- stat("Access Global SDQL2 List", GLOB.sdql2_vv_statobj)
- for(var/datum/SDQL2_query/Q as anything in GLOB.sdql2_queries)
- Q.generate_stat()
-
-
- if(has_mentor_powers(client) || client.holder) // CHOMPedit - Ticket System
- if(statpanel("Tickets"))
- GLOB.tickets.stat_entry() // CHOMPedit - Ticket System
-
- if(listed_turf && client)
- if(!TurfAdjacent(listed_turf))
- listed_turf = null
- else
- if(statpanel("Turf"))
- stat(listed_turf)
- for(var/atom/A in listed_turf)
- if(!A.mouse_opacity)
- continue
- if(A.invisibility > see_invisible)
- continue
- if(is_type_in_list(A, shouldnt_see))
- continue
- if(A.plane > plane)
- continue
- stat(A)
-
-
-// facing verbs
-/mob/proc/canface()
-// if(!canmove) return 0 //VOREStation Edit. Redundant check that only affects conscious proning, actual inability to turn and shift around handled by actual inabilities.
- if(stat) return 0
- if(anchored) return 0
- if(transforming) return 0
- return 1
-
-// Not sure what to call this. Used to check if humans are wearing an AI-controlled exosuit and hence don't need to fall over yet.
-/mob/proc/can_stand_overridden()
- return 0
-
-//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
-/mob/proc/update_canmove()
- return canmove
-
-
-/mob/proc/facedir(var/ndir)
- if(!canface() || (client && (client.moving || !checkMoveCooldown())))
- DEBUG_INPUT("Denying Facedir for [src] (moving=[client?.moving])")
- return 0
- set_dir(ndir)
- if(buckled && buckled.buckle_movable)
- buckled.set_dir(ndir)
- setMoveCooldown(movement_delay())
- return 1
-
-
-/mob/verb/eastface()
- set hidden = 1
- return facedir(client.client_dir(EAST))
-
-
-/mob/verb/westface()
- set hidden = 1
- return facedir(client.client_dir(WEST))
-
-
-/mob/verb/northface()
- set hidden = 1
- return facedir(client.client_dir(NORTH))
-
-
-/mob/verb/southface()
- set hidden = 1
- return facedir(client.client_dir(SOUTH))
-
-
-//This might need a rename but it should replace the can this mob use things check
-/mob/proc/IsAdvancedToolUser()
- return 0
-
-/mob/proc/Stun(amount)
- if(status_flags & CANSTUN)
- facing_dir = null
- stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/SetStunned(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned"
- if(status_flags & CANSTUN)
- stunned = max(amount,0)
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/AdjustStunned(amount)
- if(status_flags & CANSTUN)
- stunned = max(stunned + amount,0)
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/Weaken(amount)
- if(status_flags & CANWEAKEN)
- facing_dir = null
- weakened = max(max(weakened,amount),0)
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/SetWeakened(amount)
- if(status_flags & CANWEAKEN)
- weakened = max(amount,0)
- update_canmove() //can you guess what this does yet?
- return
-
-/mob/proc/AdjustWeakened(amount)
- if(status_flags & CANWEAKEN)
- weakened = max(weakened + amount,0)
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/Paralyse(amount)
- if(status_flags & CANPARALYSE)
- facing_dir = null
- paralysis = max(max(paralysis,amount),0)
- return
-
-/mob/proc/SetParalysis(amount)
- if(status_flags & CANPARALYSE)
- paralysis = max(amount,0)
- return
-
-/mob/proc/AdjustParalysis(amount)
- if(status_flags & CANPARALYSE)
- paralysis = max(paralysis + amount,0)
- return
-
-/mob/proc/Sleeping(amount)
- facing_dir = null
- sleeping = max(max(sleeping,amount),0)
- return
-
-/mob/proc/SetSleeping(amount)
- sleeping = max(amount,0)
- return
-
-/mob/proc/AdjustSleeping(amount)
- sleeping = max(sleeping + amount,0)
- return
-
-/mob/proc/Confuse(amount)
- confused = max(max(confused,amount),0)
- return
-
-/mob/proc/SetConfused(amount)
- confused = max(amount,0)
- return
-
-/mob/proc/AdjustConfused(amount)
- confused = max(confused + amount,0)
- return
-
-/mob/proc/Blind(amount)
- eye_blind = max(max(eye_blind,amount),0)
- return
-
-/mob/proc/SetBlinded(amount)
- eye_blind = max(amount,0)
- return
-
-/mob/proc/AdjustBlinded(amount)
- eye_blind = max(eye_blind + amount,0)
- return
-
-/mob/proc/Resting(amount)
- facing_dir = null
- resting = max(max(resting,amount),0)
- update_canmove()
- return
-
-/mob/proc/SetResting(amount)
- resting = max(amount,0)
- update_canmove()
- return
-
-/mob/proc/AdjustResting(amount)
- resting = max(resting + amount,0)
- update_canmove()
- return
-
-/mob/proc/AdjustLosebreath(amount)
- losebreath = CLAMP(losebreath + amount, 0, 25)
-
-/mob/proc/SetLosebreath(amount)
- losebreath = CLAMP(amount, 0, 25)
-
-/mob/proc/get_species()
- return ""
-
-/mob/proc/flash_weak_pain()
- flick("weak_pain",pain)
-
-/mob/proc/get_visible_implants(var/class = 0)
- var/list/visible_implants = list()
- for(var/obj/item/O in embedded)
- if(O.w_class > class)
- visible_implants += O
- return visible_implants
-
-/mob/proc/embedded_needs_process()
- return (embedded.len > 0)
-
-/mob/proc/yank_out_object()
- set category = "Object"
- set name = "Yank out object"
- set desc = "Remove an embedded item at the cost of bleeding and pain."
- set src in view(1)
-
- if(!isliving(usr) || !usr.checkClickCooldown())
- return
- usr.setClickCooldown(20)
-
- if(usr.stat == 1)
- to_chat(usr, "You are unconcious and cannot do that!")
- return
-
- if(usr.restrained())
- to_chat(usr, "You are restrained and cannot do that!")
- return
-
- var/mob/S = src
- var/mob/U = usr
- var/list/valid_objects = list()
- var/self = null
-
- if(S == U)
- self = 1 // Removing object from yourself.
-
- valid_objects = get_visible_implants(0)
- if(!valid_objects.len)
- if(self)
- to_chat(src, "You have nothing stuck in your body that is large enough to remove.")
- else
- to_chat(U, "[src] has nothing stuck in their wounds that is large enough to remove.")
- return
-
- var/obj/item/weapon/selection = tgui_input_list(usr, "What do you want to yank out?", "Embedded objects", valid_objects)
-
- if(self)
- to_chat(src, "You attempt to get a good grip on [selection] in your body.")
- else
- to_chat(U, "You attempt to get a good grip on [selection] in [S]'s body.")
-
- if(!do_after(U, 30))
- return
- if(!selection || !S || !U)
- return
-
- if(self)
- visible_message("[src] rips [selection] out of their body.","You rip [selection] out of your body.")
- else
- visible_message("[usr] rips [selection] out of [src]'s body.","[usr] rips [selection] out of your body.")
- valid_objects = get_visible_implants(0)
- if(valid_objects.len == 1) //Yanking out last object - removing verb.
- src.verbs -= /mob/proc/yank_out_object
- clear_alert("embeddedobject")
-
- if(ishuman(src))
- var/mob/living/carbon/human/H = src
- var/obj/item/organ/external/affected
-
- for(var/obj/item/organ/external/organ in H.organs) //Grab the organ holding the implant.
- for(var/obj/item/O in organ.implants)
- if(O == selection)
- affected = organ
-
- affected.implants -= selection
- H.shock_stage+=20
- affected.take_damage((selection.w_class * 3), 0, 0, 1, "Embedded object extraction")
-
- if(prob(selection.w_class * 5) && (affected.robotic < ORGAN_ROBOT)) //I'M SO ANEMIC I COULD JUST -DIE-.
- var/datum/wound/internal_bleeding/I = new (min(selection.w_class * 5, 15))
- affected.wounds += I
- H.custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 50)
-
- if (ishuman(U))
- var/mob/living/carbon/human/human_user = U
- human_user.bloody_hands(H)
-
- else if(issilicon(src))
- var/mob/living/silicon/robot/R = src
- R.embedded -= selection
- R.adjustBruteLoss(5)
- R.adjustFireLoss(10)
-
- selection.forceMove(get_turf(src))
- U.put_in_hands(selection)
-
- for(var/obj/item/weapon/O in pinned)
- if(O == selection)
- pinned -= O
- if(!pinned.len)
- anchored = FALSE
- return 1
-
-//Check for brain worms in head.
-/mob/proc/has_brain_worms()
-
- for(var/I in contents)
- if(istype(I,/mob/living/simple_mob/animal/borer))
- return I
-
- return 0
-
-/mob/proc/updateicon()
- return
-
-// Please always use this proc, never just set the var directly.
-/mob/proc/set_stat(var/new_stat)
- . = (stat != new_stat)
- stat = new_stat
-
-/mob/verb/face_direction()
-
- set name = "Face Direction"
- set category = "IC"
- set src = usr
-
- set_face_dir()
-
- if(!facing_dir)
- to_chat(usr, "You are now not facing anything.")
- else
- to_chat(usr, "You are now facing [dir2text(facing_dir)].")
-
-/mob/proc/set_face_dir(var/newdir)
- if(newdir == facing_dir)
- facing_dir = null
- else if(newdir)
- set_dir(newdir)
- facing_dir = newdir
- else if(facing_dir)
- facing_dir = null
- else
- set_dir(dir)
- facing_dir = dir
-
-/mob/set_dir()
- if(facing_dir)
- if(!canface() || lying || buckled || restrained())
- facing_dir = null
- else if(dir != facing_dir)
- return ..(facing_dir)
- else
- return ..()
-
-/mob/verb/northfaceperm()
- set hidden = 1
- set_face_dir(client.client_dir(NORTH))
-
-/mob/verb/southfaceperm()
- set hidden = 1
- set_face_dir(client.client_dir(SOUTH))
-
-/mob/verb/eastfaceperm()
- set hidden = 1
- set_face_dir(client.client_dir(EAST))
-
-/mob/verb/westfaceperm()
- set hidden = 1
- set_face_dir(client.client_dir(WEST))
-
-// Begin VOREstation edit
-/mob/verb/shiftnorth()
- set hidden = TRUE
- if(!canface())
- return FALSE
- if(pixel_y <= (default_pixel_y + 16))
- pixel_y++
- is_shifted = TRUE
-
-/mob/verb/shiftsouth()
- set hidden = TRUE
- if(!canface())
- return FALSE
- if(pixel_y >= (default_pixel_y - 16))
- pixel_y--
- is_shifted = TRUE
-
-/mob/verb/shiftwest()
- set hidden = TRUE
- if(!canface())
- return FALSE
- if(pixel_x >= (default_pixel_x - 16))
- pixel_x--
- is_shifted = TRUE
-
-/mob/verb/shifteast()
- set hidden = TRUE
- if(!canface())
- return FALSE
- if(pixel_x <= (default_pixel_x + 16))
- pixel_x++
- is_shifted = TRUE
-// End VOREstation edit
-
-/mob/proc/adjustEarDamage()
- return
-
-/mob/proc/setEarDamage()
- return
-
-// Set client view distance (size of client's screen). Returns TRUE if anything changed.
-/mob/proc/set_viewsize(var/new_view = world.view)
- if (client && new_view != client.view)
- client.view = new_view
- return TRUE
- return FALSE
-
-//Throwing stuff
-
-/mob/proc/toggle_throw_mode()
- if (src.in_throw_mode)
- throw_mode_off()
- else
- throw_mode_on()
-
-/mob/proc/throw_mode_off()
- src.in_throw_mode = 0
- if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
- src.throw_icon.icon_state = "act_throw_off"
-
-/mob/proc/throw_mode_on()
- src.in_throw_mode = 1
- if(src.throw_icon)
- src.throw_icon.icon_state = "act_throw_on"
-
-/mob/proc/isSynthetic()
- return 0
-
-/mob/proc/is_muzzled()
- return 0
-
-//Exploitable Info Update
-
-/mob/proc/amend_exploitable(var/obj/item/I)
- if(istype(I))
- exploit_addons |= I
- var/exploitmsg = html_decode("\n" + "Has " + I.name + ".")
- exploit_record += exploitmsg
-
-/client/proc/check_has_body_select()
- return mob && mob.hud_used && istype(mob.zone_sel, /obj/screen/zone_sel)
-
-/client/verb/body_toggle_head()
- set name = "body-toggle-head"
- set hidden = 1
- toggle_zone_sel(list(BP_HEAD, O_EYES, O_MOUTH))
-
-/client/verb/body_r_arm()
- set name = "body-r-arm"
- set hidden = 1
- toggle_zone_sel(list(BP_R_ARM,BP_R_HAND))
-
-/client/verb/body_l_arm()
- set name = "body-l-arm"
- set hidden = 1
- toggle_zone_sel(list(BP_L_ARM,BP_L_HAND))
-
-/client/verb/body_chest()
- set name = "body-chest"
- set hidden = 1
- toggle_zone_sel(list(BP_TORSO))
-
-/client/verb/body_groin()
- set name = "body-groin"
- set hidden = 1
- toggle_zone_sel(list(BP_GROIN))
-
-/client/verb/body_r_leg()
- set name = "body-r-leg"
- set hidden = 1
- toggle_zone_sel(list(BP_R_LEG,BP_R_FOOT))
-
-/client/verb/body_l_leg()
- set name = "body-l-leg"
- set hidden = 1
- toggle_zone_sel(list(BP_L_LEG,BP_L_FOOT))
-
-/client/proc/toggle_zone_sel(list/zones)
- if(!check_has_body_select())
- return
- var/obj/screen/zone_sel/selector = mob.zone_sel
- selector.set_selected_zone(next_in_list(mob.zone_sel.selecting,zones))
-
-// This handles setting the client's color variable, which makes everything look a specific color.
-// This proc is here so it can be called without needing to check if the client exists, or if the client relogs.
-// This is for inheritence since /mob/living will serve most cases. If you need ghosts to use this you'll have to implement that yourself.
-/mob/proc/update_client_color()
- if(client && client.color)
- animate(client, color = null, time = 10)
- return
-
-/mob/proc/swap_hand()
- return
-
-//Throwing stuff
-/mob/proc/throw_item(atom/target)
- return FALSE
-
-/mob/proc/will_show_tooltip()
- if(alpha <= EFFECTIVE_INVIS)
- return FALSE
- return TRUE
-
-/mob/MouseEntered(location, control, params)
- if(usr != src && usr.is_preference_enabled(/datum/client_preference/mob_tooltips) && src.will_show_tooltip())
- openToolTip(user = usr, tip_src = src, params = params, title = get_nametag_name(usr), content = get_nametag_desc(usr))
-
- ..()
-
-/mob/MouseDown()
- closeToolTip(usr) //No reason not to, really
-
- ..()
-
-/mob/MouseExited()
- closeToolTip(usr) //No reason not to, really
-
- ..()
-
-// Manages a global list of mobs with clients attached, indexed by z-level.
-/mob/proc/update_client_z(new_z) // +1 to register, null to unregister.
- if(registered_z != new_z)
- if(registered_z)
- GLOB.players_by_zlevel[registered_z] -= src
- if(client)
- if(new_z)
- GLOB.players_by_zlevel[new_z] += src
- registered_z = new_z
- else
- registered_z = null
-
-GLOBAL_LIST_EMPTY_TYPED(living_players_by_zlevel, /list)
-/mob/living/update_client_z(new_z)
- var/precall_reg_z = registered_z
- . = ..() // will update registered_z if necessary
- if(precall_reg_z != registered_z) // parent did work, let's do work too
- if(precall_reg_z)
- GLOB.living_players_by_zlevel[precall_reg_z] -= src
- if(registered_z)
- GLOB.living_players_by_zlevel[registered_z] += src
-
-/mob/onTransitZ(old_z, new_z)
- ..()
- update_client_z(new_z)
-
-/mob/cloak()
- . = ..()
- if(client && cloaked_selfimage)
- client.images += cloaked_selfimage
-
-/mob/uncloak()
- if(client && cloaked_selfimage)
- client.images -= cloaked_selfimage
- return ..()
-
-/mob/get_cloaked_selfimage()
- var/icon/selficon = getCompoundIcon(src)
- selficon.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) //White
- var/image/selfimage = image(selficon)
- selfimage.color = "#0000FF"
- selfimage.alpha = 100
- selfimage.layer = initial(layer)
- selfimage.plane = initial(plane)
- selfimage.loc = src
-
- return selfimage
-
-/mob/proc/GetAltName()
- return ""
-
-/mob/proc/get_ghost(even_if_they_cant_reenter = 0)
- if(mind)
- return mind.get_ghost(even_if_they_cant_reenter)
-
-/mob/proc/grab_ghost(force)
- if(mind)
- return mind.grab_ghost(force = force)
+/mob/Destroy()//This makes sure that mobs withGLOB.clients/keys are not just deleted from the game.
+ mob_list -= src
+ dead_mob_list -= src
+ living_mob_list -= src
+ unset_machine()
+ qdel(hud_used)
+ clear_fullscreen()
+ if(client)
+ for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
+ qdel(spell_master)
+ remove_screen_obj_references()
+ client.screen = list()
+ if(mind && mind.current == src)
+ spellremove(src)
+ ghostize()
+ QDEL_NULL(plane_holder)
+ ..()
+ return QDEL_HINT_HARDDEL_NOW
+
+/mob/proc/remove_screen_obj_references()
+ hands = null
+ pullin = null
+ purged = null
+ internals = null
+ i_select = null
+ m_select = null
+ healths = null
+ throw_icon = null
+ pain = null
+ item_use_icon = null
+ gun_move_icon = null
+ gun_setting_icon = null
+ spell_masters = null
+ zone_sel = null
+
+/mob/Initialize()
+ mob_list += src
+ if(stat == DEAD)
+ dead_mob_list += src
+ else
+ living_mob_list += src
+ lastarea = get_area(src)
+ set_focus(src) // VOREStation Add - Key Handling
+ hook_vr("mob_new",list(src)) //VOREStation Code
+ update_transform() // Some mobs may start bigger or smaller than normal.
+ return ..()
+
+/mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
+
+ if(!client && !teleop) return
+
+ if (type)
+ if((type & VISIBLE_MESSAGE) && (is_blind() || paralysis) )//Vision related
+ if (!( alt ))
+ return
+ else
+ msg = alt
+ type = alt_type
+ if ((type & AUDIBLE_MESSAGE) && is_deaf())//Hearing related
+ if (!( alt ))
+ return
+ else
+ msg = alt
+ type = alt_type
+ if ((type & VISIBLE_MESSAGE) && (sdisabilities & BLIND))
+ return
+ // Added voice muffling for Issue 41.
+ if(stat == UNCONSCIOUS || sleeping > 0)
+ to_chat(src, "... You can almost hear someone talking ...")
+ else
+ to_chat(src,msg)
+ if(teleop)
+ to_chat(teleop, create_text_tag("body", "BODY:", teleop.client) + "[msg]")
+ return
+
+// Show a message to all mobs and objects in sight of this one
+// This would be for visible actions by the src mob
+// 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, var/runemessage)
+ if(self_message)
+ if(LAZYLEN(exclude_mobs))
+ exclude_mobs |= src
+ else
+ exclude_mobs = list(src)
+ src.show_message(self_message, 1, blind_message, 2)
+ 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.
+// If surge is set, it will destroy/damage the recipient and not return any power.
+// Not sure where to define this, so it can sit here for the rest of time.
+/atom/proc/drain_power(var/drain_check,var/surge, var/amount = 0)
+ return -1
+
+// Show a message to all mobs and objects in earshot of this one
+// This would be for audible actions by the src mob
+// message is the message output to anyone who can hear.
+// 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, 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)
+
+ 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/O as anything in hearing_objs)
+ O.hear_talk(src, list(new /datum/multilingual_say_piece(GLOB.all_languages["Noise"], radio_message)), null)
+ else
+ for(var/obj/O as anything in hearing_objs)
+ O.show_message(message, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE)
+
+ for(var/mob/M as anything in hearing_mobs)
+ var/msg = message
+ 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)
+ if (M.real_name == text("[]", msg))
+ return M
+ return 0
+
+/mob/proc/Life()
+// if(organStructure)
+// organStructure.ProcessOrgans()
+ return
+
+#define UNBUCKLED 0
+#define PARTIALLY_BUCKLED 1
+#define FULLY_BUCKLED 2
+/mob/proc/buckled()
+ // Preliminary work for a future buckle rewrite,
+ // where one might be fully restrained (like an elecrical chair), or merely secured (shuttle chair, keeping you safe but not otherwise restrained from acting)
+ if(!buckled)
+ return UNBUCKLED
+ return restrained() ? FULLY_BUCKLED : PARTIALLY_BUCKLED
+
+/mob/proc/is_blind()
+ return ((sdisabilities & BLIND) || blinded || incapacitated(INCAPACITATION_KNOCKOUT))
+
+/mob/proc/is_deaf()
+ return ((sdisabilities & DEAF) || ear_deaf || incapacitated(INCAPACITATION_KNOCKOUT))
+
+/mob/proc/is_physically_disabled()
+ return incapacitated(INCAPACITATION_DISABLED)
+
+/mob/proc/cannot_stand()
+ return incapacitated(INCAPACITATION_KNOCKDOWN)
+
+/mob/proc/incapacitated(var/incapacitation_flags = INCAPACITATION_DEFAULT)
+ if ((incapacitation_flags & INCAPACITATION_STUNNED) && stunned)
+ return 1
+
+ if ((incapacitation_flags & INCAPACITATION_FORCELYING) && (weakened || resting))
+ return 1
+
+ if ((incapacitation_flags & INCAPACITATION_KNOCKOUT) && (stat || paralysis || sleeping || (status_flags & FAKEDEATH)))
+ return 1
+
+ if((incapacitation_flags & INCAPACITATION_RESTRAINED) && restrained())
+ return 1
+
+ if((incapacitation_flags & (INCAPACITATION_BUCKLED_PARTIALLY|INCAPACITATION_BUCKLED_FULLY)))
+ var/buckling = buckled()
+ if(buckling >= PARTIALLY_BUCKLED && (incapacitation_flags & INCAPACITATION_BUCKLED_PARTIALLY))
+ return 1
+ if(buckling == FULLY_BUCKLED && (incapacitation_flags & INCAPACITATION_BUCKLED_FULLY))
+ return 1
+
+ return 0
+
+#undef UNBUCKLED
+#undef PARTIALLY_BUCKLED
+#undef FULLY_BUCKLED
+
+/mob/proc/restrained()
+ return
+
+/mob/proc/reset_view(atom/A)
+ if (client)
+ if (istype(A, /atom/movable))
+ client.perspective = EYE_PERSPECTIVE
+ client.eye = A
+ else
+ if (isturf(loc))
+ client.eye = client.mob
+ client.perspective = MOB_PERSPECTIVE
+ else
+ client.perspective = EYE_PERSPECTIVE
+ client.eye = loc
+ return TRUE
+
+/mob/verb/pointed(atom/A as mob|obj|turf in view())
+ set name = "Point To"
+ set category = "Object"
+
+ if(!src || !isturf(src.loc) || !(A in view(src.loc)))
+ return 0
+ if(istype(A, /obj/effect/decal/point))
+ return 0
+
+ var/turf/tile = get_turf(A)
+ if (!tile)
+ return 0
+
+ var/turf/our_tile = get_turf(src)
+ var/obj/visual = new /obj/effect/decal/point(our_tile)
+ visual.invisibility = invisibility
+ visual.plane = ABOVE_PLANE
+ visual.layer = FLY_LAYER
+
+ animate(visual,
+ pixel_x = (tile.x - our_tile.x) * world.icon_size + A.pixel_x,
+ pixel_y = (tile.y - our_tile.y) * world.icon_size + A.pixel_y,
+ time = 1.7,
+ easing = EASE_OUT)
+
+ QDEL_IN(visual, 2 SECONDS) //Better qdel
+
+ face_atom(A)
+ return 1
+
+
+/mob/proc/ret_grab(list/L, flag)
+ return
+
+/mob/verb/mode()
+ set name = "Activate Held Object"
+ set category = "Object"
+ set src = usr
+
+ return
+
+/*
+/mob/verb/dump_source()
+
+ var/master = ""
+ for(var/t in typesof(/area))
+ master += text("[]\n", t)
+ //Foreach goto(26)
+ src << browse(master)
+ return
+*/
+
+/mob/verb/memory()
+ set name = "Notes"
+ set category = "IC"
+ if(mind)
+ mind.show_memory(src)
+ else
+ to_chat(src, "The game appears to have misplaced your mind datum, so we can't show you your notes.")
+
+/mob/verb/add_memory(msg as message)
+ set name = "Add Note"
+ set category = "IC"
+
+ msg = sanitize(msg)
+
+ if(mind)
+ mind.store_memory(msg)
+ else
+ to_chat(src, "The game appears to have misplaced your mind datum, so we can't show you your notes.")
+
+/mob/proc/store_memory(msg as message, popup, sane = 1)
+ msg = copytext(msg, 1, MAX_MESSAGE_LEN)
+
+ if (sane)
+ msg = sanitize(msg)
+
+ if (length(memory) == 0)
+ memory += msg
+ else
+ memory += "
[msg]"
+
+ if (popup)
+ memory()
+
+/mob/proc/update_flavor_text()
+ set src in usr
+ if(usr != src)
+ to_chat(usr, "No.")
+ var/msg = sanitize(tgui_input_text(usr,"Set the flavor text in your 'examine' verb.","Flavor Text",html_decode(flavor_text), multiline = TRUE, prevent_enter = TRUE), extra = 0) //VOREStation Edit: separating out OOC notes
+
+ if(msg != null)
+ flavor_text = msg
+
+/mob/proc/warn_flavor_changed()
+ if(flavor_text && flavor_text != "") // don't spam people that don't use it!
+ to_chat(src, "OOC Warning:
")
+ to_chat(src, "Your flavor text is likely out of date! Change")
+
+/mob/proc/print_flavor_text()
+ if (flavor_text && flavor_text != "")
+ var/msg = replacetext(flavor_text, "\n", " ")
+ if(length(msg) <= 40)
+ return "[msg]"
+ else
+ return "[copytext_preserve_html(msg, 1, 37)]... More..."
+
+/*
+/mob/verb/help()
+ set name = "Help"
+ src << browse('html/help.html', "window=help")
+ return
+*/
+
+/mob/proc/set_respawn_timer(var/time)
+ // Try to figure out what time to use
+
+ // Special cases, can never respawn
+ if(ticker?.mode?.deny_respawn)
+ time = -1
+ else if(!config.abandon_allowed)
+ time = -1
+ else if(!config.respawn)
+ time = -1
+
+ // Special case for observing before game start
+ else if(ticker?.current_state <= GAME_STATE_SETTING_UP)
+ time = 1 MINUTE
+
+ // Wasn't given a time, use the config time
+ else if(!time)
+ time = config.respawn_time
+
+ var/keytouse = ckey
+ // Try harder to find a key to use
+ if(!keytouse && key)
+ keytouse = ckey(key)
+ else if(!keytouse && mind?.key)
+ keytouse = ckey(mind.key)
+
+ GLOB.respawn_timers[keytouse] = world.time + time
+
+/mob/observer/dead/set_respawn_timer()
+ if(config.antag_hud_restricted && has_enabled_antagHUD)
+ ..(-1)
+ else
+ return // Don't set it, no need
+
+/mob/verb/abandon_mob()
+ set name = "Return to Menu"
+ set category = "OOC"
+
+ if(stat != DEAD || !ticker)
+ to_chat(usr, "You must be dead to use this!")
+ return
+
+ // Final chance to abort "respawning"
+ if(mind && timeofdeath) // They had spawned before
+ var/choice = tgui_alert(usr, "Returning to the menu will prevent your character from being revived in-round. Are you sure?", "Confirmation", list("No, wait", "Yes, leave"))
+ if(choice == "No, wait")
+ return
+ else if(mind.assigned_role)
+ var/extra_check = tgui_alert(usr, "Do you want to Quit This Round before you return to lobby? This will properly remove you from manifest, as well as prevent resleeving.","Quit This Round",list("Quit Round","Cancel"))
+ if(extra_check == "Quit Round")
+ //Update any existing objectives involving this mob.
+ for(var/datum/objective/O in all_objectives)
+ if(O.target == src.mind)
+ if(O.owner && O.owner.current)
+ to_chat(O.owner.current,"You get the feeling your target is no longer within your reach...")
+ qdel(O)
+
+ //Resleeving cleanup
+ if(mind)
+ SStranscore.leave_round(src)
+
+ //Job slot cleanup
+ var/job = src.mind.assigned_role
+ job_master.FreeRole(job)
+
+ //Their objectives cleanup
+ if(src.mind.objectives.len)
+ qdel(src.mind.objectives)
+ src.mind.special_role = null
+
+ //Cut the PDA manifest (ugh)
+ if(PDA_Manifest.len)
+ PDA_Manifest.Cut()
+ for(var/datum/data/record/R in data_core.medical)
+ if((R.fields["name"] == src.real_name))
+ qdel(R)
+ for(var/datum/data/record/T in data_core.security)
+ if((T.fields["name"] == src.real_name))
+ qdel(T)
+ for(var/datum/data/record/G in data_core.general)
+ if((G.fields["name"] == src.real_name))
+ qdel(G)
+
+ //This removes them from being 'active' list on join screen
+ src.mind.assigned_role = null
+ to_chat(src,"Your job has been free'd up, and you can rejoin as another character or quit. Thanks for properly quitting round, it helps the server!")
+
+ // Beyond this point, you're going to respawn
+ to_chat(usr, config.respawn_message)
+
+ if(!client)
+ log_game("[usr.key] AM failed due to disconnect.")
+ return
+ client.screen.Cut()
+ client.screen += client.void
+ if(!client)
+ log_game("[usr.key] AM failed due to disconnect.")
+ return
+
+ announce_ghost_joinleave(client, 0)
+
+ var/mob/new_player/M = new /mob/new_player()
+ if(!client)
+ log_game("[usr.key] AM failed due to disconnect.")
+ qdel(M)
+ return
+
+ M.key = key
+ if(M.mind)
+ M.mind.reset()
+ return
+
+/client/verb/changes()
+ set name = "Changelog"
+ set category = "OOC"
+ // CHOMPedit Start - Better Changelog
+ //src << browse('html/changelog.html', "window=changes;size=675x650")
+ //return
+
+ if(!GLOB.changelog_tgui)
+ GLOB.changelog_tgui = new /datum/changelog()
+ GLOB.changelog_tgui.tgui_interact(usr)
+ // CHOMPedit END
+ if(prefs.lastchangelog != changelog_hash)
+ prefs.lastchangelog = changelog_hash
+ SScharacter_setup.queue_preferences_save(prefs)
+ // winset(src, "rpane.changelog", "background-color=none;font-style=;") //ChompREMOVE
+
+/mob/verb/observe()
+ set name = "Observe"
+ set category = "OOC"
+ var/is_admin = 0
+
+ if(client.holder && (client.holder.rights & R_ADMIN|R_EVENT))
+ is_admin = 1
+ else if(stat != DEAD || istype(src, /mob/new_player))
+ to_chat(usr, "You must be observing to use this!")
+ return
+
+ if(is_admin && stat == DEAD)
+ is_admin = 0
+
+ var/list/targets = list()
+
+
+ targets += observe_list_format(nuke_disks)
+ targets += observe_list_format(GLOB.all_singularities) //CHOMP Edit
+ targets += getmobs()
+ targets += observe_list_format(sortAtom(mechas_list))
+ targets += observe_list_format(SSshuttles.ships)
+
+ client.perspective = EYE_PERSPECTIVE
+
+ var/eye_name = null
+
+ var/ok = "[is_admin ? "Admin Observe" : "Observe"]"
+ eye_name = tgui_input_list(usr, "Select something to [ok]:", "Select Target", targets)
+
+ if (!eye_name)
+ return
+
+ var/mob/mob_eye = targets[eye_name]
+
+ if(client && mob_eye)
+ client.eye = mob_eye
+ if (is_admin)
+ client.adminobs = 1
+ if(mob_eye == client.mob || client.eye == client.mob)
+ client.adminobs = 0
+
+/mob/verb/cancel_camera()
+ set name = "Cancel Camera View"
+ set category = "OOC"
+ unset_machine()
+ reset_view(null)
+
+/mob/Topic(href, href_list)
+ if(href_list["mach_close"])
+ var/t1 = text("window=[href_list["mach_close"]]")
+ unset_machine()
+ src << browse(null, t1)
+
+ if(href_list["flavor_more"])
+ usr << browse(text("[] []", name, replacetext(flavor_text, "\n", "
")), text("window=[];size=500x200", name))
+ onclose(usr, "[name]")
+ if(href_list["flavor_change"])
+ update_flavor_text()
+// ..()
+ return
+
+
+/mob/proc/pull_damage()
+ return 0
+
+/mob/verb/stop_pulling()
+
+ set name = "Stop Pulling"
+ set category = "IC"
+
+ if(pulling)
+ if(ishuman(pulling))
+ var/mob/living/carbon/human/H = pulling
+ visible_message(SPAN_WARNING("\The [src] lets go of \the [H]."), SPAN_NOTICE("You let go of \the [H]."), exclude_mobs = list(H))
+ if(!H.stat)
+ to_chat(H, SPAN_WARNING("\The [src] lets go of you."))
+ pulling.pulledby = null
+ pulling = null
+ if(pullin)
+ pullin.icon_state = "pull0"
+
+/mob/proc/start_pulling(var/atom/movable/AM)
+
+ if ( !AM || !usr || src==AM || !isturf(src.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort!
+ return
+
+ if (AM.anchored)
+ to_chat(src, "It won't budge!")
+ return
+
+ var/mob/M = AM
+ if(ismob(AM))
+
+ if(!can_pull_mobs || !can_pull_size)
+ to_chat(src, "They won't budge!")
+ return
+
+ if((mob_size < M.mob_size) && (can_pull_mobs != MOB_PULL_LARGER))
+ to_chat(src, "[M] is too large for you to move!")
+ return
+
+ if((mob_size == M.mob_size) && (can_pull_mobs == MOB_PULL_SMALLER))
+ to_chat(src, "[M] is too heavy for you to move!")
+ return
+
+ // If your size is larger than theirs and you have some
+ // kind of mob pull value AT ALL, you will be able to pull
+ // them, so don't bother checking that explicitly.
+
+ if(M.grabbed_by.len)
+ // Only start pulling when nobody else has a grab on them
+ . = 1
+ for(var/obj/item/weapon/grab/G in M.grabbed_by)
+ if(G.assailant != usr)
+ . = 0
+ else
+ qdel(G)
+ if(!.)
+ to_chat(src, "Somebody has a grip on them!")
+ return
+
+ if(!iscarbon(src))
+ M.LAssailant = null
+ else
+ M.LAssailant = usr
+
+ else if(isobj(AM))
+ var/obj/I = AM
+ if(!can_pull_size || can_pull_size < I.w_class)
+ to_chat(src, "It won't budge!")
+ return
+
+ if(pulling)
+ var/pulling_old = pulling
+ stop_pulling()
+ // Are we pulling the same thing twice? Just stop pulling.
+ if(pulling_old == AM)
+ return
+
+ src.pulling = AM
+ AM.pulledby = src
+
+ if(pullin)
+ pullin.icon_state = "pull1"
+
+ if(ishuman(AM))
+ var/mob/living/carbon/human/H = AM
+ if(H.lying) // If they're on the ground we're probably dragging their arms to move them
+ visible_message(SPAN_WARNING("\The [src] leans down and grips \the [H]'s arms."), SPAN_NOTICE("You lean down and grip \the [H]'s arms."), exclude_mobs = list(H))
+ if(!H.stat)
+ to_chat(H, SPAN_WARNING("\The [src] leans down and grips your arms."))
+ else //Otherwise we're probably just holding their arm to lead them somewhere
+ visible_message(SPAN_WARNING("\The [src] grips \the [H]'s arm."), SPAN_NOTICE("You grip \the [H]'s arm."), exclude_mobs = list(H))
+ if(!H.stat)
+ to_chat(H, SPAN_WARNING("\The [src] grips your arm."))
+ playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 25) //Quieter than hugging/grabbing but we still want some audio feedback
+
+ if(H.pull_damage())
+ to_chat(src, "Pulling \the [H] in their current condition would probably be a bad idea.")
+
+ //Attempted fix for people flying away through space when cuffed and dragged.
+ if(ismob(AM))
+ var/mob/pulled = AM
+ pulled.inertia_dir = 0
+
+/mob/proc/can_use_hands()
+ return
+
+/mob/proc/is_active()
+ return (0 >= usr.stat)
+
+/mob/proc/is_dead()
+ return stat == DEAD
+
+/mob/proc/is_mechanical()
+ if(mind && (mind.assigned_role == "Cyborg" || mind.assigned_role == "AI"))
+ return 1
+ return istype(src, /mob/living/silicon) || get_species() == "Machine"
+
+/mob/proc/is_ready()
+ return client && !!mind
+
+/mob/proc/get_gender()
+ return gender
+
+/mob/proc/name_gender()
+ return gender
+
+/mob/proc/see(message)
+ if(!is_active())
+ return 0
+ to_chat(src,message)
+ return 1
+
+/mob/proc/show_viewers(message)
+ for(var/mob/M in viewers())
+ M.see(message)
+
+/mob/Stat()
+ ..()
+ . = (is_client_active(10 MINUTES))
+
+ if(.)
+ if(statpanel("Status"))
+ 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)]%)")
+ if(ticker && ticker.current_state != GAME_STATE_PREGAME)
+ stat("Station Time", stationtime2text())
+ var/date = "[stationdate2text()], [capitalize(world_time_season)]"
+ stat("Station Date", date)
+ stat("Round Duration", roundduration2text())
+
+ if(client.holder)
+ if(statpanel("Status"))
+ stat("Location:", "([x], [y], [z]) [loc]")
+ stat("CPU:","[world.cpu]")
+ 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("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"))
+ stat("Location:", "([x], [y], [z]) [loc]")
+ stat("CPU:","[world.cpu]")
+ stat("Instances:","[world.contents.len]")
+ stat("World Time:", world.time)
+ stat("Real time of day:", REALTIMEOFDAY)
+ stat(null)
+ if(GLOB)
+ GLOB.stat_entry()
+ else
+ stat("Globals:", "ERROR")
+ if(Master)
+ Master.stat_entry()
+ else
+ stat("Master Controller:", "ERROR")
+ if(Failsafe)
+ Failsafe.stat_entry()
+ else
+ stat("Failsafe Controller:", "ERROR")
+ if(Master)
+ stat(null)
+ for(var/datum/controller/subsystem/SS in Master.subsystems)
+ SS.stat_entry()
+
+ // CHOMPedit - Ticket System
+ //if(statpanel("Tickets"))
+ //GLOB.ahelp_tickets.stat_entry()
+
+
+ if(length(GLOB.sdql2_queries))
+ if(statpanel("SDQL2"))
+ stat("Access Global SDQL2 List", GLOB.sdql2_vv_statobj)
+ for(var/datum/SDQL2_query/Q as anything in GLOB.sdql2_queries)
+ Q.generate_stat()
+
+ if(has_mentor_powers(client) || client.holder) // CHOMPedit - Ticket System
+ if(statpanel("Tickets"))
+ GLOB.tickets.stat_entry() // CHOMPedit - Ticket System
+
+ if(listed_turf && client)
+ if(!TurfAdjacent(listed_turf))
+ listed_turf = null
+ else
+ if(statpanel("Turf"))
+ stat(listed_turf)
+ for(var/atom/A in listed_turf)
+ if(!A.mouse_opacity)
+ continue
+ if(A.invisibility > see_invisible)
+ continue
+ if(is_type_in_list(A, shouldnt_see))
+ continue
+ if(A.plane > plane)
+ continue
+ stat(A)
+
+
+// facing verbs
+/mob/proc/canface()
+// if(!canmove) return 0 //VOREStation Edit. Redundant check that only affects conscious proning, actual inability to turn and shift around handled by actual inabilities.
+ if(stat) return 0
+ if(anchored) return 0
+ if(transforming) return 0
+ return 1
+
+// Not sure what to call this. Used to check if humans are wearing an AI-controlled exosuit and hence don't need to fall over yet.
+/mob/proc/can_stand_overridden()
+ return 0
+
+//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
+/mob/proc/update_canmove()
+ return canmove
+
+
+/mob/proc/facedir(var/ndir)
+ if(!canface() || (client && (client.moving || !checkMoveCooldown())))
+ DEBUG_INPUT("Denying Facedir for [src] (moving=[client?.moving])")
+ return 0
+ set_dir(ndir)
+ if(buckled && buckled.buckle_movable)
+ buckled.set_dir(ndir)
+ setMoveCooldown(movement_delay())
+ return 1
+
+
+/mob/verb/eastface()
+ set hidden = 1
+ return facedir(client.client_dir(EAST))
+
+
+/mob/verb/westface()
+ set hidden = 1
+ return facedir(client.client_dir(WEST))
+
+
+/mob/verb/northface()
+ set hidden = 1
+ return facedir(client.client_dir(NORTH))
+
+
+/mob/verb/southface()
+ set hidden = 1
+ return facedir(client.client_dir(SOUTH))
+
+
+//This might need a rename but it should replace the can this mob use things check
+/mob/proc/IsAdvancedToolUser()
+ return 0
+
+/mob/proc/Stun(amount)
+ if(status_flags & CANSTUN)
+ facing_dir = null
+ stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun
+ update_canmove() //updates lying, canmove and icons
+ return
+
+/mob/proc/SetStunned(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned"
+ if(status_flags & CANSTUN)
+ stunned = max(amount,0)
+ update_canmove() //updates lying, canmove and icons
+ return
+
+/mob/proc/AdjustStunned(amount)
+ if(status_flags & CANSTUN)
+ stunned = max(stunned + amount,0)
+ update_canmove() //updates lying, canmove and icons
+ return
+
+/mob/proc/Weaken(amount)
+ if(status_flags & CANWEAKEN)
+ facing_dir = null
+ weakened = max(max(weakened,amount),0)
+ update_canmove() //updates lying, canmove and icons
+ return
+
+/mob/proc/SetWeakened(amount)
+ if(status_flags & CANWEAKEN)
+ weakened = max(amount,0)
+ update_canmove() //can you guess what this does yet?
+ return
+
+/mob/proc/AdjustWeakened(amount)
+ if(status_flags & CANWEAKEN)
+ weakened = max(weakened + amount,0)
+ update_canmove() //updates lying, canmove and icons
+ return
+
+/mob/proc/Paralyse(amount)
+ if(status_flags & CANPARALYSE)
+ facing_dir = null
+ paralysis = max(max(paralysis,amount),0)
+ return
+
+/mob/proc/SetParalysis(amount)
+ if(status_flags & CANPARALYSE)
+ paralysis = max(amount,0)
+ return
+
+/mob/proc/AdjustParalysis(amount)
+ if(status_flags & CANPARALYSE)
+ paralysis = max(paralysis + amount,0)
+ return
+
+/mob/proc/Sleeping(amount)
+ facing_dir = null
+ sleeping = max(max(sleeping,amount),0)
+ return
+
+/mob/proc/SetSleeping(amount)
+ sleeping = max(amount,0)
+ return
+
+/mob/proc/AdjustSleeping(amount)
+ sleeping = max(sleeping + amount,0)
+ return
+
+/mob/proc/Confuse(amount)
+ confused = max(max(confused,amount),0)
+ return
+
+/mob/proc/SetConfused(amount)
+ confused = max(amount,0)
+ return
+
+/mob/proc/AdjustConfused(amount)
+ confused = max(confused + amount,0)
+ return
+
+/mob/proc/Blind(amount)
+ eye_blind = max(max(eye_blind,amount),0)
+ return
+
+/mob/proc/SetBlinded(amount)
+ eye_blind = max(amount,0)
+ return
+
+/mob/proc/AdjustBlinded(amount)
+ eye_blind = max(eye_blind + amount,0)
+ return
+
+/mob/proc/Resting(amount)
+ facing_dir = null
+ resting = max(max(resting,amount),0)
+ update_canmove()
+ return
+
+/mob/proc/SetResting(amount)
+ resting = max(amount,0)
+ update_canmove()
+ return
+
+/mob/proc/AdjustResting(amount)
+ resting = max(resting + amount,0)
+ update_canmove()
+ return
+
+/mob/proc/AdjustLosebreath(amount)
+ losebreath = CLAMP(losebreath + amount, 0, 25)
+
+/mob/proc/SetLosebreath(amount)
+ losebreath = CLAMP(amount, 0, 25)
+
+/mob/proc/get_species()
+ return ""
+
+/mob/proc/flash_weak_pain()
+ flick("weak_pain",pain)
+
+/mob/proc/get_visible_implants(var/class = 0)
+ var/list/visible_implants = list()
+ for(var/obj/item/O in embedded)
+ if(O.w_class > class)
+ visible_implants += O
+ return visible_implants
+
+/mob/proc/embedded_needs_process()
+ return (embedded.len > 0)
+
+/mob/proc/yank_out_object()
+ set category = "Object"
+ set name = "Yank out object"
+ set desc = "Remove an embedded item at the cost of bleeding and pain."
+ set src in view(1)
+
+ if(!isliving(usr) || !usr.checkClickCooldown())
+ return
+ usr.setClickCooldown(20)
+
+ if(usr.stat == 1)
+ to_chat(usr, "You are unconcious and cannot do that!")
+ return
+
+ if(usr.restrained())
+ to_chat(usr, "You are restrained and cannot do that!")
+ return
+
+ var/mob/S = src
+ var/mob/U = usr
+ var/list/valid_objects = list()
+ var/self = null
+
+ if(S == U)
+ self = 1 // Removing object from yourself.
+
+ valid_objects = get_visible_implants(0)
+ if(!valid_objects.len)
+ if(self)
+ to_chat(src, "You have nothing stuck in your body that is large enough to remove.")
+ else
+ to_chat(U, "[src] has nothing stuck in their wounds that is large enough to remove.")
+ return
+
+ var/obj/item/weapon/selection = tgui_input_list(usr, "What do you want to yank out?", "Embedded objects", valid_objects)
+
+ if(self)
+ to_chat(src, "You attempt to get a good grip on [selection] in your body.")
+ else
+ to_chat(U, "You attempt to get a good grip on [selection] in [S]'s body.")
+
+ if(!do_after(U, 30))
+ return
+ if(!selection || !S || !U)
+ return
+
+ if(self)
+ visible_message("[src] rips [selection] out of their body.","You rip [selection] out of your body.")
+ else
+ visible_message("[usr] rips [selection] out of [src]'s body.","[usr] rips [selection] out of your body.")
+ valid_objects = get_visible_implants(0)
+ if(valid_objects.len == 1) //Yanking out last object - removing verb.
+ src.verbs -= /mob/proc/yank_out_object
+ clear_alert("embeddedobject")
+
+ if(ishuman(src))
+ var/mob/living/carbon/human/H = src
+ var/obj/item/organ/external/affected
+
+ for(var/obj/item/organ/external/organ in H.organs) //Grab the organ holding the implant.
+ for(var/obj/item/O in organ.implants)
+ if(O == selection)
+ affected = organ
+
+ affected.implants -= selection
+ H.shock_stage+=20
+ affected.take_damage((selection.w_class * 3), 0, 0, 1, "Embedded object extraction")
+
+ if(prob(selection.w_class * 5) && (affected.robotic < ORGAN_ROBOT)) //I'M SO ANEMIC I COULD JUST -DIE-.
+ var/datum/wound/internal_bleeding/I = new (min(selection.w_class * 5, 15))
+ affected.wounds += I
+ H.custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 50)
+
+ if (ishuman(U))
+ var/mob/living/carbon/human/human_user = U
+ human_user.bloody_hands(H)
+
+ else if(issilicon(src))
+ var/mob/living/silicon/robot/R = src
+ R.embedded -= selection
+ R.adjustBruteLoss(5)
+ R.adjustFireLoss(10)
+
+ selection.forceMove(get_turf(src))
+ U.put_in_hands(selection)
+
+ for(var/obj/item/weapon/O in pinned)
+ if(O == selection)
+ pinned -= O
+ if(!pinned.len)
+ anchored = FALSE
+ return 1
+
+//Check for brain worms in head.
+/mob/proc/has_brain_worms()
+
+ for(var/I in contents)
+ if(istype(I,/mob/living/simple_mob/animal/borer))
+ return I
+
+ return 0
+
+/mob/proc/updateicon()
+ return
+
+// Please always use this proc, never just set the var directly.
+/mob/proc/set_stat(var/new_stat)
+ . = (stat != new_stat)
+ stat = new_stat
+
+/mob/verb/face_direction()
+
+ set name = "Face Direction"
+ set category = "IC"
+ set src = usr
+
+ set_face_dir()
+
+ if(!facing_dir)
+ to_chat(usr, "You are now not facing anything.")
+ else
+ to_chat(usr, "You are now facing [dir2text(facing_dir)].")
+
+/mob/proc/set_face_dir(var/newdir)
+ if(newdir == facing_dir)
+ facing_dir = null
+ else if(newdir)
+ set_dir(newdir)
+ facing_dir = newdir
+ else if(facing_dir)
+ facing_dir = null
+ else
+ set_dir(dir)
+ facing_dir = dir
+
+/mob/set_dir()
+ if(facing_dir)
+ if(!canface() || lying || buckled || restrained())
+ facing_dir = null
+ else if(dir != facing_dir)
+ return ..(facing_dir)
+ else
+ return ..()
+
+/mob/verb/northfaceperm()
+ set hidden = 1
+ set_face_dir(client.client_dir(NORTH))
+
+/mob/verb/southfaceperm()
+ set hidden = 1
+ set_face_dir(client.client_dir(SOUTH))
+
+/mob/verb/eastfaceperm()
+ set hidden = 1
+ set_face_dir(client.client_dir(EAST))
+
+/mob/verb/westfaceperm()
+ set hidden = 1
+ set_face_dir(client.client_dir(WEST))
+
+// Begin VOREstation edit
+/mob/verb/shiftnorth()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(pixel_y <= (default_pixel_y + 16))
+ pixel_y++
+ is_shifted = TRUE
+
+/mob/verb/shiftsouth()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(pixel_y >= (default_pixel_y - 16))
+ pixel_y--
+ is_shifted = TRUE
+
+/mob/verb/shiftwest()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(pixel_x >= (default_pixel_x - 16))
+ pixel_x--
+ is_shifted = TRUE
+
+/mob/verb/shifteast()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(pixel_x <= (default_pixel_x + 16))
+ pixel_x++
+ is_shifted = TRUE
+
+/mob/verb/planeup()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(plane >= MOB_PLANE + 3) //Don't bother going too high!
+ return
+ if(layer == MOB_LAYER) //Become higher
+ layer = ABOVE_MOB_LAYER
+ plane += 1 //Increase the plane
+ if(plane == MOB_PLANE) //Return to normal
+ layer = MOB_LAYER
+ is_shifted = TRUE
+
+/mob/verb/planedown()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(plane <= MOB_PLANE - 3) //Don't bother going too low!
+ return
+ if(layer == MOB_LAYER) //Become lower
+ layer = BELOW_MOB_LAYER
+ plane -= 1 //Decrease the plane
+ if(plane == MOB_PLANE) //Return to normal
+ layer = MOB_LAYER
+ is_shifted = TRUE
+
+// End VOREstation edit
+
+/mob/proc/adjustEarDamage()
+ return
+
+/mob/proc/setEarDamage()
+ return
+
+// Set client view distance (size of client's screen). Returns TRUE if anything changed.
+/mob/proc/set_viewsize(var/new_view = world.view)
+ if (client && new_view != client.view)
+ client.view = new_view
+ return TRUE
+ return FALSE
+
+//Throwing stuff
+
+/mob/proc/toggle_throw_mode()
+ if (src.in_throw_mode)
+ throw_mode_off()
+ else
+ throw_mode_on()
+
+/mob/proc/throw_mode_off()
+ src.in_throw_mode = 0
+ if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
+ src.throw_icon.icon_state = "act_throw_off"
+
+/mob/proc/throw_mode_on()
+ src.in_throw_mode = 1
+ if(src.throw_icon)
+ src.throw_icon.icon_state = "act_throw_on"
+
+/mob/proc/isSynthetic()
+ return 0
+
+/mob/proc/is_muzzled()
+ return 0
+
+//Exploitable Info Update
+
+/mob/proc/amend_exploitable(var/obj/item/I)
+ if(istype(I))
+ exploit_addons |= I
+ var/exploitmsg = html_decode("\n" + "Has " + I.name + ".")
+ exploit_record += exploitmsg
+
+/client/proc/check_has_body_select()
+ return mob && mob.hud_used && istype(mob.zone_sel, /obj/screen/zone_sel)
+
+/client/verb/body_toggle_head()
+ set name = "body-toggle-head"
+ set hidden = 1
+ toggle_zone_sel(list(BP_HEAD, O_EYES, O_MOUTH))
+
+/client/verb/body_r_arm()
+ set name = "body-r-arm"
+ set hidden = 1
+ toggle_zone_sel(list(BP_R_ARM,BP_R_HAND))
+
+/client/verb/body_l_arm()
+ set name = "body-l-arm"
+ set hidden = 1
+ toggle_zone_sel(list(BP_L_ARM,BP_L_HAND))
+
+/client/verb/body_chest()
+ set name = "body-chest"
+ set hidden = 1
+ toggle_zone_sel(list(BP_TORSO))
+
+/client/verb/body_groin()
+ set name = "body-groin"
+ set hidden = 1
+ toggle_zone_sel(list(BP_GROIN))
+
+/client/verb/body_r_leg()
+ set name = "body-r-leg"
+ set hidden = 1
+ toggle_zone_sel(list(BP_R_LEG,BP_R_FOOT))
+
+/client/verb/body_l_leg()
+ set name = "body-l-leg"
+ set hidden = 1
+ toggle_zone_sel(list(BP_L_LEG,BP_L_FOOT))
+
+/client/proc/toggle_zone_sel(list/zones)
+ if(!check_has_body_select())
+ return
+ var/obj/screen/zone_sel/selector = mob.zone_sel
+ selector.set_selected_zone(next_in_list(mob.zone_sel.selecting,zones))
+
+// This handles setting the client's color variable, which makes everything look a specific color.
+// This proc is here so it can be called without needing to check if the client exists, or if the client relogs.
+// This is for inheritence since /mob/living will serve most cases. If you need ghosts to use this you'll have to implement that yourself.
+/mob/proc/update_client_color()
+ if(client && client.color)
+ animate(client, color = null, time = 10)
+ return
+
+/mob/proc/swap_hand()
+ return
+
+//Throwing stuff
+/mob/proc/throw_item(atom/target)
+ return FALSE
+
+/mob/proc/will_show_tooltip()
+ if(alpha <= EFFECTIVE_INVIS)
+ return FALSE
+ return TRUE
+
+/mob/MouseEntered(location, control, params)
+ if(usr != src && usr.is_preference_enabled(/datum/client_preference/mob_tooltips) && src.will_show_tooltip())
+ openToolTip(user = usr, tip_src = src, params = params, title = get_nametag_name(usr), content = get_nametag_desc(usr))
+
+ ..()
+
+/mob/MouseDown()
+ closeToolTip(usr) //No reason not to, really
+
+ ..()
+
+/mob/MouseExited()
+ closeToolTip(usr) //No reason not to, really
+
+ ..()
+
+// Manages a global list of mobs with clients attached, indexed by z-level.
+/mob/proc/update_client_z(new_z) // +1 to register, null to unregister.
+ if(registered_z != new_z)
+ if(registered_z)
+ GLOB.players_by_zlevel[registered_z] -= src
+ if(client)
+ if(new_z)
+ GLOB.players_by_zlevel[new_z] += src
+ registered_z = new_z
+ else
+ registered_z = null
+
+GLOBAL_LIST_EMPTY_TYPED(living_players_by_zlevel, /list)
+/mob/living/update_client_z(new_z)
+ var/precall_reg_z = registered_z
+ . = ..() // will update registered_z if necessary
+ if(precall_reg_z != registered_z) // parent did work, let's do work too
+ if(precall_reg_z)
+ GLOB.living_players_by_zlevel[precall_reg_z] -= src
+ if(registered_z)
+ GLOB.living_players_by_zlevel[registered_z] += src
+
+/mob/onTransitZ(old_z, new_z)
+ ..()
+ update_client_z(new_z)
+
+/mob/cloak()
+ . = ..()
+ if(client && cloaked_selfimage)
+ client.images += cloaked_selfimage
+
+/mob/uncloak()
+ if(client && cloaked_selfimage)
+ client.images -= cloaked_selfimage
+ return ..()
+
+/mob/get_cloaked_selfimage()
+ var/icon/selficon = getCompoundIcon(src)
+ selficon.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) //White
+ var/image/selfimage = image(selficon)
+ selfimage.color = "#0000FF"
+ selfimage.alpha = 100
+ selfimage.layer = initial(layer)
+ selfimage.plane = initial(plane)
+ selfimage.loc = src
+
+ return selfimage
+
+/mob/proc/GetAltName()
+ return ""
+
+/mob/proc/get_ghost(even_if_they_cant_reenter = 0)
+ if(mind)
+ return mind.get_ghost(even_if_they_cant_reenter)
+
+/mob/proc/grab_ghost(force)
+ if(mind)
+ return mind.grab_ghost(force = force)
diff --git a/interface/skin.dmf b/interface/skin.dmf
index b44b9331fa..697bda534f 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -1,5 +1,5 @@
macro "borghotkeymode"
- elem
+ elem
name = "TAB"
command = ".winset \"mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5\""
elem
@@ -20,58 +20,58 @@ macro "borghotkeymode"
elem
name = "Alt+UP"
command = "KeyUp Alt"
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
- elem
+ elem
name = "SOUTHWEST"
command = ".southwest"
- elem
+ elem
name = "NORTHWEST"
command = ".northwest"
- elem
+ elem
name = "ALT+WEST"
command = "westfaceperm"
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
- elem
+ elem
name = "West"
command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
- elem
+ elem
name = "ALT+NORTH"
command = "northfaceperm"
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
- elem
+ elem
name = "North"
command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
- elem
+ elem
name = "ALT+EAST"
command = "eastfaceperm"
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
- elem
+ elem
name = "East"
command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
- elem
+ elem
name = "ALT+SOUTH"
command = "southfaceperm"
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
elem
@@ -83,91 +83,91 @@ macro "borghotkeymode"
elem
name = "CTRL+SHIFT+NORTH"
command = "shiftnorth"
- elem
+ elem
name = "CTRL+SHIFT+SOUTH"
command = "shiftsouth"
- elem
+ elem
name = "CTRL+SHIFT+WEST"
command = "shiftwest"
- elem
+ elem
name = "CTRL+SHIFT+EAST"
command = "shifteast"
- elem
+ elem
name = "INSERT"
command = "a-intent right"
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
- elem
+ elem
name = "1"
command = "toggle-module 1"
- elem
+ elem
name = "CTRL+1"
command = "toggle-module 1"
- elem
+ elem
name = "2"
command = "toggle-module 2"
- elem
+ elem
name = "CTRL+2"
command = "toggle-module 2"
- elem
+ elem
name = "3"
command = "toggle-module 3"
- elem
+ elem
name = "CTRL+3"
command = "toggle-module 3"
- elem
+ elem
name = "4"
command = "a-intent left"
- elem
+ elem
name = "CTRL+4"
command = "a-intent left"
- elem
+ elem
name = "5"
command = ".me"
- elem
+ elem
name = "6"
command = ".Subtle"
- elem
+ elem
name = "A"
command = "KeyDown A"
elem
name = "A+UP"
command = "KeyUp A"
- elem
+ elem
name = "D"
command = "KeyDown D"
elem
name = "D+UP"
command = "KeyUp D"
- elem
+ elem
name = "F"
command = "a-intent left"
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
- elem
+ elem
name = "G"
command = "a-intent right"
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
- elem
+ elem
name = "J"
command = "toggle-gun-mode"
- elem
+ elem
name = "CTRL+J"
command = "toggle-gun-mode"
- elem
+ elem
name = "Q"
command = "unequip-module"
- elem
+ elem
name = "CTRL+Q"
command = "unequip-module"
- elem
+ elem
name = "R"
command = ".southwest"
- elem
+ elem
name = "CTRL+R"
command = ".southwest"
elem "s_key"
@@ -176,7 +176,7 @@ macro "borghotkeymode"
elem
name = "S+UP"
command = "KeyUp S"
- elem
+ elem
name = "T"
command = ".say"
elem "w_key"
@@ -185,90 +185,96 @@ macro "borghotkeymode"
elem
name = "W+UP"
command = "KeyUp W"
- elem
+ elem
name = "X"
command = ".northeast"
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
- elem
+ elem
name = "Y"
command = ".Whisper"
- elem
+ elem
name = "CTRL+Y"
command = ".Whisper"
- elem
+ elem
name = "Z"
command = "Activate-Held-Object"
- elem
+ elem
name = "CTRL+Z"
command = "Activate-Held-Object"
- elem
+ elem
name = "U"
command = "Rest"
- elem
+ elem
name = "NUMPAD1"
command = "body-r-leg"
- elem
+ elem
name = "NUMPAD2"
command = "body-groin"
- elem
+ elem
name = "NUMPAD3"
command = "body-l-leg"
- elem
+ elem
name = "NUMPAD4"
command = "body-r-arm"
- elem
+ elem
name = "NUMPAD5"
command = "body-chest"
- elem
+ elem
name = "NUMPAD6"
command = "body-l-arm"
- elem
+ elem
name = "NUMPAD8"
command = "body-toggle-head"
- elem
+ elem
name = "F1"
command = "request-help"
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
- elem
+ elem
name = "F2"
command = "ooc"
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
- elem
+ elem
name = "F3"
command = ".say"
- elem
+ elem
name = "F4"
command = ".me"
- elem
+ elem
name = "F5"
command = "asay"
- elem
+ elem
name = "F6"
command = "Player-Panel-New"
- elem
+ elem
name = "F7"
command = "Admin-PM"
- elem
+ elem
name = "F8"
command = "Invisimin"
- elem
+ elem
name = "F12"
command = "F12"
+ elem
+ name = "CTRL+SHIFT+ADD"
+ command = "planeup"
+ elem
+ name = "CTRL+SHIFT+SUBTRACT"
+ command = "planedown"
macro "macro"
- elem
+ elem
name = "TAB"
command = ".winset \"mainwindow.macro=hotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true\""
- elem
+ elem
name = "Shift"
command = "KeyDown Shift"
elem
@@ -286,58 +292,58 @@ macro "macro"
elem
name = "Alt+UP"
command = "KeyUp Alt"
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
- elem
+ elem
name = "SOUTHWEST"
command = ".southwest"
- elem
+ elem
name = "NORTHWEST"
command = ".northwest"
- elem
+ elem
name = "ALT+WEST"
command = "westfaceperm"
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
- elem
+ elem
name = "West"
command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
- elem
+ elem
name = "ALT+NORTH"
command = "northfaceperm"
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
- elem
+ elem
name = "North"
command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
- elem
+ elem
name = "ALT+EAST"
command = "eastfaceperm"
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
- elem
+ elem
name = "East"
command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
- elem
+ elem
name = "ALT+SOUTH"
command = "southfaceperm"
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
elem
@@ -349,150 +355,156 @@ macro "macro"
elem
name = "CTRL+SHIFT+NORTH"
command = "shiftnorth"
- elem
+ elem
name = "CTRL+SHIFT+SOUTH"
command = "shiftsouth"
- elem
+ elem
name = "CTRL+SHIFT+WEST"
command = "shiftwest"
- elem
+ elem
name = "CTRL+SHIFT+EAST"
command = "shifteast"
- elem
+ elem
name = "INSERT"
command = "a-intent right"
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
- elem
+ elem
name = "CTRL+1"
command = "a-intent help"
- elem
+ elem
name = "CTRL+2"
command = "a-intent disarm"
- elem
+ elem
name = "CTRL+3"
command = "a-intent grab"
- elem
+ elem
name = "CTRL+4"
command = "a-intent harm"
- elem
+ elem
name = "CTRL+A"
command = "KeyDown A"
elem
name = "CTRL+A+UP"
command = "KeyUp A"
- elem
+ elem
name = "CTRL+D"
command = "KeyDown D"
elem
name = "CTRL+D+UP"
command = "KeyUp D"
- elem
+ elem
name = "CTRL+E"
command = "quick-equip"
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
- elem
+ elem
name = "CTRL+Q"
command = ".northwest"
- elem
+ elem
name = "CTRL+R"
command = ".southwest"
- elem
+ elem
name = "CTRL+S"
command = "KeyDown S"
elem
name = "CTRL+S+UP"
command = "KeyUp S"
- elem
+ elem
name = "CTRL+W"
command = "KeyDown W"
elem
name = "CTRL+W+UP"
command = "KeyUp W"
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
- elem
+ elem
name = "CTRL+Y"
command = "Activate-Held-Object"
- elem
+ elem
name = "CTRL+Z"
command = "Activate-Held-Object"
- elem
+ elem
name = "CTRL+U"
command = "Rest"
- elem
+ elem
name = "CTRL+B"
command = "Resist"
- elem
+ elem
name = "CTRL+NUMPAD1"
command = "body-r-leg"
- elem
+ elem
name = "CTRL+NUMPAD2"
command = "body-groin"
- elem
+ elem
name = "CTRL+NUMPAD3"
command = "body-l-leg"
- elem
+ elem
name = "CTRL+NUMPAD4"
command = "body-r-arm"
- elem
+ elem
name = "CTRL+NUMPAD5"
command = "body-chest"
- elem
+ elem
name = "CTRL+NUMPAD6"
command = "body-l-arm"
- elem
+ elem
name = "CTRL+NUMPAD8"
command = "body-toggle-head"
- elem
+ elem
name = "F1"
command = "request-help"
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
- elem
+ elem
name = "F2"
command = "ooc"
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
- elem
+ elem
name = "F3"
command = ".say"
- elem
+ elem
name = "F4"
command = ".me"
- elem
+ elem
name = "F5"
command = "asay"
- elem
+ elem
name = "F6"
command = "Player-Panel-New"
- elem
+ elem
name = "F7"
command = "Admin-PM"
- elem
+ elem
name = "F8"
command = "Invisimin"
- elem
+ elem
name = "F12"
command = "F12"
+ elem
+ name = "CTRL+SHIFT+ADD"
+ command = "planeup"
+ elem
+ name = "CTRL+SHIFT+SUBTRACT"
+ command = "planedown"
macro "hotkeymode"
- elem
+ elem
name = "TAB"
command = ".winset \"mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true\""
- elem
+ elem
name = "Shift"
command = "KeyDown Shift"
elem
@@ -510,58 +522,58 @@ macro "hotkeymode"
elem
name = "Alt+UP"
command = "KeyUp Alt"
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
- elem
+ elem
name = "SOUTHWEST"
command = ".southwest"
- elem
+ elem
name = "NORTHWEST"
command = ".northwest"
- elem
+ elem
name = "ALT+WEST"
command = "westfaceperm"
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
- elem
+ elem
name = "West"
command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
- elem
+ elem
name = "ALT+NORTH"
command = "northfaceperm"
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
- elem
+ elem
name = "North"
command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
- elem
+ elem
name = "ALT+EAST"
command = "eastfaceperm"
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
- elem
+ elem
name = "East"
command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
- elem
+ elem
name = "ALT+SOUTH"
command = "southfaceperm"
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
elem
@@ -573,103 +585,103 @@ macro "hotkeymode"
elem
name = "CTRL+SHIFT+NORTH"
command = "shiftnorth"
- elem
+ elem
name = "CTRL+SHIFT+SOUTH"
command = "shiftsouth"
- elem
+ elem
name = "CTRL+SHIFT+WEST"
command = "shiftwest"
- elem
+ elem
name = "CTRL+SHIFT+EAST"
command = "shifteast"
- elem
+ elem
name = "INSERT"
command = "a-intent right"
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
- elem
+ elem
name = "1"
command = "a-intent help"
- elem
+ elem
name = "CTRL+1"
command = "a-intent help"
- elem
+ elem
name = "2"
command = "a-intent disarm"
- elem
+ elem
name = "CTRL+2"
command = "a-intent disarm"
- elem
+ elem
name = "3"
command = "a-intent grab"
- elem
+ elem
name = "CTRL+3"
command = "a-intent grab"
- elem
+ elem
name = "4"
command = "a-intent harm"
- elem
+ elem
name = "CTRL+4"
command = "a-intent harm"
- elem
+ elem
name = "5"
command = ".me"
- elem
+ elem
name = "6"
command = ".Subtle"
- elem
+ elem
name = "A"
command = "KeyDown A"
elem
name = "A+UP"
command = "KeyUp A"
- elem
+ elem
name = "D"
command = "KeyDown D"
elem
name = "D+UP"
command = "KeyUp D"
- elem
+ elem
name = "E"
command = "quick-equip"
- elem
+ elem
name = "CTRL+E"
command = "quick-equip"
- elem
+ elem
name = "F"
command = "a-intent left"
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
- elem
+ elem
name = "G"
command = "a-intent right"
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
- elem
+ elem
name = "H"
command = "holster"
- elem
+ elem
name = "CTRL+H"
command = "holster"
- elem
+ elem
name = "J"
command = "toggle-gun-mode"
- elem
+ elem
name = "CTRL+J"
command = "toggle-gun-mode"
- elem
+ elem
name = "Q"
command = ".northwest"
- elem
+ elem
name = "CTRL+Q"
command = ".northwest"
- elem
+ elem
name = "R"
command = ".southwest"
- elem
+ elem
name = "CTRL+R"
command = ".southwest"
elem "s_key"
@@ -678,7 +690,7 @@ macro "hotkeymode"
elem
name = "S+UP"
command = "KeyUp S"
- elem
+ elem
name = "T"
command = ".say"
elem "w_key"
@@ -687,90 +699,96 @@ macro "hotkeymode"
elem
name = "W+UP"
command = "KeyUp W"
- elem
+ elem
name = "X"
command = ".northeast"
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
- elem
+ elem
name = "Y"
command = ".Whisper"
- elem
+ elem
name = "CTRL+Y"
command = ".Whisper"
- elem
+ elem
name = "Z"
command = "Activate-Held-Object"
- elem
+ elem
name = "CTRL+Z"
command = "Activate-Held-Object"
- elem
+ elem
name = "U"
command = "Rest"
- elem
+ elem
name = "B"
command = "Resist"
- elem
+ elem
name = "NUMPAD1"
command = "body-r-leg"
- elem
+ elem
name = "NUMPAD2"
command = "body-groin"
- elem
+ elem
name = "NUMPAD3"
command = "body-l-leg"
- elem
+ elem
name = "NUMPAD4"
command = "body-r-arm"
- elem
+ elem
name = "NUMPAD5"
command = "body-chest"
- elem
+ elem
name = "NUMPAD6"
command = "body-l-arm"
- elem
+ elem
name = "NUMPAD8"
command = "body-toggle-head"
- elem
+ elem
name = "F1"
command = "request-help"
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
- elem
+ elem
name = "F2"
command = "ooc"
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
- elem
+ elem
name = "F3"
command = ".say"
- elem
+ elem
name = "F4"
command = ".me"
- elem
+ elem
name = "F5"
command = "asay"
- elem
+ elem
name = "F6"
command = "Player-Panel-New"
- elem
+ elem
name = "F7"
command = "Admin-PM"
- elem
+ elem
name = "F8"
command = "Invisimin"
- elem
+ elem
name = "F12"
command = "F12"
+ elem
+ name = "CTRL+SHIFT+ADD"
+ command = "planeup"
+ elem
+ name = "CTRL+SHIFT+SUBTRACT"
+ command = "planedown"
macro "borgmacro"
- elem
+ elem
name = "TAB"
command = ".winset \"mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0\""
elem
@@ -791,58 +809,58 @@ macro "borgmacro"
elem
name = "Alt+UP"
command = "KeyUp Alt"
- elem
+ elem
name = "NORTHEAST"
command = ".northeast"
- elem
+ elem
name = "SOUTHEAST"
command = ".southeast"
- elem
+ elem
name = "SOUTHWEST"
command = ".southwest"
- elem
+ elem
name = "NORTHWEST"
command = ".northwest"
- elem
+ elem
name = "ALT+WEST"
command = "westfaceperm"
- elem
+ elem
name = "CTRL+WEST"
command = "westface"
- elem
+ elem
name = "West"
command = "KeyDown West"
elem
name = "West+UP"
command = "KeyUp West"
- elem
+ elem
name = "ALT+NORTH"
command = "northfaceperm"
- elem
+ elem
name = "CTRL+NORTH"
command = "northface"
- elem
+ elem
name = "North"
command = "KeyDown North"
elem
name = "North+UP"
command = "KeyUp North"
- elem
+ elem
name = "ALT+EAST"
command = "eastfaceperm"
- elem
+ elem
name = "CTRL+EAST"
command = "eastface"
- elem
+ elem
name = "East"
command = "KeyDown East"
elem
name = "East+UP"
command = "KeyUp East"
- elem
+ elem
name = "ALT+SOUTH"
command = "southfaceperm"
- elem
+ elem
name = "CTRL+SOUTH"
command = "southface"
elem
@@ -854,176 +872,181 @@ macro "borgmacro"
elem
name = "CTRL+SHIFT+NORTH"
command = "shiftnorth"
- elem
+ elem
name = "CTRL+SHIFT+SOUTH"
command = "shiftsouth"
- elem
+ elem
name = "CTRL+SHIFT+WEST"
command = "shiftwest"
- elem
+ elem
name = "CTRL+SHIFT+EAST"
command = "shifteast"
- elem
+ elem
name = "INSERT"
command = "a-intent right"
- elem
+ elem
name = "DELETE"
command = "delete-key-pressed"
- elem
+ elem
name = "CTRL+1"
command = "toggle-module 1"
- elem
+ elem
name = "CTRL+2"
command = "toggle-module 2"
- elem
+ elem
name = "CTRL+3"
command = "toggle-module 3"
- elem
+ elem
name = "CTRL+4"
command = "a-intent left"
- elem
+ elem
name = "CTRL+A"
command = "KeyDown A"
elem
name = "CTRL+A+UP"
command = "KeyUp A"
- elem
+ elem
name = "CTRL+D"
command = "KeyDown D"
elem
name = "CTRL+D+UP"
command = "KeyUp D"
- elem
+ elem
name = "CTRL+F"
command = "a-intent left"
- elem
+ elem
name = "CTRL+G"
command = "a-intent right"
- elem
+ elem
name = "CTRL+Q"
command = ".northwest"
- elem
+ elem
name = "CTRL+R"
command = ".southwest"
- elem
+ elem
name = "CTRL+S"
command = "KeyDown S"
elem
name = "CTRL+S+UP"
command = "KeyUp S"
- elem
+ elem
name = "CTRL+W"
command = "KeyDown W"
elem
name = "CTRL+W+UP"
command = "KeyUp W"
- elem
+ elem
name = "CTRL+X"
command = ".northeast"
- elem
+ elem
name = "CTRL+Y"
command = "Activate-Held-Object"
- elem
+ elem
name = "CTRL+Z"
command = "Activate-Held-Object"
- elem
+ elem
name = "CTRL+U"
command = "Rest"
- elem
+ elem
name = "CTRL+NUMPAD1"
command = "body-r-leg"
- elem
+ elem
name = "CTRL+NUMPAD2"
command = "body-groin"
- elem
+ elem
name = "CTRL+NUMPAD3"
command = "body-l-leg"
- elem
+ elem
name = "CTRL+NUMPAD4"
command = "body-r-arm"
- elem
+ elem
name = "CTRL+NUMPAD5"
command = "body-chest"
- elem
+ elem
name = "CTRL+NUMPAD6"
command = "body-l-arm"
- elem
+ elem
name = "CTRL+NUMPAD8"
command = "body-toggle-head"
- elem
+ elem
name = "F1"
command = "request-help"
- elem
+ elem
name = "CTRL+SHIFT+F1+REP"
command = ".options"
- elem
+ elem
name = "F2"
command = "ooc"
- elem
+ elem
name = "F2+REP"
command = ".screenshot auto"
- elem
+ elem
name = "SHIFT+F2+REP"
command = ".screenshot"
- elem
+ elem
name = "F3"
command = ".say"
- elem
+ elem
name = "F4"
command = ".me"
- elem
+ elem
name = "F5"
command = "asay"
- elem
+ elem
name = "F6"
command = "Player-Panel-New"
- elem
+ elem
name = "F7"
command = "Admin-PM"
- elem
+ elem
name = "F8"
command = "Invisimin"
- elem
+ elem
name = "F12"
command = "F12"
-
+ elem
+ name = "CTRL+SHIFT+ADD"
+ command = "planeup"
+ elem
+ name = "CTRL+SHIFT+SUBTRACT"
+ command = "planedown"
menu "menu"
- elem
+ elem
name = "&File"
command = ""
saved-params = "is-checked"
- elem
+ elem
name = "&Quick screenshot\tF2"
command = ".screenshot auto"
category = "&File"
saved-params = "is-checked"
- elem
+ elem
name = "&Save screenshot as...\tShift+F2"
command = ".screenshot"
category = "&File"
saved-params = "is-checked"
- elem
+ elem
name = "&Reconnect"
command = ".reconnect"
category = "&File"
saved-params = "is-checked"
- elem
+ elem
name = "&Check ping"
command = ".ping"
category = "&File"
saved-params = "is-checked"
- elem
+ elem
name = ""
command = ""
category = "&File"
saved-params = "is-checked"
- elem
+ elem
name = "&Quit"
command = ".quit"
category = "&File"
saved-params = "is-checked"
- elem
+ elem
name = "&Icons"
command = ""
saved-params = "is-checked"
@@ -1070,7 +1093,7 @@ menu "menu"
can-check = true
group = "size"
saved-params = "is-checked"
- elem
+ elem
name = ""
command = ""
category = "&Icons"
@@ -1081,7 +1104,7 @@ menu "menu"
category = "&Icons"
can-check = true
saved-params = "is-checked"
- elem
+ elem
name = "&Scaling"
command = ""
saved-params = "is-checked"
@@ -1106,16 +1129,16 @@ menu "menu"
can-check = true
group = "scale"
saved-params = "is-checked"
- elem
+ elem
name = "&Help"
command = ""
saved-params = "is-checked"
- elem
+ elem
name = "&Admin help\tF1"
command = "request-help"
category = "&Help"
saved-params = "is-checked"
- elem
+ elem
name = "&Hotkeys"
command = "hotkeys-help"
category = "&Help"
@@ -1525,4 +1548,3 @@ window "text_editor"
border = line
saved-params = ""
multi-line = true
-