basic bike support in traffic, script and car gen; some heli AI

This commit is contained in:
Nikolay Korolev 2020-06-05 11:22:15 +03:00
parent 647fd951ec
commit d325a3d247
4 changed files with 143 additions and 53 deletions

View File

@ -4,6 +4,7 @@
#include "Accident.h" #include "Accident.h"
#include "Automobile.h" #include "Automobile.h"
#include "Bike.h"
#include "Camera.h" #include "Camera.h"
#include "CarAI.h" #include "CarAI.h"
#include "CarGen.h" #include "CarGen.h"
@ -345,7 +346,7 @@ CCarCtrl::GenerateOneRandomCar()
if (CModelInfo::IsBoatModel(carModel)) if (CModelInfo::IsBoatModel(carModel))
pVehicle = new CBoat(carModel, RANDOM_VEHICLE); pVehicle = new CBoat(carModel, RANDOM_VEHICLE);
else if (CModelInfo::IsBikeModel(carModel)) else if (CModelInfo::IsBikeModel(carModel))
return; // TODO(MIAMI): spawn bikes pVehicle = new CBike(carModel, RANDOM_VEHICLE);
else else
pVehicle = new CAutomobile(carModel, RANDOM_VEHICLE); pVehicle = new CAutomobile(carModel, RANDOM_VEHICLE);
pVehicle->AutoPilot.m_nPrevRouteNode = 0; pVehicle->AutoPilot.m_nPrevRouteNode = 0;
@ -2502,7 +2503,7 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
pSwerve, pAccel, pBrake, pHandbrake); pSwerve, pAccel, pBrake, pHandbrake);
return; return;
case MISSION_HELI_FLYTOCOORS: case MISSION_HELI_FLYTOCOORS:
//SteerAIHeliTowardsTargetCoors((CAutomobile*)pVehicle); SteerAIHeliTowardsTargetCoors((CAutomobile*)pVehicle);
return; return;
case MISSION_ATTACKPLAYER: case MISSION_ATTACKPLAYER:
SteerAIBoatWithPhysicsAttackingPlayer(pVehicle, pSwerve, pAccel, pBrake, pHandbrake); SteerAIBoatWithPhysicsAttackingPlayer(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
@ -2656,9 +2657,8 @@ void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli)
else else
speed *= 0.2f; speed *= 0.2f;
} }
CVector2D vecAdvanceThisFrame = vecToTarget; vecToTarget.Normalise();
vecAdvanceThisFrame.Normalise(); CVector2D vecAdvanceThisFrame(vecToTarget * speed);
vecAdvanceThisFrame *= speed;
float resistance = Pow(0.997f, CTimer::GetTimeStep()); float resistance = Pow(0.997f, CTimer::GetTimeStep());
pHeli->m_vecMoveSpeed.x *= resistance; pHeli->m_vecMoveSpeed.x *= resistance;
pHeli->m_vecMoveSpeed.y *= resistance; pHeli->m_vecMoveSpeed.y *= resistance;
@ -2673,9 +2673,55 @@ void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli)
pHeli->AddToMoveSpeed(vecAdvanceThisFrame); pHeli->AddToMoveSpeed(vecAdvanceThisFrame);
else else
pHeli->AddToMoveSpeed(vecSpeedChange * changeMultiplier); pHeli->AddToMoveSpeed(vecSpeedChange * changeMultiplier);
pHeli->SetPosition(pHeli->GetPosition() + CVector(CTimer::GetTimeStep() * pHeli->m_vecMoveSpeed.x, CTimer::GetTimeStep() * pHeli->m_vecMoveSpeed.y, 0.0f)); pHeli->SetPosition(pHeli->GetPosition() + CVector(CTimer::GetTimeStep() * pHeli->GetMoveSpeed().x, CTimer::GetTimeStep() * pHeli->GetMoveSpeed().y, 0.0f));
assert(0); float ZTarget = pHeli->AutoPilot.m_vecDestinationCoors.z;
// This is not finished yet. Heli fields in CAutomobile required if (CTimer::GetTimeInMilliseconds() & 0x800) // switch every ~2 seconds
ZTarget += 2.0f;
float ZSpeedTarget = (ZTarget - pHeli->GetPosition().z) * 0.01f;
float ZSpeedChangeTarget = ZSpeedTarget - pHeli->GetMoveSpeed().z;
float ZSpeedChangeMax = 0.01f * CTimer::GetTimeStep();
if (!pHeli->bHeliDestroyed) {
if (Abs(ZSpeedChangeTarget) < ZSpeedChangeMax)
pHeli->SetMoveSpeed(pHeli->GetMoveSpeed().x, pHeli->GetMoveSpeed().y, ZSpeedTarget);
else if (ZSpeedChangeTarget < 0.0f)
pHeli->AddToMoveSpeed(0.0f, 0.0f, 1.5f * ZSpeedChangeMax);
else
pHeli->AddToMoveSpeed(0.0f, 0.0f, ZSpeedChangeMax);
}
pHeli->SetPosition(pHeli->GetPosition() + CVector(0.0f, 0.0f, CTimer::GetTimeStep() * pHeli->GetMoveSpeed().z));
pHeli->SetTurnSpeed(pHeli->GetTurnSpeed().x, pHeli->GetTurnSpeed().y, pHeli->GetTurnSpeed().z * Pow(0.99f, CTimer::GetTimeStep()));
float ZTurnSpeedTarget;
if (distanceToTarget < 8.0f && pHeli->m_fHeliOrientation < 0.0f)
ZTurnSpeedTarget = 0.0f;
else {
float fAngleTarget = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y) + PI;
if (pHeli->m_fHeliOrientation >= 0.0f)
fAngleTarget = pHeli->m_fHeliOrientation;
while (fAngleTarget < -PI)
fAngleTarget += TWOPI;
while (fAngleTarget > PI)
fAngleTarget -= TWOPI;
if (Abs(fAngleTarget) <= 0.4f)
ZTurnSpeedTarget = 0.0f;
else if (fAngleTarget < 0.0f)
ZTurnSpeedTarget = 0.03f;
else
ZTurnSpeedTarget = -0.03f;
}
float ZTurnSpeedChangeTarget = ZTurnSpeedTarget - pHeli->GetTurnSpeed().z;
pHeli->m_fOrientation += pHeli->GetTurnSpeed().z * CTimer::GetTimeStep();
CVector up;
if (pHeli->bHeliMinimumTilt)
up = CVector(0.5f * pHeli->GetMoveSpeed().x, 0.5f * pHeli->GetMoveSpeed().y, 1.0f);
else
up = CVector(3.0f * pHeli->GetMoveSpeed().x, 3.0f * pHeli->GetMoveSpeed().y, 1.0f);
up.Normalise();
CVector forward(Sin(pHeli->m_fOrientation), Cos(pHeli->m_fOrientation), 0.0f);
CVector right = CrossProduct(up, forward);
forward = CrossProduct(up, right);
pHeli->GetMatrix().GetRight() = right;
pHeli->GetMatrix().GetForward() = forward;
pHeli->GetMatrix().GetUp() = up;
} }
void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake) void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)

View File

@ -4,6 +4,7 @@
#include "ScriptCommands.h" #include "ScriptCommands.h"
#include "AnimBlendAssociation.h" #include "AnimBlendAssociation.h"
#include "Bike.h"
#include "Boat.h" #include "Boat.h"
#include "BulletInfo.h" #include "BulletInfo.h"
#include "Camera.h" #include "Camera.h"
@ -2189,9 +2190,12 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
else { else {
CVehicle* car; CVehicle* car;
// TODO(MIAMI) if (!CModelInfo::IsBikeModel(ScriptParams[0]))
//if (!CModelInfo::IsBikeModel(ScriptParams[0])) car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE);
car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE); else {
car = new CBike(ScriptParams[0], MISSION_VEHICLE);
((CBike*)(car))->bIsStanding = true;
}
CVector pos = *(CVector*)&ScriptParams[1]; CVector pos = *(CVector*)&ScriptParams[1];
if (pos.z <= MAP_Z_LOW_LIMIT) if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
@ -7406,7 +7410,13 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
if (pPed->GetPedState() == PED_EXIT_CAR || pPed->GetPedState() == PED_DRAG_FROM_CAR) { if (pPed->GetPedState() == PED_EXIT_CAR || pPed->GetPedState() == PED_DRAG_FROM_CAR) {
uint8 flags = 0; uint8 flags = 0;
if (pPed->m_pMyVehicle->IsBike()) { if (pPed->m_pMyVehicle->IsBike()) {
//TODO(MIAMI) if (pPed->m_vehEnterType == CAR_DOOR_LF ||
pPed->m_vehEnterType == CAR_DOOR_RF ||
pPed->m_vehEnterType == CAR_WINDSCREEN)
flags = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_RF;
else if (pPed->m_vehEnterType == CAR_DOOR_LR ||
pPed->m_vehEnterType == CAR_DOOR_RR)
flags = CAR_DOOR_FLAG_LR | CAR_DOOR_FLAG_RR;
} }
else { else {
switch (pPed->m_vehEnterType) { switch (pPed->m_vehEnterType) {
@ -8046,7 +8056,8 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle); assert(pVehicle);
if (pVehicle->IsBike()) { if (pVehicle->IsBike()) {
//TODO(MIAMI) CBike* pBike = (CBike*)pBike;
pBike->bWaterTight = ScriptParams[1] != 0;
} }
else if (pVehicle->IsCar()) { else if (pVehicle->IsCar()) {
CAutomobile* pCar = (CAutomobile*)pVehicle; CAutomobile* pCar = (CAutomobile*)pVehicle;
@ -8542,8 +8553,12 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
if (model == -1) if (model == -1)
return 0; return 0;
CVehicle* car; CVehicle* car;
//if (CModelInfo::IsBikeModel(model)) // TODO(MIAMI) if (CModelInfo::IsBikeModel(model)) {
car = new CAutomobile(model, MISSION_VEHICLE); car = new CBike(model, MISSION_VEHICLE);
((CBike*)(car))->bIsStanding = true;
}
else
car = new CAutomobile(model, MISSION_VEHICLE);
CVector pos = *(CVector*)&ScriptParams[0]; CVector pos = *(CVector*)&ScriptParams[0];
pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel(); pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel();
car->SetPosition(pos); car->SetPosition(pos);
@ -9248,8 +9263,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
if (pVehicle->m_vehType == VEHICLE_TYPE_CAR) if (pVehicle->m_vehType == VEHICLE_TYPE_CAR)
((CAutomobile*)pVehicle)->m_fTraction = fTraction; ((CAutomobile*)pVehicle)->m_fTraction = fTraction;
else else
// TODO(MIAMI) ((CBike*)pVehicle)->m_fTraction = fTraction;
//((CBike*)pVehicle)->m_fTraction = fTraction;
return 0; return 0;
} }
case COMMAND_ARE_MEASUREMENTS_IN_METRES: case COMMAND_ARE_MEASUREMENTS_IN_METRES:
@ -10337,8 +10351,21 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle); assert(pVehicle);
bool bIsBurst = false; bool bIsBurst = false;
CBike* pBike = (CBike*)pVehicle;
if (pVehicle->m_vehType == VEHICLE_APPEARANCE_BIKE) { if (pVehicle->m_vehType == VEHICLE_APPEARANCE_BIKE) {
assert("IS_CAR_TYPE_BURST not yet implemented for bikes"); if (ScriptParams[1] == 4) {
for (int i = 0; i < 2; i++) {
if (pBike->m_wheelStatus[i] == WHEEL_STATUS_BURST)
bIsBurst = true;
}
}
else {
if (ScriptParams[1] == 2)
ScriptParams[1] = 0;
if (ScriptParams[1] == 3)
ScriptParams[1] = 1;
bIsBurst = pBike->m_wheelStatus[ScriptParams[1]] == WHEEL_STATUS_BURST;
}
} }
else { else {
CAutomobile* pCar = (CAutomobile*)pVehicle; CAutomobile* pCar = (CAutomobile*)pVehicle;

View File

@ -4270,33 +4270,40 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (method != WEAPONTYPE_DROWNING) { if (method != WEAPONTYPE_DROWNING) {
#ifdef VC_PED_PORTS #ifdef VC_PED_PORTS
if (m_pMyVehicle) { if (m_pMyVehicle) {
bool bDone = false;
// TODO(Miami): Bikes if (m_pMyVehicle->IsBike()) {
if (m_pMyVehicle->IsCar() && m_pMyVehicle->pDriver == this) {
if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) {
m_pMyVehicle->SetStatus(STATUS_PHYSICS);
CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
}
m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
m_pMyVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
m_pMyVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
}
// TODO(MIAMI): argument
if (m_pMyVehicle->CanPedExitCar(false)) {
SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, m_pMyVehicle);
} else {
m_fHealth = 0.0f; m_fHealth = 0.0f;
if (m_pMyVehicle && m_pMyVehicle->pDriver == this) { //CBike::KnockOffRider -- TODO(MIAMI)
SetRadioStation(); bDone = true;
m_pMyVehicle->SetStatus(STATUS_ABANDONED); }
else {
if (m_pMyVehicle->IsCar() && m_pMyVehicle->pDriver == this) {
if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) {
m_pMyVehicle->SetStatus(STATUS_PHYSICS);
CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
}
m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
m_pMyVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
m_pMyVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
} }
SetDie(dieAnim, dieDelta, dieSpeed); // TODO(MIAMI): argument
/* if (m_pMyVehicle->CanPedExitCar(false)) {
if (damagedBy == FindPlayerPed() && damagedBy != this) { SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, m_pMyVehicle);
// TODO(Miami): PlayerInfo stuff }
else {
m_fHealth = 0.0f;
if (m_pMyVehicle && m_pMyVehicle->pDriver == this) {
SetRadioStation();
m_pMyVehicle->SetStatus(STATUS_ABANDONED);
}
SetDie(dieAnim, dieDelta, dieSpeed);
/*
if (damagedBy == FindPlayerPed() && damagedBy != this) {
// TODO(Miami): PlayerInfo stuff
}
*/
} }
*/
} }
for (int i = 0; i < ARRAY_SIZE(m_pMyVehicle->pPassengers); i++) { for (int i = 0; i < ARRAY_SIZE(m_pMyVehicle->pPassengers); i++) {
CPed* passenger = m_pMyVehicle->pPassengers[i]; CPed* passenger = m_pMyVehicle->pPassengers[i];
@ -4314,6 +4321,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
} else { } else {
CDarkel::RegisterKillNotByPlayer(this, method); CDarkel::RegisterKillNotByPlayer(this, method);
} }
if (bDone)
return true;
} }
#endif #endif
m_fHealth = 1.0f; m_fHealth = 1.0f;

View File

@ -3,6 +3,7 @@
#include "CarGen.h" #include "CarGen.h"
#include "Automobile.h" #include "Automobile.h"
#include "Bike.h"
#include "Boat.h" #include "Boat.h"
#include "Camera.h" #include "Camera.h"
#include "CarCtrl.h" #include "CarCtrl.h"
@ -88,7 +89,7 @@ void CCarGenerator::DoInternalProcessing()
pBoat->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle)); pBoat->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
pBoat->SetStatus(STATUS_ABANDONED); pBoat->SetStatus(STATUS_ABANDONED);
pBoat->m_nDoorLock = CARLOCK_UNLOCKED; pBoat->m_nDoorLock = CARLOCK_UNLOCKED;
}else{ // TODO(MIAMI): bikes }else{
bool groundFound = false; bool groundFound = false;
CVector pos = m_vecPos; CVector pos = m_vecPos;
if (pos.z > -100.0f){ if (pos.z > -100.0f){
@ -105,16 +106,23 @@ void CCarGenerator::DoInternalProcessing()
debug("CCarGenerator::DoInternalProcessing - can't find ground z for new car x = %f y = %f \n", m_vecPos.x, m_vecPos.y); debug("CCarGenerator::DoInternalProcessing - can't find ground z for new car x = %f y = %f \n", m_vecPos.x, m_vecPos.y);
return; return;
} }
CAutomobile* pCar = new CAutomobile(mi, PARKED_VEHICLE); if (CModelInfo::IsBikeModel(mi)) {
pVehicle = pCar; CBike* pBike = new CBike(mi, PARKED_VEHICLE);
pCar->bIsStatic = false; pBike->bIsStanding = true;
pCar->bEngineOn = false; pVehicle = pBike;
pos.z += pCar->GetDistanceFromCentreOfMassToBaseOfModel(); }
pCar->SetPosition(pos); else {
pCar->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle)); CAutomobile* pCar = new CAutomobile(mi, PARKED_VEHICLE);
pCar->SetStatus(STATUS_ABANDONED); pVehicle = pCar;
pCar->bLightsOn = false; }
pCar->m_nDoorLock = CARLOCK_UNLOCKED; pVehicle->bIsStatic = false;
pVehicle->bEngineOn = false;
pos.z += pVehicle->GetDistanceFromCentreOfMassToBaseOfModel();
pVehicle->SetPosition(pos);
pVehicle->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
pVehicle->SetStatus(STATUS_ABANDONED);
pVehicle->bLightsOn = false;
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
} }
CWorld::Add(pVehicle); CWorld::Add(pVehicle);