fire animation. colored guys.
This commit is contained in:
parent
0d2871d664
commit
92ed9a4c2d
@ -408,7 +408,6 @@ String LowerString(Arena *arena, String str)
|
||||
String result = Zi;
|
||||
result.text = PushStructsNoZero(arena, u8, str.len);
|
||||
result.len = str.len;
|
||||
|
||||
for (u64 i = 0; i < str.len; ++i)
|
||||
{
|
||||
u8 c = str.text[i];
|
||||
@ -418,7 +417,23 @@ String LowerString(Arena *arena, String str)
|
||||
}
|
||||
result.text[i] = c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String UpperString(Arena *arena, String str)
|
||||
{
|
||||
String result = Zi;
|
||||
result.text = PushStructsNoZero(arena, u8, str.len);
|
||||
result.len = str.len;
|
||||
for (u64 i = 0; i < str.len; ++i)
|
||||
{
|
||||
u8 c = str.text[i];
|
||||
if (97 <= c && c <= 122)
|
||||
{
|
||||
c -= 32;
|
||||
}
|
||||
result.text[i] = c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -100,6 +100,7 @@ StringArray SplitString(Arena *arena, String str, String delim);
|
||||
String ReplaceString(Arena *arena, String str, String old_pattern, String new_pattern);
|
||||
String IndentString(Arena *arena, String str, u32 indent);
|
||||
String LowerString(Arena *arena, String str);
|
||||
String UpperString(Arena *arena, String str);
|
||||
b32 MatchString(String str1, String str2);
|
||||
b32 StringContains(String str, String substring);
|
||||
b32 StringBeginsWith(String str, String substring);
|
||||
|
||||
121
src/pp/pp.c
121
src/pp/pp.c
@ -267,56 +267,97 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent)
|
||||
|
||||
// TODO: Determine animation dynamically
|
||||
i64 animation_rate_ns = NsFromSeconds(0.050);
|
||||
i64 animation_time_ns = frame->time_ns;
|
||||
i64 body_animation_time_ns = frame->time_ns;
|
||||
i64 legs_animation_time_ns = frame->time_ns;
|
||||
i64 wep_animation_time_ns = frame->time_ns;
|
||||
{
|
||||
// result.span = SPR_SpanKeyFromName(Lit("test"));
|
||||
b32 is_rolling = P_IsEntRolling(frame, ent);
|
||||
// b32 is_shooting = ent->is_guy && ((frame->time_ns - MaxI64(wep->last_fire_ns, wep->last_alt_fire_ns)) < animation_rate_ns);
|
||||
b32 is_shooting = ent->is_guy && ((frame->time_ns - MaxI64(wep->last_fire_ns, wep->last_alt_fire_ns)) < (animation_rate_ns * 2));
|
||||
b32 is_walking = !is_rolling && Vec2LenSq(ent->control.move) > (0.01 * 0.01);
|
||||
|
||||
// is_shooting = 1;
|
||||
|
||||
if (P_IsEntRolling(frame, ent))
|
||||
{
|
||||
result.span = SPR_SpanKeyFromName(Lit("roll"));
|
||||
result.weapon_over = 1;
|
||||
}
|
||||
else if (Vec2LenSq(ent->control.move) > (0.01 * 0.01))
|
||||
{
|
||||
result.span = SPR_SpanKeyFromName(Lit("walk"));
|
||||
if (ent->is_guy)
|
||||
result.body_span = SPR_SpanKeyFromName(Lit("idle"));
|
||||
result.legs_span = SPR_SpanKeyFromName(Lit("idle"));
|
||||
result.wep_span = SPR_SpanKeyFromName(Lit("idle"));
|
||||
|
||||
// if (is_shooting)
|
||||
// {
|
||||
// animation_rate_ns = NsFromSeconds(0.001);
|
||||
// }
|
||||
|
||||
|
||||
// Body
|
||||
if (is_rolling)
|
||||
{
|
||||
result.body_span = SPR_SpanKeyFromName(Lit("roll"));
|
||||
result.weapon_over = 1;
|
||||
}
|
||||
else if (is_shooting)
|
||||
{
|
||||
result.body_span = SPR_SpanKeyFromName(Lit("shoot"));
|
||||
// body_animation_time_ns = SaturateF32(NsFromSeconds(1.0 / wep->last_fire_rate));
|
||||
}
|
||||
else if (is_walking)
|
||||
{
|
||||
result.body_span = SPR_SpanKeyFromName(Lit("walk"));
|
||||
body_animation_time_ns = ent->walk_time_accum_ns;
|
||||
}
|
||||
|
||||
// Legs
|
||||
if (is_rolling)
|
||||
{
|
||||
result.legs_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("guy/legs.ase")));
|
||||
animation_time_ns = ent->walk_time_accum_ns;
|
||||
result.legs_span = SPR_SpanKeyFromName(Lit("roll"));
|
||||
// legs_animation_time_ns = ent->walk_time_accum_ns;
|
||||
}
|
||||
else if (is_walking)
|
||||
{
|
||||
result.legs_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("guy/legs.ase")));
|
||||
result.legs_span = SPR_SpanKeyFromName(Lit("walk"));
|
||||
legs_animation_time_ns = ent->walk_time_accum_ns;
|
||||
}
|
||||
|
||||
// Weapon
|
||||
if (is_shooting)
|
||||
{
|
||||
result.wep_span = SPR_SpanKeyFromName(Lit("shoot"));
|
||||
// legs_animation_time_ns = SaturateF32(NsFromSeconds(1.0 / wep->last_fire_rate));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.span = SPR_SpanKeyFromName(Lit("idle"));
|
||||
}
|
||||
}
|
||||
|
||||
result.body_frame_seq = body_animation_time_ns / animation_rate_ns;
|
||||
result.legs_frame_seq = legs_animation_time_ns / animation_rate_ns;
|
||||
result.wep_frame_seq = wep_animation_time_ns / animation_rate_ns;
|
||||
|
||||
// TODO: Use prefab lookup
|
||||
|
||||
if (ent->is_guy)
|
||||
{
|
||||
result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("guy/guy.ase")));
|
||||
result.body_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("guy/guy.ase")));
|
||||
}
|
||||
else if (ent->is_guy_spawn)
|
||||
{
|
||||
result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("prefab/GuySpawn.ase")));
|
||||
result.body_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("prefab/GuySpawn.ase")));
|
||||
}
|
||||
else if (ent->is_health_spawn)
|
||||
{
|
||||
result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("prefab/HealthSpawn.ase")));
|
||||
result.body_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("prefab/HealthSpawn.ase")));
|
||||
}
|
||||
else if (ent->is_bomb)
|
||||
{
|
||||
result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("misc/bomb.ase")));
|
||||
result.body_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("misc/bomb.ase")));
|
||||
}
|
||||
else if (ent->is_health)
|
||||
{
|
||||
result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("misc/health.ase")));
|
||||
result.body_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("misc/health.ase")));
|
||||
}
|
||||
else if (ent->is_health)
|
||||
{
|
||||
result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("misc/health.ase")));
|
||||
result.body_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("misc/health.ase")));
|
||||
}
|
||||
|
||||
if (wep->is_uzi)
|
||||
@ -324,8 +365,6 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent)
|
||||
result.wep_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("wep/uzi.ase")));
|
||||
}
|
||||
|
||||
result.frame_seq = animation_time_ns / animation_rate_ns;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2471,12 +2510,13 @@ void P_StepFrame(P_Frame *frame)
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Roll guys
|
||||
//- Accumulate control times
|
||||
|
||||
for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy))
|
||||
{
|
||||
if (guy->is_guy)
|
||||
{
|
||||
// Roll
|
||||
// if (guy->control.roll_presses && !IsVec2Zero(guy->control.move))
|
||||
if (guy->control.downs[P_Button_Roll])
|
||||
{
|
||||
@ -2492,15 +2532,24 @@ void P_StepFrame(P_Frame *frame)
|
||||
guy->last_roll_dir = NormVec2(guy->control.look);
|
||||
}
|
||||
}
|
||||
|
||||
if (!P_IsEntRolling(frame, guy))
|
||||
{
|
||||
// Walk
|
||||
b32 is_moving = Vec2LenSq(guy->control.move) > (0.001 * 0.001);
|
||||
if (is_moving)
|
||||
if (is_moving)
|
||||
{
|
||||
if (!P_IsEntRolling(frame, guy))
|
||||
{
|
||||
guy->walk_time_accum_ns += sim_dt_ns;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
guy->walk_time_accum_ns = 0;
|
||||
}
|
||||
// Fire
|
||||
if (guy->control.held[P_Button_PrimaryFire] || guy->control.held[P_Button_AltFire])
|
||||
{
|
||||
guy->fire_time_accum_ns += sim_dt_ns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3141,8 +3190,9 @@ void P_StepFrame(P_Frame *frame)
|
||||
if (button == P_Button_PrimaryFire && (firer->control.held[button] || firer->control.downs[button]))
|
||||
{
|
||||
// fire_rate = 100;
|
||||
// bullets_per_fire = 4;
|
||||
fire_rate = 10;
|
||||
bullets_per_fire = 4;
|
||||
// fire_rate = 50;
|
||||
fire_rate = 50;
|
||||
bullets_per_fire = 1;
|
||||
firing = (weapon->last_fire_ns + NsFromSeconds(1.0 / fire_rate)) <= frame->time_ns;
|
||||
if (firing)
|
||||
@ -3180,6 +3230,7 @@ void P_StepFrame(P_Frame *frame)
|
||||
bullet->sim = weapon->sim;
|
||||
}
|
||||
}
|
||||
weapon->last_fire_rate = fire_rate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3218,8 +3269,8 @@ void P_StepFrame(P_Frame *frame)
|
||||
|
||||
// f32 spread = Tau * 0.05;
|
||||
// f32 spread = Tau * 0.2;
|
||||
// f32 spread = Tau * 0.01;
|
||||
f32 spread = 0;
|
||||
f32 spread = Tau * 0.01;
|
||||
// f32 spread = 0;
|
||||
|
||||
b32 should_ricochet = 0;
|
||||
|
||||
@ -3269,8 +3320,8 @@ void P_StepFrame(P_Frame *frame)
|
||||
{
|
||||
Vec2 look = firer->control.look;
|
||||
P_Anim anim = P_AnimFromEnt(frame, firer);
|
||||
SPR_Sprite body = SPR_SpriteFromSheet(anim.sheet, anim.span, anim.frame_seq);
|
||||
SPR_Sprite wep = SPR_SpriteFromSheet(anim.wep_sheet, anim.span, anim.frame_seq);
|
||||
SPR_Sprite body = SPR_SpriteFromSheet(anim.body_sheet, anim.body_span, anim.body_frame_seq);
|
||||
SPR_Sprite wep = SPR_SpriteFromSheet(anim.wep_sheet, anim.wep_span, anim.wep_frame_seq);
|
||||
|
||||
//- Compute sprite transforms
|
||||
Affine ent_to_world_af = MulAffineXform(AffineIdentity, firer->xf);
|
||||
@ -3742,7 +3793,7 @@ void P_StepFrame(P_Frame *frame)
|
||||
death->key = P_EntKeyFromU64(MixU64s(guy->key.v, P_DeathBasis + (u64)player->deaths));
|
||||
death->death_pos = guy->xf.t;
|
||||
death->is_death = 1;
|
||||
death->death_player = player->key;
|
||||
death->death_victim = player->key;
|
||||
death->death_killer = killer->key;
|
||||
death->lifetime_seconds = P_ObservationDurationSeconds;
|
||||
}
|
||||
|
||||
19
src/pp/pp.h
19
src/pp/pp.h
@ -11,6 +11,7 @@
|
||||
#define P_BulletHitBasis 0xbc70fc783c1c507full
|
||||
#define P_BulletTrailBasis 0x27c011f891c571feull
|
||||
#define P_DeathBasis 0x2e3c75a3286d872aull
|
||||
#define P_KillfeedBasis 0xd1f84bd6f7c3cf1eull
|
||||
|
||||
Struct(P_EntKey)
|
||||
{
|
||||
@ -170,7 +171,7 @@ Struct(P_Ent)
|
||||
|
||||
b32 is_death;
|
||||
Vec2 death_pos;
|
||||
P_EntKey death_player;
|
||||
P_EntKey death_victim;
|
||||
P_EntKey death_killer;
|
||||
|
||||
//- Bomb
|
||||
@ -215,11 +216,14 @@ Struct(P_Ent)
|
||||
P_EntKey weapon;
|
||||
Vec2 last_roll_dir;
|
||||
i64 walk_time_accum_ns;
|
||||
i64 fire_time_accum_ns;
|
||||
|
||||
i64 last_fire_ns;
|
||||
i64 last_alt_fire_ns;
|
||||
i64 last_roll_ns;
|
||||
|
||||
f32 last_fire_rate;
|
||||
|
||||
//- Weapon
|
||||
|
||||
b32 is_weapon;
|
||||
@ -264,11 +268,18 @@ Struct(P_EntBin)
|
||||
|
||||
Struct(P_Anim)
|
||||
{
|
||||
i64 frame_seq;
|
||||
SPR_SpanKey span;
|
||||
SPR_SheetKey sheet;
|
||||
i64 body_frame_seq;
|
||||
SPR_SpanKey body_span;
|
||||
SPR_SheetKey body_sheet;
|
||||
|
||||
i64 legs_frame_seq;
|
||||
SPR_SpanKey legs_span;
|
||||
SPR_SheetKey legs_sheet;
|
||||
|
||||
i64 wep_frame_seq;
|
||||
SPR_SpanKey wep_span;
|
||||
SPR_SheetKey wep_sheet;
|
||||
|
||||
b32 weapon_over;
|
||||
};
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
@IncludeC pp_shared.cgh
|
||||
@IncludeG pp_shared.cgh
|
||||
@IncludeC pp.h
|
||||
@IncludeC pp_terms.h
|
||||
@IncludeC pp_transcode.h
|
||||
|
||||
@Bootstrap P_Bootstrap
|
||||
|
||||
BIN
src/pp/pp_res/guy/guy.ase
(Stored with Git LFS)
BIN
src/pp/pp_res/guy/guy.ase
(Stored with Git LFS)
Binary file not shown.
BIN
src/pp/pp_res/guy/legs.ase
(Stored with Git LFS)
BIN
src/pp/pp_res/guy/legs.ase
(Stored with Git LFS)
Binary file not shown.
BIN
src/pp/pp_res/wep/uzi.ase
(Stored with Git LFS)
BIN
src/pp/pp_res/wep/uzi.ase
(Stored with Git LFS)
Binary file not shown.
@ -544,6 +544,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
// FIXME: Only accept edits from privileged users
|
||||
|
||||
{
|
||||
u32 bots_count = 0;
|
||||
b32 should_save = 0;
|
||||
for (P_MsgNode *msg_node = in_msgs.first; msg_node; msg_node = msg_node->next)
|
||||
{
|
||||
@ -604,11 +605,22 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
P_Ent *bot = P_EntFromKey(world_frame, msg->key);
|
||||
if (!bot->is_bot)
|
||||
{
|
||||
for (P_Ent *ent = P_FirstEnt(world_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||
{
|
||||
if (ent->is_bot)
|
||||
{
|
||||
bots_count += 1;
|
||||
}
|
||||
}
|
||||
bot = P_PushTempEnt(frame_arena, &ents);
|
||||
bot->key = msg->key;
|
||||
bot->is_player = 1;
|
||||
bot->is_bot = 1;
|
||||
P_SetEntString(bot, Lit("Bot"));
|
||||
{
|
||||
String bot_name = P_PresetPlayerNames[bots_count % countof(P_PresetPlayerNames)];
|
||||
P_SetEntString(bot, bot_name);
|
||||
}
|
||||
bots_count += 1;
|
||||
}
|
||||
bot->continuity_gen += 1;
|
||||
P_Ent *guy = P_EntFromKey(world_frame, bot->guy);
|
||||
|
||||
81
src/pp/pp_terms.h
Normal file
81
src/pp/pp_terms.h
Normal file
@ -0,0 +1,81 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Killfeed terms
|
||||
|
||||
PERSIST Readonly String P_KillTerms[] = {
|
||||
CompLit("fired"),
|
||||
CompLit("reprimanded"),
|
||||
CompLit("outsourced"),
|
||||
CompLit("reassigned"),
|
||||
CompLit("laminated"),
|
||||
CompLit("downsized"),
|
||||
CompLit("laid off"),
|
||||
CompLit("terminated"),
|
||||
CompLit("demoted"),
|
||||
CompLit("restructured"),
|
||||
CompLit("shredded"),
|
||||
CompLit("decommissioned"),
|
||||
CompLit("finalized"),
|
||||
CompLit("offboarded"),
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Names
|
||||
|
||||
PERSIST Readonly String P_PresetHumanNames[] = {
|
||||
CompLit("Harold"),
|
||||
CompLit("Scruffy"),
|
||||
CompLit("Rusty"),
|
||||
CompLit("Carlile"),
|
||||
CompLit("Frank"),
|
||||
CompLit("Dick"),
|
||||
CompLit("Rick"),
|
||||
CompLit("Milton"),
|
||||
CompLit("Bruce"),
|
||||
CompLit("Leonard"),
|
||||
CompLit("Stanley"),
|
||||
CompLit("Randy"),
|
||||
CompLit("Walter"),
|
||||
CompLit("Eugene"),
|
||||
CompLit("Ron"),
|
||||
CompLit("Dale"),
|
||||
CompLit("Keith"),
|
||||
CompLit("Larry"),
|
||||
CompLit("Terry"),
|
||||
CompLit("Don"),
|
||||
CompLit("Gary"),
|
||||
CompLit("Greg"),
|
||||
CompLit("Chester"),
|
||||
CompLit("Russ"),
|
||||
CompLit("Ed"),
|
||||
CompLit("Buck"),
|
||||
};
|
||||
|
||||
// Taken from a random GMOD server
|
||||
PERSIST Readonly String P_PresetPlayerNames[] = {
|
||||
CompLit("Kirep"),
|
||||
CompLit("adoti"),
|
||||
CompLit("TaurusJ3"),
|
||||
CompLit("dub"),
|
||||
CompLit("Tidunbly"),
|
||||
CompLit("Siepter"),
|
||||
CompLit("frezh"),
|
||||
CompLit("lowayo"),
|
||||
CompLit("Zunix"),
|
||||
CompLit("_Runne_"),
|
||||
CompLit("Fr0stie"),
|
||||
CompLit("Mr. Bones"),
|
||||
CompLit("Lumby"),
|
||||
CompLit("Legs"),
|
||||
CompLit("Talids"),
|
||||
CompLit("yoyota"),
|
||||
CompLit("Train"),
|
||||
CompLit("lionberg"),
|
||||
CompLit("Cyan Crayon"),
|
||||
CompLit("Poy"),
|
||||
CompLit("Kaitsedd"),
|
||||
CompLit("Panda"),
|
||||
CompLit("THE WIFE"),
|
||||
CompLit("KARMA"),
|
||||
CompLit("jiyu"),
|
||||
CompLit("charlie main"),
|
||||
};
|
||||
@ -1860,7 +1860,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
// Rtt time
|
||||
{
|
||||
f64 lerp_rate = 1.0 * frame->dt;
|
||||
// f64 lerp_rate = 1.0 * frame->dt;
|
||||
f64 lerp_rate = (1000.0 / 150.0) * frame->dt;
|
||||
smoothed_rtt = LerpF64(smoothed_rtt, rtt, SaturateF64(lerp_rate));
|
||||
if (rtt != 0 && prev_rtt == 0)
|
||||
{
|
||||
@ -1960,13 +1961,18 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
// Compute prediction tick
|
||||
{
|
||||
frame->predict_tick_accum += frame->dt * SIM_TICKS_PER_SECOND;
|
||||
// frame->predict_tick_accum += frame->dt * SIM_TICKS_PER_SECOND;
|
||||
|
||||
f32 predict_dt = frame->dt + frame->dt * dilation_factor;
|
||||
frame->predict_tick_accum += predict_dt * SIM_TICKS_PER_SECOND;
|
||||
|
||||
|
||||
// f64 lerp_rate = 5.0 * frame->dt;
|
||||
// f64 lerp_rate = 1.0 * frame->dt;
|
||||
f64 lerp_rate = 1;
|
||||
|
||||
frame->predict_tick_accum = LerpF64(frame->predict_tick_accum, frame->target_predict_tick_accum, SaturateF64(lerp_rate));
|
||||
// frame->predict_tick_accum = LerpF64(frame->predict_tick_accum, frame->target_predict_tick_accum, SaturateF64(lerp_rate));
|
||||
frame->predict_tick_accum = frame->target_predict_tick_accum;
|
||||
}
|
||||
|
||||
if ((ack == 0 && prev_frame_ack != 0) || AbsF64(frame->predict_tick_accum - ack) > SIM_TICKS_PER_SECOND)
|
||||
@ -1977,7 +1983,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
|
||||
// We cannot simulate backwards
|
||||
frame->predict_tick_accum = MaxF64(prev_frame->predict_tick_accum, frame->predict_tick_accum);
|
||||
// frame->predict_tick_accum = MaxF64(prev_frame->predict_tick_accum, frame->predict_tick_accum);
|
||||
|
||||
// V_PushTimelineMarker(frame->predict_tick_accum, Color_Red, 1);
|
||||
// V_PushTimelineMarker(frame->target_predict_tick_accum, Color_Yellow, 1);
|
||||
@ -2270,20 +2276,21 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
// How many ticks back in time should the user thread blend between?
|
||||
// <Delay> = <USER_INTERP_RATIO> * <Tick interval>
|
||||
// E.g: At 1.5, the world will render 75ms back in time if the sim runs at 50tps
|
||||
// f64 interp_ratio = TweakFloat("Interpolation ratio", 1.5, 0, V_MaxInterpRatio);
|
||||
f64 interp_ratio = TweakFloat("Interpolation ratio", 1.5, 0, V_MaxInterpRatio);
|
||||
|
||||
//- Blended sim tick
|
||||
f64 target_blend_sim_tick = (f64)ack - interp_ratio;
|
||||
{
|
||||
f64 lerp_rate = SaturateF64(5.0 * frame->dt);
|
||||
frame->blend_sim_tick += frame->dt * SIM_TICKS_PER_SECOND;
|
||||
// frame->blend_sim_tick += frame->dt * SIM_TICKS_PER_SECOND;
|
||||
frame->blend_sim_tick += (frame->dt + frame->dt * dilation_factor) * SIM_TICKS_PER_SECOND;
|
||||
frame->blend_sim_tick = LerpF64(frame->blend_sim_tick, target_blend_sim_tick, lerp_rate);
|
||||
frame->blend_sim_tick = MaxF64(frame->blend_sim_tick, prev_frame->blend_sim_tick);
|
||||
if ((prev_frame_ack == 0 && ack != 0) || AbsF64(frame->blend_sim_tick - ack) > SIM_TICKS_PER_SECOND)
|
||||
{
|
||||
frame->blend_sim_tick = LerpF64(frame->blend_sim_tick, target_blend_sim_tick, lerp_rate);
|
||||
if ((prev_frame_ack == 0 && ack != 0) || AbsF64(frame->blend_sim_tick - ack) > SIM_TICKS_PER_SECOND)
|
||||
{
|
||||
frame->blend_sim_tick = target_blend_sim_tick;
|
||||
LogDebugF("Sim blend reset");
|
||||
}
|
||||
frame->blend_sim_tick = target_blend_sim_tick;
|
||||
LogDebugF("Sim blend reset");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2291,14 +2298,14 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
f64 target_blend_predict_tick = frame->predict_tick_accum - interp_ratio;
|
||||
{
|
||||
f64 lerp_rate = SaturateF64(2.0 * frame->dt);
|
||||
frame->blend_predict_tick += frame->dt * SIM_TICKS_PER_SECOND;
|
||||
// frame->blend_predict_tick += frame->dt * SIM_TICKS_PER_SECOND;
|
||||
frame->blend_predict_tick += (frame->dt + frame->dt * dilation_factor) * SIM_TICKS_PER_SECOND;
|
||||
frame->blend_predict_tick = LerpF64(frame->blend_predict_tick, target_blend_predict_tick, lerp_rate);
|
||||
frame->blend_predict_tick = MaxF64(frame->blend_predict_tick, prev_frame->blend_predict_tick);
|
||||
if ((prev_frame_ack == 0 && ack != 0) || AbsF64(frame->blend_predict_tick - ack) > SIM_TICKS_PER_SECOND)
|
||||
{
|
||||
frame->blend_predict_tick = LerpF64(frame->blend_predict_tick, target_blend_predict_tick, lerp_rate);
|
||||
if ((prev_frame_ack == 0 && ack != 0) || AbsF64(frame->blend_predict_tick - ack) > SIM_TICKS_PER_SECOND)
|
||||
{
|
||||
frame->blend_predict_tick = target_blend_predict_tick;
|
||||
LogDebugF("Prediction blend reset");
|
||||
}
|
||||
frame->blend_predict_tick = target_blend_predict_tick;
|
||||
LogDebugF("Prediction blend reset");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2588,8 +2595,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
P_Ent *ent = local_follow;
|
||||
|
||||
P_Anim anim = P_AnimFromEnt(local_frame, ent);
|
||||
SPR_Sprite body = SPR_SpriteFromSheet(anim.sheet, anim.span, anim.frame_seq);
|
||||
SPR_Sprite wep = SPR_SpriteFromSheet(anim.wep_sheet, anim.span, anim.frame_seq);
|
||||
SPR_Sprite body = SPR_SpriteFromSheet(anim.body_sheet, anim.body_span, anim.body_frame_seq);
|
||||
SPR_Sprite wep = SPR_SpriteFromSheet(anim.wep_sheet, anim.wep_span, anim.wep_frame_seq);
|
||||
|
||||
Vec2 look = ent->control.look;
|
||||
if (P_MatchEntKey(ent->key, local_guy->key))
|
||||
@ -2876,7 +2883,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
SPR_Sprite body = Zi;
|
||||
Affine body_pix_to_world_af = AffineIdentity;
|
||||
{
|
||||
body = SPR_SpriteFromSheet(anim.sheet, anim.span, anim.frame_seq);
|
||||
body = SPR_SpriteFromSheet(anim.body_sheet, anim.body_span, anim.body_frame_seq);
|
||||
|
||||
body_pix_to_world_af = MulAffine(body_pix_to_world_af, ent_to_world_af);
|
||||
body_pix_to_world_af = ScaleAffine(body_pix_to_world_af, pix_scale);
|
||||
@ -2890,16 +2897,20 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
SPR_Sprite legs = Zi;
|
||||
Affine legs_pix_to_world_af = AffineIdentity;
|
||||
{
|
||||
Vec2 move_dir = NormVec2(ent->control.move);
|
||||
Vec2 legs_dir = NormVec2(ent->control.move);
|
||||
if (P_IsEntRolling(local_frame, ent))
|
||||
{
|
||||
legs_dir = ent->xf.r;
|
||||
}
|
||||
|
||||
legs = SPR_SpriteFromSheet(anim.legs_sheet, anim.span, anim.frame_seq);
|
||||
legs = SPR_SpriteFromSheet(anim.legs_sheet, anim.legs_span, anim.legs_frame_seq);
|
||||
|
||||
legs_pix_to_world_af = TranslateAffine(legs_pix_to_world_af, ent_to_world_af.og);
|
||||
legs_pix_to_world_af = ScaleAffine(legs_pix_to_world_af, pix_scale);
|
||||
|
||||
SPR_Ray anchor_ray = legs.rays[SPR_RayKind_Anchor];
|
||||
legs_pix_to_world_af = RotateAffine(legs_pix_to_world_af, InvertRot(anchor_ray.dir));
|
||||
legs_pix_to_world_af = RotateAffine(legs_pix_to_world_af, move_dir);
|
||||
legs_pix_to_world_af = RotateAffine(legs_pix_to_world_af, legs_dir);
|
||||
legs_pix_to_world_af = TranslateAffine(legs_pix_to_world_af, NegVec2(anchor_ray.pos));
|
||||
}
|
||||
|
||||
@ -2908,7 +2919,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Affine wep_pix_to_world_af = AffineIdentity;
|
||||
if (ent->is_guy)
|
||||
{
|
||||
wep = SPR_SpriteFromSheet(anim.wep_sheet, anim.span, anim.frame_seq);
|
||||
wep = SPR_SpriteFromSheet(anim.wep_sheet, anim.wep_span, anim.wep_frame_seq);
|
||||
|
||||
wep_pix_to_world_af = MulAffine(wep_pix_to_world_af, ent_to_world_af);
|
||||
wep_pix_to_world_af = ScaleAffine(wep_pix_to_world_af, pix_scale);
|
||||
@ -2925,6 +2936,27 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
wep_pix_to_world_af = TranslateAffine(wep_pix_to_world_af, NegVec2(anchor_ray.pos));
|
||||
}
|
||||
|
||||
//- Determine mask colors
|
||||
Vec4 body_mask_color_lin = Zi;
|
||||
Vec4 legs_mask_color_lin = Zi;
|
||||
if (ent->is_guy)
|
||||
{
|
||||
f32 body_hue_offset = TweakFloat("Guy body hue offset", 135, 0, 360);
|
||||
f32 body_s = TweakFloat("Guy body saturation", 0.7, 0, 1);
|
||||
f32 body_v = TweakFloat("Guy body brightness", 1, 0, 1);
|
||||
f32 legs_hue_offset = TweakFloat("Guy legs hue offset", 180, 0, 360);
|
||||
f32 legs_s = TweakFloat("Guy legs saturation", 1, 0, 1);
|
||||
f32 legs_v = TweakFloat("Guy legs brightness", 1, 0, 1);
|
||||
{
|
||||
P_Ent *player = P_EntFromKey(local_frame, ent->source);
|
||||
u64 color_seed = HashString(P_StringFromEnt(player));
|
||||
f32 body_hue = (Norm16(color_seed >> 2) * 1) * 360 + body_hue_offset;
|
||||
f32 legs_hue = ModF32(body_hue + legs_hue_offset, 360);
|
||||
body_mask_color_lin = LinearFromSrgb(SrgbFromHsv(body_hue, body_s, body_v));
|
||||
legs_mask_color_lin = LinearFromSrgb(SrgbFromHsv(legs_hue, legs_s, legs_v));
|
||||
}
|
||||
}
|
||||
|
||||
//- Push weapon quad
|
||||
if (body.ready && wep.ready)
|
||||
{
|
||||
@ -2946,6 +2978,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
legs_quad.quad_uv_to_world_af = legs_uv_to_world_af;
|
||||
legs_quad.tex = legs.tex;
|
||||
legs_quad.tex_slice_uv = DivRng2Vec2(legs.tex_rect, legs.tex_dims);
|
||||
legs_quad.mask_color_lin = legs_mask_color_lin;
|
||||
}
|
||||
|
||||
//- Body quad
|
||||
@ -2957,6 +2990,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
body_quad.tex_slice_uv = DivRng2Vec2(body.tex_rect, body.tex_dims);
|
||||
if (ent->is_guy)
|
||||
{
|
||||
body_quad.mask_color_lin = body_mask_color_lin;
|
||||
body_quad.occluder_id = ent->key.v & 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
@ -3407,51 +3441,12 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//- Wall impact particles
|
||||
if (material != P_MaterialKind_Flesh)
|
||||
{
|
||||
// Debris
|
||||
// {
|
||||
// V_Emitter emitter = Zi;
|
||||
// {
|
||||
// // emitter.flags |= V_ParticleFlag_PruneWhenStill;
|
||||
// // emitter.flags |= V_ParticleFlag_StainOnPrune;
|
||||
|
||||
|
||||
// emitter.kind = V_ParticleKind_Debris;
|
||||
// emitter.count = 4;
|
||||
|
||||
// emitter.pos.p0 =
|
||||
// emitter.pos.p1 = hit_entry;
|
||||
|
||||
// emitter.speed.min = 0;
|
||||
// emitter.speed.max = 20;
|
||||
|
||||
// // emitter.velocity_falloff = 5;
|
||||
// // emitter.velocity_falloff_spread = emitter.velocity_falloff_spread * 1.5;
|
||||
|
||||
// Vec2 dir = impact_dir;
|
||||
|
||||
// f32 angle = AngleFromVec2(dir);
|
||||
// f32 angle_spread = Tau * 0.5;
|
||||
|
||||
// emitter.angle.min = angle - angle_spread / 2;
|
||||
// emitter.angle.max = angle + angle_spread / 2;
|
||||
|
||||
// // emitter.lifetime = 0.25;
|
||||
// // emitter.lifetime = 0.05;
|
||||
// // emitter.lifetime = 0.04;
|
||||
// // emitter.lifetime_spread = emitter.lifetime * 2;
|
||||
// }
|
||||
// V_PushParticles(emitter);
|
||||
// }
|
||||
|
||||
// Hot debris
|
||||
{
|
||||
V_Emitter emitter = Zi;
|
||||
emitter.kind = V_ParticleKind_HotDebris;
|
||||
// emitter.count = MaxF32(1000 * frame->dt, 1);
|
||||
emitter.count = 32;
|
||||
|
||||
// f32 angle = AngleFromVec2(SubVec2(p1, p0));
|
||||
|
||||
f32 angle = AngleFromVec2(impact_dir);
|
||||
|
||||
f32 angle_particle_spread = Tau / 2.5;
|
||||
@ -3461,30 +3456,36 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
emitter.pos.p0 =
|
||||
emitter.pos.p1 = impact_pos;
|
||||
|
||||
// emitter.color_lin = LinearFromSrgb(VEC4(0, 1, 0, 1));
|
||||
|
||||
// emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1));
|
||||
|
||||
emitter.speed.min = 0;
|
||||
emitter.speed.max = 30;
|
||||
|
||||
// emitter.angle.min = angle - angle_spread / 2;
|
||||
// emitter.angle.max = angle + angle_spread / 2;
|
||||
V_PushParticles(emitter);
|
||||
}
|
||||
|
||||
// emitter.angle.min =
|
||||
// emitter.angle.max = angle;
|
||||
|
||||
// emitter.pos.p0 =
|
||||
// emitter.pos.p1 = p0;
|
||||
|
||||
// emitter.speed.min =
|
||||
// emitter.speed.max =
|
||||
|
||||
// emitter.color_lin = LinearFromSrgb(VEC4(0, 1, 0, 1));
|
||||
|
||||
// emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1));
|
||||
// emitter.speed.min =
|
||||
// emitter.speed.max = Vec2Len(SubVec2(p1, p0)) / frame->dt;
|
||||
//- Wall spark
|
||||
{
|
||||
V_Emitter emitter = Zi;
|
||||
emitter.kind = V_ParticleKind_Spark;
|
||||
// emitter.count = MaxF32(1000 * frame->dt, 1);
|
||||
// emitter.count = 128;
|
||||
emitter.count = 1;
|
||||
|
||||
f32 angle = AngleFromVec2(impact_dir);
|
||||
|
||||
f32 angle_spread = Tau / 2;
|
||||
emitter.angle.min = angle - angle_spread / 2;
|
||||
emitter.angle.max = angle + angle_spread / 2;
|
||||
|
||||
emitter.pos.p0 =
|
||||
emitter.pos.p1 = impact_pos;
|
||||
|
||||
emitter.speed.min = 20;
|
||||
emitter.speed.max = 100;
|
||||
|
||||
|
||||
V_PushParticles(emitter);
|
||||
}
|
||||
@ -3494,6 +3495,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Wall dust
|
||||
{
|
||||
V_Emitter emitter = Zi;
|
||||
@ -3503,14 +3506,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
emitter.pos.p0 = emitter.pos.p1 = impact_pos;
|
||||
|
||||
// emitter.color_lin = LinearFromSrgb(VEC4(0.5, 0.5, 0.5, 0.75));
|
||||
|
||||
emitter.speed.min = 1;
|
||||
emitter.speed.max = 20;
|
||||
|
||||
// emitter.velocity_falloff = 12;
|
||||
// emitter.velocity_falloff_spread = emitter.velocity_falloff_spread * 1.5;
|
||||
|
||||
Vec2 dir = impact_dir;
|
||||
f32 angle = AngleFromVec2(dir);
|
||||
f32 angle_spread = Tau * 0.1;
|
||||
@ -3569,6 +3568,30 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
Vec2 death_pos = event->death_pos;
|
||||
|
||||
//- Killfeed
|
||||
{
|
||||
P_Ent *victim = P_EntFromKey(local_frame, event->death_victim);
|
||||
P_Ent *killer = P_EntFromKey(local_frame, event->death_killer);
|
||||
String victim_name = P_StringFromEnt(victim);
|
||||
String killer_name = P_StringFromEnt(killer);
|
||||
|
||||
if (victim_name.len > 0)
|
||||
{
|
||||
u64 killfeed_term_seed = MixU64s(event->key.v, P_KillfeedBasis);
|
||||
String killfeed_term = UpperString(frame->arena, P_KillTerms[killfeed_term_seed % countof(P_KillTerms)]);
|
||||
String msg = Zi;
|
||||
if (killer_name.len > 0)
|
||||
{
|
||||
msg = StringF(frame->arena, "%F %F %F", FmtString(killer_name), FmtString(killfeed_term), FmtString(victim_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = StringF(frame->arena, "%F was %F", FmtString(killfeed_term), FmtString(victim_name));
|
||||
}
|
||||
V_PushNotif(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//- Death particles
|
||||
{
|
||||
V_Emitter emitter = Zi;
|
||||
@ -3932,12 +3955,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
// TODO: More efficient name processing
|
||||
char *name_cstr = sample->name_cstr_lit;
|
||||
zone->name = StringFromCstrNoLimit(name_cstr);
|
||||
|
||||
u64 color_seed = HashString(zone->name);
|
||||
f32 h = (Norm16(color_seed >> 0) * 1) * 360;
|
||||
f32 s = TweakFloat("Profiler zone saturation", 0.50, 0, 1);
|
||||
f32 v = TweakFloat("Profiler zone brightness", 1.00, 0, 1);
|
||||
zone->color = SrgbFromHsv(h, s, v);
|
||||
}
|
||||
zone_track->open_zone = zone;
|
||||
|
||||
@ -4724,7 +4741,12 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
b32 should_collapse_zone = (visual_zone_end_px - visual_zone_start_px) <= zone_collapse_threshold_px;
|
||||
String zone_name = zone->name;
|
||||
u64 zone_id = zone->id;
|
||||
Vec4 zone_color = zone->color;
|
||||
|
||||
u64 color_seed = HashString(zone->name);
|
||||
f32 h = (Norm16(color_seed >> 0) * 1) * 360;
|
||||
f32 s = TweakFloat("Profiler zone saturation", 0.50, 0, 1);
|
||||
f32 v = TweakFloat("Profiler zone brightness", 1.00, 0, 1);
|
||||
Vec4 zone_color = SrgbFromHsv(h, s, v);
|
||||
|
||||
// b32 should_collapse_zone = visual_zone_len_px <= zone_collapse_threshold_px;
|
||||
// b32 should_collapse_zone = 0;
|
||||
@ -5593,6 +5615,19 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Update panels from cmds
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: Remove this
|
||||
if (frame->tick == 1)
|
||||
{
|
||||
frame->show_consoles = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
b32 show_editor_panels = (frame->is_editing && !hide_editor_ui) || TweakBool("Show panels when not editing", 0);
|
||||
{
|
||||
Struct(PanelBfs) { PanelBfs *next; V_Panel *panel; };
|
||||
@ -7682,16 +7717,18 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
UI_PushDF(Font, theme.player_name_font)
|
||||
UI_PushDF(FontSize, 12)
|
||||
UI_PushDF(Width, UI_Shrink(3, 1))
|
||||
UI_PushDF(Height, UI_Shrink(2, 1))
|
||||
UI_PushDF(BackgroundColor, Color_Black)
|
||||
UI_PushDF(Width, UI_Shrink(4, 1))
|
||||
UI_PushDF(Height, UI_Shrink(1, 1))
|
||||
// UI_PushDF(BackgroundColor, Color_Black)
|
||||
UI_PushDF(ChildAlignment, UI_Region_Center)
|
||||
UI_PushDF(Opacity, 0.95)
|
||||
UI_PushDF(Rounding, UI_Rgrow(0.25))
|
||||
// UI_PushDF(BackgroundColor, Color_Cyan)
|
||||
UI_PushDF(FontSize, UI_Top(FontSize) * 1.5)
|
||||
// UI_PushDF(FontSize, UI_Top(FontSize) * 1.5)
|
||||
UI_PushDF(FontSize, 16)
|
||||
// UI_PushDF(TextColor, SrgbFromHsv(32, 1, 1))
|
||||
UI_PushDF(TextColor, SrgbFromHsv(32, 0.75, 1))
|
||||
// UI_PushDF(TextColor, SrgbFromHsv(32, 0.75, 1))
|
||||
UI_PushDF(TextColor, VEC4(0.95, 0.95, 0.95, 1))
|
||||
UI_PushDF(Parent, vis_screen_overlay_box)
|
||||
UI_PushDF(Anchor, UI_Region_Bottom)
|
||||
UI_PushDF(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DrawText | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY)
|
||||
@ -7705,7 +7742,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
if (guy->is_guy && name.len > 0)
|
||||
{
|
||||
Vec2 guy_world_pos = guy->xf.t;
|
||||
guy_world_pos.y -= UI_Top(FontSize) * 0.01;
|
||||
// guy_world_pos.y -= UI_Top(FontSize) * 0.01;
|
||||
guy_world_pos.y -= 0.25;
|
||||
|
||||
Vec2 guy_screen_pos = MulAffineVec2(frame->af.world_to_screen, guy_world_pos);
|
||||
|
||||
@ -7713,21 +7751,21 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
text_pos.x = guy_screen_pos.x;
|
||||
text_pos.y = guy_screen_pos.y;
|
||||
|
||||
UI_PushDF(Text, name)
|
||||
// UI_PushDF(Text, name)
|
||||
{
|
||||
// Name box
|
||||
// UI_SetNext(TextColor, Color_Transparent);
|
||||
UI_SetNext(FloatingPos, text_pos);
|
||||
UI_PushDF(Text, name)
|
||||
UI_PushDF(Parent, UI_BuildBox())
|
||||
UI_PushDF(Text, name)
|
||||
{
|
||||
// // Drop-shadow
|
||||
// UI_SetNext(TextColor, Color_Black);
|
||||
// UI_SetNext(FloatingPos, AddVec2(text_pos, VEC2(2, 2)));
|
||||
// UI_BuildBox();
|
||||
// Drop-shadow
|
||||
UI_SetNext(TextColor, Color_Black);
|
||||
UI_SetNext(FloatingPos, VEC2(2, 2));
|
||||
UI_BuildBox();
|
||||
|
||||
// Name text
|
||||
// UI_BuildBox();
|
||||
UI_BuildBox();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -258,10 +258,7 @@ Struct(V_Zone)
|
||||
|
||||
String name;
|
||||
u64 id;
|
||||
|
||||
i64 depth;
|
||||
|
||||
Vec4 color;
|
||||
i64 start_ns;
|
||||
i64 end_ns;
|
||||
};
|
||||
|
||||
@ -406,6 +406,11 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input)
|
||||
|
||||
Vec4 albedo = tex.Sample(sampler, input.samp_uv);
|
||||
|
||||
if (quad.mask_color_lin.a != 0 && all(albedo == Color_White))
|
||||
{
|
||||
albedo = quad.mask_color_lin;
|
||||
}
|
||||
|
||||
if (is_in_world)
|
||||
{
|
||||
// TODO: Don't write occluders using screen space result. Do separate draw pass instead.
|
||||
|
||||
@ -272,6 +272,7 @@ Struct(V_GpuQuad)
|
||||
Affine quad_uv_to_world_af;
|
||||
G_TextureRef tex;
|
||||
Rng2 tex_slice_uv;
|
||||
Vec4 mask_color_lin;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
Loading…
Reference in New Issue
Block a user