Hallucination Refactor (#17661)

* begone accursed beast

* cleanup and notes

* screen object fix

* varset clear

* don't raw send sounds, spark on door sound, pain hallucination

* lengthen this a bit

* more pain messages, become jittery

* note

* lets clean that up to

* Revert "lets clean that up to"

This reverts commit 2409e41870.

* cleanup and define

* use accessors

* death isn't working so have toxins instead, it's scarier

* don't actually clean these up, because of how xenochi works

* additional protection

* hunger joke

* Use get_component instead of a cache

* empty scope removed

* Updated xenochi code to use hallu component

---------

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
Will
2025-05-15 00:17:39 -07:00
committed by GitHub
co-authored by Kashargul
parent 8eb403bf73
commit 709e9d130c
12 changed files with 689 additions and 610 deletions
+3 -189
View File
@@ -237,196 +237,10 @@
if(!owner.stat)
owner.emote("twitch")
/datum/component/xenochimera/proc/handle_feral()
if(owner.handling_hal) return
owner.handling_hal = 1
if(owner.client && feral >= 10) // largely a copy of handle_hallucinations() without the fake attackers. Unlike hallucinations, only fires once - if they're still feral they'll get hit again anyway.
spawn(rand(200,500)/(feral/10))
if(!feral) return //just to avoid fuckery in the event that they un-feral in the time it takes for the spawn to proc
var/halpick = rand(1,100)
switch(halpick)
if(0 to 15) //15% chance
//Screwy HUD
//to_chat(src, "Screwy HUD")
owner.hal_screwyhud = pick(1,2,3,3,4,4)
spawn(rand(100,250))
owner.hal_screwyhud = 0
if(16 to 25) //10% chance
//Strange items
//to_chat(src, "Traitor Items")
if(!owner.halitem)
owner.halitem = new
var/list/slots_free = list(ui_lhand,ui_rhand)
if(owner.l_hand) slots_free -= ui_lhand
if(owner.r_hand) slots_free -= ui_rhand
if(!owner.belt) slots_free += ui_belt
if(!owner.l_store) slots_free += ui_storage1
if(!owner.r_store) slots_free += ui_storage2
if(slots_free.len)
owner.halitem.screen_loc = pick(slots_free)
owner.halitem.layer = 50
switch(rand(1,6))
if(1) //revolver
owner.halitem.icon = 'icons/obj/gun.dmi'
owner.halitem.icon_state = "revolver"
owner.halitem.name = "Revolver"
if(2) //c4
owner.halitem.icon = 'icons/obj/assemblies.dmi'
owner.halitem.icon_state = "plastic-explosive0"
owner.halitem.name = "Mysterious Package"
if(prob(25))
owner.halitem.icon_state = "c4small_1"
if(3) //sword
owner.halitem.icon = 'icons/obj/weapons.dmi'
owner.halitem.icon_state = "sword1"
owner.halitem.name = "Sword"
if(4) //stun baton
owner.halitem.icon = 'icons/obj/weapons.dmi'
owner.halitem.icon_state = "stunbaton"
owner.halitem.name = "Stun Baton"
if(5) //emag
owner.halitem.icon = 'icons/obj/card.dmi'
owner.halitem.icon_state = "emag"
owner.halitem.name = "Cryptographic Sequencer"
if(6) //flashbang
owner.halitem.icon = 'icons/obj/grenade.dmi'
owner.halitem.icon_state = "flashbang1"
owner.halitem.name = "Flashbang"
if(owner.client) owner.client.screen += owner.halitem
spawn(rand(100,250))
if(owner.client)
owner.client.screen -= owner.halitem
owner.halitem = null
if(26 to 35) //10% chance
//Flashes of danger
//to_chat(src, "Danger Flash")
if(!owner.halimage)
var/list/possible_points = list()
for(var/turf/simulated/floor/F in view(owner,world.view))
possible_points += F
if(possible_points.len)
var/turf/simulated/floor/target = pick(possible_points)
switch(rand(1,3))
if(1)
//to_chat(src, "Space")
owner.halimage = image('icons/turf/space.dmi',target,"[rand(1,25)]",TURF_LAYER)
if(2)
//to_chat(src, "Fire")
owner.halimage = image('icons/effects/fire.dmi',target,"1",TURF_LAYER)
if(3)
//to_chat(src, "C4")
owner.halimage = image('icons/obj/assemblies.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01)
if(owner.client) owner.client.images += owner.halimage
spawn(rand(10,50)) //Only seen for a brief moment.
if(owner.client) owner.client.images -= owner.halimage
owner.halimage = null
if(36 to 55) //20% chance
//Strange audio
//to_chat(src, "Strange Audio")
switch(rand(1,12))
if(1) owner << 'sound/machines/door/old_airlock.ogg'
if(2)
if(prob(50))owner << 'sound/effects/Explosion1.ogg'
else owner << 'sound/effects/Explosion2.ogg'
if(3) owner << 'sound/effects/explosionfar.ogg'
if(4) owner << 'sound/effects/Glassbr1.ogg'
if(5) owner << 'sound/effects/Glassbr2.ogg'
if(6) owner << 'sound/effects/Glassbr3.ogg'
if(7) owner << 'sound/machines/twobeep.ogg'
if(8) owner << 'sound/machines/door/windowdoor.ogg'
if(9)
//To make it more realistic, I added two gunshots (enough to kill)
owner << 'sound/weapons/Gunshot1.ogg'
spawn(rand(10,30))
owner << 'sound/weapons/Gunshot2.ogg'
if(10) owner << 'sound/weapons/smash.ogg'
if(11)
//Same as above, but with tasers.
owner << 'sound/weapons/Taser.ogg'
spawn(rand(10,30))
owner << 'sound/weapons/Taser.ogg'
//Rare audio
if(12)
//These sounds are (mostly) taken from Hidden: Source
var/list/creepyasssounds = list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/Heart Beat.ogg', 'sound/effects/screech.ogg',\
'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\
'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
owner << pick(creepyasssounds)
if(56 to 60) //5% chance
//Flashes of danger
//to_chat(src, "Danger Flash")
if(!owner.halbody)
var/list/possible_points = list()
for(var/turf/simulated/floor/F in view(owner,world.view))
possible_points += F
if(possible_points.len)
var/turf/simulated/floor/target = pick(possible_points)
switch(rand(1,4))
if(1)
owner.halbody = image('icons/mob/human.dmi',target,"husk_l",TURF_LAYER)
if(2,3)
owner.halbody = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER)
if(4)
owner.halbody = image('icons/mob/alien.dmi',target,"alienother",TURF_LAYER)
// if(5)
// halbody = image('xcomalien.dmi',target,"chryssalid",TURF_LAYER)
if(owner.client) owner.client.images += owner.halbody
spawn(rand(50,80)) //Only seen for a brief moment.
if(owner.client) owner.client.images -= owner.halbody
owner.halbody = null
if(61 to 85) //25% chance
//food
if(!owner.halbody)
var/list/possible_points = list()
for(var/turf/simulated/floor/F in view(owner,world.view))
possible_points += F
if(possible_points.len)
var/turf/simulated/floor/target = pick(possible_points)
switch(rand(1,10))
if(1)
owner.halbody = image('icons/mob/animal.dmi',target,"cow",TURF_LAYER)
if(2)
owner.halbody = image('icons/mob/animal.dmi',target,"chicken",TURF_LAYER)
if(3)
owner.halbody = image('icons/obj/food.dmi',target,"bigbiteburger",TURF_LAYER)
if(4)
owner.halbody = image('icons/obj/food.dmi',target,"meatbreadslice",TURF_LAYER)
if(5)
owner.halbody = image('icons/obj/food.dmi',target,"sausage",TURF_LAYER)
if(6)
owner.halbody = image('icons/obj/food.dmi',target,"bearmeat",TURF_LAYER)
if(7)
owner.halbody = image('icons/obj/food.dmi',target,"fishfillet",TURF_LAYER)
if(8)
owner.halbody = image('icons/obj/food.dmi',target,"meat",TURF_LAYER)
if(9)
owner.halbody = image('icons/obj/food.dmi',target,"meatstake",TURF_LAYER)
if(10)
owner.halbody = image('icons/obj/food.dmi',target,"monkeysdelight",TURF_LAYER)
if(owner.client) owner.client.images += owner.halbody
spawn(rand(50,80)) //Only seen for a brief moment.
if(owner.client) owner.client.images -= owner.halbody
owner.halbody = null
if(86 to 100) //15% chance
//hear voices. Could make the voice pick from nearby creatures, but nearby creatures make feral hallucinations rare so don't bother.
var/list/hiddenspeakers = list("Someone distant", "A voice nearby","A familiar voice", "An echoing voice", "A cautious voice", "A scared voice", "Someone around the corner", "Someone", "Something", "Something scary", "An urgent voice", "An angry voice")
var/list/speakerverbs = list("calls out", "yells", "screams", "exclaims", "shrieks", "shouts", "hisses", "snarls")
var/list/spookyphrases = list("It's over here!","Stop it!", "Hunt it down!", "Get it!", "Quick, over here!", "Anyone there?", "Who's there?", "Catch that thing!", "Stop it! Kill it!", "Anyone there?", "Where is it?", "Find it!", "There it is!")
to_chat(owner, span_game(span_say(span_name(pick(hiddenspeakers)) + " [pick(speakerverbs)], \"[pick(spookyphrases)]\"")))
owner.handling_hal = 0
return
if(QDELETED(owner) || owner.get_hallucination_component() || !owner.client || feral < XENOCHIFERAL_THRESHOLD)
return
owner.LoadComponent(/datum/component/hallucinations/xenochimera)
/obj/screen/xenochimera
icon = 'icons/mob/chimerahud.dmi'