mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-08-29 17:06:23 +01:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
/datum/targetable/predator/predator_trophycount
|
||||
name = "Check trophy value"
|
||||
desc = "Displays the combined value of all trophies in your possession."
|
||||
targeted = 0
|
||||
target_nodamage_check = 0
|
||||
max_range = 0
|
||||
cooldown = 0
|
||||
pointCost = 0
|
||||
when_stunned = 3
|
||||
not_when_handcuffed = 0
|
||||
predator_only = 0
|
||||
dont_lock_holder = 1
|
||||
ignore_holder_lock = 1
|
||||
|
||||
cast(mob/target)
|
||||
if (!holder)
|
||||
return 1
|
||||
|
||||
var/mob/living/M = holder.owner
|
||||
|
||||
if (!M)
|
||||
return 1
|
||||
|
||||
var/count = M.get_skull_value()
|
||||
|
||||
if (count <= 0)
|
||||
boutput(M, __red("<b>Combined trophy value: 0</b>"))
|
||||
else
|
||||
boutput(M, __blue("<b>Combined trophy value: [count]</b>"))
|
||||
|
||||
return 0
|
||||
@@ -0,0 +1,72 @@
|
||||
/datum/targetable/predator/predator_gearspawn
|
||||
name = "Order hunting gear"
|
||||
desc = "Teleports hunting gear to your location."
|
||||
targeted = 0
|
||||
target_nodamage_check = 0
|
||||
max_range = 0
|
||||
cooldown = 0
|
||||
pointCost = 0
|
||||
when_stunned = 1
|
||||
not_when_handcuffed = 0
|
||||
predator_only = 0
|
||||
|
||||
cast(mob/target)
|
||||
if (!holder)
|
||||
return 1
|
||||
|
||||
var/mob/living/M = holder.owner
|
||||
|
||||
if (!M || !ishuman(M))
|
||||
return 1
|
||||
|
||||
actions.start(new/datum/action/bar/private/icon/predator_transform(src), M)
|
||||
return 0
|
||||
|
||||
/datum/action/bar/private/icon/predator_transform
|
||||
duration = 50
|
||||
interrupt_flags = INTERRUPT_MOVE | INTERRUPT_ACT | INTERRUPT_ACTION
|
||||
id = "predator_transform"
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
icon_state = "grabbed"
|
||||
var/datum/targetable/predator/predator_gearspawn/transform
|
||||
|
||||
New(Transform)
|
||||
transform = Transform
|
||||
..()
|
||||
|
||||
onStart()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
|
||||
if (M == null || !ishuman(M) || M.stat != 0 || M.paralysis > 0 || !transform)
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
boutput(M, __red("<B>Request acknowledged. You must stand still.</B>"))
|
||||
|
||||
onUpdate()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
|
||||
if (M == null || !ishuman(M) || M.stat != 0 || M.paralysis > 0 || !transform)
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
onEnd()
|
||||
..()
|
||||
|
||||
var/mob/living/carbon/human/M = owner
|
||||
var/datum/abilityHolder/H = transform.holder
|
||||
|
||||
if (M.predator_transform() != 1)
|
||||
boutput(M, __red("Gearspawn failed. Make sure you're a human and try again later."))
|
||||
else
|
||||
H.removeAbility(/datum/targetable/predator/predator_gearspawn)
|
||||
|
||||
onInterrupt()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
boutput(M, __red("You were interrupted!"))
|
||||
@@ -0,0 +1,180 @@
|
||||
/datum/targetable/predator/predator_taketrophy
|
||||
name = "Take trophy"
|
||||
desc = "Retrieves a trophy skull from the victim or severed head, mutilating them in the process."
|
||||
targeted = 1
|
||||
target_anything = 1
|
||||
target_nodamage_check = 1
|
||||
max_range = 1
|
||||
cooldown = 0
|
||||
pointCost = 0
|
||||
when_stunned = 0
|
||||
not_when_handcuffed = 1
|
||||
predator_only = 1
|
||||
restricted_area_check = 2
|
||||
|
||||
cast(mob/target)
|
||||
if (!holder)
|
||||
return 1
|
||||
|
||||
var/mob/living/M = holder.owner
|
||||
|
||||
if (!M || !target)
|
||||
return 1
|
||||
|
||||
if (M == target)
|
||||
boutput(M, __red("Why would you want to take your own skull?"))
|
||||
return 1
|
||||
|
||||
if (get_dist(M, target) > src.max_range)
|
||||
boutput(M, __red("[target] is too far away."))
|
||||
return 1
|
||||
|
||||
if (!istype(target, /obj/item/organ/head))
|
||||
if (!ishuman(target)) // Only human mobs and severed human heads have a skull.
|
||||
if (issilicon(target))
|
||||
boutput(M, __red("Mechanical trophies are of no interest to you."))
|
||||
return 1
|
||||
|
||||
else if (istype(target, /mob/living/carbon/wall))
|
||||
boutput(M, __red("This prey is so weak you daren't sully your claws on it!"))
|
||||
return 1
|
||||
|
||||
else
|
||||
boutput(M, __red("There's no trophy to be found here."))
|
||||
return 1
|
||||
|
||||
else
|
||||
var/mob/living/carbon/human/HH = target
|
||||
if (!ischangeling(HH) && (ismonkey(HH) || HH.bioHolder && HH.bioHolder.HasEffect("monkey"))) // Lesser form doesn't count.
|
||||
boutput(M, __red("This pitiful creature isn't worth your time."))
|
||||
return 1
|
||||
|
||||
if (HH.stat != 2)
|
||||
boutput(M, __red("It would be dishonorable to do that to something you haven't killed yet!"))
|
||||
return 1
|
||||
|
||||
else
|
||||
var/obj/item/organ/head/SH = target
|
||||
if (!(SH.skull && istype(SH.skull, /obj/item/skull/)))
|
||||
boutput(M, __red("The skull appears to be missing."))
|
||||
return 1
|
||||
|
||||
actions.start(new/datum/action/bar/private/icon/predator_taketrophy(target, src), M)
|
||||
return 0
|
||||
|
||||
/datum/action/bar/private/icon/predator_taketrophy
|
||||
duration = 60
|
||||
interrupt_flags = INTERRUPT_MOVE | INTERRUPT_ACT | INTERRUPT_STUNNED | INTERRUPT_ACTION
|
||||
id = "predator_taketrophy"
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
icon_state = "grabbed"
|
||||
var/target
|
||||
var/datum/targetable/predator/predator_taketrophy/trophy
|
||||
|
||||
New(Target, Trophy)
|
||||
target = Target
|
||||
trophy = Trophy
|
||||
..()
|
||||
|
||||
onStart()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
var/datum/abilityHolder/A = trophy.holder
|
||||
|
||||
if (ismob(target))
|
||||
var/mob/living/HH = target
|
||||
if (!trophy || get_dist(M, HH) > trophy.max_range || HH == null || M == null || !ishuman(HH) || HH.stat != 2)
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
else
|
||||
var/obj/item/organ/head/SH = target
|
||||
if (!trophy || get_dist(M, SH) > trophy.max_range || SH == null || M == null || !istype(SH) || !(SH.skull && istype(SH.skull, /obj/item/skull/)))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
M.visible_message("<span style=\"color:red\"><B>[M] unsheaths [his_or_her(M)] claws and begins to cut into [target]!</B></span>")
|
||||
A.locked = 1
|
||||
|
||||
onUpdate()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
|
||||
if (ismob(target))
|
||||
var/mob/living/HH = target
|
||||
if (!trophy || get_dist(M, HH) > trophy.max_range || HH == null || M == null || !ishuman(HH) || HH.stat != 2)
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
else
|
||||
var/obj/item/organ/head/SH = target
|
||||
if (!trophy || get_dist(M, SH) > trophy.max_range || SH == null || M == null || !istype(SH) || !(SH.skull && istype(SH.skull, /obj/item/skull/)))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
onEnd()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
var/datum/abilityHolder/A = trophy.holder
|
||||
A.locked = 0
|
||||
|
||||
var/tvalue = 0
|
||||
var/no_of_skulls = 0
|
||||
|
||||
M.visible_message("<span style=\"color:red\"><b>[M] completely rips [target] apart!</b></span>")
|
||||
|
||||
// Assign_gimmick_skull() takes care of skull replacements.
|
||||
if (ismob(target))
|
||||
var/mob/living/carbon/human/HH = target
|
||||
if (ishuman(HH))
|
||||
for (var/obj/item/W in HH)
|
||||
if (istype(W, /obj/item/skull/))
|
||||
var/obj/item/skull/S = W
|
||||
S.name = "[HH.real_name]'s skull"
|
||||
tvalue += S.value // Can might have another skull in their pocket, who knows.
|
||||
no_of_skulls++
|
||||
S.set_loc(get_turf(HH)) // We always want to drop that skull, since gib ejectables are a RNG thing.
|
||||
else
|
||||
HH.u_equip(W)
|
||||
if (W)
|
||||
W.set_loc(get_turf(HH))
|
||||
W.dropped(HH)
|
||||
W.layer = initial(W.layer)
|
||||
|
||||
logTheThing("combat", M, HH, "uses take trophy on %target%, gibbing them at [log_loc(M)].")
|
||||
HH.gib(1)
|
||||
|
||||
else
|
||||
var/obj/item/organ/head/SH = target
|
||||
if (istype(SH) && SH.skull && istype(SH.skull, /obj/item/skull/))
|
||||
var/obj/item/skull/S2 = SH.skull
|
||||
tvalue += S2.value
|
||||
no_of_skulls++
|
||||
S2.set_loc(get_turf(SH))
|
||||
SH.update_icon()
|
||||
|
||||
gibs(get_turf(SH))
|
||||
qdel(SH)
|
||||
|
||||
switch (no_of_skulls)
|
||||
if (0)
|
||||
boutput(M, __red("<b>Their skull was missing. No trophy for you.</b>"))
|
||||
if (1)
|
||||
if (tvalue <= 0)
|
||||
boutput(M, __red("<b>This trophy is completely worthless!</b>"))
|
||||
if (tvalue == 1)
|
||||
boutput(M, __blue("<b>This trophy has a value of [tvalue].</b>"))
|
||||
if (tvalue > 1)
|
||||
boutput(M, __blue("<b>You have slain a powerful opponent!<br>This trophy has a value of [tvalue].</b>"))
|
||||
else
|
||||
boutput(M, __blue("<b>You found mulitple trophies. They have a combined value of [tvalue].</b>"))
|
||||
|
||||
onInterrupt()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
var/datum/abilityHolder/A = trophy.holder
|
||||
|
||||
A.locked = 0
|
||||
boutput(M, __red("Your attempt to take the trophy was interrupted!"))
|
||||
@@ -0,0 +1,219 @@
|
||||
/datum/targetable/werewolf/werewolf_feast
|
||||
name = "Maul victim"
|
||||
desc = "Feast on the target to quell your hunger."
|
||||
targeted = 1
|
||||
target_nodamage_check = 1
|
||||
max_range = 1
|
||||
cooldown = 0
|
||||
pointCost = 0
|
||||
when_stunned = 0
|
||||
not_when_handcuffed = 1
|
||||
werewolf_only = 1
|
||||
restricted_area_check = 2
|
||||
|
||||
cast(mob/target)
|
||||
if (!holder)
|
||||
return 1
|
||||
|
||||
var/mob/living/M = holder.owner
|
||||
|
||||
if (!M || !target || !ismob(target))
|
||||
return 1
|
||||
|
||||
if (M == target)
|
||||
boutput(M, __red("Why would you want to maul yourself?"))
|
||||
return 1
|
||||
|
||||
if (get_dist(M, target) > src.max_range)
|
||||
boutput(M, __red("[target] is too far away."))
|
||||
return 1
|
||||
|
||||
if (!ishuman(target)) // Critter mobs include robots and combat drones. There's not a lot of meat on them.
|
||||
boutput(M, __red("[target] probably wouldn't taste very good."))
|
||||
return 1
|
||||
|
||||
if (target.canmove)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
return 1
|
||||
|
||||
logTheThing("combat", M, target, "starts to maul %target% at [log_loc(M)].")
|
||||
actions.start(new/datum/action/bar/private/icon/werewolf_feast(target, src), M)
|
||||
return 0
|
||||
|
||||
/datum/action/bar/private/icon/werewolf_feast
|
||||
duration = 300
|
||||
interrupt_flags = INTERRUPT_MOVE | INTERRUPT_ACT | INTERRUPT_STUNNED | INTERRUPT_ACTION
|
||||
id = "werewolf_feast"
|
||||
icon = 'icons/mob/critter_ui.dmi'
|
||||
icon_state = "devour_over"
|
||||
var/mob/living/target
|
||||
var/datum/targetable/werewolf/werewolf_feast/feast
|
||||
var/last_complete = 0
|
||||
var/do_we_get_points = 0 // For the specialist objective. Did we feed on the target long enough?
|
||||
|
||||
New(Target, Feast)
|
||||
target = Target
|
||||
feast = Feast
|
||||
..()
|
||||
|
||||
onStart()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
var/datum/abilityHolder/A = feast.holder
|
||||
|
||||
if (!feast || get_dist(M, target) > feast.max_range || target == null || M == null || !ishuman(target) || !ishuman(M) || !A || !istype(A))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
// It's okay when the victim expired half-way through the feast, but plain corpses are too cheap.
|
||||
if (target.stat == 2)
|
||||
boutput(M, __red("Urgh, this cadaver tasted horrible. Better find some fresh meat."))
|
||||
target.visible_message("<span style=\"color:red\"><B>[M] completely rips [target]'s corpse to pieces!</B></span>")
|
||||
target.gib()
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
A.locked = 1
|
||||
playsound(M.loc, pick('sound/misc/werewolf_attack1.ogg', 'sound/misc/werewolf_attack2.ogg', 'sound/misc/werewolf_attack3.ogg'), 50, 1)
|
||||
M.visible_message("<span style=\"color:red\"><B>[M] lunges at [target]!</b></span>")
|
||||
|
||||
onUpdate()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
var/datum/abilityHolder/A = feast.holder
|
||||
|
||||
if (!feast || get_dist(M, target) > feast.max_range || target == null || M == null || !ishuman(target) || !ishuman(M) || !A || !istype(A))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
var/done = world.time - started
|
||||
var/complete = max(min((done / duration), 1), 0)
|
||||
|
||||
if (complete >= 0.1 && last_complete < 0.1)
|
||||
if (M.werewolf_attack(target, "feast") != 1)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
if (complete >= 0.2 && last_complete < 0.2)
|
||||
if (M.werewolf_attack(target, "feast") != 1)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
if (complete >= 0.3 && last_complete < 0.3)
|
||||
if (M.werewolf_attack(target, "feast") != 1)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
if (complete >= 0.4 && last_complete < 0.4)
|
||||
if (M.werewolf_attack(target, "feast") != 1)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
if (complete >= 0.5 && last_complete < 0.5)
|
||||
if (M.werewolf_attack(target, "feast") != 1)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
if (complete >= 0.6 && last_complete < 0.6)
|
||||
if (M.werewolf_attack(target, "feast") != 1)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
if (complete >= 0.7 && last_complete < 0.7)
|
||||
if (M.werewolf_attack(target, "feast") != 1)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
if (target.stat != 2 && !(ismonkey(target) || target.bioHolder && target.bioHolder.HasEffect("monkey"))) // Can't farm monkeys.
|
||||
src.do_we_get_points = 1
|
||||
|
||||
if (complete >= 0.8 && last_complete < 0.8)
|
||||
if (M.werewolf_attack(target, "feast") != 1)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
if (target.stat != 2 && !(ismonkey(target) || target.bioHolder && target.bioHolder.HasEffect("monkey")))
|
||||
src.do_we_get_points = 1
|
||||
|
||||
if (complete >= 0.9 && last_complete < 0.9)
|
||||
if (M.werewolf_attack(target, "feast") != 1)
|
||||
boutput(M, __red("[target] is moving around too much."))
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
if (target.stat != 2 && !(ismonkey(target) || target.bioHolder && target.bioHolder.HasEffect("monkey")))
|
||||
src.do_we_get_points = 1
|
||||
|
||||
last_complete = complete
|
||||
|
||||
onEnd()
|
||||
..()
|
||||
|
||||
var/datum/abilityHolder/A = feast.holder
|
||||
var/mob/living/M = owner
|
||||
var/mob/living/carbon/human/HH = target
|
||||
|
||||
// AH parent var for AH.locked vs. specific one for the feed objective.
|
||||
// Critter mobs only use one specific type of abilityHolder for instance.
|
||||
if (istype(A, /datum/abilityHolder/werewolf))
|
||||
var/datum/abilityHolder/werewolf/W = A
|
||||
if (W.feed_objective && istype(W.feed_objective, /datum/objective/specialist/werewolf/feed/))
|
||||
if (src.do_we_get_points == 1)
|
||||
if (istype(HH) && HH.bioHolder)
|
||||
if (!W.feed_objective.mobs_fed_on.Find(HH.bioHolder.Uid))
|
||||
W.feed_objective.mobs_fed_on.Add(HH.bioHolder.Uid)
|
||||
W.feed_objective.feed_count++
|
||||
boutput(M, __blue("You finish chewing on [HH], but what a feast it was!"))
|
||||
else
|
||||
boutput(M, __red("You've mauled [HH] before and didn't like the aftertaste. Better find a different prey."))
|
||||
else
|
||||
boutput(M, __red("What a meagre meal. You're still hungry..."))
|
||||
else
|
||||
boutput(M, __red("What a meagre meal. You're still hungry..."))
|
||||
else
|
||||
boutput(M, __red("You finish chewing on [HH]."))
|
||||
else
|
||||
boutput(M, __red("You finish chewing on [HH]."))
|
||||
|
||||
if (A && istype(A))
|
||||
A.locked = 0
|
||||
|
||||
onInterrupt()
|
||||
..()
|
||||
|
||||
var/datum/abilityHolder/A = feast.holder
|
||||
var/mob/living/M = owner
|
||||
var/mob/living/carbon/human/HH = target
|
||||
|
||||
if (istype(A, /datum/abilityHolder/werewolf))
|
||||
var/datum/abilityHolder/werewolf/W = A
|
||||
if (W.feed_objective && istype(W.feed_objective, /datum/objective/specialist/werewolf/feed/))
|
||||
if (src.do_we_get_points == 1)
|
||||
if (istype(HH) && HH.bioHolder)
|
||||
if (!W.feed_objective.mobs_fed_on.Find(HH.bioHolder.Uid))
|
||||
W.feed_objective.mobs_fed_on.Add(HH.bioHolder.Uid)
|
||||
W.feed_objective.feed_count++
|
||||
boutput(M, __blue("Your feast was interrupted, but it satisfied your hunger for the time being."))
|
||||
else
|
||||
boutput(M, __red("You've mauled [HH] before and didn't like the aftertaste. Better find a different prey."))
|
||||
else
|
||||
boutput(M, __red("Your feast was interrupted and you're still hungry..."))
|
||||
else
|
||||
boutput(M, __red("Your feast was interrupted and you're still hungry..."))
|
||||
else
|
||||
boutput(M, __red("Your feast was interrupted."))
|
||||
else
|
||||
boutput(M, __red("Your feast was interrupted."))
|
||||
|
||||
if (A && istype(A))
|
||||
A.locked = 0
|
||||
@@ -0,0 +1,67 @@
|
||||
/datum/targetable/werewolf/werewolf_transform
|
||||
name = "Transform"
|
||||
desc = "Switch between human and wolf form, Takes a couple seconds to complete."
|
||||
targeted = 0
|
||||
target_nodamage_check = 0
|
||||
max_range = 0
|
||||
cooldown = 600
|
||||
pointCost = 0
|
||||
when_stunned = 1
|
||||
not_when_handcuffed = 0
|
||||
werewolf_only = 0
|
||||
|
||||
cast(mob/target)
|
||||
if (!holder)
|
||||
return 1
|
||||
|
||||
var/mob/living/M = holder.owner
|
||||
|
||||
if (!M)
|
||||
return 1
|
||||
|
||||
actions.start(new/datum/action/bar/private/icon/werewolf_transform(src), M)
|
||||
return 0
|
||||
|
||||
/datum/action/bar/private/icon/werewolf_transform
|
||||
duration = 50
|
||||
interrupt_flags = INTERRUPT_MOVE | INTERRUPT_ACT | INTERRUPT_ACTION
|
||||
id = "werewolf_transform"
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
icon_state = "grabbed"
|
||||
var/datum/targetable/werewolf/werewolf_transform/transform
|
||||
|
||||
New(Transform)
|
||||
transform = Transform
|
||||
..()
|
||||
|
||||
onStart()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
|
||||
if (M == null || !ishuman(M) || M.stat != 0 || M.paralysis > 0 || !transform)
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
boutput(M, __red("<B>You feel a strong burning sensation all over your body!</B>"))
|
||||
|
||||
onUpdate()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
|
||||
if (M == null || !ishuman(M) || M.stat != 0 || M.paralysis > 0 || !transform)
|
||||
interrupt(INTERRUPT_ALWAYS)
|
||||
return
|
||||
|
||||
onEnd()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
M.werewolf_transform(0, 1)
|
||||
|
||||
onInterrupt()
|
||||
..()
|
||||
|
||||
var/mob/living/M = owner
|
||||
boutput(M, __red("Your transformation was interrupted!"))
|
||||
Reference in New Issue
Block a user