Merge pull request #14111 from Arturlang/revenant_TK
[READY]Gives the revenant TK
This commit is contained in:
@@ -253,6 +253,7 @@
|
||||
|
||||
// item traits
|
||||
#define TRAIT_NODROP "nodrop"
|
||||
#define TRAIT_SPOOKY_THROW "spooky_throw"
|
||||
|
||||
// common trait sources
|
||||
#define TRAIT_GENERIC "generic"
|
||||
|
||||
@@ -130,7 +130,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
),
|
||||
/obj/item = list(
|
||||
"TRAIT_NODROP" = TRAIT_NODROP,
|
||||
"TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT
|
||||
"TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT,
|
||||
"TRAIT_SPOOKY_THROW" = TRAIT_SPOOKY_THROW
|
||||
)
|
||||
))
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ SUBSYSTEM_DEF(throwing)
|
||||
|
||||
|
||||
/datum/thrownthing/Destroy()
|
||||
if(HAS_TRAIT_FROM(thrownthing, TRAIT_SPOOKY_THROW, "revenant"))
|
||||
REMOVE_TRAIT(thrownthing, TRAIT_SPOOKY_THROW, "revenant")
|
||||
SSthrowing.processing -= thrownthing
|
||||
thrownthing.throwing = null
|
||||
thrownthing = null
|
||||
|
||||
@@ -449,6 +449,10 @@
|
||||
// this must come before the screen objects only block, dunno why it wasn't before
|
||||
if(over_object == M)
|
||||
user_show_to_mob(M)
|
||||
return
|
||||
if(isrevenant(M))
|
||||
RevenantThrow(over_object, M, source)
|
||||
return
|
||||
if(!M.incapacitated())
|
||||
if(!istype(over_object, /obj/screen))
|
||||
dump_content_at(over_object, M)
|
||||
|
||||
@@ -574,8 +574,8 @@
|
||||
return TRUE
|
||||
|
||||
//TODO: Better floating
|
||||
/atom/movable/proc/float(on)
|
||||
if(throwing)
|
||||
/atom/movable/proc/float(on, throw_override)
|
||||
if(throwing || !throw_override)
|
||||
return
|
||||
if(on && !(movement_type & FLOATING))
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
|
||||
@@ -468,6 +468,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
melee_attack_chain(usr, over)
|
||||
usr.FlushCurrentAction()
|
||||
return TRUE //returning TRUE as a "is this overridden?" flag
|
||||
if(isrevenant(usr))
|
||||
if(RevenantThrow(over, usr, src))
|
||||
return
|
||||
|
||||
if(!Adjacent(usr) || !over.Adjacent(usr))
|
||||
return // should stop you from dragging through windows
|
||||
|
||||
|
||||
@@ -82,4 +82,8 @@
|
||||
/obj/item/candle/infinite/hugbox
|
||||
heats_space = FALSE
|
||||
|
||||
/obj/item/candle/DoRevenantThrowEffects(atom/target)
|
||||
if(!infinite)
|
||||
put_out_candle()
|
||||
|
||||
#undef CANDLE_LUMINOSITY
|
||||
|
||||
@@ -136,6 +136,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/clothing/mask/cigarette/DoRevenantThrowEffects(atom/target)
|
||||
if(lit)
|
||||
attackby()
|
||||
else
|
||||
light()
|
||||
|
||||
/obj/item/clothing/mask/cigarette/attackby(obj/item/W, mob/user, params)
|
||||
if(!lit && smoketime > 0)
|
||||
var/lighting_text = W.ignition_effect(src, user)
|
||||
@@ -517,6 +523,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
overlay_state = pick(overlay_list)
|
||||
update_icon()
|
||||
|
||||
/obj/item/lighter/DoRevenantThrowEffects(atom/target)
|
||||
set_lit()
|
||||
|
||||
/obj/item/lighter/suicide_act(mob/living/carbon/user)
|
||||
if (lit)
|
||||
user.visible_message("<span class='suicide'>[user] begins holding \the [src]'s flame up to [user.p_their()] face! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
|
||||
@@ -37,11 +37,14 @@
|
||||
/obj/item/flashlight/attack_self(mob/user)
|
||||
on = !on
|
||||
update_brightness(user)
|
||||
playsound(user, on ? 'sound/weapons/magin.ogg' : 'sound/weapons/magout.ogg', 40, 1)
|
||||
playsound(src, on ? 'sound/weapons/magin.ogg' : 'sound/weapons/magout.ogg', 40, TRUE)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/item/flashlight/DoRevenantThrowEffects(atom/target)
|
||||
attack_self()
|
||||
|
||||
/obj/item/flashlight/suicide_act(mob/living/carbon/human/user)
|
||||
if (user.eye_blind)
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
if(.)
|
||||
new /obj/item/toy/eightball/haunted(loc)
|
||||
|
||||
/obj/item/toy/eightball/DoRevenantThrowEffects(atom/target)
|
||||
MakeHaunted()
|
||||
|
||||
/obj/item/toy/eightball/attack_self(mob/user)
|
||||
if(shaking)
|
||||
return
|
||||
|
||||
@@ -235,16 +235,23 @@
|
||||
return
|
||||
EmptyExtinguisher(user)
|
||||
|
||||
/obj/item/extinguisher/proc/EmptyExtinguisher(var/mob/user)
|
||||
if(loc == user && reagents.total_volume)
|
||||
/obj/item/extinguisher/DoRevenantThrowEffects(atom/target)
|
||||
EmptyExtinguisher()
|
||||
|
||||
/obj/item/extinguisher/proc/EmptyExtinguisher(mob/user)
|
||||
if(!reagents.total_volume)
|
||||
return
|
||||
if(loc == user || !user)
|
||||
reagents.clear_reagents()
|
||||
|
||||
var/turf/T = get_turf(loc)
|
||||
if(isopenturf(T))
|
||||
var/turf/open/theturf = T
|
||||
theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
|
||||
|
||||
user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "<span class='info'>You quietly empty out \the [src] by using its release valve.</span>")
|
||||
if(user)
|
||||
user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "<span class='info'>You quietly empty out \the [src] by using its release valve.</span>")
|
||||
else
|
||||
user.visible_message("The release valve of \the [src] suddenly opens and sprays it's contents on the floor!")
|
||||
|
||||
//firebot assembly
|
||||
/obj/item/extinguisher/attackby(obj/O, mob/user, params)
|
||||
|
||||
@@ -30,9 +30,13 @@
|
||||
target = null
|
||||
return ..()
|
||||
|
||||
/obj/item/pinpointer/DoRevenantThrowEffects(atom/target)
|
||||
attack_self()
|
||||
|
||||
/obj/item/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates [user.p_their()] pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
if(user)
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates [user.p_their()] pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
@@ -45,6 +45,10 @@
|
||||
return
|
||||
set_snowflake_from_config(id)
|
||||
|
||||
/obj/item/toy/plush/DoRevenantThrowEffects(atom/target)
|
||||
var/datum/component/squeak/squeaker = GetComponent(/datum/component/squeak)
|
||||
squeaker.do_play_squeak(TRUE)
|
||||
|
||||
/obj/item/toy/plush/Initialize(mapload, set_snowflake_id)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak, squeak_override)
|
||||
|
||||
@@ -43,6 +43,13 @@
|
||||
/obj/item/pneumatic_cannon/proc/init_charge() //wrapper so it can be vv'd easier
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/pneumatic_cannon/DoRevenantThrowEffects(atom/target)
|
||||
var/picked_target
|
||||
var/list/possible_targets = range(3,src)
|
||||
picked_target = pick(possible_targets)
|
||||
if(target)
|
||||
Fire(null, picked_target)
|
||||
|
||||
/obj/item/pneumatic_cannon/process()
|
||||
if(++charge_tick >= charge_ticks && charge_type)
|
||||
fill_with_type(charge_type, charge_amount)
|
||||
@@ -134,21 +141,29 @@
|
||||
Fire(user, target)
|
||||
|
||||
/obj/item/pneumatic_cannon/proc/Fire(mob/living/user, var/atom/target)
|
||||
if(!istype(user) && !target)
|
||||
if(!target)
|
||||
return
|
||||
if(user)
|
||||
if(!isliving(user))
|
||||
return
|
||||
var/discharge = 0
|
||||
if(!can_trigger_gun(user))
|
||||
if(user && !can_trigger_gun(user))
|
||||
return
|
||||
if(!loadedItems || !loadedWeightClass)
|
||||
to_chat(user, "<span class='warning'>\The [src] has nothing loaded.</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>\The [src] has nothing loaded.</span>")
|
||||
return
|
||||
if(!tank && checktank)
|
||||
to_chat(user, "<span class='warning'>\The [src] can't fire without a source of gas.</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>\The [src] can't fire without a source of gas.</span>")
|
||||
return
|
||||
if(tank && !tank.air_contents.remove(gasPerThrow * pressureSetting))
|
||||
to_chat(user, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
|
||||
else
|
||||
visible_message(src, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
|
||||
return
|
||||
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(75) && clumsyCheck && iscarbon(user))
|
||||
if(user && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(75) && clumsyCheck && iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.visible_message("<span class='warning'>[C] loses [C.p_their()] grip on [src], causing it to go off!</span>", "<span class='userdanger'>[src] slips out of your hands and goes off!</span>")
|
||||
C.dropItemToGround(src, TRUE)
|
||||
@@ -157,15 +172,18 @@
|
||||
else
|
||||
var/list/possible_targets = range(3,src)
|
||||
target = pick(possible_targets)
|
||||
discharge = 1
|
||||
if(!discharge)
|
||||
discharge = TRUE
|
||||
if(!discharge && user)
|
||||
user.visible_message("<span class='danger'>[user] fires \the [src]!</span>", \
|
||||
"<span class='danger'>You fire \the [src]!</span>")
|
||||
log_combat(user, target, "fired at", src)
|
||||
var/turf/T = get_target(target, get_turf(src))
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
|
||||
fire_items(T, user)
|
||||
if(pressureSetting >= 3 && iscarbon(user))
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, TRUE)
|
||||
if(user)
|
||||
log_combat(user, target, "fired at", src)
|
||||
fire_items(T, user)
|
||||
else
|
||||
fire_items(T)
|
||||
if(user && pressureSetting >= 3 && iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.visible_message("<span class='warning'>[C] is thrown down by the force of the cannon!</span>", "<span class='userdanger'>[src] slams into your shoulder, knocking you down!")
|
||||
C.DefaultCombatKnockdown(60)
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
cell = new preload_cell_type(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/melee/baton/DoRevenantThrowEffects(atom/target)
|
||||
switch_status()
|
||||
|
||||
/obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
..()
|
||||
//Only mob/living types have stun handling
|
||||
|
||||
@@ -73,6 +73,15 @@
|
||||
/obj/item/tank/proc/populate_gas()
|
||||
return
|
||||
|
||||
/obj/item/tank/DoRevenantThrowEffects(atom/target)
|
||||
if(air_contents)
|
||||
var/turf/open/location = get_turf(src)
|
||||
if(istype(location))
|
||||
location.assume_air(air_contents)
|
||||
air_contents.clear()
|
||||
SSair.add_to_active(location)
|
||||
visible_message("<span class='warning'[src] leaks gas!")
|
||||
|
||||
/obj/item/tank/Destroy()
|
||||
if(air_contents)
|
||||
qdel(air_contents)
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
else
|
||||
item_state = "[initial(item_state)]"
|
||||
|
||||
/obj/item/weldingtool/DoRevenantThrowEffects(atom/target)
|
||||
attack_self()
|
||||
|
||||
/obj/item/weldingtool/update_overlays()
|
||||
. = ..()
|
||||
if(change_icons)
|
||||
@@ -208,12 +211,14 @@
|
||||
//Switches the welder on
|
||||
/obj/item/weldingtool/proc/switched_on(mob/user)
|
||||
if(!status)
|
||||
to_chat(user, "<span class='warning'>[src] can't be turned on while unsecured!</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] can't be turned on while unsecured!</span>")
|
||||
return
|
||||
welding = !welding
|
||||
if(welding)
|
||||
if(get_fuel() >= 1)
|
||||
to_chat(user, "<span class='notice'>You switch [src] on.</span>")
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>You switch [src] on.</span>")
|
||||
playsound(loc, acti_sound, 50, 1)
|
||||
force = 15
|
||||
damtype = "fire"
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
var/list/drained_mobs = list() //Cannot harvest the same mob twice
|
||||
var/perfectsouls = 0 //How many perfect, regen-cap increasing souls the revenant has. //TODO, add objective for getting a perfect soul(s?)
|
||||
var/generated_objectives_and_spells = FALSE
|
||||
var/telekinesis_cooldown
|
||||
|
||||
/mob/living/simple_animal/revenant/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -93,13 +94,16 @@
|
||||
|
||||
/mob/living/simple_animal/revenant/Login()
|
||||
..()
|
||||
to_chat(src, "<span class='deadsay'><span class='big bold'>You are a revenant.</span></span>")
|
||||
to_chat(src, "<b>Your formerly mundane spirit has been infused with alien energies and empowered into a revenant.</b>")
|
||||
to_chat(src, "<b>You are not dead, not alive, but somewhere in between. You are capable of limited interaction with both worlds.</b>")
|
||||
to_chat(src, "<b>You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.</b>")
|
||||
to_chat(src, "<b>To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.</b>")
|
||||
to_chat(src, "<b><i>You do not remember anything of your past lives, nor will you remember anything about this one after your death.</i></b>")
|
||||
to_chat(src, "<b>Be sure to read <a href=\"https://tgstation13.org/wiki/Revenant\">the wiki page</a> to learn more.</b>")
|
||||
var/revenant_greet
|
||||
revenant_greet += "<span class='deadsay'><span class='big bold'>You are a revenant.</span></span>"
|
||||
revenant_greet += "<b>Your formerly mundane spirit has been infused with alien energies and empowered into a revenant.</b>"
|
||||
revenant_greet += "<b>You are not dead, not alive, but somewhere in between. You are capable of limited interaction with both worlds.</b>"
|
||||
revenant_greet += "<b>You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.</b>"
|
||||
revenant_greet += "<b>To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.</b>"
|
||||
revenant_greet += "<b><i>You do not remember anything of your past lives, nor will you remember anything about this one after your death.</i></b>"
|
||||
revenant_greet += "<b>Be sure to read <a href=\"https://tgstation13.org/wiki/Revenant\">the wiki page</a> to learn more.</b>"
|
||||
revenant_greet += "<b>You are also able to telekinetically throw objects by clickdragging them.</b>"
|
||||
to_chat(src, revenant_greet)
|
||||
if(!generated_objectives_and_spells)
|
||||
generated_objectives_and_spells = TRUE
|
||||
mind.assigned_role = ROLE_REVENANT
|
||||
@@ -317,6 +321,12 @@
|
||||
to_chat(src, "<span class='revenminor'>Lost [essence_amt]E[source ? " from [source]":""].</span>")
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/telekinesis_cooldown_end()
|
||||
if(!telekinesis_cooldown)
|
||||
CRASH("telekinesis_cooldown_end ran when telekinesis_cooldown on [src] was false")
|
||||
else
|
||||
telekinesis_cooldown = FALSE
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/death_reset()
|
||||
revealed = FALSE
|
||||
unreveal_time = 0
|
||||
@@ -431,6 +441,38 @@
|
||||
qdel(revenant)
|
||||
..()
|
||||
|
||||
/proc/RevenantThrow(over, mob/user, obj/item/throwable)
|
||||
var/mob/living/simple_animal/revenant/spooker = user
|
||||
if(!istype(throwable))
|
||||
return
|
||||
if(!throwable.anchored && !spooker.telekinesis_cooldown && spooker.essence > 20)
|
||||
if(7 < get_dist(throwable, spooker))
|
||||
return
|
||||
if(3 >= get_dist(throwable, spooker))
|
||||
spooker.stun(10)
|
||||
spooker.reveal(25)
|
||||
else
|
||||
spooker.stun(20)
|
||||
spooker.reveal(50)
|
||||
spooker.change_essence_amount(-20, FALSE, "telekinesis")
|
||||
spooker.telekinesis_cooldown = TRUE
|
||||
throwable.float(TRUE, TRUE)
|
||||
sleep(20)
|
||||
throwable.DoRevenantThrowEffects(over)
|
||||
throwable.throw_at(over, 10, 2)
|
||||
ADD_TRAIT(throwable, TRAIT_SPOOKY_THROW, "revenant")
|
||||
log_combat(throwable, over, "spooky telekinesised at", throwable)
|
||||
var/obj/effect/temp_visual/telekinesis/T = new(get_turf(throwable))
|
||||
T.color = "#8715b4"
|
||||
addtimer(CALLBACK(spooker, /mob/living/simple_animal/revenant.proc/telekinesis_cooldown_end), 50)
|
||||
sleep(5)
|
||||
throwable.float(FALSE, TRUE)
|
||||
|
||||
|
||||
//Use this for effects you want to happen when a revenant throws stuff, check the TRAIT_SPOOKY_THROW if you want to know if its still being thrown
|
||||
/obj/item/proc/DoRevenantThrowEffects(atom/target)
|
||||
return TRUE
|
||||
|
||||
//objectives
|
||||
/datum/objective/revenant
|
||||
var/targetAmount = 100
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
attack(user,user)
|
||||
return FIRELOSS
|
||||
|
||||
/obj/item/assembly/flash/DoRevenantThrowEffects(atom/target)
|
||||
AOE_flash()
|
||||
|
||||
/obj/item/assembly/flash/update_icon(flash = FALSE)
|
||||
cut_overlays()
|
||||
attached_overlays = list()
|
||||
|
||||
@@ -193,6 +193,13 @@
|
||||
user.visible_message(ignition_message)
|
||||
add_fingerprint(user)
|
||||
fire_act(I.get_temperature())
|
||||
//I would have it become a paper plane before the throw, but that would risk runtimes
|
||||
/obj/item/paper/DoRevenantThrowEffects(atom/target)
|
||||
sleep(10)
|
||||
if(HAS_TRAIT(src, TRAIT_SPOOKY_THROW))
|
||||
return
|
||||
new /obj/item/paperplane(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/paper/attackby(obj/item/P, mob/living/user, params)
|
||||
if(burn_paper_product_attackby_check(P, user))
|
||||
|
||||
Reference in New Issue
Block a user