diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 272b3157b88..cad5657fc37 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -38,7 +38,7 @@ return next_click = world.time + 1 - if(client.buildmode) + if(client && client.buildmode) build_click(src, client.buildmode, params, A) return @@ -411,7 +411,7 @@ /* if(buckled && buckled.movable) buckled.dir = direction buckled.handle_rotation()*/ - + /obj/screen/click_catcher icon = 'icons/mob/screen1_full.dmi' icon_state = "passage0" diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index c287c00975d..acea0966db9 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -147,6 +147,16 @@ var/list/uplink_items = list() cost = 2 job = list("Chef") +//Chaplain + +/datum/uplink_item/jobspecific/voodoo + name = "Voodoo Doll" + desc = "A doll created by Syndicate Witch Doctors. Ingredients: Something of the Thread, Something of the Head, Something of the Body, Something of the Dead, Secret Voodoo herbs, and Monosodium glutamate." + reference = "VD" + item = /obj/item/voodoo + cost = 13 + job = list("Chaplain") + //Janitor /datum/uplink_item/jobspecific/cautionsign diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm index 3753c888912..6f6cdd18a2f 100644 --- a/code/game/asteroid.dm +++ b/code/game/asteroid.dm @@ -80,7 +80,7 @@ var/global/max_secret_rooms = 6 walltypes = list(/turf/simulated/wall/mineral/plasma=3,/turf/simulated/mineral/random/high_chance=1) floortypes = list(/turf/simulated/floor/wood) treasureitems = list(/obj/item/weapon/veilrender/vealrender=2, /obj/item/weapon/spellbook/oneuse/blind=1,/obj/item/clothing/head/wizard/red=2, - /obj/item/weapon/spellbook/oneuse/forcewall=1, /obj/item/weapon/spellbook/oneuse/smoke=1, /obj/structure/constructshell = 1, /obj/item/toy/katana=3) + /obj/item/weapon/spellbook/oneuse/forcewall=1, /obj/item/weapon/spellbook/oneuse/smoke=1, /obj/structure/constructshell = 1, /obj/item/toy/katana=3,/obj/item/voodoo=3) fluffitems = list(/obj/structure/safe/floor=1,/obj/structure/dresser=1,/obj/item/weapon/storage/belt/soulstone=1,/obj/item/trash/candle=3, /obj/item/weapon/dice=3,/obj/item/weapon/twohanded/staff=2,/obj/effect/decal/cleanable/dirt=3,/obj/item/weapon/coin/mythril=3) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 3008d2db0c7..63de49edb1b 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -597,3 +597,239 @@ var/global/list/multiverse = list() probability_evil = 100 duplicate_self = 1 sword_type = /obj/item/weapon/multisword/pike + + +/////////////////////////////////////////Necromantic Stone/////////////////// + +/obj/item/device/necromantic_stone + name = "necromantic stone" + desc = "A shard capable of resurrecting humans as skeleton thralls." + icon = 'icons/obj/wizard.dmi' + icon_state = "necrostone" + item_state = "electronic" + origin_tech = "bluespace=4;materials=4" + w_class = 1 + var/list/spooky_scaries = list() + var/unlimited = 0 + var/heresy = 0 + +/obj/item/device/necromantic_stone/unlimited + unlimited = 1 + +/obj/item/device/necromantic_stone/attack(mob/living/carbon/human/M as mob, mob/living/carbon/human/user as mob) + + if(!istype(M)) + return ..() + + if(!istype(user)) + return + + if(M.stat != DEAD) + user << "This artifact can only affect the dead!" + return + + if(!M.mind || !M.client) + user << "There is no soul connected to this body..." + return + + check_spooky()//clean out/refresh the list + + if(spooky_scaries.len >= 3 && !unlimited) + user << "This artifact can only affect three undead at a time!" + return + M.makeSkeleton() + M.visible_message(" A massive amount of flesh sloughs off [M] and a skeleton rises up!") + M.revive() + spooky_scaries |= M + M << "You have been revived by [user.real_name]!" + M << "They are your master now, assist them even if it costs you your new life!" + equip_skeleton(M) + desc = "A shard capable of resurrecting humans as skeleton thralls[unlimited ? "." : ", [spooky_scaries.len]/3 active thralls."]" + +/obj/item/device/necromantic_stone/proc/check_spooky() + if(unlimited) //no point, the list isn't used. + return + for(var/X in spooky_scaries) + if(!istype(X, /mob/living/carbon/human)) + spooky_scaries.Remove(X) + continue + var/mob/living/carbon/human/H = X + if(H.stat == DEAD) + spooky_scaries.Remove(X) + continue + listclearnulls(spooky_scaries) + +//Funny gimmick, skeletons always seem to wear roman/ancient armour +//Voodoo Zombie Pirates added for paradise +/obj/item/device/necromantic_stone/proc/equip_skeleton(mob/living/carbon/human/H as mob) + for(var/obj/item/I in H) + H.unEquip(I) + var/randomSpooky = "roman"//defualt + if(heresy) + randomSpooky = "yand" + else + randomSpooky = pick("roman","pirate","yand","clown") + + switch(randomSpooky) + if("roman") + var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionaire) + H.equip_to_slot_or_del(new hat(H), slot_head) + H.equip_to_slot_or_del(new /obj/item/clothing/under/roman(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(H), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/weapon/shield/riot/roman(H), slot_l_hand) + H.equip_to_slot_or_del(new /obj/item/weapon/claymore(H), slot_r_hand) + H.equip_to_slot_or_del(new /obj/item/weapon/twohanded/spear(H), slot_back) + if("pirate") + H.equip_to_slot_or_del(new /obj/item/clothing/under/pirate(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/pirate_brown(H), slot_wear_suit) + H.equip_to_slot_or_del(new /obj/item/clothing/head/bandana(H), slot_head) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(H), slot_glasses) + H.equip_to_slot_or_del(new /obj/item/weapon/claymore(H), slot_r_hand) + H.equip_to_slot_or_del(new /obj/item/weapon/twohanded/spear(H), slot_back) + H.equip_to_slot_or_del(new /obj/item/weapon/shield/riot/roman(H), slot_l_hand) + if("yand")//mine is an evil laugh + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/clothing/head/kitty(H), slot_head) + H.equip_to_slot_or_del(new /obj/item/clothing/under/schoolgirl(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(H), slot_wear_suit) + H.equip_to_slot_or_del(new /obj/item/weapon/katana(H), slot_r_hand) + H.equip_to_slot_or_del(new /obj/item/weapon/shield/riot/roman(H), slot_l_hand) + H.equip_to_slot_or_del(new /obj/item/weapon/twohanded/spear(H), slot_back) + if("clown") + H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/clown(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes(H), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), slot_wear_mask) + H.equip_to_slot_or_del(new /obj/item/clothing/head/stalhelm(H), slot_head) + H.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(H), slot_l_store) + H.equip_to_slot_or_del(new /obj/item/weapon/claymore(H), slot_r_hand) + H.equip_to_slot_or_del(new /obj/item/weapon/shield/riot/roman(H), slot_l_hand) + H.equip_to_slot_or_del(new /obj/item/weapon/twohanded/spear(H), slot_back) + + +/obj/item/device/necromantic_stone/nya + name = "nya-cromantic stone" + desc = "A shard capable of resurrecting humans as creatures of Vile Heresy. Even the Wizard Federation fears it.." + icon = 'icons/obj/wizard.dmi' + icon_state = "nyacrostone" + item_state = "electronic" + origin_tech = "bluespace=4;materials=4" + w_class = 1 + heresy = 1 + unlimited = 1 + +/////////////////////////////////////////Voodoo/////////////////// + + +/obj/item/voodoo + name = "wicker doll" + desc = "Something creepy about it." + icon = 'icons/obj/wizard.dmi' + icon_state = "voodoo" + item_state = "electronic" + var/mob/living/carbon/human/target = null + var/list/mob/living/carbon/human/possible = list() + var/obj/item/link = null + var/cooldown_time = 30 //3s + var/cooldown = 0 + + + +/obj/item/voodoo/attackby(obj/item/I as obj, mob/user as mob, params) + if(target && cooldown < world.time) + if(is_hot(I)) + target << "You suddenly feel very hot" + target.bodytemperature += 50 + GiveHint(target) + else if(can_puncture(I)) + target << "You feel a stabbing pain in [parse_zone(user.zone_sel.selecting)]!" + target.Weaken(2) + GiveHint(target) + else if(istype(I,/obj/item/weapon/bikehorn)) + target << "HONK" + target << 'sound/items/AirHorn.ogg' + target.ear_damage += rand(0,3) + GiveHint(target) + cooldown = world.time +cooldown_time + return + if(!link) + if(I.loc == user && istype(I) && I.w_class <= 2) + user.drop_item() + I.loc = src + link = I + user << "You attach [I] to the doll." + update_targets() + ..() +/obj/item/voodoo/check_eye(mob/user as mob) + return src.loc == user + +/obj/item/voodoo/attack_self(mob/user as mob) + if(!target && possible.len) + target = input(user, "Select your victim!", "Voodoo") as null|anything in possible + return + if(user.zone_sel.selecting == "chest") + if(link) + target = null + link.loc = get_turf(src) + user << "You remove the [link] from the doll." + link = null + update_targets() + return + if(target && cooldown < world.time) + switch(user.zone_sel.selecting) + if("mouth") + var/wgw = sanitize(input(user, "What would you like the victim to say", "Voodoo", null) as text) + target.say(wgw) + log_game("[user][user.key] made [target][target.key] say [wgw] with a voodoo doll.") + if("eyes") + user.set_machine(src) + if(user.client) + user.client.eye = target + user.client.perspective = EYE_PERSPECTIVE + spawn(100) + user.reset_view() + user.unset_machine() + if("r_leg","l_leg") + user << "You move the doll's legs around." + var/turf/T = get_step(target,pick(cardinal)) + target.Move(T) + if("r_arm","l_arm") + //use active hand on random nearby mob + var/list/nearby_mobs = list() + for(var/mob/living/L in range(1,target)) + if(L!=target) + nearby_mobs |= L + if(nearby_mobs.len) + var/mob/living/T = pick(nearby_mobs) + log_game("[user][user.key] made [target][target.key] click on [T] with a voodoo doll.") + target.ClickOn(T) + GiveHint(target) + if("head") + user << "You smack the doll's head with your hand." + target.Dizzy(10) + target << "You suddenly feel as if your head was hit with a hammer!" + GiveHint(target,user) + cooldown = world.time + cooldown_time + +/obj/item/voodoo/proc/update_targets() + possible = list() + if(!link) + return + for(var/mob/living/carbon/human/H in living_mob_list) + if(md5(H.dna.uni_identity) in link.fingerprints) + possible |= H + +/obj/item/voodoo/proc/GiveHint(mob/victim,force=0) + if(prob(50) || force) + var/way = dir2text(get_dir(victim,get_turf(src))) + victim << "You feel a dark presence from [way]" + if(prob(20) || force) + var/area/A = get_area(src) + victim << "You feel a dark presence from [A.name]" + +/obj/item/voodoo/fire_act() + if(target) + target.adjust_fire_stacks(20) + target.IgniteMob() + GiveHint(target,1) + return ..() \ No newline at end of file diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index e98517688d8..a417c839a7e 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -2,8 +2,8 @@ /mob/proc/rightandwrong(var/summon_type) //0 = Summon Guns, 1 = Summon Magic var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","silenced","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","arg") - var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffhealing", "armor", "scrying", "staffdoor", "special") - var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos") + var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffhealing", "armor", "scrying", "staffdoor", "special","voodoo") + var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos","necromantic") usr << "You summoned [summon_type ? "magic" : "guns"]!" message_admins("[key_name_admin(usr)] summoned [summon_type ? "magic" : "guns"]!") for(var/mob/living/carbon/human/H in player_list) @@ -110,6 +110,9 @@ H.see_invisible = SEE_INVISIBLE_LEVEL_TWO H << "The walls suddenly disappear." + if("voodoo") + new /obj/item/voodoo(get_turf(H)) + if("special") magiclist -= "special" //only one super OP item per summoning max switch (randomizemagicspecial) @@ -123,4 +126,6 @@ new /obj/item/weapon/contract(get_turf(H)) if("staffchaos") new /obj/item/weapon/gun/magic/staff/chaos(get_turf(H)) + if("necromantic") + new /obj/item/device/necromantic_stone(get_turf(H)) H << "You suddenly feel lucky." diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index acf20832ba8..54426761a02 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -281,6 +281,12 @@ user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(null)) return . +/datum/spellbook_entry/item/necrostone + name = "A Necromantic Stone" + desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command." + item_path = /obj/item/device/necromantic_stone + log_name = "NS" + /datum/spellbook_entry/item/wands name = "Wand Assortment" desc = "A collection of wands that allow for a wide variety of utility. Wands do not recharge, so be conservative in use. Comes in a handy belt." diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi index 273eeab0921..c35817db609 100644 Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ