Files
Bubberstation/code/modules/bitrunning/event.dm
Jeremiah a3849062b8 Feature: bitrunner, a new supply role (READY) (#77259)
## About The Pull Request
[Design doc](https://hackmd.io/@shadowh4nd/r1P7atPjn) 

Adds a new supply role centered on short dungeon-esque runs with a focus
on unifying the job with the fun part. Some virtual domains are combat
related, some are silly, some focus on "objectives". Avatar health is
linked to your physical presence and retries are limited.


<details>
<summary>Photos, WIP</summary>

Net pod stasis

![netpod](https://github.com/tgstation/tgstation/assets/42397676/d99073a4-2438-4600-83c0-cafb7b3fee55)

Server loaded

![](https://cdn.discordapp.com/attachments/1131433451841662996/1135304774976278759/dreamseeker_N14j6dwLcK.gif)

Server cooldown

![](https://cdn.discordapp.com/attachments/1131433451841662996/1135304775945179217/dreamseeker_NkIwWLJZma.gif)

the quantum console UI
![Screenshot 2023-08-05
105742](https://github.com/tgstation/tgstation/assets/42397676/3a45feaf-8c80-46b2-81c9-355932d1b014)

Cyber police antag page
![Screenshot 2023-08-16
205303](https://github.com/tgstation/tgstation/assets/42397676/fc28bcdd-2a2a-487b-927c-904f224c1b89)

A safehouse

![image](https://github.com/tgstation/tgstation/assets/42397676/c22ac115-4e00-432a-aeeb-b6afdb1ef750)

Domain info page, every domain gets this (and sometimes help text)
![Screenshot 2023-08-04
141859](https://github.com/tgstation/tgstation/assets/42397676/ba9ed6d9-a318-4466-b246-d2da0fa05676)

Me getting steamrolled in one of the missions

![syndicant](https://github.com/tgstation/tgstation/assets/42397676/3eb3099a-f9b2-4431-854d-50d8cad9b7f0)

Ghost roles getting notified that server is kicking them out
![Screenshot 2023-08-04
135454](https://github.com/tgstation/tgstation/assets/42397676/edab916c-6255-4b83-b2e7-155df2f03aab)

Players enjoying the new combat missions
![Screenshot 2023-08-05
005727](https://github.com/tgstation/tgstation/assets/42397676/e302a66f-610d-4fe1-82e0-7c8aec3913ea)

Players exploring some of the virtual maps
![Screenshot 2023-08-06
220919](https://github.com/tgstation/tgstation/assets/42397676/75a92a0b-6aa1-4bac-8fd1-c9fb47c955da)

(Not part of the PR, but)
![Screenshot 2023-08-06
221527](https://github.com/tgstation/tgstation/assets/42397676/012475ec-bfa5-4fd3-9dcb-31d222bb7bef)

New bitrunner vendor

![dreamseeker_V62h2BGdEl](https://github.com/tgstation/tgstation/assets/42397676/37ca8f69-f75e-45c9-b324-e6b31696c7b7)

</details>

## Why It's Good For The Game
Content, firstly, and moreso being supply department content.

The framework that this implements is a great (preauthorized)
replacement for two systems which are collecting dust: BEPIS and the
gateway. They integrate into this system and it's a direct upgrade.

This adds a way for the players on station to generate materials (if
that remains). The nice part about it is that I can throw balance and
believability to the wind, as unlike its unrelated predecessor VR or
away missions, bitrunning entirely washes its hands of the map and mobs
each reboot.

It offers a very expandable map framework to add content and it's all
fairly well documented.

I'd like to add a feature that represents the idea that jobs don't have
to be mundane and "external" jobs can stay tied to the main gameplay
loop.

## Changelog
jlsnow301, kinneb, mmmiracles, ical92, spockye
🆑
add: Adds Bitrunning to supply department- a semi-offstation role that
rewards teamwork.
add: Adds new machines to complement the job- net pod, quantum server,
quantum consoles, and the nexacache vendor.
add: Adds several new maps which can be loaded and unloaded at will.
add: Some flair for the new bitrunning vendor.
add: Adds a new antagonist for the virtual domain only. Short lived
ghost role that fights bitrunners.
del: Removes the BEPIS machine, moves its tech into the Bitrunning
vendor.
/🆑

<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->

---------

Co-authored-by: MMMiracles <lolaccount1@hotmail.com>
Co-authored-by: Ical <wolfsgamingtips@gmail.com>
Co-authored-by: spockye <79304582+spockye@users.noreply.github.com>
Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com>
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
2023-09-23 11:14:12 +02:00

152 lines
5.0 KiB
Plaintext

/datum/round_event_control/bitrunning_glitch
name = "Spawn Bitrunning Glitch"
admin_setup = list(
/datum/event_admin_setup/minimum_candidate_requirement/bitrunning_glitch,
/datum/event_admin_setup/listed_options/bitrunning_glitch,
)
category = EVENT_CATEGORY_INVASION
description = "Causes a short term antagonist to spawn in the virtual domain."
dynamic_should_hijack = FALSE
max_occurrences = 5
min_players = 1
typepath = /datum/round_event/ghost_role/bitrunning_glitch
weight = 10
/// List of active servers to choose from
var/list/obj/machinery/quantum_server/active_servers = list()
/// List of possible antags to spawn
var/static/list/possible_antags = list(
ROLE_CYBER_POLICE,
)
/datum/round_event_control/bitrunning_glitch/can_spawn_event(players_amt, allow_magic = FALSE)
. = ..()
if(!.)
return .
active_servers.Cut()
get_active_servers()
if(length(active_servers))
return TRUE
/// All servers currently running, has players in it, and map has valid mobs
/datum/round_event_control/bitrunning_glitch/proc/get_active_servers()
for(var/obj/machinery/quantum_server/server in SSmachines.get_machines_by_type(/obj/machinery/quantum_server))
if(length(server.get_valid_domain_targets()))
active_servers.Add(server)
return length(active_servers) > 0
/datum/event_admin_setup/listed_options/bitrunning_glitch
input_text = "Select a role to spawn."
/datum/event_admin_setup/listed_options/bitrunning_glitch/get_list()
var/datum/round_event_control/bitrunning_glitch/control = event_control
var/list/possible = control.possible_antags.Copy() // this seems pedantic but byond is complaining control was unused
possible += list("Random")
return possible
/datum/event_admin_setup/listed_options/bitrunning_glitch/apply_to_event(datum/round_event/ghost_role/bitrunning_glitch/event)
if(chosen == "Random")
event.forced_role = null
else
event.forced_role = chosen
/datum/event_admin_setup/minimum_candidate_requirement/bitrunning_glitch
output_text = "There must be valid mobs to mutate or players in the domain!"
/datum/event_admin_setup/minimum_candidate_requirement/bitrunning_glitch/count_candidates()
var/datum/round_event_control/bitrunning_glitch/cyber_control = event_control
cyber_control.get_active_servers()
var/total = 0
for(var/obj/machinery/quantum_server/server in cyber_control.active_servers)
total += length(server.mutation_candidate_refs)
return total
/datum/round_event/ghost_role/bitrunning_glitch
minimum_required = 1
role_name = "Bitrunning Glitch"
fakeable = FALSE
/// Admin customization: What to spawn
var/forced_role
/datum/round_event/ghost_role/bitrunning_glitch/spawn_role()
var/datum/round_event_control/bitrunning_glitch/cyber_control = control
var/obj/machinery/quantum_server/unlucky_server = pick(cyber_control.active_servers)
cyber_control.active_servers.Cut()
var/list/mutation_candidates = unlucky_server.get_valid_domain_targets()
if(!length(mutation_candidates))
return MAP_ERROR
var/chosen = pick(mutation_candidates)
if(isnull(chosen) || !length(mutation_candidates))
return MAP_ERROR
var/datum/weakref/target_ref = pick(mutation_candidates)
var/mob/living/mutation_target = target_ref.resolve()
if(isnull(mutation_target)) // just in case since it takes a minute
target_ref = pick(mutation_candidates)
mutation_target = target_ref.resolve()
if(isnull(mutation_target))
return MAP_ERROR
var/chosen_role = forced_role || pick(cyber_control.possible_antags)
var/datum/mind/ghost_mind = get_ghost_mind(chosen_role)
if(isnull(ghost_mind))
return NOT_ENOUGH_PLAYERS
var/mob/living/antag_mob
switch(chosen_role)
if(ROLE_CYBER_POLICE)
antag_mob = spawn_cybercop(mutation_target, ghost_mind)
playsound(antag_mob, 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1)
message_admins("[ADMIN_LOOKUPFLW(antag_mob)] has been made into virtual antagonist by an event.")
antag_mob.log_message("was spawned as a virtual antagonist by an event.", LOG_GAME)
SEND_SIGNAL(unlucky_server, COMSIG_BITRUNNER_SPAWN_GLITCH, antag_mob)
spawned_mobs += antag_mob
return SUCCESSFUL_SPAWN
/// Polls for a ghost that wants to run it
/datum/round_event/ghost_role/bitrunning_glitch/proc/get_ghost_mind(role_name)
var/list/mob/dead/observer/ghosties = poll_ghost_candidates("A short term antagonist role is available. Would you like to spawn as a '[role_name]'?", role_name)
if(!length(ghosties))
return
shuffle_inplace(ghosties)
var/mob/dead/selected = pick(ghosties)
var/datum/mind/player_mind = new /datum/mind(selected.key)
player_mind.active = TRUE
return player_mind
/// Spawns a cybercop on the mutation target
/datum/round_event/ghost_role/bitrunning_glitch/proc/spawn_cybercop(mob/living/mutation_target, datum/mind/player_mind)
var/mob/living/carbon/human/new_agent = new(mutation_target.loc)
mutation_target.gib()
mutation_target = null
player_mind.transfer_to(new_agent)
player_mind.set_assigned_role(SSjob.GetJobType(/datum/job/cyber_police))
player_mind.special_role = ROLE_CYBER_POLICE
player_mind.add_antag_datum(/datum/antagonist/cyber_police)
return new_agent