[Ready] The Virtual Reality Hub (#42879)

About The Pull Request

VR sleepers now lead to the VR Hub, a place with a bunch of portals that lead you to other areas, or just has chill stuff like a bar. Includes portals to all the old vr maps, the megafauna training simulator map, a soon to be minecraft map, and my crappy game runner where you run away from falling tiles and fight to be the last person to survive. Merges murderdome and syndicate trainer into the vr hub map so they spawn every time with vr. Recall portals now can have multiple exits to support the old vr waypoint system from the hub. Also moves a lot of stuff around in the files to make it more organized. There's now also a ghost role that can access VR as well with infinite spawns.

VR NOW HAS A CONFIG OPTION SO ENABLE IT OR VR WILL NOT WORK.
Why It's Good For The Game

Being a ghost is boring for most people, it's nice to have a place for people to hang out rather than just leave the server. This is also a nice place where people can put gamemodes they're testing or other fun little minigames that can't be main gamemodes. VR currently is not used by really anyone so I don't see anyone getting bothered by this PR as well.
This commit is contained in:
Whoneedspacee
2019-04-22 12:16:11 +12:00
committed by oranges
parent e586883c8c
commit 5b89dea70f
19 changed files with 69388 additions and 31960 deletions
@@ -1,11 +1,11 @@
// //
// -----Vr Stuff----- //
// //
/area/awaymission/vr/megafauna_arena
name = "Virtual Reality Megafauna Trainer Safe Area"
icon_state = "awaycontent3"
/area/awaymission/vr/miner
name = "VrMining"
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
/area/awaymission/vr/megafauna_arena/arena
name = "Virtual Reality Megafauna Trainer Fighting Area"
icon_state = "awaycontent4"
pacifist = FALSE
/datum/outfit/job/miner/equipped/vr
name = "Virtual Reality Miner"
@@ -17,8 +17,91 @@
backpack_contents = list(
/obj/item/gun/energy/kinetic_accelerator=2)
/obj/effect/landmark/vr_spawn/miner
vr_outfit = /datum/outfit/job/miner/equipped/vr
/obj/effect/portal/permanent/one_way/recall/megafauna_arena
name = "Megafauna Arena Portal"
desc = "Fight against megafauna in the safety of virtual reality."
equipment = /datum/outfit/job/miner/equipped/vr
recall_equipment = /datum/outfit/vr
id = "vr megafauna arena"
light_color = LIGHT_COLOR_FIRE
light_power = 1
light_range = 10
/obj/effect/portal/permanent/one_way/destroy/megafauna_arena
name = "Megafauna Arena Exit Portal"
id = "vr megafauna arena"
/obj/effect/portal/permanent/one_way/recall/blood_drunk_miner
name = "Blood Drunk Miner Arena Portal"
desc = "You see a faded miner through the portal. His rippling eyes stare directly at you."
id = "vr blood drunk miner"
/obj/effect/portal/permanent/one_way/destroy/blood_drunk_miner
name = "Blood Drunk Miner Arena Exit Portal"
id = "vr blood drunk miner"
/obj/effect/portal/permanent/one_way/recall/dragon
name = "Ash Drake Arena Portal"
desc = "The crackling fires of hell burn on the other side."
id = "vr ash drake"
/obj/effect/portal/permanent/one_way/destroy/dragon
name = "Ash Drake Arena Exit Portal"
id = "vr ash drake"
/obj/effect/portal/permanent/one_way/recall/bubblegum
name = "Bubblegum Arena Portal"
desc = "The arena of the king of the slaughter demons. Doesn't he control all versions of himself?"
id = "vr bubblegum"
/obj/effect/portal/permanent/one_way/destroy/bubblegum
name = "Bubblegum Arena Exit Portal"
id = "vr bubblegum"
/obj/effect/portal/permanent/one_way/recall/colossus
name = "Colossus Arena Portal"
desc = "Colossus are quite dangerous in close quarters."
id = "vr colossus"
/obj/effect/portal/permanent/one_way/destroy/colossus
name = "Colossus Arena Exit Portal"
id = "vr colossus"
/obj/effect/portal/permanent/one_way/recall/hierophant
name = "Hierophant Arena Portal"
desc = "They call him the hierophant. He's the king of the rumba beat. When he plays the maracas you go Chick chicky boom Chick chicky boom."
id = "vr hierophant"
/obj/effect/portal/permanent/one_way/destroy/hierophant
name = "Hierophant Arena Exit Portal"
id = "vr hierophant"
/obj/effect/portal/permanent/one_way/recall/legion
name = "Legion Arena Portal"
desc = "The portal to the defender of the necropolis. He's mostly there for show."
id = "vr legion"
/obj/effect/portal/permanent/one_way/destroy/legion
name = "Legion Arena Exit Portal"
id = "vr legion"
/obj/effect/portal/permanent/one_way/recall/vr_boss_rush
name = "Boss Rush Portal"
desc = "You're not certain this is even possible."
id = "vr boss rush"
/obj/effect/portal/permanent/one_way/destroy/vr_boss_rush
name = "Boss Rush Exit Portal"
id = "vr boss rush"
/obj/effect/portal/permanent/one_way/keep/vr_boss_rush_continue
name = "Boss Rush Continue Portal"
desc = "You're halfway there. These next fights are even tougher, however."
id = "vr boss rush continue"
/obj/effect/portal/permanent/one_way/destroy/vr_boss_rush_continue
name = "Boss Rush Continue Exit Portal"
id = "vr boss rush continue"
/obj/structure/closet/crate/necropolis/vr_mining_gear
name = "armory chest"
@@ -114,11 +197,8 @@
/obj/item/reagent_containers/glass/bottle/potion/flight=1,
/obj/item/organ/heart/cursed/wizard=1,
/obj/item/immortality_talisman=1,
/obj/item/book/granter/spell/summonitem=1)
// //
// -----Virtual Megafauna Spawners ---- //
// //
/obj/item/book/granter/spell/summonitem=1,
/obj/item/extinguisher=1)
/datum/component/spawner/megafauna
var/spawn_wait_time = 150 // time to next spawn when the megafauna dies, 15 seconds
@@ -194,58 +274,6 @@
icon_state = "legion"
mob_types = list(/mob/living/simple_animal/hostile/megafauna/legion/virtual)
// //
// ----- Recall Portals ---- //
// //
/obj/effect/proc_holder/spell/portal_recall
name = "Portal Recall"
desc = "This will teleport you back to your previously used portal. One use only."
clothes_req = FALSE
action_icon_state = "blink"
var/list/recall_portals = list()
/obj/effect/proc_holder/spell/portal_recall/Click(mob/user = usr)
if(!recall_portals.len)
user.mind.RemoveSpell(src) // remove spell if no portals left
var/turf/recall_turf = get_turf(recall_portals[recall_portals.len])
if(recall_turf)
do_teleport(user, recall_turf, 0, no_effects = FALSE, channel = TELEPORT_CHANNEL_BLUESPACE)
recall_portals -= recall_portals[recall_portals.len]
if(!recall_portals.len)
user.mind.RemoveSpell(src) // remove spell if no portals left
/obj/effect/portal/permanent/one_way/recall
name = "recall portal"
desc = "Gives you a one time ability to return to this portal once you have entered."
mech_sized = TRUE
keep = TRUE
/obj/effect/portal/permanent/one_way/recall/Crossed(atom/movable/AM, oldloc)
if(ismob(AM))
var/mob/user = AM
var/check = locate(/obj/effect/proc_holder/spell/portal_recall) in user.mind.spell_list
if(check)
var/obj/effect/proc_holder/spell/portal_recall/mob_recall = check
for(var/obj/effect/portal/permanent/one_way/recall/P in mob_recall.recall_portals)
if(src == P)
return ..(AM, oldloc, force_stop = 1) // don't teleport if they have a recall spell with this portal already (or have just teleported onto it)
return ..()
/obj/effect/portal/permanent/one_way/recall/teleport(atom/movable/M, force = FALSE)
. = ..()
if(ismob(M))
var/mob/user = M
var/findspell = locate(/obj/effect/proc_holder/spell/portal_recall) in user.mind.spell_list
var/obj/effect/proc_holder/spell/portal_recall/personal_recall = findspell ? findspell : new
personal_recall.recall_portals += src
if(!findspell)
user.mind.AddSpell(personal_recall)
// //
// -----Virtual Megafauna----- //
// //
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/virtual
name = "blood-drunk miner hologram"
desc = "A holographic miner, eternally hunting."
@@ -1,3 +1,8 @@
/area/awaymission/vr/murderdome
name = "Murderdome"
icon_state = "awaycontent8"
pacifist = FALSE
/obj/structure/window/reinforced/fulltile/indestructable
name = "robust window"
flags_1 = PREVENT_CLICK_UNDER_1 | NODECONSTRUCT_1
@@ -34,8 +39,3 @@
if(!QDELETED(src))
new /obj/structure/barricade/security/murderdome(get_turf(src))
qdel(src)
/area/awaymission/vr/murderdome
name = "Murderdome"
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
@@ -0,0 +1,129 @@
GLOBAL_VAR_INIT(vr_runner_active, FALSE)
GLOBAL_LIST_EMPTY(vr_runner_players)
GLOBAL_LIST_EMPTY(vr_runner_tiles)
/area/awaymission/vr/runner
name = "VrRunner"
icon_state = "awaycontent5"
/datum/outfit/vr/runner
name = "Runner Equipment"
shoes = /obj/item/clothing/shoes/bhop
/obj/effect/portal/permanent/one_way/recall/pit_faller
name = "Runner Portal"
desc = "A game of eternal running, where one misstep means certain death."
equipment = /datum/outfit/vr/runner
recall_equipment = /datum/outfit/vr
id = "vr runner"
light_color = LIGHT_COLOR_FIRE
light_power = 1
light_range = 4
var/game_starting = FALSE
var/game_start_time = FALSE
var/fall_wait = 5 // time in deciseconds between randomly falling tiles
/obj/effect/portal/permanent/one_way/recall/pit_faller/teleport(atom/movable/M, force = FALSE)
if(GLOB.vr_runner_active)
return FALSE
if(!ishuman(M))
return FALSE
. = ..()
if(.)
var/mob/living/carbon/human/H = M
GLOB.vr_runner_players += H
if(!game_starting)
INVOKE_ASYNC(src, .proc/game_start_countdown)
/obj/effect/portal/permanent/one_way/recall/pit_faller/recall_effect(mob/user)
if(ishuman(user))
var/mob/living/carbon/human/H = user
GLOB.vr_runner_players -= H
if(GLOB.vr_runner_active)
if(!GLOB.vr_runner_players.len)
to_chat(H, "<span class='notice'>You win! You survived for [(world.time - game_start_time) / 10] second\s.</span>")
end_game()
else
to_chat(H, "<span class='notice'>You survived for [(world.time - game_start_time) / 10] seconds. [GLOB.vr_runner_players.len] other player(s) remained.</span>")
/obj/effect/portal/permanent/one_way/recall/pit_faller/proc/game_start_countdown(wait_seconds = 10)
game_starting = TRUE
for(var/seconds_remaining = wait_seconds to 1 step -1)
if(!GLOB.vr_runner_players.len)
game_starting = FALSE
return FALSE
for(var/mob/living/carbon/human/H in GLOB.vr_runner_players)
to_chat(H, "<span class='notice'>Game starting in [seconds_remaining].</span>")
sleep(10)
if(GLOB.vr_runner_players.len)
GLOB.vr_runner_active = TRUE
for(var/mob/living/carbon/human/H in GLOB.vr_runner_players)
to_chat(H, "<span class='notice'>Game Started!</span>")
var/turf/open/indestructible/runner/R = get_turf(H)
INVOKE_ASYNC(R, /turf/open/indestructible/runner.proc/turf_fall)
color = COLOR_RED
INVOKE_ASYNC(src, .proc/random_falling_tiles)
game_starting = FALSE
game_start_time = world.time
/obj/effect/portal/permanent/one_way/recall/pit_faller/proc/random_falling_tiles()
if(!GLOB.vr_runner_active)
return FALSE
for(var/turf/open/indestructible/runner/R in GLOB.vr_runner_tiles)
if(R.color != COLOR_ALMOST_BLACK && prob(1))
INVOKE_ASYNC(R, /turf/open/indestructible/runner.proc/turf_fall)
sleep(fall_wait)
random_falling_tiles()
/obj/effect/portal/permanent/one_way/recall/pit_faller/proc/end_game()
color = initial(color)
GLOB.vr_runner_active = FALSE
game_starting = FALSE
for(var/turf/open/indestructible/runner/R in GLOB.vr_runner_tiles)
R.reset_fall()
/obj/effect/portal/permanent/one_way/destroy/pit_faller
name = "Runner Exit Portal"
id = "vr runner"
/turf/open/indestructible/runner
name = "Shaky Ground"
desc = "If you walk on that that you better keep running!"
var/not_reset = FALSE // check so turfs dont fall after being reset
var/falling_time = 15 // time it takes for the turf to fall
/turf/open/indestructible/runner/Initialize()
. = ..()
GLOB.vr_runner_tiles += src
/turf/open/indestructible/runner/Entered(atom/movable/A)
. = ..()
if(isliving(A) && GLOB.vr_runner_active)
if(color == COLOR_ALMOST_BLACK)
if(locate(A) in GLOB.vr_runner_players)
if(!A.throwing)
var/mob/living/carbon/human/H = A
var/obj/effect/proc_holder/spell/portal_recall/findspell = locate(/obj/effect/proc_holder/spell/portal_recall) in H.mind.spell_list
findspell.Click(H)
else
qdel(A)
else if(!not_reset) // make sure it's not already currently falling
INVOKE_ASYNC(src, .proc/turf_fall)
/turf/open/indestructible/runner/proc/turf_fall()
color = COLOR_RED
not_reset = TRUE
sleep(falling_time)
if(!not_reset)
return
not_reset = FALSE
color = COLOR_ALMOST_BLACK
for(var/mob/living/carbon/human/H in contents)
var/obj/effect/proc_holder/spell/portal_recall/findspell = locate(/obj/effect/proc_holder/spell/portal_recall) in H.mind.spell_list
if(H)
findspell.Click(H)
/turf/open/indestructible/runner/proc/reset_fall()
not_reset = FALSE
color = initial(color)
return
@@ -0,0 +1,156 @@
/area/awaymission/vr/general
name = "Virtual Reality Forbidden Zone"
death = TRUE
/area/awaymission/vr/hub
name = "Virtual Reality Hub Area"
icon_state = "awaycontent2"
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/vr/hub/boxing
name = "Virtual Reality Boxing Ring"
icon_state = "awaycontent9"
pacifist = FALSE
/area/awaymission/vr/syndicate
name = "Virtual Reality Syndicate Trainer"
icon_state = "awaycontent6"
pacifist = FALSE
/obj/effect/portal/permanent/one_way/recall
name = "recall portal"
desc = "Gives you a one time ability to return to this portal once you have entered."
mech_sized = TRUE
keep = TRUE
var/datum/outfit/equipment // optional outfit to equip upon entering
var/datum/outfit/recall_equipment // optional outfit to equip upon recalling
/obj/effect/portal/permanent/one_way/recall/Crossed(atom/movable/AM, oldloc)
if(ismob(AM))
var/mob/user = AM
var/check = locate(/obj/effect/proc_holder/spell/portal_recall) in user.mind.spell_list
if(check)
var/obj/effect/proc_holder/spell/portal_recall/mob_recall = check
for(var/obj/effect/portal/permanent/one_way/recall/P in mob_recall.recall_portals)
if(src == P)
return ..(AM, oldloc, force_stop = TRUE) // don't teleport if they have a recall spell with this portal already (or have just teleported onto it)
return ..()
/obj/effect/portal/permanent/one_way/recall/teleport(atom/movable/M, force = FALSE)
. = ..()
if(. && ismob(M))
var/mob/user = M
var/findspell = locate(/obj/effect/proc_holder/spell/portal_recall) in user.mind.spell_list
var/obj/effect/proc_holder/spell/portal_recall/personal_recall = findspell ? findspell : new
personal_recall.recall_portals += src
if(!findspell)
user.mind.AddSpell(personal_recall)
if(equipment && ishuman(user))
var/mob/living/carbon/human/H = user
H.delete_equipment()
H.equipOutfit(equipment)
// the effect that happens when someone recalls to your portal
/obj/effect/portal/permanent/one_way/recall/proc/recall_effect(mob/user)
return
/obj/effect/proc_holder/spell/portal_recall
name = "Portal Recall"
desc = "This will teleport you back to your previously used portal. One use only."
clothes_req = FALSE
action_icon_state = "blink"
var/list/recall_portals = list()
/obj/effect/proc_holder/spell/portal_recall/Click(mob/user = usr)
if(!recall_portals.len)
user.mind.RemoveSpell(src) // remove spell if no portals left
var/obj/effect/portal/permanent/one_way/recall/last_portal = recall_portals[recall_portals.len]
var/turf/recall_turf = get_turf(last_portal)
if(recall_turf)
if(last_portal.recall_equipment && ishuman(user))
var/mob/living/carbon/human/H = user
H.delete_equipment()
H.equipOutfit(last_portal.recall_equipment)
last_portal.recall_effect(user)
if(user)
do_teleport(user, recall_turf, 0, no_effects = FALSE, channel = TELEPORT_CHANNEL_BLUESPACE)
recall_portals -= last_portal
if(!recall_portals.len)
user.mind.RemoveSpell(src) // remove spell if no portals left
/obj/effect/mob_spawn/human/virtual_reality
name = "Network Relay"
desc = "A machine with flashing buttons. It seems to be some sort of teleportation pad. There doesn't seem to be any way to activate it from this side."
mob_name = "Virtual Reality Human"
icon = 'icons/obj/telescience.dmi'
icon_state = "qpad-idle"
density = FALSE
roundstart = FALSE
death = FALSE
uses = -1 // infinite
random = TRUE
mob_type = /mob/living/carbon/human/virtual_reality
outfit = /datum/outfit/vr
flavour_text = "<span class='big bold'>You have connected to another stations virtual reality system</span>\n\
<b>You have been assigned a mission by nanotrasen to increase productivity in a station that lacks any and all teamwork.\n\
Your objective is to help other people by completing tasks, whether social or combatative, together, while also improving your own skills.</b>"
assignedrole = "Vr"
/obj/effect/portal/permanent/one_way/recall/murderdome
name = "Murderdome Portal"
desc = "Active, but only occasionally. Leads to an endless battle arena."
equipment = /datum/outfit/death_commando
recall_equipment = /datum/outfit/vr
id = "vr murderdome"
light_color = LIGHT_COLOR_FIRE
light_power = 1
light_range = 3
/obj/effect/portal/permanent/one_way/destroy/murderdome
name = "Murderdome Exit Portal"
id = "vr murderdome"
/obj/effect/portal/permanent/one_way/recall/syndicate
name = "Syndicate Portal"
desc = "Active, but only occasionally. Leads to a syndicate training program."
equipment = /datum/outfit/vr/syndicate
recall_equipment = /datum/outfit/vr
id = "vr syndicate"
light_color = LIGHT_COLOR_FIRE
light_power = 1
light_range = 3
/obj/effect/portal/permanent/one_way/recall/syndicate/recall_effect(mob/user)
// fuck this im not dealing with you fucks smuggling equipment out of the syndicate uplink
user.dust()
return
/obj/effect/portal/permanent/one_way/destroy/syndicate
name = "Syndicate Exit Portal"
id = "vr syndicate"
/obj/effect/portal/permanent/one_way/recall/snowdin
name = "Snowdin Portal"
desc = "Active, but only occasionally. Leads to a snowed in wasteland."
equipment = /datum/outfit/vr/snowtide
recall_equipment = /datum/outfit/vr
id = "vr snowdin"
light_color = LIGHT_COLOR_FIRE
light_power = 1
light_range = 3
/obj/effect/portal/permanent/one_way/destroy/snowdin
name = "Snowdin Exit Portal"
id = "vr snowdin"
/obj/effect/light_emitter/vr_hub
set_luminosity = 9
set_cap = 2.5
light_color = LIGHT_COLOR_WHITE
/turf/closed/indestructible/iron
name = "rough metal wall"
desc = "A wall with rough metal plating."
icon = 'icons/turf/walls/iron_wall.dmi'
icon_state = "iron"
canSmoothWith = list(/turf/closed/indestructible/iron)