power_play/src/pp/pp_ent.h

569 lines
14 KiB
C

////////////////////////////////////////////////////////////
//~ Ent props
Enum(PP_Prop)
{
PP_Prop_Active,
PP_Prop_Release,
PP_Prop_SyncSrc, /* This entity is networked to other clients */
PP_Prop_SyncDst, /* This entity is not locally created, and will sync with incoming net src ents */
PP_Prop_Player,
PP_Prop_IsMaster,
PP_Prop_Cmd,
PP_Prop_TileChunk,
PP_Prop_Wall,
/* Physics collision */
PP_Prop_Sensor, /* This entity's collisions generate contacts */
PP_Prop_Solid, /* This entity's collisions generate contacts to be solved by the physics system (overrides PP_Prop_Sensor) */
PP_Prop_Toi, /* This entity's collisions are processed using TOI (time of impact) for precise collisions */
/* Physics movement */
PP_Prop_Kinematic, /* This entity reacts to velocity */
PP_Prop_Dynamic, /* This entity reacts to velocity and forces (overrides PP_Prop_Kinematic) */
PP_Prop_Controlled,
PP_Prop_CollisionDebug,
PP_Prop_ContactConstraint,
PP_Prop_MotorJoint,
PP_Prop_MouseJoint,
PP_Prop_WeldJoint,
PP_Prop_Camera,
PP_Prop_ActiveCamera,
PP_Prop_Bullet,
PP_Prop_Smg,
PP_Prop_Launcher,
PP_Prop_Chucker,
PP_Prop_ChuckerZone,
PP_Prop_Explosion,
PP_Prop_Tracer,
PP_Prop_Quake,
PP_Prop_Attached,
/* Test props */
PP_Prop_Test,
PP_Prop_SoundEmitterTest,
PP_Prop_LightTest,
PP_Prop_Count
};
////////////////////////////////////////////////////////////
//~ Ent
Struct(PP_Ent)
{
PP_Snapshot *ss;
//- Metadata
b32 valid; /* Is this ent allocated in memory that can be written to (can always be read) */
PP_EntKey key;
u64 props[(PP_Prop_Count + 63) / 64];
u64 continuity_gen;
/* Is this the root ent */
b32 is_root;
/* Is ent a child of the root ent */
b32 is_top;
/* The key of the top level parent of the ent tree (if ent is top then this point to itself) */
PP_EntKey top;
/* Tree */
PP_EntKey parent;
PP_EntKey next;
PP_EntKey prev;
PP_EntKey first;
PP_EntKey last;
/* Lists keyed by index in snapshot ent array */
u32 next_in_id_bin;
u32 prev_in_id_bin;
u32 next_free;
//- Sync
/* PP_Prop_SyncSrc */
/* PP_Prop_SyncDst */
/* Key of the player that owns simulation for this entity */
PP_EntKey owner;
/* Key of the player that should predict simulation of this this entity locally */
PP_EntKey predictor;
//- Position
/* Use xform getters & setters to access. */
Xform _local_xform; /* Transform in relation to parent ent (or the world if ent has no parent) */
Xform _xform; /* Calculated from ent tree */
b32 _is_xform_dirty;
//- Activation
/* If 0, the ent will auto activate at start of next tick if not already active. */
u64 activation_tick;
//- Layer
i32 layer;
i32 final_layer; /* Calculated each tick from ent tree */
//- Cmd
/* PP_Prop_Cmd */
PP_CmdKind cmd_kind;
PP_EntKey cmd_player;
/* FIXME: Lerp */
/* Control cmd */
PP_ControlData cmd_control;
PP_EntKey cmd_control_hovered_ent;
/* Chat cmd */
//String cmd_chat_msg;
//- Chat
/* PP_Prop_Chat */
PP_EntKey chat_player;
//String chat_msg;
//- Tile
/* PP_Prop_TileChunk */
/* FIXME: Move out of here */
u8 tile_chunk_tiles[SIM_TILES_PER_CHUNK_SQRT * SIM_TILES_PER_CHUNK_SQRT];
Vec2I32 tile_chunk_index;
//- Client
/* PP_Prop_Player */
/* FIXME: Lerp */
PP_ClientKey player_client_key; /* The client key on the master sim's machine */
PP_ControlData player_control;
Vec2 player_cursor_pos;
PP_EntKey player_hovered_ent;
PP_EntKey player_control_ent;
PP_EntKey player_camera_ent;
PP_EntKey player_dbg_drag_joint_ent;
b32 player_dbg_drag_start;
b32 player_dbg_drag_stop;
/* Client round-trip-time to server */
i64 player_last_rtt_ns;
f64 player_average_rtt_seconds;
//- Collider
Vec2 collision_dir; /* If set, then only collisions coming from this direction will generate contacts (used for walls to prevent ghost collisions) */
CLD_Shape local_collider;
#if COLLIDER_DEBUG
ContactDebugData collision_debug_data;
#endif
PP_SpaceEntryKey space_key;
//- Constraints / joints
/* PP_Prop_ContactConstraint */
PP_ContactConstraint contact_constraint_data;
/* PP_Prop_MotorJoint */
PP_MotorJoint motor_joint_data;
/* PP_Prop_MouseJoint */
PP_MouseJoint mouse_joint_data;
/* PP_Prop_WeldJoint */
PP_WeldJoint weld_joint_data;
//- Control
/* PP_Prop_Controlled */
PP_EntKey controlling_player;
f32 control_force; /* How much force is applied to achieve desired control movement */
f32 control_force_max_speed; /* Maximum linear velocity achieved by force (m/s) */
f32 control_torque; /* How much torque is applied when turning towards desired focus */
PP_ControlData control;
PP_EntKey move_joint;
PP_EntKey aim_joint;
//- Physics
/* PP_Prop_Dynamic */
//f32 density; /* Density in kg/m^2 */
f32 friction;
f32 mass_unscaled; /* Mass of ent in kg before any transformations */
f32 inertia_unscaled; /* Inertia of ent in kg*m^2 before any transformations */
PP_EntKey ground_friction_joint;
f32 linear_ground_friction;
f32 angular_ground_friction;
/* Use PP_SetLinearVelocity & PP_SetAngularVelocity to set */
Vec2 linear_velocity; /* m/s */
f32 angular_velocity; /* rad/s */
Vec2 force;
f32 torque;
f32 linear_damping;
f32 angular_damping;
//- Sprite
ResourceKey sprite;
SPR_SpanKey sprite_span_key;
u32 sprite_tint;
Vec3 sprite_emittance;
SPR_SliceKey sprite_collider_slice_key; /* Collider will sync to bounds of this slice if set */
Xform sprite_local_xform; /* Sprite transform in relation to ent */
//- Animation
/* PP_Prop_Animating */
i64 animation_last_frame_change_time_ns;
u32 animation_frame;
//- Attachment
/* PP_Prop_Attached */
/* Slice on the parent ent's sprite to attach to */
SPR_SliceKey attach_slice_key;
//- Equip
PP_EntKey equipped;
//- Chucker
/* PP_Prop_Chucker */
PP_EntKey chucker_zone;
PP_EntKey chucker_joint;
//- Chucker zone
/* PP_Prop_ChuckerZone */
PP_EntKey chucker_zone_ent;
u64 chucker_zone_ent_tick;
//- Triggerable
i32 num_primary_triggers;
i32 num_secondary_triggers;
f32 primary_fire_delay;
f32 secondary_fire_delay;
i64 last_primary_fire_ns;
i64 last_secondary_fire_ns;
//- Trigger
/* How many times has this trigger been triggered this tick */
i64 triggered_count;
/* Other triggers to activate when this entity has been triggered */
//PP_EntKey trigger_out_left;
//PP_EntKey trigger_out_right;
//- Bullet
PP_EntKey bullet_src;
PP_EntKey bullet_tracer;
Vec2 bullet_src_pos;
Vec2 bullet_src_dir;
f32 bullet_launch_velocity;
f32 bullet_knockback;
f32 bullet_explosion_strength;
f32 bullet_explosion_radius;
b32 bullet_has_hit;
//- Explosion
f32 explosion_strength;
f32 explosion_radius;
//- Tracer
/* PP_Prop_Tracer */
Vec2 tracer_start;
Vec2 tracer_start_velocity;
f32 tracer_fade_duration; /* Time for tracer to fade from opacity of 1 to 0 */
/* calculated each frame */
Vec2 tracer_gradient_start;
Vec2 tracer_gradient_end;
//- Quake
/* PP_Prop_Quake */
f32 quake_intensity;
f32 quake_frequency;
f32 quake_fade; /* How much intensity to lose per second */
//- Testing
/* PP_Prop_Test */
b32 test_initialized;
Xform test_start_local_xform;
Xform test_start_sprite_xform;
/* PP_Prop_SoundEmitterTest */
// String sound_name;
// MIX_TrackDesc sound_desc;
// MIX_Handle sound_handle;
//- Camera
/* PP_Prop_Camera */
PP_EntKey camera_follow;
Xform camera_quad_xform;
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
u32 camera_lerp_continuity_gen;
Xform camera_xform_target; /* Calculated from camera_follow */
u32 camera_applied_lerp_continuity_gen_plus_one; /* Calculated */
f32 shake;
};
Struct(PP_EntArray)
{
PP_Ent *ents;
u64 count;
};
Struct(PP_PropArray)
{
PP_Prop *props;
u64 count;
};
Struct(PP_EntBin)
{
u32 first;
u32 last;
};
Inline PP_Ent *PP_NilEnt(void)
{
extern Readonly PP_Ent **PP_nil_ent;
return *PP_nil_ent;
}
////////////////////////////////////////////////////////////
//~ Key types
#define PP_NilEntKey ((PP_EntKey) { UID(0, 0) })
#define PP_RootEntKey ((PP_EntKey) { UID(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa) })
/* Key magic number constants (to be used in conjunction with ent ids in deterministic key combinations) */
#define PP_TileChunkBasisUid (UID(0x3ce42de071dd226b, 0x9b566f7df30c813a))
#define PP_ContactBasisUid (UID(0x6a2a5d2dbecf534f, 0x0a8ca7c372a015af))
#define PP_CollisionDebugBasisUid (UID(0x302c01182013bb02, 0x570bd270399d11a5))
////////////////////////////////////////////////////////////
//~ Key helpers
Inline b32 PP_EqEntKey(PP_EntKey a, PP_EntKey b)
{
return EqUid(a.uid, b.uid);
}
Inline b32 PP_IsNilEntKey(PP_EntKey key)
{
return EqUid(key.uid, PP_NilEntKey.uid);
}
////////////////////////////////////////////////////////////
//~ Property helpers
Inline void PP_EnableProp(PP_Ent *ent, PP_Prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
ent->props[index] |= ((u64)1 << bit);
}
Inline void PP_DisableProp(PP_Ent *ent, PP_Prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
ent->props[index] &= ~((u64)1 << bit);
}
Inline b32 PP_HasProp(PP_Ent *ent, PP_Prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
return !!(ent->props[index] & ((u64)1 << bit));
}
Inline b32 PP_IsValidAndActive(PP_Ent *ent)
{
return ent->valid && PP_HasProp(ent, PP_Prop_Active);
}
Inline b32 PP_ShouldPredict(PP_Ent *ent)
{
return PP_EqEntKey(ent->predictor, ent->ss->local_player);
}
Inline b32 PP_IsOwner(PP_Ent *ent)
{
return PP_EqEntKey(ent->owner, ent->ss->local_player);
}
Inline b32 PP_ShouldSimulate(PP_Ent *ent)
{
b32 result = 0;
if (PP_IsValidAndActive(ent))
{
result = 1;
if (PP_HasProp(ent, PP_Prop_SyncDst))
{
PP_EntKey local_player = ent->ss->local_player;
result = PP_EqEntKey(local_player, ent->owner) || PP_EqEntKey(local_player, ent->predictor);
}
}
return result;
}
////////////////////////////////////////////////////////////
//~ Acquire operations
PP_Ent *PP_AcquireRawEnt(PP_Snapshot *ss, PP_Ent *parent, PP_EntKey key);
PP_Ent *PP_AcquireLocalEnt(PP_Ent *parent);
PP_Ent *PP_AcquireLocalEntWithKey(PP_Ent *parent, PP_EntKey key);
PP_Ent *PP_AcquireSyncSrcEnt(PP_Ent *parent);
PP_Ent *PP_AcquireSyncSrcEntWithKey(PP_Ent *parent, PP_EntKey key);
PP_Ent *PP_AcquireSyncDstEnt(PP_Ent *parent, PP_EntKey ent_id, PP_EntKey owner_id);
////////////////////////////////////////////////////////////
//~ Release operations
void PP_ReleaseRawEnt(PP_Ent *ent);
void PP_Release(PP_Ent *ent);
void PP_ReleaseAllWithProp(PP_Snapshot *ss, PP_Prop prop);
////////////////////////////////////////////////////////////
//~ Activate operations
void PP_ActivateEnt(PP_Ent *ent, u64 current_tick);
////////////////////////////////////////////////////////////
//~ Key operations
u32 PP_IndexFromEnt(PP_Snapshot *ss, PP_Ent *ent);
PP_Ent *PP_EntFromIndex(PP_Snapshot *ss, u32 index);
PP_EntBin *PP_EntBinFromKey(PP_Snapshot *ss, PP_EntKey key);
void PP_SetEntKey(PP_Ent *ent, PP_EntKey key);
PP_Ent *PP_EntFromKey(PP_Snapshot *ss, PP_EntKey key);
PP_EntKey PP_RandomKey(void);
PP_EntKey PP_ContactConstraintKeyFromContactingKeys(PP_EntKey player_id, PP_EntKey id0, PP_EntKey id1);
PP_EntKey PP_CollisionDebugKeyFromKeys(PP_EntKey player_id, PP_EntKey id0, PP_EntKey id1);
PP_EntKey PP_TileChunkKeyFromIndex(Vec2I32 chunk_start);
////////////////////////////////////////////////////////////
//~ Query operations
PP_Ent *PP_FirstWithProp(PP_Snapshot *ss, PP_Prop prop);
PP_Ent *PP_FirstWithAllProps(PP_Snapshot *ss, PP_PropArray props);
////////////////////////////////////////////////////////////
//~ Tree operations
void PP_Link(PP_Ent *parent, PP_Ent *child);
void PP_Unlink(PP_Ent *ent);
////////////////////////////////////////////////////////////
//~ Xform operations
void PP_MarkChildXformsDirty(PP_Snapshot *ss, PP_Ent *ent);
Xform PP_XformFromEnt_(PP_Snapshot *ss, PP_Ent *ent);
Xform PP_XformFromEnt(PP_Ent *ent);
Xform PP_LocalXformFromEnt(PP_Ent *ent);
void PP_SetXform(PP_Ent *ent, Xform xf);
void PP_SetLocalXform(PP_Ent *ent, Xform xf);
////////////////////////////////////////////////////////////
//~ Movement operations
void PP_SetLinearVelocity(PP_Ent *ent, Vec2 velocity);
void PP_SetAngularVelocity(PP_Ent *ent, f32 velocity);
void PP_ApplyLinearImpulse(PP_Ent *ent, Vec2 impulse, Vec2 world_point);
void PP_ApplyLinearImpulseToCenter(PP_Ent *ent, Vec2 impulse);
void PP_ApplyForceToCenter(PP_Ent *ent, Vec2 force);
void PP_ApplyAngularImpulse(PP_Ent *ent, f32 impulse);
void PP_ApplyTorque(PP_Ent *ent, f32 torque);
////////////////////////////////////////////////////////////
//~ Tile operations
PP_Ent *PP_TileChunkFromChunkIndex(PP_Snapshot *ss, Vec2I32 chunk_index);
PP_Ent *PP_TileChunkFromWorldTileIndex(PP_Snapshot *ss, Vec2I32 world_tile_index);
PP_TileKind PP_TileKindFromChunk(PP_Ent *chunk_ent, Vec2I32 local_tile_index);
////////////////////////////////////////////////////////////
//~ Lerp operations
void PP_LerpEnt(PP_Ent *e, PP_Ent *e0, PP_Ent *e1, f64 blend);
////////////////////////////////////////////////////////////
//~ Sync operations
void PP_CreateMissingEntsFromSnapshots(PP_Ent *local_parent, PP_Ent *remote, PP_EntKey remote_player);
void PP_SyncEnt(PP_Ent *local, PP_Ent *remote);
////////////////////////////////////////////////////////////
//~ Encode
void PP_EncodeEnt(BB_Writer *bw, PP_Ent *e0, PP_Ent *e1);
////////////////////////////////////////////////////////////
//~ Decode
void PP_DecodeEnt(BB_Reader *br, PP_Ent *e);