Merge remote-tracking branch 'upstream/master' into universal-damage

This commit is contained in:
Fox McCloud
2019-09-17 11:24:58 -04:00
131 changed files with 1794 additions and 1012 deletions
+6 -6
View File
@@ -212,7 +212,7 @@
/datum/action/item_action/toggle_unfriendly_fire
name = "Toggle Friendly Fire \[ON\]"
desc = "Toggles if the staff causes friendly fire."
desc = "Toggles if the club's blasts cause friendly fire."
button_icon_state = "vortex_ff_on"
/datum/action/item_action/toggle_unfriendly_fire/Trigger()
@@ -220,8 +220,8 @@
UpdateButtonIcon()
/datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon()
if(istype(target, /obj/item/hierophant_staff))
var/obj/item/hierophant_staff/H = target
if(istype(target, /obj/item/hierophant_club))
var/obj/item/hierophant_club/H = target
if(H.friendly_fire_check)
button_icon_state = "vortex_ff_off"
name = "Toggle Friendly Fire \[OFF\]"
@@ -247,12 +247,12 @@
/datum/action/item_action/vortex_recall
name = "Vortex Recall"
desc = "Recall yourself, and anyone nearby, to an attuned hierophant rune at any time.<br>If no such rune exists, will produce a rune at your location."
desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.<br>If the beacon is still attached, will detach it."
button_icon_state = "vortex_recall"
/datum/action/item_action/vortex_recall/IsAvailable()
if(istype(target, /obj/item/hierophant_staff))
var/obj/item/hierophant_staff/H = target
if(istype(target, /obj/item/hierophant_club))
var/obj/item/hierophant_club/H = target
if(H.teleporting)
return 0
return ..()
+1 -1
View File
@@ -124,8 +124,8 @@ datum/map_template/ruin/lavaland/ash_walker
id = "hierophant"
description = "A strange, square chunk of metal of massive size. Inside awaits only death and many, many squares."
suffix = "lavaland_surface_hierophant.dmm"
allow_duplicates = FALSE
always_place = TRUE
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/blood_drunk_miner
name = "Blood-Drunk Miner"
+25 -3
View File
@@ -55,6 +55,7 @@
. = ..()
if(.)
if(ishuman(owner))
owner.status_flags |= IGNORESLOWDOWN
var/mob/living/carbon/human/H = owner
for(var/X in H.bodyparts)
var/obj/item/organ/external/BP = X
@@ -65,8 +66,7 @@
H.dna.species.clone_mod *= 0.1
H.dna.species.stamina_mod *= 0.1
add_attack_logs(owner, owner, "gained blood-drunk stun immunity", ATKLOG_ALL)
var/status = CANSTUN | CANWEAKEN | CANPARALYSE | IGNORESLOWDOWN
owner.status_flags &= ~status
owner.add_stun_absorption("blooddrunk", INFINITY, 4)
owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, 1)
/datum/status_effect/blooddrunk/on_remove()
@@ -81,7 +81,9 @@
H.dna.species.clone_mod *= 10
H.dna.species.stamina_mod *= 10
add_attack_logs(owner, owner, "lost blood-drunk stun immunity", ATKLOG_ALL)
owner.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | IGNORESLOWDOWN
owner.status_flags &= ~IGNORESLOWDOWN
if(islist(owner.stun_absorption) && owner.stun_absorption["blooddrunk"])
owner.stun_absorption -= "blooddrunk"
/datum/status_effect/exercised
id = "Exercised"
@@ -96,3 +98,23 @@
/datum/status_effect/exercised/Destroy()
. = ..()
STOP_PROCESSING(SSprocessing, src)
/obj/screen/alert/status_effect/regenerative_core
name = "Reinforcing Tendrils"
desc = "You can move faster than your broken body could normally handle!"
icon_state = "regenerative_core"
name = "Regenerative Core Tendrils"
/datum/status_effect/regenerative_core
id = "Regenerative Core"
duration = 1 MINUTES
status_type = STATUS_EFFECT_REPLACE
alert_type = /obj/screen/alert/status_effect/regenerative_core
/datum/status_effect/regenerative_core/on_apply()
owner.status_flags |= IGNORESLOWDOWN
owner.revive()
return TRUE
/datum/status_effect/regenerative_core/on_remove()
owner.status_flags &= ~IGNORESLOWDOWN
+2 -2
View File
@@ -43,5 +43,5 @@
duration = 40
alert_type = null
/datum/status_effect/high_five/on_timeout()
owner.visible_message("[owner] was left hanging....")
/datum/status_effect/high_five/on_remove()
owner.visible_message("[owner] was left hanging....")
+121 -4
View File
@@ -1,4 +1,3 @@
//Status effects are used to apply temporary or permanent effects to mobs. Mobs are aware of their status effects at all times.
//This file contains their code, plus code for applying and removing them.
//When making a new status effect, add a define to status_effects.dm in __DEFINES for ease of use!
@@ -52,13 +51,11 @@
tick()
tick_interval = world.time + initial(tick_interval)
if(duration != -1 && duration < world.time)
on_timeout()
qdel(src)
/datum/status_effect/proc/on_apply() //Called whenever the buff is applied; returning FALSE will cause it to autoremove itself.
return TRUE
/datum/status_effect/proc/tick() //Called every tick.
/datum/status_effect/proc/on_timeout()//called when a buff times out
/datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed; do note that at the point this is called, it is out of the owner's status_effects but owner is not yet null
/datum/status_effect/proc/be_replaced() //Called instead of on_remove when a status effect is replaced by itself or when a status effect with on_remove_on_mob_delete = FALSE has its mob deleted
owner.clear_alert(id)
@@ -66,6 +63,19 @@
owner = null
qdel(src)
/datum/status_effect/proc/refresh()
var/original_duration = initial(duration)
if(original_duration == -1)
return
duration = world.time + original_duration
//clickdelay/nextmove modifiers!
/datum/status_effect/proc/nextmove_modifier()
return 1
/datum/status_effect/proc/nextmove_adjust()
return 0
////////////////
// ALERT HOOK //
////////////////
@@ -87,6 +97,9 @@
if(S.id == initial(S1.id) && S.status_type)
if(S.status_type == STATUS_EFFECT_REPLACE)
S.be_replaced()
else if(S.status_type == STATUS_EFFECT_REFRESH)
S.refresh()
return
else
return
var/list/arguments = args.Copy()
@@ -117,4 +130,108 @@
var/datum/status_effect/S1 = effect
for(var/datum/status_effect/S in status_effects)
if(initial(S1.id) == S.id)
. += S
. += S
//////////////////////
// STACKING EFFECTS //
//////////////////////
/datum/status_effect/stacking
id = "stacking_base"
duration = -1 //removed under specific conditions
alert_type = null
var/stacks = 0 //how many stacks are accumulated, also is # of stacks that target will have when first applied
var/delay_before_decay //deciseconds until ticks start occuring, which removes stacks (first stack will be removed at this time plus tick_interval)
tick_interval = 10 //deciseconds between decays once decay starts
var/stack_decay = 1 //how many stacks are lost per tick (decay trigger)
var/stack_threshold //special effects trigger when stacks reach this amount
var/max_stacks //stacks cannot exceed this amount
var/consumed_on_threshold = TRUE //if status should be removed once threshold is crossed
var/threshold_crossed = FALSE //set to true once the threshold is crossed, false once it falls back below
var/overlay_file
var/underlay_file
var/overlay_state // states in .dmi must be given a name followed by a number which corresponds to a number of stacks. put the state name without the number in these state vars
var/underlay_state // the number is concatonated onto the string based on the number of stacks to get the correct state name
var/mutable_appearance/status_overlay
var/mutable_appearance/status_underlay
/datum/status_effect/stacking/proc/threshold_cross_effect() //what happens when threshold is crossed
/datum/status_effect/stacking/proc/stacks_consumed_effect() //runs if status is deleted due to threshold being crossed
/datum/status_effect/stacking/proc/fadeout_effect() //runs if status is deleted due to being under one stack
/datum/status_effect/stacking/proc/stack_decay_effect() //runs every time tick() causes stacks to decay
/datum/status_effect/stacking/proc/on_threshold_cross()
threshold_cross_effect()
if(consumed_on_threshold)
stacks_consumed_effect()
qdel(src)
/datum/status_effect/stacking/proc/on_threshold_drop()
/datum/status_effect/stacking/proc/can_have_status()
return owner.stat != DEAD
/datum/status_effect/stacking/proc/can_gain_stacks()
return owner.stat != DEAD
/datum/status_effect/stacking/tick()
if(!can_have_status())
qdel(src)
else
add_stacks(-stack_decay)
stack_decay_effect()
/datum/status_effect/stacking/proc/add_stacks(stacks_added)
if(stacks_added > 0 && !can_gain_stacks())
return FALSE
owner.cut_overlay(status_overlay)
owner.underlays -= status_underlay
stacks += stacks_added
if(stacks > 0)
if(stacks >= stack_threshold && !threshold_crossed) //threshold_crossed check prevents threshold effect from occuring if changing from above threshold to still above threshold
threshold_crossed = TRUE
on_threshold_cross()
else if(stacks < stack_threshold && threshold_crossed)
threshold_crossed = FALSE //resets threshold effect if we fall below threshold so threshold effect can trigger again
on_threshold_drop()
if(stacks_added > 0)
tick_interval += delay_before_decay //refreshes time until decay
stacks = min(stacks, max_stacks)
status_overlay.icon_state = "[overlay_state][stacks]"
status_underlay.icon_state = "[underlay_state][stacks]"
owner.add_overlay(status_overlay)
owner.underlays += status_underlay
else
fadeout_effect()
qdel(src) //deletes status if stacks fall under one
/datum/status_effect/stacking/on_creation(mob/living/new_owner, stacks_to_apply)
..()
add_stacks(stacks_to_apply)
/datum/status_effect/stacking/on_apply()
if(!can_have_status())
return FALSE
status_overlay = mutable_appearance(overlay_file, "[overlay_state][stacks]")
status_underlay = mutable_appearance(underlay_file, "[underlay_state][stacks]")
var/icon/I = icon(owner.icon, owner.icon_state, owner.dir)
var/icon_height = I.Height()
status_overlay.pixel_x = -owner.pixel_x
status_overlay.pixel_y = FLOOR(icon_height * 0.25, 1)
status_overlay.transform = matrix() * (icon_height/world.icon_size) //scale the status's overlay size based on the target's icon size
status_underlay.pixel_x = -owner.pixel_x
status_underlay.transform = matrix() * (icon_height/world.icon_size) * 3
status_underlay.alpha = 40
owner.add_overlay(status_overlay)
owner.underlays += status_underlay
return ..()
/datum/status_effect/stacking/Destroy()
if(owner)
owner.cut_overlay(status_overlay)
owner.underlays -= status_underlay
QDEL_NULL(status_overlay)
return ..()
+19
View File
@@ -508,6 +508,25 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
cost = 30
containername = "security clothing crate"
/datum/supply_packs/security/officerpack // Starter pack for an officer. Contains everything in a locker but backpack (officer already start with one). Convenient way to equip new officer on highpop.
name = "Officer Starter Pack"
contains = list(/obj/item/clothing/suit/armor/vest/security,
/obj/item/radio/headset/headset_sec/alt,
/obj/item/clothing/head/soft/sec,
/obj/item/reagent_containers/spray/pepper,
/obj/item/flash,
/obj/item/grenade/flashbang,
/obj/item/storage/belt/security/sec,
/obj/item/holosign_creator/security,
/obj/item/clothing/mask/gas/sechailer,
/obj/item/clothing/glasses/hud/security/sunglasses,
/obj/item/clothing/head/helmet,
/obj/item/melee/baton/loaded,
/obj/item/clothing/suit/armor/secjacket)
cost = 30 // Convenience has a price and this pack is genuinely loaded
containername = "officer starter crate"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////// Engineering /////////////////////////////////////
+2 -2
View File
@@ -1459,7 +1459,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/device_tools/shield
name = "Energy Shield"
desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles and defending against other attacks."
desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles, but it cannot block other attacks. Pair with an Energy Sword for a killer combination."
item = /obj/item/shield/energy
reference = "ESD"
cost = 16
@@ -1758,4 +1758,4 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
reference = "RTCB"
item = /obj/item/stack/telecrystal/fifty
cost = 50
gamemodes = list(/datum/game_mode/nuclear)
gamemodes = list(/datum/game_mode/nuclear)