Merge branch 'Ghommie-cit265' of https://github.com/Ghommie/Citadel-Station-13 into Ghommie-cit435
This commit is contained in:
@@ -1,92 +1,92 @@
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport
|
||||
name = "Area teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
nonabstract_req = 1
|
||||
|
||||
var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list
|
||||
var/invocation_area = 1 //if the invocation appends the selected area
|
||||
var/sound1 = 'sound/weapons/zapbang.ogg'
|
||||
var/sound2 = 'sound/weapons/zapbang.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1,mob/living/user = usr)
|
||||
var/thearea = before_cast(targets)
|
||||
if(!thearea || !cast_check(1))
|
||||
revert_cast()
|
||||
return
|
||||
invocation(thearea,user)
|
||||
if(charge_type == "recharge" && recharge)
|
||||
INVOKE_ASYNC(src, .proc/start_recharge)
|
||||
cast(targets,thearea,user)
|
||||
after_cast(targets)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/before_cast(list/targets)
|
||||
var/area/U = get_area(usr)
|
||||
if(U.noteleport && !istype(U, /area/wizard_station)) // Wizard den special check for those complaining about being unable to tele on station.
|
||||
to_chat(usr, "<span class='warning'>Unseen forces prevent you from casting this spell in this area</span>")
|
||||
return
|
||||
var/A
|
||||
if(!randomise_selection)
|
||||
A = input("Area to teleport to", "Teleport", A) as null|anything in GLOB.teleportlocs
|
||||
else
|
||||
A = pick(GLOB.teleportlocs)
|
||||
if(!A)
|
||||
return
|
||||
var/area/thearea = GLOB.teleportlocs[A]
|
||||
|
||||
return thearea
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea,mob/user = usr)
|
||||
playsound(get_turf(user), sound1, 50,1)
|
||||
for(var/mob/living/target in targets)
|
||||
var/list/L = list()
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
if(!T.density)
|
||||
var/clear = 1
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
clear = 0
|
||||
break
|
||||
if(clear)
|
||||
L+=T
|
||||
|
||||
if(!L.len)
|
||||
to_chat(usr, "The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.")
|
||||
return
|
||||
|
||||
if(target && target.buckled)
|
||||
target.buckled.unbuckle_mob(target, force=1)
|
||||
|
||||
var/forcecheck = istype(get_area(target), /area/wizard_station)
|
||||
var/list/tempL = L
|
||||
var/attempt = null
|
||||
var/success = 0
|
||||
while(tempL.len)
|
||||
attempt = pick(tempL)
|
||||
do_teleport(target, attempt, channel = TELEPORT_CHANNEL_MAGIC, forced = forcecheck)
|
||||
if(get_turf(target) == attempt)
|
||||
success = 1
|
||||
break
|
||||
else
|
||||
tempL.Remove(attempt)
|
||||
|
||||
if(!success)
|
||||
do_teleport(target, L, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = forcecheck)
|
||||
playsound(get_turf(user), sound2, 50,1)
|
||||
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null,mob/user = usr)
|
||||
if(!invocation_area || !chosenarea)
|
||||
..()
|
||||
else
|
||||
switch(invocation_type)
|
||||
if("shout")
|
||||
user.say("[invocation] [uppertext(chosenarea.name)]", forced = "spell")
|
||||
if(user.gender==MALE)
|
||||
playsound(user.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
|
||||
else
|
||||
playsound(user.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
|
||||
if("whisper")
|
||||
user.whisper("[invocation] [uppertext(chosenarea.name)]")
|
||||
|
||||
return
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport
|
||||
name = "Area teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
nonabstract_req = 1
|
||||
|
||||
var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list
|
||||
var/invocation_area = 1 //if the invocation appends the selected area
|
||||
var/sound1 = 'sound/weapons/zapbang.ogg'
|
||||
var/sound2 = 'sound/weapons/zapbang.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1,mob/living/user = usr)
|
||||
var/thearea = before_cast(targets)
|
||||
if(!thearea || !cast_check(1))
|
||||
revert_cast()
|
||||
return
|
||||
invocation(thearea,user)
|
||||
if(charge_type == "recharge" && recharge)
|
||||
INVOKE_ASYNC(src, .proc/start_recharge)
|
||||
cast(targets,thearea,user)
|
||||
after_cast(targets)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/before_cast(list/targets)
|
||||
var/area/U = get_area(usr)
|
||||
if(U.noteleport && !istype(U, /area/wizard_station)) // Wizard den special check for those complaining about being unable to tele on station.
|
||||
to_chat(usr, "<span class='warning'>Unseen forces prevent you from casting this spell in this area</span>")
|
||||
return
|
||||
var/A
|
||||
if(!randomise_selection)
|
||||
A = input("Area to teleport to", "Teleport", A) as null|anything in GLOB.teleportlocs
|
||||
else
|
||||
A = pick(GLOB.teleportlocs)
|
||||
if(!A)
|
||||
return
|
||||
var/area/thearea = GLOB.teleportlocs[A]
|
||||
|
||||
return thearea
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea,mob/user = usr)
|
||||
playsound(get_turf(user), sound1, 50,1)
|
||||
for(var/mob/living/target in targets)
|
||||
var/list/L = list()
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
if(!T.density)
|
||||
var/clear = 1
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
clear = 0
|
||||
break
|
||||
if(clear)
|
||||
L+=T
|
||||
|
||||
if(!L.len)
|
||||
to_chat(usr, "The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.")
|
||||
return
|
||||
|
||||
if(target && target.buckled)
|
||||
target.buckled.unbuckle_mob(target, force=1)
|
||||
|
||||
var/forcecheck = istype(get_area(target), /area/wizard_station)
|
||||
var/list/tempL = L
|
||||
var/attempt = null
|
||||
var/success = 0
|
||||
while(tempL.len)
|
||||
attempt = pick(tempL)
|
||||
do_teleport(target, attempt, channel = TELEPORT_CHANNEL_MAGIC, forced = forcecheck)
|
||||
if(get_turf(target) == attempt)
|
||||
success = 1
|
||||
break
|
||||
else
|
||||
tempL.Remove(attempt)
|
||||
|
||||
if(!success)
|
||||
do_teleport(target, L, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = forcecheck)
|
||||
playsound(get_turf(user), sound2, 50,1)
|
||||
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null,mob/user = usr)
|
||||
if(!invocation_area || !chosenarea)
|
||||
..()
|
||||
else
|
||||
switch(invocation_type)
|
||||
if("shout")
|
||||
user.say("[invocation] [uppertext(chosenarea.name)]", forced = "spell")
|
||||
if(user.gender==MALE)
|
||||
playsound(user.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
|
||||
else
|
||||
playsound(user.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
|
||||
if("whisper")
|
||||
user.whisper("[invocation] [uppertext(chosenarea.name)]")
|
||||
|
||||
return
|
||||
|
||||
@@ -1,100 +1,100 @@
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure
|
||||
name = "Conjure"
|
||||
desc = "This spell conjures objs of the specified types in range."
|
||||
|
||||
var/list/summon_type = list() //determines what exactly will be summoned
|
||||
//should be text, like list("/mob/living/simple_animal/bot/ed209")
|
||||
|
||||
var/summon_lifespan = 0 // 0=permanent, any other time in deciseconds
|
||||
var/summon_amt = 1 //amount of objects summoned
|
||||
var/summon_ignore_density = FALSE //if set to 1, adds dense tiles to possible spawn places
|
||||
var/summon_ignore_prev_spawn_points = 0 //if set to 1, each new object is summoned on a new spawn point
|
||||
|
||||
var/list/newVars = list() //vars of the summoned objects will be replaced with those where they meet
|
||||
//should have format of list("emagged" = 1,"name" = "Wizard's Justicebot"), for example
|
||||
|
||||
var/cast_sound = 'sound/items/welder.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets,mob/user = usr)
|
||||
playsound(get_turf(user), cast_sound, 50,1)
|
||||
for(var/turf/T in targets)
|
||||
if(T.density && !summon_ignore_density)
|
||||
targets -= T
|
||||
|
||||
for(var/i=0,i<summon_amt,i++)
|
||||
if(!targets.len)
|
||||
break
|
||||
var/summoned_object_type = pick(summon_type)
|
||||
var/spawn_place = pick(targets)
|
||||
if(summon_ignore_prev_spawn_points)
|
||||
targets -= spawn_place
|
||||
if(ispath(summoned_object_type, /turf))
|
||||
var/turf/O = spawn_place
|
||||
var/N = summoned_object_type
|
||||
O.ChangeTurf(N)
|
||||
else
|
||||
var/atom/summoned_object = new summoned_object_type(spawn_place)
|
||||
|
||||
for(var/varName in newVars)
|
||||
if(varName in newVars)
|
||||
summoned_object.vv_edit_var(varName, newVars[varName])
|
||||
summoned_object.flags_1 |= ADMIN_SPAWNED_1
|
||||
if(summon_lifespan)
|
||||
QDEL_IN(summoned_object, summon_lifespan)
|
||||
|
||||
post_summon(summoned_object, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/proc/post_summon(atom/summoned_object, mob/user)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/summonEdSwarm //test purposes - Also a lot of fun
|
||||
name = "Dispense Wizard Justice"
|
||||
desc = "This spell dispenses wizard justice."
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/bot/ed209)
|
||||
summon_amt = 10
|
||||
range = 3
|
||||
newVars = list("emagged" = 2, "remote_disabled" = 1,"shoot_sound" = 'sound/weapons/laser.ogg',"projectile" = /obj/item/projectile/beam/laser, "declare_arrests" = 0,"name" = "Wizard's Justicebot")
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/linkWorlds
|
||||
name = "Link Worlds"
|
||||
desc = "A whole new dimension for you to play with! They won't be happy about it, though."
|
||||
invocation = "WTF"
|
||||
clothes_req = FALSE
|
||||
charge_max = 600
|
||||
cooldown_min = 200
|
||||
summon_type = list(/obj/structure/spawner/nether)
|
||||
summon_amt = 1
|
||||
range = 1
|
||||
cast_sound = 'sound/weapons/marauder.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item
|
||||
name = "Summon weapon"
|
||||
desc = "A generic spell that should not exist. This summons an instance of a specific type of item, or if one already exists, un-summons it. Summons into hand if possible."
|
||||
invocation_type = "none"
|
||||
include_user = 1
|
||||
range = -1
|
||||
clothes_req = 0
|
||||
var/obj/item/item
|
||||
var/item_type = /obj/item/banhammer
|
||||
school = "conjuration"
|
||||
charge_max = 150
|
||||
cooldown_min = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/cast(list/targets, mob/user = usr)
|
||||
if (item && !QDELETED(item))
|
||||
qdel(item)
|
||||
item = null
|
||||
else
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
if(C.dropItemToGround(C.get_active_held_item()))
|
||||
C.put_in_hands(make_item(), TRUE)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/Destroy()
|
||||
if(item)
|
||||
qdel(item)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/proc/make_item()
|
||||
item = new item_type
|
||||
return item
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure
|
||||
name = "Conjure"
|
||||
desc = "This spell conjures objs of the specified types in range."
|
||||
|
||||
var/list/summon_type = list() //determines what exactly will be summoned
|
||||
//should be text, like list("/mob/living/simple_animal/bot/ed209")
|
||||
|
||||
var/summon_lifespan = 0 // 0=permanent, any other time in deciseconds
|
||||
var/summon_amt = 1 //amount of objects summoned
|
||||
var/summon_ignore_density = FALSE //if set to 1, adds dense tiles to possible spawn places
|
||||
var/summon_ignore_prev_spawn_points = 0 //if set to 1, each new object is summoned on a new spawn point
|
||||
|
||||
var/list/newVars = list() //vars of the summoned objects will be replaced with those where they meet
|
||||
//should have format of list("emagged" = 1,"name" = "Wizard's Justicebot"), for example
|
||||
|
||||
var/cast_sound = 'sound/items/welder.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets,mob/user = usr)
|
||||
playsound(get_turf(user), cast_sound, 50,1)
|
||||
for(var/turf/T in targets)
|
||||
if(T.density && !summon_ignore_density)
|
||||
targets -= T
|
||||
|
||||
for(var/i=0,i<summon_amt,i++)
|
||||
if(!targets.len)
|
||||
break
|
||||
var/summoned_object_type = pick(summon_type)
|
||||
var/spawn_place = pick(targets)
|
||||
if(summon_ignore_prev_spawn_points)
|
||||
targets -= spawn_place
|
||||
if(ispath(summoned_object_type, /turf))
|
||||
var/turf/O = spawn_place
|
||||
var/N = summoned_object_type
|
||||
O.ChangeTurf(N, flags = CHANGETURF_INHERIT_AIR)
|
||||
else
|
||||
var/atom/summoned_object = new summoned_object_type(spawn_place)
|
||||
|
||||
for(var/varName in newVars)
|
||||
if(varName in newVars)
|
||||
summoned_object.vv_edit_var(varName, newVars[varName])
|
||||
summoned_object.flags_1 |= ADMIN_SPAWNED_1
|
||||
if(summon_lifespan)
|
||||
QDEL_IN(summoned_object, summon_lifespan)
|
||||
|
||||
post_summon(summoned_object, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/proc/post_summon(atom/summoned_object, mob/user)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/summonEdSwarm //test purposes - Also a lot of fun
|
||||
name = "Dispense Wizard Justice"
|
||||
desc = "This spell dispenses wizard justice."
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/bot/ed209)
|
||||
summon_amt = 10
|
||||
range = 3
|
||||
newVars = list("emagged" = 2, "remote_disabled" = 1,"shoot_sound" = 'sound/weapons/laser.ogg',"projectile" = /obj/item/projectile/beam/laser, "declare_arrests" = 0,"name" = "Wizard's Justicebot")
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/linkWorlds
|
||||
name = "Link Worlds"
|
||||
desc = "A whole new dimension for you to play with! They won't be happy about it, though."
|
||||
invocation = "WTF"
|
||||
clothes_req = FALSE
|
||||
charge_max = 600
|
||||
cooldown_min = 200
|
||||
summon_type = list(/obj/structure/spawner/nether)
|
||||
summon_amt = 1
|
||||
range = 1
|
||||
cast_sound = 'sound/weapons/marauder.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item
|
||||
name = "Summon weapon"
|
||||
desc = "A generic spell that should not exist. This summons an instance of a specific type of item, or if one already exists, un-summons it. Summons into hand if possible."
|
||||
invocation_type = "none"
|
||||
include_user = 1
|
||||
range = -1
|
||||
clothes_req = 0
|
||||
var/obj/item/item
|
||||
var/item_type = /obj/item/banhammer
|
||||
school = "conjuration"
|
||||
charge_max = 150
|
||||
cooldown_min = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/cast(list/targets, mob/user = usr)
|
||||
if (item && !QDELETED(item))
|
||||
qdel(item)
|
||||
item = null
|
||||
else
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
if(C.dropItemToGround(C.get_active_held_item()))
|
||||
C.put_in_hands(make_item(), TRUE)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/Destroy()
|
||||
if(item)
|
||||
qdel(item)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/proc/make_item()
|
||||
item = new item_type
|
||||
return item
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
dancefloor_exists = FALSE
|
||||
for(var/i in 1 to dancefloor_turfs.len)
|
||||
var/turf/T = dancefloor_turfs[i]
|
||||
T.ChangeTurf(dancefloor_turfs_types[i])
|
||||
T.ChangeTurf(dancefloor_turfs_types[i], flags = CHANGETURF_INHERIT_AIR)
|
||||
else
|
||||
var/list/funky_turfs = RANGE_TURFS(1, user)
|
||||
for(var/turf/closed/solid in funky_turfs)
|
||||
@@ -248,7 +248,7 @@
|
||||
var/turf/T = t
|
||||
dancefloor_turfs[i] = T
|
||||
dancefloor_turfs_types[i] = T.type
|
||||
T.ChangeTurf((i % 2 == 0) ? /turf/open/floor/light/colour_cycle/dancefloor_a : /turf/open/floor/light/colour_cycle/dancefloor_b)
|
||||
T.ChangeTurf((i % 2 == 0) ? /turf/open/floor/light/colour_cycle/dancefloor_a : /turf/open/floor/light/colour_cycle/dancefloor_b, flags = CHANGETURF_INHERIT_AIR)
|
||||
i++
|
||||
|
||||
/datum/effect_system/smoke_spread/transparent/dancefloor_devil
|
||||
|
||||
@@ -1,114 +1,114 @@
|
||||
|
||||
//NEEDS MAJOR CODE CLEANUP
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire
|
||||
|
||||
var/projectile_type = ""
|
||||
var/activate_on_collision = 1
|
||||
|
||||
var/proj_icon = 'icons/obj/projectiles.dmi'
|
||||
var/proj_icon_state = "spell"
|
||||
var/proj_name = "a spell projectile"
|
||||
|
||||
var/proj_trail = 0 //if it leaves a trail
|
||||
var/proj_trail_lifespan = 0 //deciseconds
|
||||
var/proj_trail_icon = 'icons/obj/wizard.dmi'
|
||||
var/proj_trail_icon_state = "trail"
|
||||
|
||||
var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this
|
||||
|
||||
var/proj_insubstantial = 0 //if it can pass through dense objects or not
|
||||
var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target)
|
||||
|
||||
var/proj_lifespan = 100 //in deciseconds * proj_step_delay
|
||||
var/proj_step_delay = 1 //lower = faster
|
||||
var/list/ignore_factions = list() //Faction types that will be ignored
|
||||
|
||||
var/check_antimagic = TRUE
|
||||
var/check_holy = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/choose_targets(mob/user = usr)
|
||||
|
||||
var/turf/T = get_turf(user)
|
||||
for(var/i = 1; i < range; i++)
|
||||
var/turf/new_turf = get_step(T, user.dir)
|
||||
if(new_turf.density)
|
||||
break
|
||||
T = new_turf
|
||||
perform(list(T),user = user)
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/cast(list/targets, mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/turf/target in targets)
|
||||
launch_at(target, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/proc/launch_at(turf/target, mob/user)
|
||||
set waitfor = FALSE
|
||||
var/obj/effect/proc_holder/spell/targeted/projectile
|
||||
if(istext(proj_type))
|
||||
var/projectile_type = text2path(proj_type)
|
||||
projectile = new projectile_type(user)
|
||||
else if(istype(proj_type, /obj/effect/proc_holder/spell))
|
||||
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
|
||||
var/obj/effect/proc_holder/spell/targeted/trigger/T = projectile
|
||||
T.linked_spells += proj_type
|
||||
else
|
||||
projectile = new proj_type(user)
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.setDir(get_dir(projectile, target))
|
||||
projectile.name = proj_name
|
||||
|
||||
var/current_loc = user.loc
|
||||
|
||||
projectile.forceMove(current_loc)
|
||||
|
||||
for(var/i = 0,i < proj_lifespan,i++)
|
||||
if(!projectile)
|
||||
break
|
||||
|
||||
if(proj_insubstantial)
|
||||
projectile.forceMove(get_step(projectile, projectile.dir))
|
||||
else
|
||||
step(projectile, projectile.dir)
|
||||
|
||||
if(projectile.loc == current_loc || i == proj_lifespan)
|
||||
projectile.cast(current_loc,user=user)
|
||||
break
|
||||
|
||||
var/mob/living/L = locate(/mob/living) in range(projectile, proj_trigger_range) - user
|
||||
if(L && L.stat != DEAD && L.anti_magic_check(check_antimagic, check_holy))
|
||||
if(!ignore_factions.len)
|
||||
projectile.cast(L.loc,user=user)
|
||||
break
|
||||
else
|
||||
var/faction_check = FALSE
|
||||
for(var/faction in L.faction)
|
||||
if(ignore_factions.Find(faction))
|
||||
faction_check = TRUE
|
||||
break
|
||||
if(!faction_check)
|
||||
projectile.cast(L.loc,user=user)
|
||||
break
|
||||
|
||||
if(proj_trail && projectile)
|
||||
proj_trail(projectile)
|
||||
|
||||
current_loc = projectile.loc
|
||||
var/matrix/M = new
|
||||
M.Turn(dir2angle(projectile.dir))
|
||||
projectile.transform = M
|
||||
|
||||
sleep(proj_step_delay)
|
||||
|
||||
if(projectile)
|
||||
qdel(projectile)
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/proc/proj_trail(obj/effect/proc_holder/spell/targeted/projectile)
|
||||
set waitfor = FALSE
|
||||
if(projectile)
|
||||
var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc)
|
||||
trail.icon = proj_trail_icon
|
||||
trail.icon_state = proj_trail_icon_state
|
||||
trail.density = FALSE
|
||||
QDEL_IN(trail, proj_trail_lifespan)
|
||||
|
||||
//NEEDS MAJOR CODE CLEANUP
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire
|
||||
|
||||
var/projectile_type = ""
|
||||
var/activate_on_collision = 1
|
||||
|
||||
var/proj_icon = 'icons/obj/projectiles.dmi'
|
||||
var/proj_icon_state = "spell"
|
||||
var/proj_name = "a spell projectile"
|
||||
|
||||
var/proj_trail = 0 //if it leaves a trail
|
||||
var/proj_trail_lifespan = 0 //deciseconds
|
||||
var/proj_trail_icon = 'icons/obj/wizard.dmi'
|
||||
var/proj_trail_icon_state = "trail"
|
||||
|
||||
var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this
|
||||
|
||||
var/proj_insubstantial = 0 //if it can pass through dense objects or not
|
||||
var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target)
|
||||
|
||||
var/proj_lifespan = 100 //in deciseconds * proj_step_delay
|
||||
var/proj_step_delay = 1 //lower = faster
|
||||
var/list/ignore_factions = list() //Faction types that will be ignored
|
||||
|
||||
var/check_antimagic = TRUE
|
||||
var/check_holy = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/choose_targets(mob/user = usr)
|
||||
|
||||
var/turf/T = get_turf(user)
|
||||
for(var/i = 1; i < range; i++)
|
||||
var/turf/new_turf = get_step(T, user.dir)
|
||||
if(new_turf.density)
|
||||
break
|
||||
T = new_turf
|
||||
perform(list(T),user = user)
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/cast(list/targets, mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/turf/target in targets)
|
||||
launch_at(target, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/proc/launch_at(turf/target, mob/user)
|
||||
set waitfor = FALSE
|
||||
var/obj/effect/proc_holder/spell/targeted/projectile
|
||||
if(istext(proj_type))
|
||||
var/projectile_type = text2path(proj_type)
|
||||
projectile = new projectile_type(user)
|
||||
else if(istype(proj_type, /obj/effect/proc_holder/spell))
|
||||
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
|
||||
var/obj/effect/proc_holder/spell/targeted/trigger/T = projectile
|
||||
T.linked_spells += proj_type
|
||||
else
|
||||
projectile = new proj_type(user)
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.setDir(get_dir(projectile, target))
|
||||
projectile.name = proj_name
|
||||
|
||||
var/current_loc = user.loc
|
||||
|
||||
projectile.forceMove(current_loc)
|
||||
|
||||
for(var/i = 0,i < proj_lifespan,i++)
|
||||
if(!projectile)
|
||||
break
|
||||
|
||||
if(proj_insubstantial)
|
||||
projectile.forceMove(get_step(projectile, projectile.dir))
|
||||
else
|
||||
step(projectile, projectile.dir)
|
||||
|
||||
if(projectile.loc == current_loc || i == proj_lifespan)
|
||||
projectile.cast(current_loc,user=user)
|
||||
break
|
||||
|
||||
var/mob/living/L = locate(/mob/living) in range(projectile, proj_trigger_range) - user
|
||||
if(L && L.stat != DEAD && L.anti_magic_check(check_antimagic, check_holy))
|
||||
if(!ignore_factions.len)
|
||||
projectile.cast(L.loc,user=user)
|
||||
break
|
||||
else
|
||||
var/faction_check = FALSE
|
||||
for(var/faction in L.faction)
|
||||
if(ignore_factions.Find(faction))
|
||||
faction_check = TRUE
|
||||
break
|
||||
if(!faction_check)
|
||||
projectile.cast(L.loc,user=user)
|
||||
break
|
||||
|
||||
if(proj_trail && projectile)
|
||||
proj_trail(projectile)
|
||||
|
||||
current_loc = projectile.loc
|
||||
var/matrix/M = new
|
||||
M.Turn(dir2angle(projectile.dir))
|
||||
projectile.transform = M
|
||||
|
||||
sleep(proj_step_delay)
|
||||
|
||||
if(projectile)
|
||||
qdel(projectile)
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/proc/proj_trail(obj/effect/proc_holder/spell/targeted/projectile)
|
||||
set waitfor = FALSE
|
||||
if(projectile)
|
||||
var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc)
|
||||
trail.icon = proj_trail_icon
|
||||
trail.icon_state = proj_trail_icon_state
|
||||
trail.density = FALSE
|
||||
QDEL_IN(trail, proj_trail_lifespan)
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/obj/effect/proc_holder/spell/targeted/emplosion
|
||||
name = "Emplosion"
|
||||
desc = "This spell emplodes an area."
|
||||
|
||||
var/emp_heavy = 2
|
||||
var/emp_light = 3
|
||||
|
||||
action_icon_state = "emp"
|
||||
sound = 'sound/weapons/zapbang.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/emplosion/cast(list/targets,mob/user = usr)
|
||||
playsound(get_turf(user), sound, 50,1)
|
||||
for(var/mob/living/target in targets)
|
||||
if(target.anti_magic_check())
|
||||
continue
|
||||
empulse(target.loc, emp_heavy, emp_light)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/emplosion
|
||||
name = "Emplosion"
|
||||
desc = "This spell emplodes an area."
|
||||
|
||||
var/emp_heavy = 2
|
||||
var/emp_light = 3
|
||||
|
||||
action_icon_state = "emp"
|
||||
sound = 'sound/weapons/zapbang.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/emplosion/cast(list/targets,mob/user = usr)
|
||||
playsound(get_turf(user), sound, 50,1)
|
||||
for(var/mob/living/target in targets)
|
||||
if(target.anti_magic_check())
|
||||
continue
|
||||
empulse(target.loc, emp_heavy, emp_light)
|
||||
|
||||
return
|
||||
@@ -1,103 +1,103 @@
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt
|
||||
name = "Ethereal Jaunt"
|
||||
desc = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 300
|
||||
clothes_req = 1
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
cooldown_min = 100 //50 deciseconds reduction per rank
|
||||
include_user = 1
|
||||
nonabstract_req = 1
|
||||
var/jaunt_duration = 50 //in deciseconds
|
||||
var/jaunt_in_time = 5
|
||||
var/jaunt_in_type = /obj/effect/temp_visual/wizard
|
||||
var/jaunt_out_type = /obj/effect/temp_visual/wizard/out
|
||||
action_icon_state = "jaunt"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets,mob/user = usr) //magnets, so mostly hardcoded
|
||||
playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1)
|
||||
for(var/mob/living/target in targets)
|
||||
INVOKE_ASYNC(src, .proc/do_jaunt, target)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/do_jaunt(mob/living/target)
|
||||
target.notransform = 1
|
||||
var/turf/mobloc = get_turf(target)
|
||||
var/obj/effect/dummy/phased_mob/spell_jaunt/holder = new /obj/effect/dummy/phased_mob/spell_jaunt(mobloc)
|
||||
new jaunt_out_type(mobloc, target.dir)
|
||||
target.ExtinguishMob()
|
||||
target.forceMove(holder)
|
||||
target.reset_perspective(holder)
|
||||
target.notransform=0 //mob is safely inside holder now, no need for protection.
|
||||
jaunt_steam(mobloc)
|
||||
|
||||
sleep(jaunt_duration)
|
||||
|
||||
if(target.loc != holder) //mob warped out of the warp
|
||||
qdel(holder)
|
||||
return
|
||||
mobloc = get_turf(target.loc)
|
||||
jaunt_steam(mobloc)
|
||||
target.canmove = 0
|
||||
holder.reappearing = 1
|
||||
playsound(get_turf(target), 'sound/magic/ethereal_exit.ogg', 50, 1, -1)
|
||||
sleep(25 - jaunt_in_time)
|
||||
new jaunt_in_type(mobloc, holder.dir)
|
||||
target.setDir(holder.dir)
|
||||
sleep(jaunt_in_time)
|
||||
qdel(holder)
|
||||
if(!QDELETED(target))
|
||||
if(mobloc.density)
|
||||
for(var/direction in GLOB.alldirs)
|
||||
var/turf/T = get_step(mobloc, direction)
|
||||
if(T)
|
||||
if(target.Move(T))
|
||||
break
|
||||
target.canmove = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/jaunt_steam(mobloc)
|
||||
var/datum/effect_system/steam_spread/steam = new /datum/effect_system/steam_spread()
|
||||
steam.set_up(10, 0, mobloc)
|
||||
steam.start()
|
||||
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt
|
||||
name = "water"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "nothing"
|
||||
var/reappearing = 0
|
||||
var/movedelay = 0
|
||||
var/movespeed = 2
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
invisibility = 60
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt/Destroy()
|
||||
// Eject contents if deleted somehow
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.forceMove(get_turf(src))
|
||||
return ..()
|
||||
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt/relaymove(var/mob/user, direction)
|
||||
if ((movedelay > world.time) || reappearing || !direction)
|
||||
return
|
||||
var/turf/newLoc = get_step(src,direction)
|
||||
setDir(direction)
|
||||
|
||||
movedelay = world.time + movespeed
|
||||
|
||||
if(newLoc.flags_1 & NOJAUNT_1)
|
||||
to_chat(user, "<span class='warning'>Some strange aura is blocking the way.</span>")
|
||||
return
|
||||
if (locate(/obj/effect/blessing, newLoc))
|
||||
to_chat(user, "<span class='warning'>Holy energies block your path!</span>")
|
||||
return
|
||||
|
||||
forceMove(newLoc)
|
||||
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt/ex_act(blah)
|
||||
return
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt/bullet_act(blah)
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt
|
||||
name = "Ethereal Jaunt"
|
||||
desc = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 300
|
||||
clothes_req = 1
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
cooldown_min = 100 //50 deciseconds reduction per rank
|
||||
include_user = 1
|
||||
nonabstract_req = 1
|
||||
var/jaunt_duration = 50 //in deciseconds
|
||||
var/jaunt_in_time = 5
|
||||
var/jaunt_in_type = /obj/effect/temp_visual/wizard
|
||||
var/jaunt_out_type = /obj/effect/temp_visual/wizard/out
|
||||
action_icon_state = "jaunt"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets,mob/user = usr) //magnets, so mostly hardcoded
|
||||
playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1)
|
||||
for(var/mob/living/target in targets)
|
||||
INVOKE_ASYNC(src, .proc/do_jaunt, target)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/do_jaunt(mob/living/target)
|
||||
target.notransform = 1
|
||||
var/turf/mobloc = get_turf(target)
|
||||
var/obj/effect/dummy/phased_mob/spell_jaunt/holder = new /obj/effect/dummy/phased_mob/spell_jaunt(mobloc)
|
||||
new jaunt_out_type(mobloc, target.dir)
|
||||
target.ExtinguishMob()
|
||||
target.forceMove(holder)
|
||||
target.reset_perspective(holder)
|
||||
target.notransform=0 //mob is safely inside holder now, no need for protection.
|
||||
jaunt_steam(mobloc)
|
||||
|
||||
sleep(jaunt_duration)
|
||||
|
||||
if(target.loc != holder) //mob warped out of the warp
|
||||
qdel(holder)
|
||||
return
|
||||
mobloc = get_turf(target.loc)
|
||||
jaunt_steam(mobloc)
|
||||
target.canmove = 0
|
||||
holder.reappearing = 1
|
||||
playsound(get_turf(target), 'sound/magic/ethereal_exit.ogg', 50, 1, -1)
|
||||
sleep(25 - jaunt_in_time)
|
||||
new jaunt_in_type(mobloc, holder.dir)
|
||||
target.setDir(holder.dir)
|
||||
sleep(jaunt_in_time)
|
||||
qdel(holder)
|
||||
if(!QDELETED(target))
|
||||
if(mobloc.density)
|
||||
for(var/direction in GLOB.alldirs)
|
||||
var/turf/T = get_step(mobloc, direction)
|
||||
if(T)
|
||||
if(target.Move(T))
|
||||
break
|
||||
target.canmove = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/jaunt_steam(mobloc)
|
||||
var/datum/effect_system/steam_spread/steam = new /datum/effect_system/steam_spread()
|
||||
steam.set_up(10, 0, mobloc)
|
||||
steam.start()
|
||||
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt
|
||||
name = "water"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "nothing"
|
||||
var/reappearing = 0
|
||||
var/movedelay = 0
|
||||
var/movespeed = 2
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
invisibility = 60
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt/Destroy()
|
||||
// Eject contents if deleted somehow
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.forceMove(get_turf(src))
|
||||
return ..()
|
||||
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt/relaymove(var/mob/user, direction)
|
||||
if ((movedelay > world.time) || reappearing || !direction)
|
||||
return
|
||||
var/turf/newLoc = get_step(src,direction)
|
||||
setDir(direction)
|
||||
|
||||
movedelay = world.time + movespeed
|
||||
|
||||
if(newLoc.flags_1 & NOJAUNT_1)
|
||||
to_chat(user, "<span class='warning'>Some strange aura is blocking the way.</span>")
|
||||
return
|
||||
if (locate(/obj/effect/blessing, newLoc))
|
||||
to_chat(user, "<span class='warning'>Holy energies block your path!</span>")
|
||||
return
|
||||
|
||||
forceMove(newLoc)
|
||||
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt/ex_act(blah)
|
||||
return
|
||||
/obj/effect/dummy/phased_mob/spell_jaunt/bullet_act(blah)
|
||||
return
|
||||
@@ -1,16 +1,16 @@
|
||||
/obj/effect/proc_holder/spell/targeted/explosion
|
||||
name = "Explosion"
|
||||
desc = "This spell explodes an area."
|
||||
|
||||
var/ex_severe = 1
|
||||
var/ex_heavy = 2
|
||||
var/ex_light = 3
|
||||
var/ex_flash = 4
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets,mob/user = usr)
|
||||
for(var/mob/living/target in targets)
|
||||
if(target.anti_magic_check())
|
||||
continue
|
||||
explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/explosion
|
||||
name = "Explosion"
|
||||
desc = "This spell explodes an area."
|
||||
|
||||
var/ex_severe = 1
|
||||
var/ex_heavy = 2
|
||||
var/ex_light = 3
|
||||
var/ex_flash = 4
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets,mob/user = usr)
|
||||
for(var/mob/living/target in targets)
|
||||
if(target.anti_magic_check())
|
||||
continue
|
||||
explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash)
|
||||
|
||||
return
|
||||
@@ -1,44 +1,44 @@
|
||||
/obj/effect/proc_holder/spell/targeted/genetic
|
||||
name = "Genetic"
|
||||
desc = "This spell inflicts a set of mutations and disabilities upon the target."
|
||||
|
||||
var/list/active_on = list()
|
||||
var/list/traits = list() //disabilities
|
||||
var/list/mutations = list() //mutation strings
|
||||
var/duration = 100 //deciseconds
|
||||
/*
|
||||
Disabilities
|
||||
1st bit - ?
|
||||
2nd bit - ?
|
||||
3rd bit - ?
|
||||
4th bit - ?
|
||||
5th bit - ?
|
||||
6th bit - ?
|
||||
*/
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets,mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/mob/living/carbon/target in targets)
|
||||
if(target.anti_magic_check())
|
||||
continue
|
||||
if(!target.dna)
|
||||
continue
|
||||
for(var/A in mutations)
|
||||
target.dna.add_mutation(A)
|
||||
for(var/A in traits)
|
||||
ADD_TRAIT(target, A, GENETICS_SPELL)
|
||||
active_on += target
|
||||
addtimer(CALLBACK(src, .proc/remove, target), duration)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/Destroy()
|
||||
. = ..()
|
||||
for(var/V in active_on)
|
||||
remove(V)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/proc/remove(mob/living/carbon/target)
|
||||
active_on -= target
|
||||
if(!QDELETED(target))
|
||||
for(var/A in mutations)
|
||||
target.dna.remove_mutation(A)
|
||||
for(var/A in traits)
|
||||
/obj/effect/proc_holder/spell/targeted/genetic
|
||||
name = "Genetic"
|
||||
desc = "This spell inflicts a set of mutations and disabilities upon the target."
|
||||
|
||||
var/list/active_on = list()
|
||||
var/list/traits = list() //disabilities
|
||||
var/list/mutations = list() //mutation strings
|
||||
var/duration = 100 //deciseconds
|
||||
/*
|
||||
Disabilities
|
||||
1st bit - ?
|
||||
2nd bit - ?
|
||||
3rd bit - ?
|
||||
4th bit - ?
|
||||
5th bit - ?
|
||||
6th bit - ?
|
||||
*/
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets,mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/mob/living/carbon/target in targets)
|
||||
if(target.anti_magic_check())
|
||||
continue
|
||||
if(!target.dna)
|
||||
continue
|
||||
for(var/A in mutations)
|
||||
target.dna.add_mutation(A)
|
||||
for(var/A in traits)
|
||||
ADD_TRAIT(target, A, GENETICS_SPELL)
|
||||
active_on += target
|
||||
addtimer(CALLBACK(src, .proc/remove, target), duration)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/Destroy()
|
||||
. = ..()
|
||||
for(var/V in active_on)
|
||||
remove(V)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/proc/remove(mob/living/carbon/target)
|
||||
active_on -= target
|
||||
if(!QDELETED(target))
|
||||
for(var/A in mutations)
|
||||
target.dna.remove_mutation(A)
|
||||
for(var/A in traits)
|
||||
REMOVE_TRAIT(target, A, GENETICS_SPELL)
|
||||
@@ -182,3 +182,38 @@
|
||||
|
||||
if(charges <= 0)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/melee/touch_attack/nuclearfist
|
||||
name = "\improper PURE MANLINESS"
|
||||
desc = "SHOW THEM RAW POWER"
|
||||
catchphrase = "I CAST FIST!"
|
||||
on_use_sound = 'sound/weapons/nuclear_fist.ogg'
|
||||
icon_state = "disintegrate"
|
||||
item_state = "disintegrate"
|
||||
|
||||
/obj/item/melee/touch_attack/nuclearfist/afterattack(atom/movable/target, mob/living/carbon/user, proximity)
|
||||
if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.lying || user.handcuffed) //exploding after touching yourself would be bad
|
||||
return
|
||||
if(!user.can_speak_vocal())
|
||||
to_chat(user, "<span class='notice'>You can't get the words out!</span>")
|
||||
return
|
||||
var/mob/M = target
|
||||
var/atom/A = M.anti_magic_check()
|
||||
if(A)
|
||||
if(isitem(A))
|
||||
target.visible_message("<span class='warning'>[target]'s [A] glows brightly as it wards off the spell!</span>")
|
||||
user.visible_message("<span class='warning'>The feedback blows [user]'s arm off!</span>","<span class='userdanger'>The spell bounces from [M]'s skin back into your arm!</span>")
|
||||
user.flash_act()
|
||||
var/obj/item/bodypart/part = user.get_holding_bodypart_of_item(src)
|
||||
if(part)
|
||||
part.dismember()
|
||||
return ..()
|
||||
var/angle = dir2angle(get_dir(src, get_step_away(target, src)))
|
||||
var/obj/item/projectile/magic/nuclear/P = new(get_turf(src))
|
||||
P.victim = target
|
||||
target.forceMove(P)
|
||||
P.setAngle(angle)
|
||||
P.original = user
|
||||
P.firer = user
|
||||
P.fire()
|
||||
return ..()
|
||||
|
||||
@@ -1,57 +1,57 @@
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler
|
||||
name = "Inflict Handler"
|
||||
desc = "This spell blinds and/or destroys/damages/heals and/or knockdowns/stuns the target."
|
||||
|
||||
var/amt_knockdown = 0
|
||||
var/amt_hardstun
|
||||
var/amt_unconscious = 0
|
||||
var/amt_stun = 0
|
||||
|
||||
//set to negatives for healing
|
||||
var/amt_dam_stam
|
||||
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/destroys = "none" //can be "none", "gib" or "disintegrate"
|
||||
|
||||
var/summon_type = null //this will put an obj at the target's location
|
||||
|
||||
var/check_anti_magic = TRUE
|
||||
var/check_holy = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/cast(list/targets,mob/user = usr)
|
||||
for(var/mob/living/target in targets)
|
||||
playsound(target,sound, 50,1)
|
||||
if(target.anti_magic_check(check_anti_magic, check_holy))
|
||||
return
|
||||
switch(destroys)
|
||||
if("gib")
|
||||
target.gib()
|
||||
if("disintegrate")
|
||||
target.dust()
|
||||
|
||||
if(!target)
|
||||
continue
|
||||
//damage/healing
|
||||
target.adjustBruteLoss(amt_dam_brute)
|
||||
target.adjustFireLoss(amt_dam_fire)
|
||||
target.adjustToxLoss(amt_dam_tox)
|
||||
target.adjustOxyLoss(amt_dam_oxy)
|
||||
//disabling
|
||||
if(!amt_knockdown && amt_dam_stam)
|
||||
target.adjustStaminaLoss(amt_dam_stam)
|
||||
else
|
||||
target.Knockdown(amt_knockdown, override_hardstun = amt_hardstun, override_stamdmg = amt_dam_stam)
|
||||
target.Unconscious(amt_unconscious)
|
||||
target.Stun(amt_stun)
|
||||
|
||||
target.blind_eyes(amt_eye_blind)
|
||||
target.blur_eyes(amt_eye_blurry)
|
||||
//summoning
|
||||
if(summon_type)
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler
|
||||
name = "Inflict Handler"
|
||||
desc = "This spell blinds and/or destroys/damages/heals and/or knockdowns/stuns the target."
|
||||
|
||||
var/amt_knockdown = 0
|
||||
var/amt_hardstun
|
||||
var/amt_unconscious = 0
|
||||
var/amt_stun = 0
|
||||
|
||||
//set to negatives for healing
|
||||
var/amt_dam_stam
|
||||
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/destroys = "none" //can be "none", "gib" or "disintegrate"
|
||||
|
||||
var/summon_type = null //this will put an obj at the target's location
|
||||
|
||||
var/check_anti_magic = TRUE
|
||||
var/check_holy = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/cast(list/targets,mob/user = usr)
|
||||
for(var/mob/living/target in targets)
|
||||
playsound(target,sound, 50,1)
|
||||
if(target.anti_magic_check(check_anti_magic, check_holy))
|
||||
return
|
||||
switch(destroys)
|
||||
if("gib")
|
||||
target.gib()
|
||||
if("disintegrate")
|
||||
target.dust()
|
||||
|
||||
if(!target)
|
||||
continue
|
||||
//damage/healing
|
||||
target.adjustBruteLoss(amt_dam_brute)
|
||||
target.adjustFireLoss(amt_dam_fire)
|
||||
target.adjustToxLoss(amt_dam_tox)
|
||||
target.adjustOxyLoss(amt_dam_oxy)
|
||||
//disabling
|
||||
if(!amt_knockdown && amt_dam_stam)
|
||||
target.adjustStaminaLoss(amt_dam_stam)
|
||||
else
|
||||
target.Knockdown(amt_knockdown, override_hardstun = amt_hardstun, override_stamdmg = amt_dam_stam)
|
||||
target.Unconscious(amt_unconscious)
|
||||
target.Stun(amt_stun)
|
||||
|
||||
target.blind_eyes(amt_eye_blind)
|
||||
target.blur_eyes(amt_eye_blurry)
|
||||
//summoning
|
||||
if(summon_type)
|
||||
new summon_type(target.loc, target)
|
||||
@@ -1,31 +1,31 @@
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock
|
||||
name = "Knock"
|
||||
desc = "This spell opens nearby doors and does not require wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
invocation = "AULIE OXIN FIERA"
|
||||
invocation_type = "whisper"
|
||||
range = 3
|
||||
cooldown_min = 20 //20 deciseconds reduction per rank
|
||||
|
||||
action_icon_state = "knock"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets,mob/user = usr)
|
||||
SEND_SOUND(user, sound('sound/magic/knock.ogg'))
|
||||
for(var/turf/T in targets)
|
||||
for(var/obj/machinery/door/door in T.contents)
|
||||
INVOKE_ASYNC(src, .proc/open_door, door)
|
||||
for(var/obj/structure/closet/C in T.contents)
|
||||
INVOKE_ASYNC(src, .proc/open_closet, C)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_door(var/obj/machinery/door/door)
|
||||
if(istype(door, /obj/machinery/door/airlock))
|
||||
var/obj/machinery/door/airlock/A = door
|
||||
A.locked = FALSE
|
||||
door.open()
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_closet(var/obj/structure/closet/C)
|
||||
C.locked = FALSE
|
||||
C.open()
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock
|
||||
name = "Knock"
|
||||
desc = "This spell opens nearby doors and does not require wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
invocation = "AULIE OXIN FIERA"
|
||||
invocation_type = "whisper"
|
||||
range = 3
|
||||
cooldown_min = 20 //20 deciseconds reduction per rank
|
||||
|
||||
action_icon_state = "knock"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets,mob/user = usr)
|
||||
SEND_SOUND(user, sound('sound/magic/knock.ogg'))
|
||||
for(var/turf/T in targets)
|
||||
for(var/obj/machinery/door/door in T.contents)
|
||||
INVOKE_ASYNC(src, .proc/open_door, door)
|
||||
for(var/obj/structure/closet/C in T.contents)
|
||||
INVOKE_ASYNC(src, .proc/open_closet, C)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_door(var/obj/machinery/door/door)
|
||||
if(istype(door, /obj/machinery/door/airlock))
|
||||
var/obj/machinery/door/airlock/A = door
|
||||
A.locked = FALSE
|
||||
door.open()
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_closet(var/obj/structure/closet/C)
|
||||
C.locked = FALSE
|
||||
C.open()
|
||||
|
||||
@@ -1,156 +1,156 @@
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall
|
||||
name = "Invisible Wall"
|
||||
desc = "The mime's performance transmutates into physical reality."
|
||||
school = "mime"
|
||||
panel = "Mime"
|
||||
summon_type = list(/obj/effect/forcefield/mime)
|
||||
invocation_type = "emote"
|
||||
invocation_emote_self = "<span class='notice'>You form a wall in front of yourself.</span>"
|
||||
summon_lifespan = 300
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
range = 0
|
||||
cast_sound = null
|
||||
human_req = 1
|
||||
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Click()
|
||||
if(usr && usr.mind)
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a wall is in front of [usr.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mime/speak
|
||||
name = "Speech"
|
||||
desc = "Make or break a vow of silence."
|
||||
school = "mime"
|
||||
panel = "Mime"
|
||||
clothes_req = 0
|
||||
human_req = 1
|
||||
charge_max = 3000
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mime/speak/Click()
|
||||
if(!usr)
|
||||
return
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if(H.mind.miming)
|
||||
still_recharging_msg = "<span class='warning'>You can't break your vow of silence that fast!</span>"
|
||||
else
|
||||
still_recharging_msg = "<span class='warning'>You'll have to wait before you can give your vow of silence again!</span>"
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr)
|
||||
for(var/mob/living/carbon/human/H in targets)
|
||||
H.mind.miming=!H.mind.miming
|
||||
if(H.mind.miming)
|
||||
to_chat(H, "<span class='notice'>You make a vow of silence.</span>")
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "vow")
|
||||
else
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "vow", /datum/mood_event/broken_vow)
|
||||
to_chat(H, "<span class='notice'>You break your vow of silence.</span>")
|
||||
|
||||
// These spells can only be gotten from the "Guide for Advanced Mimery series" for Mime Traitors.
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/forcewall/mime
|
||||
name = "Invisible Blockade"
|
||||
desc = "Form an invisible three tile wide blockade."
|
||||
school = "mime"
|
||||
panel = "Mime"
|
||||
wall_type = /obj/effect/forcefield/mime/advanced
|
||||
invocation_type = "emote"
|
||||
invocation_emote_self = "<span class='notice'>You form a blockade in front of yourself.</span>"
|
||||
charge_max = 600
|
||||
sound = null
|
||||
clothes_req = 0
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/forcewall/mime/Click()
|
||||
if(usr && usr.mind)
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a blockade is in front of [usr.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/finger_guns
|
||||
name = "Finger Guns"
|
||||
desc = "Shoot a mimed bullet from your fingers that stuns and does some damage."
|
||||
school = "mime"
|
||||
panel = "Mime"
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
invocation_type = "emote"
|
||||
invocation_emote_self = "<span class='dangers'>You fire your finger gun!</span>"
|
||||
range = 20
|
||||
projectile_type = /obj/item/projectile/bullet/mime
|
||||
projectile_amount = 3
|
||||
sound = null
|
||||
active_msg = "You draw your fingers!"
|
||||
deactive_msg = "You put your fingers at ease. Another time."
|
||||
active = FALSE
|
||||
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
base_icon_state = "mime"
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/finger_guns/Click()
|
||||
var/mob/living/carbon/human/owner = usr
|
||||
if(owner.incapacitated())
|
||||
to_chat(owner, "<span class='warning'>You can't properly point your fingers while incapacitated.</span>")
|
||||
return
|
||||
if(usr && usr.mind)
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> fires [usr.p_their()] finger gun!"
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/book/granter/spell/mimery_blockade
|
||||
spell = /obj/effect/proc_holder/spell/targeted/forcewall/mime
|
||||
spellname = "Invisible Blockade"
|
||||
name = "Guide to Advanced Mimery Vol 1"
|
||||
desc = "The pages don't make any sound when turned."
|
||||
icon_state ="bookmime"
|
||||
remarks = list("...")
|
||||
|
||||
/obj/item/book/granter/spell/mimery_blockade/attack_self(mob/user)
|
||||
..()
|
||||
if(!locate(/obj/effect/proc_holder/spell/targeted/mime/speak) in user.mind.spell_list)
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak)
|
||||
|
||||
/obj/item/book/granter/spell/mimery_guns
|
||||
spell = /obj/effect/proc_holder/spell/aimed/finger_guns
|
||||
spellname = "Finger Guns"
|
||||
name = "Guide to Advanced Mimery Vol 2"
|
||||
desc = "There aren't any words written..."
|
||||
icon_state ="bookmime"
|
||||
remarks = list("...")
|
||||
|
||||
/obj/item/book/granter/spell/mimery_guns/attack_self(mob/user)
|
||||
..()
|
||||
if(!locate(/obj/effect/proc_holder/spell/targeted/mime/speak) in user.mind.spell_list)
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall
|
||||
name = "Invisible Wall"
|
||||
desc = "The mime's performance transmutates into physical reality."
|
||||
school = "mime"
|
||||
panel = "Mime"
|
||||
summon_type = list(/obj/effect/forcefield/mime)
|
||||
invocation_type = "emote"
|
||||
invocation_emote_self = "<span class='notice'>You form a wall in front of yourself.</span>"
|
||||
summon_lifespan = 300
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
range = 0
|
||||
cast_sound = null
|
||||
human_req = 1
|
||||
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Click()
|
||||
if(usr && usr.mind)
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a wall is in front of [usr.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mime/speak
|
||||
name = "Speech"
|
||||
desc = "Make or break a vow of silence."
|
||||
school = "mime"
|
||||
panel = "Mime"
|
||||
clothes_req = 0
|
||||
human_req = 1
|
||||
charge_max = 3000
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mime/speak/Click()
|
||||
if(!usr)
|
||||
return
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if(H.mind.miming)
|
||||
still_recharging_msg = "<span class='warning'>You can't break your vow of silence that fast!</span>"
|
||||
else
|
||||
still_recharging_msg = "<span class='warning'>You'll have to wait before you can give your vow of silence again!</span>"
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr)
|
||||
for(var/mob/living/carbon/human/H in targets)
|
||||
H.mind.miming=!H.mind.miming
|
||||
if(H.mind.miming)
|
||||
to_chat(H, "<span class='notice'>You make a vow of silence.</span>")
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "vow")
|
||||
else
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "vow", /datum/mood_event/broken_vow)
|
||||
to_chat(H, "<span class='notice'>You break your vow of silence.</span>")
|
||||
|
||||
// These spells can only be gotten from the "Guide for Advanced Mimery series" for Mime Traitors.
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/forcewall/mime
|
||||
name = "Invisible Blockade"
|
||||
desc = "Form an invisible three tile wide blockade."
|
||||
school = "mime"
|
||||
panel = "Mime"
|
||||
wall_type = /obj/effect/forcefield/mime/advanced
|
||||
invocation_type = "emote"
|
||||
invocation_emote_self = "<span class='notice'>You form a blockade in front of yourself.</span>"
|
||||
charge_max = 600
|
||||
sound = null
|
||||
clothes_req = 0
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/forcewall/mime/Click()
|
||||
if(usr && usr.mind)
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a blockade is in front of [usr.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/finger_guns
|
||||
name = "Finger Guns"
|
||||
desc = "Shoot a mimed bullet from your fingers that stuns and does some damage."
|
||||
school = "mime"
|
||||
panel = "Mime"
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
invocation_type = "emote"
|
||||
invocation_emote_self = "<span class='dangers'>You fire your finger gun!</span>"
|
||||
range = 20
|
||||
projectile_type = /obj/item/projectile/bullet/mime
|
||||
projectile_amount = 3
|
||||
sound = null
|
||||
active_msg = "You draw your fingers!"
|
||||
deactive_msg = "You put your fingers at ease. Another time."
|
||||
active = FALSE
|
||||
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
base_icon_state = "mime"
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/finger_guns/Click()
|
||||
var/mob/living/carbon/human/owner = usr
|
||||
if(owner.incapacitated())
|
||||
to_chat(owner, "<span class='warning'>You can't properly point your fingers while incapacitated.</span>")
|
||||
return
|
||||
if(usr && usr.mind)
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> fires [usr.p_their()] finger gun!"
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/book/granter/spell/mimery_blockade
|
||||
spell = /obj/effect/proc_holder/spell/targeted/forcewall/mime
|
||||
spellname = "Invisible Blockade"
|
||||
name = "Guide to Advanced Mimery Vol 1"
|
||||
desc = "The pages don't make any sound when turned."
|
||||
icon_state ="bookmime"
|
||||
remarks = list("...")
|
||||
|
||||
/obj/item/book/granter/spell/mimery_blockade/attack_self(mob/user)
|
||||
..()
|
||||
if(!locate(/obj/effect/proc_holder/spell/targeted/mime/speak) in user.mind.spell_list)
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak)
|
||||
|
||||
/obj/item/book/granter/spell/mimery_guns
|
||||
spell = /obj/effect/proc_holder/spell/aimed/finger_guns
|
||||
spellname = "Finger Guns"
|
||||
name = "Guide to Advanced Mimery Vol 2"
|
||||
desc = "There aren't any words written..."
|
||||
icon_state ="bookmime"
|
||||
remarks = list("...")
|
||||
|
||||
/obj/item/book/granter/spell/mimery_guns/attack_self(mob/user)
|
||||
..()
|
||||
if(!locate(/obj/effect/proc_holder/spell/targeted/mime/speak) in user.mind.spell_list)
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak)
|
||||
@@ -1,88 +1,88 @@
|
||||
/obj/effect/proc_holder/spell/targeted/mind_transfer
|
||||
name = "Mind Transfer"
|
||||
desc = "This spell allows the user to switch bodies with a target."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 600
|
||||
clothes_req = 0
|
||||
invocation = "GIN'YU CAPAN"
|
||||
invocation_type = "whisper"
|
||||
range = 1
|
||||
cooldown_min = 200 //100 deciseconds reduction per rank
|
||||
var/unconscious_amount_caster = 400 //how much the caster is stunned for after the spell
|
||||
var/unconscious_amount_victim = 400 //how much the victim is stunned for after the spell
|
||||
|
||||
action_icon_state = "mindswap"
|
||||
|
||||
/*
|
||||
Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do.
|
||||
Make sure spells that are removed from spell_list are actually removed and deleted when mind transferring.
|
||||
Also, you never added distance checking after target is selected. I've went ahead and did that.
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets, mob/living/user = usr, distanceoverride, silent = FALSE)
|
||||
if(!targets.len)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>No mind found!</span>")
|
||||
return
|
||||
|
||||
if(targets.len > 1)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Too many minds! You're not a hive damnit!</span>")
|
||||
return
|
||||
|
||||
var/mob/living/target = targets[1]
|
||||
|
||||
var/t_He = target.p_they(TRUE)
|
||||
var/t_is = target.p_are()
|
||||
|
||||
if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it.
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[t_He] [t_is] too far away!</span>")
|
||||
return
|
||||
|
||||
if(ismegafauna(target))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>This creature is too powerful to control!</span>")
|
||||
return
|
||||
|
||||
if(target.stat == DEAD)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>You don't particularly want to be dead!</span>")
|
||||
return
|
||||
|
||||
if(!target.key || !target.mind)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[t_He] appear[target.p_s()] to be catatonic! Not even magic can affect [target.p_their()] vacant mind.</span>")
|
||||
return
|
||||
|
||||
if(user.suiciding)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>You're killing yourself! You can't concentrate enough to do this!</span>")
|
||||
return
|
||||
|
||||
var/datum/mind/TM = target.mind
|
||||
if((target.anti_magic_check(TRUE, FALSE) || TM.has_antag_datum(/datum/antagonist/wizard) || TM.has_antag_datum(/datum/antagonist/cult) || TM.has_antag_datum(/datum/antagonist/clockcult) || TM.has_antag_datum(/datum/antagonist/changeling) || TM.has_antag_datum(/datum/antagonist/rev)) || cmptext(copytext(target.key,1,2),"@"))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[target.p_their(TRUE)] mind is resisting your spell!</span>")
|
||||
return
|
||||
|
||||
var/mob/living/victim = target//The target of the spell whos body will be transferred to.
|
||||
var/mob/living/caster = user//The wizard/whomever doing the body transferring.
|
||||
|
||||
//MIND TRANSFER BEGIN
|
||||
var/mob/dead/observer/ghost = victim.ghostize(FALSE, TRUE)
|
||||
caster.mind.transfer_to(victim)
|
||||
|
||||
ghost.mind.transfer_to(caster)
|
||||
if(ghost.key)
|
||||
ghost.transfer_ckey(caster) //have to transfer the key since the mind was not active
|
||||
qdel(ghost)
|
||||
|
||||
//MIND TRANSFER END
|
||||
|
||||
//Here we knock both mobs out for a time.
|
||||
caster.Unconscious(unconscious_amount_caster)
|
||||
victim.Unconscious(unconscious_amount_victim)
|
||||
SEND_SOUND(caster, sound('sound/magic/mandswap.ogg'))
|
||||
SEND_SOUND(victim, sound('sound/magic/mandswap.ogg'))// only the caster and victim hear the sounds, that way no one knows for sure if the swap happened
|
||||
return TRUE
|
||||
/obj/effect/proc_holder/spell/targeted/mind_transfer
|
||||
name = "Mind Transfer"
|
||||
desc = "This spell allows the user to switch bodies with a target."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 600
|
||||
clothes_req = 0
|
||||
invocation = "GIN'YU CAPAN"
|
||||
invocation_type = "whisper"
|
||||
range = 1
|
||||
cooldown_min = 200 //100 deciseconds reduction per rank
|
||||
var/unconscious_amount_caster = 400 //how much the caster is stunned for after the spell
|
||||
var/unconscious_amount_victim = 400 //how much the victim is stunned for after the spell
|
||||
|
||||
action_icon_state = "mindswap"
|
||||
|
||||
/*
|
||||
Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do.
|
||||
Make sure spells that are removed from spell_list are actually removed and deleted when mind transferring.
|
||||
Also, you never added distance checking after target is selected. I've went ahead and did that.
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets, mob/living/user = usr, distanceoverride, silent = FALSE)
|
||||
if(!targets.len)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>No mind found!</span>")
|
||||
return
|
||||
|
||||
if(targets.len > 1)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Too many minds! You're not a hive damnit!</span>")
|
||||
return
|
||||
|
||||
var/mob/living/target = targets[1]
|
||||
|
||||
var/t_He = target.p_they(TRUE)
|
||||
var/t_is = target.p_are()
|
||||
|
||||
if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it.
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[t_He] [t_is] too far away!</span>")
|
||||
return
|
||||
|
||||
if(ismegafauna(target))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>This creature is too powerful to control!</span>")
|
||||
return
|
||||
|
||||
if(target.stat == DEAD)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>You don't particularly want to be dead!</span>")
|
||||
return
|
||||
|
||||
if(!target.key || !target.mind)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[t_He] appear[target.p_s()] to be catatonic! Not even magic can affect [target.p_their()] vacant mind.</span>")
|
||||
return
|
||||
|
||||
if(user.suiciding)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>You're killing yourself! You can't concentrate enough to do this!</span>")
|
||||
return
|
||||
|
||||
var/datum/mind/TM = target.mind
|
||||
if((target.anti_magic_check(TRUE, FALSE) || TM.has_antag_datum(/datum/antagonist/wizard) || TM.has_antag_datum(/datum/antagonist/cult) || TM.has_antag_datum(/datum/antagonist/clockcult) || TM.has_antag_datum(/datum/antagonist/changeling) || TM.has_antag_datum(/datum/antagonist/rev)) || cmptext(copytext(target.key,1,2),"@"))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[target.p_their(TRUE)] mind is resisting your spell!</span>")
|
||||
return
|
||||
|
||||
var/mob/living/victim = target//The target of the spell whos body will be transferred to.
|
||||
var/mob/living/caster = user//The wizard/whomever doing the body transferring.
|
||||
|
||||
//MIND TRANSFER BEGIN
|
||||
var/mob/dead/observer/ghost = victim.ghostize(FALSE, TRUE)
|
||||
caster.mind.transfer_to(victim)
|
||||
|
||||
ghost.mind.transfer_to(caster)
|
||||
if(ghost.key)
|
||||
ghost.transfer_ckey(caster) //have to transfer the key since the mind was not active
|
||||
qdel(ghost)
|
||||
|
||||
//MIND TRANSFER END
|
||||
|
||||
//Here we knock both mobs out for a time.
|
||||
caster.Unconscious(unconscious_amount_caster)
|
||||
victim.Unconscious(unconscious_amount_victim)
|
||||
SEND_SOUND(caster, sound('sound/magic/mandswap.ogg'))
|
||||
SEND_SOUND(victim, sound('sound/magic/mandswap.ogg'))// only the caster and victim hear the sounds, that way no one knows for sure if the swap happened
|
||||
return TRUE
|
||||
|
||||
@@ -1,96 +1,96 @@
|
||||
|
||||
//NEEDS MAJOR CODE CLEANUP.
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile
|
||||
name = "Projectile"
|
||||
desc = "This spell summons projectiles which try to hit the targets."
|
||||
|
||||
var/proj_icon = 'icons/obj/projectiles.dmi'
|
||||
var/proj_icon_state = "spell"
|
||||
var/proj_name = "a spell projectile"
|
||||
|
||||
var/proj_trail = 0 //if it leaves a trail
|
||||
var/proj_trail_lifespan = 0 //deciseconds
|
||||
var/proj_trail_icon = 'icons/obj/wizard.dmi'
|
||||
var/proj_trail_icon_state = "trail"
|
||||
|
||||
|
||||
var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this
|
||||
|
||||
var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle
|
||||
var/proj_homing = 1 //if it follows the target
|
||||
var/proj_insubstantial = 0 //if it can pass through dense objects or not
|
||||
var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target)
|
||||
|
||||
var/proj_lifespan = 15 //in deciseconds * proj_step_delay
|
||||
var/proj_step_delay = 1 //lower = faster
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/mob/living/target in targets)
|
||||
launch(target, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/proc/launch(mob/living/target, mob/user)
|
||||
set waitfor = FALSE
|
||||
var/obj/effect/proc_holder/spell/targeted/projectile
|
||||
if(istext(proj_type))
|
||||
var/projectile_type = text2path(proj_type)
|
||||
projectile = new projectile_type(user)
|
||||
if(istype(proj_type, /obj/effect/proc_holder/spell))
|
||||
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
|
||||
var/obj/effect/proc_holder/spell/targeted/trigger/T = projectile
|
||||
T.linked_spells += proj_type
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.setDir(get_dir(target,projectile))
|
||||
projectile.name = proj_name
|
||||
|
||||
var/current_loc = user.loc
|
||||
|
||||
projectile.forceMove(current_loc)
|
||||
|
||||
for(var/i = 0,i < proj_lifespan,i++)
|
||||
if(!projectile)
|
||||
break
|
||||
|
||||
if(proj_homing)
|
||||
if(proj_insubstantial)
|
||||
projectile.setDir(get_dir(projectile,target))
|
||||
projectile.forceMove(get_step_to(projectile,target))
|
||||
else
|
||||
step_to(projectile,target)
|
||||
else
|
||||
if(proj_insubstantial)
|
||||
projectile.forceMove(get_step(projectile,dir))
|
||||
else
|
||||
step(projectile,dir)
|
||||
|
||||
if(!projectile) // step and step_to sleeps so we'll have to check again.
|
||||
break
|
||||
|
||||
if(!target || (!proj_lingering && projectile.loc == current_loc)) //if it didn't move since last time
|
||||
qdel(projectile)
|
||||
break
|
||||
|
||||
if(proj_trail && projectile)
|
||||
spawntrail(projectile)
|
||||
|
||||
if(projectile.loc in range(target.loc,proj_trigger_range))
|
||||
projectile.perform(list(target),user=user)
|
||||
break
|
||||
|
||||
current_loc = projectile.loc
|
||||
|
||||
sleep(proj_step_delay)
|
||||
|
||||
if(projectile)
|
||||
qdel(projectile)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/proc/spawntrail(obj/effect/proc_holder/spell/targeted/projectile)
|
||||
set waitfor = FALSE
|
||||
if(projectile)
|
||||
var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc)
|
||||
trail.icon = proj_trail_icon
|
||||
trail.icon_state = proj_trail_icon_state
|
||||
trail.density = FALSE
|
||||
QDEL_IN(trail, proj_trail_lifespan)
|
||||
|
||||
//NEEDS MAJOR CODE CLEANUP.
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile
|
||||
name = "Projectile"
|
||||
desc = "This spell summons projectiles which try to hit the targets."
|
||||
|
||||
var/proj_icon = 'icons/obj/projectiles.dmi'
|
||||
var/proj_icon_state = "spell"
|
||||
var/proj_name = "a spell projectile"
|
||||
|
||||
var/proj_trail = 0 //if it leaves a trail
|
||||
var/proj_trail_lifespan = 0 //deciseconds
|
||||
var/proj_trail_icon = 'icons/obj/wizard.dmi'
|
||||
var/proj_trail_icon_state = "trail"
|
||||
|
||||
|
||||
var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this
|
||||
|
||||
var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle
|
||||
var/proj_homing = 1 //if it follows the target
|
||||
var/proj_insubstantial = 0 //if it can pass through dense objects or not
|
||||
var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target)
|
||||
|
||||
var/proj_lifespan = 15 //in deciseconds * proj_step_delay
|
||||
var/proj_step_delay = 1 //lower = faster
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/mob/living/target in targets)
|
||||
launch(target, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/proc/launch(mob/living/target, mob/user)
|
||||
set waitfor = FALSE
|
||||
var/obj/effect/proc_holder/spell/targeted/projectile
|
||||
if(istext(proj_type))
|
||||
var/projectile_type = text2path(proj_type)
|
||||
projectile = new projectile_type(user)
|
||||
if(istype(proj_type, /obj/effect/proc_holder/spell))
|
||||
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
|
||||
var/obj/effect/proc_holder/spell/targeted/trigger/T = projectile
|
||||
T.linked_spells += proj_type
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.setDir(get_dir(target,projectile))
|
||||
projectile.name = proj_name
|
||||
|
||||
var/current_loc = user.loc
|
||||
|
||||
projectile.forceMove(current_loc)
|
||||
|
||||
for(var/i = 0,i < proj_lifespan,i++)
|
||||
if(!projectile)
|
||||
break
|
||||
|
||||
if(proj_homing)
|
||||
if(proj_insubstantial)
|
||||
projectile.setDir(get_dir(projectile,target))
|
||||
projectile.forceMove(get_step_to(projectile,target))
|
||||
else
|
||||
step_to(projectile,target)
|
||||
else
|
||||
if(proj_insubstantial)
|
||||
projectile.forceMove(get_step(projectile,dir))
|
||||
else
|
||||
step(projectile,dir)
|
||||
|
||||
if(!projectile) // step and step_to sleeps so we'll have to check again.
|
||||
break
|
||||
|
||||
if(!target || (!proj_lingering && projectile.loc == current_loc)) //if it didn't move since last time
|
||||
qdel(projectile)
|
||||
break
|
||||
|
||||
if(proj_trail && projectile)
|
||||
spawntrail(projectile)
|
||||
|
||||
if(projectile.loc in range(target.loc,proj_trigger_range))
|
||||
projectile.perform(list(target),user=user)
|
||||
break
|
||||
|
||||
current_loc = projectile.loc
|
||||
|
||||
sleep(proj_step_delay)
|
||||
|
||||
if(projectile)
|
||||
qdel(projectile)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/proc/spawntrail(obj/effect/proc_holder/spell/targeted/projectile)
|
||||
set waitfor = FALSE
|
||||
if(projectile)
|
||||
var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc)
|
||||
trail.icon = proj_trail_icon
|
||||
trail.icon_state = proj_trail_icon_state
|
||||
trail.density = FALSE
|
||||
QDEL_IN(trail, proj_trail_lifespan)
|
||||
|
||||
@@ -1,176 +1,176 @@
|
||||
//In this file: Summon Magic/Summon Guns/Summon Events
|
||||
|
||||
// 1 in 50 chance of getting something really special.
|
||||
#define SPECIALIST_MAGIC_PROB 2
|
||||
|
||||
GLOBAL_LIST_INIT(summoned_guns, list(
|
||||
/obj/item/gun/energy/e_gun/advtaser,
|
||||
/obj/item/gun/energy/e_gun,
|
||||
/obj/item/gun/energy/laser,
|
||||
/obj/item/gun/ballistic/revolver,
|
||||
/obj/item/gun/ballistic/revolver/detective,
|
||||
/obj/item/gun/ballistic/automatic/pistol/deagle/camo,
|
||||
/obj/item/gun/ballistic/automatic/gyropistol,
|
||||
/obj/item/gun/energy/pulse,
|
||||
/obj/item/gun/ballistic/automatic/pistol/suppressed,
|
||||
/obj/item/gun/ballistic/revolver/doublebarrel,
|
||||
/obj/item/gun/ballistic/shotgun,
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat,
|
||||
/obj/item/gun/ballistic/automatic/ar,
|
||||
/obj/item/gun/ballistic/revolver/mateba,
|
||||
/obj/item/gun/ballistic/shotgun/boltaction,
|
||||
/obj/item/gun/ballistic/automatic/speargun,
|
||||
/obj/item/gun/ballistic/automatic/mini_uzi,
|
||||
/obj/item/gun/energy/lasercannon,
|
||||
/obj/item/gun/energy/kinetic_accelerator/crossbow/large,
|
||||
/obj/item/gun/energy/e_gun/nuclear,
|
||||
/obj/item/gun/ballistic/automatic/proto,
|
||||
/obj/item/gun/ballistic/automatic/c20r,
|
||||
/obj/item/gun/ballistic/automatic/l6_saw,
|
||||
/obj/item/gun/ballistic/automatic/m90,
|
||||
/obj/item/gun/energy/alien,
|
||||
/obj/item/gun/energy/e_gun/dragnet,
|
||||
/obj/item/gun/energy/e_gun/turret,
|
||||
/obj/item/gun/energy/pulse/carbine,
|
||||
/obj/item/gun/energy/decloner,
|
||||
/obj/item/gun/energy/mindflayer,
|
||||
/obj/item/gun/energy/kinetic_accelerator,
|
||||
/obj/item/gun/energy/plasmacutter/adv,
|
||||
/obj/item/gun/energy/wormhole_projector,
|
||||
/obj/item/gun/ballistic/automatic/wt550,
|
||||
/obj/item/gun/ballistic/automatic/shotgun/bulldog,
|
||||
/obj/item/gun/ballistic/revolver/grenadelauncher,
|
||||
/obj/item/gun/ballistic/revolver/golden,
|
||||
/obj/item/gun/ballistic/automatic/sniper_rifle,
|
||||
/obj/item/gun/ballistic/rocketlauncher,
|
||||
/obj/item/gun/medbeam,
|
||||
/obj/item/gun/energy/laser/scatter,
|
||||
/obj/item/gun/energy/gravity_gun))
|
||||
|
||||
GLOBAL_LIST_INIT(summoned_magic, list(
|
||||
/obj/item/book/granter/spell/fireball,
|
||||
/obj/item/book/granter/spell/smoke,
|
||||
/obj/item/book/granter/spell/blind,
|
||||
/obj/item/book/granter/spell/mindswap,
|
||||
/obj/item/book/granter/spell/forcewall,
|
||||
/obj/item/book/granter/spell/knock,
|
||||
/obj/item/book/granter/spell/barnyard,
|
||||
/obj/item/book/granter/spell/charge,
|
||||
/obj/item/book/granter/spell/summonitem,
|
||||
/obj/item/gun/magic/wand,
|
||||
/obj/item/gun/magic/wand/death,
|
||||
/obj/item/gun/magic/wand/resurrection,
|
||||
/obj/item/gun/magic/wand/polymorph,
|
||||
/obj/item/gun/magic/wand/teleport,
|
||||
/obj/item/gun/magic/wand/door,
|
||||
/obj/item/gun/magic/wand/fireball,
|
||||
/obj/item/gun/magic/staff/healing,
|
||||
/obj/item/gun/magic/staff/door,
|
||||
/obj/item/scrying,
|
||||
/obj/item/voodoo,
|
||||
/obj/item/warpwhistle,
|
||||
/obj/item/clothing/suit/space/hardsuit/shielded/wizard,
|
||||
/obj/item/immortality_talisman,
|
||||
/obj/item/melee/ghost_sword))
|
||||
|
||||
GLOBAL_LIST_INIT(summoned_special_magic, list(
|
||||
/obj/item/gun/magic/staff/change,
|
||||
/obj/item/gun/magic/staff/animate,
|
||||
/obj/item/storage/belt/wands/full,
|
||||
/obj/item/antag_spawner/contract,
|
||||
/obj/item/gun/magic/staff/chaos,
|
||||
/obj/item/necromantic_stone,
|
||||
/obj/item/blood_contract))
|
||||
|
||||
// If true, it's the probability of triggering "survivor" antag.
|
||||
GLOBAL_VAR_INIT(summon_guns_triggered, FALSE)
|
||||
GLOBAL_VAR_INIT(summon_magic_triggered, FALSE)
|
||||
|
||||
/proc/give_guns(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD || !(H.client))
|
||||
return
|
||||
if(H.mind)
|
||||
if(iswizard(H) || H.mind.has_antag_datum(/datum/antagonist/survivalist/guns))
|
||||
return
|
||||
|
||||
if(prob(GLOB.summon_guns_triggered) && !(H.mind.has_antag_datum(/datum/antagonist)))
|
||||
SSticker.mode.traitors += H.mind
|
||||
|
||||
H.mind.add_antag_datum(/datum/antagonist/survivalist/guns)
|
||||
H.log_message("was made into a survivalist, and trusts no one!", LOG_ATTACK, color="red")
|
||||
|
||||
var/gun_type = pick(GLOB.summoned_guns)
|
||||
var/obj/item/gun/G = new gun_type(get_turf(H))
|
||||
G.unlock()
|
||||
playsound(get_turf(H),'sound/magic/summon_guns.ogg', 50, 1)
|
||||
|
||||
var/in_hand = H.put_in_hands(G) // not always successful
|
||||
|
||||
to_chat(H, "<span class='warning'>\A [G] appears [in_hand ? "in your hand" : "at your feet"]!</span>")
|
||||
|
||||
/proc/give_magic(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD || !(H.client))
|
||||
return
|
||||
if(H.mind)
|
||||
if(iswizard(H) || H.mind.has_antag_datum(/datum/antagonist/survivalist/magic))
|
||||
return
|
||||
|
||||
if(prob(GLOB.summon_magic_triggered) && !(H.mind.has_antag_datum(/datum/antagonist)))
|
||||
H.mind.add_antag_datum(/datum/antagonist/survivalist/magic)
|
||||
H.log_message("was made into a survivalist, and trusts no one!</font>", LOG_ATTACK, color="red")
|
||||
|
||||
var/magic_type = pick(GLOB.summoned_magic)
|
||||
var/lucky = FALSE
|
||||
if(prob(SPECIALIST_MAGIC_PROB))
|
||||
magic_type = pick(GLOB.summoned_special_magic)
|
||||
lucky = TRUE
|
||||
|
||||
var/obj/item/M = new magic_type(get_turf(H))
|
||||
playsound(get_turf(H),'sound/magic/summon_magic.ogg', 50, 1)
|
||||
|
||||
var/in_hand = H.put_in_hands(M)
|
||||
|
||||
to_chat(H, "<span class='warning'>\A [M] appears [in_hand ? "in your hand" : "at your feet"]!</span>")
|
||||
if(lucky)
|
||||
to_chat(H, "<span class='notice'>You feel incredibly lucky.</span>")
|
||||
|
||||
|
||||
/proc/rightandwrong(summon_type, mob/user, survivor_probability)
|
||||
if(user) //in this case either someone holding a spellbook or a badmin
|
||||
to_chat(user, "<span class='warning'>You summoned [summon_type]!</span>")
|
||||
message_admins("[key_name_admin(user, TRUE)] summoned [summon_type]!")
|
||||
log_game("[key_name(user)] summoned [summon_type]!")
|
||||
|
||||
if(summon_type == SUMMON_MAGIC)
|
||||
GLOB.summon_magic_triggered = survivor_probability
|
||||
else if(summon_type == SUMMON_GUNS)
|
||||
GLOB.summon_guns_triggered = survivor_probability
|
||||
else
|
||||
CRASH("Bad summon_type given: [summon_type]")
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.player_list)
|
||||
var/turf/T = get_turf(H)
|
||||
if(T && is_away_level(T.z))
|
||||
continue
|
||||
if(summon_type == SUMMON_MAGIC)
|
||||
give_magic(H)
|
||||
else
|
||||
give_guns(H)
|
||||
|
||||
/proc/summonevents()
|
||||
if(!SSevents.wizardmode)
|
||||
SSevents.frequency_lower = 600 //1 minute lower bound
|
||||
SSevents.frequency_upper = 3000 //5 minutes upper bound
|
||||
SSevents.toggleWizardmode()
|
||||
SSevents.reschedule()
|
||||
|
||||
else //Speed it up
|
||||
SSevents.frequency_upper -= 600 //The upper bound falls a minute each time, making the AVERAGE time between events lessen
|
||||
if(SSevents.frequency_upper < SSevents.frequency_lower) //Sanity
|
||||
SSevents.frequency_upper = SSevents.frequency_lower
|
||||
|
||||
SSevents.reschedule()
|
||||
message_admins("Summon Events intensifies, events will now occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes.")
|
||||
log_game("Summon Events was increased!")
|
||||
|
||||
#undef SPECIALIST_MAGIC_PROB
|
||||
//In this file: Summon Magic/Summon Guns/Summon Events
|
||||
|
||||
// 1 in 50 chance of getting something really special.
|
||||
#define SPECIALIST_MAGIC_PROB 2
|
||||
|
||||
GLOBAL_LIST_INIT(summoned_guns, list(
|
||||
/obj/item/gun/energy/e_gun/advtaser,
|
||||
/obj/item/gun/energy/e_gun,
|
||||
/obj/item/gun/energy/laser,
|
||||
/obj/item/gun/ballistic/revolver,
|
||||
/obj/item/gun/ballistic/revolver/detective,
|
||||
/obj/item/gun/ballistic/automatic/pistol/deagle/camo,
|
||||
/obj/item/gun/ballistic/automatic/gyropistol,
|
||||
/obj/item/gun/energy/pulse,
|
||||
/obj/item/gun/ballistic/automatic/pistol/suppressed,
|
||||
/obj/item/gun/ballistic/revolver/doublebarrel,
|
||||
/obj/item/gun/ballistic/shotgun,
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat,
|
||||
/obj/item/gun/ballistic/automatic/ar,
|
||||
/obj/item/gun/ballistic/revolver/mateba,
|
||||
/obj/item/gun/ballistic/shotgun/boltaction,
|
||||
/obj/item/gun/ballistic/automatic/speargun,
|
||||
/obj/item/gun/ballistic/automatic/mini_uzi,
|
||||
/obj/item/gun/energy/lasercannon,
|
||||
/obj/item/gun/energy/kinetic_accelerator/crossbow/large,
|
||||
/obj/item/gun/energy/e_gun/nuclear,
|
||||
/obj/item/gun/ballistic/automatic/proto,
|
||||
/obj/item/gun/ballistic/automatic/c20r,
|
||||
/obj/item/gun/ballistic/automatic/l6_saw,
|
||||
/obj/item/gun/ballistic/automatic/m90,
|
||||
/obj/item/gun/energy/alien,
|
||||
/obj/item/gun/energy/e_gun/dragnet,
|
||||
/obj/item/gun/energy/e_gun/turret,
|
||||
/obj/item/gun/energy/pulse/carbine,
|
||||
/obj/item/gun/energy/decloner,
|
||||
/obj/item/gun/energy/mindflayer,
|
||||
/obj/item/gun/energy/kinetic_accelerator,
|
||||
/obj/item/gun/energy/plasmacutter/adv,
|
||||
/obj/item/gun/energy/wormhole_projector,
|
||||
/obj/item/gun/ballistic/automatic/wt550,
|
||||
/obj/item/gun/ballistic/automatic/shotgun/bulldog,
|
||||
/obj/item/gun/ballistic/revolver/grenadelauncher,
|
||||
/obj/item/gun/ballistic/revolver/golden,
|
||||
/obj/item/gun/ballistic/automatic/sniper_rifle,
|
||||
/obj/item/gun/ballistic/rocketlauncher,
|
||||
/obj/item/gun/medbeam,
|
||||
/obj/item/gun/energy/laser/scatter,
|
||||
/obj/item/gun/energy/gravity_gun))
|
||||
|
||||
GLOBAL_LIST_INIT(summoned_magic, list(
|
||||
/obj/item/book/granter/spell/fireball,
|
||||
/obj/item/book/granter/spell/smoke,
|
||||
/obj/item/book/granter/spell/blind,
|
||||
/obj/item/book/granter/spell/mindswap,
|
||||
/obj/item/book/granter/spell/forcewall,
|
||||
/obj/item/book/granter/spell/knock,
|
||||
/obj/item/book/granter/spell/barnyard,
|
||||
/obj/item/book/granter/spell/charge,
|
||||
/obj/item/book/granter/spell/summonitem,
|
||||
/obj/item/gun/magic/wand,
|
||||
/obj/item/gun/magic/wand/death,
|
||||
/obj/item/gun/magic/wand/resurrection,
|
||||
/obj/item/gun/magic/wand/polymorph,
|
||||
/obj/item/gun/magic/wand/teleport,
|
||||
/obj/item/gun/magic/wand/door,
|
||||
/obj/item/gun/magic/wand/fireball,
|
||||
/obj/item/gun/magic/staff/healing,
|
||||
/obj/item/gun/magic/staff/door,
|
||||
/obj/item/scrying,
|
||||
/obj/item/voodoo,
|
||||
/obj/item/warpwhistle,
|
||||
/obj/item/clothing/suit/space/hardsuit/shielded/wizard,
|
||||
/obj/item/immortality_talisman,
|
||||
/obj/item/melee/ghost_sword))
|
||||
|
||||
GLOBAL_LIST_INIT(summoned_special_magic, list(
|
||||
/obj/item/gun/magic/staff/change,
|
||||
/obj/item/gun/magic/staff/animate,
|
||||
/obj/item/storage/belt/wands/full,
|
||||
/obj/item/antag_spawner/contract,
|
||||
/obj/item/gun/magic/staff/chaos,
|
||||
/obj/item/necromantic_stone,
|
||||
/obj/item/blood_contract))
|
||||
|
||||
// If true, it's the probability of triggering "survivor" antag.
|
||||
GLOBAL_VAR_INIT(summon_guns_triggered, FALSE)
|
||||
GLOBAL_VAR_INIT(summon_magic_triggered, FALSE)
|
||||
|
||||
/proc/give_guns(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD || !(H.client))
|
||||
return
|
||||
if(H.mind)
|
||||
if(iswizard(H) || H.mind.has_antag_datum(/datum/antagonist/survivalist/guns))
|
||||
return
|
||||
|
||||
if(prob(GLOB.summon_guns_triggered) && !(H.mind.has_antag_datum(/datum/antagonist)))
|
||||
SSticker.mode.traitors += H.mind
|
||||
|
||||
H.mind.add_antag_datum(/datum/antagonist/survivalist/guns)
|
||||
H.log_message("was made into a survivalist, and trusts no one!", LOG_ATTACK, color="red")
|
||||
|
||||
var/gun_type = pick(GLOB.summoned_guns)
|
||||
var/obj/item/gun/G = new gun_type(get_turf(H))
|
||||
G.unlock()
|
||||
playsound(get_turf(H),'sound/magic/summon_guns.ogg', 50, 1)
|
||||
|
||||
var/in_hand = H.put_in_hands(G) // not always successful
|
||||
|
||||
to_chat(H, "<span class='warning'>\A [G] appears [in_hand ? "in your hand" : "at your feet"]!</span>")
|
||||
|
||||
/proc/give_magic(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD || !(H.client))
|
||||
return
|
||||
if(H.mind)
|
||||
if(iswizard(H) || H.mind.has_antag_datum(/datum/antagonist/survivalist/magic))
|
||||
return
|
||||
|
||||
if(prob(GLOB.summon_magic_triggered) && !(H.mind.has_antag_datum(/datum/antagonist)))
|
||||
H.mind.add_antag_datum(/datum/antagonist/survivalist/magic)
|
||||
H.log_message("was made into a survivalist, and trusts no one!</font>", LOG_ATTACK, color="red")
|
||||
|
||||
var/magic_type = pick(GLOB.summoned_magic)
|
||||
var/lucky = FALSE
|
||||
if(prob(SPECIALIST_MAGIC_PROB))
|
||||
magic_type = pick(GLOB.summoned_special_magic)
|
||||
lucky = TRUE
|
||||
|
||||
var/obj/item/M = new magic_type(get_turf(H))
|
||||
playsound(get_turf(H),'sound/magic/summon_magic.ogg', 50, 1)
|
||||
|
||||
var/in_hand = H.put_in_hands(M)
|
||||
|
||||
to_chat(H, "<span class='warning'>\A [M] appears [in_hand ? "in your hand" : "at your feet"]!</span>")
|
||||
if(lucky)
|
||||
to_chat(H, "<span class='notice'>You feel incredibly lucky.</span>")
|
||||
|
||||
|
||||
/proc/rightandwrong(summon_type, mob/user, survivor_probability)
|
||||
if(user) //in this case either someone holding a spellbook or a badmin
|
||||
to_chat(user, "<span class='warning'>You summoned [summon_type]!</span>")
|
||||
message_admins("[key_name_admin(user, TRUE)] summoned [summon_type]!")
|
||||
log_game("[key_name(user)] summoned [summon_type]!")
|
||||
|
||||
if(summon_type == SUMMON_MAGIC)
|
||||
GLOB.summon_magic_triggered = survivor_probability
|
||||
else if(summon_type == SUMMON_GUNS)
|
||||
GLOB.summon_guns_triggered = survivor_probability
|
||||
else
|
||||
CRASH("Bad summon_type given: [summon_type]")
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.player_list)
|
||||
var/turf/T = get_turf(H)
|
||||
if(T && is_away_level(T.z))
|
||||
continue
|
||||
if(summon_type == SUMMON_MAGIC)
|
||||
give_magic(H)
|
||||
else
|
||||
give_guns(H)
|
||||
|
||||
/proc/summonevents()
|
||||
if(!SSevents.wizardmode)
|
||||
SSevents.frequency_lower = 600 //1 minute lower bound
|
||||
SSevents.frequency_upper = 3000 //5 minutes upper bound
|
||||
SSevents.toggleWizardmode()
|
||||
SSevents.reschedule()
|
||||
|
||||
else //Speed it up
|
||||
SSevents.frequency_upper -= 600 //The upper bound falls a minute each time, making the AVERAGE time between events lessen
|
||||
if(SSevents.frequency_upper < SSevents.frequency_lower) //Sanity
|
||||
SSevents.frequency_upper = SSevents.frequency_lower
|
||||
|
||||
SSevents.reschedule()
|
||||
message_admins("Summon Events intensifies, events will now occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes.")
|
||||
log_game("Summon Events was increased!")
|
||||
|
||||
#undef SPECIALIST_MAGIC_PROB
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
remove_hand(TRUE)
|
||||
to_chat(user, "<span class='notice'>You draw the power out of your hand.</span>")
|
||||
return
|
||||
|
||||
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
if(!attached_hand)
|
||||
if(ChargeHand(C))
|
||||
@@ -71,3 +71,15 @@
|
||||
|
||||
action_icon_state = "statue"
|
||||
sound = 'sound/magic/fleshtostone.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/touch/nuclear_fist
|
||||
name = "Nuclear Fist"
|
||||
desc = "This spell channels raw manliness, allowing you punch your enemies across the galaxy, causing them to detonate violently if hitting any other living being midflight. Does not work while laying down."
|
||||
hand_path = /obj/item/melee/touch_attack/nuclearfist
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
cooldown_min = 20
|
||||
|
||||
action_icon_state = "nuclearfist"
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
/obj/effect/proc_holder/spell/targeted/trigger
|
||||
name = "Trigger"
|
||||
desc = "This spell triggers another spell or a few."
|
||||
|
||||
var/list/linked_spells = list() //those are just referenced by the trigger spell and are unaffected by it directly
|
||||
var/list/starting_spells = list() //those are added on New() to contents from default spells and are deleted when the trigger spell is deleted to prevent memory leaks
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/Initialize()
|
||||
. = ..()
|
||||
|
||||
for(var/spell in starting_spells)
|
||||
var/spell_to_add = text2path(spell)
|
||||
new spell_to_add(src) //should result in adding to contents, needs testing
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/Destroy()
|
||||
for(var/spell in contents)
|
||||
qdel(spell)
|
||||
linked_spells = null
|
||||
starting_spells = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets,mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/mob/living/target in targets)
|
||||
for(var/obj/effect/proc_holder/spell/spell in contents)
|
||||
spell.perform(list(target),0)
|
||||
for(var/obj/effect/proc_holder/spell/spell in linked_spells)
|
||||
spell.perform(list(target),0)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger
|
||||
name = "Trigger"
|
||||
desc = "This spell triggers another spell or a few."
|
||||
|
||||
var/list/linked_spells = list() //those are just referenced by the trigger spell and are unaffected by it directly
|
||||
var/list/starting_spells = list() //those are added on New() to contents from default spells and are deleted when the trigger spell is deleted to prevent memory leaks
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/Initialize()
|
||||
. = ..()
|
||||
|
||||
for(var/spell in starting_spells)
|
||||
var/spell_to_add = text2path(spell)
|
||||
new spell_to_add(src) //should result in adding to contents, needs testing
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/Destroy()
|
||||
for(var/spell in contents)
|
||||
qdel(spell)
|
||||
linked_spells = null
|
||||
starting_spells = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets,mob/user = usr)
|
||||
playMagSound()
|
||||
for(var/mob/living/target in targets)
|
||||
for(var/obj/effect/proc_holder/spell/spell in contents)
|
||||
spell.perform(list(target),0)
|
||||
for(var/obj/effect/proc_holder/spell/spell in linked_spells)
|
||||
spell.perform(list(target),0)
|
||||
|
||||
return
|
||||
@@ -1,380 +1,380 @@
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/magic_missile
|
||||
name = "Magic Missile"
|
||||
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 200
|
||||
clothes_req = 1
|
||||
invocation = "FORTI GY AMA"
|
||||
invocation_type = "shout"
|
||||
range = 7
|
||||
cooldown_min = 60 //35 deciseconds reduction per rank
|
||||
|
||||
max_targets = 0
|
||||
|
||||
proj_icon_state = "magicm"
|
||||
proj_name = "a magic missile"
|
||||
proj_lingering = 1
|
||||
proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile"
|
||||
|
||||
proj_lifespan = 20
|
||||
proj_step_delay = 5
|
||||
|
||||
proj_trail = 1
|
||||
proj_trail_lifespan = 5
|
||||
proj_trail_icon_state = "magicmd"
|
||||
|
||||
action_icon_state = "magicm"
|
||||
sound = 'sound/magic/magic_missile.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile
|
||||
amt_knockdown = 120
|
||||
amt_hardstun = 5
|
||||
sound = 'sound/magic/mm_hit.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/mutate
|
||||
name = "Mutate"
|
||||
desc = "This spell causes you to turn into a hulk and gain laser vision for a short while."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "BIRUZ BENNAR"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
mutations = list(LASEREYES, HULK)
|
||||
duration = 300
|
||||
cooldown_min = 300 //25 deciseconds reduction per rank
|
||||
|
||||
action_icon_state = "mutate"
|
||||
sound = 'sound/magic/mutate.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/smoke
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 20 //25 deciseconds reduction per rank
|
||||
|
||||
smoke_spread = 2
|
||||
smoke_amt = 4
|
||||
|
||||
action_icon_state = "smoke"
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/smoke/lesser //Chaplain smoke book
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a small cloud of choking smoke at your location."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 360
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 2
|
||||
|
||||
action_icon_state = "smoke"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/emplosion/disable_tech
|
||||
name = "Disable Tech"
|
||||
desc = "This spell disables all weapons, cameras and most other technology in range."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "NEC CANTIO"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 200 //50 deciseconds reduction per rank
|
||||
|
||||
emp_heavy = 6
|
||||
emp_light = 10
|
||||
sound = 'sound/magic/disable_tech.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink
|
||||
name = "Blink"
|
||||
desc = "This spell randomly teleports you a short distance."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 20
|
||||
clothes_req = 1
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 5 //4 deciseconds reduction per rank
|
||||
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 0
|
||||
|
||||
inner_tele_radius = 0
|
||||
outer_tele_radius = 6
|
||||
|
||||
action_icon_state = "blink"
|
||||
sound1 = 'sound/magic/blink.ogg'
|
||||
sound2 = 'sound/magic/blink.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink/cult
|
||||
name = "quickstep"
|
||||
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
cult_req = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/teleport
|
||||
name = "Teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 1
|
||||
invocation = "SCYAR NILA"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 200 //100 deciseconds reduction per rank
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 2
|
||||
sound1 = 'sound/magic/teleport_diss.ogg'
|
||||
sound2 = 'sound/magic/teleport_app.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/timestop
|
||||
name = "Stop Time"
|
||||
desc = "This spell stops time for everyone except for you, allowing you to move freely while your enemies and even projectiles are frozen."
|
||||
charge_max = 500
|
||||
clothes_req = 1
|
||||
invocation = "TOKI YO TOMARE"
|
||||
invocation_type = "shout"
|
||||
range = 0
|
||||
cooldown_min = 100
|
||||
action_icon_state = "time"
|
||||
var/timestop_range = 2
|
||||
var/timestop_duration = 100
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/timestop/cast(list/targets, mob/user = usr)
|
||||
new /obj/effect/timestop/magic(get_turf(user), timestop_range, timestop_duration, list(user))
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/carp
|
||||
name = "Summon Carp"
|
||||
desc = "This spell conjures a simple carp."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 1200
|
||||
clothes_req = 1
|
||||
invocation = "NOUK FHUNMM SACP RISSKA"
|
||||
invocation_type = "shout"
|
||||
range = 1
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/carp)
|
||||
cast_sound = 'sound/magic/summon_karp.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/construct
|
||||
name = "Artificer"
|
||||
desc = "This spell conjures a construct which may be controlled by Shades."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/constructshell)
|
||||
|
||||
action_icon_state = "artificer"
|
||||
cast_sound = 'sound/magic/summonitems_generic.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature
|
||||
name = "Summon Creature Swarm"
|
||||
desc = "This spell tears the fabric of reality, allowing horrific daemons to spill forth."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 1200
|
||||
clothes_req = 0
|
||||
invocation = "IA IA"
|
||||
invocation_type = "shout"
|
||||
summon_amt = 10
|
||||
range = 3
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/netherworld)
|
||||
cast_sound = 'sound/magic/summonitems_generic.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/blind
|
||||
name = "Blind"
|
||||
desc = "This spell temporarily blinds a single person and does not require wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
invocation = "STI KALY"
|
||||
invocation_type = "whisper"
|
||||
message = "<span class='notice'>Your eyes cry out in pain!</span>"
|
||||
cooldown_min = 50 //12 deciseconds reduction per rank
|
||||
|
||||
starting_spells = list("/obj/effect/proc_holder/spell/targeted/inflict_handler/blind","/obj/effect/proc_holder/spell/targeted/genetic/blind")
|
||||
|
||||
action_icon_state = "blind"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature/cult
|
||||
name = "Summon Creatures (DANGEROUS)"
|
||||
cult_req = 1
|
||||
charge_max = 5000
|
||||
summon_amt = 2
|
||||
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/blind
|
||||
amt_eye_blind = 10
|
||||
amt_eye_blurry = 20
|
||||
sound = 'sound/magic/blind.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/blind
|
||||
mutations = list(BLINDMUT)
|
||||
duration = 300
|
||||
sound = 'sound/magic/blind.ogg'
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse
|
||||
name = "Repulse"
|
||||
desc = "This spell throws everything around the user away."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "GITTAH WEIGH"
|
||||
invocation_type = "shout"
|
||||
range = 5
|
||||
cooldown_min = 150
|
||||
selection_type = "view"
|
||||
sound = 'sound/magic/repulse.ogg'
|
||||
var/maxthrow = 5
|
||||
var/sparkle_path = /obj/effect/temp_visual/gravpush
|
||||
var/anti_magic_check = TRUE
|
||||
|
||||
action_icon_state = "repulse"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, stun_amt = 50)
|
||||
var/list/thrownatoms = list()
|
||||
var/atom/throwtarget
|
||||
var/distfromcaster
|
||||
playMagSound()
|
||||
for(var/turf/T in targets) //Done this way so things don't get thrown all around hilariously.
|
||||
for(var/atom/movable/AM in T)
|
||||
thrownatoms += AM
|
||||
|
||||
for(var/am in thrownatoms)
|
||||
var/atom/movable/AM = am
|
||||
if(AM == user || AM.anchored)
|
||||
continue
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(M.anti_magic_check(anti_magic_check, FALSE))
|
||||
continue
|
||||
|
||||
throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
|
||||
distfromcaster = get_dist(user, AM)
|
||||
if(distfromcaster == 0)
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Knockdown(100, override_hardstun = 20)
|
||||
M.adjustBruteLoss(5)
|
||||
to_chat(M, "<span class='userdanger'>You're slammed into the floor by [user]!</span>")
|
||||
else
|
||||
new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Knockdown(stun_amt, override_hardstun = stun_amt * 0.2)
|
||||
to_chat(M, "<span class='userdanger'>You're thrown back by [user]!</span>")
|
||||
AM.throw_at(throwtarget, ((CLAMP((maxthrow - (CLAMP(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time.
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?!
|
||||
name = "Tail Sweep"
|
||||
desc = "Throw back attackers with a sweep of your tail."
|
||||
sound = 'sound/magic/tail_swing.ogg'
|
||||
charge_max = 150
|
||||
clothes_req = 0
|
||||
range = 2
|
||||
cooldown_min = 150
|
||||
invocation_type = "none"
|
||||
sparkle_path = /obj/effect/temp_visual/dir_setting/tailsweep
|
||||
action_icon = 'icons/mob/actions/actions_xeno.dmi'
|
||||
action_icon_state = "tailsweep"
|
||||
action_background_icon_state = "bg_alien"
|
||||
anti_magic_check = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno/cast(list/targets,mob/user = usr)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
playsound(C.loc, 'sound/voice/hiss5.ogg', 80, 1, 1)
|
||||
C.spin(6,1)
|
||||
..(targets, user, 60)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame
|
||||
name = "Sacred Flame"
|
||||
desc = "Makes everyone around you more flammable, and lights yourself on fire."
|
||||
charge_max = 60
|
||||
clothes_req = 0
|
||||
invocation = "FI'RAN DADISKO"
|
||||
invocation_type = "shout"
|
||||
max_targets = 0
|
||||
range = 6
|
||||
include_user = 1
|
||||
selection_type = "view"
|
||||
action_icon_state = "sacredflame"
|
||||
sound = 'sound/magic/fireball.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/L in targets)
|
||||
if(L.anti_magic_check(TRUE, TRUE))
|
||||
continue
|
||||
L.adjust_fire_stacks(20)
|
||||
if(isliving(user))
|
||||
var/mob/living/U = user
|
||||
if(!U.anti_magic_check(TRUE, TRUE))
|
||||
U.IgniteMob()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket
|
||||
name = "Thrown Lightning"
|
||||
desc = "Forged from eldrich energies, a packet of pure power, known as a spell packet will appear in your hand, that when thrown will stun the target."
|
||||
clothes_req = 1
|
||||
item_type = /obj/item/spellpacket/lightningbolt
|
||||
charge_max = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket/cast(list/targets, mob/user = usr)
|
||||
..()
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
C.throw_mode_on()
|
||||
|
||||
/obj/item/spellpacket/lightningbolt
|
||||
name = "\improper Lightning bolt Spell Packet"
|
||||
desc = "Some birdseed wrapped in cloth that somehow crackles with electricity."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "snappop"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/spellpacket/lightningbolt/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(!..())
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/M = hit_atom
|
||||
if(!M.anti_magic_check())
|
||||
M.electrocute_act(80, src, illusion = 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/spellpacket/lightningbolt/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
. = ..()
|
||||
if(ishuman(thrower))
|
||||
var/mob/living/carbon/human/H = thrower
|
||||
H.say("LIGHTNINGBOLT!!", forced = "spell")
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/magic_missile
|
||||
name = "Magic Missile"
|
||||
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 200
|
||||
clothes_req = 1
|
||||
invocation = "FORTI GY AMA"
|
||||
invocation_type = "shout"
|
||||
range = 7
|
||||
cooldown_min = 60 //35 deciseconds reduction per rank
|
||||
|
||||
max_targets = 0
|
||||
|
||||
proj_icon_state = "magicm"
|
||||
proj_name = "a magic missile"
|
||||
proj_lingering = 1
|
||||
proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile"
|
||||
|
||||
proj_lifespan = 20
|
||||
proj_step_delay = 5
|
||||
|
||||
proj_trail = 1
|
||||
proj_trail_lifespan = 5
|
||||
proj_trail_icon_state = "magicmd"
|
||||
|
||||
action_icon_state = "magicm"
|
||||
sound = 'sound/magic/magic_missile.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile
|
||||
amt_knockdown = 120
|
||||
amt_hardstun = 5
|
||||
sound = 'sound/magic/mm_hit.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/mutate
|
||||
name = "Mutate"
|
||||
desc = "This spell causes you to turn into a hulk and gain laser vision for a short while."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "BIRUZ BENNAR"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
mutations = list(LASEREYES, HULK)
|
||||
duration = 300
|
||||
cooldown_min = 300 //25 deciseconds reduction per rank
|
||||
|
||||
action_icon_state = "mutate"
|
||||
sound = 'sound/magic/mutate.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/smoke
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 20 //25 deciseconds reduction per rank
|
||||
|
||||
smoke_spread = 2
|
||||
smoke_amt = 4
|
||||
|
||||
action_icon_state = "smoke"
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/smoke/lesser //Chaplain smoke book
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a small cloud of choking smoke at your location."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 360
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 2
|
||||
|
||||
action_icon_state = "smoke"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/emplosion/disable_tech
|
||||
name = "Disable Tech"
|
||||
desc = "This spell disables all weapons, cameras and most other technology in range."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "NEC CANTIO"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 200 //50 deciseconds reduction per rank
|
||||
|
||||
emp_heavy = 6
|
||||
emp_light = 10
|
||||
sound = 'sound/magic/disable_tech.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink
|
||||
name = "Blink"
|
||||
desc = "This spell randomly teleports you a short distance."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 20
|
||||
clothes_req = 1
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 5 //4 deciseconds reduction per rank
|
||||
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 0
|
||||
|
||||
inner_tele_radius = 0
|
||||
outer_tele_radius = 6
|
||||
|
||||
action_icon_state = "blink"
|
||||
sound1 = 'sound/magic/blink.ogg'
|
||||
sound2 = 'sound/magic/blink.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink/cult
|
||||
name = "quickstep"
|
||||
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
cult_req = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/teleport
|
||||
name = "Teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 1
|
||||
invocation = "SCYAR NILA"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 200 //100 deciseconds reduction per rank
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 2
|
||||
sound1 = 'sound/magic/teleport_diss.ogg'
|
||||
sound2 = 'sound/magic/teleport_app.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/timestop
|
||||
name = "Stop Time"
|
||||
desc = "This spell stops time for everyone except for you, allowing you to move freely while your enemies and even projectiles are frozen."
|
||||
charge_max = 500
|
||||
clothes_req = 1
|
||||
invocation = "TOKI YO TOMARE"
|
||||
invocation_type = "shout"
|
||||
range = 0
|
||||
cooldown_min = 100
|
||||
action_icon_state = "time"
|
||||
var/timestop_range = 2
|
||||
var/timestop_duration = 100
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/timestop/cast(list/targets, mob/user = usr)
|
||||
new /obj/effect/timestop/magic(get_turf(user), timestop_range, timestop_duration, list(user))
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/carp
|
||||
name = "Summon Carp"
|
||||
desc = "This spell conjures a simple carp."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 1200
|
||||
clothes_req = 1
|
||||
invocation = "NOUK FHUNMM SACP RISSKA"
|
||||
invocation_type = "shout"
|
||||
range = 1
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/carp)
|
||||
cast_sound = 'sound/magic/summon_karp.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/construct
|
||||
name = "Artificer"
|
||||
desc = "This spell conjures a construct which may be controlled by Shades."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/constructshell)
|
||||
|
||||
action_icon_state = "artificer"
|
||||
cast_sound = 'sound/magic/summonitems_generic.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature
|
||||
name = "Summon Creature Swarm"
|
||||
desc = "This spell tears the fabric of reality, allowing horrific daemons to spill forth."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 1200
|
||||
clothes_req = 0
|
||||
invocation = "IA IA"
|
||||
invocation_type = "shout"
|
||||
summon_amt = 10
|
||||
range = 3
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/netherworld)
|
||||
cast_sound = 'sound/magic/summonitems_generic.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/blind
|
||||
name = "Blind"
|
||||
desc = "This spell temporarily blinds a single person and does not require wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
invocation = "STI KALY"
|
||||
invocation_type = "whisper"
|
||||
message = "<span class='notice'>Your eyes cry out in pain!</span>"
|
||||
cooldown_min = 50 //12 deciseconds reduction per rank
|
||||
|
||||
starting_spells = list("/obj/effect/proc_holder/spell/targeted/inflict_handler/blind","/obj/effect/proc_holder/spell/targeted/genetic/blind")
|
||||
|
||||
action_icon_state = "blind"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature/cult
|
||||
name = "Summon Creatures (DANGEROUS)"
|
||||
cult_req = 1
|
||||
charge_max = 5000
|
||||
summon_amt = 2
|
||||
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/blind
|
||||
amt_eye_blind = 10
|
||||
amt_eye_blurry = 20
|
||||
sound = 'sound/magic/blind.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/blind
|
||||
mutations = list(BLINDMUT)
|
||||
duration = 300
|
||||
sound = 'sound/magic/blind.ogg'
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse
|
||||
name = "Repulse"
|
||||
desc = "This spell throws everything around the user away."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "GITTAH WEIGH"
|
||||
invocation_type = "shout"
|
||||
range = 5
|
||||
cooldown_min = 150
|
||||
selection_type = "view"
|
||||
sound = 'sound/magic/repulse.ogg'
|
||||
var/maxthrow = 5
|
||||
var/sparkle_path = /obj/effect/temp_visual/gravpush
|
||||
var/anti_magic_check = TRUE
|
||||
|
||||
action_icon_state = "repulse"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, stun_amt = 50)
|
||||
var/list/thrownatoms = list()
|
||||
var/atom/throwtarget
|
||||
var/distfromcaster
|
||||
playMagSound()
|
||||
for(var/turf/T in targets) //Done this way so things don't get thrown all around hilariously.
|
||||
for(var/atom/movable/AM in T)
|
||||
thrownatoms += AM
|
||||
|
||||
for(var/am in thrownatoms)
|
||||
var/atom/movable/AM = am
|
||||
if(AM == user || AM.anchored)
|
||||
continue
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(M.anti_magic_check(anti_magic_check, FALSE))
|
||||
continue
|
||||
|
||||
throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
|
||||
distfromcaster = get_dist(user, AM)
|
||||
if(distfromcaster == 0)
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Knockdown(100, override_hardstun = 20)
|
||||
M.adjustBruteLoss(5)
|
||||
to_chat(M, "<span class='userdanger'>You're slammed into the floor by [user]!</span>")
|
||||
else
|
||||
new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Knockdown(stun_amt, override_hardstun = stun_amt * 0.2)
|
||||
to_chat(M, "<span class='userdanger'>You're thrown back by [user]!</span>")
|
||||
AM.throw_at(throwtarget, ((CLAMP((maxthrow - (CLAMP(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time.
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?!
|
||||
name = "Tail Sweep"
|
||||
desc = "Throw back attackers with a sweep of your tail."
|
||||
sound = 'sound/magic/tail_swing.ogg'
|
||||
charge_max = 150
|
||||
clothes_req = 0
|
||||
range = 2
|
||||
cooldown_min = 150
|
||||
invocation_type = "none"
|
||||
sparkle_path = /obj/effect/temp_visual/dir_setting/tailsweep
|
||||
action_icon = 'icons/mob/actions/actions_xeno.dmi'
|
||||
action_icon_state = "tailsweep"
|
||||
action_background_icon_state = "bg_alien"
|
||||
anti_magic_check = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno/cast(list/targets,mob/user = usr)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
playsound(C.loc, 'sound/voice/hiss5.ogg', 80, 1, 1)
|
||||
C.spin(6,1)
|
||||
..(targets, user, 60)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame
|
||||
name = "Sacred Flame"
|
||||
desc = "Makes everyone around you more flammable, and lights yourself on fire."
|
||||
charge_max = 60
|
||||
clothes_req = 0
|
||||
invocation = "FI'RAN DADISKO"
|
||||
invocation_type = "shout"
|
||||
max_targets = 0
|
||||
range = 6
|
||||
include_user = 1
|
||||
selection_type = "view"
|
||||
action_icon_state = "sacredflame"
|
||||
sound = 'sound/magic/fireball.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/L in targets)
|
||||
if(L.anti_magic_check(TRUE, TRUE))
|
||||
continue
|
||||
L.adjust_fire_stacks(20)
|
||||
if(isliving(user))
|
||||
var/mob/living/U = user
|
||||
if(!U.anti_magic_check(TRUE, TRUE))
|
||||
U.IgniteMob()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket
|
||||
name = "Thrown Lightning"
|
||||
desc = "Forged from eldrich energies, a packet of pure power, known as a spell packet will appear in your hand, that when thrown will stun the target."
|
||||
clothes_req = 1
|
||||
item_type = /obj/item/spellpacket/lightningbolt
|
||||
charge_max = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket/cast(list/targets, mob/user = usr)
|
||||
..()
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
C.throw_mode_on()
|
||||
|
||||
/obj/item/spellpacket/lightningbolt
|
||||
name = "\improper Lightning bolt Spell Packet"
|
||||
desc = "Some birdseed wrapped in cloth that somehow crackles with electricity."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "snappop"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/spellpacket/lightningbolt/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(!..())
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/M = hit_atom
|
||||
if(!M.anti_magic_check())
|
||||
M.electrocute_act(80, src, illusion = 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/spellpacket/lightningbolt/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
. = ..()
|
||||
if(ishuman(thrower))
|
||||
var/mob/living/carbon/human/H = thrower
|
||||
H.say("LIGHTNINGBOLT!!", forced = "spell")
|
||||
|
||||
Reference in New Issue
Block a user