diff --git a/code/datums/spells/charge.dm b/code/datums/spells/charge.dm new file mode 100644 index 00000000000..0ace8c7d9cd --- /dev/null +++ b/code/datums/spells/charge.dm @@ -0,0 +1,74 @@ +/obj/effect/proc_holder/spell/targeted/charge + name = "Charge" + desc = "This spell can be used to charge up spent magical artifacts, among other things." + + school = "transmutation" + charge_max = 600 + clothes_req = 0 + invocation = "DIRI CEL" + invocation_type = "whisper" + range = -1 + cooldown_min = 400 //50 deciseconds reduction per rank + include_user = 1 + + +/obj/effect/proc_holder/spell/targeted/charge/cast(list/targets) + for(var/mob/living/user in targets) + var/list/hand_items = list(user.get_active_hand(),user.get_inactive_hand()) + var/charged_item = null + var/burnt_out = 0 + world << "[user.l_hand] and [user.r_hand]" + for(var/obj/item in hand_items) + if(istype(item, /obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = item + if(G.affecting) + var/mob/M = G.affecting + if(M.spell_list.len != 0) + for(var/obj/effect/proc_holder/spell/S in M.spell_list) + S.charge_counter = S.charge_max + M <<"\blue you feel raw magic flowing through you, it feels good!" + else + M <<"\blue you feel very strange for a moment, but then it passes." + burnt_out = 1 + charged_item = M + break + else if(istype(item, /obj/item/weapon/gun/magic)) + var/obj/item/weapon/gun/magic/I = item + if(prob(80)) + I.max_charges-- + if(I.max_charges <= 0) + I.max_charges = 0 + burnt_out = 1 + I.charges = I.max_charges + charged_item = I + break + else if(istype(item, /obj/item/weapon/cell/)) + var/obj/item/weapon/cell/C = item + if(prob(80)) + C.maxcharge -= 200 + if(C.maxcharge <= 1) //Div by 0 protection + C.maxcharge = 1 + burnt_out = 1 + C.charge = C.maxcharge + charged_item = C + break + else if(item.contents) + var/obj/I = null + for(I in item.contents) + if(istype(I, /obj/item/weapon/cell/)) + var/obj/item/weapon/cell/C = I + if(prob(80)) + C.maxcharge -= 200 + if(C.maxcharge <= 1) //Div by 0 protection + C.maxcharge = 1 + burnt_out = 1 + C.charge = C.maxcharge + item.update_icon() + charged_item = item + break + if(!charged_item) + user << "\blue you feel magical power surging to your hands, but the feeling rapidly fades..." + else if(burnt_out) + user << "\red [charged_item] doesn't seem to be reacting to the spell..." + else + user << "\blue [charged_item] suddenly feels very warm!" diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 5bad56a6135..3d404dfc846 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -27,6 +27,8 @@ dat += "Your apprentice is skilled in offensive magic. They know Magic Missile and Fireball.
" dat += "Bluespace Manipulation
" dat += "Your apprentice is able to defy physics, melting through solid objects and travelling great distances in the blink of an eye. They know Teleport and Ethereal Jaunt.
" + dat += "Healing
" + dat += "Your apprentice is training to cast spells that will aid your survival. They know Forcewall and Charge and come with a Staff of Healing.
" dat += "Robeless
" dat += "Your apprentice is training to cast spells without their robes. They know Knock and Mindswap.
" user << browse(dat, "window=radio") @@ -66,6 +68,11 @@ M.spell_list += new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(M) M.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(M) M << "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt." + if("healing") + M.spell_list += new /obj/effect/proc_holder/spell/targeted/charge(M) + M.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall(M) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/magic/staff/healing(M), slot_r_hand) + M << "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall." if("robeless") M.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/knock(M) M.spell_list += new /obj/effect/proc_holder/spell/targeted/mind_transfer(M) diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index c18732cdb01..4b0d7633e82 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -1,8 +1,8 @@ -/mob/proc/rightandwrong() - usr << "You summoned guns!" - message_admins("[key_name_admin(usr, 1)] summoned guns!") +/mob/proc/rightandwrong(var/summon_type) //0 = Summon Guns, 1 = Summon Magic + usr << "You summoned [summon_type ? "magic" : "guns"]!" + message_admins("[key_name_admin(usr, 1)] summoned [summon_type ? "magic" : "guns"]!") for(var/mob/living/carbon/human/H in player_list) if(H.stat == 2 || !(H.client)) continue if(is_special_character(H)) continue @@ -18,46 +18,95 @@ for(var/datum/objective/OBJ in H.mind.objectives) H << "Objective #[obj_count]: [OBJ.explanation_text]" obj_count++ - var/randomize = pick("taser","egun","laser","revolver","detective","smg","nuclear","deagle","gyrojet","pulse","silenced","cannon","doublebarrel","shotgun","combatshotgun","mateba","smg","uzi","crossbow","saw") - switch (randomize) - if("taser") - new /obj/item/weapon/gun/energy/taser(get_turf(H)) - if("egun") - new /obj/item/weapon/gun/energy/gun(get_turf(H)) - if("laser") - new /obj/item/weapon/gun/energy/laser(get_turf(H)) - if("revolver") - new /obj/item/weapon/gun/projectile/revolver(get_turf(H)) - if("detective") - new /obj/item/weapon/gun/projectile/revolver/detective(get_turf(H)) - if("smg") - new /obj/item/weapon/gun/projectile/automatic/c20r(get_turf(H)) - if("nuclear") - new /obj/item/weapon/gun/energy/gun/nuclear(get_turf(H)) - if("deagle") - new /obj/item/weapon/gun/projectile/automatic/deagle/camo(get_turf(H)) - if("gyrojet") - new /obj/item/weapon/gun/projectile/automatic/gyropistol(get_turf(H)) - if("pulse") - new /obj/item/weapon/gun/energy/pulse_rifle(get_turf(H)) - if("silenced") - new /obj/item/weapon/gun/projectile/automatic/pistol(get_turf(H)) - new /obj/item/weapon/silencer(get_turf(H)) - if("cannon") - new /obj/item/weapon/gun/energy/lasercannon(get_turf(H)) - if("doublebarrel") - new /obj/item/weapon/gun/projectile/revolver/doublebarrel(get_turf(H)) - if("shotgun") - new /obj/item/weapon/gun/projectile/shotgun/(get_turf(H)) - if("combatshotgun") - new /obj/item/weapon/gun/projectile/shotgun/combat(get_turf(H)) - if("mateba") - new /obj/item/weapon/gun/projectile/revolver/mateba(get_turf(H)) - if("smg") - new /obj/item/weapon/gun/projectile/automatic(get_turf(H)) - if("uzi") - new /obj/item/weapon/gun/projectile/automatic/mini_uzi(get_turf(H)) - if("crossbow") - new /obj/item/weapon/gun/energy/crossbow(get_turf(H)) - if("saw") - new /obj/item/weapon/gun/projectile/automatic/l6_saw(get_turf(H)) \ No newline at end of file + var/randomizeguns = pick("taser","egun","laser","revolver","detective","smg","nuclear","deagle","gyrojet","pulse","silenced","cannon","doublebarrel","shotgun","combatshotgun","mateba","smg","uzi","crossbow","saw") + var/randomizemagic = pick("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge","wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffchange", "staffanimation", "staffhealing", "armor", "scrying") + if(!summon_type) + switch (randomizeguns) + if("taser") + new /obj/item/weapon/gun/energy/taser(get_turf(H)) + if("egun") + new /obj/item/weapon/gun/energy/gun(get_turf(H)) + if("laser") + new /obj/item/weapon/gun/energy/laser(get_turf(H)) + if("revolver") + new /obj/item/weapon/gun/projectile/revolver(get_turf(H)) + if("detective") + new /obj/item/weapon/gun/projectile/revolver/detective(get_turf(H)) + if("smg") + new /obj/item/weapon/gun/projectile/automatic/c20r(get_turf(H)) + if("nuclear") + new /obj/item/weapon/gun/energy/gun/nuclear(get_turf(H)) + if("deagle") + new /obj/item/weapon/gun/projectile/automatic/deagle/camo(get_turf(H)) + if("gyrojet") + new /obj/item/weapon/gun/projectile/automatic/gyropistol(get_turf(H)) + if("pulse") + new /obj/item/weapon/gun/energy/pulse_rifle(get_turf(H)) + if("silenced") + new /obj/item/weapon/gun/projectile/automatic/pistol(get_turf(H)) + new /obj/item/weapon/silencer(get_turf(H)) + if("cannon") + new /obj/item/weapon/gun/energy/lasercannon(get_turf(H)) + if("doublebarrel") + new /obj/item/weapon/gun/projectile/revolver/doublebarrel(get_turf(H)) + if("shotgun") + new /obj/item/weapon/gun/projectile/shotgun/(get_turf(H)) + if("combatshotgun") + new /obj/item/weapon/gun/projectile/shotgun/combat(get_turf(H)) + if("mateba") + new /obj/item/weapon/gun/projectile/revolver/mateba(get_turf(H)) + if("smg") + new /obj/item/weapon/gun/projectile/automatic(get_turf(H)) + if("uzi") + new /obj/item/weapon/gun/projectile/automatic/mini_uzi(get_turf(H)) + if("crossbow") + new /obj/item/weapon/gun/energy/crossbow(get_turf(H)) + if("saw") + new /obj/item/weapon/gun/projectile/automatic/l6_saw(get_turf(H)) + else + switch (randomizemagic) + if("fireball") + new /obj/item/weapon/spellbook/oneuse/fireball(get_turf(H)) + if("smoke") + new /obj/item/weapon/spellbook/oneuse/smoke(get_turf(H)) + if("blind") + new /obj/item/weapon/spellbook/oneuse/blind(get_turf(H)) + if("mindswap") + new /obj/item/weapon/spellbook/oneuse/mindswap(get_turf(H)) + if("forcewall") + new /obj/item/weapon/spellbook/oneuse/forcewall(get_turf(H)) + if("knock") + new /obj/item/weapon/spellbook/oneuse/knock(get_turf(H)) + if("horsemask") + new /obj/item/weapon/spellbook/oneuse/horsemask(get_turf(H)) + if("charge") + new /obj/item/weapon/spellbook/oneuse/charge(get_turf(H)) + if("wandnothing") + new /obj/item/weapon/gun/magic/wand(get_turf(H)) + if("wanddeath") + new /obj/item/weapon/gun/magic/wand/death(get_turf(H)) + if("wandresurrection") + new /obj/item/weapon/gun/magic/wand/resurrection(get_turf(H)) + if("wandpolymorph") + new /obj/item/weapon/gun/magic/wand/polymorph(get_turf(H)) + if("wandteleport") + new /obj/item/weapon/gun/magic/wand/teleport(get_turf(H)) + if("wanddoor") + new /obj/item/weapon/gun/magic/wand/door(get_turf(H)) + if("staffchange") + new /obj/item/weapon/gun/magic/staff/change(get_turf(H)) + if("staffanimation") + new /obj/item/weapon/gun/magic/staff/animate(get_turf(H)) + if("staffhealing") + new /obj/item/weapon/gun/magic/staff/healing(get_turf(H)) + if("armor") + new /obj/item/clothing/suit/space/rig/wizard(get_turf(H)) + new /obj/item/clothing/head/helmet/space/rig/wizard(get_turf(H)) + if("scrying") + new /obj/item/weapon/scrying(get_turf(H)) + if (!(XRAY in H.mutations)) + H.mutations.Add(XRAY) + H.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) + H.see_in_dark = 8 + H.see_invisible = SEE_INVISIBLE_LEVEL_TWO + H << "\blue The walls suddenly disappear." diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 156554d486d..055e887981f 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -86,6 +86,9 @@ dat += "Summon Guns (One time use, global spell)
" dat += "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill eachother. Just be careful not to get hit in the crossfire!
" + dat += "Summon Magic (One time use, global spell)
" + dat += "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time.
" + dat += "
" dat += "Artefacts:
" dat += "Powerful items imbued with eldritch magics. Summoning one will count towards your maximum number of spells.
" @@ -150,7 +153,7 @@ uses-- /* */ - var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", fleshtostone = "Flesh to Stone", summonguns = "Summon Guns", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation") + var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", fleshtostone = "Flesh to Stone", summonguns = "Summon Guns", summonmagic = "Summon Magic", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation") var/already_knows = 0 for(var/obj/effect/proc_holder/spell/aspell in H.spell_list) if(available_spells[href_list["spell_choice"]] == initial(aspell.name)) @@ -246,12 +249,17 @@ temp = "You have learned flesh to stone." if("summonguns") feedback_add_details("wizard_spell_learned","SG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.rightandwrong() + H.rightandwrong(0) max_uses-- temp = "You have cast summon guns." + if("summonmagic") + feedback_add_details("wizard_spell_learned","SM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.rightandwrong(1) + max_uses-- + temp = "You have cast summon magic." if("staffchange") feedback_add_details("wizard_spell_learned","ST") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - new /obj/item/weapon/gun/energy/staff(get_turf(H)) + new /obj/item/weapon/gun/magic/staff/change(get_turf(H)) temp = "You have purchased a staff of change." max_uses-- if("soulstone") @@ -270,7 +278,7 @@ max_uses-- if("staffanimation") feedback_add_details("wizard_spell_learned","SA") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - new /obj/item/weapon/gun/energy/staff/animate(get_turf(H)) + new /obj/item/weapon/gun/magic/staff/animate(get_turf(H)) temp = "You have purchased a staff of animation." max_uses-- if("contract") @@ -295,3 +303,82 @@ attack_self(H) return + +//Single Use Spellbooks// + +/obj/item/weapon/spellbook/oneuse + var/spell = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile //just a placeholder to avoid runtimes if someone spawned the generic + var/spellname = "sandbox" + name = "spellbook of " + uses = 1 + max_uses = 1 + desc = "This template spellbook was never meant for the eyes of man..." + +/obj/item/weapon/spellbook/oneuse/New() + ..() + name += spellname + +/obj/item/weapon/spellbook/oneuse/attack_self(mob/user as mob) + var/obj/effect/proc_holder/spell/S = new spell + for(var/obj/effect/proc_holder/spell/knownspell in user.spell_list) + if(knownspell.type == S.type) + if(user.mind) + if(user.mind.special_role == "apprentice" || user.mind.special_role == "wizard") + user <<"\blue You're already far more versed in this spell than this flimsy how-to book can provide." + else + user <<"\blue You've already read this one." + return + user.spell_list += S + user <<"\blue you rapidly read through the arcane book. Suddenly it vanishes and you realize you understand [spellname]!" + del (src) + +/obj/item/weapon/spellbook/oneuse/attackby() + return + +/obj/item/weapon/spellbook/oneuse/fireball + spell = /obj/effect/proc_holder/spell/dumbfire/fireball + spellname = "fireball" + icon_state ="book2" + desc = "This book feels warm to the touch." + +/obj/item/weapon/spellbook/oneuse/smoke + spell = /obj/effect/proc_holder/spell/targeted/smoke + spellname = "smoke" + icon_state ="book5" + desc = "This book is overflowing with the dank arts." + +/obj/item/weapon/spellbook/oneuse/blind + spell = /obj/effect/proc_holder/spell/targeted/trigger/blind + spellname = "blind" + icon_state ="book1" + desc = "This book looks blurry, no matter how you look at it." + +/obj/item/weapon/spellbook/oneuse/mindswap + spell = /obj/effect/proc_holder/spell/targeted/mind_transfer + spellname = "mindswap" + icon_state ="book6" + desc = "This book's cover is pristine, though its pages look ragged and torn." + +/obj/item/weapon/spellbook/oneuse/forcewall + spell = /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall + spellname = "forcewall" + icon_state ="book4" + desc = "This book has a dedication to mimes everywhere inside the front cover." + +/obj/item/weapon/spellbook/oneuse/knock + spell = /obj/effect/proc_holder/spell/aoe_turf/knock + spellname = "knock" + icon_state ="book7" + desc = "This book is hard to hold closed properly." + +/obj/item/weapon/spellbook/oneuse/horsemask + spell = /obj/effect/proc_holder/spell/targeted/horsemask + spellname = "horses" + icon_state ="book3" + desc = "This book is more horse than your mind has room for." + +/obj/item/weapon/spellbook/oneuse/charge + spell = /obj/effect/proc_holder/spell/targeted/charge + spellname = "charging" + icon_state ="bookInfections" + desc = "This book is made of 100% post-consumer wizard." \ No newline at end of file diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 4968f427ea2..11668d874c5 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -25,8 +25,6 @@ if (istype(G, /obj/item/weapon/gun/energy/gun/nuclear) || istype(G, /obj/item/weapon/gun/energy/crossbow)) user << "Your gun's recharge port was removed to make room for a miniaturized reactor." return - if (istype(G, /obj/item/weapon/gun/energy/staff)) - return user.drop_item() G.loc = src charging = G diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 39da02b0e1d..2316f12f45a 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -219,7 +219,7 @@ if(3) A = new /obj/item/projectile/beam/pulse( loc ) if(4) - A = new /obj/item/projectile/change( loc ) + A = new /obj/item/projectile/magic/change( loc ) if(5) A = new /obj/item/projectile/bluetag( loc ) if(6) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 6b0d70beece..c1ed4531c26 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -26,55 +26,6 @@ charge_cost = 100 projectile_type = "/obj/item/projectile/energy/declone" -obj/item/weapon/gun/energy/staff - name = "staff of change" - desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" - icon = 'icons/obj/gun.dmi' - icon_state = "staffofchange" - item_state = "staffofchange" - fire_sound = 'sound/weapons/emitter.ogg' - flags = FPRINT | TABLEPASS | CONDUCT - slot_flags = SLOT_BACK - w_class = 5 - charge_cost = 200 - projectile_type = "/obj/item/projectile/change" - origin_tech = null - clumsy_check = 0 - var/charge_tick = 0 - - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(200) - return 1 - - update_icon() - return - - shoot_with_empty_chamber(mob/living/user as mob|obj) - user << "The [name] whizzles quietly." - return - -/obj/item/weapon/gun/energy/staff/animate - name = "staff of animation" - desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." - projectile_type = "/obj/item/projectile/animate" - icon_state = "staffofanimation" - item_state = "staffofanimation" - /obj/item/weapon/gun/energy/floragun name = "floral somatoray" desc = "A tool that discharges controlled radiation which induces mutation in plant cells." diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm new file mode 100644 index 00000000000..c719bd4f663 --- /dev/null +++ b/code/modules/projectiles/guns/magic.dm @@ -0,0 +1,56 @@ +/obj/item/weapon/gun/magic + name = "staff of nothing" + desc = "This staff is boring to watch because even though it came first you've seen everything it can do in other staves for years." + icon = 'icons/obj/gun.dmi' + icon_state = "staffofchange" + item_state = "staffofchange" + fire_sound = 'sound/weapons/emitter.ogg' + flags = FPRINT | TABLEPASS | CONDUCT + w_class = 5 + var/projectile_type = "/obj/item/projectile/magic" + var/max_charges = 6 + var/charges = 0 + var/recharge_rate = 4 + var/charge_tick = 0 + var/can_charge = 1 + origin_tech = null + clumsy_check = 0 + +/obj/item/weapon/gun/magic/emp_act(severity) + return + +/obj/item/weapon/gun/magic/process_chambered() + if(in_chamber) return 1 + if(!charges) return 0 + if(!projectile_type) return 0 + in_chamber = new projectile_type(src) + return 1 + +/obj/item/weapon/gun/magic/afterattack() + ..() + if(charges ) charges-- + +/obj/item/weapon/gun/magic/New() + ..() + charges = max_charges + if(can_charge) processing_objects.Add(src) + + +/obj/item/weapon/gun/magic/Del() + if(can_charge) processing_objects.Remove(src) + ..() + + +/obj/item/weapon/gun/magic/process() + charge_tick++ + if(charge_tick < recharge_rate || charges >= max_charges) return 0 + charge_tick = 0 + charges++ + return 1 + +/obj/item/weapon/gun/magic/update_icon() + return + +/obj/item/weapon/gun/magic/shoot_with_empty_chamber(mob/living/user as mob|obj) + user << "The [name] whizzles quietly." + return \ No newline at end of file diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm new file mode 100644 index 00000000000..cff5d6e603d --- /dev/null +++ b/code/modules/projectiles/guns/magic/staff.dm @@ -0,0 +1,23 @@ +obj/item/weapon/gun/magic/staff/change + name = "staff of change" + desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" + projectile_type = "/obj/item/projectile/magic/change" + icon_state = "staffofchange" + item_state = "staffofchange" + slot_flags = SLOT_BACK + +obj/item/weapon/gun/magic/staff/animate + name = "staff of animation" + desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." + projectile_type = "/obj/item/projectile/magic/animate" + icon_state = "staffofanimation" + item_state = "staffofanimation" + slot_flags = SLOT_BACK + +obj/item/weapon/gun/magic/staff/healing + name = "staff of healing" + desc = "An artefact that spits bolts of restoring magic which can remove ailments of all kinds and even raise the dead." + projectile_type = "/obj/item/projectile/magic/resurrection" + icon_state = "staffofanimation" + item_state = "staffofanimation" + slot_flags = SLOT_BACK \ No newline at end of file diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm new file mode 100644 index 00000000000..479e1fda0c7 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -0,0 +1,227 @@ +/obj/item/weapon/gun/magic/wand/ + name = "wand of nothing" + desc = "It's not just a stick, it's a MAGIC stick!" + projectile_type = "/obj/item/projectile/magic" + icon_state = "staffofanimation" + item_state = "staffofanimation" + w_class = 2 + can_charge = 0 + max_charges = 100 //100, 50, 50, 34 (max charge distribution by 25%ths) + w_class = 2 + +/obj/item/weapon/gun/magic/wand/New() + if(prob(75)) //25% chance of listed max charges, 50% chance of 1/2 max charges, 25% chance of 1/3 max charges + if(prob(33)) + max_charges = Ceiling(max_charges / 3) + else + max_charges = Ceiling(max_charges / 2) + ..() + +/obj/item/weapon/gun/magic/wand/examine() + ..() + usr << "Has [charges] charge\s remaining." + return + +/obj/item/weapon/gun/magic/wand/attack_self(mob/living/user as mob) + if(charges) + zap_self(user) + else + user << "The [name] whizzles quietly." + ..() + +/obj/item/weapon/gun/magic/wand/proc/zap_self(mob/living/user as mob) + user.visible_message("\blue [user] zaps \himself with [src]!") + +/obj/item/weapon/gun/magic/wand/death + name = "wand of death" + desc = "This deadly wand overwhelms the victim's body with pure energy, slaying them without fail." + projectile_type = "/obj/item/projectile/magic/death" + icon_state = "staffofanimation" + item_state = "staffofanimation" + max_charges = 3 //3, 2, 2, 1 + +/obj/item/weapon/gun/magic/wand/death/zap_self(mob/living/user as mob) + if(alert(user, "You really want to zap yourself with the wand of death?",, "Yes", "No") == "Yes" && charges && user.get_active_hand() == src && isliving(user)) + var/message ="\red You irradiate yourself with pure energy! " + message += pick("Do not pass go. Do not collect 200 zorkmids.","You feel more confident in your spell casting skills.","You Die...","Do you want your possessions identified?") + user << message + user.adjustOxyLoss(500) + charges-- + ..() + +/obj/item/weapon/gun/magic/wand/resurrection + name = "wand of resurrection" + desc = "This wand uses healing magics to heal and revive. They are rarely utilized within the Wizard Federation for some reason." + projectile_type = "/obj/item/projectile/magic/resurrection" + icon_state = "staffofanimation" + item_state = "staffofanimation" + max_charges = 3 //3, 2, 2, 1 + +/obj/item/weapon/gun/magic/wand/resurrection/zap_self(mob/living/user as mob) + user.setToxLoss(0) + user.setOxyLoss(0) + user.setCloneLoss(0) + user.SetParalysis(0) + user.SetStunned(0) + user.SetWeakened(0) + user.radiation = 0 + user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss()) + user.reagents.clear_reagents() + user << "You feel great!" + charges-- + ..() + +/obj/item/weapon/gun/magic/wand/polymorph + name = "wand of polymorph" + desc = "This wand inflicts is attuned to chaos and will radically alter the victim's form." + projectile_type = "/obj/item/projectile/magic/change" + icon_state = "staffofanimation" + item_state = "staffofanimation" + max_charges = 10 //10, 5, 5, 4 + +/obj/item/weapon/gun/magic/wand/polymorph/zap_self(mob/living/user as mob) + if(alert(user, "Your new form might not have arms to zap with... Continue?",, "Yes", "No") == "Yes" && charges && user.get_active_hand() == src && isliving(user)) + if(user.monkeyizing) return + user.monkeyizing = 1 + user.canmove = 0 + user.icon = null + user.overlays.Cut() + user.invisibility = 101 + for(var/obj/item/W in user) + if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something + del(W) + continue + W.layer = initial(W.layer) + W.loc = user.loc + W.dropped(user) + + var/mob/living/new_mob + + var/randomize = pick("monkey","robot","slime","xeno","human","animal") + switch(randomize) + if("monkey") + new_mob = new /mob/living/carbon/monkey(user.loc) + new_mob.universal_speak = 1 + if("robot") + new_mob = new /mob/living/silicon/robot(user.loc) + new_mob.gender = user.gender + new_mob.invisibility = 0 + new_mob.job = "Cyborg" + var/mob/living/silicon/robot/Robot = new_mob + Robot.mmi = new /obj/item/device/mmi(new_mob) + Robot.mmi.transfer_identity(user) //Does not transfer key/client. + if("slime") + if(prob(50)) new_mob = new /mob/living/carbon/slime/adult(user.loc) + else new_mob = new /mob/living/carbon/slime(user.loc) + new_mob.universal_speak = 1 + if("xeno") + if(prob(50)) + new_mob = new /mob/living/carbon/alien/humanoid/hunter(user.loc) + else + new_mob = new /mob/living/carbon/alien/humanoid/sentinel(user.loc) + new_mob.universal_speak = 1 + if("animal") + var/animal = pick("parrot","corgi","crab","pug","cat","carp","bear","mushroom","tomato","mouse","chicken","cow","lizard","chick") + switch(animal) + if("parrot") new_mob = new /mob/living/simple_animal/parrot(user.loc) + if("corgi") new_mob = new /mob/living/simple_animal/corgi(user.loc) + if("crab") new_mob = new /mob/living/simple_animal/crab(user.loc) + if("pug") new_mob = new /mob/living/simple_animal/pug(user.loc) + if("cat") new_mob = new /mob/living/simple_animal/cat(user.loc) + if("carp") new_mob = new /mob/living/simple_animal/hostile/carp(user.loc) + if("bear") new_mob = new /mob/living/simple_animal/hostile/bear(user.loc) + if("mushroom") new_mob = new /mob/living/simple_animal/mushroom(user.loc) + if("tomato") new_mob = new /mob/living/simple_animal/tomato(user.loc) + if("mouse") new_mob = new /mob/living/simple_animal/mouse(user.loc) + if("chicken") new_mob = new /mob/living/simple_animal/chicken(user.loc) + if("cow") new_mob = new /mob/living/simple_animal/cow(user.loc) + if("lizard") new_mob = new /mob/living/simple_animal/lizard(user.loc) + else new_mob = new /mob/living/simple_animal/chick(user.loc) + new_mob.universal_speak = 1 + if("human") + new_mob = new /mob/living/carbon/human(user.loc) + + var/datum/preferences/A = new() //Randomize appearance for the human + A.copy_to(new_mob) + + var/mob/living/carbon/human/H = new_mob + ready_dna(H) + if(H.dna) + H.dna.mutantrace = pick("lizard","golem","slime","plant","fly","shadow","adamantine","skeleton",8;"") + H.update_body() + else + return + + for (var/obj/effect/proc_holder/spell/S in user.spell_list) + new_mob.spell_list += new S.type + + new_mob.a_intent = "harm" + if(user.mind) + user.mind.transfer_to(new_mob) + else + new_mob.key = user.key + + new_mob << "Your form morphs into that of a [randomize]." + + del(user) + return new_mob + charges-- + ..() + +/obj/item/weapon/gun/magic/wand/teleport + name = "wand of teleportation" + desc = "This wand will wrench targets through space and time to move them somewhere else." + projectile_type = "/obj/item/projectile/magic/teleport" + icon_state = "staffofanimation" + item_state = "staffofanimation" + max_charges = 10 //10, 5, 5, 4 + +/obj/item/weapon/gun/magic/wand/teleport/zap_self(mob/living/user as mob) + var/list/turfs = new/list() + var/inner_tele_radius = 0 + var/outer_tele_radius = 6 + for(var/turf/T in range(user,outer_tele_radius)) + if(T in range(user,inner_tele_radius)) continue + if(T.x>world.maxx-outer_tele_radius || T.xworld.maxy-outer_tele_radius || T.yYou feel great!" + else + target << "You rise with a start, you're alive!!!" + +/obj/item/projectile/magic/teleport + name = "bolt of teleportation" + icon_state = "bluespace" + damage = 0 + damage_type = OXY + nodamage = 1 + flag = "magic" + var/inner_tele_radius = 0 + var/outer_tele_radius = 6 + +/obj/item/projectile/magic/teleport/on_hit(var/mob/target) + if(isturf(target)) + return + + var/list/turfs = new/list() + for(var/turf/T in range(target,outer_tele_radius)) + if(T in range(target,inner_tele_radius)) continue + if(T.x>world.maxx-outer_tele_radius || T.xworld.maxy-outer_tele_radius || T.yYour form morphs into that of a [randomize].
" + + del(M) + return new_mob + +/obj/item/projectile/magic/animate + name = "bolt of animation" + icon_state = "red_1" + damage = 0 + damage_type = BURN + nodamage = 1 + flag = "magic" + +/obj/item/projectile/magic/animate/Bump(var/atom/change) + . = ..() + if(istype(change, /obj/item) || istype(change, /obj/structure) && !is_type_in_list(change, protected_objects)) + var/obj/O = change + new /mob/living/simple_animal/hostile/mimic/copy(O.loc, O, firer) + else if(istype(change, /mob/living/simple_animal/hostile/mimic/copy)) + // Change our allegiance! + var/mob/living/simple_animal/hostile/mimic/copy/C = change + C.ChangeOwner(firer) \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 5bd8184b7dd..cbbb0dab917 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6,48 +6,6 @@ // BEGIN_FILE_DIR #define FILE_DIR . -#define FILE_DIR "html" -#define FILE_DIR "icons" -#define FILE_DIR "icons/ass" -#define FILE_DIR "icons/effects" -#define FILE_DIR "icons/mecha" -#define FILE_DIR "icons/misc" -#define FILE_DIR "icons/mob" -#define FILE_DIR "icons/obj" -#define FILE_DIR "icons/obj/assemblies" -#define FILE_DIR "icons/obj/atmospherics" -#define FILE_DIR "icons/obj/clothing" -#define FILE_DIR "icons/obj/doors" -#define FILE_DIR "icons/obj/flora" -#define FILE_DIR "icons/obj/machines" -#define FILE_DIR "icons/obj/pipes" -#define FILE_DIR "icons/obj/power_cond" -#define FILE_DIR "icons/pda_icons" -#define FILE_DIR "icons/spideros_icons" -#define FILE_DIR "icons/stamp_icons" -#define FILE_DIR "icons/Testing" -#define FILE_DIR "icons/turf" -#define FILE_DIR "icons/vending_icons" -#define FILE_DIR "nano" -#define FILE_DIR "nano/images" -#define FILE_DIR "sound" -#define FILE_DIR "sound/AI" -#define FILE_DIR "sound/ambience" -#define FILE_DIR "sound/effects" -#define FILE_DIR "sound/hallucinations" -#define FILE_DIR "sound/items" -#define FILE_DIR "sound/machines" -#define FILE_DIR "sound/mecha" -#define FILE_DIR "sound/misc" -#define FILE_DIR "sound/piano" -#define FILE_DIR "sound/violin" -#define FILE_DIR "sound/voice" -#define FILE_DIR "sound/voice/complionator" -#define FILE_DIR "sound/vox_fem" -#define FILE_DIR "sound/weapons" -#define FILE_DIR "tools" -#define FILE_DIR "tools/AddToChangelog" -#define FILE_DIR "tools/AddToChangelog/AddToChangelog" // END_FILE_DIR // BEGIN_PREFERENCES @@ -216,6 +174,7 @@ #include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\topic_input.dm" #include "code\datums\spells\area_teleport.dm" +#include "code\datums\spells\charge.dm" #include "code\datums\spells\conjure.dm" #include "code\datums\spells\construct_spells.dm" #include "code\datums\spells\dumbfire.dm" @@ -1122,6 +1081,7 @@ #include "code\modules\projectiles\ammunition\bullets.dm" #include "code\modules\projectiles\ammunition\magazines.dm" #include "code\modules\projectiles\guns\energy.dm" +#include "code\modules\projectiles\guns\magic.dm" #include "code\modules\projectiles\guns\projectile.dm" #include "code\modules\projectiles\guns\energy\laser.dm" #include "code\modules\projectiles\guns\energy\nuclear.dm" @@ -1129,15 +1089,16 @@ #include "code\modules\projectiles\guns\energy\special.dm" #include "code\modules\projectiles\guns\energy\stun.dm" #include "code\modules\projectiles\guns\energy\temperature.dm" +#include "code\modules\projectiles\guns\magic\staff.dm" +#include "code\modules\projectiles\guns\magic\wand.dm" #include "code\modules\projectiles\guns\projectile\automatic.dm" #include "code\modules\projectiles\guns\projectile\pistol.dm" #include "code\modules\projectiles\guns\projectile\revolver.dm" #include "code\modules\projectiles\guns\projectile\shotgun.dm" -#include "code\modules\projectiles\projectile\animate.dm" #include "code\modules\projectiles\projectile\beams.dm" #include "code\modules\projectiles\projectile\bullets.dm" -#include "code\modules\projectiles\projectile\change.dm" #include "code\modules\projectiles\projectile\energy.dm" +#include "code\modules\projectiles\projectile\magic.dm" #include "code\modules\projectiles\projectile\special.dm" #include "code\modules\reagents\Chemistry-Colours.dm" #include "code\modules\reagents\Chemistry-Holder.dm"