mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
[MIRROR] Replaces bees and hivelord MOUSE_OPACITY_OPAQUE with a component. (#7955)
* Replaces bees and hivelord MOUSE_OPACITY_OPAQUE with a component. (#61032) I have replaced the mouse opacity setting for bees and hivelord, its brood and legion skulls with a component that adds an almost (has to be 1 alpha to catch the click) invisible underlay to its target that doesn't block the entire turf. The component prevents the underlay from shrinking or expanding above/below certain boundaries when the attached atom transform matrix is vv'd by an admin or if it's a mob being resized. The component can be added to any atom, though there's no common signal for when objects are resized. * Replaces bees and hivelord MOUSE_OPACITY_OPAQUE with a component. Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
@@ -250,6 +250,9 @@
|
||||
///from base of atom/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
||||
#define COMSIG_ATOM_HITBY "atom_hitby"
|
||||
|
||||
///When the transform or an atom is varedited through vv topic.
|
||||
#define COMSIG_ATOM_VV_MODIFY_TRANSFORM "atom_vv_modify_transform"
|
||||
|
||||
//from base of atom/movable/on_enter_storage(): (datum/component/storage/concrete/master_storage)
|
||||
#define COMSIG_STORAGE_ENTERED "storage_entered"
|
||||
//from base of atom/movable/on_exit_storage(): (datum/component/storage/concrete/master_storage)
|
||||
@@ -569,6 +572,9 @@
|
||||
#define COMPONENT_CANT_INTERACT_WIRES (1<<0)
|
||||
#define COMSIG_MOB_EMOTED(emote_key) "mob_emoted_[emote_key]"
|
||||
|
||||
///from base of mob/update_transform()
|
||||
#define COMSIG_LIVING_POST_UPDATE_TRANSFORM "living_post_update_transform"
|
||||
|
||||
///from /obj/structure/door/crush(): (mob/living/crushed, /obj/machinery/door/crushing_door)
|
||||
#define COMSIG_LIVING_DOORCRUSHED "living_doorcrush"
|
||||
///from base of mob/living/resist() (/mob/living)
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#define CLICKBOX_LAYER FLOAT_LAYER-999
|
||||
|
||||
/**
|
||||
* This component adds a near-invisible underlay to a movable target to expand the clickable surface of its icon without
|
||||
* resorting to MOUSE_OPACITY_OPAQUE.
|
||||
* The underlay ignores the parent's color and alpha and can be offset.
|
||||
* The name is a portmanteau of "click" and "hitbox", because technically this isn't an hitbox,
|
||||
* but it helps catch clicks, and I don't want to give it a loooong name like openspace_item_click_handler
|
||||
*/
|
||||
/datum/component/clickbox
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
/// The icon state of the underlay.
|
||||
var/icon_state = "sphere"
|
||||
/// The offsets of the underlay.
|
||||
var/x_offset = 0
|
||||
var/y_offset = 0
|
||||
/// Maximum width/height of the underlay, in case the attached atom is scaled up.
|
||||
var/max_scale = 2
|
||||
/// Minimum width/height of the underlay, in case the attached atom is scaled down.
|
||||
var/min_scale = 0.5
|
||||
/// For simple animals that have different icon states when dead.
|
||||
var/dead_state
|
||||
/// the underlay that has been added to the parent.
|
||||
var/mutable_appearance/clickbox_undelay
|
||||
|
||||
/datum/component/clickbox/Initialize(icon_state = "sphere", x_offset = 0, y_offset = 0, max_scale = 2, min_scale = 0.5, dead_state)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
src.icon_state = icon_state
|
||||
src.x_offset = x_offset
|
||||
src.y_offset = y_offset
|
||||
src.max_scale = max_scale
|
||||
src.min_scale = min_scale
|
||||
|
||||
RegisterSignal(parent, COMSIG_ATOM_VV_MODIFY_TRANSFORM, .proc/on_modify_or_update_transform)
|
||||
|
||||
var/clickbox_icon_state = icon_state
|
||||
if(dead_state && isliving(parent))
|
||||
var/mob/living/living_parent = parent
|
||||
src.dead_state = dead_state
|
||||
RegisterSignal(living_parent, COMSIG_LIVING_POST_UPDATE_TRANSFORM, .proc/on_modify_or_update_transform)
|
||||
RegisterSignal(living_parent, COMSIG_LIVING_DEATH, .proc/on_death)
|
||||
RegisterSignal(living_parent, COMSIG_LIVING_REVIVE, .proc/on_revive)
|
||||
if(living_parent.stat == DEAD)
|
||||
clickbox_icon_state = dead_state
|
||||
update_underlay(clickbox_icon_state)
|
||||
|
||||
/datum/component/clickbox/UnregisterFromParent()
|
||||
var/atom/movable/mov_parent = parent
|
||||
UnregisterSignal(mov_parent, list(COMSIG_ATOM_VV_MODIFY_TRANSFORM, COMSIG_LIVING_POST_UPDATE_TRANSFORM, COMSIG_LIVING_DEATH, COMSIG_LIVING_REVIVE))
|
||||
mov_parent.underlays -= clickbox_undelay
|
||||
|
||||
/// Removes the old underlay and adds a new one if conditions are met. The underlay is scaled up/down if necessary
|
||||
/datum/component/clickbox/proc/update_underlay(clickbox_icon_state)
|
||||
var/atom/movable/mov_parent = parent
|
||||
if(!clickbox_icon_state)
|
||||
clickbox_icon_state = clickbox_undelay?.icon_state || icon_state
|
||||
mov_parent.underlays -= clickbox_undelay // Remove the previous underlay.
|
||||
|
||||
var/width = abs(mov_parent.transform.a) // Negative values flip the parent, so abs() is good to have here.
|
||||
var/height = abs(mov_parent.transform.e) // Idem.
|
||||
|
||||
var/clickbox_width = 1
|
||||
if(width > max_scale)
|
||||
clickbox_width = max_scale/width
|
||||
else if(width < min_scale && width)
|
||||
clickbox_width = min_scale/width
|
||||
|
||||
var/clickbox_height = 1
|
||||
if(height > max_scale)
|
||||
clickbox_height = max_scale/height
|
||||
else if(height < min_scale && height)
|
||||
clickbox_height = min_scale/height
|
||||
|
||||
clickbox_undelay = mutable_appearance('icons/misc/clickbox.dmi', clickbox_icon_state, CLICKBOX_LAYER, alpha = 1, appearance_flags = RESET_COLOR|RESET_ALPHA)
|
||||
clickbox_undelay.transform = clickbox_undelay.transform.Scale(clickbox_width, clickbox_height)
|
||||
//Keeps the underlay more or less centered.
|
||||
clickbox_undelay.pixel_x = x_offset * 1/clickbox_width
|
||||
clickbox_undelay.pixel_y = y_offset * 1/clickbox_height
|
||||
mov_parent.underlays += clickbox_undelay
|
||||
|
||||
/datum/component/clickbox/proc/on_modify_or_update_transform(atom/source)
|
||||
SIGNAL_HANDLER
|
||||
update_underlay()
|
||||
|
||||
/datum/component/clickbox/proc/on_death(mob/living/source)
|
||||
SIGNAL_HANDLER
|
||||
update_underlay(dead_state)
|
||||
|
||||
/datum/component/clickbox/proc/on_revive(mob/living/source)
|
||||
SIGNAL_HANDLER
|
||||
update_underlay(icon_state)
|
||||
|
||||
#undef CLICKBOX_LAYER
|
||||
+13
-6
@@ -1276,21 +1276,28 @@
|
||||
if(href_list[VV_HK_MODIFY_TRANSFORM] && check_rights(R_VAREDIT))
|
||||
var/result = input(usr, "Choose the transformation to apply","Transform Mod") as null|anything in list("Scale","Translate","Rotate")
|
||||
var/matrix/M = transform
|
||||
if(!result)
|
||||
return
|
||||
switch(result)
|
||||
if("Scale")
|
||||
var/x = input(usr, "Choose x mod","Transform Mod") as null|num
|
||||
var/y = input(usr, "Choose y mod","Transform Mod") as null|num
|
||||
if(!isnull(x) && !isnull(y))
|
||||
transform = M.Scale(x,y)
|
||||
if(isnull(x) || isnull(y))
|
||||
return
|
||||
transform = M.Scale(x,y)
|
||||
if("Translate")
|
||||
var/x = input(usr, "Choose x mod (negative = left, positive = right)","Transform Mod") as null|num
|
||||
var/y = input(usr, "Choose y mod (negative = down, positive = up)","Transform Mod") as null|num
|
||||
if(!isnull(x) && !isnull(y))
|
||||
transform = M.Translate(x,y)
|
||||
if(isnull(x) || isnull(y))
|
||||
return
|
||||
transform = M.Translate(x,y)
|
||||
if("Rotate")
|
||||
var/angle = input(usr, "Choose angle to rotate","Transform Mod") as null|num
|
||||
if(!isnull(angle))
|
||||
transform = M.Turn(angle)
|
||||
if(isnull(angle))
|
||||
return
|
||||
transform = M.Turn(angle)
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_VV_MODIFY_TRANSFORM)
|
||||
|
||||
if(href_list[VV_HK_AUTO_RENAME] && check_rights(R_VAREDIT))
|
||||
var/newname = input(usr, "What do you want to rename this to?", "Automatic Rename") as null|text
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
// update_icons() //Handled in update_transform(), leaving this here as a reminder
|
||||
update_transform()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that.
|
||||
/mob/living/carbon/alien/humanoid/perform_update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that.
|
||||
. = ..()
|
||||
update_icons()
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
else
|
||||
icon_state = "larva[state]"
|
||||
|
||||
/mob/living/carbon/alien/larva/update_transform() //All this is handled in update_icons()
|
||||
..()
|
||||
return update_icons()
|
||||
/mob/living/carbon/alien/larva/perform_update_transform() //All this is handled in update_icons()
|
||||
. = ..()
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/larva/update_inv_handcuffed()
|
||||
update_icons() //larva icon_state changes if cuffed/uncuffed.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
|
||||
/mob/living/carbon/update_transform()
|
||||
/mob/living/carbon/perform_update_transform()
|
||||
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
||||
var/final_pixel_y = pixel_y
|
||||
var/final_dir = dir
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
/// Called whenever the mob is to be resized or when lying/standing up for carbons.
|
||||
/mob/living/update_transform()
|
||||
perform_update_transform() // carbon mobs do it differently than silicons and simple animals.
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_POST_UPDATE_TRANSFORM) // ...and we want the signal to be sent last.
|
||||
|
||||
/mob/living/proc/perform_update_transform()
|
||||
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
||||
var/changed = FALSE
|
||||
|
||||
if(resize != RESIZE_DEFAULT_SIZE)
|
||||
changed = TRUE
|
||||
ntransform.Scale(resize)
|
||||
resize = RESIZE_DEFAULT_SIZE
|
||||
|
||||
if(changed)
|
||||
animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT)
|
||||
@@ -391,18 +391,6 @@
|
||||
if (aicamera)
|
||||
return aicamera.selectpicture(user)
|
||||
|
||||
/mob/living/silicon/update_transform()
|
||||
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
||||
var/changed = 0
|
||||
if(resize != RESIZE_DEFAULT_SIZE)
|
||||
changed++
|
||||
ntransform.Scale(resize)
|
||||
resize = RESIZE_DEFAULT_SIZE
|
||||
|
||||
if(changed)
|
||||
animate(src, transform = ntransform, time = 2,easing = EASE_IN|EASE_OUT)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/is_literate()
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
move_to_delay = 0
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
density = FALSE
|
||||
mob_size = MOB_SIZE_TINY
|
||||
@@ -65,6 +64,7 @@
|
||||
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
||||
generate_bee_visuals()
|
||||
AddElement(/datum/element/simple_flying)
|
||||
AddComponent(/datum/component/clickbox, x_offset = -2, y_offset = -2)
|
||||
AddComponent(/datum/component/swarming)
|
||||
|
||||
/mob/living/simple_animal/hostile/bee/mob_pickup(mob/living/L)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
icon_dead = "Hivelord_dead"
|
||||
icon_gib = "syndicate_gib"
|
||||
mob_biotypes = MOB_ORGANIC
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
move_to_delay = 14
|
||||
ranged = 1
|
||||
vision_range = 5
|
||||
@@ -33,6 +32,12 @@
|
||||
pass_flags = PASSTABLE
|
||||
loot = list(/obj/item/organ/regenerative_core)
|
||||
var/brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood
|
||||
var/has_clickbox = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/Initialize()
|
||||
. = ..()
|
||||
if(has_clickbox)
|
||||
AddComponent(/datum/component/clickbox, icon_state = "hivelord", max_scale = INFINITY, dead_state = "hivelord_dead") //they writhe so much.
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/OpenFire(the_target)
|
||||
if(world.time >= ranged_cooldown)
|
||||
@@ -65,7 +70,6 @@
|
||||
icon_aggro = "Hivelordbrood"
|
||||
icon_dead = "Hivelordbrood"
|
||||
icon_gib = "syndicate_gib"
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
move_to_delay = 1
|
||||
friendly_verb_continuous = "buzzes near"
|
||||
friendly_verb_simple = "buzz near"
|
||||
@@ -87,12 +91,15 @@
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
density = FALSE
|
||||
del_on_death = 1
|
||||
var/clickbox_state = "hivelord"
|
||||
var/clickbox_max_scale = INFINITY
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Initialize()
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src, .proc/death), 100)
|
||||
AddElement(/datum/element/simple_flying)
|
||||
AddComponent(/datum/component/swarming)
|
||||
AddComponent(/datum/component/clickbox, icon_state = clickbox_state, max_scale = clickbox_max_scale)
|
||||
|
||||
//Legion
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion
|
||||
@@ -120,6 +127,7 @@
|
||||
del_on_death = 1
|
||||
stat_attack = HARD_CRIT
|
||||
robust_searching = 1
|
||||
has_clickbox = FALSE
|
||||
var/dwarf_mob = FALSE
|
||||
var/mob/living/carbon/human/stored_mob
|
||||
|
||||
@@ -187,9 +195,10 @@
|
||||
del_on_death = TRUE
|
||||
stat_attack = HARD_CRIT
|
||||
robust_searching = 1
|
||||
clickbox_state = "sphere"
|
||||
clickbox_max_scale = 2
|
||||
var/can_infest_dead = FALSE
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life(delta_time = SSMOBS_DT, times_fired)
|
||||
. = ..()
|
||||
if(stat == DEAD || !isturf(loc))
|
||||
|
||||
@@ -553,19 +553,6 @@
|
||||
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, RESTING_TRAIT)
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/update_transform()
|
||||
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
||||
var/changed = FALSE
|
||||
|
||||
if(resize != RESIZE_DEFAULT_SIZE)
|
||||
changed = TRUE
|
||||
ntransform.Scale(resize)
|
||||
resize = RESIZE_DEFAULT_SIZE
|
||||
|
||||
if(changed)
|
||||
animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT)
|
||||
|
||||
/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion
|
||||
toggle_ai(AI_OFF) // To prevent any weirdness.
|
||||
can_have_ai = FALSE
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 345 B |
@@ -566,6 +566,7 @@
|
||||
#include "code\datums\components\butchering.dm"
|
||||
#include "code\datums\components\caltrop.dm"
|
||||
#include "code\datums\components\chasm.dm"
|
||||
#include "code\datums\components\clickbox.dm"
|
||||
#include "code\datums\components\codeword_hearing.dm"
|
||||
#include "code\datums\components\combustible_flooder.dm"
|
||||
#include "code\datums\components\connect_loc_behalf.dm"
|
||||
@@ -2734,6 +2735,7 @@
|
||||
#include "code\modules\mob\living\living_defines.dm"
|
||||
#include "code\modules\mob\living\living_movement.dm"
|
||||
#include "code\modules\mob\living\living_say.dm"
|
||||
#include "code\modules\mob\living\living_update_icons.dm"
|
||||
#include "code\modules\mob\living\login.dm"
|
||||
#include "code\modules\mob\living\logout.dm"
|
||||
#include "code\modules\mob\living\status_procs.dm"
|
||||
|
||||
Reference in New Issue
Block a user