mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-19 03:55:11 +01:00
New Wizard spell "branch": Vendormancy (#75679)
## About The Pull Request New item for wizards, ~~the Staff~~ Scepter of Runic Vendormancy. With it, you can summon Runic Vending machines to block your enemies, push them 2 tiles back around the summoning tile, throw the vendors 4 tiles away to squash them or simple detonate the vendors for direct damage against enemies within a 2 tile range. The scepter has 3 charges that can be recharged after a "long" channel so while powerful, it is a tactical weapon and wizards can't directly steamroll the crew with endless vendors. (Unless they buy multiple scepters, but that is just funny.) Also, there is a bug with the throw... I copied how baseball bats deal with knockback, but they consistently don't push the vendors back, just spin them on the same tile... I appreciate if anyone has any idea on how to fix or change that to a better system. ## New changes I made The vendor has a random set of REAL wizard robes and hat, sandals and a foam vendor scepter as products to sell now. This gives the crew some real armor, and if it is considered too much, I can swap it for the fake versions. IMO the real clothes work as the perfect bait for the crew to approach the vendors and get exploded in the process, and while a random assistant might get real wizard armor to go valid hunt the wizard, the crew might just mistake them for the real wizard and beat them to death, which is too funny. ## Why It's Good For The Game  About a year ago I played Stoneshard, and it has such an amazing Geomancy Wizard that I wanted to port some of its gameplay to SS13 as our wizards, while funny and destructive, are kinda simple to play... Summoning and blowing up rocks was nice, but I randomly had the idea of summoning Vendors while at work and vendors squashing people has become such an iconic SS13 thing to me that I had to stop being lazy and start working on this. Something, something, enviromental combat wizard. ## Changelog Gonna polish the changelog later too... 🆑 Guillaume Prata add: New Wizard spell branch: Vendormacy! Summon runic vending machines with your Vending Scepter, force push them on your enemies to squish them or blow them up while they are busy buying from the machines. /🆑 --------- Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
This commit is contained in:
@@ -390,3 +390,126 @@
|
||||
whistle.whistler = null
|
||||
whistle = null
|
||||
return ..()
|
||||
|
||||
/////////////////////////////////////////Scepter of Vendormancy///////////////////
|
||||
#define RUNIC_SCEPTER_MAX_CHARGES 3
|
||||
#define RUNIC_SCEPTER_MAX_RANGE 7
|
||||
|
||||
/obj/item/runic_vendor_scepter
|
||||
name = "scepter of runic vendormancy"
|
||||
desc = "This scepter allows you to conjure, force push and detonate Runic Vendors. It can hold up to 3 charges that can be recovered with a simple magical channeling. A modern spin on the old Geomancy spells."
|
||||
icon_state = "vendor_staff"
|
||||
inhand_icon_state = "vendor_staff"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
|
||||
icon = 'icons/obj/weapons/guns/magic.dmi'
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
force = 10
|
||||
damtype = BRUTE
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
attack_verb_continuous = list("smacks", "clubs", "wacks")
|
||||
attack_verb_simple = list("smack", "club", "wacks")
|
||||
|
||||
/// Range cap on where you can summon vendors.
|
||||
var/max_summon_range = RUNIC_SCEPTER_MAX_RANGE
|
||||
/// Channeling time to summon a vendor.
|
||||
var/summoning_time = 1 SECONDS
|
||||
/// Checks if the scepter is channeling a vendor already.
|
||||
var/scepter_is_busy_summoning = FALSE
|
||||
/// Checks if the scepter is busy channeling recharges
|
||||
var/scepter_is_busy_recharging = FALSE
|
||||
///Number of summoning charges left.
|
||||
var/summon_vendor_charges = RUNIC_SCEPTER_MAX_CHARGES
|
||||
|
||||
/obj/item/runic_vendor_scepter/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
RegisterSignal(src, COMSIG_ITEM_MAGICALLY_CHARGED, PROC_REF(on_magic_charge))
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_ITEM_MAGICALLY_CHARGED = PROC_REF(on_magic_charge),
|
||||
)
|
||||
|
||||
/obj/item/runic_vendor_scepter/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(scepter_is_busy_recharging)
|
||||
user.balloon_alert(user, "busy!")
|
||||
return
|
||||
if(!check_allowed_items(target, not_inside = TRUE))
|
||||
return
|
||||
. |= AFTERATTACK_PROCESSED_ITEM
|
||||
var/turf/afterattack_turf = get_turf(target)
|
||||
if(istype(target, /obj/machinery/vending/runic_vendor))
|
||||
var/obj/machinery/vending/runic_vendor/runic_explosion_target = target
|
||||
runic_explosion_target.runic_explosion()
|
||||
return
|
||||
var/obj/machinery/vending/runic_vendor/vendor_on_turf = locate() in afterattack_turf
|
||||
if(vendor_on_turf)
|
||||
vendor_on_turf.runic_explosion()
|
||||
return
|
||||
if(!summon_vendor_charges)
|
||||
user.balloon_alert(user, "no charges!")
|
||||
return
|
||||
if(get_dist(afterattack_turf,src) > max_summon_range)
|
||||
user.balloon_alert(user, "too far!")
|
||||
return
|
||||
if(get_turf(src) == afterattack_turf)
|
||||
user.balloon_alert(user, "too close!")
|
||||
return
|
||||
if(scepter_is_busy_summoning)
|
||||
user.balloon_alert(user, "already summoning!")
|
||||
return
|
||||
if(afterattack_turf.is_blocked_turf(TRUE))
|
||||
user.balloon_alert(user, "blocked!")
|
||||
return
|
||||
if(summoning_time)
|
||||
scepter_is_busy_summoning = TRUE
|
||||
user.balloon_alert(user, "summoning...")
|
||||
if(!do_after(user, summoning_time, target = target))
|
||||
scepter_is_busy_summoning = FALSE
|
||||
return
|
||||
scepter_is_busy_summoning = FALSE
|
||||
if(summon_vendor_charges)
|
||||
playsound(src,'sound/weapons/resonator_fire.ogg',50,TRUE)
|
||||
user.visible_message(span_warning("[user] summons a runic vendor!"))
|
||||
new /obj/machinery/vending/runic_vendor(afterattack_turf)
|
||||
summon_vendor_charges--
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/runic_vendor_scepter/attack_self(mob/user, modifiers)
|
||||
. = ..()
|
||||
user.balloon_alert(user, "recharging...")
|
||||
scepter_is_busy_recharging = TRUE
|
||||
if(!do_after(user, 5 SECONDS))
|
||||
scepter_is_busy_recharging = FALSE
|
||||
return
|
||||
user.balloon_alert(user, "fully charged")
|
||||
scepter_is_busy_recharging = FALSE
|
||||
summon_vendor_charges = RUNIC_SCEPTER_MAX_CHARGES
|
||||
|
||||
/obj/item/runic_vendor_scepter/afterattack_secondary(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
var/turf/afterattack_secondary_turf = get_turf(target)
|
||||
var/obj/machinery/vending/runic_vendor/vendor_on_turf = locate() in afterattack_secondary_turf
|
||||
if(istype(target, /obj/machinery/vending/runic_vendor))
|
||||
var/obj/machinery/vending/runic_vendor/vendor_being_throw = target
|
||||
vendor_being_throw.throw_at(get_edge_target_turf(target, get_cardinal_dir(src, target)), 4, 20, user)
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
if(vendor_on_turf)
|
||||
vendor_on_turf.throw_at(get_edge_target_turf(target, get_cardinal_dir(src, target)), 4, 20, user)
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/obj/item/runic_vendor_scepter/proc/on_magic_charge(datum/source, datum/action/cooldown/spell/charge/spell, mob/living/caster)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!ismovable(loc))
|
||||
return
|
||||
|
||||
. = COMPONENT_ITEM_CHARGED
|
||||
|
||||
summon_vendor_charges = RUNIC_SCEPTER_MAX_CHARGES
|
||||
return .
|
||||
|
||||
#undef RUNIC_SCEPTER_MAX_CHARGES
|
||||
#undef RUNIC_SCEPTER_MAX_RANGE
|
||||
|
||||
@@ -97,3 +97,12 @@
|
||||
limit = 3
|
||||
category = "Assistance"
|
||||
refundable = TRUE
|
||||
|
||||
/datum/spellbook_entry/item/vendormancer
|
||||
name = "Scepter of Vendormancy"
|
||||
desc = "A scepter containing the power of Runic Vendormancy.\
|
||||
It can summon up to 3 Runic Vendors that decay over time, but can be \
|
||||
throw around to squash oponents or be directly detonated. When out of \
|
||||
charges a long channel will restore the charges."
|
||||
item_path = /obj/item/runic_vendor_scepter
|
||||
category = "Assistance"
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#define PULSE_DISTANCE_RANGE 2
|
||||
|
||||
/obj/machinery/vending/runic_vendor
|
||||
name = "\improper Runic Vending Machine"
|
||||
desc = "This vending machine was designed for warfare! A perfect bait for Nanotrasen's crew thirst for consumerism."
|
||||
icon_state = "RunicVendor"
|
||||
panel_type = "panel10"
|
||||
product_slogans = "Come get free magic!;50% off on Mjollnirs today!; Buy a warp whistle and get another one free!"
|
||||
vend_reply = "Please, stand still near the vending machine for your special package!"
|
||||
resistance_flags = FIRE_PROOF
|
||||
light_mask = "RunicVendor-light-mask"
|
||||
/// How long the vendor stays up before it decays.
|
||||
var/time_to_decay = 30 SECONDS
|
||||
/// Area around the vendor that will pushback nearby mobs.
|
||||
var/pulse_distance = PULSE_DISTANCE_RANGE
|
||||
|
||||
|
||||
/obj/machinery/vending/runic_vendor/Initialize(mapload)
|
||||
if(mapload)
|
||||
log_mapping("[type] is not supposed to be mapped it, it decays after a set time")
|
||||
stack_trace("Someone mapped in the meme vending machine the wizard scepter spawns, please remove it")
|
||||
|
||||
addtimer(CALLBACK(src, PROC_REF(decay)), time_to_decay, TIMER_STOPPABLE)
|
||||
INVOKE_ASYNC(src, PROC_REF(runic_pulse))
|
||||
|
||||
switch(pick(1,3))
|
||||
if(1)
|
||||
products = list(
|
||||
/obj/item/clothing/head/wizard = 1,
|
||||
/obj/item/clothing/suit/wizrobe = 1,
|
||||
/obj/item/clothing/shoes/sandal/magic = 1,
|
||||
/obj/item/toy/foam_runic_scepter = 1,
|
||||
)
|
||||
if(2)
|
||||
products = list(
|
||||
/obj/item/clothing/head/wizard/red = 1,
|
||||
/obj/item/clothing/suit/wizrobe/red = 1,
|
||||
/obj/item/clothing/shoes/sandal/magic = 1,
|
||||
/obj/item/toy/foam_runic_scepter = 1,
|
||||
)
|
||||
if(3)
|
||||
products = list(
|
||||
/obj/item/clothing/head/wizard/yellow = 1,
|
||||
/obj/item/clothing/suit/wizrobe/yellow = 1,
|
||||
/obj/item/clothing/shoes/sandal/magic = 1,
|
||||
/obj/item/toy/foam_runic_scepter = 1,
|
||||
)
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/vending/runic_vendor/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = ..()
|
||||
|
||||
if(held_item)
|
||||
if(istype(held_item, /obj/item/runic_vendor_scepter))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Detonate"
|
||||
context[SCREENTIP_CONTEXT_RMB] = "Force push"
|
||||
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
return .
|
||||
|
||||
|
||||
/obj/machinery/vending/runic_vendor/Destroy()
|
||||
visible_message(span_warning("[src] flickers and disappears!"))
|
||||
playsound(src,'sound/weapons/resonator_blast.ogg',25,TRUE)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/vending/runic_vendor/proc/runic_explosion()
|
||||
explosion(src, light_impact_range = 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/vending/runic_vendor/proc/runic_pulse()
|
||||
var/pulse_locs = spiral_range_turfs(pulse_distance, get_turf(src))
|
||||
var/list/hit_things = list()
|
||||
for(var/turf/pulsing_turf in pulse_locs)
|
||||
for(var/mob/living/mob_to_be_pulsed_back in pulsing_turf.contents)
|
||||
hit_things += mob_to_be_pulsed_back
|
||||
var/atom/target = get_edge_target_turf(mob_to_be_pulsed_back, get_dir(src, get_step_away(mob_to_be_pulsed_back, src)))
|
||||
to_chat(mob_to_be_pulsed_back, span_userdanger("The field repels you with tremendous force!"))
|
||||
playsound(src, 'sound/effects/gravhit.ogg', 50, TRUE)
|
||||
mob_to_be_pulsed_back.throw_at(target, 4, 4)
|
||||
|
||||
/obj/machinery/vending/runic_vendor/screwdriver_act(mob/living/user, obj/item/I)
|
||||
explosion(src, light_impact_range = 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/vending/runic_vendor/proc/decay()
|
||||
qdel(src)
|
||||
|
||||
#undef PULSE_DISTANCE_RANGE
|
||||
Reference in New Issue
Block a user