Adds a cursed sword (and other haunted things) (#4931)
* adds cursed sword and 'haunted' object framework. * fixes back.dmi conflicts * adds cursed blade ghost pod as well as fixing some ghost pod oddities * fixes misc.dm conflicts * adds cursed sword cave POI * makes cursed sword use voice mob as opposed to a brainmob
@@ -132,3 +132,9 @@
|
||||
question = "A curious explorer has touched a mysterious rune. \
|
||||
Would you like to play as the creature it summons?"
|
||||
cutoff_number = 1
|
||||
|
||||
/datum/ghost_query/cursedblade
|
||||
role_name = "Cursed Sword"
|
||||
question = "A cursed blade has been discovered by a curious explorer. \
|
||||
Would you like to play as the soul imprisoned within?"
|
||||
cutoff_number = 1
|
||||
|
||||
@@ -51,3 +51,40 @@
|
||||
/obj/item/weapon/melee/umbrella/random/New()
|
||||
color = "#"+get_random_colour()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/cursedblade
|
||||
name = "crystal blade"
|
||||
desc = "The red crystal blade's polished surface glints in the light, giving off a faint glow."
|
||||
icon_state = "soulblade"
|
||||
slot_flags = SLOT_BELT | SLOT_BACK
|
||||
force = 30
|
||||
throwforce = 10
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
sharp = 1
|
||||
edge = 1
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
can_speak = 1
|
||||
var/list/voice_mobs = list() //The curse of the sword is that it has someone trapped inside.
|
||||
|
||||
|
||||
/obj/item/weapon/melee/cursedblade/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
|
||||
if(default_parry_check(user, attacker, damage_source) && prob(50))
|
||||
user.visible_message("<span class='danger'>\The [user] parries [attack_text] with \the [src]!</span>")
|
||||
playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/melee/cursedblade/proc/ghost_inhabit(var/mob/candidate)
|
||||
if(!isobserver(candidate))
|
||||
return
|
||||
//Handle moving the ghost into the new shell.
|
||||
announce_ghost_joinleave(candidate, 0, "They are occupying a cursed sword now.")
|
||||
var/mob/living/voice/new_voice = new /mob/living/voice(src) //Make the voice mob the ghost is going to be.
|
||||
new_voice.transfer_identity(candidate) //Now make the voice mob load from the ghost's active character in preferences.
|
||||
new_voice.mind = candidate.mind //Transfer the mind, if any.
|
||||
new_voice.ckey = candidate.ckey //Finally, bring the client over.
|
||||
new_voice.name = "cursed sword" //Cursed swords shouldn't be known characters.
|
||||
new_voice.real_name = "cursed sword"
|
||||
voice_mobs.Add(new_voice)
|
||||
listening_objects |= src
|
||||
@@ -13,6 +13,7 @@
|
||||
var/armor_penetration = 0
|
||||
var/show_messages
|
||||
var/preserve_item = 0 //whether this object is preserved when its owner goes into cryo-storage, gateway, etc
|
||||
var/can_speak = 0 //For MMIs and admin trickery. If an object has a brainmob in its contents, set this to 1 to allow it to speak.
|
||||
|
||||
var/show_examine = TRUE // Does this pop up on a mob when the mob is examined?
|
||||
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
var/needscharger //For drone pods that want their pod to turn into a charger.
|
||||
|
||||
// Call this to get a ghost volunteer.
|
||||
/obj/structure/ghost_pod/proc/trigger()
|
||||
/obj/structure/ghost_pod/proc/trigger(var/alert, var/adminalert)
|
||||
if(!ghost_query_type)
|
||||
return FALSE
|
||||
if(busy)
|
||||
return FALSE
|
||||
|
||||
visible_message(alert)
|
||||
log_and_message_admins(adminalert)
|
||||
busy = TRUE
|
||||
var/datum/ghost_query/Q = new ghost_query_type()
|
||||
var/list/winner = Q.query()
|
||||
@@ -44,7 +46,7 @@
|
||||
/obj/structure/ghost_pod/manual/attack_hand(var/mob/living/user)
|
||||
if(!used)
|
||||
if(confirm_before_open)
|
||||
if(alert(user, "Are you sure you want to open \the [src]?", "Confirm", "No", "Yes") == "No")
|
||||
if(alert(user, "Are you sure you want to touch \the [src]?", "Confirm", "No", "Yes") == "No")
|
||||
return
|
||||
trigger()
|
||||
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
needscharger = TRUE
|
||||
|
||||
/obj/structure/ghost_pod/manual/lost_drone/trigger()
|
||||
..()
|
||||
visible_message("<span class='notice'>\The [src] appears to be attempting to restart the robot contained inside.</span>")
|
||||
log_and_message_admins("is attempting to open \a [src].")
|
||||
..("<span class='notice'>\The [src] appears to be attempting to restart the robot contained inside.</span>", "is attempting to open \a [src].")
|
||||
|
||||
/obj/structure/ghost_pod/manual/lost_drone/create_occupant(var/mob/M)
|
||||
density = FALSE
|
||||
@@ -68,14 +66,13 @@
|
||||
description_info = "This will summon some manner of creature through quite dubious means. The creature will be controlled by a player."
|
||||
icon_state = "corgirune"
|
||||
icon_state_opened = "corgirune-inert"
|
||||
density = TRUE
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
ghost_query_type = /datum/ghost_query/corgi_rune
|
||||
confirm_before_open = TRUE
|
||||
|
||||
/obj/structure/ghost_pod/manual/corgi/trigger()
|
||||
..()
|
||||
visible_message("<span class='warning'>\The [usr] places their hand on the rune!</span>")
|
||||
log_and_message_admins("is attempting to summon a corgi.")
|
||||
..("<span class='warning'>\The [usr] places their hand on the rune!</span>", "is attempting to summon a corgi.")
|
||||
|
||||
/obj/structure/ghost_pod/manual/corgi/create_occupant(var/mob/M)
|
||||
density = FALSE
|
||||
@@ -87,3 +84,28 @@
|
||||
visible_message("<span class='warning'>With a bright flash of light, \the [src] disappears, and in its place stands a small corgi.</span>")
|
||||
log_and_message_admins("successfully touched \a [src] and summoned a corgi.")
|
||||
..()
|
||||
|
||||
/obj/structure/ghost_pod/manual/cursedblade
|
||||
name = "abandoned blade"
|
||||
desc = "A red crystal blade that someone jammed deep into a stone. If you try hard enough, you might be able to remove it."
|
||||
icon_state = "soulblade-embedded"
|
||||
icon_state_opened = "soulblade-released"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
ghost_query_type = /datum/ghost_query/cursedblade
|
||||
confirm_before_open = TRUE
|
||||
|
||||
/obj/structure/ghost_pod/manual/cursedblade/trigger()
|
||||
..("<span class='warning'>\The [usr] attempts to pull out the sword!</span>", "is activating a cursed blade.")
|
||||
|
||||
/obj/structure/ghost_pod/manual/cursedblade/create_occupant(var/mob/M)
|
||||
density = FALSE
|
||||
var/obj/item/weapon/melee/cursedblade/R = new(get_turf(src))
|
||||
to_chat(M, "<span class='notice'>You are a <b>Cursed Sword</b>, discovered by a hapless explorer. \
|
||||
You were once an explorer yourself, when one day you discovered a strange sword made from a red crystal. As soon as you touched it,\
|
||||
your body was reduced to ashes and your soul was cursed to remain trapped in the blade forever. \
|
||||
Now it is up to you to decide whether you want to be a faithful companion, or a bitter prisoner of the blade.</span>")
|
||||
R.ghost_inhabit(M)
|
||||
visible_message("<span class='warning'>The blade shines brightly for a brief moment as [usr] pulls it out of the stone!</span>")
|
||||
log_and_message_admins("successfully acquired a cursed sword.")
|
||||
..()
|
||||
@@ -6,6 +6,7 @@
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
icon_state = "mmi_empty"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
can_speak = 1
|
||||
origin_tech = list(TECH_BIO = 3)
|
||||
|
||||
req_access = list(access_robotics)
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
message = sanitize(message)
|
||||
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return //No MMI, can't speak, bucko./N
|
||||
if(!(container && container.can_speak))
|
||||
return //Certain objects can speak, like MMIs. Most others cannot. -Q
|
||||
else
|
||||
var/datum/language/speaking = parse_language(message)
|
||||
if(speaking)
|
||||
|
||||
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
55
maps/submaps/surface_submaps/mountains/SwordCave.dmm
Normal file
@@ -0,0 +1,55 @@
|
||||
"a" = (/turf/template_noop,/area/template_noop)
|
||||
"b" = (/turf/simulated/mineral,/area/submap/cave/swordcave)
|
||||
"c" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave)
|
||||
"d" = (/obj/machinery/crystal,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave)
|
||||
"e" = (/turf/simulated/floor/water,/area/submap/cave/swordcave)
|
||||
"f" = (/turf/simulated/floor/water/deep,/area/submap/cave/swordcave)
|
||||
"g" = (/obj/structure/ghost_pod/manual/cursedblade,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave)
|
||||
"h" = (/mob/living/simple_animal/hostile/faithless/cult,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave)
|
||||
"i" = (/obj/item/device/gps/explorer,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave)
|
||||
"j" = (/obj/structure/loot_pile/surface/bones,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave)
|
||||
"k" = (/mob/living/simple_animal/hostile/scarybat/cult,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave)
|
||||
|
||||
(1,1,1) = {"
|
||||
aaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaa
|
||||
aaaaabbbbbbbbbbbcccdccccbbbbbbbbbbbbaaaaa
|
||||
aaaabbbbbbcccccccccccccccccccccbbbbbbaaaa
|
||||
aaabbbbbbcccccccccccccccccccccccdbbbbbaaa
|
||||
aabbbbccccccceeeeeeeeeeeeeccccccccbbbbbaa
|
||||
aabbbccccccceeeeeeeeeeeeeeeccccccccbbbbaa
|
||||
aabbbcdcccceeeffffffffffffeeeccccccbbbbaa
|
||||
aabbbccccceefeeeeeeefeeeeeeeeecccccbbbbaa
|
||||
aabbbccccceefeeccceeeeeeeefffeeccccbbbaaa
|
||||
aabbbcccceeffeecccccecccceefffeecccbbbaaa
|
||||
aabbbcccceeffeeeccgcccchcceeffeecccbbbaaa
|
||||
aabbbcccdeeffeeccijcdccccceefeeccdcbbbaaa
|
||||
abbbccccceefffeeeccccccceeefeeccccccbbaaa
|
||||
abbbcccccceefffeeeccccceeeffeeccccccbbbaa
|
||||
abbbcdccccceefffeeeeeeeeffffeeccccccbbbaa
|
||||
abbcccckcccceeffffeeeeefffffeeccccccbbbaa
|
||||
abbcccccccccceeffffffffffffeeccccdccbbbaa
|
||||
abbccccccccccceeffeeeeeefffeecccccccbbbaa
|
||||
abbbccccdcccccceefeeeeeeeeeeckccccccbbbaa
|
||||
abbbcccccccccccceeecccdceeecccccccccbbaaa
|
||||
abbbcccccccccccccecccccccceccccdckccbbaaa
|
||||
abbbcccccccccckcccccccccccccccccccccbbaaa
|
||||
abbbbcccccckccccccccccccccckccccccccbbaaa
|
||||
abbbbbcccccccccccccccckccccccccckcccbbaaa
|
||||
aabbbbbccccccccccccccccccccccccccccbbbaaa
|
||||
aabbbbbccccccccccccdccccccccccccccbbbbaaa
|
||||
aabbbbbcccccdccccccccccccccccccccbbbbbaaa
|
||||
aabbbbbccccccccccckccccccccdcccccbbbbaaaa
|
||||
aabbbbbbbccccccccccccccccccccccccbbbbaaaa
|
||||
aaabbbbbbbcccccccccccccccdccccccbbbbaaaaa
|
||||
aaaabbbbbbcckcccccdcccccccccccccbbbbaaaaa
|
||||
aaaaabbbbbcccccccccccccccccccccbbbbbaaaaa
|
||||
aaaaabbbbbccccccccccccccccccccbbbbbaaaaaa
|
||||
aaaaaabbbbbcccdccccccccccccccbbbbbaaaaaaa
|
||||
aaaaaaabbbbbcccccccckccccckcbbbbbbaaaaaaa
|
||||
aaaaaaabbbbbbcccccccccccccccbbbbbaaaaaaaa
|
||||
aaaaaaabbbbbbbbbbbbccccccccccbbbaaaaaaaaa
|
||||
aaaaaaaaabbbbbbbbbbbccccccccccbaaaaaaaaaa
|
||||
aaaaaaaaaaabbbbbbbbbbccccccccccaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaacccdccccaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaccccccaaaaaaaaaaaa
|
||||
"}
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "IceCave1A.dmm"
|
||||
#include "IceCave1B.dmm"
|
||||
#include "IceCave1C.dmm"
|
||||
#include "SwordCave.dmm"
|
||||
#include "SupplyDrop1.dmm"
|
||||
#include "BlastMine1.dmm"
|
||||
#endif
|
||||
@@ -171,6 +172,11 @@
|
||||
mappath = 'maps/submaps/surface_submaps/mountains/IceCave1C.dmm'
|
||||
cost = 10
|
||||
|
||||
/datum/map_template/surface/mountains/normal/SwordCave
|
||||
name = "Cursed Sword Cave"
|
||||
desc = "An underground lake. The sword on the lake's island holds a terrible secret."
|
||||
mappath = 'maps/submaps/surface_submaps/mountains/SwordCave.dmm'
|
||||
|
||||
/datum/map_template/surface/mountains/normal/supplydrop1
|
||||
name = "Supply Drop 1"
|
||||
desc = "A drop pod that landed deep within the mountains."
|
||||
|
||||
@@ -76,13 +76,13 @@
|
||||
name = "Ice Cave 1B"
|
||||
|
||||
/area/submap/cave/IceCave1C
|
||||
|
||||
name = "Ice Cave 1C"
|
||||
name = "Mine Vault"
|
||||
|
||||
/area/submap/cave/swordcave
|
||||
name = "Cursed Sword Cave"
|
||||
|
||||
/area/submap/cave/SupplyDrop1
|
||||
name = "Supply Drop 1"
|
||||
|
||||
/area/submap/cave/BlastMine1
|
||||
name = "Blast Mine 1"
|
||||
|
||||
|
||||