mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 16:05:07 +00:00
Refactors how item actions are handled (#89654)
## About The Pull Request This PR tackles our piss-poor item action handling. Currently in order to make an item only have actions when its equipped to a certain slot you need to override a proc, which I've changed by introducing an action_slots variable. I've also cleaned up a ton of action code, and most importantly moved a lot of Trigger effects on items to do_effect, which allows actions to not call ui_action_click or attack_self on an item without bypassing IsAvailible and comsigs that parent Trigger has. This resolves issues like jump boots being usable from your hands, HUDs being toggleable out of your pockets, etc. Also moved a few actions from relying on attack_self to individual handling on their side. This also stops welding masks/hardhats from showing their action while you hold them, this part of the change is just something I thought didn't make much sense - you can use their action by using them in-hand, and flickering on your action bar can be annoying when reshuffling your backpack. Closes #89653 ## Why It's Good For The Game Makes action handling significantly less ass, allows us to avoid code like this ```js /obj/item/clothing/mask/gas/sechailer/ui_action_click(mob/user, action) if(istype(action, /datum/action/item_action/halt)) halt() else adjust_visor(user) ```
This commit is contained in:
@@ -27,7 +27,11 @@
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(target)
|
||||
var/obj/item/item_target = target
|
||||
item_target.ui_action_click(owner, src)
|
||||
return do_effect(trigger_flags)
|
||||
|
||||
/datum/action/item_action/proc/do_effect(trigger_flags)
|
||||
if(!target)
|
||||
return FALSE
|
||||
var/obj/item/item_target = target
|
||||
item_target.ui_action_click(owner, src)
|
||||
return TRUE
|
||||
|
||||
@@ -5,3 +5,18 @@
|
||||
..()
|
||||
var/obj/item/item_target = target
|
||||
name = "Adjust [item_target.name]"
|
||||
|
||||
/datum/action/item_action/adjust/do_effect(trigger_flags)
|
||||
if(!isclothing(target))
|
||||
CRASH("adjust_visor action attempted to trigger on a non-clothing atom [target] ([target?.type]) owned by [owner] ([owner?.type]!")
|
||||
var/obj/item/clothing/as_clothing = target
|
||||
as_clothing.adjust_visor(owner)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/adjust_style
|
||||
name = "Adjust Item Style"
|
||||
|
||||
/datum/action/item_action/adjust_style/New(Target)
|
||||
..()
|
||||
var/obj/item/item_target = target
|
||||
name = "Adjust [item_target.name]'s Style"
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
background_icon_state = "bg_demon"
|
||||
overlay_icon_state = "bg_demon_border"
|
||||
|
||||
/datum/action/item_action/berserk_mode/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
/datum/action/item_action/berserk_mode/do_effect(trigger_flags)
|
||||
var/obj/item/clothing/head/hooded/berserker/berserk = target
|
||||
berserk.berserk_mode(owner)
|
||||
return TRUE
|
||||
|
||||
@@ -16,24 +16,25 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/cult_dagger/Trigger(trigger_flags)
|
||||
if(target in owner.held_items)
|
||||
var/obj/item/target_item = target
|
||||
target_item.attack_self(owner)
|
||||
return
|
||||
/datum/action/item_action/cult_dagger/do_effect(trigger_flags)
|
||||
if(!isliving(owner))
|
||||
to_chat(owner, span_warning("You lack the necessary living force for this action."))
|
||||
return FALSE
|
||||
|
||||
var/obj/item/target_item = target
|
||||
var/mob/living/living_owner = owner
|
||||
if(target in owner.held_items)
|
||||
target_item.attack_self(owner)
|
||||
return TRUE
|
||||
|
||||
if(owner.can_equip(target_item, ITEM_SLOT_HANDS))
|
||||
owner.temporarilyRemoveItemFromInventory(target_item)
|
||||
owner.put_in_hands(target_item)
|
||||
target_item.attack_self(owner)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if(!isliving(owner))
|
||||
to_chat(owner, span_warning("You lack the necessary living force for this action."))
|
||||
return
|
||||
|
||||
var/mob/living/living_owner = owner
|
||||
if (living_owner.usable_hands <= 0)
|
||||
to_chat(living_owner, span_warning("You don't have any usable hands!"))
|
||||
else
|
||||
to_chat(living_owner, span_warning("Your hands are full!"))
|
||||
return FALSE
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
COOLDOWN_DECLARE(box_cooldown)
|
||||
|
||||
///Handles opening and closing the box.
|
||||
/datum/action/item_action/agent_box/Trigger(trigger_flags)
|
||||
/datum/action/item_action/agent_box/do_effect(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
@@ -20,13 +20,13 @@
|
||||
var/obj/structure/closet/cardboard/agent/box = owner.loc
|
||||
if(box.open())
|
||||
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
return
|
||||
return FALSE
|
||||
//Box closing from here on out.
|
||||
if(!isturf(owner.loc)) //Don't let the player use this to escape mechs/welded closets.
|
||||
to_chat(owner, span_warning("You need more space to activate this implant!"))
|
||||
return
|
||||
return FALSE
|
||||
if(!COOLDOWN_FINISHED(src, box_cooldown))
|
||||
return
|
||||
return FALSE
|
||||
COOLDOWN_START(src, box_cooldown, 10 SECONDS)
|
||||
var/box = new boxtype(owner.drop_location())
|
||||
owner.forceMove(box)
|
||||
|
||||
@@ -82,16 +82,14 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/toggle_hud
|
||||
/datum/action/item_action/organ_action/toggle_hud
|
||||
name = "Toggle Implant HUD"
|
||||
desc = "Disables your HUD implant's visuals. You can still access examine information."
|
||||
|
||||
/datum/action/item_action/toggle_hud/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
/datum/action/item_action/organ_action/toggle_hud/do_effect(trigger_flags)
|
||||
var/obj/item/organ/cyberimp/eyes/hud/hud_implant = target
|
||||
hud_implant.toggle_hud(owner)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/wheelys
|
||||
name = "Toggle Wheels"
|
||||
@@ -122,12 +120,10 @@
|
||||
name = "Toggle Wearable HUD"
|
||||
desc = "Toggles your wearable HUD. You can still access examine information while it's off."
|
||||
|
||||
/datum/action/item_action/toggle_wearable_hud/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
/datum/action/item_action/toggle_wearable_hud/do_effect(trigger_flags)
|
||||
var/obj/item/clothing/glasses/hud/hud_display = target
|
||||
hud_display.toggle_hud_display(owner)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/toggle_nv
|
||||
name = "Toggle Night Vision"
|
||||
@@ -138,7 +134,7 @@
|
||||
. = ..()
|
||||
target.AddElement(/datum/element/update_icon_updates_onmob)
|
||||
|
||||
/datum/action/item_action/toggle_nv/Trigger(trigger_flags)
|
||||
/datum/action/item_action/toggle_nv/do_effect(trigger_flags)
|
||||
if(!istype(target, /obj/item/clothing/glasses))
|
||||
return ..()
|
||||
var/obj/item/clothing/glasses/goggles = target
|
||||
@@ -162,3 +158,4 @@
|
||||
playsound(goggles, 'sound/machines/click.ogg', 30, TRUE, -3)
|
||||
holder?.update_sight()
|
||||
goggles.update_appearance()
|
||||
return TRUE
|
||||
|
||||
@@ -121,6 +121,8 @@
|
||||
var/list/datum/action/actions
|
||||
///list of paths of action datums to give to the item on New().
|
||||
var/list/actions_types
|
||||
///Slot flags in which this item grants actions. If null, defaults to the item's slot flags (so actions are granted when worn)
|
||||
var/action_slots = null
|
||||
|
||||
//Since any item can now be a piece of clothing, this has to be put here so all items share it.
|
||||
///This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc.
|
||||
@@ -805,6 +807,10 @@
|
||||
/obj/item/proc/item_action_slot_check(slot, mob/user, datum/action/action)
|
||||
if(slot & (ITEM_SLOT_BACKPACK|ITEM_SLOT_LEGCUFFED)) //these aren't true slots, so avoid granting actions there
|
||||
return FALSE
|
||||
if(!isnull(action_slots))
|
||||
return (slot & action_slots)
|
||||
else if (slot_flags)
|
||||
return (slot & slot_flags)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
|
||||
@@ -1619,6 +1619,7 @@
|
||||
trim = /datum/id_trim/chameleon
|
||||
wildcard_slots = WILDCARD_LIMIT_CHAMELEON_PLUS // SKYRAT EDIT - Original WILDCARD_LIMIT_CHAMELEON
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/id, /datum/action/item_action/chameleon/change/id_trim)
|
||||
action_slots = ALL
|
||||
|
||||
/// Have we set a custom name and job assignment, or will we use what we're given when we chameleon change?
|
||||
var/forged = FALSE
|
||||
|
||||
@@ -222,10 +222,6 @@
|
||||
remove_paddles(user)
|
||||
update_power()
|
||||
|
||||
/obj/item/defibrillator/item_action_slot_check(slot, mob/user)
|
||||
if(slot_flags & slot)
|
||||
return TRUE
|
||||
|
||||
/obj/item/defibrillator/proc/remove_paddles(mob/user) //this fox the bug with the paddles when other player stole you the defib when you have the paddles equiped
|
||||
if(ismob(paddles.loc))
|
||||
var/mob/M = paddles.loc
|
||||
@@ -286,10 +282,6 @@
|
||||
nocell_state = "defibcompact-nocell"
|
||||
emagged_state = "defibcompact-emagged"
|
||||
|
||||
/obj/item/defibrillator/compact/item_action_slot_check(slot, mob/user)
|
||||
if(slot & user.getBeltSlot())
|
||||
return TRUE
|
||||
|
||||
/obj/item/defibrillator/compact/loaded/Initialize(mapload)
|
||||
. = ..()
|
||||
cell = new(src)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
custom_materials = list(/datum/material/iron= SMALL_MATERIAL_AMOUNT * 0.5, /datum/material/glass= SMALL_MATERIAL_AMOUNT * 0.2)
|
||||
actions_types = list(/datum/action/item_action/toggle_light)
|
||||
action_slots = ALL
|
||||
light_system = OVERLAY_LIGHT_DIRECTIONAL
|
||||
light_color = COLOR_LIGHT_ORANGE
|
||||
light_range = 4
|
||||
|
||||
@@ -36,10 +36,6 @@
|
||||
/obj/item/clothing/glasses/sunglasses/spy/ui_action_click(mob/user)
|
||||
show_to_user(user)
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/spy/item_action_slot_check(slot)
|
||||
if(slot & ITEM_SLOT_EYES)
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/spy/Destroy()
|
||||
if(linked_bug)
|
||||
linked_bug.linked_glasses = null
|
||||
|
||||
@@ -234,15 +234,12 @@ effective or pretty fucking useless.
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/stealth_mode/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
/datum/action/item_action/stealth_mode/do_effect(trigger_flags)
|
||||
if(stealth_engaged)
|
||||
stealth_off()
|
||||
else
|
||||
stealth_on()
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/stealth_mode/proc/stealth_on()
|
||||
animate(owner, alpha = get_alpha(), time = 0.5 SECONDS)
|
||||
@@ -311,9 +308,6 @@ effective or pretty fucking useless.
|
||||
attack_verb_simple = list("whip", "lash", "discipline")
|
||||
actions_types = list(/datum/action/item_action/stealth_mode)
|
||||
|
||||
/obj/item/shadowcloak/item_action_slot_check(slot, mob/user)
|
||||
return slot & slot_flags
|
||||
|
||||
/obj/item/shadowcloak/weaker
|
||||
name = "stealth belt"
|
||||
desc = "Makes you nigh-invisible to the naked eye for a short period of time. \
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 // We detonate upon being exploded.
|
||||
obj_flags = CONDUCTS_ELECTRICITY
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
action_slots = ALL
|
||||
max_integrity = 40
|
||||
pickup_sound = 'sound/items/handling/grenade/grenade_pick_up.ogg'
|
||||
drop_sound = 'sound/items/handling/grenade/grenade_drop.ogg'
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
obj_flags = CONDUCTS_ELECTRICITY
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
action_slots = ALL
|
||||
force = 10
|
||||
throwforce = 7
|
||||
demolition_mod = 0.25
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
item_flags = NO_MAT_REDEMPTION | NOBLUDGEON
|
||||
has_ammobar = TRUE
|
||||
actions_types = list(/datum/action/item_action/rcd_scan)
|
||||
action_slots = ALL
|
||||
drop_sound = 'sound/items/handling/tools/rcd_drop.ogg'
|
||||
pickup_sound = 'sound/items/handling/tools/rcd_pickup.ogg'
|
||||
sound_vary = TRUE
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
throw_range = 7
|
||||
resistance_flags = FLAMMABLE
|
||||
actions_types = list(/datum/action/cooldown/spell/teleport/area_teleport/wizard/scroll)
|
||||
action_slots = ITEM_SLOT_HANDS
|
||||
/// Number of uses the scroll gets.
|
||||
var/uses = 4
|
||||
|
||||
@@ -33,9 +34,6 @@
|
||||
to_chat(cast_on, span_warning("[src] runs out of uses and crumbles to dust!"))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/teleportation_scroll/item_action_slot_check(slot, mob/user)
|
||||
return (slot & ITEM_SLOT_HANDS)
|
||||
|
||||
/obj/item/teleportation_scroll/apprentice
|
||||
name = "lesser scroll of teleportation"
|
||||
uses = 1
|
||||
|
||||
@@ -62,11 +62,12 @@
|
||||
/datum/action/item_action/nano_picket_sign
|
||||
name = "Retext Nano Picket Sign"
|
||||
|
||||
/datum/action/item_action/nano_picket_sign/Trigger(trigger_flags)
|
||||
/datum/action/item_action/nano_picket_sign/do_effect(trigger_flags)
|
||||
if(!istype(target, /obj/item/picket_sign))
|
||||
return
|
||||
return FALSE
|
||||
var/obj/item/picket_sign/sign = target
|
||||
sign.retext(owner)
|
||||
return TRUE
|
||||
|
||||
/datum/crafting_recipe/picket_sign
|
||||
name = "Picket Sign"
|
||||
|
||||
@@ -414,6 +414,7 @@
|
||||
icon_state = "duffel"
|
||||
inhand_icon_state = "duffel"
|
||||
actions_types = list(/datum/action/item_action/zipper)
|
||||
action_slots = ALL
|
||||
storage_type = /datum/storage/duffel
|
||||
// How much to slow you down if your bag isn't zipped up
|
||||
var/zip_slowdown = 1
|
||||
|
||||
@@ -668,6 +668,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
actions_types = list(/datum/action/item_action/reload_rebar)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/storage/bag/rebar_quiver/syndicate/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
worn_icon_state = "syndicate_holster"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/belt)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/storage/belt/holster/chameleon/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -63,10 +63,6 @@
|
||||
else
|
||||
REMOVE_TRAIT(user, TRAIT_NOGRAV_ALWAYS_DRIFT, JETPACK_TRAIT)
|
||||
|
||||
/obj/item/tank/jetpack/item_action_slot_check(slot)
|
||||
if(slot & slot_flags)
|
||||
return TRUE
|
||||
|
||||
/obj/item/tank/jetpack/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(on && !(slot & slot_flags))
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
demolition_mod = 1.25
|
||||
custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT*5)
|
||||
actions_types = list(/datum/action/item_action/set_internals)
|
||||
action_slots = ALL
|
||||
armor_type = /datum/armor/item_tank
|
||||
integrity_failure = 0.5
|
||||
/// If we are in the process of exploding, stops multi explosions
|
||||
|
||||
@@ -37,10 +37,6 @@
|
||||
/obj/item/watertank/ui_action_click(mob/user)
|
||||
toggle_mister(user)
|
||||
|
||||
/obj/item/watertank/item_action_slot_check(slot, mob/user)
|
||||
if(slot & user.getBackSlot())
|
||||
return 1
|
||||
|
||||
/obj/item/watertank/proc/toggle_mister(mob/living/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
@@ -409,10 +405,6 @@
|
||||
/obj/item/reagent_containers/chemtank/ui_action_click()
|
||||
toggle_injection()
|
||||
|
||||
/obj/item/reagent_containers/chemtank/item_action_slot_check(slot, mob/user)
|
||||
if(slot & ITEM_SLOT_BACK)
|
||||
return 1
|
||||
|
||||
/obj/item/reagent_containers/chemtank/proc/toggle_injection()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
if(!istype(user))
|
||||
|
||||
@@ -80,10 +80,6 @@
|
||||
human_target.update_worn_oversuit()
|
||||
update_item_action_buttons()
|
||||
|
||||
/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user)
|
||||
if(slot & ITEM_SLOT_OCLOTHING) //we only give the mob the ability to activate the vest if he's actually wearing it.
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/suit/armor/abductor/vest/proc/SetDisguise(datum/icon_snapshot/entry)
|
||||
disguise = entry
|
||||
|
||||
|
||||
@@ -306,6 +306,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
wound_bonus = FALSE
|
||||
|
||||
actions_types = list(/datum/action/item_action/toggle_mode)
|
||||
action_slots = ALL
|
||||
|
||||
cooldown = 0 SECONDS
|
||||
stamina_damage = 0
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/camouflage/Trigger(trigger_flags)
|
||||
/datum/action/item_action/camouflage/do_effect(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
return
|
||||
|
||||
if(cloaking)
|
||||
remove_cloaking()
|
||||
@@ -39,8 +39,6 @@
|
||||
to_chat(owner, span_notice("You activate your camouflage and blend into your surroundings..."))
|
||||
cloaking = TRUE
|
||||
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Returns the owner's alpha value to its initial value,
|
||||
*
|
||||
|
||||
@@ -156,11 +156,7 @@
|
||||
if(!length(target_sword.current_runes))
|
||||
return FALSE
|
||||
|
||||
/datum/action/item_action/rune_shatter/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
/datum/action/item_action/rune_shatter/do_effect(trigger_flags)
|
||||
owner.playsound_local(get_turf(owner), 'sound/effects/magic/blind.ogg', 50, TRUE)
|
||||
var/obj/item/melee/rune_carver/target_sword = target
|
||||
QDEL_LIST(target_sword.current_runes)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "referee whistle"
|
||||
desc = "A referee whistle used to call fouls against players."
|
||||
actions_types = list(/datum/action/innate/timeout)
|
||||
action_slots = ALL
|
||||
|
||||
// should be /datum/action/item_action but it doesn't support InterceptClickOn()
|
||||
/datum/action/innate/timeout
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
if (!active)
|
||||
. += span_warning("It requires a Bioscrambler Anomaly Core in order to function.")
|
||||
|
||||
/obj/item/polymorph_belt/item_action_slot_check(slot, mob/user, datum/action/action)
|
||||
return slot & ITEM_SLOT_BELT
|
||||
|
||||
/obj/item/polymorph_belt/update_icon_state()
|
||||
icon_state = base_icon_state + (active ? "" : "_inactive")
|
||||
worn_icon_state = base_icon_state + (active ? "" : "_inactive")
|
||||
|
||||
@@ -173,10 +173,7 @@
|
||||
else
|
||||
atom_target.icon = initial(picked_item.icon)
|
||||
|
||||
/datum/action/item_action/chameleon/change/Trigger(trigger_flags)
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return FALSE
|
||||
|
||||
/datum/action/item_action/chameleon/change/do_effect(trigger_flags)
|
||||
select_look(owner)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
button_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "random"
|
||||
|
||||
/datum/action/item_action/chameleon/drone/randomise/Trigger(trigger_flags)
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return FALSE
|
||||
|
||||
/datum/action/item_action/chameleon/drone/randomise/do_effect(trigger_flags)
|
||||
for(var/datum/action/item_action/chameleon/change/to_randomize in owner.actions)
|
||||
to_randomize.random_look()
|
||||
return TRUE
|
||||
@@ -28,10 +25,7 @@
|
||||
/datum/action/item_action/chameleon/drone/togglehatmask/IsAvailable(feedback)
|
||||
return ..() && isdrone(owner)
|
||||
|
||||
/datum/action/item_action/chameleon/drone/togglehatmask/Trigger(trigger_flags)
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return FALSE
|
||||
|
||||
/datum/action/item_action/chameleon/drone/togglehatmask/do_effect(trigger_flags)
|
||||
var/mob/living/basic/drone/droney = owner
|
||||
|
||||
// The drone unEquip() proc sets head to null after dropping
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/scanner)
|
||||
action_slots = ALL
|
||||
throw_speed = 3
|
||||
/// Range that we can scan people
|
||||
var/scan_range = 5
|
||||
|
||||
@@ -30,6 +30,7 @@ do { \
|
||||
can_adjust = FALSE
|
||||
armor_type = /datum/armor/clothing_under/chameleon
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/jumpsuit)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/clothing/under/chameleon/broken
|
||||
|
||||
@@ -56,6 +57,7 @@ do { \
|
||||
resistance_flags = NONE
|
||||
armor_type = /datum/armor/suit_chameleon
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/suit)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/clothing/suit/chameleon/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -84,6 +86,7 @@ do { \
|
||||
resistance_flags = NONE
|
||||
armor_type = /datum/armor/glasses_chameleon
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/glasses)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/clothing/glasses/chameleon/broken
|
||||
|
||||
@@ -110,6 +113,7 @@ do { \
|
||||
body_parts_covered = HANDS|ARMS
|
||||
armor_type = /datum/armor/gloves_chameleon
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/gloves)
|
||||
action_slots = ALL
|
||||
clothing_traits = list(TRAIT_FAST_CUFFING)
|
||||
|
||||
/obj/item/clothing/gloves/chameleon/broken
|
||||
@@ -135,6 +139,7 @@ do { \
|
||||
resistance_flags = NONE
|
||||
armor_type = /datum/armor/head_chameleon
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/hat)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/clothing/head/chameleon/broken
|
||||
|
||||
@@ -144,6 +149,7 @@ do { \
|
||||
|
||||
/obj/item/clothing/head/chameleon/drone
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/hat, /datum/action/item_action/chameleon/drone/togglehatmask, /datum/action/item_action/chameleon/drone/randomise)
|
||||
action_slots = ALL
|
||||
item_flags = DROPDEL
|
||||
// The camohat, I mean, holographic hat projection, is part of the drone itself.
|
||||
armor_type = /datum/armor/none
|
||||
@@ -176,6 +182,7 @@ do { \
|
||||
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/mask)
|
||||
action_slots = ALL
|
||||
/// Is our voice changer enabled or disabled?
|
||||
var/voice_change = TRUE
|
||||
|
||||
@@ -191,6 +198,7 @@ do { \
|
||||
|
||||
/obj/item/clothing/mask/chameleon/drone
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/mask, /datum/action/item_action/chameleon/drone/togglehatmask, /datum/action/item_action/chameleon/drone/randomise)
|
||||
action_slots = ALL
|
||||
item_flags = DROPDEL
|
||||
//Same as the drone chameleon hat, undroppable and no protection
|
||||
armor_type = /datum/armor/none
|
||||
@@ -228,6 +236,7 @@ do { \
|
||||
resistance_flags = NONE
|
||||
armor_type = /datum/armor/shoes_chameleon
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/shoes)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/clothing/shoes/chameleon/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -253,6 +262,7 @@ do { \
|
||||
/obj/item/storage/backpack/chameleon
|
||||
name = "backpack"
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/backpack)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/storage/backpack/chameleon/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -269,6 +279,7 @@ do { \
|
||||
name = "toolbelt"
|
||||
desc = "Holds tools."
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/belt)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/storage/belt/chameleon/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -284,6 +295,7 @@ do { \
|
||||
/obj/item/radio/headset/chameleon
|
||||
name = "radio headset"
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/headset)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/radio/headset/chameleon/broken
|
||||
|
||||
@@ -295,6 +307,7 @@ do { \
|
||||
/obj/item/modular_computer/pda/chameleon
|
||||
name = "tablet"
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/tablet)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/modular_computer/pda/chameleon/broken
|
||||
|
||||
@@ -305,6 +318,7 @@ do { \
|
||||
// Cham Stamp
|
||||
/obj/item/stamp/chameleon
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/stamp)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/stamp/chameleon/broken
|
||||
|
||||
@@ -325,6 +339,7 @@ do { \
|
||||
armor_type = /datum/armor/neck_chameleon
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
actions_types = list(/datum/action/item_action/chameleon/change/neck)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/clothing/neck/chameleon/broken
|
||||
|
||||
|
||||
@@ -130,10 +130,6 @@
|
||||
fire = 80
|
||||
acid = 100
|
||||
|
||||
/obj/item/clothing/glasses/science/item_action_slot_check(slot)
|
||||
if(slot & ITEM_SLOT_EYES)
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/glasses/science/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message(span_suicide("[user] is tightening \the [src]'s straps around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
return OXYLOSS
|
||||
|
||||
@@ -16,6 +16,3 @@
|
||||
. = ..()
|
||||
AddComponent(/datum/component/scope, range_modifier = 1.2, zoom_method = ZOOM_METHOD_ITEM_ACTION, item_action_type = /datum/action/item_action/hands_free/moth_googles)
|
||||
AddComponent(/datum/component/adjust_fishing_difficulty, -4)
|
||||
|
||||
/obj/item/clothing/head/mothcap/original/item_action_slot_check(slot, mob/user, datum/action/action)
|
||||
return (slot & ITEM_SLOT_HEAD)
|
||||
|
||||
@@ -120,9 +120,6 @@
|
||||
if (!core_installed)
|
||||
. += span_warning("It requires a hallucination anomaly core in order to function.")
|
||||
|
||||
/obj/item/clothing/head/helmet/perceptomatrix/item_action_slot_check(slot, mob/user, datum/action/action)
|
||||
return slot & ITEM_SLOT_HEAD
|
||||
|
||||
/obj/item/clothing/head/helmet/perceptomatrix/update_icon_state()
|
||||
icon_state = base_icon_state + (core_installed ? "" : "_inactive")
|
||||
worn_icon_state = base_icon_state + (core_installed ? "" : "_inactive")
|
||||
|
||||
@@ -292,7 +292,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
|
||||
flags_cover = MASKCOVERSEYES
|
||||
clothing_traits = list(TRAIT_PERCEIVED_AS_CLOWN)
|
||||
resistance_flags = FLAMMABLE
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
actions_types = list(/datum/action/item_action/adjust_style)
|
||||
dog_fashion = /datum/dog_fashion/head/clown
|
||||
var/list/clownmask_designs = list()
|
||||
voice_filter = null // performer masks expect to be talked through
|
||||
@@ -359,7 +359,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
flags_cover = MASKCOVERSEYES
|
||||
resistance_flags = FLAMMABLE
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
actions_types = list(/datum/action/item_action/adjust_style)
|
||||
species_exception = list(/datum/species/golem)
|
||||
fishing_modifier = 0
|
||||
var/list/mimemask_designs = list()
|
||||
@@ -467,7 +467,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
|
||||
resistance_flags = FLAMMABLE
|
||||
flags_cover = MASKCOVERSEYES
|
||||
max_integrity = 100
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
actions_types = list(/datum/action/item_action/adjust_style)
|
||||
dog_fashion = null
|
||||
fishing_modifier = -4
|
||||
var/list/tikimask_designs = list()
|
||||
|
||||
@@ -123,13 +123,7 @@ GLOBAL_LIST_INIT(hailer_phrases, list(
|
||||
aggressiveness = AGGR_BROKEN
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/gas/sechailer/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/halt))
|
||||
halt()
|
||||
else
|
||||
adjust_visor(user)
|
||||
|
||||
/obj/item/clothing/mask/gas/sechailer/attack_self()
|
||||
/obj/item/clothing/mask/gas/sechailer/ui_action_click(mob/user, actiontype)
|
||||
halt()
|
||||
|
||||
/obj/item/clothing/mask/gas/sechailer/emag_act(mob/user, obj/item/card/emag/emag_card)
|
||||
@@ -203,6 +197,7 @@ GLOBAL_LIST_INIT(hailer_phrases, list(
|
||||
custom_price = PAYCHECK_COMMAND * 1.5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
actions_types = list(/datum/action/item_action/halt)
|
||||
action_slots = ALL
|
||||
COOLDOWN_DECLARE(whistle_cooldown)
|
||||
|
||||
/obj/item/clothing/mask/whistle/ui_action_click(mob/user, action)
|
||||
|
||||
@@ -233,7 +233,6 @@
|
||||
var/robe_charge = TRUE
|
||||
actions_types = list(/datum/action/item_action/stickmen)
|
||||
|
||||
|
||||
/obj/item/clothing/suit/wizrobe/durathread
|
||||
name = "durathread robe"
|
||||
desc = "A rather dull durathread robe; not quite as protective as a proper piece of armour, but much more stylish."
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
force = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
actions_types = list(/datum/action/item_action/instrument)
|
||||
action_slots = ALL
|
||||
|
||||
/obj/item/instrument/harmonica/equipped(mob/user, slot, initial = FALSE)
|
||||
. = ..()
|
||||
@@ -223,12 +224,12 @@
|
||||
name = "Use Instrument"
|
||||
desc = "Use the instrument specified"
|
||||
|
||||
/datum/action/item_action/instrument/Trigger(trigger_flags)
|
||||
if(istype(target, /obj/item/instrument))
|
||||
var/obj/item/instrument/I = target
|
||||
I.interact(usr)
|
||||
return
|
||||
return ..()
|
||||
/datum/action/item_action/instrument/do_effect(trigger_flags)
|
||||
if(!istype(target, /obj/item/instrument))
|
||||
return FALSE
|
||||
var/obj/item/instrument/instrument = target
|
||||
instrument.interact(usr)
|
||||
return TRUE
|
||||
|
||||
/obj/item/instrument/bikehorn
|
||||
name = "gilded bike horn"
|
||||
|
||||
@@ -34,9 +34,6 @@
|
||||
if(gps_enabled)
|
||||
. += span_notice("The cuff's GPS signal is on.")
|
||||
|
||||
/obj/item/kheiral_cuffs/item_action_slot_check(slot)
|
||||
return (slot & ITEM_SLOT_GLOVES)
|
||||
|
||||
/obj/item/kheiral_cuffs/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(!(slot & ITEM_SLOT_GLOVES))
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
attack_verb_simple = list("smash", "crush", "cleave", "chop", "pulp")
|
||||
sharpness = SHARP_EDGED
|
||||
actions_types = list(/datum/action/item_action/toggle_light)
|
||||
action_slots = ALL
|
||||
obj_flags = UNIQUE_RENAME
|
||||
light_system = OVERLAY_LIGHT
|
||||
light_range = 5
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
hitsound = 'sound/items/weapons/sonic_jackhammer.ogg'
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
actions_types = list(/datum/action/item_action/vortex_recall)
|
||||
action_slots = ALL
|
||||
/// Linked teleport beacon for the group teleport functionality.
|
||||
var/obj/effect/hierophant/beacon
|
||||
/// TRUE if currently doing a teleport to the beacon, FALSE otherwise.
|
||||
|
||||
@@ -148,9 +148,6 @@
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
var/mob/living/carbon/human/active_owner
|
||||
|
||||
/obj/item/clothing/neck/necklace/memento_mori/item_action_slot_check(slot)
|
||||
return (slot & ITEM_SLOT_NECK)
|
||||
|
||||
/obj/item/clothing/neck/necklace/memento_mori/dropped(mob/user)
|
||||
..()
|
||||
if(active_owner)
|
||||
@@ -216,12 +213,13 @@
|
||||
name = "Memento Mori"
|
||||
desc = "Bind your life to the pendant."
|
||||
|
||||
/datum/action/item_action/hands_free/memento_mori/Trigger(trigger_flags)
|
||||
var/obj/item/clothing/neck/necklace/memento_mori/MM = target
|
||||
if(!MM.active_owner)
|
||||
if(ishuman(owner))
|
||||
MM.memento(owner)
|
||||
Remove(MM.active_owner) //Remove the action button, since there's no real use in having it now.
|
||||
/datum/action/item_action/hands_free/memento_mori/do_effect(trigger_flags)
|
||||
var/obj/item/clothing/neck/necklace/memento_mori/memento = target
|
||||
if(memento.active_owner || !ishuman(owner))
|
||||
return FALSE
|
||||
memento.memento(owner)
|
||||
Remove(memento.active_owner) //Remove the action button, since there's no real use in having it now.
|
||||
return TRUE
|
||||
|
||||
//Wisp Lantern
|
||||
/obj/item/wisp_lantern
|
||||
|
||||
@@ -566,9 +566,6 @@
|
||||
/mob/proc/getBackSlot()
|
||||
return ITEM_SLOT_BACK
|
||||
|
||||
/mob/proc/getBeltSlot()
|
||||
return ITEM_SLOT_BELT
|
||||
|
||||
//Inventory.dm is -kind of- an ok place for this I guess
|
||||
|
||||
//This is NOT for dismemberment, as the user still technically has 2 "hands"
|
||||
|
||||
@@ -78,6 +78,3 @@
|
||||
|
||||
/mob/living/basic/drone/getBackSlot()
|
||||
return ITEM_SLOT_DEX_STORAGE
|
||||
|
||||
/mob/living/basic/drone/getBeltSlot()
|
||||
return ITEM_SLOT_DEX_STORAGE
|
||||
|
||||
@@ -87,9 +87,6 @@
|
||||
/mob/living/basic/guardian/dextrous/getBackSlot()
|
||||
return ITEM_SLOT_DEX_STORAGE
|
||||
|
||||
/mob/living/basic/guardian/dextrous/getBeltSlot()
|
||||
return ITEM_SLOT_DEX_STORAGE
|
||||
|
||||
/mob/living/basic/guardian/dextrous/proc/update_inv_internal_storage()
|
||||
if(isnull(internal_storage) || isnull(client) || !hud_used?.hud_shown)
|
||||
return
|
||||
|
||||
@@ -196,16 +196,15 @@
|
||||
name = "Toggle Perspective"
|
||||
desc = "Switch between seeing normally from your head, or blindly from your body."
|
||||
|
||||
/datum/action/item_action/organ_action/dullahan/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
/datum/action/item_action/organ_action/dullahan/do_effect(trigger_flags)
|
||||
var/obj/item/organ/eyes/dullahan/dullahan_eyes = target
|
||||
dullahan_eyes.tint = dullahan_eyes.tint ? NONE : INFINITY
|
||||
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/human = owner
|
||||
if(isdullahan(human))
|
||||
var/datum/species/dullahan/dullahan_species = human.dna.species
|
||||
dullahan_species.update_vision_perspective(human)
|
||||
if(!isdullahan(owner))
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/human = owner
|
||||
var/datum/species/dullahan/dullahan_species = human.dna.species
|
||||
dullahan_species.update_vision_perspective(human)
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/dullahan_relay
|
||||
|
||||
@@ -153,11 +153,7 @@
|
||||
background_icon_state = "bg_default_on"
|
||||
overlay_icon_state = "bg_default_border"
|
||||
|
||||
/datum/action/item_action/organ_action/toggle_trip/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
/datum/action/item_action/organ_action/toggle_trip/do_effect(trigger_flags)
|
||||
var/obj/item/organ/brain/primate/monkey_brain = target
|
||||
if(monkey_brain.tripping)
|
||||
monkey_brain.tripping = FALSE
|
||||
@@ -168,6 +164,7 @@
|
||||
background_icon_state = "bg_default_on"
|
||||
to_chat(monkey_brain.owner, span_notice("You will now stumble while colliding with people who are in combat mode."))
|
||||
build_all_button_icons()
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/brain/primate/on_mob_insert(mob/living/carbon/primate)
|
||||
. = ..()
|
||||
|
||||
@@ -154,45 +154,50 @@
|
||||
name = "Drain Victim"
|
||||
desc = "Leech blood from any carbon victim you are passively grabbing."
|
||||
|
||||
/datum/action/item_action/organ_action/vampire/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
if(iscarbon(owner))
|
||||
var/mob/living/carbon/H = owner
|
||||
var/obj/item/organ/tongue/vampire/V = target
|
||||
if(!COOLDOWN_FINISHED(V, drain_cooldown))
|
||||
to_chat(H, span_warning("You just drained blood, wait a few seconds!"))
|
||||
return
|
||||
if(H.pulling && iscarbon(H.pulling))
|
||||
var/mob/living/carbon/victim = H.pulling
|
||||
if(H.blood_volume >= BLOOD_VOLUME_MAXIMUM)
|
||||
to_chat(H, span_warning("You're already full!"))
|
||||
return
|
||||
if(victim.stat == DEAD)
|
||||
to_chat(H, span_warning("You need a living victim!"))
|
||||
return
|
||||
if(!victim.blood_volume || (victim.dna && (HAS_TRAIT(victim, TRAIT_NOBLOOD) || victim.dna.species.exotic_blood)))
|
||||
to_chat(H, span_warning("[victim] doesn't have blood!"))
|
||||
return
|
||||
COOLDOWN_START(V, drain_cooldown, 3 SECONDS)
|
||||
if(victim.can_block_magic(MAGIC_RESISTANCE_HOLY, charge_cost = 0))
|
||||
victim.show_message(span_warning("[H] tries to bite you, but stops before touching you!"))
|
||||
to_chat(H, span_warning("[victim] is blessed! You stop just in time to avoid catching fire."))
|
||||
return
|
||||
if(victim.has_reagent(/datum/reagent/consumable/garlic))
|
||||
victim.show_message(span_warning("[H] tries to bite you, but recoils in disgust!"))
|
||||
to_chat(H, span_warning("[victim] reeks of garlic! you can't bring yourself to drain such tainted blood."))
|
||||
return
|
||||
if(!do_after(H, 3 SECONDS, target = victim, hidden = TRUE))
|
||||
return
|
||||
var/blood_volume_difference = BLOOD_VOLUME_MAXIMUM - H.blood_volume //How much capacity we have left to absorb blood
|
||||
var/drained_blood = min(victim.blood_volume, VAMP_DRAIN_AMOUNT, blood_volume_difference)
|
||||
victim.show_message(span_danger("[H] is draining your blood!"))
|
||||
to_chat(H, span_notice("You drain some blood!"))
|
||||
playsound(H, 'sound/items/drink.ogg', 30, TRUE, -2)
|
||||
victim.blood_volume = clamp(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
|
||||
H.blood_volume = clamp(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
|
||||
if(!victim.blood_volume)
|
||||
to_chat(H, span_notice("You finish off [victim]'s blood supply."))
|
||||
/datum/action/item_action/organ_action/vampire/do_effect(trigger_flags)
|
||||
if(!iscarbon(owner))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/user = owner
|
||||
var/obj/item/organ/tongue/vampire/licker_drinker = target
|
||||
if(!COOLDOWN_FINISHED(licker_drinker, drain_cooldown))
|
||||
to_chat(user, span_warning("You just drained blood, wait a few seconds!"))
|
||||
return FALSE
|
||||
|
||||
if(!iscarbon(user.pulling))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/victim = user.pulling
|
||||
if(user.blood_volume >= BLOOD_VOLUME_MAXIMUM)
|
||||
to_chat(user, span_warning("You're already full!"))
|
||||
return FALSE
|
||||
if(victim.stat == DEAD)
|
||||
to_chat(user, span_warning("You need a living victim!"))
|
||||
return FALSE
|
||||
if(!victim.blood_volume || (victim.dna && (HAS_TRAIT(victim, TRAIT_NOBLOOD) || victim.dna.species.exotic_blood)))
|
||||
to_chat(user, span_warning("[victim] doesn't have blood!"))
|
||||
return FALSE
|
||||
COOLDOWN_START(licker_drinker, drain_cooldown, 3 SECONDS)
|
||||
if(victim.can_block_magic(MAGIC_RESISTANCE_HOLY, charge_cost = 0))
|
||||
victim.show_message(span_warning("[user] tries to bite you, but stops before touching you!"))
|
||||
to_chat(user, span_warning("[victim] is blessed! You stop just in time to avoid catching fire."))
|
||||
return FALSE
|
||||
if(victim.has_reagent(/datum/reagent/consumable/garlic))
|
||||
victim.show_message(span_warning("[user] tries to bite you, but recoils in disgust!"))
|
||||
to_chat(user, span_warning("[victim] reeks of garlic! you can't bring yourself to drain such tainted blood."))
|
||||
return FALSE
|
||||
if(!do_after(user, 3 SECONDS, target = victim, hidden = TRUE))
|
||||
return FALSE
|
||||
var/blood_volume_difference = BLOOD_VOLUME_MAXIMUM - user.blood_volume //How much capacity we have left to absorb blood
|
||||
var/drained_blood = min(victim.blood_volume, VAMP_DRAIN_AMOUNT, blood_volume_difference)
|
||||
victim.show_message(span_danger("[user] is draining your blood!"))
|
||||
to_chat(user, span_notice("You drain some blood!"))
|
||||
playsound(user, 'sound/items/drink.ogg', 30, TRUE, -2)
|
||||
victim.blood_volume = clamp(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
|
||||
user.blood_volume = clamp(user.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
|
||||
if(!victim.blood_volume)
|
||||
to_chat(user, span_notice("You finish off [victim]'s blood supply."))
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/heart/vampire
|
||||
name = "vampire heart"
|
||||
|
||||
@@ -30,9 +30,7 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/mod/Trigger(trigger_flags)
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return FALSE
|
||||
/datum/action/item_action/mod/do_effect(trigger_flags)
|
||||
var/obj/item/mod/control/mod = target
|
||||
if(mod.malfunctioning && prob(75))
|
||||
mod.balloon_alert(usr, "button malfunctions!")
|
||||
@@ -44,7 +42,7 @@
|
||||
desc = "LMB: Deploy/Undeploy part. RMB: Deploy/Undeploy full suit."
|
||||
button_icon_state = "deploy"
|
||||
|
||||
/datum/action/item_action/mod/deploy/Trigger(trigger_flags)
|
||||
/datum/action/item_action/mod/deploy/do_effect(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -64,7 +62,7 @@
|
||||
/// First time clicking this will set it to TRUE, second time will activate it.
|
||||
var/ready = FALSE
|
||||
|
||||
/datum/action/item_action/mod/activate/Trigger(trigger_flags)
|
||||
/datum/action/item_action/mod/activate/do_effect(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -92,7 +90,7 @@
|
||||
desc = "Toggle a MODsuit module."
|
||||
button_icon_state = "module"
|
||||
|
||||
/datum/action/item_action/mod/module/Trigger(trigger_flags)
|
||||
/datum/action/item_action/mod/module/do_effect(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -107,7 +105,7 @@
|
||||
desc = "Open the MODsuit's panel."
|
||||
button_icon_state = "panel"
|
||||
|
||||
/datum/action/item_action/mod/panel/Trigger(trigger_flags)
|
||||
/datum/action/item_action/mod/panel/do_effect(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -180,7 +178,7 @@
|
||||
pinner = null
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/mod/pinnable/module/Trigger(trigger_flags)
|
||||
/datum/action/item_action/mod/pinnable/module/do_effect(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
@@ -202,10 +202,6 @@
|
||||
return
|
||||
clean_up()
|
||||
|
||||
/obj/item/mod/control/item_action_slot_check(slot)
|
||||
if(slot & slot_flags)
|
||||
return TRUE
|
||||
|
||||
// Grant pinned actions to pin owners, gives AI pinned actions to the AI and not the wearer
|
||||
/obj/item/mod/control/grant_action_to_bearer(datum/action/action)
|
||||
if (!istype(action, /datum/action/item_action/mod/pinnable))
|
||||
|
||||
@@ -182,10 +182,7 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/datum/action/item_action/mod_recall/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
/datum/action/item_action/mod_recall/do_effect(trigger_flags)
|
||||
var/obj/item/implant/mod/implant = target
|
||||
if(!COOLDOWN_FINISHED(src, recall_cooldown))
|
||||
implant.balloon_alert(implant.imp_in, "on cooldown!")
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
item_flags = NEEDS_PERMIT
|
||||
attack_verb_continuous = list("strikes", "hits", "bashes")
|
||||
attack_verb_simple = list("strike", "hit", "bash")
|
||||
action_slots = ALL
|
||||
|
||||
var/gun_flags = NONE
|
||||
var/fire_sound = 'sound/items/weapons/gun/pistol/shot.ogg'
|
||||
|
||||
@@ -38,6 +38,7 @@ Slimecrossing Armor
|
||||
icon = 'icons/obj/science/slimecrossing.dmi'
|
||||
icon_state = "prismglasses"
|
||||
actions_types = list(/datum/action/item_action/change_prism_colour, /datum/action/item_action/place_light_prism)
|
||||
|
||||
forced_glass_color = TRUE
|
||||
var/glasses_color = COLOR_WHITE
|
||||
|
||||
@@ -45,10 +46,6 @@ Slimecrossing Armor
|
||||
. = ..()
|
||||
AddElement(/datum/element/wearable_client_colour, /datum/client_colour/glass_colour, ITEM_SLOT_EYES, glasses_color, forced_glass_color)
|
||||
|
||||
/obj/item/clothing/glasses/prism_glasses/item_action_slot_check(slot)
|
||||
if(slot & ITEM_SLOT_EYES)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/light_prism
|
||||
name = "light prism"
|
||||
desc = "A shining crystal of semi-solid light. Looks fragile."
|
||||
@@ -74,9 +71,7 @@ Slimecrossing Armor
|
||||
button_icon = 'icons/obj/science/slimecrossing.dmi'
|
||||
button_icon_state = "prismcolor"
|
||||
|
||||
/datum/action/item_action/change_prism_colour/Trigger(trigger_flags)
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return
|
||||
/datum/action/item_action/change_prism_colour/do_effect(trigger_flags)
|
||||
var/obj/item/clothing/glasses/prism_glasses/glasses = target
|
||||
var/new_color = tgui_color_picker(owner, "Choose the lens color:", "Color change",glasses.glasses_color) // BUBBERSTATION EDIT: TGUI COLOR PICKER
|
||||
if(!new_color)
|
||||
@@ -90,9 +85,7 @@ Slimecrossing Armor
|
||||
button_icon = 'icons/obj/science/slimecrossing.dmi'
|
||||
button_icon_state = "lightprism"
|
||||
|
||||
/datum/action/item_action/place_light_prism/Trigger(trigger_flags)
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return
|
||||
/datum/action/item_action/place_light_prism/do_effect(trigger_flags)
|
||||
var/obj/item/clothing/glasses/prism_glasses/glasses = target
|
||||
if(locate(/obj/structure/light_prism) in get_turf(owner))
|
||||
to_chat(owner, span_warning("There isn't enough ambient energy to fabricate another light prism here."))
|
||||
|
||||
@@ -75,9 +75,7 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/activate_pill/Trigger(trigger_flags)
|
||||
if(!..())
|
||||
return FALSE
|
||||
/datum/action/item_action/activate_pill/do_effect(trigger_flags)
|
||||
owner.balloon_alert_to_viewers("[owner] grinds their teeth!", "You grit your teeth.")
|
||||
if(!do_after(owner, owner.stat * (2.5 SECONDS), owner, IGNORE_USER_LOC_CHANGE | IGNORE_INCAPACITATED))
|
||||
return FALSE
|
||||
|
||||
@@ -11,12 +11,11 @@
|
||||
name = "HUD implant"
|
||||
desc = "These cybernetic eyes will display a HUD over everything you see. Maybe."
|
||||
slot = ORGAN_SLOT_HUD
|
||||
actions_types = list(/datum/action/item_action/toggle_hud)
|
||||
actions_types = list(/datum/action/item_action/organ_action/toggle_hud)
|
||||
var/HUD_traits = list()
|
||||
/// Whether the HUD implant is on or off
|
||||
var/toggled_on = TRUE
|
||||
|
||||
|
||||
/obj/item/organ/cyberimp/eyes/hud/proc/toggle_hud(mob/living/carbon/eye_owner)
|
||||
if(toggled_on)
|
||||
toggled_on = FALSE
|
||||
|
||||
@@ -56,16 +56,14 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/organ_action/colossus/Trigger(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
/datum/action/item_action/organ_action/colossus/do_effect(trigger_flags)
|
||||
var/command = tgui_input_text(owner, "Speak with the Voice of God", "Command", max_length = MAX_MESSAGE_LEN)
|
||||
if(!command)
|
||||
return
|
||||
return FALSE
|
||||
if(QDELETED(src) || QDELETED(owner))
|
||||
return
|
||||
return FALSE
|
||||
owner.say(".x[command]")
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/vocal_cords/colossus/can_speak_with()
|
||||
if(!owner)
|
||||
@@ -98,15 +96,14 @@
|
||||
actions_types = list(/datum/action/item_action/organ_action/use/adamantine_vocal_cords)
|
||||
icon_state = "adamantine_cords"
|
||||
|
||||
/datum/action/item_action/organ_action/use/adamantine_vocal_cords/Trigger(trigger_flags)
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return
|
||||
/datum/action/item_action/organ_action/use/adamantine_vocal_cords/do_effect(trigger_flags)
|
||||
var/message = tgui_input_text(owner, "Resonate a message to all nearby golems", "Resonate", max_length = MAX_MESSAGE_LEN)
|
||||
if(!message)
|
||||
return
|
||||
return FALSE
|
||||
if(QDELETED(src) || QDELETED(owner))
|
||||
return
|
||||
return FALSE
|
||||
owner.say(".x[message]")
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/vocal_cords/adamantine/handle_speech(message)
|
||||
var/msg = span_resonate("[span_name("[owner.real_name]")] resonates, \"[message]\"")
|
||||
|
||||
@@ -114,17 +114,17 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/mod/pinnable/circuit/Trigger(trigger_flags)
|
||||
/datum/action/item_action/mod/pinnable/circuit/do_effect(trigger_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/obj/item/mod/control/mod = module.mod
|
||||
if(!istype(mod))
|
||||
return
|
||||
return FALSE
|
||||
if(!mod.active || mod.activating)
|
||||
if(mod.wearer)
|
||||
module.balloon_alert(mod.wearer, "not active!")
|
||||
return
|
||||
return FALSE
|
||||
circuit_component.user.set_output(owner)
|
||||
circuit_component.signal.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user