Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions code/datums/status_effects/debuffs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@

msg_stage++

/// Prevent clicks for the duration of the ability
/// Prevent clicks for the "duration" of the status
/datum/status_effect/debuff/clickcd
id = "clickcd"
alert_type = /atom/movable/screen/alert/status_effect/debuff/clickcd
Expand Down Expand Up @@ -538,7 +538,7 @@
/datum/status_effect/debuff/feinted
id = "feinted"
alert_type = /atom/movable/screen/alert/status_effect/debuff/feinted
duration = 30 SECONDS
duration = 20 SECONDS

/atom/movable/screen/alert/status_effect/debuff/feinted
name = "Feinted"
Expand Down
3 changes: 3 additions & 0 deletions code/game/objects/items/weapons/melee/axes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
grid_height = 64
grid_width = 32

weapon_special = /datum/special_intent/axe_swing

//................ Stone Axe ............... //
/obj/item/weapon/axe/stone
Expand Down Expand Up @@ -393,6 +394,8 @@
grid_height = 96
grid_width = 64

weapon_special = /datum/special_intent/axe_swing

/obj/item/weapon/greataxe/getonmobprop(tag)
. = ..()
if(tag)
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/items/weapons/melee/blunt.dm
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,8 @@
parrysound = "parrywood"
sellprice = 35

weapon_special = /datum/special_intent/ground_smash

/obj/item/weapon/mace/goden/getonmobprop(tag)
. = ..()
if(tag)
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/items/weapons/melee/flail.dm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
grid_width = 32
grid_height = 96

weapon_special = /datum/special_intent/flail_sweep

/obj/item/weapon/flail/getonmobprop(tag)
. = ..()
if(tag)
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/items/weapons/melee/knives.dm
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@
possible_item_intents = list(DAGGER_CUT, DAGGER_THRUST)
sellprice = 12

weapon_special = /datum/special_intent/triple_stab

/obj/item/weapon/knife/dagger/jile
name = "iron jile"
desc = "A curved iron dagger from the fallen east."
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/items/weapons/melee/special.dm
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,8 @@
grid_width = 64
grid_height = 32

weapon_special = /datum/special_intent/upper_cut

/obj/item/weapon/knuckles/getonmobprop(tag)
. = ..()
if(tag)
Expand Down
8 changes: 8 additions & 0 deletions code/game/objects/items/weapons/melee/swords.dm
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@
icon_state = "sword1"
sellprice = 30

weapon_special = /datum/special_intent/shin_swipe

/obj/item/weapon/sword/arming/Initialize()
. = ..()
if(icon_state == "sword1")
Expand Down Expand Up @@ -470,6 +472,8 @@
SET_BASE_PIXEL(-16, -16)
dropshrink = 0.8

weapon_special = /datum/special_intent/piercing_lunge

/obj/item/weapon/sword/rapier/getonmobprop(tag)
. = ..()
if(tag)
Expand Down Expand Up @@ -674,6 +678,8 @@
grid_height = 96
grid_width = 64

weapon_special = /datum/special_intent/side_sweep

/obj/item/weapon/sword/long/shotel
name = "steel shotel"
icon_state = "shotel_steel"
Expand Down Expand Up @@ -989,6 +995,8 @@
slot_flags = ITEM_SLOT_BACK
sellprice = 90

weapon_special = /datum/special_intent/greatsword_swing

/obj/item/weapon/sword/long/greatsword/getonmobprop(tag)
. = ..()
if(tag)
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/items/weapons/melee/whips.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
grid_width = 32
grid_height = 64

weapon_special = /datum/special_intent/whip_coil

/obj/item/weapon/whip/getonmobprop(tag)
. = ..()
if(tag)
Expand Down
1 change: 0 additions & 1 deletion code/game/objects/items/weapons/rmb_intents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@
var/theirskill = 0
var/skill_factor = 0


if(attacker_item?.associated_skill)
ourskill = user.get_skill_level(attacker_item.associated_skill)

Expand Down
98 changes: 68 additions & 30 deletions code/modules/combat/_special_intent.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
var/desc = "bad coders"
var/icon = 'icons/effects/effects.dmi'

/// The main place where we can draw out the pattern. Every tile entry is a list with two numbers.
/// The origin (0,0) is one step forward from the dir the owner is facing.
/// This can be modified, though it's best be done before [build_affected_turfs].
/// A third list value can be specified for a custom delay.
var/list/tile_coordinates = null

/// State to show before the attack
var/pre_icon_state = "blip"
/// Sound to play before the attack
Expand All @@ -29,11 +35,6 @@
/// Base cooldown time of the special, success OR failure
var/cooldown = 30 SECONDS

/// The main place where we can draw out the pattern. Every tile entry is a list with two numbers.
/// The origin (0,0) is one step forward from the dir the owner is facing.
/// This can be modified, though it's best be done before [build_affected_turfs].
var/list/tile_coordinates = null

/// Whether to have the howner pass through a doafter for the delay rather than it being on every turf.
/// Default code here does not allow for dir switching during the do after.
var/use_doafter = FALSE
Expand All @@ -51,10 +52,17 @@
///If the datum is using multi-timed turfs, only the FIRST one's adjacency is checked ONCE.
var/respect_adjacency = TRUE

/// Check for presence on the starting tile instead of adjacency
var/check_starting_loc = TRUE

/// The only reference we will hold, and only if [respect_adjacency] is TRUE
/// If the users loc isn't this when we end, they moved.
var/turf/starting_loc = null

/// If true we do various things to prevent the user from moving or clicking in [start_attack]
/// At that point we know that there are target turfs
var/immobilize_user = FALSE

/datum/special_intent/Destroy(force, ...)
starting_loc = null
return ..()
Expand Down Expand Up @@ -112,7 +120,7 @@

///Main pipeline. Note that _delay() calls post_delay() after a timer.
/datum/special_intent/proc/process_attack(mob/living/user, obj/item/parent, turf/target)
SHOULD_CALL_PARENT(TRUE)
SHOULD_NOT_OVERRIDE(TRUE)

if(user.ckey)
user.log_message(span_danger("Used the Special [name] on [key_name(target)]."), LOG_ATTACK)
Expand All @@ -121,13 +129,15 @@

var/list/turf/affected = build_affected_turfs(user, target)

after_creation(user, parent, affected)
start_cooldown(user)

if(!after_creation(user, parent, affected))
return

start_attack(user, parent, affected)

start_cooldown(user)

/// Do stuff before creating the grid
/// Change temporary values and coordinates here
/datum/special_intent/proc/pre_creation(mob/living/user, obj/item/parent, turf/target)
return

Expand All @@ -136,9 +146,10 @@
var/turf/origin = start_override ? start_override : get_step(user, user.dir)

var/list/turf/affected_turfs = list()
for(var/list/coords in tile_coordinates)
var/coord_x = coords[1]
var/coord_y = coords[2]
for(var/list/values in tile_coordinates)
var/coord_x = LAZYACCESS(values, 1)
var/coord_y = LAZYACCESS(values, 2)
var/delay = LAZYACCESS(values, 3)

if(respect_dir)
switch(user.dir)
Expand All @@ -156,13 +167,16 @@

var/turf/affected = locate(origin.x + coord_x, origin.y + coord_y, origin.z)
if(affected && !affected.is_blocked_turf(TRUE))
affected_turfs += affected
// Map each turf to a list of delays on it
// This allows for multiple effects on the same turf without duplicate turf entries
LAZYADDASSOCLIST(affected_turfs, affected, delay)

return affected_turfs

/// Called after the affected turfs are processed.
/// Return FALSE to cancel the attack
/datum/special_intent/proc/after_creation(mob/living/user, obj/item/parent, list/turfs)
return
return TRUE

/// Start the attack, executing it after the delay
/datum/special_intent/proc/start_attack(mob/living/user, obj/item/parent, list/turfs)
Expand All @@ -182,11 +196,17 @@
/datum/special_intent/proc/pre_delay(mob/living/user, obj/item/parent, list/turfs)
SHOULD_CALL_PARENT(TRUE)

if(immobilize_user)
user.Immobilize(attack_delay)
user.apply_status_effect(/datum/status_effect/debuff/clickcd, attack_delay)

for(var/turf/affected as anything in turfs)
var/obj/effect/temp_visual/duration_setting/effect = new(affected, attack_delay)
effect.icon = icon
effect.icon_state = pre_icon_state
effect.plane = GAME_PLANE_FOV_HIDDEN
for(var/delay in turfs[affected])
var/duration = attack_delay + delay
var/obj/effect/temp_visual/duration_setting/effect = new(affected, duration)
effect.icon = icon
effect.icon_state = pre_icon_state
effect.plane = GAME_PLANE_FOV_HIDDEN

if(pre_sound)
playsound(user, pre_sound, 100, TRUE)
Expand All @@ -195,7 +215,7 @@
/// It performs any needed adjacency checks and will try to draw the "post" visuals on any valid turfs.
/// It calls apply_hit() after where most of the logic for any on-hit effects should go.
/datum/special_intent/proc/post_delay(mob/living/user, obj/item/parent, list/turfs)
SHOULD_CALL_PARENT(TRUE)
SHOULD_NOT_OVERRIDE(TRUE)

if(QDELETED(user) || QDELETED(parent))
return
Expand All @@ -204,23 +224,41 @@
user.balloon_alert(user, "dropped weapon!")
return

if(starting_loc && get_turf(user) != starting_loc)
starting_loc = null
user.balloon_alert(user, "moved!")
return
if(starting_loc)
if(check_starting_loc && get_turf(user) != starting_loc)
starting_loc = null
user.balloon_alert(user, "moved!")
return
else if(!user.TurfAdjacent(starting_loc))
starting_loc = null
user.balloon_alert(user, "too far!")
return

for(var/turf/affected as anything in turfs)
if(post_icon_state)
var/obj/effect/temp_visual/duration_setting/effect = new(affected, fade_delay)
effect.icon = icon
effect.icon_state = post_icon_state
effect.plane = GAME_PLANE_FOV_HIDDEN

apply_hit(user, parent, affected)
for(var/delay in turfs[affected])
if(isnum(delay))
addtimer(CALLBACK(src, PROC_REF(post_delay_apply), user, parent, affected), delay)
else
post_delay_apply(user, parent, affected)

if(post_sound)
playsound(user, post_sound, 100, TRUE)

/// Apply individual tile effects
/datum/special_intent/proc/post_delay_apply(mob/living/user, obj/item/parent, turf/target)
SHOULD_CALL_PARENT(TRUE)

if(QDELETED(parent) || QDELETED(user))
return // Incredibly unlikely an open turf will change

if(post_icon_state)
var/obj/effect/temp_visual/duration_setting/effect = new(target, fade_delay)
effect.icon = icon
effect.icon_state = post_icon_state
effect.plane = GAME_PLANE_FOV_HIDDEN

apply_hit(user, parent, target)

/// Main proc where stuff should happen. This is called immediately after the post_delay of the intent.
/datum/special_intent/proc/apply_hit(mob/living/user, obj/item/parent, turf/target)
SHOULD_CALL_PARENT(FALSE)
Expand Down
Loading
Loading