mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-21 12:04:48 +01:00
Port TG pointing to inventory thought bubble, and expand valid pointing targets (#19072)
* Well that actually works * Update atoms_movable.dm * Now you can point at things inside of things.
This commit is contained in:
@@ -91,6 +91,8 @@
|
||||
/// The render target used by the emissive.
|
||||
#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE"
|
||||
|
||||
#define POINT_PLANE 14
|
||||
|
||||
#define LIGHTING_PLANE 15
|
||||
#define LIGHTING_LAYER 15
|
||||
|
||||
|
||||
@@ -58,10 +58,11 @@
|
||||
#define PREFTOGGLE_2_SIMPLE_STAT_PANEL 2048
|
||||
#define PREFTOGGLE_2_SEE_ITEM_OUTLINES 4096
|
||||
#define PREFTOGGLE_2_HIDE_ITEM_TOOLTIPS 8192
|
||||
#define PREFTOGGLE_2_THOUGHT_BUBBLE 16384
|
||||
|
||||
#define TOGGLES_2_TOTAL 16383 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
#define TOGGLES_2_TOTAL 32767 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
|
||||
#define TOGGLES_2_DEFAULT (PREFTOGGLE_2_FANCYUI|PREFTOGGLE_2_ITEMATTACK|PREFTOGGLE_2_WINDOWFLASHING|PREFTOGGLE_2_RUNECHAT|PREFTOGGLE_2_DEATHMESSAGE|PREFTOGGLE_2_EMOTE_BUBBLE|PREFTOGGLE_2_SEE_ITEM_OUTLINES)
|
||||
#define TOGGLES_2_DEFAULT (PREFTOGGLE_2_FANCYUI|PREFTOGGLE_2_ITEMATTACK|PREFTOGGLE_2_WINDOWFLASHING|PREFTOGGLE_2_RUNECHAT|PREFTOGGLE_2_DEATHMESSAGE|PREFTOGGLE_2_EMOTE_BUBBLE|PREFTOGGLE_2_SEE_ITEM_OUTLINES|PREFTOGGLE_2_THOUGHT_BUBBLE)
|
||||
|
||||
// Sanity checks
|
||||
#if TOGGLES_TOTAL > 16777215
|
||||
|
||||
@@ -49,6 +49,16 @@
|
||||
. = ..()
|
||||
add_filter("emissives", 1, alpha_mask_filter(render_source = EMISSIVE_RENDER_TARGET, flags = MASK_INVERSE))
|
||||
|
||||
/obj/screen/plane_master/point
|
||||
name = "point plane master"
|
||||
plane = POINT_PLANE
|
||||
appearance_flags = PLANE_MASTER //should use client color
|
||||
blend_mode = BLEND_OVERLAY
|
||||
|
||||
/obj/screen/plane_master/point/backdrop(mob/mymob)
|
||||
if(istype(mymob) && mymob.client && mymob.client.prefs)
|
||||
alpha = (mymob.client.prefs.toggles2 & PREFTOGGLE_2_THOUGHT_BUBBLE) ? 255 : 0
|
||||
|
||||
/**
|
||||
* Things placed on this mask the lighting plane. Doesn't render directly.
|
||||
*
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
var/blocks_emissive = FALSE
|
||||
///Internal holder for emissive blocker object, do not use directly use blocks_emissive
|
||||
var/atom/movable/emissive_blocker/em_block
|
||||
/// Icon state for thought bubbles. Normally set by mobs.
|
||||
var/thought_bubble_image = "thought_bubble"
|
||||
|
||||
/atom/movable/attempt_init(loc, ...)
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
if(!the_s_bomb)
|
||||
the_s_bomb = locate()
|
||||
|
||||
/obj/item/pinpointer/proc/point_at(atom/target)
|
||||
/obj/item/pinpointer/proc/point_at_target(atom/target)
|
||||
if(!target)
|
||||
icon_state = icon_null
|
||||
return
|
||||
@@ -130,15 +130,15 @@
|
||||
|
||||
/obj/item/pinpointer/proc/workdisk()
|
||||
scandisk()
|
||||
point_at(the_disk)
|
||||
point_at_target(the_disk)
|
||||
|
||||
/obj/item/pinpointer/proc/workbomb()
|
||||
if(!syndicate)
|
||||
scanbomb()
|
||||
point_at(the_bomb)
|
||||
point_at_target(the_bomb)
|
||||
else
|
||||
scanbomb()
|
||||
point_at(the_s_bomb)
|
||||
point_at_target(the_s_bomb)
|
||||
|
||||
/obj/item/pinpointer/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -161,13 +161,13 @@
|
||||
if(SETTING_DISK)
|
||||
workdisk()
|
||||
if(SETTING_LOCATION)
|
||||
point_at(location)
|
||||
point_at_target(location)
|
||||
if(SETTING_OBJECT)
|
||||
point_at(target)
|
||||
point_at_target(target)
|
||||
|
||||
/obj/item/pinpointer/advpinpointer/workdisk() //since mode works diffrently for advpinpointer
|
||||
scandisk()
|
||||
point_at(the_disk)
|
||||
point_at_target(the_disk)
|
||||
|
||||
/obj/item/pinpointer/advpinpointer/verb/toggle_mode()
|
||||
set category = "Object"
|
||||
@@ -274,7 +274,7 @@
|
||||
visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed
|
||||
return //Get outta here
|
||||
scandisk()
|
||||
point_at(the_disk)
|
||||
point_at_target(the_disk)
|
||||
|
||||
/obj/item/pinpointer/nukeop/workbomb()
|
||||
if(GLOB.bomb_set) //If the bomb is set, lead to the shuttle
|
||||
@@ -284,7 +284,7 @@
|
||||
visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed
|
||||
return //Get outta here
|
||||
scanbomb()
|
||||
point_at(the_s_bomb)
|
||||
point_at_target(the_s_bomb)
|
||||
|
||||
/obj/item/pinpointer/nukeop/proc/worklocation()
|
||||
if(!GLOB.bomb_set)
|
||||
@@ -301,7 +301,7 @@
|
||||
if(loc.z != home.z) //If you are on a different z-level from the shuttle
|
||||
icon_state = icon_null
|
||||
else
|
||||
point_at(home)
|
||||
point_at_target(home)
|
||||
|
||||
/obj/item/pinpointer/operative
|
||||
name = "operative pinpointer"
|
||||
@@ -327,7 +327,7 @@
|
||||
/obj/item/pinpointer/operative/proc/workop()
|
||||
if(mode == MODE_OPERATIVE)
|
||||
scan_for_ops()
|
||||
point_at(nearest_op, FALSE)
|
||||
point_at_target(nearest_op, FALSE)
|
||||
else
|
||||
return FALSE
|
||||
|
||||
@@ -418,9 +418,9 @@
|
||||
|
||||
/obj/item/pinpointer/crew/process()
|
||||
if(mode != MODE_OFF && target_set)
|
||||
point_at(target)
|
||||
point_at_target(target)
|
||||
|
||||
/obj/item/pinpointer/crew/point_at(atom/target)
|
||||
/obj/item/pinpointer/crew/point_at_target(atom/target)
|
||||
if(!target || !trackable(target))
|
||||
icon_state = icon_null
|
||||
return
|
||||
@@ -485,14 +485,14 @@
|
||||
/obj/item/pinpointer/tendril/process()
|
||||
if(mode == MODE_TENDRIL)
|
||||
worktendril()
|
||||
point_at(target, FALSE)
|
||||
point_at_target(target, FALSE)
|
||||
else
|
||||
icon_state = icon_off
|
||||
|
||||
/obj/item/pinpointer/tendril/proc/worktendril()
|
||||
if(mode == MODE_TENDRIL)
|
||||
scan_for_tendrils()
|
||||
point_at(target)
|
||||
point_at_target(target)
|
||||
else
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
/obj/effect/temp_visual/point
|
||||
name = "arrow"
|
||||
desc = "It's an arrow hanging in mid-air. There may be a wizard about."
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "arrow"
|
||||
layer = POINT_LAYER
|
||||
duration = 20
|
||||
randomdir = FALSE
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/bloodsplatter
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
duration = 5
|
||||
|
||||
@@ -963,6 +963,12 @@
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.remake_hud()
|
||||
|
||||
if("thought_bubble")
|
||||
toggles2 ^= PREFTOGGLE_2_THOUGHT_BUBBLE
|
||||
if(length(parent?.screen))
|
||||
var/obj/screen/plane_master/point/PM = locate(/obj/screen/plane_master/point) in parent.screen
|
||||
PM.backdrop(parent.mob)
|
||||
|
||||
if("be_special")
|
||||
var/r = href_list["role"]
|
||||
if(r in GLOB.special_roles)
|
||||
|
||||
@@ -423,6 +423,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
dat += "<b>Play Admin MIDIs:</b> <a href='?_src_=prefs;preference=hear_midis'><b>[(sound & SOUND_MIDI) ? "Yes" : "No"]</b></a><br>"
|
||||
dat += "<b>Play Lobby Music:</b> <a href='?_src_=prefs;preference=lobby_music'><b>[(sound & SOUND_LOBBY) ? "Yes" : "No"]</b></a><br>"
|
||||
dat += "<b>Randomized Character Slot:</b> <a href='?_src_=prefs;preference=randomslot'><b>[toggles2 & PREFTOGGLE_2_RANDOMSLOT ? "Yes" : "No"]</b></a><br>"
|
||||
dat += "<b>Thought Bubble:</b> <a href='?_src_=prefs;preference=thought_bubble'>[(toggles2 & PREFTOGGLE_2_THOUGHT_BUBBLE) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Window Flashing:</b> <a href='?_src_=prefs;preference=winflash'>[(toggles2 & PREFTOGGLE_2_WINDOWFLASHING) ? "Yes" : "No"]</a><br>"
|
||||
// RIGHT SIDE OF THE PAGE
|
||||
dat += "</td><td width='300px' height='300px' valign='top'>"
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
if(istype(owner,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.update_hair()
|
||||
|
||||
owner.thought_bubble_image = initial(owner.thought_bubble_image)
|
||||
. = ..()
|
||||
|
||||
/obj/item/organ/internal/brain/insert(mob/living/target,special = 0)
|
||||
|
||||
@@ -251,15 +251,18 @@
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/obj/item/hand_item = get_active_hand()
|
||||
var/pointed_object = "\the [A]"
|
||||
if(A.loc in src)
|
||||
pointed_object += " inside [A.loc]"
|
||||
if(istype(hand_item, /obj/item/gun) && A != hand_item)
|
||||
if(a_intent == INTENT_HELP || !ismob(A))
|
||||
visible_message("<b>[src]</b> points to [A] with [hand_item]")
|
||||
visible_message("<b>[src]</b> points to [pointed_object] with [hand_item]")
|
||||
return TRUE
|
||||
A.visible_message("<span class='danger'>[src] points [hand_item] at [A]!</span>",
|
||||
A.visible_message("<span class='danger'>[src] points [hand_item] at [pointed_object]!</span>",
|
||||
"<span class='userdanger'>[src] points [hand_item] at you!</span>")
|
||||
SEND_SOUND(A, sound('sound/weapons/targeton.ogg'))
|
||||
return TRUE
|
||||
visible_message("<b>[src]</b> points to [A]")
|
||||
visible_message("<b>[src]</b> points to [pointed_object]")
|
||||
return TRUE
|
||||
|
||||
/mob/living/verb/succumb()
|
||||
|
||||
@@ -609,33 +609,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
var/list/result = A.examine(src)
|
||||
to_chat(src, result.Join("\n"))
|
||||
|
||||
//same as above
|
||||
//note: ghosts can point, this is intended
|
||||
//visible_message will handle invisibility properly
|
||||
//overriden here and in /mob/dead/observer for different point span classes and sanity checks
|
||||
/mob/verb/pointed(atom/A as mob|obj|turf in view())
|
||||
set name = "Point To"
|
||||
set category = "Object"
|
||||
|
||||
if(next_move >= world.time)
|
||||
return
|
||||
if(!isturf(loc) || istype(A, /obj/effect/temp_visual/point) || istype(A, /obj/effect/hallucination))
|
||||
return FALSE
|
||||
|
||||
var/tile = get_turf(A)
|
||||
if(!tile)
|
||||
return FALSE
|
||||
|
||||
changeNext_move(CLICK_CD_POINT)
|
||||
var/obj/P = new /obj/effect/temp_visual/point(tile)
|
||||
P.invisibility = invisibility
|
||||
if(get_turf(src) != tile)
|
||||
// Start off from the pointer and make it slide to the pointee
|
||||
P.pixel_x = (x - A.x) * 32
|
||||
P.pixel_y = (y - A.y) * 32
|
||||
animate(P, 0.5 SECONDS, pixel_x = A.pixel_x, pixel_y = A.pixel_y, easing = QUAD_EASING)
|
||||
return TRUE
|
||||
|
||||
/mob/proc/ret_grab(obj/effect/list_container/mobl/L as obj, flag)
|
||||
if((!( istype(l_hand, /obj/item/grab) ) && !( istype(r_hand, /obj/item/grab) )))
|
||||
if(!( L ))
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#define POINT_TIME (2.5 SECONDS)
|
||||
|
||||
/**
|
||||
* Point at an atom
|
||||
*
|
||||
* Intended to enable and standardise the pointing animation for all atoms
|
||||
*
|
||||
* Not intended as a replacement for the mob verb
|
||||
*/
|
||||
/atom/movable/proc/point_at(atom/pointed_atom)
|
||||
if(!isturf(loc))
|
||||
return
|
||||
|
||||
if((pointed_atom in src) || (pointed_atom.loc in src))
|
||||
create_point_bubble(pointed_atom)
|
||||
return
|
||||
|
||||
var/turf/tile = get_turf(pointed_atom)
|
||||
if(!tile)
|
||||
return
|
||||
|
||||
var/turf/our_tile = get_turf(src)
|
||||
var/obj/visual = new /obj/effect/temp_visual/point(our_tile, invisibility)
|
||||
|
||||
animate(visual, pixel_x = (tile.x - our_tile.x) * world.icon_size + pointed_atom.pixel_x, pixel_y = (tile.y - our_tile.y) * world.icon_size + pointed_atom.pixel_y, time = 1.7, easing = EASE_OUT)
|
||||
|
||||
/atom/movable/proc/create_point_bubble(atom/pointed_atom)
|
||||
var/obj/effect/thought_bubble_effect = new
|
||||
|
||||
var/mutable_appearance/thought_bubble = mutable_appearance(
|
||||
'icons/effects/effects.dmi',
|
||||
thought_bubble_image,
|
||||
layer = POINT_LAYER,
|
||||
appearance_flags = KEEP_APART,
|
||||
)
|
||||
|
||||
var/mutable_appearance/pointed_atom_appearance = new(pointed_atom.appearance)
|
||||
pointed_atom_appearance.blend_mode = BLEND_INSET_OVERLAY
|
||||
pointed_atom_appearance.layer = POINT_LAYER
|
||||
pointed_atom_appearance.pixel_x = 0
|
||||
pointed_atom_appearance.pixel_y = 0
|
||||
thought_bubble.overlays += pointed_atom_appearance
|
||||
|
||||
var/hover_outline_index = pointed_atom.get_filter("hover_outline")
|
||||
if (!isnull(hover_outline_index))
|
||||
pointed_atom_appearance.filters.Cut(hover_outline_index, hover_outline_index + 1)
|
||||
|
||||
thought_bubble.pixel_x = 16
|
||||
thought_bubble.pixel_y = 32
|
||||
thought_bubble.alpha = 200
|
||||
thought_bubble.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
var/mutable_appearance/point_visual = mutable_appearance(
|
||||
'icons/mob/screen_gen.dmi',
|
||||
"arrow",
|
||||
layer = thought_bubble.layer,
|
||||
)
|
||||
|
||||
point_visual.pixel_y = 7
|
||||
thought_bubble.overlays += point_visual
|
||||
thought_bubble.plane = POINT_PLANE
|
||||
|
||||
// vis_contents is used to preserve mouse opacity
|
||||
thought_bubble_effect.appearance = thought_bubble
|
||||
vis_contents += thought_bubble_effect
|
||||
|
||||
QDEL_IN(thought_bubble_effect, 2 SECONDS)
|
||||
|
||||
/obj/effect/temp_visual/point
|
||||
name = "arrow"
|
||||
desc = "It's an arrow hanging in mid-air. There may be a wizard about."
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "arrow"
|
||||
layer = POINT_LAYER
|
||||
duration = 2 SECONDS
|
||||
randomdir = FALSE
|
||||
|
||||
/obj/effect/temp_visual/point/Initialize(mapload, set_invis = 0)
|
||||
. = ..()
|
||||
invisibility = set_invis
|
||||
|
||||
#undef POINT_TIME
|
||||
|
||||
/**
|
||||
* Point at an atom
|
||||
*
|
||||
* mob verbs are faster than object verbs. See
|
||||
* [this byond forum post](https://secure.byond.com/forum/?post=1326139&page=2#comment8198716)
|
||||
* for why this isn't atom/verb/pointed()
|
||||
*
|
||||
* note: ghosts can point, this is intended
|
||||
*
|
||||
* visible_message will handle invisibility properly
|
||||
*
|
||||
* overridden here and in /mob/dead/observer for different point span classes and sanity checks
|
||||
*/
|
||||
/mob/verb/pointed(atom/A as mob|obj|turf in view())
|
||||
set name = "Point To"
|
||||
set category = "Object"
|
||||
|
||||
if(istype(A, /obj/effect/temp_visual/point) || istype(A, /atom/movable/emissive_blocker))
|
||||
return FALSE
|
||||
|
||||
if(A.loc in src) // Object is inside a container on the mob. It's not part of the verb's list since it's not in view and requires middle clicking.
|
||||
point_at(A)
|
||||
return TRUE
|
||||
|
||||
if(client && !(A in view(client.view, src)))
|
||||
return FALSE
|
||||
|
||||
point_at(A)
|
||||
|
||||
return TRUE
|
||||
@@ -15,6 +15,7 @@
|
||||
..()
|
||||
// To supersede the over-writing of the MMI's name from `insert`
|
||||
update_from_mmi()
|
||||
target.thought_bubble_image = "thought_bubble_machine"
|
||||
|
||||
/obj/item/organ/internal/brain/mmi_holder/remove(mob/living/user, special = 0)
|
||||
if(!special)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 391 KiB After Width: | Height: | Size: 392 KiB |
@@ -2251,6 +2251,7 @@
|
||||
#include "code\modules\pda\pdas.dm"
|
||||
#include "code\modules\pda\utilities.dm"
|
||||
#include "code\modules\persistence\persistence.dm"
|
||||
#include "code\modules\point\point.dm"
|
||||
#include "code\modules\power\apc.dm"
|
||||
#include "code\modules\power\cable.dm"
|
||||
#include "code\modules\power\cable_logic.dm"
|
||||
|
||||
Reference in New Issue
Block a user