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 "Automobile.h"
#include "Bike.h"
#include "Camera.h"
#include "CarAI.h"
#include "CarGen.h"
@ -345,7 +346,7 @@ CCarCtrl::GenerateOneRandomCar()
if (CModelInfo::IsBoatModel(carModel))
pVehicle = new CBoat(carModel, RANDOM_VEHICLE);
else if (CModelInfo::IsBikeModel(carModel))
return; // TODO(MIAMI): spawn bikes
pVehicle = new CBike(carModel, RANDOM_VEHICLE);
else
pVehicle = new CAutomobile(carModel, RANDOM_VEHICLE);
pVehicle->AutoPilot.m_nPrevRouteNode = 0;
@ -2502,7 +2503,7 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
pSwerve, pAccel, pBrake, pHandbrake);
return;
case MISSION_HELI_FLYTOCOORS:
//SteerAIHeliTowardsTargetCoors((CAutomobile*)pVehicle);
SteerAIHeliTowardsTargetCoors((CAutomobile*)pVehicle);
return;
case MISSION_ATTACKPLAYER:
SteerAIBoatWithPhysicsAttackingPlayer(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
@ -2656,9 +2657,8 @@ void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli)
else
speed *= 0.2f;
}
CVector2D vecAdvanceThisFrame = vecToTarget;
vecAdvanceThisFrame.Normalise();
vecAdvanceThisFrame *= speed;
vecToTarget.Normalise();
CVector2D vecAdvanceThisFrame(vecToTarget * speed);
float resistance = Pow(0.997f, CTimer::GetTimeStep());
pHeli->m_vecMoveSpeed.x *= resistance;
pHeli->m_vecMoveSpeed.y *= resistance;
@ -2673,9 +2673,55 @@ void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli)
pHeli->AddToMoveSpeed(vecAdvanceThisFrame);
else
pHeli->AddToMoveSpeed(vecSpeedChange * changeMultiplier);
pHeli->SetPosition(pHeli->GetPosition() + CVector(CTimer::GetTimeStep() * pHeli->m_vecMoveSpeed.x, CTimer::GetTimeStep() * pHeli->m_vecMoveSpeed.y, 0.0f));
assert(0);
// This is not finished yet. Heli fields in CAutomobile required
pHeli->SetPosition(pHeli->GetPosition() + CVector(CTimer::GetTimeStep() * pHeli->GetMoveSpeed().x, CTimer::GetTimeStep() * pHeli->GetMoveSpeed().y, 0.0f));
float ZTarget = pHeli->AutoPilot.m_vecDestinationCoors.z;
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)

View File

@ -4,6 +4,7 @@
#include "ScriptCommands.h"
#include "AnimBlendAssociation.h"
#include "Bike.h"
#include "Boat.h"
#include "BulletInfo.h"
#include "Camera.h"
@ -2189,9 +2190,12 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
else {
CVehicle* car;
// TODO(MIAMI)
//if (!CModelInfo::IsBikeModel(ScriptParams[0]))
car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE);
if (!CModelInfo::IsBikeModel(ScriptParams[0]))
car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE);
else {
car = new CBike(ScriptParams[0], MISSION_VEHICLE);
((CBike*)(car))->bIsStanding = true;
}
CVector pos = *(CVector*)&ScriptParams[1];
if (pos.z <= MAP_Z_LOW_LIMIT)
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) {
uint8 flags = 0;
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 {
switch (pPed->m_vehEnterType) {
@ -8046,7 +8056,8 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle);
if (pVehicle->IsBike()) {
//TODO(MIAMI)
CBike* pBike = (CBike*)pBike;
pBike->bWaterTight = ScriptParams[1] != 0;
}
else if (pVehicle->IsCar()) {
CAutomobile* pCar = (CAutomobile*)pVehicle;
@ -8542,8 +8553,12 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
if (model == -1)
return 0;
CVehicle* car;
//if (CModelInfo::IsBikeModel(model)) // TODO(MIAMI)
car = new CAutomobile(model, MISSION_VEHICLE);
if (CModelInfo::IsBikeModel(model)) {
car = new CBike(model, MISSION_VEHICLE);
((CBike*)(car))->bIsStanding = true;
}
else
car = new CAutomobile(model, MISSION_VEHICLE);
CVector pos = *(CVector*)&ScriptParams[0];
pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel();
car->SetPosition(pos);
@ -9248,8 +9263,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
if (pVehicle->m_vehType == VEHICLE_TYPE_CAR)
((CAutomobile*)pVehicle)->m_fTraction = fTraction;
else
// TODO(MIAMI)
//((CBike*)pVehicle)->m_fTraction = fTraction;
((CBike*)pVehicle)->m_fTraction = fTraction;
return 0;
}
case COMMAND_ARE_MEASUREMENTS_IN_METRES:
@ -10337,8 +10351,21 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle);
bool bIsBurst = false;
CBike* pBike = (CBike*)pVehicle;
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 {
CAutomobile* pCar = (CAutomobile*)pVehicle;

View File

@ -4270,33 +4270,40 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (method != WEAPONTYPE_DROWNING) {
#ifdef VC_PED_PORTS
if (m_pMyVehicle) {
// TODO(Miami): Bikes
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 {
bool bDone = false;
if (m_pMyVehicle->IsBike()) {
m_fHealth = 0.0f;
if (m_pMyVehicle && m_pMyVehicle->pDriver == this) {
SetRadioStation();
m_pMyVehicle->SetStatus(STATUS_ABANDONED);
//CBike::KnockOffRider -- TODO(MIAMI)
bDone = true;
}
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);
/*
if (damagedBy == FindPlayerPed() && damagedBy != this) {
// TODO(Miami): PlayerInfo stuff
// TODO(MIAMI): argument
if (m_pMyVehicle->CanPedExitCar(false)) {
SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, m_pMyVehicle);
}
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++) {
CPed* passenger = m_pMyVehicle->pPassengers[i];
@ -4314,6 +4321,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
} else {
CDarkel::RegisterKillNotByPlayer(this, method);
}
if (bDone)
return true;
}
#endif
m_fHealth = 1.0f;

View File

@ -3,6 +3,7 @@
#include "CarGen.h"
#include "Automobile.h"
#include "Bike.h"
#include "Boat.h"
#include "Camera.h"
#include "CarCtrl.h"
@ -88,7 +89,7 @@ void CCarGenerator::DoInternalProcessing()
pBoat->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
pBoat->SetStatus(STATUS_ABANDONED);
pBoat->m_nDoorLock = CARLOCK_UNLOCKED;
}else{ // TODO(MIAMI): bikes
}else{
bool groundFound = false;
CVector pos = m_vecPos;
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);
return;
}
CAutomobile* pCar = new CAutomobile(mi, PARKED_VEHICLE);
pVehicle = pCar;
pCar->bIsStatic = false;
pCar->bEngineOn = false;
pos.z += pCar->GetDistanceFromCentreOfMassToBaseOfModel();
pCar->SetPosition(pos);
pCar->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
pCar->SetStatus(STATUS_ABANDONED);
pCar->bLightsOn = false;
pCar->m_nDoorLock = CARLOCK_UNLOCKED;
if (CModelInfo::IsBikeModel(mi)) {
CBike* pBike = new CBike(mi, PARKED_VEHICLE);
pBike->bIsStanding = true;
pVehicle = pBike;
}
else {
CAutomobile* pCar = new CAutomobile(mi, PARKED_VEHICLE);
pVehicle = pCar;
}
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);