Skip to content

Commit

Permalink
Cleaned up the Roid Rat Punch code (#36771)
Browse files Browse the repository at this point in the history
* clean

* fix and more clean-up

* more stuff

* tiny fix

* Removed a list
  • Loading branch information
boy2mantwicethefam authored Jul 18, 2024
1 parent 21a8520 commit 0ea20eb
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 129 deletions.
1 change: 1 addition & 0 deletions code/_hooks/events.dm
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@
// atom/hit_atom: the atom hit by the throw impact
// speed: the speed at which the thrown atom was thrown
// mob/living/user: the mob who threw the atom, if any
// thrown_atom: the atom that was thrown
/event/throw_impact

//Called by examine
Expand Down
2 changes: 1 addition & 1 deletion code/datums/components/coinflip.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
if(!isfood(parent))
coinflip(user, TRUE)

/datum/component/coinflip/proc/on_throw_impact(atom/hit_atom, speed, mob/user)
/datum/component/coinflip/proc/on_throw_impact(atom/hit_atom, speed, mob/user, atom/thrown_atom)
coinflip(thrown = TRUE)

/datum/component/coinflip/proc/equipped(mob/user, slot, hand_index = 0)
Expand Down
2 changes: 1 addition & 1 deletion code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ var/global/list/ghdel_profiling = list()
if(istype(src,/mob/living))
var/mob/living/M = src
M.take_organ_damage(10)
INVOKE_EVENT(src, /event/throw_impact, "hit_atom" = hit_atom, "speed" = speed, "user" = user)
INVOKE_EVENT(src, /event/throw_impact, "hit_atom" = hit_atom, "speed" = speed, "user" = user, "thrown_atom" = src)

/atom/Destroy()
QDEL_NULL(reagents)
Expand Down
139 changes: 82 additions & 57 deletions code/modules/spells/targeted/punch.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
var/mob/living/present_target //A placeholder proc that records the target for the purpose of actually getting the impact handled.
var/has_triggered = 0 //Variable to avoid having multiple explosions as a result of multiple to_bump and throw_impact being triggered

//A bunch of variables used for roid rat punching, to avoid copypasting a lot of code
var/explosive_punches = 1 //Whether it will actually cause an explosion
var/flat_damage //If set to a value, will override the L.get_unarmed_damage(target) * (multiplier) with the flat damage

/spell/targeted/punch/invocation(mob/user, list/targets)
invocation = pick("ROCKETTOPANCHI", "FARUKONPANCHI", "NORUMARUPANCHI", "BANZAI") //Look the BANZAI is a reference and if you get it then hats off to you.
..()
Expand All @@ -37,71 +41,66 @@

/spell/targeted/punch/cast(var/list/targets)
var/mob/living/L = holder
if(istype(L) && L.has_hand_check() && !L.restrained())
var/image/I = generate_punch_sprite()
for(var/mob/living/target in targets)
if(L.is_pacified(1,target))
return
playsound(get_turf(L), 'sound/weapons/punch_reverb.ogg', 100)
if(M_HULK in target.mutations) //Target is a hulk and too tough to throw, cannot be stunned
L.visible_message("<span class='danger'>[L] throws an overwhelmingly powerful punch against \the [target]!</span>")
L.do_attack_animation(target, L, I)
target.take_organ_damage(L.get_unarmed_damage(target) * 10)
explosive_punch(target)
return
if(istype(target.locked_to, /obj/structure/bed)) //Target is sitting on something, knock them off it
var/obj/structure/bed/B = target.locked_to
if(!B.unlock_atom(target)) //We can't knock them off, let them taste the full brunt of this super punch
L.visible_message("<span class='danger'>[L] throws an overwhelmingly powerful punch against \the [target]!</span>")
L.do_attack_animation(target, L, I)
target.take_organ_damage(L.get_unarmed_damage(target) * 10)
explosive_punch(target)
return
present_target = target
//Use two events because each does something the other cannot do, even if they are mostly similar.
target.register_event(/event/to_bump, src, nameof(src::handle_bump()))
target.register_event(/event/throw_impact, src, nameof(src::handle_throw_impact()))
L.do_attack_animation(target, L, I)
target.take_organ_damage(L.get_unarmed_damage(target) * 5) //A PUNCH THAT SHALL PIERCE PROTECTIONS
target.throw_at(get_edge_target_turf(L, L.dir), INFINITY, 1)
L.visible_message("<span class='danger'>[L] throws a mighty punch that launches \the [target] away!</span>")
var/turns = 0 //Fixes a bug where the transform could occasionally get messed up such as when the target is lying down
spawn(0) //Continue spell-code
target.SetStunned(2) //Make sure this kicks in ASAP
while(target.throwing)
sleep(1) //Moved it here so that it fixes a bug caused by throw_at() cancelling time stop for a split second
if(!target.timestopped)
target.transform = turn(target.transform, 45) //Spin the target
target.SetStunned(2) //We don't want the target to move during this time
turns += 45
target.transform = turn(target.transform, -turns)
target.Knockdown(2)
target.unregister_event(/event/to_bump, src, nameof(src::handle_bump())) //Just in case
target.unregister_event(/event/throw_impact, src, nameof(src::handle_throw_impact()))

for(var/obj/mecha/M in targets) //Target is a mecha
if(L.is_pacified(1, M))
return
L.visible_message("<span class='danger'>[L] throws an overwhelmingly powerful punch that breaks \the [M]!</span>")
L.do_attack_animation(M, L, I)
explosive_punch(M)
M.ex_act(1)
if(!istype(L) || !L.has_hand_check() || L.restrained())
return
var/T = targets[1]
if(L.is_pacified(1,T))
return
var/image/I = generate_punch_sprite()
playsound(get_turf(L), 'sound/weapons/punch_reverb.ogg', 100)
if(istype(T, /obj/mecha)) //Target is a mecha, destroy it
var/obj/mecha/M = T
L.visible_message("<span class='danger'>[L] throws an overwhelmingly powerful punch that breaks \the [M]!</span>")
L.do_attack_animation(M, L, I)
explosive_punch(M)
M.ex_act(1)
return
var/mob/living/target = T
var/obj/structure/bed/B = target.locked_to //If the target can't be unlocked from something they're sitting on, do a super punch
if((M_HULK in target.mutations) || (B && !B.unlock_atom(target))) //Target is a hulk or can't be removed, do the punch
L.visible_message("<span class='danger'>[L] throws an overwhelmingly powerful punch against \the [target]!</span>")
L.do_attack_animation(target, L, I)
target.take_organ_damage(calculate_damage(flat_damage, TRUE, target))
explosive_punch(target)
return
//Use two events because each does something the other cannot do, even if they are mostly similar.
if(explosive_punches)
target.register_event(/event/to_bump, src, nameof(src::handle_bump()))
target.register_event(/event/throw_impact, src, nameof(src::handle_throw_impact()))
L.do_attack_animation(target, L, I)
target.take_organ_damage(calculate_damage(flat_damage, FALSE, target)) //A PUNCH THAT SHALL PIERCE PROTECTIONS
target.throw_at(get_edge_target_turf(L, L.dir), INFINITY, 1)
L.visible_message("<span class='danger'>[L] throws a mighty punch that launches \the [target] away!</span>")
var/turns = 0 //Fixes a bug where the transform could occasionally get messed up such as when the target is lying down
spawn(0) //Continue spell-code
target.SetStunned(2) //Make sure this kicks in ASAP
while(target.throwing)
sleep(1) //Moved it here so that it fixes a bug caused by throw_at() cancelling time stop for a split second
if(!target.timestopped)
target.transform = turn(target.transform, 45) //Spin the target
target.SetStunned(2) //We don't want the target to move during this time
turns += 45
target.transform = turn(target.transform, -turns)
target.Knockdown(2)
if(explosive_punches)
target.unregister_event(/event/to_bump, src, nameof(src::handle_bump())) //Just in case
target.unregister_event(/event/throw_impact, src, nameof(src::handle_throw_impact()))

/spell/targeted/punch/proc/handle_bump(atom/movable/bumper, atom/bumped)
present_target.unregister_event(/event/to_bump, src, nameof(src::handle_bump()))
present_target.unregister_event(/event/throw_impact, src, nameof(src::handle_throw_impact()))
bumper.unregister_event(/event/to_bump, src, nameof(src::handle_bump()))
bumper.unregister_event(/event/throw_impact, src, nameof(src::handle_throw_impact()))
var/mob/living/L = holder
explode_on_impact(bumped, present_target, L)
explode_on_impact(bumped, bumper, L)

/spell/targeted/punch/proc/handle_throw_impact(atom/hit_atom, speed, mob/living/user)
present_target.unregister_event(/event/to_bump, src, nameof(src::handle_bump()))
present_target.unregister_event(/event/throw_impact, src, nameof(src::handle_throw_impact()))
/spell/targeted/punch/proc/handle_throw_impact(atom/hit_atom, speed, mob/living/user, atom/thrown_atom)
thrown_atom.unregister_event(/event/to_bump, src, nameof(src::handle_bump()))
thrown_atom.unregister_event(/event/throw_impact, src, nameof(src::handle_throw_impact()))
var/mob/living/L = holder
explode_on_impact(hit_atom, present_target, L)
explode_on_impact(hit_atom, thrown_atom, L)

//Explosion is centered on the collided entity.
/spell/targeted/punch/proc/explode_on_impact(var/atom/bumped, var/mob/living/T, var/mob/living/user)
if(has_triggered)
if(has_triggered || !explosive_punches)
return
var/list/explosion_whitelist = list()
var/list/projectile_whitelist = list()
Expand All @@ -118,6 +117,8 @@

//Explosion as a result of the target not flying away, significantly stronger than launching punches
/spell/targeted/punch/proc/explosive_punch(atom/target)
if(!explosive_punches) //No explosive punches allowed!
return
var/list/explosion_whitelist = list()
var/list/projectile_whitelist = list()
explosion_whitelist += holder
Expand All @@ -130,3 +131,27 @@

/spell/targeted/punch/proc/generate_punch_sprite()
return image(icon = 'icons/mob/screen_spells.dmi', icon_state = hud_state)

/spell/targeted/punch/proc/calculate_damage(flat_damage, tough_target, var/target)
if(flat_damage)
return flat_damage
var/mob/living/L = holder
return L.get_unarmed_damage(target) * (tough_target ? 10 : 5)


// Rat punch code here
/spell/targeted/punch/roidrat // A much less powerful version of the wizard punch. Can launch a mob a long distance, but causes no explosion. Even this rat's gains have their limits
name = "Roid Rat Punch"
desc = "This spell empowers your next close-and-personal unarmed attack to launch the enemy with great force"
abbreviation = "RP"
user_type = USER_TYPE_GYMRAT
charge_max = 300 // Much longer cooldown than the wizard spell
spell_flags = IS_HARMFUL | WAIT_FOR_CLICK
invocation_type = SpI_NONE
valid_targets = list(/mob/living) // Unlike the other version, this one can't target and destroy mechs
hud_state = "gen_hulk"
explosive_punches = 0
flat_damage = 30

/spell/targeted/punch/roidrat/invocation(mob/user, list/targets) // No invocation on this one, just raw muscle
return
69 changes: 0 additions & 69 deletions code/modules/spells/targeted/roidrat_punch.dm

This file was deleted.

1 change: 0 additions & 1 deletion vgstation13.dme
Original file line number Diff line number Diff line change
Expand Up @@ -2816,7 +2816,6 @@
#include "code\modules\spells\targeted\push.dm"
#include "code\modules\spells\targeted\recall.dm"
#include "code\modules\spells\targeted\retard.dm"
#include "code\modules\spells\targeted\roidrat_punch.dm"
#include "code\modules\spells\targeted\shoesnatch.dm"
#include "code\modules\spells\targeted\street_alchemy.dm"
#include "code\modules\spells\targeted\summon_snacks.dm"
Expand Down

0 comments on commit 0ea20eb

Please sign in to comment.