mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
[READY] dilutes the staff of chaos pool with some more bolts (#42719)
* staves * projectiles * sapped event * last of the staves (need to sprite and get sounds) * last of the projectiles * Squash is a single-use plant in Plants vs. Zombies and returns as a premium plant in Plants vs. Zombies 2. * removes staff of cooperation, adds fly magic status effect * a couple things with flight + tweaks * removes old bolts/staves, finishes and adds parts of the new set * fixes * fetching + flying fixes, added chill and wipe * and done * cobblestone's review
This commit is contained in:
@@ -38,6 +38,8 @@
|
||||
|
||||
#define STATUS_EFFECT_REGENERATIVE_CORE /datum/status_effect/regenerative_core
|
||||
|
||||
#define STATUS_EFFECT_ANTIMAGIC /datum/status_effect/antimagic //grants antimagic (and reapplies if lost) for the duration
|
||||
|
||||
/////////////
|
||||
// DEBUFFS //
|
||||
/////////////
|
||||
@@ -110,6 +112,8 @@
|
||||
|
||||
#define STATUS_EFFECT_HIVE_RADAR /datum/status_effect/agent_pinpointer/hivemind
|
||||
|
||||
#define STATUS_EFFECT_BOUNTY /datum/status_effect/bounty //rewards the person who added this to the target with refreshed spells and a fair heal
|
||||
|
||||
/////////////
|
||||
// SLIME //
|
||||
/////////////
|
||||
|
||||
@@ -74,26 +74,34 @@
|
||||
|
||||
/mob/camera/imaginary_friend/Login()
|
||||
..()
|
||||
greet()
|
||||
Show()
|
||||
|
||||
/mob/camera/imaginary_friend/proc/greet()
|
||||
to_chat(src, "<span class='notice'><b>You are the imaginary friend of [owner]!</b></span>")
|
||||
to_chat(src, "<span class='notice'>You are absolutely loyal to your friend, no matter what.</span>")
|
||||
to_chat(src, "<span class='notice'>You cannot directly influence the world around you, but you can see what [owner] cannot.</span>")
|
||||
Show()
|
||||
|
||||
/mob/camera/imaginary_friend/Initialize(mapload, _trauma)
|
||||
. = ..()
|
||||
var/gender = pick(MALE, FEMALE)
|
||||
real_name = random_unique_name(gender)
|
||||
name = real_name
|
||||
|
||||
trauma = _trauma
|
||||
owner = trauma.owner
|
||||
copy_known_languages_from(owner, TRUE)
|
||||
human_image = get_flat_human_icon(null, pick(SSjob.occupations))
|
||||
|
||||
setup_friend()
|
||||
|
||||
join = new
|
||||
join.Grant(src)
|
||||
hide = new
|
||||
hide.Grant(src)
|
||||
|
||||
/mob/camera/imaginary_friend/proc/setup_friend()
|
||||
var/gender = pick(MALE, FEMALE)
|
||||
real_name = random_unique_name(gender)
|
||||
name = real_name
|
||||
human_image = get_flat_human_icon(null, pick(SSjob.occupations))
|
||||
|
||||
/mob/camera/imaginary_friend/proc/Show()
|
||||
if(!client) //nobody home
|
||||
return
|
||||
@@ -219,3 +227,41 @@
|
||||
I.hidden = !I.hidden
|
||||
I.Show()
|
||||
update_status()
|
||||
|
||||
//down here is the trapped mind
|
||||
//like imaginary friend but a lot less imagination and more like mind prison//
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/trapped_owner
|
||||
name = "Trapped Victim"
|
||||
desc = "Patient appears to be targeted by an invisible entity."
|
||||
gain_text = ""
|
||||
lose_text = ""
|
||||
random_gain = FALSE
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/trapped_owner/make_friend()
|
||||
friend = new /mob/camera/imaginary_friend/trapped(get_turf(owner), src)
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/trapped_owner/reroll_friend() //no rerolling- it's just the last owner's hell
|
||||
if(friend.client) //reconnected
|
||||
return
|
||||
friend_initialized = FALSE
|
||||
QDEL_NULL(friend)
|
||||
qdel(src)
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/trapped_owner/get_ghost() //no randoms
|
||||
return
|
||||
|
||||
/mob/camera/imaginary_friend/trapped
|
||||
name = "figment of imagination?"
|
||||
real_name = "figment of imagination?"
|
||||
desc = "The previous host of this body."
|
||||
|
||||
/mob/camera/imaginary_friend/trapped/greet()
|
||||
to_chat(src, "<span class='notice'><b>You have managed to hold on as a figment of the new host's imagination!</b></span>")
|
||||
to_chat(src, "<span class='notice'>All hope is lost for you, but at least you may interact with your host. You do not have to be loyal to them.</span>")
|
||||
to_chat(src, "<span class='notice'>You cannot directly influence the world around you, but you can see what the host cannot.</span>")
|
||||
|
||||
/mob/camera/imaginary_friend/trapped/setup_friend()
|
||||
real_name = "[owner.real_name]?"
|
||||
name = real_name
|
||||
human_image = icon('icons/mob/lavaland/lavaland_monsters.dmi', icon_state = "curseblob")
|
||||
|
||||
@@ -167,6 +167,13 @@
|
||||
mood_change = -3
|
||||
timeout = 900
|
||||
|
||||
/datum/mood_event/sapped
|
||||
description = "<span class='boldwarning'>Some unexplainable sadness is consuming me...</span>\n"
|
||||
mood_change = -15
|
||||
timeout = 900
|
||||
|
||||
/datum/mood_event/sapped
|
||||
|
||||
//These are unused so far but I want to remember them to use them later
|
||||
/datum/mood_event/cloned_corpse
|
||||
description = "<span class='boldwarning'>I recently saw my own corpse...</span>\n"
|
||||
|
||||
@@ -579,3 +579,19 @@
|
||||
|
||||
/datum/status_effect/regenerative_core/on_remove()
|
||||
owner.remove_trait(TRAIT_IGNOREDAMAGESLOWDOWN, "regenerative_core")
|
||||
|
||||
/datum/status_effect/antimagic
|
||||
id = "antimagic"
|
||||
duration = 10 SECONDS
|
||||
examine_text = "<span class='notice'>They seem to be covered in a dull, grey aura.</span>"
|
||||
|
||||
/datum/status_effect/antimagic/on_apply()
|
||||
owner.visible_message("<span class='notice'>[owner] is coated with a dull aura!</span>")
|
||||
owner.add_trait(TRAIT_ANTIMAGIC, MAGIC_TRAIT)
|
||||
//glowing wings overlay
|
||||
playsound(owner, 'sound/weapons/fwoosh.wav', 75, 0)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/antimagic/on_remove()
|
||||
owner.remove_trait(TRAIT_ANTIMAGIC, MAGIC_TRAIT)
|
||||
owner.visible_message("<span class='warning'>[owner]'s dull aura fades away...</span>")
|
||||
|
||||
@@ -85,6 +85,41 @@
|
||||
. = ..()
|
||||
owner.remove_trait(TRAIT_SOOTHED_THROAT, "[STATUS_EFFECT_TRAIT]_[id]")
|
||||
|
||||
/datum/status_effect/bounty
|
||||
id = "bounty"
|
||||
status_type = STATUS_EFFECT_UNIQUE
|
||||
var/mob/living/rewarded
|
||||
|
||||
/datum/status_effect/bounty/on_creation(mob/living/new_owner, mob/living/caster)
|
||||
. = ..()
|
||||
if(.)
|
||||
rewarded = caster
|
||||
|
||||
/datum/status_effect/bounty/on_apply()
|
||||
to_chat(owner, "<span class='boldnotice'>You hear something behind you talking...</span> <span class='notice'>You have been marked for death by [rewarded]. If you die, they will be rewarded.</span>")
|
||||
playsound(owner, 'sound/weapons/shotgunpump.ogg', 75, 0)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/bounty/tick()
|
||||
if(owner.stat == DEAD)
|
||||
rewards()
|
||||
qdel(src)
|
||||
|
||||
/datum/status_effect/bounty/proc/rewards()
|
||||
if(rewarded && rewarded.mind && rewarded.stat != DEAD)
|
||||
to_chat(owner, "<span class='boldnotice'>You hear something behind you talking...</span> <span class='notice'>Bounty claimed.</span>")
|
||||
playsound(owner, 'sound/weapons/shotgunshot.ogg', 75, 0)
|
||||
to_chat(rewarded, "<span class='greentext'>You feel a surge of mana flow into you!</span>")
|
||||
for(var/obj/effect/proc_holder/spell/spell in rewarded.mind.spell_list)
|
||||
spell.charge_counter = spell.charge_max
|
||||
spell.recharging = FALSE
|
||||
spell.update_icon()
|
||||
rewarded.adjustBruteLoss(-25)
|
||||
rewarded.adjustFireLoss(-25)
|
||||
rewarded.adjustToxLoss(-25)
|
||||
rewarded.adjustOxyLoss(-25)
|
||||
rewarded.adjustCloneLoss(-25)
|
||||
|
||||
/datum/status_effect/bugged //Lets another mob hear everything you can
|
||||
id = "bugged"
|
||||
duration = -1
|
||||
|
||||
@@ -47,3 +47,21 @@
|
||||
|
||||
/obj/item/ammo_casing/magic/locker
|
||||
projectile_type = /obj/item/projectile/magic/locker
|
||||
|
||||
/obj/item/ammo_casing/magic/flying
|
||||
projectile_type = /obj/item/projectile/magic/flying
|
||||
|
||||
/obj/item/ammo_casing/magic/bounty
|
||||
projectile_type = /obj/item/projectile/magic/bounty
|
||||
|
||||
/obj/item/ammo_casing/magic/antimagic
|
||||
projectile_type = /obj/item/projectile/magic/antimagic
|
||||
|
||||
/obj/item/ammo_casing/magic/sapping
|
||||
projectile_type = /obj/item/projectile/magic/sapping
|
||||
|
||||
/obj/item/ammo_casing/magic/necropotence
|
||||
projectile_type = /obj/item/projectile/magic/necropotence
|
||||
|
||||
/obj/item/ammo_casing/magic/wipe
|
||||
projectile_type = /obj/item/projectile/magic/wipe
|
||||
|
||||
@@ -43,7 +43,9 @@
|
||||
no_den_usage = 1
|
||||
var/allowed_projectile_types = list(/obj/item/projectile/magic/change, /obj/item/projectile/magic/animate, /obj/item/projectile/magic/resurrection,
|
||||
/obj/item/projectile/magic/death, /obj/item/projectile/magic/teleport, /obj/item/projectile/magic/door, /obj/item/projectile/magic/aoe/fireball,
|
||||
/obj/item/projectile/magic/spellblade, /obj/item/projectile/magic/arcane_barrage, /obj/item/projectile/magic/locker)
|
||||
/obj/item/projectile/magic/spellblade, /obj/item/projectile/magic/arcane_barrage, /obj/item/projectile/magic/locker, /obj/item/projectile/magic/flying,
|
||||
/obj/item/projectile/magic/bounty, /obj/item/projectile/magic/antimagic, /obj/item/projectile/magic/fetch, /obj/item/projectile/magic/sapping,
|
||||
/obj/item/projectile/magic/necropotence, /obj/item/projectile/magic, /obj/item/projectile/temp/chill, /obj/item/projectile/magic/wipe)
|
||||
|
||||
/obj/item/gun/magic/staff/chaos/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
|
||||
chambered.projectile_type = pick(allowed_projectile_types)
|
||||
@@ -105,4 +107,36 @@
|
||||
max_charges = 6
|
||||
recharge_rate = 4
|
||||
|
||||
//yes, they don't have sounds. they're admin staves, and their projectiles will play the chaos bolt sound anyway so why bother?
|
||||
|
||||
/obj/item/gun/magic/staff/flying
|
||||
name = "staff of flying"
|
||||
desc = "An artefact that spits bolts of graceful magic that can make something fly."
|
||||
fire_sound = 'sound/magic/staff_healing.ogg'
|
||||
ammo_type = /obj/item/ammo_casing/magic/flying
|
||||
icon_state = "staffofflight"
|
||||
item_state = "staffofflight"
|
||||
|
||||
/obj/item/gun/magic/staff/sapping
|
||||
name = "staff of sapping"
|
||||
desc = "An artefact that spits bolts of sapping magic that can make something sad."
|
||||
fire_sound = 'sound/magic/staff_change.ogg'
|
||||
ammo_type = /obj/item/ammo_casing/magic/sapping
|
||||
icon_state = "staffofsapping"
|
||||
item_state = "staffofsapping"
|
||||
|
||||
/obj/item/gun/magic/staff/necropotence
|
||||
name = "staff of necropotence"
|
||||
desc = "An artefact that spits bolts of death magic that can repurpose the soul."
|
||||
fire_sound = 'sound/magic/staff_change.ogg'
|
||||
ammo_type = /obj/item/ammo_casing/magic/necropotence
|
||||
icon_state = "staffofnecropotence"
|
||||
item_state = "staffofnecropotence"
|
||||
|
||||
/obj/item/gun/magic/staff/wipe
|
||||
name = "staff of possession"
|
||||
desc = "An artefact that spits bolts of mind-unlocking magic that can let ghosts invade the victim's mind."
|
||||
fire_sound = 'sound/magic/staff_change.ogg'
|
||||
ammo_type = /obj/item/ammo_casing/magic/wipe
|
||||
icon_state = "staffofwipe"
|
||||
item_state = "staffofwipe"
|
||||
|
||||
@@ -451,6 +451,142 @@
|
||||
addtimer(CALLBACK(src, .proc/decay), 15 SECONDS)
|
||||
icon_welded = "welded"
|
||||
|
||||
/obj/item/projectile/magic/flying
|
||||
name = "bolt of flying"
|
||||
icon_state = "flight"
|
||||
|
||||
/obj/item/projectile/magic/flying/on_hit(target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.anti_magic_check())
|
||||
L.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
|
||||
return BULLET_ACT_BLOCK
|
||||
var/atom/throw_target = get_edge_target_turf(L, angle2dir(Angle))
|
||||
L.throw_at(throw_target, 200, 4)
|
||||
|
||||
/obj/item/projectile/magic/bounty
|
||||
name = "bolt of bounty"
|
||||
icon_state = "bounty"
|
||||
|
||||
/obj/item/projectile/magic/bounty/on_hit(target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.anti_magic_check() || !firer)
|
||||
L.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
|
||||
return BULLET_ACT_BLOCK
|
||||
L.apply_status_effect(STATUS_EFFECT_BOUNTY, firer)
|
||||
|
||||
/obj/item/projectile/magic/antimagic
|
||||
name = "bolt of antimagic"
|
||||
icon_state = "antimagic"
|
||||
|
||||
/obj/item/projectile/magic/antimagic/on_hit(target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.anti_magic_check())
|
||||
L.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
|
||||
return BULLET_ACT_BLOCK
|
||||
L.apply_status_effect(STATUS_EFFECT_ANTIMAGIC)
|
||||
|
||||
/obj/item/projectile/magic/fetch
|
||||
name = "bolt of fetching"
|
||||
icon_state = "fetch"
|
||||
|
||||
/obj/item/projectile/magic/fetch/on_hit(target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.anti_magic_check() || !firer)
|
||||
L.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
|
||||
return BULLET_ACT_BLOCK
|
||||
var/atom/throw_target = get_edge_target_turf(L, get_dir(L, firer))
|
||||
L.throw_at(throw_target, 200, 4)
|
||||
|
||||
/obj/item/projectile/magic/sapping
|
||||
name = "bolt of sapping"
|
||||
icon_state = "sapping"
|
||||
|
||||
/obj/item/projectile/magic/sapping/on_hit(target)
|
||||
. = ..()
|
||||
if(ismob(target))
|
||||
var/mob/M = target
|
||||
if(M.anti_magic_check())
|
||||
M.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
|
||||
return BULLET_ACT_BLOCK
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, src, /datum/mood_event/sapped)
|
||||
|
||||
/obj/item/projectile/magic/necropotence
|
||||
name = "bolt of necropotence"
|
||||
icon_state = "necropotence"
|
||||
|
||||
/obj/item/projectile/magic/necropotence/on_hit(target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.anti_magic_check() || !L.mind || !L.mind.hasSoul)
|
||||
L.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
|
||||
return BULLET_ACT_BLOCK
|
||||
to_chat(L, "<span class='danger'>Your body feels drained and there is a burning pain in your chest.</span>")
|
||||
L.maxHealth -= 20
|
||||
L.health = min(L.health, L.maxHealth)
|
||||
if(L.maxHealth <= 0)
|
||||
to_chat(L, "<span class='userdanger'>Your weakened soul is completely consumed by the [src]!</span>")
|
||||
L.mind.hasSoul = FALSE
|
||||
for(var/obj/effect/proc_holder/spell/spell in L.mind.spell_list)
|
||||
spell.charge_counter = spell.charge_max
|
||||
spell.recharging = FALSE
|
||||
spell.update_icon()
|
||||
|
||||
/obj/item/projectile/magic/wipe
|
||||
name = "bolt of possession"
|
||||
icon_state = "wipe"
|
||||
|
||||
/obj/item/projectile/magic/wipe/on_hit(target)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
if(M.anti_magic_check())
|
||||
M.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
|
||||
return BULLET_ACT_BLOCK
|
||||
for(var/x in M.get_traumas())//checks to see if the victim is already going through possession
|
||||
if(istype(x, /datum/brain_trauma/special/imaginary_friend/trapped_owner))
|
||||
M.visible_message("<span class='warning'>[src] vanishes on contact with [target]!</span>")
|
||||
return BULLET_ACT_BLOCK
|
||||
to_chat(M, "<span class='warning'>Your mind has been opened to possession!</span>")
|
||||
possession_test(M)
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
/obj/item/projectile/magic/wipe/proc/possession_test(var/mob/living/carbon/M)
|
||||
var/datum/brain_trauma/special/imaginary_friend/trapped_owner/trauma = M.gain_trauma(/datum/brain_trauma/special/imaginary_friend/trapped_owner)
|
||||
var/poll_message = "Do you want to play as [M.real_name]?"
|
||||
if(M.mind && M.mind.assigned_role)
|
||||
poll_message = "[poll_message] Job:[M.mind.assigned_role]."
|
||||
if(M.mind && M.mind.special_role)
|
||||
poll_message = "[poll_message] Status:[M.mind.special_role]."
|
||||
else if(M.mind)
|
||||
var/datum/antagonist/A = M.mind.has_antag_datum(/datum/antagonist/)
|
||||
if(A)
|
||||
poll_message = "[poll_message] Status:[A.name]."
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob(poll_message, ROLE_PAI, null, FALSE, 100, M)
|
||||
if(M.stat == DEAD)//boo.
|
||||
return
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
to_chat(M, "You have been noticed by a ghost, and it has possessed you!")
|
||||
var/oldkey = M.key
|
||||
M.ghostize(0)
|
||||
M.key = C.key
|
||||
trauma.friend.key = oldkey
|
||||
trauma.friend.reset_perspective(null)
|
||||
trauma.friend.Show()
|
||||
trauma.friend_initialized = TRUE
|
||||
else
|
||||
to_chat(M, "<span class='notice'>Your mind has managed to go unnoticed in the spirit world.</span>")
|
||||
qdel(trauma)
|
||||
|
||||
/obj/item/projectile/magic/aoe
|
||||
name = "Area Bolt"
|
||||
desc = "What the fuck does this do?!"
|
||||
@@ -540,3 +676,15 @@
|
||||
var/turf/T = get_turf(target)
|
||||
for(var/i=0, i<50, i+=10)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, T, -1, exp_heavy, exp_light, exp_flash, FALSE, FALSE, exp_fire), i)
|
||||
|
||||
//still magic related, but a different path
|
||||
|
||||
/obj/item/projectile/temp/chill
|
||||
name = "bolt of chills"
|
||||
icon_state = "ice_2"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
armour_penetration = 100
|
||||
temperature = 50
|
||||
flag = "magic"
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 120 KiB |
Reference in New Issue
Block a user