diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 5de92892b30..5275cd7ca91 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -45,7 +45,8 @@ var/global/list/blocked_mobs = list(/mob/living/simple_animal/hostile, /mob/living/simple_animal/hostile/mining_drone, /mob/living/simple_animal/hostile/spaceWorm, /mob/living/simple_animal/hostile/spaceWorm/wormHead, - /mob/living/simple_animal/ascendant_shadowling + /mob/living/simple_animal/ascendant_shadowling, + /mob/living/simple_animal/slaughter ) var/global/list/med_hud_users = list() diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 5eb2ad4ecd6..d3b96551e16 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -9,7 +9,7 @@ /obj/item/weapon/antag_spawner/proc/equip_antag(mob/target as mob) return - + /obj/item/weapon/antag_spawner/borg_tele name = "Syndicate Cyborg Teleporter" @@ -49,16 +49,16 @@ checking = 0 spawn_antag(possibleborg, get_turf(src.loc), "syndieborg") else - possiblecandidates -= possibleborg + possiblecandidates -= possibleborg get_candidate_answer(user, possiblecandidates) return - + sleep(300) if(checking) - possiblecandidates -= possibleborg + possiblecandidates -= possibleborg get_candidate_answer(user, possiblecandidates) - return - + return + /obj/item/weapon/antag_spawner/borg_tele/spawn_antag(var/client/C, var/turf/T, var/type = "") var/datum/effect/effect/system/spark_spread/S = new /datum/effect/effect/system/spark_spread @@ -70,3 +70,51 @@ ticker.mode.update_synd_icons_added(R.mind) R.mind.special_role = "syndicate" R.faction = list("syndicate") + +/obj/item/weapon/antag_spawner/slaughter_demon //Warning edgiest item in the game + name = "vial of blood" + desc = "A magically infused bottle of blood, distilled from countless murder victims. Used in unholy rituals to attract horrifying creatures." + icon = 'icons/obj/wizard.dmi' + icon_state = "vial" + + + +/obj/item/weapon/antag_spawner/slaughter_demon/attack_self(mob/user as mob) + var/list/demon_candidates = get_candidates(BE_ALIEN) + if(user.z == ZLEVEL_CENTCOMM)//this is to make sure the wizard does NOT summon a demon from the Den.. + user << "You should probably wait until you reach the station." + return + if(demon_candidates.len > 0) + used = 1 + var/client/C = pick(demon_candidates) + spawn_antag(C, get_turf(src.loc), "Slaughter Demon") + user << "You shatter the bottle, no turning back now!" + user << "You sense a dark presence lurking just beyond the veil..." + playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1) + qdel(src) + else + user << "You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later." + + +/obj/item/weapon/antag_spawner/slaughter_demon/spawn_antag(var/client/C, var/turf/T, var/type = "", mob/user as mob) + + var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T) + var/mob/living/simple_animal/slaughter/S = new /mob/living/simple_animal/slaughter/(holder) + S.vialspawned = TRUE + S.holder = holder + S.key = C.key + S.mind.assigned_role = "Slaughter Demon" + S.mind.special_role = "Slaughter Demon" + ticker.mode.traitors += S.mind + var/datum/objective/assassinate/KillDaWiz = new /datum/objective/assassinate + KillDaWiz.owner = S.mind + KillDaWiz.target = user.mind + KillDaWiz.explanation_text = "Kill [user.real_name], the one who was foolish enough to summon you." + S.mind.objectives += KillDaWiz + var/datum/objective/KillDaCrew = new /datum/objective + KillDaCrew.owner = S.mind + KillDaCrew.explanation_text = "Kill everyone else while you're at it." + S.mind.objectives += KillDaCrew + S.mind.objectives += KillDaCrew + S << "Objective #[1]: [KillDaWiz.explanation_text]" + S << "Objective #[2]: [KillDaCrew.explanation_text]" \ No newline at end of file diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 786d3f1f08e..7e16791cf74 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -118,70 +118,82 @@ force = 15 throwforce = 10 w_class = 3 - var/charged = 1 hitsound = 'sound/weapons/bladeslice.ogg' + var/charged = 1 + var/spawn_type = /obj/singularity/narsie/wizard + var/spawn_amt = 1 + var/activate_descriptor = "reality" + var/rend_desc = "You should run now." + +/obj/item/weapon/veilrender/attack_self(mob/user as mob) + if(charged) + new /obj/effect/rend(get_turf(user), spawn_type, spawn_amt, rend_desc) + charged = 0 + user.visible_message("[src] hums with power as [user] deals a blow to [activate_descriptor] itself!") + else + user << "The unearthly energies that powered the blade are now dormant." + /obj/effect/rend name = "tear in the fabric of reality" - desc = "You should run now" + desc = "You should run now." icon = 'icons/obj/biomass.dmi' icon_state = "rift" density = 1 unacidable = 1 anchored = 1.0 + var/spawn_path = /mob/living/simple_animal/cow //defaulty cows to prevent unintentional narsies + var/spawn_amt_left = 20 -/obj/effect/rend/New() - spawn(50) - new /obj/singularity/narsie/wizard(get_turf(src)) +/obj/effect/rend/New(loc, var/spawn_type, var/spawn_amt, var/desc) + ..() + src.spawn_path = spawn_type + src.spawn_amt_left = spawn_amt + src.desc = desc + + processing_objects.Add(src) + //return + +/obj/effect/rend/process() + for(var/mob/M in loc) + return + new spawn_path(loc) + spawn_amt_left-- + if(spawn_amt_left <= 0) + qdel(src) + +/obj/effect/rend/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/weapon/nullrod)) + user.visible_message("[user] seals \the [src] with \the [I].") qdel(src) return - return - -/obj/item/weapon/veilrender/attack_self(mob/user as mob) - if(charged == 1) - new /obj/effect/rend(get_turf(usr)) - charged = 0 - visible_message("\red [src] hums with power as [usr] deals a blow to reality itself!") - else - user << "\red The unearthly energies that powered the blade are now dormant." - - + ..() /obj/item/weapon/veilrender/vealrender name = "veal render" desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast farm." + spawn_type = /mob/living/simple_animal/cow + spawn_amt = 20 + activate_descriptor = "hunger" + rend_desc = "Reverberates with the sound of ten thousand moos." -/obj/item/weapon/veilrender/vealrender/attack_self(mob/user as mob) - if(charged) - new /obj/effect/rend/cow(get_turf(usr)) - charged = 0 - visible_message("\red [src] hums with power as [usr] deals a blow to hunger itself!") - else - user << "\red The unearthly energies that powered the blade are now dormant." +/obj/item/weapon/veilrender/honkrender + name = "honk render" + desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast circus." + spawn_type = /mob/living/simple_animal/hostile/retaliate/clown + spawn_amt = 10 + activate_descriptor = "depression" + rend_desc = "Gently wafting with the sounds of endless laughter." + icon_state = "clownrender" -/obj/effect/rend/cow - desc = "Reverberates with the sound of ten thousand moos." - var/cowsleft = 20 - -/obj/effect/rend/cow/New() - processing_objects.Add(src) - return - -/obj/effect/rend/cow/process() - if(locate(/mob) in loc) return - new /mob/living/simple_animal/cow(loc) - cowsleft-- - if(cowsleft <= 0) - qdel(src) - -/obj/effect/rend/cow/attackby(obj/item/I as obj, mob/user as mob, params) - if(istype(I, /obj/item/weapon/nullrod)) - visible_message("\red [I] strikes a blow against \the [src], banishing it!") - spawn(1) - qdel(src) - return - ..() +/obj/item/weapon/veilrender/crabrender + name = "crab render" + desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast aquarium." + spawn_type = /mob/living/simple_animal/crab + spawn_amt = 10 + activate_descriptor = "sea life" + rend_desc = "Gently wafting with the sounds of endless clacking." /////////////////////////////////////////Scrying/////////////////// @@ -198,6 +210,6 @@ hitsound = 'sound/items/welder2.ogg' /obj/item/weapon/scrying/attack_self(mob/user as mob) - user << "\blue You can see...everything!" - visible_message("\red [usr] stares into [src], their eyes glazing over.") + user << " You can see...everything!" + visible_message("[user] stares into [src], their eyes glazing over.") user.ghostize(1) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 969a8998cdb..07ea73d65df 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -10,11 +10,12 @@ var/surplus = -1 // -1 for infinite, not used by anything atm 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/buy_word = "Learn" + var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook /datum/spellbook_entry/proc/IsAvailible() // For config prefs / gamemode restrictions - these are round applied return 1 /datum/spellbook_entry/proc/CanBuy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book) // Specific circumstances - if(book.usesThe contract has been used, you can't get your points back now!" else user << "You feed the contract back into the spellbook, refunding your points." - src.uses++ + + uses++ + qdel(O) + if(istype(O, /obj/item/weapon/antag_spawner/slaughter_demon)) + user << "On second thought, maybe summoning a demon is a bad idea. You refund your points." + + uses++ + for(var/datum/spellbook_entry/item/bloodbottle/BB in entries) + if(!isnull(BB.limit)) + BB.limit++ + qdel(O) + /obj/item/weapon/spellbook/proc/GetCategoryHeader(var/category) var/dat = "" switch(category) @@ -492,12 +512,16 @@ E = entries[text2num(href_list["buy"])] if(E && E.CanBuy(H,src)) if(E.Buy(H,src)) + if(E.limit) + E.limit-- uses -= E.cost else if(href_list["refund"]) E = entries[text2num(href_list["refund"])] if(E && E.refundable) var/result = E.Refund(H,src) if(result > 0) + if(!isnull(E.limit)) + E.limit += result uses += result else if(href_list["page"]) tab = sanitize(href_list["page"]) diff --git a/code/modules/events/slaughterevent.dm b/code/modules/events/slaughterevent.dm new file mode 100644 index 00000000000..7b39f035010 --- /dev/null +++ b/code/modules/events/slaughterevent.dm @@ -0,0 +1,64 @@ + +/datum/event/spawn_slaughter + var/key_of_slaughter + + + +/datum/event/spawn_slaughter/proc/get_slaughter(var/end_if_fail = 0) + key_of_slaughter = null + if(!key_of_slaughter) + var/list/candidates = get_candidates(BE_ALIEN) + if(!candidates.len) + if(end_if_fail) + return 0 + return find_slaughter() + var/client/C = pick(candidates) + key_of_slaughter = C.key + if(!key_of_slaughter) + if(end_if_fail) + return 0 + return find_slaughter() + var/datum/mind/player_mind = new /datum/mind(key_of_slaughter) + player_mind.active = 1 + var/list/spawn_locs = list() + for(var/obj/effect/landmark/L in landmarks_list) + if(isturf(L.loc)) + switch(L.name) + if("revenantspawn") + spawn_locs += L.loc + if(!spawn_locs) //If we can't find any revenant spawns, try the carp spawns + for(var/obj/effect/landmark/L in landmarks_list) + if(isturf(L.loc)) + switch(L.name) + if("carpspawn") + spawn_locs += L.loc + if(!spawn_locs) //If we can't find either, just spawn the revenant at the player's location + spawn_locs += get_turf(player_mind.current) + if(!spawn_locs) //If we can't find THAT, then just retry + return find_slaughter() + var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(pick(spawn_locs)) + var/mob/living/simple_animal/slaughter/S = new /mob/living/simple_animal/slaughter/(holder) + S.holder = holder + player_mind.transfer_to(S) + player_mind.assigned_role = "Slaughter Demon" + player_mind.special_role = "Slaughter Demon" + message_admins("[key_of_slaughter] has been made into a Slaughter Demon by an event.") + log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.") + return 1 + + + +/datum/event/spawn_slaughter/start() + get_slaughter() + + + +/datum/event/spawn_slaughter/proc/find_slaughter() + message_admins("Attempted to spawn a Slaughter Demon but there was no players available. Will try again momentarily.") + spawn(50) + if(get_slaughter(1)) + message_admins("Situation has been resolved, [key_of_slaughter] has been spawned as a Slaughter Demon.") + log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.") + return 0 + message_admins("Unfortunately, no candidates were available for becoming a Slaugter Demon. Shutting down.") + kill() \ No newline at end of file diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm new file mode 100644 index 00000000000..76c71cfeb87 --- /dev/null +++ b/code/modules/mob/living/bloodcrawl.dm @@ -0,0 +1,152 @@ +//Travel through pools of blood. Slaughter Demon powers for everyone! +#define BLOODCRAWL 1 +#define BLOODCRAWL_EAT 2 + +/mob/living/proc/phaseout(var/obj/effect/decal/cleanable/B) + var/mob/living/kidnapped = null + var/turf/mobloc = get_turf(src.loc) + var/turf/bloodloc = get_turf(B.loc) + if(Adjacent(bloodloc)) + src.notransform = TRUE + spawn(0) + src.visible_message("[src] sinks into [B].") + playsound(get_turf(src), 'sound/misc/enter_blood.ogg', 100, 1, -1) + var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter( mobloc ) + var/atom/movable/overlay/animation = new /atom/movable/overlay( mobloc ) + animation.name = "odd blood" + animation.density = 0 + animation.anchored = 1 + animation.icon = 'icons/mob/mob.dmi' + animation.icon_state = "jaunt" + animation.layer = 5 + animation.master = holder + animation.dir = src.dir + + src.ExtinguishMob() + if(src.buckled) + src.buckled.unbuckle() + if(src.pulling && src.bloodcrawl == BLOODCRAWL_EAT) + if(istype(src.pulling, /mob/living/)) + var/mob/living/victim = src.pulling + if(victim.stat == CONSCIOUS) + src.visible_message("[victim] kicks free of \the [src] at the last second!") + else + victim.loc = holder///holder + src.visible_message("\The [src] drags [victim] into [B]!") + kidnapped = victim + flick("jaunt",animation) + src.loc = holder + src.holder = holder + + if(kidnapped) + src << "You begin to feast on [kidnapped]. You can not move while you are doing this." + src.visible_message("Loud eating sounds come from the blood...") + sleep(6) + if (animation) + qdel(animation) + playsound(get_turf(src),'sound/misc/Demon_consume.ogg', 100, 1) + sleep(30) + playsound(get_turf(src),'sound/misc/Demon_consume.ogg', 100, 1) + sleep(30) + playsound(get_turf(src),'sound/misc/Demon_consume.ogg', 100, 1) + sleep(30) + src << "You devour [kidnapped]. Your health is fully restored." + src.adjustBruteLoss(-1000) + src.adjustFireLoss(-1000) + src.adjustOxyLoss(-1000) + src.adjustToxLoss(-1000) + kidnapped.ghostize() + qdel(kidnapped) + if (istype(src, /mob/living/simple_animal/slaughter)) //rason, do not want humans to get this + + var/mob/living/simple_animal/slaughter/demon = src + demon.devoured++ + else + sleep(6) + if (animation) + qdel(animation) + src.notransform = 0 + +/mob/living/proc/phasein(var/obj/effect/decal/cleanable/B) + if(src.notransform) + src << "Finish eating first!" + else + var/atom/movable/overlay/animation = new /atom/movable/overlay( B.loc ) + animation.name = "odd blood" + animation.density = 0 + animation.anchored = 1 + animation.icon = 'icons/mob/mob.dmi' + animation.icon_state = "jauntup" //Paradise Port:I reversed the jaunt animation so it looks like its rising up + animation.layer = 5 + animation.master = B.loc + animation.dir = src.dir + flick("jauntup",animation) + src.loc = B.loc + src.client.eye = src + if (prob(25)) + 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(get_turf(src), pick(voice),50, 1, -1) + src.visible_message("\The [src] rises out of \the [B]!") + playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1) + qdel(src.holder) + src.holder = null + sleep(6) + if(animation) + qdel(animation) + +/obj/effect/decal/cleanable/blood/CtrlClick(mob/living/user) + ..() + if(user.bloodcrawl) + if(user.holder) + user.phasein(src) + else + user.phaseout(src) + + + +/obj/effect/decal/cleanable/trail_holder/CtrlClick(mob/living/user) + ..() + if(user.bloodcrawl) + if(user.holder) + user.phasein(src) + else + user.phaseout(src) + + + +/turf/CtrlClick(var/mob/living/user) + ..() + if(user.bloodcrawl) + for(var/obj/effect/decal/cleanable/B in src.contents) + if(istype(B, /obj/effect/decal/cleanable/blood) || istype(B, /obj/effect/decal/cleanable/trail_holder)) + if(user.holder) + user.phasein(B) + break + else + user.phaseout(B) + break + +/obj/effect/dummy/slaughter //Can't use the wizard one, blocked by jaunt/slow + name = "odd blood" + icon = 'icons/effects/effects.dmi' + icon_state = "nothing" + var/canmove = 1 + density = 0 + anchored = 1 + +/obj/effect/dummy/slaughter/relaymove(var/mob/user, direction) + if (!src.canmove || !direction) return + var/turf/newLoc = get_step(src,direction) + loc = newLoc + src.canmove = 0 + spawn(1) + src.canmove = 1 + +/obj/effect/dummy/slaughter/ex_act(severity) + return 1 + +/obj/effect/dummy/slaughter/bullet_act(blah) + return + +/obj/effect/dummy/slaughter/singularity_act(blah) + return \ No newline at end of file diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index b25ec423316..4c35f62aecf 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -46,6 +46,9 @@ var/floating = 0 var/nightvision = 0 + var/bloodcrawl = 0 //0 No blood crawling, 1 blood crawling, 2 blood crawling+mob devour + var/holder = null //The holder for blood crawling + var/ventcrawler = 0 //0 No vent crawling, 1 vent crawling in the nude, 2 vent crawling always var/list/icon/pipes_shown = list() var/last_played_vent diff --git a/code/modules/mob/living/simple_animal/slaughter/slaughter.dm b/code/modules/mob/living/simple_animal/slaughter/slaughter.dm new file mode 100644 index 00000000000..a03b9b5173b --- /dev/null +++ b/code/modules/mob/living/simple_animal/slaughter/slaughter.dm @@ -0,0 +1,187 @@ +//////////////////The Monster + +/mob/living/simple_animal/slaughter + name = "Slaughter Demon" + real_name = "Slaughter Demon" + desc = "You should run." + speak_emote = list("gurgles") + emote_hear = list("wails","screeches") + response_help = "thinks better of touching" + response_disarm = "flails at" + response_harm = "punches" + icon = 'icons/mob/mob.dmi' + icon_state = "daemon" + icon_living = "daemon" + speed = 1 + a_intent = "harm" + stop_automated_movement = 1 + status_flags = CANPUSH + attack_sound = 'sound/misc/demon_attack1.ogg' + min_oxy = 0 + max_oxy = INFINITY + min_tox = 0 + max_tox = INFINITY + min_co2 = 0 + max_co2 = INFINITY + min_n2 = 0 + max_n2 = INFINITY + minbodytemp = 0 + maxbodytemp = INFINITY + faction = list("slaughter") + attacktext = "wildly tears into" + maxHealth = 200 + health = 200 + environment_smash = 1 + //universal_understand = 1 + melee_damage_lower = 30 + melee_damage_upper = 30 + see_in_dark = 8 + see_invisible = SEE_INVISIBLE_MINIMUM + var/boost = 0 + bloodcrawl = BLOODCRAWL_EAT + + + var/devoured = 0 + + var/list/nearby_mortals = list() + var/cooldown = 0 + var/gorecooldown = 0 + var/vialspawned = FALSE + var/playstyle_string = "You are the Slaughter Demon, a terrible creature from another existence. You have a single desire: To kill. \ + You may Ctrl+Click on blood pools to travel through them, appearing and dissaapearing from the station at will. \ + Pulling a dead or critical mob while you enter a pool will pull them in with you, allowing you to feast. \ + You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. " + + +/mob/living/simple_animal/slaughter/New() + ..() + spawn() + if(src.mind) + src.mind.current.verbs += /mob/living/simple_animal/slaughter/proc/slaughterWhisper + src << src.playstyle_string + src << "You are not currently in the same plane of existence as the station. Ctrl+Click a blood pool to manifest." + if(!(vialspawned)) + var/datum/objective/slaughter/objective = new + var/datum/objective/demonFluff/fluffObjective = new + ticker.mode.traitors |= src.mind + objective.owner = src.mind + fluffObjective.owner = src.mind + //Paradise Port:I added the objective for one spawned like this + src.mind.objectives += objective + src.mind.objectives += fluffObjective + src << "Objective #[1]: [objective.explanation_text]" + src << "Objective #[2]: [fluffObjective.explanation_text]" + + +/mob/living/simple_animal/slaughter/Life() + ..() + if(boostThe [src] screams in anger as its form collapes into a pool of viscera.") + ghostize() + qdel(src) + + + +/mob/living/simple_animal/slaughter/phasein() + ..() + speed = 0 + boost = world.time + 30 + +/mob/living/simple_animal/slaughter/say(message) + return 0 +////////////////////The Powers + +//Paradise Port:I added this cuase..SPOOPY DEMON IN YOUR BRAIN + + +/mob/living/simple_animal/slaughter/proc/slaughterWhisper() + set name = "Whisper" + set desc = "Whisper to a mortal" + set category = "Daemon" + + var/list/choices = list() + for(var/mob/living/carbon/C in living_mob_list) + if(C.stat != 2 && C.client && C.stat != DEAD) + choices += C + + var/mob/living/carbon/M = input(src,"Who do you wish to talk to?") in null|choices + spawn(0) + var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "") + if(!(msg)) + return + usr << "You whisper to [M]: [msg]" + M << "Suddenly a strange,demonic,voice resonates in your head... [msg]" + +//////////The Loot + +/obj/item/weapon/demonheart + name = "demon's heart" + desc = "It's still faintly beating with rage" + icon = 'icons/obj/surgery.dmi' + icon_state = "heart-on" + origin_tech = "combat=5;biotech=8" + + +/obj/item/weapon/demonheart/attack_self(mob/living/user) + visible_message("[user] feasts upon the [src].") + if(user.bloodcrawl == 0) + user << "You absorb some of the demon's power!" + user.bloodcrawl = BLOODCRAWL + else if(user.bloodcrawl == 1) + user << "You absorb some of the demon's power!" + user << "You feel diffr- CONSUME THEM! " + user.bloodcrawl = BLOODCRAWL_EAT + qdel(src) + + +//Objectives and helpers. + +//Objective info, Based on Reverent mini Atang +/datum/objective/slaughter + var/targetKill = 10 + +/datum/objective/slaughter/New() + targetKill = rand(10,20) + explanation_text = "Devour [targetKill] mortals." + ..() + +/datum/objective/slaughter/check_completion() + if(!istype(owner.current, /mob/living/simple_animal/slaughter) || !owner.current) + return 0 + var/mob/living/simple_animal/slaughter/R = owner.current + if(!R || R.stat == DEAD) + return 0 + var/deathCount = R.devoured + if(deathCount < targetKill) + return 0 + return 1 + +/datum/objective/demonFluff + + +/datum/objective/demonFluff/New() + find_target() + var/targetname = "someone" + if(target && target.current) + targetname = target.current.real_name + var/list/explanationTexts = list("Attempt to make your presence unknown to the crew.", \ + "Kill or Destroy all Janitors or Sanitation bots.", \ + "Drive [targetname] insane with demonic whispering." + ) + + explanation_text = pick(explanationTexts) + ..() + +/datum/objective/demonFluff/check_completion() + return 1 \ No newline at end of file diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index dbdb0001592..c9d9b674b1d 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi index 52bbd89fe86..60168f993eb 100644 Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ diff --git a/paradise.dme b/paradise.dme index 1e625854674..7d3cd4d7a8b 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1122,6 +1122,7 @@ #include "code\modules\events\prison_break.dm" #include "code\modules\events\radiation_storm.dm" #include "code\modules\events\rogue_drones.dm" +#include "code\modules\events\slaughterevent.dm" #include "code\modules\events\spacevine.dm" #include "code\modules\events\spider_infestation.dm" #include "code\modules\events\tear.dm" @@ -1261,6 +1262,7 @@ #include "code\modules\mob\dead\observer\observer.dm" #include "code\modules\mob\dead\observer\say.dm" #include "code\modules\mob\dead\observer\spells.dm" +#include "code\modules\mob\living\bloodcrawl.dm" #include "code\modules\mob\living\damage_procs.dm" #include "code\modules\mob\living\default_language.dm" #include "code\modules\mob\living\living.dm" @@ -1455,6 +1457,7 @@ #include "code\modules\mob\living\simple_animal\revenant\revenant.dm" #include "code\modules\mob\living\simple_animal\revenant\revenant_abilities.dm" #include "code\modules\mob\living\simple_animal\revenant\revenant_spawn_event.dm" +#include "code\modules\mob\living\simple_animal\slaughter\slaughter.dm" #include "code\modules\mob\new_player\login.dm" #include "code\modules\mob\new_player\logout.dm" #include "code\modules\mob\new_player\new_player.dm" diff --git a/sound/misc/Demon_consume.ogg b/sound/misc/Demon_consume.ogg new file mode 100644 index 00000000000..ef9276e74c0 Binary files /dev/null and b/sound/misc/Demon_consume.ogg differ diff --git a/sound/misc/demon_attack1.ogg b/sound/misc/demon_attack1.ogg new file mode 100644 index 00000000000..e3c765afd0c Binary files /dev/null and b/sound/misc/demon_attack1.ogg differ diff --git a/sound/misc/demon_dies.ogg b/sound/misc/demon_dies.ogg new file mode 100644 index 00000000000..ad2a95f397d Binary files /dev/null and b/sound/misc/demon_dies.ogg differ diff --git a/sound/misc/enter_blood.ogg b/sound/misc/enter_blood.ogg new file mode 100644 index 00000000000..4deba11b465 Binary files /dev/null and b/sound/misc/enter_blood.ogg differ diff --git a/sound/misc/exit_blood.ogg b/sound/misc/exit_blood.ogg new file mode 100644 index 00000000000..c4399a2ecc6 Binary files /dev/null and b/sound/misc/exit_blood.ogg differ