sync with upstream

This commit is contained in:
Nikolay Korolev 2020-05-16 01:50:45 +03:00
commit 21329b8440
38 changed files with 2383 additions and 1316 deletions

View File

@ -44,7 +44,7 @@ CAnimBlendAssocGroup::DestroyAssociations(void)
CAnimBlendAssociation*
CAnimBlendAssocGroup::GetAnimation(uint32 id)
{
return &assocList[id];
return &assocList[id - firstAnimId];
}
CAnimBlendAssociation*

View File

@ -18,6 +18,7 @@ enum {
ASSOC_NOWALK = 0x400, // see CPed::PlayFootSteps(void)
ASSOC_BLOCK = 0x800, // unused in assoc description, blocks other anims from being played
ASSOC_FRONTAL = 0x1000, // anims that we fall to front
ASSOC_DRIVING = 0x2000, // new in VC
};
// Anim hierarchy associated with a clump

View File

@ -67,27 +67,6 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_HIT_WALL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FLOOR_HIT_F, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_HIT_BEHIND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_PUNCH_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_KICK_FLOOR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_BAT_H, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_BAT_V, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_HGUN_BODY, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_WEAPON_AK_BODY, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_PUMP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_SNIPER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_THROW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_THROWU, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_START_THROW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BOMBER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_HGUN_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_AK_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
// { ANIM_FPS_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
// { ANIM_FPS_BAT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
// { ANIM_FPS_UZI, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
// { ANIM_FPS_PUMP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
// { ANIM_FPS_AK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
// { ANIM_FPS_M16, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
// { ANIM_FPS_ROCKET, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_IDLE, ASSOC_REPEAT },
{ ANIM_FIGHT2_IDLE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_SH_F, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@ -100,6 +79,17 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_FIGHT_ROUNDHOUSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FIGHT_LONGKICK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FIGHT_PPUNCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_FIGHT_JAB, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_ELBOW_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_ELBOW_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_BKICK_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_BKICK_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BOMBER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_PUNCH_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_PPUNCH2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_KICK_FLOOR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_THROWU, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_SH_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_CAR_JACKED_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_CAR_LJACKED_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_CAR_JACKED_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
@ -118,6 +108,7 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_CAR_CLOSEDOOR_LOW_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_ROLLDOOR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_ROLLDOOR_LOW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_JUMPIN_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_GETOUT_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_GETOUT_LOW_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CLOSE_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
@ -133,39 +124,41 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_CAR_CLOSEDOOR_LOW_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_SHUFFLE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_LSHUFFLE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_SIT, ASSOC_DELETEFADEDOUT },
{ ANIM_CAR_LSIT, ASSOC_DELETEFADEDOUT },
{ ANIM_CAR_SITP, ASSOC_DELETEFADEDOUT },
{ ANIM_CAR_SITPLO, ASSOC_DELETEFADEDOUT },
{ ANIM_DRIVE_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_DRIVE_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_DRIVE_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_DRIVE_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_DRIVEBY_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_DRIVEBY_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_CAR_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_DRIVE_BOAT, ASSOC_DELETEFADEDOUT },
{ ANIM_CAR_SIT, ASSOC_DELETEFADEDOUT},
{ ANIM_CAR_LSIT, ASSOC_DELETEFADEDOUT},
{ ANIM_CAR_SITP, ASSOC_DELETEFADEDOUT},
{ ANIM_CAR_SITPLO, ASSOC_DELETEFADEDOUT},
{ ANIM_DRIVE_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVE_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVE_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVE_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_L_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVEBY_L_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_CAR_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVE_BOAT, ASSOC_DELETEFADEDOUT | ASSOC_DRIVING },
{ ANIM_DRIVE_BOAT_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVE_BOAT_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_DRIVE_BOAT_BACK, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_PICKUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_PICKUP_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_PULLUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_PULLUP_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_ELBOW_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_ELBOW_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_FALL_OFF, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_BIKE_FALL_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_CAR_GETOUT_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_GETOUT_LOW_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CLOSE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_HOOKERTALK, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_COACH_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_COACH_OPEN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_COACH_IN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_COACH_IN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_COACH_OUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_TRAIN_GETIN, ASSOC_PARTIAL },
{ ANIM_TRAIN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_IDLE_STANCE2, ASSOC_PARTIAL },
{ ANIM_IDLE_STANCE3, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CRAWLOUT_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CRAWLOUT_RHS2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_GETIN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_CLOSE_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_GETOUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_OPEN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_GETIN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_CLOSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_ROLLOUT_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
{ ANIM_CAR_ROLLOUT_LHS2, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
{ ANIM_GETUP1, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_GETUP2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_GETUP3, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@ -177,6 +170,8 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_FALL_GLIDE, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_FALL_LAND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FALL_COLLAPSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FALL_BACK, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_FALL_FRONT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_EV_STEP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_EV_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
{ ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_FLAG_XPRESS },
@ -184,26 +179,123 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_TURN_180, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_ARREST_GUN, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_DROWN, ASSOC_PARTIAL },
{ ANIM_CPR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_DUCK_DOWN, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_DUCK_LOW, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_WEAPON_CROUCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_RBLOCK_CSHOOT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_WEAPON_THROWU2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_HANDSUP, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_HANDSCOWER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FUCKU, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_PHONE_IN, ASSOC_PARTIAL },
{ ANIM_PHONE_IN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_PHONE_OUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_PHONE_TALK, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_SEAT_DOWN, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_SEAT_UP, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_SEAT_IDLE, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_SEAT_DOWN2, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_ATM, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_ABSEIL, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
};
AnimAssocDesc aVanAnimDescs[] = {
{ ANIM_VAN_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_GETIN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_CLOSE_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_GETOUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_OPEN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_GETIN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_CLOSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_VAN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
AnimAssocDesc aCoachAnimDescs[] = {
{ ANIM_COACH_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_COACH_OPEN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_COACH_IN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_COACH_IN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_COACH_OUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
AnimAssocDesc aBikeAnimDescs[] = {
{ ANIM_BIKE_RIDE, ASSOC_DELETEFADEDOUT},
{ ANIM_BIKE_STILL, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_LEFT, ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_RIGHT, ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_BACK, ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_FWD, ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_PUSHES, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_JUMPON_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_JUMPON_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_KICK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_HIT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_GETOFF_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_GETOFF_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_BIKE_GETOFF_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_BIKE_DRIVEBY_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_DRIVEBY_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_DRIVEBY_FT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
{ ANIM_BIKE_PASSENGER, ASSOC_DELETEFADEDOUT | ASSOC_DRIVING },
};
AnimAssocDesc aMeleeAnimDescs[] = {
{ ANIM_MELEE_ATTACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_MELEE_ATTACK_2ND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_MELEE_ATTACK_START, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_WEAPON_CROUCHRELOAD, ASSOC_REPEAT }, // TODO(Miami): Overload that name for melee/swing
{ ANIM_WEAPON_SPECIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, // TODO(Miami): Overload that name for melee/swing
};
AnimAssocDesc aSwingAnimDescs[] = {
{ ANIM_MELEE_ATTACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_MELEE_ATTACK_2ND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_MELEE_ATTACK_START, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_CROUCHRELOAD, ASSOC_REPEAT }, // TODO(Miami): Overload that name for melee/swing
{ ANIM_WEAPON_SPECIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, // TODO(Miami): Overload that name for melee/swing
};
AnimAssocDesc aWeaponAnimDescs[] = {
{ ANIM_WEAPON_FIRE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_CROUCHFIRE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_CROUCHRELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_WEAPON_SPECIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
AnimAssocDesc aMedicAnimDescs[] = {
{ ANIM_CPR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
AnimAssocDesc aSunbatheAnimDescs[] = {
{ ANIM_SUNBATHE, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_SUNBATHE_DOWN, ASSOC_REPEAT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
{ ANIM_SUNBATHE_UP, ASSOC_REPEAT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
{ ANIM_SUNBATHE_ESCAPE, ASSOC_REPEAT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
};
AnimAssocDesc aPlayerIdleAnimDescs[] = {
{ ANIM_IDLE_STRETCH, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_IDLE_TIME, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_IDLE_SHOULDER, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_IDLE_STRETCH_LEG, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
AnimAssocDesc aRiotAnimDescs[] = {
{ ANIM_RIOT_ANGRY, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_RIOT_ANGRY_B, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_RIOT_CHANT, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_RIOT_PUNCHES, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_RIOT_SHOUT, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_RIOT_CHALLENGE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_RIOT_FUKU, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
AnimAssocDesc aStripAnimDescs[] = {
{ ANIM_STRIP_A, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STRIP_B, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STRIP_C, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STRIP_D, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STRIP_E, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STRIP_F, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STRIP_G, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
AnimAssocDesc aStdAnimDescsSide[] = {
{ ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
{ ANIM_RUN, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
{ ANIM_SPRINT, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
{ ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
{ ANIM_RUN, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
{ ANIM_SPRINT, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
{ ANIM_IDLE_STANCE, ASSOC_REPEAT },
{ ANIM_WALK_START, ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
};
char const *aStdAnimations[] = {
char const* aStdAnimations[] = {
"walk_civi",
"run_civi",
"sprint_panic",
@ -211,7 +303,7 @@ char const *aStdAnimations[] = {
"walk_start",
"run_stop",
"run_stopR",
"idle_cam",
"idle_hbhb",
"idle_hbhb",
"idle_tired",
"idle_armed",
@ -249,27 +341,6 @@ char const *aStdAnimations[] = {
"HIT_wall",
"FLOOR_hit_f",
"HIT_behind",
"punchR",
"KICK_floor",
"WEAPON_bat_h",
"WEAPON_bat_v",
"WEAPON_hgun_body",
"WEAPON_AK_body",
"WEAPON_pump",
"WEAPON_sniper",
"WEAPON_throw",
"WEAPON_throwu",
"WEAPON_start_throw",
"bomber",
"WEAPON_hgun_rload",
"WEAPON_AK_rload",
// "FPS_PUNCH",
// "FPS_BAT",
// "FPS_UZI",
// "FPS_PUMP",
// "FPS_AK",
// "FPS_M16",
// "FPS_ROCKET",
"FIGHTIDLE",
"FIGHT2IDLE",
"FIGHTsh_F",
@ -282,6 +353,17 @@ char const *aStdAnimations[] = {
"FIGHTrndhse",
"FIGHTlngkck",
"FIGHTppunch",
"FIGHTjab",
"FIGHTelbowL",
"FIGHTelbowR",
"FIGHTbkickL",
"FIGHTbkickR",
"bomber",
"punchR",
"FIGHTppunch",
"KICK_floor",
"WEAPON_throwu",
"FIGHTsh_back",
"car_jackedRHS",
"car_LjackedRHS",
"car_jackedLHS",
@ -300,6 +382,7 @@ char const *aStdAnimations[] = {
"CAR_closedoorL_LHS",
"CAR_rolldoor",
"CAR_rolldoorLO",
"CAR_jumpin_LHS",
"CAR_getout_LHS",
"CAR_getoutL_LHS",
"CAR_close_LHS",
@ -325,29 +408,31 @@ char const *aStdAnimations[] = {
"Drive_LO_R",
"Driveby_L",
"Driveby_R",
"DrivebyL_L",
"DrivebyL_R",
"CAR_LB",
"DRIVE_BOAT",
"DRIVE_BOAT_L",
"DRIVE_BOAT_R",
"DRIVE_BOAT_back",
"BIKE_pickupR",
"BIKE_pickupL",
"BIKE_pullupR",
"BIKE_pullupL",
"BIKE_elbowR",
"BIKE_elbowL",
"BIKE_fall_off",
"BIKE_fallR",
"CAR_getout_RHS",
"CAR_getoutL_RHS",
"CAR_close_RHS",
"car_hookertalk",
"COACH_opnL",
"COACH_opnR",
"COACH_inL",
"COACH_inR",
"COACH_outL",
"TRAIN_getin",
"TRAIN_getout",
"idle_stance",
"idle_stance",
"CAR_crawloutRHS",
"CAR_crawloutRHS",
"VAN_openL",
"VAN_getinL",
"VAN_closeL",
"VAN_getoutL",
"VAN_open",
"VAN_getin",
"VAN_close",
"VAN_getout",
"CAR_rollout_LHS",
"CAR_rollout_LHS",
"Getup",
"Getup",
"Getup",
@ -359,6 +444,8 @@ char const *aStdAnimations[] = {
"FALL_glide",
"FALL_land",
"FALL_collapse",
"FALL_back",
"FALL_front",
"EV_step",
"EV_dive",
"XPRESSscratch",
@ -366,213 +453,444 @@ char const *aStdAnimations[] = {
"TURN_180",
"ARRESTgun",
"DROWN",
"CPR",
"DUCK_down",
"DUCK_low",
"WEAPON_crouch",
"RBLOCK_Cshoot",
"WEAPON_throwu",
"handsup",
"handsCOWER",
"FUCKU",
"PHONE_in",
"PHONE_out",
"PHONE_talk",
"SEAT_down",
"SEAT_up",
"SEAT_idle",
"SEAT_down",
"ATM",
"abseil",
};
char const *aPlayerAnimations[] = {
char const* aVanAnimations[] = {
"VAN_openL",
"VAN_getinL",
"VAN_closeL",
"VAN_getoutL",
"VAN_open",
"VAN_getin",
"VAN_close",
"VAN_getout",
};
char const* aCoachAnimations[] = {
"COACH_opnL",
"COACH_opnL",
"COACH_inL",
"COACH_inL",
"COACH_outL",
};
char const* aBikesAnimations[] = {
"BIKEs_Ride",
"BIKEs_Still",
"BIKEs_Left",
"BIKEs_Right",
"BIKEs_Back",
"BIKEs_Fwd",
"BIKEs_pushes",
"BIKEs_jumponR",
"BIKEs_jumponL",
"BIKEs_kick",
"BIKEs_hit",
"BIKEs_getoffRHS",
"BIKEs_getoffLHS",
"BIKEs_getoffBACK",
"BIKEs_drivebyLHS",
"BIKEs_drivebyRHS",
"BIKEs_drivebyFT",
"BIKEs_passenger",
};
char const* aBikevAnimations[] = {
"BIKEv_Ride",
"BIKEv_Still",
"BIKEv_Left",
"BIKEv_Right",
"BIKEv_Back",
"BIKEv_Fwd",
"BIKEv_pushes",
"BIKEv_jumponR",
"BIKEv_jumponL",
"BIKEv_kick",
"BIKEv_hit",
"BIKEv_getoffRHS",
"BIKEv_getoffLHS",
"BIKEv_getoffBACK",
"BIKEv_drivebyLHS",
"BIKEv_drivebyRHS",
"BIKEv_drivebyFT",
"BIKEv_passenger",
};
char const* aBikehAnimations[] = {
"BIKEh_Ride",
"BIKEh_Still",
"BIKEh_Left",
"BIKEh_Right",
"BIKEh_Back",
"BIKEh_Fwd",
"BIKEh_pushes",
"BIKEh_jumponR",
"BIKEh_jumponL",
"BIKEh_kick",
"BIKEh_hit",
"BIKEh_getoffRHS",
"BIKEh_getoffLHS",
"BIKEh_getoffBACK",
"BIKEh_drivebyLHS",
"BIKEh_drivebyRHS",
"BIKEh_drivebyFT",
"BIKEh_passenger",
};
char const* aBikedAnimations[] = {
"BIKEd_Ride",
"BIKEd_Still",
"BIKEd_Left",
"BIKEd_Right",
"BIKEd_Back",
"BIKEd_Fwd",
"BIKEd_pushes",
"BIKEd_jumponR",
"BIKEd_jumponL",
"BIKEd_kick",
"BIKEd_hit",
"BIKEd_getoffRHS",
"BIKEd_getoffLHS",
"BIKEd_getoffBACK",
"BIKEd_drivebyLHS",
"BIKEd_drivebyRHS",
"BIKEd_drivebyFT",
"BIKEd_passenger",
};
char const* aUnarmedAnimations[] = {
"punchR",
"KICK_floor",
"FIGHTppunch",
};
char const* aScrewdriverAnimations[] = {
"FIGHTbodyblow",
"FIGHTbodyblow",
"FIGHTppunch",
"FIGHTIDLE",
"FIGHTbodyblow",
};
char const* aKnifeAnimations[] = {
"WEAPON_knife_1",
"WEAPON_knife_2",
"knife_part",
"WEAPON_knifeidle",
"WEAPON_knife_3",
};
char const* aBaseballbatAnimations[] = {
"WEAPON_bat_h",
"WEAPON_bat_v",
"BAT_PART",
"WEAPON_bat_h",
"WEAPON_golfclub",
};
char const* aGolfclubAnimations[] = {
"WEAPON_bat_h",
"WEAPON_golfclub",
"BAT_PART",
"WEAPON_bat_h",
"WEAPON_bat_v",
};
char const* aChainsawAnimations[] = {
"WEAPON_csaw",
"WEAPON_csawlo",
"csaw_part",
};
char const* aPythonAnimations[] = {
"python_fire",
"python_crouchfire",
"python_reload",
"python_crouchreload",
};
char const* aColtAnimations[] = {
"colt45_fire",
"colt45_crouchfire",
"colt45_reload",
"colt45_crouchreload",
"colt45_cop",
};
char const* aShotgunAnimations[] = {
"shotgun_fire",
"shotgun_crouchfire",
};
char const* aBuddyAnimations[] = {
"buddy_fire",
"buddy_crouchfire",
};
char const* aTecAnimations[] = {
"TEC_fire",
"TEC_crouchfire",
"TEC_reload",
"TEC_crouchreload",
};
char const* aUziAnimations[] = {
"UZI_fire",
"UZI_crouchfire",
"UZI_reload",
"UZI_crouchreload",
};
char const* aRifleAnimations[] = {
"RIFLE_fire",
"RIFLE_crouchfire",
"RIFLE_load",
"RIFLE_crouchload",
};
char const* aM60Animations[] = {
"M60_fire",
"M60_fire",
"M60_reload",
};
char const* aSniperAnimations[] = {
"WEAPON_sniper",
};
char const* aThrowAnimations[] = {
"WEAPON_throw",
"WEAPON_throwu",
"WEAPON_start_throw",
};
char const* aFlamethrowerAnimations[] = {
"FLAME_fire",
};
char const* aMedicAnimations[] = {
"CPR",
};
char const* aSunbatheAnimations[] = {
"bather",
"batherdown",
"batherup",
"batherscape",
};
char const* aPlayerIdleAnimations[] = {
"stretch",
"time",
"shldr",
"strleg",
};
char const* aRiotAnimations[] = {
"riot_angry",
"riot_angry_b",
"riot_chant",
"riot_punches",
"riot_shout",
"riot_challenge",
"riot_fuku",
};
char const* aStripAnimations[] = {
"strip_A",
"strip_B",
"strip_C",
"strip_D",
"strip_E",
"strip_F",
"strip_G",
};
char const* aLanceAnimations[] = {
"lance",
};
char const* aPlayerAnimations[] = {
"walk_player",
"run_player",
"SPRINT_civi",
"IDLE_STANCE",
"walk_start",
};
char const *aPlayerWithRocketAnimations[] = {
char const* aPlayerWithRocketAnimations[] = {
"walk_rocket",
"run_rocket",
"run_rocket",
"idle_rocket",
"walk_start_rocket",
};
char const *aPlayer1ArmedAnimations[] = {
char const* aPlayer1ArmedAnimations[] = {
"walk_player",
"run_1armed",
"SPRINT_civi",
"IDLE_STANCE",
"walk_start",
};
char const *aPlayer2ArmedAnimations[] = {
"walk_player",
char const* aPlayer2ArmedAnimations[] = {
"walk_armed",
"run_armed",
"run_armed",
"idle_stance",
"walk_start",
"idle_armed",
"walk_start_armed",
};
char const *aPlayerBBBatAnimations[] = {
char const* aPlayerBBBatAnimations[] = {
"walk_player",
"run_player",
"run_player",
"IDLE_STANCE",
"walk_start",
};
char const *aPlayerChainsawAnimations[] = {
char const* aPlayerChainsawAnimations[] = {
"walk_csaw",
"run_csaw",
"run_csaw",
"IDLE_csaw",
"walk_start_csaw",
};
char const *aShuffleAnimations[] = {
char const* aShuffleAnimations[] = {
"WALK_shuffle",
"RUN_civi",
"SPRINT_civi",
"IDLE_STANCE",
};
char const *aOldAnimations[] = {
char const* aOldAnimations[] = {
"walk_old",
"run_civi",
"sprint_civi",
"idle_stance",
};
char const *aGang1Animations[] = {
char const* aGang1Animations[] = {
"walk_gang1",
"run_gang1",
"sprint_civi",
"idle_stance",
};
char const *aGang2Animations[] = {
char const* aGang2Animations[] = {
"walk_gang2",
"run_gang1",
"sprint_civi",
"idle_stance",
};
char const *aFatAnimations[] = {
char const* aFatAnimations[] = {
"walk_fat",
"run_civi",
"woman_runpanic",
"idle_stance",
};
char const *aOldFatAnimations[] = {
char const* aOldFatAnimations[] = {
"walk_fatold",
"run_fatold",
"woman_runpanic",
"idle_stance",
};
char const *aJoggerAnimations[] = {
char const* aJoggerAnimations[] = {
"JOG_maleA",
"run_civi",
"sprint_civi",
"idle_stance",
};
char const *aStdWomanAnimations[] = {
char const* aStdWomanAnimations[] = {
"woman_walknorm",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
char const *aWomanShopAnimations[] = {
char const* aWomanShopAnimations[] = {
"woman_walkshop",
"woman_run",
"woman_run",
"woman_idlestance",
};
char const *aBusyWomanAnimations[] = {
char const* aBusyWomanAnimations[] = {
"woman_walkbusy",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
char const *aSexyWomanAnimations[] = {
char const* aSexyWomanAnimations[] = {
"woman_walksexy",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
char const *aFatWomanAnimations[] = {
char const* aFatWomanAnimations[] = {
"walk_fat",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
char const *aOldWomanAnimations[] = {
char const* aOldWomanAnimations[] = {
"woman_walkold",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
char const *aJoggerWomanAnimations[] = {
char const* aJoggerWomanAnimations[] = {
"JOG_maleB",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
char const *aPanicChunkyAnimations[] = {
char const* aPanicChunkyAnimations[] = {
"run_fatold",
"woman_runpanic",
"woman_runpanic",
"idle_stance",
};
char const *aSkateAnimations[] = {
char const* aSkateAnimations[] = {
"skate_run",
"skate_sprint",
"skate_sprint",
"skate_idle",
};
char const *aPlayerStrafeBackAnimations[] = {
char const* aPlayerStrafeBackAnimations[] = {
"walk_back",
"run_back",
"run_back",
"IDLE_STANCE",
"walk_start_back",
};
char const *aPlayerStrafeLeftAnimations[] = {
char const* aPlayerStrafeLeftAnimations[] = {
"walk_left",
"run_left",
"run_left",
"IDLE_STANCE",
"walk_start_left",
};
char const *aPlayerStrafeRightAnimations[] = {
char const* aPlayerStrafeRightAnimations[] = {
"walk_right",
"run_right",
"run_right",
"IDLE_STANCE",
"walk_start_right",
};
char const *aRocketStrafeBackAnimations[] = {
char const* aRocketStrafeBackAnimations[] = {
"walk_rocket_back",
"run_rocket_back",
"run_rocket_back",
"idle_rocket",
"walkst_rocket_back",
};
char const *aRocketStrafeLeftAnimations[] = {
char const* aRocketStrafeLeftAnimations[] = {
"walk_rocket_left",
"run_rocket_left",
"run_rocket_left",
"idle_rocket",
"walkst_rocket_left",
};
char const *aRocketStrafeRightAnimations[] = {
char const* aRocketStrafeRightAnimations[] = {
"walk_rocket_right",
"run_rocket_right",
"run_rocket_right",
"idle_rocket",
"walkst_rocket_right",
};
char const *aChainsawStrafeBackAnimations[] = {
char const* aChainsawStrafeBackAnimations[] = {
"walk_csaw_back",
"run_csaw_back",
"run_csaw_back",
"idle_csaw",
"walkst_csaw_back",
};
char const *aChainsawStrafeLeftAnimations[] = {
char const* aChainsawStrafeLeftAnimations[] = {
"walk_csaw_left",
"run_csaw_left",
"run_csaw_left",
"idle_csaw",
"walkst_csaw_left",
};
char const *aChainsawStrafeRightAnimations[] = {
char const* aChainsawStrafeRightAnimations[] = {
"walk_csaw_right",
"run_csaw_right",
"run_csaw_right",
@ -580,8 +898,39 @@ char const *aChainsawStrafeRightAnimations[] = {
"walkst_csaw_right",
};
const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS] = {
{ "man", "ped", MI_COP, 173, aStdAnimations, aStdAnimDescs },
{ "van", "van", MI_COP, 8, aVanAnimations, aVanAnimDescs },
{ "coach", "coach", MI_COP, 5, aCoachAnimations, aCoachAnimDescs },
{ "bikes", "bikes", MI_COP, 18, aBikesAnimations, aBikeAnimDescs },
{ "bikev", "bikev", MI_COP, 18, aBikevAnimations, aBikeAnimDescs },
{ "bikeh", "bikeh", MI_COP, 18, aBikehAnimations, aBikeAnimDescs },
{ "biked", "biked", MI_COP, 18, aBikedAnimations, aBikeAnimDescs },
{ "unarmed", "ped", MI_COP, 3, aUnarmedAnimations, aMeleeAnimDescs },
{ "screwdrv", "ped", MI_COP, 5, aScrewdriverAnimations, aMeleeAnimDescs },
{ "knife", "knife", MI_COP, 5, aKnifeAnimations, aMeleeAnimDescs },
{ "baseball", "baseball", MI_COP, 5, aBaseballbatAnimations, aSwingAnimDescs },
{ "golfclub", "baseball", MI_COP, 5, aGolfclubAnimations, aSwingAnimDescs },
{ "chainsaw", "chainsaw", MI_COP, 3, aChainsawAnimations, aMeleeAnimDescs },
{ "python", "python", MI_COP, 4, aPythonAnimations, aWeaponAnimDescs },
{ "colt45", "colt45", MI_COP, 5, aColtAnimations, aWeaponAnimDescs },
{ "shotgun", "shotgun", MI_COP, 2, aShotgunAnimations, aWeaponAnimDescs },
{ "buddy", "buddy", MI_COP, 2, aBuddyAnimations, aWeaponAnimDescs },
{ "tec", "tec", MI_COP, 4, aTecAnimations, aWeaponAnimDescs },
{ "uzi", "uzi", MI_COP, 4, aUziAnimations, aWeaponAnimDescs },
{ "rifle", "rifle", MI_COP, 4, aRifleAnimations, aWeaponAnimDescs },
{ "m60", "m60", MI_COP, 3, aM60Animations, aWeaponAnimDescs },
{ "sniper", "sniper", MI_COP, 1, aSniperAnimations, aWeaponAnimDescs },
{ "grenade", "grenade", MI_COP, 3, aThrowAnimations, aWeaponAnimDescs },
{ "flame", "flame", MI_COP, 1, aFlamethrowerAnimations, aWeaponAnimDescs },
{ "medic", "medic", MI_COP, 1, aMedicAnimations, aMedicAnimDescs },
{ "sunbathe", "sunbathe", MI_COP, 1, aSunbatheAnimations, aSunbatheAnimDescs },
{ "playidles", "playidles", MI_COP, 4, aPlayerIdleAnimations, aPlayerIdleAnimDescs },
{ "riot", "riot", MI_COP, 7, aRiotAnimations, aRiotAnimDescs },
{ "strip", "strip", MI_COP, 7, aStripAnimations, aStripAnimDescs },
{ "lance", "lance", MI_COP, 1, aLanceAnimations, aSunbatheAnimDescs },
{ "player", "ped", MI_COP, 5, aPlayerAnimations, aStdAnimDescs },
{ "playerrocket", "ped", MI_COP, 5, aPlayerWithRocketAnimations, aStdAnimDescs },
{ "player1armed", "ped", MI_COP, 5, aPlayer1ArmedAnimations, aStdAnimDescs },
@ -603,7 +952,7 @@ const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_
{ "oldwoman", "ped", MI_COP, 4, aOldWomanAnimations, aStdAnimDescs },
{ "jogwoman", "ped", MI_COP, 4, aJoggerWomanAnimations, aStdAnimDescs },
{ "panicchunky", "ped", MI_COP, 4, aPanicChunkyAnimations, aStdAnimDescs },
{ "skate", "ped", MI_COP, 4, aSkateAnimations, aStdAnimDescs },
{ "skate", "skate", MI_COP, 4, aSkateAnimations, aStdAnimDescs },
{ "playerback", "ped", MI_COP, 5, aPlayerStrafeBackAnimations, aStdAnimDescs },
{ "playerleft", "ped", MI_COP, 5, aPlayerStrafeLeftAnimations, aStdAnimDescsSide },
{ "playerright", "ped", MI_COP, 5, aPlayerStrafeRightAnimations, aStdAnimDescsSide },
@ -903,7 +1252,9 @@ CAnimManager::CreateAnimAssocGroups(void)
group->firstAnimId = def->animDescs[0].animId;
group->CreateAssociations(def->blockName, clump, def->animNames, def->numAnims);
for(j = 0; j < group->numAssociations; j++)
group->GetAnimation(j)->flags |= def->animDescs[j].flags;
// GetAnimation(i) in III (but it's in LoadAnimFiles), GetAnimation(group->animDesc[j].animId) in VC
group->GetAnimation(def->animDescs[j].animId)->flags |= def->animDescs[j].flags;
#ifdef PED_SKIN
if(IsClumpSkinned(clump))
RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);

View File

@ -6,6 +6,35 @@
enum AssocGroupId
{
ASSOCGRP_STD,
ASSOCGRP_VAN,
ASSOCGRP_COACH,
ASSOCGRP_BIKES,
ASSOCGRP_BIKEV,
ASSOCGRP_BIKEH,
ASSOCGRP_BIKED,
ASSOCGRP_UNARMED,
ASSOCGRP_SCREWDRIVER,
ASSOCGRP_KNIFE,
ASSOCGRP_BASEBALLBAT,
ASSOCGRP_GOLFCLUB,
ASSOCGRP_CHAINSAW,
ASSOCGRP_PYTHON,
ASSOCGRP_COLT,
ASSOCGRP_SHOTGUN,
ASSOCGRP_BUDDY,
ASSOCGRP_TEC,
ASSOCGRP_UZI,
ASSOCGRP_RIFLE,
ASSOCGRP_M60,
ASSOCGRP_SNIPER,
ASSOCGRP_THROW,
ASSOCGRP_FLAMETHROWER,
ASSOCGRP_MEDIC,
ASSOCGRP_SUNBATHE,
ASSOCGRP_PLAYER_IDLE,
ASSOCGRP_RIOT,
ASSOCGRP_STRIP,
ASSOCGRP_LANCE,
ASSOCGRP_PLAYER,
ASSOCGRP_PLAYERROCKET,
ASSOCGRP_PLAYER1ARMED,
@ -38,7 +67,7 @@ enum AssocGroupId
ASSOCGRP_CHAINSAWLEFT,
ASSOCGRP_CHAINSAWRIGHT,
NUM_ANIM_ASSOC_GROUPS // should be 61 in the end
NUM_ANIM_ASSOC_GROUPS
};
class CAnimBlendAssociation;

View File

@ -47,27 +47,6 @@ enum AnimationId
ANIM_HIT_WALL,
ANIM_FLOOR_HIT_F,
ANIM_HIT_BEHIND,
ANIM_PUNCH_R,
ANIM_KICK_FLOOR,
ANIM_WEAPON_BAT_H,
ANIM_WEAPON_BAT_V,
ANIM_WEAPON_HGUN_BODY,
ANIM_WEAPON_AK_BODY,
ANIM_WEAPON_PUMP,
ANIM_WEAPON_SNIPER,
ANIM_WEAPON_THROW,
ANIM_WEAPON_THROWU,
ANIM_WEAPON_START_THROW,
ANIM_BOMBER,
ANIM_HGUN_RELOAD,
ANIM_AK_RELOAD,
// ANIM_FPS_PUNCH,
// ANIM_FPS_BAT,
// ANIM_FPS_UZI,
// ANIM_FPS_PUMP,
// ANIM_FPS_AK,
// ANIM_FPS_M16,
// ANIM_FPS_ROCKET,
ANIM_FIGHT_IDLE,
ANIM_FIGHT2_IDLE,
ANIM_FIGHT_SH_F,
@ -80,6 +59,21 @@ enum AnimationId
ANIM_FIGHT_ROUNDHOUSE,
ANIM_FIGHT_LONGKICK,
ANIM_FIGHT_PPUNCH,
ANIM_FIGHT_JAB,
ANIM_FIGHT_ELBOW_L,
ANIM_FIGHT_ELBOW_R,
ANIM_FIGHT_BKICK_L,
ANIM_FIGHT_BKICK_R,
ANIM_BOMBER,
ANIM_PUNCH_R,
ANIM_FIGHT_PPUNCH2,
ANIM_KICK_FLOOR,
ANIM_WEAPON_THROWU,
ANIM_FIGHT_SH_BACK,
ANIM_CAR_JACKED_RHS,
ANIM_CAR_LJACKED_RHS,
ANIM_CAR_JACKED_LHS,
@ -98,6 +92,7 @@ enum AnimationId
ANIM_CAR_CLOSEDOOR_LOW_LHS,
ANIM_CAR_ROLLDOOR,
ANIM_CAR_ROLLDOOR_LOW,
ANIM_CAR_JUMPIN_LHS,
ANIM_CAR_GETOUT_LHS,
ANIM_CAR_GETOUT_LOW_LHS,
ANIM_CAR_CLOSE_LHS,
@ -123,29 +118,36 @@ enum AnimationId
ANIM_DRIVE_LOW_R,
ANIM_DRIVEBY_L,
ANIM_DRIVEBY_R,
ANIM_DRIVEBY_L_L, // TODO: is this LOW?
ANIM_DRIVEBY_L_R,
ANIM_CAR_LB,
ANIM_DRIVE_BOAT,
ANIM_DRIVE_BOAT_L,
ANIM_DRIVE_BOAT_R,
ANIM_DRIVE_BOAT_BACK,
ANIM_BIKE_PICKUP_R,
ANIM_BIKE_PICKUP_L,
ANIM_BIKE_PULLUP_R,
ANIM_BIKE_PULLUP_L,
ANIM_BIKE_ELBOW_R,
ANIM_BIKE_ELBOW_L,
ANIM_BIKE_FALL_OFF,
ANIM_BIKE_FALL_R,
ANIM_CAR_GETOUT_RHS,
ANIM_CAR_GETOUT_LOW_RHS,
ANIM_CAR_CLOSE_RHS,
ANIM_CAR_HOOKERTALK,
ANIM_COACH_OPEN_L,
ANIM_COACH_OPEN_R,
ANIM_COACH_IN_L,
ANIM_COACH_IN_R,
ANIM_COACH_OUT_L,
ANIM_TRAIN_GETIN,
ANIM_TRAIN_GETOUT,
ANIM_IDLE_STANCE2,
ANIM_IDLE_STANCE3,
ANIM_CAR_CRAWLOUT_RHS,
ANIM_CAR_CRAWLOUT_RHS2,
ANIM_VAN_OPEN_L,
ANIM_VAN_GETIN_L,
ANIM_VAN_CLOSE_L,
ANIM_VAN_GETOUT_L,
ANIM_VAN_OPEN,
ANIM_VAN_GETIN,
ANIM_VAN_CLOSE,
ANIM_VAN_GETOUT,
ANIM_CAR_ROLLOUT_LHS,
ANIM_CAR_ROLLOUT_LHS2, // was this meant to be RHS?
ANIM_GETUP1,
ANIM_GETUP2,
ANIM_GETUP3,
@ -157,6 +159,9 @@ enum AnimationId
ANIM_FALL_GLIDE,
ANIM_FALL_LAND,
ANIM_FALL_COLLAPSE,
ANIM_FALL_BACK,
ANIM_FALL_FRONT,
ANIM_EV_STEP,
ANIM_EV_DIVE,
ANIM_XPRESS_SCRATCH,
@ -164,11 +169,12 @@ enum AnimationId
ANIM_TURN_180,
ANIM_ARREST_GUN,
ANIM_DROWN,
ANIM_CPR,
ANIM_DUCK_DOWN,
ANIM_DUCK_LOW,
ANIM_WEAPON_CROUCH,
ANIM_RBLOCK_CSHOOT,
ANIM_WEAPON_THROWU2,
ANIM_HANDSUP,
ANIM_HANDSCOWER,
ANIM_FUCKU,
@ -176,5 +182,90 @@ enum AnimationId
ANIM_PHONE_OUT,
ANIM_PHONE_TALK,
ANIM_SEAT_DOWN,
ANIM_SEAT_UP,
ANIM_SEAT_IDLE,
ANIM_SEAT_DOWN2,
ANIM_ATM,
ANIM_ABSEIL,
NUM_STD_ANIMS,
ANIM_VAN_OPEN_L,
ANIM_VAN_GETIN_L,
ANIM_VAN_CLOSE_L,
ANIM_VAN_GETOUT_L,
ANIM_VAN_OPEN,
ANIM_VAN_GETIN,
ANIM_VAN_CLOSE,
ANIM_VAN_GETOUT,
ANIM_COACH_OPEN_L,
ANIM_COACH_OPEN_R,
ANIM_COACH_IN_L,
ANIM_COACH_IN_R,
ANIM_COACH_OUT_L,
ANIM_BIKE_RIDE,
ANIM_BIKE_STILL,
ANIM_BIKE_LEFT,
ANIM_BIKE_RIGHT,
ANIM_BIKE_BACK,
ANIM_BIKE_FWD,
ANIM_BIKE_PUSHES,
ANIM_BIKE_JUMPON_R,
ANIM_BIKE_JUMPON_L,
ANIM_BIKE_KICK,
ANIM_BIKE_HIT,
ANIM_BIKE_GETOFF_RHS,
ANIM_BIKE_GETOFF_LHS,
ANIM_BIKE_GETOFF_BACK,
ANIM_BIKE_DRIVEBY_RHS,
ANIM_BIKE_DRIVEBY_LHS,
ANIM_BIKE_DRIVEBY_FT,
ANIM_BIKE_PASSENGER,
ANIM_WEAPON_FIRE,
ANIM_WEAPON_CROUCHFIRE,
ANIM_WEAPON_RELOAD,
ANIM_WEAPON_CROUCHRELOAD,
ANIM_WEAPON_SPECIAL,
ANIM_MELEE_ATTACK = ANIM_WEAPON_FIRE,
ANIM_MELEE_ATTACK_2ND,
ANIM_MELEE_ATTACK_START,
ANIM_THROWABLE_THROW = ANIM_WEAPON_FIRE,
ANIM_THROWABLE_THROWU,
ANIM_THROWABLE_START_THROW,
ANIM_WEAPON_FIRE_2ND = ANIM_WEAPON_CROUCHFIRE,
ANIM_WEAPON_FIRE_3RD = ANIM_WEAPON_SPECIAL,
ANIM_SUNBATHE,
ANIM_SUNBATHE_DOWN,
ANIM_SUNBATHE_UP,
ANIM_SUNBATHE_ESCAPE,
ANIM_CPR,
ANIM_IDLE_STRETCH,
ANIM_IDLE_TIME,
ANIM_IDLE_SHOULDER,
ANIM_IDLE_STRETCH_LEG,
ANIM_RIOT_ANGRY,
ANIM_RIOT_ANGRY_B,
ANIM_RIOT_CHANT,
ANIM_RIOT_PUNCHES,
ANIM_RIOT_SHOUT,
ANIM_RIOT_CHALLENGE,
ANIM_RIOT_FUKU,
ANIM_STRIP_A,
ANIM_STRIP_B,
ANIM_STRIP_C,
ANIM_STRIP_D,
ANIM_STRIP_E,
ANIM_STRIP_F,
ANIM_STRIP_G,
NUM_ANIMS
};

View File

@ -3860,7 +3860,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
{
CollectParameters(&m_nIp, 2);
CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++){
for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++){
if (pPed->m_weapons[i].m_eWeaponType == ScriptParams[1])
pPed->m_nSelectedWepSlot = i;
}
@ -3870,7 +3870,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) {
for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
if (pPed->m_weapons[i].m_eWeaponType == ScriptParams[1])
pPed->SetCurrentWeapon(i);
}

View File

@ -1627,20 +1627,6 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
entity = nil;
}
if(CamTargetEntity->m_rwObject){
// what's going on here?
if(RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_PUMP) ||
RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_THROW) ||
RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_THROWU) ||
RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_START_THROW)){
CPed *player = FindPlayerPed();
float PlayerDist = (Source - player->GetPosition()).Magnitude();
if(PlayerDist < 2.75f)
Near = PlayerDist/2.75f * DEFAULT_NEAR - 0.3f;
RwCameraSetNearClipPlane(Scene.camera, Max(Near, 0.1f));
}
}
TheCamera.m_bCamDirectlyInFront = false;
TheCamera.m_bCamDirectlyBehind = false;

View File

@ -375,11 +375,11 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){
assert(mi->IsSimple());
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
mi->SetAtomic(n, atomic);
RpClumpRemoveAtomic(clump, atomic);
RpAtomicSetFrame(atomic, RwFrameCreate());
CVisibilityPlugins::SetAtomicModelInfo(atomic, mi);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
}else{
debug("Can't find Atomic %s\n", name);
}
@ -506,11 +506,11 @@ CFileLoader::SetRelatedModelInfoCB(RpAtomic *atomic, void *data)
nodename = GetFrameNodeName(RpAtomicGetFrame(atomic));
GetNameAndLOD(nodename, name, &n);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
gpRelatedModelInfo->SetAtomic(n, atomic);
RpClumpRemoveAtomic(clump, atomic);
RpAtomicSetFrame(atomic, RwFrameCreate());
CVisibilityPlugins::SetAtomicModelInfo(atomic, gpRelatedModelInfo);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
return atomic;
}

View File

@ -314,6 +314,7 @@ bool CGame::Initialise(const char* datFile)
printf("Streaming uses %dK of its memory", CStreaming::ms_memoryUsed / 1024);
LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen());
CAnimManager::LoadAnimFiles();
CStreaming::LoadInitialWeapons();
CPed::Initialise();
CRouteNode::Initialise();
CEventList::Initialise();

View File

@ -65,17 +65,36 @@ extern bool gbFastTime;
void WeaponCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT2"), true);
CStreaming::RequestModel(MI_GRENADE, STREAMFLAGS_DONT_REMOVE);
CStreaming::RequestModel(MI_BOMB, STREAMFLAGS_DONT_REMOVE);
CStreaming::RequestModel(MI_AK47, STREAMFLAGS_DONT_REMOVE);
CStreaming::RequestModel(MI_BASEBALL_BAT, STREAMFLAGS_DONT_REMOVE);
CStreaming::RequestModel(MI_COLT, STREAMFLAGS_DONT_REMOVE);
CStreaming::RequestModel(MI_ROCKETLAUNCHER, STREAMFLAGS_DONT_REMOVE);
CStreaming::RequestModel(MI_SHOTGUN, STREAMFLAGS_DONT_REMOVE);
CStreaming::RequestModel(MI_SNIPER, STREAMFLAGS_DONT_REMOVE);
CStreaming::RequestModel(MI_MP5, STREAMFLAGS_DONT_REMOVE);
CStreaming::LoadAllRequestedModels(false);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 0);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_COLT45, 100);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_UZI, 100);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_MP5, 100);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 20);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_AK47, 200);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_M16, 200);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 5);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 5);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 5);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_FLAMETHROWER, 200);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_DETONATOR_GRENADE, 5);
CStreaming::SetModelIsDeletable(MI_GRENADE);
CStreaming::SetModelIsDeletable(MI_BOMB);
CStreaming::SetModelIsDeletable(MI_AK47);
CStreaming::SetModelIsDeletable(MI_BASEBALL_BAT);
CStreaming::SetModelIsDeletable(MI_COLT);
CStreaming::SetModelIsDeletable(MI_ROCKETLAUNCHER);
CStreaming::SetModelIsDeletable(MI_SHOTGUN);
CStreaming::SetModelIsDeletable(MI_SNIPER);
CStreaming::SetModelIsDeletable(MI_MP5);
}
void HealthCheat()

View File

@ -499,8 +499,20 @@ INITSAVEBUF
pPed->CharCreatedBy = pBufferPlayer->CharCreatedBy;
pPed->m_currentWeapon = 0;
pPed->m_maxWeaponTypeAllowed = pBufferPlayer->m_maxWeaponTypeAllowed;
for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++)
pPed->m_weapons[i] = pBufferPlayer->m_weapons[i];
for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
if (pBufferPlayer->HasWeaponSlot(i)) {
int modelId = CWeaponInfo::GetWeaponInfo(pBufferPlayer->GetWeapon(i).m_eWeaponType)->m_nModelId;
if (modelId != -1) {
CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY);
int modelId2 = CWeaponInfo::GetWeaponInfo(pBufferPlayer->GetWeapon(i).m_eWeaponType)->m_nModel2Id;
if (modelId2 != -1)
CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY);
CStreaming::LoadAllRequestedModels(false);
}
pPed->GiveWeapon(pBufferPlayer->GetWeapon(i).m_eWeaponType, pBufferPlayer->GetWeapon(i).m_nAmmoTotal);
}
}
if (pedtype == PEDTYPE_PLAYER1) {
pPed->m_wepAccuracy = 100;

View File

@ -1332,12 +1332,14 @@ CStreaming::LoadInitialPeds(void)
RequestModel(MI_COP, STREAMFLAGS_DONT_REMOVE);
RequestModel(MI_MALE01, STREAMFLAGS_DONT_REMOVE);
RequestModel(MI_TAXI_D, STREAMFLAGS_DONT_REMOVE);
}
// TODO(MIAMI): remove this hack once we can stream weapons
for(int i = 0; i < MODELINFOSIZE; i++)
if(CModelInfo::GetModelInfo(i) &&
CModelInfo::GetModelInfo(i)->GetModelType() == MITYPE_WEAPON)
RequestModel(i, STREAMFLAGS_DONT_REMOVE);
void
CStreaming::LoadInitialWeapons(void)
{
// TODO(Miami): Enable when weapons have been ported
//CStreaming::RequestModel(MI_NIGHTSTICK, STREAMFLAGS_DONT_REMOVE);
CStreaming::RequestModel(MI_MISSILE, STREAMFLAGS_DONT_REMOVE);
}
void

View File

@ -165,6 +165,7 @@ public:
static void SetModelTxdIsDeletable(int32 id);
static void SetMissionDoesntRequireModel(int32 id);
static void LoadInitialPeds(void);
static void LoadInitialWeapons(void);
static void LoadInitialVehicles(void);
static void StreamVehiclesAndPeds(void);
static void StreamZoneModels(const CVector &pos);

View File

@ -2048,9 +2048,12 @@ CWorld::Process(void)
movingPed->EnteringCar()) {
CVehicle *movingCar = movingPed->m_pMyVehicle;
if(movingCar) {
#ifdef GTA_TRAIN
if(movingCar->IsTrain()) {
movingPed->SetPedPositionInTrain();
} else {
} else
#endif
{
switch(movingPed->m_nPedState) {
case PED_ENTER_CAR:
case PED_CARJACK: movingPed->EnterCar(); break;
@ -2235,6 +2238,7 @@ CWorld::UseDetonator(CEntity *pEntity)
pVehicle->m_pBlowUpEntity->RegisterReference(&pVehicle->m_pBlowUpEntity);
}
}
CProjectileInfo::RemoveDetonatorProjectiles();
}
bool

View File

@ -387,20 +387,21 @@ enum
MI_TRAIN = -1,
MI_DODO = -2,
MI_GRENADE = 258,
MI_AK47,
MI_BASEBALL_BAT,
MI_COLT,
MI_MOLOTOV,
MI_ROCKETLAUNCHER,
MI_SHOTGUN,
MI_SNIPER,
MI_UZI,
MI_MISSILE,
MI_M16,
MI_FLAMETHROWER,
MI_BOMB,
MI_FINGERS,
MI_BASEBALL_BAT = 264,
MI_GRENADE = 270,
MI_MOLOTOV = 272,
MI_MISSILE = 273,
MI_COLT = 274,
MI_AK47 = 276,
MI_SHOTGUN = 279,
MI_M16 = 280,
MI_UZI = 282,
MI_MP5 = 284,
MI_SNIPER = 285,
MI_ROCKETLAUNCHER = 287,
MI_FLAMETHROWER = 288,
MI_BOMB = 291,
MI_FINGERS = 293,
MI_CUTOBJ01 = 295,
MI_CUTOBJ02,

View File

@ -39,9 +39,10 @@ public:
RwObject *CreateInstance(RwMatrix *);
RwObject *GetRwObject(void) { return (RwObject*)m_atomics[0]; }
virtual void SetAtomic(int n, RpAtomic *atomic);
void Init(void);
void IncreaseAlpha(void);
void SetAtomic(int n, RpAtomic *atomic);
void SetLodDistances(float *dist);
float GetLodDistance(int i);
float GetNearDistance(void);

View File

@ -14,9 +14,9 @@ public:
virtual void SetAnimFile(const char *file);
virtual void ConvertAnimFileIndex(void);
virtual int GetAnimFileIndex(void) { return m_animFileIndex; }
virtual void SetAtomic(int n, RpAtomic *atomic);
void Init(void);
void SetWeaponInfo(int32 weaponId);
int32 GetWeaponInfo(void);
void SetAtomic(int n, RpAtomic *atomic);
};

View File

@ -23,7 +23,8 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
switch (copType) {
case COP_STREET:
SetModelIndex(MI_COP);
GiveWeapon(WEAPONTYPE_COLT45, 1000);
// GiveWeapon(WEAPONTYPE_NIGHTSTICK, 1000, true); // TODO(Miami)
GiveDelayedWeapon(WEAPONTYPE_COLT45, 1000);
m_currentWeapon = WEAPONTYPE_UNARMED;
m_fArmour = 0.0f;
m_wepSkills = 208; /* TODO: what is this? seems unused */
@ -31,17 +32,15 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
break;
case COP_FBI:
SetModelIndex(MI_FBI);
GiveWeapon(WEAPONTYPE_COLT45, 1000);
GiveWeapon(WEAPONTYPE_AK47, 1000);
SetCurrentWeapon(WEAPONTYPE_AK47);
GiveDelayedWeapon(WEAPONTYPE_MP5, 1000);
SetCurrentWeapon(WEAPONTYPE_MP5);
m_fArmour = 100.0f;
m_wepSkills = 176; /* TODO: what is this? seems unused */
m_wepAccuracy = 76;
break;
case COP_SWAT:
SetModelIndex(MI_SWAT);
GiveWeapon(WEAPONTYPE_COLT45, 1000);
GiveWeapon(WEAPONTYPE_UZI, 1000);
GiveDelayedWeapon(WEAPONTYPE_UZI, 1000);
SetCurrentWeapon(WEAPONTYPE_UZI);
m_fArmour = 50.0f;
m_wepSkills = 32; /* TODO: what is this? seems unused */
@ -49,10 +48,8 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
break;
case COP_ARMY:
SetModelIndex(MI_ARMY);
GiveWeapon(WEAPONTYPE_COLT45, 1000);
GiveWeapon(WEAPONTYPE_M16, 1000);
GiveWeapon(WEAPONTYPE_GRENADE, 10);
SetCurrentWeapon(WEAPONTYPE_M16);
GiveDelayedWeapon(WEAPONTYPE_MP5, 1000);
SetCurrentWeapon(WEAPONTYPE_MP5);
m_fArmour = 100.0f;
m_wepSkills = 32; /* TODO: what is this? seems unused */
m_wepAccuracy = 84;
@ -69,7 +66,7 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
case 7: SetModelIndex(MI_VICE8); break;
default: assert(0); break;
}
GiveWeapon(WEAPONTYPE_UZI, 1000);
GiveDelayedWeapon(WEAPONTYPE_UZI, 1000);
SetCurrentWeapon(WEAPONTYPE_UZI);
m_fArmour = 100.0f;
m_wepSkills = 176;

View File

@ -314,7 +314,7 @@ CEmergencyPed::MedicAI(void)
m_nEmergencyPedState = EMERGENCY_PED_STAND_STILL;
} else {
m_nEmergencyPedState = EMERGENCY_PED_FACE_TO_PATIENT;
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CPR, 4.0f);
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_MEDIC, ANIM_CPR, 4.0f);
bIsDucking = true;
}
SetLookTimer(2000);

File diff suppressed because it is too large Load Diff

View File

@ -521,8 +521,9 @@ public:
uint8 m_stateUnused;
uint32 m_timerUnused;
CVector2D *m_wanderRangeBounds; // array with 2 CVector2D (actually unused CRange2D class) - unused
CWeapon m_weapons[WEAPONTYPE_TOTAL_INVENTORY_WEAPONS];
CWeapon m_weapons[TOTAL_WEAPON_SLOTS];
eWeaponType m_storedWeapon;
uint32 m_storedWeaponAmmo;
uint8 m_currentWeapon; // eWeaponType
uint8 m_maxWeaponTypeAllowed; // eWeaponType
uint8 m_wepSkills;
@ -548,12 +549,26 @@ public:
uint32 m_duckTimer;
uint32 m_duckAndCoverTimer;
uint32 m_bloodyFootprintCountOrDeathTime; // Death time when bDoBloodyFootprints is false. Weird decision
uint32 m_shotTime;
uint32 m_shotTimeAdd;
uint8 m_panicCounter;
bool m_deadBleeding;
int8 m_bodyPartBleeding; // PedNode, but -1 if there isn't
CPed *m_nearPeds[10];
uint16 m_numNearPeds;
uint16 m_pedMoney;
int8 m_lastWepDam;
CEntity *m_lastDamEntity;
CEntity *m_attachedTo;
CVector m_vecAttachOffset;
uint16 m_attachType;
float m_attachRot;
uint32 m_attachWepAmmo;
uint32 m_threatFlags;
uint32 m_threatCheck;
uint32 m_lastThreatCheck;
uint32 m_sayType;
uint32 m_sayTimer;
uint32 m_lastSoundStart;
uint32 m_soundStart;
uint16 m_lastQueuedSound;
@ -601,7 +616,8 @@ public:
void ClearAttack(void);
bool IsPedHeadAbovePos(float zOffset);
void RemoveWeaponModel(int modelId);
void SetCurrentWeapon(uint32 weaponType);
void SetCurrentWeapon(eWeaponType weaponType);
void SetCurrentWeapon(int weapon);
void Duck(void);
void ClearDuck(void);
void ClearPointGunAt(void);
@ -612,7 +628,7 @@ public:
void PlayFootSteps(void);
void QuitEnteringCar(void);
void BuildPedLists(void);
uint32 GiveWeapon(eWeaponType weaponType, uint32 ammo);
int32 GiveWeapon(eWeaponType weaponType, uint32 ammo, bool unused = false);
void CalculateNewOrientation(void);
float WorkOutHeadingForMovingFirstPerson(float);
void CalculateNewVelocity(void);
@ -685,6 +701,7 @@ public:
void RemoveInCarAnims(void);
void CollideWithPed(CPed*);
void SetDirectionToWalkAroundObject(CEntity*);
void RemoveWeaponAnims(int, float);
void CreateDeadPedMoney(void);
void CreateDeadPedWeaponPickups(void);
void SetAttackTimer(uint32);
@ -700,7 +717,6 @@ public:
void EnterCar(void);
uint8 GetNearestTrainPedPosition(CVehicle*, CVector&);
uint8 GetNearestTrainDoor(CVehicle*, CVector&);
void LineUpPedWithTrain(void);
void ExitCar(void);
void Fight(void);
bool FindBestCoordsFromNodes(CVector, CVector*);
@ -747,7 +763,6 @@ public:
void SetExitCar(CVehicle*, uint32);
void SetFormation(eFormation);
bool WillChat(CPed*);
void SetEnterTrain(CVehicle*, uint32);
void SetEnterCar_AllClear(CVehicle*, uint32, uint32);
void SetSolicit(uint32 time);
void ScanForInterestingStuff(void);
@ -756,6 +771,9 @@ public:
bool WarpPedToNearLeaderOffScreen(void);
void Solicit(void);
void SetExitBoat(CVehicle*);
void ClearFollowPath();
void GiveDelayedWeapon(eWeaponType weapon, uint32 ammo);
void RequestDelayedWeapon();
// Static methods
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
@ -783,8 +801,9 @@ public:
static void PedSetDraggedOutCarCB(CAnimBlendAssociation *assoc, void *arg);
static void PedAnimStepOutCarCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetInTrainCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetOutTrainCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetOutTrainCB(CAnimBlendAssociation *assoc, void *arg); // TODO(Miami): Should be under GTA_TRAIN
static void FinishedAttackCB(CAnimBlendAssociation *assoc, void *arg);
static void FinishedReloadCB(CAnimBlendAssociation *assoc, void *arg);
static void FinishFightMoveCB(CAnimBlendAssociation *assoc, void *arg);
static void PedAnimDoorCloseRollingCB(CAnimBlendAssociation *assoc, void *arg);
static void FinishJumpCB(CAnimBlendAssociation *assoc, void *arg);
@ -813,8 +832,14 @@ public:
void SetPedStats(ePedStats);
bool IsGangMember(void);
void Die(void);
#ifdef GTA_TRAIN
void EnterTrain(void);
void ExitTrain(void);
void SetExitTrain(CVehicle*);
void SetPedPositionInTrain(void);
void LineUpPedWithTrain(void);
void SetEnterTrain(CVehicle*, uint32);
#endif
void Fall(void);
bool IsPedShootable(void);
void Look(void);
@ -822,11 +847,9 @@ public:
void RestoreHeadPosition(void);
void PointGunAt(void);
bool ServiceTalkingWhenDead(void);
void SetPedPositionInTrain(void);
void SetShootTimer(uint32);
void SetSeekCar(CVehicle*, uint32);
void SetSeekBoatPosition(CVehicle*);
void SetExitTrain(CVehicle*);
void WanderRange(void);
void SetFollowRoute(int16, int16);
void SeekBoatPosition(void);
@ -866,6 +889,35 @@ public:
void ReplaceWeaponWhenExitingVehicle(void);
void RemoveWeaponWhenEnteringVehicle(void);
bool IsNotInWreckedVehicle();
// My addons. Maybe inlined in VC?
AnimationId GetFireAnimNotDucking(CWeaponInfo* weapon) {
// TODO(Miami): Revert that when weapons got ported
if (weapon->m_AnimToPlay == ASSOCGRP_STD)
return ANIM_FIGHT_PPUNCH;
if (m_nPedType == PEDTYPE_COP && !!weapon->m_bCop3rd)
return ANIM_WEAPON_FIRE_3RD;
else
return weapon->m_bAnimDetonate ? ANIM_BOMBER : ANIM_WEAPON_FIRE;
}
static AnimationId GetFireAnimGround(CWeaponInfo* weapon, bool kickFloorIfNone = true) {
// TODO(Miami): Revert that when weapons got ported
if (weapon->m_AnimToPlay == ASSOCGRP_STD)
return ANIM_KICK_FLOOR;
if (!!weapon->m_bGround2nd)
return ANIM_WEAPON_CROUCHFIRE;
else if (!!weapon->m_bGround3rd)
return ANIM_WEAPON_SPECIAL;
else if (kickFloorIfNone)
return ANIM_KICK_FLOOR;
else
return (AnimationId)0;
}
// --
// My additions, because there were many, many instances of that.
inline void SetFindPathAndFlee(CEntity *fleeFrom, int time, bool walk = false)
{
@ -884,43 +936,24 @@ public:
if (walk)
SetMoveState(PEDMOVE_WALK);
}
// --
// Using this to abstract nodes of skinned and non-skinned meshes
CVector GetNodePosition(int32 node)
{
#ifdef PED_SKIN
if(IsClumpSkinned(GetClump())){
RwV3d pos = { 0.0f, 0.0f, 0.0f };
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
// this is just stupid
//RwV3dTransformPoints(&pos, &pos, 1, &mats[idx]);
pos = mats[idx].pos;
return pos;
}else
#endif
{
RwMatrix mat;
CPedIK::GetWorldMatrix(m_pFrames[node]->frame, &mat);
return mat.pos;
}
}
void TransformToNode(CVector &pos, int32 node)
{
#ifdef PED_SKIN
if(IsClumpSkinned(GetClump())){
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
RwV3dTransformPoints((RwV3d*)&pos, (RwV3d*)&pos, 1, &mats[idx]);
}else
#endif
{
RwFrame *frame;
for (frame = m_pFrames[node]->frame; frame; frame = RwFrameGetParent(frame))
RwV3dTransformPoints((RwV3d*)&pos, (RwV3d*)&pos, 1, RwFrameGetMatrix(frame));
}
}
// set by 0482:set_threat_reaction_range_multiplier opcode
@ -953,6 +986,7 @@ public:
void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
// TODO(Miami): Change those when Ped struct is done
#ifndef PED_SKIN
VALIDATE_SIZE(CPed, 0x53C);
#endif

View File

@ -7,11 +7,13 @@
#include "General.h"
#include "RwHelper.h"
LimbMovementInfo CPedIK::ms_torsoInfo = { DEGTORAD(50.0f), DEGTORAD(-50.0f), DEGTORAD(15.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(7.0f) };
LimbMovementInfo CPedIK::ms_headInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(10.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) };
//--MIAMI: file almost done (only some special weapon cases left)
LimbMovementInfo CPedIK::ms_torsoInfo = { DEGTORAD(50.0f), DEGTORAD(-50.0f), DEGTORAD(8.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) };
LimbMovementInfo CPedIK::ms_headInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(15.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(8.0f) };
LimbMovementInfo CPedIK::ms_headRestoreInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(10.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) };
LimbMovementInfo CPedIK::ms_upperArmInfo = { DEGTORAD(20.0f), DEGTORAD(-100.0f), DEGTORAD(20.0f), DEGTORAD(70.0f), DEGTORAD(-70.0f), DEGTORAD(10.0f) };
LimbMovementInfo CPedIK::ms_lowerArmInfo = { DEGTORAD(80.0f), DEGTORAD(0.0f), DEGTORAD(20.0f), DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(5.0f) };
LimbMovementInfo CPedIK::ms_upperArmInfo = { DEGTORAD(5.0f), DEGTORAD(-120.0f), DEGTORAD(20.0f), DEGTORAD(70.0f), DEGTORAD(-70.0f), DEGTORAD(20.0f) };
LimbMovementInfo CPedIK::ms_lowerArmInfo = { DEGTORAD(60.0f), DEGTORAD(0.0f), DEGTORAD(15.0f), DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(10.0f) };
const RwV3d XaxisIK = { 1.0f, 0.0f, 0.0f};
const RwV3d YaxisIK = { 0.0f, 1.0f, 0.0f};
@ -21,17 +23,16 @@ CPedIK::CPedIK(CPed *ped)
{
m_ped = ped;
m_flags = 0;
m_headOrient.phi = 0.0f;
m_headOrient.theta = 0.0f;
m_torsoOrient.phi = 0.0f;
m_torsoOrient.theta = 0.0f;
m_upperArmOrient.phi = 0.0f;
m_upperArmOrient.theta = 0.0f;
m_lowerArmOrient.phi = 0.0f;
m_lowerArmOrient.theta = 0.0f;
m_headOrient.yaw = 0.0f;
m_headOrient.pitch = 0.0f;
m_torsoOrient.yaw = 0.0f;
m_torsoOrient.pitch = 0.0f;
m_upperArmOrient.yaw = 0.0f;
m_upperArmOrient.pitch = 0.0f;
m_lowerArmOrient.yaw = 0.0f;
m_lowerArmOrient.pitch = 0.0f;
}
#ifdef PED_SKIN
inline RwMatrix*
GetBoneMatrix(CPed *ped, int32 bone)
{
@ -45,174 +46,60 @@ GetComponentMatrix(CPed *ped, int32 node)
{
return GetBoneMatrix(ped, ped->m_pFrames[node]->nodeID);
}
#endif
void
CPedIK::RotateTorso(AnimBlendFrameData *node, LimbOrientation *limb, bool changeRoll)
{
#ifdef PED_SKIN
if(IsClumpSkinned(m_ped->GetClump())){
RtQuat *q = &node->hanimFrame->q;
#ifndef FIX_BUGS
// this is what the game does (also VC), but it does not look great
RtQuatRotate(q, &XaxisIK, RADTODEG(limb->phi), rwCOMBINEPRECONCAT);
RtQuatRotate(q, &ZaxisIK, RADTODEG(limb->theta), rwCOMBINEPRECONCAT); // pitch
#else
// copied the code from the non-skinned case
// this seems to work ok
// We can't get the parent matrix of an hanim frame but
// this function is always called with PED_MID, so we know the parent frame.
// Trouble is that PED_MID is "Smid" on PS2/PC but BONE_torso on mobile/xbox...
// so this doesn't exactly do what we'd like anyway
RwMatrix* mat = GetComponentMatrix(m_ped, PED_MID);
RwV3d vec1, vec2;
vec1.x = mat->right.z;
vec1.y = mat->up.z;
vec1.z = mat->at.z;
float c = Cos(m_ped->m_fRotationCur);
float s = Sin(m_ped->m_fRotationCur);
vec2.x = -(c*mat->right.x + s*mat->right.y);
vec2.y = -(c*mat->up.x + s*mat->up.y);
vec2.z = -(c*mat->at.x + s*mat->at.y);
// Not sure what exactly to do here
RtQuatRotate(q, &vec1, RADTODEG(limb->phi), rwCOMBINEPRECONCAT);
RtQuatRotate(q, &vec2, RADTODEG(limb->theta), rwCOMBINEPRECONCAT);
#endif
RtQuatRotate(q, &XaxisIK, RADTODEG(limb->yaw), rwCOMBINEREPLACE);
RtQuatRotate(q, &ZaxisIK, RADTODEG(limb->pitch), rwCOMBINEPRECONCAT);
m_ped->bDontAcceptIKLookAts = true;
}else
#endif
{
RwFrame *f = node->frame;
RwMatrix *mat = GetWorldMatrix(RwFrameGetParent(f), RwMatrixCreate());
RwV3d upVector = { mat->right.z, mat->up.z, mat->at.z };
RwV3d rightVector;
RwV3d pos = RwFrameGetMatrix(f)->pos;
// rotation == 0 -> looking in y direction
// left? vector
float c = Cos(m_ped->m_fRotationCur);
float s = Sin(m_ped->m_fRotationCur);
rightVector.x = -(c*mat->right.x + s*mat->right.y);
rightVector.y = -(c*mat->up.x + s*mat->up.y);
rightVector.z = -(c*mat->at.x + s*mat->at.y);
if(changeRoll){
// Used when aiming only involves over the legs.(canAimWithArm)
// Automatically changes roll(forward rotation) axis of the parts above upper legs while moving, based on position of upper legs.
// Not noticeable in normal conditions...
RwV3d forwardVector;
CVector inversedForward = CrossProduct(CVector(0.0f, 0.0f, 1.0f), mat->up);
inversedForward.Normalise();
float dotProduct = DotProduct(mat->at, inversedForward);
if(dotProduct > 1.0f) dotProduct = 1.0f;
if(dotProduct < -1.0f) dotProduct = -1.0f;
float alpha = Acos(dotProduct);
if(mat->at.z < 0.0f)
alpha = -alpha;
forwardVector.x = s * mat->right.x - c * mat->right.y;
forwardVector.y = s * mat->up.x - c * mat->up.y;
forwardVector.z = s * mat->at.x - c * mat->at.y;
float curYaw, curPitch;
ExtractYawAndPitchWorld(mat, &curYaw, &curPitch);
RwMatrixRotate(RwFrameGetMatrix(f), &rightVector, RADTODEG(limb->theta), rwCOMBINEPOSTCONCAT);
RwMatrixRotate(RwFrameGetMatrix(f), &upVector, RADTODEG(limb->phi - (curYaw - m_ped->m_fRotationCur)), rwCOMBINEPOSTCONCAT);
RwMatrixRotate(RwFrameGetMatrix(f), &forwardVector, RADTODEG(alpha), rwCOMBINEPOSTCONCAT);
}else{
// pitch
RwMatrixRotate(RwFrameGetMatrix(f), &rightVector, RADTODEG(limb->theta), rwCOMBINEPOSTCONCAT);
// yaw
RwMatrixRotate(RwFrameGetMatrix(f), &upVector, RADTODEG(limb->phi), rwCOMBINEPOSTCONCAT);
}
RwFrameGetMatrix(f)->pos = pos;
RwMatrixDestroy(mat);
}
}
void
CPedIK::GetComponentPosition(RwV3d *pos, uint32 node)
{
RwFrame *f;
RwMatrix *mat;
#ifdef PED_SKIN
if(IsClumpSkinned(m_ped->GetClump())){
pos->x = 0.0f;
pos->y = 0.0f;
pos->z = 0.0f;
mat = GetComponentMatrix(m_ped, node);
// could just copy the position out of the matrix...
RwV3dTransformPoints(pos, pos, 1, mat);
}else
#endif
{
f = m_ped->m_pFrames[node]->frame;
mat = RwFrameGetMatrix(f);
*pos = mat->pos;
for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f))
RwV3dTransformPoints(pos, pos, 1, RwFrameGetMatrix(f));
}
}
RwMatrix*
CPedIK::GetWorldMatrix(RwFrame *source, RwMatrix *destination)
{
RwFrame *i;
*destination = *RwFrameGetMatrix(source);
for (i = RwFrameGetParent(source); i; i = RwFrameGetParent(i))
RwMatrixTransform(destination, RwFrameGetMatrix(i), rwCOMBINEPOSTCONCAT);
return destination;
*pos = GetComponentMatrix(m_ped, node)->pos;
}
LimbMoveStatus
CPedIK::MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo)
CPedIK::MoveLimb(LimbOrientation &limb, float targetYaw, float targetPitch, LimbMovementInfo &moveInfo)
{
LimbMoveStatus result = ONE_ANGLE_COULDNT_BE_SET_EXACTLY;
// phi
// yaw
if (limb.phi > approxPhi) {
limb.phi -= moveInfo.yawD;
} else if (limb.phi < approxPhi) {
limb.phi += moveInfo.yawD;
}
if (Abs(limb.phi - approxPhi) < moveInfo.yawD) {
limb.phi = approxPhi;
if(Abs(limb.yaw-targetYaw) < moveInfo.yawD){
limb.yaw = targetYaw;
result = ANGLES_SET_EXACTLY;
}else{
if (limb.yaw > targetYaw) {
limb.yaw -= moveInfo.yawD;
} else if (limb.yaw < targetYaw) {
limb.yaw += moveInfo.yawD;
}
}
if (limb.phi > moveInfo.maxYaw || limb.phi < moveInfo.minYaw) {
limb.phi = clamp(limb.phi, moveInfo.minYaw, moveInfo.maxYaw);
if (limb.yaw > moveInfo.maxYaw || limb.yaw < moveInfo.minYaw) {
limb.yaw = clamp(limb.yaw, moveInfo.minYaw, moveInfo.maxYaw);
result = ANGLES_SET_TO_MAX;
}
// theta
// pitch
if (limb.theta > approxTheta) {
limb.theta -= moveInfo.pitchD;
} else if (limb.theta < approxTheta) {
limb.theta += moveInfo.pitchD;
if (Abs(limb.pitch - targetPitch) < moveInfo.pitchD){
limb.pitch = targetPitch;
}else{
if (limb.pitch > targetPitch) {
limb.pitch -= moveInfo.pitchD;
} else if (limb.pitch < targetPitch) {
limb.pitch += moveInfo.pitchD;
}
result = ONE_ANGLE_COULDNT_BE_SET_EXACTLY;
}
if (Abs(limb.theta - approxTheta) < moveInfo.pitchD)
limb.theta = approxTheta;
else
result = ONE_ANGLE_COULDNT_BE_SET_EXACTLY;
if (limb.theta > moveInfo.maxPitch || limb.theta < moveInfo.minPitch) {
limb.theta = clamp(limb.theta, moveInfo.minPitch, moveInfo.maxPitch);
if (limb.pitch > moveInfo.maxPitch || limb.pitch < moveInfo.minPitch) {
limb.pitch = clamp(limb.pitch, moveInfo.minPitch, moveInfo.maxPitch);
result = ANGLES_SET_TO_MAX;
}
return result;
@ -226,259 +113,189 @@ CPedIK::RestoreGunPosn(void)
return limbStatus == ANGLES_SET_EXACTLY;
}
#ifdef PED_SKIN
void
CPedIK::RotateHead(void)
{
RtQuat *q = &m_ped->m_pFrames[PED_HEAD]->hanimFrame->q;
RtQuatRotate(q, &XaxisIK, RADTODEG(m_headOrient.phi), rwCOMBINEREPLACE);
RtQuatRotate(q, &ZaxisIK, RADTODEG(m_headOrient.theta), rwCOMBINEPOSTCONCAT);
m_ped->bDontAcceptIKLookAts = true;
}
#endif
bool
CPedIK::LookInDirection(float phi, float theta)
CPedIK::LookInDirection(float targetYaw, float targetPitch)
{
bool success = true;
float yaw, pitch;
#ifdef PED_SKIN
if(IsClumpSkinned(m_ped->GetClump())){
if (!(m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION)) {
m_ped->m_pFrames[PED_HEAD]->flag |= AnimBlendFrameData::IGNORE_ROTATION;
ExtractYawAndPitchLocalSkinned(m_ped->m_pFrames[PED_HEAD], &m_headOrient.phi, &m_headOrient.theta);
RwMatrix *m = GetComponentMatrix(m_ped, PED_NECK);
m_headOrient.yaw = Atan2(-m->at.y, -m->at.x);
m_headOrient.yaw -= m_ped->m_fRotationCur;
m_headOrient.yaw = CGeneral::LimitRadianAngle(m_headOrient.yaw);
float up = clamp(m->up.z, -1.0f, 1.0f);
m_headOrient.pitch = Atan2(-up, Sqrt(1.0f - SQR(-up)));
}
// parent of head is torso
RwMatrix worldMat = *GetComponentMatrix(m_ped, PED_NECK);
ExtractYawAndPitchWorld(&worldMat, &yaw, &pitch);
// parent of head is neck
RwMatrix *m = GetComponentMatrix(m_ped, PED_NECK);
yaw = CGeneral::LimitRadianAngle(Atan2(-m->at.y, -m->at.x));
float up = clamp(m->up.z, -1.0f, 1.0f);
pitch = Atan2(-up, Sqrt(1.0f - SQR(-up)));
float headYaw = CGeneral::LimitRadianAngle(targetYaw - (yaw + m_torsoOrient.yaw));
float headPitch = CGeneral::LimitRadianAngle(targetPitch - pitch) * Cos(Min(Abs(headYaw), HALFPI));
LimbMoveStatus headStatus = MoveLimb(m_headOrient, CGeneral::LimitRadianAngle(phi - yaw),
CGeneral::LimitRadianAngle(DEGTORAD(10.0f)), ms_headInfo);
LimbMoveStatus headStatus = MoveLimb(m_headOrient, headYaw, headPitch, ms_headInfo);
if (headStatus == ANGLES_SET_TO_MAX)
success = false;
if (headStatus != ANGLES_SET_EXACTLY){
if (!(m_flags & LOOKAROUND_HEAD_ONLY)){
if (MoveLimb(m_torsoOrient, CGeneral::LimitRadianAngle(phi), theta, ms_torsoInfo))
if (headStatus != ANGLES_SET_EXACTLY && !(m_flags & LOOKAROUND_HEAD_ONLY))
if (MoveLimb(m_torsoOrient, CGeneral::LimitRadianAngle(targetYaw-m_ped->m_fRotationCur), targetPitch, ms_torsoInfo))
success = true;
}else{
RotateHead();
return success;
}
}
// This was RotateHead
RtQuat *q = &m_ped->m_pFrames[PED_HEAD]->hanimFrame->q;
RtQuatRotate(q, &ZaxisIK, RADTODEG(m_headOrient.pitch), rwCOMBINEREPLACE);
RtQuatRotate(q, &XaxisIK, RADTODEG(m_headOrient.yaw), rwCOMBINEPRECONCAT);
m_ped->bDontAcceptIKLookAts = true;
if (!(m_flags & LOOKAROUND_HEAD_ONLY))
RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
RotateHead();
}else
#endif
{
RwFrame *frame = m_ped->m_pFrames[PED_HEAD]->frame;
RwMatrix *frameMat = RwFrameGetMatrix(frame);
if (!(m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION)) {
m_ped->m_pFrames[PED_HEAD]->flag |= AnimBlendFrameData::IGNORE_ROTATION;
ExtractYawAndPitchLocal(frameMat, &m_headOrient.phi, &m_headOrient.theta);
}
RwMatrix *worldMat = RwMatrixCreate();
worldMat = GetWorldMatrix(RwFrameGetParent(frame), worldMat);
ExtractYawAndPitchWorld(worldMat, &yaw, &pitch);
RwMatrixDestroy(worldMat);
yaw += m_torsoOrient.phi;
float neededPhiTurn = CGeneral::LimitRadianAngle(phi - yaw);
pitch *= Cos(neededPhiTurn);
float neededThetaTurn = CGeneral::LimitRadianAngle(theta - pitch);
LimbMoveStatus headStatus = MoveLimb(m_headOrient, neededPhiTurn, neededThetaTurn, ms_headInfo);
if (headStatus == ANGLES_SET_TO_MAX)
success = false;
if (headStatus != ANGLES_SET_EXACTLY && !(m_flags & LOOKAROUND_HEAD_ONLY)) {
float remainingTurn = CGeneral::LimitRadianAngle(phi - m_ped->m_fRotationCur);
if (MoveLimb(m_torsoOrient, remainingTurn, theta, ms_torsoInfo))
success = true;
}
CMatrix nextFrame = CMatrix(frameMat);
CVector framePos = nextFrame.GetPosition();
nextFrame.SetRotateZ(m_headOrient.theta);
nextFrame.RotateX(m_headOrient.phi);
nextFrame.GetPosition() += framePos;
nextFrame.UpdateRW();
if (!(m_flags & LOOKAROUND_HEAD_ONLY))
RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
}
return success;
}
bool
CPedIK::LookAtPosition(CVector const &pos)
{
float phiToFace = CGeneral::GetRadianAngleBetweenPoints(
RwV3d *pedpos = &GetComponentMatrix(m_ped, PED_MID)->pos;
float yawToFace = CGeneral::GetRadianAngleBetweenPoints(
pos.x, pos.y,
m_ped->GetPosition().x, m_ped->GetPosition().y);
pedpos->x, pedpos->y);
float thetaToFace = CGeneral::GetRadianAngleBetweenPoints(
float pitchToFace = CGeneral::GetRadianAngleBetweenPoints(
// BUG? not using pedpos here
pos.z, (m_ped->GetPosition() - pos).Magnitude2D(),
m_ped->GetPosition().z, 0.0f);
pedpos->z, 0.0f);
return LookInDirection(phiToFace, thetaToFace);
return LookInDirection(yawToFace, pitchToFace);
}
bool
CPedIK::PointGunInDirection(float phi, float theta)
CPedIK::PointGunInDirection(float targetYaw, float targetPitch)
{
bool result = true;
bool armPointedToGun = false;
float angle = CGeneral::LimitRadianAngle(phi - m_ped->m_fRotationCur);
m_flags &= (~GUN_POINTED_SUCCESSFULLY);
targetYaw = CGeneral::LimitRadianAngle(targetYaw - m_ped->GetForward().Heading());
m_flags &= ~GUN_POINTED_SUCCESSFULLY;
m_flags |= LOOKAROUND_HEAD_ONLY;
if (m_flags & AIMS_WITH_ARM) {
armPointedToGun = PointGunInDirectionUsingArm(angle, theta);
angle = CGeneral::LimitRadianAngle(angle - m_upperArmOrient.phi);
armPointedToGun = PointGunInDirectionUsingArm(targetYaw, targetPitch);
targetYaw = CGeneral::LimitRadianAngle(targetYaw - (m_upperArmOrient.yaw + m_lowerArmOrient.yaw));
}
if (armPointedToGun) {
if (m_flags & AIMS_WITH_ARM && m_torsoOrient.phi * m_upperArmOrient.phi < 0.0f)
MoveLimb(m_torsoOrient, 0.0f, m_torsoOrient.theta, ms_torsoInfo);
if (m_flags & AIMS_WITH_ARM && m_torsoOrient.yaw * m_upperArmOrient.yaw < 0.0f)
MoveLimb(m_torsoOrient, 0.0f, m_torsoOrient.pitch, ms_torsoInfo);
} else {
// Unused code
RwMatrix *matrix;
float yaw, pitch;
#ifdef PED_SKIN
if(IsClumpSkinned(m_ped->GetClump())){
matrix = RwMatrixCreate();
*matrix = *GetComponentMatrix(m_ped, PED_UPPERARMR);
*matrix = *GetComponentMatrix(m_ped, PED_CLAVICLER);
ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
RwMatrixDestroy(matrix);
}else
#endif
{
matrix = GetWorldMatrix(RwFrameGetParent(m_ped->m_pFrames[PED_UPPERARMR]->frame), RwMatrixCreate());
ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
RwMatrixDestroy(matrix);
}
//
LimbMoveStatus status = MoveLimb(m_torsoOrient, angle, theta, ms_torsoInfo);
if(m_flags & AIMS_WITH_ARM){
if(targetPitch > 0.0f)
targetPitch = Max(targetPitch - Abs(targetYaw), 0.0f);
else
targetPitch = Min(targetPitch + Abs(targetYaw), 0.0f);
}
LimbMoveStatus status = MoveLimb(m_torsoOrient, targetYaw, targetPitch, ms_torsoInfo);
if (status == ANGLES_SET_TO_MAX)
result = false;
else if (status == ANGLES_SET_EXACTLY)
m_flags |= GUN_POINTED_SUCCESSFULLY;
}
if (TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam() && m_flags & AIMS_WITH_ARM)
RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, true);
else
RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
RwMatrix *m = GetBoneMatrix(m_ped, BONE_spine); // BUG: game uses index 2 directly, which happens to be identical to BONE_spine
RwV3d axis = { 0.0f, 0.0f, 0.0f };
float axisangle = -CGeneral::LimitRadianAngle(Atan2(-m->at.y, -m->at.x) - m_ped->m_fRotationCur);
axis.y = -Sin(axisangle);
axis.z = Cos(axisangle);
// this was RotateTorso
RtQuat *q = &m_ped->m_pFrames[PED_MID]->hanimFrame->q;
RtQuatRotate(q, &axis, RADTODEG(m_torsoOrient.pitch), rwCOMBINEPOSTCONCAT);
RtQuatRotate(q, &XaxisIK, RADTODEG(m_torsoOrient.yaw), rwCOMBINEPOSTCONCAT);
m_ped->bDontAcceptIKLookAts = true;
return result;
}
bool
CPedIK::PointGunInDirectionUsingArm(float phi, float theta)
CPedIK::PointGunInDirectionUsingArm(float targetYaw, float targetPitch)
{
bool result = false;
RwV3d upVector; // only for non-skinned
RwMatrix *matrix;
float yaw, pitch;
#ifdef PED_SKIN
if(IsClumpSkinned(m_ped->GetClump())){
matrix = RwMatrixCreate();
*matrix = *GetComponentMatrix(m_ped, PED_UPPERARMR);
ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
RwMatrixDestroy(matrix);
}else
#endif
{
RwFrame *frame = m_ped->m_pFrames[PED_UPPERARMR]->frame;
matrix = GetWorldMatrix(RwFrameGetParent(frame), RwMatrixCreate());
// with PED_SKIN this is actually done below (with a memory leak)
upVector.x = matrix->right.z;
upVector.y = matrix->up.z;
upVector.z = matrix->at.z;
float uaRoll = 45.0f;
float handRoll = 30.0f;
ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
RwMatrixDestroy(matrix);
}
matrix = GetComponentMatrix(m_ped, PED_CLAVICLER);
yaw = CGeneral::LimitRadianAngle(Atan2(matrix->right.y, matrix->right.x) - m_ped->m_fRotationCur);
pitch = Atan2(matrix->up.z, Sqrt(1.0f - SQR(matrix->up.z)));
RwV3d rightVector = { 0.0f, 0.0f, 1.0f };
RwV3d forwardVector = { 1.0f, 0.0f, 0.0f };
float uaPhi, uaTheta;
#ifdef PED_SKIN
if(IsClumpSkinned(m_ped->GetClump())){
uaPhi = phi;
uaTheta = theta + DEGTORAD(10.0f);
}else
#endif
{
uaPhi = phi - m_torsoOrient.phi - DEGTORAD(15.0f);
uaTheta = CGeneral::LimitRadianAngle(theta - pitch);
}
LimbMoveStatus uaStatus = MoveLimb(m_upperArmOrient, uaPhi, uaTheta, ms_upperArmInfo);
float uaYaw, uaPitch;
uaYaw = CGeneral::LimitRadianAngle(targetYaw - yaw - DEGTORAD(15.0f));
uaPitch = CGeneral::LimitRadianAngle(targetPitch - pitch + DEGTORAD(10.0f));
LimbMoveStatus uaStatus = MoveLimb(m_upperArmOrient, uaYaw, uaPitch, ms_upperArmInfo);
if (uaStatus == ANGLES_SET_EXACTLY) {
m_flags |= GUN_POINTED_SUCCESSFULLY;
result = true;
}
#ifdef PED_SKIN
// this code is completely missing on xbox & android, but we can keep it with the check
// TODO? implement it for skinned geometry?
if(!IsClumpSkinned(m_ped->GetClump()))
#endif
if (uaStatus == ANGLES_SET_TO_MAX) {
float laPhi = uaPhi - m_upperArmOrient.phi;
float laYaw = uaYaw - m_upperArmOrient.yaw;
LimbMoveStatus laStatus;
if (laPhi > 0.0f)
laStatus = MoveLimb(m_lowerArmOrient, laPhi, -DEGTORAD(45.0f), ms_lowerArmInfo);
else
laStatus = MoveLimb(m_lowerArmOrient, laPhi, 0.0f, ms_lowerArmInfo);
if (laYaw > 0.0f){
float rollReduce = laYaw/DEGTORAD(30.0f);
uaRoll *= 1.0f - Min(rollReduce, 1.0f);
handRoll *= 1.0f - Min(rollReduce, 1.0f);
laYaw *= 1.9f;
laStatus = MoveLimb(m_lowerArmOrient, laYaw, 0.0f, ms_lowerArmInfo);
// some unused statics here
float uaPitchAmount = 1.0f - (m_lowerArmOrient.yaw + m_upperArmOrient.yaw) * 0.34f;
float f1 = ms_upperArmInfo.maxPitch * Max(uaPitchAmount, 0.0f);
float f2 = 0.2f*m_lowerArmOrient.yaw + m_upperArmOrient.pitch;
m_upperArmOrient.pitch = Min(f1, f2);
}else
laStatus = MoveLimb(m_lowerArmOrient, laYaw, 0.0f, ms_lowerArmInfo);
if (laStatus == ANGLES_SET_EXACTLY) {
m_flags |= GUN_POINTED_SUCCESSFULLY;
result = true;
}
RwFrame *child = GetFirstChild(m_ped->m_pFrames[PED_UPPERARMR]->frame);
RwV3d pos = RwFrameGetMatrix(child)->pos;
RwMatrixRotate(RwFrameGetMatrix(child), &forwardVector, RADTODEG(m_lowerArmOrient.theta), rwCOMBINEPOSTCONCAT);
RwMatrixRotate(RwFrameGetMatrix(child), &rightVector, RADTODEG(-m_lowerArmOrient.phi), rwCOMBINEPOSTCONCAT);
RwFrameGetMatrix(child)->pos = pos;
// game does this stupidly by going through the clump extension...
RtQuat *q = &m_ped->m_pFrames[PED_FOREARMR]->hanimFrame->q;
RtQuatRotate(q, &ZaxisIK, -RADTODEG(m_lowerArmOrient.yaw), rwCOMBINEREPLACE);
RtQuatRotate(q, &XaxisIK, -RADTODEG(m_lowerArmOrient.pitch), rwCOMBINEPOSTCONCAT);
m_ped->bDontAcceptIKLookAts = true;
}
#ifdef PED_SKIN
if(IsClumpSkinned(m_ped->GetClump())){
RtQuat *q = &m_ped->m_pFrames[PED_UPPERARMR]->hanimFrame->q;
RtQuatRotate(q, &XaxisIK, RADTODEG(m_upperArmOrient.phi), rwCOMBINEPOSTCONCAT);
RtQuatRotate(q, &ZaxisIK, RADTODEG(m_upperArmOrient.theta), rwCOMBINEPOSTCONCAT);
RtQuatRotate(q, &XaxisIK, uaRoll, rwCOMBINEREPLACE);
RtQuatRotate(q, &YaxisIK, -RADTODEG(m_upperArmOrient.pitch), rwCOMBINEPOSTCONCAT);
RtQuatRotate(q, &ZaxisIK, -RADTODEG(m_upperArmOrient.yaw+HALFPI), rwCOMBINEPOSTCONCAT);
m_ped->bDontAcceptIKLookAts = true;
}else
#endif
{
RwFrame *frame = m_ped->m_pFrames[PED_UPPERARMR]->frame;
// with PED_SKIN we're also getting upVector here
RwV3d pos = RwFrameGetMatrix(frame)->pos;
RwMatrixRotate(RwFrameGetMatrix(frame), &rightVector, RADTODEG(m_upperArmOrient.theta), rwCOMBINEPOSTCONCAT);
RwMatrixRotate(RwFrameGetMatrix(frame), &upVector, RADTODEG(m_upperArmOrient.phi), rwCOMBINEPOSTCONCAT);
RwFrameGetMatrix(frame)->pos = pos;
}
q = &m_ped->m_pFrames[PED_HANDR]->hanimFrame->q;
RtQuatRotate(q, &XaxisIK, handRoll, rwCOMBINEPRECONCAT);
return result;
}
bool
CPedIK::PointGunAtPosition(CVector const& position)
{
// TODO(MIAMI): special cases for some weapons
return PointGunInDirection(
CGeneral::GetRadianAngleBetweenPoints(position.x, position.y, m_ped->GetPosition().x, m_ped->GetPosition().y),
CGeneral::GetRadianAngleBetweenPoints(position.z, Distance2D(m_ped->GetPosition(), position.x, position.y),
m_ped->GetPosition().z,
0.0f));
CGeneral::GetRadianAngleBetweenPoints(position.z, Distance2D(m_ped->GetPosition(), position.x, position.y), m_ped->GetPosition().z, 0.0f));
}
bool
@ -487,8 +304,6 @@ CPedIK::RestoreLookAt(void)
bool result = false;
float yaw, pitch;
#ifdef PED_SKIN
if(IsClumpSkinned(m_ped->GetClump())){
if (m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION) {
m_ped->m_pFrames[PED_HEAD]->flag &= (~AnimBlendFrameData::IGNORE_ROTATION);
} else {
@ -496,31 +311,17 @@ CPedIK::RestoreLookAt(void)
if (MoveLimb(m_headOrient, yaw, pitch, ms_headRestoreInfo) == ANGLES_SET_EXACTLY)
result = true;
}
RotateHead();
}else
#endif
{
RwMatrix *mat = RwFrameGetMatrix(m_ped->m_pFrames[PED_HEAD]->frame);
if (m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION) {
m_ped->m_pFrames[PED_HEAD]->flag &= (~AnimBlendFrameData::IGNORE_ROTATION);
} else {
ExtractYawAndPitchLocal(mat, &yaw, &pitch);
if (MoveLimb(m_headOrient, yaw, pitch, ms_headRestoreInfo) == ANGLES_SET_EXACTLY)
result = true;
}
CMatrix matrix(mat);
CVector pos = matrix.GetPosition();
matrix.SetRotateZ(m_headOrient.theta);
matrix.RotateX(m_headOrient.phi);
matrix.Translate(pos);
matrix.UpdateRW();
}
if (!(m_flags & LOOKAROUND_HEAD_ONLY)){
// This was RotateHead
RtQuat *q = &m_ped->m_pFrames[PED_HEAD]->hanimFrame->q;
RtQuatRotate(q, &XaxisIK, RADTODEG(m_headOrient.yaw), rwCOMBINEREPLACE);
RtQuatRotate(q, &ZaxisIK, RADTODEG(m_headOrient.pitch), rwCOMBINEPRECONCAT);
m_ped->bDontAcceptIKLookAts = true;
if (!(m_flags & LOOKAROUND_HEAD_ONLY))
MoveLimb(m_torsoOrient, 0.0f, 0.0f, ms_torsoInfo);
if (!(m_flags & LOOKAROUND_HEAD_ONLY))
RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
}
return result;
}
@ -548,7 +349,6 @@ CPedIK::ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch)
if (mat->up.x > 0.0f) *pitch = -*pitch;
}
#ifdef PED_SKIN
void
CPedIK::ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch)
{
@ -557,4 +357,3 @@ CPedIK::ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, flo
ExtractYawAndPitchLocal(mat, yaw, pitch);
RwMatrixDestroy(mat);
}
#endif

View File

@ -4,8 +4,8 @@
struct LimbOrientation
{
float phi;
float theta;
float yaw;
float pitch;
};
struct LimbMovementInfo {
@ -48,19 +48,17 @@ public:
static LimbMovementInfo ms_lowerArmInfo;
CPedIK(CPed *ped);
bool PointGunInDirection(float phi, float theta);
bool PointGunInDirectionUsingArm(float phi, float theta);
bool PointGunInDirection(float targetYaw, float targetPitch);
bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch);
bool PointGunAtPosition(CVector const& position);
void GetComponentPosition(RwV3d *pos, uint32 node);
static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination);
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
void ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch);
void ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch);
LimbMoveStatus MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo);
LimbMoveStatus MoveLimb(LimbOrientation &limb, float targetYaw, float targetPitch, LimbMovementInfo &moveInfo);
bool RestoreGunPosn(void);
void RotateHead(void);
bool LookInDirection(float phi, float theta);
bool LookInDirection(float targetYaw, float targetPitch);
bool LookAtPosition(CVector const& pos);
bool RestoreLookAt(void);
};

View File

@ -16,6 +16,7 @@
#include "Pools.h"
#include "Darkel.h"
#include "CarCtrl.h"
#include "MBlur.h"
#define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f
@ -31,6 +32,7 @@ CPlayerPed::~CPlayerPed()
delete m_pWanted;
}
// --MIAMI: Done except commented out things
CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
{
m_fMoveSpeed = 0.0f;
@ -44,26 +46,47 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
m_nSpeedTimer = 0;
m_bSpeedTimerFlag = false;
// This should be something inlined
// TODO(Miami)
// if (pPointGunAt)
// m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
m_pPointGunAt = nil;
if (m_nPedState == PED_FOLLOW_PATH)
ClearFollowPath();
// TODO(Miami)
// This should be something inlined
m_nPedState = PED_IDLE;
m_fMaxStamina = 150.0f;
m_fCurrentStamina = m_fMaxStamina;
m_fStaminaProgress = 0.0f;
m_nEvadeAmount = 0;
field_1367 = 0;
m_pEvadingFrom = nil;
m_nHitAnimDelayTimer = 0;
m_fAttackButtonCounter = 0.0f;
m_bHaveTargetSelected = false;
m_bHasLockOnTarget = false;
m_bDrunkVisualsWearOff = true;
m_bCanBeDamaged = true;
m_fWalkAngle = 0.0f;
m_fFPSMoveHeading = 0.0f;
m_pMinigunTopAtomic = nil;
m_fGunSpinSpeed = 0.0;
m_fGunSpinAngle = 0.0;
m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1;
field_1413 = 0;
unused1 = false;
for (int i = 0; i < 6; i++) {
m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f);
m_pPedAtSafePos[i] = nil;
m_pCheckPlayers[i] = nil;
}
m_nCheckPlayersIndex = 0;
m_nPadUpPressedInMilliseconds = 0;
m_nPadDownPressedInMilliseconds = 0;
// TODO(Miami): Idle anim block index
}
void CPlayerPed::ClearWeaponTarget()
@ -181,8 +204,9 @@ CPlayerPed::UseSprintEnergy(void)
}
}
// --MIAMI: Use that on everywhere except ProcessPlayerWeapon
void
CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon)
{
if (m_nPedState == PED_SNIPER_MODE) {
RestorePreviousState();
@ -195,7 +219,7 @@ CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim))
ClearWeaponTarget();
CAnimBlendAssociation *weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)->m_AnimToPlay);
CAnimBlendAssociation* weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)->m_bAnimDetonate ? 62 : 205);
if (weaponAnim) {
weaponAnim->SetRun();
weaponAnim->flags |= ASSOC_FADEOUTWHENDONE;
@ -203,6 +227,14 @@ CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
TheCamera.ClearPlayerWeaponMode();
}
// --MIAMI: Done, but this should be only called from ProcessPlayerWeapon
void
CPlayerPed::MakeChangesForNewWeapon(int32 slot)
{
if(slot != -1)
MakeChangesForNewWeapon(m_weapons[slot].m_eWeaponType);
}
void
CPlayerPed::ReApplyMoveAnims(void)
{
@ -222,14 +254,19 @@ CPlayerPed::ReApplyMoveAnims(void)
}
}
// --MIAMI: Done
void
CPlayerPed::SetInitialState(void)
{
m_nDrunkenness = 0;
m_nFadeDrunkenness = 0;
CMBlur::ClearDrunkBlur();
m_nDrunkCountdown = 0;
m_bAdrenalineActive = false;
m_nAdrenalineTime = 0;
CTimer::SetTimeStep(1.0f);
CTimer::SetTimeScale(1.0f);
m_pSeekTarget = nil;
m_vecSeekPos = { 0.0f, 0.0f, 0.0f };
m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
m_fleeFromPosX = 0.0f;
m_fleeFromPosY = 0.0f;
m_fleeFrom = nil;
@ -241,9 +278,14 @@ CPlayerPed::SetInitialState(void)
ClearLookFlag();
bIsPointingGunAt = false;
bRenderPedInCar = true;
if (m_pFire)
m_pFire->Extinguish();
RpAnimBlendClumpRemoveAllAssociations(GetClump());
if (m_nPedState == PED_FOLLOW_PATH)
ClearFollowPath();
m_nPedState = PED_IDLE;
SetMoveState(PEDMOVE_STILL);
m_nLastPedState = PED_NONE;
@ -257,6 +299,11 @@ CPlayerPed::SetInitialState(void)
m_bCanBeDamaged = true;
m_pedStats->m_temper = 50;
m_fWalkAngle = 0.0f;
if (m_attachedTo && !bUsesCollision)
bUsesCollision = true;
m_attachedTo = nil;
m_attachWepAmmo = 0;
}
void
@ -497,8 +544,9 @@ CPlayerPed::DoWeaponSmoothSpray(void)
{
if (m_nPedState == PED_ATTACK && !m_pPointGunAt) {
eWeaponType weapon = GetWeapon()->m_eWeaponType;
if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || weapon == WEAPONTYPE_SHOTGUN ||
weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON)
if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI ||
weapon == WEAPONTYPE_TEC9 || weapon == WEAPONTYPE_SILENCED_INGRAM || weapon == WEAPONTYPE_MP5 ||
weapon == WEAPONTYPE_SHOTGUN || weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON)
return true;
}
return false;
@ -586,14 +634,16 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed)
GetWeapon()->Update(m_audioEntityId);
}
// --MIAMI: Made compatible with slots, but still TODO
// I think R* also used goto in here.
void
CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
{
if (CDarkel::FrenzyOnGoing())
if (CDarkel::FrenzyOnGoing() || m_attachedTo)
goto switchDetectDone;
if (padUsed->CycleWeaponRightJustDown() && !m_pPointGunAt) {
if (!m_pPointGunAt && /* !byte_A10B57 && */ GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR) {
if (padUsed->CycleWeaponRightJustDown()) {
if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT
@ -602,40 +652,53 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT) {
for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; ++m_nSelectedWepSlot) {
if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
goto switchDetectDone;
for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < TOTAL_WEAPON_SLOTS; ++m_nSelectedWepSlot) {
if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
goto spentAmmoCheck;
}
}
m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
m_nSelectedWepSlot = 0;
}
} else if (padUsed->CycleWeaponLeftJustDown() && !m_pPointGunAt) {
} else if (padUsed->CycleWeaponLeftJustDown()) {
if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) {
if (m_nSelectedWepSlot < WEAPONTYPE_UNARMED)
m_nSelectedWepSlot = WEAPONTYPE_DETONATOR;
if (m_nSelectedWepSlot < 0)
m_nSelectedWepSlot = 9;
if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
goto switchDetectDone;
if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
break;
}
}
}
} else if (CWeaponInfo::GetWeaponInfo((eWeaponType)m_currentWeapon)->m_eWeaponFire != WEAPON_FIRE_MELEE) {
if (GetWeapon(m_currentWeapon).m_nAmmoTotal <= 0) {
}
}
spentAmmoCheck:
if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_eWeaponFire != WEAPON_FIRE_MELEE
/*&& (!padUsed->GetWeapon() || GetWeapon()->m_eWeaponType != WEAPONTYPE_MINIGUN) */) {
if (GetWeapon()->m_nAmmoTotal <= 0) {
if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
for (m_nSelectedWepSlot = m_currentWeapon - 1; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) {
if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && HasWeapon(WEAPONTYPE_BASEBALLBAT)
|| GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE) {
if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR
|| GetWeapon(2).m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE)
m_nSelectedWepSlot = m_currentWeapon - 1;
else
m_nSelectedWepSlot = 2;
// BUG: m_nSelectedWepSlot is slot in VC but they compared against weapon types, lol.
for (; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) {
if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && GetWeapon(6).m_eWeaponType == WEAPONTYPE_BASEBALLBAT
|| GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0
/*&& m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE && m_nSelectedWepSlot != WEAPONTYPE_TEARGAS */) {
goto switchDetectDone;
}
}
m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
m_nSelectedWepSlot = 0;
}
}
}
@ -643,6 +706,7 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
switchDetectDone:
if (m_nSelectedWepSlot != m_currentWeapon) {
if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT)
RemoveWeaponAnims(m_currentWeapon, -1000.0f);
MakeChangesForNewWeapon(m_nSelectedWepSlot);
}
}
@ -934,6 +998,7 @@ CPlayerPed::FindWeaponLockOnTarget(void)
return true;
}
// --MIAMI: Done, but uncomment new weapon types when weapons got ported
void
CPlayerPed::ProcessAnimGroups(void)
{
@ -946,17 +1011,29 @@ CPlayerPed::ProcessAnimGroups(void)
if (m_fWalkAngle > 0.0f) {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
groupToSet = ASSOCGRP_ROCKETLEFT;
else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */
GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER
/* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/ )
groupToSet = ASSOCGRP_CHAINSAWLEFT;
else
groupToSet = ASSOCGRP_PLAYERLEFT;
} else {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
groupToSet = ASSOCGRP_ROCKETRIGHT;
else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */
GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER
/* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/)
groupToSet = ASSOCGRP_CHAINSAWRIGHT;
else
groupToSet = ASSOCGRP_PLAYERRIGHT;
}
} else {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
groupToSet = ASSOCGRP_ROCKETBACK;
else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */
GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER
/* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/)
groupToSet = ASSOCGRP_CHAINSAWBACK;
else
groupToSet = ASSOCGRP_PLAYERBACK;
}
@ -964,9 +1041,21 @@ CPlayerPed::ProcessAnimGroups(void)
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
groupToSet = ASSOCGRP_PLAYERROCKET;
} else {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT) {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT
/* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MACHETE */)
groupToSet = ASSOCGRP_PLAYERBBBAT;
} else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_COLT45 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UZI) {
else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */
GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER
/* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/)
groupToSet = ASSOCGRP_PLAYERCHAINSAW;
else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_COLT45 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UZI
// I hope this was inlined...
/*
&& GetWeapon()->m_eWeaponType != WEAPONTYPE_PYTHON*/ && GetWeapon()->m_eWeaponType != WEAPONTYPE_TEC9
&& GetWeapon()->m_eWeaponType != WEAPONTYPE_SILENCED_INGRAM && GetWeapon()->m_eWeaponType != WEAPONTYPE_MP5 /*
&& GetWeapon()->m_eWeaponType != WEAPONTYPE_GOLFCLUB && GetWeapon()->m_eWeaponType != WEAPONTYPE_KATANA
&& GetWeapon()->m_eWeaponType != WEAPONTYPE_CAMERA
*/) {
if (!GetWeapon()->IsType2Handed()) {
groupToSet = ASSOCGRP_PLAYER;
} else {
@ -1185,7 +1274,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);
if (doSmoothSpray) {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || GetWeapon()->m_eWeaponType == WEAPONTYPE_COLT45
|| GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI)
|| CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nWeaponSlot == 5)
m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 80.0f) * CTimer::GetTimeStep();
else
m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 128.0f) * CTimer::GetTimeStep();

View File

@ -18,22 +18,32 @@ public:
int8 m_nSelectedWepSlot; // eWeaponType
bool m_bSpeedTimerFlag;
uint8 m_nEvadeAmount;
int8 field_1367;
uint32 m_nSpeedTimer;
uint32 m_nHitAnimDelayTimer;
uint32 m_nSpeedTimer; // m_nStandStillTimer?
uint32 m_nHitAnimDelayTimer; // m_nShotDelay?
float m_fAttackButtonCounter;
bool m_bHaveTargetSelected; // may have better name
CEntity *m_pEvadingFrom; // is this CPhysical?
int32 m_nTargettableObjects[4];
uint32 m_nAdrenalineTime;
uint8 m_nDrunkenness; // Needed to work out whether we lost target this frame
uint8 m_nFadeDrunkenness;
uint8 m_nDrunkCountdown; //countdown in frames when the drunk effect ends
bool m_bAdrenalineActive;
bool m_bHasLockOnTarget;
uint32 m_nAdrenalineTime;
bool m_bCanBeDamaged;
int8 field_1413;
bool m_bDrunkVisualsWearOff; // TODO(Miami): That may be something else
CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree
CPed *m_pPedAtSafePos[6];
float m_fWalkAngle;
CPlayerPed* m_pCheckPlayers[6]; //checks something with players, could be a leftover from original multiplayer
char unused1;
int16 m_nCheckPlayersIndex;
float m_fWalkAngle; //angle between heading and walking direction
float m_fFPSMoveHeading;
RpAtomic* m_pMinigunTopAtomic; //atomic for the spinning part of the minigun model
float m_fGunSpinSpeed; // for minigun
float m_fGunSpinAngle;
unsigned int m_nPadDownPressedInMilliseconds;
unsigned int m_nPadUpPressedInMilliseconds;
CPlayerPed();
~CPlayerPed();
@ -45,7 +55,8 @@ public:
void SetWantedLevelNoDrop(int32 level);
void KeepAreaAroundPlayerClear(void);
void AnnoyPlayerPed(bool);
void MakeChangesForNewWeapon(int8);
void MakeChangesForNewWeapon(int32);
void MakeChangesForNewWeapon(eWeaponType);
void SetInitialState(void);
void ProcessControl(void);
void ClearAdrenaline(void);

View File

@ -471,9 +471,28 @@ CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors,
ped->SetOrientation(0.0f, 0.0f, 0.0f);
CWorld::Add(ped);
if (ms_bGivePedsWeapons) {
eWeaponType weapon = (eWeaponType)CGeneral::GetRandomNumberInRange(WEAPONTYPE_UNARMED, WEAPONTYPE_DETONATOR);
eWeaponType weapon;
// TODO(Miami): Look here when weapons have been ported
switch (CGeneral::GetRandomNumber() & 3) {
case 0:
weapon = WEAPONTYPE_COLT45;
break;
case 1:
//weapon = WEAPONTYPE_NIGHTSTICK;
//break;
case 2:
//weapon = WEAPONTYPE_GOLFCLUB;
//break;
case 3:
weapon = WEAPONTYPE_TEC9;
break;
default:
break;
}
if (weapon != WEAPONTYPE_UNARMED) {
ped->SetCurrentWeapon(ped->GiveWeapon(weapon, 25001));
ped->GiveDelayedWeapon(weapon, 25001);
ped->SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weapon)->m_nWeaponSlot);
}
}
return ped;
@ -501,12 +520,14 @@ CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors,
ped->SetOrientation(0.0f, 0.0f, 0.0f);
CWorld::Add(ped);
uint32 weapon;
eWeaponType weapon;
if (CGeneral::GetRandomNumberInRange(0, 100) >= 50)
weapon = ped->GiveWeapon((eWeaponType)CGangs::GetGangInfo(pedType - PEDTYPE_GANG1)->m_Weapon2, 25001);
weapon = (eWeaponType)CGangs::GetGangInfo(pedType - PEDTYPE_GANG1)->m_Weapon2;
else
weapon = ped->GiveWeapon((eWeaponType)CGangs::GetGangInfo(pedType - PEDTYPE_GANG1)->m_Weapon1, 25001);
ped->SetCurrentWeapon(weapon);
weapon = (eWeaponType)CGangs::GetGangInfo(pedType - PEDTYPE_GANG1)->m_Weapon1;
ped->GiveDelayedWeapon(weapon, 25001);
ped->SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weapon)->m_nWeaponSlot);
return ped;
}
case PEDTYPE_EMERGENCY:

View File

@ -258,9 +258,11 @@ void CHud::Draw()
/*
DrawAmmo
*/
uint32 AmmoAmount = CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition;
uint32 AmmoInClip = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_nAmmoInClip;
uint32 TotalAmmo = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_nAmmoTotal;
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType);
CWeapon *weapon = FindPlayerPed()->GetWeapon();
uint32 AmmoAmount = weaponInfo->m_nAmountofAmmunition;
uint32 AmmoInClip = weapon->m_nAmmoInClip;
uint32 TotalAmmo = weapon->m_nAmmoTotal;
uint32 Ammo, Clip;
if (AmmoAmount <= 1 || AmmoAmount >= 1000)
@ -291,6 +293,8 @@ void CHud::Draw()
/*
DrawWeaponIcon
*/
if (weaponInfo->m_nModelId <= 0) {
Sprites[WeaponType].Draw(
CRect(SCREEN_SCALE_FROM_RIGHT(99.0f), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(91.0f)),
CRGBA(255, 255, 255, 255),
@ -302,6 +306,23 @@ void CHud::Draw()
1.0f,
1.0f,
1.0f);
} else {
CBaseModelInfo *weaponModel = CModelInfo::GetModelInfo(weaponInfo->m_nModelId);
RwTexDictionary *weaponTxd = CTxdStore::GetSlot(weaponModel->GetTxdSlot())->texDict;
if (weaponTxd) {
RwTexture *weaponIcon = RwTexDictionaryFindNamedTexture(weaponTxd, weaponModel->GetName());
if (weaponIcon) {
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(weaponIcon));
const float xSize = SCREEN_SCALE_X(64.0f / 2.0f);
const float ySize = SCREEN_SCALE_X(64.0f / 2.0f);
CSprite::RenderOneXLUSprite(SCREEN_SCALE_FROM_RIGHT(99.0f) + xSize, SCREEN_SCALE_Y(25.0f) + ySize, 1.0f, xSize, ySize,
255, 255, 255, 255, 1.0f, 255);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
}
}
}
CFont::SetBackgroundOff();
CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f));
@ -311,9 +332,12 @@ void CHud::Draw()
CFont::SetPropOn();
CFont::SetFontStyle(FONT_BANK);
if (!CDarkel::FrenzyOnGoing() && WeaponType != WEAPONTYPE_UNARMED && WeaponType != WEAPONTYPE_BASEBALLBAT) {
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(66.0f), SCREEN_SCALE_Y(73.0f), sPrint);
if (!CDarkel::FrenzyOnGoing() && weaponInfo->m_nWeaponSlot > 1 && weapon->m_eWeaponType != WEAPONTYPE_DETONATOR) {
CFont::SetDropShadowPosition(2);
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetColor(CRGBA(255, 150, 225, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(66.0f), SCREEN_SCALE_Y(90.0f), sPrint);
CFont::SetDropShadowPosition(0);
}
/*
@ -394,10 +418,10 @@ void CHud::Draw()
DrawWantedLevel
*/
CFont::SetBackgroundOff();
CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(1.25f));
CFont::SetJustifyOff();
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
CFont::SetRightJustifyOn();
CFont::SetPropOn();
CFont::SetFontStyle(FONT_HEADING);
@ -405,13 +429,13 @@ void CHud::Draw()
for (int i = 0; i < 6; i++) {
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(2.0f + SCREEN_SCALE_FROM_RIGHT(60.0f - 2.0f + 24.0f * i), SCREEN_SCALE_Y(87.0f + 2.0f), sPrintIcon);
CFont::PrintString(2.0f + SCREEN_SCALE_FROM_RIGHT(110.0f - 2.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f + 2.0f), sPrintIcon);
if (FindPlayerPed()->m_pWanted->m_nWantedLevel > i
&& (CTimer::GetTimeInMilliseconds() > FindPlayerPed()->m_pWanted->m_nLastWantedLevelChange
+ 2000 || CTimer::GetFrameCounter() & 4)) {
CFont::SetColor(CRGBA(193, 164, 120, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(60.0f + 24.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon);
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon);
}
}

View File

@ -3,12 +3,14 @@
#include "RwHelper.h"
#include "Camera.h"
#include "MBlur.h"
#include "Timer.h"
// Originally taken from RW example 'mblur'
RwRaster *CMBlur::pFrontBuffer;
bool CMBlur::ms_bJustInitialised;
bool CMBlur::BlurOn;
float CMBlur::Drunkness;
static RwIm2DVertex Vertex[4];
static RwIm2DVertex Vertex2[4];
@ -281,3 +283,10 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type)
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}
void
CMBlur::ClearDrunkBlur()
{
Drunkness = 0.0f;
CTimer::SetTimeScale(1.0f);
}

View File

@ -6,6 +6,7 @@ public:
static RwRaster *pFrontBuffer;
static bool ms_bJustInitialised;
static bool BlurOn;
static float Drunkness;
public:
static void MotionBlurOpen(RwCamera *cam);
@ -13,4 +14,5 @@ public:
static void CreateImmediateModeData(RwCamera *cam, RwRect *rect);
static void MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type);
static void OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type);
static void ClearDrunkBlur();
};

View File

@ -3018,7 +3018,7 @@ CAutomobile::DoDriveByShootings(void)
{
CAnimBlendAssociation *anim;
CWeapon *weapon = pDriver->GetWeapon();
if(weapon->m_eWeaponType != WEAPONTYPE_UZI)
if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != 5)
return;
weapon->Update(pDriver->m_audioEntityId);

View File

@ -18,6 +18,7 @@
#include "Radar.h"
#include "Fire.h"
#include "Darkel.h"
#include "Streaming.h"
bool CVehicle::bWheelsOnlyCheat;
bool CVehicle::bAllDodosCheat;
@ -596,11 +597,14 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage
break;
case WEAPONTYPE_COLT45:
case WEAPONTYPE_UZI:
case WEAPONTYPE_TEC9:
case WEAPONTYPE_SILENCED_INGRAM:
case WEAPONTYPE_MP5:
case WEAPONTYPE_SHOTGUN:
case WEAPONTYPE_AK47:
case WEAPONTYPE_M16:
case WEAPONTYPE_SNIPERRIFLE:
case WEAPONTYPE_TOTAL_INVENTORY_WEAPONS:
case WEAPONTYPE_HELICANNON:
case WEAPONTYPE_UZI_DRIVEBY:
if (bBulletProof)
return;
@ -1078,9 +1082,10 @@ CVehicle::SetDriver(CPed *driver)
FindPlayerPed()->m_fHealth = Min(FindPlayerPed()->m_fHealth + 20.0f, 100.0f);
else if(GetModelIndex() == MI_TAXI)
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25;
else if(GetModelIndex() == MI_POLICE)
else if (GetModelIndex() == MI_POLICE) {
CStreaming::RequestModel(WEAPONTYPE_SHOTGUN, STREAMFLAGS_DONT_REMOVE);
driver->GiveWeapon(WEAPONTYPE_SHOTGUN, 5);
else if(GetModelIndex() == MI_ENFORCER)
} else if (GetModelIndex() == MI_ENFORCER)
driver->m_fArmour = Max(driver->m_fArmour, 100.0f);
else if(GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_ZEBRA) // TODO(MIAMI): check zebra
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25;

View File

@ -45,6 +45,7 @@ CProjectileInfo::GetProjectileInfo(int32 id)
return &gaProjectileInfo[id];
}
// --MIAMI: Mostly done
bool
CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos, float speed)
{
@ -58,10 +59,16 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
switch (weapon)
{
case WEAPONTYPE_ROCKETLAUNCHER:
case WEAPONTYPE_ROCKET:
{
float vy = 1.25f;
time = CTimer::GetTimeInMilliseconds() + 1400;
float vy = 0.35f;
time = CTimer::GetTimeInMilliseconds() + 2000;
if (entity->GetModelIndex() == MI_SPARROW || entity->GetModelIndex() == MI_HUNTER || entity->GetModelIndex() == MI_SENTINEL) {
matrix = ped->GetMatrix();
matrix.GetPosition() = pos;
CVector vecSpeed = ((CPhysical*)entity)->m_vecMoveSpeed;
vy += Max(0.0f, DotProduct(vecSpeed, entity->GetForward())) + Max(0.0f, DotProduct(vecSpeed, entity->GetUp()));
} else {
if (ped->IsPlayer()) {
matrix.GetForward() = TheCamera.Cams[TheCamera.ActiveCam].Front;
matrix.GetUp() = TheCamera.Cams[TheCamera.ActiveCam].Up;
@ -77,13 +84,11 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
} else {
matrix = ped->GetMatrix();
}
}
velocity = Multiply3x3(matrix, CVector(0.0f, vy, 0.0f));
gravity = false;
break;
}
case WEAPONTYPE_FLAMETHROWER:
Error("Undefined projectile type, AddProjectile, ProjectileInfo.cpp");
break;
case WEAPONTYPE_MOLOTOV:
{
time = CTimer::GetTimeInMilliseconds() + 2000;
@ -100,6 +105,7 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
break;
}
case WEAPONTYPE_GRENADE:
case WEAPONTYPE_DETONATOR_GRENADE:
{
time = CTimer::GetTimeInMilliseconds() + 2000;
float scale = 0.0f;
@ -116,7 +122,9 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
elasticity = 0.5f;
break;
}
default: break;
default:
Error("Undefined projectile type, AddProjectile, ProjectileInfo.cpp");
break;
}
int i = 0;
@ -127,7 +135,7 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
switch (weapon)
{
case WEAPONTYPE_ROCKETLAUNCHER:
case WEAPONTYPE_ROCKET:
ms_apProjectile[i] = new CProjectile(MI_MISSILE);
break;
case WEAPONTYPE_FLAMETHROWER:
@ -136,6 +144,7 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
ms_apProjectile[i] = new CProjectile(MI_MOLOTOV);
break;
case WEAPONTYPE_GRENADE:
case WEAPONTYPE_DETONATOR_GRENADE:
ms_apProjectile[i] = new CProjectile(MI_GRENADE);
break;
default: break;
@ -158,6 +167,10 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
CWorld::Add(ms_apProjectile[i]);
gaProjectileInfo[i].m_vecPos = ms_apProjectile[i]->GetPosition();
if (entity && entity->IsPed() && !ped->m_pCollidingEntity) {
ped->m_pCollidingEntity = ms_apProjectile[i];
}
return true;
}
@ -182,7 +195,7 @@ CProjectileInfo::RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector p
case WEAPONTYPE_MOLOTOV:
CExplosion::AddExplosion(nil, entity, EXPLOSION_MOLOTOV, pos, 0);
break;
case WEAPONTYPE_ROCKETLAUNCHER:
case WEAPONTYPE_ROCKET:
CExplosion::AddExplosion(nil, entity, EXPLOSION_ROCKET, pos, 0);
break;
default: break;
@ -204,17 +217,17 @@ CProjectileInfo::Update()
continue;
}
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET) {
CParticle::AddParticle(PARTICLE_SMOKE, ms_apProjectile[i]->GetPosition(), CVector(0.0f, 0.0f, 0.0f));
}
if (CTimer::GetTimeInMilliseconds() <= gaProjectileInfo[i].m_nExplosionTime) {
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET) {
CVector pos = ms_apProjectile[i]->GetPosition();
CWorld::pIgnoreEntity = ms_apProjectile[i];
if (ms_apProjectile[i]->bHasCollided
|| !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false)
|| gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) {
|| gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) {
RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
}
CWorld::pIgnoreEntity = nil;
@ -227,15 +240,26 @@ CProjectileInfo::Update()
{
if (ms_apProjectile[i]->bHasCollided
|| !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false)
|| gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) {
|| gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) {
RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
}
}
CWorld::pIgnoreEntity = nil;
}
} else {
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE) {
CEntity *ent = gaProjectileInfo[i].m_pSource;
if (ent->IsPed() && ((CPed*)ped)->IsPlayer()) {
CPed *ped = (CPed*)ent;
if (ped->GetWeapon(ped->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponType != WEAPONTYPE_DETONATOR
|| ped->GetWeapon(ped->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_nAmmoTotal == 0) {
gaProjectileInfo[i].m_nExplosionTime = 0;
}
}
} else {
RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
}
}
gaProjectileInfo[i].m_vecPos = ms_apProjectile[i]->GetPosition();
}
@ -247,7 +271,7 @@ CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, flo
bool result = false;
for (int i = 0; i < ARRAY_SIZE(ms_apProjectile); i++) {
if (gaProjectileInfo[i].m_bInUse) {
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_MOLOTOV || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_GRENADE) {
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_MOLOTOV || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_GRENADE) {
const CVector &pos = ms_apProjectile[i]->GetPosition();
if (pos.x >= x1 && pos.x <= x2 && pos.y >= y1 && pos.y <= y2 && pos.z >= z1 && pos.z <= z2) {
result = true;
@ -263,6 +287,20 @@ CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, flo
return result;
}
// --MIAMI: Done
void
CProjectileInfo::RemoveDetonatorProjectiles()
{
for (int i = 0; i < ARRAY_SIZE(ms_apProjectile); i++) {
if (gaProjectileInfo[i].m_bInUse && gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE) {
CExplosion::AddExplosion(nil, gaProjectileInfo[i].m_pSource, EXPLOSION_GRENADE, gaProjectileInfo[i].m_vecPos, 0); // TODO(Miami): New parameter (1)
gaProjectileInfo[i].m_bInUse = false;
CWorld::Remove(ms_apProjectile[i]);
delete ms_apProjectile[i];
}
}
}
void
CProjectileInfo::RemoveAllProjectiles()
{

View File

@ -26,6 +26,7 @@ public:
static void RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos);
static bool RemoveIfThisIsAProjectile(CObject *pObject);
static void RemoveAllProjectiles();
static void RemoveDetonatorProjectiles();
static void Update();
static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
};

View File

@ -35,7 +35,10 @@ uint16 gReloadSampleTime[WEAPONTYPE_LAST_WEAPONTYPE] =
0, // UNARMED
0, // BASEBALLBAT
250, // COLT45
400, // UZI
400, // TEC9
400, // UZIhec
400, // SILENCED_INGRAM
400, // MP5
650, // SHOTGUN
300, // AK47
300, // M16
@ -43,7 +46,9 @@ uint16 gReloadSampleTime[WEAPONTYPE_LAST_WEAPONTYPE] =
400, // ROCKETLAUNCHER
0, // FLAMETHROWER
0, // MOLOTOV
0, // ROCKET
0, // GRENADE
0, // DETONATEGRENADE
0, // DETONATOR
0 // HELICANNON
};
@ -85,6 +90,7 @@ CWeapon::UpdateWeapons(void)
CBulletInfo::Update();
}
// --MIAMI: Done
void
CWeapon::Initialise(eWeaponType type, int32 ammo)
{
@ -97,6 +103,32 @@ CWeapon::Initialise(eWeaponType type, int32 ammo)
m_nAmmoInClip = 0;
Reload();
m_nTimer = 0;
int modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
if (modelId != -1)
CModelInfo::GetModelInfo(modelId)->AddRef();
int model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
if (model2Id != -1)
CModelInfo::GetModelInfo(model2Id)->AddRef();
}
// --MIAMI: Done
void
CWeapon::Shutdown()
{
int modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
if (modelId != -1)
CModelInfo::GetModelInfo(modelId)->RemoveRef();
int model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
if (model2Id != -1)
CModelInfo::GetModelInfo(model2Id)->RemoveRef();
m_eWeaponType = WEAPONTYPE_UNARMED;
m_eWeaponState = WEAPONSTATE_READY;
m_nAmmoInClip = 0;
m_nAmmoTotal = 0;
m_nTimer = 0;
}
bool
@ -141,8 +173,19 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
case WEAPONTYPE_COLT45:
case WEAPONTYPE_UZI:
case WEAPONTYPE_TEC9:
case WEAPONTYPE_SILENCED_INGRAM:
case WEAPONTYPE_MP5:
case WEAPONTYPE_AK47:
case WEAPONTYPE_M16:
case WEAPONTYPE_HELICANNON:
{
if ((TheCamera.PlayerWeaponMode.Mode == CCam::MODE_HELICANNON_1STPERSON || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON)
&& shooter == FindPlayerPed())
{
fired = FireM16_1stPerson(shooter);
}
else
fired = FireInstantHit(shooter, source);
break;
@ -155,16 +198,6 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
break;
}
case WEAPONTYPE_M16:
{
if ( TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON && shooter == FindPlayerPed() )
fired = FireM16_1stPerson(shooter);
else
fired = FireInstantHit(shooter, source);
break;
}
case WEAPONTYPE_ROCKETLAUNCHER:
{
if ( shooter->IsPed() && ((CPed*)shooter)->m_pSeekTarget != nil )
@ -184,6 +217,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
case WEAPONTYPE_MOLOTOV:
case WEAPONTYPE_GRENADE:
case WEAPONTYPE_DETONATOR_GRENADE:
{
if ( shooter == FindPlayerPed() )
{
@ -201,6 +235,11 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
else
fired = FireProjectile(shooter, source, 0.3f);
if (m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE) {
((CPed*)shooter)->GiveWeapon(WEAPONTYPE_DETONATOR, 1, true);
((CPed*)shooter)->GetWeapon(((CPed*)shooter)->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY;
((CPed*)shooter)->SetCurrentWeapon(WEAPONTYPE_DETONATOR);
}
break;
}
@ -221,19 +260,6 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
break;
}
case WEAPONTYPE_HELICANNON:
{
if ( (TheCamera.PlayerWeaponMode.Mode == CCam::MODE_HELICANNON_1STPERSON || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON )
&& shooter == FindPlayerPed() )
{
fired = FireM16_1stPerson(shooter);
}
else
fired = FireInstantHit(shooter, source);
break;
}
default:
{
debug("Unknown weapon type, Weapon.cpp");
@ -343,6 +369,7 @@ CWeapon::FireFromCar(CAutomobile *shooter, bool left)
return true;
}
// --MIAMI: Just a few lines is done
bool
CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
{
@ -350,9 +377,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
CWeaponInfo *info = GetInfo();
bool anim2Playing = false;
if ( RpAnimBlendClumpGetAssociation(shooter->GetClump(), info->m_Anim2ToPlay) )
anim2Playing = true;
bool anim2Playing = RpAnimBlendClumpGetAssociation(shooter->GetClump(), CPed::GetFireAnimGround(info, false));
ASSERT(shooter->IsPed());
@ -739,6 +764,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
case WEAPONTYPE_UZI:
case WEAPONTYPE_TEC9:
case WEAPONTYPE_SILENCED_INGRAM:
case WEAPONTYPE_MP5:
{
CPointLights::AddLight(CPointLights::LIGHT_POINT,
*fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f,
@ -1387,10 +1415,12 @@ CWeapon::FireProjectile(CEntity *shooter, CVector *fireSource, float power)
ASSERT(fireSource!=nil);
CVector source, target;
eWeaponType projectileType = m_eWeaponType;
if ( m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER )
{
source = *fireSource;
projectileType = WEAPONTYPE_ROCKET;
if ( shooter->IsPed() && ((CPed*)shooter)->IsPlayer() )
{
@ -1432,7 +1462,7 @@ CWeapon::FireProjectile(CEntity *shooter, CVector *fireSource, float power)
if ( !CWorld::GetIsLineOfSightClear(source, target, true, true, false, true, false, false, false) )
{
if ( m_eWeaponType != WEAPONTYPE_GRENADE )
CProjectileInfo::RemoveNotAdd(shooter, m_eWeaponType, *fireSource);
CProjectileInfo::RemoveNotAdd(shooter, projectileType, *fireSource);
else
{
if ( shooter->IsPed() )
@ -1441,14 +1471,14 @@ CWeapon::FireProjectile(CEntity *shooter, CVector *fireSource, float power)
source.z -= 0.4f;
if ( !CWorld::TestSphereAgainstWorld(source, 0.5f, nil, false, false, true, false, false, false) )
CProjectileInfo::AddProjectile(shooter, m_eWeaponType, source, 0.0f);
CProjectileInfo::AddProjectile(shooter, WEAPONTYPE_GRENADE, source, 0.0f);
else
CProjectileInfo::RemoveNotAdd(shooter, m_eWeaponType, *fireSource);
CProjectileInfo::RemoveNotAdd(shooter, WEAPONTYPE_GRENADE, *fireSource);
}
}
}
else
CProjectileInfo::AddProjectile(shooter, m_eWeaponType, *fireSource, power);
CProjectileInfo::AddProjectile(shooter, projectileType, *fireSource, power);
return true;
}
@ -1555,6 +1585,7 @@ CWeapon::FireSniper(CEntity *shooter)
return true;
}
// --MIAMI: Heavily TODO
bool
CWeapon::FireM16_1stPerson(CEntity *shooter)
{
@ -1599,7 +1630,9 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
DoBulletImpact(shooter, victim, &source, &target, &point, front);
CVector bulletPos;
if ( CHeli::TestBulletCollision(&source, &target, &bulletPos, 4) )
// TODO(Miami): M60
if ( CHeli::TestBulletCollision(&source, &target, &bulletPos, (/*m_eWeaponType == WEAPONTYPE_M60 || */ m_eWeaponType == WEAPONTYPE_HELICANNON ? 20 : 4)) )
{
for ( int32 i = 0; i < 16; i++ )
CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f));
@ -1609,16 +1642,27 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
{
CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
if ( m_eWeaponType == WEAPONTYPE_M16 )
{
TheCamera.Cams[TheCamera.ActiveCam].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0003f;
TheCamera.Cams[TheCamera.ActiveCam].Alpha += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0003f;
}
else if ( m_eWeaponType == WEAPONTYPE_HELICANNON )
{
TheCamera.Cams[TheCamera.ActiveCam].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0001f;
TheCamera.Cams[TheCamera.ActiveCam].Alpha += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0001f;
// TODO(Miami)
float mult;
switch (m_eWeaponType) {
case WEAPONTYPE_M16: // case WEAPONTYPE_M4:
case WEAPONTYPE_HELICANNON:
// case WEAPONTYPE_M60:
mult = 0.0003f;
break;
case WEAPONTYPE_AK47: // case WEAPONTYPE_RUGER:
mult = 0.00015f;
break;
default:
mult = 0.0002f;
break;
}
if (FindPlayerPed()->bIsDucking || FindPlayerPed()->m_attachedTo)
mult *= 0.3f;
TheCamera.Cams[TheCamera.ActiveCam].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * mult;
TheCamera.Cams[TheCamera.ActiveCam].Alpha += float((CGeneral::GetRandomNumber() & 127) - 64) * mult;
}
return true;

View File

@ -32,6 +32,7 @@ public:
static void UpdateWeapons (void);
void Initialise(eWeaponType type, int32 ammo);
void Shutdown();
bool Fire (CEntity *shooter, CVector *fireSource);
bool FireFromCar (CAutomobile *shooter, bool left);

View File

@ -6,14 +6,25 @@
#include "AnimManager.h"
#include "AnimBlendAssociation.h"
#include "Weapon.h"
#include "ModelInfo.h"
#include "ModelIndices.h"
// Yeah...
int32 CWeaponInfo::ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
CWeaponInfo CWeaponInfo::ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
// --MIAMI: Todo
static char ms_aWeaponNames[][32] = {
"Unarmed",
"BaseballBat",
"Colt45",
"Tec9",
"Uzi",
"SilencedIngram",
"Mp5",
"Shotgun",
"AK47",
"M16",
@ -21,9 +32,11 @@ static char ms_aWeaponNames[][32] = {
"RocketLauncher",
"FlameThrower",
"Molotov",
"Rocket",
"Grenade",
"DetonateGrenade",
"Detonator",
"HeliCannon"
"HeliCannon",
};
CWeaponInfo*
@ -31,45 +44,62 @@ CWeaponInfo::GetWeaponInfo(eWeaponType weaponType) {
return &CWeaponInfo::ms_apWeaponInfos[weaponType];
}
// --MIAMI: done except WEAPONTYPE_TOTALWEAPONS value
void
CWeaponInfo::Initialise(void)
{
debug("Initialising CWeaponInfo...\n");
for (int i = 0; i < WEAPONTYPE_TOTALWEAPONS; i++) {
ms_apWeaponInfos[i].m_eWeaponFire = WEAPON_FIRE_INSTANT_HIT;
ms_apWeaponInfos[i].m_AnimToPlay = ANIM_PUNCH_R;
ms_apWeaponInfos[i].m_Anim2ToPlay = NUM_ANIMS;
ms_apWeaponInfos[i].m_fRange = 0.0f;
ms_apWeaponInfos[i].m_nFiringRate = 0;
ms_apWeaponInfos[i].m_nReload = 0;
ms_apWeaponInfos[i].m_nAmountofAmmunition = 0;
ms_apWeaponInfos[i].m_nDamage = 0;
ms_apWeaponInfos[i].m_fSpeed = 0.0f;
ms_apWeaponInfos[i].m_fRadius = 0.0f;
ms_apWeaponInfos[i].m_fLifespan = 0.0f;
ms_apWeaponInfos[i].m_fSpread = 0.0f;
ms_apWeaponInfos[i].m_vecFireOffset = CVector(0.0f, 0.0f, 0.0f);
// TODO(Miami): ASSOCGRP_UNARMED
ms_apWeaponInfos[i].m_AnimToPlay = ASSOCGRP_STD;
ms_apWeaponInfos[i].m_fAnimLoopStart = 0.0f;
ms_apWeaponInfos[i].m_fAnimLoopEnd = 0.0f;
ms_apWeaponInfos[i].m_fAnimFrameFire = 0.0f;
ms_apWeaponInfos[i].m_fAnim2LoopStart = 0.0f;
ms_apWeaponInfos[i].m_fAnim2LoopEnd = 0.0f;
ms_apWeaponInfos[i].m_fAnim2FrameFire = 0.0f;
ms_apWeaponInfos[i].m_fAnimBreakout = 0.0f;
ms_apWeaponInfos[i].m_bUseGravity = 1;
ms_apWeaponInfos[i].m_bSlowsDown = 1;
ms_apWeaponInfos[i].m_bRandSpeed = 1;
ms_apWeaponInfos[i].m_bExpands = 1;
ms_apWeaponInfos[i].m_bExplodes = 1;
ms_apWeaponInfos[i].m_nWeaponSlot = 0;
}
debug("Loading weapon data...\n");
LoadWeaponData();
debug("CWeaponInfo ready\n");
}
// --MIAMI: Done, commented parts wait for weapons port
void
CWeaponInfo::LoadWeaponData(void)
{
float spread, speed, lifeSpan, radius;
float range, fireOffsetX, fireOffsetY, fireOffsetZ;
float delayBetweenAnimAndFire, delayBetweenAnim2AndFire, animLoopStart, animLoopEnd;
float anim2LoopStart, anim2LoopEnd, delayBetweenAnim2AndFire, animBreakout;
float delayBetweenAnimAndFire, animLoopStart, animLoopEnd;
int flags, ammoAmount, damage, reload, weaponType;
int firingRate, modelId;
int firingRate, modelId, modelId2, weaponSlot;
char line[256], weaponName[32], fireType[32];
char animToPlay[32], anim2ToPlay[32];
CAnimBlendAssociation *animAssoc;
AnimationId animId;
char animToPlay[32];
int bp, buflen;
int lp, linelen;
CFileMgr::SetDir("DATA");
buflen = CFileMgr::LoadFile("WEAPON.DAT", work_buff, sizeof(work_buff), "r");
CFileMgr::SetDir("");
for (bp = 0; bp < buflen; ) {
// read file line by line
@ -101,10 +131,9 @@ CWeaponInfo::LoadWeaponData(void)
fireType[0] = '\0';
fireOffsetY = 0.0f;
fireOffsetZ = 0.0f;
animId = ANIM_WALK;
sscanf(
&line[lp],
"%s %s %f %d %d %d %d %f %f %f %f %f %f %f %s %s %f %f %f %f %d %d",
"%s %s %f %d %d %d %d %f %f %f %f %f %f %f %s %f %f %f %f %f %f %f %d %d %x %d",
weaponName,
fireType,
&range,
@ -120,27 +149,23 @@ CWeaponInfo::LoadWeaponData(void)
&fireOffsetY,
&fireOffsetZ,
animToPlay,
anim2ToPlay,
&animLoopStart,
&animLoopEnd,
&delayBetweenAnimAndFire,
&anim2LoopStart,
&anim2LoopEnd,
&delayBetweenAnim2AndFire,
&animBreakout,
&modelId,
&flags);
&modelId2,
&flags,
&weaponSlot);
if (strncmp(weaponName, "ENDWEAPONDATA", 13) == 0)
return;
weaponType = FindWeaponType(weaponName);
animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animToPlay);
animId = static_cast<AnimationId>(animAssoc->animId);
if (strncmp(anim2ToPlay, "null", 4) != 0) {
animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, anim2ToPlay);
ms_apWeaponInfos[weaponType].m_Anim2ToPlay = (AnimationId) animAssoc->animId;
}
CVector vecFireOffset(fireOffsetX, fireOffsetY, fireOffsetZ);
ms_apWeaponInfos[weaponType].m_eWeaponFire = FindWeaponFireType(fireType);
@ -154,12 +179,16 @@ CWeaponInfo::LoadWeaponData(void)
ms_apWeaponInfos[weaponType].m_fLifespan = lifeSpan;
ms_apWeaponInfos[weaponType].m_fSpread = spread;
ms_apWeaponInfos[weaponType].m_vecFireOffset = vecFireOffset;
ms_apWeaponInfos[weaponType].m_AnimToPlay = animId;
ms_apWeaponInfos[weaponType].m_fAnimLoopStart = animLoopStart / 30.0f;
ms_apWeaponInfos[weaponType].m_fAnimLoopEnd = animLoopEnd / 30.0f;
ms_apWeaponInfos[weaponType].m_fAnim2LoopStart = anim2LoopStart / 30.0f;
ms_apWeaponInfos[weaponType].m_fAnim2LoopEnd = anim2LoopEnd / 30.0f;
ms_apWeaponInfos[weaponType].m_fAnimFrameFire = delayBetweenAnimAndFire / 30.0f;
ms_apWeaponInfos[weaponType].m_fAnim2FrameFire = delayBetweenAnim2AndFire / 30.0f;
ms_apWeaponInfos[weaponType].m_fAnimBreakout = animBreakout / 30.0f;
ms_apWeaponInfos[weaponType].m_nModelId = modelId;
ms_apWeaponInfos[weaponType].m_nModel2Id = modelId2;
ms_apWeaponInfos[weaponType].m_bUseGravity = flags;
ms_apWeaponInfos[weaponType].m_bSlowsDown = flags >> 1;
ms_apWeaponInfos[weaponType].m_bDissipates = flags >> 2;
@ -171,6 +200,39 @@ CWeaponInfo::LoadWeaponData(void)
ms_apWeaponInfos[weaponType].m_b1stPerson = flags >> 8;
ms_apWeaponInfos[weaponType].m_bHeavy = flags >> 9;
ms_apWeaponInfos[weaponType].m_bThrow = flags >> 10;
ms_apWeaponInfos[weaponType].m_bReloadLoop2Start = flags >> 11;
ms_apWeaponInfos[weaponType].m_bUse2nd = flags >> 12;
ms_apWeaponInfos[weaponType].m_bGround2nd = flags >> 13;
ms_apWeaponInfos[weaponType].m_bFinish3rd = flags >> 14;
ms_apWeaponInfos[weaponType].m_bReload = flags >> 15;
ms_apWeaponInfos[weaponType].m_bFightMode = flags >> 16;
ms_apWeaponInfos[weaponType].m_bCrouchFire = flags >> 17;
ms_apWeaponInfos[weaponType].m_bCop3rd = flags >> 18;
ms_apWeaponInfos[weaponType].m_bGround3rd = flags >> 19;
ms_apWeaponInfos[weaponType].m_bPartialAttack = flags >> 20;
ms_apWeaponInfos[weaponType].m_bAnimDetonate = flags >> 21;
ms_apWeaponInfos[weaponType].m_nWeaponSlot = weaponSlot;
// TODO(Miami): Enable once weapons are done
if (animLoopEnd < 98.0f && weaponType != WEAPONTYPE_FLAMETHROWER && weaponType != WEAPONTYPE_SHOTGUN
/*&& weaponType != 20 && weaponType != 21*/)
ms_apWeaponInfos[weaponType].m_nFiringRate = ((ms_apWeaponInfos[weaponType].m_fAnimLoopEnd - ms_apWeaponInfos[weaponType].m_fAnimLoopStart) * 900.0f);
if (weaponType == WEAPONTYPE_DETONATOR || weaponType == WEAPONTYPE_HELICANNON)
modelId = -1;
else if (weaponType == WEAPONTYPE_DETONATOR_GRENADE)
modelId = MI_BOMB;
if (modelId != -1)
((CWeaponModelInfo*)CModelInfo::GetModelInfo(modelId))->SetWeaponInfo(weaponType);
for (int i = 0; i < NUM_ANIM_ASSOC_GROUPS; i++) {
if (!strcmp(animToPlay, CAnimManager::GetAnimGroupName((AssocGroupId)i))) {
ms_apWeaponInfos[weaponType].m_AnimToPlay = (AssocGroupId)i;
break;
}
}
}
}

View File

@ -3,10 +3,13 @@
#include "AnimationId.h"
#include "WeaponType.h"
enum AssocGroupId;
class CWeaponInfo {
// static CWeaponInfo(&ms_apWeaponInfos)[14];
static CWeaponInfo ms_apWeaponInfos[14];
static CWeaponInfo ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
public:
static int32 ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS];
eWeaponFire m_eWeaponFire;
float m_fRange;
uint32 m_nFiringRate;
@ -18,13 +21,16 @@ public:
float m_fLifespan;
float m_fSpread;
CVector m_vecFireOffset;
AnimationId m_AnimToPlay;
AnimationId m_Anim2ToPlay;
AssocGroupId m_AnimToPlay;
float m_fAnimLoopStart;
float m_fAnimLoopEnd;
float m_fAnimFrameFire;
float m_fAnim2LoopStart;
float m_fAnim2LoopEnd;
float m_fAnim2FrameFire;
float m_fAnimBreakout;
int32 m_nModelId;
int32 m_nModel2Id;
// flags
uint8 m_bUseGravity : 1;
uint8 m_bSlowsDown : 1;
@ -34,9 +40,24 @@ public:
uint8 m_bExplodes : 1;
uint8 m_bCanAim : 1;
uint8 m_bCanAimWithArm : 1;
uint8 m_b1stPerson : 1;
uint8 m_bHeavy : 1;
uint8 m_bThrow : 1;
uint8 m_bReloadLoop2Start : 1;
uint8 m_bUse2nd : 1;
uint8 m_bGround2nd : 1;
uint8 m_bFinish3rd : 1;
uint8 m_bReload : 1;
uint8 m_bFightMode : 1;
uint8 m_bCrouchFire : 1;
uint8 m_bCop3rd : 1;
uint8 m_bGround3rd : 1;
uint8 m_bPartialAttack : 1;
uint8 m_bAnimDetonate : 1;
uint32 m_nWeaponSlot;
static void Initialise(void);
static void LoadWeaponData(void);
@ -46,4 +67,4 @@ public:
static void Shutdown(void);
};
VALIDATE_SIZE(CWeaponInfo, 0x54);
VALIDATE_SIZE(CWeaponInfo, 0x64);

View File

@ -1,11 +1,15 @@
#pragma once
// --MIAMI: TODO
enum eWeaponType
{
WEAPONTYPE_UNARMED,
WEAPONTYPE_BASEBALLBAT,
WEAPONTYPE_COLT45,
WEAPONTYPE_TEC9,
WEAPONTYPE_UZI,
WEAPONTYPE_SILENCED_INGRAM,
WEAPONTYPE_MP5,
WEAPONTYPE_SHOTGUN,
WEAPONTYPE_AK47,
WEAPONTYPE_M16,
@ -13,7 +17,9 @@ enum eWeaponType
WEAPONTYPE_ROCKETLAUNCHER,
WEAPONTYPE_FLAMETHROWER,
WEAPONTYPE_MOLOTOV,
WEAPONTYPE_ROCKET,
WEAPONTYPE_GRENADE,
WEAPONTYPE_DETONATOR_GRENADE,
WEAPONTYPE_DETONATOR,
WEAPONTYPE_HELICANNON,
WEAPONTYPE_LAST_WEAPONTYPE,
@ -27,7 +33,10 @@ enum eWeaponType
WEAPONTYPE_UNIDENTIFIED,
WEAPONTYPE_TOTALWEAPONS = WEAPONTYPE_LAST_WEAPONTYPE,
WEAPONTYPE_TOTAL_INVENTORY_WEAPONS = 13,
};
enum {
TOTAL_WEAPON_SLOTS = 10,
};
enum eWeaponFire {