diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 8faa569f556..2a89db64269 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1434,6 +1434,17 @@ var/global/floorIsLava = 0 if(istype(H)) H.regenerate_icons() +/datum/admins/proc/ashInvokedEmotions() + set category = "Admin" + set name = "Ash Invoked Emotions" + set desc = "Ashes all paper from the 'invoke emotions' wizard spell. Emergency porn purge." + if(alert("Are you sure you want to ash all invoked emotions?", "Invoked Emotions Panic", "Yes", "No") != "No") + var/numEmot = 0 + for(var/obj/item/weapon/paper/emotion_invoker/EI in invoked_emotions) + EI.destroyEmotion() + numEmot++ + message_admins("[numEmot] invoked emotions ashed.") + // // //ALL DONE diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index d32395d3fea..dc633923d3e 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -89,7 +89,8 @@ var/list/admin_verbs_admin = list( /client/proc/persistence_panel, /*lets you check out the kind of shit that will persist to the next round and say "holy fuck no"*/ /client/proc/diseases_panel, /client/proc/artifacts_panel, - /client/proc/climate_panel + /client/proc/climate_panel, + /datum/admins/proc/ashInvokedEmotions /*Ashes all paper from the invoke emotion spell. An emergency purge.*/ ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, diff --git a/code/modules/spells/targeted/invoke_emotion.dm b/code/modules/spells/targeted/invoke_emotion.dm new file mode 100644 index 00000000000..52e1b4d125d --- /dev/null +++ b/code/modules/spells/targeted/invoke_emotion.dm @@ -0,0 +1,174 @@ +var/global/list/invoked_emotions = list() + +/spell/targeted/invoke_emotion + name = "Invoke Emotion" + desc = "Summon a cursed document that forces itself to, eventually, be read by your target. Once your message is complete, simply throw the document and it will find its way." + abbreviation = "IE" + user_type = USER_TYPE_WIZARD + specialization = SSUTILITY + hud_state = "invoke_emotion" + invocation = "YU'V GO'T MA'LE" + invocation_type = SpI_WHISPER + spell_flags = WAIT_FOR_CLICK | SELECTABLE | INCLUDEUSER + price = 0.25 * Sp_BASE_PRICE + range = 9 + charge_max = 150 + cooldown_min = 10 + compatible_mobs = list(/mob/living/carbon) + spell_levels = list(Sp_SPEED = 0, Sp_POWER = 0, Sp_MOVE = 0) + level_max = list(Sp_TOTAL = 7, Sp_SPEED = 1, Sp_POWER = 5, Sp_MOVE = 1) + + var/obj/item/weapon/paper/emotion_invoker/thePaper = null + var/obj/item/weapon/pen/invoked_quill/theQuill = null + +/spell/targeted/invoke_emotion/cast(var/list/targets, mob/user) + ..() + for(var/mob/living/carbon/target in targets) + var/obj/item/weapon/paper/emotion_invoker/thePaper = new /obj/item/weapon/paper/emotion_invoker(user.loc) + thePaper.curseTarget = target + thePaper.cursePower = spell_levels[Sp_POWER] + thePaper.forcesHand = spell_levels[Sp_MOVE] + user.put_in_hands(thePaper) + if(!theQuill) + theQuill = new /obj/item/weapon/pen/invoked_quill(user.loc) + theQuill.quillSpell = src + user.put_in_hands(theQuill) + else if(theQuill.loc != user) + theQuill.forceMove(user.loc) + user.put_in_hands(theQuill) + + +/spell/targeted/invoke_emotion/apply_upgrade(upgrade_type) + switch(upgrade_type) + if(Sp_SPEED) + return quicken_spell() + if(Sp_POWER) + spell_levels[Sp_POWER]++ + return "Your invoked emotions now cut slightly deeper." + if(Sp_MOVE) + spell_levels[Sp_MOVE]++ + return "Your invoked emotions are now harder to ignore." + +/spell/targeted/invoke_emotion/get_upgrade_price(upgrade_type) + switch(upgrade_type) + if(Sp_SPEED) + return 20 + if(Sp_POWER) + return 1 + if(Sp_MOVE) + return 5 + +/spell/targeted/invoke_emotion/get_upgrade_info(upgrade_type) + switch(upgrade_type) + if(Sp_SPEED) + return "Nearly removes the cooldown of the spell." + if(Sp_POWER) + return "Invoked paper is more likely to cut, or otherwise curse, the target." + if(Sp_MOVE) + return "Invoked emotions have a chance to place themselves in their target's hand." + +/obj/item/weapon/pen/invoked_quill + name = "invoked quill" + desc = "A magical quill that requires no inkwell. So it's a pen." + var/spell/targeted/invoke_emotion/quillSpell = null //Just for preventing hard deletes + +/obj/item/weapon/pen/invoked_quill/Destroy() + quillSpell.theQuill = null + quillSpell = null + ..() + +/obj/item/weapon/paper/emotion_invoker + name = "emotion invoker" + desc = "A cursed sheet of paper designed to transfer or create powerful emotions. Seeks out its target after being thrown." + fire_fuel = 0 //Covering my bases on potential infinite fire bugs + throw_range = 6 + var/mob/living/curseTarget = null + var/isActive = FALSE + var/emotionInvoked = FALSE + var/forcesHand = 0 + var/cursePower = 0 + +/obj/item/weapon/paper/emotion_invoker/New() + ..() + invoked_emotions += src + +/obj/item/weapon/paper/emotion_invoker/canfold(mob/user) + return FALSE + +/obj/item/weapon/paper/emotion_invoker/acidable() + return FALSE + +/obj/item/weapon/paper/emotion_invoker/ashify_item(mob/user) + if(isActive) + return FALSE //Not that easy + ..() + +/obj/item/weapon/paper/emotion_invoker/pickup(mob/living/carbon/user) + if(isActive && curseTarget) + if(user != curseTarget) + var/datum/organ/external/affecting = user.get_active_hand_organ() + if(affecting.take_damage(1 * cursePower)) + user.UpdateDamageIcon() + to_chat(user, "Ouch, paper cut!") + user.drop_item(src) + +/obj/item/weapon/paper/emotion_invoker/Destroy() + processing_objects.Remove(src) + invoked_emotions -= src + ..() + +/obj/item/weapon/paper/emotion_invoker/process() + if(curseTarget) + if(curseTarget.gcDestroyed) + isActive = FALSE + ashify() + if(loc != curseTarget) + if(emotionInvoked) + destroyEmotion() + else + goToTarget() + +/obj/item/weapon/paper/emotion_invoker/proc/destroyEmotion() + new /obj/effect/decal/cleanable/ash(get_turf(src)) + qdel(src) + +/obj/item/weapon/paper/emotion_invoker/throw_impact(atom/hit_atom) + ..() + if(isActive) + if(hit_atom == curseTarget) + inflictCurse() + else + activateInvoker() + +/obj/item/weapon/paper/emotion_invoker/on_enter_storage(obj/item/weapon/storage/S) + if(isActive) + spawn(5) + do_teleport(src, curseTarget, 2) + +/obj/item/weapon/paper/emotion_invoker/proc/activateInvoker() + isActive = TRUE + processing_objects.Add(src) + +/obj/item/weapon/paper/emotion_invoker/proc/goToTarget() + if(curseTarget in viewers(src)) + throw_at(curseTarget, 10, 2) + else + do_teleport(src, curseTarget, 2) + +/obj/item/weapon/paper/emotion_invoker/proc/inflictCurse() + if(prob(10 * cursePower)) + curseTarget.adjustBruteLoss(1) + to_chat(curseTarget, "You receive a paper cut!") + if(prob(cursePower)) + curseTarget.Knockdown(1) + if(forcesHand && prob(20)) + curseTarget.put_in_hands(src) + +/obj/item/weapon/paper/emotion_invoker/show_text(var/mob/user, var/links = FALSE, var/starred = FALSE) + ..() + if(isActive && curseTarget) + if(user == curseTarget && !starred) + emotionInvoked = TRUE + else if(info) + message_admins("[key_name(user)] has written on an invoke emotion paper [formatJumpTo(get_turf(src))]!") + log_admin("[key_name(user)] wrote on an invoked emotion: [info]") diff --git a/vgstation13.dme b/vgstation13.dme index c8b2964413c..2d08606062d 100644 --- a/vgstation13.dme +++ b/vgstation13.dme @@ -2602,6 +2602,7 @@ #include "code\modules\spells\targeted\heal.dm" #include "code\modules\spells\targeted\hypnotise.dm" #include "code\modules\spells\targeted\ice_barrage.dm" +#include "code\modules\spells\targeted\invoke_emotion.dm" #include "code\modules\spells\targeted\mind_transfer.dm" #include "code\modules\spells\targeted\pacify.dm" #include "code\modules\spells\targeted\parrotmorph.dm"