mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Merge remote-tracking branch 'upstream/dev-freeze' into dev
Conflicts: code/game/gamemodes/cult/runes.dm code/game/objects/items/weapons/implants/implantcase.dm code/game/objects/items/weapons/melee/energy.dm code/modules/mob/living/carbon/human/emote.dm code/modules/mob/living/carbon/human/human.dm code/modules/mob/living/carbon/human/human_attackhand.dm code/modules/mob/living/silicon/robot/drone/drone.dm code/modules/mob/living/silicon/robot/emote.dm code/modules/mob/living/silicon/robot/robot.dm code/modules/nano/modules/crew_monitor.dm code/modules/organs/organ_internal.dm
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
/*
|
||||
Aoe turf spells target a ring of tiles around the user
|
||||
This ring has an outer radius (range) and an inner radius (inner_radius)
|
||||
Aoe turf spells have two useful flags: IGNOREDENSE and IGNORESPACE. These are explained in setup.dm
|
||||
*/
|
||||
|
||||
/spell/aoe_turf //affects all turfs in view or range (depends)
|
||||
spell_flags = IGNOREDENSE
|
||||
var/inner_radius = -1 //for all your ring spell needs
|
||||
|
||||
/spell/aoe_turf/choose_targets(mob/user = usr)
|
||||
var/list/targets = list()
|
||||
|
||||
for(var/turf/target in view_or_range(range,user,selection_type))
|
||||
if(!(target in view_or_range(inner_radius,user,selection_type)))
|
||||
if(target.density && (spell_flags & IGNOREDENSE))
|
||||
continue
|
||||
if(istype(target, /turf/space) && (spell_flags & IGNORESPACE))
|
||||
continue
|
||||
targets += target
|
||||
|
||||
if(!targets.len) //doesn't waste the spell
|
||||
return
|
||||
|
||||
/*
|
||||
Aoe turf spells target a ring of tiles around the user
|
||||
This ring has an outer radius (range) and an inner radius (inner_radius)
|
||||
Aoe turf spells have two useful flags: IGNOREDENSE and IGNORESPACE. These are explained in setup.dm
|
||||
*/
|
||||
|
||||
/spell/aoe_turf //affects all turfs in view or range (depends)
|
||||
spell_flags = IGNOREDENSE
|
||||
var/inner_radius = -1 //for all your ring spell needs
|
||||
|
||||
/spell/aoe_turf/choose_targets(mob/user = usr)
|
||||
var/list/targets = list()
|
||||
|
||||
for(var/turf/target in view_or_range(range, holder, selection_type))
|
||||
if(!(target in view_or_range(inner_radius, holder, selection_type)))
|
||||
if(target.density && (spell_flags & IGNOREDENSE))
|
||||
continue
|
||||
if(istype(target, /turf/space) && (spell_flags & IGNORESPACE))
|
||||
continue
|
||||
targets += target
|
||||
|
||||
if(!targets.len) //doesn't waste the spell
|
||||
return
|
||||
|
||||
return targets
|
||||
@@ -1,9 +1,9 @@
|
||||
var/list/spells = typesof(/spell) //needed for the badmin verb for now
|
||||
|
||||
/spell
|
||||
name = "Spell"
|
||||
desc = "A spell"
|
||||
parent_type = /atom/movable
|
||||
var/name = "Spell"
|
||||
var/desc = "A spell"
|
||||
parent_type = /datum
|
||||
var/panel = "Spells"//What panel the proc holder needs to go on.
|
||||
|
||||
var/school = "evocation" //not relevant at now, but may be important later if there are changes to how spells work. the ones I used for now will probably be changed... maybe spell presets? lacking flexibility but with some other benefit?
|
||||
@@ -25,8 +25,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
|
||||
var/range = 7 //the range of the spell; outer radius for aoe spells
|
||||
var/message = "" //whatever it says to the guy affected by it
|
||||
var/selection_type = "view" //can be "range" or "view"
|
||||
var/atom/movable/holder //where the spell is. Normally the user, can be a projectile
|
||||
|
||||
var/atom/movable/holder //where the spell is. Normally the user, can be an item
|
||||
var/duration = 0 //how long the spell lasts
|
||||
|
||||
var/list/spell_levels = list(Sp_SPEED = 0, Sp_POWER = 0) //the current spell levels - total spell levels can be obtained by just adding the two values
|
||||
@@ -53,6 +52,8 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
|
||||
var/hud_state = "" //name of the icon used in generating the spell hud object
|
||||
var/override_base = ""
|
||||
|
||||
var/obj/screen/connected_button
|
||||
|
||||
///////////////////////
|
||||
///SETUP AND PROCESS///
|
||||
///////////////////////
|
||||
@@ -69,11 +70,6 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
|
||||
sleep(1)
|
||||
return
|
||||
|
||||
/spell/Click()
|
||||
..()
|
||||
|
||||
perform(usr)
|
||||
|
||||
/////////////////
|
||||
/////CASTING/////
|
||||
/////////////////
|
||||
@@ -182,18 +178,19 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
|
||||
|
||||
/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
|
||||
|
||||
if(!(src in user.spell_list))
|
||||
if(!(src in user.spell_list) && holder == user)
|
||||
error("[user] utilized the spell '[src]' without having it.")
|
||||
user << "<span class='warning'>You shouldn't have this spell! Something's wrong.</span>"
|
||||
return 0
|
||||
|
||||
if(silenced > 0)
|
||||
return
|
||||
|
||||
var/turf/Turf = get_turf(user)
|
||||
if(!Turf)
|
||||
var/turf/user_turf = get_turf(user)
|
||||
if(!user_turf)
|
||||
user << "<span class='warning'>You cannot cast spells in null space!</span>"
|
||||
|
||||
if(spell_flags & Z2NOCAST && (Turf.z in config.admin_levels)) //Certain spells are not allowed on the centcomm zlevel
|
||||
if(spell_flags & Z2NOCAST && (user_turf.z in config.admin_levels)) //Certain spells are not allowed on the centcomm zlevel
|
||||
return 0
|
||||
|
||||
if(spell_flags & CONSTRUCT_CHECK)
|
||||
@@ -201,7 +198,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
|
||||
if(findNullRod(T))
|
||||
return 0
|
||||
|
||||
if(istype(user, /mob/living/simple_animal))
|
||||
if(istype(user, /mob/living/simple_animal) && holder == user)
|
||||
var/mob/living/simple_animal/SA = user
|
||||
if(SA.purge)
|
||||
SA << "<span class='warning'>The nullrod's power interferes with your own!</span>"
|
||||
@@ -210,7 +207,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
|
||||
if(!src.check_charge(skipcharge, user)) //sees if we can cast based on charges alone
|
||||
return 0
|
||||
|
||||
if(!(spell_flags & GHOSTCAST))
|
||||
if(!(spell_flags & GHOSTCAST) && holder == user)
|
||||
if(user.stat && !(spell_flags & STATALLOWED))
|
||||
usr << "Not when you're incapacitated."
|
||||
return 0
|
||||
@@ -221,7 +218,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
|
||||
return 0
|
||||
|
||||
var/spell/noclothes/spell = locate() in user.spell_list
|
||||
if((spell_flags & NEEDSCLOTHES) && !(spell && istype(spell)))//clothes check
|
||||
if((spell_flags & NEEDSCLOTHES) && !(spell && istype(spell)) && holder == user)//clothes check
|
||||
if(!user.wearing_wiz_garb())
|
||||
return 0
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
var/spell/targeted/projectile/carried
|
||||
|
||||
penetrating = 0
|
||||
kill_count = 10 //set by the duration of the spell
|
||||
|
||||
var/proj_trail = 0 //if it leaves a trail
|
||||
@@ -15,18 +16,15 @@
|
||||
var/list/trails = new()
|
||||
|
||||
/obj/item/projectile/spell_projectile/Destroy()
|
||||
..()
|
||||
for(var/trail in trails)
|
||||
qdel(trail)
|
||||
carried = null
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/spell_projectile/ex_act()
|
||||
return
|
||||
|
||||
/obj/item/projectile/spell_projectile/before_move()
|
||||
if(carried)
|
||||
var/list/targets = carried.choose_prox_targets(user = carried.holder, spell_holder = src)
|
||||
if(targets.len)
|
||||
src.prox_cast(targets)
|
||||
if(proj_trail && src && src.loc) //pretty trails
|
||||
var/obj/effect/overlay/trail = PoolOrNew(/obj/effect/overlay, src.loc)
|
||||
trails += trail
|
||||
@@ -44,19 +42,14 @@
|
||||
return
|
||||
|
||||
/obj/item/projectile/spell_projectile/Bump(var/atom/A)
|
||||
if(loc)
|
||||
if(loc && carried)
|
||||
prox_cast(carried.choose_prox_targets(user = carried.holder, spell_holder = src))
|
||||
return
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/spell_projectile/on_impact()
|
||||
if(loc)
|
||||
if(loc && carried)
|
||||
prox_cast(carried.choose_prox_targets(user = carried.holder, spell_holder = src))
|
||||
return
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/spell_projectile/seeking
|
||||
name = "seeking spell"
|
||||
|
||||
/obj/item/projectile/spell_projectile/seeking/process_step()
|
||||
..()
|
||||
if(original && !isnull(src.loc))
|
||||
current = original //update the target
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
<I>This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage.</I><BR>
|
||||
<A href='byond://?src=\ref[src];spell_choice=fireball'>Fireball</A> (10)<BR>
|
||||
<I>This spell fires a fireball in the direction you're facing and does not require wizard garb. Be careful not to fire it at people that are standing next to you.</I><BR>
|
||||
<A href='byond://?src=\ref[src];spell_choice=disintegrate'>Disintegrate</A> (60)<BR>
|
||||
<I>This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown.</I><BR>
|
||||
<A href='byond://?src=\ref[src];spell_choice=disabletech'>Disable Technology</A> (60)<BR>
|
||||
<I>This spell disables all weapons, cameras and most other technology in range.</I><BR>
|
||||
<A href='byond://?src=\ref[src];spell_choice=smoke'>Smoke</A> (10)<BR>
|
||||
@@ -125,7 +123,7 @@
|
||||
uses--
|
||||
/*
|
||||
*/
|
||||
var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", subjugation = "Subjugation", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", staffchange = "Staff of Change", mentalfocus = "Mental Focus", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", noclothes = "No Clothes",fleshtostone = "Flesh to Stone")
|
||||
var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", subjugation = "Subjugation", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", staffchange = "Staff of Change", mentalfocus = "Mental Focus", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", noclothes = "No Clothes",fleshtostone = "Flesh to Stone")
|
||||
var/already_knows = 0
|
||||
for(var/spell/aspell in H.spell_list)
|
||||
if(available_spells[href_list["spell_choice"]] == initial(aspell.name))
|
||||
@@ -165,10 +163,6 @@
|
||||
feedback_add_details("wizard_spell_learned","FB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
||||
H.add_spell(new/spell/targeted/projectile/dumbfire/fireball)
|
||||
temp = "You have learned fireball."
|
||||
if("disintegrate")
|
||||
feedback_add_details("wizard_spell_learned","DG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
||||
H.add_spell(new/spell/targeted/disintegrate)
|
||||
temp = "You have learned disintegrate."
|
||||
if("disabletech")
|
||||
feedback_add_details("wizard_spell_learned","DT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
||||
H.add_spell(new/spell/aoe_turf/disable_tech)
|
||||
@@ -215,12 +209,8 @@
|
||||
temp = "You have learned knock."
|
||||
if("horseman")
|
||||
feedback_add_details("wizard_spell_learned","HH") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
||||
H.add_spell(new/spell/targeted/horsemask)
|
||||
H.add_spell(new/spell/targeted/equip_item/horsemask)
|
||||
temp = "You have learned curse of the horseman."
|
||||
if("fleshtostone")
|
||||
feedback_add_details("wizard_spell_learned","FS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
||||
H.add_spell(new/spell/targeted/flesh_to_stone)
|
||||
temp = "You have learned flesh to stone."
|
||||
if("staffchange")
|
||||
feedback_add_details("wizard_spell_learned","ST") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
|
||||
new /obj/item/weapon/gun/energy/staff(get_turf(H))
|
||||
@@ -258,7 +248,7 @@
|
||||
H.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
|
||||
H.see_in_dark = 8
|
||||
H.see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
H << "\blue The walls suddenly disappear."
|
||||
H << "span class='notice'>The walls suddenly disappear.</span>"
|
||||
temp = "You have purchased a scrying orb, and gained x-ray vision."
|
||||
max_uses--
|
||||
else
|
||||
@@ -429,7 +419,7 @@
|
||||
user.Weaken(20)
|
||||
|
||||
/obj/item/weapon/spellbook/oneuse/horsemask
|
||||
spell = /spell/targeted/horsemask
|
||||
spell = /spell/targeted/equip_item/horsemask
|
||||
spellname = "horses"
|
||||
icon_state ="bookhorses"
|
||||
desc = "This book is more horse than your mind has room for."
|
||||
|
||||
@@ -1,20 +1,37 @@
|
||||
/datum/mind
|
||||
var/list/learned_spells
|
||||
|
||||
/mob/Life()
|
||||
..()
|
||||
if(spell_masters && spell_masters.len)
|
||||
for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
|
||||
spell_master.update_spells(0, src)
|
||||
|
||||
/mob/Stat()
|
||||
/mob/Login()
|
||||
..()
|
||||
if(spell_list && spell_list.len && statpanel("Spells"))
|
||||
if(spell_masters)
|
||||
for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
|
||||
spell_master.toggle_open(1)
|
||||
client.screen -= spell_master
|
||||
|
||||
/mob/Stat()
|
||||
. = ..()
|
||||
if(. && spell_list && spell_list.len)
|
||||
for(var/spell/S in spell_list)
|
||||
if((!S.connected_button) || !statpanel(S.panel))
|
||||
continue //Not showing the noclothes spell
|
||||
switch(S.charge_type)
|
||||
if(Sp_RECHARGE)
|
||||
statpanel("Spells","[S.charge_counter/10.0]/[S.charge_max/10]",S)
|
||||
statpanel(S.panel,"[S.charge_counter/10.0]/[S.charge_max/10]",S.connected_button)
|
||||
if(Sp_CHARGES)
|
||||
statpanel("Spells","[S.charge_counter]/[S.charge_max]",S)
|
||||
statpanel(S.panel,"[S.charge_counter]/[S.charge_max]",S.connected_button)
|
||||
if(Sp_HOLDVAR)
|
||||
statpanel("Spells","[S.holder_var_type] [S.holder_var_amount]",S)
|
||||
statpanel(S.panel,"[S.holder_var_type] [S.holder_var_amount]",S.connected_button)
|
||||
|
||||
/hook/clone/proc/restore_spells(var/mob/H)
|
||||
if(H.mind && H.mind.learned_spells)
|
||||
for(var/spell/spell_to_add in H.mind.learned_spells)
|
||||
H.add_spell(spell_to_add)
|
||||
|
||||
/mob/proc/add_spell(var/spell/spell_to_add, var/spell_base = "wiz_spell_ready", var/master_type = /obj/screen/movable/spell_master)
|
||||
if(!spell_masters)
|
||||
@@ -36,6 +53,11 @@
|
||||
new_spell_master.icon_state = spell_base
|
||||
spell_masters.Add(new_spell_master)
|
||||
spell_list.Add(spell_to_add)
|
||||
if(mind)
|
||||
if(!mind.learned_spells)
|
||||
mind.learned_spells = list()
|
||||
mind.learned_spells += spell_to_add
|
||||
|
||||
return 1
|
||||
|
||||
/mob/proc/remove_spell(var/spell/spell_to_remove)
|
||||
@@ -48,6 +70,8 @@
|
||||
if(!spell_masters || !spell_masters.len)
|
||||
return
|
||||
|
||||
if(mind && mind.learned_spells)
|
||||
mind.learned_spells.Remove(spell_to_remove)
|
||||
spell_list.Remove(spell_to_remove)
|
||||
for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
|
||||
spell_master.remove_spell(spell_to_remove)
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/spell/targeted/disintegrate
|
||||
name = "Disintegrate"
|
||||
desc = "This spell instantly kills somebody adjacent to you with the vilest of magick."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 600
|
||||
spell_flags = NEEDSCLOTHES
|
||||
invocation = "EI NATH"
|
||||
invocation_type = SpI_SHOUT
|
||||
range = 1
|
||||
cooldown_min = 200 //100 deciseconds reduction per rank
|
||||
|
||||
sparks_spread = 1
|
||||
sparks_amt = 4
|
||||
|
||||
hud_state = "wiz_disint"
|
||||
|
||||
/spell/targeted/disintegrate/cast(var/list/targets)
|
||||
..()
|
||||
for(var/mob/living/target in targets)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(!C.has_brain()) // Their brain is already taken out
|
||||
var/obj/item/organ/brain/B = new(C.loc)
|
||||
B.transfer_identity(C)
|
||||
target.gib()
|
||||
return
|
||||
40
code/modules/spells/targeted/equip/equip.dm
Normal file
40
code/modules/spells/targeted/equip/equip.dm
Normal file
@@ -0,0 +1,40 @@
|
||||
//You can set duration to 0 to have the items last forever
|
||||
|
||||
/spell/targeted/equip_item
|
||||
name = "equipment spell"
|
||||
|
||||
var/list/equipped_summons = list() //assoc list of text ids and paths to spawn
|
||||
|
||||
var/list/summoned_items = list() //list of items we summoned and will dispose when the spell runs out
|
||||
|
||||
var/delete_old = 1 //if the item previously in the slot is deleted - otherwise, it's dropped
|
||||
|
||||
/spell/targeted/equip_item/cast(list/targets, mob/user = usr)
|
||||
..()
|
||||
for(var/mob/living/L in targets)
|
||||
for(var/slot_id in equipped_summons)
|
||||
var/to_create = equipped_summons[slot_id]
|
||||
slot_id = text2num(slot_id) //because the index is text, we access this instead
|
||||
var/obj/item/new_item = summon_item(to_create)
|
||||
var/obj/item/old_item = L.get_equipped_item(slot_id)
|
||||
L.equip_to_slot(new_item, slot_id)
|
||||
if(old_item)
|
||||
L.remove_from_mob(old_item)
|
||||
if(delete_old)
|
||||
qdel(old_item)
|
||||
else
|
||||
old_item.loc = L.loc
|
||||
|
||||
if(duration)
|
||||
summoned_items += new_item //we store it in a list to remove later
|
||||
|
||||
if(duration)
|
||||
spawn(duration)
|
||||
for(var/obj/item/to_remove in summoned_items)
|
||||
if(istype(to_remove.loc, /mob))
|
||||
var/mob/M = to_remove.loc
|
||||
M.remove_from_mob(to_remove)
|
||||
qdel(to_remove)
|
||||
|
||||
/spell/targeted/equip_item/proc/summon_item(var/newtype)
|
||||
return new newtype
|
||||
@@ -1,35 +1,39 @@
|
||||
/spell/targeted/horsemask
|
||||
name = "Curse of the Horseman"
|
||||
desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes."
|
||||
school = "transmutation"
|
||||
charge_type = Sp_RECHARGE
|
||||
charge_max = 150
|
||||
charge_counter = 0
|
||||
spell_flags = 0
|
||||
invocation = "KN'A FTAGHU, PUCK 'BTHNK!"
|
||||
invocation_type = SpI_SHOUT
|
||||
range = 7
|
||||
max_targets = 1
|
||||
cooldown_min = 30 //30 deciseconds reduction per rank
|
||||
selection_type = "range"
|
||||
|
||||
compatible_mobs = list(/mob/living/carbon/human)
|
||||
|
||||
hud_state = "wiz_horse"
|
||||
|
||||
/spell/targeted/horsemask/cast(list/targets, mob/user = usr)
|
||||
..()
|
||||
for(var/mob/living/target in targets)
|
||||
var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead
|
||||
magichead.canremove = 0 //curses!
|
||||
magichead.flags_inv = null //so you can still see their face
|
||||
magichead.voicechange = 1 //NEEEEIIGHH
|
||||
target.visible_message( "<span class='danger'>[target]'s face lights up in fire, and after the event a horse's head takes its place!</span>", \
|
||||
"<span class='danger'>Your face burns up, and shortly after the fire you realise you have the face of a horse!</span>")
|
||||
var/obj/old_mask = target.wear_mask
|
||||
if(old_mask)
|
||||
target.drop_from_inventory(old_mask)
|
||||
qdel(old_mask) //get rid of this shit
|
||||
target.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1)
|
||||
|
||||
flick("e_flash", target.flash)
|
||||
/spell/targeted/equip_item/horsemask
|
||||
name = "Curse of the Horseman"
|
||||
desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes."
|
||||
school = "transmutation"
|
||||
charge_type = Sp_RECHARGE
|
||||
charge_max = 150
|
||||
charge_counter = 0
|
||||
spell_flags = 0
|
||||
invocation = "KN'A FTAGHU, PUCK 'BTHNK!"
|
||||
invocation_type = SpI_SHOUT
|
||||
range = 7
|
||||
max_targets = 1
|
||||
cooldown_min = 30 //30 deciseconds reduction per rank
|
||||
selection_type = "range"
|
||||
|
||||
compatible_mobs = list(/mob/living/carbon/human)
|
||||
|
||||
hud_state = "wiz_horse"
|
||||
|
||||
/spell/targeted/equip_item/horsemask/New()
|
||||
..()
|
||||
equipped_summons = list("[slot_wear_mask]" = /obj/item/clothing/mask/horsehead)
|
||||
|
||||
/spell/targeted/equip_item/horsemask/cast(list/targets, mob/user = usr)
|
||||
..()
|
||||
for(var/mob/living/target in targets)
|
||||
target.visible_message( "<span class='danger'>[target]'s face lights up in fire, and after the event a horse's head takes its place!</span>", \
|
||||
"<span class='danger'>Your face burns up, and shortly after the fire you realise you have the face of a horse!</span>")
|
||||
flick("e_flash", target.flash)
|
||||
|
||||
/spell/targeted/equip_item/horsemask/summon_item(var/new_type)
|
||||
var/obj/item/new_item = new new_type
|
||||
new_item.canremove = 0 //curses!
|
||||
new_item.unacidable = 1
|
||||
if(istype(new_item, /obj/item/clothing/mask/horsehead))
|
||||
var/obj/item/clothing/mask/horsehead/magichead = new_item
|
||||
magichead.flags_inv = null //so you can still see their face
|
||||
magichead.voicechange = 1 //NEEEEIIGHH
|
||||
return new_item
|
||||
@@ -1,21 +0,0 @@
|
||||
/spell/targeted/flesh_to_stone
|
||||
name = "Flesh to Stone"
|
||||
desc = "This spell turns a single person into an inert statue for a long period of time."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 600
|
||||
spell_flags = NEEDSCLOTHES
|
||||
range = 3
|
||||
max_targets = 1
|
||||
invocation = "STAUN EI"
|
||||
invocation_type = SpI_SHOUT
|
||||
amt_stunned = 5//just exists to make sure the statue "catches" them
|
||||
cooldown_min = 200 //100 deciseconds reduction per rank
|
||||
|
||||
hud_state = "wiz_statue"
|
||||
|
||||
/spell/targeted/flesh_to_stone/cast(var/list/targets, mob/user)
|
||||
..()
|
||||
for(var/mob/living/target in targets)
|
||||
new /obj/structure/closet/statue(target.loc, target) //makes the statue
|
||||
return
|
||||
@@ -57,7 +57,7 @@ code\game\dna\genes\goon_powers.dm
|
||||
spell_flags = Z2NOCAST | NEEDSCLOTHES | INCLUDEUSER
|
||||
invocation = "BIRUZ BENNAR"
|
||||
invocation_type = SpI_SHOUT
|
||||
message = "\blue You feel strong! You feel a pressure building behind your eyes!"
|
||||
message = "<span class='notice'>You feel strong! You feel a pressure building behind your eyes!</span>"
|
||||
range = 0
|
||||
max_targets = 1
|
||||
|
||||
|
||||
@@ -51,7 +51,10 @@
|
||||
ghost.spell_list = victim.spell_list//If they have spells, transfer them. Now we basically have a backup mob.
|
||||
|
||||
caster.mind.transfer_to(victim)
|
||||
victim.spell_list = caster.spell_list//Now they are inside the victim's body.
|
||||
victim.spell_list = list() //clear those out
|
||||
for(var/spell/S in caster.spell_list)
|
||||
victim.add_spell(S) //Now they are inside the victim's body - this also generates the HUD
|
||||
caster.spell_list = list() //clean that out as well
|
||||
|
||||
if(victim.mind.special_verbs.len)//To add all the special verbs for the original caster.
|
||||
for(var/V in caster.mind.special_verbs)//Not too important but could come into play.
|
||||
@@ -59,7 +62,9 @@
|
||||
|
||||
ghost.mind.transfer_to(caster)
|
||||
caster.key = ghost.key //have to transfer the key since the mind was not active
|
||||
caster.spell_list = ghost.spell_list
|
||||
for(var/spell/S in ghost.spell_list)
|
||||
caster.add_spell(S)
|
||||
ghost.spell_list = list()
|
||||
|
||||
if(caster.mind.special_verbs.len)//If they had any special verbs, we add them here.
|
||||
for(var/V in caster.mind.special_verbs)
|
||||
@@ -71,4 +76,4 @@
|
||||
|
||||
//After a certain amount of time the victim gets a message about being in a different body.
|
||||
spawn(msg_wait)
|
||||
caster << "\red You feel woozy and lightheaded. <b>Your body doesn't seem like your own.</b>"
|
||||
caster << "<span class='danger'>You feel woozy and lightheaded. Your body doesn't seem like your own.</span>"
|
||||
|
||||
@@ -1,145 +1,145 @@
|
||||
/*
|
||||
Targeted spells (with the exception of dumbfire) select from all the mobs in the defined range
|
||||
Targeted spells have two useful flags: INCLUDEUSER and SELECTABLE. These are explained in setup.dm
|
||||
*/
|
||||
|
||||
|
||||
/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob
|
||||
var/max_targets = 1 //leave 0 for unlimited targets in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range
|
||||
var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast
|
||||
|
||||
|
||||
var/amt_weakened = 0
|
||||
var/amt_paralysis = 0
|
||||
var/amt_stunned = 0
|
||||
|
||||
var/amt_dizziness = 0
|
||||
var/amt_confused = 0
|
||||
var/amt_stuttering = 0
|
||||
|
||||
//set to negatives for healing
|
||||
var/amt_dam_fire = 0
|
||||
var/amt_dam_brute = 0
|
||||
var/amt_dam_oxy = 0
|
||||
var/amt_dam_tox = 0
|
||||
|
||||
var/amt_eye_blind = 0
|
||||
var/amt_eye_blurry = 0
|
||||
|
||||
var/list/compatible_mobs = list()
|
||||
|
||||
|
||||
/spell/targeted/choose_targets(mob/user = usr)
|
||||
var/list/targets = list()
|
||||
|
||||
if(max_targets == 0) //unlimited
|
||||
if(range == -2)
|
||||
targets = living_mob_list
|
||||
else
|
||||
for(var/mob/living/target in view_or_range(range, user, selection_type))
|
||||
targets += target
|
||||
|
||||
else if(max_targets == 1) //single target can be picked
|
||||
if((range == 0 || range == -1) && spell_flags & INCLUDEUSER)
|
||||
targets += user
|
||||
else
|
||||
var/list/possible_targets = list()
|
||||
var/list/starting_targets
|
||||
if(range == -2)
|
||||
starting_targets = living_mob_list
|
||||
else
|
||||
starting_targets = view_or_range(range, user, selection_type)
|
||||
|
||||
for(var/mob/living/M in starting_targets)
|
||||
if(!(spell_flags & INCLUDEUSER) && M == user)
|
||||
continue
|
||||
if(compatible_mobs && compatible_mobs.len)
|
||||
if(!is_type_in_list(M, compatible_mobs)) continue
|
||||
if(compatible_mobs && compatible_mobs.len && !is_type_in_list(M, compatible_mobs))
|
||||
continue
|
||||
possible_targets += M
|
||||
|
||||
if(possible_targets.len)
|
||||
if(spell_flags & SELECTABLE) //if we are allowed to choose. see setup.dm for details
|
||||
var/mob/temp_target = input(user, "Choose the target for the spell.", "Targeting") as null|mob in possible_targets
|
||||
if(temp_target)
|
||||
targets += temp_target
|
||||
else
|
||||
targets += pick(possible_targets)
|
||||
//Adds a safety check post-input to make sure those targets are actually in range.
|
||||
|
||||
|
||||
else
|
||||
var/list/possible_targets = list()
|
||||
var/list/starting_targets
|
||||
|
||||
if(range == -2)
|
||||
starting_targets = living_mob_list
|
||||
else
|
||||
starting_targets = view_or_range(range, user, selection_type)
|
||||
|
||||
for(var/mob/living/target in starting_targets)
|
||||
if(!(spell_flags & INCLUDEUSER) && target == user)
|
||||
continue
|
||||
if(compatible_mobs && !is_type_in_list(target, compatible_mobs))
|
||||
continue
|
||||
possible_targets += target
|
||||
|
||||
if(spell_flags & SELECTABLE)
|
||||
for(var/i = 1; i<=max_targets, i++)
|
||||
if(!possible_targets.len)
|
||||
break
|
||||
var/mob/M = input(user, "Choose the target for the spell.", "Targeting") as null|mob in possible_targets
|
||||
if(!M)
|
||||
break
|
||||
if(range != -2)
|
||||
if(!(M in view_or_range(range, user, selection_type)))
|
||||
continue
|
||||
targets += M
|
||||
possible_targets -= M
|
||||
else
|
||||
for(var/i=1,i<=max_targets,i++)
|
||||
if(!possible_targets.len)
|
||||
break
|
||||
if(target_ignore_prev)
|
||||
var/target = pick(possible_targets)
|
||||
possible_targets -= target
|
||||
targets += target
|
||||
else
|
||||
targets += pick(possible_targets)
|
||||
|
||||
if(!(spell_flags & INCLUDEUSER) && (user in targets))
|
||||
targets -= user
|
||||
|
||||
if(compatible_mobs && compatible_mobs.len)
|
||||
for(var/mob/living/target in targets) //filters out all the non-compatible mobs
|
||||
if(!is_type_in_list(target, compatible_mobs))
|
||||
targets -= target
|
||||
|
||||
return targets
|
||||
|
||||
/spell/targeted/cast(var/list/targets, mob/user)
|
||||
for(var/mob/living/target in targets)
|
||||
if(range >= 0)
|
||||
if(!(target in view_or_range(range, user, selection_type))) //filter at time of casting
|
||||
targets -= target
|
||||
continue
|
||||
apply_spell_damage(target)
|
||||
|
||||
/spell/targeted/proc/apply_spell_damage(mob/living/target)
|
||||
target.adjustBruteLoss(amt_dam_brute)
|
||||
target.adjustFireLoss(amt_dam_fire)
|
||||
target.adjustToxLoss(amt_dam_tox)
|
||||
target.adjustOxyLoss(amt_dam_oxy)
|
||||
//disabling
|
||||
target.Weaken(amt_weakened)
|
||||
target.Paralyse(amt_paralysis)
|
||||
target.Stun(amt_stunned)
|
||||
if(amt_weakened || amt_paralysis || amt_stunned)
|
||||
if(target.buckled)
|
||||
target.buckled = null
|
||||
target.eye_blind += amt_eye_blind
|
||||
target.eye_blurry += amt_eye_blurry
|
||||
target.dizziness += amt_dizziness
|
||||
target.confused += amt_confused
|
||||
/*
|
||||
Targeted spells (with the exception of dumbfire) select from all the mobs in the defined range
|
||||
Targeted spells have two useful flags: INCLUDEUSER and SELECTABLE. These are explained in setup.dm
|
||||
*/
|
||||
|
||||
|
||||
/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob
|
||||
var/max_targets = 1 //leave 0 for unlimited targets in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range
|
||||
var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast
|
||||
|
||||
|
||||
var/amt_weakened = 0
|
||||
var/amt_paralysis = 0
|
||||
var/amt_stunned = 0
|
||||
|
||||
var/amt_dizziness = 0
|
||||
var/amt_confused = 0
|
||||
var/amt_stuttering = 0
|
||||
|
||||
//set to negatives for healing
|
||||
var/amt_dam_fire = 0
|
||||
var/amt_dam_brute = 0
|
||||
var/amt_dam_oxy = 0
|
||||
var/amt_dam_tox = 0
|
||||
|
||||
var/amt_eye_blind = 0
|
||||
var/amt_eye_blurry = 0
|
||||
|
||||
var/list/compatible_mobs = list()
|
||||
|
||||
|
||||
/spell/targeted/choose_targets(mob/user = usr)
|
||||
var/list/targets = list()
|
||||
|
||||
if(max_targets == 0) //unlimited
|
||||
if(range == -2)
|
||||
targets = living_mob_list
|
||||
else
|
||||
for(var/mob/living/target in view_or_range(range, holder, selection_type))
|
||||
targets += target
|
||||
|
||||
else if(max_targets == 1) //single target can be picked
|
||||
if((range == 0 || range == -1) && spell_flags & INCLUDEUSER)
|
||||
targets += user
|
||||
else
|
||||
var/list/possible_targets = list()
|
||||
var/list/starting_targets
|
||||
if(range == -2)
|
||||
starting_targets = living_mob_list
|
||||
else
|
||||
starting_targets = view_or_range(range, holder, selection_type)
|
||||
|
||||
for(var/mob/living/M in starting_targets)
|
||||
if(!(spell_flags & INCLUDEUSER) && M == user)
|
||||
continue
|
||||
if(compatible_mobs && compatible_mobs.len)
|
||||
if(!is_type_in_list(M, compatible_mobs)) continue
|
||||
if(compatible_mobs && compatible_mobs.len && !is_type_in_list(M, compatible_mobs))
|
||||
continue
|
||||
possible_targets += M
|
||||
|
||||
if(possible_targets.len)
|
||||
if(spell_flags & SELECTABLE) //if we are allowed to choose. see setup.dm for details
|
||||
var/mob/temp_target = input(user, "Choose the target for the spell.", "Targeting") as null|mob in possible_targets
|
||||
if(temp_target)
|
||||
targets += temp_target
|
||||
else
|
||||
targets += pick(possible_targets)
|
||||
//Adds a safety check post-input to make sure those targets are actually in range.
|
||||
|
||||
|
||||
else
|
||||
var/list/possible_targets = list()
|
||||
var/list/starting_targets
|
||||
|
||||
if(range == -2)
|
||||
starting_targets = living_mob_list
|
||||
else
|
||||
starting_targets = view_or_range(range, holder, selection_type)
|
||||
|
||||
for(var/mob/living/target in starting_targets)
|
||||
if(!(spell_flags & INCLUDEUSER) && target == user)
|
||||
continue
|
||||
if(compatible_mobs && !is_type_in_list(target, compatible_mobs))
|
||||
continue
|
||||
possible_targets += target
|
||||
|
||||
if(spell_flags & SELECTABLE)
|
||||
for(var/i = 1; i<=max_targets, i++)
|
||||
if(!possible_targets.len)
|
||||
break
|
||||
var/mob/M = input(user, "Choose the target for the spell.", "Targeting") as null|mob in possible_targets
|
||||
if(!M)
|
||||
break
|
||||
if(range != -2)
|
||||
if(!(M in view_or_range(range, holder, selection_type)))
|
||||
continue
|
||||
targets += M
|
||||
possible_targets -= M
|
||||
else
|
||||
for(var/i=1,i<=max_targets,i++)
|
||||
if(!possible_targets.len)
|
||||
break
|
||||
if(target_ignore_prev)
|
||||
var/target = pick(possible_targets)
|
||||
possible_targets -= target
|
||||
targets += target
|
||||
else
|
||||
targets += pick(possible_targets)
|
||||
|
||||
if(!(spell_flags & INCLUDEUSER) && (user in targets))
|
||||
targets -= user
|
||||
|
||||
if(compatible_mobs && compatible_mobs.len)
|
||||
for(var/mob/living/target in targets) //filters out all the non-compatible mobs
|
||||
if(!is_type_in_list(target, compatible_mobs))
|
||||
targets -= target
|
||||
|
||||
return targets
|
||||
|
||||
/spell/targeted/cast(var/list/targets, mob/user)
|
||||
for(var/mob/living/target in targets)
|
||||
if(range >= 0)
|
||||
if(!(target in view_or_range(range, holder, selection_type))) //filter at time of casting
|
||||
targets -= target
|
||||
continue
|
||||
apply_spell_damage(target)
|
||||
|
||||
/spell/targeted/proc/apply_spell_damage(mob/living/target)
|
||||
target.adjustBruteLoss(amt_dam_brute)
|
||||
target.adjustFireLoss(amt_dam_fire)
|
||||
target.adjustToxLoss(amt_dam_tox)
|
||||
target.adjustOxyLoss(amt_dam_oxy)
|
||||
//disabling
|
||||
target.Weaken(amt_weakened)
|
||||
target.Paralyse(amt_paralysis)
|
||||
target.Stun(amt_stunned)
|
||||
if(amt_weakened || amt_paralysis || amt_stunned)
|
||||
if(target.buckled)
|
||||
target.buckled = null
|
||||
target.eye_blind += amt_eye_blind
|
||||
target.eye_blurry += amt_eye_blurry
|
||||
target.dizziness += amt_dizziness
|
||||
target.confused += amt_confused
|
||||
target.stuttering += amt_stuttering
|
||||
Reference in New Issue
Block a user