fire bullets from weapon position
This commit is contained in:
parent
80f9434af8
commit
399f3a1528
68
src/pp/pp.c
68
src/pp/pp.c
@ -2460,34 +2460,60 @@ void P_StepFrame(P_Frame *frame)
|
||||
{
|
||||
P_Shape firer_world_shape = P_WorldShapeFromEnt(firer);
|
||||
|
||||
Vec2 base_pos = P_EdgePointFromShape(firer_world_shape, firer->control.look);
|
||||
Vec2 base_dir = firer->control.look;
|
||||
// Vec2 fire_pos = P_EdgePointFromShape(firer_world_shape, firer->control.look);
|
||||
// Vec2 fire_dir = firer->control.look;
|
||||
|
||||
// Xform base_xf = Zi;
|
||||
// {
|
||||
// P_Anim anim = P_AnimFromEnt(firer, frame->time_ns);
|
||||
Vec2 fire_pos = Zi;
|
||||
Vec2 fire_dir = Zi;
|
||||
{
|
||||
Vec2 look = firer->control.look;
|
||||
P_Anim anim = P_AnimFromEnt(firer, frame->time_ns);
|
||||
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_LayerKey origin_layer = SPR_LayerKeyFromName(Lit(".origin"));
|
||||
// SPR_LayerKey ap_layer = SPR_LayerKeyFromName(Lit(".ap"));
|
||||
//- Compute sprite transforms
|
||||
Affine ent_to_world_af = MulAffineXform(AffineIdentity, firer->xf);
|
||||
Affine body_pix_to_world_af = AffineIdentity;
|
||||
Affine wep_pix_to_world_af = AffineIdentity;
|
||||
{
|
||||
Vec2 pix_scale = VEC2(1.0 / P_CellsPerMeter, 1.0 / P_CellsPerMeter);
|
||||
|
||||
// Xform firer_to_body_origin_xf = SPR_XformFromSheet(anim.sheet, origin_layer, anim.span, anim.frame_seq);
|
||||
// Xform firer_to_body_ap_xf = SPR_XformFromSheet(anim.sheet, ap_layer, anim.span, anim.frame_seq);
|
||||
//- Compute body transform
|
||||
Affine body_pix_to_ent_af = AffineIdentity;
|
||||
{
|
||||
body_pix_to_ent_af = ScaleAffine(body_pix_to_ent_af, pix_scale);
|
||||
|
||||
// Xform body_ap_to_wep_origin_xf = SPR_XformFromSheet(anim.wep_sheet, origin_layer, anim.span, anim.frame_seq);
|
||||
// Xform body_ap_to_wep_ap_xf = SPR_XformFromSheet(anim.wep_sheet, ap_layer, anim.span, anim.frame_seq);
|
||||
SPR_Ray anchor_ray = body.rays[SPR_RayKind_Anchor];
|
||||
body_pix_to_ent_af = RotateAffine(body_pix_to_ent_af, InvertRot(anchor_ray.dir));
|
||||
body_pix_to_ent_af = TranslateAffine(body_pix_to_ent_af, NegVec2(anchor_ray.pos));
|
||||
}
|
||||
|
||||
// // Xform fo2w = SubVec2(firer_
|
||||
// Xform firer_to_world_xf = firer->xf;
|
||||
// Xform bullet_xf = MulXform(firer_to_world_xf, firer_to_body_ap_xf);
|
||||
// base_pos = bullet_xf.t;
|
||||
//- Compute weapon transform
|
||||
Affine wep_pix_to_ent_af = AffineIdentity;
|
||||
{
|
||||
wep_pix_to_ent_af = ScaleAffine(wep_pix_to_ent_af, pix_scale);
|
||||
|
||||
// // FIXME: Real dir
|
||||
// // base_dir = firer->control.look;
|
||||
// base_dir = bullet_xf.r;
|
||||
// }
|
||||
SPR_Ray body_anchor_ray = body.rays[SPR_RayKind_Anchor];
|
||||
SPR_Ray body_ap_ray = body.rays[SPR_RayKind_Ap];
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, InvertRot(body_anchor_ray.dir));
|
||||
wep_pix_to_ent_af = TranslateAffine(wep_pix_to_ent_af, SubVec2(body_ap_ray.pos, body_anchor_ray.pos));
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, InvertRot(body_ap_ray.dir));
|
||||
|
||||
SPR_Ray anchor_ray = wep.rays[SPR_RayKind_Anchor];
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, anchor_ray.dir);
|
||||
wep_pix_to_ent_af = TranslateAffine(wep_pix_to_ent_af, NegVec2(anchor_ray.pos));
|
||||
}
|
||||
|
||||
body_pix_to_world_af = MulAffine(ent_to_world_af, body_pix_to_ent_af);
|
||||
wep_pix_to_world_af = MulAffine(ent_to_world_af, wep_pix_to_ent_af);
|
||||
}
|
||||
|
||||
SPR_Ray fire_ray = wep.rays[SPR_RayKind_Ap];
|
||||
fire_pos = MulAffineVec2(wep_pix_to_world_af, fire_ray.pos);
|
||||
fire_dir = NormRot(MulAffineBasisVec2(wep_pix_to_world_af, fire_ray.dir));
|
||||
}
|
||||
|
||||
// FIXME: Prevent obstructed weapons from firing through walls
|
||||
for (i64 bullet_idx = 0; bullet_idx < tick_bullets_count; ++bullet_idx)
|
||||
{
|
||||
P_Ent *bullet = P_PushTempEnt(scratch.arena, &bullets_to_spawn);
|
||||
@ -2498,14 +2524,14 @@ void P_StepFrame(P_Frame *frame)
|
||||
f32 rand_angle = ((f32)P_RandU64FromEnt(firer) / (f32)0xFFFFFFFFFFFFFFFFull) - 0.5;
|
||||
|
||||
f32 speed = tweak_speed * sim_dt;
|
||||
f32 angle = AngleFromVec2(base_dir);
|
||||
f32 angle = AngleFromVec2(fire_dir);
|
||||
|
||||
speed += (speed * 0.5) * rand_speed;
|
||||
angle += rand_angle * spread;
|
||||
|
||||
Vec2 dir = Vec2FromAngle(angle);
|
||||
|
||||
bullet->bullet_start = base_pos;
|
||||
bullet->bullet_start = fire_pos;
|
||||
bullet->bullet_end = AddVec2(bullet->bullet_start, MulVec2(dir, speed));
|
||||
bullet->bullet_firer = firer->key;
|
||||
}
|
||||
|
||||
@ -577,6 +577,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
frame->sim_key = prev_frame->sim_key;
|
||||
frame->desired_sim_key = prev_frame->desired_sim_key;
|
||||
frame->predict_tick_accum = prev_frame->predict_tick_accum;
|
||||
frame->af = prev_frame->af;
|
||||
|
||||
frame->tick = V.current_frame_tick;
|
||||
frame->time_ns = TimeNs();
|
||||
@ -830,6 +831,17 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Compute movement & look
|
||||
|
||||
f32 look_radius = 0;
|
||||
{
|
||||
Vec2 world_screen_dims = MulAffineBasisVec2(prev_frame->af.screen_to_world, prev_frame->screen_dims);
|
||||
// look_radius = MinF32(world_screen_dims.x, world_screen_dims.y) * 0.5;
|
||||
look_radius = MinF32(world_screen_dims.x, world_screen_dims.y) * 0.75;
|
||||
|
||||
// FIXME: Lower
|
||||
f32 max_look_radius = 10;
|
||||
look_radius = ClampF32(look_radius, 1, max_look_radius);
|
||||
}
|
||||
|
||||
if (!frame->is_editing && !frame->palette.is_showing)
|
||||
{
|
||||
WND_PushCmd(window_frame, .kind = WND_CmdKind_SetLockedCursor, .v = 1);
|
||||
@ -849,14 +861,11 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Vec2 look = Zi;
|
||||
f32 fire_presses = fire_held && !prev_frame->held_buttons[Button_M1];
|
||||
{
|
||||
// Vec2 center = P_WorldShapeFromEnt(local_guy).centroid;
|
||||
// look = SubVec2(frame->world_cursor, center);
|
||||
|
||||
// TODO: Adjustable sensitivity
|
||||
f32 mouse_scale_factor = 0.005;
|
||||
|
||||
look = frame->look;
|
||||
look = AddVec2(look, MulVec2(mouse_delta, mouse_scale_factor));
|
||||
look = ClampVec2Len(look, look_radius);
|
||||
}
|
||||
if (frame->is_editing)
|
||||
{
|
||||
@ -923,14 +932,63 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
else
|
||||
{
|
||||
// // Vec2 look_ratio = VEC2(0.5, 0.5);
|
||||
// Vec2 look_ratio = VEC2(0.75, 0.75);
|
||||
// // Vec2 look_ratio = VEC2(1.0, 1.0);
|
||||
// {
|
||||
// // look_ratio.y = 0.5;
|
||||
// // look_ratio.x = look_ratio.y / (16.0 / 9.0);
|
||||
// }
|
||||
|
||||
// Vec2 look_ratio = Zi;
|
||||
// {
|
||||
// Vec2 max_look = Vec2WithLen(frame->look, look_radius);
|
||||
|
||||
// Vec2 look_ratio_of_max = DivVec2Vec2(frame->look, Vec2WithLen(frame->look, look_radius));
|
||||
|
||||
// look_ratio = look_ratio_of_max;
|
||||
|
||||
// // Vec2 screen_look = MulAffineVec2(frame->af.world_to_screen, frame->look);
|
||||
// // Vec2 screen_max_look = MulAffineVec2(frame->af.world_to_screen, frame->look)
|
||||
|
||||
// // look_ratio.x = screen_look.x / frame->screen_dims.x;
|
||||
// // look_ratio.x = frame->look.x / look_radius;
|
||||
|
||||
|
||||
// if (IsNan(look_ratio.x) || IsNan(look_ratio.y))
|
||||
// {
|
||||
// look_ratio = VEC2(0, 0);
|
||||
// }
|
||||
// }
|
||||
|
||||
Vec2 look_ratio = Zi;
|
||||
look_ratio.y = 0.5;
|
||||
look_ratio.x = look_ratio.y / (16.0 / 9.0);
|
||||
{
|
||||
Vec2 max_look = Vec2WithLen(frame->look, look_radius);
|
||||
|
||||
Vec2 look_ratio_of_radius = DivVec2Vec2(frame->look, Vec2WithLen(frame->look, look_radius));
|
||||
|
||||
look_ratio = look_ratio_of_radius;
|
||||
|
||||
// Vec2 screen_look = MulAffineVec2(frame->af.world_to_screen, frame->look);
|
||||
// Vec2 screen_max_look = MulAffineVec2(frame->af.world_to_screen, frame->look)
|
||||
|
||||
// look_ratio.x = screen_look.x / frame->screen_dims.x;
|
||||
// look_ratio.x = frame->look.x / look_radius;
|
||||
|
||||
|
||||
if (IsNan(look_ratio.x) || IsNan(look_ratio.y))
|
||||
{
|
||||
look_ratio = VEC2(0, 0);
|
||||
}
|
||||
|
||||
// look_ratio = MulVec2(look_ratio, 0.5);
|
||||
look_ratio = VEC2(0.5, 0.5);
|
||||
}
|
||||
|
||||
P_Ent *player = P_EntFromKey(local_world->last_frame, V.player_key);
|
||||
P_Ent *guy = P_EntFromKey(local_world->last_frame, player->guy);
|
||||
Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid;
|
||||
Vec2 screen_center = MulVec2(frame->screen_dims, 0.5);
|
||||
// Vec2 look = MulAffineBasisVec2(prev_frame->af.screen_to_world, SubVec2(ui_frame->cursor_pos, screen_center));
|
||||
target_camera_pos = guy_center;
|
||||
target_camera_pos = AddVec2(target_camera_pos, MulVec2Vec2(frame->look, look_ratio));
|
||||
target_camera_zoom = 1;
|
||||
@ -1932,6 +1990,93 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Draw crosshair
|
||||
|
||||
// // TODO: Alive / weapon check
|
||||
// if (!P_IsEntNil(local_guy))
|
||||
// {
|
||||
// P_Ent *ent = local_guy;
|
||||
|
||||
// P_Anim anim = P_AnimFromEnt(ent, local_frame->time_ns);
|
||||
// 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);
|
||||
|
||||
// Vec2 look = ent->control.look;
|
||||
// if (P_MatchKey(ent->key, local_guy->key))
|
||||
// {
|
||||
// // Late latch local player aim direction for lower-latency
|
||||
// look = frame->look;
|
||||
// }
|
||||
|
||||
// //- Compute sprite transforms
|
||||
// Affine cur_ent_to_world_af = MulAffineXform(AffineIdentity, ent->xf);
|
||||
// Affine desired_ent_to_world_af = MulAffineXform(AffineIdentity, XformTR(ent->xf.t, NormRot(look)));
|
||||
// Affine cur_body_pix_to_world_af = AffineIdentity;
|
||||
// Affine cur_wep_pix_to_world_af = AffineIdentity;
|
||||
// Affine desired_body_pix_to_world_af = AffineIdentity;
|
||||
// Affine desired_wep_pix_to_world_af = AffineIdentity;
|
||||
// {
|
||||
// Vec2 pix_scale = VEC2(1.0 / P_CellsPerMeter, 1.0 / P_CellsPerMeter);
|
||||
|
||||
// //- Compute body transform
|
||||
// Affine body_pix_to_ent_af = AffineIdentity;
|
||||
// {
|
||||
// body_pix_to_ent_af = ScaleAffine(body_pix_to_ent_af, pix_scale);
|
||||
|
||||
// SPR_Ray anchor_ray = body.rays[SPR_RayKind_Anchor];
|
||||
// body_pix_to_ent_af = RotateAffine(body_pix_to_ent_af, InvertRot(anchor_ray.dir));
|
||||
// body_pix_to_ent_af = TranslateAffine(body_pix_to_ent_af, NegVec2(anchor_ray.pos));
|
||||
// }
|
||||
|
||||
// //- Compute weapon transform
|
||||
// Affine wep_pix_to_ent_af = AffineIdentity;
|
||||
// {
|
||||
// wep_pix_to_ent_af = ScaleAffine(wep_pix_to_ent_af, pix_scale);
|
||||
|
||||
// SPR_Ray body_anchor_ray = body.rays[SPR_RayKind_Anchor];
|
||||
// SPR_Ray body_ap_ray = body.rays[SPR_RayKind_Ap];
|
||||
// wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, InvertRot(body_anchor_ray.dir));
|
||||
// wep_pix_to_ent_af = TranslateAffine(wep_pix_to_ent_af, SubVec2(body_ap_ray.pos, body_anchor_ray.pos));
|
||||
// wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, InvertRot(body_ap_ray.dir));
|
||||
|
||||
// SPR_Ray anchor_ray = wep.rays[SPR_RayKind_Anchor];
|
||||
// wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, anchor_ray.dir);
|
||||
// wep_pix_to_ent_af = TranslateAffine(wep_pix_to_ent_af, NegVec2(anchor_ray.pos));
|
||||
// }
|
||||
|
||||
// cur_body_pix_to_world_af = MulAffine(cur_ent_to_world_af, body_pix_to_ent_af);
|
||||
// cur_wep_pix_to_world_af = MulAffine(cur_ent_to_world_af, wep_pix_to_ent_af);
|
||||
// desired_body_pix_to_world_af = MulAffine(desired_ent_to_world_af, body_pix_to_ent_af);
|
||||
// desired_wep_pix_to_world_af = MulAffine(desired_ent_to_world_af, wep_pix_to_ent_af);
|
||||
// }
|
||||
|
||||
// SPR_Ray fire_ray = wep.rays[SPR_RayKind_Ap];
|
||||
|
||||
// Vec2 cur_fire_pos = MulAffineVec2(cur_wep_pix_to_world_af, fire_ray.pos);
|
||||
// Vec2 cur_fire_dir = NormRot(MulAffineBasisVec2(cur_wep_pix_to_world_af, fire_ray.dir));
|
||||
// Vec2 desired_fire_pos = MulAffineVec2(desired_wep_pix_to_world_af, fire_ray.pos);
|
||||
// Vec2 desired_fire_dir = NormRot(MulAffineBasisVec2(desired_wep_pix_to_world_af, fire_ray.dir));
|
||||
|
||||
// Vec2 look_rot = NormRot(look);
|
||||
|
||||
// Vec2 line_start = cur_fire_pos;
|
||||
// Vec2 line_end = AddVec2(line_start, cur_fire_dir);
|
||||
// P_DebugDrawLine(line_start, line_end, Color_Yellow);
|
||||
|
||||
// // Vec2 cross = fire_pos;
|
||||
// // Vec2 cross = MulAffineVec2(frame->af.screen_to_world, look);
|
||||
|
||||
// // f32 cross_dist = 1.0;
|
||||
// f32 cross_dist = Vec2Len(look);
|
||||
|
||||
// Vec2 cross = AddVec2(desired_fire_pos, MulVec2(look_rot, cross_dist));
|
||||
|
||||
// // P_DebugDrawPoint(AddVec2(MulAffineVec2(frame->af.screen_to_world, MulVec2(frame->screen_dims, 0.5)), look), Color_Red);
|
||||
// P_DebugDrawPoint(AddVec2(cur_ent_to_world_af.og, look), Color_Red);
|
||||
// P_DebugDrawPoint(cross, Color_Green);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: Alive / weapon check
|
||||
if (!P_IsEntNil(local_guy))
|
||||
{
|
||||
@ -1941,8 +2086,16 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
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);
|
||||
|
||||
//- Compute sprite transforms
|
||||
Vec2 look = ent->control.look;
|
||||
if (P_MatchKey(ent->key, local_guy->key))
|
||||
{
|
||||
// Late latch local player aim direction for lower-latency
|
||||
look = frame->look;
|
||||
}
|
||||
|
||||
//- Compute sprite transforms
|
||||
Affine cur_ent_to_world_af = MulAffineXform(AffineIdentity, ent->xf);
|
||||
Affine desired_ent_to_world_af = MulAffineXform(AffineIdentity, XformTR(ent->xf.t, NormRot(look)));
|
||||
Affine cur_body_pix_to_world_af = AffineIdentity;
|
||||
Affine cur_wep_pix_to_world_af = AffineIdentity;
|
||||
Affine desired_body_pix_to_world_af = AffineIdentity;
|
||||
@ -1950,9 +2103,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
Vec2 pix_scale = VEC2(1.0 / P_CellsPerMeter, 1.0 / P_CellsPerMeter);
|
||||
|
||||
Affine cur_ent_to_world_af = MulAffineXform(AffineIdentity, ent->xf);
|
||||
Affine desired_ent_to_world_af = MulAffineXform(AffineIdentity, XformTR(ent->xf.t, NormRot(ent->control.look)));
|
||||
|
||||
//- Compute body transform
|
||||
Affine body_pix_to_ent_af = AffineIdentity;
|
||||
{
|
||||
@ -1992,26 +2142,31 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Vec2 desired_fire_pos = MulAffineVec2(desired_wep_pix_to_world_af, fire_ray.pos);
|
||||
Vec2 desired_fire_dir = NormRot(MulAffineBasisVec2(desired_wep_pix_to_world_af, fire_ray.dir));
|
||||
|
||||
Vec2 look_dir = NormRot(frame->look);
|
||||
Vec2 look_rot = NormRot(look);
|
||||
|
||||
Vec2 line_start = cur_fire_pos;
|
||||
Vec2 line_end = AddVec2(line_start, cur_fire_dir);
|
||||
P_DebugDrawLine(line_start, line_end, Color_Yellow);
|
||||
// P_DebugDrawLine(line_start, line_end, Color_Yellow);
|
||||
|
||||
// Vec2 cross = fire_pos;
|
||||
// Vec2 cross = MulAffineVec2(frame->af.screen_to_world, frame->look);
|
||||
// Vec2 cross = MulAffineVec2(frame->af.screen_to_world, look);
|
||||
|
||||
// f32 cross_dist = 1.0;
|
||||
f32 cross_dist = Vec2Len(frame->look);
|
||||
f32 cross_dist = Vec2Len(look) - Vec2Len(SubVec2(desired_fire_pos, desired_ent_to_world_af.og));
|
||||
|
||||
Vec2 cross = AddVec2(desired_fire_pos, MulVec2(look_dir, cross_dist));
|
||||
Vec2 cross = AddVec2(desired_fire_pos, MulVec2(look_rot, cross_dist));
|
||||
|
||||
// P_DebugDrawPoint(AddVec2(MulAffineVec2(frame->af.screen_to_world, MulVec2(frame->screen_dims, 0.5)), frame->look), Color_Red);
|
||||
// P_DebugDrawPoint(AddVec2(MulAffineVec2(frame->af.screen_to_world, MulVec2(frame->screen_dims, 0.5)), look), Color_Red);
|
||||
// P_DebugDrawPoint(AddVec2(desired_ent_to_world_af.og, look), Color_Red);
|
||||
P_DebugDrawPoint(cross, Color_Green);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
//- Push test bullet particles
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user