[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:
tralezab
2019-03-08 05:24:57 -08:00
committed by Nich
parent 7fd7ce0e66
commit 852ad6c92f
10 changed files with 318 additions and 10 deletions

View File

@@ -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 //
/////////////

View File

@@ -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")

View File

@@ -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"

View File

@@ -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>")

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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