Merge pull request #16096 from SandPoot/actions

Fixes MAJOR (maybe not) issues with actions
This commit is contained in:
deathride58
2024-08-12 17:55:19 -04:00
committed by GitHub
10 changed files with 266 additions and 232 deletions

View File

@@ -29,25 +29,31 @@
return ..()
/atom/movable/screen/movable/action_button/proc/can_use(mob/user)
if (linked_action)
if(isobserver(user))
var/mob/dead/observer/dead_mob = user
if(dead_mob.observetarget) // Observers can only click on action buttons if they're not observing something
return FALSE
if(linked_action)
if(linked_action.viewers[user.hud_used])
return TRUE
return FALSE
else if (isobserver(user))
var/mob/dead/observer/O = user
return !O.observetarget
else
return TRUE
return TRUE
/atom/movable/screen/movable/action_button/Click(location,control,params)
if (!can_use(usr))
return
var/list/modifiers = params2list(params)
if(modifiers["shift"])
if(LAZYACCESS(modifiers, SHIFT_CLICK))
var/datum/hud/our_hud = usr.hud_used
our_hud.position_action(src, SCRN_OBJ_DEFAULT)
return TRUE
var/mob/clicker = usr
if(!clicker.CheckActionCooldown())
return
clicker.DelayNextAction(1)
linked_action.Trigger()
return TRUE
@@ -82,7 +88,7 @@
closeToolTip(usr)
return ..()
/atom/movable/screen/movable/action_button/MouseDrop(over_object)
/atom/movable/screen/movable/action_button/MouseDrop(atom/over_object, mob/user, src_location, over_location, params)
last_hovored_ref = null
if(!can_use(usr))
return
@@ -107,7 +113,6 @@
our_hud.position_action_relative(src, button)
save_position()
return
. = ..()
our_hud.position_action(src, screen_loc)
save_position()
@@ -141,6 +146,12 @@
user.client.prefs.action_buttons_screen_locs -= "[name]_[id]"
user.client.prefs.queue_save_pref(1 SECONDS, TRUE)
/**
* This is a silly proc used in hud code code to determine what icon and icon state we should be using
* for hud elements (such as action buttons) that don't have their own icon and icon state set.
*
* It returns a list, which is pretty much just a struct of info
*/
/datum/hud/proc/get_action_buttons_icons()
. = list()
.["bg_icon"] = ui_style
@@ -153,8 +164,15 @@
var/datum/action/A = X
A.UpdateButtons(status_only)
//This is the proc used to update all the action buttons.
/mob/proc/update_action_buttons(reload_screen)
/**
* This proc handles adding all of the mob's actions to their screen
*
* If you just need to update existing buttons, use [/mob/proc/update_mob_action_buttons]!
*
* Arguments:
* * update_flags - reload_screen - bool, if TRUE, this proc will add the button to the screen of the passed mob as well
*/
/mob/proc/update_action_buttons(reload_screen = FALSE)
if(!hud_used || !client)
return

View File

@@ -5,32 +5,50 @@
#define AB_CHECK_ALIVE 16
/datum/action
/// The name of the action
var/name = "Generic Action"
/// The description of what the action does, shown in button tooltips
var/desc = null
var/atom/target = null
var/check_flags = 0
var/required_mobility_flags = MOBILITY_USE
var/processing = FALSE
var/buttontooltipstyle = ""
var/transparent_when_unavailable = TRUE
/// The target the action is attached to. If the target datum is deleted, the action is as well.
/// Set in New() via the proc link_to(). PLEASE set a target if you're making an action
var/datum/target = null
/// Where any buttons we create should be by default. Accepts screen_loc and location defines
var/default_button_position = SCRN_OBJ_IN_LIST
var/button_icon = 'icons/mob/actions/backgrounds.dmi' //This is the file for the BACKGROUND icon
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND //And this is the state for the background icon
var/icon_icon = 'icons/mob/actions.dmi' //This is the file for the ACTION icon
var/button_icon_state = "default" //And this is the state for the action icon
/// This is who currently owns the action, and most often, this is who is using the action if it is triggered
/// This can be the same as "target" but is not ALWAYS the same - this is set and unset with Grant() and Remove()
var/mob/owner
/// Flags that will determine of the owner / user of the action can... use the action
var/check_flags = NONE
var/required_mobility_flags = MOBILITY_USE
var/processing = FALSE
/// Whether the button becomes transparent when it can't be used, or just reddened
var/transparent_when_unavailable = TRUE
///List of all mobs that are viewing our action button -> A unique movable for them to view.
var/list/viewers = list()
/// The style the button's tooltips appear to be
var/buttontooltipstyle = ""
/// This is the file for the BACKGROUND underlay icon of the button
var/button_icon = 'icons/mob/actions/backgrounds.dmi'
/// This is the icon state state for the BACKGROUND underlay icon of the button
/// (If set to ACTION_BUTTON_DEFAULT_BACKGROUND, uses the hud's default background)
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND
/// This is the file for the icon that appears on the button
var/icon_icon = 'icons/mob/actions.dmi'
/// This is the icon state for the icon that appears on the button
var/button_icon_state = "default"
/datum/action/New(Target)
link_to(Target)
/datum/action/proc/link_to(Target)
target = Target
RegisterSignal(Target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(OnUpdatedIcon))
RegisterSignal(Target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE)
if(isatom(Target))
RegisterSignal(Target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(OnUpdatedIcon))
/datum/action/Destroy()
if(owner)
@@ -39,23 +57,8 @@
QDEL_LIST_ASSOC_VAL(viewers) // Qdel the buttons in the viewers list **NOT THE HUDS**
return ..()
/datum/action/proc/Grant(mob/M)
if(!M)
Remove(owner)
return
if(owner)
if(owner == M)
return
Remove(owner)
owner = M
RegisterSignal(owner, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE)
// Register some signals based on our check_flags
// so that our button icon updates when relevant
if(check_flags & AB_CHECK_CONSCIOUS)
RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(update_status_on_signal))
GiveAction(M)
/// Signal proc that clears any references based on the owner or target deleting
/// If the owner's deleted, we will simply remove from them, but if the target's deleted, we will self-delete
/datum/action/proc/clear_ref(datum/ref)
SIGNAL_HANDLER
if(ref == owner)
@@ -63,23 +66,51 @@
if(ref == target)
qdel(src)
/datum/action/proc/Remove(mob/M)
/datum/action/proc/Grant(mob/grant_to)
if(isnull(grant_to))
Remove(owner)
return
if(grant_to == owner)
return // We already have it
var/mob/previous_owner = owner
owner = grant_to
if(!isnull(previous_owner))
Remove(previous_owner)
RegisterSignal(owner, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE)
// Register some signals based on our check_flags
// so that our button icon updates when relevant
if(check_flags & AB_CHECK_CONSCIOUS)
RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(update_status_on_signal))
GiveAction(grant_to)
/datum/action/proc/Remove(mob/remove_from)
SHOULD_CALL_PARENT(TRUE)
for(var/datum/hud/hud in viewers)
if(!hud.mymob)
continue
HideFrom(hud.mymob)
LAZYREMOVE(M.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared
LAZYREMOVE(remove_from.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared
viewers = list()
if(owner)
UnregisterSignal(owner, list(
COMSIG_PARENT_QDELETING,
COMSIG_MOB_STATCHANGE
))
if(target == owner)
RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref))
if(isnull(owner))
return
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
// Clean up our check_flag signals
UnregisterSignal(owner, list(
COMSIG_MOB_STATCHANGE
))
if(target == owner)
RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref))
if(owner == remove_from)
owner = null
/// Actually triggers the effects of the action.
/// Called when the on-screen button is clicked, for example.
/datum/action/proc/Trigger()
if(!IsAvailable())
return FALSE
@@ -90,6 +121,10 @@
/datum/action/proc/Process()
return
/**
* Whether our action is currently available to use or not
* * silent - If false this is being called to check if we have any messages to show to the owner
*/
/datum/action/proc/IsAvailable(silent = FALSE)
if(!owner)
return FALSE
@@ -104,9 +139,13 @@
return FALSE
if(check_flags & AB_CHECK_LYING)
if(istype(L) && !CHECK_MOBILITY(L, MOBILITY_STAND))
if (!silent)
owner.balloon_alert(owner, "must stand up!")
return FALSE
if(check_flags & AB_CHECK_CONSCIOUS)
if(owner.stat)
if (!silent)
owner.balloon_alert(owner, "unconscious!")
return FALSE
if(check_flags & AB_CHECK_ALIVE)
if(owner.stat == DEAD)
@@ -166,7 +205,8 @@
SIGNAL_HANDLER
UpdateButtons(force = TRUE)
//Give our action button to the player
/// Gives our action to the passed viewer.
/// Puts our action in their actions list and shows them the button.
/datum/action/proc/GiveAction(mob/viewer)
var/datum/hud/our_hud = viewer.hud_used
if(viewers[our_hud]) // Already have a copy of us? go away
@@ -175,7 +215,7 @@
LAZYOR(viewer.actions, src) // Move this in
ShowTo(viewer)
//Adds our action button to the screen of a player
/// Adds our action button to the screen of the passed viewer.
/datum/action/proc/ShowTo(mob/viewer)
var/datum/hud/our_hud = viewer.hud_used
if(!our_hud || viewers[our_hud]) // There's no point in this if you have no hud in the first place
@@ -192,7 +232,7 @@
button.load_position(viewer)
viewer.update_action_buttons()
//Removes our action button from the screen of a player
/// Removes our action from the passed viewer.
/datum/action/proc/HideFrom(mob/viewer)
var/datum/hud/our_hud = viewer.hud_used
var/atom/movable/screen/movable/action_button/button = viewers[our_hud]
@@ -445,7 +485,8 @@
/datum/action/item_action/toggle/New(Target)
..()
name = "Toggle [target.name]"
var/obj/item/item_target = target
name = "Toggle [item_target.name]"
/datum/action/item_action/halt
name = "HALT!"
@@ -473,7 +514,9 @@
/datum/action/item_action/adjust/New(Target)
..()
name = "Adjust [target.name]"
var/obj/item/item_target = target
name = "Adjust [item_target.name]"
/datum/action/item_action/switch_hud
name = "Switch HUD"
@@ -548,21 +591,31 @@
return ..()
/datum/action/item_action/organ_action
name = "Organ Action"
check_flags = AB_CHECK_CONSCIOUS
/datum/action/item_action/organ_action/IsAvailable(silent = FALSE)
var/obj/item/organ/I = target
if(!I.owner)
var/obj/item/organ/attached_organ = target
if(!attached_organ.owner)
return FALSE
return ..()
/datum/action/item_action/organ_action/toggle
name = "Toggle Organ"
/datum/action/item_action/organ_action/toggle/New(Target)
..()
name = "Toggle [target.name]"
var/obj/item/organ/organ_target = target
name = "Toggle [organ_target.name]"
/datum/action/item_action/organ_action/use
name = "Use Organ"
/datum/action/item_action/organ_action/use/New(Target)
..()
name = "Use [target.name]"
var/obj/item/organ/organ_target = target
name = "Use [organ_target.name]"
/datum/action/item_action/cult_dagger
name = "Draw Blood Rune"
@@ -956,20 +1009,8 @@
/datum/action/item_action/storage_gather_mode
name = "Switch gathering mode"
desc = "Switches the gathering mode of a storage object."
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "storage_gather_switch"
/datum/action/item_action/storage_gather_mode/ApplyIcon(atom/movable/screen/movable/action_button/current_button)
. = ..()
var/old_layer = target.layer
var/old_plane = target.plane
target.layer = FLOAT_LAYER //AAAH
target.plane = FLOAT_PLANE //^ what that guy said
current_button.cut_overlays()
current_button.add_overlay(target)
target.layer = old_layer
target.plane = old_plane
current_button.appearance_cache = target.appearance
button_icon = 'icons/mob/actions/actions_items.dmi'
background_icon_state = "storage_gather_switch"
/proc/get_action_of_type(mob/M, action_type)
if(!M.actions || !ispath(action_type, /datum/action))

View File

@@ -204,7 +204,9 @@
check_flags = NONE
/datum/action/item_action/polychromic/ApplyIcon(atom/movable/screen/movable/action_button/current_button, force)
var/matrix/save_matrix = target.transform
target.transform = matrix(0.8, 0, 0, 0, 0.8, 0)
var/atom/polychromic_thing = target
var/matrix/save_matrix = polychromic_thing.transform
polychromic_thing.transform = matrix(0.8, 0, 0, 0, 0.8, 0)
. = ..()
target.transform = save_matrix
polychromic_thing.transform = save_matrix

View File

@@ -3,18 +3,23 @@
desc = "Used to access the various cameras on the station."
icon_screen = "cameras"
icon_keyboard = "security_key"
light_color = LIGHT_COLOR_RED
var/list/z_lock = list() // Lock use to these z levels
var/lock_override = NONE
var/mob/camera/aiEye/remote/eyeobj
var/mob/living/current_user = null
var/list/networks = list("ss13")
var/datum/action/innate/camera_off/off_action = new
var/datum/action/innate/camera_jump/jump_action = new
var/list/actions = list()
/// Should we suppress the user's view?
var/should_supress_view_changes = TRUE
/// Typepath of the action button we use as "off"
/// It's a typepath so subtypes can give it fun new names
var/datum/action/innate/camera_off/off_action = /datum/action/innate/camera_off
/// Typepath for jumping
var/datum/action/innate/camera_jump/jump_action = /datum/action/innate/camera_jump
light_color = LIGHT_COLOR_RED
/// List of all actions to give to a user when they're well, granted actions
var/list/actions = list()
///Should we supress any view changes?
var/should_supress_view_changes = TRUE
/obj/machinery/computer/camera_advanced/Initialize(mapload)
. = ..()
@@ -31,6 +36,11 @@
if(lock_override & CAMERA_LOCK_REEBE)
z_lock |= SSmapping.levels_by_trait(ZTRAIT_REEBE)
if(off_action)
actions += new off_action(src)
if(jump_action)
actions += new jump_action(src)
/obj/machinery/computer/camera_advanced/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
for(var/i in networks)
networks -= i
@@ -47,40 +57,30 @@
eyeobj.origin = src
/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/user)
if(off_action)
off_action.target = user
off_action.Grant(user)
actions += off_action
if(jump_action)
jump_action.target = user
jump_action.Grant(user)
actions += jump_action
for(var/datum/action/to_grant as anything in actions)
to_grant.Grant(user)
/obj/machinery/proc/remove_eye_control(mob/living/user)
CRASH("[type] does not implement ai eye handling")
/obj/machinery/computer/camera_advanced/remove_eye_control(mob/living/user)
if(!user)
if(isnull(user?.client))
return
for(var/V in actions)
var/datum/action/A = V
A.Remove(user)
actions.Cut()
for(var/V in eyeobj.visibleCameraChunks)
var/datum/camerachunk/C = V
C.remove(eyeobj)
if(user.client)
user.reset_perspective(null)
if(eyeobj.visible_icon && user.client)
user.client.images -= eyeobj.user_image
for(var/datum/action/actions_removed as anything in actions)
actions_removed.Remove(user)
for(var/datum/camerachunk/camerachunks_gone as anything in eyeobj.visibleCameraChunks)
camerachunks_gone.remove(eyeobj)
user.reset_perspective(null)
if(eyeobj.visible_icon)
user.client.images -= eyeobj.user_image
user.client.view_size.unsupress()
eyeobj.eye_user = null
user.remote_control = null
current_user = null
user.unset_machine()
user.client.view_size.unsupress()
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE)
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && hasSiliconAccessInArea(user)) || user.eye_blind || user.incapacitated() )
@@ -89,8 +89,7 @@
/obj/machinery/computer/camera_advanced/Destroy()
if(current_user)
current_user.unset_machine()
if(eyeobj)
qdel(eyeobj)
QDEL_NULL(eyeobj)
QDEL_LIST(actions)
return ..()
@@ -153,6 +152,8 @@
return //AIs would need to disable their own camera procs to use the console safely. Bugs happen otherwise.
/obj/machinery/computer/camera_advanced/proc/give_eye_control(mob/user)
if(isnull(user?.client))
return
GrantActions(user)
current_user = user
eyeobj.eye_user = user
@@ -193,16 +194,19 @@
return eye_user.client
return null
/mob/camera/aiEye/remote/setLoc(T)
/mob/camera/aiEye/remote/setLoc(destination)
if(eye_user)
T = get_turf(T)
if (T)
forceMove(T)
destination = get_turf(destination)
if (destination)
abstract_move(destination)
else
moveToNullspace()
update_ai_detect_hud()
if(use_static != USE_STATIC_NONE)
GLOB.cameranet.visibility(src, GetViewerClient(), null, use_static)
if(visible_icon)
if(eye_user.client)
eye_user.client.images -= user_image
@@ -233,12 +237,11 @@
button_icon_state = "camera_off"
/datum/action/innate/camera_off/Activate()
if(!target || !isliving(target))
if(!owner || !isliving(owner))
return
var/mob/living/C = target
var/mob/camera/aiEye/remote/remote_eye = C.remote_control
var/mob/camera/aiEye/remote/remote_eye = owner.remote_control
var/obj/machinery/computer/camera_advanced/console = remote_eye.origin
console.remove_eye_control(target)
console.remove_eye_control(owner)
/datum/action/innate/camera_jump
name = "Jump To Camera"
@@ -246,16 +249,15 @@
button_icon_state = "camera_jump"
/datum/action/innate/camera_jump/Activate()
if(!target || !isliving(target))
if(!owner || !isliving(owner))
return
var/mob/living/C = target
var/mob/camera/aiEye/remote/remote_eye = C.remote_control
var/mob/camera/aiEye/remote/remote_eye = owner.remote_control
var/obj/machinery/computer/camera_advanced/origin = remote_eye.origin
var/list/L = list()
for (var/obj/machinery/camera/cam in GLOB.cameranet.cameras)
if(origin.z_lock.len && !(cam.z in origin.z_lock))
for (var/obj/machinery/camera/cam as anything in GLOB.cameranet.cameras)
if(length(origin.z_lock) && !(cam.z in origin.z_lock))
continue
L.Add(cam)
@@ -265,17 +267,23 @@
for (var/obj/machinery/camera/netcam in L)
var/list/tempnetwork = netcam.network & origin.networks
if (tempnetwork.len)
if (length(tempnetwork))
if(!netcam.c_tag)
continue
T["[netcam.c_tag][netcam.can_use() ? null : " (Deactivated)"]"] = netcam
playsound(origin, 'sound/machines/terminal_prompt.ogg', 25, 0)
playsound(origin, 'sound/machines/terminal_prompt.ogg', 25, FALSE)
var/camera = input("Choose which camera you want to view", "Cameras") as null|anything in T
if(isnull(camera))
return
if(isnull(T[camera]))
return
var/obj/machinery/camera/final = T[camera]
playsound(src, "terminal_type", 25, 0)
playsound(src, "terminal_type", 25, FALSE)
if(final)
playsound(origin, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
playsound(origin, 'sound/machines/terminal_prompt_confirm.ogg', 25, FALSE)
remote_eye.setLoc(get_turf(final))
C.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash/static)
C.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console!
owner.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash/static)
owner.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console!
else
playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0)
playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, FALSE)

View File

@@ -254,7 +254,7 @@
/datum/team/cult
name = "Cult"
var/blood_target
var/atom/blood_target
var/image/blood_target_image
var/blood_target_reset_timer

View File

@@ -363,8 +363,8 @@
addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob, update_action_buttons_icon)), base_cooldown)
C.cult_team.blood_target_image = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER)
C.cult_team.blood_target_image.appearance_flags = RESET_COLOR
C.cult_team.blood_target_image.pixel_x = -target.pixel_x
C.cult_team.blood_target_image.pixel_y = -target.pixel_y
C.cult_team.blood_target_image.pixel_x = -C.cult_team.blood_target.pixel_x
C.cult_team.blood_target_image.pixel_y = -C.cult_team.blood_target.pixel_y
SEND_SOUND(owner, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75))
owner.client.images += C.cult_team.blood_target_image
for(var/datum/mind/B in SSticker.mode.cult)

View File

@@ -212,13 +212,15 @@
UpdateButtons()
/datum/action/item_action/chameleon/change/proc/update_item(obj/item/picked_item)
target.name = initial(picked_item.name)
target.desc = initial(picked_item.desc)
target.icon_state = initial(picked_item.icon_state)
if(isitem(target))
var/obj/item/I = target
var/obj/item/chameleon_item = target
chameleon_item.name = initial(picked_item.name)
chameleon_item.desc = initial(picked_item.desc)
chameleon_item.icon_state = initial(picked_item.icon_state)
if(isitem(chameleon_item))
var/obj/item/I = chameleon_item
I.item_state = initial(picked_item.item_state)
var/obj/item/clothing/CL = target
var/obj/item/clothing/CL = chameleon_item
var/obj/item/clothing/PCL = new picked_item
if(istype(CL) && istype(PCL))
CL.flags_cover = PCL.flags_cover
@@ -226,7 +228,7 @@
CL.mutantrace_variation = PCL.mutantrace_variation
CL.mob_overlay_icon = PCL.mob_overlay_icon
qdel(PCL)
target.icon = initial(picked_item.icon)
chameleon_item.icon = initial(picked_item.icon)
/datum/action/item_action/chameleon/change/pda/update_item(obj/item/pda/picked_item)
if(!istype(target, /obj/item/pda))

View File

@@ -39,15 +39,15 @@
networks = list("ss13")
var/obj/item/construction/rcd/internal/RCD //Internal RCD. The computer passes user commands to this in order to avoid massive copypaste.
circuit = /obj/item/circuitboard/computer/base_construction
off_action = new/datum/action/innate/camera_off/base_construction
off_action = /datum/action/innate/camera_off/base_construction
jump_action = null
var/datum/action/innate/aux_base/switch_mode/switch_mode_action = new //Action for switching the RCD's build modes
var/datum/action/innate/aux_base/build/build_action = new //Action for using the RCD
var/datum/action/innate/aux_base/airlock_type/airlock_mode_action = new //Action for setting the airlock type
var/datum/action/innate/aux_base/window_type/window_action = new //Action for setting the window type
var/datum/action/innate/aux_base/place_fan/fan_action = new //Action for spawning fans
var/datum/action/innate/aux_base/switch_mode/switch_mode_action = /datum/action/innate/aux_base/switch_mode //Action for switching the RCD's build modes
var/datum/action/innate/aux_base/build/build_action = /datum/action/innate/aux_base/build //Action for using the RCD
var/datum/action/innate/aux_base/airlock_type/airlock_mode_action = /datum/action/innate/aux_base/airlock_type //Action for setting the airlock type
var/datum/action/innate/aux_base/window_type/window_action = /datum/action/innate/aux_base/window_type //Action for setting the window type
var/datum/action/innate/aux_base/place_fan/fan_action = /datum/action/innate/aux_base/place_fan //Action for spawning fans
var/fans_remaining = 0 //Number of fans in stock.
var/datum/action/innate/aux_base/install_turret/turret_action = new //Action for spawning turrets
var/datum/action/innate/aux_base/install_turret/turret_action = /datum/action/innate/aux_base/install_turret //Action for spawning turrets
var/turret_stock = 0 //Turrets in stock
var/obj/machinery/computer/auxillary_base/found_aux_console //Tracker for the Aux base console, so the eye can always find it.
@@ -58,6 +58,9 @@
/obj/machinery/computer/camera_advanced/base_construction/Initialize(mapload)
. = ..()
populate_actions_list()
RCD = new(src)
RCD.console = src
if(mapload) //Map spawned consoles have a filled RCD and stocked special structures
@@ -65,6 +68,20 @@
fans_remaining = 4
turret_stock = 4
/**
* Fill the construction_actios list with actions
*
* Instantiate each action object that we'll be giving to users of
* this console, and put it in the actions list
*/
/obj/machinery/computer/camera_advanced/base_construction/proc/populate_actions_list()
actions += new switch_mode_action(src)
actions += new build_action(src)
actions += new airlock_mode_action(src)
actions += new window_action(src)
actions += new fan_action(src)
actions += new turret_action(src)
/obj/machinery/computer/camera_advanced/base_construction/CreateEye()
var/spawn_spot
@@ -94,43 +111,12 @@
return ..()
/obj/machinery/computer/camera_advanced/base_construction/GrantActions(mob/living/user)
..()
if(switch_mode_action)
switch_mode_action.target = src
switch_mode_action.Grant(user)
actions += switch_mode_action
if(build_action)
build_action.target = src
build_action.Grant(user)
actions += build_action
if(airlock_mode_action)
airlock_mode_action.target = src
airlock_mode_action.Grant(user)
actions += airlock_mode_action
if(window_action)
window_action.target = src
window_action.Grant(user)
actions += window_action
if(fan_action)
fan_action.target = src
fan_action.Grant(user)
actions += fan_action
if(turret_action)
turret_action.target = src
turret_action.Grant(user)
actions += turret_action
eyeobj.invisibility = 0 //When the eye is in use, make it visible to players so they know when someone is building.
return ..()
/obj/machinery/computer/camera_advanced/base_construction/remove_eye_control(mob/living/user)
..()
eyeobj.invisibility = INVISIBILITY_MAXIMUM //Hide the eye when not in use.
return ..()
/datum/action/innate/aux_base //Parent aux base action
icon_icon = 'icons/mob/actions/actions_construction.dmi'

View File

@@ -22,13 +22,13 @@
desc = "A computer used for remotely handling slimes."
networks = list("ss13")
circuit = /obj/item/circuitboard/computer/xenobiology
var/datum/action/innate/slime_place/slime_place_action
var/datum/action/innate/slime_pick_up/slime_up_action
var/datum/action/innate/feed_slime/feed_slime_action
var/datum/action/innate/monkey_recycle/monkey_recycle_action
var/datum/action/innate/slime_scan/scan_action
var/datum/action/innate/feed_potion/potion_action
var/datum/action/innate/hotkey_help/hotkey_help
var/datum/action/innate/slime_place/slime_place_action = /datum/action/innate/slime_place
var/datum/action/innate/slime_pick_up/slime_up_action = /datum/action/innate/slime_pick_up
var/datum/action/innate/feed_slime/feed_slime_action = /datum/action/innate/feed_slime
var/datum/action/innate/monkey_recycle/monkey_recycle_action = /datum/action/innate/monkey_recycle
var/datum/action/innate/slime_scan/scan_action = /datum/action/innate/slime_scan
var/datum/action/innate/feed_potion/potion_action = /datum/action/innate/feed_potion
var/datum/action/innate/hotkey_help/hotkey_help = /datum/action/innate/hotkey_help
var/list/stored_slimes
var/obj/item/slimepotion/slime/current_potion
@@ -43,16 +43,16 @@
/obj/machinery/computer/camera_advanced/xenobio/Initialize(mapload)
. = ..()
slime_place_action = new
slime_up_action = new
feed_slime_action = new
monkey_recycle_action = new
scan_action = new
potion_action = new
hotkey_help = new
generate_actions()
stored_slimes = list()
RegisterSignal(src, COMSIG_ATOM_CONTENTS_DEL, PROC_REF(on_contents_del))
/obj/machinery/computer/camera_advanced/xenobio/proc/generate_actions()
actions += new scan_action(src)
actions += new hotkey_help(src)
/obj/machinery/computer/camera_advanced/xenobio/Destroy()
stored_slimes = null
QDEL_NULL(current_potion)
@@ -72,41 +72,6 @@
/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user)
..()
if(slime_up_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
slime_up_action.target = src
slime_up_action.Grant(user)
actions += slime_up_action
if(slime_place_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
slime_place_action.target = src
slime_place_action.Grant(user)
actions += slime_place_action
if(feed_slime_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
feed_slime_action.target = src
feed_slime_action.Grant(user)
actions += feed_slime_action
if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
monkey_recycle_action.target = src
monkey_recycle_action.Grant(user)
actions += monkey_recycle_action
if(scan_action)
scan_action.target = src
scan_action.Grant(user)
actions += scan_action
if(potion_action && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV
potion_action.target = src
potion_action.Grant(user)
actions += potion_action
if(hotkey_help)
hotkey_help.target = src
hotkey_help.Grant(user)
actions += hotkey_help
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, PROC_REF(XenoSlimeClickCtrl))
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, PROC_REF(XenoSlimeClickAlt))
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, PROC_REF(XenoSlimeClickShift))
@@ -139,10 +104,21 @@
else
upgradetier |= I
successfulupgrade = TRUE
if(I == XENOBIO_UPGRADE_SLIMEBASIC)
actions += new slime_up_action(src)
actions += new slime_place_action(src)
if(I == XENOBIO_UPGRADE_SLIMEADV)
actions += new potion_action(src)
max_slimes = 10
if(I == XENOBIO_UPGRADE_MONKEYS)
actions += new feed_slime_action(src)
actions += new monkey_recycle_action(src)
if(successfulupgrade)
to_chat(user, "<span class='notice'>You have successfully upgraded [src] with [O].</span>")
for(var/datum/action/actions_removed as anything in actions)
actions_removed.Remove(current_user)
GrantActions(current_user)
else
to_chat(user, "<span class='warning'>[src] already has the contents of [O] installed!</span>")
return

View File

@@ -33,10 +33,11 @@
/datum/action/item_action/hands_free/activate_pill/Trigger()
if(!..())
return FALSE
to_chat(owner, "<span class='caution'>You grit your teeth and burst the implanted [target.name]!</span>")
var/obj/item/item_target = target
to_chat(owner, span_notice("You grit your teeth and burst the implanted [item_target.name]!"))
log_combat(owner, null, "swallowed an implanted pill", target)
if(target.reagents.total_volume)
target.reagents.reaction(owner, INGEST)
target.reagents.trans_to(owner, target.reagents.total_volume, log = "dental pill swallow")
if(item_target.reagents.total_volume)
item_target.reagents.reaction(owner, INGEST)
item_target.reagents.trans_to(owner, item_target.reagents.total_volume, log = "dental pill swallow")
qdel(target)
return TRUE