Skip to content

Commit

Permalink
[MIRROR] RPG Loot: Revisited & READY (#2886)
Browse files Browse the repository at this point in the history
* RPG Loot: Revisited & READY

* Update client_procs.dm

---------

Co-authored-by: NovaBot <[email protected]>
Co-authored-by: Jeremiah <[email protected]>
Co-authored-by: SomeRandomOwl <[email protected]>
  • Loading branch information
4 people authored Apr 15, 2024
1 parent cc1c995 commit 416a5b6
Show file tree
Hide file tree
Showing 44 changed files with 876 additions and 256 deletions.
1 change: 1 addition & 0 deletions code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
#define INIT_ORDER_PATH -50
#define INIT_ORDER_DECAY -61 //NOVA EDIT ADDITION
#define INIT_ORDER_EXPLOSIONS -69
#define INIT_ORDER_LOOT -70
#define INIT_ORDER_STATPANELS -97
#define INIT_ORDER_BAN_CACHE -98
#define INIT_ORDER_INIT_PROFILER -99 //Near the end, logs the costs of initialize
Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/traits/declarations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1114,4 +1114,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Trait applied to objects and mobs that can attack a boulder and break it down. (See /obj/item/boulder/manual_process())
#define TRAIT_BOULDER_BREAKER "boulder_breaker"

/// Prevents the affected object from opening a loot window via alt click. See atom/AltClick()
#define TRAIT_ALT_CLICK_BLOCKER "no_alt_click"

// END TRAIT DEFINES
1 change: 1 addition & 0 deletions code/_globalvars/traits/_traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
GLOBAL_LIST_INIT(traits_by_type, list(
/atom = list(
"TRAIT_AI_PAUSED" = TRAIT_AI_PAUSED,
"TRAIT_ALT_CLICK_BLOCKER" = TRAIT_ALT_CLICK_BLOCKER,
"TRAIT_BANNED_FROM_CARGO_SHUTTLE" = TRAIT_BANNED_FROM_CARGO_SHUTTLE,
"TRAIT_BEING_SHOCKED" = TRAIT_BEING_SHOCKED,
"TRAIT_COMMISSIONED" = TRAIT_COMMISSIONED,
Expand Down
44 changes: 32 additions & 12 deletions code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -395,14 +395,40 @@
return
A.AltClick(src)

/**
* Alt click on an atom.
* Performs alt-click actions before attempting to open a loot window.
* Returns TRUE if successful, FALSE if not.
*/
/atom/proc/AltClick(mob/user)
if(!user.can_interact_with(src))
return FALSE

if(SEND_SIGNAL(src, COMSIG_CLICK_ALT, user) & COMPONENT_CANCEL_CLICK_ALT)
return
var/turf/T = get_turf(src)
if(T && (isturf(loc) || isturf(src)) && user.TurfAdjacent(T) && !HAS_TRAIT(user, TRAIT_MOVE_VENTCRAWLING))
user.set_listed_turf(T)
return TRUE

if(HAS_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER) && !isobserver(user))
return TRUE

var/turf/tile = get_turf(src)
if(isnull(tile))
return FALSE

if(!isturf(loc) && !isturf(src))
return FALSE

if(!user.TurfAdjacent(tile))
return FALSE

if(HAS_TRAIT(user, TRAIT_MOVE_VENTCRAWLING))
return FALSE

var/datum/lootpanel/panel = user.client?.loot_panel
if(isnull(panel))
return FALSE

panel.open(tile)
return TRUE

///The base proc of when something is right clicked on when alt is held - generally use alt_click_secondary instead
/atom/proc/alt_click_on_secondary(atom/A)
Expand All @@ -421,14 +447,8 @@
user.client.toggle_tag_datum(src)
return

/// Use this instead of [/mob/proc/AltClickOn] where you only want turf content listing without additional atom alt-click interaction
/atom/proc/AltClickNoInteract(mob/user, atom/A)
var/turf/T = get_turf(A)
if(T && user.TurfAdjacent(T))
user.set_listed_turf(T)

/mob/proc/TurfAdjacent(turf/T)
return T.Adjacent(src)
/mob/proc/TurfAdjacent(turf/tile)
return tile.Adjacent(src)

/**
* Control+Shift click
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/observer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
MiddleClickOn(A, params)
return
if(LAZYACCESS(modifiers, ALT_CLICK))
AltClickNoInteract(src, A)
A.AltClick(src)
return
if(LAZYACCESS(modifiers, CTRL_CLICK))
CtrlClickOn(A)
Expand Down
24 changes: 0 additions & 24 deletions code/controllers/subsystem/processing/obj_tab_items.dm

This file was deleted.

183 changes: 0 additions & 183 deletions code/controllers/subsystem/statpanel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,6 @@ SUBSYSTEM_DEF(statpanels)
if(update_actions && num_fires % default_wait == 0)
set_action_tabs(target, target_mob)

// Handle the examined turf of the stat panel, if it's been long enough, or if we've generated new images for it
var/turf/listed_turf = target_mob?.listed_turf
if(listed_turf && num_fires % default_wait == 0)
if(target.stat_tab == listed_turf.name || !(listed_turf.name in target.panel_tabs))
set_turf_examine_tab(target, target_mob)

if(MC_TICK_CHECK)
return

Expand Down Expand Up @@ -185,71 +179,6 @@ SUBSYSTEM_DEF(statpanels)

target.stat_panel.send_message("update_spells", list(spell_tabs = target.spell_tabs, actions = actions))

/datum/controller/subsystem/statpanels/proc/set_turf_examine_tab(client/target, mob/target_mob)
var/list/overrides = list()
for(var/image/target_image as anything in target.images)
if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override)
continue
overrides += target_image.loc

var/list/atoms_to_display = list(target_mob.listed_turf)
for(var/atom/movable/turf_content as anything in target_mob.listed_turf)
if(turf_content.mouse_opacity == MOUSE_OPACITY_TRANSPARENT)
continue
if(turf_content.invisibility > target_mob.see_invisible)
continue
if(turf_content in overrides)
continue
if(turf_content.IsObscured())
continue
atoms_to_display += turf_content

/// Set the atoms we're meant to display
var/datum/object_window_info/obj_window = target.obj_window
obj_window.atoms_to_show = atoms_to_display
START_PROCESSING(SSobj_tab_items, obj_window)
refresh_client_obj_view(target)

/datum/controller/subsystem/statpanels/proc/refresh_client_obj_view(client/refresh)
var/list/turf_items = return_object_images(refresh)
if(!length(turf_items) || !refresh.mob?.listed_turf)
return
refresh.stat_panel.send_message("update_listedturf", turf_items)

#define OBJ_IMAGE_LOADING "statpanels obj loading temporary"
/// Returns all our ready object tab images
/// Returns a list in the form list(list(object_name, object_ref, loaded_image), ...)
/datum/controller/subsystem/statpanels/proc/return_object_images(client/load_from)
// You might be inclined to think that this is a waste of cpu time, since we
// A: Double iterate over atoms in the build case, or
// B: Generate these lists over and over in the refresh case
// It's really not very hot. The hot portion of this code is genuinely mostly in the image generation
// So it's ok to pay a performance cost for cleanliness here

// No turf? go away
if(!load_from.mob?.listed_turf)
return list()
var/datum/object_window_info/obj_window = load_from.obj_window
var/list/already_seen = obj_window.atoms_to_images
var/list/to_make = obj_window.atoms_to_imagify
var/list/turf_items = list()
for(var/atom/turf_item as anything in obj_window.atoms_to_show)
// First, we fill up the list of refs to display
// If we already have one, just use that
var/existing_image = already_seen[turf_item]
if(existing_image == OBJ_IMAGE_LOADING)
continue
// We already have it. Success!
if(existing_image)
turf_items[++turf_items.len] = list("[turf_item.name]", REF(turf_item), existing_image)
continue
// Now, we're gonna queue image generation out of those refs
to_make += turf_item
already_seen[turf_item] = OBJ_IMAGE_LOADING
obj_window.RegisterSignal(turf_item, COMSIG_QDELETING, TYPE_PROC_REF(/datum/object_window_info,viewing_atom_deleted)) // we reset cache if anything in it gets deleted
return turf_items

#undef OBJ_IMAGE_LOADING

/datum/controller/subsystem/statpanels/proc/generate_mc_data()
mc_data = list(
Expand Down Expand Up @@ -291,16 +220,6 @@ SUBSYSTEM_DEF(statpanels)
set_action_tabs(target, target_mob)
return TRUE

// Handle turfs

if(target_mob?.listed_turf)
if(!target_mob.TurfAdjacent(target_mob.listed_turf))
target_mob.set_listed_turf(null)

else if(target.stat_tab == target_mob?.listed_turf.name || !(target_mob?.listed_turf.name in target.panel_tabs))
set_turf_examine_tab(target, target_mob)
return TRUE

if(!target.holder)
return FALSE

Expand All @@ -320,105 +239,3 @@ SUBSYSTEM_DEF(statpanels)

/// Stat panel window declaration
/client/var/datum/tgui_window/stat_panel

/// Datum that holds and tracks info about a client's object window
/// Really only exists because I want to be able to do logic with signals
/// And need a safe place to do the registration
/datum/object_window_info
/// list of atoms to show to our client via the object tab, at least currently
var/list/atoms_to_show = list()
/// list of atom -> image string for objects we have had in the right click tab
/// this is our caching
var/list/atoms_to_images = list()
/// list of atoms to turn into images for the object tab
var/list/atoms_to_imagify = list()
/// Our owner client
var/client/parent
/// Are we currently tracking a turf?
var/actively_tracking = FALSE

/datum/object_window_info/New(client/parent)
. = ..()
src.parent = parent

/datum/object_window_info/Destroy(force)
atoms_to_show = null
atoms_to_images = null
atoms_to_imagify = null
parent.obj_window = null
parent = null
STOP_PROCESSING(SSobj_tab_items, src)
return ..()

/// Takes a client, attempts to generate object images for it
/// We will update the client with any improvements we make when we're done
/datum/object_window_info/process(seconds_per_tick)
// Cache the datum access for sonic speed
var/list/to_make = atoms_to_imagify
var/list/newly_seen = atoms_to_images
var/index = 0
for(index in 1 to length(to_make))
var/atom/thing = to_make[index]

var/generated_string
if(ismob(thing) || length(thing.overlays) > 2)
generated_string = costly_icon2html(thing, parent, sourceonly=TRUE)
else
generated_string = icon2html(thing, parent, sourceonly=TRUE)

newly_seen[thing] = generated_string
if(TICK_CHECK)
to_make.Cut(1, index + 1)
index = 0
break
// If we've not cut yet, do it now
if(index)
to_make.Cut(1, index + 1)
SSstatpanels.refresh_client_obj_view(parent)
if(!length(to_make))
return PROCESS_KILL

/datum/object_window_info/proc/start_turf_tracking()
if(actively_tracking)
stop_turf_tracking()
var/static/list/connections = list(
COMSIG_MOVABLE_MOVED = PROC_REF(on_mob_move),
COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout),
)
AddComponent(/datum/component/connect_mob_behalf, parent, connections)
actively_tracking = TRUE

/datum/object_window_info/proc/stop_turf_tracking()
qdel(GetComponent(/datum/component/connect_mob_behalf))
actively_tracking = FALSE

/datum/object_window_info/proc/on_mob_move(mob/source)
SIGNAL_HANDLER
var/turf/listed = source.listed_turf
if(!listed || !source.TurfAdjacent(listed))
source.set_listed_turf(null)

/datum/object_window_info/proc/on_mob_logout(mob/source)
SIGNAL_HANDLER
on_mob_move(parent.mob)

/// Clears any cached object window stuff
/// We use hard refs cause we'd need a signal for this anyway. Cleaner this way
/datum/object_window_info/proc/viewing_atom_deleted(atom/deleted)
SIGNAL_HANDLER
atoms_to_show -= deleted
atoms_to_imagify -= deleted
atoms_to_images -= deleted

/mob/proc/set_listed_turf(turf/new_turf)
listed_turf = new_turf
if(!client)
return
if(!client.obj_window)
client.obj_window = new(client)
if(listed_turf)
client.stat_panel.send_message("create_listedturf", listed_turf.name)
client.obj_window.start_turf_tracking()
else
client.stat_panel.send_message("remove_listedturf")
client.obj_window.stop_turf_tracking()
1 change: 1 addition & 0 deletions code/datums/components/gps.dm
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ GLOBAL_LIST_EMPTY(GPS_list)
SIGNAL_HANDLER

toggletracking(user)
return COMPONENT_CANCEL_CLICK_ALT

///Toggles the tracking for the gps
/datum/component/gps/item/proc/toggletracking(mob/user)
Expand Down
4 changes: 4 additions & 0 deletions code/datums/components/rotation.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
RegisterSignal(parent, COMSIG_CLICK_ALT_SECONDARY, PROC_REF(rotate_right))
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(ExamineMessage))
RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item))

ADD_TRAIT(parent, TRAIT_ALT_CLICK_BLOCKER, REF(src))
return ..()

/datum/component/simple_rotation/PostTransfer()
Expand All @@ -41,6 +43,8 @@
COMSIG_ATOM_EXAMINE,
COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM,
))

REMOVE_TRAIT(parent, TRAIT_ALT_CLICK_BLOCKER, REF(src))
return ..()

/datum/component/simple_rotation/Destroy()
Expand Down
1 change: 1 addition & 0 deletions code/game/objects/items/grenades/_grenade.dm
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
/obj/item/grenade/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT, type)
ADD_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER, REF(src))
RegisterSignal(src, COMSIG_ITEM_USED_AS_INGREDIENT, PROC_REF(on_used_as_ingredient))

/obj/item/grenade/suicide_act(mob/living/carbon/user)
Expand Down
28 changes: 28 additions & 0 deletions code/modules/asset_cache/assets/icon_ref_map.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// Maps icon names to ref values
/datum/asset/json/icon_ref_map
name = "icon_ref_map"
early = TRUE

/datum/asset/json/icon_ref_map/generate()
var/list/data = list() //"icons/obj/drinks.dmi" => "[0xc000020]"

//var/start = "0xc000000"
var/value = 0

while(TRUE)
value += 1
var/ref = "\[0xc[num2text(value,6,16)]\]"
var/mystery_meat = locate(ref)

if(isicon(mystery_meat))
if(!isfile(mystery_meat)) // Ignore the runtime icons for now
continue
var/path = get_icon_dmi_path(mystery_meat) //Try to get the icon path
if(path)
data[path] = ref
else if(mystery_meat)
continue; //Some other non-icon resource, ogg/json/whatever
else //Out of resources end this, could also try to end this earlier as soon as runtime generated icons appear but eh
break;

return data
Loading

0 comments on commit 416a5b6

Please sign in to comment.