initial commit - cross reference with 5th port - obviously has compile errors

This commit is contained in:
LetterJay
2016-07-03 02:17:19 -05:00
commit 35a1723e98
4355 changed files with 2221257 additions and 0 deletions
+598
View File
@@ -0,0 +1,598 @@
//Apprenticeship contract - moved to antag_spawner.dm
///////////////////////////Veil Render//////////////////////
/obj/item/weapon/veilrender
name = "veil render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast city."
icon = 'icons/obj/wizard.dmi'
icon_state = "render"
item_state = "render"
force = 15
throwforce = 10
w_class = 3
hitsound = 'sound/weapons/bladeslice.ogg'
var/charges = 1
var/spawn_type = /obj/singularity/wizard
var/spawn_amt = 1
var/activate_descriptor = "reality"
var/rend_desc = "You should run now."
var/spawn_fast = 0 //if 1, ignores checking for mobs on loc before spawning
/obj/item/weapon/veilrender/attack_self(mob/user)
if(charges > 0)
new /obj/effect/rend(get_turf(user), spawn_type, spawn_amt, rend_desc, spawn_fast)
charges--
user.visible_message("<span class='boldannounce'>[src] hums with power as [user] deals a blow to [activate_descriptor] itself!</span>")
else
user << "<span class='danger'>The unearthly energies that powered the blade are now dormant.</span>"
/obj/effect/rend
name = "tear in the fabric of reality"
desc = "You should run now."
icon = 'icons/obj/biomass.dmi'
icon_state = "rift"
density = 1
unacidable = 1
anchored = 1
var/spawn_path = /mob/living/simple_animal/cow //defaulty cows to prevent unintentional narsies
var/spawn_amt_left = 20
var/spawn_fast = 0
/obj/effect/rend/New(loc, var/spawn_type, var/spawn_amt, var/desc, var/spawn_fast)
src.spawn_path = spawn_type
src.spawn_amt_left = spawn_amt
src.desc = desc
src.spawn_fast = spawn_fast
START_PROCESSING(SSobj, src)
return
/obj/effect/rend/process()
if(!spawn_fast)
if(locate(/mob) in loc)
return
new spawn_path(loc)
spawn_amt_left--
if(spawn_amt_left <= 0)
qdel(src)
/obj/effect/rend/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/nullrod))
user.visible_message("<span class='danger'>[user] seals \the [src] with \the [I].</span>")
qdel(src)
return
else
return ..()
/obj/item/weapon/veilrender/vealrender
name = "veal render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast farm."
spawn_type = /mob/living/simple_animal/cow
spawn_amt = 20
activate_descriptor = "hunger"
rend_desc = "Reverberates with the sound of ten thousand moos."
/obj/item/weapon/veilrender/honkrender
name = "honk render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast circus."
spawn_type = /mob/living/simple_animal/hostile/retaliate/clown
spawn_amt = 10
activate_descriptor = "depression"
rend_desc = "Gently wafting with the sounds of endless laughter."
icon_state = "clownrender"
////TEAR IN REALITY
/obj/singularity/wizard
name = "tear in the fabric of reality"
desc = "This isn't right."
icon = 'icons/obj/singularity.dmi'
icon_state = "singularity_s1"
icon = 'icons/effects/224x224.dmi'
icon_state = "reality"
pixel_x = -96
pixel_y = -96
grav_pull = 6
consume_range = 3
current_size = STAGE_FOUR
allowed_size = STAGE_FOUR
/obj/singularity/wizard/process()
move()
eat()
return
/////////////////////////////////////////Scrying///////////////////
/obj/item/weapon/scrying
name = "scrying orb"
desc = "An incandescent orb of otherworldly energy, staring into it gives you vision beyond mortal means."
icon = 'icons/obj/projectiles.dmi'
icon_state ="bluespace"
throw_speed = 3
throw_range = 7
throwforce = 15
damtype = BURN
force = 15
hitsound = 'sound/items/welder2.ogg'
/obj/item/weapon/scrying/attack_self(mob/user)
user << "<span class='notice'>You can see...everything!</span>"
visible_message("<span class='danger'>[user] stares into [src], their eyes glazing over.</span>")
user.ghostize(1)
return
/////////////////////////////////////////Necromantic Stone///////////////////
/obj/item/device/necromantic_stone
name = "necromantic stone"
desc = "A shard capable of resurrecting humans as skeleton thralls."
icon = 'icons/obj/wizard.dmi'
icon_state = "necrostone"
item_state = "electronic"
origin_tech = "bluespace=4;materials=4"
w_class = 1
var/list/spooky_scaries = list()
var/unlimited = 0
/obj/item/device/necromantic_stone/unlimited
unlimited = 1
/obj/item/device/necromantic_stone/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
if(!istype(M))
return ..()
if(!istype(user) || !user.canUseTopic(M,1))
return
if(M.stat != DEAD)
user << "<span class='warning'>This artifact can only affect the dead!</span>"
return
if(!M.mind || !M.client)
user << "<span class='warning'>There is no soul connected to this body...</span>"
return
check_spooky()//clean out/refresh the list
if(spooky_scaries.len >= 3 && !unlimited)
user << "<span class='warning'>This artifact can only affect three undead at a time!</span>"
return
M.set_species(/datum/species/skeleton, icon_update=0)
M.revive(full_heal = 1, admin_revive = 1)
spooky_scaries |= M
M << "<span class='userdanger'>You have been revived by </span><B>[user.real_name]!</B>"
M << "<span class='userdanger'>They are your master now, assist them even if it costs you your new life!</span>"
equip_roman_skeleton(M)
desc = "A shard capable of resurrecting humans as skeleton thralls[unlimited ? "." : ", [spooky_scaries.len]/3 active thralls."]"
/obj/item/device/necromantic_stone/proc/check_spooky()
if(unlimited) //no point, the list isn't used.
return
for(var/X in spooky_scaries)
if(!istype(X, /mob/living/carbon/human))
spooky_scaries.Remove(X)
continue
var/mob/living/carbon/human/H = X
if(H.stat == DEAD)
spooky_scaries.Remove(X)
continue
listclearnulls(spooky_scaries)
//Funny gimmick, skeletons always seem to wear roman/ancient armour
/obj/item/device/necromantic_stone/proc/equip_roman_skeleton(mob/living/carbon/human/H)
for(var/obj/item/I in H)
H.unEquip(I)
var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionaire)
H.equip_to_slot_or_del(new hat(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/under/roman(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/weapon/shield/riot/roman(H), slot_l_hand)
H.equip_to_slot_or_del(new /obj/item/weapon/claymore(H), slot_r_hand)
H.equip_to_slot_or_del(new /obj/item/weapon/twohanded/spear(H), slot_back)
/////////////////////Multiverse Blade////////////////////
var/global/list/multiverse = list()
/obj/item/weapon/multisword
name = "multiverse sword"
desc = "A weapon capable of conquering the universe and beyond. Activate it to summon copies of yourself from others dimensions to fight by your side."
icon = 'icons/obj/weapons.dmi'
icon_state = "multiverse"
item_state = "multiverse"
hitsound = 'sound/weapons/bladeslice.ogg'
flags = CONDUCT
slot_flags = SLOT_BELT
force = 20
throwforce = 10
w_class = 2
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
var/faction = list("unassigned")
var/cooldown = 0
var/assigned = "unassigned"
var/evil = TRUE
/obj/item/weapon/multisword/New()
..()
multiverse |= src
/obj/item/weapon/multisword/Destroy()
multiverse.Remove(src)
return ..()
/obj/item/weapon/multisword/attack_self(mob/user)
if(user.mind.special_role == "apprentice")
user << "<span class='warning'>You know better than to touch your teacher's stuff.</span>"
return
if(cooldown < world.time)
var/faction_check = 0
for(var/F in faction)
if(F in user.faction)
faction_check = 1
break
if(faction_check == 0)
faction = list("[user.real_name]")
assigned = "[user.real_name]"
user.faction = list("[user.real_name]")
user << "You bind the sword to yourself. You can now use it to summon help."
if(!usr.mind.special_role)
if(prob(30))
user << "<span class='warning'><B>With your new found power you could easily conquer the station!</B></span>"
var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone
hijack_objective.owner = usr.mind
usr.mind.objectives += hijack_objective
hijack_objective.explanation_text = "Ensure only [usr.real_name] and their copies are on the shuttle!"
usr << "<B>Objective #[1]</B>: [hijack_objective.explanation_text]"
ticker.mode.traitors += usr.mind
usr.mind.special_role = "[usr.real_name] Prime"
evil = TRUE
else
user << "<span class='warning'><B>With your new found power you could easily defend the station!</B></span>"
var/datum/objective/survive/new_objective = new /datum/objective/survive
new_objective.owner = usr.mind
new_objective.explanation_text = "Survive, and help defend the innocent from the mobs of multiverse clones."
usr << "<B>Objective #[1]</B>: [new_objective.explanation_text]"
usr.mind.objectives += new_objective
ticker.mode.traitors += usr.mind
usr.mind.special_role = "[usr.real_name] Prime"
evil = FALSE
else
var/list/candidates = get_candidates(ROLE_WIZARD)
if(candidates.len)
var/client/C = pick(candidates)
spawn_copy(C, get_turf(user.loc), user)
user << "<span class='warning'><B>The sword flashes, and you find yourself face to face with...you!</B></span>"
cooldown = world.time + 400
for(var/obj/item/weapon/multisword/M in multiverse)
if(M.assigned == assigned)
M.cooldown = cooldown
else
user << "You fail to summon any copies of yourself. Perhaps you should try again in a bit."
else
user << "<span class='warning'><B>[src] is recharging! Keep in mind it shares a cooldown with the swords wielded by your copies.</span>"
/obj/item/weapon/multisword/proc/spawn_copy(var/client/C, var/turf/T)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
C.prefs.copy_to(M, icon_updates=0)
M.key = C.key
M.mind.name = usr.real_name
M << "<B>You are an alternate version of [usr.real_name] from another universe! Help them accomplish their goals at all costs.</B>"
M.real_name = usr.real_name
M.name = usr.real_name
M.faction = list("[usr.real_name]")
if(prob(50))
var/list/all_species = list()
for(var/speciestype in subtypesof(/datum/species))
var/datum/species/S = new speciestype()
if(!S.dangerous_existence)
all_species += speciestype
M.set_species(pick(all_species), icon_update=0)
M.update_body()
M.update_hair()
M.update_body_parts()
M.dna.update_dna_identity()
equip_copy(M)
if(evil)
var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone
hijack_objective.owner = M.mind
M.mind.objectives += hijack_objective
hijack_objective.explanation_text = "Ensure only [usr.real_name] and their copies are on the shuttle!"
M << "<B>Objective #[1]</B>: [hijack_objective.explanation_text]"
M.mind.special_role = "multiverse traveller"
log_game("[M.key] was made a multiverse traveller with the objective to help [usr.real_name] hijack.")
else
var/datum/objective/protect/new_objective = new /datum/objective/protect
new_objective.owner = M.mind
new_objective.target = usr.mind
new_objective.explanation_text = "Protect [usr.real_name], your copy, and help them defend the innocent from the mobs of multiverse clones."
M.mind.objectives += new_objective
M << "<B>Objective #[1]</B>: [new_objective.explanation_text]"
M.mind.special_role = "multiverse traveller"
log_game("[M.key] was made a multiverse traveller with the objective to help [usr.real_name] protect the station.")
/obj/item/weapon/multisword/proc/equip_copy(var/mob/living/carbon/human/M)
var/obj/item/weapon/multisword/sword = new /obj/item/weapon/multisword
sword.assigned = assigned
sword.faction = list("[assigned]")
sword.evil = evil
var/randomize = pick("mobster","roman","wizard","cyborg","syndicate","assistant", "animu", "cultist", "highlander", "clown", "killer", "pirate", "soviet", "officer", "gladiator")
switch(randomize)
if("mobster")
M.equip_to_slot_or_del(new /obj/item/clothing/head/fedora(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket/really_black(M), slot_w_uniform)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("roman")
var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionaire)
M.equip_to_slot_or_del(new hat(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/under/roman(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/weapon/shield/riot/roman(M), slot_l_hand)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("wizard")
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(M), slot_head)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("cyborg")
for(var/X in M.bodyparts)
var/obj/item/bodypart/affecting = X
affecting.change_bodypart_status(ORGAN_ROBOTIC)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("syndicate")
M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/swat(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M),slot_wear_mask)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("assistant")
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/black(M), slot_shoes)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("animu")
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/head/kitty(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/under/schoolgirl/red(M), slot_w_uniform)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("cultist")
M.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("highlander")
M.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/head/beret(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("clown")
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/clown(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(M), slot_l_store)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("killer")
M.equip_to_slot_or_del(new /obj/item/clothing/under/overalls(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/white(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/latex(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/clothing/head/welding(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/knife(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/scalpel(M), slot_r_store)
M.equip_to_slot_or_del(sword, slot_r_hand)
for(var/obj/item/carried_item in M.contents)
if(!istype(carried_item, /obj/item/weapon/implant))
carried_item.add_mob_blood(M)
if("pirate")
M.equip_to_slot_or_del(new /obj/item/clothing/under/pirate(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/brown(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/head/bandana(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("soviet")
M.equip_to_slot_or_del(new /obj/item/clothing/head/hgpiratecap(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/hgpirate(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("officer")
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/beret(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/havana(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/jacket/miljacket(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses)
M.equip_to_slot_or_del(sword, slot_r_hand)
if("gladiator")
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/gladiator(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/under/gladiator(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
M.equip_to_slot_or_del(sword, slot_r_hand)
else
return
M.update_icons()
M.update_body_parts()
var/obj/item/weapon/card/id/W = new /obj/item/weapon/card/id
W.icon_state = "centcom"
W.access += access_maint_tunnels
W.assignment = "Multiverse Traveller"
W.registered_name = M.real_name
W.update_label(M.real_name)
M.equip_to_slot_or_del(W, slot_wear_id)
/obj/item/voodoo
name = "wicker doll"
desc = "Something creepy about it."
icon = 'icons/obj/wizard.dmi'
icon_state = "voodoo"
item_state = "electronic"
var/mob/living/carbon/human/target = null
var/list/mob/living/carbon/human/possible = list()
var/obj/item/link = null
var/cooldown_time = 30 //3s
var/cooldown = 0
burntime = 0
burn_state = FLAMMABLE
/obj/item/voodoo/attackby(obj/item/I, mob/user, params)
if(target && cooldown < world.time)
if(I.is_hot())
target << "<span class='userdanger'>You suddenly feel very hot</span>"
target.bodytemperature += 50
GiveHint(target)
else if(is_pointed(I))
target << "<span class='userdanger'>You feel a stabbing pain in [parse_zone(user.zone_selected)]!</span>"
target.Weaken(2)
GiveHint(target)
else if(istype(I,/obj/item/weapon/bikehorn))
target << "<span class='userdanger'>HONK</span>"
target << 'sound/items/AirHorn.ogg'
target.adjustEarDamage(0,3)
GiveHint(target)
cooldown = world.time +cooldown_time
return
if(!link)
if(I.loc == user && istype(I) && I.w_class <= 2)
user.drop_item()
I.loc = src
link = I
user << "You attach [I] to the doll."
update_targets()
/obj/item/voodoo/check_eye(mob/user)
if(loc != user)
user.reset_perspective(null)
user.unset_machine()
/obj/item/voodoo/attack_self(mob/user)
if(!target && possible.len)
target = input(user, "Select your victim!", "Voodoo") as null|anything in possible
return
if(user.zone_selected == "chest")
if(link)
target = null
link.loc = get_turf(src)
user << "<span class='notice'>You remove the [link] from the doll.</span>"
link = null
update_targets()
return
if(target && cooldown < world.time)
switch(user.zone_selected)
if("mouth")
var/wgw = sanitize(input(user, "What would you like the victim to say", "Voodoo", null) as text)
target.say(wgw)
log_game("[user][user.key] made [target][target.key] say [wgw] with a voodoo doll.")
if("eyes")
user.set_machine(src)
user.reset_perspective(target)
spawn(100)
user.reset_perspective(null)
user.unset_machine()
if("r_leg","l_leg")
user << "<span class='notice'>You move the doll's legs around.</span>"
var/turf/T = get_step(target,pick(cardinal))
target.Move(T)
if("r_arm","l_arm")
//use active hand on random nearby mob
var/list/nearby_mobs = list()
for(var/mob/living/L in range(1, target))
if(L!=target)
nearby_mobs |= L
if(nearby_mobs.len)
var/mob/living/T = pick(nearby_mobs)
log_game("[user][user.key] made [target][target.key] click on [T] with a voodoo doll.")
target.ClickOn(T)
GiveHint(target)
if("head")
user << "<span class='notice'>You smack the doll's head with your hand.</span>"
target.Dizzy(10)
target << "<span class='warning'>You suddenly feel as if your head was hit with a hammer!</span>"
GiveHint(target,user)
cooldown = world.time + cooldown_time
/obj/item/voodoo/proc/update_targets()
possible = list()
if(!link)
return
for(var/mob/living/carbon/human/H in living_mob_list)
if(md5(H.dna.uni_identity) in link.fingerprints)
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
if(prob(50) || force)
var/way = dir2text(get_dir(victim,get_turf(src)))
victim << "<span class='notice'>You feel a dark presence from [way]</span>"
if(prob(20) || force)
var/area/A = get_area(src)
victim << "<span class='notice'>You feel a dark presence from [A.name]</span>"
/obj/item/voodoo/fire_act()
if(target)
target.adjust_fire_stacks(20)
target.IgniteMob()
GiveHint(target,1)
return ..()
//Provides a decent heal, need to pump every 6 seconds
/obj/item/organ/heart/cursed/wizard
pump_delay = 60
heal_brute = 25
heal_burn = 25
heal_oxy = 25
+160
View File
@@ -0,0 +1,160 @@
/datum/game_mode/wizard/raginmages
name = "ragin' mages"
config_tag = "raginmages"
required_players = 20
use_huds = 1
var/max_mages = 0
var/making_mage = 0
var/mages_made = 1
var/time_checked = 0
var/bullshit_mode = 0 // requested by hornygranny
var/time_check = 1500
var/spawn_delay_min = 500
var/spawn_delay_max = 700
/datum/game_mode/wizard/announce()
world << "<B>The current game mode is - Ragin' Mages!</B>"
world << "<B>The <span class='warning'>Space Wizard Federation</span> is pissed, help defeat all the space wizards!</B>"
/datum/game_mode/wizard/raginmages/post_setup()
..()
var/playercount = 0
if(!max_mages && !bullshit_mode)
for(var/mob/living/player in mob_list)
if(player.client && player.stat != 2)
playercount += 1
max_mages = round(playercount / 8)
if(max_mages > 20)
max_mages = 20
if(max_mages < 1)
max_mages = 1
if(bullshit_mode)
max_mages = INFINITY
/datum/game_mode/wizard/raginmages/greet_wizard(datum/mind/wizard, you_are=1)
if (you_are)
wizard.current << "<B>You are the Space Wizard!</B>"
wizard.current << "<B>The Space Wizards Federation has given you the following tasks:</B>"
var/obj_count = 1
wizard.current << "<b>Objective Alpha</b>: Make sure the station pays for its actions against our diplomats"
for(var/datum/objective/objective in wizard.objectives)
wizard.current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
return
/datum/game_mode/wizard/raginmages/check_finished()
var/wizards_alive = 0
for(var/datum/mind/wizard in wizards)
if(!istype(wizard.current,/mob/living/carbon))
continue
if(istype(wizard.current,/mob/living/carbon/brain))
continue
if(wizard.current.stat==DEAD)
continue
if(wizard.current.stat==UNCONSCIOUS)
if(wizard.current.health < 0)
wizard.current << "<font size='4'>The Space Wizard Federation is upset with your performance and have terminated your employment.</font>"
wizard.current.death()
continue
wizards_alive++
if(!time_checked)
time_checked = world.time
if(bullshit_mode)
if(world.time > time_checked + time_check)
max_mages = INFINITY
time_checked = world.time
make_more_mages()
return ..()
if (wizards_alive)
if(world.time > time_checked + time_check && (mages_made < max_mages))
time_checked = world.time
make_more_mages()
else
if(mages_made >= max_mages)
finished = 1
return ..()
else
make_more_mages()
return ..()
/datum/game_mode/wizard/raginmages/proc/make_more_mages()
if(making_mage)
return 0
if(mages_made >= max_mages)
return 0
making_mage = 1
mages_made++
var/list/mob/dead/observer/candidates = list()
var/mob/dead/observer/theghost = null
spawn(rand(spawn_delay_min, spawn_delay_max))
message_admins("SWF is still pissed, sending another wizard - [max_mages - mages_made] left.")
for(var/mob/dead/observer/G in player_list)
if(G.client && !G.client.holder && !G.client.is_afk() && (ROLE_WIZARD in G.client.prefs.be_special))
if(!jobban_isbanned(G, ROLE_WIZARD) && !jobban_isbanned(G, "Syndicate"))
if(age_check(G.client))
candidates += G
if(!candidates.len)
message_admins("No applicable ghosts for the next ragin' mage, asking ghosts instead.")
var/time_passed = world.time
for(var/mob/dead/observer/G in player_list)
if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
if(age_check(G.client))
spawn(0)
switch(alert(G, "Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","Yes","No"))
if("Yes")
if((world.time-time_passed)>300)//If more than 30 game seconds passed.
continue
candidates += G
if("No")
continue
sleep(300)
if(!candidates.len)
message_admins("This is awkward, sleeping until another mage check...")
making_mage = 0
mages_made--
return
else
shuffle(candidates)
for(var/mob/i in candidates)
if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard
theghost = i
break
if(theghost)
var/mob/living/carbon/human/new_character= makeBody(theghost)
new_character.mind.make_Wizard()
making_mage = 0
return 1
/datum/game_mode/wizard/raginmages/declare_completion()
if(finished)
feedback_set_details("round_end_result","loss - wizard killed")
world << "<FONT size=3><B>The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!</B></FONT>"
..(1)
/datum/game_mode/wizard/raginmages/proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
if(!G_found || !G_found.key)
return
//First we spawn a dude.
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
G_found.client.prefs.copy_to(new_character)
new_character.dna.update_dna_identity()
new_character.key = G_found.key
return new_character
/datum/game_mode/wizard/raginmages/bullshit
name = "very ragin' bullshit mages"
config_tag = "veryraginbullshitmages"
required_players = 20
use_huds = 1
bullshit_mode = 1
time_check = 250
spawn_delay_min = 50
spawn_delay_max = 150
+274
View File
@@ -0,0 +1,274 @@
/obj/item/device/soulstone
name = "soulstone shard"
icon = 'icons/obj/wizard.dmi'
icon_state = "soulstone"
item_state = "electronic"
desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefact's power."
w_class = 1
slot_flags = SLOT_BELT
origin_tech = "bluespace=4;materials=5"
var/usability = 0
var/reusable = TRUE
var/spent = FALSE
/obj/item/device/soulstone/proc/was_used()
if(!reusable)
spent = TRUE
name = "dull [name]"
desc = "A fragment of the legendary treasure known simply as \
the 'Soul Stone'. The shard lies still, dull and lifeless; \
whatever spark it once held long extinguished."
/obj/item/device/soulstone/anybody
usability = 1
/obj/item/device/soulstone/anybody/chaplain
name = "mysterious old shard"
reusable = FALSE
/obj/item/device/soulstone/pickup(mob/living/user)
..()
if(!iscultist(user) && !iswizard(user) && !usability)
user << "<span class='danger'>An overwhelming feeling of dread comes over you as you pick up the soulstone. It would be wise to be rid of this quickly.</span>"
user.Dizzy(120)
/obj/item/device/soulstone/examine(mob/user)
..()
if(usability || iscultist(user) || iswizard(user) || isobserver(user))
user << "<span class='cult'>A soulstone, used to capture souls, either from unconscious or sleeping humans or from freed shades.</span>"
user << "<span class='cult'>The captured soul can be placed into a construct shell to produce a construct, or released from the stone as a shade.</span>"
if(spent)
user << "<span class='cult'>This shard is spent; it is now just \
a creepy rock.</span>"
//////////////////////////////Capturing////////////////////////////////////////////////////////
/obj/item/device/soulstone/attack(mob/living/carbon/human/M, mob/user)
if(!iscultist(user) && !iswizard(user) && !usability)
user.Paralyse(5)
user << "<span class='userdanger'>Your body is wracked with debilitating pain!</span>"
return
if(spent)
user << "<span class='warning'>There is no power left in the shard.\
</span>"
return
if(!istype(M, /mob/living/carbon/human))//If target is not a human.
return ..()
if(iscultist(M))
user << "<span class='cultlarge'>\"Come now, do not capture your fellow's soul.\"</span>"
return
add_logs(user, M, "captured [M.name]'s soul", src)
transfer_soul("VICTIM", M, user)
///////////////////Options for using captured souls///////////////////////////////////////
/obj/item/device/soulstone/attack_self(mob/user)
if(!in_range(src, user))
return
if(!iscultist(user) && !iswizard(user) && !usability)
user.Paralyse(5)
user << "<span class='userdanger'>Your body is wracked with debilitating pain!</span>"
return
for(var/mob/living/simple_animal/shade/A in src)
A.status_flags &= ~GODMODE
A.canmove = 1
A.forceMove(get_turf(user))
A.cancel_camera()
icon_state = "soulstone"
name = initial(name)
if(iswizard(user) || usability)
A << "<b>You have been released from your prison, but you are still bound to [user.real_name]'s will. Help them succeed in their goals at all costs.</b>"
else if(iscultist(user))
A << "<b>You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs.</b>"
was_used()
///////////////////////////Transferring to constructs/////////////////////////////////////////////////////
/obj/structure/constructshell
name = "empty shell"
icon = 'icons/obj/wizard.dmi'
icon_state = "construct-cult"
desc = "A wicked machine used by those skilled in magical arts. It is inactive."
/obj/structure/constructshell/examine(mob/user)
..()
if(iscultist(user) || iswizard(user) || user.stat == DEAD)
user << "<span class='cult'>A construct shell, used to house bound souls from a soulstone.</span>"
user << "<span class='cult'>Placing a soulstone with a soul into this shell allows you to produce your choice of the following:</span>"
user << "<span class='cult'>An <b>Artificer</b>, which can produce <b>more shells and soulstones</b>, as well as fortifications.</span>"
user << "<span class='cult'>A <b>Wraith</b>, which does high damage and can jaunt through walls, though it is quite fragile.</span>"
user << "<span class='cult'>A <b>Juggernaut</b>, which is very hard to kill and can produce temporary walls, but is slow.</span>"
/obj/structure/constructshell/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/device/soulstone))
var/obj/item/device/soulstone/SS = O
if(!iscultist(user) && !iswizard(user) && !SS.usability)
user << "<span class='danger'>An overwhelming feeling of dread comes over you as you attempt to place the soulstone into the shell. It would be wise to be rid of this quickly.</span>"
user.Dizzy(120)
return
SS.transfer_soul("CONSTRUCT",src,user)
SS.was_used()
else
return ..()
////////////////////////////Proc for moving soul in and out off stone//////////////////////////////////////
/obj/item/device/soulstone/proc/transfer_soul(choice as text, target, mob/user).
switch(choice)
if("FORCE")
if(!iscarbon(target)) //TODO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul
return 0
if(contents.len)
return 0
var/mob/living/carbon/T = target
if(T.client != null)
for(var/obj/item/W in T)
T.unEquip(W)
init_shade(T, user)
return 1
else
user << "<span class='userdanger'>Capture failed!</span>: The soul has already fled its mortal frame. You attempt to bring it back..."
return getCultGhost(T,user)
if("VICTIM")
var/mob/living/carbon/human/T = target
if(ticker.mode.name == "cult" && T.mind == ticker.mode:sacrifice_target)
if(iscultist(user))
user << "<span class='cult'><b>\"This soul is mine.</b></span> <span class='cultlarge'>SACRIFICE THEM!\"</span>"
else
user << "<span class='danger'>The soulstone doesn't work for no apparent reason.</span>"
return 0
if(contents.len)
user << "<span class='userdanger'>Capture failed!</span>: The soulstone is full! Free an existing soul to make room."
else
if(T.stat != CONSCIOUS)
if(T.client == null)
user << "<span class='userdanger'>Capture failed!</span>: The soul has already fled its mortal frame. You attempt to bring it back..."
getCultGhost(T,user)
else
for(var/obj/item/W in T)
T.unEquip(W)
init_shade(T, user, vic = 1)
qdel(T)
else
user << "<span class='userdanger'>Capture failed!</span>: Kill or maim the victim first!"
if("SHADE")
var/mob/living/simple_animal/shade/T = target
if(contents.len)
user << "<span class='userdanger'>Capture failed!</span>: The soulstone is full! Free an existing soul to make room."
else
T.loc = src //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
icon_state = "soulstone2"
name = "soulstone: Shade of [T.real_name]"
T << "<span class='notice'>Your soul has been captured by the soulstone. Its arcane energies are reknitting your ethereal form.</span>"
if(user != T)
user << "<span class='info'><b>Capture successful!</b>:</span> [T.real_name]'s soul has been captured and stored within the soulstone."
if("CONSTRUCT")
var/obj/structure/constructshell/T = target
var/mob/living/simple_animal/shade/A = locate() in src
if(A)
var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
if(!T || !T.loc)
return
switch(construct_class)
if("Juggernaut")
makeNewConstruct(/mob/living/simple_animal/hostile/construct/armored, A, user, 0, T.loc)
if("Wraith")
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, A, user, 0, T.loc)
if("Artificer")
if(iscultist(user) || iswizard(user))
makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, A, user, 0, T.loc)
else
makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder/noncult, A, user, 0, T.loc)
qdel(T)
user.drop_item()
qdel(src)
else
user << "<span class='userdanger'>Creation failed!</span>: The soul stone is empty! Go kill someone!"
/proc/makeNewConstruct(mob/living/simple_animal/hostile/construct/ctype, mob/target, mob/stoner = null, cultoverride = 0, loc_override = null)
var/mob/living/simple_animal/hostile/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target)))
newstruct.faction |= "\ref[stoner]"
newstruct.key = target.key
if(newstruct.mind)
if(stoner && iscultist(stoner) || cultoverride)
if(ticker.mode.name == "cult")
ticker.mode:add_cultist(newstruct.mind, 0)
else
ticker.mode.cult += newstruct.mind
ticker.mode.update_cult_icons_added(newstruct.mind)
newstruct << newstruct.playstyle_string
if(iscultist(stoner))
newstruct << "<b>You are still bound to serve the cult and [stoner], follow their orders and help them complete their goals at all costs.</b>"
else
newstruct << "<b>You are still bound to serve your creator, [stoner], follow their orders and help them complete their goals at all costs.</b>"
newstruct.cancel_camera()
/obj/item/device/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/U, vic = 0)
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
T.invisibility = INVISIBILITY_ABSTRACT
var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc )
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = T
flick("dust-h", animation)
qdel(animation)
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade(src)
S.status_flags |= GODMODE //So they won't die inside the stone somehow
S.canmove = 0//Can't move out of the soul stone
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
S.key = T.key
if(U)
S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation
if(U && iscultist(U))
ticker.mode.add_cultist(S.mind, 0)
S.cancel_camera()
name = "soulstone: Shade of [T.real_name]"
icon_state = "soulstone2"
if(U && (iswizard(U) || usability))
S << "Your soul has been captured! You are now bound to [U.real_name]'s will. Help them succeed in their goals at all costs."
else if(U && iscultist(U))
S << "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs."
if(vic && U)
U << "<span class='info'><b>Capture successful!</b>:</span> [T.real_name]'s soul has been ripped from their body and stored within the soul stone."
/obj/item/device/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/U)
var/mob/dead/observer/chosen_ghost
for(var/mob/dead/observer/ghost in player_list) //We put them back in their body
if(ghost.mind && ghost.mind.current == T && ghost.client)
chosen_ghost = ghost
break
if(!chosen_ghost) //Failing that, we grab a ghost
var/list/consenting_candidates = pollCandidates("Would you like to play as a Shade?", "Cultist", null, ROLE_CULTIST, poll_time = 100)
if(consenting_candidates.len)
chosen_ghost = pick(consenting_candidates)
if(!T)
return 0
if(!chosen_ghost)
U << "<span class='danger'>There were no spirits willing to become a shade.</span>"
return 0
if(contents.len) //If they used the soulstone on someone else in the meantime
return 0
T.ckey = chosen_ghost.ckey
for(var/obj/item/W in T)
T.unEquip(W)
init_shade(T, U)
qdel(T)
return 1
+878
View File
@@ -0,0 +1,878 @@
/datum/spellbook_entry
var/name = "Entry Name"
var/spell_type = null
var/desc = ""
var/category = "Offensive"
var/log_name = "XX" //What it shows up as in logs
var/cost = 2
var/refundable = 1
var/surplus = -1 // -1 for infinite, not used by anything atm
var/obj/effect/proc_holder/spell/S = null //Since spellbooks can be used by only one person anyway we can track the actual spell
var/buy_word = "Learn"
var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook
/datum/spellbook_entry/proc/IsAvailible() // For config prefs / gamemode restrictions - these are round applied
return 1
/datum/spellbook_entry/proc/CanBuy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book) // Specific circumstances
if(book.uses<cost || limit == 0)
return 0
return 1
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book) //return 1 on success
if(!S || qdeleted(S))
S = new spell_type()
//Check if we got the spell already
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name)) // Not using directly in case it was learned from one spellbook then upgraded in another
if(aspell.spell_level >= aspell.level_max)
user << "<span class='warning'>This spell cannot be improved further.</span>"
return 0
else
aspell.name = initial(aspell.name)
aspell.spell_level++
aspell.charge_max = round(initial(aspell.charge_max) - aspell.spell_level * (initial(aspell.charge_max) - aspell.cooldown_min)/ aspell.level_max)
if(aspell.charge_max < aspell.charge_counter)
aspell.charge_counter = aspell.charge_max
switch(aspell.spell_level)
if(1)
user << "<span class='notice'>You have improved [aspell.name] into Efficient [aspell.name].</span>"
aspell.name = "Efficient [aspell.name]"
if(2)
user << "<span class='notice'>You have further improved [aspell.name] into Quickened [aspell.name].</span>"
aspell.name = "Quickened [aspell.name]"
if(3)
user << "<span class='notice'>You have further improved [aspell.name] into Free [aspell.name].</span>"
aspell.name = "Free [aspell.name]"
if(4)
user << "<span class='notice'>You have further improved [aspell.name] into Instant [aspell.name].</span>"
aspell.name = "Instant [aspell.name]"
if(aspell.spell_level >= aspell.level_max)
user << "<span class='notice'>This spell cannot be strengthened any further.</span>"
return 1
//No same spell found - just learn it
feedback_add_details("wizard_spell_learned",log_name)
user.mind.AddSpell(S)
user << "<span class='notice'>You have learned [S.name].</span>"
return 1
/datum/spellbook_entry/proc/CanRefund(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
if(!refundable)
return 0
if(!S)
S = new spell_type()
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name))
return 1
return 0
/datum/spellbook_entry/proc/Refund(mob/living/carbon/human/user,obj/item/weapon/spellbook/book) //return point value or -1 for failure
var/area/wizard_station/A = locate()
if(!(user in A.contents))
user << "<span clas=='warning'>You can only refund spells at the wizard lair</span>"
return -1
if(!S)
S = new spell_type()
var/spell_levels = 0
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name))
spell_levels = aspell.spell_level
user.mind.spell_list.Remove(aspell)
qdel(S)
return cost * (spell_levels+1)
return -1
/datum/spellbook_entry/proc/GetInfo()
if(!S)
S = new spell_type()
var/dat =""
dat += "<b>[initial(S.name)]</b>"
if(S.charge_type == "recharge")
dat += " Cooldown:[S.charge_max/10]"
dat += " Cost:[cost]<br>"
dat += "<i>[S.desc][desc]</i><br>"
dat += "[S.clothes_req?"Needs wizard garb":"Can be cast without wizard garb"]<br>"
return dat
/datum/spellbook_entry/fireball
name = "Fireball"
spell_type = /obj/effect/proc_holder/spell/dumbfire/fireball
log_name = "FB"
/datum/spellbook_entry/magicm
name = "Magic Missile"
spell_type = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile
log_name = "MM"
category = "Defensive"
/datum/spellbook_entry/disintegrate
name = "Disintegrate"
spell_type = /obj/effect/proc_holder/spell/targeted/touch/disintegrate
log_name = "DG"
/datum/spellbook_entry/disabletech
name = "Disable Tech"
spell_type = /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech
log_name = "DT"
category = "Defensive"
cost = 1
/datum/spellbook_entry/repulse
name = "Repulse"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/repulse
log_name = "RP"
category = "Defensive"
/datum/spellbook_entry/timestop
name = "Time Stop"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop
log_name = "TS"
category = "Defensive"
/datum/spellbook_entry/smoke
name = "Smoke"
spell_type = /obj/effect/proc_holder/spell/targeted/smoke
log_name = "SM"
category = "Defensive"
cost = 1
/datum/spellbook_entry/blind
name = "Blind"
spell_type = /obj/effect/proc_holder/spell/targeted/trigger/blind
log_name = "BD"
cost = 1
/datum/spellbook_entry/mindswap
name = "Mindswap"
spell_type = /obj/effect/proc_holder/spell/targeted/mind_transfer
log_name = "MT"
category = "Mobility"
/datum/spellbook_entry/forcewall
name = "Force Wall"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall
log_name = "FW"
category = "Defensive"
cost = 1
/datum/spellbook_entry/blink
name = "Blink"
spell_type = /obj/effect/proc_holder/spell/targeted/turf_teleport/blink
log_name = "BL"
category = "Mobility"
/datum/spellbook_entry/teleport
name = "Teleport"
spell_type = /obj/effect/proc_holder/spell/targeted/area_teleport/teleport
log_name = "TP"
category = "Mobility"
/datum/spellbook_entry/mutate
name = "Mutate"
spell_type = /obj/effect/proc_holder/spell/targeted/genetic/mutate
log_name = "MU"
/datum/spellbook_entry/jaunt
name = "Ethereal Jaunt"
spell_type = /obj/effect/proc_holder/spell/targeted/ethereal_jaunt
log_name = "EJ"
category = "Mobility"
/datum/spellbook_entry/knock
name = "Knock"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock
log_name = "KN"
category = "Mobility"
cost = 1
/datum/spellbook_entry/fleshtostone
name = "Flesh to Stone"
spell_type = /obj/effect/proc_holder/spell/targeted/touch/flesh_to_stone
log_name = "FS"
/datum/spellbook_entry/summonitem
name = "Summon Item"
spell_type = /obj/effect/proc_holder/spell/targeted/summonitem
log_name = "IS"
category = "Assistance"
cost = 1
/datum/spellbook_entry/lichdom
name = "Bind Soul"
spell_type = /obj/effect/proc_holder/spell/targeted/lichdom
log_name = "LD"
category = "Defensive"
/datum/spellbook_entry/lightningbolt
name = "Lightning Bolt"
spell_type = /obj/effect/proc_holder/spell/targeted/lightning
log_name = "LB"
/datum/spellbook_entry/infinite_guns
name = "Lesser Summon Guns"
spell_type = /obj/effect/proc_holder/spell/targeted/infinite_guns
log_name = "IG"
cost = 3
/datum/spellbook_entry/barnyard
name = "Barnyard Curse"
spell_type = /obj/effect/proc_holder/spell/targeted/barnyardcurse
log_name = "BC"
/datum/spellbook_entry/charge
name = "Charge"
spell_type = /obj/effect/proc_holder/spell/targeted/charge
log_name = "CH"
category = "Assistance"
cost = 1
/datum/spellbook_entry/shapeshift
name = "Wild Shapeshift"
spell_type = /obj/effect/proc_holder/spell/targeted/shapeshift
log_name = "WS"
category = "Assistance"
cost = 1
/datum/spellbook_entry/spacetime_dist
name = "Spacetime Distortion"
spell_type = /obj/effect/proc_holder/spell/spacetime_dist
log_name = "STD"
category = "Defensive"
cost = 1
/datum/spellbook_entry/item
name = "Buy Item"
refundable = 0
buy_word = "Summon"
var/item_path= null
/datum/spellbook_entry/item/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
new item_path(get_turf(user))
feedback_add_details("wizard_spell_learned",log_name)
return 1
/datum/spellbook_entry/item/GetInfo()
var/dat =""
dat += "<b>[name]</b>"
dat += " Cost:[cost]<br>"
dat += "<i>[desc]</i><br>"
if(surplus>=0)
dat += "[surplus] left.<br>"
return dat
/datum/spellbook_entry/item/staffchange
name = "Staff of Change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
item_path = /obj/item/weapon/gun/magic/staff/change
log_name = "ST"
/datum/spellbook_entry/item/staffanimation
name = "Staff of Animation"
desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines."
item_path = /obj/item/weapon/gun/magic/staff/animate
log_name = "SA"
category = "Assistance"
/datum/spellbook_entry/item/staffchaos
name = "Staff of Chaos"
desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended."
item_path = /obj/item/weapon/gun/magic/staff/chaos
log_name = "SC"
/datum/spellbook_entry/item/staffdoor
name = "Staff of Door Creation"
desc = "A particular staff that can mold solid metal into ornate doors. Useful for getting around in the absence of other transportation. Does not work on glass."
item_path = /obj/item/weapon/gun/magic/staff/door
log_name = "SD"
cost = 1
category = "Mobility"
/datum/spellbook_entry/item/staffhealing
name = "Staff of Healing"
desc = "An altruistic staff that can heal the lame and raise the dead."
item_path = /obj/item/weapon/gun/magic/staff/healing
log_name = "SH"
cost = 1
category = "Defensive"
/datum/spellbook_entry/item/scryingorb
name = "Scrying Orb"
desc = "An incandescent orb of crackling energy, using it will allow you to ghost while alive, allowing you to spy upon the station with ease. In addition, buying it will permanently grant you x-ray vision."
item_path = /obj/item/weapon/scrying
log_name = "SO"
category = "Defensive"
/datum/spellbook_entry/item/scryingorb/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
if(..())
if (!(user.dna.check_mutation(XRAY)))
user.dna.add_mutation(XRAY)
return 1
/datum/spellbook_entry/item/soulstones
name = "Six Soul Stone Shards and the spell Artificer"
desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot."
item_path = /obj/item/weapon/storage/belt/soulstone/full
log_name = "SS"
category = "Assistance"
/datum/spellbook_entry/item/soulstones/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
. =..()
if(.)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(null))
return .
/datum/spellbook_entry/item/necrostone
name = "A Necromantic Stone"
desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command."
item_path = /obj/item/device/necromantic_stone
log_name = "NS"
category = "Assistance"
/datum/spellbook_entry/item/wands
name = "Wand Assortment"
desc = "A collection of wands that allow for a wide variety of utility. Wands have a limited number of charges, so be conservative in use. Comes in a handy belt."
item_path = /obj/item/weapon/storage/belt/wands/full
log_name = "WA"
category = "Defensive"
/datum/spellbook_entry/item/armor
name = "Mastercrafted Armor Set"
desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space."
item_path = /obj/item/clothing/suit/space/hardsuit/wizard
log_name = "HS"
category = "Defensive"
/datum/spellbook_entry/item/armor/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
. = ..()
if(.)
new /obj/item/clothing/shoes/sandal(get_turf(user)) //In case they've lost them.
new /obj/item/clothing/gloves/color/purple(get_turf(user))//To complete the outfit
/datum/spellbook_entry/item/contract
name = "Contract of Apprenticeship"
desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side."
item_path = /obj/item/weapon/antag_spawner/contract
log_name = "CT"
category = "Assistance"
/datum/spellbook_entry/item/bloodbottle
name = "Bottle of Blood"
desc = "A bottle of magically infused blood, the smell of which will attract extradimensional beings when broken. Be careful though, the kinds of creatures summoned by blood magic are indiscriminate in their killing, and you yourself may become a victim."
item_path = /obj/item/weapon/antag_spawner/slaughter_demon
log_name = "BB"
limit = 3
category = "Assistance"
/datum/spellbook_entry/item/hugbottle
name = "Bottle of Tickles"
desc = "A bottle of magically infused fun, the smell of which will \
attract adorable extradimensional beings when broken. These beings \
are similar to slaughter demons, but they do not permamently kill \
their victims, instead putting them in an extradimensional hugspace, \
to be released on the demon's death. Chaotic, but not ultimately \
damaging. The crew's reaction to the other hand could be very \
destructive."
item_path = /obj/item/weapon/antag_spawner/slaughter_demon/laughter
cost = 1 //non-destructive; it's just a jape, sibling!
log_name = "HB"
limit = 3
category = "Assistance"
/datum/spellbook_entry/item/hadesstone
name = "Dark Seed"
desc = "A small, dark stone that whispers to you menacingly.\
The seed calls for the corpses of living beings,\
in order to summon an ancient, powerful being.\
The power and tenacity of the summoned being directly\
correlates to the power of the absorbed beings,\
so choose your targets wisely."
item_path = /obj/item/hades_summoner
cost = 2
log_name = "DS"
limit = 1
category = "Assistance"
/datum/spellbook_entry/item/mjolnir
name = "Mjolnir"
desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power."
item_path = /obj/item/weapon/twohanded/mjollnir
log_name = "MJ"
/datum/spellbook_entry/item/singularity_hammer
name = "Singularity Hammer"
desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everthing nearby to the point of impact."
item_path = /obj/item/weapon/twohanded/singularityhammer
log_name = "SI"
/datum/spellbook_entry/item/cursed_heart
name = "Cursed Heart"
desc = "A heart that has been revived by dark magicks, the user must \
concentrate to ensure the heart beats, but every beat heals them. It \
must beat every 6 seconds. The heart is fickle, and will not work for a \
lich."
item_path = /obj/item/organ/heart/cursed/wizard
log_name = "CH"
cost = 1
category = "Defensive"
/datum/spellbook_entry/summon
name = "Summon Stuff"
category = "Rituals"
refundable = 0
buy_word = "Cast"
var/active = 0
/datum/spellbook_entry/summon/CanBuy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
return ..() && !active
/datum/spellbook_entry/summon/GetInfo()
var/dat =""
dat += "<b>[name]</b>"
if(cost>0)
dat += " Cost:[cost]<br>"
else
dat += " No Cost<br>"
dat += "<i>[desc]</i><br>"
if(active)
dat += "<b>Already cast!</b><br>"
return dat
/datum/spellbook_entry/summon/guns
name = "Summon Guns"
category = "Rituals"
desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long!"
log_name = "SG"
/datum/spellbook_entry/summon/guns/IsAvailible()
if(!ticker.mode) // In case spellbook is placed on map
return 0
return (ticker.mode.name != "ragin' mages" && !config.no_summon_guns)
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
feedback_add_details("wizard_spell_learned",log_name)
rightandwrong(0, user, 25)
playsound(get_turf(user),"sound/magic/CastSummon.ogg",50,1)
user << "<span class='notice'>You have cast summon guns!</span>"
return 1
/datum/spellbook_entry/summon/magic
name = "Summon Magic"
category = "Challenges"
desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time."
cost = 0
log_name = "SU"
/datum/spellbook_entry/summon/magic/IsAvailible()
if(!ticker.mode) // In case spellbook is placed on map
return 0
return (ticker.mode.name != "ragin' mages" && !config.no_summon_magic)
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
feedback_add_details("wizard_spell_learned",log_name)
rightandwrong(1, user, 0)
book.uses += 1
active = 1
playsound(get_turf(user),"sound/magic/CastSummon.ogg",50,1)
user << "<span class='notice'>You have cast summon magic and gained an extra charge for your spellbook.</span>"
return 1
/datum/spellbook_entry/summon/events
name = "Summon Events"
desc = "Give Murphy's law a little push and replace all events with special wizard ones that will confound and confuse everyone. Multiple castings increase the rate of these events."
cost = 2
log_name = "SE"
var/times = 0
/datum/spellbook_entry/summon/events/IsAvailible()
if(!ticker.mode) // In case spellbook is placed on map
return 0
return (ticker.mode.name != "ragin' mages" && !config.no_summon_events)
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
feedback_add_details("wizard_spell_learned",log_name)
summonevents()
times++
playsound(get_turf(user),"sound/magic/CastSummon.ogg",50,1)
user << "<span class='notice'>You have cast summon events.</span>"
return 1
/datum/spellbook_entry/summon/events/GetInfo()
. = ..()
if(times>0)
. += "You cast it [times] times.<br>"
return .
/obj/item/weapon/spellbook
name = "spell book"
desc = "An unearthly tome that glows with power."
icon = 'icons/obj/library.dmi'
icon_state ="book"
throw_speed = 2
throw_range = 5
w_class = 1
var/uses = 10
var/temp = null
var/op = 1
var/tab = null
var/mob/living/carbon/human/owner
var/list/datum/spellbook_entry/entries = list()
var/list/categories = list()
/obj/item/weapon/spellbook/examine(mob/user)
..()
if(owner)
user << "There is a small signature on the front cover: \"[owner]\"."
else
user << "It appears to have no author."
/obj/item/weapon/spellbook/proc/Initialize()
var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon
for(var/T in entry_types)
var/datum/spellbook_entry/E = new T
if(E.IsAvailible())
entries |= E
categories |= E.category
else
qdel(E)
tab = categories[1]
/obj/item/weapon/spellbook/New()
..()
Initialize()
/obj/item/weapon/spellbook/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/weapon/antag_spawner/contract))
var/obj/item/weapon/antag_spawner/contract/contract = O
if(contract.used)
user << "<span class='warning'>The contract has been used, you can't get your points back now!</span>"
else
user << "<span class='notice'>You feed the contract back into the spellbook, refunding your points.</span>"
uses++
for(var/datum/spellbook_entry/item/contract/CT in entries)
if(!isnull(CT.limit))
CT.limit++
qdel(O)
else if(istype(O, /obj/item/weapon/antag_spawner/slaughter_demon))
user << "<span class='notice'>On second thought, maybe summoning a demon is a bad idea. You refund your points.</span>"
uses++
for(var/datum/spellbook_entry/item/bloodbottle/BB in entries)
if(!isnull(BB.limit))
BB.limit++
qdel(O)
/obj/item/weapon/spellbook/proc/GetCategoryHeader(category)
var/dat = ""
switch(category)
if("Offensive")
dat += "Spells and items geared towards debilitating and destroying.<BR><BR>"
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
dat += "For spells: the number after the spell name is the cooldown time.<BR>"
dat += "You can reduce this number by spending more points on the spell.<BR>"
if("Defensive")
dat += "Spells and items geared towards improving your survivabilty or reducing foes ability to attack.<BR><BR>"
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
dat += "For spells: the number after the spell name is the cooldown time.<BR>"
dat += "You can reduce this number by spending more points on the spell.<BR>"
if("Mobility")
dat += "Spells and items geared towards improving your ability to move. It is a good idea to take at least one.<BR><BR>"
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
dat += "For spells: the number after the spell name is the cooldown time.<BR>"
dat += "You can reduce this number by spending more points on the spell.<BR>"
if("Assistance")
dat += "Spells and items geared towards bringing in outside forces to aid you or improving upon your other items and abilties.<BR><BR>"
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
dat += "For spells: the number after the spell name is the cooldown time.<BR>"
dat += "You can reduce this number by spending more points on the spell.<BR>"
if("Challenges")
dat += "The Wizard Federation typically has hard limits on the potency and number of spells brought to the station based on risk.<BR>"
dat += "Arming the station against you will increases the risk, but will grant you one more charge for your spellbook.<BR>"
if("Rituals")
dat += "These powerful spells change the very fabric of reality. Not always in your favour.<BR>"
return dat
/obj/item/weapon/spellbook/proc/wrap(content)
var/dat = ""
dat +="<html><head><title>Spellbook</title></head>"
dat += {"
<head>
<style type="text/css">
body { font-size: 80%; font-family: 'Lucida Grande', Verdana, Arial, Sans-Serif; }
ul#tabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; }
ul#tabs li { display: inline; }
ul#tabs li a { color: #42454a; background-color: #dedbde; border: 1px solid #c9c3ba; border-bottom: none; padding: 0.3em; text-decoration: none; }
ul#tabs li a:hover { background-color: #f1f0ee; }
ul#tabs li a.selected { color: #000; background-color: #f1f0ee; font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; }
div.tabContent { border: 1px solid #c9c3ba; padding: 0.5em; background-color: #f1f0ee; }
div.tabContent.hide { display: none; }
</style>
</head>
"}
dat += {"[content]</body></html>"}
return dat
/obj/item/weapon/spellbook/attack_self(mob/user)
if(!owner)
user << "<span class='notice'>You bind the spellbook to yourself.</span>"
owner = user
return
if(user != owner)
user << "<span class='warning'>The [name] does not recognize you as it's owner and refuses to open!</span>"
return
user.set_machine(src)
var/dat = ""
dat += "<ul id=\"tabs\">"
var/list/cat_dat = list()
for(var/category in categories)
cat_dat[category] = "<hr>"
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=\ref[src];page=[category]'>[category]</a></li>"
dat += "<li><a><b>Points remaining : [uses]</b></a></li>"
dat += "</ul>"
var/datum/spellbook_entry/E
for(var/i=1,i<=entries.len,i++)
var/spell_info = ""
E = entries[i]
spell_info += E.GetInfo()
if(E.CanBuy(user,src))
spell_info+= "<a href='byond://?src=\ref[src];buy=[i]'>[E.buy_word]</A><br>"
else
spell_info+= "<span>Can't [E.buy_word]</span><br>"
if(E.CanRefund(user,src))
spell_info+= "<a href='byond://?src=\ref[src];refund=[i]'>Refund</A><br>"
spell_info += "<hr>"
if(cat_dat[E.category])
cat_dat[E.category] += spell_info
for(var/category in categories)
dat += "<div class=\"[tab==category?"tabContent":"tabContent hide"]\" id=\"[category]\">"
dat += GetCategoryHeader(category)
dat += cat_dat[category]
dat += "</div>"
user << browse(wrap(dat), "window=spellbook;size=700x500")
onclose(user, "spellbook")
return
/obj/item/weapon/spellbook/Topic(href, href_list)
..()
var/mob/living/carbon/human/H = usr
if(H.stat || H.restrained())
return
if(!istype(H, /mob/living/carbon/human))
return 1
if(H.mind.special_role == "apprentice")
temp = "If you got caught sneaking a peak from your teacher's spellbook, you'd likely be expelled from the Wizard Academy. Better not."
return
var/datum/spellbook_entry/E = null
if(loc == H || (in_range(src, H) && istype(loc, /turf)))
H.set_machine(src)
if(href_list["buy"])
E = entries[text2num(href_list["buy"])]
if(E && E.CanBuy(H,src))
if(E.Buy(H,src))
if(E.limit)
E.limit--
uses -= E.cost
else if(href_list["refund"])
E = entries[text2num(href_list["refund"])]
if(E && E.refundable)
var/result = E.Refund(H,src)
if(result > 0)
if(!isnull(E.limit))
E.limit += result
uses += result
else if(href_list["page"])
tab = sanitize(href_list["page"])
attack_self(H)
return
//Single Use Spellbooks//
/obj/item/weapon/spellbook/oneuse
var/spell = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile //just a placeholder to avoid runtimes if someone spawned the generic
var/spellname = "sandbox"
var/used = 0
name = "spellbook of "
uses = 1
desc = "This template spellbook was never meant for the eyes of man..."
/obj/item/weapon/spellbook/oneuse/New()
..()
name += spellname
/obj/item/weapon/spellbook/oneuse/Initialize() //No need to init
return
/obj/item/weapon/spellbook/oneuse/attack_self(mob/user)
var/obj/effect/proc_holder/spell/S = new spell
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
if(knownspell.type == S.type)
if(user.mind)
if(user.mind.special_role == "apprentice" || user.mind.special_role == "Wizard")
user <<"<span class='notice'>You're already far more versed in this spell than this flimsy how-to book can provide.</span>"
else
user <<"<span class='notice'>You've already read this one.</span>"
return
if(used)
recoil(user)
else
user.mind.AddSpell(S)
user <<"<span class='notice'>you rapidly read through the arcane book. Suddenly you realize you understand [spellname]!</span>"
user.attack_log += text("\[[time_stamp()]\] <font color='orange'>[user.real_name] ([user.ckey]) learned the spell [spellname] ([S]).</font>")
onlearned(user)
/obj/item/weapon/spellbook/oneuse/proc/recoil(mob/user)
user.visible_message("<span class='warning'>[src] glows in a black light!</span>")
/obj/item/weapon/spellbook/oneuse/proc/onlearned(mob/user)
used = 1
user.visible_message("<span class='caution'>[src] glows dark for a second!</span>")
/obj/item/weapon/spellbook/oneuse/attackby()
return
/obj/item/weapon/spellbook/oneuse/fireball
spell = /obj/effect/proc_holder/spell/dumbfire/fireball
spellname = "fireball"
icon_state ="bookfireball"
desc = "This book feels warm to the touch."
/obj/item/weapon/spellbook/oneuse/fireball/recoil(mob/user)
..()
explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2)
qdel(src)
/obj/item/weapon/spellbook/oneuse/smoke
spell = /obj/effect/proc_holder/spell/targeted/smoke
spellname = "smoke"
icon_state ="booksmoke"
desc = "This book is overflowing with the dank arts."
/obj/item/weapon/spellbook/oneuse/smoke/recoil(mob/user)
..()
user <<"<span class='caution'>Your stomach rumbles...</span>"
if(user.nutrition)
user.nutrition -= 200
if(user.nutrition <= 0)
user.nutrition = 0
/obj/item/weapon/spellbook/oneuse/blind
spell = /obj/effect/proc_holder/spell/targeted/trigger/blind
spellname = "blind"
icon_state ="bookblind"
desc = "This book looks blurry, no matter how you look at it."
/obj/item/weapon/spellbook/oneuse/blind/recoil(mob/user)
..()
user <<"<span class='warning'>You go blind!</span>"
user.blind_eyes(10)
/obj/item/weapon/spellbook/oneuse/mindswap
spell = /obj/effect/proc_holder/spell/targeted/mind_transfer
spellname = "mindswap"
icon_state ="bookmindswap"
desc = "This book's cover is pristine, though its pages look ragged and torn."
var/mob/stored_swap = null //Used in used book recoils to store an identity for mindswaps
/obj/item/weapon/spellbook/oneuse/mindswap/onlearned()
spellname = pick("fireball","smoke","blind","forcewall","knock","barnyard","charge")
icon_state = "book[spellname]"
name = "spellbook of [spellname]" //Note, desc doesn't change by design
..()
/obj/item/weapon/spellbook/oneuse/mindswap/recoil(mob/user)
..()
if(stored_swap in dead_mob_list)
stored_swap = null
if(!stored_swap)
stored_swap = user
user <<"<span class='warning'>For a moment you feel like you don't even know who you are anymore.</span>"
return
if(stored_swap == user)
user <<"<span class='notice'>You stare at the book some more, but there doesn't seem to be anything else to learn...</span>"
return
var/obj/effect/proc_holder/spell/targeted/mind_transfer/swapper = new
swapper.cast(user, stored_swap, 1)
stored_swap <<"<span class='warning'>You're suddenly somewhere else... and someone else?!</span>"
user <<"<span class='warning'>Suddenly you're staring at [src] again... where are you, who are you?!</span>"
stored_swap = null
/obj/item/weapon/spellbook/oneuse/forcewall
spell = /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall
spellname = "forcewall"
icon_state ="bookforcewall"
desc = "This book has a dedication to mimes everywhere inside the front cover."
/obj/item/weapon/spellbook/oneuse/forcewall/recoil(mob/user)
..()
user <<"<span class='warning'>You suddenly feel very solid!</span>"
var/obj/structure/closet/statue/S = new /obj/structure/closet/statue(user.loc, user)
S.timer = 30
user.drop_item()
/obj/item/weapon/spellbook/oneuse/knock
spell = /obj/effect/proc_holder/spell/aoe_turf/knock
spellname = "knock"
icon_state ="bookknock"
desc = "This book is hard to hold closed properly."
/obj/item/weapon/spellbook/oneuse/knock/recoil(mob/user)
..()
user <<"<span class='warning'>You're knocked down!</span>"
user.Weaken(20)
/obj/item/weapon/spellbook/oneuse/barnyard
spell = /obj/effect/proc_holder/spell/targeted/barnyardcurse
spellname = "barnyard"
icon_state ="bookhorses"
desc = "This book is more horse than your mind has room for."
/obj/item/weapon/spellbook/oneuse/barnyard/recoil(mob/living/carbon/user)
if(istype(user, /mob/living/carbon/human))
user <<"<font size='15' color='red'><b>HOR-SIE HAS RISEN</b></font>"
var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead
magichead.flags |= NODROP //curses!
magichead.flags_inv &= ~HIDEFACE //so you can still see their face
magichead.voicechange = 1 //NEEEEIIGHH
if(!user.unEquip(user.wear_mask))
qdel(user.wear_mask)
user.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1)
qdel(src)
else
user <<"<span class='notice'>I say thee neigh</span>" //It still lives here
/obj/item/weapon/spellbook/oneuse/charge
spell = /obj/effect/proc_holder/spell/targeted/charge
spellname = "charging"
icon_state ="bookcharge"
desc = "This book is made of 100% post-consumer wizard."
/obj/item/weapon/spellbook/oneuse/charge/recoil(mob/user)
..()
user <<"<span class='warning'>[src] suddenly feels very warm!</span>"
empulse(src, 1, 1)
/obj/item/weapon/spellbook/oneuse/summonitem
spell = /obj/effect/proc_holder/spell/targeted/summonitem
spellname = "instant summons"
icon_state ="booksummons"
desc = "This book is bright and garish, very hard to miss."
/obj/item/weapon/spellbook/oneuse/summonitem/recoil(mob/user)
..()
user <<"<span class='warning'>[src] suddenly vanishes!</span>"
qdel(src)
/obj/item/weapon/spellbook/oneuse/random/New()
var/real_type = pick(subtypesof(/obj/item/weapon/spellbook/oneuse))
new real_type(loc)
qdel(src)
+277
View File
@@ -0,0 +1,277 @@
/datum/game_mode
var/list/datum/mind/wizards = list()
var/list/datum/mind/apprentices = list()
/datum/game_mode/wizard
name = "wizard"
config_tag = "wizard"
antag_flag = ROLE_WIZARD
required_players = 20
required_enemies = 1
recommended_enemies = 1
enemy_minimum_age = 14
round_ends_with_antag_death = 1
var/use_huds = 0
var/finished = 0
/datum/game_mode/wizard/announce()
world << "<B>The current game mode is - Wizard!</B>"
world << "<B>There is a <span class='danger'>SPACE WIZARD</span>\black on the station. You can't let him achieve his objective!</B>"
/datum/game_mode/wizard/pre_setup()
var/datum/mind/wizard = pick(antag_candidates)
wizards += wizard
modePlayer += wizard
wizard.assigned_role = "Wizard"
wizard.special_role = "Wizard"
if(wizardstart.len == 0)
wizard.current << "<span class='boldannounce'>A starting location for you could not be found, please report this bug!</span>"
return 0
for(var/datum/mind/wiz in wizards)
wiz.current.loc = pick(wizardstart)
return 1
/datum/game_mode/wizard/post_setup()
for(var/datum/mind/wizard in wizards)
log_game("[wizard.key] (ckey) has been selected as a Wizard")
equip_wizard(wizard.current)
forge_wizard_objectives(wizard)
if(use_huds)
update_wiz_icons_added(wizard)
greet_wizard(wizard)
name_wizard(wizard.current)
..()
return
/datum/game_mode/proc/forge_wizard_objectives(datum/mind/wizard)
switch(rand(1,100))
if(1 to 30)
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = wizard
kill_objective.find_target()
wizard.objectives += kill_objective
if (!(locate(/datum/objective/escape) in wizard.objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = wizard
wizard.objectives += escape_objective
if(31 to 60)
var/datum/objective/steal/steal_objective = new
steal_objective.owner = wizard
steal_objective.find_target()
wizard.objectives += steal_objective
if (!(locate(/datum/objective/escape) in wizard.objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = wizard
wizard.objectives += escape_objective
if(61 to 85)
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = wizard
kill_objective.find_target()
wizard.objectives += kill_objective
var/datum/objective/steal/steal_objective = new
steal_objective.owner = wizard
steal_objective.find_target()
wizard.objectives += steal_objective
if (!(locate(/datum/objective/survive) in wizard.objectives))
var/datum/objective/survive/survive_objective = new
survive_objective.owner = wizard
wizard.objectives += survive_objective
else
if (!(locate(/datum/objective/hijack) in wizard.objectives))
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = wizard
wizard.objectives += hijack_objective
return
/datum/game_mode/proc/name_wizard(mob/living/carbon/human/wizard_mob)
//Allows the wizard to choose a custom name or go with a random one. Spawn 0 so it does not lag the round starting.
var/wizard_name_first = pick(wizard_first)
var/wizard_name_second = pick(wizard_second)
var/randomname = "[wizard_name_first] [wizard_name_second]"
spawn(0)
var/newname = copytext(sanitize(input(wizard_mob, "You are the Space Wizard. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN)
if (!newname)
newname = randomname
wizard_mob.real_name = newname
wizard_mob.name = newname
if(wizard_mob.mind)
wizard_mob.mind.name = newname
return
/datum/game_mode/proc/greet_wizard(datum/mind/wizard, you_are=1)
if (you_are)
wizard.current << "<span class='boldannounce'>You are the Space Wizard!</span>"
wizard.current << "<B>The Space Wizards Federation has given you the following tasks:</B>"
var/obj_count = 1
for(var/datum/objective/objective in wizard.objectives)
wizard.current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
return
/datum/game_mode/proc/learn_basic_spells(mob/living/carbon/human/wizard_mob)
if(!istype(wizard_mob) || !wizard_mob.mind)
return 0
wizard_mob.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) //Wizards get Magic Missile and Ethereal Jaunt by default
wizard_mob.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
/datum/game_mode/proc/equip_wizard(mob/living/carbon/human/wizard_mob)
if (!istype(wizard_mob))
return
//So zards properly get their items when they are admin-made.
qdel(wizard_mob.wear_suit)
qdel(wizard_mob.head)
qdel(wizard_mob.shoes)
qdel(wizard_mob.r_hand)
qdel(wizard_mob.r_store)
qdel(wizard_mob.l_store)
wizard_mob.set_species(/datum/species/human)
wizard_mob.equip_to_slot_or_del(new /obj/item/device/radio/headset(wizard_mob), slot_ears)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head)
wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(wizard_mob), slot_back)
wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(wizard_mob), slot_in_backpack)
wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(wizard_mob), slot_r_store)
var/obj/item/weapon/spellbook/spellbook = new /obj/item/weapon/spellbook(wizard_mob)
spellbook.owner = wizard_mob
wizard_mob.equip_to_slot_or_del(spellbook, slot_r_hand)
wizard_mob << "You will find a list of available spells in your spell book. Choose your magic arsenal carefully."
wizard_mob << "The spellbook is bound to you, and others cannot use it."
wizard_mob << "In your pockets you will find a teleport scroll. Use it as needed."
wizard_mob.mind.store_memory("<B>Remember:</B> do not forget to prepare your spells.")
wizard_mob.update_icons()
return 1
/datum/game_mode/wizard/check_finished()
for(var/datum/mind/wizard in wizards)
if(isliving(wizard.current) && wizard.current.stat!=DEAD)
return ..()
if(SSevent.wizardmode) //If summon events was active, turn it off
SSevent.toggleWizardmode()
SSevent.resetFrequency()
return ..()
/datum/game_mode/wizard/declare_completion()
if(finished)
feedback_set_details("round_end_result","loss - wizard killed")
world << "<span class='userdanger'>The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!</span>"
..()
return 1
/datum/game_mode/proc/auto_declare_completion_wizard()
if(wizards.len)
var/text = "<br><font size=3><b>the wizards/witches were:</b></font>"
for(var/datum/mind/wizard in wizards)
text += "<br><b>[wizard.key]</b> was <b>[wizard.name]</b> ("
if(wizard.current)
if(wizard.current.stat == DEAD)
text += "died"
else
text += "survived"
if(wizard.current.real_name != wizard.name)
text += " as <b>[wizard.current.real_name]</b>"
else
text += "body destroyed"
text += ")"
var/count = 1
var/wizardwin = 1
for(var/datum/objective/objective in wizard.objectives)
if(objective.check_completion())
text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='green'><B>Success!</B></font>"
feedback_add_details("wizard_objective","[objective.type]|SUCCESS")
else
text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='red'>Fail.</font>"
feedback_add_details("wizard_objective","[objective.type]|FAIL")
wizardwin = 0
count++
if(wizard.current && wizard.current.stat!=2 && wizardwin)
text += "<br><font color='green'><B>The wizard was successful!</B></font>"
feedback_add_details("wizard_success","SUCCESS")
else
text += "<br><font color='red'><B>The wizard has failed!</B></font>"
feedback_add_details("wizard_success","FAIL")
if(wizard.spell_list.len>0)
text += "<br><B>[wizard.name] used the following spells: </B>"
var/i = 1
for(var/obj/effect/proc_holder/spell/S in wizard.spell_list)
text += "[S.name]"
if(wizard.spell_list.len > i)
text += ", "
i++
text += "<br>"
world << text
return 1
//OTHER PROCS
//To batch-remove wizard spells. Linked to mind.dm.
/mob/proc/spellremove(mob/M)
if(!mind)
return
for(var/X in src.mind.spell_list)
var/obj/effect/proc_holder/spell/spell_to_remove = X
qdel(spell_to_remove)
mind.spell_list -= spell_to_remove
/*Checks if the wizard can cast spells.
Made a proc so this is not repeated 14 (or more) times.*/
/mob/proc/casting()
//Removed the stat check because not all spells require clothing now.
if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe))
usr << "I don't feel strong enough without my robe."
return 0
if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal))
usr << "I don't feel strong enough without my sandals."
return 0
if(!istype(usr:head, /obj/item/clothing/head/wizard))
usr << "I don't feel strong enough without my hat."
return 0
else
return 1
//returns whether the mob is a wizard (or apprentice)
/proc/iswizard(mob/living/M)
return istype(M) && M.mind && ticker && ticker.mode && ((M.mind in ticker.mode.wizards) || (M.mind in ticker.mode.apprentices))
/datum/game_mode/proc/update_wiz_icons_added(datum/mind/wiz_mind)
var/datum/atom_hud/antag/wizhud = huds[ANTAG_HUD_WIZ]
wizhud.join_hud(wiz_mind.current)
set_antag_hud(wiz_mind.current, ((wiz_mind in wizards) ? "wizard" : "apprentice"))
/datum/game_mode/proc/update_wiz_icons_removed(datum/mind/wiz_mind)
var/datum/atom_hud/antag/wizhud = huds[ANTAG_HUD_WIZ]
wizhud.leave_hud(wiz_mind.current)
set_antag_hud(wiz_mind.current, null)