wall drop shadows, more tile types

This commit is contained in:
jacob 2026-04-04 21:14:58 -05:00
parent be610d4055
commit 9d6fb0ed40
16 changed files with 159 additions and 43 deletions

View File

@ -45,7 +45,7 @@ String TweakEx(Arena *arena, TweakVar desc, b32 update_existing)
} }
PushAlign(perm, IsolationSize); PushAlign(perm, IsolationSize);
SllQueuePushN(bin->first, bin->last, e, next_in_bin); SllQueuePushN(bin->first, bin->last, e, next_in_bin);
SllQueuePushN(Base.tweak.first_entry, Base.tweak.last_entry, e, next_in_list); SllQueuePush(Base.tweak.first_entry, Base.tweak.last_entry, e);
Base.tweak.entries_count += 1; Base.tweak.entries_count += 1;
} }
else if (update_existing) else if (update_existing)
@ -74,7 +74,7 @@ TweakVarArray GetAllTweakVars(Arena *arena)
result.count = Base.tweak.entries_count; result.count = Base.tweak.entries_count;
result.v = PushStructsNoZero(arena, TweakVar, result.count); result.v = PushStructsNoZero(arena, TweakVar, result.count);
i64 var_idx = 0; i64 var_idx = 0;
for (TweakVarEntry *e = Base.tweak.first_entry; e; e = e->next_in_list) for (TweakVarEntry *e = Base.tweak.first_entry; e; e = e->next)
{ {
TweakVar *src = &e->v; TweakVar *src = &e->v;
TweakVar *dst = &result.v[var_idx]; TweakVar *dst = &result.v[var_idx];

View File

@ -56,8 +56,8 @@ Struct(TweakFloatDesc)
Struct(TweakVarEntry) Struct(TweakVarEntry)
{ {
TweakVarEntry *next;
TweakVarEntry *next_in_bin; TweakVarEntry *next_in_bin;
TweakVarEntry *next_in_list;
u64 hash; u64 hash;
TweakVar v; TweakVar v;
}; };

BIN
src/pp/pp_res/tile/Carpet.ase (Stored with Git LFS)

Binary file not shown.

BIN
src/pp/pp_res/tile/DarkBrick.ase (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/pp/pp_res/tile/DarkTile.ase (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/pp/pp_res/tile/LightBrick.ase (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/pp/pp_res/tile/SmallGreenTile.ase (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/pp/pp_res/tile/SmallPurpleTile.ase (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/pp/pp_res/tile/Test.ase (Stored with Git LFS) Normal file

Binary file not shown.

BIN
src/pp/pp_res/tile/Tile.ase (Stored with Git LFS)

Binary file not shown.

View File

@ -29,8 +29,13 @@ Enum(P_MaterialKind)
#define P_TilesXList(X) \ #define P_TilesXList(X) \
X(Empty) \ X(Empty) \
X(Wall) \ X(Wall) \
X(Tile) \ X(SmallGreenTile) \
X(SmallPurpleTile) \
X(DarkTile) \
X(DarkBrick) \
X(LightBrick) \
X(Carpet) \ X(Carpet) \
X(Test) \
/* -------------------- */ /* -------------------- */
//- Tile kinds //- Tile kinds
@ -47,9 +52,9 @@ Enum(P_TileKind)
#define P_PrefabsXList(X) \ #define P_PrefabsXList(X) \
X(None, P_PrefabFlag_HideFromEditor) \ X(None, P_PrefabFlag_HideFromEditor) \
X(Bot, P_PrefabFlag_None) \
X(GuySpawn, P_PrefabFlag_None) \ X(GuySpawn, P_PrefabFlag_None) \
X(HealthSpawn, P_PrefabFlag_None) \ X(HealthSpawn, P_PrefabFlag_None) \
X(Bot, P_PrefabFlag_None) \
/* --------------------------------------------------- */ /* --------------------------------------------------- */
//- Prefab flags //- Prefab flags

View File

@ -421,32 +421,97 @@ void S_TickForever(WaveLaneCtx *lane)
} }
} }
////////////////////////////// //////////////////////////////
//- Apply bot controls //- Apply bot controls
{ {
f32 move_bias = TweakFloat("Bot movement bias", 0, -1, 1); b32 should_bots_target_player = TweakBool("Swarm bots to player", 1);
f32 move_frequency = TweakFloat("Bot movement frequency", 0, 0, 10); if (should_bots_target_player)
f32 turn_frequency = TweakFloat("Bot turn frequency", 0, 0, 10); {
// b32 bot_movement_enabled = TweakBool("Bot movement enabled", 1); P_Ent *target_player = &P_NilEnt;
for (P_Ent *player = P_FirstEnt(world_frame); !P_IsEntNil(player); player = P_NextEnt(player))
{
if (player->is_player && !player->is_bot)
{
target_player = player;
break;
}
}
P_Ent *target_guy = P_EntFromKey(world_frame, target_player->guy);
if (target_guy->is_guy)
{
u64 bots_count = 0;
for (P_Ent *bot = P_FirstEnt(world_frame); !P_IsEntNil(bot); bot = P_NextEnt(bot)) for (P_Ent *bot = P_FirstEnt(world_frame); !P_IsEntNil(bot); bot = P_NextEnt(bot))
{ {
if (bot->is_bot) if (bot->is_bot)
{ {
i64 alive_time_ns = world_frame->time_ns - bot->created_at_ns; bots_count += 1;
f64 alive_time = SecondsFromNs(alive_time_ns); }
// i64 frequency_ns = NsFromSeconds(0.1); }
// bot->control.move.y = SinF32((f64)alive_time_ns / (f64)frequency_ns);
f32 move_t = alive_time * move_frequency * Tau; {
f32 look_t = alive_time * turn_frequency * Tau; u64 bot_idx = 0;
f32 spacing_len = 2;
for (P_Ent *bot = P_FirstEnt(world_frame); !P_IsEntNil(bot); bot = P_NextEnt(bot))
{
if (bot->is_bot)
{
f32 radius_ratio = (f32)bot_idx / (f32)bots_count;
Vec2 spacing = MulVec2(Vec2FromAngle(radius_ratio * Tau), spacing_len);
Vec2 target_pos = AddVec2(target_guy->xf.t, spacing);
{
P_Ent *bot_guy = P_EntFromKey(world_frame, bot->guy);
Vec2 dir_to_target = SubVec2(target_pos, bot_guy->xf.t);
bot->control.move = dir_to_target;
bot->control.look = dir_to_target;
}
bot_idx += 1;
}
}
}
}
}
}
bot->control.move.y = SinF32(move_t);
bot->control.move.y += move_bias;
bot->control.look = MulVec2(VEC2(CosF32(look_t), SinF32(look_t)), 3);
}
}
}
// //////////////////////////////
// //- Apply bot controls
// {
// f32 move_bias = TweakFloat("Bot movement bias", 0, -1, 1);
// f32 move_frequency = TweakFloat("Bot movement frequency", 0, 0, 10);
// f32 turn_frequency = TweakFloat("Bot turn frequency", 0, 0, 10);
// // b32 bot_movement_enabled = TweakBool("Bot movement enabled", 1);
// for (P_Ent *bot = P_FirstEnt(world_frame); !P_IsEntNil(bot); bot = P_NextEnt(bot))
// {
// if (bot->is_bot)
// {
// i64 alive_time_ns = world_frame->time_ns - bot->created_at_ns;
// f64 alive_time = SecondsFromNs(alive_time_ns);
// // i64 frequency_ns = NsFromSeconds(0.1);
// // bot->control.move.y = SinF32((f64)alive_time_ns / (f64)frequency_ns);
// f32 move_t = alive_time * move_frequency * Tau;
// f32 look_t = alive_time * turn_frequency * Tau;
// bot->control.move.y = SinF32(move_t);
// bot->control.move.y += move_bias;
// bot->control.look = MulVec2(VEC2(CosF32(look_t), SinF32(look_t)), 3);
// }
// }
// }
@ -544,7 +609,7 @@ void S_TickForever(WaveLaneCtx *lane)
// FIXME: Only accept edits from privileged users // FIXME: Only accept edits from privileged users
{ {
u32 bots_count = 0; u64 bots_count = 0;
b32 should_save = 0; b32 should_save = 0;
for (P_MsgNode *msg_node = in_msgs.first; msg_node; msg_node = msg_node->next) for (P_MsgNode *msg_node = in_msgs.first; msg_node; msg_node = msg_node->next)
{ {

View File

@ -52,30 +52,30 @@ PERSIST Readonly String P_PresetHumanNames[] = {
// Taken from a random GMOD server // Taken from a random GMOD server
PERSIST Readonly String P_PresetPlayerNames[] = { PERSIST Readonly String P_PresetPlayerNames[] = {
CompLit("Tidunbly"),
CompLit("lowayo"),
CompLit("_Runne_"),
CompLit("lionberg"), CompLit("lionberg"),
CompLit("charlie main"), CompLit("charlie main"),
CompLit("Fr0stie"),
CompLit("Mr. Bones"),
CompLit("Legs"),
CompLit("Poy"),
CompLit("frezh"), CompLit("frezh"),
CompLit("KARMA"),
CompLit("Kirep"), CompLit("Kirep"),
CompLit("Cyan Crayon"), CompLit("Cyan Crayon"),
CompLit("THE WIFE"), CompLit("THE WIFE"),
CompLit("Panda"), CompLit("Panda"),
CompLit("KARMA"),
CompLit("adoti"), CompLit("adoti"),
CompLit("yoyota"), CompLit("yoyota"),
CompLit("Mr. Bones"),
CompLit("TaurusJ3"), CompLit("TaurusJ3"),
CompLit("dub"), CompLit("dub"),
CompLit("Tidunbly"),
CompLit("Siepter"), CompLit("Siepter"),
CompLit("lowayo"),
CompLit("Zunix"), CompLit("Zunix"),
CompLit("_Runne_"),
CompLit("Fr0stie"),
CompLit("Lumby"), CompLit("Lumby"),
CompLit("Legs"),
CompLit("Talids"), CompLit("Talids"),
CompLit("Train"), CompLit("Train"),
CompLit("Poy"),
CompLit("Kaitsedd"), CompLit("Kaitsedd"),
CompLit("jiyu"), CompLit("jiyu"),
}; };

View File

@ -7995,12 +7995,13 @@ void V_TickForever(WaveLaneCtx *lane)
String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name)); String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name));
ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name);
SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource);
tile_sprite = SPR_SpriteFromSheet(sheet, SPR_NilSpanKey, 0); // Don't use atlas for tile so that we can easily wrap samples
tile_sprite = SPR_SpriteFromSheetEx(sheet, SPR_NilSpanKey, 0, SPR_SheetFlag_NoAtlas);
} }
V_TileDesc tile_desc = Zi; V_TileDesc tile_desc = Zi;
{ {
tile_desc.tex = tile_sprite.tex; tile_desc.tex = tile_sprite.tex;
tile_desc.tex_slice_uv = DivRng2Vec2(tile_sprite.tex_rect, tile_sprite.tex_dims); tile_desc.tex_dims = tile_sprite.tex_dims;
} }
frame->tile_descs[tile_kind] = tile_desc; frame->tile_descs[tile_kind] = tile_desc;
} }

View File

@ -796,6 +796,7 @@ ComputeShader(V_CompositeCS)
// Texture2D<Vec4> shade_tex = G_Deref(frame.shade, Texture2D<Vec4>); // Texture2D<Vec4> shade_tex = G_Deref(frame.shade, Texture2D<Vec4>);
SamplerState point_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState); SamplerState point_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState);
SamplerState bilinear_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState); SamplerState bilinear_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp], SamplerState);
SamplerState tile_sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointWrap], SamplerState);
Texture2D<Vec4> albedo_tex = G_Deref(frame.albedo, Texture2D<Vec4>); Texture2D<Vec4> albedo_tex = G_Deref(frame.albedo, Texture2D<Vec4>);
RWTexture2D<Vec4> screen_tex = G_Deref(frame.screen, RWTexture2D<Vec4>); RWTexture2D<Vec4> screen_tex = G_Deref(frame.screen, RWTexture2D<Vec4>);
Texture2D<Vec4> stains = G_Deref(frame.stains, Texture2D<Vec4>); Texture2D<Vec4> stains = G_Deref(frame.stains, Texture2D<Vec4>);
@ -880,6 +881,7 @@ ComputeShader(V_CompositeCS)
// TODO: Remove this // TODO: Remove this
b32 tile_is_wall = 0; b32 tile_is_wall = 0;
b32 tile_is_empty = 0;
Vec4 tile_color = 0; Vec4 tile_color = 0;
{ {
P_TileKind tile_tl = tiles[Vec2(tile_pos.x - 0.99, tile_pos.y - 0.99)]; P_TileKind tile_tl = tiles[Vec2(tile_pos.x - 0.99, tile_pos.y - 0.99)];
@ -904,8 +906,10 @@ ComputeShader(V_CompositeCS)
if (tile == P_TileKind_Wall) if (tile == P_TileKind_Wall)
{ {
Vec4 outer = LinearFromSrgb(Vec4(0.05, 0.05, 0.05, 1)); // Vec4 outer = LinearFromSrgb(Vec4(0.05, 0.05, 0.05, 1));
Vec4 inner = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1)); // Vec4 inner = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1));
Vec4 outer = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1));
Vec4 inner = LinearFromSrgb(Vec4(0.20, 0.20, 0.20, 1));
tile_color = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.375)); tile_color = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.375));
tile_is_wall = 1; tile_is_wall = 1;
} }
@ -913,9 +917,12 @@ ComputeShader(V_CompositeCS)
{ {
V_TileDesc tile_desc = frame.tile_descs[tile]; V_TileDesc tile_desc = frame.tile_descs[tile];
Texture2D<Vec4> tile_tex = G_Deref(tile_desc.tex, Texture2D<Vec4>); Texture2D<Vec4> tile_tex = G_Deref(tile_desc.tex, Texture2D<Vec4>);
Vec2 samp_t = clamp(frac(world_pos), 0.00001, 1.0 - 0.00001); Vec2 samp_uv = world_pos * (Vec2(P_CellsPerMeter, P_CellsPerMeter) / tile_desc.tex_dims);
Vec2 samp_uv = lerp(tile_desc.tex_slice_uv.p0, tile_desc.tex_slice_uv.p1, samp_t); tile_color = tile_tex.SampleLevel(tile_sampler, samp_uv, 0);
tile_color = tile_tex.SampleLevel(point_sampler, samp_uv, 0); }
else
{
tile_is_empty = 1;
} }
} }
@ -1042,8 +1049,24 @@ ComputeShader(V_CompositeCS)
//////////////////////////////
//- Shadow
Vec4 shadow_color = 0;
if (!tile_is_wall && !tile_is_empty)
{
// TODO: Move this to a frame var
f32 shadow_size = 0.05;
Vec2 tile_shadow_pos = mul(frame.af.world_to_tile, Vec3(world_pos.xy - Vec2(shadow_size, shadow_size), 1));
b32 is_in_shadow = 0;
P_TileKind shadow_tile = tiles[tile_shadow_pos];
is_in_shadow = shadow_tile == P_TileKind_Wall;
if (is_in_shadow)
{
shadow_color = Vec4(0, 0, 0, 0.75);
}
}
////////////////////////////// //////////////////////////////
//- Compose world //- Compose world
@ -1056,6 +1079,13 @@ ComputeShader(V_CompositeCS)
world_color = BlendPremul(tile_color, world_color); // Blend ground tile world_color = BlendPremul(tile_color, world_color); // Blend ground tile
world_color = BlendPremul(stain_color, world_color); // Blend ground stain world_color = BlendPremul(stain_color, world_color); // Blend ground stain
world_color = BlendPremul(ground_particle_color, world_color); // Blend ground particle world_color = BlendPremul(ground_particle_color, world_color); // Blend ground particle
// TODO: Blend shadows over tex?
world_color = BlendPremul(shadow_color, world_color); // Blend shadow
// if (shadow_color.a != 0)
// {
// world_color.rgb *= 0.5; // Blend shadow
// }
} }
world_color = BlendPremul(albedo_tex_color, world_color); world_color = BlendPremul(albedo_tex_color, world_color);
if (tile_is_wall) if (tile_is_wall)

View File

@ -317,7 +317,7 @@ Struct(V_ProfilerFrame)
Struct(V_TileDesc) Struct(V_TileDesc)
{ {
G_TextureRef tex; G_TextureRef tex;
Rng2 tex_slice_uv; Vec2 tex_dims;
}; };
Enum(V_SelectionMode) Enum(V_SelectionMode)