diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 55165724caa..ad993433eac 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -347,6 +347,8 @@ #define COMSIG_MOB_THROW "mob_throw" ///called when a user willingly drops something (i.e. keybind, or UI action) #define COMSIG_MOB_WILLINGLY_DROP "mob_willingly_drop" +///called when a user is getting new weapon and we want to remove previous weapon to clear hands +#define COMSIG_MOB_WEAPON_APPEARS "mob_weapon_appears" ///from base of /mob/verb/examinate(): (atom/target) #define COMSIG_MOB_EXAMINATE "mob_examinate" ///from base of /mob/update_sight(): () diff --git a/code/datums/spells/alien_spells/basetype_alien_touch.dm b/code/datums/spells/alien_spells/basetype_alien_touch.dm index af15f280143..24141fe3a4c 100644 --- a/code/datums/spells/alien_spells/basetype_alien_touch.dm +++ b/code/datums/spells/alien_spells/basetype_alien_touch.dm @@ -25,10 +25,6 @@ to_chat(user, "You withdraw your [src].") ..() -/obj/effect/proc_holder/spell/touch/alien_spell/cast(list/targets, mob/living/carbon/user) - user.add_plasma(plasma_cost) - ..() - /obj/effect/proc_holder/spell/touch/alien_spell/write_custom_logs(list/targets, mob/user) user.create_log(ATTACK_LOG, "Cast the spell [name]") diff --git a/code/datums/spells/mime.dm b/code/datums/spells/mime.dm index 6c3769364f0..e40dd88df96 100644 --- a/code/datums/spells/mime.dm +++ b/code/datums/spells/mime.dm @@ -99,17 +99,32 @@ action_icon_state = "fingergun" action_background_icon_state = "bg_mime" var/gun = /obj/item/gun/projectile/revolver/fingergun + var/obj/item/gun/projectile/revolver/fingergun/current_gun /obj/effect/proc_holder/spell/mime/fingergun/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/human/C in targets) - if(!istype(C.get_active_hand(), gun) && !istype(C.get_inactive_hand(), gun)) + if(!current_gun) to_chat(user, "You draw your fingers!") + current_gun = new gun(get_turf(user), src) C.drop_item() - C.put_in_hands(new gun) + C.put_in_hands(current_gun) + RegisterSignal(C, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(holster_hand)) else - to_chat(user, "Holster your fingers first.") + holster_hand(user, TRUE) revert_cast(user) + +/obj/effect/proc_holder/spell/mime/fingergun/Destroy() + current_gun = null + return ..() + +/obj/effect/proc_holder/spell/mime/fingergun/proc/holster_hand(atom/target, any=FALSE) + SIGNAL_HANDLER + if(!current_gun || !any && action.owner.get_active_hand() != current_gun) + return + to_chat(action.owner, "You holster your fingers. Another time perhaps...") + QDEL_NULL(current_gun) + /obj/effect/proc_holder/spell/mime/fingergun/fake desc = "Pretend you're shooting bullets out of your fingers! 3 bullets available per cast. Use your fingers to holster them manually." gun = /obj/item/gun/projectile/revolver/fingergun/fake diff --git a/code/datums/spells/touch_attacks.dm b/code/datums/spells/touch_attacks.dm index 3611c0c1353..fc10eeb27e0 100644 --- a/code/datums/spells/touch_attacks.dm +++ b/code/datums/spells/touch_attacks.dm @@ -9,26 +9,14 @@ /obj/effect/proc_holder/spell/touch/Click(mob/user = usr) if(attached_hand) - qdel(attached_hand) - cooldown_handler.revert_cast() - attached_hand = null - if(on_remove_message) - to_chat(user, "You draw the power out of your hand.") + discharge_hand(user, TRUE) return FALSE - ..() + charge_hand(user) -/obj/effect/proc_holder/spell/touch/cast(list/targets, mob/user = usr) - for(var/mob/living/carbon/target in targets) - if(!attached_hand) - if(!ChargeHand(target)) - return FALSE - while(attached_hand) //hibernate untill the spell is actually used - cooldown_handler.recharge_time++ // adds a tick onto the cooldown each tick - sleep(1) - -/obj/effect/proc_holder/spell/touch/proc/ChargeHand(mob/living/carbon/user) +/obj/effect/proc_holder/spell/touch/proc/charge_hand(mob/living/carbon/user) var/hand_handled = 1 attached_hand = new hand_path(src) + RegisterSignal(user, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(discharge_hand)) if(isalien(user)) user.put_in_hands(attached_hand) return @@ -42,13 +30,23 @@ hand_handled = 0 if(!hand_handled) qdel(attached_hand) - cooldown_handler.revert_cast() attached_hand = null to_chat(user, "Your hands are full!") return 0 to_chat(user, "You channel the power of the spell to your hand.") return 1 +/obj/effect/proc_holder/spell/touch/proc/discharge_hand(atom/target, any = FALSE) + SIGNAL_HANDLER + var/mob/living/carbon/user = action.owner + if(!istype(attached_hand)) + return + if(!any && attached_hand != user.get_active_hand()) + return + QDEL_NULL(attached_hand) + if(on_remove_message) + to_chat(user, "You draw the power out of your hand.") + /obj/effect/proc_holder/spell/touch/disintegrate name = "Disintegrate" diff --git a/code/game/gamemodes/wizard/godhand.dm b/code/game/gamemodes/wizard/godhand.dm index 42eafd0fd3a..86a590c3e51 100644 --- a/code/game/gamemodes/wizard/godhand.dm +++ b/code/game/gamemodes/wizard/godhand.dm @@ -17,6 +17,12 @@ attached_spell = spell ..() +/obj/item/melee/touch_attack/Destroy() + if(attached_spell) + attached_spell.attached_hand = null + attached_spell.UnregisterSignal(attached_spell.action.owner, COMSIG_MOB_WILLINGLY_DROP) + return ..() + /obj/item/melee/touch_attack/attack(mob/target, mob/living/carbon/user) if(!iscarbon(user)) //Look ma, no hands return @@ -28,14 +34,10 @@ /obj/item/melee/touch_attack/afterattack(atom/target, mob/user, proximity) if(catchphrase) user.say(catchphrase) - playsound(get_turf(user), on_use_sound,50,1) - attached_spell.attached_hand = null - qdel(src) - -/obj/item/melee/touch_attack/Destroy() + playsound(get_turf(user), on_use_sound, 50, 1) if(attached_spell) - attached_spell.attached_hand = null - return ..() + attached_spell.perform(list()) + qdel(src) /obj/item/melee/touch_attack/disintegrate name = "disintegrating touch" diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index cf445b96e3c..30dbaeb3b7f 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -18,28 +18,40 @@ var/weapon_name_simple /datum/action/changeling/weapon/try_to_sting(mob/user, mob/target) - if(istype(user.l_hand, weapon_type)) //Not the nicest way to do it, but eh - qdel(user.l_hand) - if(!silent) - user.visible_message("With a sickening crunch, [user] reforms [user.p_their()] [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "You hear organic matter ripping and tearing!") - user.update_inv_l_hand() - return - if(istype(user.r_hand, weapon_type)) - qdel(user.r_hand) - if(!silent) - user.visible_message("With a sickening crunch, [user] reforms [user.p_their()] [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "You hear organic matter ripping and tearing!") - user.update_inv_r_hand() + if(istype(user.l_hand, weapon_type) || istype(user.r_hand, weapon_type)) + retract(user, TRUE) return ..(user, target) /datum/action/changeling/weapon/sting_action(mob/user) + SEND_SIGNAL(user, COMSIG_MOB_WEAPON_APPEARS) if(!user.drop_item()) to_chat(user, "[user.get_active_hand()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!") return FALSE - var/obj/item/W = new weapon_type(user, silent) + var/obj/item/W = new weapon_type(user, silent, src) user.put_in_hands(W) + RegisterSignal(user, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(retract), override = TRUE) + RegisterSignal(user, COMSIG_MOB_WEAPON_APPEARS, PROC_REF(retract), override = TRUE) return W +/datum/action/changeling/weapon/proc/retract(atom/target, any_hand = FALSE) + SIGNAL_HANDLER + if(!ischangeling(owner)) + return + if(!any_hand && !istype(owner.get_active_hand(), weapon_type)) + return + var/done = FALSE + if(istype(owner.l_hand, weapon_type)) + qdel(owner.l_hand) + owner.update_inv_l_hand() + done = TRUE + if(istype(owner.r_hand, weapon_type)) + qdel(owner.r_hand) + owner.update_inv_r_hand() + done = TRUE + if(done && !silent) + owner.visible_message("With a sickening crunch, [owner] reforms [owner.p_their()] [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "You hear organic matter ripping and tearing!") + //Parent to space suits and armor. /datum/action/changeling/suit name = "Organic Suit" @@ -122,11 +134,20 @@ throwforce = 0 //Just to be on the safe side throw_range = 0 throw_speed = 0 + var/datum/action/changeling/weapon/parent_action -/obj/item/melee/arm_blade/Initialize(mapload) +/obj/item/melee/arm_blade/Initialize(mapload, silent, new_parent_action) . = ..() + parent_action = new_parent_action ADD_TRAIT(src, TRAIT_FORCES_OPEN_DOORS_ITEM, ROUNDSTART_TRAIT) +/obj/item/melee/arm_blade/Destroy() + if(parent_action) + parent_action.UnregisterSignal(parent_action.owner, COMSIG_MOB_WILLINGLY_DROP) + parent_action.UnregisterSignal(parent_action.owner, COMSIG_MOB_WEAPON_APPEARS) + parent_action = null + return ..() + /obj/item/melee/arm_blade/afterattack(atom/target, mob/user, proximity) if(!proximity) return @@ -139,7 +160,6 @@ var/obj/machinery/computer/C = target C.attack_alien(user) //muh copypasta - /***************************************\ |***********COMBAT TENTACLES*************| \***************************************/ @@ -177,15 +197,24 @@ throwforce = 0 //Just to be on the safe side throw_range = 0 throw_speed = 0 + var/datum/action/changeling/weapon/parent_action -/obj/item/gun/magic/tentacle/Initialize(mapload, silent) +/obj/item/gun/magic/tentacle/Initialize(mapload, silent, new_parent_action) . = ..() + parent_action = new_parent_action if(ismob(loc)) if(!silent) loc.visible_message("[loc.name]\'s arm starts stretching inhumanly!", "Our arm twists and mutates, transforming it into a tentacle.", "You hear organic matter ripping and tearing!") else to_chat(loc, "You prepare to extend a tentacle.") +/obj/item/gun/magic/tentacle/Destroy() + if(parent_action) + parent_action.UnregisterSignal(parent_action.owner, COMSIG_MOB_WILLINGLY_DROP) + parent_action.UnregisterSignal(parent_action.owner, COMSIG_MOB_WEAPON_APPEARS) + parent_action = null + return ..() + /obj/item/gun/magic/tentacle/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "[src] is not ready yet.") @@ -382,7 +411,6 @@ remaining_uses-- return ..() - /***************************************\ |*********SPACE SUIT + HELMET***********| \***************************************/ diff --git a/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm b/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm index 19fe443e467..9737d5d37a3 100644 --- a/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm @@ -13,9 +13,23 @@ user.drop_r_hand() else to_chat(user, "Large blades of blood spring from your fingers!") - var/obj/item/twohanded/required/vamp_claws/claws = new /obj/item/twohanded/required/vamp_claws(user.loc) + var/obj/item/twohanded/required/vamp_claws/claws = new /obj/item/twohanded/required/vamp_claws(user.loc, src) + RegisterSignal(user, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(dispel)) user.put_in_hands(claws) +/obj/effect/proc_holder/spell/vampire/self/vamp_claws/proc/dispel() + SIGNAL_HANDLER + var/mob/living/carbon/human/user = action.owner + if(user.mind.has_antag_datum(/datum/antagonist/vampire)) + return + var/current + if(istype(user.l_hand, /obj/item/twohanded/required/vamp_claws)) + current = user.l_hand + if(istype(user.r_hand, /obj/item/twohanded/required/vamp_claws)) + current = user.r_hand + if(current) + qdel(current) + to_chat(user, "You dispel your claws!") /obj/effect/proc_holder/spell/vampire/self/vamp_claws/can_cast(mob/user, charge_check, show_message) var/mob/living/L = user @@ -40,6 +54,17 @@ var/durability = 15 var/blood_drain_amount = 15 var/blood_absorbed_amount = 5 + var/obj/effect/proc_holder/spell/vampire/self/vamp_claws/parent_spell + +/obj/item/twohanded/required/vamp_claws/Initialize(mapload, new_parent_spell) + . = ..() + parent_spell = new_parent_spell + +/obj/item/twohanded/required/vamp_claws/Destroy() + if(parent_spell) + parent_spell.UnregisterSignal(parent_spell.action.owner, COMSIG_MOB_WILLINGLY_DROP) + parent_spell = null + return ..() /obj/item/twohanded/required/vamp_claws/afterattack(atom/target, mob/user, proximity) if(!proximity) @@ -72,8 +97,8 @@ user.changeNext_move(CLICK_CD_MELEE * 0.5) /obj/item/twohanded/required/vamp_claws/attack_self(mob/user) - to_chat(user, "You dispel your claws!") qdel(src) + to_chat(user, "You dispel your claws!") /obj/effect/proc_holder/spell/vampire/blood_tendrils name = "Blood Tendrils (10)" diff --git a/code/modules/mob/inventory_procs.dm b/code/modules/mob/inventory_procs.dm index d0cb1b47637..b871d35e75a 100644 --- a/code/modules/mob/inventory_procs.dm +++ b/code/modules/mob/inventory_procs.dm @@ -125,7 +125,7 @@ return unEquip(r_hand, force) //Why was this not calling unEquip in the first place jesus fuck. //Drops the item in our active hand. -/mob/proc/drop_item() //THIS. DOES. NOT. NEED. AN. ARGUMENT. +/mob/proc/drop_item() if(hand) return drop_l_hand() else diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_inventory.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_inventory.dm index d4b7ca7c9ca..223736b3668 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_inventory.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_inventory.dm @@ -1,6 +1,6 @@ //unequip /mob/living/carbon/alien/humanoid/unEquip(obj/item/I, force, silent = FALSE) - . = ..(I, force) + . = ..() if(!. || !I) return diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 5f1a5e45168..8dae5f84ed2 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -108,13 +108,22 @@ trigger_guard = TRIGGER_GUARD_ALLOW_ALL clumsy_check = FALSE //Stole your uplink! Honk! needs_permit = FALSE //go away beepsky + var/obj/effect/proc_holder/spell/mime/fingergun/parent_spell + +/obj/item/gun/projectile/revolver/fingergun/Destroy() + if(parent_spell) + parent_spell.current_gun = null + parent_spell.UnregisterSignal(parent_spell.action.owner, COMSIG_MOB_WILLINGLY_DROP) + parent_spell = null + return ..() /obj/item/gun/projectile/revolver/fingergun/fake desc = "Pew pew pew!" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38/invisible/fake -/obj/item/gun/projectile/revolver/fingergun/Initialize(mapload) +/obj/item/gun/projectile/revolver/fingergun/Initialize(mapload, new_parent_spell) . = ..() + parent_spell = new_parent_spell verbs -= /obj/item/gun/projectile/revolver/verb/spin /obj/item/gun/projectile/revolver/fingergun/shoot_with_empty_chamber(/*mob/living/user as mob|obj*/)