mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 02:24:11 +01:00
Datumizes spells (#24242)
* datumized spells * finished * last changes * conflict * Update code/datums/spells/alien_spells/transfer_plasma.dm * conflicts * shitty runtime fix until i get to this tomorrow * Update code/datums/spell.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spell_handler/alien_spell_handler.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/alien_spells/regurgitate.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/alien_spells/regurgitate.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/bloodcrawl.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/bloodcrawl.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/modules/awaymissions/mission_code/ruins/wizardcrash.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/modules/research/xenobiology/xenobiology.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/modules/mob/living/carbon/superheroes.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/conjure.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/ethereal_jaunt.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/emplosion.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/turf_teleport.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/wizard_spells.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/wizard_spells.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/game/dna/mutations/mutation_powers.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/wizard_spells.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/spells/wizard_spells.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/game/dna/mutations/mutation_powers.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/game/gamemodes/miniantags/revenant/revenant_abilities.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * guess who just rework the entire malf ai actionsf ai * gc better --------- Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
@@ -600,9 +600,9 @@
|
||||
#define COMSIG_ITEM_PICKUP "item_pickup"
|
||||
///from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone)
|
||||
#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone"
|
||||
///return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/lichdom/cast(): (mob/user)
|
||||
///return a truthy value to prevent ensouling, checked in /datum/spell/lichdom/cast(): (mob/user)
|
||||
#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul"
|
||||
///called before marking an object for retrieval, checked in /obj/effect/proc_holder/spell/summonitem/cast() : (mob/user)
|
||||
///called before marking an object for retrieval, checked in /datum/spell/summonitem/cast() : (mob/user)
|
||||
#define COMSIG_ITEM_MARK_RETRIEVAL "item_mark_retrieval"
|
||||
#define COMPONENT_BLOCK_MARK_RETRIEVAL (1<<0)
|
||||
///from base of obj/item/hit_reaction(): (list/args)
|
||||
|
||||
@@ -637,7 +637,7 @@
|
||||
|
||||
/datum/action/spell_action/New(Target)
|
||||
..()
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
var/datum/spell/S = target
|
||||
S.action = src
|
||||
name = S.name
|
||||
desc = S.desc
|
||||
@@ -648,7 +648,7 @@
|
||||
|
||||
|
||||
/datum/action/spell_action/Destroy()
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
var/datum/spell/S = target
|
||||
S.action = null
|
||||
return ..()
|
||||
|
||||
@@ -656,27 +656,27 @@
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(target)
|
||||
var/obj/effect/proc_holder/spell = target
|
||||
var/datum/spell/spell = target
|
||||
spell.Click()
|
||||
return TRUE
|
||||
|
||||
/datum/action/spell_action/AltTrigger()
|
||||
if(target)
|
||||
var/obj/effect/proc_holder/spell/spell = target
|
||||
var/datum/spell/spell = target
|
||||
spell.AltClick(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/action/spell_action/IsAvailable()
|
||||
if(!target)
|
||||
return FALSE
|
||||
var/obj/effect/proc_holder/spell/spell = target
|
||||
var/datum/spell/spell = target
|
||||
|
||||
if(owner)
|
||||
return spell.can_cast(owner)
|
||||
return FALSE
|
||||
|
||||
/datum/action/spell_action/apply_unavailable_effect(atom/movable/screen/movable/action_button/button)
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
var/datum/spell/S = target
|
||||
if(!istype(S))
|
||||
return ..()
|
||||
|
||||
|
||||
+5
-5
@@ -1052,7 +1052,7 @@
|
||||
log_admin("[key_name(usr)] has removed [key_name(current)]'s vampire subclass.")
|
||||
message_admins("[key_name_admin(usr)] has removed [key_name_admin(current)]'s vampire subclass.")
|
||||
else
|
||||
vamp.upgrade_tiers -= /obj/effect/proc_holder/spell/vampire/self/specialize
|
||||
vamp.upgrade_tiers -= /datum/spell/vampire/self/specialize
|
||||
vamp.change_subclass(subclass_type)
|
||||
log_admin("[key_name(usr)] has removed [key_name(current)]'s vampire subclass.")
|
||||
message_admins("[key_name_admin(usr)] has removed [key_name_admin(current)]'s vampire subclass.")
|
||||
@@ -1676,14 +1676,14 @@
|
||||
SEND_SOUND(H, sound('sound/ambience/antag/abductors.ogg'))
|
||||
H.create_log(MISC_LOG, "[H] was made into an abductor")
|
||||
|
||||
/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S)
|
||||
/datum/mind/proc/AddSpell(datum/spell/S)
|
||||
spell_list += S
|
||||
S.action.Grant(current)
|
||||
|
||||
/datum/mind/proc/RemoveSpell(obj/effect/proc_holder/spell/spell) //To remove a specific spell from a mind
|
||||
/datum/mind/proc/RemoveSpell(datum/spell/spell) //To remove a specific spell from a mind
|
||||
if(!spell)
|
||||
return
|
||||
for(var/obj/effect/proc_holder/spell/S in spell_list)
|
||||
for(var/datum/spell/S in spell_list)
|
||||
if(istype(S, spell))
|
||||
qdel(S)
|
||||
spell_list -= S
|
||||
@@ -1696,7 +1696,7 @@
|
||||
|
||||
/datum/mind/proc/transfer_mindbound_actions(mob/living/new_character)
|
||||
for(var/X in spell_list)
|
||||
var/obj/effect/proc_holder/spell/S = X
|
||||
var/datum/spell/S = X
|
||||
if(!S.on_mind_transfer(new_character))
|
||||
current.RemoveSpell(S)
|
||||
continue
|
||||
|
||||
@@ -1410,8 +1410,8 @@
|
||||
box = /obj/item/storage/box/wizard
|
||||
|
||||
//The spells that the enforcer has.
|
||||
var/list/spell_paths = list(/obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter,
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/lightning, /obj/effect/proc_holder/spell/summonitem)
|
||||
var/list/spell_paths = list(/datum/spell/aoe/conjure/summon_supermatter,
|
||||
/datum/spell/charge_up/bounce/lightning, /datum/spell/summonitem)
|
||||
|
||||
/datum/outfit/admin/enforcer/post_equip(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
|
||||
+63
-71
@@ -1,29 +1,9 @@
|
||||
/obj/effect/proc_holder
|
||||
var/panel = "Debug"//What panel the proc holder needs to go on.
|
||||
var/active = FALSE //Used by toggle based abilities.
|
||||
var/ranged_mousepointer
|
||||
var/mob/ranged_ability_user
|
||||
|
||||
/obj/effect/proc_holder/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/singularity_pull()
|
||||
return
|
||||
|
||||
GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
|
||||
/obj/effect/proc_holder/proc/InterceptClickOn(mob/user, params, atom/A)
|
||||
if(user.ranged_ability != src)
|
||||
to_chat(user, "<span class='warning'><b>[user.ranged_ability.name]</b> has been disabled.")
|
||||
user.ranged_ability.remove_ranged_ability(user)
|
||||
return TRUE //TRUE for failed, FALSE for passed.
|
||||
user.face_atom(A)
|
||||
return FALSE
|
||||
GLOBAL_LIST_INIT(spells, typesof(/datum/spell))
|
||||
|
||||
/datum/click_intercept/proc_holder
|
||||
var/obj/effect/proc_holder/spell
|
||||
var/datum/spell/spell
|
||||
|
||||
/datum/click_intercept/proc_holder/New(client/C, obj/effect/proc_holder/spell_to_cast)
|
||||
/datum/click_intercept/proc_holder/New(client/C, datum/spell/spell_to_cast)
|
||||
. = ..()
|
||||
spell = spell_to_cast
|
||||
|
||||
@@ -34,7 +14,15 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
spell.remove_ranged_ability(spell.ranged_ability_user)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/proc/add_ranged_ability(mob/user, msg)
|
||||
/datum/spell/proc/InterceptClickOn(mob/user, params, atom/A)
|
||||
if(user.ranged_ability != src)
|
||||
to_chat(user, "<span class='warning'><b>[user.ranged_ability.name]</b> has been disabled.</span>")
|
||||
user.ranged_ability.remove_ranged_ability(user)
|
||||
return TRUE //TRUE for failed, FALSE for passed.
|
||||
user.face_atom(A)
|
||||
return FALSE
|
||||
|
||||
/datum/spell/proc/add_ranged_ability(mob/user, msg)
|
||||
if(!user || !user.client)
|
||||
return
|
||||
if(user.ranged_ability && user.ranged_ability != src)
|
||||
@@ -47,17 +35,20 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
active = TRUE
|
||||
if(msg)
|
||||
to_chat(user, msg)
|
||||
update_icon()
|
||||
update_spell_icon()
|
||||
|
||||
/obj/effect/proc_holder/proc/add_mousepointer(client/C)
|
||||
/datum/spell/proc/update_spell_icon()
|
||||
return
|
||||
|
||||
/datum/spell/proc/add_mousepointer(client/C)
|
||||
if(C && ranged_mousepointer && C.mouse_pointer_icon == initial(C.mouse_pointer_icon))
|
||||
C.mouse_pointer_icon = ranged_mousepointer
|
||||
|
||||
/obj/effect/proc_holder/proc/remove_mousepointer(client/C)
|
||||
/datum/spell/proc/remove_mousepointer(client/C)
|
||||
if(C && ranged_mousepointer && C.mouse_pointer_icon == ranged_mousepointer)
|
||||
C.mouse_pointer_icon = initial(C.mouse_pointer_icon)
|
||||
|
||||
/obj/effect/proc_holder/proc/remove_ranged_ability(mob/user, msg)
|
||||
/datum/spell/proc/remove_ranged_ability(mob/user, msg)
|
||||
if(!user || (user.ranged_ability && user.ranged_ability != src)) //To avoid removing the wrong ability
|
||||
return
|
||||
user.ranged_ability = null
|
||||
@@ -69,14 +60,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
remove_mousepointer(user.client)
|
||||
if(msg)
|
||||
to_chat(user, msg)
|
||||
update_icon()
|
||||
update_spell_icon()
|
||||
|
||||
/obj/effect/proc_holder/spell
|
||||
name = "Spell" // Only rename this if the spell you're making is not abstract
|
||||
desc = "A wizard spell"
|
||||
panel = "Spells"//What panel the proc holder needs to go on.
|
||||
density = FALSE
|
||||
opacity = FALSE
|
||||
/datum/spell
|
||||
var/name = "Spell" // Only rename this if the spell you're making is not abstract
|
||||
var/desc = "A wizard spell"
|
||||
var/panel = "Spells"//What panel the proc holder needs to go on.
|
||||
|
||||
var/school = "evocation" //not relevant at now, but may be important later if there are changes to how spells work. the ones I used for now will probably be changed... maybe spell presets? lacking flexibility but with some other benefit?
|
||||
///recharge time in deciseconds
|
||||
@@ -87,6 +76,9 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
|
||||
var/holder_var_type = "bruteloss" //only used if charge_type equals to "holder_var"
|
||||
var/holder_var_amount = 20 //same. The amount adjusted with the mob's var when the spell is used
|
||||
var/active = FALSE //Used by toggle based abilities.
|
||||
var/ranged_mousepointer
|
||||
var/mob/ranged_ability_user
|
||||
|
||||
var/ghost = FALSE // Skip life check.
|
||||
var/clothes_req = TRUE //see if it requires clothes
|
||||
@@ -153,7 +145,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* @param start_recharge If the proc should set the cooldown
|
||||
* @param user The caster of the spell
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
|
||||
/datum/spell/proc/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
|
||||
// SHOULD_NOT_OVERRIDE(TRUE) Todo for another refactor
|
||||
if(!can_cast(user, charge_check, TRUE))
|
||||
return FALSE
|
||||
@@ -178,7 +170,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* * target - Who is being considered
|
||||
* * user - Who is the user of this spell
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/valid_target(target, user)
|
||||
/datum/spell/proc/valid_target(target, user)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
@@ -187,7 +179,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* Arguments:
|
||||
* * user - Who used this spell?
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/spend_spell_cost(mob/user)
|
||||
/datum/spell/proc/spend_spell_cost(mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
|
||||
custom_handler?.spend_spell_cost(user, src)
|
||||
@@ -195,7 +187,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
if(action)
|
||||
action.UpdateButtons()
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/invocation(mob/user) //spelling the spell out and setting it on recharge/reducing charges amount
|
||||
/datum/spell/proc/invocation(mob/user) //spelling the spell out and setting it on recharge/reducing charges amount
|
||||
switch(invocation_type)
|
||||
if("shout")
|
||||
if(!user.IsVocal() || user.cannot_speak_loudly())
|
||||
@@ -213,10 +205,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
if("emote")
|
||||
user.visible_message(invocation, invocation_emote_self) //same style as in mob/living/emote.dm
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/playMagSound()
|
||||
/datum/spell/proc/playMagSound()
|
||||
playsound(get_turf(usr), sound,50,1)
|
||||
|
||||
/obj/effect/proc_holder/spell/New()
|
||||
/datum/spell/New()
|
||||
..()
|
||||
action = new(src)
|
||||
still_recharging_msg = "<span class='notice'>[name] is still recharging.</span>"
|
||||
@@ -236,7 +228,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
cooldown_handler = create_new_cooldown()
|
||||
cooldown_handler.cooldown_init(src)
|
||||
|
||||
/obj/effect/proc_holder/spell/Destroy()
|
||||
/datum/spell/Destroy()
|
||||
QDEL_NULL(action)
|
||||
QDEL_NULL(cooldown_handler)
|
||||
return ..()
|
||||
@@ -245,7 +237,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* Creates and returns the targeting datum for this spell type. Override this!
|
||||
* Should return a value of type [/datum/spell_targeting]
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/create_new_targeting()
|
||||
/datum/spell/proc/create_new_targeting()
|
||||
RETURN_TYPE(/datum/spell_targeting)
|
||||
return
|
||||
|
||||
@@ -254,7 +246,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* Override this if you want a custom spell handler.
|
||||
* Should return a value of type [/datum/spell_handler] or NONE
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/create_new_handler()
|
||||
/datum/spell/proc/create_new_handler()
|
||||
RETURN_TYPE(/datum/spell_handler)
|
||||
return NONE
|
||||
|
||||
@@ -263,29 +255,30 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* Override this if you wish to use a different method of cooldown
|
||||
*/
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/create_new_cooldown()
|
||||
/datum/spell/proc/create_new_cooldown()
|
||||
RETURN_TYPE(/datum/spell_cooldown)
|
||||
var/datum/spell_cooldown/S = new
|
||||
S.recharge_duration = base_cooldown
|
||||
S.starts_off_cooldown = starts_charged
|
||||
return S
|
||||
|
||||
/obj/effect/proc_holder/spell/Click()
|
||||
/datum/spell/proc/Click()
|
||||
if(cast_check(TRUE, FALSE, usr))
|
||||
choose_targets(usr)
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/spell/AltClick(mob/user)
|
||||
/datum/spell/proc/AltClick(mob/user)
|
||||
return Click()
|
||||
|
||||
/obj/effect/proc_holder/spell/InterceptClickOn(mob/user, params, atom/A)
|
||||
/datum/spell/InterceptClickOn(mob/user, params, atom/A)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
targeting.InterceptClickOn(user, params, A, src)
|
||||
if(targeting)
|
||||
targeting.InterceptClickOn(user, params, A, src)
|
||||
|
||||
///Lets the spell have a special effect applied to it when upgraded. By default, does nothing.
|
||||
/obj/effect/proc_holder/spell/proc/on_purchase_upgrade()
|
||||
/datum/spell/proc/on_purchase_upgrade()
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -295,7 +288,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* Arguments:
|
||||
* * user - The caster of the spell
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/choose_targets(mob/user)
|
||||
/datum/spell/proc/choose_targets(mob/user)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
if(targeting.use_intercept_click)
|
||||
if(active)
|
||||
@@ -317,7 +310,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* * targets - The targets the spell is being performed on
|
||||
* * user - The caster of the spell
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/try_perform(list/targets, mob/user)
|
||||
/datum/spell/proc/try_perform(list/targets, mob/user)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
if(!length(targets))
|
||||
to_chat(user, "<span class='warning'>No suitable target found.</span>")
|
||||
@@ -333,7 +326,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* Called in `try_perform` before removing the click interceptor. useful to override if you have a spell that requires more than 1 click
|
||||
*/
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/should_remove_click_intercept()
|
||||
/datum/spell/proc/should_remove_click_intercept()
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
@@ -344,7 +337,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* * recharge - Whether or not the spell should go recharge
|
||||
* * user - The caster of the spell
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = TRUE, mob/user = usr) //if recharge is started is important for the trigger spells
|
||||
/datum/spell/proc/perform(list/targets, recharge = TRUE, mob/user = usr) //if recharge is started is important for the trigger spells
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
before_cast(targets, user)
|
||||
invocation(user)
|
||||
@@ -371,11 +364,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* * targets - The targets being targeted by the spell
|
||||
* * user - The user of the spell
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/write_custom_logs(list/targets, mob/user)
|
||||
/datum/spell/proc/write_custom_logs(list/targets, mob/user)
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/before_cast(list/targets, mob/user)
|
||||
/datum/spell/proc/before_cast(list/targets, mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(overlay)
|
||||
for(var/atom/target in targets)
|
||||
@@ -394,7 +386,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
|
||||
custom_handler?.before_cast(targets, user, src)
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/after_cast(list/targets, mob/user)
|
||||
/datum/spell/proc/after_cast(list/targets, mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
for(var/atom/target in targets)
|
||||
var/location
|
||||
@@ -427,21 +419,21 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
* * targets - The targets being targeted by the spell
|
||||
* * user - The caster of the spell
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/proc/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/proc/cast(list/targets, mob/user = usr)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/revert_cast(mob/user = usr) //resets recharge or readds a charge
|
||||
/datum/spell/proc/revert_cast(mob/user = usr) //resets recharge or readds a charge
|
||||
cooldown_handler.revert_cast()
|
||||
custom_handler?.revert_cast(user, src)
|
||||
|
||||
if(action)
|
||||
action.UpdateButtons()
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/UpdateButtons()
|
||||
/datum/spell/proc/UpdateButtons()
|
||||
if(action)
|
||||
action.UpdateButtons()
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/adjust_var(mob/living/target = usr, type, amount) //handles the adjustment of the var when the spell is used. has some hardcoded types
|
||||
/datum/spell/proc/adjust_var(mob/living/target = usr, type, amount) //handles the adjustment of the var when the spell is used. has some hardcoded types
|
||||
switch(type)
|
||||
if("bruteloss")
|
||||
target.adjustBruteLoss(amount)
|
||||
@@ -462,10 +454,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
return
|
||||
|
||||
///This proc is ran when a mind is transfered to a new mob. Tells it if the action should be transfered on return true, and tells it not to remove it on false
|
||||
/obj/effect/proc_holder/spell/proc/on_mind_transfer(mob/living/L)
|
||||
/datum/spell/proc/on_mind_transfer(mob/living/L)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe
|
||||
/datum/spell/aoe
|
||||
name = "Spell"
|
||||
create_attack_logs = FALSE
|
||||
create_custom_logs = TRUE
|
||||
@@ -474,10 +466,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
|
||||
// Normally, AoE spells will generate an attack log for every turf they loop over, while searching for targets.
|
||||
// With this override, all /aoe type spells will only generate 1 log, saying that the user has cast the spell.
|
||||
/obj/effect/proc_holder/spell/aoe/write_custom_logs(list/targets, mob/user)
|
||||
/datum/spell/aoe/write_custom_logs(list/targets, mob/user)
|
||||
add_attack_logs(user, null, "Cast the AoE spell [name]", ATKLOG_ALL)
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE)
|
||||
/datum/spell/proc/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE)
|
||||
if(((!user.mind) || !(src in user.mind.spell_list)) && !(src in user.mob_spell_list))
|
||||
if(show_message)
|
||||
to_chat(user, "<span class='warning'>You shouldn't have this spell! Something's wrong.</span>")
|
||||
@@ -509,8 +501,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/clothcheck = locate(/obj/effect/proc_holder/spell/noclothes) in user.mob_spell_list
|
||||
var/clothcheck2 = user.mind && (locate(/obj/effect/proc_holder/spell/noclothes) in user.mind.spell_list)
|
||||
var/clothcheck = locate(/datum/spell/noclothes) in user.mob_spell_list
|
||||
var/clothcheck2 = user.mind && (locate(/datum/spell/noclothes) in user.mind.spell_list)
|
||||
if(clothes_req && !clothcheck && !clothcheck2) //clothes check
|
||||
var/obj/item/clothing/robe = H.wear_suit
|
||||
var/obj/item/clothing/hat = H.head
|
||||
@@ -538,7 +530,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/summonmob
|
||||
/datum/spell/summonmob
|
||||
name = "Summon Servant"
|
||||
desc = "This spell can be used to call your servant, whenever you need it."
|
||||
base_cooldown = 10 SECONDS
|
||||
@@ -552,10 +544,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
|
||||
action_icon_state = "summons"
|
||||
|
||||
/obj/effect/proc_holder/spell/summonmob/create_new_targeting()
|
||||
/datum/spell/summonmob/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/summonmob/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/summonmob/cast(list/targets, mob/user = usr)
|
||||
if(!target_mob)
|
||||
return
|
||||
var/turf/Start = get_turf(user)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/// the time at which a spell charge can be used
|
||||
var/charge_time
|
||||
|
||||
/datum/spell_cooldown/charges/cooldown_init(obj/effect/proc_holder/spell/new_spell)
|
||||
/datum/spell_cooldown/charges/cooldown_init(datum/spell/new_spell)
|
||||
. = ..()
|
||||
if(starts_off_cooldown)
|
||||
current_charges = max_charges
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
/// does it start off cooldown?
|
||||
var/starts_off_cooldown = TRUE
|
||||
/// holds a ref to the spell
|
||||
var/obj/effect/proc_holder/spell/spell_parent
|
||||
var/datum/spell/spell_parent
|
||||
|
||||
/datum/spell_cooldown/Destroy()
|
||||
spell_parent = null
|
||||
return ..()
|
||||
|
||||
/datum/spell_cooldown/proc/cooldown_init(obj/effect/proc_holder/spell/new_spell)
|
||||
/datum/spell_cooldown/proc/cooldown_init(datum/spell/new_spell)
|
||||
spell_parent = new_spell
|
||||
if(!starts_off_cooldown)
|
||||
start_recharge()
|
||||
|
||||
@@ -8,24 +8,24 @@ This was also the case with the verb implementation, it's just much more obvious
|
||||
/// Amount of plasma required to use this ability
|
||||
var/plasma_cost = 0
|
||||
|
||||
/datum/spell_handler/alien/can_cast(mob/living/carbon/user, charge_check, show_message, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/alien/can_cast(mob/living/carbon/user, charge_check, show_message, datum/spell/spell)
|
||||
var/obj/item/organ/internal/alien/plasmavessel/vessel = user.get_int_organ(/obj/item/organ/internal/alien/plasmavessel)
|
||||
if(!vessel)
|
||||
return 0
|
||||
return FALSE
|
||||
if(vessel.stored_plasma < plasma_cost)
|
||||
if(show_message)
|
||||
to_chat(user, "<span class='warning'>You require at least [plasma_cost] plasma to use this ability!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/spell_handler/alien/spend_spell_cost(mob/living/carbon/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/alien/spend_spell_cost(mob/living/carbon/user, datum/spell/spell)
|
||||
user.use_plasma_spell(plasma_cost, user)
|
||||
|
||||
/datum/spell_handler/alien/before_cast(list/targets, mob/living/carbon/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/alien/before_cast(list/targets, mob/living/carbon/user, datum/spell/spell)
|
||||
to_chat(user, "<span class='boldnotice'>You have [user.get_plasma()] plasma left to use.</span>")
|
||||
user.update_plasma_display(user)
|
||||
|
||||
/datum/spell_handler/alien/revert_cast(mob/living/carbon/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/alien/revert_cast(mob/living/carbon/user, datum/spell/spell)
|
||||
user.add_plasma(plasma_cost, user)
|
||||
to_chat(user, "<span class='boldnotice'>You have [user.get_plasma()] plasma left to use.</span>")
|
||||
user.update_plasma_display(user)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/// How much food it costs the morph to use this
|
||||
var/hunger_cost = 0
|
||||
|
||||
/datum/spell_handler/morph/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/morph/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message, datum/spell/spell)
|
||||
if(!istype(user))
|
||||
if(show_message)
|
||||
to_chat(user, "<span class='warning'>You should not be able to use this abilty! Report this as a bug on github please.</span>")
|
||||
@@ -15,13 +15,13 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/spell_handler/morph/spend_spell_cost(mob/living/simple_animal/hostile/morph/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/morph/spend_spell_cost(mob/living/simple_animal/hostile/morph/user, datum/spell/spell)
|
||||
user.use_food(hunger_cost)
|
||||
|
||||
/datum/spell_handler/morph/before_cast(list/targets, mob/living/simple_animal/hostile/morph/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/morph/before_cast(list/targets, mob/living/simple_animal/hostile/morph/user, datum/spell/spell)
|
||||
if(hunger_cost)
|
||||
to_chat(user, "<span class='boldnotice'>You have [user.gathered_food] left to use.</span>")
|
||||
|
||||
/datum/spell_handler/morph/revert_cast(mob/living/simple_animal/hostile/morph/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/morph/revert_cast(mob/living/simple_animal/hostile/morph/user, datum/spell/spell)
|
||||
user.add_food(hunger_cost)
|
||||
to_chat(user, "<span class='boldnotice'>You have [user.gathered_food] left to use.</span>")
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
|
||||
/datum/spell_handler
|
||||
|
||||
/datum/spell_handler/proc/can_cast(mob/user, charge_check, show_message, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/proc/can_cast(mob/user, charge_check, show_message, datum/spell/spell)
|
||||
return TRUE
|
||||
|
||||
/datum/spell_handler/proc/spend_spell_cost(mob/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/proc/spend_spell_cost(mob/user, datum/spell/spell)
|
||||
return
|
||||
|
||||
/datum/spell_handler/proc/revert_cast(mob/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/proc/revert_cast(mob/user, datum/spell/spell)
|
||||
return
|
||||
|
||||
/datum/spell_handler/proc/before_cast(list/targets, mob/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/proc/before_cast(list/targets, mob/user, datum/spell/spell)
|
||||
return
|
||||
|
||||
/datum/spell_handler/proc/after_cast(list/targets, mob/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/proc/after_cast(list/targets, mob/user, datum/spell/spell)
|
||||
return
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// If the blood cost should be handled by this handler. Or if the spell will handle it itself
|
||||
var/deduct_blood_on_cast = TRUE
|
||||
|
||||
/datum/spell_handler/vampire/can_cast(mob/user, charge_check, show_message, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/vampire/can_cast(mob/user, charge_check, show_message, datum/spell/spell)
|
||||
var/datum/antagonist/vampire/vampire = user.mind.has_antag_datum(/datum/antagonist/vampire)
|
||||
|
||||
if(!vampire)
|
||||
@@ -31,7 +31,7 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/spell_handler/vampire/spend_spell_cost(mob/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/vampire/spend_spell_cost(mob/user, datum/spell/spell)
|
||||
if(!required_blood || !deduct_blood_on_cast) //don't take the blood yet if this is false!
|
||||
return
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
var/blood_cost = round(required_blood * blood_cost_modifier)
|
||||
return blood_cost
|
||||
|
||||
/datum/spell_handler/vampire/after_cast(list/targets, mob/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_handler/vampire/after_cast(list/targets, mob/user, datum/spell/spell)
|
||||
if(!spell.should_recharge_after_cast)
|
||||
return
|
||||
if(!required_blood)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/datum/spell_targeting/alive_mob_list
|
||||
allowed_type = /mob/living
|
||||
|
||||
/datum/spell_targeting/alive_mob_list/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/alive_mob_list/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
var/list/possible_targets = list()
|
||||
for(var/mob/living/possible_target as anything in GLOB.alive_mob_list)
|
||||
if(valid_target(possible_target, user, spell, FALSE))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/// The radius of turfs not being affected. -1 is inactive
|
||||
var/inner_radius = -1
|
||||
|
||||
/datum/spell_targeting/aoe/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/aoe/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
var/list/targets = list()
|
||||
var/spell_center = use_turf_of_user ? get_turf(user) : user
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
var/random_target_priority = SPELL_TARGET_CLOSEST
|
||||
|
||||
|
||||
/datum/spell_targeting/click/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/click/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
var/list/targets = list()
|
||||
if(valid_target(clicked_atom, user, spell))
|
||||
targets.Add(clicked_atom)
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
/datum/spell_targeting/clicked_atom
|
||||
use_intercept_click = TRUE
|
||||
|
||||
/datum/spell_targeting/clicked_atom/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/clicked_atom/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
if(clicked_atom)
|
||||
return list(clicked_atom)
|
||||
|
||||
/datum/spell_targeting/clicked_atom/external/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/clicked_atom/external/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return list()
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
/obj/item/bio_chip
|
||||
)
|
||||
|
||||
/datum/spell_targeting/matter_eater/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/matter_eater/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
var/list/possible_targets = list()
|
||||
|
||||
for(var/atom/movable/O in view_or_range(range, user, selection_type))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
/datum/spell_targeting/reachable_turfs
|
||||
|
||||
/datum/spell_targeting/reachable_turfs/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/reachable_turfs/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
var/list/turf/locs = list()
|
||||
for(var/direction in GLOB.alldirs)
|
||||
if(length(locs) == max_targets) //we found 2 locations and thats all we need
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
/datum/spell_targeting/remoteview
|
||||
|
||||
/datum/spell_targeting/remoteview/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/remoteview/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
var/list/remoteviewers = list()
|
||||
for(var/mob/M in GLOB.alive_mob_list)
|
||||
if(M == user)
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
*/
|
||||
/datum/spell_targeting/self
|
||||
|
||||
/datum/spell_targeting/self/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/self/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
return list(user) // That's how simple it is
|
||||
|
||||
@@ -34,14 +34,14 @@
|
||||
* * params - Params given by the intercept click. Only available if use_intercept_click is TRUE
|
||||
* * clicked_atom - The atom clicked on. Only available if use_intercept_click is TRUE
|
||||
*/
|
||||
/datum/spell_targeting/proc/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/proc/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
RETURN_TYPE(/list)
|
||||
return
|
||||
|
||||
/**
|
||||
* Will attempt to auto target the spell. Only works with 1 target currently
|
||||
*/
|
||||
/datum/spell_targeting/proc/attempt_auto_target(mob/user, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_targeting/proc/attempt_auto_target(mob/user, datum/spell/spell)
|
||||
var/atom/target
|
||||
for(var/atom/A in view_or_range(range, use_turf_of_user ? get_turf(user) : user, selection_type))
|
||||
if(valid_target(A, user, spell, FALSE))
|
||||
@@ -64,7 +64,7 @@
|
||||
* * A - Atom the user clicked on
|
||||
* * spell - The spell being cast
|
||||
*/
|
||||
/datum/spell_targeting/proc/InterceptClickOn(mob/user, params, atom/A, obj/effect/proc_holder/spell/spell)
|
||||
/datum/spell_targeting/proc/InterceptClickOn(mob/user, params, atom/A, datum/spell/spell)
|
||||
var/list/targets = choose_targets(user, spell, params, A)
|
||||
spell.try_perform(targets, user)
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
* * spell - The spell being cast
|
||||
* * check_if_in_range - If a view/range check has to be done to see if the target is valid
|
||||
*/
|
||||
/datum/spell_targeting/proc/valid_target(target, user, obj/effect/proc_holder/spell/spell, check_if_in_range = TRUE)
|
||||
/datum/spell_targeting/proc/valid_target(target, user, datum/spell/spell, check_if_in_range = TRUE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
return istype(target, allowed_type) && (include_user || target != user) && \
|
||||
spell.valid_target(target, user) && (!check_if_in_range || (target in view_or_range(range, use_turf_of_user ? get_turf(user) : user, selection_type))) \
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/// Who to target when too many targets are found. Only matters when max_targets = 1
|
||||
var/target_priority = SPELL_TARGET_CLOSEST
|
||||
|
||||
/datum/spell_targeting/targeted/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/targeted/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
var/list/targets = list()
|
||||
var/list/possible_targets = list()
|
||||
var/atom/spell_location = use_turf_of_user ? get_turf(user) : user
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
/datum/spell_targeting/telepathic
|
||||
|
||||
/datum/spell_targeting/telepathic/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom)
|
||||
/datum/spell_targeting/telepathic/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom)
|
||||
var/list/valid_targets = list()
|
||||
var/turf/T = get_turf(user)
|
||||
var/list/mobs_in_view = user.get_visible_mobs()
|
||||
|
||||
@@ -17,7 +17,7 @@ Updates the spell's actions on use as well, so they know when they can or can't
|
||||
for(var/datum/action/spell_action/action in actions)
|
||||
action.UpdateButtons()
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell
|
||||
/datum/spell/alien_spell
|
||||
action_background_icon_state = "bg_alien"
|
||||
clothes_req = FALSE
|
||||
base_cooldown = 0
|
||||
@@ -28,15 +28,15 @@ Updates the spell's actions on use as well, so they know when they can or can't
|
||||
var/plasma_cost = 0
|
||||
|
||||
/// Every single alien spell uses a "spell name + plasmacost" format
|
||||
/obj/effect/proc_holder/spell/alien_spell/Initialize(mapload)
|
||||
. = ..()
|
||||
/datum/spell/alien_spell/New()
|
||||
..()
|
||||
if(plasma_cost)
|
||||
name = "[name] ([plasma_cost])"
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/write_custom_logs(list/targets, mob/user)
|
||||
/datum/spell/alien_spell/write_custom_logs(list/targets, mob/user)
|
||||
user.create_log(ATTACK_LOG, "Cast the spell [name]")
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/create_new_handler()
|
||||
/datum/spell/alien_spell/create_new_handler()
|
||||
var/datum/spell_handler/alien/handler = new
|
||||
handler.plasma_cost = plasma_cost
|
||||
return handler
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/touch/alien_spell
|
||||
/datum/spell/touch/alien_spell
|
||||
name = "Basetype Alien spell"
|
||||
desc = "You should not see this in game, if you do file a github report!"
|
||||
hand_path = "/obj/item/melee/touch_attack/alien"
|
||||
@@ -15,20 +15,20 @@
|
||||
var/plasma_cost = 0
|
||||
action_icon_state = "gib"
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/alien_spell/Initialize(mapload)
|
||||
. = ..()
|
||||
/datum/spell/touch/alien_spell/New()
|
||||
..()
|
||||
if(plasma_cost)
|
||||
name = "[name] ([plasma_cost])"
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/alien_spell/Click(mob/user = usr)
|
||||
/datum/spell/touch/alien_spell/Click(mob/user = usr)
|
||||
if(attached_hand)
|
||||
to_chat(user, "<span class='noticealien'>You withdraw your [src].</span>")
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/alien_spell/write_custom_logs(list/targets, mob/user)
|
||||
/datum/spell/touch/alien_spell/write_custom_logs(list/targets, mob/user)
|
||||
user.create_log(ATTACK_LOG, "Cast the spell [name]")
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/alien_spell/create_new_handler()
|
||||
/datum/spell/touch/alien_spell/create_new_handler()
|
||||
var/datum/spell_handler/alien/H = new
|
||||
H.plasma_cost = plasma_cost
|
||||
return H
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/obj/effect/proc_holder/spell/alien_spell/build_resin
|
||||
/datum/spell/alien_spell/build_resin
|
||||
name = "Build Resin Structure"
|
||||
desc = "Allows you to create resin structures. Does not work while in space."
|
||||
plasma_cost = 55
|
||||
action_icon_state = "alien_resin"
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/build_resin/create_new_targeting()
|
||||
/datum/spell/alien_spell/build_resin/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/build_resin/cast(list/targets, mob/living/carbon/user)
|
||||
var/static/list/resin_buildings = list("Resin Wall" = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"),
|
||||
"Resin Nest" = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"),
|
||||
"Resin Door" = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin"),
|
||||
/datum/spell/alien_spell/build_resin/cast(list/targets, mob/living/carbon/user)
|
||||
var/static/list/resin_buildings = list("Resin Wall (55)" = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"),
|
||||
"Resin Nest (55)" = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"),
|
||||
"Resin door (80)" = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin"),
|
||||
"Revival Nest" = image(icon = 'icons/mob/alien.dmi', icon_state = "placeholder_rejuv_nest"))
|
||||
var/choice = show_radial_menu(user, user, resin_buildings, src, radius = 40)
|
||||
var/turf/turf_to_spawn_at = user.loc
|
||||
@@ -29,7 +29,7 @@
|
||||
to_chat(user, "<span class='danger'>There is already a resin construction here.</span>")
|
||||
revert_cast(user)
|
||||
return
|
||||
visible_message("<span class='alertalien'>[user] vomits up a thick purple substance and shapes it!</span>")
|
||||
user.visible_message("<span class='alertalien'>[user] vomits up a thick purple substance and shapes it!</span>")
|
||||
switch(choice)
|
||||
if("Resin Wall")
|
||||
new /obj/structure/alien/resin/wall(turf_to_spawn_at)
|
||||
@@ -40,7 +40,7 @@
|
||||
if("Revival Nest")
|
||||
new /obj/structure/bed/revival_nest(turf_to_spawn_at)
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/alien_spell/consume_resin
|
||||
/datum/spell/touch/alien_spell/consume_resin
|
||||
name = "Consume resin structures"
|
||||
desc = "Allows you to rip and tear straight through resin structures."
|
||||
action_icon_state = "alien_resin"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/touch/alien_spell/corrosive_acid
|
||||
/datum/spell/touch/alien_spell/corrosive_acid
|
||||
name = "Corrosive acid"
|
||||
desc = "Spit acid on someone in range, this acid melts through nearly anything and heavily damages anyone lacking proper safety equipment."
|
||||
hand_path = "/obj/item/melee/touch_attack/alien/corrosive_acid"
|
||||
@@ -32,7 +32,7 @@
|
||||
to_chat(user, "<span class='noticealien'>You cannot dissolve this object.</span>")
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/alien_spell/burning_touch
|
||||
/datum/spell/touch/alien_spell/burning_touch
|
||||
name = "Blazing touch"
|
||||
desc = "Boil acid within your hand to burn through anything you touch with it, deals a lot of damage to aliens and destroys resin structures instantly."
|
||||
hand_path = "/obj/item/melee/touch_attack/alien/burning_touch"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Make this reflect amount grown, can't do that currently
|
||||
/obj/effect/proc_holder/spell/alien_spell/evolve_larva
|
||||
/datum/spell/alien_spell/evolve_larva
|
||||
name = "Evolve."
|
||||
desc = "Evolve into a fully grown Alien."
|
||||
action_icon_state = "alien_evolve_larva"
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/evolve_larva/create_new_targeting()
|
||||
/datum/spell/alien_spell/evolve_larva/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/evolve_larva/cast(list/targets, mob/living/carbon/alien/larva/user)
|
||||
/datum/spell/alien_spell/evolve_larva/cast(list/targets, mob/living/carbon/alien/larva/user)
|
||||
if(user.stat != CONSCIOUS)
|
||||
return
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/alien_spell/plant_weeds/eggs
|
||||
/datum/spell/alien_spell/plant_weeds/eggs
|
||||
name = "Plant alien eggs"
|
||||
desc = "Allows you to plant alien eggs on your current turf, does not work while in space."
|
||||
plasma_cost = 75
|
||||
@@ -7,17 +7,17 @@
|
||||
action_icon_state = "alien_egg"
|
||||
requires_do_after = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers
|
||||
/datum/spell/alien_spell/combust_facehuggers
|
||||
name = "Combust facehuggers and eggs"
|
||||
desc = "Take over the programming of facehuggers and eggs, sending out a shockwave which causes them to combust."
|
||||
plasma_cost = 25
|
||||
action_icon_state = "alien_egg"
|
||||
base_cooldown = 3 SECONDS
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/create_new_targeting()
|
||||
/datum/spell/alien_spell/combust_facehuggers/create_new_targeting()
|
||||
return new /datum/spell_targeting/clicked_atom
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/cast(list/targets, mob/living/carbon/user)
|
||||
/datum/spell/alien_spell/combust_facehuggers/cast(list/targets, mob/living/carbon/user)
|
||||
var/obj/target = targets[1]
|
||||
var/turf/T = user.loc
|
||||
if(!istype(T) || !istype(target))
|
||||
@@ -33,7 +33,7 @@
|
||||
to_chat(user, "<span class='noticealien'>[target] will explode in 3 seconds!</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/proc/blow_it_up(obj/target, mob/user)
|
||||
/datum/spell/alien_spell/combust_facehuggers/proc/blow_it_up(obj/target, mob/user)
|
||||
add_attack_logs(user, target, "Caused it to explode")
|
||||
explosion(get_turf(target), 0, 2, 3, 3, cause = user)
|
||||
to_chat(user, "<span class='noticealien'>[target] has detonated!</span>")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/alien_spell/neurotoxin
|
||||
/datum/spell/alien_spell/neurotoxin
|
||||
name = "Neurotoxin spit"
|
||||
desc = "This ability allows you to fire some neurotoxin. Knocks down anyone you hit, applies a small amount of stamina damage as well."
|
||||
base_cooldown = 3 SECONDS
|
||||
@@ -9,16 +9,16 @@
|
||||
action_icon_state = "alien_neurotoxin_0"
|
||||
active = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/neurotoxin/create_new_targeting()
|
||||
/datum/spell/alien_spell/neurotoxin/create_new_targeting()
|
||||
return new /datum/spell_targeting/clicked_atom
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/neurotoxin/update_icon_state()
|
||||
/datum/spell/alien_spell/neurotoxin/update_spell_icon()
|
||||
if(!action)
|
||||
return
|
||||
action.button_icon_state = "alien_neurotoxin_[active]"
|
||||
action.UpdateButtons()
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/neurotoxin/cast(list/targets, mob/living/carbon/user)
|
||||
/datum/spell/alien_spell/neurotoxin/cast(list/targets, mob/living/carbon/user)
|
||||
var/target = targets[1]
|
||||
var/turf/T = user.loc
|
||||
var/turf/U = get_step(user, user.dir) // A little aimbot is fine
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/neurotoxin/death_to_xenos
|
||||
/datum/spell/alien_spell/neurotoxin/death_to_xenos
|
||||
name = "Neurotoxin spit"
|
||||
desc = "This ability allows you to fire some neurotoxin. Knocks aliens down."
|
||||
neurotoxin_type = /obj/item/projectile/bullet/anti_alien_toxin
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/alien_spell/plant_weeds
|
||||
/datum/spell/alien_spell/plant_weeds
|
||||
name = "Plant weeds"
|
||||
desc = "Allows you to plant some alien weeds on the floor below you. Does not work while in space."
|
||||
plasma_cost = 50
|
||||
@@ -7,10 +7,10 @@
|
||||
action_icon_state = "alien_plant"
|
||||
var/requires_do_after = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/plant_weeds/create_new_targeting()
|
||||
/datum/spell/alien_spell/plant_weeds/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/plant_weeds/cast(list/targets, mob/living/carbon/user)
|
||||
/datum/spell/alien_spell/plant_weeds/cast(list/targets, mob/living/carbon/user)
|
||||
var/turf/T = user.loc
|
||||
if(locate(weed_type) in T)
|
||||
to_chat(user, "<span class='noticealien'>There's already \a [weed_name] here.</span>")
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/obj/effect/proc_holder/spell/alien_spell/evolve_queen
|
||||
/datum/spell/alien_spell/evolve_queen
|
||||
name = "Evolve into an alien queen"
|
||||
desc = "Evolve into an alien queen."
|
||||
plasma_cost = 300
|
||||
action_icon_state = "alien_evolve_drone"
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/evolve_queen/create_new_targeting()
|
||||
/datum/spell/alien_spell/evolve_queen/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/evolve_queen/cast(list/targets, mob/living/carbon/user)
|
||||
/datum/spell/alien_spell/evolve_queen/cast(list/targets, mob/living/carbon/user)
|
||||
/// First we check if there is a living queen
|
||||
for(var/mob/living/carbon/alien/humanoid/queen/living_queen in GLOB.alive_mob_list)
|
||||
if(living_queen.key || !living_queen.get_int_organ(/obj/item/organ/internal/brain)) // We do a once over to check the queen didn't end up going away into the magic land of semi-dead
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/obj/effect/proc_holder/spell/alien_spell/regurgitate
|
||||
/datum/spell/alien_spell/regurgitate
|
||||
name = "Regurgitate"
|
||||
desc = "Empties the contents of your stomach onto the ground."
|
||||
action_icon_state = "alien_barf"
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/regurgitate/create_new_targeting()
|
||||
/datum/spell/alien_spell/regurgitate/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/regurgitate/cast(list/targets, mob/living/carbon/user)
|
||||
/datum/spell/alien_spell/regurgitate/cast(list/targets, mob/living/carbon/user)
|
||||
for(var/mob/M in user.stomach_contents)
|
||||
var/turf/output_loc = user.loc
|
||||
if(!istype(output_loc))
|
||||
return
|
||||
user.stomach_contents -= M
|
||||
M.forceMove(output_loc)
|
||||
visible_message("<span class='alertalien'><B>[user] hurls out the contents of [p_their()] stomach!</span>")
|
||||
user.visible_message("<span class='alertalien'><b>[user] hurls out the contents of [p_their()] stomach!</b></span>")
|
||||
return
|
||||
visible_message("<span class='alertalien'><B>[user] dry heaves!</span>")
|
||||
user.visible_message("<span class='alertalien'><b>[user] dry heaves!</b></span>")
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/obj/effect/proc_holder/spell/alien_spell/tail_lash
|
||||
/datum/spell/alien_spell/tail_lash
|
||||
name = "Tail lash"
|
||||
desc = "Knocks down anyone around you."
|
||||
action_icon_state = "tailsweep"
|
||||
base_cooldown = 10 SECONDS
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/tail_lash/create_new_targeting()
|
||||
/datum/spell/alien_spell/tail_lash/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/tail_lash/cast(list/targets, mob/user)
|
||||
/datum/spell/alien_spell/tail_lash/cast(list/targets, mob/user)
|
||||
var/turf/T = user.loc
|
||||
var/cast_resolved = FALSE
|
||||
if(!istype(T))
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/obj/effect/proc_holder/spell/alien_spell/transfer_plasma
|
||||
/datum/spell/alien_spell/transfer_plasma
|
||||
name = "Transfer Plasma"
|
||||
desc = "Transfers 50 plasma to a nearby alien"
|
||||
action_icon_state = "alien_transfer"
|
||||
plasma_cost = 50
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/transfer_plasma/create_new_targeting()
|
||||
/datum/spell/alien_spell/transfer_plasma/create_new_targeting()
|
||||
return new /datum/spell_targeting/clicked_atom
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/transfer_plasma/cast(list/targets, mob/living/carbon/user)
|
||||
/datum/spell/alien_spell/transfer_plasma/cast(list/targets, mob/living/carbon/user)
|
||||
var/mob/living/carbon/alien/target = targets[1]
|
||||
var/turf/T = user.loc
|
||||
if(!istype(T) || !istype(target))
|
||||
@@ -20,17 +20,17 @@
|
||||
to_chat(target, "<span class='noticealien'>[user] has transfered 50 plasma to you!</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/syphon_plasma
|
||||
/datum/spell/alien_spell/syphon_plasma
|
||||
name = "Syphon plasma"
|
||||
desc = "Syphons 150 plasma from a nearby alien."
|
||||
action_icon_state = "alien_transfer"
|
||||
plasma_cost = 0
|
||||
base_cooldown = 10 SECONDS
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/syphon_plasma/create_new_targeting()
|
||||
/datum/spell/alien_spell/syphon_plasma/create_new_targeting()
|
||||
return new /datum/spell_targeting/clicked_atom
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/syphon_plasma/cast(list/targets, mob/living/carbon/user)
|
||||
/datum/spell/alien_spell/syphon_plasma/cast(list/targets, mob/living/carbon/user)
|
||||
var/mob/living/carbon/alien/target = targets[1]
|
||||
var/turf/T = user.loc
|
||||
if(!istype(T) || !istype(target))
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/obj/effect/proc_holder/spell/alien_spell/whisper
|
||||
/datum/spell/alien_spell/whisper
|
||||
name = "Whisper"
|
||||
desc = "Whisper into a target's mind."
|
||||
plasma_cost = 10
|
||||
action_icon_state = "alien_whisper"
|
||||
var/target
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/whisper/create_new_targeting() // Yeah this is copy and pasted code from cryoken and it's good enough
|
||||
/datum/spell/alien_spell/whisper/create_new_targeting() // Yeah this is copy and pasted code from cryoken and it's good enough
|
||||
var/datum/spell_targeting/click/T = new()
|
||||
T.allowed_type = /mob/living
|
||||
T.click_radius = 0
|
||||
@@ -14,7 +14,7 @@
|
||||
T.include_user = TRUE
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/alien_spell/whisper/cast(list/targets, mob/living/carbon/user)
|
||||
/datum/spell/alien_spell/whisper/cast(list/targets, mob/living/carbon/user)
|
||||
var/mob/living/target = targets[1]
|
||||
|
||||
var/msg = tgui_input_text(user, "Message:", "Alien Whisper")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/area_teleport
|
||||
/datum/spell/area_teleport
|
||||
nonabstract_req = TRUE
|
||||
|
||||
var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list
|
||||
@@ -8,7 +8,7 @@
|
||||
var/sound2 = 'sound/weapons/zapbang.ogg'
|
||||
var/area/selected_area
|
||||
|
||||
/obj/effect/proc_holder/spell/area_teleport/before_cast(list/targets, mob/user)
|
||||
/datum/spell/area_teleport/before_cast(list/targets, mob/user)
|
||||
..()
|
||||
selected_area = null // Reset it
|
||||
var/area_name
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
selected_area = thearea
|
||||
|
||||
/obj/effect/proc_holder/spell/area_teleport/cast(list/targets, mob/living/user)
|
||||
/datum/spell/area_teleport/cast(list/targets, mob/living/user)
|
||||
if(!selected_area)
|
||||
revert_cast(user)
|
||||
return
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/area_teleport/invocation(mob/user)
|
||||
/datum/spell/area_teleport/invocation(mob/user)
|
||||
if(!invocation_area || !selected_area)
|
||||
return
|
||||
switch(invocation_type)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/touch/banana
|
||||
/datum/spell/touch/banana
|
||||
name = "Banana Touch"
|
||||
desc = "A spell popular at wizard birthday parties, this spell will put on a clown costume on the target, \
|
||||
stun them with a loud HONK, and mutate them to make them more entertaining! \
|
||||
@@ -19,7 +19,7 @@
|
||||
icon_state = "banana_touch"
|
||||
item_state = "banana_touch"
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/banana/apprentice
|
||||
/datum/spell/touch/banana/apprentice
|
||||
hand_path = /obj/item/melee/touch_attack/banana/apprentice
|
||||
|
||||
/obj/item/melee/touch_attack/banana/apprentice
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/bloodcrawl
|
||||
/datum/spell/bloodcrawl
|
||||
name = "Blood Crawl"
|
||||
desc = "Use pools of blood to phase out of existence."
|
||||
base_cooldown = 1 SECONDS
|
||||
@@ -12,7 +12,7 @@
|
||||
var/allowed_type = /obj/effect/decal/cleanable
|
||||
var/phased = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/create_new_targeting()
|
||||
/datum/spell/bloodcrawl/create_new_targeting()
|
||||
var/datum/spell_targeting/targeted/T = new()
|
||||
T.selection_type = SPELL_SELECTION_RANGE
|
||||
T.allowed_type = allowed_type
|
||||
@@ -21,17 +21,17 @@
|
||||
T.use_turf_of_user = TRUE
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/valid_target(obj/effect/decal/cleanable/target, user)
|
||||
/datum/spell/bloodcrawl/valid_target(obj/effect/decal/cleanable/target, user)
|
||||
return target.can_bloodcrawl_in()
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/can_cast(mob/living/user, charge_check, show_message)
|
||||
/datum/spell/bloodcrawl/can_cast(mob/living/user, charge_check, show_message)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!isliving(user))
|
||||
return FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/cast(list/targets, mob/living/user)
|
||||
/datum/spell/bloodcrawl/cast(list/targets, mob/living/user)
|
||||
var/atom/target = targets[1]
|
||||
if(!phased)
|
||||
if(phaseout(target, user))
|
||||
@@ -78,7 +78,7 @@
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/block_hands(mob/living/carbon/C)
|
||||
/datum/spell/bloodcrawl/proc/block_hands(mob/living/carbon/C)
|
||||
if(C.l_hand || C.r_hand)
|
||||
to_chat(C, "<span class='warning'>You may not hold items while blood crawling!</span>")
|
||||
return FALSE
|
||||
@@ -101,13 +101,13 @@
|
||||
. = ..()
|
||||
flick(animation_state, src) // Setting the icon_state to the animation has timing issues and can cause frame skips
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/sink_animation(atom/A, mob/living/L)
|
||||
/datum/spell/bloodcrawl/proc/sink_animation(atom/A, mob/living/L)
|
||||
var/turf/mob_loc = get_turf(L)
|
||||
visible_message("<span class='danger'>[L] sinks into [A].</span>")
|
||||
playsound(mob_loc, 'sound/misc/enter_blood.ogg', 100, 1, -1)
|
||||
mob_loc.visible_message("<span class='danger'>[L] sinks into [A].</span>")
|
||||
playsound(mob_loc, 'sound/misc/enter_blood.ogg', 100, TRUE, -1)
|
||||
new /obj/effect/temp_visual/dir_setting/bloodcrawl(mob_loc, L.dir, "jaunt")
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder)
|
||||
/datum/spell/bloodcrawl/proc/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder)
|
||||
if(!HAS_TRAIT(L, TRAIT_BLOODCRAWL_EAT))
|
||||
return
|
||||
|
||||
@@ -176,10 +176,10 @@
|
||||
victim.ghostize()
|
||||
qdel(victim)
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder)
|
||||
/datum/spell/bloodcrawl/proc/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder)
|
||||
L.notransform = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/phaseout(obj/effect/decal/cleanable/B, mob/living/L)
|
||||
/datum/spell/bloodcrawl/proc/phaseout(obj/effect/decal/cleanable/B, mob/living/L)
|
||||
|
||||
if(iscarbon(L) && !block_hands(L))
|
||||
return FALSE
|
||||
@@ -187,7 +187,7 @@
|
||||
INVOKE_ASYNC(src, PROC_REF(async_phase), B, L)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/async_phase(obj/effect/decal/cleanable/B, mob/living/L)
|
||||
/datum/spell/bloodcrawl/proc/async_phase(obj/effect/decal/cleanable/B, mob/living/L)
|
||||
var/turf/mobloc = get_turf(L)
|
||||
sink_animation(B, L)
|
||||
var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(mobloc)
|
||||
@@ -196,24 +196,24 @@
|
||||
handle_consumption(L, L.pulling, B, holder)
|
||||
post_phase_in(L, holder)
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/rise_animation(turf/tele_loc, mob/living/L, atom/A)
|
||||
/datum/spell/bloodcrawl/proc/rise_animation(turf/tele_loc, mob/living/L, atom/A)
|
||||
new /obj/effect/temp_visual/dir_setting/bloodcrawl(tele_loc, L.dir, "jauntup")
|
||||
if(prob(25) && isdemon(L))
|
||||
var/list/voice = list('sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/i_see_you1.ogg')
|
||||
playsound(tele_loc, pick(voice),50, 1, -1)
|
||||
A.visible_message("<span class='warning'><b>[L] rises out of [A]!</b>")
|
||||
playsound(get_turf(tele_loc), 'sound/misc/exit_blood.ogg', 100, 1, -1)
|
||||
playsound(tele_loc, pick(voice),50, TRUE, -1)
|
||||
A.visible_message("<span class='warning'><b>[L] rises out of [A]!</b></span>")
|
||||
playsound(get_turf(tele_loc), 'sound/misc/exit_blood.ogg', 100, TRUE, -1)
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/unblock_hands(mob/living/carbon/C)
|
||||
/datum/spell/bloodcrawl/proc/unblock_hands(mob/living/carbon/C)
|
||||
if(!istype(C))
|
||||
return
|
||||
for(var/obj/item/bloodcrawl/BC in C)
|
||||
qdel(BC)
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/rise_message(atom/A)
|
||||
/datum/spell/bloodcrawl/proc/rise_message(atom/A)
|
||||
A.visible_message("<span class='warning'>[A] starts to bubble...</span>")
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/post_phase_out(atom/A, mob/living/L)
|
||||
/datum/spell/bloodcrawl/proc/post_phase_out(atom/A, mob/living/L)
|
||||
if(isslaughterdemon(L))
|
||||
var/mob/living/simple_animal/demon/slaughter/S = L
|
||||
S.speed = 0
|
||||
@@ -222,7 +222,7 @@
|
||||
addtimer(VARSET_CALLBACK(L, color, null), 6 SECONDS)
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/proc/phasein(atom/A, mob/living/L)
|
||||
/datum/spell/bloodcrawl/proc/phasein(atom/A, mob/living/L)
|
||||
|
||||
if(L.notransform)
|
||||
to_chat(L, "<span class='warning'>Finish eating first!</span>")
|
||||
@@ -246,30 +246,30 @@
|
||||
post_phase_out(A, L)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl
|
||||
/datum/spell/bloodcrawl/shadow_crawl
|
||||
name = "Shadow Crawl"
|
||||
desc = "Fade into the shadows, increasing your speed and making you incomprehensible. Will not work in brightened terrane."
|
||||
allowed_type = /turf
|
||||
action_background_icon_state = "shadow_demon_bg"
|
||||
action_icon_state = "shadow_crawl"
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/valid_target(turf/target, user)
|
||||
/datum/spell/bloodcrawl/shadow_crawl/valid_target(turf/target, user)
|
||||
return target.get_lumcount() < 0.2
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/rise_message(atom/A)
|
||||
/datum/spell/bloodcrawl/shadow_crawl/rise_message(atom/A)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/rise_animation(turf/tele_loc, mob/living/L, atom/A)
|
||||
/datum/spell/bloodcrawl/shadow_crawl/rise_animation(turf/tele_loc, mob/living/L, atom/A)
|
||||
new /obj/effect/temp_visual/dir_setting/bloodcrawl(get_turf(L), L.dir, "shadowwalk_appear")
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder)
|
||||
/datum/spell/bloodcrawl/shadow_crawl/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/sink_animation(atom/A, mob/living/L)
|
||||
/datum/spell/bloodcrawl/shadow_crawl/sink_animation(atom/A, mob/living/L)
|
||||
A.visible_message("<span class='danger'>[L] sinks into the shadows...</span>")
|
||||
new /obj/effect/temp_visual/dir_setting/bloodcrawl(get_turf(L), L.dir, "shadowwalk_disappear")
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder)
|
||||
/datum/spell/bloodcrawl/shadow_crawl/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder)
|
||||
..()
|
||||
if(!istype(L, /mob/living/simple_animal/demon/shadow))
|
||||
return
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/chaplain_bless
|
||||
/datum/spell/chaplain_bless
|
||||
name = "Bless"
|
||||
desc = "Blesses a single person."
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
cooldown_min = 20
|
||||
action_icon_state = "shield"
|
||||
|
||||
/obj/effect/proc_holder/spell/chaplain_bless/create_new_targeting()
|
||||
/datum/spell/chaplain_bless/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new()
|
||||
T.range = 1
|
||||
T.click_radius = -1
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/chaplain_bless/valid_target(mob/living/carbon/human/target, mob/user)
|
||||
/datum/spell/chaplain_bless/valid_target(mob/living/carbon/human/target, mob/user)
|
||||
return target.mind && target.ckey && !target.stat
|
||||
|
||||
/obj/effect/proc_holder/spell/chaplain_bless/cast(list/targets, mob/living/user = usr)
|
||||
/datum/spell/chaplain_bless/cast(list/targets, mob/living/user = usr)
|
||||
if(!istype(user))
|
||||
to_chat(user, "Somehow, you are not a living mob. This should never happen. Report this bug.")
|
||||
revert_cast()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/charge
|
||||
/datum/spell/charge
|
||||
name = "Charge"
|
||||
desc = "This spell can be used to recharge a variety of things in your hands, from magical artifacts to electrical components. A creative wizard can even use it to grant magical power to a fellow magic user."
|
||||
school = "transmutation"
|
||||
@@ -9,10 +9,10 @@
|
||||
cooldown_min = 400 //50 deciseconds reduction per rank
|
||||
action_icon_state = "charge"
|
||||
|
||||
/obj/effect/proc_holder/spell/charge/create_new_targeting()
|
||||
/datum/spell/charge/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/charge/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/charge/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/L in targets)
|
||||
var/list/hand_items = list(L.get_active_hand(),L.get_inactive_hand())
|
||||
var/charged_item = null
|
||||
@@ -21,10 +21,10 @@
|
||||
if(L.pulling && (isliving(L.pulling)))
|
||||
var/mob/living/M = L.pulling
|
||||
if(M.mob_spell_list.len != 0 || (M.mind && M.mind.spell_list.len != 0))
|
||||
for(var/obj/effect/proc_holder/spell/S in M.mob_spell_list)
|
||||
for(var/datum/spell/S in M.mob_spell_list)
|
||||
S.cooldown_handler.revert_cast()
|
||||
if(M.mind)
|
||||
for(var/obj/effect/proc_holder/spell/S in M.mind.spell_list)
|
||||
for(var/datum/spell/S in M.mind.spell_list)
|
||||
S.cooldown_handler.revert_cast()
|
||||
to_chat(M, "<span class='notice'>You feel raw magical energy flowing through you, it feels good!</span>")
|
||||
else
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* A click-based spell template which starts charging up once you click the action button/verb. Click again on something to activate the actual spell
|
||||
*/
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up
|
||||
/datum/spell/charge_up
|
||||
var/start_time = 0
|
||||
/// The overlay used to show that you are charging. Create this in the New of the spell
|
||||
var/image/charge_up_overlay
|
||||
@@ -17,13 +17,13 @@
|
||||
/// The text shown when you are over the charge limit and thus can't stop.
|
||||
var/stop_charging_fail_text
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/create_new_targeting()
|
||||
/datum/spell/charge_up/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new()
|
||||
T.allowed_type = /mob/living
|
||||
T.try_auto_target = FALSE
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/Click()
|
||||
/datum/spell/charge_up/Click()
|
||||
if(cast_check(TRUE, FALSE, usr))
|
||||
if(!start_time)
|
||||
INVOKE_ASYNC(src, PROC_REF(StartChargeup), usr)
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/proc/try_stop_buildup(mob/user)
|
||||
/datum/spell/charge_up/proc/try_stop_buildup(mob/user)
|
||||
var/energy_perc = get_energy_charge() / max_charge_time
|
||||
if(energy_perc < 0.5)
|
||||
cooldown_handler.start_recharge((1 - energy_perc) * cooldown_handler.recharge_duration) // Shorten the cooldown based on how long it was charged for.
|
||||
@@ -44,10 +44,10 @@
|
||||
to_chat(user, "<span class='danger'>[stop_charging_fail_text]</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/proc/get_energy_charge()
|
||||
/datum/spell/charge_up/proc/get_energy_charge()
|
||||
return min(world.time - start_time, max_charge_time)
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/proc/StartChargeup(mob/user)
|
||||
/datum/spell/charge_up/proc/StartChargeup(mob/user)
|
||||
to_chat(user, "<span class='notice'>[start_charging_text]</span>")
|
||||
user.add_overlay(charge_up_overlay)
|
||||
playsound(user, charge_sound, 50, FALSE, channel = charge_sound.channel)
|
||||
@@ -56,25 +56,25 @@
|
||||
if(start_time)
|
||||
Discharge(user)
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/proc/stopped_casting()
|
||||
/datum/spell/charge_up/proc/stopped_casting()
|
||||
return start_time == 0
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/proc/Reset(mob/user)
|
||||
/datum/spell/charge_up/proc/Reset(mob/user)
|
||||
start_time = 0
|
||||
user.cut_overlay(charge_up_overlay)
|
||||
remove_ranged_ability(user)
|
||||
playsound(user, null, 50, FALSE, channel = charge_sound.channel)
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/revert_cast(mob/user)
|
||||
/datum/spell/charge_up/revert_cast(mob/user)
|
||||
Reset(user)
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/proc/Discharge(mob/user)
|
||||
/datum/spell/charge_up/proc/Discharge(mob/user)
|
||||
to_chat(user, "<span class='danger'>You lose control over the spell!</span>")
|
||||
Reset(user)
|
||||
spend_spell_cost(user)
|
||||
cooldown_handler.start_recharge()
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/after_cast(list/targets, mob/user)
|
||||
/datum/spell/charge_up/after_cast(list/targets, mob/user)
|
||||
..()
|
||||
Reset(user)
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
* A spell template that adds bounces to the charge_up spell template. The spell will bounce between targets once released.
|
||||
* Don't override cast and instead override apply_bounce_effect and the other procs
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce
|
||||
/datum/spell/charge_up/bounce
|
||||
var/bounce_hit_sound
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/create_new_targeting()
|
||||
/datum/spell/charge_up/bounce/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new
|
||||
T.allowed_type = /mob/living
|
||||
T.try_auto_target = FALSE
|
||||
T.use_obstacle_check = TRUE
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/charge_up/bounce/cast(list/targets, mob/user = usr)
|
||||
var/mob/living/target = targets[1]
|
||||
|
||||
bounce(user, target, get_bounce_energy(), get_bounce_amount(), user)
|
||||
@@ -20,13 +20,13 @@
|
||||
/**
|
||||
* How much energy should each bounce have?
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/proc/get_bounce_energy()
|
||||
/datum/spell/charge_up/bounce/proc/get_bounce_energy()
|
||||
return
|
||||
|
||||
/**
|
||||
* How much bounces should there be in total?
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/proc/get_bounce_amount()
|
||||
/datum/spell/charge_up/bounce/proc/get_bounce_amount()
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -36,7 +36,7 @@
|
||||
* * origin - Where the bounce came from
|
||||
* * target - The mob that got hit
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/proc/create_beam(mob/origin, mob/target)
|
||||
/datum/spell/charge_up/bounce/proc/create_beam(mob/origin, mob/target)
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -49,10 +49,10 @@
|
||||
* * energy - How much energy the bounce has
|
||||
* * user - The caster of the spell
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/proc/apply_bounce_effect(mob/origin, mob/target, energy, mob/user)
|
||||
/datum/spell/charge_up/bounce/proc/apply_bounce_effect(mob/origin, mob/target, energy, mob/user)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/proc/bounce(mob/origin, mob/target, energy, bounces, mob/user)
|
||||
/datum/spell/charge_up/bounce/proc/bounce(mob/origin, mob/target, energy, bounces, mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
create_beam(origin, target)
|
||||
apply_bounce_effect(origin, target, energy, user)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/touch/cluwne
|
||||
/datum/spell/touch/cluwne
|
||||
name = "Curse of the Cluwne"
|
||||
desc = "Turns the target into a fat and cursed monstrosity of a clown."
|
||||
hand_path = /obj/item/melee/touch_attack/cluwne
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/aoe/conjure
|
||||
/datum/spell/aoe/conjure
|
||||
desc = "This spell conjures objs of the specified types in range."
|
||||
|
||||
var/list/summon_type = list() //determines what exactly will be summoned
|
||||
@@ -15,14 +15,14 @@
|
||||
|
||||
var/cast_sound = 'sound/items/welder.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/create_new_targeting()
|
||||
/datum/spell/aoe/conjure/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/turf/targeting = new()
|
||||
targeting.range = aoe_range
|
||||
return targeting
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/cast(list/targets,mob/living/user = usr)
|
||||
/datum/spell/aoe/conjure/cast(list/targets,mob/living/user = usr)
|
||||
var/list/what_conjure_summoned = list()
|
||||
playsound(get_turf(user), cast_sound, 50,1)
|
||||
playsound(get_turf(user), cast_sound, 50, TRUE)
|
||||
for(var/turf/T in targets)
|
||||
if(T.density && !summon_ignore_density)
|
||||
targets -= T
|
||||
@@ -57,8 +57,7 @@
|
||||
|
||||
return what_conjure_summoned
|
||||
|
||||
/// test purposes
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/summonEdSwarm
|
||||
/datum/spell/aoe/conjure/summonEdSwarm
|
||||
name = "Dispense Wizard Justice"
|
||||
desc = "This spell dispenses wizard justice."
|
||||
summon_type = list(/mob/living/simple_animal/bot/ed209)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/conjure_item
|
||||
/datum/spell/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."
|
||||
invocation_type = "none"
|
||||
@@ -9,10 +9,10 @@
|
||||
base_cooldown = 15 SECONDS
|
||||
cooldown_min = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/conjure_item/create_new_targeting()
|
||||
/datum/spell/conjure_item/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/conjure_item/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/conjure_item/cast(list/targets, mob/user = usr)
|
||||
if(item)
|
||||
QDEL_NULL(item)
|
||||
else
|
||||
@@ -21,6 +21,6 @@
|
||||
item = new item_type
|
||||
C.put_in_hands(item)
|
||||
|
||||
/obj/effect/proc_holder/spell/conjure_item/Destroy()
|
||||
/datum/spell/conjure_item/Destroy()
|
||||
QDEL_NULL(item)
|
||||
return ..()
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
//////////////////////////////Construct Spells/////////////////////////
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/construct/lesser
|
||||
/datum/spell/aoe/conjure/construct/lesser
|
||||
base_cooldown = 1800
|
||||
action_icon_state = "artificer"
|
||||
action_background_icon_state = "bg_cult"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build
|
||||
/datum/spell/aoe/conjure/build
|
||||
aoe_range = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build/floor
|
||||
/datum/spell/aoe/conjure/build/floor
|
||||
name = "Summon Cult Floor"
|
||||
desc = "This spell constructs a cult floor"
|
||||
action_icon_state = "floorconstruct"
|
||||
@@ -22,7 +22,7 @@
|
||||
centcom_cancast = FALSE //Stop crashing the server by spawning turfs on transit tiles
|
||||
holy_area_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build/wall
|
||||
/datum/spell/aoe/conjure/build/wall
|
||||
name = "Summon Cult Wall"
|
||||
desc = "This spell constructs a cult wall"
|
||||
action_icon_state = "cultforcewall"
|
||||
@@ -36,7 +36,7 @@
|
||||
centcom_cancast = FALSE //Stop crashing the server by spawning turfs on transit tiles
|
||||
holy_area_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build/wall/reinforced
|
||||
/datum/spell/aoe/conjure/build/wall/reinforced
|
||||
name = "Greater Construction"
|
||||
desc = "This spell constructs a reinforced metal wall"
|
||||
school = "conjuration"
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
summon_type = list(/turf/simulated/wall/r_wall)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build/soulstone
|
||||
/datum/spell/aoe/conjure/build/soulstone
|
||||
name = "Summon Soulstone"
|
||||
desc = "This spell uses vile sorcery to create a spirit-trapping soulstone."
|
||||
action_icon_state = "summonsoulstone"
|
||||
@@ -64,12 +64,12 @@
|
||||
|
||||
summon_type = list(/obj/item/soulstone)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build/soulstone/holy
|
||||
/datum/spell/aoe/conjure/build/soulstone/holy
|
||||
action_icon_state = "summonsoulstone_holy"
|
||||
|
||||
summon_type = list(/obj/item/soulstone/anybody/purified)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build/pylon
|
||||
/datum/spell/aoe/conjure/build/pylon
|
||||
name = "Cult Pylon"
|
||||
desc = "This spell uses dark magic to craft an unholy beacon. Heals cultists, and makes a handy light source."
|
||||
action_icon_state = "pylon"
|
||||
@@ -84,7 +84,7 @@
|
||||
summon_type = list(/obj/structure/cult/functional/pylon)
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build/lesserforcewall
|
||||
/datum/spell/aoe/conjure/build/lesserforcewall
|
||||
name = "Shield"
|
||||
desc = "This spell creates a temporary forcefield to shield yourself and allies from incoming fire"
|
||||
action_icon_state = "cultforcewall"
|
||||
@@ -105,7 +105,7 @@
|
||||
icon_state = "m_shield_cult"
|
||||
light_color = LIGHT_COLOR_PURE_RED
|
||||
|
||||
/obj/effect/proc_holder/spell/ethereal_jaunt/shift
|
||||
/datum/spell/ethereal_jaunt/shift
|
||||
name = "Phase Shift"
|
||||
desc = "This spell allows you to pass through walls"
|
||||
action_icon_state = "phaseshift"
|
||||
@@ -119,7 +119,7 @@
|
||||
jaunt_in_type = /obj/effect/temp_visual/dir_setting/wraith
|
||||
jaunt_out_type = /obj/effect/temp_visual/dir_setting/wraith/out
|
||||
|
||||
/obj/effect/proc_holder/spell/ethereal_jaunt/shift/do_jaunt(mob/living/target)
|
||||
/datum/spell/ethereal_jaunt/shift/do_jaunt(mob/living/target)
|
||||
target.set_light(0)
|
||||
..()
|
||||
if(isconstruct(target))
|
||||
@@ -129,10 +129,10 @@
|
||||
else
|
||||
C.set_light(2, 3, l_color = GET_CULT_DATA(construct_glow, LIGHT_COLOR_BLOOD_MAGIC))
|
||||
|
||||
/obj/effect/proc_holder/spell/ethereal_jaunt/shift/jaunt_steam(mobloc)
|
||||
/datum/spell/ethereal_jaunt/shift/jaunt_steam(mobloc)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/projectile/magic_missile/lesser
|
||||
/datum/spell/projectile/magic_missile/lesser
|
||||
name = "Lesser Magic Missile"
|
||||
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."
|
||||
action_background_icon_state = "bg_cult"
|
||||
@@ -144,20 +144,21 @@
|
||||
holy_area_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
|
||||
proj_lifespan = 10
|
||||
proj_step_delay = 5
|
||||
proj_type = "/obj/effect/proc_holder/spell/inflict_handler/magic_missile/lesser"
|
||||
proj_type = /obj/item/projectile/magic/magic_missile/lesser
|
||||
|
||||
/obj/effect/proc_holder/spell/projectile/magic_missile/lesser/create_new_targeting()
|
||||
/datum/spell/projectile/magic_missile/lesser/create_new_targeting()
|
||||
var/datum/spell_targeting/targeted/T = new()
|
||||
T.allowed_type = /mob/living
|
||||
T.random_target = TRUE
|
||||
T.max_targets = 6
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/inflict_handler/magic_missile/lesser
|
||||
amt_knockdown = 6 SECONDS
|
||||
amt_weakened = 0
|
||||
/obj/item/projectile/magic/magic_missile/lesser
|
||||
name = "lesser magic missile"
|
||||
knockdown = 6 SECONDS
|
||||
weaken = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/smoke/disable
|
||||
/datum/spell/smoke/disable
|
||||
name = "Paralysing Smoke"
|
||||
desc = "This spell spawns a cloud of paralysing smoke."
|
||||
action_icon_state = "parasmoke"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/disguise_self
|
||||
/datum/spell/disguise_self
|
||||
name = "Disguise Self"
|
||||
desc = "Disguise yourself as a crewmember, based on your current location. Also changes your voice. \
|
||||
The disguise will not hold up to being examined directly, and will break if you're damaged."
|
||||
@@ -12,10 +12,10 @@
|
||||
action_icon_state = "disguise_self"
|
||||
sound = null
|
||||
|
||||
/obj/effect/proc_holder/spell/disguise_self/create_new_targeting()
|
||||
/datum/spell/disguise_self/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/disguise_self/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/disguise_self/cast(list/targets, mob/user = usr)
|
||||
if(!ishuman(user))
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/emplosion
|
||||
/datum/spell/emplosion
|
||||
name = "Emplosion"
|
||||
desc = "This spell emplodes an area."
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
|
||||
action_icon_state = "emp"
|
||||
|
||||
/obj/effect/proc_holder/spell/emplosion/create_new_targeting()
|
||||
/datum/spell/emplosion/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/emplosion/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/emplosion/cast(list/targets, mob/user = usr)
|
||||
|
||||
for(var/mob/living/target in targets)
|
||||
empulse(target.loc, emp_heavy, emp_light, 1)
|
||||
empulse(target.loc, emp_heavy, emp_light, TRUE)
|
||||
|
||||
return
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/ethereal_jaunt
|
||||
/datum/spell/ethereal_jaunt
|
||||
name = "Ethereal Jaunt"
|
||||
desc = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls."
|
||||
|
||||
@@ -20,18 +20,18 @@
|
||||
|
||||
action_icon_state = "jaunt"
|
||||
|
||||
/obj/effect/proc_holder/spell/ethereal_jaunt/create_new_targeting()
|
||||
/datum/spell/ethereal_jaunt/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/ethereal_jaunt/cast(list/targets, mob/user = usr) //magnets, so mostly hardcoded
|
||||
playsound(get_turf(user), sound1, 50, 1, -1)
|
||||
/datum/spell/ethereal_jaunt/cast(list/targets, mob/user = usr) //magnets, so mostly hardcoded
|
||||
playsound(get_turf(user), sound1, 50, TRUE, -1)
|
||||
for(var/mob/living/target in targets)
|
||||
if(!target.can_safely_leave_loc()) // No more brainmobs hopping out of their brains
|
||||
to_chat(target, "<span class='warning'>You are somehow too bound to your current location to abandon it.</span>")
|
||||
continue
|
||||
INVOKE_ASYNC(src, PROC_REF(do_jaunt), target)
|
||||
|
||||
/obj/effect/proc_holder/spell/ethereal_jaunt/proc/do_jaunt(mob/living/target)
|
||||
/datum/spell/ethereal_jaunt/proc/do_jaunt(mob/living/target)
|
||||
target.notransform = TRUE
|
||||
var/turf/mobloc = get_turf(target)
|
||||
var/obj/effect/dummy/spell_jaunt/holder = new jaunt_type_path(mobloc)
|
||||
@@ -74,7 +74,7 @@
|
||||
REMOVE_TRAIT(target, TRAIT_IMMOBILIZED, "jaunt")
|
||||
target.remove_CC()
|
||||
|
||||
/obj/effect/proc_holder/spell/ethereal_jaunt/proc/jaunt_steam(mobloc)
|
||||
/datum/spell/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()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/touch/fake_disintegrate
|
||||
/datum/spell/touch/fake_disintegrate
|
||||
name = "Disintegrate"
|
||||
desc = "This spell charges your hand with vile energy that can be used to violently explode victims."
|
||||
hand_path = "/obj/item/melee/touch_attack/fake_disintegrate"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/obj/effect/proc_holder/spell/genetic
|
||||
/datum/spell/genetic
|
||||
desc = "This spell inflicts a set of mutations and disabilities upon the target."
|
||||
|
||||
var/list/active_on = list()
|
||||
var/list/traits = list() // traits
|
||||
var/list/mutations = list() // mutation defines. Set these in Initialize. Refactor this nonsense one day
|
||||
var/duration = 100 // deciseconds
|
||||
var/duration = 10 SECONDS
|
||||
|
||||
/obj/effect/proc_holder/spell/genetic/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/genetic/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/target in targets)
|
||||
if(!target.dna)
|
||||
continue
|
||||
@@ -17,15 +17,19 @@
|
||||
ADD_TRAIT(target, A, MAGIC_TRAIT)
|
||||
active_on += target
|
||||
target.regenerate_icons()
|
||||
do_additional_effects(target)
|
||||
if(duration < base_cooldown)
|
||||
addtimer(CALLBACK(src, PROC_REF(remove), target), duration, TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
|
||||
/obj/effect/proc_holder/spell/genetic/Destroy()
|
||||
/datum/spell/genetic/proc/do_additional_effects(mob/target)
|
||||
return
|
||||
|
||||
/datum/spell/genetic/Destroy()
|
||||
for(var/V in active_on)
|
||||
remove(V)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/genetic/proc/remove(mob/living/carbon/target)
|
||||
/datum/spell/genetic/proc/remove(mob/living/carbon/target)
|
||||
active_on -= target
|
||||
if(!QDELETED(target))
|
||||
for(var/A in mutations)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/horsemask
|
||||
/datum/spell/horsemask
|
||||
name = "Curse of the Horseman"
|
||||
desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes."
|
||||
school = "transmutation"
|
||||
@@ -15,13 +15,13 @@
|
||||
action_icon_state = "barn"
|
||||
sound = 'sound/magic/HorseHead_curse.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/horsemask/create_new_targeting()
|
||||
/datum/spell/horsemask/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new()
|
||||
T.selection_type = SPELL_SELECTION_RANGE
|
||||
return T
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/horsemask/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/horsemask/cast(list/targets, mob/user = usr)
|
||||
if(!targets.len)
|
||||
to_chat(user, "<span class='notice'>No target found in range.</span>")
|
||||
return
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/infinite_guns
|
||||
/datum/spell/infinite_guns
|
||||
name = "Lesser Summon Guns"
|
||||
desc = "Why reload when you have infinite guns? Summons an unending stream of bolt action rifles. Requires both hands free to use."
|
||||
invocation_type = "none"
|
||||
@@ -10,10 +10,10 @@
|
||||
action_icon_state = "bolt_action"
|
||||
var/gun_type = /obj/item/gun/projectile/shotgun/boltaction/enchanted
|
||||
|
||||
/obj/effect/proc_holder/spell/infinite_guns/create_new_targeting()
|
||||
/datum/spell/infinite_guns/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/infinite_guns/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/infinite_guns/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
C.drop_item()
|
||||
C.swap_hand()
|
||||
@@ -21,7 +21,7 @@
|
||||
var/obj/item/gun/projectile/shotgun/boltaction/enchanted/GUN = new gun_type()
|
||||
C.put_in_hands(GUN)
|
||||
|
||||
/obj/effect/proc_holder/spell/infinite_guns/fireball
|
||||
/datum/spell/infinite_guns/fireball
|
||||
name = "Rapid-fire Fireball"
|
||||
desc = "Multiple Fireballs. Need I explain more? Requires both hands free to use."
|
||||
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/obj/effect/proc_holder/spell/inflict_handler
|
||||
name = "Inflict Handler"
|
||||
desc = "This spell blinds and/or destroys/damages/heals and/or weakens/stuns the target."
|
||||
|
||||
var/amt_weakened = 0
|
||||
var/amt_paralysis = 0
|
||||
var/amt_stunned = 0
|
||||
var/amt_knockdown = 0
|
||||
|
||||
//set to negatives for healing
|
||||
var/amt_dam_fire = 0
|
||||
var/amt_dam_brute = 0
|
||||
var/amt_dam_oxy = 0
|
||||
var/amt_dam_tox = 0
|
||||
|
||||
var/amt_eye_blind = 0
|
||||
var/amt_eye_blurry = 0
|
||||
|
||||
var/destroys = "none" //can be "none", "gib" or "disintegrate"
|
||||
|
||||
var/summon_type = null //this will put an obj at the target's location
|
||||
|
||||
/obj/effect/proc_holder/spell/inflict_handler/create_new_targeting()
|
||||
return new /datum/spell_targeting/self // Dummy value since it is never used for this spell... why is this even a spell
|
||||
|
||||
/obj/effect/proc_holder/spell/inflict_handler/cast(list/targets, mob/user = usr)
|
||||
|
||||
for(var/mob/living/target in targets)
|
||||
switch(destroys)
|
||||
if("gib")
|
||||
target.gib()
|
||||
if("disintegrate")
|
||||
target.dust()
|
||||
|
||||
if(!target)
|
||||
continue
|
||||
//damage
|
||||
if(amt_dam_brute > 0)
|
||||
if(amt_dam_fire >= 0)
|
||||
target.take_overall_damage(amt_dam_brute,amt_dam_fire)
|
||||
else if(amt_dam_fire < 0)
|
||||
target.take_overall_damage(amt_dam_brute,0)
|
||||
target.heal_overall_damage(0,amt_dam_fire)
|
||||
else if(amt_dam_brute < 0)
|
||||
if(amt_dam_fire > 0)
|
||||
target.take_overall_damage(0,amt_dam_fire)
|
||||
target.heal_overall_damage(amt_dam_brute,0)
|
||||
else if(amt_dam_fire <= 0)
|
||||
target.heal_overall_damage(amt_dam_brute,amt_dam_fire)
|
||||
target.adjustToxLoss(amt_dam_tox)
|
||||
target.adjustOxyLoss(amt_dam_oxy)
|
||||
//disabling
|
||||
target.Weaken(amt_weakened)
|
||||
target.Paralyse(amt_paralysis)
|
||||
target.Stun(amt_stunned)
|
||||
target.KnockDown(amt_knockdown)
|
||||
|
||||
target.AdjustEyeBlind(amt_eye_blind)
|
||||
target.AdjustEyeBlurry(amt_eye_blurry)
|
||||
//summoning
|
||||
if(summon_type)
|
||||
new summon_type(target.loc, target)
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/aoe/knock
|
||||
/datum/spell/aoe/knock
|
||||
name = "Knock"
|
||||
desc = "This spell opens nearby doors and does not require wizard garb."
|
||||
|
||||
@@ -13,31 +13,31 @@
|
||||
sound = 'sound/magic/knock.ogg'
|
||||
aoe_range = 3
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/knock/create_new_targeting()
|
||||
/datum/spell/aoe/knock/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/turf/targeting = new()
|
||||
targeting.range = aoe_range
|
||||
return targeting
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/knock/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/aoe/knock/cast(list/targets, mob/user = usr)
|
||||
for(var/turf/T in targets)
|
||||
for(var/obj/machinery/door/door in T.contents)
|
||||
INVOKE_ASYNC(src, PROC_REF(try_open_airlock), door)
|
||||
for(var/obj/structure/closet/C in T.contents)
|
||||
INVOKE_ASYNC(src, PROC_REF(try_open_closet), C)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/knock/proc/try_open_airlock(obj/machinery/door/door)
|
||||
/datum/spell/aoe/knock/proc/try_open_airlock(obj/machinery/door/door)
|
||||
if(istype(door, /obj/machinery/door/airlock))
|
||||
var/obj/machinery/door/airlock/A = door
|
||||
A.unlock(TRUE) //forced because it's magic!
|
||||
door.open()
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/knock/proc/try_open_closet(obj/structure/closet/C)
|
||||
/datum/spell/aoe/knock/proc/try_open_closet(obj/structure/closet/C)
|
||||
if(istype(C, /obj/structure/closet/secure_closet))
|
||||
var/obj/structure/closet/secure_closet/SC = C
|
||||
SC.locked = FALSE
|
||||
C.open()
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/knock/greater
|
||||
/datum/spell/aoe/knock/greater
|
||||
name = "Greater Knock"
|
||||
desc = "On first cast, will remove access restrictions on all airlocks on the station, and announce this spell's use to the station. On any further cast, will open all doors in sight. Cannot be refunded once bought!"
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
action_icon_state = "greater_knock"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/knock/greater/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/aoe/knock/greater/cast(list/targets, mob/user = usr)
|
||||
if(!used)
|
||||
used = TRUE
|
||||
for(var/obj/machinery/door/airlock/A in GLOB.airlocks)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/lichdom
|
||||
/datum/spell/lichdom
|
||||
name = "Bind Soul"
|
||||
desc = "A dark necromantic pact that can forever bind your soul to an item of your choosing. So long as both your body and the item remain intact and on the same plane you can revive from death, though the time between reincarnations grows steadily with use."
|
||||
school = "necromancy"
|
||||
@@ -17,26 +17,26 @@
|
||||
|
||||
action_icon_state = "skeleton"
|
||||
|
||||
/obj/effect/proc_holder/spell/lichdom/create_new_targeting()
|
||||
/datum/spell/lichdom/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/lichdom/Destroy()
|
||||
/datum/spell/lichdom/Destroy()
|
||||
for(var/datum/mind/M in SSticker.mode.wizards) //Make sure no other bones are about
|
||||
for(var/obj/effect/proc_holder/spell/S in M.spell_list)
|
||||
if(istype(S,/obj/effect/proc_holder/spell/lichdom) && S != src)
|
||||
for(var/datum/spell/S in M.spell_list)
|
||||
if(istype(S,/datum/spell/lichdom) && S != src)
|
||||
return ..()
|
||||
if(existence_stops_round_end)
|
||||
GLOB.configuration.gamemode.disable_certain_round_early_end = FALSE
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/lichdom/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/lichdom/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/M in targets)
|
||||
if(stat_allowed)
|
||||
attempt_revive(M)
|
||||
else if(!marked_item_uid)
|
||||
attempt_mark_item(M)
|
||||
|
||||
/obj/effect/proc_holder/spell/lichdom/proc/attempt_revive(mob/user)
|
||||
/datum/spell/lichdom/proc/attempt_revive(mob/user)
|
||||
// Can only cast when unconscious/dead
|
||||
if(user.stat == CONSCIOUS)
|
||||
to_chat(user, "<span class='notice'>You aren't dead enough to revive!</span>")
|
||||
@@ -95,7 +95,7 @@
|
||||
cooldown_handler.recharge_duration += 1 MINUTES
|
||||
to_chat(lich, "<span class='warning'>Your bones clatter and shudder as they're pulled back into this world!</span>")
|
||||
|
||||
/obj/effect/proc_holder/spell/lichdom/proc/attempt_mark_item(mob/user)
|
||||
/datum/spell/lichdom/proc/attempt_mark_item(mob/user)
|
||||
var/obj/item/target = user.get_active_hand()
|
||||
if(!target)
|
||||
to_chat(user, "<span class='warning'>You must hold an item you wish to make your phylactery!</span>")
|
||||
@@ -141,7 +141,7 @@
|
||||
existence_stops_round_end = TRUE
|
||||
GLOB.configuration.gamemode.disable_certain_round_early_end = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/lichdom/proc/is_revive_possible()
|
||||
/datum/spell/lichdom/proc/is_revive_possible()
|
||||
var/obj/item/marked_item = locateUID(marked_item_uid)
|
||||
if(QDELETED(marked_item))
|
||||
return FALSE
|
||||
@@ -153,12 +153,12 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/lichdom/proc/check_revivability_handler()
|
||||
/datum/spell/lichdom/proc/check_revivability_handler()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// There are other liches about, so round may still continue
|
||||
for(var/datum/mind/M in SSticker.mode.wizards)
|
||||
for(var/obj/effect/proc_holder/spell/lichdom/S in M.spell_list)
|
||||
for(var/datum/spell/lichdom/S in M.spell_list)
|
||||
if(S == src)
|
||||
continue
|
||||
// Other lich can still revive
|
||||
@@ -170,7 +170,7 @@
|
||||
|
||||
GLOB.configuration.gamemode.disable_certain_round_early_end = is_revive_possible()
|
||||
|
||||
/obj/effect/proc_holder/spell/lichdom/proc/equip_lich(mob/living/carbon/human/H)
|
||||
/datum/spell/lichdom/proc/equip_lich(mob/living/carbon/human/H)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), SLOT_HUD_OUTER_SUIT)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), SLOT_HUD_HEAD)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), SLOT_HUD_SHOES)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/lightning
|
||||
/datum/spell/charge_up/bounce/lightning
|
||||
name = "Lightning Bolt"
|
||||
desc = "Throws a lightning bolt at your enemies. Classic. When clicked will start to charge in power. Then click on a mob to send the bolt before it overloads with power."
|
||||
base_cooldown = 30 SECONDS
|
||||
@@ -15,29 +15,29 @@
|
||||
bounce_hit_sound = 'sound/magic/lightningshock.ogg'
|
||||
var/damaging = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/lightning/New()
|
||||
/datum/spell/charge_up/bounce/lightning/New()
|
||||
..()
|
||||
charge_up_overlay = image(icon = 'icons/effects/effects.dmi', icon_state = "electricity", layer = EFFECTS_LAYER)
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/lightning/lightnian
|
||||
/datum/spell/charge_up/bounce/lightning/lightnian
|
||||
clothes_req = FALSE
|
||||
invocation_type = "none"
|
||||
damaging = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/lightning/get_bounce_energy()
|
||||
/datum/spell/charge_up/bounce/lightning/get_bounce_energy()
|
||||
if(damaging)
|
||||
return max(15, get_energy_charge() / 2)
|
||||
return 0
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/lightning/get_bounce_amount()
|
||||
/datum/spell/charge_up/bounce/lightning/get_bounce_amount()
|
||||
if(damaging)
|
||||
return 5
|
||||
return round(get_energy_charge() / 20)
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/lightning/create_beam(mob/origin, mob/target)
|
||||
/datum/spell/charge_up/bounce/lightning/create_beam(mob/origin, mob/target)
|
||||
origin.Beam(target, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5)
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/lightning/apply_bounce_effect(mob/origin, mob/living/target, energy, mob/user)
|
||||
/datum/spell/charge_up/bounce/lightning/apply_bounce_effect(mob/origin, mob/living/target, energy, mob/user)
|
||||
if(damaging)
|
||||
target.electrocute_act(energy, "Lightning Bolt", flags = SHOCK_NOGLOVES)
|
||||
else
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/magnet
|
||||
/datum/spell/charge_up/bounce/magnet
|
||||
name = "Magnetic Pull"
|
||||
desc = "Pulls metalic objects from enemies hands with the power of MAGNETS."
|
||||
action_icon_state = "magnet"
|
||||
@@ -14,22 +14,22 @@
|
||||
start_charging_text = "You start gathering magnetism around you."
|
||||
bounce_hit_sound = 'sound/machines/defib_zap.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/magnet/New()
|
||||
/datum/spell/charge_up/bounce/magnet/New()
|
||||
..()
|
||||
charge_up_overlay = image(icon = 'icons/effects/effects.dmi', icon_state = "electricity", layer = EFFECTS_LAYER)
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/magnet/get_bounce_energy()
|
||||
/datum/spell/charge_up/bounce/magnet/get_bounce_energy()
|
||||
return get_energy_charge()
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/magnet/get_bounce_amount()
|
||||
/datum/spell/charge_up/bounce/magnet/get_bounce_amount()
|
||||
if(get_energy_charge() >= 75)
|
||||
return 5
|
||||
return 0
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/magnet/create_beam(mob/origin, mob/target)
|
||||
/datum/spell/charge_up/bounce/magnet/create_beam(mob/origin, mob/target)
|
||||
origin.Beam(target, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5)
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/magnet/apply_bounce_effect(mob/origin, mob/target, energy, mob/user)
|
||||
/datum/spell/charge_up/bounce/magnet/apply_bounce_effect(mob/origin, mob/target, energy, mob/user)
|
||||
var/list/items_to_throw = list()
|
||||
switch(energy)
|
||||
if(0 to 25)
|
||||
@@ -47,7 +47,7 @@
|
||||
for(var/I in items_to_throw)
|
||||
try_throw_object(user, target, I)
|
||||
|
||||
/obj/effect/proc_holder/spell/charge_up/bounce/magnet/proc/try_throw_object(mob/user, mob/thrower, obj/item/to_throw)
|
||||
/datum/spell/charge_up/bounce/magnet/proc/try_throw_object(mob/user, mob/thrower, obj/item/to_throw)
|
||||
if(!(to_throw.flags & CONDUCT) || !thrower.unEquip(to_throw, silent = TRUE))
|
||||
return FALSE
|
||||
thrower.visible_message("<span class='warning'>[to_throw] gets thrown out of [thrower] [thrower.p_their()] hands!</span>",
|
||||
|
||||
+21
-21
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build/mime_wall
|
||||
/datum/spell/aoe/conjure/build/mime_wall
|
||||
name = "Invisible Wall"
|
||||
desc = "The mime's performance transmutates into physical reality."
|
||||
school = "mime"
|
||||
@@ -15,7 +15,7 @@
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/build/mime_wall/Click()
|
||||
/datum/spell/aoe/conjure/build/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>")
|
||||
@@ -25,10 +25,10 @@
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/mime/create_new_targeting()
|
||||
/datum/spell/mime/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/mime/speak
|
||||
/datum/spell/mime/speak
|
||||
name = "Speech"
|
||||
desc = "Make or break a vow of silence."
|
||||
school = "mime"
|
||||
@@ -40,7 +40,7 @@
|
||||
action_icon_state = "mime_silence"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/mime/speak/Click()
|
||||
/datum/spell/mime/speak/Click()
|
||||
if(!usr)
|
||||
return
|
||||
if(!ishuman(usr))
|
||||
@@ -52,7 +52,7 @@
|
||||
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/mime/speak/cast(list/targets,mob/user = usr)
|
||||
/datum/spell/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)
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
//Advanced Mimery traitor item spells
|
||||
|
||||
/obj/effect/proc_holder/spell/forcewall/mime
|
||||
/datum/spell/forcewall/mime
|
||||
name = "Invisible Greater Wall"
|
||||
desc = "Form an invisible three tile wide blockade."
|
||||
school = "mime"
|
||||
@@ -77,7 +77,7 @@
|
||||
action_icon_state = "mime_bigwall"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/forcewall/mime/Click()
|
||||
/datum/spell/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>")
|
||||
@@ -87,7 +87,7 @@
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
/obj/effect/proc_holder/spell/mime/fingergun
|
||||
/datum/spell/mime/fingergun
|
||||
name = "Finger Gun"
|
||||
desc = "Shoot lethal, silencing bullets out of your fingers! 3 bullets available per cast. Use your fingers to holster them manually."
|
||||
school = "mime"
|
||||
@@ -101,7 +101,7 @@
|
||||
var/gun = /obj/item/gun/projectile/revolver/fingergun
|
||||
var/obj/item/gun/projectile/revolver/fingergun/current_gun
|
||||
|
||||
/obj/effect/proc_holder/spell/mime/fingergun/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/mime/fingergun/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/carbon/human/C in targets)
|
||||
if(!current_gun)
|
||||
to_chat(user, "<span class='notice'>You draw your fingers!</span>")
|
||||
@@ -114,33 +114,33 @@
|
||||
revert_cast(user)
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/mime/fingergun/Destroy()
|
||||
/datum/spell/mime/fingergun/Destroy()
|
||||
current_gun = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/mime/fingergun/proc/holster_hand(atom/target, any=FALSE)
|
||||
/datum/spell/mime/fingergun/proc/holster_hand(atom/target, any=FALSE)
|
||||
SIGNAL_HANDLER
|
||||
if(!current_gun || !any && action.owner.get_active_hand() != current_gun)
|
||||
return
|
||||
to_chat(action.owner, "<span class='notice'>You holster your fingers. Another time perhaps...</span>")
|
||||
QDEL_NULL(current_gun)
|
||||
|
||||
/obj/effect/proc_holder/spell/mime/fingergun/fake
|
||||
/datum/spell/mime/fingergun/fake
|
||||
desc = "Pretend you're shooting bullets out of your fingers! 3 bullets available per cast. Use your fingers to holster them manually."
|
||||
gun = /obj/item/gun/projectile/revolver/fingergun/fake
|
||||
|
||||
// Mime Spellbooks
|
||||
|
||||
/obj/item/spellbook/oneuse/mime
|
||||
spell = /obj/effect/proc_holder/spell/aoe/conjure/build/mime_wall
|
||||
spell = /datum/spell/aoe/conjure/build/mime_wall
|
||||
spellname = "Invisible Wall"
|
||||
name = "Miming Manual : "
|
||||
desc = "It contains various pictures of mimes mid-performance, aswell as some illustrated tutorials."
|
||||
icon_state = "bookmime"
|
||||
|
||||
/obj/item/spellbook/oneuse/mime/attack_self(mob/user)
|
||||
var/obj/effect/proc_holder/spell/S = new spell
|
||||
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
|
||||
var/datum/spell/S = new spell
|
||||
for(var/datum/spell/knownspell in user.mind.spell_list)
|
||||
if(knownspell.type == S.type)
|
||||
if(user.mind)
|
||||
to_chat(user, "<span class='notice'>You've already read this one.</span>")
|
||||
@@ -159,19 +159,19 @@
|
||||
|
||||
/obj/item/spellbook/oneuse/mime/onlearned(mob/user)
|
||||
used = TRUE
|
||||
if(!locate(/obj/effect/proc_holder/spell/mime/speak) in user.mind.spell_list) //add vow of silence if not known by user
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/mime/speak)
|
||||
if(!locate(/datum/spell/mime/speak) in user.mind.spell_list) //add vow of silence if not known by user
|
||||
user.mind.AddSpell(new /datum/spell/mime/speak)
|
||||
to_chat(user, "<span class='notice'>You have learned how to use silence to improve your performance.</span>")
|
||||
|
||||
/obj/item/spellbook/oneuse/mime/fingergun
|
||||
spell = /obj/effect/proc_holder/spell/mime/fingergun
|
||||
spell = /datum/spell/mime/fingergun
|
||||
spellname = "Finger Gun"
|
||||
desc = "It contains illustrations of guns and how to mime them."
|
||||
|
||||
/obj/item/spellbook/oneuse/mime/fingergun/fake
|
||||
spell = /obj/effect/proc_holder/spell/mime/fingergun/fake
|
||||
spell = /datum/spell/mime/fingergun/fake
|
||||
|
||||
/obj/item/spellbook/oneuse/mime/greaterwall
|
||||
spell = /obj/effect/proc_holder/spell/forcewall/mime
|
||||
spell = /datum/spell/forcewall/mime
|
||||
spellname = "Invisible Greater Wall"
|
||||
desc = "It contains illustrations of the great walls of human history."
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/touch/mime_malaise
|
||||
/datum/spell/touch/mime_malaise
|
||||
name = "Mime Malaise"
|
||||
desc = "A spell popular with theater nerd wizards and contrarian pranksters, this spell will put on a mime costume on the target, \
|
||||
stun them so that they may contemplate Art, and silence them. \
|
||||
|
||||
+21
-21
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/mimic
|
||||
/datum/spell/mimic
|
||||
name = "Mimic"
|
||||
desc = "Learn a new form to mimic or become one of your known forms"
|
||||
clothes_req = FALSE
|
||||
@@ -32,7 +32,7 @@
|
||||
)
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/create_new_targeting()
|
||||
/datum/spell/mimic/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new
|
||||
T.include_user = TRUE // To change forms
|
||||
T.allowed_type = /atom/movable
|
||||
@@ -40,7 +40,7 @@
|
||||
T.click_radius = -1
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/valid_target(atom/target, user)
|
||||
/datum/spell/mimic/valid_target(atom/target, user)
|
||||
if(is_type_in_list(target, black_listed_form_types))
|
||||
return FALSE
|
||||
if(istype(target, /atom/movable))
|
||||
@@ -51,7 +51,7 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/cast(list/targets, mob/user)
|
||||
/datum/spell/mimic/cast(list/targets, mob/user)
|
||||
var/atom/movable/A = targets[1]
|
||||
if(A == user)
|
||||
INVOKE_ASYNC(src, PROC_REF(pick_form), user)
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
INVOKE_ASYNC(src, PROC_REF(remember_form), A, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/proc/remember_form(atom/movable/A, mob/user)
|
||||
/datum/spell/mimic/proc/remember_form(atom/movable/A, mob/user)
|
||||
if(A.name in available_forms)
|
||||
to_chat(user, "<span class='warning'>[A] is already an available form.</span>")
|
||||
revert_cast(user)
|
||||
@@ -83,7 +83,7 @@
|
||||
available_forms[A.name] = new /datum/mimic_form(A, user)
|
||||
to_chat(user, "<span class='sinister'>You learn the form of [A].</span>")
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/proc/pick_form(mob/user)
|
||||
/datum/spell/mimic/proc/pick_form(mob/user)
|
||||
if(!length(available_forms) && !selected_form)
|
||||
to_chat(user, "<span class='warning'>No available forms. Learn more forms by using this spell on other objects first.</span>")
|
||||
revert_cast(user)
|
||||
@@ -109,7 +109,7 @@
|
||||
return
|
||||
take_form(available_forms[what], user)
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/proc/take_form(datum/mimic_form/form, mob/user)
|
||||
/datum/spell/mimic/proc/take_form(datum/mimic_form/form, mob/user)
|
||||
var/old_name = "[user]"
|
||||
if(ishuman(user))
|
||||
// Not fully finished yet
|
||||
@@ -132,10 +132,10 @@
|
||||
|
||||
selected_form = form
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/proc/show_change_form_message(mob/user, old_name, new_name)
|
||||
/datum/spell/mimic/proc/show_change_form_message(mob/user, old_name, new_name)
|
||||
user.visible_message("<span class='warning'>[old_name] contorts and slowly becomes [new_name]!</span>", "<span class='sinister'>You take form of [new_name].</span>", "You hear loud cracking noises!")
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/proc/restore_form(mob/user, show_message = TRUE)
|
||||
/datum/spell/mimic/proc/restore_form(mob/user, show_message = TRUE)
|
||||
selected_form = null
|
||||
var/old_name = "[user]"
|
||||
|
||||
@@ -157,21 +157,21 @@
|
||||
|
||||
UnregisterSignal(user, list(COMSIG_PARENT_EXAMINE, COMSIG_MOB_DEATH))
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/proc/show_restore_form_message(mob/user, old_name, new_name)
|
||||
/datum/spell/mimic/proc/show_restore_form_message(mob/user, old_name, new_name)
|
||||
user.visible_message("<span class='warning'>[old_name] shakes and contorts and quickly becomes [new_name]!</span>", "<span class='sinister'>You take return to your normal self.</span>", "You hear loud cracking noises!")
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/proc/examine_override(datum/source, mob/user, list/examine_list)
|
||||
/datum/spell/mimic/proc/examine_override(datum/source, mob/user, list/examine_list)
|
||||
examine_list.Cut()
|
||||
examine_list += selected_form.examine_text
|
||||
if(!perfect_disguise && get_dist(user, source) <= 3)
|
||||
examine_list += "<span class='warning'>It doesn't look quite right...</span>"
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/proc/on_death(mob/user, gibbed)
|
||||
/datum/spell/mimic/proc/on_death(mob/user, gibbed)
|
||||
if(!gibbed)
|
||||
restore_form(user, FALSE)
|
||||
show_death_message(user)
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/proc/show_death_message(mob/user)
|
||||
/datum/spell/mimic/proc/show_death_message(mob/user)
|
||||
user.visible_message("<span class='warning'>[user] shakes and contorts as [user.p_they()] die[user.p_s()], returning to [user.p_their()] true form!</span>", "<span class='deadsay'>Your disguise fails as your life forces drain away.</span>", "You hear loud cracking noises followed by a thud!")
|
||||
|
||||
|
||||
@@ -188,34 +188,34 @@
|
||||
examine_text = form.examine(user)
|
||||
name = form.name
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/morph
|
||||
/datum/spell/mimic/morph
|
||||
action_background_icon_state = "bg_morph"
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/morph/create_new_handler()
|
||||
/datum/spell/mimic/morph/create_new_handler()
|
||||
var/datum/spell_handler/morph/H = new
|
||||
return H
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/morph/valid_target(atom/target, user)
|
||||
/datum/spell/mimic/morph/valid_target(atom/target, user)
|
||||
if(target != user && ismorph(target))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/morph/take_form(datum/mimic_form/form, mob/living/simple_animal/hostile/morph/user)
|
||||
/datum/spell/mimic/morph/take_form(datum/mimic_form/form, mob/living/simple_animal/hostile/morph/user)
|
||||
..()
|
||||
user.assume()
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/morph/restore_form(mob/living/simple_animal/hostile/morph/user, show_message = TRUE)
|
||||
/datum/spell/mimic/morph/restore_form(mob/living/simple_animal/hostile/morph/user, show_message = TRUE)
|
||||
..()
|
||||
user.restore()
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/morph/show_change_form_message(mob/user, old_name, new_name)
|
||||
/datum/spell/mimic/morph/show_change_form_message(mob/user, old_name, new_name)
|
||||
user.visible_message("<span class='warning'>[old_name] suddenly twists and changes shape, becoming a copy of [new_name]!</span>", \
|
||||
"<span class='notice'>You twist your body and assume the form of [new_name].</span>")
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/morph/show_restore_form_message(mob/user, old_name, new_name)
|
||||
/datum/spell/mimic/morph/show_restore_form_message(mob/user, old_name, new_name)
|
||||
user.visible_message("<span class='warning'>[old_name] suddenly collapses in on itself, dissolving into a pile of green flesh!</span>", \
|
||||
"<span class='notice'>You reform to your normal body.</span>")
|
||||
|
||||
/obj/effect/proc_holder/spell/mimic/morph/show_death_message(mob/user)
|
||||
/datum/spell/mimic/morph/show_death_message(mob/user)
|
||||
user.visible_message("<span class='warning'>[user] twists and dissolves into a pile of green flesh!</span>", \
|
||||
"<span class='userdanger'>Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--</span>")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/mind_transfer
|
||||
/datum/spell/mind_transfer
|
||||
name = "Mind Transfer"
|
||||
desc = "This spell allows the user to switch bodies with a target."
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
var/paralysis_amount_victim = 40 SECONDS //how much the victim is paralysed for after the spell
|
||||
action_icon_state = "mindswap"
|
||||
|
||||
/obj/effect/proc_holder/spell/mind_transfer/create_new_targeting()
|
||||
/datum/spell/mind_transfer/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new()
|
||||
T.allowed_type = /mob/living
|
||||
T.range = 1
|
||||
T.click_radius = 0
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/mind_transfer/valid_target(mob/living/target, mob/user)
|
||||
/datum/spell/mind_transfer/valid_target(mob/living/target, mob/user)
|
||||
return target.stat != DEAD && target.key && target.mind
|
||||
|
||||
/*
|
||||
@@ -30,7 +30,7 @@ Urist: I don't feel like figuring out how you store object spells so I'm leaving
|
||||
Make sure spells that are removed from spell_list are actually removed and deleted when mind transfering.
|
||||
Also, you never added distance checking after target is selected. I've went ahead and did that.
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/mind_transfer/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/mind_transfer/cast(list/targets, mob/user = usr)
|
||||
|
||||
var/mob/living/target = targets[1]
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/night_vision
|
||||
/datum/spell/night_vision
|
||||
name = "Toggle Nightvision"
|
||||
desc = "Toggle your nightvision mode."
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
message = "<span class='notice'>You toggle your night vision!</span>"
|
||||
|
||||
/obj/effect/proc_holder/spell/night_vision/create_new_targeting()
|
||||
/datum/spell/night_vision/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/night_vision/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/night_vision/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/target in targets)
|
||||
switch(target.lighting_alpha)
|
||||
if(LIGHTING_PLANE_ALPHA_VISIBLE)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/projectile
|
||||
/datum/spell/projectile
|
||||
desc = "This spell summons projectiles which try to hit the targets."
|
||||
|
||||
var/proj_icon = 'icons/obj/projectiles.dmi'
|
||||
@@ -10,7 +10,8 @@
|
||||
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
|
||||
/// The projectile we spawn. Make sure to override this
|
||||
var/proj_type
|
||||
|
||||
var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle
|
||||
var/proj_homing = 1 //if it follows the target
|
||||
@@ -20,64 +21,51 @@
|
||||
var/proj_lifespan = 15 //in deciseconds * proj_step_delay
|
||||
var/proj_step_delay = 1 //lower = faster
|
||||
|
||||
/obj/effect/proc_holder/spell/projectile/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/projectile/cast(list/targets, mob/user = usr)
|
||||
|
||||
for(var/mob/living/target in targets)
|
||||
spawn(0)
|
||||
var/obj/effect/proc_holder/spell/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/trigger(user)
|
||||
projectile:linked_spells += proj_type
|
||||
var/obj/item/projectile/projectile = new proj_type(get_turf(user))
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.dir = get_dir(target,projectile)
|
||||
projectile.dir = get_dir(target, projectile)
|
||||
projectile.name = proj_name
|
||||
var/current_loc = get_turf(projectile)
|
||||
|
||||
var/current_loc = user.loc
|
||||
|
||||
projectile.loc = current_loc
|
||||
|
||||
for(var/i = 0,i < proj_lifespan,i++)
|
||||
for(var/i in 1 to proj_lifespan)
|
||||
if(!projectile)
|
||||
break
|
||||
|
||||
if(proj_homing)
|
||||
if(proj_insubstantial)
|
||||
projectile.dir = get_dir(projectile,target)
|
||||
projectile.loc = get_step_to(projectile,target)
|
||||
projectile.forceMove(get_step_to(projectile, target))
|
||||
else
|
||||
step_to(projectile,target)
|
||||
else
|
||||
if(proj_insubstantial)
|
||||
projectile.loc = get_step(projectile,dir)
|
||||
projectile.forceMove(get_step(projectile, projectile.dir))
|
||||
else
|
||||
step(projectile,dir)
|
||||
step(projectile, projectile.dir)
|
||||
|
||||
if(!projectile) // step and step_to sleeps so we'll have to check again.
|
||||
break
|
||||
|
||||
if(!proj_lingering && projectile.loc == current_loc) //if it didn't move since last time
|
||||
if(!proj_lingering && (get_turf(projectile) == current_loc)) //if it didn't move since last time
|
||||
qdel(projectile)
|
||||
break
|
||||
|
||||
if(proj_trail && projectile)
|
||||
spawn(0)
|
||||
if(projectile)
|
||||
var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc)
|
||||
var/obj/effect/overlay/trail = new /obj/effect/overlay(get_turf(projectile))
|
||||
trail.icon = proj_trail_icon
|
||||
trail.icon_state = proj_trail_icon_state
|
||||
trail.density = FALSE
|
||||
spawn(proj_trail_lifespan)
|
||||
qdel(trail)
|
||||
|
||||
if(projectile.loc in range(target.loc,proj_trigger_range))
|
||||
projectile.perform(list(target), user = user)
|
||||
break
|
||||
|
||||
current_loc = projectile.loc
|
||||
current_loc = get_turf(projectile)
|
||||
|
||||
sleep(proj_step_delay)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/rathens
|
||||
/datum/spell/rathens
|
||||
name = "Rathen's Secret"
|
||||
desc = "Summons a powerful shockwave around you that tears the appendix out of enemies, and occasionally removes their limbs."
|
||||
base_cooldown = 50 SECONDS
|
||||
@@ -8,12 +8,12 @@
|
||||
cooldown_min = 20 SECONDS
|
||||
action_icon_state = "lungpunch"
|
||||
|
||||
/obj/effect/proc_holder/spell/rathens/create_new_targeting()
|
||||
/datum/spell/rathens/create_new_targeting()
|
||||
var/datum/spell_targeting/targeted/T = new()
|
||||
T.max_targets = INFINITY
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/rathens/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/rathens/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/carbon/human/H in targets)
|
||||
var/datum/effect_system/smoke_spread/s = new
|
||||
s.set_up(5, FALSE, H)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/rod_form
|
||||
/datum/spell/rod_form
|
||||
name = "Rod Form"
|
||||
desc = "Take on the form of an immovable rod, destroying all in your path."
|
||||
clothes_req = TRUE
|
||||
@@ -13,10 +13,10 @@
|
||||
sound = 'sound/effects/whoosh.ogg'
|
||||
var/rod_delay = 2
|
||||
|
||||
/obj/effect/proc_holder/spell/rod_form/create_new_targeting()
|
||||
/datum/spell/rod_form/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/rod_form/cast(list/targets,mob/user = usr)
|
||||
/datum/spell/rod_form/cast(list/targets,mob/user = usr)
|
||||
if(get_turf(user) != user.loc)
|
||||
to_chat(user, "<span class='warning'>You cannot summon a rod in the ether, the spell fizzles out!</span>")
|
||||
revert_cast()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/sentient_sword_lunge
|
||||
/datum/spell/sentient_sword_lunge
|
||||
name = "Lunge"
|
||||
desc = "Lunge at something in your view range."
|
||||
clothes_req = FALSE
|
||||
@@ -8,10 +8,10 @@
|
||||
sound = 'sound/magic/repulse.ogg'
|
||||
action_icon_state = "lunge"
|
||||
|
||||
/obj/effect/proc_holder/spell/sentient_sword_lunge/create_new_targeting()
|
||||
/datum/spell/sentient_sword_lunge/create_new_targeting()
|
||||
return new /datum/spell_targeting/clicked_atom
|
||||
|
||||
/obj/effect/proc_holder/spell/sentient_sword_lunge/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/sentient_sword_lunge/cast(list/targets, mob/user = usr)
|
||||
if(!istype(user.loc, /obj/item))
|
||||
to_chat(user, "<span class='warning'>You cannot use this ability if you're outside a blade!</span>")
|
||||
return
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/shapeshift
|
||||
/datum/spell/shapeshift
|
||||
name = "Shapechange"
|
||||
desc = "Take on the shape of another for a time to use their natural abilities. Once you've made your choice it cannot be changed."
|
||||
clothes_req = FALSE
|
||||
@@ -17,10 +17,10 @@
|
||||
/mob/living/simple_animal/bot/ed209,
|
||||
/mob/living/simple_animal/hostile/construct/armoured)
|
||||
|
||||
/obj/effect/proc_holder/spell/shapeshift/create_new_targeting()
|
||||
/datum/spell/shapeshift/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/shapeshift/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/shapeshift/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/M in targets)
|
||||
if(!shapeshift_type)
|
||||
var/list/animal_list = list()
|
||||
@@ -36,7 +36,7 @@
|
||||
else
|
||||
Shapeshift(M)
|
||||
|
||||
/obj/effect/proc_holder/spell/shapeshift/proc/Shapeshift(mob/living/caster)
|
||||
/datum/spell/shapeshift/proc/Shapeshift(mob/living/caster)
|
||||
for(var/mob/living/M in caster)
|
||||
if(M.status_flags & GODMODE)
|
||||
to_chat(caster, "<span class='warning'>You're already shapeshifted!</span>")
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
caster.mind.transfer_to(shape)
|
||||
|
||||
/obj/effect/proc_holder/spell/shapeshift/proc/Restore(mob/living/shape)
|
||||
/datum/spell/shapeshift/proc/Restore(mob/living/shape)
|
||||
var/mob/living/caster
|
||||
for(var/mob/living/M in shape)
|
||||
if(M in current_casters)
|
||||
@@ -72,7 +72,7 @@
|
||||
shape.mind.transfer_to(caster)
|
||||
qdel(shape) //Gib it maybe ?
|
||||
|
||||
/obj/effect/proc_holder/spell/shapeshift/dragon
|
||||
/datum/spell/shapeshift/dragon
|
||||
name = "Dragon Form"
|
||||
desc = "Take on the shape a lesser ash drake after a short delay."
|
||||
invocation = "*scream"
|
||||
@@ -82,7 +82,7 @@
|
||||
current_casters = list()
|
||||
possible_shapes = list(/mob/living/simple_animal/hostile/megafauna/dragon/lesser)
|
||||
|
||||
/obj/effect/proc_holder/spell/shapeshift/dragon/Shapeshift(mob/living/caster)
|
||||
/datum/spell/shapeshift/dragon/Shapeshift(mob/living/caster)
|
||||
caster.visible_message("<span class='danger'>[caster] screams in agony as bones and claws erupt out of their flesh!</span>",
|
||||
"<span class='danger'>You begin channeling the transformation.</span>")
|
||||
if(!do_after(caster, 5 SECONDS, FALSE, caster))
|
||||
@@ -90,7 +90,7 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/shapeshift/bats
|
||||
/datum/spell/shapeshift/bats
|
||||
name = "Bat Form"
|
||||
desc = "Take on the shape of a swarm of bats."
|
||||
invocation = "none"
|
||||
@@ -103,7 +103,7 @@
|
||||
current_casters = list()
|
||||
possible_shapes = list(/mob/living/simple_animal/hostile/scarybat/adminvampire)
|
||||
|
||||
/obj/effect/proc_holder/spell/shapeshift/hellhound
|
||||
/datum/spell/shapeshift/hellhound
|
||||
name = "Lesser Hellhound Form"
|
||||
desc = "Take on the shape of a Hellhound."
|
||||
invocation = "none"
|
||||
@@ -117,7 +117,7 @@
|
||||
current_casters = list()
|
||||
possible_shapes = list(/mob/living/simple_animal/hostile/hellhound)
|
||||
|
||||
/obj/effect/proc_holder/spell/shapeshift/hellhound/greater
|
||||
/datum/spell/shapeshift/hellhound/greater
|
||||
name = "Greater Hellhound Form"
|
||||
shapeshift_type = /mob/living/simple_animal/hostile/hellhound/greater
|
||||
current_shapes = list(/mob/living/simple_animal/hostile/hellhound/greater)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This could probably be an aoe spell but it's a little cursed, so I'm not touching it
|
||||
/obj/effect/proc_holder/spell/spacetime_dist
|
||||
/datum/spell/spacetime_dist
|
||||
name = "Spacetime Distortion"
|
||||
desc = "Entangle the strings of space-time in an area around you, \
|
||||
randomizing the layout and making proper movement impossible. The strings vibrate... \
|
||||
@@ -25,23 +25,23 @@
|
||||
/// A lazylist of all scramble effects this spell has created.
|
||||
var/list/effects
|
||||
|
||||
/obj/effect/proc_holder/spell/spacetime_dist/Destroy()
|
||||
/datum/spell/spacetime_dist/Destroy()
|
||||
QDEL_LIST_CONTENTS(effects)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/spacetime_dist/create_new_targeting()
|
||||
/datum/spell/spacetime_dist/create_new_targeting()
|
||||
var/datum/spell_targeting/spiral/targeting = new()
|
||||
targeting.range = scramble_radius + 3 * spell_level
|
||||
return targeting
|
||||
|
||||
/obj/effect/proc_holder/spell/spacetime_dist/on_purchase_upgrade()
|
||||
/datum/spell/spacetime_dist/on_purchase_upgrade()
|
||||
. = ..()
|
||||
targeting = create_new_targeting()
|
||||
|
||||
/obj/effect/proc_holder/spell/spacetime_dist/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/user = usr)
|
||||
/datum/spell/spacetime_dist/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/user = usr)
|
||||
return ..() && ready
|
||||
|
||||
/obj/effect/proc_holder/spell/spacetime_dist/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/spacetime_dist/cast(list/targets, mob/user = usr)
|
||||
. = ..()
|
||||
var/list/turf/to_switcharoo = targets
|
||||
if(!length(to_switcharoo))
|
||||
@@ -64,12 +64,12 @@
|
||||
effects += effect_b
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/spacetime_dist/after_cast(list/targets, mob/user)
|
||||
/datum/spell/spacetime_dist/after_cast(list/targets, mob/user)
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src, PROC_REF(clean_turfs)), duration)
|
||||
|
||||
/// Callback which cleans up our effects list after the duration expires.
|
||||
/obj/effect/proc_holder/spell/spacetime_dist/proc/clean_turfs()
|
||||
/datum/spell/spacetime_dist/proc/clean_turfs()
|
||||
QDEL_LIST_CONTENTS(effects)
|
||||
ready = TRUE
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter
|
||||
/datum/spell/aoe/conjure/summon_supermatter
|
||||
name = "Summon Supermatter Crystal"
|
||||
desc = "Summons an active supermatter crystal. Imbues you with some supermatter, giving you resistance to it's hallucinations and radiation immunity."
|
||||
base_cooldown = 5 MINUTES
|
||||
@@ -8,7 +8,7 @@
|
||||
summon_amt = 1
|
||||
aoe_range = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter/cast(list/targets, mob/living/user = usr)
|
||||
/datum/spell/aoe/conjure/summon_supermatter/cast(list/targets, mob/living/user = usr)
|
||||
var/list/summoned_objects = ..()
|
||||
for(var/obj/machinery/atmospherics/supermatter_crystal/our_crystal in summoned_objects)
|
||||
addtimer(CALLBACK(our_crystal, TYPE_PROC_REF(/obj/machinery/atmospherics/supermatter_crystal, manual_start), 3000), 3 SECONDS)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/summonitem
|
||||
/datum/spell/summonitem
|
||||
name = "Instant Summons"
|
||||
desc = "This spell can be used to recall a previously marked item to your hand from anywhere in the universe."
|
||||
school = "transmutation"
|
||||
@@ -14,10 +14,10 @@
|
||||
var/static/list/blacklisted_summons = list(/obj/machinery/computer/cryopod = TRUE, /obj/machinery/atmospherics = TRUE, /obj/structure/disposalholder = TRUE, /obj/machinery/disposal = TRUE)
|
||||
action_icon_state = "summons"
|
||||
|
||||
/obj/effect/proc_holder/spell/summonitem/create_new_targeting()
|
||||
/datum/spell/summonitem/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/summonitem/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/summonitem/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/target in targets)
|
||||
var/list/hand_items = list(target.get_active_hand(),target.get_inactive_hand())
|
||||
var/butterfingers = FALSE
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/obj/effect/proc_holder/spell/touch
|
||||
/datum/spell/touch
|
||||
var/hand_path = /obj/item/melee/touch_attack
|
||||
var/obj/item/melee/touch_attack/attached_hand = null
|
||||
var/on_remove_message = TRUE
|
||||
invocation_type = "none" //you scream on connecting, not summoning
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/create_new_targeting()
|
||||
/datum/spell/touch/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/Click(mob/user = usr)
|
||||
/datum/spell/touch/Click(mob/user = usr)
|
||||
if(attached_hand)
|
||||
discharge_hand(user, TRUE)
|
||||
return FALSE
|
||||
charge_hand(user)
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/proc/charge_hand(mob/living/carbon/user)
|
||||
/datum/spell/touch/proc/charge_hand(mob/living/carbon/user)
|
||||
var/hand_handled = 1
|
||||
attached_hand = new hand_path(src)
|
||||
RegisterSignal(user, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(discharge_hand))
|
||||
@@ -36,7 +36,7 @@
|
||||
to_chat(user, "<span class='notice'>You channel the power of the spell to your hand.</span>")
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/proc/discharge_hand(atom/target, any = FALSE)
|
||||
/datum/spell/touch/proc/discharge_hand(atom/target, any = FALSE)
|
||||
SIGNAL_HANDLER
|
||||
var/mob/living/carbon/user = action.owner
|
||||
if(!istype(attached_hand))
|
||||
@@ -48,7 +48,7 @@
|
||||
to_chat(user, "<span class='notice'>You draw the power out of your hand.</span>")
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/disintegrate
|
||||
/datum/spell/touch/disintegrate
|
||||
name = "Disintegrate"
|
||||
desc = "This spell charges your hand with vile energy that can be used to violently explode victims."
|
||||
hand_path = /obj/item/melee/touch_attack/disintegrate
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
action_icon_state = "gib"
|
||||
|
||||
/obj/effect/proc_holder/spell/touch/flesh_to_stone
|
||||
/datum/spell/touch/flesh_to_stone
|
||||
name = "Flesh to Stone"
|
||||
desc = "This spell charges your hand with the power to turn victims into inert statues for a long period of time."
|
||||
hand_path = /obj/item/melee/touch_attack/fleshtostone
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/obj/effect/proc_holder/spell/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/trigger/New()
|
||||
..()
|
||||
|
||||
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/trigger/Destroy()
|
||||
for(var/spell in contents)
|
||||
qdel(spell)
|
||||
linked_spells = null
|
||||
starting_spells = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/trigger/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/target in targets)
|
||||
for(var/obj/effect/proc_holder/spell/spell in contents)
|
||||
spell.perform(list(target), 0, user = user)
|
||||
for(var/obj/effect/proc_holder/spell/spell in linked_spells)
|
||||
spell.perform(list(target), 0, user = user)
|
||||
|
||||
return
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/turf_teleport
|
||||
/datum/spell/turf_teleport
|
||||
name = "Turf Teleport"
|
||||
desc = "This spell teleports the target to the turf in range."
|
||||
nonabstract_req = TRUE
|
||||
@@ -14,12 +14,12 @@
|
||||
var/sound1 = 'sound/weapons/zapbang.ogg'
|
||||
var/sound2 = 'sound/weapons/zapbang.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/turf_teleport/create_new_targeting()
|
||||
/datum/spell/turf_teleport/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/turf_teleport/cast(list/targets,mob/living/user = usr)
|
||||
/datum/spell/turf_teleport/cast(list/targets,mob/living/user = usr)
|
||||
if(sound1)
|
||||
playsound(get_turf(user), sound1, 50,1)
|
||||
playsound(get_turf(user), sound1, 50, TRUE)
|
||||
|
||||
for(var/mob/living/target in targets)
|
||||
var/list/turfs = new/list()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/projectile/magic_missile
|
||||
/datum/spell/projectile/magic_missile
|
||||
name = "Magic Missile"
|
||||
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
proj_icon_state = "magicm"
|
||||
proj_name = "a magic missile"
|
||||
proj_lingering = 1
|
||||
proj_type = "/obj/effect/proc_holder/spell/inflict_handler/magic_missile"
|
||||
proj_type = /obj/item/projectile/magic/magic_missile
|
||||
|
||||
proj_lifespan = 20
|
||||
proj_step_delay = 2
|
||||
@@ -25,33 +25,33 @@
|
||||
|
||||
sound = 'sound/magic/magic_missile.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/projectile/magic_missile/create_new_targeting()
|
||||
/datum/spell/projectile/magic_missile/create_new_targeting()
|
||||
var/datum/spell_targeting/targeted/T = new()
|
||||
T.allowed_type = /mob/living
|
||||
T.max_targets = INFINITY
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/inflict_handler/magic_missile
|
||||
amt_weakened = 6 SECONDS
|
||||
sound = 'sound/magic/mm_hit.ogg'
|
||||
/obj/item/projectile/magic/magic_missile
|
||||
name = "Magic Missile"
|
||||
hitsound = 'sound/magic/mm_hit.ogg'
|
||||
weaken = 6 SECONDS
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/projectile/honk_missile
|
||||
/datum/spell/projectile/honk_missile
|
||||
name = "Honk Missile"
|
||||
desc = "This spell fires several, slow moving, magic bikehorns at nearby targets."
|
||||
|
||||
school = "evocation"
|
||||
base_cooldown = 60
|
||||
base_cooldown = 6 SECONDS
|
||||
clothes_req = FALSE
|
||||
invocation = "HONK GY AMA"
|
||||
invocation_type = "shout"
|
||||
cooldown_min = 60 //35 deciseconds reduction per rank
|
||||
cooldown_min = 6 SECONDS
|
||||
|
||||
proj_icon = 'icons/obj/items.dmi'
|
||||
proj_icon_state = "bike_horn"
|
||||
proj_name = "A bike horn"
|
||||
proj_lingering = 1
|
||||
proj_type = "/obj/effect/proc_holder/spell/inflict_handler/honk_missile"
|
||||
proj_type = /obj/item/projectile/magic/magic_missile/honk_missile
|
||||
|
||||
proj_lifespan = 20
|
||||
proj_step_delay = 5
|
||||
@@ -65,25 +65,25 @@
|
||||
|
||||
sound = 'sound/items/bikehorn.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/projectile/honk_missile/create_new_targeting()
|
||||
/datum/spell/projectile/honk_missile/create_new_targeting()
|
||||
var/datum/spell_targeting/targeted/T = new()
|
||||
T.allowed_type = /mob/living
|
||||
T.max_targets = INFINITY
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/inflict_handler/honk_missile
|
||||
amt_weakened = 6 SECONDS
|
||||
sound = 'sound/items/bikehorn.ogg'
|
||||
/obj/item/projectile/magic/magic_missile/honk_missile
|
||||
name = "Funny Missile"
|
||||
hitsound = 'sound/items/bikehorn.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/noclothes
|
||||
/datum/spell/noclothes
|
||||
name = "No Clothes"
|
||||
desc = "This always-on spell allows you to cast magic without your garments."
|
||||
action_icon_state = "no_clothes"
|
||||
|
||||
/obj/effect/proc_holder/spell/noclothes/create_new_targeting()
|
||||
/datum/spell/noclothes/create_new_targeting()
|
||||
return new /datum/spell_targeting/self // Dummy value
|
||||
|
||||
/obj/effect/proc_holder/spell/genetic/mutate
|
||||
/datum/spell/genetic/mutate
|
||||
name = "Mutate"
|
||||
desc = "This spell causes you to turn into a hulk and gain laser vision for a short while."
|
||||
|
||||
@@ -102,14 +102,14 @@
|
||||
action_icon_state = "mutate"
|
||||
sound = 'sound/magic/mutate.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/genetic/mutate/Initialize(mapload)
|
||||
. = ..()
|
||||
/datum/spell/genetic/mutate/New()
|
||||
..()
|
||||
mutations = list(GLOB.hulkblock)
|
||||
|
||||
/obj/effect/proc_holder/spell/genetic/mutate/create_new_targeting()
|
||||
/datum/spell/genetic/mutate/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/smoke
|
||||
/datum/spell/smoke
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
|
||||
|
||||
@@ -125,13 +125,13 @@
|
||||
|
||||
action_icon_state = "smoke"
|
||||
|
||||
/obj/effect/proc_holder/spell/smoke/create_new_targeting()
|
||||
/datum/spell/smoke/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/emplosion/disable_tech
|
||||
/datum/spell/emplosion/disable_tech
|
||||
name = "Disable Tech"
|
||||
desc = "This spell disables all weapons, cameras and most other technology in range."
|
||||
base_cooldown = 400
|
||||
base_cooldown = 40 SECONDS
|
||||
clothes_req = TRUE
|
||||
invocation = "NEC CANTIO"
|
||||
invocation_type = "shout"
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
sound = 'sound/magic/disable_tech.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/turf_teleport/blink
|
||||
/datum/spell/turf_teleport/blink
|
||||
name = "Blink"
|
||||
desc = "This spell randomly teleports you a short distance."
|
||||
|
||||
@@ -167,10 +167,10 @@
|
||||
sound1 = 'sound/magic/blink.ogg'
|
||||
sound2 = 'sound/magic/blink.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/turf_teleport/blink/create_new_targeting()
|
||||
/datum/spell/turf_teleport/blink/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/area_teleport/teleport
|
||||
/datum/spell/area_teleport/teleport
|
||||
name = "Teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
|
||||
@@ -187,10 +187,10 @@
|
||||
sound1 = 'sound/magic/teleport_diss.ogg'
|
||||
sound2 = 'sound/magic/teleport_app.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/area_teleport/teleport/create_new_targeting()
|
||||
/datum/spell/area_teleport/teleport/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/return_to_teacher
|
||||
/datum/spell/return_to_teacher
|
||||
name = "Return to Teacher"
|
||||
desc = "This spell teleports you back to your teacher."
|
||||
|
||||
@@ -204,16 +204,16 @@
|
||||
action_icon_state = "spell_teleport"
|
||||
var/datum/mind/teacher
|
||||
|
||||
/obj/effect/proc_holder/spell/return_to_teacher/create_new_targeting()
|
||||
/datum/spell/return_to_teacher/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/return_to_teacher/cast(list/targets, mob/living/user = usr)
|
||||
/datum/spell/return_to_teacher/cast(list/targets, mob/living/user = usr)
|
||||
if(!(teacher && teacher.current))
|
||||
to_chat(user, "<span class='danger'>The link to your teacher is broken!</span>")
|
||||
return
|
||||
do_teleport(user, teacher.current, 1, sound_in = 'sound/magic/blink.ogg', sound_out = 'sound/magic/blink.ogg', safe_turf_pick = TRUE)
|
||||
|
||||
/obj/effect/proc_holder/spell/forcewall
|
||||
/datum/spell/forcewall
|
||||
name = "Force Wall"
|
||||
desc = "This spell creates a 3 tile wide unbreakable wall that only you can pass through, and does not need wizard garb. Lasts 30 seconds."
|
||||
|
||||
@@ -227,10 +227,10 @@
|
||||
cooldown_min = 5 SECONDS //25 deciseconds reduction per rank
|
||||
var/wall_type = /obj/effect/forcefield/wizard
|
||||
|
||||
/obj/effect/proc_holder/spell/forcewall/create_new_targeting()
|
||||
/datum/spell/forcewall/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/forcewall/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/forcewall/cast(list/targets, mob/user = usr)
|
||||
new wall_type(get_turf(user), user)
|
||||
if(user.dir == SOUTH || user.dir == NORTH)
|
||||
new wall_type(get_step(user, EAST), user)
|
||||
@@ -239,10 +239,10 @@
|
||||
new wall_type(get_step(user, NORTH), user)
|
||||
new wall_type(get_step(user, SOUTH), user)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/timestop
|
||||
/datum/spell/aoe/conjure/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."
|
||||
base_cooldown = 500
|
||||
base_cooldown = 50 SECONDS
|
||||
clothes_req = TRUE
|
||||
invocation = "TOKI WO TOMARE"
|
||||
invocation_type = "shout"
|
||||
@@ -255,7 +255,7 @@
|
||||
aoe_range = 0
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/carp
|
||||
/datum/spell/aoe/conjure/carp
|
||||
name = "Summon Carp"
|
||||
desc = "This spell conjures a simple carp."
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
cast_sound = 'sound/magic/summon_karp.ogg'
|
||||
aoe_range = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/construct
|
||||
/datum/spell/aoe/conjure/construct
|
||||
name = "Artificer"
|
||||
desc = "This spell conjures a construct which may be controlled by Shades"
|
||||
|
||||
@@ -286,7 +286,7 @@
|
||||
cast_sound = 'sound/magic/summonitems_generic.ogg'
|
||||
aoe_range = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/creature
|
||||
/datum/spell/aoe/conjure/creature
|
||||
name = "Summon Creature Swarm"
|
||||
desc = "This spell tears the fabric of reality, allowing horrific daemons to spill forth"
|
||||
|
||||
@@ -301,10 +301,9 @@
|
||||
cast_sound = 'sound/magic/summonitems_generic.ogg'
|
||||
aoe_range = 3
|
||||
|
||||
/obj/effect/proc_holder/spell/trigger/blind
|
||||
/datum/spell/genetic/blind
|
||||
name = "Blind"
|
||||
desc = "This spell temporarily blinds a single person and does not require wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
base_cooldown = 10 SECONDS
|
||||
clothes_req = FALSE
|
||||
@@ -312,30 +311,22 @@
|
||||
invocation_type = "whisper"
|
||||
message = "<span class='notice'>Your eyes cry out in pain!</span>"
|
||||
cooldown_min = 2 SECONDS
|
||||
traits = list(TRAIT_BLIND)
|
||||
|
||||
starting_spells = list("/obj/effect/proc_holder/spell/inflict_handler/blind","/obj/effect/proc_holder/spell/genetic/blind")
|
||||
duration = 30 SECONDS
|
||||
sound = 'sound/magic/blind.ogg'
|
||||
|
||||
action_icon_state = "blind"
|
||||
|
||||
/obj/effect/proc_holder/spell/trigger/blind/create_new_targeting()
|
||||
/datum/spell/genetic/blind/create_new_targeting()
|
||||
var/datum/spell_targeting/click/C = new()
|
||||
C.allowed_type = /mob/living
|
||||
return C
|
||||
|
||||
/obj/effect/proc_holder/spell/inflict_handler/blind
|
||||
amt_eye_blind = 10
|
||||
amt_eye_blurry = 20
|
||||
sound = 'sound/magic/blind.ogg'
|
||||
/datum/spell/genetic/blind/do_additional_effects(mob/living/target)
|
||||
target.EyeBlurry(20 SECONDS)
|
||||
target.EyeBlind(10 SECONDS)
|
||||
SEND_SOUND(target, sound('sound/magic/blind.ogg'))
|
||||
|
||||
/obj/effect/proc_holder/spell/genetic/blind
|
||||
traits = list(TRAIT_BLIND)
|
||||
duration = 300
|
||||
sound = 'sound/magic/blind.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/genetic/blind/create_new_targeting()
|
||||
return new /datum/spell_targeting/self // Dummy value since it is never used by an user directly
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball
|
||||
/datum/spell/fireball
|
||||
name = "Fireball"
|
||||
desc = "This spell fires a fireball at a target and does not require wizard garb."
|
||||
|
||||
@@ -355,21 +346,21 @@
|
||||
|
||||
active = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/apprentice
|
||||
/datum/spell/fireball/apprentice
|
||||
centcom_cancast = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/create_new_targeting()
|
||||
/datum/spell/fireball/create_new_targeting()
|
||||
var/datum/spell_targeting/clicked_atom/external/C = new()
|
||||
C.range = 20
|
||||
return C
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/update_icon_state()
|
||||
/datum/spell/fireball/update_spell_icon()
|
||||
if(!action)
|
||||
return
|
||||
action.button_icon_state = "fireball[active]"
|
||||
action.UpdateButtons()
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/cast(list/targets, mob/living/user = usr)
|
||||
/datum/spell/fireball/cast(list/targets, mob/living/user = usr)
|
||||
var/target = targets[1] //There is only ever one target for fireball
|
||||
var/turf/T = user.loc
|
||||
var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction
|
||||
@@ -386,7 +377,7 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/toolbox
|
||||
/datum/spell/fireball/toolbox
|
||||
name = "Homing Toolbox"
|
||||
desc = "This spell summons and throws a magical homing toolbox at your opponent."
|
||||
sound = 'sound/weapons/smash.ogg'
|
||||
@@ -396,7 +387,7 @@
|
||||
selection_activated_message = "<span class='notice'>You prepare to cast your homing toolbox! <B>Left-click to cast at a target!</B></span>"
|
||||
selection_deactivated_message = "<span class='notice'>You unrobust your toolbox...for now.</span>"
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/homing
|
||||
/datum/spell/fireball/homing
|
||||
name = "Greater Homing Fireball"
|
||||
desc = "This spell fires a strong homing fireball at a target."
|
||||
invocation = "ZI-ONI SOMA"
|
||||
@@ -405,10 +396,10 @@
|
||||
selection_activated_message = "<span class='notice'>You prepare to cast your greater homing fireball spell! <B>Left-click to cast at a target!</B></span>"
|
||||
base_cooldown = 6 SECONDS
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/repulse
|
||||
/datum/spell/aoe/repulse
|
||||
name = "Repulse"
|
||||
desc = "This spell throws everything around the user away."
|
||||
base_cooldown = 400
|
||||
base_cooldown = 40 SECONDS
|
||||
clothes_req = TRUE
|
||||
invocation = "GITTAH WEIGH"
|
||||
invocation_type = "shout"
|
||||
@@ -419,12 +410,12 @@
|
||||
action_icon_state = "repulse"
|
||||
aoe_range = 5
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/repulse/create_new_targeting()
|
||||
/datum/spell/aoe/repulse/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/turf/targeting = new()
|
||||
targeting.range = aoe_range
|
||||
return targeting
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/repulse/cast(list/targets, mob/user = usr, stun_amt = 4 SECONDS)
|
||||
/datum/spell/aoe/repulse/cast(list/targets, mob/user = usr, stun_amt = 4 SECONDS)
|
||||
var/list/thrownatoms = list()
|
||||
var/atom/throwtarget
|
||||
var/distfromcaster
|
||||
@@ -455,24 +446,24 @@
|
||||
spawn(0)
|
||||
AM.throw_at(throwtarget, ((clamp((maxthrow - (clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1)//So stuff gets tossed around at the same time.
|
||||
|
||||
/obj/effect/proc_holder/spell/sacred_flame
|
||||
/datum/spell/sacred_flame
|
||||
name = "Sacred Flame"
|
||||
desc = "Makes everyone around you more flammable, and lights yourself on fire."
|
||||
base_cooldown = 60
|
||||
base_cooldown = 6 SECONDS
|
||||
clothes_req = FALSE
|
||||
invocation = "FI'RAN DADISKO"
|
||||
invocation_type = "shout"
|
||||
action_icon_state = "sacredflame"
|
||||
sound = 'sound/magic/fireball.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/sacred_flame/create_new_targeting()
|
||||
/datum/spell/sacred_flame/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/A = new()
|
||||
A.include_user = TRUE
|
||||
A.range = 6
|
||||
A.allowed_type = /mob/living
|
||||
return A
|
||||
|
||||
/obj/effect/proc_holder/spell/sacred_flame/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/sacred_flame/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/L in targets)
|
||||
L.adjust_fire_stacks(20)
|
||||
if(isliving(user))
|
||||
|
||||
@@ -481,13 +481,13 @@
|
||||
desc = "The subject becomes able to convert excess cellular energy into thermal energy."
|
||||
activation_messages = list("You suddenly feel rather hot.")
|
||||
deactivation_messages = list("You no longer feel uncomfortably hot.")
|
||||
spelltype = /obj/effect/proc_holder/spell/immolate
|
||||
spelltype = /datum/spell/immolate
|
||||
|
||||
/datum/mutation/grant_spell/immolate/New()
|
||||
..()
|
||||
block = GLOB.immolateblock
|
||||
|
||||
/obj/effect/proc_holder/spell/immolate
|
||||
/datum/spell/immolate
|
||||
name = "Incendiary Mitochondria"
|
||||
desc = "The subject becomes able to convert excess cellular energy into thermal energy."
|
||||
panel = "Abilities"
|
||||
@@ -501,10 +501,10 @@
|
||||
|
||||
action_icon_state = "genetic_incendiary"
|
||||
|
||||
/obj/effect/proc_holder/spell/immolate/create_new_targeting()
|
||||
/datum/spell/immolate/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/immolate/cast(list/targets, mob/living/user = usr)
|
||||
/datum/spell/immolate/cast(list/targets, mob/living/user = usr)
|
||||
var/mob/living/carbon/L = user
|
||||
L.adjust_fire_stacks(0.5)
|
||||
L.visible_message("<span class='danger'>[L.name]</b> suddenly bursts into flames!</span>")
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/mutation/grant_spell
|
||||
var/obj/effect/proc_holder/spell/spelltype
|
||||
var/datum/spell/spelltype
|
||||
|
||||
/datum/mutation/grant_spell/activate(mob/M)
|
||||
M.AddSpell(new spelltype(null))
|
||||
@@ -255,7 +255,7 @@
|
||||
return TRUE
|
||||
|
||||
/datum/mutation/grant_spell/deactivate(mob/M)
|
||||
for(var/obj/effect/proc_holder/spell/S in M.mob_spell_list)
|
||||
for(var/datum/spell/S in M.mob_spell_list)
|
||||
if(istype(S, spelltype))
|
||||
M.RemoveSpell(S)
|
||||
..()
|
||||
@@ -268,13 +268,13 @@
|
||||
activation_messages = list("You notice a strange cold tingle in your fingertips.")
|
||||
deactivation_messages = list("Your fingers feel warmer.")
|
||||
instability = GENE_INSTABILITY_MODERATE
|
||||
spelltype = /obj/effect/proc_holder/spell/cryokinesis
|
||||
spelltype = /datum/spell/cryokinesis
|
||||
|
||||
/datum/mutation/grant_spell/cryo/New()
|
||||
..()
|
||||
block = GLOB.cryoblock
|
||||
|
||||
/obj/effect/proc_holder/spell/cryokinesis
|
||||
/datum/spell/cryokinesis
|
||||
name = "Cryokinesis"
|
||||
desc = "Drops the bodytemperature of another person."
|
||||
panel = "Abilities"
|
||||
@@ -291,7 +291,7 @@
|
||||
|
||||
action_icon_state = "genetic_cryo"
|
||||
|
||||
/obj/effect/proc_holder/spell/cryokinesis/create_new_targeting()
|
||||
/datum/spell/cryokinesis/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new()
|
||||
T.allowed_type = /mob/living/carbon
|
||||
T.click_radius = 0
|
||||
@@ -300,7 +300,7 @@
|
||||
T.include_user = TRUE
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/cryokinesis/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/cryokinesis/cast(list/targets, mob/user = usr)
|
||||
|
||||
var/mob/living/carbon/C = targets[1]
|
||||
|
||||
@@ -339,13 +339,13 @@
|
||||
deactivation_messages = list("You don't feel quite so hungry anymore.")
|
||||
instability = GENE_INSTABILITY_MODERATE
|
||||
|
||||
spelltype=/obj/effect/proc_holder/spell/eat
|
||||
spelltype=/datum/spell/eat
|
||||
|
||||
/datum/mutation/grant_spell/mattereater/New()
|
||||
..()
|
||||
block = GLOB.eatblock
|
||||
|
||||
/obj/effect/proc_holder/spell/eat
|
||||
/datum/spell/eat
|
||||
name = "Eat"
|
||||
desc = "Eat just about anything!"
|
||||
panel = "Abilities"
|
||||
@@ -358,10 +358,10 @@
|
||||
|
||||
action_icon_state = "genetic_eat"
|
||||
|
||||
/obj/effect/proc_holder/spell/eat/create_new_targeting()
|
||||
/datum/spell/eat/create_new_targeting()
|
||||
return new /datum/spell_targeting/matter_eater
|
||||
|
||||
/obj/effect/proc_holder/spell/eat/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE)
|
||||
/datum/spell/eat/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -374,7 +374,7 @@
|
||||
can_eat = FALSE
|
||||
return can_eat
|
||||
|
||||
/obj/effect/proc_holder/spell/eat/proc/doHeal(mob/user)
|
||||
/datum/spell/eat/proc/doHeal(mob/user)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
for(var/name in H.bodyparts_by_name)
|
||||
@@ -390,7 +390,7 @@
|
||||
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/eat/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/eat/cast(list/targets, mob/user = usr)
|
||||
if(!targets.len)
|
||||
to_chat(user, "<span class='notice'>No target found in range.</span>")
|
||||
return
|
||||
@@ -462,13 +462,13 @@
|
||||
deactivation_messages = list("Your leg muscles shrink back to normal.")
|
||||
instability = GENE_INSTABILITY_MODERATE
|
||||
|
||||
spelltype =/obj/effect/proc_holder/spell/leap
|
||||
spelltype =/datum/spell/leap
|
||||
|
||||
/datum/mutation/grant_spell/jumpy/New()
|
||||
..()
|
||||
block = GLOB.jumpblock
|
||||
|
||||
/obj/effect/proc_holder/spell/leap
|
||||
/datum/spell/leap
|
||||
name = "Jump"
|
||||
desc = "Leap great distances!"
|
||||
panel = "Abilities"
|
||||
@@ -481,10 +481,10 @@
|
||||
|
||||
action_icon_state = "genetic_jump"
|
||||
|
||||
/obj/effect/proc_holder/spell/leap/create_new_targeting()
|
||||
/datum/spell/leap/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/leap/cast(list/targets, mob/living/user = usr)
|
||||
/datum/spell/leap/cast(list/targets, mob/living/user = usr)
|
||||
var/failure = FALSE
|
||||
if(ismob(user.loc) || IS_HORIZONTAL(user) || user.IsStunned() || user.buckled || user.stat)
|
||||
to_chat(user, "<span class='warning'>You can't jump right now!</span>")
|
||||
@@ -551,7 +551,7 @@
|
||||
name = "Polymorphism"
|
||||
desc = "Enables the subject to reconfigure their appearance to mimic that of others."
|
||||
|
||||
spelltype =/obj/effect/proc_holder/spell/polymorph
|
||||
spelltype =/datum/spell/polymorph
|
||||
//cooldown = 1800
|
||||
activation_messages = list("You don't feel entirely like yourself somehow.")
|
||||
deactivation_messages = list("You feel secure in your identity.")
|
||||
@@ -561,7 +561,7 @@
|
||||
..()
|
||||
block = GLOB.polymorphblock
|
||||
|
||||
/obj/effect/proc_holder/spell/polymorph
|
||||
/datum/spell/polymorph
|
||||
name = "Polymorph"
|
||||
desc = "Mimic the appearance of others!"
|
||||
panel = "Abilities"
|
||||
@@ -577,7 +577,7 @@
|
||||
|
||||
action_icon_state = "genetic_poly"
|
||||
|
||||
/obj/effect/proc_holder/spell/polymorph/create_new_targeting()
|
||||
/datum/spell/polymorph/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new()
|
||||
T.try_auto_target = FALSE
|
||||
T.click_radius = -1
|
||||
@@ -585,7 +585,7 @@
|
||||
T.selection_type = SPELL_SELECTION_RANGE
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/polymorph/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/polymorph/cast(list/targets, mob/user = usr)
|
||||
var/mob/living/carbon/human/target = targets[1]
|
||||
|
||||
user.visible_message("<span class='warning'>[user]'s body shifts and contorts.</span>")
|
||||
@@ -605,7 +605,7 @@
|
||||
name = "Empathic Thought"
|
||||
desc = "The subject becomes able to read the minds of others for certain information."
|
||||
|
||||
spelltype = /obj/effect/proc_holder/spell/empath
|
||||
spelltype = /datum/spell/empath
|
||||
activation_messages = list("You suddenly notice more about others than you did before.")
|
||||
deactivation_messages = list("You no longer feel able to sense intentions.")
|
||||
instability = GENE_INSTABILITY_MINOR
|
||||
@@ -614,10 +614,10 @@
|
||||
..()
|
||||
block = GLOB.empathblock
|
||||
|
||||
/obj/effect/proc_holder/spell/empath
|
||||
/datum/spell/empath
|
||||
name = "Read Mind"
|
||||
desc = "Read the minds of others for information."
|
||||
base_cooldown = 180
|
||||
base_cooldown = 18 SECONDS
|
||||
clothes_req = FALSE
|
||||
human_req = TRUE
|
||||
stat_allowed = CONSCIOUS
|
||||
@@ -625,13 +625,13 @@
|
||||
|
||||
action_icon_state = "genetic_empath"
|
||||
|
||||
/obj/effect/proc_holder/spell/empath/create_new_targeting()
|
||||
/datum/spell/empath/create_new_targeting()
|
||||
var/datum/spell_targeting/targeted/T = new()
|
||||
T.allowed_type = /mob/living/carbon
|
||||
T.selection_type = SPELL_SELECTION_RANGE
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/empath/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/empath/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/carbon/M in targets)
|
||||
if(!iscarbon(M))
|
||||
to_chat(user, "<span class='warning'>You may only use this on other organic beings.</span>")
|
||||
@@ -714,7 +714,7 @@
|
||||
/datum/mutation/grant_spell/morph
|
||||
name = "Morphism"
|
||||
desc = "Enables the subject to reconfigure their appearance to that of any human."
|
||||
spelltype =/obj/effect/proc_holder/spell/morph
|
||||
spelltype =/datum/spell/morph
|
||||
activation_messages = list("Your body feels like it can alter its appearance.")
|
||||
deactivation_messages = list("Your body doesn't feel capable of altering its appearance.")
|
||||
instability = GENE_INSTABILITY_MODERATE
|
||||
@@ -723,7 +723,7 @@
|
||||
..()
|
||||
block = GLOB.morphblock
|
||||
|
||||
/obj/effect/proc_holder/spell/morph
|
||||
/datum/spell/morph
|
||||
name = "Morph"
|
||||
desc = "Mimic the appearance of your choice!"
|
||||
panel = "Abilities"
|
||||
@@ -735,10 +735,10 @@
|
||||
|
||||
action_icon_state = "genetic_morph"
|
||||
|
||||
/obj/effect/proc_holder/spell/morph/create_new_targeting()
|
||||
/datum/spell/morph/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/morph/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/morph/cast(list/targets, mob/user = usr)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
|
||||
@@ -897,7 +897,7 @@
|
||||
deactivation_messages = list("You no longer feel you can project your thoughts.")
|
||||
instability = GENE_INSTABILITY_MINOR
|
||||
|
||||
spelltype =/obj/effect/proc_holder/spell/remotetalk
|
||||
spelltype =/datum/spell/remotetalk
|
||||
|
||||
/datum/mutation/grant_spell/remotetalk/New()
|
||||
..()
|
||||
@@ -905,15 +905,15 @@
|
||||
|
||||
/datum/mutation/grant_spell/remotetalk/activate(mob/living/M)
|
||||
..()
|
||||
M.AddSpell(new /obj/effect/proc_holder/spell/mindscan(null))
|
||||
M.AddSpell(new /datum/spell/mindscan(null))
|
||||
|
||||
/datum/mutation/grant_spell/remotetalk/deactivate(mob/user)
|
||||
..()
|
||||
for(var/obj/effect/proc_holder/spell/S in user.mob_spell_list)
|
||||
if(istype(S, /obj/effect/proc_holder/spell/mindscan))
|
||||
for(var/datum/spell/S in user.mob_spell_list)
|
||||
if(istype(S, /datum/spell/mindscan))
|
||||
user.RemoveSpell(S)
|
||||
|
||||
/obj/effect/proc_holder/spell/remotetalk
|
||||
/datum/spell/remotetalk
|
||||
name = "Project Mind"
|
||||
desc = "Make people understand your thoughts!"
|
||||
base_cooldown = 0
|
||||
@@ -924,10 +924,10 @@
|
||||
|
||||
action_icon_state = "genetic_project"
|
||||
|
||||
/obj/effect/proc_holder/spell/remotetalk/create_new_targeting()
|
||||
/datum/spell/remotetalk/create_new_targeting()
|
||||
return new /datum/spell_targeting/telepathic
|
||||
|
||||
/obj/effect/proc_holder/spell/remotetalk/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/remotetalk/cast(list/targets, mob/user = usr)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(user.mind?.miming) // Dont let mimes telepathically talk
|
||||
@@ -949,7 +949,7 @@
|
||||
for(var/mob/dead/observer/G in GLOB.player_list)
|
||||
G.show_message("<i>Telepathic message from <b>[user]</b> ([ghost_follow_link(user, ghost=G)]) to <b>[target]</b> ([ghost_follow_link(target, ghost=G)]): [say]</i>")
|
||||
|
||||
/obj/effect/proc_holder/spell/mindscan
|
||||
/datum/spell/mindscan
|
||||
name = "Scan Mind"
|
||||
desc = "Offer people a chance to share their thoughts!"
|
||||
base_cooldown = 0
|
||||
@@ -959,10 +959,10 @@
|
||||
action_icon_state = "genetic_mindscan"
|
||||
var/list/available_targets = list()
|
||||
|
||||
/obj/effect/proc_holder/spell/mindscan/create_new_targeting()
|
||||
/datum/spell/mindscan/create_new_targeting()
|
||||
return new /datum/spell_targeting/telepathic
|
||||
|
||||
/obj/effect/proc_holder/spell/mindscan/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/mindscan/cast(list/targets, mob/user = usr)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
for(var/mob/living/target in targets)
|
||||
@@ -974,13 +974,13 @@
|
||||
available_targets += target
|
||||
addtimer(CALLBACK(src, PROC_REF(removeAvailability), target), 100)
|
||||
|
||||
/obj/effect/proc_holder/spell/mindscan/proc/removeAvailability(mob/living/target)
|
||||
/datum/spell/mindscan/proc/removeAvailability(mob/living/target)
|
||||
if(target in available_targets)
|
||||
available_targets -= target
|
||||
if(!(target in available_targets))
|
||||
target.show_message("<i><span class='abductor'>You feel the sensation fade...</span></i>")
|
||||
|
||||
/obj/effect/proc_holder/spell/mindscan/Topic(href, href_list)
|
||||
/datum/spell/mindscan/Topic(href, href_list)
|
||||
var/mob/living/user
|
||||
if(href_list["user"])
|
||||
user = locateUID(href_list["user"])
|
||||
@@ -1005,7 +1005,7 @@
|
||||
for(var/mob/dead/observer/G in GLOB.player_list)
|
||||
G.show_message("<i>Telepathic response from <b>[target]</b> ([ghost_follow_link(target, ghost=G)]) to <b>[user]</b> ([ghost_follow_link(user, ghost=G)]): [say]</i>")
|
||||
|
||||
/obj/effect/proc_holder/spell/mindscan/Destroy()
|
||||
/datum/spell/mindscan/Destroy()
|
||||
available_targets.Cut()
|
||||
return ..()
|
||||
|
||||
@@ -1015,7 +1015,7 @@
|
||||
deactivation_messages = list("Your mind can no longer can see things from afar.")
|
||||
instability = GENE_INSTABILITY_MINOR
|
||||
|
||||
spelltype =/obj/effect/proc_holder/spell/remoteview
|
||||
spelltype =/datum/spell/remoteview
|
||||
|
||||
/datum/mutation/grant_spell/remoteview/New()
|
||||
..()
|
||||
@@ -1028,10 +1028,10 @@
|
||||
H.remoteview_target = null
|
||||
H.reset_perspective()
|
||||
|
||||
/obj/effect/proc_holder/spell/remoteview
|
||||
/datum/spell/remoteview
|
||||
name = "Remote View"
|
||||
desc = "Spy on people from any range!"
|
||||
base_cooldown = 100
|
||||
base_cooldown = 10 SECONDS
|
||||
|
||||
clothes_req = FALSE
|
||||
stat_allowed = CONSCIOUS
|
||||
@@ -1039,10 +1039,10 @@
|
||||
|
||||
action_icon_state = "genetic_view"
|
||||
|
||||
/obj/effect/proc_holder/spell/remoteview/create_new_targeting()
|
||||
/datum/spell/remoteview/create_new_targeting()
|
||||
return new /datum/spell_targeting/remoteview
|
||||
|
||||
/obj/effect/proc_holder/spell/remoteview/cast(list/targets, mob/user = usr)
|
||||
/datum/spell/remoteview/cast(list/targets, mob/user = usr)
|
||||
var/mob/living/carbon/human/H
|
||||
if(ishuman(user))
|
||||
H = user
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
name = "Hallucinations"
|
||||
desc = "Gives hallucinations to a target at range. A silent and invisible spell."
|
||||
button_icon_state = "horror"
|
||||
var/obj/effect/proc_holder/horror/PH
|
||||
var/datum/spell/horror/PH
|
||||
charges = 4
|
||||
|
||||
/datum/action/innate/cult/blood_spell/horror/New()
|
||||
@@ -274,7 +274,7 @@
|
||||
..()
|
||||
|
||||
/datum/action/innate/cult/blood_spell/horror/Destroy()
|
||||
var/obj/effect/proc_holder/horror/destroy = PH
|
||||
var/datum/spell/horror/destroy = PH
|
||||
. = ..()
|
||||
if(!QDELETED(destroy))
|
||||
QDEL_NULL(destroy)
|
||||
@@ -283,24 +283,24 @@
|
||||
PH.toggle(owner) //the important bit
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/horror
|
||||
/datum/spell/horror
|
||||
active = FALSE
|
||||
ranged_mousepointer = 'icons/effects/cult_target.dmi'
|
||||
var/datum/action/innate/cult/blood_spell/attached_action
|
||||
|
||||
/obj/effect/proc_holder/horror/Destroy()
|
||||
/datum/spell/horror/Destroy()
|
||||
var/datum/action/innate/cult/blood_spell/AA = attached_action
|
||||
. = ..()
|
||||
if(!QDELETED(AA))
|
||||
QDEL_NULL(AA)
|
||||
|
||||
/obj/effect/proc_holder/horror/proc/toggle(mob/user)
|
||||
/datum/spell/horror/proc/toggle(mob/user)
|
||||
if(active)
|
||||
remove_ranged_ability(user, "<span class='cult'>You dispel the magic...</span>")
|
||||
else
|
||||
add_ranged_ability(user, "<span class='cult'>You prepare to horrify a target...</span>")
|
||||
|
||||
/obj/effect/proc_holder/horror/InterceptClickOn(mob/living/user, params, atom/target)
|
||||
/datum/spell/horror/InterceptClickOn(mob/living/user, params, atom/target)
|
||||
if(..())
|
||||
return
|
||||
if(ranged_ability_user.incapacitated() || !IS_CULTIST(user))
|
||||
|
||||
@@ -4,117 +4,91 @@
|
||||
// crit percent
|
||||
#define MALF_AI_ROLL_CRIT_CHANCE 5
|
||||
|
||||
//The malf AI action subtype. All malf actions are subtypes of this.
|
||||
/datum/action/innate/ai
|
||||
name = "AI Action"
|
||||
//The malf AI spell subtype. All malf actions are subtypes of this.
|
||||
/datum/spell/ai_spell
|
||||
name = "AI Spell"
|
||||
desc = "You aren't entirely sure what this does, but it's very beepy and boopy."
|
||||
background_icon_state = "bg_tech_blue"
|
||||
var/mob/living/silicon/ai/owner_AI //The owner AI, so we don't have to typecast every time
|
||||
action_background_icon_state = "bg_tech_blue"
|
||||
clothes_req = FALSE
|
||||
base_cooldown = 0
|
||||
var/uses //If we have multiple uses of the same power
|
||||
var/auto_use_uses = TRUE //If we automatically use up uses on each activation
|
||||
var/cooldown_period //If applicable, the time in deciseconds we have to wait before using any more modules
|
||||
|
||||
/datum/action/innate/ai/Grant(mob/living/L)
|
||||
. = ..()
|
||||
if(!isAI(owner))
|
||||
WARNING("AI action [name] attempted to grant itself to non-AI mob [L.real_name] ([L.key])!")
|
||||
qdel(src)
|
||||
else
|
||||
owner_AI = owner
|
||||
/datum/spell/ai_spell/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/datum/action/innate/ai/IsAvailable()
|
||||
/datum/spell/ai_spell/can_cast(mob/living/silicon/ai/user, charge_check, show_message)
|
||||
. = ..()
|
||||
if(owner_AI && owner_AI.malf_cooldown > world.time)
|
||||
if(!.)
|
||||
return
|
||||
if(!istype(user))
|
||||
stack_trace("A non ai ([user]) tried to cast an AI spell.")
|
||||
user.RemoveSpell(src)
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/ai/Trigger(left_click)
|
||||
/datum/spell/ai_spell/after_cast(list/targets, mob/user)
|
||||
. = ..()
|
||||
if(auto_use_uses)
|
||||
adjust_uses(-1)
|
||||
if(cooldown_period)
|
||||
owner_AI.malf_cooldown = world.time + cooldown_period
|
||||
adjust_uses(-1, user)
|
||||
|
||||
/datum/action/innate/ai/proc/adjust_uses(amt, silent)
|
||||
/datum/spell/ai_spell/proc/adjust_uses(amt, mob/living/silicon/ai/owner, silent)
|
||||
uses += amt
|
||||
if(!silent && uses)
|
||||
to_chat(owner, "<span class='notice'>[name] now has <b>[uses]</b> use[uses > 1 ? "s" : ""] remaining.</span>")
|
||||
if(!uses)
|
||||
if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
|
||||
to_chat(owner, "<span class='warning'>[name] has run out of uses!</span>")
|
||||
qdel(src)
|
||||
owner.RemoveSpell(src)
|
||||
if(QDELETED(src) || uses) //Not sure if not having src here would cause a runtime, so it's here to be safe
|
||||
return
|
||||
desc = "[initial(desc)] It has [uses] use\s remaining."
|
||||
UpdateButtons()
|
||||
|
||||
//Framework for ranged abilities that can have different effects by left-clicking stuff.
|
||||
/datum/action/innate/ai/ranged
|
||||
/datum/spell/ai_spell/ranged
|
||||
name = "Ranged AI Action"
|
||||
auto_use_uses = FALSE //This is so we can do the thing and disable/enable freely without having to constantly add uses
|
||||
var/obj/effect/proc_holder/ranged_ai/linked_ability //The linked proc holder that contains the actual ability code
|
||||
var/linked_ability_type //The path of our linked ability
|
||||
selection_activated_message = "<span class='notice'>Hello World!</span>"
|
||||
selection_deactivated_message = "<span class='danger'>Goodbye Cruel World!</span>"
|
||||
|
||||
/datum/action/innate/ai/ranged/New()
|
||||
if(!linked_ability_type)
|
||||
WARNING("Ranged AI action [name] attempted to spawn without a linked ability!")
|
||||
qdel(src) //uh oh!
|
||||
return
|
||||
linked_ability = new linked_ability_type()
|
||||
linked_ability.attached_action = src
|
||||
..()
|
||||
|
||||
/datum/action/innate/ai/ranged/adjust_uses(amt, silent)
|
||||
/datum/spell/ai_spell/ranged/adjust_uses(amt, mob/living/silicon/ai/owner, silent)
|
||||
uses += amt
|
||||
if(!silent && uses)
|
||||
to_chat(owner, "<span class='notice'>[name] now has <b>[uses]</b> use[uses > 1 ? "s" : ""] remaining.</span>")
|
||||
if(!uses)
|
||||
if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
|
||||
to_chat(owner, "<span class='warning'>[name] has run out of uses!</span>")
|
||||
Remove(owner)
|
||||
QDEL_IN(src, 100) //let any active timers on us finish up
|
||||
owner.mob_spell_list -= src
|
||||
QDEL_IN(src, 10 SECONDS) //let any active timers on us finish up
|
||||
|
||||
/datum/action/innate/ai/ranged/Destroy()
|
||||
QDEL_NULL(linked_ability)
|
||||
return ..()
|
||||
/datum/spell/ai_spell/ranged/create_new_targeting()
|
||||
var/datum/spell_targeting/clicked_atom/external/C = new()
|
||||
C.range = INFINITY
|
||||
return C
|
||||
|
||||
/datum/action/innate/ai/ranged/Activate()
|
||||
linked_ability.toggle(owner)
|
||||
return TRUE
|
||||
|
||||
//The actual ranged proc holder.
|
||||
/obj/effect/proc_holder/ranged_ai
|
||||
var/enable_text = "<span class='notice'>Hello World!</span>" //Appears when the user activates the ability
|
||||
var/disable_text = "<span class='danger'>Goodbye Cruel World!</span>" //Context clues!
|
||||
var/datum/action/innate/ai/ranged/attached_action
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/proc/toggle(mob/user)
|
||||
if(active)
|
||||
remove_ranged_ability(user, disable_text)
|
||||
else
|
||||
add_ranged_ability(user, enable_text)
|
||||
|
||||
/datum/action/innate/ai/choose_modules
|
||||
/datum/spell/ai_spell/choose_modules
|
||||
name = "Choose Modules"
|
||||
desc = "Spend your processing time to gain a variety of different abilities."
|
||||
button_icon_state = "choose_module"
|
||||
action_icon_state = "choose_module"
|
||||
auto_use_uses = FALSE // This is an infinite ability.
|
||||
create_attack_logs = FALSE
|
||||
|
||||
/datum/action/innate/ai/choose_modules/Trigger(left_click)
|
||||
/datum/spell/ai_spell/choose_modules/cast(list/targets, mob/living/silicon/ai/user)
|
||||
. = ..()
|
||||
owner_AI.malf_picker.use(owner_AI)
|
||||
user.malf_picker.use(user)
|
||||
|
||||
/datum/action/innate/ai/return_to_core
|
||||
/datum/spell/ai_spell/return_to_core
|
||||
name = "Return to Main Core"
|
||||
desc = "Leave the APC you are shunted to, and return to your core."
|
||||
icon_icon = 'icons/obj/power.dmi'
|
||||
button_icon_state = "apcemag"
|
||||
action_icon = 'icons/obj/power.dmi'
|
||||
action_icon_state = "apcemag"
|
||||
auto_use_uses = FALSE // Here just to prevent the "You have X uses remaining" from popping up.
|
||||
|
||||
/datum/action/innate/ai/return_to_core/Trigger(left_click)
|
||||
/datum/spell/ai_spell/return_to_core/cast(list/targets, mob/living/silicon/ai/user)
|
||||
. = ..()
|
||||
var/obj/machinery/power/apc/apc = owner_AI.loc
|
||||
var/obj/machinery/power/apc/apc = user.loc
|
||||
if(!istype(apc)) // This shouldn't happen but here for safety.
|
||||
to_chat(src, "<span class='notice'>You are already in your Main Core.</span>")
|
||||
to_chat(user, "<span class='notice'>You are already in your Main Core.</span>")
|
||||
return
|
||||
apc.malfvacate()
|
||||
qdel(src)
|
||||
@@ -127,9 +101,9 @@
|
||||
|
||||
/datum/module_picker/New()
|
||||
possible_modules = list()
|
||||
for(var/type in typesof(/datum/AI_Module))
|
||||
for(var/type in subtypesof(/datum/AI_Module))
|
||||
var/datum/AI_Module/AM = new type
|
||||
if((AM.power_type && AM.power_type != /datum/action/innate/ai) || AM.upgrade)
|
||||
if(AM.power_type || AM.upgrade)
|
||||
possible_modules += AM
|
||||
|
||||
/datum/module_picker/proc/use(mob/user)
|
||||
@@ -167,7 +141,7 @@
|
||||
temp = "You cannot afford this module."
|
||||
break
|
||||
|
||||
var/datum/action/innate/ai/action = locate(AM.power_type) in A.actions
|
||||
var/datum/spell/ai_spell/action = locate(AM.power_type) in A.mob_spell_list
|
||||
|
||||
// Give the power and take away the money.
|
||||
if(AM.upgrade) //upgrade and upgrade() are separate, be careful!
|
||||
@@ -178,8 +152,8 @@
|
||||
else
|
||||
if(AM.power_type)
|
||||
if(!action) //Unlocking for the first time
|
||||
var/datum/action/AC = new AM.power_type
|
||||
AC.Grant(A)
|
||||
var/datum/spell/ai_spell/AC = new AM.power_type
|
||||
A.AddSpell(AC)
|
||||
A.current_modules += new AM.type
|
||||
temp = AM.description
|
||||
if(AM.one_purchase)
|
||||
@@ -207,7 +181,7 @@
|
||||
var/description = ""
|
||||
var/cost = 5
|
||||
var/one_purchase = FALSE //If this module can only be purchased once. This always applies to upgrades, even if the variable is set to false.
|
||||
var/power_type = /datum/action/innate/ai //If the module gives an active ability, use this. Mutually exclusive with upgrade.
|
||||
var/power_type = /datum/spell/ai_spell //If the module gives an active ability, use this. Mutually exclusive with upgrade.
|
||||
var/upgrade //If the module gives a passive upgrade, use this. Mutually exclusive with power_type.
|
||||
var/unlock_text = "<span class='notice'>Hello World!</span>" //Text shown when an ability is unlocked
|
||||
var/unlock_sound //Sound played when an ability is unlocked
|
||||
@@ -223,36 +197,39 @@
|
||||
description = "Activate a weapon that will disintegrate all organic life on the station after a 450 second delay. Can only be used while on the station, will fail if your core is moved off station or destroyed."
|
||||
cost = 130
|
||||
one_purchase = TRUE
|
||||
power_type = /datum/action/innate/ai/nuke_station
|
||||
power_type = /datum/spell/ai_spell/nuke_station
|
||||
unlock_text = "<span class='notice'>You slowly, carefully, establish a connection with the on-station self-destruct. You can now activate it at any time.</span>"
|
||||
unlock_sound = 'sound/items/timer.ogg'
|
||||
|
||||
/datum/action/innate/ai/nuke_station
|
||||
/datum/spell/ai_spell/nuke_station
|
||||
name = "Doomsday Device"
|
||||
desc = "Activates the doomsday device. This is not reversible."
|
||||
button_icon_state = "doomsday_device"
|
||||
action_icon_state = "doomsday_device"
|
||||
auto_use_uses = FALSE
|
||||
var/in_use
|
||||
|
||||
/datum/action/innate/ai/nuke_station/Activate()
|
||||
var/turf/T = get_turf(owner)
|
||||
/datum/spell/ai_spell/nuke_station/cast(list/targets, mob/living/silicon/ai/user)
|
||||
var/turf/T = get_turf(user)
|
||||
if(!istype(T) || !is_station_level(T.z))
|
||||
to_chat(owner, "<span class='warning'>You cannot activate the doomsday device while off-station!</span>")
|
||||
to_chat(user, "<span class='warning'>You cannot activate the doomsday device while off-station!</span>")
|
||||
return
|
||||
if(tgui_alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", list("confirm = TRUE;", "confirm = FALSE;")) != "confirm = TRUE;")
|
||||
if(tgui_alert(user, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", list("confirm = TRUE;", "confirm = FALSE;")) != "confirm = TRUE;")
|
||||
return
|
||||
if(active)
|
||||
if(!istype(user) || QDELETED(user))
|
||||
return
|
||||
if(in_use)
|
||||
return //prevent the AI from activating an already active doomsday
|
||||
active = TRUE
|
||||
set_us_up_the_bomb()
|
||||
in_use = TRUE
|
||||
set_us_up_the_bomb(user)
|
||||
|
||||
/datum/action/innate/ai/nuke_station/proc/set_us_up_the_bomb()
|
||||
to_chat(owner_AI, "<span class='notice'>Nuclear device armed.</span>")
|
||||
/datum/spell/ai_spell/nuke_station/proc/set_us_up_the_bomb(mob/living/silicon/ai/user)
|
||||
to_chat(user, "<span class='notice'>Nuclear device armed.</span>")
|
||||
GLOB.major_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/AI/aimalf.ogg')
|
||||
SSsecurity_level.set_level(SEC_LEVEL_DELTA)
|
||||
owner_AI.nuking = TRUE
|
||||
var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(owner_AI)
|
||||
owner_AI.doomsday_device = DOOM
|
||||
owner_AI.doomsday_device.start()
|
||||
user.nuking = TRUE
|
||||
var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(user)
|
||||
user.doomsday_device = DOOM
|
||||
user.doomsday_device.start()
|
||||
for(var/obj/item/pinpointer/point in GLOB.pinpointer_list)
|
||||
for(var/mob/living/silicon/ai/A in GLOB.ai_list)
|
||||
if((A.stat != DEAD) && A.nuking)
|
||||
@@ -352,17 +329,17 @@
|
||||
opening all doors on the station."
|
||||
cost = 30
|
||||
one_purchase = TRUE
|
||||
power_type = /datum/action/innate/ai/lockdown
|
||||
power_type = /datum/spell/ai_spell/lockdown
|
||||
unlock_text = "<span class='notice'>You upload a sleeper trojan into the door control systems. You can send a signal to set it off at any time.</span>"
|
||||
|
||||
/datum/action/innate/ai/lockdown
|
||||
/datum/spell/ai_spell/lockdown
|
||||
name = "Lockdown"
|
||||
desc = "Closes, bolts, and depowers every airlock, firelock, and blast door on the station. After 90 seconds, they will reset themselves."
|
||||
button_icon_state = "lockdown"
|
||||
action_icon_state = "lockdown"
|
||||
uses = 1
|
||||
|
||||
/datum/action/innate/ai/lockdown/Activate()
|
||||
to_chat(owner, "<span class='warning'>Lockdown Initiated. Network reset in 90 seconds.</span>")
|
||||
/datum/spell/ai_spell/lockdown/cast(list/targets, mob/user)
|
||||
to_chat(user, "<span class='warning'>Lockdown Initiated. Network reset in 90 seconds.</span>")
|
||||
new /datum/event/door_runtime()
|
||||
|
||||
//Destroy RCDs: Detonates all non-cyborg RCDs on the station.
|
||||
@@ -372,17 +349,17 @@
|
||||
description = "Send a specialised pulse to detonate all hand-held and exosuit Rapid Construction Devices on the station."
|
||||
cost = 25
|
||||
one_purchase = TRUE
|
||||
power_type = /datum/action/innate/ai/destroy_rcds
|
||||
power_type = /datum/spell/ai_spell/destroy_rcds
|
||||
unlock_text = "<span class='notice'>After some improvisation, you rig your onboard radio to be able to send a signal to detonate all RCDs.</span>"
|
||||
|
||||
/datum/action/innate/ai/destroy_rcds
|
||||
/datum/spell/ai_spell/destroy_rcds
|
||||
name = "Destroy RCDs"
|
||||
desc = "Detonate all non-cyborg RCDs on the station."
|
||||
button_icon_state = "detonate_rcds"
|
||||
action_icon_state = "detonate_rcds"
|
||||
uses = 1
|
||||
cooldown_period = 10 SECONDS
|
||||
base_cooldown = 10 SECONDS
|
||||
|
||||
/datum/action/innate/ai/destroy_rcds/Activate()
|
||||
/datum/spell/ai_spell/destroy_rcds/cast(list/targets, mob/user)
|
||||
for(var/obj/item/rcd/RCD in GLOB.rcd_list)
|
||||
if(istype(RCD, /obj/item/rcd/borg)) //Ensures that cyborg RCDs are spared.
|
||||
continue
|
||||
@@ -390,8 +367,8 @@
|
||||
if(is_level_reachable(RCD_turf.z))
|
||||
RCD.detonate_pulse()
|
||||
|
||||
to_chat(owner, "<span class='danger'>RCD detonation pulse emitted.</span>")
|
||||
owner.playsound_local(owner, 'sound/machines/twobeep.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
to_chat(user, "<span class='danger'>RCD detonation pulse emitted.</span>")
|
||||
user.playsound_local(user, 'sound/machines/twobeep.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
|
||||
//Unlock Mech Domination: Unlocks the ability to dominate mechs. Big shocker, right?
|
||||
/datum/AI_Module/mecha_domination
|
||||
@@ -415,22 +392,22 @@
|
||||
Anyone can check the fire alarm's interface and may be tipped off by its status."
|
||||
one_purchase = TRUE
|
||||
cost = 25
|
||||
power_type = /datum/action/innate/ai/break_fire_alarms
|
||||
power_type = /datum/spell/ai_spell/break_fire_alarms
|
||||
unlock_text = "<span class='notice'>You replace the thermal sensing capabilities of all fire alarms with a manual override, allowing you to turn them off at will.</span>"
|
||||
|
||||
/datum/action/innate/ai/break_fire_alarms
|
||||
/datum/spell/ai_spell/break_fire_alarms
|
||||
name = "Override Thermal Sensors"
|
||||
desc = "Disables the automatic temperature sensing on all fire alarms, making them effectively useless."
|
||||
button_icon_state = "break_fire_alarms"
|
||||
action_icon_state = "break_fire_alarms"
|
||||
uses = 1
|
||||
|
||||
/datum/action/innate/ai/break_fire_alarms/Activate()
|
||||
/datum/spell/ai_spell/break_fire_alarms/cast(list/targets, mob/user)
|
||||
for(var/obj/machinery/firealarm/F in GLOB.machines)
|
||||
if(!is_station_level(F.z))
|
||||
continue
|
||||
F.emagged = TRUE
|
||||
to_chat(owner, "<span class='notice'>All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.</span>")
|
||||
owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
to_chat(user, "<span class='notice'>All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.</span>")
|
||||
user.playsound_local(user, 'sound/machines/terminal_off.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
|
||||
//Air Alarm Safety Override: Unlocks the ability to enable flooding on all air alarms.
|
||||
/datum/AI_Module/break_air_alarms
|
||||
@@ -440,23 +417,22 @@
|
||||
Anyone can check the air alarm's interface and may be tipped off by their nonfunctionality."
|
||||
one_purchase = TRUE
|
||||
cost = 50
|
||||
power_type = /datum/action/innate/ai/break_air_alarms
|
||||
power_type = /datum/spell/ai_spell/break_air_alarms
|
||||
unlock_text = "<span class='notice'>You remove the safety overrides on all air alarms, but you leave the confirm prompts open. You can hit 'Yes' at any time... you bastard.</span>"
|
||||
|
||||
/datum/action/innate/ai/break_air_alarms
|
||||
/datum/spell/ai_spell/break_air_alarms
|
||||
name = "Override Air Alarm Safeties"
|
||||
desc = "Enables the Flood setting on all air alarms."
|
||||
button_icon_state = "break_air_alarms"
|
||||
action_icon_state = "break_air_alarms"
|
||||
uses = 1
|
||||
|
||||
/datum/action/innate/ai/break_air_alarms/Activate()
|
||||
/datum/spell/ai_spell/break_air_alarms/cast(list/targets, mob/user)
|
||||
for(var/obj/machinery/alarm/AA in GLOB.machines)
|
||||
if(!is_station_level(AA.z))
|
||||
continue
|
||||
AA.emagged = TRUE
|
||||
to_chat(owner, "<span class='notice'>All air alarm safeties on the station have been overridden. Air alarms may now use the Flood environmental mode.")
|
||||
owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
|
||||
to_chat(user, "<span class='notice'>All air alarm safeties on the station have been overridden. Air alarms may now use the Flood environmental mode.")
|
||||
user.playsound_local(user, 'sound/machines/terminal_off.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
|
||||
//Overload Machine: Allows the AI to overload a machine, detonating it after a delay. Two uses per purchase.
|
||||
/datum/AI_Module/overload_machine
|
||||
@@ -464,95 +440,78 @@
|
||||
mod_pick_name = "overload"
|
||||
description = "Overheats an electrical machine, causing a moderately-sized explosion and destroying it. Four uses per purchase."
|
||||
cost = 20
|
||||
power_type = /datum/action/innate/ai/ranged/overload_machine
|
||||
power_type = /datum/spell/ai_spell/ranged/overload_machine
|
||||
unlock_text = "<span class='notice'>You enable the ability for the station's APCs to direct intense energy into machinery.</span>"
|
||||
|
||||
/datum/action/innate/ai/ranged/overload_machine
|
||||
/datum/spell/ai_spell/ranged/overload_machine
|
||||
name = "Overload Machine"
|
||||
desc = "Overheats a machine, causing a moderately-sized explosion after a short time."
|
||||
button_icon_state = "overload_machine"
|
||||
action_icon_state = "overload_machine"
|
||||
uses = 4
|
||||
linked_ability_type = /obj/effect/proc_holder/ranged_ai/overload_machine
|
||||
active = FALSE
|
||||
ranged_mousepointer = 'icons/effects/cult_target.dmi'
|
||||
selection_activated_message = "<span class='notice'>You tap into the station's powernet. Click on a machine to detonate it, or use the ability again to cancel.</span>"
|
||||
selection_deactivated_message = "<span class='notice'>You release your hold on the powernet.</span>"
|
||||
|
||||
/datum/action/innate/ai/ranged/overload_machine/proc/detonate_machine(obj/machinery/M)
|
||||
/datum/spell/ai_spell/ranged/overload_machine/cast(list/targets, mob/user)
|
||||
var/obj/machinery/target = targets[1]
|
||||
if(!istype(target))
|
||||
to_chat(user, "<span class='warning'>You can only overload machines!</span>")
|
||||
return
|
||||
if(target.flags_2 & NO_MALF_EFFECT_2)
|
||||
to_chat(user, "<span class='warning'>That machine can't be overloaded!</span>")
|
||||
return
|
||||
|
||||
user.playsound_local(user, "sparks", 50, FALSE, use_reverb = FALSE)
|
||||
adjust_uses(-1, user)
|
||||
target.audible_message("<span class='italics'>You hear a loud electrical buzzing sound coming from [target]!</span>")
|
||||
addtimer(CALLBACK(src, PROC_REF(detonate_machine), target), 5 SECONDS) //kaboom!
|
||||
to_chat(user, "<span class='warning'>Overloading machine circuitry...</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/spell/ai_spell/ranged/overload_machine/proc/detonate_machine(obj/machinery/M)
|
||||
if(M && !QDELETED(M))
|
||||
explosion(get_turf(M), 0, 3, 5, 0)
|
||||
if(M) //to check if the explosion killed it before we try to delete it
|
||||
qdel(M)
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/overload_machine
|
||||
active = FALSE
|
||||
ranged_mousepointer = 'icons/effects/cult_target.dmi'
|
||||
enable_text = "<span class='notice'>You tap into the station's powernet. Click on a machine to detonate it, or use the ability again to cancel.</span>"
|
||||
disable_text = "<span class='notice'>You release your hold on the powernet.</span>"
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/overload_machine/InterceptClickOn(mob/living/caller, params, obj/machinery/target)
|
||||
if(..())
|
||||
return
|
||||
if(ranged_ability_user.incapacitated())
|
||||
remove_ranged_ability()
|
||||
return
|
||||
if(!istype(target))
|
||||
to_chat(ranged_ability_user, "<span class='warning'>You can only overload machines!</span>")
|
||||
return
|
||||
if(target.flags_2 & NO_MALF_EFFECT_2)
|
||||
to_chat(ranged_ability_user, "<span class='warning'>That machine can't be overloaded!</span>")
|
||||
return
|
||||
|
||||
ranged_ability_user.playsound_local(ranged_ability_user, "sparks", 50, FALSE, use_reverb = FALSE)
|
||||
attached_action.adjust_uses(-1)
|
||||
target.audible_message("<span class='italics'>You hear a loud electrical buzzing sound coming from [target]!</span>")
|
||||
addtimer(CALLBACK(attached_action, TYPE_PROC_REF(/datum/action/innate/ai/ranged/overload_machine, detonate_machine), target), 50) //kaboom!
|
||||
remove_ranged_ability(ranged_ability_user, "<span class='warning'>Overloading machine circuitry...</span>")
|
||||
return TRUE
|
||||
|
||||
|
||||
//Override Machine: Allows the AI to override a machine, animating it into an angry, living version of itself.
|
||||
/datum/AI_Module/override_machine
|
||||
module_name = "Machine Override"
|
||||
mod_pick_name = "override"
|
||||
description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. Four uses."
|
||||
cost = 30
|
||||
power_type = /datum/action/innate/ai/ranged/override_machine
|
||||
power_type = /datum/spell/ai_spell/ranged/override_machine
|
||||
unlock_text = "<span class='notice'>You procure a virus from the Space Dark Web and distribute it to the station's machines.</span>"
|
||||
|
||||
/datum/action/innate/ai/ranged/override_machine
|
||||
/datum/spell/ai_spell/ranged/override_machine
|
||||
name = "Override Machine"
|
||||
desc = "Animates a targeted machine, causing it to attack anyone nearby."
|
||||
button_icon_state = "override_machine"
|
||||
action_icon_state = "override_machine"
|
||||
uses = 4
|
||||
linked_ability_type = /obj/effect/proc_holder/ranged_ai/override_machine
|
||||
|
||||
/datum/action/innate/ai/ranged/override_machine/proc/animate_machine(obj/machinery/M)
|
||||
if(M && !QDELETED(M))
|
||||
new/mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, owner, 1)
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/override_machine
|
||||
active = FALSE
|
||||
ranged_mousepointer = 'icons/effects/override_machine_target.dmi'
|
||||
enable_text = "<span class='notice'>You tap into the station's powernet. Click on a machine to animate it, or use the ability again to cancel.</span>"
|
||||
disable_text = "<span class='notice'>You release your hold on the powernet.</span>"
|
||||
selection_activated_message = "<span class='notice'>You tap into the station's powernet. Click on a machine to animate it, or use the ability again to cancel.</span>"
|
||||
selection_deactivated_message = "<span class='notice'>You release your hold on the powernet.</span>"
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/override_machine/InterceptClickOn(mob/living/caller, params, obj/machinery/target)
|
||||
if(..())
|
||||
return
|
||||
if(ranged_ability_user.incapacitated())
|
||||
remove_ranged_ability()
|
||||
return
|
||||
/datum/spell/ai_spell/ranged/override_machine/cast(list/targets, mob/user)
|
||||
var/obj/machinery/target = targets[1]
|
||||
if(!istype(target))
|
||||
to_chat(ranged_ability_user, "<span class='warning'>You can only animate machines!</span>")
|
||||
to_chat(user, "<span class='warning'>You can only animate machines!</span>")
|
||||
return
|
||||
if(target.flags_2 & NO_MALF_EFFECT_2)
|
||||
to_chat(ranged_ability_user, "<span class='warning'>That machine can't be overridden!</span>")
|
||||
to_chat(user, "<span class='warning'>That machine can't be overridden!</span>")
|
||||
return
|
||||
|
||||
ranged_ability_user.playsound_local(ranged_ability_user, 'sound/misc/interference.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
attached_action.adjust_uses(-1)
|
||||
user.playsound_local(user, 'sound/misc/interference.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
adjust_uses(-1, user)
|
||||
target.audible_message("<span class='userdanger'>You hear a loud electrical buzzing sound coming from [target]!</span>")
|
||||
addtimer(CALLBACK(attached_action, TYPE_PROC_REF(/datum/action/innate/ai/ranged/override_machine, animate_machine), target), 50) //kabeep!
|
||||
remove_ranged_ability(ranged_ability_user, "<span class='danger'>Sending override signal...</span>")
|
||||
addtimer(CALLBACK(src, PROC_REF(animate_machine), target), 5 SECONDS) //kabeep!
|
||||
to_chat(user, "<span class='danger'>Sending override signal...</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/spell/ai_spell/ranged/override_machine/proc/animate_machine(obj/machinery/M, mob/user)
|
||||
if(M && !QDELETED(M))
|
||||
new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, user, 1)
|
||||
|
||||
//Robotic Factory: Places a large machine that converts humans that go through it into cyborgs. Unlocking this ability removes shunting.
|
||||
/datum/AI_Module/place_cyborg_transformer
|
||||
@@ -561,46 +520,47 @@
|
||||
description = "Build a machine anywhere, using expensive nanomachines, that can convert a living human into a loyal cyborg slave when placed inside."
|
||||
cost = 100
|
||||
one_purchase = TRUE
|
||||
power_type = /datum/action/innate/ai/place_transformer
|
||||
power_type = /datum/spell/ai_spell/place_transformer
|
||||
unlock_text = "<span class='notice'>You prepare a robotics factory for deployment.</span>"
|
||||
unlock_sound = 'sound/machines/ping.ogg'
|
||||
|
||||
/datum/action/innate/ai/place_transformer
|
||||
/datum/spell/ai_spell/place_transformer
|
||||
name = "Place Robotics Factory"
|
||||
desc = "Places a machine that converts humans into cyborgs. Conveyor belts included!"
|
||||
button_icon_state = "robotic_factory"
|
||||
action_icon_state = "robotic_factory"
|
||||
uses = 1
|
||||
auto_use_uses = FALSE //So we can attempt multiple times
|
||||
var/list/turfOverlays
|
||||
var/in_use = FALSE
|
||||
|
||||
/datum/action/innate/ai/place_transformer/New()
|
||||
/datum/spell/ai_spell/place_transformer/New()
|
||||
..()
|
||||
for(var/i in 1 to 3)
|
||||
var/image/I = image("icon"='icons/turf/overlays.dmi')
|
||||
LAZYADD(turfOverlays, I)
|
||||
|
||||
/datum/action/innate/ai/place_transformer/Activate()
|
||||
if(!owner_AI.can_place_transformer(src))
|
||||
/datum/spell/ai_spell/place_transformer/cast(list/targets, mob/living/silicon/ai/user)
|
||||
if(!user.can_place_transformer(src))
|
||||
return
|
||||
active = TRUE
|
||||
if(tgui_alert(owner, "Are you sure you want to place the machine here?", "Are you sure?", list("Yes", "No")) != "Yes")
|
||||
in_use = TRUE
|
||||
if(tgui_alert(user, "Are you sure you want to place the machine here?", "Are you sure?", list("Yes", "No")) != "Yes")
|
||||
active = FALSE
|
||||
return
|
||||
if(!owner_AI.can_place_transformer(src))
|
||||
if(!user.can_place_transformer(src))
|
||||
active = FALSE
|
||||
return
|
||||
var/turf/T = get_turf(owner_AI.eyeobj)
|
||||
new /obj/machinery/transformer(T, owner_AI)
|
||||
var/turf/T = get_turf(user.eyeobj)
|
||||
new /obj/machinery/transformer(T, user)
|
||||
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
|
||||
owner_AI.can_shunt = FALSE
|
||||
to_chat(owner, "<span class='warning'>You are no longer able to shunt your core to APCs.</span>")
|
||||
adjust_uses(-1)
|
||||
user.can_shunt = FALSE
|
||||
to_chat(user, "<span class='warning'>You are no longer able to shunt your core to APCs.</span>")
|
||||
adjust_uses(-1, user)
|
||||
|
||||
/mob/living/silicon/ai/proc/remove_transformer_image(client/C, image/I, turf/T)
|
||||
if(C && I.loc == T)
|
||||
C.images -= I
|
||||
|
||||
/mob/living/silicon/ai/proc/can_place_transformer(datum/action/innate/ai/place_transformer/action)
|
||||
/mob/living/silicon/ai/proc/can_place_transformer(datum/spell/ai_spell/place_transformer/action)
|
||||
if(!eyeobj || !isturf(loc) || incapacitated() || !action)
|
||||
return
|
||||
var/turf/middle = get_turf(eyeobj)
|
||||
@@ -634,46 +594,46 @@
|
||||
mod_pick_name = "turretdeployer"
|
||||
description = "Build a turret anywhere that lethally targets organic life in sight."
|
||||
cost = 30
|
||||
power_type = /datum/action/innate/ai/place_turret
|
||||
power_type = /datum/spell/ai_spell/place_turret
|
||||
unlock_text = "<span class='notice'>You prepare an energy turret for deployment.</span>"
|
||||
unlock_sound = 'sound/items/rped.ogg'
|
||||
|
||||
/datum/action/innate/ai/place_turret
|
||||
/datum/spell/ai_spell/place_turret
|
||||
name = "Deploy Turret"
|
||||
desc = "Build a turret anywhere that lethally targets organic life in sight."
|
||||
button_icon_state = "deploy_turret"
|
||||
action_icon_state = "deploy_turret"
|
||||
uses = 1
|
||||
auto_use_uses = FALSE
|
||||
var/image/turf_overlay
|
||||
var/in_use = FALSE
|
||||
|
||||
/datum/action/innate/ai/place_turret/New()
|
||||
/datum/spell/ai_spell/place_turret/New()
|
||||
..()
|
||||
turf_overlay = image('icons/turf/overlays.dmi')
|
||||
|
||||
/datum/action/innate/ai/place_turret/Activate()
|
||||
if(active)
|
||||
to_chat(owner, "<span class='notice'>Your assemblers can only construct one turret at a time.</span>")
|
||||
/datum/spell/ai_spell/place_turret/cast(list/targets, mob/living/silicon/ai/user)
|
||||
if(in_use)
|
||||
to_chat(user, "<span class='notice'>Your assemblers can only construct one turret at a time.</span>")
|
||||
return
|
||||
if(!owner_AI.can_place_turret(src))
|
||||
if(!user.can_place_turret(src))
|
||||
return
|
||||
active = TRUE
|
||||
var/response = alert(owner, "Are you sure you want to place a turret here? Deployment will take a few seconds to complete, in which the turret will be vulnerable.", "Are you sure?", "No", "Yes")
|
||||
if(!response || response == "No")
|
||||
active = FALSE
|
||||
in_use = TRUE
|
||||
if(tgui_alert(user, "Are you sure you want to place a turret here? Deployment will take a few seconds to complete, in which the turret will be vulnerable.", "Are you sure?", list("No", "Yes")) != "Yes")
|
||||
in_use = FALSE
|
||||
return
|
||||
if(!owner_AI.can_place_turret(src))
|
||||
active = FALSE
|
||||
if(!user.can_place_turret(src))
|
||||
in_use = FALSE
|
||||
return
|
||||
deploy_turret()
|
||||
active = FALSE
|
||||
deploy_turret(user)
|
||||
in_use = FALSE
|
||||
|
||||
/datum/action/innate/ai/place_turret/proc/deploy_turret()
|
||||
var/turf/T = get_turf(owner_AI.eyeobj)
|
||||
/datum/spell/ai_spell/place_turret/proc/deploy_turret(mob/living/silicon/ai/user)
|
||||
var/turf/T = get_turf(user.eyeobj)
|
||||
|
||||
//Handles the turret construction and configuration
|
||||
playsound(T, 'sound/items/rped.ogg', 100, TRUE) //Plays a sound both at the location of the construction to alert players and to the user as feedback
|
||||
owner.playsound_local(owner, 'sound/items/rped.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
to_chat(owner, "<span class='notice'>You order your electronics to assemble a turret. This will take a few seconds.</span>")
|
||||
user.playsound_local(user, 'sound/items/rped.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
to_chat(user, "<span class='notice'>You order your electronics to assemble a turret. This will take a few seconds.</span>")
|
||||
var/obj/effect/temp_visual/rcd_effect/spawning_effect = new(T)
|
||||
QDEL_IN(spawning_effect, 5 SECONDS)
|
||||
|
||||
@@ -687,21 +647,21 @@
|
||||
turret.invisibility = 100
|
||||
|
||||
//If turrets are already upgraded, beef it up
|
||||
if(owner_AI.turrets_upgraded)
|
||||
if(user.turrets_upgraded)
|
||||
turret.health += 30
|
||||
turret.eprojectile = /obj/item/projectile/beam/laser/ai_turret/heavylaser //Big gun
|
||||
turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
|
||||
if(do_after_once(owner, 5 SECONDS, target = T, allow_moving = TRUE)) //Once this is done, turret is armed and dangerous
|
||||
if(do_after_once(user, 5 SECONDS, target = T, allow_moving = TRUE)) //Once this is done, turret is armed and dangerous
|
||||
turret.raised = initial(turret.raised)
|
||||
turret.invisibility = initial(turret.invisibility)
|
||||
turret.disabled = initial(turret.disabled)
|
||||
new /obj/effect/temp_visual/rcd_effect/end(T)
|
||||
playsound(T, 'sound/items/deconstruct.ogg', 100, TRUE)
|
||||
to_chat(owner, "<span class='notice'>Turret deployed.</span>")
|
||||
adjust_uses(-1)
|
||||
to_chat(user, "<span class='notice'>Turret deployed.</span>")
|
||||
adjust_uses(-1, user)
|
||||
|
||||
/mob/living/silicon/ai/proc/can_place_turret(datum/action/innate/ai/place_turret/action)
|
||||
/mob/living/silicon/ai/proc/can_place_turret(datum/spell/ai_spell/place_turret/action)
|
||||
if(!eyeobj || !isturf(eyeobj.loc) || incapacitated() || !action)
|
||||
return
|
||||
|
||||
@@ -735,26 +695,26 @@
|
||||
mod_pick_name = "blackout"
|
||||
description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. Three uses."
|
||||
cost = 15
|
||||
power_type = /datum/action/innate/ai/blackout
|
||||
power_type = /datum/spell/ai_spell/blackout
|
||||
unlock_text = "<span class='notice'>You hook into the powernet and route bonus power towards the station's lighting.</span>"
|
||||
|
||||
/datum/action/innate/ai/blackout
|
||||
/datum/spell/ai_spell/blackout
|
||||
name = "Blackout"
|
||||
desc = "Overloads random lights across the station."
|
||||
button_icon_state = "blackout"
|
||||
action_icon_state = "blackout"
|
||||
uses = 3
|
||||
auto_use_uses = FALSE
|
||||
|
||||
/datum/action/innate/ai/blackout/Activate()
|
||||
/datum/spell/ai_spell/blackout/cast(list/targets, mob/user)
|
||||
for(var/thing in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/apc = thing
|
||||
if(prob(30 * apc.overload))
|
||||
INVOKE_ASYNC(apc, TYPE_PROC_REF(/obj/machinery/power/apc, overload_lighting))
|
||||
else
|
||||
apc.overload++
|
||||
to_chat(owner, "<span class='notice'>Overcurrent applied to the powernet.</span>")
|
||||
owner.playsound_local(owner, "sparks", 50, FALSE, use_reverb = FALSE)
|
||||
adjust_uses(-1)
|
||||
to_chat(user, "<span class='notice'>Overcurrent applied to the powernet.</span>")
|
||||
user.playsound_local(user, "sparks", 50, FALSE, use_reverb = FALSE)
|
||||
adjust_uses(-1, user)
|
||||
|
||||
//Reactivate Camera Network: Reactivates up to 30 cameras across the station.
|
||||
/datum/AI_Module/reactivate_cameras
|
||||
@@ -762,19 +722,18 @@
|
||||
mod_pick_name = "recam"
|
||||
description = "Runs a network-wide diagnostic on the camera network, resetting focus and re-routing power to failed cameras. Can be used to repair up to 30 cameras."
|
||||
cost = 10
|
||||
power_type = /datum/action/innate/ai/reactivate_cameras
|
||||
power_type = /datum/spell/ai_spell/reactivate_cameras
|
||||
unlock_text = "<span class='notice'>You deploy nanomachines to the cameranet.</span>"
|
||||
|
||||
/datum/action/innate/ai/reactivate_cameras
|
||||
/datum/spell/ai_spell/reactivate_cameras
|
||||
name = "Reactivate Cameras"
|
||||
desc = "Reactivates disabled cameras across the station; remaining uses can be used later."
|
||||
button_icon_state = "reactivate_cameras"
|
||||
action_icon_state = "reactivate_cameras"
|
||||
uses = 10
|
||||
auto_use_uses = FALSE
|
||||
cooldown_period = 3 SECONDS
|
||||
base_cooldown = 3 SECONDS
|
||||
|
||||
/datum/action/innate/ai/reactivate_cameras/Activate()
|
||||
var/mob/living/silicon/ai/user = usr
|
||||
/datum/spell/ai_spell/reactivate_cameras/cast(list/targets, mob/living/silicon/ai/user)
|
||||
var/repaired_cameras = 0
|
||||
if(!istype(user))
|
||||
return
|
||||
@@ -782,14 +741,14 @@
|
||||
if(!uses)
|
||||
break
|
||||
if(!camera_to_repair.status || camera_to_repair.view_range != initial(camera_to_repair.view_range))
|
||||
camera_to_repair.toggle_cam(owner_AI, 0)
|
||||
camera_to_repair.toggle_cam(user, 0)
|
||||
camera_to_repair.view_range = initial(camera_to_repair.view_range)
|
||||
camera_to_repair.wires.cut_wires.Cut()
|
||||
repaired_cameras++
|
||||
uses--
|
||||
to_chat(owner, "<span class='notice'>Diagnostic complete! Cameras reactivated: <b>[repaired_cameras]</b>. Reactivations remaining: <b>[uses]</b>.</span>")
|
||||
owner.playsound_local(owner, 'sound/items/wirecutter.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
adjust_uses(0, TRUE)
|
||||
to_chat(user, "<span class='notice'>Diagnostic complete! Cameras reactivated: <b>[repaired_cameras]</b>. Reactivations remaining: <b>[uses]</b>.</span>")
|
||||
user.playsound_local(user, 'sound/items/wirecutter.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
adjust_uses(0, user, TRUE)
|
||||
|
||||
//Upgrade Camera Network: EMP-proofs all cameras, in addition to giving them X-ray vision.
|
||||
/datum/AI_Module/upgrade_cameras
|
||||
@@ -880,124 +839,113 @@
|
||||
mod_pick_name = "repair_borg"
|
||||
description = "Causes an electrical surge in the targeted cyborg, rebooting and repairing most of its subsystems. Requires two uses on a cyborg with broken armor."
|
||||
cost = 20
|
||||
power_type = /datum/action/innate/ai/ranged/repair_cyborg
|
||||
power_type = /datum/spell/ai_spell/ranged/repair_cyborg
|
||||
unlock_text = "<span class='notice'>TLB exception on load: Error pointing to address 0000001H, Proceed with execution anywa- SURGE protocols installed, welcome to open APC!</span>"
|
||||
unlock_sound = 'sound/items/rped.ogg'
|
||||
|
||||
/datum/action/innate/ai/ranged/repair_cyborg
|
||||
/datum/spell/ai_spell/ranged/repair_cyborg
|
||||
name = "Repair Cyborg"
|
||||
desc = "Shocks a cyborg back to 'life' after a short delay."
|
||||
button_icon_state = "overload_machine"
|
||||
action_icon_state = "overload_machine"
|
||||
uses = 2
|
||||
linked_ability_type = /obj/effect/proc_holder/ranged_ai/repair_cyborg
|
||||
ranged_mousepointer = 'icons/effects/overload_machine_target.dmi'
|
||||
selection_activated_message = "<span class='notice'>Call to address 0FFFFFFF in APC logic thread, awaiting user response.</span>"
|
||||
selection_deactivated_message = "<span class='notice'>APC logic thread restarting...</span>"
|
||||
var/is_active = FALSE
|
||||
|
||||
/datum/spell/ai_spell/ranged/repair_cyborg/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new
|
||||
T.allowed_type = /mob/living/silicon/robot
|
||||
T.try_auto_target = FALSE
|
||||
return T
|
||||
|
||||
/datum/action/innate/ai/ranged/repair_cyborg/proc/fix_borg(mob/living/silicon/robot/to_repair)
|
||||
/datum/spell/ai_spell/ranged/repair_cyborg/cast(list/targets, mob/user)
|
||||
var/mob/living/silicon/robot/robot_target = targets[1]
|
||||
if(!istype(robot_target))
|
||||
to_chat(user, "<span class='warning'>You can only repair robots with this ability!</span>")
|
||||
return
|
||||
if(is_active)
|
||||
to_chat(user, "<span class='warning'>You can only repair one robot at a time!</span>")
|
||||
return
|
||||
is_active = TRUE
|
||||
user.playsound_local(user, "sparks", 50, FALSE, use_reverb = FALSE)
|
||||
adjust_uses(-1, user)
|
||||
robot_target.audible_message("<span class='italics'>You hear a loud electrical buzzing sound coming from [robot_target]!</span>")
|
||||
if(!do_mob(user, robot_target, 10 SECONDS))
|
||||
is_active = FALSE
|
||||
return
|
||||
is_active = FALSE
|
||||
fix_borg(robot_target)
|
||||
to_chat(user, "<span class='warning'>[robot_target] successfully rebooted.</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/spell/ai_spell/ranged/repair_cyborg/proc/fix_borg(mob/living/silicon/robot/to_repair)
|
||||
for(var/datum/robot_component/component in to_repair.components)
|
||||
component.brute_damage = 0
|
||||
component.electronics_damage = 0
|
||||
component.component_disabled = FALSE
|
||||
to_repair.revive()
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/repair_cyborg
|
||||
active = FALSE
|
||||
ranged_mousepointer = 'icons/effects/overload_machine_target.dmi'
|
||||
enable_text = "<span class='notice'>Call to address 0FFFFFFF in APC logic thread, awaiting user response.</span>"
|
||||
disable_text = "<span class='notice'>APC logic thread restarting...</span>"
|
||||
var/is_active = FALSE
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/repair_cyborg/InterceptClickOn(mob/living/caller, params, mob/living/silicon/robot/robot_target)
|
||||
if(..())
|
||||
return
|
||||
if(ranged_ability_user.incapacitated())
|
||||
remove_ranged_ability()
|
||||
return
|
||||
if(!istype(robot_target))
|
||||
to_chat(ranged_ability_user, "<span class='warning'>You can only repair robots with this ability!</span>")
|
||||
return
|
||||
if(is_active)
|
||||
to_chat(ranged_ability_user, "<span class='warning'>You can only repair one robot at a time!</span>")
|
||||
return
|
||||
is_active = TRUE
|
||||
ranged_ability_user.playsound_local(ranged_ability_user, "sparks", 50, FALSE, use_reverb = FALSE)
|
||||
var/datum/action/innate/ai/ranged/repair_cyborg/actual_action = attached_action
|
||||
actual_action.adjust_uses(-1)
|
||||
robot_target.audible_message("<span class='italics'>You hear a loud electrical buzzing sound coming from [robot_target]!</span>")
|
||||
if(!do_mob(caller, robot_target, 10 SECONDS))
|
||||
is_active = FALSE
|
||||
return
|
||||
is_active = FALSE
|
||||
actual_action.fix_borg(robot_target)
|
||||
remove_ranged_ability(ranged_ability_user, "<span class='warning'>[robot_target] successfully rebooted.</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/AI_Module/core_tilt
|
||||
module_name = "Rolling Servos"
|
||||
mod_pick_name = "watchforrollingcores"
|
||||
description = "Allows you to slowly roll your core around, crushing anything in your path with your bulk."
|
||||
cost = 10
|
||||
one_purchase = FALSE
|
||||
power_type = /datum/action/innate/ai/ranged/core_tilt
|
||||
one_purchase = TRUE
|
||||
power_type = /datum/spell/ai_spell/ranged/core_tilt
|
||||
unlock_sound = 'sound/effects/bang.ogg'
|
||||
unlock_text = "<span class='notice'>You gain the ability to roll over and crush anything in your way.</span>"
|
||||
|
||||
/datum/action/innate/ai/ranged/core_tilt
|
||||
/datum/spell/ai_spell/ranged/core_tilt
|
||||
name = "Roll Over"
|
||||
button_icon_state = "roll_over"
|
||||
action_icon_state = "roll_over"
|
||||
desc = "Allows you to roll over in the direction of your choosing, crushing anything in your way."
|
||||
auto_use_uses = FALSE
|
||||
linked_ability_type = /obj/effect/proc_holder/ranged_ai/roll_over
|
||||
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/roll_over
|
||||
active = FALSE
|
||||
ranged_mousepointer = 'icons/effects/cult_target.dmi'
|
||||
enable_text = "<span class='notice'>Your inner servos shift as you prepare to roll around. Click adjacent tiles to roll into them!</span>"
|
||||
disable_text = "<span class='notice'>You disengage your rolling protocols.</span>"
|
||||
selection_activated_message = "<span class='notice'>Your inner servos shift as you prepare to roll around. Click adjacent tiles to roll into them!</span>"
|
||||
selection_deactivated_message = "<span class='notice'>You disengage your rolling protocols.</span>"
|
||||
COOLDOWN_DECLARE(time_til_next_tilt)
|
||||
/// How long does it take us to roll?
|
||||
var/roll_over_time = MALF_AI_ROLL_TIME
|
||||
/// How long does it take for the ability to cool down, on top of [roll_over_time]?
|
||||
var/roll_over_cooldown = MALF_AI_ROLL_COOLDOWN
|
||||
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/roll_over/InterceptClickOn(mob/living/caller, params, atom/target_atom)
|
||||
if(..())
|
||||
/datum/spell/ai_spell/ranged/core_tilt/cast(list/targets, mob/living/silicon/ai/user)
|
||||
var/atom/target_atom = targets[1]
|
||||
if(!istype(user))
|
||||
return
|
||||
if(!isAI(ranged_ability_user))
|
||||
return
|
||||
if(ranged_ability_user.incapacitated() || !isturf(ranged_ability_user.loc))
|
||||
remove_ranged_ability()
|
||||
if(!isturf(user.loc))
|
||||
user.RemoveSpell(src)
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, time_til_next_tilt))
|
||||
to_chat(ranged_ability_user, "<span class='warning'>Your rolling capacitors are still powering back up!</span>")
|
||||
to_chat(user, "<span class='warning'>Your rolling capacitors are still powering back up!</span>")
|
||||
return
|
||||
|
||||
var/turf/target = get_turf(target_atom)
|
||||
if(isnull(target))
|
||||
return
|
||||
|
||||
if(target == get_turf(ranged_ability_user))
|
||||
to_chat(ranged_ability_user, "<span class='warning'>You can't roll over on yourself!</span>")
|
||||
if(target == get_turf(user))
|
||||
to_chat(user, "<span class='warning'>You can't roll over on yourself!</span>")
|
||||
return
|
||||
|
||||
var/picked_dir = get_dir(caller, target)
|
||||
var/picked_dir = get_dir(user, target)
|
||||
if(!picked_dir)
|
||||
return FALSE
|
||||
// we can move during the timer so we cant just pass the ref
|
||||
var/turf/temp_target = get_step(ranged_ability_user, picked_dir)
|
||||
var/turf/temp_target = get_step(user, picked_dir)
|
||||
|
||||
new /obj/effect/temp_visual/single_user/ai_telegraph(temp_target, ranged_ability_user)
|
||||
ranged_ability_user.visible_message("<span class='danger'>[ranged_ability_user] seems to be winding up!</span>")
|
||||
addtimer(CALLBACK(src, PROC_REF(do_roll_over), caller, picked_dir), MALF_AI_ROLL_TIME)
|
||||
new /obj/effect/temp_visual/single_user/ai_telegraph(temp_target, user)
|
||||
user.visible_message("<span class='danger'>[user] seems to be winding up!</span>")
|
||||
addtimer(CALLBACK(src, PROC_REF(do_roll_over), user, picked_dir), MALF_AI_ROLL_TIME)
|
||||
|
||||
to_chat(ranged_ability_user, "<span class='warning'>Overloading machine circuitry...</span>")
|
||||
to_chat(user, "<span class='warning'>Overloading machine circuitry...</span>")
|
||||
|
||||
COOLDOWN_START(src, time_til_next_tilt, roll_over_cooldown)
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/roll_over/proc/do_roll_over(mob/living/silicon/ai/ai_caller, picked_dir)
|
||||
/datum/spell/ai_spell/ranged/core_tilt/proc/do_roll_over(mob/living/silicon/ai/ai_caller, picked_dir)
|
||||
var/turf/target = get_step(ai_caller, picked_dir) // in case we moved we pass the dir not the target turf
|
||||
|
||||
if(isnull(target) || ai_caller.incapacitated() || !isturf(ai_caller.loc))
|
||||
@@ -1009,7 +957,7 @@
|
||||
ai_caller.fall_and_crush(target, MALF_AI_ROLL_DAMAGE, prob(MALF_AI_ROLL_CRIT_CHANCE), 2, null, paralyze_time, crush_dir = picked_dir, angle = get_rotation_from_dir(picked_dir))
|
||||
ai_caller.allow_teleporter = FALSE
|
||||
|
||||
/obj/effect/proc_holder/ranged_ai/roll_over/proc/get_rotation_from_dir(dir)
|
||||
/datum/spell/ai_spell/ranged/core_tilt/proc/get_rotation_from_dir(dir)
|
||||
switch(dir)
|
||||
if(NORTH, NORTHWEST, WEST, SOUTHWEST)
|
||||
return 270 // try our best to not return 180 since it works badly with animate
|
||||
|
||||
@@ -147,8 +147,8 @@
|
||||
|
||||
/mob/living/simple_animal/demon/shadow/Initialize(mapload)
|
||||
. = ..()
|
||||
AddSpell(new /obj/effect/proc_holder/spell/fireball/shadow_grapple)
|
||||
var/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/S = new
|
||||
AddSpell(new /datum/spell/fireball/shadow_grapple)
|
||||
var/datum/spell/bloodcrawl/shadow_crawl/S = new
|
||||
AddSpell(S)
|
||||
whisper_action.button_icon_state = "shadow_whisper"
|
||||
whisper_action.background_icon_state = "shadow_demon_bg"
|
||||
@@ -176,7 +176,7 @@
|
||||
return lum_count
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/shadow_grapple
|
||||
/datum/spell/fireball/shadow_grapple
|
||||
name = "Shadow Grapple"
|
||||
desc = "Fire one of your hands, if it hits a person it pulls them in. If you hit a structure you get pulled to the structure. Any light source hit with this will be disabled in a two tile radius."
|
||||
base_cooldown = 10 SECONDS
|
||||
@@ -193,7 +193,7 @@
|
||||
invocation_type = "none"
|
||||
invocation = null
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/shadow_grapple/update_icon_state()
|
||||
/datum/spell/fireball/shadow_grapple/update_spell_icon()
|
||||
return
|
||||
|
||||
/obj/item/projectile/magic/shadow_hand
|
||||
@@ -239,9 +239,9 @@
|
||||
/obj/item/organ/internal/heart/demon/shadow/insert(mob/living/carbon/M, special = 0)
|
||||
. = ..()
|
||||
if(M.mind)
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball/shadow_grapple)
|
||||
M.mind.AddSpell(new /datum/spell/fireball/shadow_grapple)
|
||||
|
||||
/obj/item/organ/internal/heart/demon/shadow/remove(mob/living/carbon/M, special = 0)
|
||||
. = ..()
|
||||
if(M.mind)
|
||||
M.mind.RemoveSpell(/obj/effect/proc_holder/spell/fireball/shadow_grapple)
|
||||
M.mind.RemoveSpell(/datum/spell/fireball/shadow_grapple)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
..()
|
||||
remove_from_all_data_huds()
|
||||
ADD_TRAIT(src, TRAIT_BLOODCRAWL_EAT, "bloodcrawl_eat")
|
||||
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
|
||||
var/datum/spell/bloodcrawl/bloodspell = new
|
||||
AddSpell(bloodspell)
|
||||
if(istype(loc, /obj/effect/dummy/slaughter))
|
||||
bloodspell.phased = TRUE
|
||||
@@ -102,7 +102,7 @@
|
||||
to emerge from it. You are fast, powerful, and almost invincible. By dragging a dead or unconscious body into a blood pool with you, you will consume it after a time and fully regain \
|
||||
your health. You may use the ability 'Sense Victims' in your Cultist tab to locate a random, living heretic.</span></b>"
|
||||
|
||||
/obj/effect/proc_holder/spell/sense_victims
|
||||
/datum/spell/sense_victims
|
||||
name = "Sense Victims"
|
||||
desc = "Sense the location of heretics"
|
||||
base_cooldown = 0
|
||||
@@ -113,13 +113,13 @@
|
||||
action_background_icon_state = "bg_cult"
|
||||
panel = "Demon"
|
||||
|
||||
/obj/effect/proc_holder/spell/sense_victims/create_new_targeting()
|
||||
/datum/spell/sense_victims/create_new_targeting()
|
||||
return new /datum/spell_targeting/alive_mob_list
|
||||
|
||||
/obj/effect/proc_holder/spell/sense_victims/valid_target(mob/living/target, user)
|
||||
/datum/spell/sense_victims/valid_target(mob/living/target, user)
|
||||
return target.stat == CONSCIOUS && target.key && !IS_CULTIST(target) // Only conscious, non cultist players
|
||||
|
||||
/obj/effect/proc_holder/spell/sense_victims/cast(list/targets, mob/user)
|
||||
/datum/spell/sense_victims/cast(list/targets, mob/user)
|
||||
var/mob/living/victim = targets[1]
|
||||
to_chat(victim, "<span class='userdanger'>You feel an awful sense of being watched...</span>")
|
||||
victim.Stun(6 SECONDS) //HUE
|
||||
@@ -153,7 +153,7 @@
|
||||
S.mind.special_role = "Harbinger of the Slaughter"
|
||||
to_chat(S, playstyle_string)
|
||||
S.mind.add_antag_datum(/datum/antagonist/cultist)
|
||||
var/obj/effect/proc_holder/spell/sense_victims/SV = new
|
||||
var/datum/spell/sense_victims/SV = new
|
||||
AddSpell(SV)
|
||||
|
||||
S.mind.add_mind_objective(/datum/objective/cult_slaughter)
|
||||
@@ -257,14 +257,14 @@
|
||||
/obj/item/organ/internal/heart/demon/slaughter/insert(mob/living/carbon/M, special = 0)
|
||||
. = ..()
|
||||
if(M.mind)
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/bloodcrawl(null))
|
||||
M.mind.AddSpell(new /datum/spell/bloodcrawl(null))
|
||||
|
||||
/obj/item/organ/internal/heart/demon/slaughter/remove(mob/living/carbon/M, special = 0)
|
||||
. = ..()
|
||||
if(M.mind)
|
||||
REMOVE_TRAIT(M, TRAIT_BLOODCRAWL, "bloodcrawl")
|
||||
REMOVE_TRAIT(M, TRAIT_BLOODCRAWL_EAT, "bloodcrawl_eat")
|
||||
M.mind.RemoveSpell(/obj/effect/proc_holder/spell/bloodcrawl)
|
||||
M.mind.RemoveSpell(/datum/spell/bloodcrawl)
|
||||
|
||||
/mob/living/simple_animal/demon/slaughter/laughter
|
||||
// The laughter demon! It's everyone's best friend! It just wants to hug
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
dust_if_respawnable(new_stand)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/proc_holder/spell/summon_guardian_beacon
|
||||
/datum/spell/summon_guardian_beacon
|
||||
name = "Place Teleportation Beacon"
|
||||
desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon requires an anchor, will not work on space tiles."
|
||||
clothes_req = FALSE
|
||||
@@ -111,10 +111,10 @@
|
||||
action_background_icon_state = "reset"
|
||||
action_icon = 'icons/mob/guardian.dmi'
|
||||
|
||||
/obj/effect/proc_holder/spell/summon_guardian_beacon/create_new_targeting()
|
||||
/datum/spell/summon_guardian_beacon/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/summon_guardian_beacon/cast(list/targets, mob/living/user = usr)
|
||||
/datum/spell/summon_guardian_beacon/cast(list/targets, mob/living/user = usr)
|
||||
var/target = targets[1]
|
||||
var/mob/living/simple_animal/hostile/guardian/healer/guardian_user = user
|
||||
var/turf/beacon_loc = get_turf(target)
|
||||
@@ -125,7 +125,7 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/surveillance_snare
|
||||
/datum/spell/surveillance_snare
|
||||
name = "Set Surveillance Snare"
|
||||
desc = "Places an invisible Surveillance Snare on the ground, if someone walks over it you'll be alerted. Max of 6 snares active at a time"
|
||||
clothes_req = FALSE
|
||||
@@ -134,10 +134,10 @@
|
||||
action_background_icon_state = "reset"
|
||||
action_icon = 'icons/mob/guardian.dmi'
|
||||
|
||||
/obj/effect/proc_holder/spell/surveillance_snare/create_new_targeting()
|
||||
/datum/spell/surveillance_snare/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/surveillance_snare/cast(list/targets, mob/living/user = usr)
|
||||
/datum/spell/surveillance_snare/cast(list/targets, mob/living/user = usr)
|
||||
var/target = targets[1]
|
||||
var/mob/living/simple_animal/hostile/guardian/ranged/guardian_user = user
|
||||
if(length(guardian_user.snares) < 6)
|
||||
@@ -156,7 +156,7 @@
|
||||
to_chat(user, "<span class='notice'>Snare disarmed.</span>")
|
||||
revert_cast()
|
||||
|
||||
/obj/effect/proc_holder/spell/choose_battlecry
|
||||
/datum/spell/choose_battlecry
|
||||
name = "Change battlecry"
|
||||
desc = "Changes your battlecry."
|
||||
clothes_req = FALSE
|
||||
@@ -165,10 +165,10 @@
|
||||
action_background_icon_state = "communicate"
|
||||
action_icon = 'icons/mob/guardian.dmi'
|
||||
|
||||
/obj/effect/proc_holder/spell/choose_battlecry/create_new_targeting()
|
||||
/datum/spell/choose_battlecry/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/choose_battlecry/cast(list/targets, mob/living/user = usr)
|
||||
/datum/spell/choose_battlecry/cast(list/targets, mob/living/user = usr)
|
||||
var/mob/living/simple_animal/hostile/guardian/punch/guardian_user = user
|
||||
var/input = tgui_input_text(guardian_user, "What do you want your battlecry to be? Max length of 6 characters.", "Change Battlecry", guardian_user.battlecry, 6)
|
||||
if(!input)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/healer/Initialize(mapload, mob/living/host)
|
||||
. = ..()
|
||||
AddSpell(new /obj/effect/proc_holder/spell/summon_guardian_beacon(null))
|
||||
AddSpell(new /datum/spell/summon_guardian_beacon(null))
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/healer/Destroy()
|
||||
QDEL_NULL(beacon)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/ranged/Initialize(mapload, mob/living/host)
|
||||
. = ..()
|
||||
AddSpell(new /obj/effect/proc_holder/spell/surveillance_snare(null))
|
||||
AddSpell(new /datum/spell/surveillance_snare(null))
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/ranged/ToggleMode()
|
||||
if(loc == summoner)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/punch/Initialize(mapload, mob/living/host)
|
||||
. = ..()
|
||||
AddSpell(new /obj/effect/proc_holder/spell/choose_battlecry(null))
|
||||
AddSpell(new /datum/spell/choose_battlecry(null))
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/punch/AttackingTarget()
|
||||
. = ..()
|
||||
|
||||
@@ -45,11 +45,11 @@
|
||||
/// How much weaken a successful ambush attack applies
|
||||
var/ambush_weaken = 6 SECONDS
|
||||
/// The spell the morph uses to morph
|
||||
var/obj/effect/proc_holder/spell/mimic/morph/mimic_spell
|
||||
var/datum/spell/mimic/morph/mimic_spell
|
||||
/// The ambush action used by the morph
|
||||
var/obj/effect/proc_holder/spell/morph_spell/ambush/ambush_spell
|
||||
var/datum/spell/morph_spell/ambush/ambush_spell
|
||||
/// The spell the morph uses to pass through airlocks
|
||||
var/obj/effect/proc_holder/spell/morph_spell/pass_airlock/pass_airlock_spell
|
||||
var/datum/spell/morph_spell/pass_airlock/pass_airlock_spell
|
||||
|
||||
/// How much the morph has gathered in terms of food. Used to reproduce and such
|
||||
var/gathered_food = 20 // Start with a bit to use abilities
|
||||
@@ -60,8 +60,8 @@
|
||||
AddSpell(mimic_spell)
|
||||
ambush_spell = new
|
||||
AddSpell(ambush_spell)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/morph_spell/reproduce)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/morph_spell/open_vent)
|
||||
AddSpell(new /datum/spell/morph_spell/reproduce)
|
||||
AddSpell(new /datum/spell/morph_spell/open_vent)
|
||||
pass_airlock_spell = new
|
||||
AddSpell(pass_airlock_spell)
|
||||
|
||||
@@ -83,8 +83,8 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/wizard/Initialize(mapload)
|
||||
. = ..()
|
||||
AddSpell(new /obj/effect/proc_holder/spell/smoke)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/forcewall)
|
||||
AddSpell(new /datum/spell/smoke)
|
||||
AddSpell(new /datum/spell/forcewall)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/proc/try_eat(atom/movable/A)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#define MORPH_AMBUSH_PERFECTION_TIME 15 SECONDS
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/ambush
|
||||
/datum/spell/morph_spell/ambush
|
||||
name = "Prepare Ambush"
|
||||
desc = "Prepare an ambush. Dealing significantly more damage on the first hit and you will weaken the target. Only works while morphed. If the target tries to use you with their hands then you will do even more damage. \
|
||||
Keeping still for another 15 seconds will perfect your disguise."
|
||||
action_icon_state = "morph_ambush"
|
||||
base_cooldown = 8 SECONDS
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/ambush/create_new_targeting()
|
||||
/datum/spell/morph_spell/ambush/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/ambush/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message)
|
||||
/datum/spell/morph_spell/ambush/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -23,7 +23,7 @@
|
||||
to_chat(user, "<span class='warning'>You are already prepared!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/ambush/cast(list/targets, mob/living/simple_animal/hostile/morph/user)
|
||||
/datum/spell/morph_spell/ambush/cast(list/targets, mob/living/simple_animal/hostile/morph/user)
|
||||
to_chat(user, "<span class='sinister'>You start preparing an ambush.</span>")
|
||||
if(!do_after(user, 6 SECONDS, FALSE, user, TRUE, list(CALLBACK(src, PROC_REF(prepare_check), user)), FALSE))
|
||||
if(!user.morphed)
|
||||
@@ -33,7 +33,7 @@
|
||||
return
|
||||
user.prepare_ambush()
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/ambush/proc/prepare_check(mob/living/simple_animal/hostile/morph/user)
|
||||
/datum/spell/morph_spell/ambush/proc/prepare_check(mob/living/simple_animal/hostile/morph/user)
|
||||
return !user.morphed
|
||||
|
||||
/datum/status_effect/morph_ambush
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
/obj/effect/proc_holder/spell/morph_spell
|
||||
/datum/spell/morph_spell
|
||||
action_background_icon_state = "bg_morph"
|
||||
clothes_req = FALSE
|
||||
/// How much food it costs the morph to use this
|
||||
var/hunger_cost = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/Initialize(mapload)
|
||||
. = ..()
|
||||
/datum/spell/morph_spell/New()
|
||||
..()
|
||||
if(hunger_cost)
|
||||
name = "[name] ([hunger_cost])"
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/create_new_handler()
|
||||
/datum/spell/morph_spell/create_new_handler()
|
||||
var/datum/spell_handler/morph/H = new
|
||||
H.hunger_cost = hunger_cost
|
||||
return H
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/obj/effect/proc_holder/spell/morph_spell/open_vent
|
||||
/datum/spell/morph_spell/open_vent
|
||||
name = "Open Vents"
|
||||
desc = "Spit out acidic puke on nearby vents or scrubbers. Will take a little while for the acid to take effect. Not usable from inside a vent."
|
||||
action_icon_state = "acid_vent"
|
||||
base_cooldown = 10 SECONDS
|
||||
hunger_cost = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/open_vent/create_new_targeting()
|
||||
/datum/spell/morph_spell/open_vent/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/T = new
|
||||
T.range = 1
|
||||
T.allowed_type = /obj/machinery/atmospherics/unary
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/open_vent/valid_target(target, user)
|
||||
/datum/spell/morph_spell/open_vent/valid_target(target, user)
|
||||
if(istype(target, /obj/machinery/atmospherics/unary/vent_scrubber))
|
||||
var/obj/machinery/atmospherics/unary/vent_scrubber/S = target
|
||||
return S.welded
|
||||
@@ -20,7 +20,7 @@
|
||||
return V.welded
|
||||
return FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/open_vent/cast(list/targets, mob/user)
|
||||
/datum/spell/morph_spell/open_vent/cast(list/targets, mob/user)
|
||||
if(!length(targets))
|
||||
to_chat(user, "<span class='warning'>No nearby welded vents found!</span>")
|
||||
revert_cast(user)
|
||||
@@ -36,7 +36,7 @@
|
||||
addtimer(CALLBACK(src, PROC_REF(unweld_vent), U), 2 SECONDS)
|
||||
playsound(U, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/open_vent/proc/unweld_vent(obj/machinery/atmospherics/unary/U)
|
||||
/datum/spell/morph_spell/open_vent/proc/unweld_vent(obj/machinery/atmospherics/unary/U)
|
||||
if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber))
|
||||
var/obj/machinery/atmospherics/unary/vent_scrubber/S = U
|
||||
S.welded = FALSE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// TODO refactor when spell code is component based instead of OO based
|
||||
/obj/effect/proc_holder/spell/morph_spell/pass_airlock
|
||||
/datum/spell/morph_spell/pass_airlock
|
||||
name = "Pass Airlock"
|
||||
desc = "Reform yourself so you can fit through a non bolted airlock. Takes a while to do and can only be used in a non disguised form."
|
||||
action_background_icon_state = "bg_morph"
|
||||
@@ -8,7 +8,7 @@
|
||||
base_cooldown = 10 SECONDS
|
||||
selection_activated_message = "<span class='sinister'>Click on an airlock to try pass it.</span>"
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/pass_airlock/create_new_targeting()
|
||||
/datum/spell/morph_spell/pass_airlock/create_new_targeting()
|
||||
var/datum/spell_targeting/click/T = new
|
||||
T.range = 1
|
||||
T.allowed_type = /obj/machinery/door/airlock
|
||||
@@ -16,7 +16,7 @@
|
||||
return T
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/pass_airlock/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message)
|
||||
/datum/spell/morph_spell/pass_airlock/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -26,7 +26,7 @@
|
||||
to_chat(user, "<span class='warning'>You can only pass through airlocks in your true form!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/pass_airlock/cast(list/targets, mob/living/simple_animal/hostile/morph/user)
|
||||
/datum/spell/morph_spell/pass_airlock/cast(list/targets, mob/living/simple_animal/hostile/morph/user)
|
||||
var/obj/machinery/door/airlock/A = targets[1]
|
||||
if(A.locked)
|
||||
to_chat(user, "<span class='warning'>[A] is bolted shut! You're unable to create a crack to pass through!</span>")
|
||||
@@ -49,5 +49,5 @@
|
||||
user.forceMove(A.loc) // Move into the turf of the airlock
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/pass_airlock/proc/pass_check(mob/living/simple_animal/hostile/morph/user, obj/machinery/door/airlock/A)
|
||||
/datum/spell/morph_spell/pass_airlock/proc/pass_check(mob/living/simple_animal/hostile/morph/user, obj/machinery/door/airlock/A)
|
||||
return user.morphed || A.locked
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/effect/proc_holder/spell/morph_spell/reproduce
|
||||
/datum/spell/morph_spell/reproduce
|
||||
name = "Reproduce"
|
||||
desc = "Split yourself in half making a new morph. Can only be used while on a floor. Makes you temporarily unable to vent crawl."
|
||||
hunger_cost = 150 // 5 humans
|
||||
@@ -6,10 +6,10 @@
|
||||
action_icon_state = "morph_reproduce"
|
||||
create_attack_logs = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/reproduce/create_new_targeting()
|
||||
/datum/spell/morph_spell/reproduce/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/reproduce/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message)
|
||||
/datum/spell/morph_spell/reproduce/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -18,7 +18,7 @@
|
||||
to_chat(user, "<span class='warning'>You can only split while on flooring!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/morph_spell/reproduce/cast(list/targets, mob/living/simple_animal/hostile/morph/user)
|
||||
/datum/spell/morph_spell/reproduce/cast(list/targets, mob/living/simple_animal/hostile/morph/user)
|
||||
to_chat(user, "<span class='sinister'>You prepare to split in two, making you unable to vent crawl!</span>")
|
||||
user.ventcrawler = VENTCRAWLER_NONE // Temporarily disable it
|
||||
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a morph?", ROLE_MORPH, TRUE, poll_time = 10 SECONDS, source = /mob/living/simple_animal/hostile/morph)
|
||||
|
||||
@@ -254,16 +254,16 @@
|
||||
SSticker.mode.traitors |= mind
|
||||
|
||||
/mob/living/simple_animal/demon/pulse_demon/proc/give_spells()
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/cycle_camera)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/toggle/do_drain(do_drain))
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable(can_exit_cable))
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/cablehop)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/emagtamper)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/emp)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/overload)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/remotehijack)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/remotedrain)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/open_upgrades)
|
||||
AddSpell(new /datum/spell/pulse_demon/cycle_camera)
|
||||
AddSpell(new /datum/spell/pulse_demon/toggle/do_drain(do_drain))
|
||||
AddSpell(new /datum/spell/pulse_demon/toggle/can_exit_cable(can_exit_cable))
|
||||
AddSpell(new /datum/spell/pulse_demon/cablehop)
|
||||
AddSpell(new /datum/spell/pulse_demon/emagtamper)
|
||||
AddSpell(new /datum/spell/pulse_demon/emp)
|
||||
AddSpell(new /datum/spell/pulse_demon/overload)
|
||||
AddSpell(new /datum/spell/pulse_demon/remotehijack)
|
||||
AddSpell(new /datum/spell/pulse_demon/remotedrain)
|
||||
AddSpell(new /datum/spell/pulse_demon/open_upgrades)
|
||||
|
||||
/mob/living/simple_animal/demon/pulse_demon/get_status_tab_items()
|
||||
var/list/status_tab_data = ..()
|
||||
@@ -299,7 +299,7 @@
|
||||
forceMove(T)
|
||||
Move(T)
|
||||
if(!current_cable && !current_power)
|
||||
var/obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable/S = locate() in mob_spell_list
|
||||
var/datum/spell/pulse_demon/toggle/can_exit_cable/S = locate() in mob_spell_list
|
||||
if(!S.locked && !can_exit_cable)
|
||||
can_exit_cable = TRUE
|
||||
S.do_toggle(can_exit_cable)
|
||||
@@ -318,7 +318,7 @@
|
||||
|
||||
if((!prev && !controlling_area) || (prev && controlling_area))
|
||||
return // only update icons when we get or no longer have ANY area
|
||||
for(var/obj/effect/proc_holder/spell/pulse_demon/S in mob_spell_list)
|
||||
for(var/datum/spell/pulse_demon/S in mob_spell_list)
|
||||
if(!S.action || S.locked)
|
||||
continue
|
||||
if(S.requires_area)
|
||||
@@ -429,7 +429,7 @@
|
||||
charge_drained += realdelta
|
||||
|
||||
update_glow()
|
||||
for(var/obj/effect/proc_holder/spell/pulse_demon/S in mob_spell_list)
|
||||
for(var/datum/spell/pulse_demon/S in mob_spell_list)
|
||||
if(!S.action || S.locked || !S.cast_cost)
|
||||
continue
|
||||
var/dist = S.cast_cost - orig
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define PD_UPGRADE_HEALTH_COST "Efficiency"
|
||||
#define PD_UPGRADE_MAX_CHARGE "Capacity"
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon
|
||||
/datum/spell/pulse_demon
|
||||
panel = "Pulse Demon"
|
||||
school = "pulse demon"
|
||||
clothes_req = FALSE
|
||||
@@ -21,11 +21,11 @@
|
||||
base_cooldown = 20 SECONDS
|
||||
level_max = 4
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/New()
|
||||
/datum/spell/pulse_demon/New()
|
||||
. = ..()
|
||||
update_info()
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/proc/update_info()
|
||||
/datum/spell/pulse_demon/proc/update_info()
|
||||
if(locked)
|
||||
name = "[initial(name)] (Locked) ([format_si_suffix(unlock_cost)]W)"
|
||||
desc = "[initial(desc)] It costs [format_si_suffix(unlock_cost)]W to unlock."
|
||||
@@ -36,7 +36,7 @@
|
||||
action.desc = desc
|
||||
action.UpdateButtons()
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/can_cast(mob/living/simple_animal/demon/pulse_demon/user, charge_check, show_message)
|
||||
/datum/spell/pulse_demon/can_cast(mob/living/simple_animal/demon/pulse_demon/user, charge_check, show_message)
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(!istype(user))
|
||||
@@ -57,7 +57,7 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/cast(list/targets, mob/living/simple_animal/demon/pulse_demon/user)
|
||||
/datum/spell/pulse_demon/cast(list/targets, mob/living/simple_animal/demon/pulse_demon/user)
|
||||
if(!istype(user) || locked || user.charge < cast_cost || !length(targets))
|
||||
return FALSE
|
||||
if(requires_area && !user.controlling_area)
|
||||
@@ -72,14 +72,14 @@
|
||||
revert_cast(user)
|
||||
return FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/create_new_targeting()
|
||||
/datum/spell/pulse_demon/create_new_targeting()
|
||||
return new /datum/spell_targeting/clicked_atom
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/proc/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/proc/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
return FALSE
|
||||
|
||||
// handles purchasing and upgrading abilities
|
||||
/obj/effect/proc_holder/spell/pulse_demon/AltClick(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
/datum/spell/pulse_demon/AltClick(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
|
||||
@@ -115,11 +115,11 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You cannot afford to upgrade this ability! It costs [format_si_suffix(upgrade_cost)]W to upgrade.</span>")
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/proc/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
/datum/spell/pulse_demon/proc/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
cooldown_handler.recharge_duration = round(base_cooldown / (1.5 ** spell_level))
|
||||
to_chat(user, "<span class='notice'>You have upgraded [initial(name)] to level [spell_level + 1], it now takes [cooldown_handler.recharge_duration / 10] seconds to recharge.</span>")
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/cablehop
|
||||
/datum/spell/pulse_demon/cablehop
|
||||
name = "Cable Hop"
|
||||
desc = "Jump to another cable in view."
|
||||
action_icon_state = "pd_cablehop"
|
||||
@@ -127,7 +127,7 @@
|
||||
cast_cost = 5 KW
|
||||
upgrade_cost = 75 KW
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/cablehop/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/cablehop/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
var/turf/O = get_turf(user)
|
||||
var/turf/T = get_turf(target)
|
||||
var/obj/structure/cable/C = locate(/obj/structure/cable) in T
|
||||
@@ -145,7 +145,7 @@
|
||||
user.Move(T)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/emagtamper
|
||||
/datum/spell/pulse_demon/emagtamper
|
||||
name = "Electromagnetic Tamper"
|
||||
desc = "Unlocks hidden programming in machines. Must be inside a hijacked APC to use."
|
||||
action_icon_state = "pd_emag"
|
||||
@@ -154,12 +154,12 @@
|
||||
upgrade_cost = 200 KW
|
||||
requires_area = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/emagtamper/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/emagtamper/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
to_chat(user, "<span class='warning'>You attempt to tamper with [target]!</span>")
|
||||
target.emag_act(user)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/emp
|
||||
/datum/spell/pulse_demon/emp
|
||||
name = "Electromagnetic Pulse"
|
||||
desc = "Creates an EMP where you click. Be careful not to use it on yourself!"
|
||||
action_icon_state = "pd_emp"
|
||||
@@ -168,12 +168,12 @@
|
||||
upgrade_cost = 200 KW
|
||||
requires_area = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/emp/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/emp/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
to_chat(user, "<span class='warning'>You attempt to EMP [target]!</span>")
|
||||
empulse(get_turf(target), 1, 1)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/overload
|
||||
/datum/spell/pulse_demon/overload
|
||||
name = "Overload Machine"
|
||||
desc = "Overloads a machine, causing it to explode."
|
||||
action_icon_state = "pd_overload"
|
||||
@@ -182,7 +182,7 @@
|
||||
upgrade_cost = 500 KW
|
||||
requires_area = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/overload/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/overload/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
var/obj/machinery/M = target
|
||||
if(!istype(M))
|
||||
to_chat(user, "<span class='warning'>That is not a machine.</span>")
|
||||
@@ -194,13 +194,13 @@
|
||||
addtimer(CALLBACK(src, PROC_REF(detonate), M), 5 SECONDS)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/overload/proc/detonate(obj/machinery/target)
|
||||
/datum/spell/pulse_demon/overload/proc/detonate(obj/machinery/target)
|
||||
if(!QDELETED(target))
|
||||
explosion(get_turf(target), 0, 1, 1, 0)
|
||||
if(!QDELETED(target))
|
||||
qdel(target)
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/remotehijack
|
||||
/datum/spell/pulse_demon/remotehijack
|
||||
name = "Remote Hijack"
|
||||
desc = "Remotely hijacks an APC."
|
||||
action_icon_state = "pd_remotehack"
|
||||
@@ -209,7 +209,7 @@
|
||||
level_max = 0
|
||||
base_cooldown = 3 SECONDS // you have to wait for the regular hijack time anyway
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/remotehijack/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/remotehijack/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
var/obj/machinery/power/apc/A = target
|
||||
if(!istype(A))
|
||||
to_chat(user, "<span class='warning'>That is not an APC.</span>")
|
||||
@@ -218,7 +218,7 @@
|
||||
to_chat(user, "<span class='warning'>You cannot hijack that APC right now!</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/remotedrain
|
||||
/datum/spell/pulse_demon/remotedrain
|
||||
name = "Remote Drain"
|
||||
desc = "Remotely drains a power source."
|
||||
action_icon_state = "pd_remotedrain"
|
||||
@@ -226,7 +226,7 @@
|
||||
cast_cost = 100
|
||||
upgrade_cost = 100 KW
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/remotedrain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/remotedrain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
if(isapc(target))
|
||||
var/drained = user.drain_APC(target, PULSEDEMON_REMOTE_DRAIN_MULTIPLIER)
|
||||
if(drained == PULSEDEMON_SOURCE_DRAIN_INVALID)
|
||||
@@ -241,20 +241,20 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle
|
||||
/datum/spell/pulse_demon/toggle
|
||||
base_cooldown = 0
|
||||
cast_cost = 0
|
||||
create_attack_logs = FALSE
|
||||
var/base_message = "see messages you shouldn't!"
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle/New(initstate = FALSE)
|
||||
/datum/spell/pulse_demon/toggle/New(initstate = FALSE)
|
||||
. = ..()
|
||||
do_toggle(initstate, null)
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle/create_new_targeting()
|
||||
/datum/spell/pulse_demon/toggle/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle/proc/do_toggle(varstate, mob/user)
|
||||
/datum/spell/pulse_demon/toggle/proc/do_toggle(varstate, mob/user)
|
||||
if(action)
|
||||
action.background_icon_state = varstate ? action_background_icon_state : "[action_background_icon_state]_disabled"
|
||||
action.UpdateButtons()
|
||||
@@ -262,7 +262,7 @@
|
||||
to_chat(user, "<span class='notice'>You will [varstate ? "now" : "no longer"] [base_message]</span>")
|
||||
return varstate
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle/do_drain
|
||||
/datum/spell/pulse_demon/toggle/do_drain
|
||||
name = "Toggle Draining"
|
||||
desc = "Toggle whether you drain charge from power sources."
|
||||
base_message = "drain charge from power sources."
|
||||
@@ -270,11 +270,11 @@
|
||||
locked = FALSE
|
||||
level_max = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle/do_drain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/toggle/do_drain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
user.do_drain = do_toggle(!user.do_drain, user)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle/do_drain/AltClick(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
/datum/spell/pulse_demon/toggle/do_drain/AltClick(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
|
||||
@@ -288,7 +288,7 @@
|
||||
user.power_drain_rate = amount
|
||||
to_chat(user, "<span class='notice'>Drain speed has been set to [format_si_suffix(user.power_drain_rate)]W per second.</span>")
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable
|
||||
/datum/spell/pulse_demon/toggle/can_exit_cable
|
||||
name = "Toggle Self-Sustaining"
|
||||
desc = "Toggle whether you can move outside of cables or power sources."
|
||||
base_message = "move outside of cables."
|
||||
@@ -297,18 +297,18 @@
|
||||
upgrade_cost = 300 KW
|
||||
level_max = 3
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/toggle/can_exit_cable/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
if(user.can_exit_cable && !(user.current_cable || user.current_power))
|
||||
to_chat(user, "<span class='warning'>Enter a cable or power source first!</span>")
|
||||
return FALSE
|
||||
user.can_exit_cable = do_toggle(!user.can_exit_cable, user)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
/datum/spell/pulse_demon/toggle/can_exit_cable/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
user.outside_cable_speed = max(initial(user.outside_cable_speed) - spell_level, 1)
|
||||
to_chat(user, "<span class='notice'>You have upgraded [initial(name)] to level [spell_level + 1], you will now move faster outside of cables.</span>")
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/cycle_camera
|
||||
/datum/spell/pulse_demon/cycle_camera
|
||||
name = "Cycle Camera View"
|
||||
desc = "Jump between the cameras in your APC's area. Alt-click to return to the APC."
|
||||
action_icon_state = "pd_camera_view"
|
||||
@@ -320,10 +320,10 @@
|
||||
requires_area = TRUE
|
||||
var/current_camera = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/cycle_camera/create_new_targeting()
|
||||
/datum/spell/pulse_demon/cycle_camera/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/cycle_camera/AltClick(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
/datum/spell/pulse_demon/cycle_camera/AltClick(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
current_camera = 0
|
||||
@@ -334,7 +334,7 @@
|
||||
return
|
||||
user.forceMove(user.current_power)
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/cycle_camera/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/cycle_camera/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
if(!length(user.controlling_area.cameras))
|
||||
return FALSE
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
user.forceMove(locateUID(user.controlling_area.cameras[current_camera + 1]))
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/open_upgrades
|
||||
/datum/spell/pulse_demon/open_upgrades
|
||||
name = "Open Upgrade Menu"
|
||||
desc = "Open the upgrades menu. Alt-click for descriptions and costs."
|
||||
action_icon_state = "pd_upgrade"
|
||||
@@ -380,10 +380,10 @@
|
||||
PD_UPGRADE_MAX_CHARGE = "Increase the total amount of charge you can have at once."
|
||||
)
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/create_new_targeting()
|
||||
/datum/spell/pulse_demon/open_upgrades/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/proc/calc_cost(mob/living/simple_animal/demon/pulse_demon/user, upgrade)
|
||||
/datum/spell/pulse_demon/open_upgrades/proc/calc_cost(mob/living/simple_animal/demon/pulse_demon/user, upgrade)
|
||||
var/cost
|
||||
switch(upgrade)
|
||||
if(PD_UPGRADE_HIJACK_SPEED)
|
||||
@@ -416,7 +416,7 @@
|
||||
return -1
|
||||
return round(cost)
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/proc/get_upgrades(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
/datum/spell/pulse_demon/open_upgrades/proc/get_upgrades(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
var/upgrades = list()
|
||||
for(var/upgrade in upgrade_icons)
|
||||
var/cost = calc_cost(user, upgrade)
|
||||
@@ -425,7 +425,7 @@
|
||||
upgrades["[upgrade] ([format_si_suffix(cost)]W)"] = upgrade_icons[upgrade]
|
||||
return upgrades
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/AltClick(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
/datum/spell/pulse_demon/open_upgrades/AltClick(mob/living/simple_animal/demon/pulse_demon/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
|
||||
@@ -434,7 +434,7 @@
|
||||
var/cost = calc_cost(user, upgrade)
|
||||
to_chat(user, "<b>[upgrade]</b> ([cost == -1 ? "Fully Upgraded" : "[format_si_suffix(cost)]W"]) - [upgrade_descs[upgrade]]")
|
||||
|
||||
/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
/datum/spell/pulse_demon/open_upgrades/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target)
|
||||
var/upgrades = get_upgrades(user)
|
||||
if(!length(upgrades))
|
||||
to_chat(user, "<span class='warning'>You have already fully upgraded everything available!</span>")
|
||||
|
||||
@@ -192,13 +192,13 @@
|
||||
to_chat(src, chat_box_red(messages.Join("<br>")))
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/giveSpells()
|
||||
mind.AddSpell(new /obj/effect/proc_holder/spell/night_vision/revenant(null))
|
||||
mind.AddSpell(new /obj/effect/proc_holder/spell/revenant_transmit(null))
|
||||
mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/defile(null))
|
||||
mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/malfunction(null))
|
||||
mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/overload(null))
|
||||
mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/haunt_object(null))
|
||||
mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/hallucinations(null))
|
||||
mind.AddSpell(new /datum/spell/night_vision/revenant(null))
|
||||
mind.AddSpell(new /datum/spell/revenant_transmit(null))
|
||||
mind.AddSpell(new /datum/spell/aoe/revenant/defile(null))
|
||||
mind.AddSpell(new /datum/spell/aoe/revenant/malfunction(null))
|
||||
mind.AddSpell(new /datum/spell/aoe/revenant/overload(null))
|
||||
mind.AddSpell(new /datum/spell/aoe/revenant/haunt_object(null))
|
||||
mind.AddSpell(new /datum/spell/aoe/revenant/hallucinations(null))
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
return
|
||||
|
||||
//Toggle night vision: lets the revenant toggle its night vision
|
||||
/obj/effect/proc_holder/spell/night_vision/revenant
|
||||
/datum/spell/night_vision/revenant
|
||||
base_cooldown = 0
|
||||
panel = "Revenant Abilities"
|
||||
message = "<span class='revennotice'>You toggle your night vision.</span>"
|
||||
@@ -116,7 +116,7 @@
|
||||
action_background_icon_state = "bg_revenant"
|
||||
|
||||
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
|
||||
/obj/effect/proc_holder/spell/revenant_transmit
|
||||
/datum/spell/revenant_transmit
|
||||
name = "Transmit"
|
||||
desc = "Telepathically transmits a message to the target."
|
||||
panel = "Revenant Abilities"
|
||||
@@ -125,12 +125,12 @@
|
||||
action_icon_state = "r_transmit"
|
||||
action_background_icon_state = "bg_revenant"
|
||||
|
||||
/obj/effect/proc_holder/spell/revenant_transmit/create_new_targeting()
|
||||
/datum/spell/revenant_transmit/create_new_targeting()
|
||||
var/datum/spell_targeting/targeted/T = new()
|
||||
T.allowed_type = /mob/living
|
||||
return T
|
||||
|
||||
/obj/effect/proc_holder/spell/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
/datum/spell/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
for(var/mob/living/M in targets)
|
||||
spawn(0)
|
||||
var/msg = tgui_input_text(user, "What do you wish to tell [M]?", "Transmit")
|
||||
@@ -141,7 +141,7 @@
|
||||
to_chat(user, "<span class='revennotice'><b>You transmit to [M]:</b> [msg]</span>")
|
||||
to_chat(M, "<span class='revennotice'><b>An alien voice resonates from all around...</b></span><i> [msg]</I>")
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant
|
||||
/datum/spell/aoe/revenant
|
||||
name = "Spell"
|
||||
clothes_req = FALSE
|
||||
action_background_icon_state = "bg_revenant"
|
||||
@@ -157,20 +157,20 @@
|
||||
/// How much essence it costs to use
|
||||
var/cast_amount = 50
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/New()
|
||||
/datum/spell/aoe/revenant/New()
|
||||
..()
|
||||
if(locked)
|
||||
name = "[initial(name)] ([unlock_amount]E)"
|
||||
else
|
||||
name = "[initial(name)] ([cast_amount]E)"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/revert_cast(mob/user)
|
||||
/datum/spell/aoe/revenant/revert_cast(mob/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='revennotice'>Your ability wavers and fails!</span>")
|
||||
var/mob/living/simple_animal/revenant/R = user
|
||||
R?.essence += cast_amount //refund the spell and reset
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/can_cast(mob/living/simple_animal/revenant/user = usr, charge_check = TRUE, show_message = FALSE)
|
||||
/datum/spell/aoe/revenant/can_cast(mob/living/simple_animal/revenant/user = usr, charge_check = TRUE, show_message = FALSE)
|
||||
if(user.inhibited)
|
||||
return FALSE
|
||||
if(cooldown_handler.is_on_cooldown())
|
||||
@@ -182,7 +182,7 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr)
|
||||
/datum/spell/aoe/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr)
|
||||
if(locked)
|
||||
if(!user.castcheck(-unlock_amount))
|
||||
cooldown_handler.revert_cast()
|
||||
@@ -204,7 +204,7 @@
|
||||
return TRUE
|
||||
|
||||
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/overload
|
||||
/datum/spell/aoe/revenant/overload
|
||||
name = "Overload Lights"
|
||||
desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby."
|
||||
base_cooldown = 20 SECONDS
|
||||
@@ -215,21 +215,21 @@
|
||||
action_icon_state = "overload_lights"
|
||||
aoe_range = 5
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/overload/create_new_targeting()
|
||||
/datum/spell/aoe/revenant/overload/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/targeting = new()
|
||||
targeting.range = aoe_range
|
||||
targeting.allowed_type = /obj/machinery/light
|
||||
return targeting
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
/datum/spell/aoe/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
if(attempt_cast(user))
|
||||
for(var/obj/machinery/light/L as anything in targets)
|
||||
INVOKE_ASYNC(src, PROC_REF(shock_lights), L, user)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/overload/proc/shock_lights(obj/machinery/light/L, mob/living/simple_animal/revenant/user)
|
||||
/datum/spell/aoe/revenant/overload/proc/shock_lights(obj/machinery/light/L, mob/living/simple_animal/revenant/user)
|
||||
if(!L.on)
|
||||
return
|
||||
L.visible_message("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</span>")
|
||||
L.visible_message("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</b></span>")
|
||||
do_sparks(4, 0, L)
|
||||
new /obj/effect/temp_visual/revenant(L.loc)
|
||||
sleep(2 SECONDS)
|
||||
@@ -246,7 +246,7 @@
|
||||
playsound(M, 'sound/machines/defib_zap.ogg', 50, TRUE, -1)
|
||||
|
||||
//Defile: Corrupts nearby stuff, unblesses floor tiles.
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/defile
|
||||
/datum/spell/aoe/revenant/defile
|
||||
name = "Defile"
|
||||
desc = "Twists and corrupts the nearby area as well as dispelling holy auras on floors."
|
||||
base_cooldown = 15 SECONDS
|
||||
@@ -257,12 +257,12 @@
|
||||
action_icon_state = "defile"
|
||||
aoe_range = 4
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/defile/create_new_targeting()
|
||||
/datum/spell/aoe/revenant/defile/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/turf/targeting = new()
|
||||
targeting.range = aoe_range
|
||||
return targeting
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
/datum/spell/aoe/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
if(!attempt_cast(user))
|
||||
return
|
||||
for(var/turf/T in targets)
|
||||
@@ -271,7 +271,7 @@
|
||||
A.defile()
|
||||
|
||||
//Malfunction: Makes bad stuff happen to robots and machines.
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/malfunction
|
||||
/datum/spell/aoe/revenant/malfunction
|
||||
name = "Malfunction"
|
||||
desc = "Corrupts and damages nearby machines and mechanical objects."
|
||||
base_cooldown = 200
|
||||
@@ -280,18 +280,18 @@
|
||||
action_icon_state = "malfunction"
|
||||
aoe_range = 2
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/malfunction/create_new_targeting()
|
||||
/datum/spell/aoe/revenant/malfunction/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/turf/targeting = new()
|
||||
targeting.range = aoe_range
|
||||
return targeting
|
||||
|
||||
//A note to future coders: do not replace this with an EMP because it will wreck malf AIs and gang dominators and everyone will hate you.
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
/datum/spell/aoe/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
if(attempt_cast(user))
|
||||
for(var/turf/T in targets)
|
||||
INVOKE_ASYNC(src, PROC_REF(effect), user, T)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/malfunction/proc/effect(mob/living/simple_animal/revenant/user, turf/T)
|
||||
/datum/spell/aoe/revenant/malfunction/proc/effect(mob/living/simple_animal/revenant/user, turf/T)
|
||||
T.rev_malfunction(TRUE)
|
||||
for(var/atom/A in T.contents)
|
||||
A.rev_malfunction(TRUE)
|
||||
@@ -299,7 +299,7 @@
|
||||
/**
|
||||
* Makes objects be haunted and then throws them at conscious people to do damage, spooky!
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/haunt_object
|
||||
/datum/spell/aoe/revenant/haunt_object
|
||||
name = "Haunt Objects"
|
||||
desc = "Empower nearby objects to you with ghostly energy, causing them to attack nearby mortals. \
|
||||
Items closer to you are more likely to be haunted."
|
||||
@@ -315,13 +315,13 @@
|
||||
/// A list of all attack timers started by this spell being cast
|
||||
var/list/attack_timers = list()
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/create_new_targeting()
|
||||
/datum/spell/aoe/revenant/haunt_object/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/targeting = new()
|
||||
targeting.range = aoe_range
|
||||
targeting.allowed_type = /obj/item
|
||||
return targeting
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
/datum/spell/aoe/revenant/haunt_object/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
if(!attempt_cast(user))
|
||||
return
|
||||
|
||||
@@ -357,7 +357,7 @@
|
||||
addtimer(CALLBACK(src, PROC_REF(stop_timers)), 65 SECONDS, TIMER_UNIQUE)
|
||||
|
||||
/// Handles making an object haunted and setting it up to attack
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/proc/make_spooky(obj/item/item_to_possess, mob/living/simple_animal/revenant/user)
|
||||
/datum/spell/aoe/revenant/haunt_object/proc/make_spooky(obj/item/item_to_possess, mob/living/simple_animal/revenant/user)
|
||||
new /obj/effect/temp_visual/revenant(get_turf(item_to_possess)) // Thematic spooky visuals
|
||||
var/mob/living/simple_animal/possessed_object/possessed_object = new(item_to_possess) // Begin haunting object
|
||||
item_to_possess.throwforce = min(item_to_possess.throwforce + 5, 15) // Damage it should do? throwforce+5 or 15, whichever is lower
|
||||
@@ -372,7 +372,7 @@
|
||||
addtimer(CALLBACK(possessed_object, TYPE_PROC_REF(/mob/living/simple_animal/possessed_object, death)), 70 SECONDS, TIMER_UNIQUE) // De-haunt the object
|
||||
|
||||
/// Handles finding a valid target and throwing us at it
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/proc/attack(mob/living/simple_animal/possessed_object/possessed_object, mob/living/simple_animal/revenant/user)
|
||||
/datum/spell/aoe/revenant/haunt_object/proc/attack(mob/living/simple_animal/possessed_object/possessed_object, mob/living/simple_animal/revenant/user)
|
||||
var/list/potential_victims = list()
|
||||
for(var/turf/turf_to_search in spiral_range_turfs(aoe_range, get_turf(possessed_object)))
|
||||
for(var/mob/living/carbon/potential_victim in turf_to_search)
|
||||
@@ -393,20 +393,20 @@
|
||||
possessed_object.throw_at(victim, aoe_range, 2, user, dodgeable = FALSE)
|
||||
|
||||
/// Sets the glow on the haunted object, scales up based on throwforce
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/proc/set_outline(mob/living/simple_animal/possessed_object/possessed_object)
|
||||
/datum/spell/aoe/revenant/haunt_object/proc/set_outline(mob/living/simple_animal/possessed_object/possessed_object)
|
||||
possessed_object.remove_filter("haunt_glow")
|
||||
var/outline_size = min((possessed_object.possessed_item.throwforce / 15) * 3, 3)
|
||||
possessed_object.add_filter("haunt_glow", 2, list("type" = "outline", "color" = "#7A4FA9", "size" = outline_size)) // Give it spooky purple outline
|
||||
|
||||
/// Stop all attack timers cast by the previous spell use
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/proc/stop_timers()
|
||||
/datum/spell/aoe/revenant/haunt_object/proc/stop_timers()
|
||||
for(var/I in attack_timers)
|
||||
deltimer(I)
|
||||
|
||||
/**
|
||||
* Gives everyone in a 7 tile radius 2 minutes of hallucinations
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/hallucinations
|
||||
/datum/spell/aoe/revenant/hallucinations
|
||||
name = "Hallucination Aura"
|
||||
desc = "Toy with the living nearby, giving them glimpses of things that could be or once were."
|
||||
action_icon_state = "hallucinations"
|
||||
@@ -416,13 +416,13 @@
|
||||
stun = 1 SECONDS
|
||||
reveal = 3 SECONDS
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/hallucinations/create_new_targeting()
|
||||
/datum/spell/aoe/revenant/hallucinations/create_new_targeting()
|
||||
var/datum/spell_targeting/aoe/targeting = new()
|
||||
targeting.range = aoe_range
|
||||
targeting.allowed_type = /mob/living/carbon
|
||||
return targeting
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe/revenant/hallucinations/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
/datum/spell/aoe/revenant/hallucinations/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
if(!attempt_cast(user))
|
||||
return
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "High Five?"
|
||||
var/catchphrase = "High Five!"
|
||||
var/on_use_sound = null
|
||||
var/obj/effect/proc_holder/spell/touch/attached_spell
|
||||
var/datum/spell/touch/attached_spell
|
||||
icon = 'icons/obj/weapons/magical_weapons.dmi'
|
||||
icon_state = "disintegrate"
|
||||
item_state = null
|
||||
|
||||
@@ -400,9 +400,9 @@
|
||||
if(SS.purified)
|
||||
make_holy()
|
||||
// Replace regular soulstone summoning with purified soulstones
|
||||
if(is_type_in_list(/obj/effect/proc_holder/spell/aoe/conjure/build/soulstone, mob_spell_list))
|
||||
RemoveSpell(/obj/effect/proc_holder/spell/aoe/conjure/build/soulstone)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe/conjure/build/soulstone/holy)
|
||||
if(is_type_in_list(/datum/spell/aoe/conjure/build/soulstone, mob_spell_list))
|
||||
RemoveSpell(/datum/spell/aoe/conjure/build/soulstone)
|
||||
AddSpell(new /datum/spell/aoe/conjure/build/soulstone/holy)
|
||||
|
||||
else if(mind.has_antag_datum(/datum/antagonist/cultist)) // Re-grant cult actions, lost in the transfer
|
||||
var/datum/action/innate/cult/comm/CC = new
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
var/category = "Offensive"
|
||||
var/cost = 2
|
||||
var/refundable = TRUE
|
||||
var/obj/effect/proc_holder/spell/S = null //Since spellbooks can be used by only one person anyway we can track the actual spell
|
||||
var/datum/spell/S = null //Since spellbooks can be used by only one person anyway we can track the actual spell
|
||||
var/buy_word = "Learn"
|
||||
var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
return LearnSpell(user, book, S)
|
||||
|
||||
/datum/spellbook_entry/proc/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell)
|
||||
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
|
||||
/datum/spellbook_entry/proc/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, datum/spell/newspell)
|
||||
for(var/datum/spell/aspell in user.mind.spell_list)
|
||||
if(initial(newspell.name) == initial(aspell.name)) // Not using directly in case it was learned from one spellbook then upgraded in another
|
||||
if(aspell.spell_level >= aspell.level_max)
|
||||
to_chat(user, "<span class='warning'>This spell cannot be improved further.</span>")
|
||||
@@ -59,7 +59,7 @@
|
||||
return FALSE
|
||||
if(!S)
|
||||
S = new spell_type()
|
||||
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
|
||||
for(var/datum/spell/aspell in user.mind.spell_list)
|
||||
if(initial(S.name) == initial(aspell.name))
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -72,7 +72,7 @@
|
||||
if(!S) //This happens when the spell's source is from another spellbook, from loadouts, or adminery, this create a new template temporary spell
|
||||
S = new spell_type()
|
||||
var/spell_levels = 0
|
||||
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
|
||||
for(var/datum/spell/aspell in user.mind.spell_list)
|
||||
if(initial(S.name) == initial(aspell.name))
|
||||
spell_levels = aspell.spell_level
|
||||
user.mind.spell_list.Remove(aspell)
|
||||
@@ -97,126 +97,126 @@
|
||||
//Offensive
|
||||
/datum/spellbook_entry/blind
|
||||
name = "Blind"
|
||||
spell_type = /obj/effect/proc_holder/spell/trigger/blind
|
||||
spell_type = /datum/spell/genetic/blind
|
||||
category = "Offensive"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/lightningbolt
|
||||
name = "Lightning Bolt"
|
||||
spell_type = /obj/effect/proc_holder/spell/charge_up/bounce/lightning
|
||||
spell_type = /datum/spell/charge_up/bounce/lightning
|
||||
category = "Offensive"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/cluwne
|
||||
name = "Curse of the Cluwne"
|
||||
spell_type = /obj/effect/proc_holder/spell/touch/cluwne
|
||||
spell_type = /datum/spell/touch/cluwne
|
||||
category = "Offensive"
|
||||
|
||||
/datum/spellbook_entry/banana_touch
|
||||
name = "Banana Touch"
|
||||
spell_type = /obj/effect/proc_holder/spell/touch/banana
|
||||
spell_type = /datum/spell/touch/banana
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/mime_malaise
|
||||
name = "Mime Malaise"
|
||||
spell_type = /obj/effect/proc_holder/spell/touch/mime_malaise
|
||||
spell_type = /datum/spell/touch/mime_malaise
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/horseman
|
||||
name = "Curse of the Horseman"
|
||||
spell_type = /obj/effect/proc_holder/spell/horsemask
|
||||
spell_type = /datum/spell/horsemask
|
||||
category = "Offensive"
|
||||
|
||||
/datum/spellbook_entry/disintegrate
|
||||
name = "Disintegrate"
|
||||
spell_type = /obj/effect/proc_holder/spell/touch/disintegrate
|
||||
spell_type = /datum/spell/touch/disintegrate
|
||||
category = "Offensive"
|
||||
|
||||
/datum/spellbook_entry/fireball
|
||||
name = "Fireball"
|
||||
spell_type = /obj/effect/proc_holder/spell/fireball
|
||||
spell_type = /datum/spell/fireball
|
||||
category = "Offensive"
|
||||
|
||||
/datum/spellbook_entry/summon_toolbox
|
||||
name = "Homing Toolbox"
|
||||
spell_type = /obj/effect/proc_holder/spell/fireball/toolbox
|
||||
spell_type = /datum/spell/fireball/toolbox
|
||||
category = "Offensive"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/fleshtostone
|
||||
name = "Flesh to Stone"
|
||||
spell_type = /obj/effect/proc_holder/spell/touch/flesh_to_stone
|
||||
spell_type = /datum/spell/touch/flesh_to_stone
|
||||
category = "Offensive"
|
||||
|
||||
/datum/spellbook_entry/mutate
|
||||
name = "Mutate"
|
||||
spell_type = /obj/effect/proc_holder/spell/genetic/mutate
|
||||
spell_type = /datum/spell/genetic/mutate
|
||||
category = "Offensive"
|
||||
|
||||
/datum/spellbook_entry/rod_form
|
||||
name = "Rod Form"
|
||||
spell_type = /obj/effect/proc_holder/spell/rod_form
|
||||
spell_type = /datum/spell/rod_form
|
||||
category = "Offensive"
|
||||
|
||||
/datum/spellbook_entry/infinite_guns
|
||||
name = "Lesser Summon Guns"
|
||||
spell_type = /obj/effect/proc_holder/spell/infinite_guns
|
||||
spell_type = /datum/spell/infinite_guns
|
||||
category = "Offensive"
|
||||
|
||||
//Defensive
|
||||
/datum/spellbook_entry/disabletech
|
||||
name = "Disable Tech"
|
||||
spell_type = /obj/effect/proc_holder/spell/emplosion/disable_tech
|
||||
spell_type = /datum/spell/emplosion/disable_tech
|
||||
category = "Defensive"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/forcewall
|
||||
name = "Force Wall"
|
||||
spell_type = /obj/effect/proc_holder/spell/forcewall
|
||||
spell_type = /datum/spell/forcewall
|
||||
category = "Defensive"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/rathens
|
||||
name = "Rathen's Secret"
|
||||
spell_type = /obj/effect/proc_holder/spell/rathens
|
||||
spell_type = /datum/spell/rathens
|
||||
category = "Defensive"
|
||||
cost = 2
|
||||
|
||||
/datum/spellbook_entry/repulse
|
||||
name = "Repulse"
|
||||
spell_type = /obj/effect/proc_holder/spell/aoe/repulse
|
||||
spell_type = /datum/spell/aoe/repulse
|
||||
category = "Defensive"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/smoke
|
||||
name = "Smoke"
|
||||
spell_type = /obj/effect/proc_holder/spell/smoke
|
||||
spell_type = /datum/spell/smoke
|
||||
category = "Defensive"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/lichdom
|
||||
name = "Bind Soul"
|
||||
spell_type = /obj/effect/proc_holder/spell/lichdom
|
||||
spell_type = /datum/spell/lichdom
|
||||
category = "Defensive"
|
||||
is_ragin_restricted = TRUE
|
||||
|
||||
/datum/spellbook_entry/magicm
|
||||
name = "Magic Missile"
|
||||
spell_type = /obj/effect/proc_holder/spell/projectile/magic_missile
|
||||
spell_type = /datum/spell/projectile/magic_missile
|
||||
category = "Defensive"
|
||||
|
||||
/datum/spellbook_entry/timestop
|
||||
name = "Time Stop"
|
||||
spell_type = /obj/effect/proc_holder/spell/aoe/conjure/timestop
|
||||
spell_type = /datum/spell/aoe/conjure/timestop
|
||||
category = "Defensive"
|
||||
|
||||
/datum/spellbook_entry/sacred_flame
|
||||
name = "Sacred Flame and Fire Immunity"
|
||||
spell_type = /obj/effect/proc_holder/spell/sacred_flame
|
||||
spell_type = /datum/spell/sacred_flame
|
||||
cost = 1
|
||||
category = "Defensive"
|
||||
|
||||
/datum/spellbook_entry/sacred_flame/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell)
|
||||
/datum/spellbook_entry/sacred_flame/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, datum/spell/newspell)
|
||||
to_chat(user, "<span class='notice'>You feel fireproof.</span>")
|
||||
ADD_TRAIT(user, TRAIT_RESISTHEAT, MAGIC_TRAIT)
|
||||
ADD_TRAIT(user, TRAIT_RESISTHIGHPRESSURE, MAGIC_TRAIT)
|
||||
@@ -230,11 +230,11 @@
|
||||
|
||||
/datum/spellbook_entry/summon_supermatter
|
||||
name = "Summon Supermatter Crystal"
|
||||
spell_type = /obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter
|
||||
spell_type = /datum/spell/aoe/conjure/summon_supermatter
|
||||
cost = 3
|
||||
category = "Defensive"
|
||||
|
||||
/datum/spellbook_entry/summon_supermatter/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell)
|
||||
/datum/spellbook_entry/summon_supermatter/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, datum/spell/newspell)
|
||||
to_chat(user, "<span class='notice'>You feel a little bit of supermatter enter your body.</span>")
|
||||
ADD_TRAIT(user, TRAIT_RADIMMUNE, MAGIC_TRAIT)
|
||||
ADD_TRAIT(user, SM_HALLUCINATION_IMMUNE, MAGIC_TRAIT)
|
||||
@@ -249,64 +249,64 @@
|
||||
//Mobility
|
||||
/datum/spellbook_entry/knock
|
||||
name = "Knock"
|
||||
spell_type = /obj/effect/proc_holder/spell/aoe/knock
|
||||
spell_type = /datum/spell/aoe/knock
|
||||
category = "Mobility"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/blink
|
||||
name = "Blink"
|
||||
spell_type = /obj/effect/proc_holder/spell/turf_teleport/blink
|
||||
spell_type = /datum/spell/turf_teleport/blink
|
||||
category = "Mobility"
|
||||
|
||||
/datum/spellbook_entry/jaunt
|
||||
name = "Ethereal Jaunt"
|
||||
spell_type = /obj/effect/proc_holder/spell/ethereal_jaunt
|
||||
spell_type = /datum/spell/ethereal_jaunt
|
||||
category = "Mobility"
|
||||
|
||||
/datum/spellbook_entry/spacetime_dist
|
||||
name = "Spacetime Distortion"
|
||||
spell_type = /obj/effect/proc_holder/spell/spacetime_dist
|
||||
spell_type = /datum/spell/spacetime_dist
|
||||
cost = 1 //Better defence than greater forcewall (maybe) but good luck hitting anyone, so 1 point.
|
||||
category = "Mobility"
|
||||
|
||||
/datum/spellbook_entry/greaterknock
|
||||
name = "Greater Knock"
|
||||
spell_type = /obj/effect/proc_holder/spell/aoe/knock/greater
|
||||
spell_type = /datum/spell/aoe/knock/greater
|
||||
category = "Mobility"
|
||||
refundable = 0 //global effect on cast
|
||||
|
||||
/datum/spellbook_entry/mindswap
|
||||
name = "Mindswap"
|
||||
spell_type = /obj/effect/proc_holder/spell/mind_transfer
|
||||
spell_type = /datum/spell/mind_transfer
|
||||
category = "Mobility"
|
||||
|
||||
/datum/spellbook_entry/teleport
|
||||
name = "Teleport"
|
||||
spell_type = /obj/effect/proc_holder/spell/area_teleport/teleport
|
||||
spell_type = /datum/spell/area_teleport/teleport
|
||||
category = "Mobility"
|
||||
|
||||
//Assistance
|
||||
/datum/spellbook_entry/charge
|
||||
name = "Charge"
|
||||
spell_type = /obj/effect/proc_holder/spell/charge
|
||||
spell_type = /datum/spell/charge
|
||||
category = "Assistance"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/summonitem
|
||||
name = "Summon Item"
|
||||
spell_type = /obj/effect/proc_holder/spell/summonitem
|
||||
spell_type = /datum/spell/summonitem
|
||||
category = "Assistance"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/disguiseself
|
||||
name = "Disguise Self"
|
||||
spell_type = /obj/effect/proc_holder/spell/disguise_self
|
||||
spell_type = /datum/spell/disguise_self
|
||||
category = "Assistance"
|
||||
cost = 1
|
||||
|
||||
/datum/spellbook_entry/noclothes
|
||||
name = "Remove Clothes Requirement"
|
||||
spell_type = /obj/effect/proc_holder/spell/noclothes
|
||||
spell_type = /datum/spell/noclothes
|
||||
category = "Assistance"
|
||||
cost = 1
|
||||
|
||||
@@ -433,7 +433,7 @@
|
||||
/datum/spellbook_entry/item/soulstones/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
|
||||
. = ..()
|
||||
if(.)
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/conjure/construct(null))
|
||||
user.mind.AddSpell(new /datum/spell/aoe/conjure/construct(null))
|
||||
return .
|
||||
|
||||
/datum/spellbook_entry/item/wands
|
||||
@@ -676,7 +676,7 @@
|
||||
new path(B)
|
||||
user.put_in_hands(B)
|
||||
for(var/path in spells_path)
|
||||
var/obj/effect/proc_holder/spell/S = new path()
|
||||
var/datum/spell/S = new path()
|
||||
LearnSpell(user, book, S)
|
||||
OnBuy(user, book)
|
||||
return TRUE
|
||||
@@ -946,7 +946,7 @@
|
||||
|
||||
//Single Use Spellbooks
|
||||
/obj/item/spellbook/oneuse
|
||||
var/spell = /obj/effect/proc_holder/spell/projectile/magic_missile //just a placeholder to avoid runtimes if someone spawned the generic
|
||||
var/spell = /datum/spell/projectile/magic_missile //just a placeholder to avoid runtimes if someone spawned the generic
|
||||
var/spellname = "sandbox"
|
||||
var/used = FALSE
|
||||
name = "spellbook of "
|
||||
@@ -961,8 +961,8 @@
|
||||
return
|
||||
|
||||
/obj/item/spellbook/oneuse/attack_self(mob/user)
|
||||
var/obj/effect/proc_holder/spell/S = new spell
|
||||
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
|
||||
var/datum/spell/S = new spell
|
||||
for(var/datum/spell/knownspell in user.mind.spell_list)
|
||||
if(knownspell.type == S.type)
|
||||
if(user.mind)
|
||||
if(user.mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE || user.mind.special_role == SPECIAL_ROLE_WIZARD)
|
||||
@@ -990,7 +990,7 @@
|
||||
return
|
||||
|
||||
/obj/item/spellbook/oneuse/fireball
|
||||
spell = /obj/effect/proc_holder/spell/fireball
|
||||
spell = /datum/spell/fireball
|
||||
spellname = "fireball"
|
||||
icon_state = "bookfireball"
|
||||
desc = "This book feels warm to the touch."
|
||||
@@ -1001,7 +1001,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/spellbook/oneuse/smoke
|
||||
spell = /obj/effect/proc_holder/spell/smoke
|
||||
spell = /datum/spell/smoke
|
||||
spellname = "smoke"
|
||||
icon_state = "booksmoke"
|
||||
desc = "This book is overflowing with the dank arts."
|
||||
@@ -1012,7 +1012,7 @@
|
||||
user.adjust_nutrition(-200)
|
||||
|
||||
/obj/item/spellbook/oneuse/blind
|
||||
spell = /obj/effect/proc_holder/spell/trigger/blind
|
||||
spell = /datum/spell/genetic/blind
|
||||
spellname = "blind"
|
||||
icon_state = "bookblind"
|
||||
desc = "This book looks blurry, no matter how you look at it."
|
||||
@@ -1025,7 +1025,7 @@
|
||||
L.EyeBlind(20 SECONDS)
|
||||
|
||||
/obj/item/spellbook/oneuse/mindswap
|
||||
spell = /obj/effect/proc_holder/spell/mind_transfer
|
||||
spell = /datum/spell/mind_transfer
|
||||
spellname = "mindswap"
|
||||
icon_state = "bookmindswap"
|
||||
desc = "This book's cover is pristine, though its pages look ragged and torn."
|
||||
@@ -1049,7 +1049,7 @@
|
||||
to_chat(user, "<span class='notice'>You stare at the book some more, but there doesn't seem to be anything else to learn...</span>")
|
||||
return
|
||||
|
||||
var/obj/effect/proc_holder/spell/mind_transfer/swapper = new
|
||||
var/datum/spell/mind_transfer/swapper = new
|
||||
swapper.cast(user, stored_swap)
|
||||
|
||||
to_chat(stored_swap, "<span class='warning'>You're suddenly somewhere else... and someone else?!</span>")
|
||||
@@ -1057,7 +1057,7 @@
|
||||
stored_swap = null
|
||||
|
||||
/obj/item/spellbook/oneuse/forcewall
|
||||
spell = /obj/effect/proc_holder/spell/forcewall
|
||||
spell = /datum/spell/forcewall
|
||||
spellname = "forcewall"
|
||||
icon_state = "bookforcewall"
|
||||
desc = "This book has a dedication to mimes everywhere inside the front cover."
|
||||
@@ -1070,7 +1070,7 @@
|
||||
user.drop_item()
|
||||
|
||||
/obj/item/spellbook/oneuse/knock
|
||||
spell = /obj/effect/proc_holder/spell/aoe/knock
|
||||
spell = /datum/spell/aoe/knock
|
||||
spellname = "knock"
|
||||
icon_state = "bookknock"
|
||||
desc = "This book is hard to hold closed properly."
|
||||
@@ -1081,7 +1081,7 @@
|
||||
user.Weaken(40 SECONDS)
|
||||
|
||||
/obj/item/spellbook/oneuse/horsemask
|
||||
spell = /obj/effect/proc_holder/spell/horsemask
|
||||
spell = /datum/spell/horsemask
|
||||
spellname = "horses"
|
||||
icon_state = "bookhorses"
|
||||
desc = "This book is more horse than your mind has room for."
|
||||
@@ -1101,7 +1101,7 @@
|
||||
to_chat(user, "<span class='notice'>I say thee neigh</span>")
|
||||
|
||||
/obj/item/spellbook/oneuse/charge
|
||||
spell = /obj/effect/proc_holder/spell/charge
|
||||
spell = /datum/spell/charge
|
||||
spellname = "charging"
|
||||
icon_state = "bookcharge"
|
||||
desc = "This book is made of 100% post-consumer wizard."
|
||||
@@ -1112,7 +1112,7 @@
|
||||
empulse(src, 1, 1)
|
||||
|
||||
/obj/item/spellbook/oneuse/summonitem
|
||||
spell = /obj/effect/proc_holder/spell/summonitem
|
||||
spell = /datum/spell/summonitem
|
||||
spellname = "instant summons"
|
||||
icon_state = "booksummons"
|
||||
desc = "This book is bright and garish, very hard to miss."
|
||||
@@ -1123,13 +1123,13 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/spellbook/oneuse/fake_gib
|
||||
spell = /obj/effect/proc_holder/spell/touch/fake_disintegrate
|
||||
spell = /datum/spell/touch/fake_disintegrate
|
||||
spellname = "disintegrate"
|
||||
icon_state = "bookfireball"
|
||||
desc = "This book feels like it will rip stuff apart."
|
||||
|
||||
/obj/item/spellbook/oneuse/sacredflame
|
||||
spell = /obj/effect/proc_holder/spell/sacred_flame
|
||||
spell = /datum/spell/sacred_flame
|
||||
spellname = "sacred flame"
|
||||
icon_state = "booksacredflame"
|
||||
desc = "Become one with the flames that burn within... and invite others to do so as well."
|
||||
|
||||
@@ -122,13 +122,13 @@
|
||||
/mob/proc/spellremove()
|
||||
if(!mind)
|
||||
return
|
||||
for(var/obj/effect/proc_holder/spell/spell_to_remove in mind.spell_list)
|
||||
for(var/datum/spell/spell_to_remove in mind.spell_list)
|
||||
qdel(spell_to_remove)
|
||||
mind.spell_list -= spell_to_remove
|
||||
|
||||
//To batch-remove mob spells.
|
||||
/mob/proc/mobspellremove()
|
||||
for(var/obj/effect/proc_holder/spell/spell_to_remove in mob_spell_list)
|
||||
for(var/datum/spell/spell_to_remove in mob_spell_list)
|
||||
qdel(spell_to_remove)
|
||||
mob_spell_list -= spell_to_remove
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
Ethereal Jaunt and Blink provide escape and mobility, while Magic Missile and Disintegrate can be used together for dangerous or key targets. <br> \
|
||||
As this set lacks any form of healing or resurrection, healing items should be acquired from the station, and you should be careful to avoid being hurt in the first place. <br><br> \
|
||||
</i>Provides Mutate, Ethereal Jaunt, Blink, Magic Missile, and Disintegrate.<i>"
|
||||
spells_path = list(/obj/effect/proc_holder/spell/genetic/mutate, /obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/turf_teleport/blink, \
|
||||
/obj/effect/proc_holder/spell/projectile/magic_missile, /obj/effect/proc_holder/spell/touch/disintegrate)
|
||||
spells_path = list(/datum/spell/genetic/mutate, /datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, \
|
||||
/datum/spell/projectile/magic_missile, /datum/spell/touch/disintegrate)
|
||||
|
||||
/datum/spellbook_entry/loadout/lich
|
||||
name = "Defense Focus - Lich"
|
||||
@@ -16,8 +16,8 @@
|
||||
Ethereal Jaunt provides escape, Fireball and Rod Form are your offensive spells, and Disable Tech and Forcewall provides utility in disabling sec equipment or blocking their path. <br> \
|
||||
Care should be taken in hiding the item you choose as your phylactery after using Bind Soul, as you cannot revive if it destroyed or too far from your body! <br><br> \
|
||||
</i>Provides Bind Soul, Ethereal Jaunt, Fireball, Rod Form, Disable Tech, and Greater Forcewall.<i>"
|
||||
spells_path = list(/obj/effect/proc_holder/spell/lichdom, /obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/fireball, \
|
||||
/obj/effect/proc_holder/spell/rod_form, /obj/effect/proc_holder/spell/emplosion/disable_tech, /obj/effect/proc_holder/spell/forcewall)
|
||||
spells_path = list(/datum/spell/lichdom, /datum/spell/ethereal_jaunt, /datum/spell/fireball, \
|
||||
/datum/spell/rod_form, /datum/spell/emplosion/disable_tech, /datum/spell/forcewall)
|
||||
is_ragin_restricted = TRUE
|
||||
|
||||
/datum/spellbook_entry/loadout/wands
|
||||
@@ -27,8 +27,8 @@
|
||||
Do not lose any of your wands to the station's crew, as they are extremely deadly even in their hands. Remember that the Revive wand can be used on yourself for a full heal! <br><br> \
|
||||
</i>Provides a Belt of Wands, Charge, Ethereal Jaunt, Blink, Repulse, and Disintegrate.<i>"
|
||||
items_path = list(/obj/item/storage/belt/wands/full)
|
||||
spells_path = list(/obj/effect/proc_holder/spell/charge, /obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/turf_teleport/blink, \
|
||||
/obj/effect/proc_holder/spell/aoe/repulse, /obj/effect/proc_holder/spell/touch/disintegrate)
|
||||
spells_path = list(/datum/spell/charge, /datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, \
|
||||
/datum/spell/aoe/repulse, /datum/spell/touch/disintegrate)
|
||||
|
||||
//Unique loadouts, which are more gimmicky. Should contain some unique spell or item that separates it from just buying standard wiz spells, and be balanced around a 10 spell point cost.
|
||||
/datum/spellbook_entry/loadout/mimewiz
|
||||
@@ -37,14 +37,14 @@
|
||||
</i>Provides Finger Gun and Invisible Greater Wall manuals, Mime Robes, a Cane and Duct Tape, Ethereal Jaunt, Blink, Teleport, Mime Malaise, Knock, and Stop Time.<i>"
|
||||
items_path = list(/obj/item/spellbook/oneuse/mime/fingergun, /obj/item/spellbook/oneuse/mime/greaterwall, /obj/item/clothing/suit/wizrobe/mime, /obj/item/clothing/head/wizard/mime, \
|
||||
/obj/item/clothing/mask/gas/mime/wizard, /obj/item/clothing/shoes/sandal/marisa, /obj/item/cane, /obj/item/stack/tape_roll)
|
||||
spells_path = list(/obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/turf_teleport/blink, /obj/effect/proc_holder/spell/area_teleport/teleport, \
|
||||
/obj/effect/proc_holder/spell/touch/mime_malaise, /obj/effect/proc_holder/spell/aoe/knock, /obj/effect/proc_holder/spell/aoe/conjure/timestop)
|
||||
spells_path = list(/datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, /datum/spell/area_teleport/teleport, \
|
||||
/datum/spell/touch/mime_malaise, /datum/spell/aoe/knock, /datum/spell/aoe/conjure/timestop)
|
||||
category = "Unique"
|
||||
destroy_spellbook = TRUE
|
||||
|
||||
/datum/spellbook_entry/loadout/mimewiz/OnBuy(mob/living/carbon/human/user, obj/item/spellbook/book)
|
||||
if(user.mind)
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/mime/speak(null))
|
||||
user.mind.AddSpell(new /datum/spell/mime/speak(null))
|
||||
user.mind.miming = TRUE
|
||||
|
||||
/datum/spellbook_entry/loadout/gunreaper
|
||||
@@ -54,13 +54,13 @@
|
||||
You will likely need to scavenge additional ammo or weapons aboard the station. <br><br>\
|
||||
</i>Provides a .357 Revolver, 4 speedloaders of ammo, Ethereal Jaunt, Blink, Summon Item, No Clothes, and Bind Soul, with a unique outfit.<i>"
|
||||
items_path = list(/obj/item/gun/projectile/revolver, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/clothing/under/syndicate)
|
||||
spells_path = list(/obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/turf_teleport/blink, \
|
||||
/obj/effect/proc_holder/spell/summonitem, /obj/effect/proc_holder/spell/noclothes, /obj/effect/proc_holder/spell/lichdom/gunslinger)
|
||||
spells_path = list(/datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, \
|
||||
/datum/spell/summonitem, /datum/spell/noclothes, /datum/spell/lichdom/gunslinger)
|
||||
category = "Unique"
|
||||
destroy_spellbook = TRUE
|
||||
is_ragin_restricted = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/lichdom/gunslinger/equip_lich(mob/living/carbon/human/H)
|
||||
/datum/spell/lichdom/gunslinger/equip_lich(mob/living/carbon/human/H)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_suit(H), SLOT_HUD_OUTER_SUIT)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), SLOT_HUD_SHOES)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(H), SLOT_HUD_GLOVES)
|
||||
@@ -74,8 +74,8 @@
|
||||
</i>Provides His Grace, an Ancient Jumpsuit, an Assistant ID, a Gas Mask and Shoes, Insulated Gloves, a full Toolbelt, Ethereal Jaunt, Force Wall, Homing Toolbox, Knock and No Clothes.<i>"
|
||||
items_path = list(/obj/item/his_grace, /obj/item/clothing/under/color/grey/glorf, /obj/item/clothing/mask/gas, /obj/item/clothing/shoes/black, \
|
||||
/obj/item/clothing/gloves/color/yellow, /obj/item/storage/belt/utility/full/multitool)
|
||||
spells_path = list(/obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/forcewall, \
|
||||
/obj/effect/proc_holder/spell/aoe/knock, /obj/effect/proc_holder/spell/noclothes, /obj/effect/proc_holder/spell/fireball/toolbox)
|
||||
spells_path = list(/datum/spell/ethereal_jaunt, /datum/spell/forcewall, \
|
||||
/datum/spell/aoe/knock, /datum/spell/noclothes, /datum/spell/fireball/toolbox)
|
||||
category = "Unique"
|
||||
destroy_spellbook = TRUE
|
||||
|
||||
@@ -111,8 +111,8 @@
|
||||
items_path = list(/obj/item/supermatter_halberd, /obj/item/clothing/gloves/color/white/supermatter_immune, \
|
||||
/obj/item/clothing/suit/hooded/oblivion, /obj/item/clothing/mask/gas/voice_modulator/oblivion, /obj/item/tank/internals/emergency_oxygen/double, \
|
||||
/obj/item/clothing/under/color/white/enforcer, /obj/item/clothing/shoes/white/enforcer)
|
||||
spells_path = list(/obj/effect/proc_holder/spell/summonitem, /obj/effect/proc_holder/spell/charge_up/bounce/lightning, \
|
||||
/obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter)
|
||||
spells_path = list(/datum/spell/summonitem, /datum/spell/charge_up/bounce/lightning, \
|
||||
/datum/spell/aoe/conjure/summon_supermatter)
|
||||
category = "Unique"
|
||||
destroy_spellbook = TRUE
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
name = "Fireball. Fireball. Fireball."
|
||||
desc = "Who cares about the rest of the spells. Become an expert in fire magic. Devote yourself to the craft. The only spell you need anyways is <b>Fireball.</b><br>\
|
||||
</i>Provides fire immunity, homing fireballs, rapid-fire fireballs, and some fireball wands. Provides no mobility spells. Replaces your robes with infernal versions.<i>"
|
||||
spells_path = list(/obj/effect/proc_holder/spell/sacred_flame, /obj/effect/proc_holder/spell/fireball/homing, /obj/effect/proc_holder/spell/infinite_guns/fireball)
|
||||
spells_path = list(/datum/spell/sacred_flame, /datum/spell/fireball/homing, /datum/spell/infinite_guns/fireball)
|
||||
category = "Unique"
|
||||
destroy_spellbook = TRUE
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user