diff --git a/code/__defines/hallucination.dm b/code/__defines/hallucination.dm
new file mode 100644
index 0000000000..8bd739f1ac
--- /dev/null
+++ b/code/__defines/hallucination.dm
@@ -0,0 +1,8 @@
+#define HALLUCINATION_THRESHOLD 20
+#define XENOCHIFERAL_THRESHOLD 10
+
+#define HUD_HALLUCINATION_NONE 0
+#define HUD_HALLUCINATION_CRIT 1
+#define HUD_HALLUCINATION_TOXIN 2
+#define HUD_HALLUCINATION_OXY 3
+#define HUD_HALLUCINATION_ONFIRE 4
diff --git a/code/controllers/subsystems/motion_tracker.dm b/code/controllers/subsystems/motion_tracker.dm
index 2d3127143b..5cd4b1459a 100644
--- a/code/controllers/subsystems/motion_tracker.dm
+++ b/code/controllers/subsystems/motion_tracker.dm
@@ -43,10 +43,12 @@ SUBSYSTEM_DEF(motiontracker)
if(Rt && At && count)
while(count-- > 0)
// Place at root turf offset from signal responder's turf using px offsets. So it will show up over visblocking.
- var/image/motion_echo/E = new /image/motion_echo('icons/effects/effects.dmi', Rt, "motion_echo", OBFUSCATION_LAYER, SOUTH)
+ var/image/client_only/motion_echo/E = new /image/client_only/motion_echo('icons/effects/effects.dmi', Rt, "motion_echo", OBFUSCATION_LAYER, SOUTH)
E.place_from_root(At)
- for(var/datum/weakref/C in clients)
- E.append_client(C)
+ for(var/datum/weakref/CW in clients)
+ var/client/C = CW?.resolve()
+ if(C)
+ E.append_client(C)
currentrun.Remove(key)
expended_echos[key] = data
if(MC_TICK_CHECK)
diff --git a/code/datums/components/species/xenochimera.dm b/code/datums/components/species/xenochimera.dm
index d29ffe6b9b..8351ace06e 100644
--- a/code/datums/components/species/xenochimera.dm
+++ b/code/datums/components/species/xenochimera.dm
@@ -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'
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 1f2262f896..d8cd36a4d0 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -674,6 +674,7 @@ About the new airlock wires panel:
return
else if(user.hallucination > 50 && prob(10) && src.operating == 0)
to_chat(user, span_danger("You feel a powerful shock course through your body!"))
+ user.playsound_local(get_turf(user), get_sfx("sparks"), vol = 75)
user.halloss += 10
user.stunned += 10
return
diff --git a/code/game/objects/effects/client_only_image.dm b/code/game/objects/effects/client_only_image.dm
new file mode 100644
index 0000000000..3b87c721c1
--- /dev/null
+++ b/code/game/objects/effects/client_only_image.dm
@@ -0,0 +1,23 @@
+/*
+* Sending images to clients can cause memory leaks if not handled safely.
+* This is a wrapper for handling it safely. Mostly used by self deleting effects.
+*/
+/image/client_only
+ var/list/clients = list()
+
+/image/client_only/proc/append_client(var/client/C)
+ C.images += src
+ clients.Add(WEAKREF(C))
+
+/image/client_only/Destroy(force)
+ . = ..()
+ for(var/datum/weakref/CW in clients)
+ var/client/C = CW?.resolve()
+ if(C)
+ C.images -= src
+
+// Mostly for motion echos, but someone will probably find another use for it... So parent type gets it instead!
+/image/client_only/proc/place_from_root(var/turf/At)
+ var/rand_limit = 12
+ pixel_x += ((At.x - loc.x) * 32) + rand(-rand_limit,rand_limit)
+ pixel_y += ((At.y - loc.y) * 32) + rand(-rand_limit,rand_limit)
diff --git a/code/game/objects/effects/motion_echo.dm b/code/game/objects/effects/motion_echo.dm
index 19face9b88..211af8975c 100644
--- a/code/game/objects/effects/motion_echo.dm
+++ b/code/game/objects/effects/motion_echo.dm
@@ -1,27 +1,8 @@
-/image/motion_echo
+/image/client_only/motion_echo
plane = PLANE_FULLSCREEN
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
appearance_flags = (RESET_COLOR|PIXEL_SCALE|KEEP_APART)
- var/list/clients = list()
-/image/motion_echo/New(icon, loc, icon_state, layer, dir)
+/image/client_only/motion_echo/New(icon, loc, icon_state, layer, dir)
. = ..()
QDEL_IN(src, 2 SECONDS)
-
-/image/motion_echo/proc/place_from_root(var/turf/At)
- var/rand_limit = 12
- pixel_x += ((At.x - loc.x) * 32) + rand(-rand_limit,rand_limit)
- pixel_y += ((At.y - loc.y) * 32) + rand(-rand_limit,rand_limit)
-
-/image/motion_echo/proc/append_client(var/datum/weakref/C)
- var/client/CW = C?.resolve()
- if(CW)
- CW.images += src
- clients.Add(C)
-
-/image/motion_echo/Destroy(force)
- . = ..()
- for(var/datum/weakref/C in clients)
- var/client/CW = C?.resolve()
- if(CW)
- CW.images -= src
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 75b2cb43b2..a5c3204dc3 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -8,409 +8,132 @@ Brief flashes of fire/space/bombs/c4/dangerous shit (done)
Items that are rare/traitorous/don't exist appearing in your inventory slots (done)
Strange audio (should be rare) (done)
Gunshots/explosions/opening doors/less rare audio (done)
-
*/
-/mob/living/carbon/var
- image/halimage
- image/halbody
- obj/halitem
- hal_screwyhud = 0 //1 - critical, 2 - dead, 3 - oxygen indicator, 4 - toxin indicator
- handling_hal = 0
- hal_crit = 0
+/datum/component/hallucinations
+ dupe_mode = COMPONENT_DUPE_UNIQUE // First come first serve
-/mob/living/carbon/proc/handle_hallucinations()
- if(handling_hal) return
- handling_hal = 1
- while(client && hallucination > 20)
- sleep(rand(200,500)/(hallucination/25))
- var/halpick = rand(1,100)
- switch(halpick)
- if(0 to 15)
- //Screwy HUD
- //to_chat(src, "Screwy HUD")
- hal_screwyhud = pick(1,2,3,3,4,4)
- spawn(rand(100,250))
- hal_screwyhud = 0
- if(16 to 25)
- //Strange items
- //to_chat(src, "Traitor Items")
- if(!halitem)
- halitem = new
- var/list/slots_free = list(ui_lhand,ui_rhand)
- if(l_hand) slots_free -= ui_lhand
- if(r_hand) slots_free -= ui_rhand
- if(ishuman(src))
- var/mob/living/carbon/human/H = src
- if(!H.belt) slots_free += ui_belt
- if(!H.l_store) slots_free += ui_storage1
- if(!H.r_store) slots_free += ui_storage2
- if(slots_free.len)
- halitem.screen_loc = pick(slots_free)
- halitem.hud_layerise()
- switch(rand(1,6))
- if(1) //revolver
- halitem.icon = 'icons/obj/gun.dmi'
- halitem.icon_state = "revolver"
- halitem.name = "Revolver"
- if(2) //c4
- halitem.icon = 'icons/obj/assemblies.dmi'
- halitem.icon_state = "plastic-explosive0"
- halitem.name = "Mysterious Package"
- if(prob(25))
- halitem.icon_state = "c4small_1"
- if(3) //sword
- halitem.icon = 'icons/obj/weapons.dmi'
- halitem.icon_state = "sword1"
- halitem.name = "Sword"
- if(4) //stun baton
- halitem.icon = 'icons/obj/weapons.dmi'
- halitem.icon_state = "stunbaton"
- halitem.name = "Stun Baton"
- if(5) //emag
- halitem.icon = 'icons/obj/card.dmi'
- halitem.icon_state = "emag"
- halitem.name = "Cryptographic Sequencer"
- if(6) //flashbang
- halitem.icon = 'icons/obj/grenade.dmi'
- halitem.icon_state = "flashbang1"
- halitem.name = "Flashbang"
- if(client) client.screen += halitem
- spawn(rand(100,250))
- if(client)
- client.screen -= halitem
- halitem = null
- if(26 to 40)
- //Flashes of danger
- //to_chat(src, "Danger Flash")
- if(!halimage)
- var/list/possible_points = list()
- for(var/turf/simulated/floor/F in view(src,world.view))
- possible_points += F
- if(possible_points.len)
- var/turf/simulated/floor/target = pick(possible_points)
+ VAR_PRIVATE/mob/living/carbon/human/our_human = null
+ VAR_PRIVATE/datum/weakref/halimage
+ VAR_PRIVATE/datum/weakref/halbody
+ VAR_PRIVATE/list/halitem = list() // weakref pair of obj-key, client-value
- switch(rand(1,3))
- if(1)
- //to_chat(src, "Space")
- halimage = image('icons/turf/space.dmi',target,"[rand(1,25)]",TURF_LAYER)
- if(2)
- //to_chat(src, "Fire")
- halimage = image('icons/effects/fire.dmi',target,"1",TURF_LAYER)
- if(3)
- //to_chat(src, "C4")
- halimage = image('icons/obj/assemblies.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01)
+ VAR_PRIVATE/hal_crit = FALSE
+ VAR_PRIVATE/hal_screwyhud = HUD_HALLUCINATION_NONE
+/datum/component/hallucinations/Initialize()
+ if(!ishuman(parent))
+ return COMPONENT_INCOMPATIBLE
+ our_human = parent
+ make_timer()
- if(client) client.images += halimage
- spawn(rand(10,50)) //Only seen for a brief moment.
- if(client) client.images -= halimage
- halimage = null
-
-
- if(41 to 65)
- //Strange audio
- //to_chat(src, "Strange Audio")
- switch(rand(1,12))
- if(1) src << 'sound/machines/door/old_airlock.ogg'
- if(2)
- if(prob(50))src << 'sound/effects/Explosion1.ogg'
- else src << 'sound/effects/Explosion2.ogg'
- if(3) src << 'sound/effects/explosionfar.ogg'
- if(4) src << 'sound/effects/Glassbr1.ogg'
- if(5) src << 'sound/effects/Glassbr2.ogg'
- if(6) src << 'sound/effects/Glassbr3.ogg'
- if(7) src << 'sound/machines/twobeep.ogg'
- if(8) src << 'sound/machines/door/windowdoor.ogg'
- if(9)
- //To make it more realistic, I added two gunshots (enough to kill)
- src << 'sound/weapons/Gunshot1.ogg'
- spawn(rand(10,30))
- src << 'sound/weapons/Gunshot2.ogg'
- if(10) src << 'sound/weapons/smash.ogg'
- if(11)
- //Same as above, but with tasers.
- src << 'sound/weapons/Taser.ogg'
- spawn(rand(10,30))
- src << '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')
- src << pick(creepyasssounds)
- if(66 to 70)
- //Flashes of danger
- //to_chat(src, "Danger Flash")
- if(!halbody)
- var/list/possible_points = list()
- for(var/turf/simulated/floor/F in view(src,world.view))
- possible_points += F
- if(possible_points.len)
- var/turf/simulated/floor/target = pick(possible_points)
- switch(rand(1,4))
- if(1)
- halbody = image('icons/mob/human.dmi',target,"husk_l",TURF_LAYER)
- if(2,3)
- halbody = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER)
- if(4)
- halbody = image('icons/mob/alien.dmi',target,"alienother",TURF_LAYER)
- // if(5)
- // halbody = image('xcomalien.dmi',target,"chryssalid",TURF_LAYER)
-
- if(client) client.images += halbody
- spawn(rand(50,80)) //Only seen for a brief moment.
- if(client) client.images -= halbody
- halbody = null
- if(71 to 72)
- //Fake death
-// src.sleeping_willingly = 1
- SetSleeping(20)
- hal_crit = 1
- hal_screwyhud = 1
- spawn(rand(50,100))
-// src.sleeping_willingly = 0
- SetSleeping(0)
- hal_crit = 0
- hal_screwyhud = 0
- handling_hal = 0
-
-
-
-
-/*obj/machinery/proc/mockpanel(list/buttons,start_txt,end_txt,list/mid_txts)
-
- if(!mocktxt)
-
- mocktxt = ""
-
- var/possible_txt = list("Launch Escape Pods","Self-Destruct Sequence","\[Swipe ID\]","De-Monkify",\
- "Reticulate Splines","Plasma","Open Valve","Lockdown","Nerf Airflow","Kill Traitor","Nihilism",\
- "OBJECTION!","Arrest Stephen Bowman","Engage Anti-Trenna Defenses","Increase Site Manager IQ","Retrieve Arms",\
- "Play Charades","Oxygen","Inject BeAcOs","Ninja Lizards","Limit Break","Build Sentry")
-
- if(mid_txts)
- while(mid_txts.len)
- var/mid_txt = pick(mid_txts)
- mocktxt += mid_txt
- mid_txts -= mid_txt
-
- while(buttons.len)
-
- var/button = pick(buttons)
-
- var/button_txt = pick(possible_txt)
-
- mocktxt += "[button_txt]
"
-
- buttons -= button
- possible_txt -= button_txt
-
- return start_txt + mocktxt + end_txt + "