Allows us to drop NODROP items if there is other way to get rid of them (#21080)

* adds proc to check if we can drop nodrop items

* C:/Program Files/Git/obj/effect/proc_holder/spell/touch refactor, support for wizard spells, xeno spells and changeling shield

* bug fixes, cleanup

* moved to signals, added support for mime fingergun

* fixed bugs

* cleanup

* same proc for removing weapon from active or any hand

* changeling fast swap exist again

* cleanup

* fix runtime

* signals cleanup

* review update

* Update code/datums/spells/mime.dm

Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>

* Update code/datums/spells/mime.dm

Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>

* Update code/datums/spells/touch_attacks.dm

Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>

* review updates

* fixing bug

---------

Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>
This commit is contained in:
HMBGERDO
2023-06-15 20:18:17 +02:00
committed by GitHub
parent b05e27bb17
commit b74cd79c03
10 changed files with 127 additions and 52 deletions

View File

@@ -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(): ()

View File

@@ -25,10 +25,6 @@
to_chat(user, "<span class='noticealien'>You withdraw your [src].</span>")
..()
/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]")

View File

@@ -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, "<span class='notice'>You draw your fingers!</span>")
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, "<span class='notice'>Holster your fingers first.</span>")
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, "<span class='notice'>You holster your fingers. Another time perhaps...</span>")
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

View File

@@ -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, "<span class='notice'>You draw the power out of your hand.</span>")
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, "<span class='warning'>Your hands are full!</span>")
return 0
to_chat(user, "<span class='notice'>You channel the power of the spell to your hand.</span>")
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, "<span class='notice'>You draw the power out of your hand.</span>")
/obj/effect/proc_holder/spell/touch/disintegrate
name = "Disintegrate"

View File

@@ -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"

View File

@@ -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("<span class='warning'>With a sickening crunch, [user] reforms [user.p_their()] [weapon_name_simple] into an arm!</span>", "<span class='notice'>We assimilate the [weapon_name_simple] back into our body.</span>", "<span class='warning'>You hear organic matter ripping and tearing!</span>")
user.update_inv_l_hand()
return
if(istype(user.r_hand, weapon_type))
qdel(user.r_hand)
if(!silent)
user.visible_message("<span class='warning'>With a sickening crunch, [user] reforms [user.p_their()] [weapon_name_simple] into an arm!</span>", "<span class='notice'>We assimilate the [weapon_name_simple] back into our body.</span>", "<span class='warning'>You hear organic matter ripping and tearing!</span>")
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("<span class='warning'>With a sickening crunch, [owner] reforms [owner.p_their()] [weapon_name_simple] into an arm!</span>", "<span class='notice'>We assimilate the [weapon_name_simple] back into our body.</span>", "<span class='warning'>You hear organic matter ripping and tearing!</span>")
//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("<span class='warning'>[loc.name]\'s arm starts stretching inhumanly!</span>", "<span class='warning'>Our arm twists and mutates, transforming it into a tentacle.</span>", "<span class='italics'>You hear organic matter ripping and tearing!</span>")
else
to_chat(loc, "<span class='notice'>You prepare to extend a tentacle.</span>")
/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, "<span class='warning'>[src] is not ready yet.</span>")
@@ -382,7 +411,6 @@
remaining_uses--
return ..()
/***************************************\
|*********SPACE SUIT + HELMET***********|
\***************************************/

View File

@@ -13,9 +13,23 @@
user.drop_r_hand()
else
to_chat(user, "<span class='notice'>Large blades of blood spring from your fingers!</span>")
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, "<span class='notice'>You dispel your claws!</span>")
/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, "<span class='notice'>You dispel your claws!</span>")
qdel(src)
to_chat(user, "<span class='notice'>You dispel your claws!</span>")
/obj/effect/proc_holder/spell/vampire/blood_tendrils
name = "Blood Tendrils (10)"

View File

@@ -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

View File

@@ -1,6 +1,6 @@
//unequip
/mob/living/carbon/alien/humanoid/unEquip(obj/item/I, force, silent = FALSE)
. = ..(I, force)
. = ..()
if(!. || !I)
return

View File

@@ -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*/)