mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-22 08:01:06 +00:00
Wizard spellbooks can now be stored in the belt slot.
Necromancers now get 10 spell points, up from 8.
Smoke now properly layers over mobs, obscuring them.
Wizard Apprentices and Skeletons are now in the Ghost Spawner menu. The former can be enabled by buying an Apprentice Pebble artifact, a new wizard item which acts as a portable spawnpoint. The latter by casting Raise Dead on a corpse.
Apprentices are now given additional spells at the bottom of their spellbook, depending on which type of wizard their master is."
Bought artifacts now appear in your hands, if you have any free.
The Return to Master spell has received numerous bugfixes and should now work as expected, most of the time.
250 lines
9.2 KiB
Plaintext
250 lines
9.2 KiB
Plaintext
#define LOCKED 2
|
|
#define CAN_MAKE_CONTRACTS 4
|
|
|
|
var/list/artefact_feedback = list(/obj/structure/closet/wizard/armor = "HS",
|
|
/obj/item/gun/energy/staff/focus = "MF",
|
|
/obj/item/monster_manual = "MA",
|
|
/obj/item/contract/apprentice = "CP",
|
|
/obj/item/apprentice_pebble = "AP",
|
|
/obj/structure/closet/wizard/souls = "SS",
|
|
/obj/structure/closet/wizard/scrying = "SO",
|
|
/obj/item/teleportation_scroll = "TS",
|
|
/obj/item/gun/energy/staff = "ST",
|
|
/obj/item/gun/energy/staff/animate = "SA",
|
|
/obj/item/melee/energy/wizard = "WS",
|
|
/obj/item/gun/energy/staff/chaos = "SC",
|
|
/obj/item/storage/belt/wands/full = "WB")
|
|
|
|
/obj/item/spellbook
|
|
name = "master spell book"
|
|
desc = "The legendary book of spells of the wizard."
|
|
icon = 'icons/obj/wizard.dmi'
|
|
icon_state = "spellbook"
|
|
throw_speed = 1
|
|
throw_range = 5
|
|
w_class = ITEMSIZE_SMALL
|
|
slot_flags = SLOT_BELT
|
|
var/uses = 1
|
|
var/temp = null
|
|
var/datum/spellbook/spellbook
|
|
var/spellbook_type = /datum/spellbook //for spawning specific spellbooks.
|
|
|
|
/obj/item/spellbook/Initialize()
|
|
. = ..()
|
|
set_spellbook(spellbook_type)
|
|
|
|
/obj/item/spellbook/proc/set_spellbook(var/type)
|
|
if(spellbook)
|
|
qdel(spellbook)
|
|
spellbook = new type()
|
|
uses = spellbook.max_uses
|
|
name = spellbook.name
|
|
desc = spellbook.desc
|
|
|
|
/obj/item/spellbook/attack_self(mob/user as mob)
|
|
if(!user)
|
|
return
|
|
if(!(user.faction == "Space Wizard"))
|
|
if(istype(user, /mob/living/carbon/human))
|
|
//Save the users active hand
|
|
var/mob/living/carbon/human/H = user
|
|
var/obj/item/organ/external/LA = H.get_organ(BP_L_ARM)
|
|
var/obj/item/organ/external/RA = H.get_organ(BP_R_ARM)
|
|
var/active_hand = H.hand
|
|
to_chat(user, "<span class='warning'>You feel unimaginable agony as your eyes pour over millenia of forbidden knowledge!</span>")
|
|
user.show_message("<b>[user]</b> screams in horror!",2)
|
|
H.ChangeToHusk()
|
|
H.adjust_fire_stacks(0, H.fire_stacks)
|
|
H.IgniteMob(2)
|
|
H.updatehealth()
|
|
user.drop_item()
|
|
playsound(user, 'sound/hallucinations/i_see_you2.ogg', 100, 1)
|
|
if(active_hand)
|
|
LA.droplimb(0,DROPLIMB_BURN)
|
|
else
|
|
RA.droplimb(0,DROPLIMB_BURN)
|
|
return
|
|
else
|
|
interact(user)
|
|
|
|
/obj/item/spellbook/interact(mob/user as mob)
|
|
var/dat = null
|
|
if(temp)
|
|
dat = "[temp]<br><a href='byond://?src=\ref[src];temp=1'>Return</a>"
|
|
else
|
|
dat = "<center><h3>[spellbook.title]</h3><i>[spellbook.title_desc]</i><br>You have [uses] spell slot[uses > 1 ? "s" : ""] left.</center><br>"
|
|
dat += "<center><font color='#ff33cc'>Requires Wizard Garb</font><br><font color='#ff6600'>Selectable Target</font><br><font color='#33cc33'>Spell Charge Type: Recharge, Sacrifice, Charges</font></center><br>"
|
|
for(var/i in 1 to spellbook.spells.len)
|
|
var/name = "" //name of target
|
|
var/desc = "" //description of target
|
|
var/info = "" //additional information
|
|
if(ispath(spellbook.spells[i],/datum/spellbook))
|
|
var/datum/spellbook/S = spellbook.spells[i]
|
|
name = initial(S.name)
|
|
desc = initial(S.book_desc)
|
|
info = "<font color='#ff33cc'>[initial(S.max_uses)] Spell Slots</font>"
|
|
else if(ispath(spellbook.spells[i],/obj))
|
|
var/obj/O = spellbook.spells[i]
|
|
name = "Artefact: [capitalize(initial(O.name))]" //because 99.99% of objects dont have capitals in them and it makes it look weird.
|
|
desc = initial(O.desc)
|
|
else if(ispath(spellbook.spells[i],/spell))
|
|
var/spell/S = spellbook.spells[i]
|
|
name = initial(S.name)
|
|
desc = initial(S.desc)
|
|
var/testing = initial(S.spell_flags)
|
|
if(testing & NEEDSCLOTHES)
|
|
info = "<font color='#ff33cc'>W</font>"
|
|
var/type = ""
|
|
switch(initial(S.charge_type))
|
|
if(Sp_RECHARGE)
|
|
type = "R"
|
|
if(Sp_HOLDVAR)
|
|
type = "S"
|
|
if(Sp_CHARGES)
|
|
type = "C"
|
|
info += "<font color='#33cc33'>[type]</font>"
|
|
dat += "<A href='byond://?src=\ref[src];path=[spellbook.spells[i]]'>[name]</a>"
|
|
if(length(info))
|
|
dat += " ([info])"
|
|
dat += " ([spellbook.spells[spellbook.spells[i]]] spell slot[spellbook.spells[spellbook.spells[i]] > 1 ? "s" : "" ])"
|
|
if(spellbook.book_flags & CAN_MAKE_CONTRACTS)
|
|
dat += " <A href='byond://?src=\ref[src];path=[spellbook.spells[i]];contract=1;'>Make Contract</a>"
|
|
dat += "<br><i>[desc]</i><br>"
|
|
dat += "<center><A href='byond://?src=\ref[src];reset=1'>Re-memorize your spellbook.</a></center>"
|
|
dat += "<center><A href='byond://?src=\ref[src];lock=1'>[spellbook.book_flags & LOCKED ? "Unlock" : "Lock"] the spellbook.</a></center>"
|
|
user << browse(dat,"window=spellbook")
|
|
|
|
/obj/item/spellbook/Topic(href,href_list)
|
|
..()
|
|
|
|
var/mob/living/carbon/human/H = usr
|
|
|
|
if(H.stat || H.restrained())
|
|
return
|
|
|
|
if(!istype(H))
|
|
return
|
|
|
|
if(H.mind && spellbook.book_flags & LOCKED && H.mind.special_role == "apprentice") //make sure no scrubs get behind the lock
|
|
return
|
|
|
|
if(!H.contents.Find(src))
|
|
H << browse(null,"window=spellbook")
|
|
return
|
|
|
|
if(href_list["lock"])
|
|
if(spellbook.book_flags & LOCKED)
|
|
spellbook.book_flags &= ~LOCKED
|
|
else
|
|
spellbook.book_flags |= LOCKED
|
|
|
|
if(href_list["temp"])
|
|
temp = null
|
|
|
|
if(href_list["path"])
|
|
var/path = text2path(href_list["path"])
|
|
if(uses < spellbook.spells[path])
|
|
to_chat(usr, "<span class='notice'>You do not have enough spell slots to purchase this.</span>")
|
|
return
|
|
uses -= spellbook.spells[path]
|
|
send_feedback(path) //feedback stuff
|
|
if(ispath(path,/datum/spellbook))
|
|
src.set_spellbook(path)
|
|
temp = "You have chosen a new spellbook."
|
|
else
|
|
if(href_list["contract"])
|
|
if(!(spellbook.book_flags & CAN_MAKE_CONTRACTS))
|
|
return //no
|
|
spellbook.max_uses -= spellbook.spells[path] //no basksies
|
|
var/obj/O = new /obj/item/contract/boon(get_turf(usr),path)
|
|
temp = "You have purchased \the [O]."
|
|
else
|
|
if(ispath(path,/spell))
|
|
temp = src.add_spell(usr,path)
|
|
else if(ispath(path, /obj/item/contract/apprentice))
|
|
var/obj/item/contract/apprentice/A = new path(get_turf(usr))
|
|
A.contract_master = usr
|
|
A.additional_spells = spellbook.apprentice_spells
|
|
temp = "You have purchased \a [A]."
|
|
spellbook.max_uses -= spellbook.spells[path]
|
|
playsound(get_turf(usr),'sound/effects/phasein.ogg',50,1)
|
|
usr.put_in_hands(A)
|
|
else if(ispath(path, /obj/item/apprentice_pebble))
|
|
var/obj/item/apprentice_pebble/A = new path(get_turf(usr))
|
|
A.contract.additional_spells = spellbook.apprentice_spells
|
|
A.contract.contract_master = usr
|
|
temp = "You have purchased \a [A]."
|
|
spellbook.max_uses -= spellbook.spells[path]
|
|
playsound(get_turf(usr),'sound/effects/phasein.ogg',50,1)
|
|
usr.put_in_hands(A)
|
|
else
|
|
var/obj/O = new path(get_turf(usr))
|
|
usr.put_in_hands(O)
|
|
temp = "You have purchased \a [O]."
|
|
spellbook.max_uses -= spellbook.spells[path]
|
|
//finally give it a bit of an oomf
|
|
playsound(get_turf(usr),'sound/effects/phasein.ogg',50,1)
|
|
if(href_list["reset"])
|
|
var/area/wizard_station/A = locate()
|
|
if(usr in A.contents)
|
|
uses = spellbook.max_uses
|
|
H.spellremove()
|
|
temp = "All spells have been removed. You may now memorize a new set of spells."
|
|
feedback_add_details("wizard_spell_learned","UM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
|
else
|
|
to_chat(usr, "<span class='warning'>You must be in the wizard academy to re-memorize your spells.</span>")
|
|
|
|
src.interact(usr)
|
|
|
|
|
|
/obj/item/spellbook/proc/send_feedback(var/path)
|
|
if(ispath(path,/datum/spellbook))
|
|
var/datum/spellbook/S = path
|
|
feedback_add_details("wizard_spell_learned","[initial(S.feedback)]")
|
|
else if(ispath(path,/spell))
|
|
var/spell/S = path
|
|
feedback_add_details("wizard_spell_learned","[initial(S.feedback)]")
|
|
else if(ispath(path,/obj))
|
|
feedback_add_details("wizard_spell_learned","[artefact_feedback[path]]")
|
|
|
|
|
|
/obj/item/spellbook/proc/add_spell(var/mob/user, var/spell_path)
|
|
for(var/spell/S in user.spell_list)
|
|
if(istype(S,spell_path))
|
|
if(!S.can_improve())
|
|
uses += spellbook.spells[spell_path]
|
|
return "You cannot improve the spell [S] further."
|
|
if(S.can_improve(Sp_SPEED) && S.can_improve(Sp_POWER))
|
|
switch(alert(user, "Do you want to upgrade this spell's speed or power?", "Spell upgrade", "Speed", "Power", "Cancel"))
|
|
if("Speed")
|
|
return S.quicken_spell()
|
|
if("Power")
|
|
return S.empower_spell()
|
|
else
|
|
uses += spellbook.spells[spell_path]
|
|
return
|
|
else if(S.can_improve(Sp_POWER))
|
|
return S.empower_spell()
|
|
else if(S.can_improve(Sp_SPEED))
|
|
return S.quicken_spell()
|
|
|
|
var/spell/S = new spell_path()
|
|
user.add_spell(S)
|
|
return "You learn the spell [S]"
|
|
|
|
/datum/spellbook
|
|
var/name = "\improper book of tomes"
|
|
var/desc = "The legendary book of spells of the wizard."
|
|
var/book_desc = "Holds information on the various tomes available to a wizard"
|
|
var/feedback = "" //doesn't need one.
|
|
var/book_flags = 0
|
|
var/max_uses = 1
|
|
var/title = "Book of Tomes"
|
|
var/title_desc = "This tome marks down all the available tomes for use. Choose wisely, there are no refunds."
|
|
var/list/spells = list(/datum/spellbook/standard = 1,
|
|
/datum/spellbook/cleric = 1,
|
|
/datum/spellbook/battlemage = 1,
|
|
/datum/spellbook/druid = 1,
|
|
/datum/spellbook/necromancer = 1
|
|
) //spell's path = cost of spell
|
|
var/list/apprentice_spells = list() // extra spells that apprentices get, based on their master's book |