diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index a77d6c29ccc..da2b76853da 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -150,3 +150,43 @@ #define MASSDRIVER_CHAPEL "chapelgun" #define MASSDRIVER_DISPOSALS "trash" #define MASSDRIVER_SHACK "shack" + +//orion game states +#define ORION_STATUS_START 0 +#define ORION_STATUS_INSTRUCTIONS 1 +#define ORION_STATUS_NORMAL 2 +#define ORION_STATUS_GAMEOVER 3 +#define ORION_STATUS_MARKET 4 + +//orion delays (how many turns an action costs) +#define ORION_SHORT_DELAY 2 +#define ORION_LONG_DELAY 6 + +//starting orion crew count +#define ORION_STARTING_CREW_COUNT 4 + +//orion food to fuel / fuel to food conversion rate +#define ORION_TRADE_RATE 5 + +//and whether you want fuel or food +#define ORION_I_WANT_FUEL 1 +#define ORION_I_WANT_FOOD 2 + +//orion price of buying pioneer +#define ORION_BUY_CREW_PRICE 10 + +//...and selling one (its less because having less pioneers is actually not that bad) +#define ORION_SELL_CREW_PRICE 7 + +//defining the magic numbers sent by tgui +#define ORION_BUY_ENGINE_PARTS 1 +#define ORION_BUY_ELECTRONICS 2 +#define ORION_BUY_HULL_PARTS 3 + +//orion gaming record (basically how worried it is that you're a deranged gunk gamer) +//game gives up on trying to help you +#define ORION_GAMER_GIVE_UP -2 +//game spawns a pamphlet, post report +#define ORION_GAMER_PAMPHLET -1 +//game begins to have a chance to warn sec and med +#define ORION_GAMER_REPORT_THRESHOLD 2 diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm deleted file mode 100644 index bb6188ad3a1..00000000000 --- a/code/game/machinery/computer/arcade.dm +++ /dev/null @@ -1,1588 +0,0 @@ -GLOBAL_LIST_INIT(arcade_prize_pool, list( - /obj/item/storage/box/snappops = 2, - /obj/item/toy/talking/ai = 2, - /obj/item/toy/talking/codex_gigas = 2, - /obj/item/clothing/under/syndicate/tacticool = 2, - /obj/item/toy/sword = 2, - /obj/item/toy/gun = 2, - /obj/item/gun/ballistic/shotgun/toy/crossbow = 2, - /obj/item/storage/box/fakesyndiesuit = 2, - /obj/item/storage/crayons = 2, - /obj/item/toy/spinningtoy = 2, - /obj/item/toy/balloon/arrest = 2, - /obj/item/toy/prize/ripley = 1, - /obj/item/toy/prize/fireripley = 1, - /obj/item/toy/prize/deathripley = 1, - /obj/item/toy/prize/gygax = 1, - /obj/item/toy/prize/durand = 1, - /obj/item/toy/prize/honk = 1, - /obj/item/toy/prize/marauder = 1, - /obj/item/toy/prize/seraph = 1, - /obj/item/toy/prize/mauler = 1, - /obj/item/toy/prize/odysseus = 1, - /obj/item/toy/prize/phazon = 1, - /obj/item/toy/prize/reticence = 1, - /obj/item/toy/prize/clarke = 1, - /obj/item/toy/cards/deck = 2, - /obj/item/toy/nuke = 2, - /obj/item/toy/minimeteor = 2, - /obj/item/toy/redbutton = 2, - /obj/item/toy/talking/owl = 2, - /obj/item/toy/talking/griffin = 2, - /obj/item/coin/antagtoken = 2, - /obj/item/stack/tile/fakespace/loaded = 2, - /obj/item/stack/tile/fakepit/loaded = 2, - /obj/item/stack/tile/eighties/loaded = 2, - /obj/item/toy/toy_xeno = 2, - /obj/item/storage/box/actionfigure = 1, - /obj/item/restraints/handcuffs/fake = 2, - /obj/item/grenade/chem_grenade/glitter/pink = 1, - /obj/item/grenade/chem_grenade/glitter/blue = 1, - /obj/item/grenade/chem_grenade/glitter/white = 1, - /obj/item/toy/eightball = 2, - /obj/item/toy/windup_toolbox = 2, - /obj/item/toy/clockwork_watch = 2, - /obj/item/toy/toy_dagger = 2, - /obj/item/extendohand/acme = 1, - /obj/item/hot_potato/harmless/toy = 1, - /obj/item/card/emagfake = 1, - /obj/item/clothing/shoes/wheelys = 2, - /obj/item/clothing/shoes/kindle_kicks = 2, - /obj/item/toy/plush/goatplushie = 2, - /obj/item/toy/plush/moth = 2, - /obj/item/toy/plush/pkplush = 2, - /obj/item/storage/belt/military/snack = 2, - /obj/item/toy/brokenradio = 2, - /obj/item/toy/braintoy = 2, - /obj/item/toy/eldritch_book = 2, - /obj/item/storage/box/heretic_box = 1, - /obj/item/toy/foamfinger = 2, - /obj/item/clothing/glasses/trickblindfold = 2)) - -/obj/machinery/computer/arcade - name = "random arcade" - desc = "random arcade machine" - icon_state = "arcade" - icon_keyboard = "no_keyboard" - icon_screen = "invaders" - light_color = LIGHT_COLOR_GREEN - var/list/prize_override - -/obj/machinery/computer/arcade/proc/Reset() - return - -/obj/machinery/computer/arcade/Initialize() - . = ..() - - Reset() - -/obj/machinery/computer/arcade/proc/prizevend(mob/user, prizes = 1) - SEND_SIGNAL(user, COMSIG_ARCADE_PRIZEVEND, user, prizes) - if(user.mind?.get_skill_level(/datum/skill/gaming) >= SKILL_LEVEL_LEGENDARY && HAS_TRAIT(user, TRAIT_GAMERGOD)) - visible_message("[user] inputs an intense cheat code!",\ - "You hear a flurry of buttons being pressed.") - say("CODE ACTIVATED: EXTRA PRIZES.") - prizes *= 2 - for(var/i = 0, i < prizes, i++) - SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "arcade", /datum/mood_event/arcade) - if(prob(0.0001)) //1 in a million - new /obj/item/gun/energy/pulse/prize(src) - visible_message("[src] dispenses.. woah, a gun! Way past cool.", "You hear a chime and a shot.") - user.client.give_award(/datum/award/achievement/misc/pulse, user) - return - - var/prizeselect - if(prize_override) - prizeselect = pickweight(prize_override) - else - prizeselect = pickweight(GLOB.arcade_prize_pool) - var/atom/movable/the_prize = new prizeselect(get_turf(src)) - playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) - visible_message("[src] dispenses [the_prize]!", "You hear a chime and a clunk.") - -/obj/machinery/computer/arcade/emp_act(severity) - . = ..() - var/override = FALSE - if(prize_override) - override = TRUE - - if(machine_stat & (NOPOWER|BROKEN) || . & EMP_PROTECT_SELF) - return - - var/empprize = null - var/num_of_prizes = 0 - switch(severity) - if(1) - num_of_prizes = rand(1,4) - if(2) - num_of_prizes = rand(0,2) - for(var/i = num_of_prizes; i > 0; i--) - if(override) - empprize = pickweight(prize_override) - else - empprize = pickweight(GLOB.arcade_prize_pool) - new empprize(loc) - explosion(loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes) - -/obj/machinery/computer/arcade/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/stack/arcadeticket)) - var/obj/item/stack/arcadeticket/T = O - var/amount = T.get_amount() - if(amount <2) - to_chat(user, "You need 2 tickets to claim a prize!") - return - prizevend(user) - T.pay_tickets() - T.update_appearance() - O = T - to_chat(user, "You turn in 2 tickets to the [src] and claim a prize!") - return - -// ** BATTLE ** // -/obj/machinery/computer/arcade/battle - name = "arcade machine" - desc = "Does not support Pinball." - icon_state = "arcade" - circuit = /obj/item/circuitboard/computer/arcade/battle - - var/enemy_name = "Space Villain" - ///Enemy health/attack points - var/enemy_hp = 100 - var/enemy_mp = 40 - ///Temporary message, for attack messages, etc - var/temp = "

Winners don't use space drugs

" - ///the list of passive skill the enemy currently has. the actual passives are added in the enemy_setup() proc - var/list/enemy_passive - ///if all the enemy's weakpoints have been triggered becomes TRUE - var/finishing_move = FALSE - ///linked to passives, when it's equal or above the max_passive finishing move will become TRUE - var/pissed_off = 0 - ///the number of passives the enemy will start with - var/max_passive = 3 - ///weapon wielded by the enemy, the shotgun doesn't count. - var/chosen_weapon - - ///Player health - var/player_hp = 85 - ///player magic points - var/player_mp = 20 - ///used to remember the last three move of the player before this turn. - var/list/last_three_move - ///if the enemy or player died. restart the game when TRUE - var/gameover = FALSE - ///the player cannot make any move while this is set to TRUE. should only TRUE during enemy turns. - var/blocked = FALSE - ///used to clear the enemy_action proc timer when the game is restarted - var/timer_id - ///weapon used by the enemy, pure fluff.for certain actions - var/list/weapons - ///unique to the emag mode, acts as a time limit where the player dies when it reaches 0. - var/bomb_cooldown = 19 - - -///creates the enemy base stats for a new round along with the enemy passives -/obj/machinery/computer/arcade/battle/proc/enemy_setup(player_skill) - player_hp = 85 - player_mp = 20 - enemy_hp = 100 - enemy_mp = 40 - gameover = FALSE - blocked = FALSE - finishing_move = FALSE - pissed_off = 0 - last_three_move = null - - enemy_passive = list("short_temper" = TRUE, "poisonous" = TRUE, "smart" = TRUE, "shotgun" = TRUE, "magical" = TRUE, "chonker" = TRUE) - for(var/i = LAZYLEN(enemy_passive); i > max_passive; i--) //we'll remove passives from the list until we have the number of passive we want - var/picked_passive = pick(enemy_passive) - LAZYREMOVE(enemy_passive, picked_passive) - - if(LAZYACCESS(enemy_passive, "chonker")) - enemy_hp += 20 - - if(LAZYACCESS(enemy_passive, "shotgun")) - chosen_weapon = "shotgun" - else if(weapons) - chosen_weapon = pick(weapons) - else - chosen_weapon = "null gun" //if the weapons list is somehow empty, shouldn't happen but runtimes are sneaky bastards. - - if(player_skill) - player_hp += player_skill * 2 - - -/obj/machinery/computer/arcade/battle/Reset() - max_passive = 3 - var/name_action - var/name_part1 - var/name_part2 - - if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) - name_action = pick_list(ARCADE_FILE, "rpg_action_halloween") - name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_halloween") - name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_halloween") - weapons = strings(ARCADE_FILE, "rpg_weapon_halloween") - else if(SSevents.holidays && SSevents.holidays[CHRISTMAS]) - name_action = pick_list(ARCADE_FILE, "rpg_action_xmas") - name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_xmas") - name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_xmas") - weapons = strings(ARCADE_FILE, "rpg_weapon_xmas") - else if(SSevents.holidays && SSevents.holidays[VALENTINES]) - name_action = pick_list(ARCADE_FILE, "rpg_action_valentines") - name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_valentines") - name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_valentines") - weapons = strings(ARCADE_FILE, "rpg_weapon_valentines") - else - name_action = pick_list(ARCADE_FILE, "rpg_action") - name_part1 = pick_list(ARCADE_FILE, "rpg_adjective") - name_part2 = pick_list(ARCADE_FILE, "rpg_enemy") - weapons = strings(ARCADE_FILE, "rpg_weapon") - - enemy_name = ("The " + name_part1 + " " + name_part2) - name = (name_action + " " + enemy_name) - - enemy_setup(0) //in the case it's reset we assume the player skill is 0 because the VOID isn't a gamer - - -/obj/machinery/computer/arcade/battle/ui_interact(mob/user) - . = ..() - screen_setup(user) - - -///sets up the main screen for the user -/obj/machinery/computer/arcade/battle/proc/screen_setup(mob/user) - var/dat = "Close" - dat += "

[enemy_name]

" - - dat += "[temp]" - dat += "
Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]
" - - if (gameover) - dat += "
New Game" - else - dat += "
Light attack" - dat += "
Defend" - dat += "
Counter attack" - dat += "
Power attack" - - dat += "
" - if(user.client) //mainly here to avoid a runtime when the player gets gibbed when losing the emag mode. - var/datum/browser/popup = new(user, "arcade", "Space Villain 2000") - popup.set_content(dat) - popup.open() - - -/obj/machinery/computer/arcade/battle/Topic(href, href_list) - if(..()) - return - var/gamerSkill = 0 - if(usr?.mind) - gamerSkill = usr.mind.get_skill_level(/datum/skill/gaming) - - if (!blocked && !gameover) - var/attackamt = rand(5,7) + rand(0, gamerSkill) - - if(finishing_move) //time to bonk that fucker,cuban pete will sometime survive a finishing move. - attackamt *= 100 - - //light attack suck absolute ass but it doesn't cost any MP so it's pretty good to finish an enemy off - if (href_list["attack"]) - temp = "

you do quick jab for [attackamt] of damage!

" - enemy_hp -= attackamt - arcade_action(usr,"attack",attackamt) - - //defend lets you gain back MP and take less damage from non magical attack. - else if(href_list["defend"]) - temp = "

you take a defensive stance and gain back 10 mp!

" - player_mp += 10 - arcade_action(usr,"defend",attackamt) - playsound(src, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3) - - //mainly used to counter short temper and their absurd damage, will deal twice the damage the player took of a non magical attack. - else if(href_list["counter_attack"] && player_mp >= 10) - temp = "

you prepare yourself to counter the next attack!

" - player_mp -= 10 - arcade_action(usr,"counter_attack",attackamt) - playsound(src, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3) - - else if(href_list["counter_attack"] && player_mp < 10) - temp = "

you don't have the mp necessary to counter attack and defend yourself instead

" - player_mp += 10 - arcade_action(usr,"defend",attackamt) - playsound(src, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3) - - //power attack deals twice the amount of damage but is really expensive MP wise, mainly used with combos to get weakpoints. - else if (href_list["power_attack"] && player_mp >= 20) - temp = "

You attack [enemy_name] with all your might for [attackamt * 2] damage!

" - enemy_hp -= attackamt * 2 - player_mp -= 20 - arcade_action(usr,"power_attack",attackamt) - - else if(href_list["power_attack"] && player_mp < 20) - temp = "

You don't have the mp necessary for a power attack and settle for a light attack!

" - enemy_hp -= attackamt - arcade_action(usr,"attack",attackamt) - - if (href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") - - else if (href_list["newgame"]) //Reset everything - temp = "

New Round

" - - if(obj_flags & EMAGGED) - Reset() - obj_flags &= ~EMAGGED - - enemy_setup(gamerSkill) - screen_setup(usr) - - - add_fingerprint(usr) - updateUsrDialog() - return - - -///happens after a player action and before the enemy turn. the enemy turn will be cancelled if there's a gameover. -/obj/machinery/computer/arcade/battle/proc/arcade_action(mob/user,player_stance,attackamt) - screen_setup(user) - blocked = TRUE - if(player_stance == "attack" || player_stance == "power_attack") - if(attackamt > 40) - playsound(src, 'sound/arcade/boom.ogg', 50, TRUE, extrarange = -3) - else - playsound(src, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3) - - timer_id = addtimer(CALLBACK(src, .proc/enemy_action,player_stance,user),1 SECONDS,TIMER_STOPPABLE) - gameover_check(user) - - -///the enemy turn, the enemy's action entirely depend on their current passive and a teensy tiny bit of randomness -/obj/machinery/computer/arcade/battle/proc/enemy_action(player_stance,mob/user) - var/list/list_temp = list() - - switch(LAZYLEN(last_three_move)) //we keep the last three action of the player in a list here - if(0 to 2) - LAZYADD(last_three_move, player_stance) - if(3) - for(var/i in 1 to 2) - last_three_move[i] = last_three_move[i + 1] - last_three_move[3] = player_stance - - if(4 to INFINITY) - last_three_move = null //this shouldn't even happen but we empty the list if it somehow goes above 3 - - var/enemy_stance - var/attack_amount = rand(8,10) //making the attack amount not vary too much so that it's easier to see if the enemy has a shotgun - - if(player_stance == "defend") - attack_amount -= 5 - - //if emagged, cuban pete will set up a bomb acting up as a timer. when it reaches 0 the player fucking dies - if(obj_flags & EMAGGED) - switch(bomb_cooldown--) - if(18) - list_temp += "

[enemy_name] takes two valve tank and links them together, what's he planning?

" - if(15) - list_temp += "

[enemy_name] adds a remote control to the tan- ho god is that a bomb?

" - if(12) - list_temp += "

[enemy_name] throws the bomb next to you, you'r too scared to pick it up.

" - if(6) - list_temp += "

[enemy_name]'s hand brushes the remote linked to the bomb, your heart skipped a beat.

" - if(2) - list_temp += "

[enemy_name] is going to press the button! It's now or never!

" - if(0) - player_hp -= attack_amount * 1000 //hey it's a maxcap we might as well go all in - - //yeah I used the shotgun as a passive, you know why? because the shotgun gives +5 attack which is pretty good - if(LAZYACCESS(enemy_passive, "shotgun")) - if(weakpoint_check("shotgun","defend","defend","power_attack")) - list_temp += "

You manage to disarm [enemy_name] with a surprise power attack and shoot him with his shotgun until it runs out of ammo!

" - enemy_hp -= 10 - chosen_weapon = "empty shotgun" - else - attack_amount += 5 - - //heccing chonker passive, only gives more HP at the start of a new game but has one of the hardest weakpoint to trigger. - if(LAZYACCESS(enemy_passive, "chonker")) - if(weakpoint_check("chonker","power_attack","power_attack","power_attack")) - list_temp += "

After a lot of power attacks you manage to tip over [enemy_name] as they fall over their enormous weight

" - enemy_hp -= 30 - - //smart passive trait, mainly works in tandem with other traits, makes the enemy unable to be counter_attacked - if(LAZYACCESS(enemy_passive, "smart")) - if(weakpoint_check("smart","defend","defend","attack")) - list_temp += "

[enemy_name] is confused by your illogical strategy!

" - attack_amount -= 5 - - else if(attack_amount >= player_hp) - player_hp -= attack_amount - list_temp += "

[enemy_name] figures out you are really close to death and finishes you off with their [chosen_weapon]!

" - enemy_stance = "attack" - - else if(player_stance == "counter_attack") - list_temp += "

[enemy_name] is not taking your bait.

" - if(LAZYACCESS(enemy_passive, "short_temper")) - list_temp += "However controlling their hatred of you still takes a toll on their mental and physical health!" - enemy_hp -= 5 - enemy_mp -= 5 - enemy_stance = "defensive" - - //short temper passive trait, gets easily baited into being counter attacked but will bypass your counter when low on HP - if(LAZYACCESS(enemy_passive, "short_temper")) - if(weakpoint_check("short_temper","counter_attack","counter_attack","counter_attack")) - list_temp += "

[enemy_name] is getting frustrated at all your counter attacks and throws a tantrum!

" - enemy_hp -= attack_amount - - else if(player_stance == "counter_attack") - if(!(LAZYACCESS(enemy_passive, "smart")) && enemy_hp > 30) - list_temp += "

[enemy_name] took the bait and allowed you to counter attack for [attack_amount * 2] damage!

" - player_hp -= attack_amount - enemy_hp -= attack_amount * 2 - enemy_stance = "attack" - - else if(enemy_hp <= 30) //will break through the counter when low enough on HP even when smart. - list_temp += "

[enemy_name] is getting tired of your tricks and breaks through your counter with their [chosen_weapon]!

" - player_hp -= attack_amount - enemy_stance = "attack" - - else if(!enemy_stance) - var/added_temp - - if(rand()) - added_temp = "you for [attack_amount + 5] damage!" - player_hp -= attack_amount + 5 - enemy_stance = "attack" - else - added_temp = "the wall, breaking their skull in the process and losing [attack_amount] hp!" //[enemy_name] you have a literal dent in your skull - enemy_hp -= attack_amount - enemy_stance = "attack" - - list_temp += "

[enemy_name] grits their teeth and charge right into [added_temp]

" - - //in the case none of the previous passive triggered, Mainly here to set an enemy stance for passives that needs it like the magical passive. - if(!enemy_stance) - enemy_stance = pick("attack","defensive") - if(enemy_stance == "attack") - player_hp -= attack_amount - list_temp += "

[enemy_name] attacks you for [attack_amount] points of damage with their [chosen_weapon]

" - if(player_stance == "counter_attack") - enemy_hp -= attack_amount * 2 - list_temp += "

You counter [enemy_name]'s attack and deal [attack_amount * 2] points of damage!

" - - if(enemy_stance == "defensive" && enemy_mp < 15) - list_temp += "

[enemy_name] take some time to get some mp back!

" - enemy_mp += attack_amount - - else if (enemy_stance == "defensive" && enemy_mp >= 15 && !(LAZYACCESS(enemy_passive, "magical"))) - list_temp += "

[enemy_name] quickly heal themselves for 5 hp!

" - enemy_mp -= 15 - enemy_hp += 5 - - //magical passive trait, recharges MP nearly every turn it's not blasting you with magic. - if(LAZYACCESS(enemy_passive, "magical")) - if(player_mp >= 50) - list_temp += "

the huge amount of magical energy you have acumulated throws [enemy_name] off balance!

" - enemy_mp = 0 - LAZYREMOVE(enemy_passive, "magical") - pissed_off++ - - else if(LAZYACCESS(enemy_passive, "smart") && player_stance == "counter_attack" && enemy_mp >= 20) - list_temp += "

[enemy_name] blasts you with magic from afar for 10 points of damage before you can counter!

" - player_hp -= 10 - enemy_mp -= 20 - - else if(enemy_hp >= 20 && enemy_mp >= 40 && enemy_stance == "defensive") - list_temp += "

[enemy_name] Blasts you with magic from afar!

" - enemy_mp -= 40 - player_hp -= 30 - enemy_stance = "attack" - - else if(enemy_hp < 20 && enemy_mp >= 20 && enemy_stance == "defensive") //it's a pretty expensive spell so they can't spam it that much - list_temp += "

[enemy_name] heal themselves with magic and gain back 20 hp!

" - enemy_hp += 20 - enemy_mp -= 30 - else - list_temp += "

[enemy_name]'s magical nature lets them get some mp back!

" - enemy_mp += attack_amount - - //poisonous passive trait, while it's less damage added than the shotgun it acts up even when the enemy doesn't attack at all. - if(LAZYACCESS(enemy_passive, "poisonous")) - if(weakpoint_check("poisonous","attack","attack","attack")) - list_temp += "

your flurry of attack throws back the poisonnous gas at [enemy_name] and makes them choke on it!

" - enemy_hp -= 5 - else - list_temp += "

the stinky breath of [enemy_name] hurts you for 3 hp!

" - player_hp -= 3 - - //if all passive's weakpoint have been triggered, set finishing_move to TRUE - if(pissed_off >= max_passive && !finishing_move) - list_temp += "

You have weakened [enemy_name] enough for them to show their weak point, you will do 10 times as much damage with your next attack!

" - finishing_move = TRUE - - playsound(src, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3) - - temp = list_temp.Join() - gameover_check(user) - screen_setup(user) - blocked = FALSE - - -/obj/machinery/computer/arcade/battle/proc/gameover_check(mob/user) - var/xp_gained = 0 - if(enemy_hp <= 0) - if(!gameover) - if(timer_id) - deltimer(timer_id) - timer_id = null - if(player_hp <= 0) - player_hp = 1 //let's just pretend the enemy didn't kill you so not both the player and enemy look dead. - gameover = TRUE - blocked = FALSE - temp = "

[enemy_name] has fallen! Rejoice!

" - playsound(loc, 'sound/arcade/win.ogg', 50, TRUE) - - if(obj_flags & EMAGGED) - new /obj/effect/spawner/newbomb/timer/syndicate(loc) - new /obj/item/clothing/head/collectable/petehat(loc) - message_admins("[ADMIN_LOOKUPFLW(usr)] has outbombed Cuban Pete and been awarded a bomb.") - log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.") - Reset() - obj_flags &= ~EMAGGED - xp_gained += 100 - else - prizevend(user) - xp_gained += 50 - SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("win", (obj_flags & EMAGGED ? "emagged":"normal"))) - - else if(player_hp <= 0) - if(timer_id) - deltimer(timer_id) - timer_id = null - gameover = TRUE - temp = "

You have been crushed! GAME OVER

" - playsound(loc, 'sound/arcade/lose.ogg', 50, TRUE) - xp_gained += 10//pity points - if(obj_flags & EMAGGED) - var/mob/living/living_user = user - if (istype(living_user)) - living_user.gib() - SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal"))) - - if(gameover) - user?.mind?.adjust_experience(/datum/skill/gaming, xp_gained+1)//always gain at least 1 point of XP - - -///used to check if the last three move of the player are the one we want in the right order and if the passive's weakpoint has been triggered yet -/obj/machinery/computer/arcade/battle/proc/weakpoint_check(passive,first_move,second_move,third_move) - if(LAZYLEN(last_three_move) < 3) - return FALSE - - if(last_three_move[1] == first_move && last_three_move[2] == second_move && last_three_move[3] == third_move && LAZYACCESS(enemy_passive, passive)) - LAZYREMOVE(enemy_passive, passive) - pissed_off++ - return TRUE - else - return FALSE - - -/obj/machinery/computer/arcade/battle/Destroy() - enemy_passive = null - weapons = null - last_three_move = null - return ..() //well boys we did it, lists are no more - -/obj/machinery/computer/arcade/battle/examine_more(mob/user) - var/list/msg = list("You notice some writing scribbled on the side of [src]...") - msg += "\tsmart -> defend, defend, light attack" - msg += "\tshotgun -> defend, defend, power attack" - msg += "\tshort temper -> counter, counter, counter" - msg += "\tpoisonous -> light attack, light attack, light attack" - msg += "\tchonker -> power attack, power attack, power attack" - return msg - -/obj/machinery/computer/arcade/battle/emag_act(mob/user) - if(obj_flags & EMAGGED) - return - - to_chat(user, "A mesmerizing Rhumba beat starts playing from the arcade machine's speakers!") - temp = "

If you die in the game, you die for real!

" - max_passive = 6 - bomb_cooldown = 18 - var/gamerSkill = 0 - if(usr?.mind) - gamerSkill = usr.mind.get_skill_level(/datum/skill/gaming) - enemy_setup(gamerSkill) - enemy_hp += 100 //extra HP just to make cuban pete even more bullshit - player_hp += 30 //the player will also get a few extra HP in order to have a fucking chance - - screen_setup(user) - gameover = FALSE - - obj_flags |= EMAGGED - - enemy_name = "Cuban Pete" - name = "Outbomb Cuban Pete" - - updateUsrDialog() - - -// *** THE ORION TRAIL ** // - -#define ORION_TRAIL_WINTURN 9 - -//Orion Trail Events -#define ORION_TRAIL_RAIDERS "Raiders" -#define ORION_TRAIL_FLUX "Interstellar Flux" -#define ORION_TRAIL_ILLNESS "Illness" -#define ORION_TRAIL_BREAKDOWN "Breakdown" -#define ORION_TRAIL_LING "Changelings?" -#define ORION_TRAIL_LING_ATTACK "Changeling Ambush" -#define ORION_TRAIL_MALFUNCTION "Malfunction" -#define ORION_TRAIL_COLLISION "Collision" -#define ORION_TRAIL_SPACEPORT "Spaceport" -#define ORION_TRAIL_BLACKHOLE "BlackHole" -#define ORION_TRAIL_OLDSHIP "Old Ship" -#define ORION_TRAIL_SEARCH "Old Ship Search" - -#define ORION_STATUS_START 1 -#define ORION_STATUS_NORMAL 2 -#define ORION_STATUS_GAMEOVER 3 -#define ORION_STATUS_MARKET 4 - -/obj/machinery/computer/arcade/orion_trail - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - icon_state = "arcade" - circuit = /obj/item/circuitboard/computer/arcade/orion_trail - var/busy = FALSE //prevent clickspam that allowed people to ~speedrun~ the game. - var/engine = 0 - var/hull = 0 - var/electronics = 0 - var/food = 80 - var/fuel = 60 - var/turns = 4 - var/alive = 4 - var/eventdat = null - var/event = null - var/list/settlers = list("Harry","Larry","Bob") - var/list/events = list(ORION_TRAIL_RAIDERS = 3, - ORION_TRAIL_FLUX = 1, - ORION_TRAIL_ILLNESS = 3, - ORION_TRAIL_BREAKDOWN = 2, - ORION_TRAIL_LING = 3, - ORION_TRAIL_MALFUNCTION = 2, - ORION_TRAIL_COLLISION = 1, - ORION_TRAIL_SPACEPORT = 2, - ORION_TRAIL_OLDSHIP = 2 - ) - var/list/stops = list() - var/list/stopblurbs = list() - var/lings_aboard = 0 - var/spaceport_raided = 0 - var/spaceport_freebie = 0 - var/last_spaceport_action = "" - var/gameStatus = ORION_STATUS_START - var/canContinueEvent = 0 - - var/obj/item/radio/Radio - var/list/gamers = list() - var/killed_crew = 0 - - -/obj/machinery/computer/arcade/orion_trail/Initialize() - . = ..() - Radio = new /obj/item/radio(src) - Radio.listening = 0 - -/obj/machinery/computer/arcade/orion_trail/Destroy() - QDEL_NULL(Radio) - return ..() - -/obj/machinery/computer/arcade/orion_trail/kobayashi - name = "Kobayashi Maru control computer" - desc = "A test for cadets" - icon = 'icons/obj/machines/particle_accelerator.dmi' - icon_state = "control_boxp" - events = list("Raiders" = 3, "Interstellar Flux" = 1, "Illness" = 3, "Breakdown" = 2, "Malfunction" = 2, "Collision" = 1, "Spaceport" = 2) - prize_override = list(/obj/item/paper/fluff/holodeck/trek_diploma = 1) - settlers = list("Kirk","Worf","Gene") - -/obj/machinery/computer/arcade/orion_trail/Reset() - // Sets up the main trail - stops = list("Pluto","Asteroid Belt","Proxima Centauri","Dead Space","Rigel Prime","Tau Ceti Beta","Black Hole","Space Outpost Beta-9","Orion Prime") - stopblurbs = list( - "Pluto, long since occupied with long-range sensors and scanners, stands ready to, and indeed continues to probe the far reaches of the galaxy.", - "At the edge of the Sol system lies a treacherous asteroid belt. Many have been crushed by stray asteroids and misguided judgement.", - "The nearest star system to Sol, in ages past it stood as a reminder of the boundaries of sub-light travel, now a low-population sanctuary for adventurers and traders.", - "This region of space is particularly devoid of matter. Such low-density pockets are known to exist, but the vastness of it is astounding.", - "Rigel Prime, the center of the Rigel system, burns hot, basking its planetary bodies in warmth and radiation.", - "Tau Ceti Beta has recently become a waypoint for colonists headed towards Orion. There are many ships and makeshift stations in the vicinity.", - "Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through. We could stay of course, but risk of being overcome by its gravity, or we could change course to go around, which will take longer.", - "You have come into range of the first man-made structure in this region of space. It has been constructed not by travellers from Sol, but by colonists from Orion. It stands as a monument to the colonists' success.", - "You have made it to Orion! Congratulations! Your crew is one of the few to start a new foothold for mankind!" - ) - -/obj/machinery/computer/arcade/orion_trail/proc/newgame() - // Set names of settlers in crew - settlers = list() - for(var/i = 1; i <= 3; i++) - add_crewmember() - add_crewmember("[usr]") - // Re-set items to defaults - engine = 1 - hull = 1 - electronics = 1 - food = 80 - fuel = 60 - alive = 4 - turns = 1 - event = null - gameStatus = ORION_STATUS_NORMAL - lings_aboard = 0 - killed_crew = 0 - - //spaceport junk - spaceport_raided = 0 - spaceport_freebie = 0 - last_spaceport_action = "" - -/obj/machinery/computer/arcade/orion_trail/proc/report_player(mob/gamer) - if(gamers[gamer] == -2) - return // enough harassing them - - if(gamers[gamer] == -1) - say("WARNING: Continued antisocial behavior detected: Dispensing self-help literature.") - new /obj/item/paper/pamphlet/violent_video_games(drop_location()) - gamers[gamer]-- - return - - if(!(gamer in gamers)) - gamers[gamer] = 0 - - gamers[gamer]++ // How many times the player has 'prestiged' (massacred their crew) - - if(gamers[gamer] > 2 && prob(20 * gamers[gamer])) - - Radio.set_frequency(FREQ_SECURITY) - Radio.talk_into(src, "SECURITY ALERT: Crewmember [gamer] recorded displaying antisocial tendencies in [get_area(src)]. Please watch for violent behavior.", FREQ_SECURITY) - - Radio.set_frequency(FREQ_MEDICAL) - Radio.talk_into(src, "PSYCH ALERT: Crewmember [gamer] recorded displaying antisocial tendencies in [get_area(src)]. Please schedule psych evaluation.", FREQ_MEDICAL) - - gamers[gamer] = -1 - - gamer.client.give_award(/datum/award/achievement/misc/gamer, gamer) // PSYCH REPORT NOTE: patient kept rambling about how they did it for an "achievement", recommend continued holding for observation - gamer.mind?.adjust_experience(/datum/skill/gaming, 50) // cheevos make u better - - if(!isnull(GLOB.data_core.general)) - for(var/datum/data/record/R in GLOB.data_core.general) - if(R.fields["name"] == gamer.name) - R.fields["m_stat"] = "*Unstable*" - return - -/obj/machinery/computer/arcade/orion_trail/ui_interact(mob/_user) - . = ..() - if (!isliving(_user)) - return - var/mob/living/user = _user - if(fuel <= 0 || food <=0 || settlers.len == 0) - gameStatus = ORION_STATUS_GAMEOVER - event = null - var/dat = "" - if(gameStatus == ORION_STATUS_GAMEOVER) - dat = "

Game Over

" - dat += "Like many before you, your crew never made it to Orion, lost to space...
Forever." - if(!settlers.len) - dat += "
Your entire crew died, and your ship joins the fleet of ghost-ships littering the galaxy." - else - if(food <= 0) - dat += "
You ran out of food and starved." - if(obj_flags & EMAGGED) - user.set_nutrition(0) //yeah you pretty hongry - to_chat(user, "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.") - if(fuel <= 0) - dat += "
You ran out of fuel, and drift, slowly, into a star." - if(obj_flags & EMAGGED) - var/mob/living/M = user - M.adjust_fire_stacks(5) - M.IgniteMob() //flew into a star, so you're on fire - to_chat(user, "You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames.") - - if(obj_flags & EMAGGED) - to_chat(user, "You're never going to make it to Orion...") - user.death() - obj_flags &= ~EMAGGED //removes the emagged status after you lose - gameStatus = ORION_STATUS_START - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - - dat += "

May They Rest In Peace

" - user?.mind?.adjust_experience(/datum/skill/gaming, 10)//learning from your mistakes is the first rule of roguelikes - - else if(event) - dat = eventdat - else if(gameStatus == ORION_STATUS_NORMAL) - var/title = stops[turns] - var/subtext = stopblurbs[turns] - dat = "

[title]

" - dat += "[subtext]" - dat += "

Crew:

" - dat += english_list(settlers) - dat += "
Food: [food] | Fuel: [fuel]" - dat += "
Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" - if(turns == 7) - dat += "

Go Around Continue

" - else - dat += "

Continue

" - dat += "

Kill a Crewmember

" - dat += "

Close

" - else - dat = "

The Orion Trail

" - dat += "

Experience the journey of your ancestors!



" - dat += "
New Game
" - dat += "

Close

" - var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700) - popup.set_content(dat) - popup.open() - return - -/obj/machinery/computer/arcade/orion_trail/Topic(href, href_list) - if(..()) - return - if(href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") - - if(busy) - return - busy = TRUE - - var/gamerSkillLevel = 0 - var/gamerSkill = 0 - var/gamerSkillRands = 0 - - if(usr?.mind) - gamerSkillLevel = usr.mind.get_skill_level(/datum/skill/gaming) - gamerSkill = usr.mind.get_skill_modifier(/datum/skill/gaming, SKILL_PROBS_MODIFIER) - gamerSkillRands = usr.mind.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER) - - - var/xp_gained = 0 - if (href_list["continue"]) //Continue your travels - if(gameStatus == ORION_STATUS_NORMAL && !event && turns != 7) - if(turns >= ORION_TRAIL_WINTURN) - win(usr) - xp_gained += 34 - else - food -= (alive+lings_aboard)*2 - fuel -= 5 - if(turns == 2 && prob(30-gamerSkill)) - event = ORION_TRAIL_COLLISION - event() - else if(prob(75-gamerSkill)) - event = pickweight(events) - if(lings_aboard) - if(event == ORION_TRAIL_LING || prob(55-gamerSkill)) - event = ORION_TRAIL_LING_ATTACK - event() - turns += 1 - if(obj_flags & EMAGGED) - var/mob/living/carbon/M = usr //for some vars - switch(event) - if(ORION_TRAIL_RAIDERS) - if(prob(50-gamerSkill)) - to_chat(usr, "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?") - M.hallucination += 30 - else - to_chat(usr, "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...") - M.take_bodypart_damage(30) - playsound(loc, 'sound/weapons/genhit2.ogg', 100, TRUE) - if(ORION_TRAIL_ILLNESS) - var/maxSeverity = 3 - if(gamerSkillLevel >= SKILL_LEVEL_EXPERT) - maxSeverity = 2 //part of gitting gud is rng mitigation - var/severity = rand(1,maxSeverity) //pray to RNGesus. PRAY, PIGS - if(severity == 1) - to_chat(M, "You suddenly feel slightly nauseated." ) - if(severity == 2) - to_chat(usr, "You suddenly feel extremely nauseated and hunch over until it passes.") - M.Stun(60) - if(severity >= 3) //you didn't pray hard enough - to_chat(M, "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.") - M.Stun(100) - sleep(30) - M.vomit(10, distance = 5) - if(ORION_TRAIL_FLUX) - if(prob(75-gamerSkill)) - M.Paralyze(60) - say("A sudden gust of powerful wind slams [M] into the floor!") - M.take_bodypart_damage(25) - playsound(loc, 'sound/weapons/genhit.ogg', 100, TRUE) - else - to_chat(M, "A violent gale blows past you, and you barely manage to stay standing!") - if(ORION_TRAIL_COLLISION) //by far the most damaging event - if(prob(90-gamerSkill)) - playsound(loc, 'sound/effects/bang.ogg', 100, TRUE) - var/turf/open/floor/F - for(F in orange(1, src)) - F.ScrapeAway() - say("Something slams into the floor around [src], exposing it to space!") - if(hull) - sleep(10) - say("A new floor suddenly appears around [src]. What the hell?") - playsound(loc, 'sound/weapons/genhit.ogg', 100, TRUE) - var/turf/open/space/T - for(T in orange(1, src)) - T.PlaceOnTop(/turf/open/floor/plating) - else - say("Something slams into the floor around [src] - luckily, it didn't get through!") - playsound(loc, 'sound/effects/bang.ogg', 50, TRUE) - if(ORION_TRAIL_MALFUNCTION) - playsound(loc, 'sound/effects/empulse.ogg', 50, TRUE) - visible_message("[src] malfunctions, randomizing in-game stats!") - var/oldfood = food - var/oldfuel = fuel - food = rand(10,80) / rand(1,2) - fuel = rand(10,60) / rand(1,2) - if(electronics) - sleep(10) - if(oldfuel > fuel && oldfood > food) - audible_message("[src] lets out a somehow reassuring chime.") - else if(oldfuel < fuel || oldfood < food) - audible_message("[src] lets out a somehow ominous chime.") - food = oldfood - fuel = oldfuel - playsound(loc, 'sound/machines/chime.ogg', 50, TRUE) - - else if(href_list["newgame"]) //Reset everything - if(gameStatus == ORION_STATUS_START) - newgame() - else if(href_list["menu"]) //back to the main menu - if(gameStatus == ORION_STATUS_GAMEOVER) - gameStatus = ORION_STATUS_START - event = null - food = 80 - fuel = 60 - settlers = list("Harry","Larry","Bob") - else if(href_list["search"]) //search old ship - if(event == ORION_TRAIL_OLDSHIP) - event = ORION_TRAIL_SEARCH - event() - else if(href_list["slow"]) //slow down - if(event == ORION_TRAIL_FLUX) - food -= (alive+lings_aboard)*2 - fuel -= 5 - event = null - else if(href_list["pastblack"]) //slow down - if(turns == 7) - food -= ((alive+lings_aboard)*2)*3 - fuel -= 15 - turns += 1 - event = null - else if(href_list["useengine"]) //use parts - if(event == ORION_TRAIL_BREAKDOWN) - engine = max(0, --engine) - event = null - else if(href_list["useelec"]) //use parts - if(event == ORION_TRAIL_MALFUNCTION) - electronics = max(0, --electronics) - event = null - else if(href_list["usehull"]) //use parts - if(event == ORION_TRAIL_COLLISION) - hull = max(0, --hull) - event = null - else if(href_list["wait"]) //wait 3 days - if(event == ORION_TRAIL_BREAKDOWN || event == ORION_TRAIL_MALFUNCTION || event == ORION_TRAIL_COLLISION) - food -= ((alive+lings_aboard)*2)*3 - event = null - else if(href_list["keepspeed"]) //keep speed - if(event == ORION_TRAIL_FLUX) - if(prob(75)) - event = "Breakdown" - event() - else - event = null - else if(href_list["blackhole"]) //keep speed past a black hole - if(turns == 7) - if(prob(75-gamerSkill)) - event = ORION_TRAIL_BLACKHOLE - event() - if(obj_flags & EMAGGED) - playsound(loc, 'sound/effects/supermatter.ogg', 100, TRUE) - say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!") - if(isliving(usr)) - var/mob/living/L = usr - L.Stun(200, ignore_canstun = TRUE) //you can't run :^) - var/S = new /obj/singularity/academy(usr.loc) - addtimer(CALLBACK(src, /atom/movable/proc/say, "[S] winks out, just as suddenly as it appeared."), 50) - QDEL_IN(S, 50) - else - event = null - turns += 1 - else if(href_list["holedeath"]) - if(event == ORION_TRAIL_BLACKHOLE) - gameStatus = ORION_STATUS_GAMEOVER - event = null - else if(href_list["eventclose"]) //end an event - if(canContinueEvent) - event = null - - else if(href_list["killcrew"]) //shoot a crewmember - if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_LING) - var/sheriff = remove_crewmember() //I shot the sheriff - playsound(loc,'sound/weapons/gun/pistol/shot.ogg', 100, TRUE) - killed_crew++ - - var/mob/living/user = usr - - if(settlers.len == 0 || alive == 0) - say("The last crewmember [sheriff], shot themselves, GAME OVER!") - if(obj_flags & EMAGGED) - user.death() - gameStatus = ORION_STATUS_GAMEOVER - event = null - - if(killed_crew >= 4) - xp_gained -= 15//no cheating by spamming game overs - report_player(usr) - else if(obj_flags & EMAGGED) - if(usr.name == sheriff) - say("The crew of the ship chose to kill [usr.name]!") - user.death() - - if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places - event = null - killed_crew-- // the kill was valid - - //Spaceport specific interactions - //they get a header because most of them don't reset event (because it's a shop, you leave when you want to) - //they also call event() again, to regen the eventdata, which is kind of odd but necessary - else if(href_list["buycrew"]) //buy a crewmember - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided && food >= 10 && fuel >= 10) - var/bought = add_crewmember() - last_spaceport_action = "You hired [bought] as a new crewmember." - fuel -= 10 - food -= 10 - event() - killed_crew-- // I mean not really but you know - - else if(href_list["sellcrew"]) //sell a crewmember - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided && settlers.len > 1) - var/sold = remove_crewmember() - last_spaceport_action = "You sold your crewmember, [sold]!" - fuel += 7 - food += 7 - event() - - else if(href_list["leave_spaceport"]) - if(gameStatus == ORION_STATUS_MARKET) - event = null - gameStatus = ORION_STATUS_NORMAL - spaceport_raided = 0 - spaceport_freebie = 0 - last_spaceport_action = "" - - else if(href_list["raid_spaceport"]) - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided) - var/success = min(15 * alive + gamerSkill,100) //default crew (4) have a 60% chance - spaceport_raided = 1 - - var/FU = 0 - var/FO = 0 - if(prob(success)) - FU = rand(5 + gamerSkillRands,15 + gamerSkillRands) - FO = rand(5 + gamerSkillRands,15 + gamerSkillRands) - last_spaceport_action = "You successfully raided the spaceport! You gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)" - xp_gained += 10 - else - FU = rand(-5,-15) - FO = rand(-5,-15) - last_spaceport_action = "You failed to raid the spaceport! You lost [FU*-1] Fuel and [FO*-1] Food in your scramble to escape! ([FU]FU,[FO]FO)" - - //your chance of lose a crewmember is 1/2 your chance of success - //this makes higher % failures hurt more, don't get cocky space cowboy! - if(prob(success*5)) - var/lost_crew = remove_crewmember() - last_spaceport_action = "You failed to raid the spaceport! You lost [FU*-1] Fuel and [FO*-1] Food, AND [lost_crew] in your scramble to escape! ([FU]FI,[FO]FO,-Crew)" - if(obj_flags & EMAGGED) - say("WEEWOO! WEEWOO! Spaceport security en route!") - playsound(src, 'sound/items/weeoo1.ogg', 100, FALSE) - for(var/i, i<=3, i++) - var/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion(get_turf(src)) - O.target = usr - - - fuel += FU - food += FO - event() - - else if(href_list["buyparts"]) - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided && fuel > 5) - switch(text2num(href_list["buyparts"])) - if(1) //Engine Parts - engine++ - last_spaceport_action = "Bought Engine Parts" - if(2) //Hull Plates - hull++ - last_spaceport_action = "Bought Hull Plates" - if(3) //Spare Electronics - electronics++ - last_spaceport_action = "Bought Spare Electronics" - fuel -= 5 //they all cost 5 - event() - - else if(href_list["trade"]) - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided) - switch(text2num(href_list["trade"])) - if(1) //Fuel - if(fuel > 5) - fuel -= 5 - food += 5 - last_spaceport_action = "Traded Fuel for Food" - event() - if(2) //Food - if(food > 5) - fuel += 5 - food -= 5 - last_spaceport_action = "Traded Food for Fuel" - event() - - add_fingerprint(usr) - updateUsrDialog() - busy = FALSE - usr?.mind?.adjust_experience(/datum/skill/gaming, xp_gained+1) - - -/obj/machinery/computer/arcade/orion_trail/proc/event() - eventdat = "

[event]

" - canContinueEvent = 0 - switch(event) - if(ORION_TRAIL_RAIDERS) - eventdat += "Raiders have come aboard your ship!" - if(prob(50)) - var/sfood = rand(1,10) - var/sfuel = rand(1,10) - food -= sfood - fuel -= sfuel - eventdat += "
They have stolen [sfood] Food and [sfuel] Fuel." - else if(prob(10)) - var/deadname = remove_crewmember() - eventdat += "
[deadname] tried to fight back, but was killed." - else - eventdat += "
Fortunately, you fended them off without any trouble." - eventdat += "

Continue

" - eventdat += "

Close

" - canContinueEvent = 1 - - if(ORION_TRAIL_FLUX) - eventdat += "This region of space is highly turbulent.
If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." - eventdat += "
What will you do?" - eventdat += "

Slow Down Continue

" - eventdat += "

Close

" - - if(ORION_TRAIL_OLDSHIP) - eventdat += "
Your crew spots an old ship floating through space. It might have some supplies, but then again it looks rather unsafe." - eventdat += "

Search itLeave it

Close

" - canContinueEvent = 1 - - if(ORION_TRAIL_SEARCH) - switch(rand(100)) - if(0 to 15) - var/rescued = add_crewmember() - var/oldfood = rand(1,7) - var/oldfuel = rand(4,10) - food += oldfood - fuel += oldfuel - eventdat += "
As you look through it you find some supplies and a living person!" - eventdat += "
[rescued] was rescued from the abandoned ship!" - eventdat += "
You found [oldfood] Food and [oldfuel] Fuel." - if(15 to 35) - var/lfuel = rand(4,7) - var/deadname = remove_crewmember() - fuel -= lfuel - eventdat += "
[deadname] was lost deep in the wreckage, and your own vessel lost [lfuel] Fuel maneuvering to the the abandoned ship." - if(35 to 65) - var/oldfood = rand(5,11) - food += oldfood - engine++ - eventdat += "
You found [oldfood] Food and some parts amongst the wreck." - else - eventdat += "
As you look through the wreck you cannot find much of use." - eventdat += "

Continue

" - eventdat += "

Close

" - canContinueEvent = 1 - - if(ORION_TRAIL_ILLNESS) - eventdat += "A deadly illness has been contracted!" - var/deadname = remove_crewmember() - eventdat += "
[deadname] was killed by the disease." - eventdat += "

Continue

" - eventdat += "

Close

" - canContinueEvent = 1 - - if(ORION_TRAIL_BREAKDOWN) - eventdat += "Oh no! The engine has broken down!" - eventdat += "
You can repair it with an engine part, or you can make repairs for 3 days." - if(engine >= 1) - eventdat += "

Use PartWait

" - else - eventdat += "

Wait

" - eventdat += "

Close

" - - if(ORION_TRAIL_MALFUNCTION) - eventdat += "The ship's systems are malfunctioning!" - eventdat += "
You can replace the broken electronics with spares, or you can spend 3 days troubleshooting the AI." - if(electronics >= 1) - eventdat += "

Use PartWait

" - else - eventdat += "

Wait

" - eventdat += "

Close

" - - if(ORION_TRAIL_COLLISION) - eventdat += "Something hit us! Looks like there's some hull damage." - if(prob(25)) - var/sfood = rand(5,15) - var/sfuel = rand(5,15) - food -= sfood - fuel -= sfuel - eventdat += "
[sfood] Food and [sfuel] Fuel was vented out into space." - if(prob(10)) - var/deadname = remove_crewmember() - eventdat += "
[deadname] was killed by rapid depressurization." - eventdat += "
You can repair the damage with hull plates, or you can spend the next 3 days welding scrap together." - if(hull >= 1) - eventdat += "

Use PartWait

" - else - eventdat += "

Wait

" - eventdat += "

Close

" - - if(ORION_TRAIL_BLACKHOLE) - eventdat += "You were swept away into the black hole." - eventdat += "

Oh...

" - eventdat += "

Close

" - settlers = list() - - if(ORION_TRAIL_LING) - eventdat += "Strange reports warn of changelings infiltrating crews on trips to Orion..." - if(settlers.len <= 2) - eventdat += "
Your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..." - eventdat += "

Continue

" - eventdat += "

Close

" - if(prob(10)) // "likely", I didn't say it was guaranteed! - lings_aboard = min(++lings_aboard,2) - else - if(lings_aboard) //less likely to stack lings - if(prob(20)) - lings_aboard = min(++lings_aboard,2) - else if(prob(70)) - lings_aboard = min(++lings_aboard,2) - - eventdat += "

Kill a Crewmember

" - eventdat += "

Risk it

" - eventdat += "

Close

" - canContinueEvent = 1 - - if(ORION_TRAIL_LING_ATTACK) - if(lings_aboard <= 0) //shouldn't trigger, but hey. - eventdat += "Haha, fooled you, there are no changelings on board!" - eventdat += "
(You should report this to a coder :S)" - else - var/ling1 = remove_crewmember() - var/ling2 = "" - if(lings_aboard >= 2) - ling2 = remove_crewmember() - - eventdat += "Changelings among your crew suddenly burst from hiding and attack!" - if(ling2) - eventdat += "
[ling1] and [ling2]'s arms twist and contort into grotesque blades!" - else - eventdat += "
[ling1]'s arm twists and contorts into a grotesque blade!" - - var/chance2attack = alive*20 - if(prob(chance2attack)) - var/chancetokill = 30*lings_aboard-(5*alive) //eg: 30*2-(10) = 50%, 2 lings, 2 crew is 50% chance - if(prob(chancetokill)) - var/deadguy = remove_crewmember() - var/murder_text = pick("The changeling[ling2 ? "s" : ""] bring[ling2 ? "" : "s"] down [deadguy] and disembowel[ling2 ? "" : "s"] them in a spray of gore!", \ - "[ling2 ? pick(ling1, ling2) : ling1] corners [deadguy] and impales them through the stomach!", \ - "[ling2 ? pick(ling1, ling2) : ling1] decapitates [deadguy] in a single cleaving arc!") - eventdat += "
[murder_text]" - else - eventdat += "

You valiantly fight off the changeling[ling2 ? "s":""]!" - if(ling2) - food += 30 - lings_aboard = max(0,lings_aboard-2) - else - food += 15 - lings_aboard = max(0,--lings_aboard) - eventdat += "
Well, it's perfectly good food...\ -
You cut the changeling[ling2 ? "s" : ""] into meat, gaining [ling2 ? "30" : "15"] Food!" - else - eventdat += "

[pick("Sensing unfavorable odds", "After a failed attack", "Suddenly breaking nerve")], \ - the changeling[ling2 ? "s":""] vanish[ling2 ? "" : "es"] into space through the airlocks! You're safe... for now." - if(ling2) - lings_aboard = max(0,lings_aboard-2) - else - lings_aboard = max(0,--lings_aboard) - - eventdat += "

Continue

" - eventdat += "

Close

" - canContinueEvent = 1 - - - if(ORION_TRAIL_SPACEPORT) - gameStatus = ORION_STATUS_MARKET - if(spaceport_raided) - eventdat += "The spaceport is on high alert! You've been barred from docking by the local authorities after your failed raid." - if(last_spaceport_action) - eventdat += "
Last Spaceport Action: [last_spaceport_action]" - eventdat += "

Depart Spaceport

" - eventdat += "

Close

" - else - eventdat += "Your jump into the sector yields a spaceport - a lucky find!" - eventdat += "
This spaceport is home to travellers who failed to reach Orion, but managed to find a different home..." - eventdat += "
Trading terms: FU = Fuel, FO = Food" - if(last_spaceport_action) - eventdat += "
Last action: [last_spaceport_action]" - eventdat += "

Crew:

" - eventdat += english_list(settlers) - eventdat += "
Food: [food] | Fuel: [fuel]" - eventdat += "
Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" - - - //If your crew is pathetic you can get freebies (provided you haven't already gotten one from this port) - if(!spaceport_freebie && (fuel < 20 || food < 20)) - spaceport_freebie++ - var/FU = 10 - var/FO = 10 - var/freecrew = 0 - if(prob(30)) - FU = 25 - FO = 25 - - if(prob(10)) - add_crewmember() - freecrew++ - - eventdat += "
The traders of the spaceport take pity on you, and generously give you some free supplies! (+[FU]FU, +[FO]FO)" - if(freecrew) - eventdat += "
You also gain a new crewmember!" - - fuel += FU - food += FO - - //CREW INTERACTIONS - eventdat += "

Crew Management:

" - - //Buy crew - if(food >= 10 && fuel >= 10) - eventdat += "

Hire a New Crewmember (-10FU, -10FO)

" - else - eventdat += "

You cannot afford a new crewmember.

" - - //Sell crew - if(settlers.len > 1) - eventdat += "

Sell Crew for Fuel and Food (+7FU, +7FO)

" - else - eventdat += "

You have no other crew to sell.

" - - //BUY/SELL STUFF - eventdat += "

Spare Parts:

" - - //Engine parts - if(fuel > 5) - eventdat += "

Buy Engine Parts (-5FU)

" - else - eventdat += "

You cannot afford engine parts." - - //Hull plates - if(fuel > 5) - eventdat += "

Buy Hull Plates (-5FU)

" - else - eventdat += "

You cannot afford hull plates." - - //Electronics - if(fuel > 5) - eventdat += "

Buy Spare Electronics (-5FU)

" - else - eventdat += "

You cannot afford spare electronics." - - //Trade - if(fuel > 5) - eventdat += "

Trade Fuel for Food (-5FU,+5FO)

" - else - eventdat += "

You don't have 5FU to trade. 5) - eventdat += "

Trade Food for Fuel (+5FU,-5FO)

" - else - eventdat += "

You don't have 5FO to trade.You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.") - name = "The Orion Trail: Realism Edition" - desc = "Learn how our ancestors got to Orion, and try not to die in the process!" - newgame() - obj_flags |= EMAGGED - -/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion - name = "spaceport security" - desc = "Premier corporate security forces for all spaceports found along the Orion Trail." - faction = list("orion") - loot = list() - del_on_death = TRUE - -/obj/item/orion_ship - name = "model settler ship" - desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." - icon = 'icons/obj/toy.dmi' - icon_state = "ship" - w_class = WEIGHT_CLASS_SMALL - var/active = 0 //if the ship is on - -/obj/item/orion_ship/examine(mob/user) - . = ..() - if(!(in_range(user, src))) - return - if(!active) - . += "There's a little switch on the bottom. It's flipped down." - else - . += "There's a little switch on the bottom. It's flipped up." - -/obj/item/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse - if(active) - return - - log_bomber(usr, "primed an explosive", src, "for detonation") - - to_chat(user, "You flip the switch on the underside of [src].") - active = 1 - visible_message("[src] softly beeps and whirs to life!") - playsound(loc, 'sound/machines/defib_SaftyOn.ogg', 25, TRUE) - say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") - sleep(20) - visible_message("[src] begins to vibrate...") - say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") - sleep(30) - say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") - playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, TRUE) - sleep(3.6) - visible_message("[src] explodes!") - explosion(loc, 2,4,8, flame_range = 16) - qdel(src) - -// ** AMPUTATION ** // - -/obj/machinery/computer/arcade/amputation - name = "Mediborg's Amputation Adventure" - desc = "A picture of a blood-soaked medical cyborg flashes on the screen. The mediborg has a speech bubble that says, \"Put your hand in the machine if you aren't a coward!\"" - icon_state = "arcade" - circuit = /obj/item/circuitboard/computer/arcade/amputation - -/obj/machinery/computer/arcade/amputation/attack_hand(mob/user, list/modifiers) - if(!iscarbon(user)) - return - var/mob/living/carbon/c_user = user - if(!c_user.get_bodypart(BODY_ZONE_L_ARM) && !c_user.get_bodypart(BODY_ZONE_R_ARM)) - return - to_chat(c_user, "You move your hand towards the machine, and begin to hesitate as a bloodied guillotine emerges from inside of it...") - if(do_after(c_user, 50, target = src)) - to_chat(c_user, "The guillotine drops on your arm, and the machine sucks it in!") - playsound(loc, 'sound/weapons/slice.ogg', 25, TRUE, -1) - var/which_hand = BODY_ZONE_L_ARM - if(!(c_user.active_hand_index % 2)) - which_hand = BODY_ZONE_R_ARM - var/obj/item/bodypart/chopchop = c_user.get_bodypart(which_hand) - chopchop.dismember() - qdel(chopchop) - user.mind?.adjust_experience(/datum/skill/gaming, 100) - playsound(loc, 'sound/arcade/win.ogg', 50, TRUE) - prizevend(user, rand(3,5)) - else - to_chat(c_user, "You (wisely) decide against putting your hand in the machine.") - -/obj/machinery/computer/arcade/amputation/festive //dispenses wrapped gifts instead of arcade prizes, also known as the ancap christmas tree - name = "Mediborg's Festive Amputation Adventure" - desc = "A picture of a blood-soaked medical cyborg wearing a Santa hat flashes on the screen. The mediborg has a speech bubble that says, \"Put your hand in the machine if you aren't a coward!\"" - prize_override = list(/obj/item/a_gift/anything = 1) - -#undef ORION_TRAIL_WINTURN -#undef ORION_TRAIL_RAIDERS -#undef ORION_TRAIL_FLUX -#undef ORION_TRAIL_ILLNESS -#undef ORION_TRAIL_BREAKDOWN -#undef ORION_TRAIL_LING -#undef ORION_TRAIL_LING_ATTACK -#undef ORION_TRAIL_MALFUNCTION -#undef ORION_TRAIL_COLLISION -#undef ORION_TRAIL_SPACEPORT -#undef ORION_TRAIL_BLACKHOLE -#undef ORION_TRAIL_OLDSHIP -#undef ORION_TRAIL_SEARCH - -#undef ORION_STATUS_START -#undef ORION_STATUS_NORMAL -#undef ORION_STATUS_GAMEOVER -#undef ORION_STATUS_MARKET diff --git a/code/game/machinery/computer/arcade/arcade.dm b/code/game/machinery/computer/arcade/arcade.dm new file mode 100644 index 00000000000..74ad9b711e3 --- /dev/null +++ b/code/game/machinery/computer/arcade/arcade.dm @@ -0,0 +1,661 @@ +GLOBAL_LIST_INIT(arcade_prize_pool, list( + /obj/item/storage/box/snappops = 2, + /obj/item/toy/talking/ai = 2, + /obj/item/toy/talking/codex_gigas = 2, + /obj/item/clothing/under/syndicate/tacticool = 2, + /obj/item/toy/sword = 2, + /obj/item/toy/gun = 2, + /obj/item/gun/ballistic/shotgun/toy/crossbow = 2, + /obj/item/storage/box/fakesyndiesuit = 2, + /obj/item/storage/crayons = 2, + /obj/item/toy/spinningtoy = 2, + /obj/item/toy/balloon/arrest = 2, + /obj/item/toy/prize/ripley = 1, + /obj/item/toy/prize/fireripley = 1, + /obj/item/toy/prize/deathripley = 1, + /obj/item/toy/prize/gygax = 1, + /obj/item/toy/prize/durand = 1, + /obj/item/toy/prize/honk = 1, + /obj/item/toy/prize/marauder = 1, + /obj/item/toy/prize/seraph = 1, + /obj/item/toy/prize/mauler = 1, + /obj/item/toy/prize/odysseus = 1, + /obj/item/toy/prize/phazon = 1, + /obj/item/toy/prize/reticence = 1, + /obj/item/toy/prize/clarke = 1, + /obj/item/toy/cards/deck = 2, + /obj/item/toy/nuke = 2, + /obj/item/toy/minimeteor = 2, + /obj/item/toy/redbutton = 2, + /obj/item/toy/talking/owl = 2, + /obj/item/toy/talking/griffin = 2, + /obj/item/coin/antagtoken = 2, + /obj/item/stack/tile/fakespace/loaded = 2, + /obj/item/stack/tile/fakepit/loaded = 2, + /obj/item/stack/tile/eighties/loaded = 2, + /obj/item/toy/toy_xeno = 2, + /obj/item/storage/box/actionfigure = 1, + /obj/item/restraints/handcuffs/fake = 2, + /obj/item/grenade/chem_grenade/glitter/pink = 1, + /obj/item/grenade/chem_grenade/glitter/blue = 1, + /obj/item/grenade/chem_grenade/glitter/white = 1, + /obj/item/toy/eightball = 2, + /obj/item/toy/windup_toolbox = 2, + /obj/item/toy/clockwork_watch = 2, + /obj/item/toy/toy_dagger = 2, + /obj/item/extendohand/acme = 1, + /obj/item/hot_potato/harmless/toy = 1, + /obj/item/card/emagfake = 1, + /obj/item/clothing/shoes/wheelys = 2, + /obj/item/clothing/shoes/kindle_kicks = 2, + /obj/item/toy/plush/goatplushie = 2, + /obj/item/toy/plush/moth = 2, + /obj/item/toy/plush/pkplush = 2, + /obj/item/storage/belt/military/snack = 2, + /obj/item/toy/brokenradio = 2, + /obj/item/toy/braintoy = 2, + /obj/item/toy/eldritch_book = 2, + /obj/item/storage/box/heretic_box = 1, + /obj/item/toy/foamfinger = 2, + /obj/item/clothing/glasses/trickblindfold = 2)) + +/obj/machinery/computer/arcade + name = "random arcade" + desc = "random arcade machine" + icon_state = "arcade" + icon_keyboard = "no_keyboard" + icon_screen = "invaders" + light_color = LIGHT_COLOR_GREEN + var/list/prize_override + +/obj/machinery/computer/arcade/proc/Reset() + return + +/obj/machinery/computer/arcade/Initialize() + . = ..() + + Reset() + +/obj/machinery/computer/arcade/proc/prizevend(mob/user, prizes = 1) + SEND_SIGNAL(user, COMSIG_ARCADE_PRIZEVEND, user, prizes) + if(user.mind?.get_skill_level(/datum/skill/gaming) >= SKILL_LEVEL_LEGENDARY && HAS_TRAIT(user, TRAIT_GAMERGOD)) + visible_message("[user] inputs an intense cheat code!",\ + "You hear a flurry of buttons being pressed.") + say("CODE ACTIVATED: EXTRA PRIZES.") + prizes *= 2 + for(var/i = 0, i < prizes, i++) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "arcade", /datum/mood_event/arcade) + if(prob(0.0001)) //1 in a million + new /obj/item/gun/energy/pulse/prize(src) + visible_message("[src] dispenses.. woah, a gun! Way past cool.", "You hear a chime and a shot.") + user.client.give_award(/datum/award/achievement/misc/pulse, user) + return + + var/prizeselect + if(prize_override) + prizeselect = pickweight(prize_override) + else + prizeselect = pickweight(GLOB.arcade_prize_pool) + var/atom/movable/the_prize = new prizeselect(get_turf(src)) + playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) + visible_message("[src] dispenses [the_prize]!", "You hear a chime and a clunk.") + +/obj/machinery/computer/arcade/emp_act(severity) + . = ..() + var/override = FALSE + if(prize_override) + override = TRUE + + if(machine_stat & (NOPOWER|BROKEN) || . & EMP_PROTECT_SELF) + return + + var/empprize = null + var/num_of_prizes = 0 + switch(severity) + if(1) + num_of_prizes = rand(1,4) + if(2) + num_of_prizes = rand(0,2) + for(var/i = num_of_prizes; i > 0; i--) + if(override) + empprize = pickweight(prize_override) + else + empprize = pickweight(GLOB.arcade_prize_pool) + new empprize(loc) + explosion(loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes) + +/obj/machinery/computer/arcade/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/stack/arcadeticket)) + var/obj/item/stack/arcadeticket/T = O + var/amount = T.get_amount() + if(amount <2) + to_chat(user, "You need 2 tickets to claim a prize!") + return + prizevend(user) + T.pay_tickets() + T.update_appearance() + O = T + to_chat(user, "You turn in 2 tickets to the [src] and claim a prize!") + return + +// ** BATTLE ** // +/obj/machinery/computer/arcade/battle + name = "arcade machine" + desc = "Does not support Pinball." + icon_state = "arcade" + circuit = /obj/item/circuitboard/computer/arcade/battle + + var/enemy_name = "Space Villain" + ///Enemy health/attack points + var/enemy_hp = 100 + var/enemy_mp = 40 + ///Temporary message, for attack messages, etc + var/temp = "

Winners don't use space drugs

" + ///the list of passive skill the enemy currently has. the actual passives are added in the enemy_setup() proc + var/list/enemy_passive + ///if all the enemy's weakpoints have been triggered becomes TRUE + var/finishing_move = FALSE + ///linked to passives, when it's equal or above the max_passive finishing move will become TRUE + var/pissed_off = 0 + ///the number of passives the enemy will start with + var/max_passive = 3 + ///weapon wielded by the enemy, the shotgun doesn't count. + var/chosen_weapon + + ///Player health + var/player_hp = 85 + ///player magic points + var/player_mp = 20 + ///used to remember the last three move of the player before this turn. + var/list/last_three_move + ///if the enemy or player died. restart the game when TRUE + var/gameover = FALSE + ///the player cannot make any move while this is set to TRUE. should only TRUE during enemy turns. + var/blocked = FALSE + ///used to clear the enemy_action proc timer when the game is restarted + var/timer_id + ///weapon used by the enemy, pure fluff.for certain actions + var/list/weapons + ///unique to the emag mode, acts as a time limit where the player dies when it reaches 0. + var/bomb_cooldown = 19 + + +///creates the enemy base stats for a new round along with the enemy passives +/obj/machinery/computer/arcade/battle/proc/enemy_setup(player_skill) + player_hp = 85 + player_mp = 20 + enemy_hp = 100 + enemy_mp = 40 + gameover = FALSE + blocked = FALSE + finishing_move = FALSE + pissed_off = 0 + last_three_move = null + + enemy_passive = list("short_temper" = TRUE, "poisonous" = TRUE, "smart" = TRUE, "shotgun" = TRUE, "magical" = TRUE, "chonker" = TRUE) + for(var/i = LAZYLEN(enemy_passive); i > max_passive; i--) //we'll remove passives from the list until we have the number of passive we want + var/picked_passive = pick(enemy_passive) + LAZYREMOVE(enemy_passive, picked_passive) + + if(LAZYACCESS(enemy_passive, "chonker")) + enemy_hp += 20 + + if(LAZYACCESS(enemy_passive, "shotgun")) + chosen_weapon = "shotgun" + else if(weapons) + chosen_weapon = pick(weapons) + else + chosen_weapon = "null gun" //if the weapons list is somehow empty, shouldn't happen but runtimes are sneaky bastards. + + if(player_skill) + player_hp += player_skill * 2 + + +/obj/machinery/computer/arcade/battle/Reset() + max_passive = 3 + var/name_action + var/name_part1 + var/name_part2 + + if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) + name_action = pick_list(ARCADE_FILE, "rpg_action_halloween") + name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_halloween") + name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_halloween") + weapons = strings(ARCADE_FILE, "rpg_weapon_halloween") + else if(SSevents.holidays && SSevents.holidays[CHRISTMAS]) + name_action = pick_list(ARCADE_FILE, "rpg_action_xmas") + name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_xmas") + name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_xmas") + weapons = strings(ARCADE_FILE, "rpg_weapon_xmas") + else if(SSevents.holidays && SSevents.holidays[VALENTINES]) + name_action = pick_list(ARCADE_FILE, "rpg_action_valentines") + name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_valentines") + name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_valentines") + weapons = strings(ARCADE_FILE, "rpg_weapon_valentines") + else + name_action = pick_list(ARCADE_FILE, "rpg_action") + name_part1 = pick_list(ARCADE_FILE, "rpg_adjective") + name_part2 = pick_list(ARCADE_FILE, "rpg_enemy") + weapons = strings(ARCADE_FILE, "rpg_weapon") + + enemy_name = ("The " + name_part1 + " " + name_part2) + name = (name_action + " " + enemy_name) + + enemy_setup(0) //in the case it's reset we assume the player skill is 0 because the VOID isn't a gamer + + +/obj/machinery/computer/arcade/battle/ui_interact(mob/user) + . = ..() + screen_setup(user) + + +///sets up the main screen for the user +/obj/machinery/computer/arcade/battle/proc/screen_setup(mob/user) + var/dat = "Close" + dat += "

[enemy_name]

" + + dat += "[temp]" + dat += "
Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]
" + + if (gameover) + dat += "
New Game" + else + dat += "
Light attack" + dat += "
Defend" + dat += "
Counter attack" + dat += "
Power attack" + + dat += "
" + if(user.client) //mainly here to avoid a runtime when the player gets gibbed when losing the emag mode. + var/datum/browser/popup = new(user, "arcade", "Space Villain 2000") + popup.set_content(dat) + popup.open() + + +/obj/machinery/computer/arcade/battle/Topic(href, href_list) + if(..()) + return + var/gamerSkill = 0 + if(usr?.mind) + gamerSkill = usr.mind.get_skill_level(/datum/skill/gaming) + + if (!blocked && !gameover) + var/attackamt = rand(5,7) + rand(0, gamerSkill) + + if(finishing_move) //time to bonk that fucker,cuban pete will sometime survive a finishing move. + attackamt *= 100 + + //light attack suck absolute ass but it doesn't cost any MP so it's pretty good to finish an enemy off + if (href_list["attack"]) + temp = "

you do quick jab for [attackamt] of damage!

" + enemy_hp -= attackamt + arcade_action(usr,"attack",attackamt) + + //defend lets you gain back MP and take less damage from non magical attack. + else if(href_list["defend"]) + temp = "

you take a defensive stance and gain back 10 mp!

" + player_mp += 10 + arcade_action(usr,"defend",attackamt) + playsound(src, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3) + + //mainly used to counter short temper and their absurd damage, will deal twice the damage the player took of a non magical attack. + else if(href_list["counter_attack"] && player_mp >= 10) + temp = "

you prepare yourself to counter the next attack!

" + player_mp -= 10 + arcade_action(usr,"counter_attack",attackamt) + playsound(src, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3) + + else if(href_list["counter_attack"] && player_mp < 10) + temp = "

you don't have the mp necessary to counter attack and defend yourself instead

" + player_mp += 10 + arcade_action(usr,"defend",attackamt) + playsound(src, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3) + + //power attack deals twice the amount of damage but is really expensive MP wise, mainly used with combos to get weakpoints. + else if (href_list["power_attack"] && player_mp >= 20) + temp = "

You attack [enemy_name] with all your might for [attackamt * 2] damage!

" + enemy_hp -= attackamt * 2 + player_mp -= 20 + arcade_action(usr,"power_attack",attackamt) + + else if(href_list["power_attack"] && player_mp < 20) + temp = "

You don't have the mp necessary for a power attack and settle for a light attack!

" + enemy_hp -= attackamt + arcade_action(usr,"attack",attackamt) + + if (href_list["close"]) + usr.unset_machine() + usr << browse(null, "window=arcade") + + else if (href_list["newgame"]) //Reset everything + temp = "

New Round

" + + if(obj_flags & EMAGGED) + Reset() + obj_flags &= ~EMAGGED + + enemy_setup(gamerSkill) + screen_setup(usr) + + + add_fingerprint(usr) + return + + +///happens after a player action and before the enemy turn. the enemy turn will be cancelled if there's a gameover. +/obj/machinery/computer/arcade/battle/proc/arcade_action(mob/user,player_stance,attackamt) + screen_setup(user) + blocked = TRUE + if(player_stance == "attack" || player_stance == "power_attack") + if(attackamt > 40) + playsound(src, 'sound/arcade/boom.ogg', 50, TRUE, extrarange = -3) + else + playsound(src, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3) + + timer_id = addtimer(CALLBACK(src, .proc/enemy_action,player_stance,user),1 SECONDS,TIMER_STOPPABLE) + gameover_check(user) + + +///the enemy turn, the enemy's action entirely depend on their current passive and a teensy tiny bit of randomness +/obj/machinery/computer/arcade/battle/proc/enemy_action(player_stance,mob/user) + var/list/list_temp = list() + + switch(LAZYLEN(last_three_move)) //we keep the last three action of the player in a list here + if(0 to 2) + LAZYADD(last_three_move, player_stance) + if(3) + for(var/i in 1 to 2) + last_three_move[i] = last_three_move[i + 1] + last_three_move[3] = player_stance + + if(4 to INFINITY) + last_three_move = null //this shouldn't even happen but we empty the list if it somehow goes above 3 + + var/enemy_stance + var/attack_amount = rand(8,10) //making the attack amount not vary too much so that it's easier to see if the enemy has a shotgun + + if(player_stance == "defend") + attack_amount -= 5 + + //if emagged, cuban pete will set up a bomb acting up as a timer. when it reaches 0 the player fucking dies + if(obj_flags & EMAGGED) + switch(bomb_cooldown--) + if(18) + list_temp += "

[enemy_name] takes two valve tank and links them together, what's he planning?

" + if(15) + list_temp += "

[enemy_name] adds a remote control to the tan- ho god is that a bomb?

" + if(12) + list_temp += "

[enemy_name] throws the bomb next to you, you'r too scared to pick it up.

" + if(6) + list_temp += "

[enemy_name]'s hand brushes the remote linked to the bomb, your heart skipped a beat.

" + if(2) + list_temp += "

[enemy_name] is going to press the button! It's now or never!

" + if(0) + player_hp -= attack_amount * 1000 //hey it's a maxcap we might as well go all in + + //yeah I used the shotgun as a passive, you know why? because the shotgun gives +5 attack which is pretty good + if(LAZYACCESS(enemy_passive, "shotgun")) + if(weakpoint_check("shotgun","defend","defend","power_attack")) + list_temp += "

You manage to disarm [enemy_name] with a surprise power attack and shoot him with his shotgun until it runs out of ammo!

" + enemy_hp -= 10 + chosen_weapon = "empty shotgun" + else + attack_amount += 5 + + //heccing chonker passive, only gives more HP at the start of a new game but has one of the hardest weakpoint to trigger. + if(LAZYACCESS(enemy_passive, "chonker")) + if(weakpoint_check("chonker","power_attack","power_attack","power_attack")) + list_temp += "

After a lot of power attacks you manage to tip over [enemy_name] as they fall over their enormous weight

" + enemy_hp -= 30 + + //smart passive trait, mainly works in tandem with other traits, makes the enemy unable to be counter_attacked + if(LAZYACCESS(enemy_passive, "smart")) + if(weakpoint_check("smart","defend","defend","attack")) + list_temp += "

[enemy_name] is confused by your illogical strategy!

" + attack_amount -= 5 + + else if(attack_amount >= player_hp) + player_hp -= attack_amount + list_temp += "

[enemy_name] figures out you are really close to death and finishes you off with their [chosen_weapon]!

" + enemy_stance = "attack" + + else if(player_stance == "counter_attack") + list_temp += "

[enemy_name] is not taking your bait.

" + if(LAZYACCESS(enemy_passive, "short_temper")) + list_temp += "However controlling their hatred of you still takes a toll on their mental and physical health!" + enemy_hp -= 5 + enemy_mp -= 5 + enemy_stance = "defensive" + + //short temper passive trait, gets easily baited into being counter attacked but will bypass your counter when low on HP + if(LAZYACCESS(enemy_passive, "short_temper")) + if(weakpoint_check("short_temper","counter_attack","counter_attack","counter_attack")) + list_temp += "

[enemy_name] is getting frustrated at all your counter attacks and throws a tantrum!

" + enemy_hp -= attack_amount + + else if(player_stance == "counter_attack") + if(!(LAZYACCESS(enemy_passive, "smart")) && enemy_hp > 30) + list_temp += "

[enemy_name] took the bait and allowed you to counter attack for [attack_amount * 2] damage!

" + player_hp -= attack_amount + enemy_hp -= attack_amount * 2 + enemy_stance = "attack" + + else if(enemy_hp <= 30) //will break through the counter when low enough on HP even when smart. + list_temp += "

[enemy_name] is getting tired of your tricks and breaks through your counter with their [chosen_weapon]!

" + player_hp -= attack_amount + enemy_stance = "attack" + + else if(!enemy_stance) + var/added_temp + + if(rand()) + added_temp = "you for [attack_amount + 5] damage!" + player_hp -= attack_amount + 5 + enemy_stance = "attack" + else + added_temp = "the wall, breaking their skull in the process and losing [attack_amount] hp!" //[enemy_name] you have a literal dent in your skull + enemy_hp -= attack_amount + enemy_stance = "attack" + + list_temp += "

[enemy_name] grits their teeth and charge right into [added_temp]

" + + //in the case none of the previous passive triggered, Mainly here to set an enemy stance for passives that needs it like the magical passive. + if(!enemy_stance) + enemy_stance = pick("attack","defensive") + if(enemy_stance == "attack") + player_hp -= attack_amount + list_temp += "

[enemy_name] attacks you for [attack_amount] points of damage with their [chosen_weapon]

" + if(player_stance == "counter_attack") + enemy_hp -= attack_amount * 2 + list_temp += "

You counter [enemy_name]'s attack and deal [attack_amount * 2] points of damage!

" + + if(enemy_stance == "defensive" && enemy_mp < 15) + list_temp += "

[enemy_name] take some time to get some mp back!

" + enemy_mp += attack_amount + + else if (enemy_stance == "defensive" && enemy_mp >= 15 && !(LAZYACCESS(enemy_passive, "magical"))) + list_temp += "

[enemy_name] quickly heal themselves for 5 hp!

" + enemy_mp -= 15 + enemy_hp += 5 + + //magical passive trait, recharges MP nearly every turn it's not blasting you with magic. + if(LAZYACCESS(enemy_passive, "magical")) + if(player_mp >= 50) + list_temp += "

the huge amount of magical energy you have acumulated throws [enemy_name] off balance!

" + enemy_mp = 0 + LAZYREMOVE(enemy_passive, "magical") + pissed_off++ + + else if(LAZYACCESS(enemy_passive, "smart") && player_stance == "counter_attack" && enemy_mp >= 20) + list_temp += "

[enemy_name] blasts you with magic from afar for 10 points of damage before you can counter!

" + player_hp -= 10 + enemy_mp -= 20 + + else if(enemy_hp >= 20 && enemy_mp >= 40 && enemy_stance == "defensive") + list_temp += "

[enemy_name] Blasts you with magic from afar!

" + enemy_mp -= 40 + player_hp -= 30 + enemy_stance = "attack" + + else if(enemy_hp < 20 && enemy_mp >= 20 && enemy_stance == "defensive") //it's a pretty expensive spell so they can't spam it that much + list_temp += "

[enemy_name] heal themselves with magic and gain back 20 hp!

" + enemy_hp += 20 + enemy_mp -= 30 + else + list_temp += "

[enemy_name]'s magical nature lets them get some mp back!

" + enemy_mp += attack_amount + + //poisonous passive trait, while it's less damage added than the shotgun it acts up even when the enemy doesn't attack at all. + if(LAZYACCESS(enemy_passive, "poisonous")) + if(weakpoint_check("poisonous","attack","attack","attack")) + list_temp += "

your flurry of attack throws back the poisonnous gas at [enemy_name] and makes them choke on it!

" + enemy_hp -= 5 + else + list_temp += "

the stinky breath of [enemy_name] hurts you for 3 hp!

" + player_hp -= 3 + + //if all passive's weakpoint have been triggered, set finishing_move to TRUE + if(pissed_off >= max_passive && !finishing_move) + list_temp += "

You have weakened [enemy_name] enough for them to show their weak point, you will do 10 times as much damage with your next attack!

" + finishing_move = TRUE + + playsound(src, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3) + + temp = list_temp.Join() + gameover_check(user) + screen_setup(user) + blocked = FALSE + + +/obj/machinery/computer/arcade/battle/proc/gameover_check(mob/user) + var/xp_gained = 0 + if(enemy_hp <= 0) + if(!gameover) + if(timer_id) + deltimer(timer_id) + timer_id = null + if(player_hp <= 0) + player_hp = 1 //let's just pretend the enemy didn't kill you so not both the player and enemy look dead. + gameover = TRUE + blocked = FALSE + temp = "

[enemy_name] has fallen! Rejoice!

" + playsound(loc, 'sound/arcade/win.ogg', 50, TRUE) + + if(obj_flags & EMAGGED) + new /obj/effect/spawner/newbomb/timer/syndicate(loc) + new /obj/item/clothing/head/collectable/petehat(loc) + message_admins("[ADMIN_LOOKUPFLW(usr)] has outbombed Cuban Pete and been awarded a bomb.") + log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.") + Reset() + obj_flags &= ~EMAGGED + xp_gained += 100 + else + prizevend(user) + xp_gained += 50 + SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("win", (obj_flags & EMAGGED ? "emagged":"normal"))) + + else if(player_hp <= 0) + if(timer_id) + deltimer(timer_id) + timer_id = null + gameover = TRUE + temp = "

You have been crushed! GAME OVER

" + playsound(loc, 'sound/arcade/lose.ogg', 50, TRUE) + xp_gained += 10//pity points + if(obj_flags & EMAGGED) + var/mob/living/living_user = user + if (istype(living_user)) + living_user.gib() + SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal"))) + + if(gameover) + user?.mind?.adjust_experience(/datum/skill/gaming, xp_gained+1)//always gain at least 1 point of XP + + +///used to check if the last three move of the player are the one we want in the right order and if the passive's weakpoint has been triggered yet +/obj/machinery/computer/arcade/battle/proc/weakpoint_check(passive,first_move,second_move,third_move) + if(LAZYLEN(last_three_move) < 3) + return FALSE + + if(last_three_move[1] == first_move && last_three_move[2] == second_move && last_three_move[3] == third_move && LAZYACCESS(enemy_passive, passive)) + LAZYREMOVE(enemy_passive, passive) + pissed_off++ + return TRUE + else + return FALSE + + +/obj/machinery/computer/arcade/battle/Destroy() + enemy_passive = null + weapons = null + last_three_move = null + return ..() //well boys we did it, lists are no more + +/obj/machinery/computer/arcade/battle/examine_more(mob/user) + var/list/msg = list("You notice some writing scribbled on the side of [src]...") + msg += "\tsmart -> defend, defend, light attack" + msg += "\tshotgun -> defend, defend, power attack" + msg += "\tshort temper -> counter, counter, counter" + msg += "\tpoisonous -> light attack, light attack, light attack" + msg += "\tchonker -> power attack, power attack, power attack" + return msg + +/obj/machinery/computer/arcade/battle/emag_act(mob/user) + if(obj_flags & EMAGGED) + return + + to_chat(user, "A mesmerizing Rhumba beat starts playing from the arcade machine's speakers!") + temp = "

If you die in the game, you die for real!

" + max_passive = 6 + bomb_cooldown = 18 + var/gamerSkill = 0 + if(usr?.mind) + gamerSkill = usr.mind.get_skill_level(/datum/skill/gaming) + enemy_setup(gamerSkill) + enemy_hp += 100 //extra HP just to make cuban pete even more bullshit + player_hp += 30 //the player will also get a few extra HP in order to have a fucking chance + + screen_setup(user) + gameover = FALSE + + obj_flags |= EMAGGED + + enemy_name = "Cuban Pete" + name = "Outbomb Cuban Pete" + + updateUsrDialog() + +// ** AMPUTATION ** // + +/obj/machinery/computer/arcade/amputation + name = "Mediborg's Amputation Adventure" + desc = "A picture of a blood-soaked medical cyborg flashes on the screen. The mediborg has a speech bubble that says, \"Put your hand in the machine if you aren't a coward!\"" + icon_state = "arcade" + circuit = /obj/item/circuitboard/computer/arcade/amputation + +/obj/machinery/computer/arcade/amputation/attack_hand(mob/user, list/modifiers) + if(!iscarbon(user)) + return + var/mob/living/carbon/c_user = user + if(!c_user.get_bodypart(BODY_ZONE_L_ARM) && !c_user.get_bodypart(BODY_ZONE_R_ARM)) + return + to_chat(c_user, "You move your hand towards the machine, and begin to hesitate as a bloodied guillotine emerges from inside of it...") + if(do_after(c_user, 50, target = src)) + to_chat(c_user, "The guillotine drops on your arm, and the machine sucks it in!") + playsound(loc, 'sound/weapons/slice.ogg', 25, TRUE, -1) + var/which_hand = BODY_ZONE_L_ARM + if(!(c_user.active_hand_index % 2)) + which_hand = BODY_ZONE_R_ARM + var/obj/item/bodypart/chopchop = c_user.get_bodypart(which_hand) + chopchop.dismember() + qdel(chopchop) + user.mind?.adjust_experience(/datum/skill/gaming, 100) + playsound(loc, 'sound/arcade/win.ogg', 50, TRUE) + prizevend(user, rand(3,5)) + else + to_chat(c_user, "You (wisely) decide against putting your hand in the machine.") + +/obj/machinery/computer/arcade/amputation/festive //dispenses wrapped gifts instead of arcade prizes, also known as the ancap christmas tree + name = "Mediborg's Festive Amputation Adventure" + desc = "A picture of a blood-soaked medical cyborg wearing a Santa hat flashes on the screen. The mediborg has a speech bubble that says, \"Put your hand in the machine if you aren't a coward!\"" + prize_override = list(/obj/item/a_gift/anything = 1) diff --git a/code/game/machinery/computer/arcade/orion.dm b/code/game/machinery/computer/arcade/orion.dm new file mode 100644 index 00000000000..2241e0f6831 --- /dev/null +++ b/code/game/machinery/computer/arcade/orion.dm @@ -0,0 +1,533 @@ +// *** THE ORION TRAIL ** // + +#define ORION_TRAIL_WINTURN 9 + +//defines in machines.dm + +///assoc list, [datum singleton] = weight +GLOBAL_LIST_INIT(orion_events, generate_orion_events()) + +/proc/generate_orion_events() + . = list() + for(var/path in subtypesof(/datum/orion_event)) + var/datum/orion_event/new_event = new path(src) + .[new_event] = new_event.weight + +/obj/machinery/computer/arcade/orion_trail + name = "The Orion Trail" + desc = "Learn how our ancestors got to Orion, and have fun in the process!" + icon_state = "arcade" + circuit = /obj/item/circuitboard/computer/arcade/orion_trail + var/busy = FALSE //prevent clickspam that allowed people to ~speedrun~ the game. + var/engine = 0 + var/hull = 0 + var/electronics = 0 + var/food = 80 + var/fuel = 60 + var/turns = 4 + var/alive = ORION_STARTING_CREW_COUNT + var/datum/orion_event/event = null + var/reason + var/list/settlers = list("Harry","Larry","Bob") + var/list/settlermoods = list() + var/list/events + //actual amount of lings on board + var/lings_aboard = 0 + //if the game should pretend there are lings on board. + var/lings_suspected = FALSE + var/spaceport_raided = FALSE + var/gameStatus = ORION_STATUS_START + + var/obj/item/radio/radio + var/list/gamers = list() + var/killed_crew = 0 + +/obj/machinery/computer/arcade/orion_trail/Initialize() + . = ..() + radio = new /obj/item/radio(src) + radio.listening = 0 + setup_events() + +/obj/machinery/computer/arcade/orion_trail/proc/setup_events() + events = GLOB.orion_events + +/obj/machinery/computer/arcade/orion_trail/Destroy() + QDEL_NULL(radio) + events = null + return ..() + +/obj/machinery/computer/arcade/orion_trail/kobayashi + name = "Kobayashi Maru control computer" + desc = "A test for cadets." + icon = 'icons/obj/machines/particle_accelerator.dmi' + icon_state = "control_boxp" + //kobatashi has a smaller list of events, so we copy from the global list and cut whatever isn't here + var/list/event_whitelist = list( + /datum/orion_event/raiders, + /datum/orion_event/flux, + /datum/orion_event/illness, + /datum/orion_event/engine_part, + /datum/orion_event/electronic_part, + /datum/orion_event/hull_part, + /datum/orion_event/space_port, + /datum/orion_event/space_port/tau_ceti, + /datum/orion_event/space_port_raid, + /datum/orion_event/black_hole, + /datum/orion_event/black_hole_death, + ) + prize_override = list(/obj/item/paper/fluff/holodeck/trek_diploma = 1) + settlers = list("Kirk","Worf","Gene") + +/obj/machinery/computer/arcade/orion_trail/kobayashi/setup_events() + events = GLOB.orion_events.Copy() + for(var/datum/orion_event/event as anything in events) + if(!(event.type in event_whitelist)) + events.Remove(event) + +/obj/machinery/computer/arcade/orion_trail/proc/newgame() + // Set names of settlers in crew + var/mob/living/carbon/player = usr + var/player_crew_name = player.first_name() + settlers = list() + for(var/i in 1 to ORION_STARTING_CREW_COUNT - 1) //one reserved to be YOU + add_crewmember(update = FALSE) + add_crewmember("[player_crew_name]") + // Re-set items to defaults + engine = 1 + hull = 1 + electronics = 1 + food = 80 + fuel = 60 + alive = ORION_STARTING_CREW_COUNT + turns = 1 + event = null + gameStatus = ORION_STATUS_NORMAL + lings_aboard = 0 + lings_suspected = FALSE + killed_crew = 0 + + //spaceport junk + spaceport_raided = FALSE + +/obj/machinery/computer/arcade/orion_trail/proc/report_player(mob/gamer) + if(gamers[gamer] == ORION_GAMER_GIVE_UP) + return // enough harassing them + + if(gamers[gamer] == ORION_GAMER_PAMPHLET) + say("WARNING: Continued antisocial behavior detected: Dispensing self-help literature.") + new /obj/item/paper/pamphlet/violent_video_games(drop_location()) + gamers[gamer]-- + return + + if(!(gamer in gamers)) + gamers[gamer] = 0 + + gamers[gamer]++ // How many times the player has 'prestiged' (massacred their crew) + + if(gamers[gamer] > ORION_GAMER_REPORT_THRESHOLD && prob(20 * gamers[gamer])) + + radio.set_frequency(FREQ_SECURITY) + radio.talk_into(src, "SECURITY ALERT: Crewmember [gamer] recorded displaying antisocial tendencies in [get_area(src)]. Please watch for violent behavior.", FREQ_SECURITY) + + radio.set_frequency(FREQ_MEDICAL) + radio.talk_into(src, "PSYCH ALERT: Crewmember [gamer] recorded displaying antisocial tendencies in [get_area(src)]. Please schedule psych evaluation.", FREQ_MEDICAL) + + gamers[gamer] = ORION_GAMER_PAMPHLET //next report send a pamph + + gamer.client.give_award(/datum/award/achievement/misc/gamer, gamer) // PSYCH REPORT NOTE: patient kept rambling about how they did it for an "achievement", recommend continued holding for observation + gamer.mind?.adjust_experience(/datum/skill/gaming, 50) // cheevos make u better + + if(!isnull(GLOB.data_core.general)) + for(var/datum/data/record/insanity_records in GLOB.data_core.general) + if(insanity_records.fields["name"] == gamer.name) + insanity_records.fields["m_stat"] = "*Unstable*" + return + +/obj/machinery/computer/arcade/orion_trail/ui_interact(mob/user, datum/tgui/ui) + . = ..() + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OrionGame", name) + ui.open() + +/obj/machinery/computer/arcade/orion_trail/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/moods), + ) + +/obj/machinery/computer/arcade/orion_trail/ui_data(mob/user) + var/list/data = list() + data["gamestatus"] = gameStatus + + data["engine"] = engine + data["turns"] = turns + data["hull"] = hull + data["electronics"] = electronics + data["food"] = food + data["fuel"] = fuel + data["lings_suspected"] = lings_suspected + + data["eventname"] = event?.name + data["eventtext"] = event?.text + data["buttons"] = event?.event_responses + + data["spaceport_raided"] = spaceport_raided + + data["reason"] = reason + + return data + +/obj/machinery/computer/arcade/orion_trail/ui_static_data(mob/user) + var/list/static_data = list() + static_data["gamename"] = name + static_data["emagged"] = obj_flags & EMAGGED + static_data["settlers"] = settlers + static_data["settlermoods"] = settlermoods + return static_data + +/obj/machinery/computer/arcade/orion_trail/ui_act(action, list/params) + . = ..() + if(.) + return + + var/mob/living/carbon/gamer = usr + if(!istype(gamer)) + return + + . = TRUE + + + + var/gamer_skill_level = 0 + var/gamer_skill = 0 + var/gamer_skill_rands = 0 + + if(gamer?.mind) + gamer_skill_level = gamer.mind.get_skill_level(/datum/skill/gaming) + gamer_skill = gamer.mind.get_skill_modifier(/datum/skill/gaming, SKILL_PROBS_MODIFIER) + gamer_skill_rands = gamer.mind.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER) + + var/xp_gained = 0 + + if(event) + event.response(src, action) + if(!settlers.len || food <= 0 || fuel <= 0) + set_game_over(gamer) + return + new_settler_mood() //events shake people up a bit and can also change food + update_static_data(usr) + return TRUE + switch(action) + if("start_game") + if(gameStatus != ORION_STATUS_START) + return + newgame() + if("instructions") + if(gameStatus != ORION_STATUS_START) + return + gameStatus = ORION_STATUS_INSTRUCTIONS + if("back_to_menu") //back to the main menu + gameStatus = ORION_STATUS_START + if(gameStatus == ORION_STATUS_GAMEOVER) + event = null + reason = null + food = 80 + fuel = 60 + settlers = list("Harry","Larry","Bob") + if("continue") + if(turns >= ORION_TRAIL_WINTURN) + win(gamer) + xp_gained += 34 + return + gamer.mind.adjust_experience(/datum/skill/gaming, xp_gained+1) + food -= (alive+lings_aboard)*2 + fuel -= 5 + turns += 1 + //out of supplies, die + if(food <= 0 || fuel <= 0) + set_game_over(gamer) + if(turns == 2 && prob(30-gamer_skill)) //asteroids part of the trip + encounter_event(/datum/orion_event/hull_part, gamer, gamer_skill, gamer_skill_level, gamer_skill_rands) + return + if(turns == 4) //halfway mark + encounter_event(/datum/orion_event/space_port/tau_ceti, gamer, gamer_skill, gamer_skill_level, gamer_skill_rands) + return + if(turns == 7) //black hole part of the trip + encounter_event(/datum/orion_event/black_hole, gamer, gamer_skill, gamer_skill_level, gamer_skill_rands) + return + //an uneventful (get it) turn + if(prob(25 + gamer_skill)) + return + encounter_event(null, gamer, gamer_skill, gamer_skill_level) + if(lings_aboard && (istype(event, /datum/orion_event/changeling_infiltration) || prob(45 + gamer_skill))) + //upgrade infiltration/whatever else we got to attack right away + encounter_event(/datum/orion_event/changeling_attack, gamer, gamer_skill, gamer_skill_level, gamer_skill_rands) + if("random_kill") + execute_crewmember(gamer) + if("target_kill") + execute_crewmember(gamer, params["who"]) + //Spaceport specific interactions + if("buycrew") //buy a crewmember + if(!spaceport_raided && food >= 10 && fuel >= 10) + if(params["odd"]) + //find some silly crewmember name + add_crewmember(pick(GLOB.commando_names + GLOB.nightmare_names + GLOB.ai_names + GLOB.clown_names + GLOB.mime_names + GLOB.plasmaman_names + GLOB.ethereal_names + GLOB.carp_names)) + else + add_crewmember() + fuel -= ORION_BUY_CREW_PRICE + food -= ORION_BUY_CREW_PRICE + killed_crew-- // I mean not really but you know + if("sellcrew") //sell a crewmember + if(!spaceport_raided && settlers.len > 1) + remove_crewmember() + fuel += ORION_SELL_CREW_PRICE + food += ORION_SELL_CREW_PRICE + if("leave_spaceport") + gameStatus = ORION_STATUS_NORMAL + spaceport_raided = FALSE + if("raid_spaceport") + spaceport_raided = TRUE + encounter_event(/datum/orion_event/space_port_raid, gamer, gamer_skill, gamer_skill_level, gamer_skill_rands) + if("buyparts") + if(!spaceport_raided && fuel > ORION_TRADE_RATE) + switch(params["part"]) + if(ORION_BUY_ENGINE_PARTS) + engine++ + if(ORION_BUY_ELECTRONICS) + hull++ + if(ORION_BUY_HULL_PARTS) + electronics++ + fuel -= ORION_TRADE_RATE + if("trade") + if(!spaceport_raided) + switch(params["what"]) + if(ORION_I_WANT_FUEL) + if(fuel > ORION_TRADE_RATE) + fuel -= ORION_TRADE_RATE + food += ORION_TRADE_RATE + if(ORION_I_WANT_FOOD) + if(food > ORION_TRADE_RATE) + fuel += ORION_TRADE_RATE + food -= ORION_TRADE_RATE + add_fingerprint(gamer) + +/** + * pickweights a new event, sets event var as it. it then preps the event if it needs it + * + * giving a path argument will instead find that instanced datum instead of pickweighting. Used in events that follow from events. + * Arguments: + * * path: if we want a specific event, this is the path of the wanted one + * * gamer: person using the arcade, used in emag effects + * * gamer_skill: gaming skill of the player + * * gamer_skill_level: gaming skill level of the player + * * gamer_skill_rands: See above but for random chances, you can just look at gaming skill to see how it chalks that up + */ +/obj/machinery/computer/arcade/orion_trail/proc/encounter_event(path, gamer, gamer_skill, gamer_skill_level, gamer_skill_rands) + if(!path) + event = pickweightAllowZero(events) + else + for(var/datum/orion_event/instance as anything in events) + if(instance.type == path) + event = instance + break + if(!event) + CRASH("Woah, hey! we could not find the specified event \"[path]\"! Add it to the events list, numb nuts!") + event.on_select(src, gamer_skill, gamer_skill_level, gamer_skill_rands) + if(obj_flags & EMAGGED) + event.emag_effect(src, gamer) + +/obj/machinery/computer/arcade/orion_trail/proc/set_game_over(user, given_reason) + gameStatus = ORION_STATUS_GAMEOVER + event = null + reason = given_reason || death_reason(user) + +/obj/machinery/computer/arcade/orion_trail/proc/death_reason(mob/living/carbon/gamer) + var/reason + if(!settlers.len) + reason = "Your entire crew died, and your ship joins the fleet of ghost-ships littering the galaxy." + else + if(food <= 0) + reason = "You ran out of food and starved." + if(obj_flags & EMAGGED) + gamer.set_nutrition(0) //yeah you pretty hongry + to_chat(gamer, "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.") + if(fuel <= 0) + reason = "You ran out of fuel, and drift, slowly, into a star." + if(obj_flags & EMAGGED) + gamer.adjust_fire_stacks(5) + gamer.IgniteMob() //flew into a star, so you're on fire + to_chat(gamer, "You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames.") + + if(obj_flags & EMAGGED) + to_chat(gamer, "You're never going to make it to Orion...") + gamer.death() + obj_flags &= ~EMAGGED //removes the emagged status after you lose + gameStatus = ORION_STATUS_START + name = "The Orion Trail" + desc = "Learn how our ancestors got to Orion, and have fun in the process!" + + gamer?.mind?.adjust_experience(/datum/skill/gaming, 10)//learning from your mistakes is the first rule of roguelikes + return reason + +//Add Random/Specific crewmember +/obj/machinery/computer/arcade/orion_trail/proc/add_crewmember(specific = "", update = TRUE) + var/newcrew = "" + if(specific) + newcrew = specific + else + if(prob(50)) + newcrew = pick(GLOB.first_names_male) + else + newcrew = pick(GLOB.first_names_female) + if(newcrew) + settlers += newcrew + alive++ + if(update) + new_settler_mood()//new faces! + update_static_data(usr) + return newcrew + + +//Remove Random/Specific crewmember +/obj/machinery/computer/arcade/orion_trail/proc/remove_crewmember(specific = "", dont_remove = "", update = TRUE) + var/list/safe_to_remove = settlers + var/removed = "" + if(dont_remove) + safe_to_remove -= dont_remove + if(specific && specific != dont_remove) + safe_to_remove = list(specific) + removed = pick(safe_to_remove) + + if(removed) + if(lings_aboard && prob(40*lings_aboard)) //if there are 2 lings you're twice as likely to get one, obviously + lings_aboard = max(0,--lings_aboard) + settlers -= removed + alive-- + if(update) + new_settler_mood()//bro, i... + update_static_data(usr) + return removed + +/** + * Crewmember executed code, targeted when there are no lings and untargeted when there are some + * If there was no suspected lings (aka random shots) this is just murder and counts towards killed crew + * + * Arguments: + * * gamer: carbon that may need emag effects applied + */ +/obj/machinery/computer/arcade/orion_trail/proc/execute_crewmember(mob/living/carbon/gamer, target) + var/sheriff = remove_crewmember(target) //I shot the sheriff + if(target) + killed_crew += 1 //if there was no suspected lings, this is just plain murder + playsound(loc,'sound/weapons/gun/pistol/shot.ogg', 100, TRUE) + if(!settlers.len || !alive) + say("The last crewmember [sheriff], shot themselves, GAME OVER!") + if(obj_flags & EMAGGED) + gamer.death() + set_game_over(gamer, "Your last pioneer committed suicide.") + if(killed_crew >= ORION_STARTING_CREW_COUNT) + gamer.mind?.adjust_experience(/datum/skill/gaming, -15)//no cheating by spamming game overs + report_player(gamer) + else if(obj_flags & EMAGGED) + if(findtext(gamer.name, sheriff)) + say("The crew of the ship chose to kill [gamer]!") + gamer.death() + +/** + * Creates a new mood icon for each settler + * + * Things that effect mood: + * * Pioneer count + * * Low food + * * Low parts + * * Sometimes they're just a bit happier or sadder + * Arguments: + * * None! + */ +/obj/machinery/computer/arcade/orion_trail/proc/new_settler_mood() + settlermoods.Cut() + for(var/i in 1 to settlers.len) + var/food_mood = food >= 15 + var/supply_mood = -2 + if(hull) + supply_mood++ + if(electronics) + supply_mood++ + if(engine) + supply_mood++ + var/changing_mood = 0 + if(prob(60)) //sometimes they just feel better or worse + changing_mood = rand(-1,1) + settlermoods[settlers[i]] += max(settlers.len + food_mood + supply_mood + changing_mood, 1) + if(lings_suspected) //lings ruin any good mood + settlermoods[settlers[i]] = min(settlermoods[settlers[i]], 3) + +/obj/machinery/computer/arcade/orion_trail/proc/win(mob/user) + gameStatus = ORION_STATUS_START + say("Congratulations, you made it to Orion!") + if(obj_flags & EMAGGED) + new /obj/item/orion_ship(loc) + message_admins("[ADMIN_LOOKUPFLW(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") + log_game("[key_name(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") + else + prizevend(user) + obj_flags &= ~EMAGGED + name = initial(name) + desc = initial(desc) + +/obj/machinery/computer/arcade/orion_trail/emag_act(mob/user) + if(obj_flags & EMAGGED) + return + to_chat(user, "You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.") + name = "The Orion Trail: Realism Edition" + desc = "Learn how our ancestors got to Orion, and try not to die in the process!" + newgame() + obj_flags |= EMAGGED + +/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion + name = "spaceport security" + desc = "Premier corporate security forces for all spaceports found along the Orion Trail." + faction = list("orion") + loot = list() + del_on_death = TRUE + +/obj/item/orion_ship + name = "model settler ship" + desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." + icon = 'icons/obj/toy.dmi' + icon_state = "ship" + w_class = WEIGHT_CLASS_SMALL + var/active = 0 //if the ship is on + +/obj/item/orion_ship/examine(mob/user) + . = ..() + if(!(in_range(user, src))) + return + if(!active) + . += "There's a little switch on the bottom. It's flipped down." + else + . += "There's a little switch on the bottom. It's flipped up." + +/obj/item/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse + if(active) + return + + log_bomber(usr, "primed an explosive", src, "for detonation") + + to_chat(user, "You flip the switch on the underside of [src].") + active = 1 + visible_message("[src] softly beeps and whirs to life!") + playsound(loc, 'sound/machines/defib_SaftyOn.ogg', 25, TRUE) + say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") + sleep(20) + visible_message("[src] begins to vibrate...") + say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") + sleep(30) + say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") + playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, TRUE) + sleep(3.6) + visible_message("[src] explodes!") + explosion(loc, 2,4,8, flame_range = 16) + qdel(src) + +#undef ORION_TRAIL_WINTURN diff --git a/code/game/machinery/computer/arcade/orion_event.dm b/code/game/machinery/computer/arcade/orion_event.dm new file mode 100644 index 00000000000..9ed2c04a2a8 --- /dev/null +++ b/code/game/machinery/computer/arcade/orion_event.dm @@ -0,0 +1,532 @@ + +//yep you guessed it back at it again with another datum singleton. +/datum/orion_event + var/name = "this displays the events name" + var/text = "this displays a blurb about the event" + ///pickweight to show up. will still be in the events pool if added to the events list but not RANDOM, only triggered. + var/weight = 0 + ///buttons to pick in response to the event. Don't worry, orion js will handle the rest + var/list/event_responses = list() + ///default emag effect of events is to play an audible message and sound + var/emag_message = "Coders forgot to set this!" + var/emag_sound = 'sound/effects/bamf.ogg' + ///gaming skill level of the player + var/gamer_skill_level = 0 + ///gaming skill of the player + var/gamer_skill = 0 + ///some other metric that makes it easier to do randoms with skill testing, god really 3 vars guys + var/gamer_skill_rands = 0 + +/** + * What happens when this event is selected to trigger, sets vars. also can set some event pre-encounter randomization + * + * Arguments: + * * game: arcade machine calling this + * * gamer_skill: gaming skill of the player + * * gamer_skill_level: gaming skill level of the player + * * gamer_skill_rands: See above but it's another metric, you can just look at gaming skill to see how it chalks that up + */ +/datum/orion_event/proc/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + SHOULD_CALL_PARENT(TRUE) + src.gamer_skill_level = gamer_skill_level + src.gamer_skill = gamer_skill + src.gamer_skill_rands = gamer_skill_rands + +/** + * What happens when you respond to this event by choosing one of the buttons + * + * Arguments: + * * game: arcade machine calling this + * * choice: name of the button you pressed. + */ +/datum/orion_event/proc/response(obj/machinery/computer/arcade/orion_trail/game, choice) + game.event = null + +/** + * Some effect that happens to the carbon when this event triggers on an emagged arcade machine. + * + * By default, it just sends an audible message and a sound, both vars on the orion datum + * Arguments: + * * game: arcade machine calling this + * * gamer: victim to apply effects to + * * gamer_skill: skill of the gamer, because gamers gods can lessen the effects of the emagged machine + * * gamer_skill_level: skill level of the gamer, another way to measure emag downside avoidance + */ +/datum/orion_event/proc/emag_effect(obj/machinery/computer/arcade/orion_trail/game, mob/living/carbon/gamer) + if(emag_message) + game.audible_message(emag_message) + if(emag_sound) + playsound(game, emag_sound, 100, TRUE) + +#define BUTTON_FIX_ENGINE "Fix Engine" +#define BUTTON_WAIT "Wait" + +///Engine Breakdown - spend one engine part or wait 3 days (harmless emag effect) +/datum/orion_event/engine_part + name = "Engine Breakdown" + text = "Oh no! The engine has broken down! \ + You can repair it with an engine part, or you \ + can make repairs for 3 days." + emag_message = "You hear some large object lurch to a halt right behind you! When you go to look, nothing's there..." + emag_sound = 'sound/effects/creak1.ogg' + weight = 2 + event_responses = list() + +/datum/orion_event/engine_part/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + ..() + if(game.engine >= 1) + event_responses += BUTTON_FIX_ENGINE + event_responses += BUTTON_WAIT + +/datum/orion_event/engine_part/response(obj/machinery/computer/arcade/orion_trail/game, choice) + if(choice == BUTTON_FIX_ENGINE) + game.engine = max(0, --game.engine) + else + game.food -= (game.alive + game.lings_aboard) * ORION_LONG_DELAY + event_responses.Cut() + ..() + +#define BUTTON_REPAIR_ELECTRONICS "Repair Electronics" + +///Malfunction - spend one engine part or wait 3 days (emag effect randomizes some stats) +/datum/orion_event/electronic_part + name = "Malfunction" + text = "The ship's systems are malfunctioning! \ + You can replace the broken electronics with spares, \ + or you can spend 3 days troubleshooting the AI." + weight = 2 + //set by select + event_responses = list() + +/datum/orion_event/electronic_part/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + ..() + if(game.electronics >= 1) + event_responses += BUTTON_REPAIR_ELECTRONICS + event_responses += BUTTON_WAIT + +/datum/orion_event/electronic_part/response(obj/machinery/computer/arcade/orion_trail/game, choice) + if(choice == BUTTON_REPAIR_ELECTRONICS) + game.electronics = max(0, game.electronics - 1) + else + game.food -= (game.alive + game.lings_aboard) * ORION_LONG_DELAY + event_responses.Cut() + ..() + +/datum/orion_event/electronic_part/emag_effect(obj/machinery/computer/arcade/orion_trail/game, mob/living/carbon/gamer) + playsound(game, 'sound/effects/empulse.ogg', 50, TRUE) + game.visible_message("[src] malfunctions, randomizing in-game stats!") + var/oldfood = game.food + var/oldfuel = game.fuel + game.food = rand(10,80) / rand(1,2) + game.fuel = rand(10,60) / rand(1,2) + if(game.electronics) + addtimer(CALLBACK(game, .proc/revert_random, game, oldfood, oldfuel), 1 SECONDS) + +/datum/orion_event/electronic_part/proc/revert_random(obj/machinery/computer/arcade/orion_trail/game, oldfood, oldfuel) + if(oldfuel > game.fuel && oldfood > game.food) + game.audible_message("[src] lets out a somehow reassuring chime.") + else if(oldfuel < game.fuel || oldfood < game.food) + game.audible_message("[src] lets out a somehow ominous chime.") + game.food = oldfood + game.fuel = oldfuel + playsound(game, 'sound/machines/chime.ogg', 50, TRUE) + +#define BUTTON_RESTORE_HULL "Restore Hull" + +///Collision - spend one engine part or wait 3 days (has a nasty emag effect) +/datum/orion_event/hull_part + name = "Collision" + text = "Something hit us! Looks like there's some hull damage. \ + You can repair the damage with hull plates, or you can spend \ + the next 3 days welding scrap together." + weight = 2 + event_responses = list() + +/datum/orion_event/hull_part/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + ..() + if(game.hull >= 1) + event_responses += BUTTON_RESTORE_HULL + event_responses += BUTTON_WAIT + +/datum/orion_event/hull_part/response(obj/machinery/computer/arcade/orion_trail/game, choice) + if(choice == BUTTON_RESTORE_HULL) + game.hull = max(0, game.hull - 1) + else + game.food -= (game.alive + game.lings_aboard) * ORION_LONG_DELAY + event_responses.Cut() + ..() + +/datum/orion_event/hull_part/emag_effect(obj/machinery/computer/arcade/orion_trail/game, mob/living/carbon/gamer) + if(prob(10+gamer_skill)) + game.say("Something slams into the floor around [src] - luckily, it didn't get through!") + playsound(game, 'sound/effects/bang.ogg', 50, TRUE) + return + playsound(game, 'sound/effects/bang.ogg', 100, TRUE) + for(var/turf/open/floor/smashed in orange(1, src)) + smashed.ScrapeAway() + game.say("Something slams into the floor around [src], exposing it to space!") + if(game.hull) + addtimer(CALLBACK(game, .proc/fix_floor, game), 1 SECONDS) + +/datum/orion_event/hull_part/proc/fix_floor(obj/machinery/computer/arcade/orion_trail/game) + game.say("A new floor suddenly appears around [src]. What the hell?") + playsound(game, 'sound/weapons/genhit.ogg', 100, TRUE) + for(var/turf/open/space/fixed in orange(1, src)) + fixed.PlaceOnTop(/turf/open/floor/plating) + +#define BUTTON_EXPLORE_SHIP "Explore Ship" +#define BUTTON_LEAVE_THE_DERELICT "Leave the Derelict" + +/datum/orion_event/old_ship + name = "Derelict Ship" + text = "Your crew spots an old ship floating through space. \ + It might have some supplies, but then again it looks rather unsafe." + weight = 2 + event_responses = list(BUTTON_EXPLORE_SHIP, BUTTON_LEAVE_THE_DERELICT) + +/datum/orion_event/old_ship/response(obj/machinery/computer/arcade/orion_trail/game, choice) + if(choice == BUTTON_LEAVE_THE_DERELICT) + return ..() + game.encounter_event(/datum/orion_event/exploring_derelict) + +/datum/orion_event/old_ship/emag_effect(obj/machinery/computer/arcade/orion_trail/game, mob/living/carbon/gamer) + return //do nothing because this leads into an event where we actually will do something. + +#define BUTTON_WELCOME_ABOARD "Welcome aboard." +#define BUTTON_WHERE_DID_YOU_GO "Where did you go?!" +#define BUTTON_A_GOOD_FIND "A good find." +#define BUTTON_CONTINUE_TRAVELS "Continue travels." + +/datum/orion_event/exploring_derelict + name = "Derelict Exploration" + weight = 2 + //set by on_select + event_responses = list() + +/datum/orion_event/exploring_derelict/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + ..() + switch(rand(100)) + if(0 to 14) + var/rescued = game.add_crewmember() + var/oldfood = rand(1,7) + var/oldfuel = rand(4,10) + game.food += oldfood + game.fuel += oldfuel + text = "As you look through it you find some supplies and a living person! \ + [rescued] was rescued from the abandoned ship! You also found [oldfood] Food and [oldfuel] Fuel." + event_responses += BUTTON_WELCOME_ABOARD + if(15 to 35) + var/lostfuel = rand(4,7) + var/deadname = game.remove_crewmember() + game.fuel -= lostfuel + text = "[deadname] was lost deep in the wreckage, and your own vessel lost [lostfuel] Fuel maneuvering to the the abandoned ship." + event_responses += BUTTON_WHERE_DID_YOU_GO + if(36 to 65) + var/oldfood = rand(5,11) + game.food += oldfood + game.engine++ + text = "You found [oldfood] Food and some parts amongst the wreck." + event_responses += BUTTON_A_GOOD_FIND + else + text = "As you look through the wreck you cannot find much of use." + event_responses += BUTTON_CONTINUE_TRAVELS + +/datum/orion_event/exploring_derelict/response(obj/machinery/computer/arcade/orion_trail/game, choice) + event_responses.Cut() //so they don't pile up between games + ..() + +#define BUTTON_CONTINUE "Continue" + +/datum/orion_event/raiders + name = "Raiders" + weight = 3 + event_responses = list(BUTTON_CONTINUE) + +/datum/orion_event/raiders/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + ..() + text = "Raiders have come aboard your ship! " + if(prob(50)) + var/sfood = rand(1,10) + var/sfuel = rand(1,10) + game.food -= sfood + game.fuel -= sfuel + text += "They have stolen [sfood] Food and [sfuel] Fuel." + else if(prob(10)) + var/deadname = game.remove_crewmember() + text += "[deadname] tried to fight back, but was killed." + else + text += "Fortunately, you fended them off without any trouble." + +/datum/orion_event/raiders/emag_effect(obj/machinery/computer/arcade/orion_trail/game, mob/living/carbon/gamer) + if(prob(50-gamer_skill)) + to_chat(usr, "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?") + gamer.hallucination += 30 + else + to_chat(usr, "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...") + gamer.take_bodypart_damage(30) + playsound(game, 'sound/weapons/genhit2.ogg', 100, TRUE) + +/datum/orion_event/illness + name = "Space Illness" + //needs to specify who died, set by select + weight = 3 + event_responses = list(BUTTON_CONTINUE) + +/datum/orion_event/illness/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + ..() + var/deadname = game.remove_crewmember() + text = "A deadly illness has been contracted! [deadname] was killed by the disease." + +/datum/orion_event/illness/emag_effect(obj/machinery/computer/arcade/orion_trail/game, mob/living/carbon/gamer) + var/maxSeverity = 3 + if(gamer_skill_level >= SKILL_LEVEL_EXPERT) + maxSeverity = 2 //part of gitting gud is rng mitigation + var/severity = rand(1,maxSeverity) //pray to RNGesus. PRAY, PIGS + if(severity == 1) + to_chat(gamer, "You suddenly feel slightly nauseated." ) + gamer.adjust_disgust(50) + if(severity == 2) + to_chat(usr, "You suddenly feel extremely nauseated and hunch over until it passes.") + gamer.adjust_disgust(110) + gamer.Stun(60) + if(severity >= 3) //you didn't pray hard enough + to_chat(gamer, "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.") + gamer.adjust_disgust(150) //max this bitch out so they barf a lot + gamer.Stun(100) + +#define BUTTON_KEEP_SPEED "Keep Speed" +#define BUTTON_SLOW_DOWN "Slow Down" + +/datum/orion_event/flux + name = "Flux" + text = "This region of space is highly turbulent. If we go \ + slowly we may avoid more damage, but if we keep our speed we won't waste supplies." + weight = 1 + event_responses = list(BUTTON_KEEP_SPEED, BUTTON_SLOW_DOWN) + +/datum/orion_event/flux/response(obj/machinery/computer/arcade/orion_trail/game, choice) + if(choice == BUTTON_KEEP_SPEED) + if(prob(25)) + return ..() + game.encounter_event(/datum/orion_event/engine_part) + else //Slow Down response + game.food -= (game.alive+game.lings_aboard) * ORION_SHORT_DELAY + game.fuel -= 5 + ..() + +/datum/orion_event/flux/emag_effect(obj/machinery/computer/arcade/orion_trail/game, mob/living/carbon/gamer) + if(prob(25 + gamer_skill))//withstand the wind with your GAMER SKILL + to_chat(gamer, "A violent gale blows past you, and you barely manage to stay standing!") + return + gamer.Paralyze(60) + game.say("A sudden gust of powerful wind slams [gamer] into the floor!") + gamer.take_bodypart_damage(25) + playsound(game, 'sound/weapons/genhit.ogg', 100, TRUE) + +/datum/orion_event/changeling_infiltration + name = "Changeling Infiltration" + weight = 3 + event_responses = list(BUTTON_CONTINUE) + +/datum/orion_event/changeling_infiltration/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + . = ..() + text = "Strange reports warn of changelings infiltrating crews on trips to Orion..." + if(game.settlers.len <= 2) + text += " But your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..." + if(prob(10)) // "likely", I didn't say it was guaranteed! //worst outcome too because changeling controls don't even enable + game.lings_aboard = min(++game.lings_aboard,2) + else + if(game.lings_aboard) //less likely to stack lings + if(prob(20)) + game.lings_aboard = min(++game.lings_aboard,2) + else if(prob(70)) + game.lings_aboard = min(++game.lings_aboard,2) + + text += " You have reasonable suspicion there may be a changeling. Some menu options have been changed." + game.lings_suspected = TRUE + +/datum/orion_event/changeling_attack + name = "Changeling Attack" + event_responses = list(BUTTON_CONTINUE) + +/datum/orion_event/changeling_attack/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + . = ..() + text = "" + if(game.lings_aboard <= 0) //shouldn't trigger, but hey. + text = "Haha, fooled you, there are no changelings on board! (You should report this to a coder :S )" + return + var/ling1 = game.remove_crewmember() + var/ling2 = "" + if(game.lings_aboard >= 2) + ling2 = game.remove_crewmember() + if(ling2) + text = " [ling1] and [ling2]'s arms twist and contort into grotesque blades!" + else + text = " [ling1]'s arm twists and contorts into a grotesque blade!" + + var/chance2attack = game.alive*20 + if(!prob(chance2attack)) + text += " [pick("Sensing unfavorable odds", "After a failed attack", "Suddenly breaking nerve")], \ + the changeling[ling2 ? "s":""] vanish[ling2 ? "" : "es"] into space through the airlocks! You're safe... for now." + if(ling2) + game.lings_aboard = max(0,game.lings_aboard-2) + else + game.lings_aboard = max(0,game.lings_aboard - 2) + return + + var/chancetokill = 30*game.lings_aboard-(5*game.alive) //eg: 30*2-(10) = 50%, 2 lings, 2 crew is 50% chance + if(prob(chancetokill)) + var/deadguy = game.remove_crewmember() + var/murder_text = pick( + "The changeling[ling2 ? "s" : ""] bring[ling2 ? "" : "s"] down [deadguy] and disembowel[ling2 ? "" : "s"] them in a spray of gore!", \ + "[ling2 ? pick(ling1, ling2) : ling1] corners [deadguy] and impales them through the stomach!", \ + "[ling2 ? pick(ling1, ling2) : ling1] decapitates [deadguy] in a single cleaving arc!") + text += " [murder_text]" + else + text += " You valiantly fight off the changeling[ling2 ? "s":""]!" + if(ling2) + game.food += 30 + game.lings_aboard = max(0, game.lings_aboard - 2) + else + game.food += 15 + game.lings_aboard = max(0, game.lings_aboard - 1) + text += " Well, it's perfectly good food... \ + You cut the changeling[ling2 ? "s" : ""] into meat, gaining [ling2 ? "30" : "15"] Food!" + +#define BUTTON_SPEED_PAST "Speed Past" +#define BUTTON_GO_AROUND "Go Around" + +///Black Hole - final (emag can spawn singulo, see death event) +/datum/orion_event/black_hole + name = "Looming Black Hole" + text = "Sensors indicate that a black hole's gravitational field is \ + affecting the region of space we were headed through. We could stay \ + of course, but risk of being overcome by its gravity, or we could \ + change course to go around, which will take longer." + event_responses = list(BUTTON_SPEED_PAST, BUTTON_GO_AROUND) + +/datum/orion_event/black_hole/response(obj/machinery/computer/arcade/orion_trail/game, choice) + if(choice == BUTTON_GO_AROUND) + game.food -= (game.alive + game.lings_aboard) * ORION_LONG_DELAY + game.fuel -= 15 + game.turns += 1 + return ..() + if(prob(75-gamer_skill)) + game.encounter_event(/datum/orion_event/black_hole_death) + return + game.turns += 1 + ..() + +#define BUTTON_OH "Oh..." + +///You died to a black hole, have some fluff text +/datum/orion_event/black_hole_death + name = "Event Horizon" + text = "As you jet the shuttle forward, you realize you underestimated the \ + pull of the black hole. Try as you may, you cannot escape its stellar force. \ + It isn't long before you pass the event horizon, and you close your eyes, readying \ + to be torn apart as your ship begins to buckle under the pull." + event_responses = list(BUTTON_OH) + +/datum/orion_event/black_hole_death/response(obj/machinery/computer/arcade/orion_trail/game, choice) + game.set_game_over(usr, "You were swept away into the black hole.") + ..() + +/datum/orion_event/black_hole_death/emag_effect(obj/machinery/computer/arcade/orion_trail/game, mob/living/carbon/gamer) + if(game.obj_flags & EMAGGED) + playsound(game.loc, 'sound/effects/supermatter.ogg', 100, TRUE) + game.say("A miniature black hole suddenly appears in front of [game], devouring [gamer] alive!") + gamer.Stun(200, ignore_canstun = TRUE) //you can't run :^) + var/black_hole = new /obj/singularity/academy(gamer.loc) + addtimer(CALLBACK(game, /atom/movable/proc/say, "[black_hole] winks out, just as suddenly as it appeared."), 50) + QDEL_IN(black_hole, 5 SECONDS) + +#define BUTTON_DOCK "Dock" + +///You found a space port! +/datum/orion_event/space_port + name = "Space Port" + var/normal_arrival = "You have spotted a small pocket of civilization \ + along the Orion Trail. A friendly hailing from the nearby space port \ + assures that you can dock to rest and prepare for the travels ahead." + weight = 2 + event_responses = list(BUTTON_DOCK) + +/datum/orion_event/space_port/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + . = ..() + //If your crew is pathetic you can get freebies (provided you haven't already gotten one from this port) + if(game.fuel > 20 && game.food > 20) //but you don't need one + text = normal_arrival + return + text = "The workers at the Port are shocked at the state of \ + your pioneers. With supplies that low, they take pity on you and \ + your crew, generously giving you some free supplies! " + + + var/pity_fuel = 10 + var/pity_food = 10 + var/freecrew = prob(10) + if(prob(30)) + pity_fuel = 25 + pity_fuel = 25 + if(freecrew) + game.add_crewmember() + text += "(+[pity_food] fuel, +[pity_fuel] food)" + if(freecrew) + text += " A worker at the Port is inspired by your determination, and joins your crew!" + game.fuel += pity_fuel + game.food += pity_food + +/datum/orion_event/space_port/response(obj/machinery/computer/arcade/orion_trail/game, choice) + game.gameStatus = ORION_STATUS_MARKET + ..() + +///You found the midway mark! +/datum/orion_event/space_port/tau_ceti + name = "Tau Ceti Beta" + normal_arrival = "You have reached the halfway point in your journey, the largest space port \ + along the trail: Tau Ceti Beta. It bustles with activity and life. It gives you hope \ + of finding your future at Orion." + //triggered by getting halfway + weight = 0 + +///You raided a space port! +/datum/orion_event/space_port_raid + name = "Space Port Raid" + + event_responses = list(BUTTON_CONTINUE) + +/datum/orion_event/space_port_raid/on_select(obj/machinery/computer/arcade/orion_trail/game, gamer_skill, gamer_skill_level, gamer_skill_rands) + . = ..() + var/success = min(15 * game.alive + gamer_skill,100) //default crew (4) have a 60% chance + game.spaceport_raided = TRUE + + var/fuel = 0 + var/food = 0 + if(prob(success)) + fuel = rand(5 + gamer_skill_rands,15 + gamer_skill_rands) + food = rand(5 + gamer_skill_rands,15 + gamer_skill_rands) + text = "You successfully raided the spaceport! You gained [fuel] Fuel and [food] Food! (+[fuel] fuel, +[food] food)" + usr?.mind?.adjust_experience(/datum/skill/gaming, 10) + else + fuel = rand(-5,-15) + food = rand(-5,-15) + text = "You failed to raid the spaceport! You lost [fuel*-1] Fuel and [food*-1] Food in your scramble to escape! ([fuel] fuel, [food] food)" + + //your chance of lose a crewmember is 1/2 your chance of success + //this makes higher % failures hurt more, don't get cocky space cowboy! + if(prob(success*5)) + var/lost_crew = game.remove_crewmember() + if(!game.settlers.len) + game.set_game_over(usr, "You were gunned down by space port security.") + return ..() + text = "You failed to raid the spaceport! You lost [fuel*-1] Fuel and [food*-1] Food, AND [lost_crew] in your scramble to escape! ([fuel]fuel, [food] food, -Crew)" + if(game.obj_flags & EMAGGED) + game.say("WEEWOO! WEEWOO! Spaceport security en route!") + playsound(game, 'sound/items/weeoo1.ogg', 100, FALSE) + for(var/i, i<=3, i++) + var/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion/spaceport_security = new(get_turf(src)) + spaceport_security.target = usr + game.fuel += fuel + game.food += food + diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index 72f33d4c5ed..427ff037b8f 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -165,7 +165,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( flags |= CHANGETURF_RECALC_ADJACENT return ..() -// Take off the top layer turf and replace it with the next baseturf down +/// Take off the top layer turf and replace it with the next baseturf down /turf/proc/ScrapeAway(amount=1, flags) if(!amount) return diff --git a/code/modules/asset_cache/asset_list.dm b/code/modules/asset_cache/asset_list.dm index 94ffbb318cc..b2583ca12ec 100644 --- a/code/modules/asset_cache/asset_list.dm +++ b/code/modules/asset_cache/asset_list.dm @@ -169,6 +169,8 @@ GLOBAL_LIST_EMPTY(asset_datums) I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving) if (!I || !length(icon_states(I))) // that direction or state doesn't exist return + //any sprite modifications we want to do (aka, coloring a greyscaled asset) + I = ModifyInserted(I) var/size_id = "[I.Width()]x[I.Height()]" var/size = sizes[size_id] @@ -185,6 +187,15 @@ GLOBAL_LIST_EMPTY(asset_datums) sizes[size_id] = size = list(1, I, null) sprites[sprite_name] = list(size_id, 0) +/** + * A simple proc handing the Icon for you to modify before it gets turned into an asset. + * + * Arguments: + * * I: icon being turned into an asset + */ +/datum/asset/spritesheet/proc/ModifyInserted(icon/pre_asset) + return pre_asset + /datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions) if (length(prefix)) prefix = "[prefix]-" diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index f72a05cd762..62b8c60851f 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -529,3 +529,32 @@ assets = list( "chem_help_advisor.gif" = 'icons/UI_Icons/Advisors/chem_help_advisor.gif', ) + +/datum/asset/spritesheet/moods + name = "moods" + var/iconinserted = 1 + +/datum/asset/spritesheet/moods/register() + for(var/i in 1 to 9) + var/target_to_insert = "mood"+"[iconinserted]" + Insert(target_to_insert, 'icons/hud/screen_gen.dmi', target_to_insert) + iconinserted++ + ..() + +/datum/asset/spritesheet/moods/ModifyInserted(icon/pre_asset) + var/blended_color + switch(iconinserted) + if(1) + blended_color = "#f15d36" + if(2 to 3) + blended_color = "#f38943" + if(4) + blended_color = "#dfa65b" + if(5) + blended_color = "#4b96c4" + if(6) + blended_color = "#86d656" + else + blended_color = "#2eeb9a" + pre_asset.Blend(blended_color, ICON_MULTIPLY) + return pre_asset diff --git a/tgstation.dme b/tgstation.dme index 5e7c7578760..d9797bdf7c7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -937,7 +937,6 @@ #include "code\game\machinery\computer\_computer.dm" #include "code\game\machinery\computer\aifixer.dm" #include "code\game\machinery\computer\apc_control.dm" -#include "code\game\machinery\computer\arcade.dm" #include "code\game\machinery\computer\arena.dm" #include "code\game\machinery\computer\atmos_alert.dm" #include "code\game\machinery\computer\atmos_control.dm" @@ -959,6 +958,9 @@ #include "code\game\machinery\computer\teleporter.dm" #include "code\game\machinery\computer\tram_controls.dm" #include "code\game\machinery\computer\warrant.dm" +#include "code\game\machinery\computer\arcade\arcade.dm" +#include "code\game\machinery\computer\arcade\orion.dm" +#include "code\game\machinery\computer\arcade\orion_event.dm" #include "code\game\machinery\computer\chef_orders\chef_order.dm" #include "code\game\machinery\computer\chef_orders\order_datum.dm" #include "code\game\machinery\computer\prisoner\_prisoner.dm" diff --git a/tgui/packages/tgui/interfaces/OrionGame.js b/tgui/packages/tgui/interfaces/OrionGame.js new file mode 100644 index 00000000000..189433c4090 --- /dev/null +++ b/tgui/packages/tgui/interfaces/OrionGame.js @@ -0,0 +1,636 @@ +import { multiline } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Box, Button, Dimmer, Divider, Icon, NumberInput, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +const buttonWidth = 2; + +const goodstyle = { + color: 'lightgreen', + fontWeight: 'bold', +}; + +const badstyle = { + color: 'red', + fontWeight: 'bold', +}; + +const partstyle = { + color: 'yellow', + fontWeight: 'bold', +}; + +const fuelstyle = { + color: 'olive', + fontWeight: 'bold', +}; + +const variousButtonIcons = { + "Restore Hull": "wrench", + "Fix Engine": "rocket", + "Repair Electronics": "server", + "Wait": "clock", + "Continue": "arrow-right", + "Explore Ship": "door-open", + "Leave the Derelict": "arrow-right", + "Welcome aboard.": "user-plus", + "Where did you go?!": "user-minus", + "A good find.": "box-open", + "Continue travels.": "arrow-right", + "Keep Speed": "tachometer-alt", + "Slow Down": "arrow-left", + "Speed Past": "tachometer-alt", + "Go Around": "redo", + "Oh...": "circle", + "Dock": "dollar-sign", +}; + +const STATUS2COMPONENT = [ + { component: () => ORION_STATUS_START }, + { component: () => ORION_STATUS_INSTRUCTIONS }, + { component: () => ORION_STATUS_NORMAL }, + { component: () => ORION_STATUS_GAMEOVER }, + { component: () => ORION_STATUS_MARKET }, +]; + +const locationInfo = [ + { + title: "Pluto", + blurb: "Pluto, long since occupied with long-range sensors and scanners, stands ready to, and indeed continues to probe the far reaches of the galaxy.", + }, + { + title: "Asteroid Belt", + blurb: "At the edge of the Sol system lies a treacherous asteroid belt. Many have been crushed by stray asteroids and misguided judgement.", + }, + { + title: "Proxima Centauri", + blurb: "The nearest star system to Sol, in ages past it stood as a reminder of the boundaries of sub-light travel, now a low-population sanctuary for adventurers and traders.", + }, + { + title: "Dead Space", + blurb: "This region of space is particularly devoid of matter. Such low-density pockets are known to exist, but the vastness of it is astounding.", + }, + { + title: "Rigel Prime", + blurb: "Rigel Prime, the center of the Rigel system, burns hot, basking its planetary bodies in warmth and radiation.", + }, + { + title: "Tau Ceti Beta", + blurb: "Tau Ceti Beta has recently become a waypoint for colonists headed towards Orion. There are many ships and makeshift stations in the vicinity.", + }, + { + title: "Space Bugs", + blurb: "You see some space bugs out your window. They contort in various reality bending ways, and it makes you sick. You know it's Galactic Policy to report all sightings of space bugs.", + }, + { + title: "Space Outpost Beta-9", + blurb: "You have come into range of the first man-made structure in this region of space. It has been constructed not by travellers from Sol, but by colonists from Orion. It stands as a monument to the colonists' success.", + }, + { + title: "Orion Prime", + blurb: "You have made it to Orion! Congratulations! Your crew is one of the few to start a new foothold for mankind!", + }, +]; + +const AdventureStatus = (props, context) => { + const { data, act } = useBackend(context); + const { + lings_suspected, + eventname, + settlers, + settlermoods, + hull, + electronics, + engine, + food, + fuel, + } = data; + return ( +
act('random_kill')} /> + ) + )} > + + + {settlers?.map(settler => ( + + + {settler} + + +
+ ); +}; + +const ORION_STATUS_START = (props, context) => { + const { data, act } = useBackend(context); + const { + gamename, + } = data; + return ( +
+ + + + {gamename} + + + {"\"Experience the journey of your ancestors!\""} + + +
+ ); +}; + +const ORION_STATUS_INSTRUCTIONS = (props, context) => { + const { act } = useBackend(context); + const fake_settlers = ["John", "William", "Alice", "Tom"]; + return ( + + +
act('back_to_menu')} /> + )}> + + In the 2200's, the Orion trail was established as a dangerous + yet opportunistic trail through space for those willing to risk it. + Many pioneers seeking new lives on the galactic frontier would find + exactly what they were seeking... or lose their lives on the way. + +
+
+ +
+ + + {fake_settlers?.map(settler => ( + + + {settler} + + +
+
+ +
+ + + If you want to make it to Orion, + you'll need to manage your resources: +
+ Food: Your crewmembers consume + it. More crew means this goes down faster! +
+ Fuel: You use 5u of fuel with + every movement. Don't let it run out. +
+ Parts: Used to repair breakdowns. + Nobody likes wasting time on repairs! +
+ + + + +
+
+
+ ); +}; + +const ORION_STATUS_NORMAL = (props, context) => { + const { data, act } = useBackend(context); + const { + settlers, + settlermoods, + hull, + electronics, + engine, + food, + fuel, + turns, + eventname, + eventtext, + buttons, + } = data; + return ( + + +
+ + + + {!!eventname && eventname || locationInfo[turns-1].title} + +
+ + {!!eventtext && eventtext || locationInfo[turns-1].blurb} + +
+ + {!!buttons && ( + buttons.map(button => ( + +
+
+ + + +
+ ); +}; + +const ORION_STATUS_GAMEOVER = (props, context) => { + const { data, act } = useBackend(context); + const { + reason, + } = data; + return ( +
+ + + + {"Game Over"} + + + {reason} + + +
+ ); +}; + +const marketButtonSpacing = 0.8; + +const ORION_STATUS_MARKET = (props, context) => { + const { data, act } = useBackend(context); + const { + turns, + spaceport_raided, + } = data; + return ( + + +
+
+
+ + + +
+ ); +}; + +export const OrionGame = (props, context) => { + const { act, data } = useBackend(context); + const { + gamestatus, + gamename, + eventname, + } = data; + const GameStatusComponent = STATUS2COMPONENT[gamestatus].component(); + const MarketRaid = STATUS2COMPONENT[2].component(); + return ( + + + {eventname === "Space Port Raid" && ( + + ) || ( + + )} + + + ); +};