Skip to content

Commit

Permalink
Adds spinny bolas (#400)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrMelbert authored Jan 28, 2024
1 parent 5e251bc commit 8d2c5fc
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions maplestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -6139,6 +6139,7 @@
#include "maplestation_modules\code\game\objects\effects\temporary_visuals\projectiles\impact.dm"
#include "maplestation_modules\code\game\objects\effects\temporary_visuals\projectiles\muzzle.dm"
#include "maplestation_modules\code\game\objects\effects\temporary_visuals\projectiles\tracer.dm"
#include "maplestation_modules\code\game\objects\items\bola.dm"
#include "maplestation_modules\code\game\objects\items\captain_weapons.dm"
#include "maplestation_modules\code\game\objects\items\holy_weapons.dm"
#include "maplestation_modules\code\game\objects\items\locker_spawners.dm"
Expand Down
5 changes: 5 additions & 0 deletions maplestation_modules/code/__DEFINES/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,10 @@
/// A carbon is being flashed - actually being blinded and taking (eye) damage
#define COMSIG_CARBON_FLASH_ACT "carbon_flash_act"

/// Sent when a carbon enables throw mode
#define COMSIG_CARBON_THROW_ON "carbon_throw_on"
/// Sent when a carbon disables throw mode
#define COMSIG_CARBON_THROW_OFF "carbon_throw_off"

/// A carbon drank some caffeine. (signal, caffeine_content)
#define COMSIG_CARBON_DRINK_CAFFEINE "carbon_drink_caffeine"
121 changes: 121 additions & 0 deletions maplestation_modules/code/game/objects/items/bola.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/mob/living/carbon/throw_mode_off(method)
. = ..()
if(throw_mode)
return
SEND_SIGNAL(src, COMSIG_CARBON_THROW_OFF)

/mob/living/carbon/throw_mode_on(mode = THROW_MODE_TOGGLE)
. = ..()
if(!throw_mode)
return
SEND_SIGNAL(src, COMSIG_CARBON_THROW_ON)

/obj/item/restraints/legcuffs/bola
throw_speed = 1
throw_range = 1
/// Number of spins before we reach max power
var/max_spins = 4
/// Throw range of bola after max spins
var/max_range = 7
/// Throw speed of bola after max spins
var/max_speed = 3
/// Base time it takes per spin. Decreases per spin to model momentum.
var/spin_time = 0.75 SECONDS
/// Tracks if the bola is actively spinning
VAR_PRIVATE/is_spinning = FALSE
/// Trakcs if a throw has been queued with the bola, to prevent resetting stats mid throw
VAR_PRIVATE/being_thrown = FALSE

/obj/item/restraints/legcuffs/bola/examine(mob/user)
. = ..()
. += span_notice("It takes [max_spins] spins to reach its maximum speed and range.")

/obj/item/restraints/legcuffs/bola/equipped(mob/user, slot, initial)
. = ..()
if(!(slot & ITEM_SLOT_HANDS))
return

RegisterSignal(user, COMSIG_MOB_SWAP_HANDS, PROC_REF(swapped_hands), override = TRUE)
swapped_hands(user)

/obj/item/restraints/legcuffs/bola/dropped(mob/user, silent)
. = ..()
UnregisterSignal(user, COMSIG_CARBON_THROW_ON)
UnregisterSignal(user, COMSIG_MOB_SWAP_HANDS)
if(!being_thrown)
stop_spinning()

/obj/item/restraints/legcuffs/bola/on_thrown(mob/living/carbon/user, atom/target)
being_thrown = TRUE
return ..()

/obj/item/restraints/legcuffs/bola/proc/swapped_hands(mob/living/carbon/source)
SIGNAL_HANDLER

if(source.get_active_held_item() == src)
RegisterSignal(source, COMSIG_CARBON_THROW_ON, PROC_REF(throw_enabled), override = TRUE)
else
UnregisterSignal(source, COMSIG_CARBON_THROW_ON)
stop_spinning()

/obj/item/restraints/legcuffs/bola/proc/throw_enabled(mob/living/carbon/source)
SIGNAL_HANDLER

INVOKE_ASYNC(src, PROC_REF(begin_spinning), source)

/obj/item/restraints/legcuffs/bola/attack_self(mob/user, modifiers)
. = ..()
if(.)
return .
if(!iscarbon(user))
return .
var/mob/living/carbon/thrower = user
thrower.toggle_throw_mode()
return TRUE

/obj/item/restraints/legcuffs/bola/proc/begin_spinning(mob/living/carbon/spinner)
if(is_spinning)
return

is_spinning = TRUE

var/range_increment = round((max_range - throw_range) / max_spins, 0.5)
var/speed_increment = round((max_speed - throw_speed) / max_spins, 0.5)
var/spin_time_with_momentum = spin_time
for(var/current_spin in 1 to max_spins)
spin_time_with_momentum = round(spin_time - (spin_time * 0.33 * (current_spin / max_spins)), 0.5)
spin_sound(spin_time_with_momentum)
animate(src, spin_time_with_momentum, transform = transform.Turn(90), easing = (current_spin == 1 ? CUBIC_EASING : NONE)/*, flags = ANIMATION_CONTINUE*/)
if(!do_after(spinner, spin_time_with_momentum, spinner, timed_action_flags = IGNORE_USER_LOC_CHANGE|IGNORE_SLOWDOWNS, extra_checks = CALLBACK(src, PROC_REF(can_keep_spinning), spinner)))
stop_spinning()
return

throw_range += range_increment
throw_speed += speed_increment

var/infi_loop_time = spin_time * 0.8
while(can_keep_spinning(spinner))
spin_sound(infi_loop_time)
animate(src, infi_loop_time, transform = transform.Turn(90)/*, flags = ANIMATION_CONTINUE*/)
sleep(infi_loop_time)

/obj/item/restraints/legcuffs/bola/proc/can_keep_spinning(mob/living/carbon/spinner)
return !QDELETED(src) && !QDELETED(spinner) && is_spinning && spinner.throw_mode && spinner.get_active_held_item() == src

/obj/item/restraints/legcuffs/bola/proc/spin_sound(spin_time)
playsound(src, 'sound/weapons/punchmiss.ogg', 40, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, frequency = 0.33 SECONDS / spin_time)

/obj/item/restraints/legcuffs/bola/proc/stop_spinning()
if(!is_spinning)
return

is_spinning = FALSE
throw_range = initial(throw_range)
throw_speed = initial(throw_speed)
animate(src)
transform = null
being_thrown = FALSE

/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
stop_spinning()
return ..()

0 comments on commit 8d2c5fc

Please sign in to comment.