slerp legs
This commit is contained in:
parent
92ed9a4c2d
commit
be610d4055
98
src/pp/pp.c
98
src/pp/pp.c
@ -1992,20 +1992,7 @@ void P_SpawnEntsFromList(P_Frame *frame, P_EntList ents)
|
||||
DllQueuePushNPZ(&P_NilEnt, frame->first_ent, frame->last_ent, dst, next, prev);
|
||||
DllQueuePushNP(bin->first, bin->last, dst, next_in_bin, prev_in_bin);
|
||||
}
|
||||
{
|
||||
P_Ent *old_next = dst->next;
|
||||
P_Ent *old_prev = dst->prev;
|
||||
P_Ent *old_next_in_bin = dst->next_in_bin;
|
||||
P_Ent *old_prev_in_bin = dst->prev_in_bin;
|
||||
{
|
||||
*dst = *src;
|
||||
dst->xf = NormXform(dst->xf);
|
||||
}
|
||||
dst->next = old_next;
|
||||
dst->prev = old_prev;
|
||||
dst->next_in_bin = old_next_in_bin;
|
||||
dst->prev_in_bin = old_prev_in_bin;
|
||||
}
|
||||
dst->net_state = src->net_state;
|
||||
dst->created_at_ns = frame->time_ns;
|
||||
dst->created_at_tick = frame->tick;
|
||||
dst->sim = !P_tl.is_client;
|
||||
@ -3189,11 +3176,11 @@ void P_StepFrame(P_Frame *frame)
|
||||
b32 is_bomb = 0;
|
||||
if (button == P_Button_PrimaryFire && (firer->control.held[button] || firer->control.downs[button]))
|
||||
{
|
||||
// fire_rate = 100;
|
||||
bullets_per_fire = 4;
|
||||
fire_rate = 25;
|
||||
bullets_per_fire = 5;
|
||||
// fire_rate = 50;
|
||||
fire_rate = 50;
|
||||
bullets_per_fire = 1;
|
||||
// fire_rate = 50;
|
||||
// bullets_per_fire = 1;
|
||||
firing = (weapon->last_fire_ns + NsFromSeconds(1.0 / fire_rate)) <= frame->time_ns;
|
||||
if (firing)
|
||||
{
|
||||
@ -3267,9 +3254,10 @@ void P_StepFrame(P_Frame *frame)
|
||||
//////////////////////////////
|
||||
//- Bullet properties
|
||||
|
||||
// f32 spread = Tau * 0.05;
|
||||
// f32 spread = Tau * 0.5;
|
||||
f32 spread = Tau * 0.05;
|
||||
// f32 spread = Tau * 0.2;
|
||||
f32 spread = Tau * 0.01;
|
||||
// f32 spread = Tau * 0.01;
|
||||
// f32 spread = 0;
|
||||
|
||||
b32 should_ricochet = 0;
|
||||
@ -3754,54 +3742,58 @@ void P_StepFrame(P_Frame *frame)
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
//- Kill guys
|
||||
|
||||
{
|
||||
P_EntList ents_to_spawn = Zi;
|
||||
for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy))
|
||||
{
|
||||
if (guy->is_guy && guy->health <= 0)
|
||||
P_EntList ents_to_spawn = Zi;
|
||||
for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy))
|
||||
{
|
||||
P_Ent *old_guy = P_EntFromKey(prev_frame, guy->key);
|
||||
if (old_guy->health > 0)
|
||||
if (guy->is_guy && guy->health <= 0)
|
||||
{
|
||||
P_Ent *player = P_EntFromKey(frame, guy->source);
|
||||
P_Ent *killer = P_EntFromKey(frame, guy->damage_attribution);
|
||||
// Update kill info
|
||||
P_Ent *old_guy = P_EntFromKey(prev_frame, guy->key);
|
||||
if (old_guy->health > 0)
|
||||
{
|
||||
if (player->is_player)
|
||||
P_Ent *player = P_EntFromKey(frame, guy->source);
|
||||
P_Ent *killer = P_EntFromKey(frame, guy->damage_attribution);
|
||||
// Update kill info
|
||||
{
|
||||
player->deaths += 1;
|
||||
if (player->is_player)
|
||||
{
|
||||
player->deaths += 1;
|
||||
}
|
||||
if (killer->is_player && !P_MatchEntKey(player->key, killer->key))
|
||||
{
|
||||
killer->kills += 1;
|
||||
}
|
||||
guy->exists = 0;
|
||||
guy->continuity_gen += 1;
|
||||
guy->health = 1;
|
||||
}
|
||||
if (killer->is_player && !P_MatchEntKey(player->key, killer->key))
|
||||
// Push kill event
|
||||
{
|
||||
killer->kills += 1;
|
||||
P_Ent *death = P_PushTempEnt(scratch.arena, &ents_to_spawn);
|
||||
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_victim = player->key;
|
||||
death->death_killer = killer->key;
|
||||
death->lifetime_seconds = P_ObservationDurationSeconds;
|
||||
}
|
||||
guy->exists = 0;
|
||||
guy->continuity_gen += 1;
|
||||
guy->health = 1;
|
||||
}
|
||||
// Push kill event
|
||||
{
|
||||
P_Ent *death = P_PushTempEnt(scratch.arena, &ents_to_spawn);
|
||||
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_victim = player->key;
|
||||
death->death_killer = killer->key;
|
||||
death->lifetime_seconds = P_ObservationDurationSeconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
P_SpawnEntsFromList(frame, ents_to_spawn);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Smooth values
|
||||
|
||||
for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||
{
|
||||
f32 lerp_rate = SaturateF32(25 * sim_dt);
|
||||
ent->smoothed_move_dir = SlerpVec2(ent->smoothed_move_dir, NormVec2(ent->control.move), lerp_rate);
|
||||
}
|
||||
P_SpawnEntsFromList(frame, ents_to_spawn);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Debug draw
|
||||
|
||||
52
src/pp/pp.h
52
src/pp/pp.h
@ -113,29 +113,13 @@ Struct(P_Control)
|
||||
f32 downs[P_Button_COUNT];
|
||||
};
|
||||
|
||||
Struct(P_Ent)
|
||||
Struct(P_NetworkedEntState)
|
||||
{
|
||||
//- Internal world state
|
||||
|
||||
P_Ent *next;
|
||||
P_Ent *prev;
|
||||
|
||||
P_Ent *next_in_bin;
|
||||
P_Ent *prev_in_bin;
|
||||
|
||||
//- Persistent data
|
||||
|
||||
P_EntKey key;
|
||||
u64 rand_seq;
|
||||
i64 created_at_ns;
|
||||
i64 created_at_tick;
|
||||
f64 lifetime_seconds;
|
||||
|
||||
//- Client data
|
||||
|
||||
i64 initial_observation_time_ns;
|
||||
i64 last_observation_time_ns;
|
||||
b32 is_first_observation;
|
||||
|
||||
//- Build data
|
||||
|
||||
@ -150,12 +134,15 @@ Struct(P_Ent)
|
||||
|
||||
Xform xf;
|
||||
|
||||
f64 lifetime_seconds;
|
||||
|
||||
u64 rand_seq;
|
||||
|
||||
//- Bullet
|
||||
|
||||
b32 is_bullet;
|
||||
u32 bullet_hits_count;
|
||||
|
||||
|
||||
//- Events
|
||||
|
||||
b32 is_trail;
|
||||
@ -242,6 +229,35 @@ Struct(P_Ent)
|
||||
|
||||
Vec2 v; // Linear velocity
|
||||
f32 w; // Angular velocity
|
||||
|
||||
//- Smoothed values
|
||||
Vec2 smoothed_move_dir;
|
||||
};
|
||||
|
||||
Struct(P_LocalEntState)
|
||||
{
|
||||
//- Observation info
|
||||
|
||||
i64 initial_observation_time_ns;
|
||||
i64 last_observation_time_ns;
|
||||
b32 is_first_observation;
|
||||
|
||||
// Vec2 smoothed_v;
|
||||
// Vec2 smoothed_v_dir;
|
||||
// Vec2 smoothed_move_dir;
|
||||
// f32 smoothed_w;
|
||||
};
|
||||
|
||||
Struct(P_Ent)
|
||||
{
|
||||
P_Ent *next;
|
||||
P_Ent *prev;
|
||||
|
||||
P_Ent *next_in_bin;
|
||||
P_Ent *prev_in_bin;
|
||||
|
||||
Embed(P_NetworkedEntState, net_state);
|
||||
Embed(P_LocalEntState, local_state);
|
||||
};
|
||||
|
||||
Struct(P_EntListNode)
|
||||
|
||||
@ -794,7 +794,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
// TODO: Delta compress
|
||||
should_transmit = 1;
|
||||
BB_WriteBytes(&packer_bbw, StringFromStruct(ent));
|
||||
BB_WriteBytes(&packer_bbw, StringFromStruct(&ent->net_state));
|
||||
}
|
||||
u64 delta_end = BB_GetNumBytesWritten(&packer_bbw);
|
||||
if (should_transmit)
|
||||
|
||||
@ -52,30 +52,30 @@ PERSIST Readonly String P_PresetHumanNames[] = {
|
||||
|
||||
// Taken from a random GMOD server
|
||||
PERSIST Readonly String P_PresetPlayerNames[] = {
|
||||
CompLit("lionberg"),
|
||||
CompLit("charlie main"),
|
||||
CompLit("frezh"),
|
||||
CompLit("KARMA"),
|
||||
CompLit("Kirep"),
|
||||
CompLit("Cyan Crayon"),
|
||||
CompLit("THE WIFE"),
|
||||
CompLit("Panda"),
|
||||
CompLit("adoti"),
|
||||
CompLit("yoyota"),
|
||||
CompLit("Mr. Bones"),
|
||||
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"),
|
||||
};
|
||||
|
||||
@ -1822,11 +1822,11 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
while (!done && BB_NumBitsRemaining(&bbr) > 0)
|
||||
{
|
||||
// TODO: Delta compress
|
||||
P_Ent *raw_ent = (P_Ent *)BB_ReadBytesRaw(&bbr, sizeof(P_Ent));
|
||||
if (raw_ent)
|
||||
P_NetworkedEntState *raw_net_state = (P_NetworkedEntState *)BB_ReadBytesRaw(&bbr, sizeof(P_NetworkedEntState));
|
||||
if (raw_net_state)
|
||||
{
|
||||
P_EntListNode tmp_ent_node = Zi;
|
||||
CopyStruct(&tmp_ent_node.ent, raw_ent);
|
||||
CopyStruct(&tmp_ent_node.ent.net_state, raw_net_state);
|
||||
P_EntList ent_list = Zi;
|
||||
ent_list.first = &tmp_ent_node;
|
||||
ent_list.last = &tmp_ent_node;
|
||||
@ -2429,8 +2429,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
ent->xf.t = LerpVec2(left->xf.t, right->xf.t, blend_t);
|
||||
ent->xf.r = SlerpVec2(left->xf.r, right->xf.r, blend_t);
|
||||
ent->walk_time_accum_ns = LerpI64(left->walk_time_accum_ns, right->walk_time_accum_ns, blend_t);
|
||||
ent->fire_time_accum_ns = LerpI64(left->fire_time_accum_ns, right->fire_time_accum_ns, blend_t);
|
||||
ent->v = LerpVec2(left->v, right->v, blend_t);
|
||||
ent->w = LerpF32(left->w, right->w, blend_t);
|
||||
ent->smoothed_move_dir = SlerpVec2(left->smoothed_move_dir, right->smoothed_move_dir, blend_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2456,6 +2458,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
P_EntKey key = ent->key;
|
||||
i64 expiration_ns = NsFromSeconds(P_ObservationDurationSeconds);
|
||||
|
||||
//- Fetch observation
|
||||
V_Observation *obs = 0;
|
||||
{
|
||||
V_ObservationBin *bin = &V.observation_bins[key.v % countof(V.observation_bins)];
|
||||
@ -2499,6 +2503,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
obs->last_observation_time_ns = frame->time_ns;
|
||||
}
|
||||
|
||||
//- Observe
|
||||
ent->last_observation_time_ns = frame->time_ns;
|
||||
ent->is_first_observation = obs->initial_observation_time_ns == frame->time_ns;
|
||||
}
|
||||
@ -2897,7 +2903,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
SPR_Sprite legs = Zi;
|
||||
Affine legs_pix_to_world_af = AffineIdentity;
|
||||
{
|
||||
Vec2 legs_dir = NormVec2(ent->control.move);
|
||||
// Vec2 legs_dir = NormVec2(ent->control.move);
|
||||
Vec2 legs_dir = ent->smoothed_move_dir;
|
||||
if (P_IsEntRolling(local_frame, ent))
|
||||
{
|
||||
legs_dir = ent->xf.r;
|
||||
@ -3441,10 +3448,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//- Wall impact particles
|
||||
if (material != P_MaterialKind_Flesh)
|
||||
{
|
||||
// Hot debris
|
||||
//- Debris
|
||||
{
|
||||
V_Emitter emitter = Zi;
|
||||
emitter.kind = V_ParticleKind_HotDebris;
|
||||
emitter.kind = V_ParticleKind_Debris;
|
||||
emitter.count = 32;
|
||||
|
||||
f32 angle = AngleFromVec2(impact_dir);
|
||||
@ -3466,13 +3473,13 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
|
||||
|
||||
//- Wall spark
|
||||
//- Hot debris
|
||||
{
|
||||
V_Emitter emitter = Zi;
|
||||
emitter.kind = V_ParticleKind_Spark;
|
||||
emitter.kind = V_ParticleKind_HotDebris;
|
||||
// emitter.count = MaxF32(1000 * frame->dt, 1);
|
||||
// emitter.count = 128;
|
||||
emitter.count = 1;
|
||||
emitter.count = 32;
|
||||
|
||||
f32 angle = AngleFromVec2(impact_dir);
|
||||
|
||||
@ -3668,12 +3675,16 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
// f32 speed = 100;
|
||||
f32 speed_spread = speed * 2;
|
||||
|
||||
emitter.pos.p0 = emitter.pos.p1 = frame->world_cursor;
|
||||
f32 particles_per_meter_per_second = Kibi(128);
|
||||
emitter.pos.p0 = prev_frame->world_cursor;
|
||||
emitter.pos.p1 = frame->world_cursor;
|
||||
f32 len_meters = MaxF32(Vec2Len(SubVec2(emitter.pos.p1, emitter.pos.p0)), 1);
|
||||
emitter.count = particles_per_meter_per_second * len_meters * frame->dt;
|
||||
|
||||
emitter.speed.min = speed - speed_spread * 0.5;
|
||||
emitter.speed.max = speed + speed_spread * 0.5;
|
||||
emitter.angle.min = angle - angle_spread * 0.5;
|
||||
emitter.angle.max = angle + angle_spread * 0.5;
|
||||
emitter.count = Kibi(32) * frame->dt;
|
||||
V_PushParticles(emitter);
|
||||
}
|
||||
|
||||
@ -3733,26 +3744,18 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
f32 speed = 100;
|
||||
f32 speed_spread = speed * 2;
|
||||
|
||||
emitter.pos.p0 = emitter.pos.p1 = frame->world_cursor;
|
||||
f32 particles_per_meter_per_second = Kibi(128);
|
||||
|
||||
emitter.pos.p0 = prev_frame->world_cursor;
|
||||
emitter.pos.p1 = frame->world_cursor;
|
||||
f32 len_meters = MaxF32(Vec2Len(SubVec2(emitter.pos.p1, emitter.pos.p0)), 1);
|
||||
emitter.count = particles_per_meter_per_second * len_meters * frame->dt;
|
||||
|
||||
emitter.speed.min = speed - speed_spread * 0.5;
|
||||
emitter.speed.max = speed + speed_spread * 0.5;
|
||||
emitter.angle.min = angle - angle_spread * 0.5;
|
||||
emitter.angle.max = angle + angle_spread * 0.5;
|
||||
|
||||
// emitter.falloff.min = emitter.falloff.max = 0;
|
||||
|
||||
// emitter.count = CeilF32(Kibi(64) * frame->dt);
|
||||
// emitter.count = CeilF32(Mebi(32) * frame->dt);
|
||||
// emitter.count = CeilF32(Mebi(8) * frame->dt);
|
||||
// emitter.count = Mebi(16);
|
||||
// emitter.count = Mebi(2);
|
||||
// emitter.count = Kibi(32);
|
||||
emitter.count = Kibi(8);
|
||||
// emitter.count = 128;
|
||||
// emitter.count = 128;
|
||||
// emitter.count = 32;
|
||||
// emitter.count = 1;
|
||||
|
||||
V_PushParticles(emitter);
|
||||
}
|
||||
|
||||
@ -5619,10 +5622,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
|
||||
// TODO: Remove this
|
||||
if (frame->tick == 1)
|
||||
{
|
||||
frame->show_consoles = 1;
|
||||
}
|
||||
// if (frame->tick == 1)
|
||||
// {
|
||||
// frame->show_consoles = 1;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
@ -378,6 +378,7 @@ Struct(V_Observation)
|
||||
V_Observation *prev;
|
||||
V_Observation *next_in_bin;
|
||||
V_Observation *prev_in_bin;
|
||||
|
||||
u64 key;
|
||||
i64 initial_observation_time_ns;
|
||||
i64 last_observation_time_ns;
|
||||
|
||||
@ -79,10 +79,10 @@ Enum(V_ParticleLayer)
|
||||
/* Layer */ V_ParticleLayer_Mid, \
|
||||
/* Stain rate, pen chance */ 0, 0, \
|
||||
/* Lifetime */ Inf, Inf, \
|
||||
/* Falloff */ 10, 20, \
|
||||
/* Prune speed threshold */ 0.01, \
|
||||
/* Falloff */ 20, 30, \
|
||||
/* Prune speed threshold */ 0.1, \
|
||||
/* Base color */ VEC4(0.4, 0.3, 0.2, 1), \
|
||||
/* Dry color factor */ VEC4(1, 1, 1, 1) \
|
||||
/* Dry color factor */ VEC4(0.2, 0.1, 0.1, 1) \
|
||||
) \
|
||||
X( \
|
||||
/* Name */ Fire, \
|
||||
@ -103,12 +103,12 @@ Enum(V_ParticleLayer)
|
||||
/* Lifetime */ Inf, Inf, \
|
||||
/* Falloff */ 20, 30, \
|
||||
/* Prune speed threshold */ 0.1, \
|
||||
/* Base color */ VEC4(0.4, 0.3, 0.2, 1), \
|
||||
/* Base color */ VEC4(2, 0.5, 0, 1), \
|
||||
/* Dry color factor */ VEC4(0.2, 0.1, 0.1, 1) \
|
||||
) \
|
||||
X( \
|
||||
/* Name */ Spark, \
|
||||
/* Flags */ V_ParticleFlag_StainWhenPruned, \
|
||||
/* Flags */ V_ParticleFlag_None, \
|
||||
/* Layer */ V_ParticleLayer_Mid, \
|
||||
/* Stain rate, pen chance */ 0, 0, \
|
||||
/* Lifetime */ 0.2, 0.3, \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user