Deal items on ready, /pvp, and calmer rival windows
- Readying in a countdown deals any empty slots at random right away, and the countdown reads "Starting..." once everyone is ready. - /pvp toggles PvP in the sandbox, offline or in a lobby. - Rival windows sit at half opacity (half again when knocked out, and when hovered), show no item tooltips, and drop to small icons past two full-size rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6f112ab231
commit
5d6ebf2bba
5 files changed
+77
-68
No files matched your search
@@ -238,8 +238,18 @@ void Chat::command(Game& game, const std::string& text)
|
|||||||
system("/color <colour>: Changes your colour. Colours: Red, Blue, Yellow, Green, Orange, Purple, Cyan, Pink, "
|
system("/color <colour>: Changes your colour. Colours: Red, Blue, Yellow, Green, Orange, Purple, Cyan, Pink, "
|
||||||
"Lime, Teal, Magenta, Sky, Peach, Lavender, Brown, Silver.");
|
"Lime, Teal, Magenta, Sky, Peach, Lavender, Brown, Silver.");
|
||||||
system("/kick \"<player>\" \"<reason>\": Removes a player from the lobby (host only).");
|
system("/kick \"<player>\" \"<reason>\": Removes a player from the lobby (host only).");
|
||||||
|
system("/pvp: Turns PvP on or off in the sandbox.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (name == "/pvp")
|
||||||
|
{
|
||||||
|
if (game.sim.match.state != MATCH_PRACTICE)
|
||||||
|
return system("PvP can only be changed in the sandbox.");
|
||||||
|
// Sent through this screen's controls like the menu's toggle, so every machine sees it on the same tick.
|
||||||
|
bool isPvp = !game.local_get().isPvp;
|
||||||
|
game.input.edit_send(game.devices[game.local], edit_encode({.type = EDIT_PVP, .value = isPvp}));
|
||||||
|
return system(isPvp ? "PvP is now on." : "PvP is now off.");
|
||||||
|
}
|
||||||
if (name == "/kick")
|
if (name == "/kick")
|
||||||
{
|
{
|
||||||
if (words.size() < 2)
|
if (words.size() < 2)
|
||||||
|
|||||||
+27
-13
@@ -140,14 +140,17 @@ void Match::update(Sim& sim)
|
|||||||
break;
|
break;
|
||||||
case MATCH_COUNTDOWN:
|
case MATCH_COUNTDOWN:
|
||||||
{
|
{
|
||||||
// Ready sticks once pressed, and bots always are. Once everyone is, the wait drops to its last second.
|
// Ready sticks once pressed, and bots always are. Readying deals any slots still empty at random. Once
|
||||||
// Fighters choosing items pick them through their controls.
|
// everyone is, the wait drops to its last second. Fighters choosing items pick them through their controls.
|
||||||
bool isEveryone = true;
|
bool isEveryone = true;
|
||||||
for (int i = 0; i < sim.fighterCount; i++)
|
for (int i = 0; i < sim.fighterCount; i++)
|
||||||
{
|
{
|
||||||
Fighter& fighter = sim.fighters[i];
|
Fighter& fighter = sim.fighters[i];
|
||||||
edit_take(sim, fighter);
|
edit_take(sim, fighter);
|
||||||
|
bool wasReady = isReady[i];
|
||||||
isReady[i] |= fighter.isBot || fighter.is_down(CONTROL_READY);
|
isReady[i] |= fighter.isBot || fighter.is_down(CONTROL_READY);
|
||||||
|
if (isReady[i] && !wasReady)
|
||||||
|
loadout_deal(sim, i);
|
||||||
isEveryone &= isReady[i];
|
isEveryone &= isReady[i];
|
||||||
}
|
}
|
||||||
if (isEveryone)
|
if (isEveryone)
|
||||||
@@ -421,20 +424,31 @@ void Match::mirror_copy(Sim& sim, bool isTrinket)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The countdown is over: slots still empty after choosing are dealt at random (once, and shared, when mirrored), and
|
// Deals a fighter's empty slots at random. A mirrored kind is dealt only to the first fighter, and copied to everyone.
|
||||||
// the menu closes.
|
void Match::loadout_deal(Sim& sim, int index)
|
||||||
|
{
|
||||||
|
Fighter& fighter = sim.fighters[index];
|
||||||
|
for (int kind = 0; kind < 2; kind++)
|
||||||
|
{
|
||||||
|
bool isTrinket = kind == 1;
|
||||||
|
ItemRules& items = isTrinket ? rules.trinkets : rules.weapons;
|
||||||
|
if (items.isMirror && index > 0)
|
||||||
|
continue;
|
||||||
|
if (isTrinket)
|
||||||
|
picks_deal(sim.rng, fighter.trinketLoadout, fighter.trinketSlots, TRINKET_COUNT, items.isDuplicates);
|
||||||
|
else
|
||||||
|
picks_deal(sim.rng, fighter.weaponLoadout, fighter.weaponSlots, WEAPON_COUNT, items.isDuplicates);
|
||||||
|
if (items.isMirror)
|
||||||
|
mirror_copy(sim, isTrinket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The countdown is over: slots still empty after choosing (by anyone who never readied) are dealt at random, and the
|
||||||
|
// menu closes.
|
||||||
void Match::fight_start(Sim& sim)
|
void Match::fight_start(Sim& sim)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < sim.fighterCount; i++)
|
for (int i = 0; i < sim.fighterCount; i++)
|
||||||
{
|
loadout_deal(sim, i);
|
||||||
Fighter& fighter = sim.fighters[i];
|
|
||||||
picks_deal(sim.rng, fighter.weaponLoadout, fighter.weaponSlots, WEAPON_COUNT, rules.weapons.isDuplicates);
|
|
||||||
picks_deal(sim.rng, fighter.trinketLoadout, fighter.trinketSlots, TRINKET_COUNT, rules.trinkets.isDuplicates);
|
|
||||||
if (i == 0 && rules.weapons.isMirror)
|
|
||||||
mirror_copy(sim, false);
|
|
||||||
if (i == 0 && rules.trinkets.isMirror)
|
|
||||||
mirror_copy(sim, true);
|
|
||||||
}
|
|
||||||
if (isWeaponPick || isTrinketPick)
|
if (isWeaponPick || isTrinketPick)
|
||||||
sim.cues->choice_close();
|
sim.cues->choice_close();
|
||||||
isWeaponPick = false;
|
isWeaponPick = false;
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ private:
|
|||||||
void fight_start(Sim& sim);
|
void fight_start(Sim& sim);
|
||||||
void edit_take(Sim& sim, Fighter& fighter);
|
void edit_take(Sim& sim, Fighter& fighter);
|
||||||
void mirror_copy(Sim& sim, bool isTrinket);
|
void mirror_copy(Sim& sim, bool isTrinket);
|
||||||
|
void loadout_deal(Sim& sim, int fighter);
|
||||||
void deathmatch_update(Sim& sim);
|
void deathmatch_update(Sim& sim);
|
||||||
void race_update(Sim& sim);
|
void race_update(Sim& sim);
|
||||||
void queues_update(Sim& sim);
|
void queues_update(Sim& sim);
|
||||||
|
|||||||
+37
-53
@@ -14,7 +14,8 @@ constexpr float RIVAL_BAR_MIN = 16;
|
|||||||
constexpr float RIVAL_DIVIDER = 1;
|
constexpr float RIVAL_DIVIDER = 1;
|
||||||
constexpr float RIVAL_GAP = 4;
|
constexpr float RIVAL_GAP = 4;
|
||||||
constexpr float RIVAL_ICON_GAP = 2;
|
constexpr float RIVAL_ICON_GAP = 2;
|
||||||
constexpr float RIVAL_OUT_ALPHA = 0.25f;
|
constexpr float RIVAL_ALPHA = 0.5f;
|
||||||
|
constexpr float RIVAL_OUT_SHARE = 0.5f;
|
||||||
constexpr float SPECTATE_GAP = 4;
|
constexpr float SPECTATE_GAP = 4;
|
||||||
constexpr Control SPECTATE_CONTROLS[] = {CONTROL_LEFT, CONTROL_RIGHT, CONTROL_ATTACK};
|
constexpr Control SPECTATE_CONTROLS[] = {CONTROL_LEFT, CONTROL_RIGHT, CONTROL_ATTACK};
|
||||||
constexpr float HUD_IDLE_ALPHA = 0.5f;
|
constexpr float HUD_IDLE_ALPHA = 0.5f;
|
||||||
@@ -25,6 +26,8 @@ constexpr int RIVAL_COLUMNS_MAX = 3;
|
|||||||
// What the other fighters' windows try, from largest to smallest, until they all fit in a couple of rows: shrinking
|
// What the other fighters' windows try, from largest to smallest, until they all fit in a couple of rows: shrinking
|
||||||
// icons before the font, then leaving the icons out.
|
// icons before the font, then leaving the icons out.
|
||||||
constexpr int RIVAL_ROWS_MAX = 2;
|
constexpr int RIVAL_ROWS_MAX = 2;
|
||||||
|
// The most rows of full-size icons the windows can stack up between them before the icons shrink.
|
||||||
|
constexpr int RIVAL_FULL_ICON_ROWS_MAX = 2;
|
||||||
constexpr int RIVAL_STYLES = 6;
|
constexpr int RIVAL_STYLES = 6;
|
||||||
constexpr int RIVAL_ICON_STYLES = 4;
|
constexpr int RIVAL_ICON_STYLES = 4;
|
||||||
constexpr Font RIVAL_FONTS[RIVAL_STYLES] = {FONT_SMALL, FONT_SMALL, FONT_TINY, FONT_TINY, FONT_SMALL, FONT_TINY};
|
constexpr Font RIVAL_FONTS[RIVAL_STYLES] = {FONT_SMALL, FONT_SMALL, FONT_TINY, FONT_TINY, FONT_SMALL, FONT_TINY};
|
||||||
@@ -393,7 +396,7 @@ void Ui::match_draw(Game& game)
|
|||||||
if (game.menu.isOpen)
|
if (game.menu.isOpen)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SDL_snprintf(text, sizeof(text), "%s %d", info.round, info.seconds);
|
SDL_snprintf(text, sizeof(text), "%s %s", info.round, info.time);
|
||||||
text_center_draw(game, text, y, ROUND_SCALE);
|
text_center_draw(game, text, y, ROUND_SCALE);
|
||||||
y += game.text.line_height_get(FONT_SMALL, ROUND_SCALE) + READY_GAP;
|
y += game.text.line_height_get(FONT_SMALL, ROUND_SCALE) + READY_GAP;
|
||||||
SDL_snprintf(text, sizeof(text), isLocalReady ? "%d/%d Ready" : "%d/%d Ready - Press %s to Ready Up",
|
SDL_snprintf(text, sizeof(text), isLocalReady ? "%d/%d Ready" : "%d/%d Ready - Press %s to Ready Up",
|
||||||
@@ -731,7 +734,8 @@ void Ui::loadout_draw(Game& game, float alpha, float top)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Text centred across the canvas with its top at y.
|
// Text centred across the canvas with its top at y.
|
||||||
// What the countdown shows: the round's name, whole seconds left, how many are ready, and the key that readies up.
|
// What the countdown shows: the round's name, whole seconds left (or Starting... once everyone's ready), how many are
|
||||||
|
// ready, and the key that readies up.
|
||||||
static CountdownInfo countdown_info_get(Game& game, bool isPad)
|
static CountdownInfo countdown_info_get(Game& game, bool isPad)
|
||||||
{
|
{
|
||||||
Match& match = game.sim.match;
|
Match& match = game.sim.match;
|
||||||
@@ -742,9 +746,12 @@ static CountdownInfo countdown_info_get(Game& game, bool isPad)
|
|||||||
SDL_strlcpy(info.round, "Final Round", sizeof(info.round));
|
SDL_strlcpy(info.round, "Final Round", sizeof(info.round));
|
||||||
else
|
else
|
||||||
SDL_snprintf(info.round, sizeof(info.round), "Round %d", match.round + 1);
|
SDL_snprintf(info.round, sizeof(info.round), "Round %d", match.round + 1);
|
||||||
info.seconds = (int)std::ceil(match.timer);
|
|
||||||
for (int i = 0; i < game.sim.fighterCount; i++)
|
for (int i = 0; i < game.sim.fighterCount; i++)
|
||||||
info.ready += match.isReady[i];
|
info.ready += match.isReady[i];
|
||||||
|
if (info.ready == game.sim.fighterCount)
|
||||||
|
SDL_strlcpy(info.time, "Starting...", sizeof(info.time));
|
||||||
|
else
|
||||||
|
SDL_snprintf(info.time, sizeof(info.time), "%d", (int)std::ceil(match.timer));
|
||||||
Binding binding = game.input.bindings[CONTROL_READY];
|
Binding binding = game.input.bindings[CONTROL_READY];
|
||||||
game.input.binding_name_get(isPad ? binding.pad : binding.key, isPad, info.key, sizeof(info.key));
|
game.input.binding_name_get(isPad ? binding.pad : binding.key, isPad, info.key, sizeof(info.key));
|
||||||
return info;
|
return info;
|
||||||
@@ -758,7 +765,6 @@ void Ui::countdown_aside_draw(Game& game, bool isPad)
|
|||||||
{
|
{
|
||||||
CountdownInfo info = countdown_info_get(game, isPad);
|
CountdownInfo info = countdown_info_get(game, isPad);
|
||||||
const char* round = info.round;
|
const char* round = info.round;
|
||||||
int seconds = info.seconds;
|
|
||||||
int ready = info.ready;
|
int ready = info.ready;
|
||||||
const char* key = game.sim.match.isReady[game.local] ? nullptr : info.key;
|
const char* key = game.sim.match.isReady[game.local] ? nullptr : info.key;
|
||||||
float margin = (CANVAS_WIDTH - MENU_WIDTH) / 2;
|
float margin = (CANVAS_WIDTH - MENU_WIDTH) / 2;
|
||||||
@@ -771,16 +777,20 @@ void Ui::countdown_aside_draw(Game& game, bool isPad)
|
|||||||
return game.text.line_height_get(FONT_SMALL, scale);
|
return game.text.line_height_get(FONT_SMALL, scale);
|
||||||
};
|
};
|
||||||
|
|
||||||
float labelScale = game.text.size_get(round, FONT_SMALL, ASIDE_LABEL_SCALE).x <= margin - ASIDE_PADDING * 2
|
// Each line at the largest size that fits the margin.
|
||||||
? ASIDE_LABEL_SCALE
|
auto scale_fit = [&](const char* line, float scale) {
|
||||||
: 1;
|
for (; scale > 1; scale--)
|
||||||
float height =
|
if (game.text.size_get(line, FONT_SMALL, scale).x <= margin - ASIDE_PADDING * 2)
|
||||||
game.text.line_height_get(FONT_SMALL, labelScale) + game.text.line_height_get(FONT_SMALL, ROUND_SCALE);
|
break;
|
||||||
|
return scale;
|
||||||
|
};
|
||||||
|
float labelScale = scale_fit(round, ASIDE_LABEL_SCALE);
|
||||||
|
float timeScale = scale_fit(info.time, ROUND_SCALE);
|
||||||
|
float height = game.text.line_height_get(FONT_SMALL, labelScale) + game.text.line_height_get(FONT_SMALL, timeScale);
|
||||||
float y = middle - height / 2;
|
float y = middle - height / 2;
|
||||||
y += line_draw(round, margin / 2, y, labelScale);
|
y += line_draw(round, margin / 2, y, labelScale);
|
||||||
|
line_draw(info.time, margin / 2, y, timeScale);
|
||||||
char text[TOOLTIP_LENGTH];
|
char text[TOOLTIP_LENGTH];
|
||||||
SDL_snprintf(text, sizeof(text), "%d", seconds);
|
|
||||||
line_draw(text, margin / 2, y, ROUND_SCALE);
|
|
||||||
|
|
||||||
float rightX = CANVAS_WIDTH - margin / 2;
|
float rightX = CANVAS_WIDTH - margin / 2;
|
||||||
y = middle - (key ? LINE_HEIGHT * 3 : LINE_HEIGHT) / 2;
|
y = middle - (key ? LINE_HEIGHT * 3 : LINE_HEIGHT) / 2;
|
||||||
@@ -1177,12 +1187,12 @@ static void effects_preview_get(Game& game, const char* now, const char* next, c
|
|||||||
|
|
||||||
// Name, numbers at a level and description of a weapon or trinket. Trinkets say how many copies are equipped, and
|
// Name, numbers at a level and description of a weapon or trinket. Trinkets say how many copies are equipped, and
|
||||||
// when they stack.
|
// when they stack.
|
||||||
Tooltip Ui::tooltip_build(Game& game, bool isTrinket, int item, int level, int owner)
|
Tooltip Ui::tooltip_build(Game& game, bool isTrinket, int item, int level)
|
||||||
{
|
{
|
||||||
Tooltip tooltip;
|
Tooltip tooltip;
|
||||||
tooltip.isTrinket = isTrinket;
|
tooltip.isTrinket = isTrinket;
|
||||||
tooltip.item = item;
|
tooltip.item = item;
|
||||||
Fighter& fighter = owner >= 0 ? game.sim.fighters[owner] : game.local_get();
|
Fighter& fighter = game.local_get();
|
||||||
int* loadout = isTrinket ? fighter.trinketLoadout : fighter.weaponLoadout;
|
int* loadout = isTrinket ? fighter.trinketLoadout : fighter.weaponLoadout;
|
||||||
int slots = isTrinket ? fighter.trinketSlots : fighter.weaponSlots;
|
int slots = isTrinket ? fighter.trinketSlots : fighter.weaponSlots;
|
||||||
tooltip.slot = std::find(loadout, loadout + slots, item) - loadout;
|
tooltip.slot = std::find(loadout, loadout + slots, item) - loadout;
|
||||||
@@ -2271,10 +2281,11 @@ static float rival_ping_get(Game& game, int fighter)
|
|||||||
|
|
||||||
// Lays out the other fighters' windows in the HUD's right column, from the bottom up to the readouts above, in no more
|
// Lays out the other fighters' windows in the HUD's right column, from the bottom up to the readouts above, in no more
|
||||||
// than two rows: as many to a row as fit across (the rows as even as they go). A window is as wide as its icons, name
|
// than two rows: as many to a row as fit across (the rows as even as they go). A window is as wide as its icons, name
|
||||||
// or health (with its connection's bars, online). Without icons, the health number can go to make room. When they don't
|
// or health (with its connection's bars, online). Without icons, the health number can go to make room. Full-size
|
||||||
// all fit, the icons shrink to small, then the font to tiny, then the icons to tiny, then the icons are left out. Each
|
// icons stack no more than two rows deep across the windows. When they don't all fit, the icons shrink to small, then
|
||||||
// kind of icon wraps onto more rows past three across, and tiny icons wrap further if they still don't fit. If even
|
// the font to tiny, then the icons to tiny, then the icons are left out. Each kind of icon wraps onto more rows past
|
||||||
// names and health alone don't fit, the windows split the column evenly and the names are cut short.
|
// three across, and tiny icons wrap further if they still don't fit. If even names and health alone don't fit, the
|
||||||
|
// windows split the column evenly and the names are cut short.
|
||||||
RivalLayout Ui::rivals_layout(Game& game)
|
RivalLayout Ui::rivals_layout(Game& game)
|
||||||
{
|
{
|
||||||
RivalLayout layout;
|
RivalLayout layout;
|
||||||
@@ -2336,7 +2347,8 @@ RivalLayout Ui::rivals_layout(Game& game)
|
|||||||
perRow = std::clamp((int)((HUD_COLUMN_WIDTH + RIVAL_GAP) / (width + RIVAL_GAP)), 1, layout.count);
|
perRow = std::clamp((int)((HUD_COLUMN_WIDTH + RIVAL_GAP) / (width + RIVAL_GAP)), 1, layout.count);
|
||||||
int cardRows = (layout.count + perRow - 1) / perRow;
|
int cardRows = (layout.count + perRow - 1) / perRow;
|
||||||
perRow = (layout.count + cardRows - 1) / cardRows;
|
perRow = (layout.count + cardRows - 1) / cardRows;
|
||||||
isFit = width <= HUD_COLUMN_WIDTH && cardRows <= RIVAL_ROWS_MAX &&
|
bool isFullTall = layout.size == ICON_FULL && cardRows * layout.rows > RIVAL_FULL_ICON_ROWS_MAX;
|
||||||
|
isFit = width <= HUD_COLUMN_WIDTH && cardRows <= RIVAL_ROWS_MAX && !isFullTall &&
|
||||||
cardRows * (height + RIVAL_GAP) - RIVAL_GAP <= room;
|
cardRows * (height + RIVAL_GAP) - RIVAL_GAP <= room;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2359,9 +2371,8 @@ RivalLayout Ui::rivals_layout(Game& game)
|
|||||||
|
|
||||||
// Every other fighter's window in a match, bordered in its colour: its name centred (cut short if it doesn't fit), its
|
// Every other fighter's window in a match, bordered in its colour: its name centred (cut short if it doesn't fit), its
|
||||||
// health (online with its connection's bars after), then (with room) its weapons, a divider, and its trinkets, the
|
// health (online with its connection's bars after), then (with room) its weapons, a divider, and its trinkets, the
|
||||||
// weapon in hand lit. Each is laid over the game as one piece,
|
// weapon in hand lit. Each is laid over the game as one piece, half see-through (half again for a fighter out of the
|
||||||
// see-through for a fighter out of the round, and fades while the mouse is over it. Hovering an icon shows the item's
|
// round), and fades by half again while the mouse is over it.
|
||||||
// tooltip, as that fighter has it, in its colour.
|
|
||||||
void Ui::rivals_draw(Game& game)
|
void Ui::rivals_draw(Game& game)
|
||||||
{
|
{
|
||||||
Match& match = game.sim.match;
|
Match& match = game.sim.match;
|
||||||
@@ -2372,15 +2383,12 @@ void Ui::rivals_draw(Game& game)
|
|||||||
float inset = PANEL_BORDER + RIVAL_PADDING;
|
float inset = PANEL_BORDER + RIVAL_PADDING;
|
||||||
float iconSize = ICON_PIXELS[layout.size];
|
float iconSize = ICON_PIXELS[layout.size];
|
||||||
float cell = iconSize + RIVAL_ICON_GAP;
|
float cell = iconSize + RIVAL_ICON_GAP;
|
||||||
int hoveredFighter = -1;
|
|
||||||
int hoveredKind = 0;
|
|
||||||
int hoveredSlot = 0;
|
|
||||||
for (int k = 0; k < layout.count; k++)
|
for (int k = 0; k < layout.count; k++)
|
||||||
{
|
{
|
||||||
int index = layout.fighters[k];
|
int index = layout.fighters[k];
|
||||||
Fighter& fighter = game.sim.fighters[index];
|
Fighter& fighter = game.sim.fighters[index];
|
||||||
Rect card = layout.cards[k];
|
Rect card = layout.cards[k];
|
||||||
float base = fighter.isAlive || match.is_racing() || index == spectated ? 1 : RIVAL_OUT_ALPHA;
|
float base = RIVAL_ALPHA * (fighter.isAlive || match.is_racing() || index == spectated ? 1 : RIVAL_OUT_SHARE);
|
||||||
Color color = game.color_get(index);
|
Color color = game.color_get(index);
|
||||||
Color dim = color_shade(color, SECONDARY_SHADE);
|
Color dim = color_shade(color, SECONDARY_SHADE);
|
||||||
renderer.layer_begin();
|
renderer.layer_begin();
|
||||||
@@ -2446,21 +2454,13 @@ void Ui::rivals_draw(Game& game)
|
|||||||
int* loadout = isTrinket ? fighter.trinketLoadout : fighter.weaponLoadout;
|
int* loadout = isTrinket ? fighter.trinketLoadout : fighter.weaponLoadout;
|
||||||
for (int slot = 0; slot < slots; slot++)
|
for (int slot = 0; slot < slots; slot++)
|
||||||
{
|
{
|
||||||
Rect box = {x + slot % layout.columns[kind] * cell, y + slot / layout.columns[kind] * cell, iconSize,
|
|
||||||
iconSize};
|
|
||||||
int item = loadout[slot];
|
int item = loadout[slot];
|
||||||
if (item < 0)
|
if (item < 0)
|
||||||
continue;
|
continue;
|
||||||
bool isLit = isTrinket || slot == fighter.slot;
|
bool isLit = isTrinket || slot == fighter.slot;
|
||||||
icon_draw(game, isTrinket, item,
|
Vec2 centre = {x + slot % layout.columns[kind] * cell + iconSize / 2,
|
||||||
{.color = isLit ? color : dim, .position = {box.x + box.w / 2, box.y + box.h / 2}},
|
y + slot / layout.columns[kind] * cell + iconSize / 2};
|
||||||
layout.size);
|
icon_draw(game, isTrinket, item, {.color = isLit ? color : dim, .position = centre}, layout.size);
|
||||||
if (is_point_in_rect(game.input.mouse, box))
|
|
||||||
{
|
|
||||||
hoveredFighter = index;
|
|
||||||
hoveredKind = kind;
|
|
||||||
hoveredSlot = slot;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
x += layout.columns[kind] * cell;
|
x += layout.columns[kind] * cell;
|
||||||
if (kind == 0)
|
if (kind == 0)
|
||||||
@@ -2471,22 +2471,6 @@ void Ui::rivals_draw(Game& game)
|
|||||||
}
|
}
|
||||||
renderer.layer_end(base * hover_alpha_get(rivalHovers[index]));
|
renderer.layer_end(base * hover_alpha_get(rivalHovers[index]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hoveredFighter < 0 || game.menu.isOpen)
|
|
||||||
return;
|
|
||||||
Fighter& fighter = game.sim.fighters[hoveredFighter];
|
|
||||||
bool isTrinket = hoveredKind == 1;
|
|
||||||
int item = (isTrinket ? fighter.trinketLoadout : fighter.weaponLoadout)[hoveredSlot];
|
|
||||||
int level = (isTrinket ? fighter.trinketSlotLevels : fighter.weaponSlotLevels)[hoveredSlot];
|
|
||||||
Tooltip tooltip = tooltip_build(game, isTrinket, item, level, hoveredFighter);
|
|
||||||
tooltip.slot = hoveredSlot;
|
|
||||||
// The tooltip takes that fighter's colour for the moment, so it's clear whose item it is.
|
|
||||||
Color colors[2] = {tint, shade};
|
|
||||||
tint = game.color_get(hoveredFighter);
|
|
||||||
shade = color_shade(tint, SECONDARY_SHADE);
|
|
||||||
tooltip_draw(game, tooltip);
|
|
||||||
tint = colors[0];
|
|
||||||
shade = colors[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choosing items with several players on this screen: a panel each below top (side by side for two, a 2x2 grid for
|
// Choosing items with several players on this screen: a panel each below top (side by side for two, a 2x2 grid for
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ struct RivalLayout
|
|||||||
struct CountdownInfo
|
struct CountdownInfo
|
||||||
{
|
{
|
||||||
char round[64] = {};
|
char round[64] = {};
|
||||||
int seconds = 0;
|
char time[16] = {};
|
||||||
int ready = 0;
|
int ready = 0;
|
||||||
char key[64] = {};
|
char key[64] = {};
|
||||||
};
|
};
|
||||||
@@ -198,7 +198,7 @@ public:
|
|||||||
void draw(Game& game);
|
void draw(Game& game);
|
||||||
void slot_draw(Game& game, Slot slot);
|
void slot_draw(Game& game, Slot slot);
|
||||||
void panel_draw(Renderer& renderer, Rect rect, Color border, float fillAlpha = -1, float stroke = PANEL_BORDER);
|
void panel_draw(Renderer& renderer, Rect rect, Color border, float fillAlpha = -1, float stroke = PANEL_BORDER);
|
||||||
Tooltip tooltip_build(Game& game, bool isTrinket, int item, int level, int owner = -1);
|
Tooltip tooltip_build(Game& game, bool isTrinket, int item, int level);
|
||||||
void stats_table_build(Fighter& fighter, int weapon, int level, bool isPreview, Tooltip& tooltip);
|
void stats_table_build(Fighter& fighter, int weapon, int level, bool isPreview, Tooltip& tooltip);
|
||||||
void table_row_draw(Game& game, Tooltip& tooltip, int row, Vec2 corner, const float* columns, Font font,
|
void table_row_draw(Game& game, Tooltip& tooltip, int row, Vec2 corner, const float* columns, Font font,
|
||||||
float alpha);
|
float alpha);
|
||||||
|
|||||||
Reference in new issue
Block a user