#pragma once #include "audio.h" #include "balance.h" #include "chat.h" #include "menu.h" #include "effects.h" #include "input.h" #include "net.h" #include "renderer.h" #include "rollback.h" #include "scene.h" #include "session.h" #include "settings.h" #include "sim.h" #include "sprites.h" #include "stats.h" #include "text.h" #include "ui.h" constexpr float PVP_OFF_SHADE = 0.4f; // How a fighter's color is asked for: as it shows in the world (darkened when PvP keeps it out of this screen's // fights), or plain, as the HUD shows it. enum Tint { TINT_PVP, TINT_PLAIN }; // Every manager in one place, so systems can reach each other through a single reference. // Devices say which input plays each fighter on this screen (none for bots). Sim is the game being // played, saved in snapshots. Local is the fighter this screen // controls and follows. Camera, alpha, settings and the window are presentation. Alpha is how far drawing sits between // the previous tick and the current one. Net is the connection to the server and other players. struct Game { Audio audio; Balance balance; Chat chat; Menu menu; Effects effects; Input input; Net net; Renderer renderer; Rollback rollback; Settings settings; Scene scene{*this}; Session session; Sim sim; Sprites sprites; Stats stats; Text text; Ui ui; Vec2 camera; Vec2 cameraPrevious; float alpha = 1; int devices[MAX_FIGHTERS]; int local = 0; SDL_Window* window = nullptr; // This screen starts with the keyboard playing the first fighter. Game() { std::fill(std::begin(devices), std::end(devices), DEVICE_NONE); devices[0] = DEVICE_KEYBOARD; } Fighter& local_get() { return sim.fighters[local]; } // Whether a fighter is played on this screen, by its keyboard and mouse or one of its gamepads. bool is_local(int fighter) { return fighter < sim.fighterCount && devices[fighter] != DEVICE_NONE && !sim.fighters[fighter].isBot; } int local_count() { int count = 0; for (int i = 0; i < sim.fighterCount; i++) count += is_local(i); return count; } // A fighter's color: its match color (handed out when the match starts), or in the sandbox this screen's own // (picked in Profile, white while unassigned) until others join, when everyone // gets one. With others in the sandbox, everything of another fighter is darkened on this screen unless it and this // screen's own both have PvP on (so they can hurt each other); this screen's own always shows in full. Asked for // plain (TINT_PLAIN, as the HUD's tint is), it's never darkened. Color color_get(int fighter, Tint tint = TINT_PVP) { if (sim.match.state == MATCH_PRACTICE && sim.fighterCount == 1) { int color = settings.color_get(); return color >= 0 ? PALETTE[color] : WHITE; } Color color = PALETTE[sim.match.colors[fighter]]; bool isHostile = sim.fighters[fighter].isPvp && sim.fighters[local].isPvp; bool isPeaceful = tint == TINT_PVP && fighter != local && sim.match.state == MATCH_PRACTICE && !isHostile; return isPeaceful ? color_shade(color, PVP_OFF_SHADE) : color; } // What a fighter wears: in the sandbox alone, what Profile has picked, otherwise what the match has them in. int fashion_get(int fighter) { bool isAlone = sim.match.state == MATCH_PRACTICE && sim.fighterCount == 1; return isAlone ? settings.fashion : sim.match.fashions[fighter]; } }; void game_tick(Game& game);