From 1fde2ba468ee88764620b8d01740e9504106c897 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 15 May 2020 19:41:44 +0200 Subject: [PATCH 1/2] CPedIK --- src/peds/Ped.cpp | 45 ++-- src/peds/Ped.h | 40 +--- src/peds/PedIK.cpp | 547 ++++++++++++++------------------------------- src/peds/PedIK.h | 14 +- 4 files changed, 203 insertions(+), 443 deletions(-) diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 8bfa6654..db2692ec 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -2522,40 +2522,23 @@ CPed::CalculateNewVelocity(void) if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc) { #endif LimbOrientation newUpperLegs; - newUpperLegs.phi = localWalkAngle; + newUpperLegs.yaw = localWalkAngle; - if (newUpperLegs.phi < -DEGTORAD(100.0f)) { - newUpperLegs.phi += PI; - } else if (newUpperLegs.phi > DEGTORAD(100.0f)) { - newUpperLegs.phi -= PI; + if (newUpperLegs.yaw < -DEGTORAD(100.0f)) { + newUpperLegs.yaw += PI; + } else if (newUpperLegs.yaw > DEGTORAD(100.0f)) { + newUpperLegs.yaw -= PI; } - if (newUpperLegs.phi > -DEGTORAD(50.0f) && newUpperLegs.phi < DEGTORAD(50.0f)) { -#ifdef PED_SKIN - if(IsClumpSkinned(GetClump())){ -/* - // this looks shit - newUpperLegs.theta = 0.0f; - RwV3d axis = { -1.0f, 0.0f, 0.0f }; - RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &axis, RADTODEG(newUpperLegs.phi), rwCOMBINEPRECONCAT); - RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &axis, RADTODEG(newUpperLegs.phi), rwCOMBINEPRECONCAT); -*/ - newUpperLegs.theta = 0.1f; - RwV3d Xaxis = { 1.0f, 0.0f, 0.0f }; - RwV3d Zaxis = { 0.0f, 0.0f, 1.0f }; - RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.theta), rwCOMBINEPOSTCONCAT); - RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.phi), rwCOMBINEPOSTCONCAT); - RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.theta), rwCOMBINEPOSTCONCAT); - RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.phi), rwCOMBINEPOSTCONCAT); - - bDontAcceptIKLookAts = true; - }else -#endif - { - newUpperLegs.theta = 0.0f; - m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGL], &newUpperLegs, false); - m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGR], &newUpperLegs, false); - } + if (newUpperLegs.yaw > -DEGTORAD(50.0f) && newUpperLegs.yaw < DEGTORAD(50.0f)) { + newUpperLegs.pitch = 0.1f; + RwV3d Xaxis = { 1.0f, 0.0f, 0.0f }; + RwV3d Zaxis = { 0.0f, 0.0f, 1.0f }; + RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.pitch), rwCOMBINEPOSTCONCAT); + RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.yaw), rwCOMBINEPOSTCONCAT); + RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.pitch), rwCOMBINEPOSTCONCAT); + RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.yaw), rwCOMBINEPOSTCONCAT); + bDontAcceptIKLookAts = true; } } } diff --git a/src/peds/Ped.h b/src/peds/Ped.h index ccffc3cb..573b74c1 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -833,39 +833,19 @@ public: // 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; - } + RwV3d pos = { 0.0f, 0.0f, 0.0f }; + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); + int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID); + RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier); + pos = mats[idx].pos; + return 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)); - } + RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); + int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID); + RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier); + RwV3dTransformPoints((RwV3d*)&pos, (RwV3d*)&pos, 1, &mats[idx]); } // set by 0482:set_threat_reaction_range_multiplier opcode diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp index 9dae5ff1..8b3835b3 100644 --- a/src/peds/PedIK.cpp +++ b/src/peds/PedIK.cpp @@ -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 - 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); - } + RtQuat *q = &node->hanimFrame->q; + RtQuatRotate(q, &XaxisIK, RADTODEG(limb->yaw), rwCOMBINEREPLACE); + RtQuatRotate(q, &ZaxisIK, RADTODEG(limb->pitch), rwCOMBINEPRECONCAT); + m_ped->bDontAcceptIKLookAts = true; } 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); - } - - // parent of head is torso - RwMatrix worldMat = *GetComponentMatrix(m_ped, PED_NECK); - ExtractYawAndPitchWorld(&worldMat, &yaw, &pitch); - - LimbMoveStatus headStatus = MoveLimb(m_headOrient, CGeneral::LimitRadianAngle(phi - yaw), - CGeneral::LimitRadianAngle(DEGTORAD(10.0f)), 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)) - success = true; - }else{ - RotateHead(); - return success; - } - } - - 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); - + if (!(m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION)) { + m_ped->m_pFrames[PED_HEAD]->flag |= AnimBlendFrameData::IGNORE_ROTATION; + 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 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, headYaw, headPitch, ms_headInfo); + if (headStatus == ANGLES_SET_TO_MAX) + success = false; + + 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; + + // 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); 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); - 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); - } - // + matrix = RwMatrixCreate(); + *matrix = *GetComponentMatrix(m_ped, PED_CLAVICLER); + 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); - 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; - } + RtQuat *q = &m_ped->m_pFrames[PED_UPPERARMR]->hanimFrame->q; + 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; + + 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,40 +304,24 @@ 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 { - ExtractYawAndPitchLocalSkinned(m_ped->m_pFrames[PED_HEAD], &yaw, &pitch); - 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; - } + if (m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION) { + m_ped->m_pFrames[PED_HEAD]->flag &= (~AnimBlendFrameData::IGNORE_ROTATION); + } else { + ExtractYawAndPitchLocalSkinned(m_ped->m_pFrames[PED_HEAD], &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); - } + 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 diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h index a1cb5d13..b5f895cd 100644 --- a/src/peds/PedIK.h +++ b/src/peds/PedIK.h @@ -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); }; From acd1ea9909da281acea6af8f0775e456a67d4a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Fri, 15 May 2020 17:30:25 +0300 Subject: [PATCH 2/2] Weapon layer in Peds --- src/animation/AnimBlendAssocGroup.cpp | 2 +- src/animation/AnimBlendAssociation.h | 1 + src/animation/AnimManager.cpp | 649 +++++++++--- src/animation/AnimManager.h | 31 +- src/animation/AnimationId.h | 167 +++- src/control/Script.cpp | 4 +- src/core/Cam.cpp | 14 - src/core/FileLoader.cpp | 4 +- src/core/Game.cpp | 1 + src/core/Pad.cpp | 29 +- src/core/Pools.cpp | 16 +- src/core/Streaming.cpp | 12 +- src/core/Streaming.h | 1 + src/core/World.cpp | 6 +- src/modelinfo/ModelIndices.h | 29 +- src/modelinfo/SimpleModelInfo.h | 3 +- src/modelinfo/WeaponModelInfo.h | 4 +- src/peds/CopPed.cpp | 19 +- src/peds/EmergencyPed.cpp | 2 +- src/peds/Ped.cpp | 1300 ++++++++++++++++--------- src/peds/Ped.h | 76 +- src/peds/PlayerPed.cpp | 177 +++- src/peds/PlayerPed.h | 25 +- src/peds/Population.cpp | 33 +- src/render/Hud.cpp | 66 +- src/render/MBlur.cpp | 9 + src/render/MBlur.h | 2 + src/vehicles/Automobile.cpp | 2 +- src/vehicles/Vehicle.cpp | 11 +- src/weapons/ProjectileInfo.cpp | 82 +- src/weapons/ProjectileInfo.h | 1 + src/weapons/Weapon.cpp | 128 ++- src/weapons/Weapon.h | 1 + src/weapons/WeaponInfo.cpp | 108 +- src/weapons/WeaponInfo.h | 31 +- src/weapons/WeaponType.h | 11 +- 36 files changed, 2182 insertions(+), 875 deletions(-) diff --git a/src/animation/AnimBlendAssocGroup.cpp b/src/animation/AnimBlendAssocGroup.cpp index c3d6b2c1..c5711fda 100644 --- a/src/animation/AnimBlendAssocGroup.cpp +++ b/src/animation/AnimBlendAssocGroup.cpp @@ -44,7 +44,7 @@ CAnimBlendAssocGroup::DestroyAssociations(void) CAnimBlendAssociation* CAnimBlendAssocGroup::GetAnimation(uint32 id) { - return &assocList[id]; + return &assocList[id - firstAnimId]; } CAnimBlendAssociation* diff --git a/src/animation/AnimBlendAssociation.h b/src/animation/AnimBlendAssociation.h index fe9b18e0..90e0cfd9 100644 --- a/src/animation/AnimBlendAssociation.h +++ b/src/animation/AnimBlendAssociation.h @@ -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 diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp index c6f84871..55bd7d53 100644 --- a/src/animation/AnimManager.cpp +++ b/src/animation/AnimManager.cpp @@ -35,26 +35,26 @@ AnimAssocDesc aStdAnimDescs[] = { { ANIM_IDLE_ARMED, ASSOC_REPEAT | ASSOC_PARTIAL }, { ANIM_IDLE_CHAT, ASSOC_REPEAT | ASSOC_PARTIAL }, { ANIM_IDLE_TAXI, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, - { ANIM_KO_SHOT_FRONT1, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, - { ANIM_KO_SHOT_FRONT2, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, - { ANIM_KO_SHOT_FRONT3, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, - { ANIM_KO_SHOT_FRONT4, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, - { ANIM_KO_SHOT_FACE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, + { ANIM_KO_SHOT_FRONT1, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, + { ANIM_KO_SHOT_FRONT2, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, + { ANIM_KO_SHOT_FRONT3, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, + { ANIM_KO_SHOT_FRONT4, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, + { ANIM_KO_SHOT_FACE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, { ANIM_KO_SHOT_STOM, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, - { ANIM_KO_SHOT_ARML, ASSOC_PARTIAL | ASSOC_FRONTAL }, - { ANIM_KO_SHOT_ARMR, ASSOC_PARTIAL | ASSOC_FRONTAL }, + { ANIM_KO_SHOT_ARML, ASSOC_PARTIAL | ASSOC_FRONTAL }, + { ANIM_KO_SHOT_ARMR, ASSOC_PARTIAL | ASSOC_FRONTAL }, { ANIM_KO_SHOT_LEGL, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, { ANIM_KO_SHOT_LEGR, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, - { ANIM_KD_LEFT, ASSOC_PARTIAL | ASSOC_FRONTAL }, - { ANIM_KD_RIGHT, ASSOC_PARTIAL | ASSOC_FRONTAL }, + { ANIM_KD_LEFT, ASSOC_PARTIAL | ASSOC_FRONTAL }, + { ANIM_KD_RIGHT, ASSOC_PARTIAL | ASSOC_FRONTAL }, { ANIM_KO_SKID_FRONT, ASSOC_PARTIAL }, { ANIM_KO_SPIN_R, ASSOC_PARTIAL }, - { ANIM_KO_SKID_BACK, ASSOC_PARTIAL | ASSOC_FRONTAL }, + { ANIM_KO_SKID_BACK, ASSOC_PARTIAL | ASSOC_FRONTAL }, { ANIM_KO_SPIN_L, ASSOC_PARTIAL }, - { ANIM_SHOT_FRONT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, - { ANIM_SHOT_LEFT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, - { ANIM_SHOT_BACK_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, - { ANIM_SHOT_RIGHT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, + { ANIM_SHOT_FRONT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, + { ANIM_SHOT_LEFT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, + { ANIM_SHOT_BACK_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, + { ANIM_SHOT_RIGHT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, { ANIM_HIT_FRONT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, { ANIM_HIT_LEFT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_HIT_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, @@ -65,29 +65,8 @@ AnimAssocDesc aStdAnimDescs[] = { { ANIM_HIT_HEAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, { ANIM_HIT_WALK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, { ANIM_HIT_WALL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, - { ANIM_FLOOR_HIT_F, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL }, + { 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 }, @@ -99,7 +78,18 @@ AnimAssocDesc aStdAnimDescs[] = { { ANIM_FIGHT_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { 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_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,33 +170,132 @@ 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 }, + { ANIM_EV_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL }, + { ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_FLAG_XPRESS }, { ANIM_ROAD_CROSS, ASSOC_REPEAT | ASSOC_PARTIAL }, { 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_FUCKU, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, + { 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); diff --git a/src/animation/AnimManager.h b/src/animation/AnimManager.h index 96239cda..905cac6c 100644 --- a/src/animation/AnimManager.h +++ b/src/animation/AnimManager.h @@ -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; diff --git a/src/animation/AnimationId.h b/src/animation/AnimationId.h index 37979ae0..9fe0cb0e 100644 --- a/src/animation/AnimationId.h +++ b/src/animation/AnimationId.h @@ -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 }; \ No newline at end of file diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 3bcfa745..8342ef46 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -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); } diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index b6d46580..afa153f9 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -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; diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index a78bf635..e073b4cb 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -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; } diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 9aea817e..b96c8988 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -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(); diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index f6685388..a40366ad 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -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() diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index 17b9e08d..6838ef8e 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -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; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 03a7757a..e854da59 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -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 diff --git a/src/core/Streaming.h b/src/core/Streaming.h index 22316ee1..8a92266f 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -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); diff --git a/src/core/World.cpp b/src/core/World.cpp index 493ce042..8c69d846 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -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,4 +2238,5 @@ CWorld::UseDetonator(CEntity *pEntity) pVehicle->m_pBlowUpEntity->RegisterReference(&pVehicle->m_pBlowUpEntity); } } + CProjectileInfo::RemoveDetonatorProjectiles(); } diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h index 7d3524d6..a21da7d3 100644 --- a/src/modelinfo/ModelIndices.h +++ b/src/modelinfo/ModelIndices.h @@ -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, diff --git a/src/modelinfo/SimpleModelInfo.h b/src/modelinfo/SimpleModelInfo.h index 55d6149c..986cb886 100644 --- a/src/modelinfo/SimpleModelInfo.h +++ b/src/modelinfo/SimpleModelInfo.h @@ -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); diff --git a/src/modelinfo/WeaponModelInfo.h b/src/modelinfo/WeaponModelInfo.h index 17e717db..5c690c29 100644 --- a/src/modelinfo/WeaponModelInfo.h +++ b/src/modelinfo/WeaponModelInfo.h @@ -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); }; diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp index 9e77ec72..1affb64d 100644 --- a/src/peds/CopPed.cpp +++ b/src/peds/CopPed.cpp @@ -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; diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp index 2cb36843..04e5dd6a 100644 --- a/src/peds/EmergencyPed.cpp +++ b/src/peds/EmergencyPed.cpp @@ -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); diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 8bfa6654..d03dbad5 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -57,6 +57,7 @@ #include "Timecycle.h" #include "ParticleObject.h" #include "Floater.h" +#include "Streaming.h" #define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f) @@ -635,7 +636,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_currentWeapon = WEAPONTYPE_UNARMED; m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; - for(int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) { + for(int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { CWeapon &weapon = GetWeapon(i); weapon.m_eWeaponType = WEAPONTYPE_UNARMED; weapon.m_eWeaponState = WEAPONSTATE_READY; @@ -657,27 +658,43 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) CPopulation::UpdatePedCount((ePedType)m_nPedType, false); } -uint32 -CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo) +// --MIAMI: Done +int32 +CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo, bool unused) { - CWeapon &weapon = GetWeapon(weaponType); + int slot = GetWeaponSlot(weaponType); - if (HasWeapon(weaponType)) { - if (weapon.m_nAmmoTotal + ammo > 99999) - weapon.m_nAmmoTotal = 99999; - else - weapon.m_nAmmoTotal += ammo; + if (m_weapons[slot].m_eWeaponType == weaponType) { + GetWeapon(slot).m_nAmmoTotal += ammo; + if (weaponType < WEAPONTYPE_LAST_WEAPONTYPE && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) { - weapon.Reload(); + // Looks like abandoned idea. This block never runs, ms_aMaxAmmoForWeapon is always -1. + GetWeapon(slot).m_nAmmoTotal = Min(CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType], (int32) GetWeapon(slot).m_nAmmoTotal); + } else { + GetWeapon(slot).m_nAmmoTotal = Min(99999, GetWeapon(slot).m_nAmmoTotal); + } + GetWeapon(slot).Reload(); + if (GetWeapon(slot).m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO && GetWeapon(slot).m_nAmmoTotal > 0) + GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY; } else { - weapon.Initialise(weaponType, ammo); - // TODO: It seems game uses this as both weapon count and max WeaponType we have, which is ofcourse erroneous. - m_maxWeaponTypeAllowed++; - } - if (weapon.m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO) - weapon.m_eWeaponState = WEAPONSTATE_READY; + if (HasWeaponSlot(slot)) { - return weaponType; + // TODO(Miami): Make an enum for that + if (slot == 4 || slot == 5 || slot == 6) + ammo += GetWeapon(slot).m_nAmmoTotal; + + RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(GetWeapon(slot).m_eWeaponType)->m_nModelId); + GetWeapon(slot).Shutdown(); + } + GetWeapon(slot).Initialise(weaponType, ammo); + if (slot == m_currentWeapon && !bInVehicle) { + AddWeaponModel(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nModelId); + } + } + if (GetWeapon(slot).m_eWeaponState != WEAPONSTATE_OUT_OF_AMMO) + GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY; + + return slot; } static RwObject* @@ -831,8 +848,12 @@ CPed::AddWeaponModel(int id) if (id != -1) { #ifdef PED_SKIN - if(IsClumpSkinned(GetClump())) + if (IsClumpSkinned(GetClump())) { + if (m_pWeaponModel) + RemoveWeaponModel(-1); + m_pWeaponModel = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance(); + } else #endif { @@ -841,7 +862,12 @@ CPed::AddWeaponModel(int id) RpAtomicSetFrame(atm, m_pFrames[PED_HANDR]->frame); RpClumpAddAtomic(GetClump(), atm); } + CModelInfo::GetModelInfo(id)->AddRef(); m_wepModelID = id; + + // TODO(Miami) + // if (IsPlayer() && id == MI_MINIGUN) + // ((CPlayerPed*)this)->m_pMinigunTopAtomic = (RpAtomic*)CModelInfo::GetModelInfo(MI_MINIGUN2)->CreateInstance(); } } @@ -1127,48 +1153,143 @@ CPed::IsPedHeadAbovePos(float zOffset) return zOffset + GetPosition().z < GetNodePosition(PED_HEAD).z; } +// --MIAMI: Done +void +CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg) +{ + CPed *ped = (CPed*)arg; + CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType); + + if (ped->DyingOrDead()) + return; + + if (ped->bIsDucking && ped->bCrouchWhenShooting) { + CAnimBlendAssociation *crouchFireAssoc = nil; + if (!!weapon->m_bCrouchFire) { + crouchFireAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_WEAPON_CROUCHFIRE); + } + if (!!weapon->m_bReload && reloadAssoc) { + if (reloadAssoc->animId == ANIM_WEAPON_CROUCHRELOAD && !crouchFireAssoc) { + CAnimBlendAssociation *crouchAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f); + crouchAssoc->SetCurrentTime(crouchAssoc->hierarchy->totalLength); + crouchAssoc->flags &= ~ASSOC_RUNNING; + } + } + } else if (weapon->m_bReloadLoop2Start && ped->bIsAttacking) { + CAnimBlendAssociation *fireAssoc = + CAnimManager::BlendAnimation(ped->GetClump(), weapon->m_AnimToPlay, weapon->m_bAnimDetonate ? ANIM_BOMBER : ANIM_WEAPON_FIRE, 8.0f); + fireAssoc->SetFinishCallback(FinishedAttackCB, ped); + fireAssoc->SetRun(); + if (fireAssoc->currentTime != reloadAssoc->hierarchy->totalLength) { + if (fireAssoc->currentTime >= weapon->m_fAnimLoopStart) + return; + + fireAssoc->SetCurrentTime(Max(weapon->m_fAnimLoopStart - 0.04f, 0.0f)); + } else { + fireAssoc->SetCurrentTime(Max(weapon->m_fAnimLoopStart - 0.04f, 0.0f)); + } + } +} + +// --MIAMI: Done void CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) { - CWeaponInfo *currentWeapon; - CAnimBlendAssociation *newAnim; + CAnimBlendAssociation *newAnim, *reloadAnimAssoc; CPed *ped = (CPed*)arg; + CWeaponInfo *currentWeapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType); - if (attackAssoc) { - switch (attackAssoc->animId) { - case ANIM_WEAPON_START_THROW: - // what?! - if ((!ped->IsPlayer() || ((CPlayerPed*)ped)->m_bHaveTargetSelected) && ped->IsPlayer()) { - attackAssoc->blendDelta = -1000.0f; - newAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_THROWU); - } else { - attackAssoc->blendDelta = -1000.0f; - newAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_THROW); + if (ped->m_nPedState != PED_ATTACK) { + if (ped->bIsDucking && ped->IsPedInControl()) { + if (currentWeapon->m_bReload) { + reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_WEAPON_CROUCHRELOAD); + } + if (currentWeapon->m_bCrouchFire && attackAssoc) { + if (attackAssoc->animId == ANIM_WEAPON_CROUCHFIRE && !reloadAnimAssoc) { + newAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f); + newAnim->SetCurrentTime(newAnim->hierarchy->totalLength); + newAnim->flags &= ~ASSOC_RUNNING; } - - newAnim->SetFinishCallback(FinishedAttackCB, ped); - return; - - case ANIM_FIGHT_PPUNCH: - attackAssoc->blendDelta = -8.0f; - attackAssoc->flags |= ASSOC_DELETEFADEDOUT; - ped->ClearAttack(); - return; - - case ANIM_WEAPON_THROW: - case ANIM_WEAPON_THROWU: - if (ped->GetWeapon()->m_nAmmoTotal > 0) { - currentWeapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType); - ped->AddWeaponModel(currentWeapon->m_nModelId); - } - break; - default: - break; + } } + return; + } + if (attackAssoc && attackAssoc->animId == ANIM_THROWABLE_START_THROW && currentWeapon->m_AnimToPlay == ASSOCGRP_THROW) { + if ((!ped->IsPlayer() || ((CPlayerPed*)ped)->m_bHaveTargetSelected) && ped->IsPlayer()) { + attackAssoc->blendDelta = -1000.0f; + newAnim = CAnimManager::AddAnimation(ped->GetClump(), currentWeapon->m_AnimToPlay, ANIM_THROWABLE_THROWU); + } else { + attackAssoc->blendDelta = -1000.0; + newAnim = CAnimManager::AddAnimation(ped->GetClump(), currentWeapon->m_AnimToPlay, ANIM_THROWABLE_THROW); + } + newAnim->SetFinishCallback(FinishedAttackCB, ped); + return; + } + + if (ped->bIsDucking && ped->bCrouchWhenShooting) { + if (currentWeapon->m_bReload) { + reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_WEAPON_CROUCHRELOAD); + } + if (currentWeapon->m_bCrouchFire && attackAssoc) { + if (attackAssoc->animId == ANIM_WEAPON_CROUCHFIRE && !reloadAnimAssoc) { + newAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f); + newAnim->SetCurrentTime(newAnim->hierarchy->totalLength); + newAnim->flags &= ~ASSOC_RUNNING; + } + } + + if (!ped->bIsAttacking) + ped->ClearAttack(); + + return; } - if (!ped->bIsAttacking) - ped->ClearAttack(); + // Not for unarmed, it's for weapons using unarmed anims + if (currentWeapon->m_bUse2nd && ped->bIsAttacking && currentWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) { + AnimationId groundAnim = GetFireAnimGround(currentWeapon); + CAnimBlendAssociation *groundAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), groundAnim); + if (!groundAnimAssoc || groundAnimAssoc->blendAmount <= 0.95f && groundAnimAssoc->blendDelta <= 0.0f) { + if (attackAssoc && attackAssoc->animId == ANIM_MELEE_ATTACK) { + newAnim = CAnimManager::BlendAnimation( + ped->GetClump(), currentWeapon->m_AnimToPlay, ANIM_MELEE_ATTACK_2ND, 8.0f); + } else { + newAnim = CAnimManager::BlendAnimation( + ped->GetClump(), currentWeapon->m_AnimToPlay, ANIM_MELEE_ATTACK, 8.0f); + } + newAnim->SetFinishCallback(FinishedAttackCB, ped); + } + } else { + // TODO(Miami): Remove this block when fighting has been ported + if (attackAssoc && attackAssoc->animId == ANIM_FIGHT_PPUNCH && currentWeapon->m_AnimToPlay == ASSOCGRP_STD) + { + attackAssoc->blendDelta = -8.0f; + attackAssoc->flags |= ASSOC_DELETEFADEDOUT; + ped->ClearAttack(); + return; + } + + if (attackAssoc && attackAssoc->animId == ANIM_MELEE_ATTACK && currentWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) + { + attackAssoc->blendDelta = -8.0f; + attackAssoc->flags |= ASSOC_DELETEFADEDOUT; + ped->ClearAttack(); + return; + } + if (attackAssoc) + { + if (currentWeapon->m_AnimToPlay == ASSOCGRP_THROW) + { + if ((attackAssoc->animId == ANIM_THROWABLE_THROW || attackAssoc->animId == ANIM_THROWABLE_THROWU) && ped->GetWeapon()->m_nAmmoTotal > 0) + { + ped->RemoveWeaponModel(currentWeapon->m_nModelId); + ped->AddWeaponModel(currentWeapon->m_nModelId); + } + } + } + + if (!ped->bIsAttacking) + ped->ClearAttack(); + } } void @@ -1176,7 +1297,6 @@ CPed::Attack(void) { CAnimBlendAssociation *weaponAnimAssoc; int32 weaponAnim; - float animStart; eWeaponType ourWeaponType; float weaponAnimTime; eWeaponFire ourWeaponFire; @@ -1185,58 +1305,132 @@ CPed::Attack(void) bool attackShouldContinue; AnimationId reloadAnim; CAnimBlendAssociation *reloadAnimAssoc; + CAnimBlendAssociation *throwAssoc; float delayBetweenAnimAndFire; + float animLoopStart; CVector firePos; ourWeaponType = GetWeapon()->m_eWeaponType; ourWeapon = CWeaponInfo::GetWeaponInfo(ourWeaponType); ourWeaponFire = ourWeapon->m_eWeaponFire; - weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ourWeapon->m_AnimToPlay); + weaponAnimAssoc = nil; attackShouldContinue = bIsAttacking; reloadAnimAssoc = nil; + throwAssoc = nil; reloadAnim = NUM_ANIMS; + animLoopStart = ourWeapon->m_fAnimLoopStart; + animLoopEnd = ourWeapon->m_fAnimLoopEnd; delayBetweenAnimAndFire = ourWeapon->m_fAnimFrameFire; weaponAnim = ourWeapon->m_AnimToPlay; - if (weaponAnim == ANIM_WEAPON_HGUN_BODY) - reloadAnim = ANIM_HGUN_RELOAD; - else if (weaponAnim == ANIM_WEAPON_AK_BODY) - reloadAnim = ANIM_AK_RELOAD; + if (bIsDucking) { + if (!!ourWeapon->m_bCrouchFire && bCrouchWhenShooting) { + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + if (weaponAnimAssoc) { + animLoopStart = ourWeapon->m_fAnim2LoopStart; + animLoopEnd = ourWeapon->m_fAnim2LoopEnd; + delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire; + } + } + } else { + AnimationId anim = GetFireAnimNotDucking(ourWeapon); + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), anim); + if (anim == ANIM_WEAPON_FIRE_3RD && weaponAnimAssoc) { + animLoopStart = 11.f/30.f; + animLoopEnd = 19.f/30.f; + delayBetweenAnimAndFire = 14.f/30.f; + } + } - if (reloadAnim != NUM_ANIMS) - reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), reloadAnim); + if (ourWeapon->m_bReload) { + reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD); + } - if (bIsDucking) - return; + if (!!ourWeapon->m_bReload && !reloadAnimAssoc) { + reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); + } - if (reloadAnimAssoc) { + if ( reloadAnimAssoc && reloadAnimAssoc->IsRunning() ) { if (!IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) ClearAttack(); - return; } - if (CTimer::GetTimeInMilliseconds() < m_shootTimer) + if ( reloadAnimAssoc ) { + reloadAnimAssoc->flags |= ASSOC_DELETEFADEDOUT; + if ( reloadAnimAssoc->blendDelta >= 0.0f ) + reloadAnimAssoc->blendDelta = -8.0f; + } + + if (!!ourWeapon->m_bThrow) { + throwAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_THROWABLE_START_THROW); + } + + if ( CTimer::GetTimeInMilliseconds() < m_shootTimer ) attackShouldContinue = true; - if (!weaponAnimAssoc) { - weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ourWeapon->m_Anim2ToPlay); - delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire; + bool meleeAttackStarted = false; + if ( !weaponAnimAssoc ) { + if (!!ourWeapon->m_bPartialAttack) { + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_ATTACK_START); + if ( weaponAnimAssoc ) { + if ( IsPlayer() ) + meleeAttackStarted = true; - // Long throw granade, molotov - if (!weaponAnimAssoc && ourWeapon->m_bThrow) { - weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_THROWU); - delayBetweenAnimAndFire = 0.2f; + switch ( ourWeapon->m_AnimToPlay ) { + case ASSOCGRP_STD: // TODO(Miami): Remove that when weapons ported + case ASSOCGRP_UNARMED: + case ASSOCGRP_SCREWDRIVER: + case ASSOCGRP_KNIFE: + case ASSOCGRP_BASEBALLBAT: + case ASSOCGRP_GOLFCLUB: + case ASSOCGRP_CHAINSAW: + delayBetweenAnimAndFire = 0.2f; + animLoopStart = 0.1f; + break; + default: + break; + } + animLoopEnd = 99.9f; + } } + } + if (!weaponAnimAssoc) { + if (!!ourWeapon->m_bUse2nd) { + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE_2ND); + if (weaponAnimAssoc) { + animLoopStart = ourWeapon->m_fAnim2LoopStart; + animLoopEnd = ourWeapon->m_fAnim2LoopEnd; + delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire; + } + } + } + if (!weaponAnimAssoc) { + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(ourWeapon)); + if (weaponAnimAssoc) { + animLoopStart = ourWeapon->m_fAnim2LoopStart; + animLoopEnd = ourWeapon->m_fAnim2LoopEnd; + delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire; + } + } - if (!weaponAnimAssoc) { + if (!weaponAnimAssoc) { + if (!throwAssoc) { if (attackShouldContinue) { if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) { - if (!CGame::nastyGame || ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) { - weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f); - } - else { - weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f); + if (bCrouchWhenShooting && bIsDucking && !!ourWeapon->m_bCrouchFire) { + weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, ANIM_WEAPON_CROUCHFIRE, 8.0f); + + } else if(!!ourWeapon->m_bUse2nd && CGeneral::GetRandomNumber() & 1){ + weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE_2ND, 8.0f); + + } else if (!CGame::nastyGame || (!ourWeapon->m_bGround2nd && !ourWeapon->m_bGround3rd) || + ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) { + + weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetFireAnimNotDucking(ourWeapon), 8.0f); + + } else { + weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetFireAnimGround(ourWeapon, false), 8.0f); } weaponAnimAssoc->SetFinishCallback(CPed::FinishedAttackCB, this); @@ -1253,66 +1447,79 @@ CPed::Attack(void) } else FinishedAttackCB(nil, this); - return; + } + return; + } + + if (meleeAttackStarted && IsPlayer()) { + if (((CPlayerPed*)this)->m_bHaveTargetSelected || ((CPlayerPed*)this)->m_fMoveSpeed < 0.5f) { + weaponAnimAssoc->SetRun(); + } else { + if (weaponAnimAssoc->currentTime > animLoopStart && weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep <= animLoopStart) + weaponAnimAssoc->flags &= ~ASSOC_RUNNING; } } - animStart = ourWeapon->m_fAnimLoopStart; + float animStart = ourWeapon->m_fAnimLoopStart * 0.4f; weaponAnimTime = weaponAnimAssoc->currentTime; if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) { - if (ourWeapon->m_bCanAimWithArm) + if (!bIsDucking && !(m_nPedType == PEDTYPE_COP && ourWeapon->m_bCop3rd && weaponAnimAssoc->animId == ANIM_WEAPON_FIRE_3RD) && ourWeapon->m_bCanAimWithArm) m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM; else m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; } + // TODO(Miami): Chainsaw if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) { if (weaponAnimAssoc->speed < 1.0f) weaponAnimAssoc->speed = 1.0f; } else { firePos = ourWeapon->m_vecFireOffset; - if (ourWeaponType == WEAPONTYPE_BASEBALLBAT) { - if (weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay) - firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f; + // TODO(Miami): Katana & Chainsaw + if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE) { firePos = GetMatrix() * firePos; - } else if (ourWeaponType != WEAPONTYPE_UNARMED) { - TransformToNode(firePos, weaponAnimAssoc->animId == ANIM_KICK_FLOOR ? PED_FOOTR : PED_HANDR); } else { - firePos = GetMatrix() * firePos; + // TODO(Miami): Remove ANIM_KICK_FLOOR when fighting is done + TransformToNode(firePos, (weaponAnimAssoc->animId == ANIM_KICK_FLOOR || + weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND && ourWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) ? PED_FOOTR : PED_HANDR); } GetWeapon()->Fire(this, &firePos); - if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE) { + // TODO(Miami) + if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE + /* ourWeaponType == WEAPONTYPE_TEARGAS*/) { RemoveWeaponModel(ourWeapon->m_nModelId); } if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) { SelectGunIfArmed(); } - if (GetWeapon()->m_eWeaponState != WEAPONSTATE_MELEE_MADECONTACT) { - // If reloading just began, start the animation - // Last condition will always return true, even IDA hides it - if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING && reloadAnim != NUM_ANIMS /* && !reloadAnimAssoc*/) { - CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, reloadAnim, 8.0f); - ClearLookFlag(); - ClearAimFlag(); - bIsAttacking = false; - bIsPointingGunAt = false; - m_shootTimer = CTimer::GetTimeInMilliseconds(); - return; + if (GetWeapon()->m_eWeaponState == WEAPONSTATE_MELEE_MADECONTACT) { + int damagerType = 0; + if (m_pDamageEntity && (m_fDamageImpulse == 0.0f || !m_pDamageEntity->IsBuilding())) { + damagerType = m_pDamageEntity->GetType(); } - } else { - if (weaponAnimAssoc->animId == ANIM_WEAPON_BAT_V || weaponAnimAssoc->animId == ANIM_WEAPON_BAT_H) { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f); - } else if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH) { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f); + switch (ourWeapon->m_AnimToPlay) { + case ASSOCGRP_STD: // TODO(Miami): Remove after fighting done + case ASSOCGRP_UNARMED: + if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH || // TODO(Miami): Remove after fighting done + weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) { + DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, (damagerType | (ourWeaponType << 8))); + } + break; + case ASSOCGRP_KNIFE: + case ASSOCGRP_BASEBALLBAT: + case ASSOCGRP_GOLFCLUB: + case ASSOCGRP_CHAINSAW: + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8))); + break; + default: + break; } - weaponAnimAssoc->speed = 0.5f; - if (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) { weaponAnimAssoc->callbackType = 0; } @@ -1321,10 +1528,11 @@ CPed::Attack(void) attackShouldContinue = false; } - if (ourWeaponType == WEAPONTYPE_SHOTGUN) { + if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT && ourWeapon->m_AnimToPlay == ASSOCGRP_SHOTGUN) { weaponAnimTime = weaponAnimAssoc->currentTime; firePos = ourWeapon->m_vecFireOffset; + //TODO(Miami): Check if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) { TransformToNode(firePos, PED_HANDR); @@ -1343,85 +1551,112 @@ CPed::Attack(void) GetWeapon()->AddGunshell(this, gunshellPos, gunshellRot, 0.025f); } } -#ifdef VC_PED_PORTS + + // TODO(Miami): CSpecialFX::AddWeaponStreak + + // Anim breakout on running if (IsPlayer()) { if (CPad::GetPad(0)->GetSprint()) { - // animBreakout is a member of WeaponInfo in VC, so it's me that added the below line. - float animBreakOut = ((ourWeaponType == WEAPONTYPE_FLAMETHROWER || ourWeaponType == WEAPONTYPE_UZI || ourWeaponType == WEAPONTYPE_SHOTGUN) ? 25 / 30.0f : 99 / 30.0f); - if (!attackShouldContinue && weaponAnimAssoc->currentTime > animBreakOut) { + if (!attackShouldContinue && weaponAnimAssoc->currentTime > ourWeapon->m_fAnimBreakout) { weaponAnimAssoc->blendDelta = -4.0f; FinishedAttackCB(nil, this); return; } } } -#endif - animLoopEnd = ourWeapon->m_fAnimLoopEnd; - if (ourWeaponFire == WEAPON_FIRE_MELEE && weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay) - animLoopEnd = 3.4f/6.0f; weaponAnimTime = weaponAnimAssoc->currentTime; // Anim loop end, either start the loop again or finish the attack if (weaponAnimTime > animLoopEnd || !weaponAnimAssoc->IsRunning() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) { - - if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd - && (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) - && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) { - - weaponAnim = weaponAnimAssoc->animId; - if (ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) { - if (weaponAnim != ourWeapon->m_Anim2ToPlay || weaponAnim == ANIM_RBLOCK_CSHOOT) { - weaponAnimAssoc->Start(ourWeapon->m_fAnimLoopStart); - } else { - CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f); + if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING) { + if (ourWeapon->m_bReload && !reloadAnimAssoc) { + if (!CWorld::Players[CWorld::PlayerInFocus].m_bFastReload) { + CAnimBlendAssociation *newReloadAssoc; + if (bIsDucking) { + newReloadAssoc = CAnimManager::BlendAnimation( + GetClump(), ourWeapon->m_AnimToPlay, + ANIM_WEAPON_CROUCHRELOAD, + 8.0f); + } else { + newReloadAssoc = CAnimManager::BlendAnimation( + GetClump(), ourWeapon->m_AnimToPlay, + ANIM_WEAPON_RELOAD, + 8.0f); + } + newReloadAssoc->SetFinishCallback(FinishedReloadCB, this); } - } else { - if (weaponAnim == ourWeapon->m_Anim2ToPlay) - weaponAnimAssoc->SetCurrentTime(0.1f); - else - CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f); - } -#ifdef VC_PED_PORTS - } else if (IsPlayer() && m_pPointGunAt && bIsAimingGun && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) { - weaponAnimAssoc->SetCurrentTime(ourWeapon->m_fAnimLoopEnd); - weaponAnimAssoc->flags &= ~ASSOC_RUNNING; - SetPointGunAt(m_pPointGunAt); -#endif - } else { - ClearAimFlag(); - - // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading) - if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep <= ourWeapon->m_fAnimLoopEnd) { - switch (ourWeaponType) { - case WEAPONTYPE_UZI: - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f); - break; - case WEAPONTYPE_AK47: - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f); - break; - case WEAPONTYPE_M16: - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f); - break; - default: - break; - } - } - - // Fun fact: removing this part leds to reloading flamethrower - if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) { - weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT; - weaponAnimAssoc->flags &= ~ASSOC_RUNNING; - weaponAnimAssoc->blendDelta = -4.0f; + ClearLookFlag(); + ClearAimFlag(); + bIsAttacking = false; + bIsPointingGunAt = false; + m_shootTimer = CTimer::GetTimeInMilliseconds(); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType); + return; } } + if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd + && (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) + && (GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING + /* || GetWeapon()->m_nWeaponType == WEAPONTYPE_MINIGUN */)) { + + PedOnGroundState pedOnGroundState; + if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE && + (CGame::nastyGame && ((pedOnGroundState = CheckForPedsOnGroundToAttack(this, nil)) > PED_IN_FRONT_OF_ATTACKER) + || GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) { + + AnimationId fireAnim = GetFireAnimGround(ourWeapon, false); + if (weaponAnimAssoc->animId == fireAnim) + weaponAnimAssoc->SetCurrentTime(0.1f); + else { + if (fireAnim) { + weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, fireAnim, 8.0f); + } else { + weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_KICK_FLOOR, 8.0f); + } + } + weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this); + } else if (!!ourWeapon->m_bUse2nd) { + if (weaponAnimAssoc->animId == ANIM_WEAPON_FIRE_2ND) { + weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE, 8.0f); + } else { + weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE_2ND, 8.0f); + } + weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this); + } else { + weaponAnimAssoc->SetCurrentTime(animLoopStart); + weaponAnimAssoc->SetRun(); + } + } + } else if (IsPlayer() && m_pPointGunAt && bIsAimingGun && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) { + weaponAnimAssoc->SetCurrentTime(animLoopEnd); + weaponAnimAssoc->flags &= ~ASSOC_RUNNING; + SetPointGunAt(m_pPointGunAt); + } else { + ClearAimFlag(); + + // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading) + if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < ourWeapon->m_fAnimLoopEnd) { + + // What?! Weapon id as volume?? + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType); + } + + // Fun fact: removing this part leds to reloading flamethrower + if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) { + weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT; + weaponAnimAssoc->flags &= ~ASSOC_RUNNING; + weaponAnimAssoc->blendDelta = -4.0f; + } } + if (weaponAnimAssoc->currentTime > delayBetweenAnimAndFire) attackShouldContinue = false; bIsAttacking = attackShouldContinue; } +// --MIAMI: Done void CPed::RemoveWeaponModel(int modelId) { @@ -1429,32 +1664,63 @@ CPed::RemoveWeaponModel(int modelId) #ifdef PED_SKIN if(IsClumpSkinned(GetClump())){ if(m_pWeaponModel){ - RwFrame *frm = RpAtomicGetFrame(m_pWeaponModel); - RpAtomicDestroy(m_pWeaponModel); - RwFrameDestroy(frm); - m_pWeaponModel = nil; + if (modelId == -1 + || CVisibilityPlugins::GetAtomicModelInfo(m_pWeaponModel) == CModelInfo::GetModelInfo(modelId)) { + CVisibilityPlugins::GetAtomicModelInfo(m_pWeaponModel)->RemoveRef(); + RwFrame* frm = RpAtomicGetFrame(m_pWeaponModel); + RpAtomicDestroy(m_pWeaponModel); + RwFrameDestroy(frm); + m_pWeaponModel = nil; + } } }else #endif RwFrameForAllObjects(m_pFrames[PED_HANDR]->frame,RemoveAllModelCB,nil); + + // TODO(Miami): Minigun + if (IsPlayer() && (modelId == -1 /* || modelId == MI_MINIGUN)*/)) { + RpAtomic* &atm = ((CPlayerPed*)this)->m_pMinigunTopAtomic; + if (atm) { + RwFrame *frm = RpAtomicGetFrame(atm); + RpAtomicDestroy(atm); + RwFrameDestroy(frm); + atm = nil; + } + } m_wepModelID = -1; } +// --MIAMI: Done void -CPed::SetCurrentWeapon(uint32 weaponType) +CPed::SetCurrentWeapon(eWeaponType weaponType) { - CWeaponInfo *weaponInfo; - if (HasWeapon(weaponType)) { + SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot); +} + +// --MIAMI: Done +void +CPed::SetCurrentWeapon(int slot) +{ + if (slot == -1) + return; + + CWeaponInfo* weaponInfo; + if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) { weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); RemoveWeaponModel(weaponInfo->m_nModelId); + } + m_currentWeapon = slot; - m_currentWeapon = weaponType; + if (FindPlayerPed() && IsPlayer()) + ((CPlayerPed*)this)->m_nSelectedWepSlot = m_currentWeapon; + if (HasWeaponSlot(slot)) { weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); AddWeaponModel(weaponInfo->m_nModelId); } } +// --MIAMI: TODO when weapons got converted // Only used while deciding which gun ped should switch to, if no ammo left. bool CPed::SelectGunIfArmed(void) @@ -1504,6 +1770,7 @@ CPed::ClearDuck(void) } } +// --MIAMI: Done except commented thing void CPed::ClearPointGunAt(void) { @@ -1513,27 +1780,24 @@ CPed::ClearPointGunAt(void) ClearLookFlag(); ClearAimFlag(); bIsPointingGunAt = false; -#ifndef VC_PED_PORTS - if (m_nPedState == PED_AIM_GUN) { - RestorePreviousState(); -#else if (m_nPedState == PED_AIM_GUN || m_nPedState == PED_ATTACK) { + + if (m_nPedState == PED_FOLLOW_PATH) + ClearFollowPath(); m_nPedState = PED_IDLE; RestorePreviousState(); } -#endif - weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weaponInfo->m_AnimToPlay); - if (!animAssoc || animAssoc->blendDelta < 0.0f) { - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weaponInfo->m_Anim2ToPlay); + weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); + if (!animAssoc || animAssoc->blendDelta < 0.0f) { + if (!!weaponInfo->m_bCrouchFire) { + animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); } - if (animAssoc) { - animAssoc->flags |= ASSOC_DELETEFADEDOUT; - animAssoc->blendDelta = -4.0f; - } -#ifndef VC_PED_PORTS } -#endif + if (animAssoc) { + animAssoc->flags |= ASSOC_DELETEFADEDOUT; + animAssoc->blendDelta = -4.0f; + } } void @@ -3609,29 +3873,45 @@ CPed::ClearAttack(void) } } +// --MIAMI: Done void CPed::ClearAttackByRemovingAnim(void) { - if (m_nPedState != PED_ATTACK || bIsDucking) + if (m_nPedState != PED_ATTACK) return; CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weapon->m_AnimToPlay); + CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weapon->m_bAnimDetonate ? ANIM_BOMBER : ANIM_WEAPON_FIRE); + + // TODO(Miami): Remove when fighting got ported if (!weaponAssoc) { - weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weapon->m_Anim2ToPlay); - - if (!weaponAssoc && weapon->m_bThrow) - weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_THROWU); - - if (!weaponAssoc) { - ClearAttack(); - return; - } + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_PPUNCH); + } + + if (!weaponAssoc) { + if (!!weapon->m_bCrouchFire) + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + } + if (!weaponAssoc) { + if(!!weapon->m_bFinish3rd) + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_SPECIAL); + } + if (!weaponAssoc) { + if(!!weapon->m_bUse2nd) + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + } + if (!weaponAssoc) { + if(!!weapon->m_bCop3rd) + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_SPECIAL); + } + if (weaponAssoc) { + weaponAssoc->blendDelta = -8.0f; + weaponAssoc->flags &= ~ASSOC_RUNNING; + weaponAssoc->flags |= ASSOC_DELETEFADEDOUT; + weaponAssoc->SetDeleteCallback(FinishedAttackCB, this); + } else { + ClearAttack(); } - weaponAssoc->blendDelta = -8.0f; - weaponAssoc->flags &= ~ASSOC_RUNNING; - weaponAssoc->flags |= ASSOC_DELETEFADEDOUT; - weaponAssoc->SetDeleteCallback(FinishedAttackCB, this); } void @@ -3885,6 +4165,9 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi 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: @@ -4254,7 +4537,7 @@ CPed::SetGetUp(void) if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE || collidingVeh && collidingVeh->IsVehicle() && collidingVeh->m_vehType != VEHICLE_TYPE_BIKE && ((uint8)(CTimer::GetFrameCounter() + m_randomSeed + 5) % 8 || - CCollision::ProcessColModels(GetMatrix(), *GetColModel(), collidingVeh->GetMatrix(), *collidingVeh->GetColModel(), + CCollision::ProcessColModels(GetMatrix(), *GetColModel(), collidingVeh->GetMatrix(), *collidingVeh->GetColModel(), aTempPedColPts, nil, nil) > 0)) { bGetUpAnimStarted = false; @@ -4433,25 +4716,15 @@ CPed::SetWanderPath(int8 pathStateDest) } } +// --MIAMI: Done void CPed::ClearWeapons(void) { - CWeaponInfo *currentWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - RemoveWeaponModel(currentWeapon->m_nModelId); - - m_maxWeaponTypeAllowed = WEAPONTYPE_BASEBALLBAT; - m_currentWeapon = WEAPONTYPE_UNARMED; - - currentWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - AddWeaponModel(currentWeapon->m_nModelId); - for(int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) { - CWeapon &weapon = GetWeapon(i); - weapon.m_eWeaponType = WEAPONTYPE_UNARMED; - weapon.m_eWeaponState = WEAPONSTATE_READY; - weapon.m_nAmmoInClip = 0; - weapon.m_nAmmoTotal = 0; - weapon.m_nTimer = 0; + RemoveWeaponModel(-1); + for (int i = 0; i < ARRAY_SIZE(m_weapons); i++) { + GetWeapon(i).Shutdown(); } + SetCurrentWeapon(WEAPONTYPE_UNARMED); } void @@ -4556,68 +4829,100 @@ CPed::SetAimFlag(float angle) m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; } +// --MIAMI: Done void CPed::SetPointGunAt(CEntity *to) { if (to) { SetLookFlag(to, true); SetAimFlag(to); -#ifdef VC_PED_PORTS SetLookTimer(INT32_MAX); -#endif } - if (m_nPedState == PED_AIM_GUN || bIsDucking || m_nWaitState == WAITSTATE_PLAYANIM_DUCK) + CWeaponInfo* curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + if (m_nPedState == PED_AIM_GUN || (bIsDucking && !IsPlayer()) || m_nWaitState == WAITSTATE_PLAYANIM_DUCK || curWeapon->m_AnimToPlay == ASSOCGRP_STD) return; if (m_nPedState != PED_ATTACK) SetStoredState(); + if (m_nPedState == PED_FOLLOW_PATH) + ClearFollowPath(); + m_nPedState = PED_AIM_GUN; bIsPointingGunAt = true; - CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); SetMoveState(PEDMOVE_NONE); CAnimBlendAssociation *aimAssoc; - if (bCrouchWhenShooting) - aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), curWeapon->m_Anim2ToPlay); - else - aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), curWeapon->m_AnimToPlay); + if (bCrouchWhenShooting && bIsDucking) { + if (!!curWeapon->m_bCrouchFire) { + aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + } + } else { + aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); + } if (!aimAssoc || aimAssoc->blendDelta < 0.0f) { - if (bCrouchWhenShooting) - aimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_Anim2ToPlay, 4.0f); - else - aimAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_AnimToPlay); + if (bCrouchWhenShooting && bIsDucking) { + if (!!curWeapon->m_bCrouchFire) { + aimAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_WEAPON_CROUCHFIRE, 4.0f); + } + } else { + aimAssoc = CAnimManager::AddAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE); + } aimAssoc->blendAmount = 0.0f; aimAssoc->blendDelta = 8.0f; } - if (to) + if (to && !IsPlayer()) Say(SOUND_PED_ATTACK); } +// --MIAMI: Done void CPed::SetAmmo(eWeaponType weaponType, uint32 ammo) { - if (HasWeapon(weaponType)) { - GetWeapon(weaponType).m_nAmmoTotal = ammo; + int slot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot; + if (slot == -1) + return; + + GetWeapon(slot).m_nAmmoTotal += ammo; + if (weaponType < WEAPONTYPE_LAST_WEAPONTYPE && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) { + + // Looks like abandoned idea. This block never runs, ms_aMaxAmmoForWeapon is always -1. + GetWeapon(slot).m_nAmmoTotal = Min(CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType], (int32)GetWeapon(slot).m_nAmmoTotal); } else { - GetWeapon(weaponType).Initialise(weaponType, ammo); - m_maxWeaponTypeAllowed++; + GetWeapon(slot).m_nAmmoTotal = Min(99999, GetWeapon(slot).m_nAmmoTotal); } + uint32 newClip = GetWeapon(slot).m_nAmmoTotal; + if (newClip >= GetWeapon(slot).m_nAmmoInClip) + newClip = GetWeapon(slot).m_nAmmoInClip; + GetWeapon(slot).m_nAmmoInClip = newClip; + + if (GetWeapon(slot).m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO && GetWeapon(slot).m_nAmmoTotal > 0) + GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY; } +// --MIAMI: Done void CPed::GrantAmmo(eWeaponType weaponType, uint32 ammo) { - if (HasWeapon(weaponType)) { - GetWeapon(weaponType).m_nAmmoTotal += ammo; + int slot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot; + if (slot == -1) + return; + + GetWeapon(slot).m_nAmmoTotal += ammo; + if (weaponType < WEAPONTYPE_LAST_WEAPONTYPE && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) { + + // Looks like abandoned idea. This block never runs, ms_aMaxAmmoForWeapon is always -1. + GetWeapon(slot).m_nAmmoTotal = Min(CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType], (int32)GetWeapon(slot).m_nAmmoTotal); } else { - GetWeapon(weaponType).Initialise(weaponType, ammo); - m_maxWeaponTypeAllowed++; + GetWeapon(slot).m_nAmmoTotal = Min(99999, GetWeapon(slot).m_nAmmoTotal); } + + if (GetWeapon(slot).m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO && GetWeapon(slot).m_nAmmoTotal > 0) + GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY; } void @@ -4808,28 +5113,22 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump) } } +// --MIAMI: Done void CPed::SetAttack(CEntity *victim) { CPed *victimPed = nil; + CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + CAnimBlendAssociation *animAssoc; + if (victim && victim->IsPed()) victimPed = (CPed*)victim; - CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_ARMED); - if (animAssoc) { - animAssoc->blendDelta = -1000.0f; - animAssoc->flags |= ASSOC_DELETEFADEDOUT; - } - - if (m_attackTimer > CTimer::GetTimeInMilliseconds() || m_nWaitState == WAITSTATE_SURPRISE) + if (m_attackTimer > CTimer::GetTimeInMilliseconds() || m_nWaitState == WAITSTATE_SURPRISE || (bIsDucking && !bCrouchWhenShooting)) return; - if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_HGUN_RELOAD)) { - bIsAttacking = false; - return; - } - - if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_AK_RELOAD)) { + if (curWeapon->m_bReload && + (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD) || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD))) { if (!IsPlayer() || m_nPedState != PED_ATTACK || ((CPlayerPed*)this)->m_bHaveTargetSelected) bIsAttacking = false; else @@ -4838,20 +5137,23 @@ CPed::SetAttack(CEntity *victim) return; } - CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - if (curWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT && !IsPlayer()) { - if (GetWeapon()->HitsGround(this, nil, victim)) - return; - } - - if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED) { + // TODO(Miami): Brass knuckles + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || curWeapon->m_bFightMode /* || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLES */) { if (IsPlayer() || - (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS))) { + (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL + && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS) && curWeapon->m_bPartialAttack)) { if (m_nPedState != PED_ATTACK) { + if (m_nPedState == PED_FOLLOW_PATH) + ClearFollowPath(); + m_nPedState = PED_ATTACK; bIsAttacking = false; - animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_AnimToPlay, 8.0f); + + // TODO(Miami): Revert when fighting got ported + animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, + GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED ? ANIM_FIGHT_PPUNCH : ANIM_MELEE_ATTACK_START, 8.0f); + // CAnimBlendAssociation *animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_MELEE_ATTACK_START, 8.0f); animAssoc->SetRun(); if (animAssoc->currentTime == animAssoc->hierarchy->totalLength) animAssoc->SetCurrentTime(0.0f); @@ -4859,33 +5161,66 @@ CPed::SetAttack(CEntity *victim) animAssoc->SetFinishCallback(FinishedAttackCB, this); } } else { - StartFightAttack(CGeneral::GetRandomNumber() % 256); + StartFightAttack(CGeneral::GetRandomNumber()); } return; } + if (curWeapon->m_bPartialAttack && + (IsPlayer() && ((CPlayerPed*)this)->m_fMoveSpeed >= 1.0f || + m_nMoveState == PEDMOVE_WALK || m_nMoveState == PEDMOVE_RUN)) { + + if (m_nPedState != PED_ATTACK) { + if (m_nPedState == PED_FOLLOW_PATH) + ClearFollowPath(); + + m_nPedState = PED_ATTACK; + bIsAttacking = false; + CAnimBlendAssociation* animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_MELEE_ATTACK_START, 8.0f); + animAssoc->SetRun(); + if (animAssoc->currentTime == animAssoc->hierarchy->totalLength) + animAssoc->SetCurrentTime(0.0f); + + animAssoc->SetFinishCallback(FinishedAttackCB, this); + } + return; + } + + // TODO(Miami): Clean up old referene m_pSeekTarget = victim; if (m_pSeekTarget) m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget); if (curWeapon->m_bCanAim) { CVector aimPos = GetRight() * 0.1f + GetForward() * 0.2f + GetPosition(); + aimPos += GetUp() * 0.35f; CEntity *obstacle = CWorld::TestSphereAgainstWorld(aimPos, 0.2f, nil, true, false, false, true, false, false); - if (obstacle) - return; + if (obstacle) { + if(gaTempSphereColPoints[0].surfaceB != SURFACE_SCAFFOLD && gaTempSphereColPoints[0].surfaceB != SURFACE_METAL_FENCE && + gaTempSphereColPoints[0].surfaceB != SURFACE_WOOD_BOX && gaTempSphereColPoints[0].surfaceB != SURFACE_METAL_POLE) { + if (!IsPlayer()) { + bObstacleShowedUpDuringKillObjective = true; + m_shootTimer = 0; + SetAttackTimer(1500); + m_shotTime = CTimer::GetTimeInMilliseconds(); + } + return; + } + } m_pLookTarget = victim; if (victim) { m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget); m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget); } + if (m_pLookTarget) { SetAimFlag(m_pLookTarget); - } else { + } else if (this == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam()) { + SetAimFlag(m_fRotationCur); + ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch(); + } else if (curWeapon->m_bCanAimWithArm) { SetAimFlag(m_fRotationCur); - - if (FindPlayerPed() == this && TheCamera.Cams[0].Using3rdPersonMouseCam()) - ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch(); } } if (m_nPedState == PED_ATTACK) { @@ -4893,7 +5228,7 @@ CPed::SetAttack(CEntity *victim) return; } - if (IsPlayer() || !victimPed || victimPed->IsPedInControl()) { + if (IsPlayer() || (!victimPed || victimPed->IsPedInControl())) { if (IsPlayer()) CPad::GetPad(0)->ResetAverageWeapon(); @@ -4907,7 +5242,7 @@ CPed::SetAttack(CEntity *victim) ClearAimFlag(); // This condition is pointless - if (pointBlankStatus == POINT_BLANK_FOR_WANTED_PED || !victimPed) + if (pointBlankStatus == POINT_BLANK_FOR_WANTED_PED || !victimPed && (IsPlayer() || !m_carInObjective)) StartFightAttack(200); } else { if (!curWeapon->m_bCanAim) @@ -4916,21 +5251,45 @@ CPed::SetAttack(CEntity *victim) if (m_nPedState != PED_AIM_GUN) SetStoredState(); + if (m_nPedState == PED_FOLLOW_PATH) + ClearFollowPath(); + m_nPedState = PED_ATTACK; SetMoveState(PEDMOVE_NONE); - if (bCrouchWhenShooting) { - animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_RBLOCK_CSHOOT, 4.0f); + if (bCrouchWhenShooting && bIsDucking && !!curWeapon->m_bCrouchFire) { + CAnimBlendAssociation* curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + if (curMoveAssoc) { + if (strcmp(CAnimManager::GetAnimAssociation(curWeapon->m_AnimToPlay, ANIM_WEAPON_CROUCHFIRE)->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) { + delete curMoveAssoc; + } + } + animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_WEAPON_CROUCHFIRE, 8.0f); } else { float animDelta = 8.0f; if (curWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE) animDelta = 1000.0f; - if (GetWeapon()->m_eWeaponType != WEAPONTYPE_BASEBALLBAT - || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) { - animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_AnimToPlay, animDelta); + AnimationId fireAnim; + if (curWeapon->m_bThrow) + fireAnim = ANIM_THROWABLE_START_THROW; + else if (CGame::nastyGame && (curWeapon->m_bGround2nd || curWeapon->m_bGround3rd)) { + PedOnGroundState pedOnGround = CheckForPedsOnGroundToAttack(this, nil); + if (pedOnGround > PED_IN_FRONT_OF_ATTACKER || pedOnGround == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle()) { + fireAnim = GetFireAnimGround(curWeapon, false); + } else { + fireAnim = GetFireAnimNotDucking(curWeapon); + } } else { - animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_Anim2ToPlay, animDelta); + fireAnim = GetFireAnimNotDucking(curWeapon); } + + CAnimBlendAssociation* curFireAssoc = RpAnimBlendClumpGetAssociation(GetClump(), fireAnim); + if (curFireAssoc) { + if (strcmp(CAnimManager::GetAnimAssociation(curWeapon->m_AnimToPlay, fireAnim)->hierarchy->name, curFireAssoc->hierarchy->name) != 0) { + delete curFireAssoc; + } + } + animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, fireAnim, animDelta); } animAssoc->SetRun(); @@ -4945,7 +5304,8 @@ CPed::SetAttack(CEntity *victim) if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && victimPed->m_nPedState == PED_GETUP) SetWaitState(WAITSTATE_SURPRISE, nil); - SetLookFlag(victim, false); + // TODO(Miami): New parameter + SetLookFlag(victim, true); //true); SetLookTimer(100); } @@ -5123,7 +5483,7 @@ CPed::GetLocalDirection(const CVector2D &posOffset) bool CPed::FightStrike(CVector &touchedNodePos) { - CColModel *ourCol; + CColModel *hisCol; CVector attackDistance; ePedPieceTypes closestPedPiece = PEDPIECE_TORSO; float maxDistanceToBeBeaten; @@ -5147,33 +5507,20 @@ CPed::FightStrike(CVector &touchedNodePos) if (nearPed->bUsesCollision || nearPed->m_nPedState == PED_DEAD) { CVector nearPedCentre; + + // Have to animate a skinned clump because the initial col model is useless + hisCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(nearPed->GetModelIndex()))->AnimatePedColModelSkinnedWorld(nearPed->GetClump()); + nearPed->GetBoundCentre(nearPedCentre); CVector potentialAttackDistance = nearPedCentre - touchedNodePos; // He can beat us if (sq(maxDistanceToBeBeaten) > potentialAttackDistance.MagnitudeSqr()) { - // Have to animate a skinned clump because the initial col model is useless - ourCol = ((CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()))->AnimatePedColModelSkinned(GetClump()); -/* this should all be gone, right? - if (nearPed->m_nPedState == PED_FALL - || nearPed->m_nPedState == PED_DEAD || nearPed->m_nPedState == PED_DIE - || !nearPed->IsPedHeadAbovePos(-0.3f)) { - ourCol = &CTempColModels::ms_colModelPedGroundHit; - } else { -#ifdef ANIMATE_PED_COL_MODEL - ourCol = CPedModelInfo::AnimatePedColModel(((CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()))->GetHitColModel(), - RpClumpGetFrame(GetClump())); -#else - ourCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->GetHitColModel(); -#endif - } -*/ - - for (int j = 0; j < ourCol->numSpheres; j++) { - attackDistance = nearPed->GetPosition() + ourCol->spheres[j].center; + for (int j = 0; j < hisCol->numSpheres; j++) { + attackDistance = hisCol->spheres[j].center; attackDistance -= touchedNodePos; - CColSphere *ourPieces = ourCol->spheres; + CColSphere *ourPieces = hisCol->spheres; float maxDistanceToBeat = ourPieces[j].radius + tFightMoves[m_lastFightMove].strikeRadius; // We can beat him too @@ -5958,7 +6305,7 @@ CPed::CreateDeadPedWeaponPickups(void) if (bInVehicle) return; - for(int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) { + for(int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { eWeaponType weapon = GetWeapon(i).m_eWeaponType; int weaponAmmo = GetWeapon(i).m_nAmmoTotal; @@ -6083,18 +6430,64 @@ CPed::SetChat(CEntity *chatWith, uint32 time) m_lookTimer = CTimer::GetTimeInMilliseconds() + 3000; } +// --MIAMI: Done +void +CPed::RemoveWeaponAnims(int unused, float animDelta) +{ + CAnimBlendAssociation *weaponAssoc; + //CWeaponInfo::GetWeaponInfo(unused); + + // TODO(Miami): Remove when fighting got ported + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_PPUNCH); + if (weaponAssoc) { + weaponAssoc->blendDelta = animDelta; + weaponAssoc->flags |= ASSOC_DELETEFADEDOUT; + } + + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); + if (weaponAssoc) { + weaponAssoc->blendDelta = animDelta; + weaponAssoc->flags |= ASSOC_DELETEFADEDOUT; + } + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + if (weaponAssoc) { + weaponAssoc->blendDelta = animDelta; + weaponAssoc->flags |= ASSOC_DELETEFADEDOUT; + } + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD); + if (weaponAssoc) { + weaponAssoc->blendDelta = animDelta; + weaponAssoc->flags |= ASSOC_DELETEFADEDOUT; + } + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); + if (weaponAssoc) { + weaponAssoc->blendDelta = animDelta; + weaponAssoc->flags |= ASSOC_DELETEFADEDOUT; + } + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_SPECIAL); + if (weaponAssoc) { + weaponAssoc->flags |= ASSOC_DELETEFADEDOUT; + if (weaponAssoc->flags & ASSOC_PARTIAL) + weaponAssoc->blendDelta = animDelta; + else + CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, -animDelta); + } +} + +// --MIAMI: Done void CPed::SetDead(void) { -#ifdef VC_PED_PORTS if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DROWN)) -#endif bUsesCollision = false; m_fHealth = 0.0f; if (m_nPedState == PED_DRIVING) bIsVisible = false; + if (m_nPedState == PED_FOLLOW_PATH) + ClearFollowPath(); + m_nPedState = PED_DEAD; m_pVehicleAnim = nil; m_pCollidingEntity = nil; @@ -6105,6 +6498,7 @@ CPed::SetDead(void) m_currentWeapon = WEAPONTYPE_UNARMED; CEventList::RegisterEvent(EVENT_INJURED_PED, EVENT_ENTITY_PED, this, nil, 250); if (this != FindPlayerPed()) { + RemoveWeaponAnims(0, -1000.0f); CreateDeadPedWeaponPickups(); CreateDeadPedMoney(); } @@ -6474,6 +6868,7 @@ CPed::GetNearestTrainDoor(CVehicle *train, CVector &doorPos) return 1; } +#ifdef GTA_TRAIN void CPed::LineUpPedWithTrain(void) { @@ -6525,6 +6920,7 @@ CPed::ExitTrain(void) { LineUpPedWithTrain(); } +#endif void CPed::ExitCar(void) @@ -7061,9 +7457,7 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg) if (obstacle) { animAssoc->flags |= ASSOC_DELETEFADEDOUT; - - // ANIM_HIT_WALL in VC (which makes more sense) - CAnimBlendAssociation *handsCoverAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_HANDSCOWER, 8.0f); + CAnimBlendAssociation *handsCoverAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 8.0f); handsCoverAssoc->flags &= ~ASSOC_FADEOUTWHENDONE; handsCoverAssoc->SetFinishCallback(FinishHitHeadCB, ped); ped->bIsLanding = true; @@ -8041,14 +8435,11 @@ CPed::GetPedRadioCategory(uint32 modelIndex) return 1; } -// Some kind of VC leftover I think +// --MIAMI: Done int CPed::GetWeaponSlot(eWeaponType weaponType) { - if (HasWeapon(weaponType)) - return weaponType; - else - return -1; + return CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot; } void @@ -8198,6 +8589,11 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void) { // FIX: If there were no translations on enter anims, there were overflows all over this function. + int vanBlock = CAnimManager::GetAnimationBlockIndex("van"); + CStreaming::RequestAnim(vanBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::LoadAllRequestedModels(false); + CAnimManager::AddAnimBlockRef(vanBlock); + CAnimBlendHierarchy *enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_JACKED_LHS)->hierarchy; CAnimBlendSequence *seq = enterAssoc->sequences; CAnimManager::UncompressAnimation(enterAssoc); @@ -8246,7 +8642,7 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void) } } - enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_VAN_GETIN_L)->hierarchy; + enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_VAN, ANIM_VAN_GETIN_L)->hierarchy; seq = enterAssoc->sequences; CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { @@ -8257,7 +8653,7 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void) vecPedVanRearDoorAnimOffset = lastFrame->translation; } } - +#ifdef GTA_TRAIN enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_TRAIN_GETOUT)->hierarchy; seq = enterAssoc->sequences; CAnimManager::UncompressAnimation(enterAssoc); @@ -8269,6 +8665,7 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void) vecPedTrainDoorAnimOffset = lastFrame->translation; } } +#endif } void @@ -8474,7 +8871,7 @@ CPed::InvestigateEvent(void) bool CPed::IsPedDoingDriveByShooting(void) { - if (FindPlayerPed() == this && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) { + if (FindPlayerPed() == this && CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nWeaponSlot == 5) { if (TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight) return true; } @@ -8724,7 +9121,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse) if ((m_nPedState == PED_FALL || m_nPedState == PED_DIE || m_nPedState == PED_DEAD) && !m_pCollidingEntity && - (!IsPlayer() || bHasHitWall || car->GetModelIndex() == MI_TRAIN || m_vecDamageNormal.z < -0.8f)) { + (!IsPlayer() || bHasHitWall || car->GetModelIndex() == MI_TRAIN || m_vecDamageNormal.z < -0.8f)) { m_pCollidingEntity = car; } @@ -9224,7 +9621,6 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) bool itsLow = !!veh->bLowVehicle; #endif eDoors enterDoor; - AnimationId enterAnim; switch (ped->m_vehEnterType) { case CAR_DOOR_RF: @@ -9254,28 +9650,27 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) } if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) { if (itsVan) { - enterAnim = ANIM_VAN_GETIN; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN); } else if (itsBus) { - enterAnim = ANIM_COACH_IN_R; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_R); #ifdef FIX_BUGS } else if (itsLow) { - enterAnim = ANIM_CAR_GETIN_LOW_RHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_RHS); #endif } else { - enterAnim = ANIM_CAR_GETIN_RHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_RHS); } } else if (itsVan) { - enterAnim = ANIM_VAN_GETIN_L; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN_L); } else if (itsBus) { - enterAnim = ANIM_COACH_IN_L; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_L); #ifdef FIX_BUGS } else if (itsLow) { - enterAnim = ANIM_CAR_GETIN_LOW_LHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_LHS); #endif } else { - enterAnim = ANIM_CAR_GETIN_LHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS); } - ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, enterAnim); ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped); } else if (veh->CanPedOpenLocks(ped)) { @@ -9283,16 +9678,16 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) veh->AutoPilot.m_nCruiseSpeed = 0; if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) { if (itsVan) { - ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_VAN_OPEN); + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_OPEN); } else if (itsBus) { - ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_COACH_OPEN_R); + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_OPEN_R); } else { ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_OPEN_RHS); } } else if (itsVan) { - ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_VAN_OPEN_L); + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_OPEN_L); } else if (itsBus) { - ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_COACH_OPEN_L); + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_OPEN_L); } else { if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && veh->pDriver) { @@ -10270,12 +10665,13 @@ CPed::ProcessControl(void) CPhysical::ProcessControl(); #endif if (m_nPedState != PED_DIE || bIsPedDieAnimPlaying) { + RequestDelayedWeapon(); + PlayFootSteps(); if (m_nPedState != PED_DEAD) { CalculateNewVelocity(); CalculateNewOrientation(); } UpdatePosition(); - PlayFootSteps(); if (IsPedInControl() && !bIsStanding && !m_pDamageEntity && CheckIfInTheAir()) { SetInTheAir(); #ifdef VC_PED_PORTS @@ -10471,12 +10867,14 @@ CPed::ProcessControl(void) case PED_GETUP: SetGetUp(); break; +#ifdef GTA_TRAIN case PED_ENTER_TRAIN: EnterTrain(); break; case PED_EXIT_TRAIN: ExitTrain(); break; +#endif case PED_DRIVING: { if (!m_pMyVehicle) { @@ -10681,18 +11079,27 @@ CPed::RestoreHeadPosition(void) } } +// --MIAMI: Done void CPed::PointGunAt(void) { CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weaponInfo->m_AnimToPlay); - if (!weaponAssoc || weaponAssoc->blendDelta < 0.0f) - weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weaponInfo->m_Anim2ToPlay); + float animLoopStart = weaponInfo->m_fAnimLoopStart; + CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); + if (!weaponAssoc || weaponAssoc->blendDelta < 0.0f) { + if (!!weaponInfo->m_bCrouchFire) { + weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE); + animLoopStart = weaponInfo->m_fAnim2LoopStart; + } + } - if (weaponAssoc && weaponAssoc->currentTime > weaponInfo->m_fAnimLoopStart) { - weaponAssoc->SetCurrentTime(weaponInfo->m_fAnimLoopStart); + if (weaponAssoc && weaponAssoc->currentTime > animLoopStart * 0.4f) { + weaponAssoc->SetCurrentTime(animLoopStart); weaponAssoc->flags &= ~ASSOC_RUNNING; + if (bIsDucking) + m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; + if (weaponInfo->m_bCanAimWithArm) m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM; else @@ -10871,28 +11278,26 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) isVan = false; if (ped->m_nPedState != PED_CARJACK || isBus) { - AnimationId animToPlay; if (ped->m_vehEnterType != CAR_DOOR_LF && ped->m_vehEnterType != CAR_DOOR_LR) { if (isVan) { - animToPlay = ANIM_VAN_GETIN; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN); } else if (isBus) { - animToPlay = ANIM_COACH_IN_R; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_R); } else if (isLow) { - animToPlay = ANIM_CAR_GETIN_LOW_RHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_RHS); } else { - animToPlay = ANIM_CAR_GETIN_RHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_RHS); } } else if (isVan) { - animToPlay = ANIM_VAN_GETIN_L; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN_L); } else if (isBus) { - animToPlay = ANIM_COACH_IN_L; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_L); } else if (isLow) { - animToPlay = ANIM_CAR_GETIN_LOW_LHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_LHS); } else { - animToPlay = ANIM_CAR_GETIN_LHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS); } - ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, animToPlay); ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped); } else { CPed *pedToDragOut = nil; @@ -11001,51 +11406,17 @@ CPed::ServiceTalkingWhenDead(void) return m_queuedSound == SOUND_PED_DEATH; } +// --MIAMI: Done void CPed::RemoveInCarAnims(void) { - if (!IsPlayer()) - return; + CAnimBlendAssociation* assoc; - CAnimBlendAssociation *animAssoc; - - if (m_pMyVehicle && m_pMyVehicle->bLowVehicle) { - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_LOW_L); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_LOW_R); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_L); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_R); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - } else { - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_L); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_R); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_L); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_R); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; + for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_DRIVING); assoc; + assoc = RpAnimBlendGetNextAssociation(assoc, ASSOC_DRIVING)) { + assoc->flags |= ASSOC_DELETEFADEDOUT; + assoc->blendDelta = -1000.0f; } - -#ifdef VC_PED_PORTS - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; -#endif - - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LB); - if (animAssoc) - animAssoc->blendDelta = -1000.0f; } void @@ -11167,32 +11538,32 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg) if (veh->IsDoorMissing(enterDoor) || isBus) { PedAnimDoorCloseCB(nil, ped); } else { - AnimationId animToPlay; if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) { if (isVan) { - animToPlay = ANIM_VAN_CLOSE; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_CLOSE); } else if (isLow) { - animToPlay = ANIM_CAR_CLOSEDOOR_LOW_RHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LOW_RHS); } else { - animToPlay = ANIM_CAR_CLOSEDOOR_RHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_RHS); } } else if (isVan) { - animToPlay = ANIM_VAN_CLOSE_L; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_CLOSE_L); } else if (isLow) { - animToPlay = ANIM_CAR_CLOSEDOOR_LOW_LHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LOW_LHS); } else { - animToPlay = ANIM_CAR_CLOSEDOOR_LHS; + ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LHS); } - ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, animToPlay); ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorCloseCB, ped); } } +#ifdef GTA_TRAIN void CPed::SetPedPositionInTrain(void) { LineUpPedWithTrain(); } +#endif void CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg) @@ -12189,14 +12560,14 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) } } -// It was inlined in III but not in VC. +// --MIAMI: Done, but enumarate weapon slots inline void CPed::ReplaceWeaponWhenExitingVehicle(void) { eWeaponType weaponType = GetWeapon()->m_eWeaponType; // If it's Uzi, we may have stored weapon. Uzi is the only gun we can use in car. - if (IsPlayer() && weaponType == WEAPONTYPE_UZI) { + if (IsPlayer() && GetWeaponSlot(weaponType) == 5) { if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) { SetCurrentWeapon(m_storedWeapon); m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; @@ -12206,14 +12577,14 @@ CPed::ReplaceWeaponWhenExitingVehicle(void) } } -// Same, it's inlined in III. +// --MIAMI: Add driveby check, enumarate weapon slots inline void CPed::RemoveWeaponWhenEnteringVehicle(void) { - if (IsPlayer() && HasWeapon(WEAPONTYPE_UZI) && GetWeapon(WEAPONTYPE_UZI).m_nAmmoTotal > 0) { + if (IsPlayer() && GetWeapon(5).m_eWeaponType && GetWeapon(5).m_nAmmoTotal > 0) { if (m_storedWeapon == WEAPONTYPE_UNIDENTIFIED) m_storedWeapon = GetWeapon()->m_eWeaponType; - SetCurrentWeapon(WEAPONTYPE_UZI); + SetCurrentWeapon(GetWeapon(5).m_eWeaponType); } else { CWeaponInfo *ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); RemoveWeaponModel(ourWeapon->m_nModelId); @@ -12798,8 +13169,8 @@ CPed::ProcessObjective(void) int chosenModel = CCarCtrl::ChooseModel(&zoneInfo, &ourPos, &chosenCarClass); CAutomobile *newVeh = new CAutomobile(chosenModel, RANDOM_VEHICLE); if (newVeh) { - newVeh->GetMatrix().GetPosition() = ThePaths.m_pathNodes[closestNode].GetPosition(); - newVeh->GetMatrix().GetPosition().z += 4.0f; + newVeh->GetMatrix().GetPosition() = ThePaths.m_pathNodes[closestNode].GetPosition(); + newVeh->GetMatrix().GetPosition().z += 4.0f; newVeh->SetHeading(DEGTORAD(200.0f)); newVeh->SetStatus(STATUS_ABANDONED); newVeh->m_nDoorLock = CARLOCK_UNLOCKED; @@ -13726,7 +14097,7 @@ CPed::ProcessObjective(void) float distWithTargetScSqr = distWithTarget.MagnitudeSqr(); if (distWithTargetScSqr <= sq(10.0f)) { if (distWithTargetScSqr <= sq(1.4f)) { - CAnimBlendAssociation *reloadAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_AK_RELOAD); + CAnimBlendAssociation *reloadAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FUCKU); m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( m_pedInObjective->GetPosition().x, m_pedInObjective->GetPosition().y, GetPosition().x, GetPosition().y); @@ -13763,7 +14134,7 @@ CPed::ProcessObjective(void) if (weaponType != WEAPONTYPE_UNARMED && weaponType != WEAPONTYPE_BASEBALLBAT) SetCurrentWeapon(WEAPONTYPE_UNARMED); - CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_AK_RELOAD, 8.0f); + CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FUCKU, 8.0f); newReloadAssoc->flags |= ASSOC_DELETEFADEDOUT; newReloadAssoc->flags |= ASSOC_FADEOUTWHENDONE; } @@ -13796,23 +14167,21 @@ CPed::ProcessObjective(void) case OBJECTIVE_LEAVE_VEHICLE: if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) { if (InVehicle() -#ifdef VC_PED_PORTS && (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate() || bBusJacked) -#endif ) { if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN && (m_nPedType != PEDTYPE_COP -#ifdef VC_PED_PORTS || m_pMyVehicle->IsBoat() -#endif || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) { +#ifdef GTA_TRAIN if (m_pMyVehicle->IsTrain()) SetExitTrain(m_pMyVehicle); -#ifdef VC_PED_PORTS - else if (m_pMyVehicle->IsBoat()) - SetExitBoat(m_pMyVehicle); + else #endif + if (m_pMyVehicle->IsBoat()) + SetExitBoat(m_pMyVehicle); + else SetExitCar(m_pMyVehicle, 0); } @@ -13916,6 +14285,7 @@ CPed::SetSeekBoatPosition(CVehicle *boat) m_nPedState = PED_SEEK_IN_BOAT; } +#ifdef GTA_TRAIN void CPed::SetExitTrain(CVehicle* train) { @@ -13933,6 +14303,7 @@ CPed::SetExitTrain(CVehicle* train) bUsesCollision = false; LineUpPedWithTrain(); } +#endif #ifdef NEW_WALK_AROUND_ALGORITHM CVector @@ -14661,7 +15032,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) bSomeVCflag1 = false; } #else - GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z; + GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z; #endif m_nSurfaceTouched = intersectionPoint.surfaceB; if (m_nSurfaceTouched == SURFACE_STONE) { @@ -14669,8 +15040,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) m_vecDamageNormal = intersectionPoint.normal; } } - // VC code is working perfectly, but we don't want mega jumps to damage us significantly :shrug: -#if 0 // #ifdef VC_PED_PORTS + float upperSpeedLimit = 0.33f; float lowerSpeedLimit = -0.25f; float speed = m_vecMoveSpeed.Magnitude2D(); @@ -14678,7 +15048,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) upperSpeedLimit *= 2.0f; lowerSpeedLimit *= 1.5f; } - if (!m_ped_flagA2) { + if (!bWasStanding) { if ((speed <= upperSpeedLimit /* || (bfFlagsL >> 5) & 1 */) && m_vecMoveSpeed.z >= lowerSpeedLimit || m_pCollidingEntity == collidingEnt) { @@ -14701,27 +15071,6 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) Say(SOUND_PED_LAND); } } -#else - float speedSqr = 0.0f; - if (!bWasStanding) { - if (m_vecMoveSpeed.z >= -0.25f && (speedSqr = m_vecMoveSpeed.MagnitudeSqr()) <= sq(0.5f)) { - - if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL) && -0.016f * CTimer::GetTimeStep() > m_vecMoveSpeed.z) { - InflictDamage(collidingEnt, WEAPONTYPE_FALL, 15.0f, PEDPIECE_TORSO, 2); - } - } else { - if (speedSqr == 0.0f) - speedSqr = sq(m_vecMoveSpeed.z); - - uint8 dir = 2; // from backward - if (m_vecMoveSpeed.x > 0.01f || m_vecMoveSpeed.x < -0.01f || m_vecMoveSpeed.y > 0.01f || m_vecMoveSpeed.y < -0.01f) { - CVector2D offset = -m_vecMoveSpeed; - dir = GetLocalDirection(offset); - } - InflictDamage(collidingEnt, WEAPONTYPE_FALL, 350.0f * sq(speedSqr), PEDPIECE_TORSO, dir); - } - } -#endif m_vecMoveSpeed.z = 0.0f; bIsStanding = true; #ifndef VC_PED_PORTS @@ -14858,6 +15207,7 @@ CPed::WillChat(CPed *stranger) return true; } +#ifdef GTA_TRAIN void CPed::SetEnterTrain(CVehicle *train, uint32 unused) { @@ -14883,6 +15233,7 @@ CPed::SetEnterTrain(CVehicle *train, uint32 unused) ((CPlayerPed*)this)->ClearAdrenaline(); } } +#endif void CPed::SetDuck(uint32 time) @@ -15565,7 +15916,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) switch (m_vehEnterType) { case CAR_DOOR_RF: if (veh->bIsBus) { - m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_COACH_OUT_L); + m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_COACH, ANIM_COACH_OUT_L); } else { if (isLow) m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LOW_RHS); @@ -15578,7 +15929,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) break; case CAR_DOOR_RR: if (veh->bIsVan) { - m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_VAN_GETOUT); + m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETOUT); } else if (isLow) { m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LOW_RHS); } else { @@ -15587,7 +15938,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) break; case CAR_DOOR_LF: if (veh->bIsBus) { - m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_COACH_OUT_L); + m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_COACH, ANIM_COACH_OUT_L); } else { if (isLow) m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LOW_LHS); @@ -15600,7 +15951,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) break; case CAR_DOOR_LR: if (veh->bIsVan) { - m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_VAN_GETOUT_L); + m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETOUT_L); } else if (isLow) { m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LOW_LHS); } else { @@ -16099,9 +16450,12 @@ CPed::SeekCar(void) if (Seek()) { if (!foundBetterPosToSeek) { if (1.5f + GetPosition().z > dest.z && GetPosition().z - 0.5f < dest.z) { +#ifdef GTA_TRAIN if (vehToSeek->IsTrain()) { SetEnterTrain(vehToSeek, m_vehEnterType); - } else { + } else +#endif + { m_fRotationCur = m_fRotationDest; if (!bVehEnterDoorIsBlocked) { vehToSeek->bIsStatic = false; @@ -17222,7 +17576,7 @@ CPed::WanderPath(void) if (!Seek()) return; - CPathNode *previousLastNode = m_pLastPathNode; + CPathNode *previousLastNode = m_pLastPathNode; uint8 randVal = (m_randomSeed + 3 * CTimer::GetFrameCounter()) % 100; // We don't prefer 180-degree turns in normal situations @@ -17493,7 +17847,7 @@ CPed::SetCarJack(CVehicle* car) pedInSeat = car->pDriver; if (m_fHealth > 0.0f && (IsPlayer() || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS || - (car->VehicleCreatedBy != MISSION_VEHICLE && car->GetModelIndex() != MI_DODO))) + (car->VehicleCreatedBy != MISSION_VEHICLE && car->GetModelIndex() != MI_DODO))) if (pedInSeat && !pedInSeat->IsPedDoingDriveByShooting() && pedInSeat->m_nPedState == PED_DRIVING) if (m_nPedState != PED_CARJACK && !m_pVehicleAnim) if ((car->IsDoorReady(door) || car->IsDoorFullyOpen(door))) @@ -17640,7 +17994,7 @@ CPed::Save(uint8*& buf) CopyToBuf(buf, m_fHealth); CopyToBuf(buf, m_fArmour); SkipSaveBuf(buf, 148); - for (int i = 0; i < 13; i++) // has to be hardcoded + for (int i = 0; i < 10; i++) // has to be hardcoded m_weapons[i].Save(buf); SkipSaveBuf(buf, 5); CopyToBuf(buf, m_maxWeaponTypeAllowed); @@ -17660,8 +18014,24 @@ CPed::Load(uint8*& buf) CopyFromBuf(buf, m_fHealth); CopyFromBuf(buf, m_fArmour); SkipSaveBuf(buf, 148); - for (int i = 0; i < 13; i++) // has to be hardcoded - m_weapons[i].Load(buf); + + CWeapon bufWeapon; + for (int i = 0; i < 10; i++) { // has to be hardcoded + bufWeapon.Load(buf); + + if (bufWeapon.m_eWeaponType != WEAPONTYPE_UNARMED) { + int modelId = CWeaponInfo::GetWeaponInfo(bufWeapon.m_eWeaponType)->m_nModelId; + if (modelId != -1) { + CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY); + int modelId2 = CWeaponInfo::GetWeaponInfo(bufWeapon.m_eWeaponType)->m_nModel2Id; + if (modelId2 != -1) + CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY); + + CStreaming::LoadAllRequestedModels(false); + } + GiveWeapon(bufWeapon.m_eWeaponType, bufWeapon.m_nAmmoTotal); + } + } SkipSaveBuf(buf, 5); CopyFromBuf(buf, m_maxWeaponTypeAllowed); SkipSaveBuf(buf, 162); @@ -17669,3 +18039,53 @@ CPed::Load(uint8*& buf) #undef CopyFromBuf #undef CopyToBuf #endif + +void +CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo) +{ + m_storedWeapon = weapon; + m_storedWeaponAmmo = ammo; + if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) { + int modelId1 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModelId; + int modelId2 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModel2Id; + if (modelId1 != -1) + CStreaming::RequestModel(modelId1, STREAMFLAGS_DEPENDENCY); + if (modelId2 != -1) + CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY); + + if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1)) + && (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) { + GiveWeapon(m_storedWeapon, m_storedWeaponAmmo, 1); + m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; + } + } +} + +void +CPed::RequestDelayedWeapon() +{ + if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) { + int modelId1 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModelId; + int modelId2 = CWeaponInfo::GetWeaponInfo(m_storedWeapon)->m_nModel2Id; + if (modelId1 != -1) + CStreaming::RequestModel(modelId1, STREAMFLAGS_DEPENDENCY); + if (modelId2 != -1) + CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY); + + if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1)) + && (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) { + GiveWeapon(m_storedWeapon, m_storedWeaponAmmo, 1); + m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; + } + } +} + +void +CPed::ClearFollowPath() +{ + for (int i = 0; i < ARRAY_SIZE(m_pPathNodesStates); i++) { + m_pPathNodesStates[i] = nil; + } + m_nPathNodes = 0; + m_nCurPathNode = 0; +} \ No newline at end of file diff --git a/src/peds/Ped.h b/src/peds/Ped.h index ccffc3cb..23f1a376 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -476,8 +476,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; @@ -503,12 +504,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; - int8 m_lastWepDam; + 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; @@ -556,7 +571,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); @@ -567,7 +583,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); @@ -639,6 +655,7 @@ public: void RemoveInCarAnims(void); void CollideWithPed(CPed*); void SetDirectionToWalkAroundObject(CEntity*); + void RemoveWeaponAnims(int, float); void CreateDeadPedMoney(void); void CreateDeadPedWeaponPickups(void); void SetAttackTimer(uint32); @@ -654,7 +671,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*); @@ -701,7 +717,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); @@ -710,6 +725,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); @@ -737,8 +755,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); @@ -767,8 +786,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); @@ -776,11 +801,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); @@ -793,8 +816,8 @@ public: bool CanPedJumpThis(CEntity*); #endif - bool HasWeapon(uint8 weaponType) { return m_weapons[weaponType].m_eWeaponType == weaponType; } - CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; } + bool HasWeaponSlot(uint8 slot) { return m_weapons[slot].m_eWeaponType != WEAPONTYPE_UNARMED; } + CWeapon &GetWeapon(uint8 slot) { return m_weapons[slot]; } CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; } PedState GetPedState(void) { return m_nPedState; } @@ -811,6 +834,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) { @@ -829,6 +881,7 @@ public: if (walk) SetMoveState(PEDMOVE_WALK); } + // -- // Using this to abstract nodes of skinned and non-skinned meshes CVector GetNodePosition(int32 node) @@ -898,6 +951,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 diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 3c6fad57..04251860 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -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,56 +634,71 @@ 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 - && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER - && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT - && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER - && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT) { + if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER + && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT + && 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 = 0; } - m_nSelectedWepSlot = WEAPONTYPE_UNARMED; - } - } else if (padUsed->CycleWeaponLeftJustDown() && !m_pPointGunAt) { - 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 (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) { - goto switchDetectDone; - } - } - } - } else if (CWeaponInfo::GetWeaponInfo((eWeaponType)m_currentWeapon)->m_eWeaponFire != WEAPON_FIRE_MELEE) { - if (GetWeapon(m_currentWeapon).m_nAmmoTotal <= 0) { + } 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 >= 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) { + for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) { + if (m_nSelectedWepSlot < 0) + m_nSelectedWepSlot = 9; + + if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) { + break; + } + } + } + } + } + +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) { + + 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(); diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index e8173c8c..354140df 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -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); diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index 2dc0bbab..14bd042c 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -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: diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index c3fcb7bf..e06cc143 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -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,17 +293,36 @@ void CHud::Draw() /* DrawWeaponIcon */ - 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), - 0.015f, - 0.015f, - 1.0f, - 0.0f, - 0.015f, - 1.0f, - 1.0f, - 1.0f); + + 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), + 0.015f, + 0.015f, + 1.0f, + 0.0f, + 0.015f, + 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); } } diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp index 7b8d777e..9934ae18 100644 --- a/src/render/MBlur.cpp +++ b/src/render/MBlur.cpp @@ -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); +} \ No newline at end of file diff --git a/src/render/MBlur.h b/src/render/MBlur.h index ce6f3d2e..3129c070 100644 --- a/src/render/MBlur.h +++ b/src/render/MBlur.h @@ -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(); }; diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 6fc0436c..6e88b997 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -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); diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index b6045062..4149fe6c 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -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; diff --git a/src/weapons/ProjectileInfo.cpp b/src/weapons/ProjectileInfo.cpp index 47bc65ac..35e55b36 100644 --- a/src/weapons/ProjectileInfo.cpp +++ b/src/weapons/ProjectileInfo.cpp @@ -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,32 +59,36 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos, switch (weapon) { - case WEAPONTYPE_ROCKETLAUNCHER: + case WEAPONTYPE_ROCKET: { - float vy = 1.25f; - time = CTimer::GetTimeInMilliseconds() + 1400; - if (ped->IsPlayer()) { - matrix.GetForward() = TheCamera.Cams[TheCamera.ActiveCam].Front; - matrix.GetUp() = TheCamera.Cams[TheCamera.ActiveCam].Up; - matrix.GetRight() = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Up, TheCamera.Cams[TheCamera.ActiveCam].Front); + 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; - } else if (ped->m_pSeekTarget != nil) { + 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; + matrix.GetRight() = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Up, TheCamera.Cams[TheCamera.ActiveCam].Front); + matrix.GetPosition() = pos; + } else if (ped->m_pSeekTarget != nil) { float ry = CGeneral::GetRadianAngleBetweenPoints(1.0f, ped->m_pSeekTarget->GetPosition().z, 1.0f, pos.z); float rz = Atan2(-ped->GetForward().x, ped->GetForward().y); vy = 0.35f * speed + 0.15f; matrix.SetTranslate(0.0f, 1.0f, 1.0f); matrix.Rotate(0.0f, ry, rz); matrix.GetPosition() += pos; - } else { - matrix = ped->GetMatrix(); + } 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,14 +240,25 @@ 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 { - RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]); + 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() { diff --git a/src/weapons/ProjectileInfo.h b/src/weapons/ProjectileInfo.h index 3d8074c9..d1688948 100644 --- a/src/weapons/ProjectileInfo.h +++ b/src/weapons/ProjectileInfo.h @@ -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); }; diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 18c605bc..deb77cb9 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -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,9 +173,20 @@ 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: { - fired = FireInstantHit(shooter, source); + 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; diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h index 1b2c0320..32322da0 100644 --- a/src/weapons/Weapon.h +++ b/src/weapons/Weapon.h @@ -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); diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp index c4ab75d2..7128a04f 100644 --- a/src/weapons/WeaponInfo.cpp +++ b/src/weapons/WeaponInfo.cpp @@ -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(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; + } + } } } diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h index b5882082..cb10f095 100644 --- a/src/weapons/WeaponInfo.h +++ b/src/weapons/WeaponInfo.h @@ -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); \ No newline at end of file +VALIDATE_SIZE(CWeaponInfo, 0x64); diff --git a/src/weapons/WeaponType.h b/src/weapons/WeaponType.h index b45740b7..61d03ad3 100644 --- a/src/weapons/WeaponType.h +++ b/src/weapons/WeaponType.h @@ -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 {