mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-29 23:17:02 +01:00
Add wizard loadouts
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
config.continuous_rounds = 0
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/lichdom/cast(list/targets,mob/user = usr)
|
||||
/obj/effect/proc_holder/spell/targeted/lichdom/cast(list/targets, mob/user = usr)
|
||||
if(!config.continuous_rounds)
|
||||
existence_stops_round_end = 1
|
||||
config.continuous_rounds = 1
|
||||
@@ -36,7 +36,7 @@
|
||||
for(var/mob/M in targets)
|
||||
var/list/hand_items = list()
|
||||
if(iscarbon(M))
|
||||
hand_items = list(M.get_active_hand(),M.get_inactive_hand())
|
||||
hand_items = list(M.get_active_hand(), M.get_inactive_hand())
|
||||
|
||||
if(marked_item && !stat_allowed) //sanity, shouldn't happen without badminry
|
||||
marked_item = null
|
||||
@@ -74,12 +74,9 @@
|
||||
var/mob/old_body = current_body
|
||||
var/turf/body_turf = get_turf(old_body)
|
||||
current_body = lich
|
||||
lich.Weaken(10+10*resurrections)
|
||||
lich.Weaken(10 + 10 * resurrections)
|
||||
++resurrections
|
||||
lich.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(lich), slot_shoes)
|
||||
lich.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(lich), slot_w_uniform)
|
||||
lich.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(lich), slot_wear_suit)
|
||||
lich.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(lich), slot_head)
|
||||
equip_lich(lich)
|
||||
|
||||
if(old_body && old_body.loc)
|
||||
if(iscarbon(old_body))
|
||||
@@ -127,7 +124,10 @@
|
||||
H.unEquip(H.head)
|
||||
H.unEquip(H.shoes)
|
||||
H.unEquip(H.head)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), slot_head)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(H), slot_w_uniform)
|
||||
equip_lich(H)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/lichdom/proc/equip_lich(mob/living/carbon/human/H)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), slot_head)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(H), slot_w_uniform)
|
||||
@@ -6,34 +6,36 @@
|
||||
var/category = "Offensive"
|
||||
var/log_name = "XX" //What it shows up as in logs
|
||||
var/cost = 2
|
||||
var/refundable = 1
|
||||
var/refundable = TRUE
|
||||
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/IsSpellAvailable() // For config prefs / gamemode restrictions - these are round applied
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/datum/spellbook_entry/proc/CanBuy(mob/living/carbon/human/user, obj/item/spellbook/book) // Specific circumstances
|
||||
if(book.uses<cost || limit == 0)
|
||||
return 0
|
||||
return 1
|
||||
if(book.uses < cost || limit == 0)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) //return 1 on success
|
||||
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) //return TRUE on success
|
||||
if(!S)
|
||||
S = new spell_type()
|
||||
|
||||
//Check if we got the spell already
|
||||
return LearnSpell(user, book, S)
|
||||
|
||||
/datum/spellbook_entry/proc/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell)
|
||||
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(initial(newspell.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)
|
||||
to_chat(user, "<span class='warning'>This spell cannot be improved further.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
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)
|
||||
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)
|
||||
@@ -51,12 +53,12 @@
|
||||
aspell.name = "Instant [aspell.name]"
|
||||
if(aspell.spell_level >= aspell.level_max)
|
||||
to_chat(user, "<span class='notice'>This spell cannot be strengthened any further.</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
//No same spell found - just learn it
|
||||
feedback_add_details("wizard_spell_learned",log_name)
|
||||
user.mind.AddSpell(S)
|
||||
to_chat(user, "<span class='notice'>You have learned [S.name].</span>")
|
||||
return 1
|
||||
feedback_add_details("wizard_spell_learned", log_name)
|
||||
user.mind.AddSpell(newspell)
|
||||
to_chat(user, "<span class='notice'>You have learned [newspell.name].</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/spellbook_entry/proc/CanRefund(mob/living/carbon/human/user, obj/item/spellbook/book)
|
||||
if(!refundable)
|
||||
@@ -71,7 +73,7 @@
|
||||
/datum/spellbook_entry/proc/Refund(mob/living/carbon/human/user, obj/item/spellbook/book) //return point value or -1 for failure
|
||||
var/area/wizard_station/A = locate()
|
||||
if(!(user in A.contents))
|
||||
to_chat(user, "<span clas=='warning'>You can only refund spells at the wizard lair</span>")
|
||||
to_chat(user, "<span class='warning'>You can only refund spells at the wizard lair.</span>")
|
||||
return -1
|
||||
if(!S)
|
||||
S = new spell_type()
|
||||
@@ -81,7 +83,7 @@
|
||||
spell_levels = aspell.spell_level
|
||||
user.mind.spell_list.Remove(aspell)
|
||||
QDEL_NULL(S)
|
||||
return cost * (spell_levels+1)
|
||||
return cost * (spell_levels + 1)
|
||||
return -1
|
||||
|
||||
/datum/spellbook_entry/proc/GetInfo()
|
||||
@@ -571,6 +573,48 @@
|
||||
category = "Summons"
|
||||
limit = 1
|
||||
|
||||
//Spell loadouts datum, list of loadouts is in wizloadouts.dm
|
||||
/datum/spellbook_entry/loadout
|
||||
name = "Standard Loadout"
|
||||
cost = 10
|
||||
category = "Standard"
|
||||
refundable = FALSE
|
||||
buy_word = "Summon"
|
||||
var/list/items_path = list()
|
||||
var/list/spells_path = list()
|
||||
var/destroy_spellbook = FALSE //Destroy the spellbook when bought, for loadouts containing non-standard items/spells, otherwise wiz can refund spells
|
||||
|
||||
/datum/spellbook_entry/loadout/GetInfo()
|
||||
var/dat = ""
|
||||
dat += "<b>[name]</b>"
|
||||
if(cost > 0)
|
||||
dat += " Cost:[cost]<br>"
|
||||
else
|
||||
dat += " No Cost<br>"
|
||||
dat += "<i>[desc]</i><br>"
|
||||
return dat
|
||||
|
||||
/datum/spellbook_entry/loadout/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
|
||||
if(destroy_spellbook)
|
||||
var/response = alert(user, "The [src] loadout cannot be refunded once bought. Are you sure this is what you want?", "No refunds!", "No", "Yes")
|
||||
if(response == "No")
|
||||
return FALSE
|
||||
to_chat(user, "<span class='notice'>[book] crumbles to ashes as you acquire its knowledge.</span>")
|
||||
qdel(book)
|
||||
else if(items_path.len)
|
||||
var/response = alert(user, "The [src] loadout contains items that will not be refundable if bought. Are you sure this is what you want?", "No refunds!", "No", "Yes")
|
||||
if(response == "No")
|
||||
return FALSE
|
||||
if(items_path.len)
|
||||
var/obj/item/storage/box/wizard/B = new(src)
|
||||
for(var/path in items_path)
|
||||
new path(B)
|
||||
user.put_in_hands(B)
|
||||
for(var/path in spells_path)
|
||||
var/obj/effect/proc_holder/spell/S = new path()
|
||||
LearnSpell(user, book, S)
|
||||
return TRUE
|
||||
|
||||
/obj/item/spellbook
|
||||
name = "spell book"
|
||||
desc = "The legendary book of spells of the wizard."
|
||||
@@ -587,12 +631,13 @@
|
||||
var/mob/living/carbon/human/owner
|
||||
var/list/datum/spellbook_entry/entries = list()
|
||||
var/list/categories = list()
|
||||
var/list/main_categories = list("Spells", "Magical Items")
|
||||
var/list/main_categories = list("Spells", "Magical Items", "Loadouts")
|
||||
var/list/spell_categories = list("Offensive", "Defensive", "Mobility", "Assistance", "Rituals")
|
||||
var/list/item_categories = list("Artefacts", "Weapons and Armors", "Staves", "Summons")
|
||||
var/list/loadout_categories = list("Standard", "Unique")
|
||||
|
||||
/obj/item/spellbook/proc/initialize()
|
||||
var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon
|
||||
var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon - /datum/spellbook_entry/loadout
|
||||
for(var/T in entry_types)
|
||||
var/datum/spellbook_entry/E = new T
|
||||
if(E.IsSpellAvailable())
|
||||
@@ -676,6 +721,12 @@
|
||||
if("Summons")
|
||||
dat += "Magical items geared towards bringing in outside forces to aid you.<BR><BR>"
|
||||
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
|
||||
if("Standard")
|
||||
dat += "These battle-tested spell sets are easy to use and provide good balance between offense and defense.<BR><BR>"
|
||||
dat += "They all cost, and are worth, 10 spell points. You are able to refund any of the spells included as long as you stay in the wizard den.<BR>"
|
||||
if("Unique")
|
||||
dat += "These esoteric loadouts usually contain spells or items that cannot be bought elsewhere in this spellbook.<BR><BR>"
|
||||
dat += "Recommended for experienced wizards looking for something new. No refunds once purchased!<BR>"
|
||||
return dat
|
||||
|
||||
/obj/item/spellbook/proc/wrap(content)
|
||||
@@ -720,23 +771,24 @@
|
||||
cat_dat[main_category] = "<hr>"
|
||||
dat += "<li><a [main_tab==main_category?"class=selected":""] href='byond://?src=[UID()];mainpage=[main_category]'>[main_category]</a></li>"
|
||||
dat += "</ul>"
|
||||
dat += "<ul id=\"tabs\">"
|
||||
switch(main_tab)
|
||||
if("Spells")
|
||||
dat += "<ul id=\"tabs\">"
|
||||
for(var/category in categories)
|
||||
if(category in item_categories)
|
||||
continue
|
||||
cat_dat[category] = "<hr>"
|
||||
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
|
||||
dat += "<li><a><b>Points remaining : [uses]</b></a></li>"
|
||||
if("Magical Items")
|
||||
dat += "<ul id=\"tabs\">"
|
||||
for(var/category in categories)
|
||||
if(category in spell_categories)
|
||||
continue
|
||||
cat_dat[category] = "<hr>"
|
||||
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
|
||||
dat += "<li><a><b>Points remaining : [uses]</b></a></li>"
|
||||
cat_dat[category] = "<hr>"
|
||||
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
|
||||
if("Magical Items")
|
||||
for(var/category in categories)
|
||||
if(category in item_categories)
|
||||
cat_dat[category] = "<hr>"
|
||||
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
|
||||
if("Loadouts")
|
||||
for(var/category in categories)
|
||||
if(category in loadout_categories)
|
||||
cat_dat[category] = "<hr>"
|
||||
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[UID()];page=[category]'>[category]</a></li>"
|
||||
dat += "<li><a><b>Points remaining : [uses]</b></a></li>"
|
||||
dat += "</ul>"
|
||||
|
||||
var/datum/spellbook_entry/E
|
||||
@@ -801,6 +853,8 @@
|
||||
tab = spell_categories[1]
|
||||
else if(main_tab == "Magical Items")
|
||||
tab = item_categories[1]
|
||||
else if(main_tab == "Loadouts")
|
||||
tab = loadout_categories[1]
|
||||
else if(href_list["page"])
|
||||
tab = sanitize(href_list["page"])
|
||||
attack_self(H)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
//Contains wizard loadouts and associated unique spells
|
||||
|
||||
//Standard loadouts, which are meant to be suggestions for beginners. Should always be worth exactly 10 spell points, and only contain standard wizard spells/items.
|
||||
/datum/spellbook_entry/loadout/mutant
|
||||
name = "Offense Focus : Mutant"
|
||||
desc = "A spellset focused around the Mutate spell as its main source of damage, which provides stun protection, laser eyes, and strong punches. <br> \
|
||||
Ethereal Jaunt and Blink provide escape and mobility, while Magic Missile and Desintegrate can be used together for dangerous or key targets. <br> \
|
||||
As this set lacks any form of healing or resurrection, healing items should be acquired from the station, and you should be careful to avoid being hurt in the first place. <br><br> \
|
||||
Provides Mutate, Ethereal Jaunt, Blink, Magic Missile, and Disintegrate."
|
||||
log_name = "OM"
|
||||
spells_path = list(/obj/effect/proc_holder/spell/targeted/genetic/mutate, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/targeted/turf_teleport/blink, \
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/magic_missile, /obj/effect/proc_holder/spell/targeted/touch/disintegrate)
|
||||
|
||||
/datum/spellbook_entry/loadout/lich
|
||||
name = "Defense Focus : Lich"
|
||||
desc = "This spellset uses the Bind Soul spell to safeguard your life as a lich and allow for more dangerous offensive spells to be used. <br> \
|
||||
Ethereal Jaunt provides escape, Fireball and Rod Form are your offensive spells, and Disable Tech and Greater Forcewall provides utility in disabling sec equipment or blocking their path. <br> \
|
||||
Care should be taken in hiding the item you choose as your phylactery after using Bind Soul, as you cannot revive if it destroyed or too far from your body! <br><br> \
|
||||
Provides Bind Soul, Ethereal Jaunt, Fireball, Rod Form, Disable Tech, and Greater Forcewall."
|
||||
log_name = "DL"
|
||||
spells_path = list(/obj/effect/proc_holder/spell/targeted/lichdom, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/fireball, \
|
||||
/obj/effect/proc_holder/spell/targeted/rod_form, /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech, /obj/effect/proc_holder/spell/targeted/forcewall/greater)
|
||||
|
||||
/datum/spellbook_entry/loadout/wands
|
||||
name = "Utility Focus : Wands"
|
||||
desc = "This set contain a Belt of Wands, providing offensive, defensive, and utility wands. Wands have limited charges, but can be partially recharged with the Charge spell included. <br> \
|
||||
Ethereal Jaunt and Blink provide escape and mobility, while Disintegrate and Repulse can be used to annihilate or push away anyone that gets too close to you. <br> \
|
||||
Do not lose any of your wands to the station's crew, as they are extremely deadly even in their hands. Remember that the Revive wand can be used on yourself for a full heal! <br><br> \
|
||||
Provides a Belt of Wands, Charge, Ethereal Jaunt, Blink, Repulse, and Desintegrate."
|
||||
log_name = "UW"
|
||||
items_path = list(/obj/item/storage/belt/wands/full)
|
||||
spells_path = list(/obj/effect/proc_holder/spell/targeted/charge, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/targeted/turf_teleport/blink, \
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse, /obj/effect/proc_holder/spell/targeted/touch/disintegrate)
|
||||
|
||||
//Unique loadouts, which are more gimmicky. Should contain some unique spell or item that separates it from just buying standard wiz spells, and be balanced around a 10 spell point cost.
|
||||
/datum/spellbook_entry/loadout/gunreaper
|
||||
name = "Gunslinging Reaper"
|
||||
desc = "Cloned over and over, the souls aboard this station yearn for a deserved rest.<br> \
|
||||
Bring them to the afterlife, one trigger pull at a time. <br> \
|
||||
You will likely need to scavenge additional ammo or weapons aboard the station. <br><br>\
|
||||
Provides a .357 Revolver, 4 speedloaders of ammo, Ethereal Jaunt, Blink, Summon Item, No Clothes, and Bind Soul, with a unique outfit."
|
||||
log_name = "GR"
|
||||
items_path = list(/obj/item/gun/projectile/revolver, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/clothing/under/syndicate)
|
||||
spells_path = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/targeted/turf_teleport/blink, \
|
||||
/obj/effect/proc_holder/spell/targeted/summonitem, /obj/effect/proc_holder/spell/noclothes, /obj/effect/proc_holder/spell/targeted/lichdom/gunslinger)
|
||||
category = "Unique"
|
||||
destroy_spellbook = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/lichdom/gunslinger/equip_lich(mob/living/carbon/human/H)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_suit(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(H), slot_w_uniform)
|
||||
@@ -60,7 +60,7 @@
|
||||
return
|
||||
|
||||
if(thearea.tele_proof && !istype(thearea, /area/wizard_station))
|
||||
to_chat(user, "A mysterious force disrupts your arcane spell matrix, and you remain where you are.")
|
||||
to_chat(user, "<span class='warning'>A mysterious force disrupts your arcane spell matrix, and you remain where you are.</span>")
|
||||
return
|
||||
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
@@ -79,7 +79,7 @@
|
||||
L+=T
|
||||
|
||||
if(!L.len)
|
||||
to_chat(user, "The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.")
|
||||
to_chat(user, "<span class='warning'>The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.</span>")
|
||||
return
|
||||
|
||||
if(user && user.buckled)
|
||||
@@ -104,3 +104,5 @@
|
||||
|
||||
smoke.start()
|
||||
src.uses -= 1
|
||||
for(var/datum/action/act in actions) //Update action buttons as some spells might now be castable
|
||||
act.UpdateButtonIcon()
|
||||
@@ -1124,6 +1124,11 @@
|
||||
playsound(loc, "rustle", 50, 1, -5)
|
||||
user.visible_message("<span class='notice'>[user] hugs \the [src].</span>","<span class='notice'>You hug \the [src].</span>")
|
||||
|
||||
/obj/item/storage/box/wizard
|
||||
name = "magical box"
|
||||
desc = "It's just an ordinary magical box."
|
||||
icon_state = "box_wizard"
|
||||
|
||||
#undef NODESIGN
|
||||
#undef NANOTRASEN
|
||||
#undef SYNDI
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 75 KiB |
@@ -595,6 +595,7 @@
|
||||
#include "code\game\gamemodes\wizard\soulstone.dm"
|
||||
#include "code\game\gamemodes\wizard\spellbook.dm"
|
||||
#include "code\game\gamemodes\wizard\wizard.dm"
|
||||
#include "code\game\gamemodes\wizard\wizloadouts.dm"
|
||||
#include "code\game\jobs\access.dm"
|
||||
#include "code\game\jobs\job_exp.dm"
|
||||
#include "code\game\jobs\job_objective.dm"
|
||||
|
||||
Reference in New Issue
Block a user