Room and lobby chat, /host, /fashion, player-colored lines, context tips, and American spelling

- Chat goes to your room (the sandbox, or your game) by default, and to the whole lobby with /all or a leading !.
  Lines from elsewhere say where they came from ([Sandbox], [Game 2]), lobby-wide ones from your room say [All].
  Typing shows only to your room. Protocol 8.
- Hosting: everyone is told who hosts now, and the host can hand it over with /host "player".
- /fashion <item> wears a fashion locally, like /color.
- Lines that mention a player show in that player's color, looked up as they draw.
- Tips are tagged with the item and situations they fit, and those that fit are 1.5x as likely. They turn over every
  10 seconds on one continuous run, show under the menu too, and can be turned off with Tips in HUD / Gameplay. The
  HUD hotbars hide while the menu is up (except on its item tabs).
- American spelling throughout: color, center, gray, mustache, and so on.
This commit is contained in:
shweet committed 2026-11-10 19:37:19 -05:00
1 parent f4e7784f3c
commit 93cdf46d5a
38 files changed
+603 -325

No files matched your search

+19 -19
View File
@@ -138,7 +138,7 @@ constexpr Burst TRAIL_BURST = {.life = 0.25f, .size = 2, .speed = 120, .spread =
constexpr Burst WARP_BURST = {.gravity = -60, .life = 0.4f, .size = 2, .speed = 50, .spread = PI, .count = 1};
constexpr Burst PORTAL_BURST = {.life = 0.4f, .size = 3, .speed = 140, .spread = PI, .count = 14};
// Flies a thrown weapon back towards the hand, reporting whether it got there.
// Flies a thrown weapon back toward the hand, reporting whether it got there.
static bool is_caught(Fighter& fighter, Attack& attack)
{
Vec2 toHand = fighter.hand_get() - attack.position;
@@ -415,7 +415,7 @@ Vec2 muzzle_get(Attack& attack)
return attack.origin + vec2_polar(attack.angle, muzzle.x) + vec2_polar(attack.angle + PI / 2, muzzle.y * side);
}
// How much of an attack's black fill its colour takes over, from none at plain damage to all at FILL_STRENGTH.
// How much of an attack's black fill its color takes over, from none at plain damage to all at FILL_STRENGTH.
float fill_get(float strength)
{
return std::clamp((strength - 1) / (FILL_STRENGTH - 1), 0.0f, 1.0f);
@@ -615,8 +615,8 @@ void Weapons::fire(Sim& sim, Fighter& fighter, float charge)
}
}
// Whether the fighter's box would fit with its middle at centre, clear of walls (and inside the map).
static bool is_box_clear(Sim& sim, Fighter& fighter, Vec2 centre)
// Whether the fighter's box would fit with its middle at center, clear of walls (and inside the map).
static bool is_box_clear(Sim& sim, Fighter& fighter, Vec2 center)
{
Rect box = fighter.body.box;
int columns = (int)(box.w / TELEPORT_PROBE) + 1;
@@ -624,7 +624,7 @@ static bool is_box_clear(Sim& sim, Fighter& fighter, Vec2 centre)
for (int row = 0; row <= rows; row++)
for (int column = 0; column <= columns; column++)
{
Vec2 point = {centre.x - box.w / 2 + box.w * column / columns, centre.y - box.h / 2 + box.h * row / rows};
Vec2 point = {center.x - box.w / 2 + box.w * column / columns, center.y - box.h / 2 + box.h * row / rows};
if (sim.world.is_blocking_at(point))
return false;
}
@@ -635,17 +635,17 @@ static bool is_box_clear(Sim& sim, Fighter& fighter, Vec2 centre)
// the fighter until its box fits there. Returns the fighter's own middle if nowhere fits.
static Vec2 teleport_spot(Sim& sim, Fighter& fighter, Vec2 target, float range)
{
Vec2 centre = fighter.center_get();
Vec2 offset = target - centre;
Vec2 center = fighter.center_get();
Vec2 offset = target - center;
float distance = std::min(range, vec2_length(offset));
Vec2 direction = vec2_normalize(offset);
for (float along = distance; along > 0; along -= TELEPORT_STEP)
{
Vec2 spot = centre + direction * along;
Vec2 spot = center + direction * along;
if (is_box_clear(sim, fighter, spot))
return spot;
}
return centre;
return center;
}
// The fighter's speed along the aim that an inheriting shot gains. Launched fighters lend nothing.
@@ -663,7 +663,7 @@ static float bonus_get(Fighter& fighter, const AttackDef& def, Vec2 aim)
return 1 + (SPEED_DAMAGE + fighter.stat_get(STAT_SPEED_DAMAGE)) * speed / SPEED_UNIT;
}
// How much a fighter's colour fills in from the bonus its held weapon would get firing right now.
// How much a fighter's color fills in from the bonus its held weapon would get firing right now.
float Weapons::buff_get(Fighter& fighter)
{
int held = fighter.weapon_get();
@@ -873,7 +873,7 @@ bool Weapons::is_spawned(Sim& sim, Fighter& fighter, Shot shot)
attack.stats.speed *= power;
// One piece per volley shot per split, each fanned around the aim (or set side by side when the volley has no
// fan). The centre split stays primary and the rest are secondary.
// fan). The center split stays primary and the rest are secondary.
for (int v = 0; v < stats.volley; v++)
{
float place = stats.volley > 1 ? (float)v / (stats.volley - 1) - 0.5f : 0;
@@ -937,7 +937,7 @@ bool Weapons::is_spawned(Sim& sim, Fighter& fighter, Shot shot)
if (variant == VARIANT_CHARGED)
sim.cues->shake_add(def.shake * FIRE_SHAKE);
// An uppercut launches its fighter the way it rises, cancelling any speed against that first. Shock Absorber
// An uppercut launches its fighter the way it rises, canceling any speed against that first. Shock Absorber
// softens every push the shot gives its own fighter: lunges, kickback and Recoil Coil.
float absorb = fighter.stat_get(STAT_MOVEMENT);
Vec2 lunge = kind == ATTACK_UPPERCUT ? vec2_polar(attack.angle, 1) : aim;
@@ -1544,7 +1544,7 @@ void Weapons::attack_hit(Sim& sim, Attack& attack, int target, Vec2 point)
}
impact_play(sim, def.kind);
// Explosions deal full damage at their centre, down to a fraction at the edge, by the target's nearest point. A
// Explosions deal full damage at their center, down to a fraction at the edge, by the target's nearest point. A
// Vacuum's suck bites harder the closer to its muzzle.
float taper = is_cone(def) ? cone_strength_get(attack, point) : 1;
taper *= def.kind == ATTACK_GRENADE ? GRENADE_CONTACT_SHARE : 1;
@@ -1783,7 +1783,7 @@ void Weapons::teleport_move(Sim& sim, Attack& attack)
}
// Tesla Coil: a web of lightning between every weapon the fighter has out in the world (anything but explosions).
// Each piece arcs to its nearest few neighbours within reach, so everything nearby is connected without the
// Each piece arcs to its nearest few neighbors within reach, so everything nearby is connected without the
// links growing out of hand for rapid-fire weapons. Each coil makes the links thicker.
std::vector<Capsule> Weapons::chain_get(Sim& sim, Fighter& fighter)
{
@@ -1881,8 +1881,8 @@ std::vector<Path> Weapons::paths_get(Sim& sim, Fighter& fighter)
Vec2 from = fighter.center_get();
Path path = {.area = stats.area * def.scale * fighter.stat_get(STAT_ATTACK_SIZE)};
float length = vec2_length(spot - from);
for (float travelled = 0; travelled < length; travelled += TRAJECTORY_STEP)
path.steps.push_back(from + (spot - from) * (travelled / length));
for (float traveled = 0; traveled < length; traveled += TRAJECTORY_STEP)
path.steps.push_back(from + (spot - from) * (traveled / length));
path.steps.push_back(spot);
paths.push_back(path);
return paths;
@@ -1926,7 +1926,7 @@ std::vector<Path> Weapons::paths_get(Sim& sim, Fighter& fighter)
int bounces = def.isBouncy ? (int)fighter.stat_get(STAT_RICOCHETS) : 0;
Path path;
bool isEnded = stats.range <= TRAJECTORY_REACH;
for (float travelled = area > 0 ? MUZZLE_DISTANCE : 0; travelled < reach; travelled += TRAJECTORY_STEP)
for (float traveled = area > 0 ? MUZZLE_DISTANCE : 0; traveled < reach; traveled += TRAJECTORY_STEP)
{
float time = TRAJECTORY_STEP / std::max(1.0f, vec2_length(velocity));
Vec2 next = point + velocity * time;
@@ -2043,7 +2043,7 @@ void Weapons::attack_explode(Sim& sim, Attack& attack)
}
// Queues an explosion that hits everything inside it next tick, weaker toward its edge. Pushing blasts fling every
// fighter away from the centre, harder the closer they are.
// fighter away from the center, harder the closer they are.
void Weapons::blast_spawn(Sim& sim, Blast blast)
{
float reach = blast.area * KNOCKBACK_REACH;
@@ -2226,7 +2226,7 @@ static void shot_restore(Attack& shot, float share)
// to fly straight out of the cone from its point (along the aim, give or take where in the cone it is), at its own
// speed plus the blow's, and pull speeds each toward the point. A shot stuck to a surface comes loose first (a
// grapple's hook too), popping out toward the point at the cone's own speed when pulled, and glancing off the surface
// if it would head straight back in. A claiming attack makes other fighters' shots its owner's, burst into its colour
// if it would head straight back in. A claiming attack makes other fighters' shots its owner's, burst into its color
// (all but those tied to their fighter's weapon: on a rope or chain, waiting to be set off, or the weapon itself). The
// owner's own shots then get back restore's share of what they set off with (see shot_restore).
void Weapons::shots_drift(Sim& sim, Attack& source, float blow, float pull, float restore)