#define AB_CHECK_RESTRAINED 1 #define AB_CHECK_STUN 2 #define AB_CHECK_LYING 4 #define AB_CHECK_CONSCIOUS 8 /datum/action var/name = "Generic Action" var/desc = null var/obj/target = null var/check_flags = NONE var/processing = FALSE var/atom/movable/screen/movable/action_button/button = null var/buttontooltipstyle = "" var/transparent_when_unavailable = TRUE 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 var/mob/owner var/syndicate = FALSE // are these buttons only for syndicates? var/atom/movable/screen/cooldown_overlay/cooldown_overlay /datum/action/New(Target) link_to(Target) button = new button.linked_action = src button.name = name button.actiontooltipstyle = buttontooltipstyle if(desc) button.desc = desc /datum/action/proc/link_to(Target) target = Target /datum/action/Destroy() if(owner) Remove(owner) target = null qdel(button) button = null return ..() /datum/action/proc/Grant(mob/M) if(M) M.originalactions += src if(owner) if(owner == M) return Remove(owner) owner = M if(syndicate) if(!is_syndicate(M) && !is_clockcult(M)) // if a syndicate check is failed; don't generate button on the hud at all unless you are a clock cultist as well. - Hopek return //button id generation var/counter = 0 var/bitfield = 0 for(var/datum/action/A in M.actions) if(A.name == name && A.button.id) counter += 1 bitfield |= A.button.id bitfield = ~bitfield var/bitflag = 1 for(var/i in 1 to (counter + 1)) if(bitfield & bitflag) button.id = bitflag break bitflag *= 2 M.actions += src if(M.client) M.client.screen += button button.locked = M.client.prefs.buttons_locked || button.id ? M.client.prefs.action_buttons_screen_locs["[name]_[button.id]"] : FALSE //even if it's not defaultly locked we should remember we locked it before button.moved = button.id ? M.client.prefs.action_buttons_screen_locs["[name]_[button.id]"] : FALSE for(var/mob/dead/observer/O in M.observers) O?.client.screen += button M.update_action_buttons() // Now push the owners buttons back else Remove(owner) /datum/action/proc/Remove(mob/M) if(M) if(M.client) M.client.screen -= button for(var/mob/dead/observer/O in M.observers) O?.client.screen -= button M.originalactions -= src M.actions -= src M.update_action_buttons() owner = null button.moved = FALSE //so the button appears in its normal position when given to another owner. button.locked = FALSE button.id = null /datum/action/proc/Trigger() if(!IsAvailable()) return FALSE if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, src) & COMPONENT_ACTION_BLOCK_TRIGGER) return FALSE return TRUE /datum/action/proc/Process() return /datum/action/proc/IsAvailable() if(!owner) return FALSE if(check_flags & AB_CHECK_RESTRAINED) if(owner.restrained()) return FALSE if(check_flags & AB_CHECK_STUN) if(isliving(owner)) var/mob/living/L = owner if(L.IsParalyzed() || L.IsStun()) return FALSE if(check_flags & AB_CHECK_LYING) if(isliving(owner)) var/mob/living/L = owner if(!(L.mobility_flags & MOBILITY_STAND)) return FALSE if(check_flags & AB_CHECK_CONSCIOUS) if(owner.stat) return FALSE return TRUE /datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE) if(button) if(!status_only) button.name = name button.desc = desc if(owner && owner.hud_used && background_icon_state == ACTION_BUTTON_DEFAULT_BACKGROUND) var/list/settings = owner.hud_used.get_action_buttons_icons() if(button.icon != settings["bg_icon"]) button.icon = settings["bg_icon"] if(button.icon_state != settings["bg_state"]) button.icon_state = settings["bg_state"] else if(button.icon != button_icon) button.icon = button_icon if(button.icon_state != background_icon_state) button.icon_state = background_icon_state ApplyIcon(button, force) if(!IsAvailable()) button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0) else button.color = rgb(255,255,255,255) return 1 /datum/action/proc/ApplyIcon(atom/movable/screen/movable/action_button/current_button, force = FALSE) if(icon_icon && button_icon_state && ((current_button.button_icon_state != button_icon_state) || force)) current_button.cut_overlays(TRUE) current_button.add_overlay(mutable_appearance(icon_icon, button_icon_state)) current_button.button_icon_state = button_icon_state //Presets for item actions /datum/action/item_action check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING|AB_CHECK_CONSCIOUS button_icon_state = null // If you want to override the normal icon being the item // then change this to an icon state /datum/action/item_action/New(Target) ..() var/obj/item/I = target LAZYINITLIST(I.actions) I.actions += src /datum/action/item_action/Destroy() var/obj/item/I = target I.actions -= src UNSETEMPTY(I.actions) return ..() /datum/action/item_action/Trigger() if(!..()) return 0 if(target) var/obj/item/I = target I.ui_action_click(owner, src) return 1 /datum/action/item_action/ApplyIcon(atom/movable/screen/movable/action_button/current_button, force) if(button_icon && button_icon_state) // If set, use the custom icon that we set instead // of the item appearence ..() else if((target && current_button.appearance_cache != target.appearance) || force) //replace with /ref comparison if this is not valid. var/obj/item/I = target var/old_layer = I.layer var/old_plane = I.plane I.layer = FLOAT_LAYER //AAAH I.plane = FLOAT_PLANE //^ what that guy said current_button.cut_overlays() current_button.add_overlay(I) I.layer = old_layer I.plane = old_plane current_button.appearance_cache = I.appearance /datum/action/item_action/toggle_light name = "Toggle Light" /datum/action/item_action/toggle_laser_sight name = "Toggle Laser Sight" icon_icon = 'icons/obj/guns/attachment.dmi' button_icon_state = "laser_sight" var/obj/item/attachment/laser_sight/att /datum/action/item_action/toggle_laser_sight/Trigger() if(!att) if(istype(target, /obj/item/gun)) var/obj/item/gun/parent_gun = target for(var/obj/item/attachment/A in parent_gun.current_attachments) if(istype(A, /obj/item/attachment/laser_sight)) att = A break att?.toggle_on() UpdateButtonIcon() /datum/action/item_action/toggle_laser_sight/UpdateButtonIcon(status_only = FALSE, force) button_icon_state = "laser_sight[att?.is_on ? "_on" : ""]" ..() /datum/action/item_action/change_laser_sight_color name = "Change Laser Sight Color" icon_icon = 'icons/obj/guns/attachment.dmi' button_icon_state = "laser_sight" var/obj/item/attachment/laser_sight/att /datum/action/item_action/change_laser_sight_color/Trigger() if(!att) if(istype(target, /obj/item/gun)) var/obj/item/gun/H = target for(var/obj/item/attachment/A in H.current_attachments) if(istype(A, /obj/item/attachment/laser_sight)) att = A break if(att && owner) var/C = input(owner, "Select Laser Color", "Select laser color", att.laser_color) as null|color if(!C || QDELETED(att)) return att.laser_color = C UpdateButtonIcon() /datum/action/item_action/change_laser_sight_color/UpdateButtonIcon(status_only = FALSE, force) button_icon_state = "laser_sight[att?.is_on ? "_on" : ""]" ..() /datum/action/item_action/toggle_hood name = "Toggle Hood" /datum/action/item_action/toggle_firemode name = "Toggle Firemode" /datum/action/item_action/toggle_bodycam name = "Toggle Bodycamera" /datum/action/item_action/rcl_col name = "Change Cable Color" icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "rcl_rainbow" /datum/action/item_action/rcl_gui name = "Toggle Fast Wiring Gui" icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "rcl_gui" /datum/action/item_action/startchainsaw name = "Pull The Starting Cord" /datum/action/item_action/charge_hammer name = "Charge the Blast Pads" /datum/action/item_action/charge_hammer/Trigger() var/obj/item/twohanded/vxtvulhammer/V = target if(istype(V)) V.charge_hammer(owner) /datum/action/item_action/toggle_gunlight name = "Toggle Gunlight" /datum/action/item_action/toggle_mode name = "Toggle Mode" /datum/action/item_action/toggle_barrier_spread name = "Toggle Barrier Spread" /datum/action/item_action/equip_unequip_TED_Gun name = "Equip/Unequip TED Gun" /datum/action/item_action/toggle_paddles name = "Toggle Paddles" /datum/action/item_action/set_internals name = "Set Internals" /datum/action/item_action/set_internals/UpdateButtonIcon(status_only = FALSE, force) if(..()) //button available if(iscarbon(owner)) var/mob/living/carbon/C = owner if(target == C.internal) button.icon_state = "template_active" /datum/action/item_action/pick_color name = "Choose A Color" /datum/action/item_action/toggle_mister name = "Toggle Mister" /datum/action/item_action/activate_injector name = "Activate Injector" /datum/action/item_action/toggle_helmet_light name = "Toggle Helmet Light" /datum/action/item_action/toggle_welding_screen name = "Toggle Welding Screen" /datum/action/item_action/toggle_welding_screen/Trigger() var/obj/item/clothing/head/hardhat/weldhat/H = target if(istype(H)) H.toggle_welding_screen(owner) /datum/action/item_action/toggle_headphones name = "Toggle Headphones" desc = "UNTZ UNTZ UNTZ" /datum/action/item_action/toggle_headphones/Trigger() var/obj/item/clothing/ears/headphones/H = target if(istype(H)) H.toggle(owner) /datum/action/item_action/toggle_unfriendly_fire name = "Toggle Friendly Fire \[ON\]" desc = "Toggles if the club's blasts cause friendly fire." icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "vortex_ff_on" /datum/action/item_action/toggle_unfriendly_fire/Trigger() if(..()) UpdateButtonIcon() /datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon(status_only = FALSE, force) if(istype(target, /obj/item/hierophant_club)) var/obj/item/hierophant_club/H = target if(H.friendly_fire_check) button_icon_state = "vortex_ff_off" name = "Toggle Friendly Fire \[OFF\]" else button_icon_state = "vortex_ff_on" name = "Toggle Friendly Fire \[ON\]" ..() /datum/action/item_action/vortex_recall name = "Vortex Recall" desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.
If the beacon is still attached, will detach it." icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "vortex_recall" /datum/action/item_action/vortex_recall/IsAvailable() if(istype(target, /obj/item/hierophant_club)) var/obj/item/hierophant_club/H = target if(H.teleporting) return 0 return ..() /datum/action/item_action/clock icon_icon = 'icons/mob/actions/actions_clockcult.dmi' background_icon_state = "bg_clock" buttontooltipstyle = "clockcult" /datum/action/item_action/clock/IsAvailable() if(!is_servant_of_ratvar(owner)) return 0 return ..() /datum/action/item_action/clock/toggle_visor name = "Create Judicial Marker" desc = "Allows you to create a stunning Judicial Marker at any location in view. Click again to disable." /datum/action/item_action/clock/toggle_visor/IsAvailable() if(!is_servant_of_ratvar(owner)) return 0 if(istype(target, /obj/item/clothing/glasses/judicial_visor)) var/obj/item/clothing/glasses/judicial_visor/V = target if(V.recharging) return 0 return ..() /datum/action/item_action/clock/hierophant name = "Hierophant Network" desc = "Lets you discreetly talk with all other servants. Nearby listeners can hear you whispering, so make sure to do this privately." button_icon_state = "hierophant_slab" /datum/action/item_action/clock/quickbind name = "Quickbind" desc = "If you're seeing this, file a bug report." var/scripture_index = 0 //the index of the scripture we're associated with /datum/action/item_action/toggle_helmet_flashlight name = "Toggle Helmet Flashlight" /datum/action/item_action/toggle_helmet_mode name = "Toggle Helmet Mode" /datum/action/item_action/toggle /datum/action/item_action/toggle/New(Target) ..() name = "Toggle [target.name]" button.name = name /datum/action/item_action/halt name = "HALT!" /datum/action/item_action/toggle_voice_box name = "Toggle Voice Box" /datum/action/item_action/change name = "Change" /datum/action/item_action/hatsky_voiceline name = "Press Voice Button" desc = "Engage the voice box on your Hatsky to hear a classic line from the real Officer Beepsky!" /datum/action/item_action/nano_picket_sign name = "Retext Nano Picket Sign" var/obj/item/picket_sign/S /datum/action/item_action/nano_picket_sign/New(Target) ..() if(istype(Target, /obj/item/picket_sign)) S = Target /datum/action/item_action/nano_picket_sign/Trigger() if(istype(S)) S.retext(owner) /datum/action/item_action/adjust /datum/action/item_action/adjust/New(Target) ..() name = "Adjust [target.name]" button.name = name /datum/action/item_action/switch_hud name = "Switch HUD" /datum/action/item_action/toggle_wings name = "Toggle Wings" /datum/action/item_action/toggle_human_head name = "Toggle Human Head" /datum/action/item_action/toggle_helmet name = "Toggle Helmet" /datum/action/item_action/toggle_jetpack name = "Toggle Jetpack" /datum/action/item_action/jetpack_stabilization name = "Toggle Jetpack Stabilization" /datum/action/item_action/jetpack_stabilization/IsAvailable() var/obj/item/tank/jetpack/J = target if(!istype(J) || !J.on) return 0 return ..() /datum/action/item_action/hands_free check_flags = AB_CHECK_CONSCIOUS /datum/action/item_action/hands_free/activate name = "Activate" /datum/action/item_action/hands_free/shift_nerves name = "Shift Nerves" /datum/action/item_action/explosive_implant check_flags = NONE name = "Activate Explosive Implant" /datum/action/item_action/toggle_research_scanner name = "Toggle Research Scanner" icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "scan_mode" var/active = FALSE /datum/action/item_action/toggle_research_scanner/Trigger() if(IsAvailable()) active = !active if(active) owner.research_scanner++ else owner.research_scanner-- to_chat(owner, span_notice("[target] research scanner has been [active ? "activated" : "deactivated"].")) return 1 /datum/action/item_action/toggle_research_scanner/Remove(mob/M) if(owner && active) owner.research_scanner-- active = FALSE ..() /datum/action/item_action/instrument name = "Use Instrument" desc = "Use the instrument specified" /datum/action/item_action/instrument/Trigger() if(istype(target, /obj/item/instrument)) var/obj/item/instrument/I = target I.interact(usr) return return ..() /datum/action/item_action/organ_action check_flags = AB_CHECK_CONSCIOUS /datum/action/item_action/organ_action/IsAvailable() var/obj/item/organ/I = target if(!I.owner) return 0 return ..() /datum/action/item_action/organ_action/toggle/New(Target) ..() name = "Toggle [target.name]" button.name = name /datum/action/item_action/organ_action/use/New(Target) ..() name = "Use [target.name]" button.name = name /datum/action/item_action/cult_dagger name = "Draw Blood Rune" desc = "Use the ritual dagger to create a powerful blood rune" icon_icon = 'icons/mob/actions/actions_cult.dmi' button_icon_state = "draw" buttontooltipstyle = "cult" background_icon_state = "bg_demon" /datum/action/item_action/cult_dagger/Grant(mob/M) if(iscultist(M)) ..() button.screen_loc = "6:157,4:-2" button.moved = "6:157,4:-2" else Remove(owner) /datum/action/item_action/cult_dagger/Trigger() for(var/obj/item/H in owner.held_items) //In case we were already holding another dagger if(istype(H, /obj/item/melee/cultblade/dagger)) H.attack_self(owner) return var/obj/item/I = target if(owner.can_equip(I, SLOT_HANDS)) owner.temporarilyRemoveItemFromInventory(I) owner.put_in_hands(I) I.attack_self(owner) else if (owner.get_num_arms() <= 0) to_chat(owner, span_warning("You don't have any usable hands!")) else to_chat(owner, span_warning("Your hands are full!")) /datum/action/item_action/agent_box name = "Deploy Box" desc = "Find inner peace, here, in the box." check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS background_icon_state = "bg_agent" icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "deploy_box" var/cooldown = 0 var/obj/structure/closet/cardboard/agent/box /datum/action/item_action/agent_box/Trigger() if(!..()) return FALSE if(QDELETED(box)) if(cooldown < world.time - 100) box = new(owner.drop_location()) owner.forceMove(box) cooldown = world.time owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE) else owner.forceMove(box.drop_location()) owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE) QDEL_NULL(box) /datum/action/item_action/visegrip name = "Vise Grip" desc = "Remotely detonate marked targets. People become rooted for 1 second. Animals become rooted for 6 seconds and take hefty damage." icon_icon = 'icons/effects/effects.dmi' button_icon_state = "leghold" /datum/action/item_action/reach name = "Reach" desc = "Mark those standing on blood for 10 seconds." icon_icon = 'icons/effects/effects.dmi' button_icon_state = "rshield" //Preset for spells /datum/action/spell_action check_flags = NONE background_icon_state = "bg_spell" /datum/action/spell_action/New(Target) ..() var/obj/effect/proc_holder/S = target S.action = src name = S.name desc = S.desc icon_icon = S.action_icon button_icon_state = S.action_icon_state background_icon_state = S.action_background_icon_state button.name = name /datum/action/spell_action/Destroy() var/obj/effect/proc_holder/S = target S.action = null return ..() /datum/action/spell_action/Trigger() if(!..()) return FALSE if(target) var/obj/effect/proc_holder/S = target S.Click() return TRUE /datum/action/spell_action/IsAvailable() if(!target) return FALSE return TRUE /datum/action/spell_action/spell /datum/action/spell_action/spell/IsAvailable() if(!target) return FALSE var/obj/effect/proc_holder/spell/S = target if(owner) return S.can_cast(owner) return FALSE /datum/action/spell_action/alien /datum/action/spell_action/alien/IsAvailable() if(!target) return FALSE var/obj/effect/proc_holder/alien/ab = target if(owner) return ab.cost_check(ab.check_turf,owner,1) return FALSE //Preset for general and toggled actions /datum/action/innate check_flags = NONE var/active = 0 /datum/action/innate/Trigger() if(!..()) return 0 if(!active) Activate() else Deactivate() return 1 /datum/action/innate/proc/Activate() return /datum/action/innate/proc/Deactivate() return //Preset for an action with a cooldown /datum/action/cooldown check_flags = NONE transparent_when_unavailable = FALSE var/cooldown_time = 0 var/next_use_time = 0 /datum/action/cooldown/New() ..() button.maptext = "" button.maptext_x = 8 button.maptext_y = 0 button.maptext_width = 24 button.maptext_height = 12 /datum/action/cooldown/IsAvailable() return next_use_time <= world.time /datum/action/cooldown/proc/StartCooldown() next_use_time = world.time + cooldown_time button.maptext = "[round(cooldown_time/10, 0.1)]" UpdateButtonIcon() START_PROCESSING(SSfastprocess, src) /datum/action/cooldown/process() if(!owner) button.maptext = "" STOP_PROCESSING(SSfastprocess, src) var/timeleft = max(next_use_time - world.time, 0) if(timeleft == 0) button.maptext = "" UpdateButtonIcon() STOP_PROCESSING(SSfastprocess, src) else button.maptext = "[round(timeleft/10, 0.1)]" /datum/action/cooldown/Grant(mob/M) ..() if(owner) UpdateButtonIcon() if(next_use_time > world.time) START_PROCESSING(SSfastprocess, src) //Stickmemes /datum/action/item_action/stickmen name = "Summon Stick Minions" desc = "Allows you to summon faithful stickmen allies to aide you in battle." icon_icon = 'icons/mob/actions/actions_minor_antag.dmi' button_icon_state = "art_summon" //surf_ss13 /datum/action/item_action/bhop name = "Activate Jump Boots" desc = "Activates the jump boot's internal propulsion system, allowing the user to dash over 4-wide gaps." icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "jetboot" /datum/action/item_action/dash name = "Dash" desc = "Momentarily maximizes the jets of the shoes, allowing the user to dash a short distance." icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "thrust" /datum/action/language_menu name = "Language Menu" desc = "Open the language menu to review your languages, their keys, and select your default language." button_icon_state = "language_menu" check_flags = NONE /datum/action/language_menu/Trigger() if(!..()) return FALSE if(ismob(owner)) var/mob/M = owner var/datum/language_holder/H = M.get_language_holder() H.open_language_menu(usr) /datum/action/item_action/wheelys name = "Toggle Wheely-Heel's Wheels" desc = "Pops out or in your wheely-heel's wheels." icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "wheelys" /datum/action/item_action/airshoes name = "Toggle thrust on air shoes." desc = "Switch between walking and hovering." icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "airshoes_a" /datum/action/item_action/kindleKicks name = "Activate Kindle Kicks" desc = "Kick you feet together, activating the lights in your Kindle Kicks." icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "kindleKicks" //Small sprites /datum/action/small_sprite name = "Toggle Giant Sprite" desc = "Others will always see you as giant" icon_icon = 'icons/mob/actions/actions_xeno.dmi' button_icon_state = "smallqueen" background_icon_state = "bg_alien" var/small = FALSE var/small_icon var/small_icon_state /datum/action/small_sprite/queen small_icon = 'icons/mob/alien.dmi' small_icon_state = "alienq" /datum/action/small_sprite/megafauna icon_icon = 'icons/mob/actions/actions_xeno.dmi' button_icon_state = "smallqueen" background_icon_state = "bg_alien" small_icon = 'icons/mob/lavaland/lavaland_monsters.dmi' /datum/action/small_sprite/megafauna/drake small_icon_state = "ash_whelp" /datum/action/small_sprite/megafauna/colossus small_icon_state = "Basilisk" /datum/action/small_sprite/megafauna/stalwart small_icon_state = "Basilisk" /datum/action/small_sprite/megafauna/bubblegum small_icon_state = "goliath2" /datum/action/small_sprite/megafauna/legion small_icon_state = "dwarf_legion" /datum/action/small_sprite/megafauna/spacedragon small_icon = 'icons/mob/carp.dmi' small_icon_state = "carp" /datum/action/small_sprite/Trigger() ..() if(!small) var/image/I = image(icon = small_icon, icon_state = small_icon_state, loc = owner) I.override = TRUE I.pixel_x -= owner.pixel_x I.pixel_y -= owner.pixel_y owner.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic, "smallsprite", I, AA_TARGET_SEE_APPEARANCE | AA_MATCH_TARGET_OVERLAYS) small = TRUE else owner.remove_alt_appearance("smallsprite") small = FALSE /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