Merge pull request #1 from GTAmodding/miami

Miami
This commit is contained in:
Fire_Head 2020-07-29 12:20:02 +03:00 committed by GitHub
commit 52e77c6634
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
267 changed files with 23832 additions and 29992 deletions

View file

@ -19,7 +19,7 @@ struct AnimBlendFrameData
#ifdef PED_SKIN
union {
RwFrame *frame;
RpHAnimStdKeyFrame *hanimFrame;
RpHAnimStdInterpFrame *hanimFrame;
};
int32 nodeID;
#else

View file

@ -238,14 +238,14 @@ AnimAssocDesc aMeleeAnimDescs[] = {
{ ANIM_MELEE_ATTACK_2ND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_MELEE_ATTACK_START, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_MELEE_IDLE_FIGHTMODE, ASSOC_REPEAT },
{ ANIM_WEAPON_SPECIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, // TODO(Miami): Overload that name for melee/swing
{ ANIM_MELEE_ATTACK_FINISH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
};
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_MELEE_IDLE_FIGHTMODE, ASSOC_REPEAT },
{ ANIM_WEAPON_SPECIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, // TODO(Miami): Overload that name for melee/swing
{ ANIM_MELEE_ATTACK_FINISH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
AnimAssocDesc aWeaponAnimDescs[] = {
{ ANIM_WEAPON_FIRE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },

View file

@ -234,6 +234,7 @@ enum AnimationId
ANIM_MELEE_ATTACK_2ND,
ANIM_MELEE_ATTACK_START,
ANIM_MELEE_IDLE_FIGHTMODE,
ANIM_MELEE_ATTACK_FINISH,
ANIM_THROWABLE_THROW = ANIM_WEAPON_FIRE,
ANIM_THROWABLE_THROWU,
ANIM_THROWABLE_START_THROW,

View file

@ -236,7 +236,7 @@ FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
float transBlendAmount = 0.0f;
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
float totalBlendAmount = 0.0f;
RpHAnimStdKeyFrame *xform = frame->hanimFrame;
RpHAnimStdInterpFrame *xform = frame->hanimFrame;
CAnimBlendNode **node;
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
@ -297,7 +297,7 @@ FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void
float curx = 0.0f, cury = 0.0f;
float endx = 0.0f, endy = 0.0f;
bool looped = false;
RpHAnimStdKeyFrame *xform = frame->hanimFrame;
RpHAnimStdInterpFrame *xform = frame->hanimFrame;
CAnimBlendNode **node;
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
@ -381,7 +381,7 @@ FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, vo
CVector cur(0.0f, 0.0f, 0.0f);
CVector end(0.0f, 0.0f, 0.0f);
bool looped = false;
RpHAnimStdKeyFrame *xform = frame->hanimFrame;
RpHAnimStdInterpFrame *xform = frame->hanimFrame;
CAnimBlendNode **node;
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;

View file

@ -169,7 +169,11 @@ RpAnimBlendClumpInitSkinned(RpClump *clump)
for(i = 0; i < numBones; i++){
frames[i].nodeID = HIERNODEID(hier, i);
frames[i].resetPos = boneTab[i];
frames[i].hanimFrame = (RpHAnimStdKeyFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
#ifdef LIBRW
frames[i].hanimFrame = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
#else
frames[i].hanimFrame = (RpHAnimStdInterpFrame*)rtANIMGETINTERPFRAME(hier->currentAnim, i);
#endif
}
clumpData->ForAllFrames(FrameInitCBskin, nil);
clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION;

View file

@ -166,7 +166,7 @@ cAudioManager::PostInitialiseGameSpecificSetup()
m_sMissionAudio.m_nSampleIndex[0] = NO_SAMPLE;
m_sMissionAudio.m_nLoadingStatus[0] = LOADING_STATUS_NOT_LOADED;
m_sMissionAudio.m_nPlayStatus[0] = PLAY_STATUS_STOPPED;
m_sMissionAudio.field_22[0] = 0;
m_sMissionAudio.m_bIsPlaying[0] = false;
m_sMissionAudio.m_bIsPlayed[0] = false;
m_sMissionAudio.m_bPredefinedProperties[0] = true;
m_sMissionAudio.m_nMissionAudioCounter[0] = 0;
@ -175,7 +175,7 @@ cAudioManager::PostInitialiseGameSpecificSetup()
m_sMissionAudio.m_nSampleIndex[1] = NO_SAMPLE;
m_sMissionAudio.m_nLoadingStatus[1] = LOADING_STATUS_NOT_LOADED;
m_sMissionAudio.m_nPlayStatus[1] = PLAY_STATUS_STOPPED;
m_sMissionAudio.field_22[1] = 0;
m_sMissionAudio.m_bIsPlaying[1] = false;
m_sMissionAudio.m_bIsPlayed[1] = false;
m_sMissionAudio.m_bPredefinedProperties[1] = true;
m_sMissionAudio.m_nMissionAudioCounter[1] = 0;
@ -1077,15 +1077,15 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams *params)
}
break;
case 'F':
if (automobile->m_aWheelState[VEHWHEEL_FRONT_LEFT] == WHEEL_STATE_SPINNING)
if (automobile->m_aWheelState[CARWHEEL_FRONT_LEFT] == WHEEL_STATE_SPINNING)
traction += 0.1f;
if (automobile->m_aWheelState[VEHWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING)
if (automobile->m_aWheelState[CARWHEEL_FRONT_RIGHT] == WHEEL_STATE_SPINNING)
traction += 0.1f;
break;
case 'R':
if (automobile->m_aWheelState[VEHWHEEL_FRONT_RIGHT] == WHEEL_STATE_SPINNING)
if (automobile->m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING)
traction += 0.1f;
if (automobile->m_aWheelState[VEHWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)
if (automobile->m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)
traction += 0.1f;
break;
}
@ -1096,7 +1096,7 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams *params)
relativeGearChange =
Min(1.0f, (params->m_fVelocityChange - transmission->Gears[currentGear].fShiftDownVelocity) / transmission->fMaxVelocity * 2.5f);
if (traction == 0.0f && automobile->GetStatus() != STATUS_SIMPLE &&
params->m_fVelocityChange >= transmission->Gears[1].fShiftUpVelocity) {
params->m_fVelocityChange < transmission->Gears[1].fShiftUpVelocity) {
traction = 0.7f;
}
relativeChange = traction * automobile->m_fGasPedalAudio * 0.95f + (1.0f - traction) * relativeGearChange;
@ -1109,7 +1109,7 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams *params)
relativeChange = automobile->m_fGasPedalAudio;
}
modificator = relativeChange;
if (currentGear || !automobile->m_nWheelsOnGround)
if (currentGear != 0 || automobile->m_nWheelsOnGround == 0)
freq = 1200 * currentGear + 18000.f * modificator + 14000;
else
freq = 13000.f * modificator + 14000;
@ -1366,12 +1366,12 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
lostTraction = true;
break;
case 'F':
if ((automobile->m_aWheelState[VEHWHEEL_FRONT_LEFT] != WHEEL_STATE_NORMAL || automobile->m_aWheelState[VEHWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL) &&
(automobile->m_aWheelState[VEHWHEEL_FRONT_RIGHT] != WHEEL_STATE_NORMAL || automobile->m_aWheelState[VEHWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL))
if ((automobile->m_aWheelState[CARWHEEL_FRONT_LEFT] != WHEEL_STATE_NORMAL || automobile->m_aWheelState[CARWHEEL_FRONT_RIGHT] != WHEEL_STATE_NORMAL) &&
(automobile->m_aWheelState[CARWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL || automobile->m_aWheelState[CARWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL))
lostTraction = true;
break;
case 'R':
if ((automobile->m_aWheelState[VEHWHEEL_FRONT_RIGHT] != WHEEL_STATE_NORMAL) || (automobile->m_aWheelState[VEHWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL))
if ((automobile->m_aWheelState[CARWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL) || (automobile->m_aWheelState[CARWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL))
lostTraction = true;
break;
}
@ -1395,7 +1395,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
SampleManager.StopChannel(m_nActiveSamples);
bAccelSampleStopped = true;
}
if (!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction)
if (automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction)
gasPedalAudio = automobile->m_fGasPedalAudio;
else
gasPedalAudio = Min(1.0f, params->m_fVelocityChange / params->m_pTransmission->fMaxReverseVelocity);
@ -1408,8 +1408,8 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
bAccelSampleStopped = true;
}
nCruising = 0;
if (!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction ||
params->m_fVelocityChange >= 0.01f && automobile->m_fGasPedalAudio > 0.2f) {
if (automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction ||
params->m_fVelocityChange < 0.01f && automobile->m_fGasPedalAudio > 0.2f) {
automobile->m_fGasPedalAudio *= 0.6f;
gasPedalAudio = automobile->m_fGasPedalAudio;
}
@ -1429,11 +1429,11 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
CurrentPretendGear = Max(1, currentGear);
} else {
while (nCruising == 0) {
if (accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction ||
if (accelerateState < 150 || automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction ||
currentGear < 2 && velocityChange - automobile->m_fVelocityChangeForAudio < 0.01f) { // here could be used abs
if (!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction) {
if (!automobile->m_nWheelsOnGround && automobile->m_nDriveWheelsOnGround ||
(automobile->bIsHandbrakeOn && !bHandbrakeOnLastFrame || lostTraction && !bLostTractionLastFrame) && automobile->m_nWheelsOnGround) {
if (automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction) {
if (automobile->m_nWheelsOnGround == 0 && automobile->m_nDriveWheelsOnGround != 0 ||
(automobile->bIsHandbrakeOn && !bHandbrakeOnLastFrame || lostTraction && !bLostTractionLastFrame) && automobile->m_nWheelsOnGround != 0) {
automobile->m_fGasPedalAudio *= 0.6f;
}
freqModifier = 0;
@ -1497,11 +1497,11 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
}
if (nCruising != 0) {
bAccelSampleStopped = true;
if (accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction ||
if (accelerateState < 150 || automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction ||
currentGear < params->m_pTransmission->nNumberOfGears - 1) {
nCruising = 0;
} else {
if (accelerateState >= 220 && 0.001f + params->m_fVelocityChange < automobile->m_fVelocityChangeForAudio) {
if (accelerateState >= 220 && params->m_fVelocityChange + 0.001f < automobile->m_fVelocityChangeForAudio) {
if (nCruising < 800)
++nCruising;
} else if (nCruising > 3) {
@ -1520,7 +1520,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
bLostTractionLastFrame = lostTraction;
}
void
bool
cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
{
const float SOUND_INTENSITY = 40.0f;
@ -1532,10 +1532,10 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
float skidVal = 0.0f;
if (params->m_fDistance >= SQR(SOUND_INTENSITY))
return;
return false;
automobile = (CAutomobile *)params->m_pVehicle;
if (!automobile->m_nWheelsOnGround)
return;
if (automobile->m_nWheelsOnGround == 0)
return true;
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
for (int32 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) {
if (automobile->m_aWheelState[i] == WHEEL_STATE_NORMAL || automobile->Damage.GetWheelStatus(i) == WHEEL_STATUS_MISSING)
@ -1575,6 +1575,8 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
emittingVol /= 4;
m_sQueueSample.m_nFrequency = 13000.f * skidVal + 35000.f;
m_sQueueSample.m_nVolume /= 4;
if (m_sQueueSample.m_nVolume == 0)
return true;
break;
case SURFACE_GRAVEL:
case SURFACE_MUD_DRY:
@ -1606,43 +1608,40 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
AddSampleToRequestedQueue();
}
}
return true;
}
float
cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange)
{
tWheelState wheelState;
float relativeVelChange;
float relativeVelChange = 0.0f;
float gasPedalAudio = automobile->m_fGasPedalAudio;
float modificator;
float velChange;
float relativeVel;
wheelState = automobile->m_aWheelState[wheel];
if (wheelState == WHEEL_STATE_SPINNING && gasPedalAudio > 0.4f) {
relativeVelChange = (gasPedalAudio - 0.4f) * 1.25f;
} else if (wheelState == WHEEL_STATE_SKIDDING) {
switch (automobile->m_aWheelState[wheel])
{
case WHEEL_STATE_SPINNING:
if (gasPedalAudio > 0.4f)
relativeVelChange = (gasPedalAudio - 0.4f) * (5.0f / 3.0f) / (4.0f / 3.0f);
break;
case WHEEL_STATE_SKIDDING:
relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
} else if (wheelState == WHEEL_STATE_FIXED) {
modificator = 0.4f;
relativeVelChange = gasPedalAudio;
if (relativeVelChange > 0.4f) {
relativeVelChange = relativeVelChange - 0.4f;
modificator = 5.f / 3.f;
}
break;
case WHEEL_STATE_FIXED:
relativeVel = gasPedalAudio;
if (relativeVel > 0.4f)
relativeVel = (gasPedalAudio - 0.4f) * (5.0f / 3.0f);
velChange = Abs(velocityChange);
if (relativeVelChange > 0.4f)
relativeVelChange = relativeVelChange * modificator;
if (velChange > 0.04f) {
relativeVel = Min(1.0f, velChange / transmission->fMaxVelocity);
} else {
relativeVel = 0.0f;
}
if (relativeVel >= relativeVelChange)
if (velChange > 0.04f)
relativeVelChange = Min(1.0f, velChange / transmission->fMaxVelocity);
if (relativeVel > relativeVelChange)
relativeVelChange = relativeVel;
} else {
relativeVelChange = 0.0f;
break;
default:
break;
}
return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
@ -1651,12 +1650,10 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil
float
cAudioManager::GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange)
{
float relativeVelChange;
float relativeVelChange = 0.0f;
if (automobile->m_aWheelState[wheel] == WHEEL_STATE_SKIDDING)
relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
else
relativeVelChange = 0.0f;
return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
}
@ -2550,10 +2547,7 @@ cAudioManager::ProcessBoatEngine(cVehicleParams *params)
AddSampleToRequestedQueue();
}
if (FindPlayerVehicle() == params->m_pVehicle) {
if (Pads[0].GetAccelerate() <= Pads[0].GetBrake())
padAccelerate = Pads[0].GetBrake();
else
padAccelerate = Pads[0].GetAccelerate();
padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake());
padRelativeAccerate = padAccelerate / 255;
emittingVol = (100.f * padRelativeAccerate) + 15;
m_sQueueSample.m_nFrequency = (3000.f * padRelativeAccerate) + 6000;
@ -2592,10 +2586,7 @@ cAudioManager::ProcessBoatEngine(cVehicleParams *params)
m_sQueueSample.m_bRequireReflection = false;
} else {
if (FindPlayerVehicle() == params->m_pVehicle) {
if (Pads[0].GetAccelerate() <= Pads[0].GetBrake())
padAccelerate = Pads[0].GetBrake();
else
padAccelerate = Pads[0].GetAccelerate();
padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake());
if (padAccelerate <= 20) {
emittingVol = 45 - 45 * padAccelerate / 40;
m_sQueueSample.m_nFrequency = 100 * padAccelerate + 11025;
@ -2671,7 +2662,7 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams *params)
return true;
velocityChange = Min(0.75f, velocityChange);
multiplier = (velocityChange - 0.0005f) * 1.3342f;
multiplier = (velocityChange - 0.0005f) / (1499.0f / 2000.0f);
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
vol = (30.f * multiplier);
m_sQueueSample.m_nVolume = ComputeVolume(vol, 50.f, m_sQueueSample.m_fDistance);
@ -2792,7 +2783,7 @@ cAudioManager::ProcessJumbo(cVehicleParams *params)
DoJumboVolOffset();
position = PlanePathPosition[plane->m_nPlaneId];
if (position <= TakeOffPoint) {
if (plane->m_fSpeed <= 0.10334f) {
if (plane->m_fSpeed <= 0.103344f) {
ProcessJumboTaxi();
return;
}
@ -2804,7 +2795,7 @@ cAudioManager::ProcessJumbo(cVehicleParams *params)
ProcessJumboFlying();
} else {
if (position > LandingPoint) {
if (plane->m_fSpeed > 0.10334f) {
if (plane->m_fSpeed > 0.103344f) {
ProcessJumboDecel(plane);
return;
}
@ -2834,7 +2825,7 @@ cAudioManager::ProcessJumboAccel(CPlane *plane)
float modificator;
if (SetupJumboFlySound(20)) {
modificator = (plane->m_fSpeed - 0.10334f) * 1.676f;
modificator = (plane->m_fSpeed - 0.103344f) * 1.6760077f;
if (modificator > 1.0f)
modificator = 1.0f;
if (SetupJumboRumbleSound(MAX_VOLUME * modificator) && SetupJumboTaxiSound((1.0f - modificator) * 75.f)) {
@ -2887,7 +2878,7 @@ void
cAudioManager::ProcessJumboDecel(CPlane *plane)
{
if (SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) {
const float modificator = Min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f);
const float modificator = Min(1.f, (plane->m_fSpeed - 0.103344f) * 1.6760077f);
SetupJumboEngineSound(MAX_VOLUME * modificator, 6050.f * modificator + 16000);
SetupJumboWhineSound(18, 29500);
}
@ -5645,7 +5636,7 @@ cAudioManager::PreloadMissionAudio(uint8 slot, Const char *name)
m_sMissionAudio.m_nSampleIndex[slot] = missionAudioSfx;
m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_NOT_LOADED;
m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_STOPPED;
m_sMissionAudio.field_22[slot] = 0;
m_sMissionAudio.m_bIsPlaying[slot] = false;
m_sMissionAudio.m_nMissionAudioCounter[slot] = m_nTimeSpent * SampleManager.GetStreamedFileLength(missionAudioSfx) / 1000;
m_sMissionAudio.m_nMissionAudioCounter[slot] *= 4;
m_sMissionAudio.m_bIsPlayed[slot] = false;
@ -5726,10 +5717,12 @@ cAudioManager::ClearMissionAudio(uint8 slot)
m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE;
m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_NOT_LOADED;
m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_STOPPED;
m_sMissionAudio.field_22[slot] = 0;
m_sMissionAudio.m_bIsPlaying[slot] = false;
m_sMissionAudio.m_bIsPlayed[slot] = false;
m_sMissionAudio.m_bPredefinedProperties[slot] = true;
m_sMissionAudio.m_nMissionAudioCounter[slot] = 0;
m_sMissionAudio.m_bIsMobile[slot] = false;
SampleManager.StopStreamedFile(slot + 1);
}
}
@ -5828,7 +5821,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot)
m_sMissionAudio.m_nMissionAudioCounter[slot] = 0;
}
}
} else if (m_sMissionAudio.field_22[slot]) {
} else if (m_sMissionAudio.m_bIsPlaying[slot]) {
if (SampleManager.IsStreamPlaying(slot + 1) || m_nUserPause || m_nPreviousUserPause) {
if (m_nUserPause)
SampleManager.PauseStream(1, slot + 1);
@ -5870,7 +5863,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot)
break;
nCheckPlayingDelay[slot] = 0;
}
m_sMissionAudio.field_22[slot] = 1;
m_sMissionAudio.m_bIsPlaying[slot] = true;
}
break;
default:

View file

@ -169,11 +169,11 @@ cAudioManager::SetEntityStatus(int32 id, uint8 status)
void
cAudioManager::PlayOneShot(int32 index, int16 sound, float vol)
{
static const uint8 OneShotPriority[] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1, 1, 4, 4, 3, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 3, 2, 2, 2, 2, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 3, 1, 1, 1, 9,
2, 2, 0, 0, 0, 0, 3, 3, 5, 1, 1, 1, 1, 3, 4, 7, 6, 6, 6, 6, 1, 3, 4, 3, 4, 2, 1, 3, 5, 4, 6, 6, 1, 3,
1, 1, 1, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const uint8 OneShotPriority[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 2, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1, 1, 1, 4, 4, 4, 3, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 3, 4, 2, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 3, 1, 1, 1, 9, 0, 0, 0, 1, 2, 2, 0, 0, 2, 3, 3, 3, 5, 1, 1,
1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 7, 1, 4, 3, 4, 2, 2, 2, 3, 1, 2, 1, 3, 5, 3, 4, 6, 4, 6, 3, 0, 0, 0, 0, 0,
0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0, 3, 3, 1, 0 };
if (m_bIsInitialised) {
if (index >= 0 && index < NUM_AUDIOENTITIES) {
@ -437,7 +437,7 @@ cAudioManager::ServiceSoundEffects()
}
ClearActiveSamples();
}
m_nActiveSampleQueue = m_nActiveSampleQueue != 1;
m_nActiveSampleQueue = m_nActiveSampleQueue == 1 ? 0 : 1;
ProcessReverb();
ProcessSpecial();
ClearRequestedQueue();
@ -687,7 +687,7 @@ cAudioManager::AddReleasingSounds()
{
bool toProcess[44]; // why not 27?
int8 queue = m_nActiveSampleQueue == 0;
int8 queue = m_nActiveSampleQueue == 0 ? 1 : 0;
for (int32 i = 0; i < m_SampleRequestQueuesStatus[queue]; i++) {
tSound &sample = m_asSamples[queue][m_abSampleQueueIndexTable[queue][i]];

View file

@ -108,7 +108,7 @@ public:
int32 m_nSampleIndex[MISSION_AUDIO_SLOTS];
uint8 m_nLoadingStatus[MISSION_AUDIO_SLOTS];
uint8 m_nPlayStatus[MISSION_AUDIO_SLOTS];
uint8 field_22[MISSION_AUDIO_SLOTS]; // todo find a name
bool m_bIsPlaying[MISSION_AUDIO_SLOTS];
int32 m_nMissionAudioCounter[MISSION_AUDIO_SLOTS];
bool m_bIsPlayed[MISSION_AUDIO_SLOTS];
bool m_bIsMobile[MISSION_AUDIO_SLOTS];
@ -362,7 +362,7 @@ public:
bool ProcessVehicleReverseWarning(cVehicleParams *params);
bool ProcessVehicleRoadNoise(cVehicleParams *params);
bool ProcessVehicleSirenOrAlarm(cVehicleParams *params);
void ProcessVehicleSkidding(cVehicleParams *params);
bool ProcessVehicleSkidding(cVehicleParams *params);
void ProcessWaterCannon(int32);
void ProcessWeather(int32 id);
bool ProcessWetRoadNoise(cVehicleParams *params);

View file

@ -112,25 +112,69 @@ cDMAudio::Get3DProviderName(uint8 id)
return AudioManager.Get3DProviderName(id);
}
// TODO(Miami): Content of this moved to cSampleManager or cAudioManager
int8 cDMAudio::AutoDetect3DProviders(void)
{
if (!AudioManager.IsAudioInitialised())
return -1;
int eax = -1, eax2 = -1, eax3 = -1, ds3dh = -1, ds3ds = -1;
for ( int32 i = 0; i < GetNum3DProvidersAvailable(); i++ )
{
wchar buff[64];
char *name = Get3DProviderName(i);
AsciiToUnicode(name, buff);
char *providername = UnicodeToAscii(buff);
char *providername = Get3DProviderName(i);
strupr(providername);
#if defined(AUDIO_MSS)
if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") )
return i;
#elif defined(AUDIO_OAL)
if ( !strcmp(providername, "OPENAL SOFT") )
return i;
#if defined(AUDIO_OAL)
if (!strcmp(providername, "OPENAL SOFT")) {
SetCurrent3DProvider(i);
if (GetCurrent3DProviderIndex() == i)
return i;
}
#else
if (!strcmp(providername, "CREATIVE LABS EAX 3 (TM)")) {
SetCurrent3DProvider(i);
if (GetCurrent3DProviderIndex() == i) {
eax3 = i;
}
}
if (!strcmp(providername, "CREATIVE LABS EAX 2 (TM)")) {
SetCurrent3DProvider(i);
if (GetCurrent3DProviderIndex() == i)
eax2 = i;
}
if (!strcmp(providername, "CREATIVE LABS EAX (TM)")) {
SetCurrent3DProvider(i);
if (GetCurrent3DProviderIndex() == i)
eax = i;
}
if (!strcmp(providername, "DIRECTSOUND3D HARDWARE SUPPORT")) {
SetCurrent3DProvider(i);
if (GetCurrent3DProviderIndex() == i)
ds3dh = i;
}
if (!strcmp(providername, "DIRECTSOUND3D SOFTWARE EMULATION")) {
SetCurrent3DProvider(i);
if (GetCurrent3DProviderIndex() == i)
ds3ds = i;
}
#endif
}
if (eax3 != -1)
return eax3;
if (eax2 != -1)
return eax2;
if (eax != -1)
return eax;
if (ds3dh != -1)
return ds3dh;
if (ds3ds != -1)
return ds3ds;
return -1;
}

View file

@ -7,6 +7,9 @@
#define AEHANDLE_IS_FAILED(h) ((h)<0)
#define AEHANDLE_IS_OK(h) ((h)>=0)
#define NO_AUDIO_PROVIDER -3
#define AUDIO_PROVIDER_NOT_DETERMINED -99
class cAudioScriptObject;
class CEntity;

View file

@ -714,15 +714,17 @@ cMusicManager::UsesPoliceRadio(CVehicle *veh)
{
switch (veh->GetModelIndex())
{
case MI_FBICAR:
case MI_POLICE:
case MI_ENFORCER:
case MI_PREDATOR:
case MI_VCNMAV:
case MI_POLMAV:
case MI_COASTG:
case MI_RHINO:
case MI_BARRACKS:
return true;
case MI_MRWHOOP:
case MI_HUNTER:
return false;
}
return false;
return veh->UsesSiren();
}
void

View file

@ -27,6 +27,7 @@
#ifndef _WIN32
#define _stricmp strcasecmp
#define _strnicmp strncasecmp
#define _strdup strdup
#endif
#ifdef AUDIO_OAL
@ -71,7 +72,7 @@ ALDeviceList::ALDeviceList()
if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) {
ALDEVICEINFO ALDeviceInfo;
ALDeviceInfo.bSelected = true;
ALDeviceInfo.strDeviceName = actualDeviceName;
ALDeviceInfo.strDeviceName = _strdup(actualDeviceName);
alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion);
alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion);

View file

@ -5,7 +5,11 @@
#include "sampman.h"
#ifdef _WIN32
// TODO: This is due to version difference of 32-bit libmpg123 and 64-bit libmpg123, fix it
#ifndef _WIN64
typedef long ssize_t;
#endif
#pragma comment( lib, "libsndfile-1.lib" )
#pragma comment( lib, "libmpg123.lib" )
#else
@ -173,8 +177,11 @@ public:
size_t size;
int err = mpg123_read(m_pMH, (unsigned char *)buffer, GetBufferSize(), &size);
#if defined(__LP64__) || defined(_WIN64)
assert("We can't handle audio files more then 2 GB yet :shrug:" && (size < UINT32_MAX));
#endif
if (err != MPG123_OK && err != MPG123_DONE) return 0;
return size;
return (uint32)size;
}
};
@ -248,15 +255,11 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF
{
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32)
FILE *test = fopen(filename, "r");
if (!test) {
char *r = (char*)alloca(strlen(filename) + 2);
if (casepath(filename, r))
{
strcpy(m_aFilename, r);
}
char *real = casepath(filename);
if (real) {
strcpy(m_aFilename, real);
free(real);
} else {
fclose(test);
#else
{
#endif

View file

@ -1012,6 +1012,15 @@ cSampleManager::Initialise(void)
}
#ifdef AUDIO_CACHE
TRACE("cache");
FILE *cacheFile = fopen("audio\\sound.cache", "rb");
if (cacheFile) {
fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
fclose(cacheFile);
m_bInitialised = true;
}else {
#endif
TRACE("cdrom");
S32 tatalms;
@ -1168,7 +1177,13 @@ cSampleManager::Initialise(void)
_bUseHDDAudio = false;
}
#endif
#ifdef AUDIO_CACHE
cacheFile = fopen("audio\\sound.cache", "wb");
fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
fclose(cacheFile);
}
#endif
TRACE("stream");
{
for ( int32 i = 0; i < MAX_STREAMS; i++ )

View file

@ -604,7 +604,13 @@ cSampleManager::Initialise(void)
return false;
}
}
#ifdef AUDIO_CACHE
FILE *cacheFile = fopen("audio\\sound.cache", "rb");
if (cacheFile) {
fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
fclose(cacheFile);
} else
#endif
{
for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
@ -622,6 +628,11 @@ cSampleManager::Initialise(void)
else
USERERROR("Can't open '%s'\n", StreamedNameTable[i]);
}
#ifdef AUDIO_CACHE
cacheFile = fopen("audio\\sound.cache", "wb");
fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
fclose(cacheFile);
#endif
}
LoadSampleBank(SAMPLEBANK_MAIN);

View file

@ -113,7 +113,7 @@ enum eSound : uint16
SOUND_PED_BURNING,
SOUND_PED_PLAYER_REACTTOCOP,
SOUND_PED_ARREST_COP,
SOUND_111,
SOUND_PED_MIAMIVICE_EXITING_CAR,
SOUND_PED_COP_HELIPILOTPHRASE,
SOUND_PED_PULLOUTWEAPON,
SOUND_PED_HELI_PLAYER_FOUND,
@ -188,7 +188,7 @@ enum eSound : uint16
SOUND_186, // makes same sound with 40
SOUND_187, // makes same sound with 46
SOUND_MELEE_ATTACK_START,
SOUND_189,
SOUND_SKATING,
SOUND_WEAPON_MINIGUN_ATTACK,
SOUND_WEAPON_MINIGUN_2,
SOUND_WEAPON_MINIGUN_3,

View file

@ -80,7 +80,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
if (FindSwitchDistanceClose(pVehicle) > (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
pVehicle->AutoPilot.m_bIgnorePathfinding) {
pVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_CLOSE;
if (pVehicle->UsesSiren(pVehicle->GetModelIndex()))
if (pVehicle->UsesSiren())
pVehicle->m_bSirenOrAlarm = true;
}
BackToCruisingIfNoWantedLevel(pVehicle);
@ -136,7 +136,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
if (FindSwitchDistanceClose(pVehicle) > (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
pVehicle->AutoPilot.m_bIgnorePathfinding) {
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_CLOSE;
if (pVehicle->UsesSiren(pVehicle->GetModelIndex()))
if (pVehicle->UsesSiren())
pVehicle->m_bSirenOrAlarm = true;
}
BackToCruisingIfNoWantedLevel(pVehicle);
@ -294,7 +294,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
if ((pVehicle->AutoPilot.m_pTargetCar->GetPosition() - pVehicle->GetPosition()).Magnitude2D() < FindSwitchDistanceClose(pVehicle) ||
pVehicle->AutoPilot.m_bIgnorePathfinding){
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKCAR_CLOSE;
if (pVehicle->UsesSiren(pVehicle->GetModelIndex()))
if (pVehicle->UsesSiren())
pVehicle->m_bSirenOrAlarm = true;
}
}else{
@ -540,7 +540,7 @@ void CCarAI::AddPoliceCarOccupants(CVehicle* pVehicle)
return;
pVehicle->bOccupantsHaveBeenGenerated = true;
switch (pVehicle->GetModelIndex()){
case MI_FBICAR:
case MI_FBIRANCH:
case MI_ENFORCER:
pVehicle->SetUpDriver();
for (int i = 0; i < 3; i++)

View file

@ -366,7 +366,7 @@ CCarCtrl::GenerateOneRandomCar()
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
}
if (carModel == MI_FBICAR){
if (carModel == MI_FBIRANCH){
pVehicle->m_currentColour1 = 0;
pVehicle->m_currentColour2 = 0;
}
@ -874,9 +874,9 @@ CCarCtrl::ChoosePoliceCarModel(void)
CStreaming::HasModelLoaded(MI_POLICE))
return ((CGeneral::GetRandomNumber() & 0xF) == 0) ? MI_ENFORCER : MI_POLICE;
if (FindPlayerPed()->m_pWanted->AreFbiRequired() &&
CStreaming::HasModelLoaded(MI_FBICAR) &&
CStreaming::HasModelLoaded(MI_FBIRANCH) &&
CStreaming::HasModelLoaded(MI_FBI))
return MI_FBICAR;
return MI_FBIRANCH;
if (FindPlayerPed()->m_pWanted->AreArmyRequired() &&
CStreaming::HasModelLoaded(MI_RHINO) &&
CStreaming::HasModelLoaded(MI_BARRACKS) &&

View file

@ -27,6 +27,7 @@ int32 CDarkel::KillsNeeded;
int8 CDarkel::InterruptedWeapon;
/*
* TODO: Collect timer/kill counter RGBA colors on top like in Hud/Frontend.
* bStandardSoundAndMessages is a completely beta thing,
* makes game handle sounds & messages instead of SCM (just like in GTA2)
* but it's never been used in the game. Has unused sliding text when frenzy completed etc.
@ -102,7 +103,7 @@ CDarkel::DrawMessages()
if (timeLeft > 4000 || CTimer::GetFrameCounter() & 1) {
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(109.0f), gUString);
CFont::SetColor(CRGBA(150, 100, 255, 255));
CFont::SetColor(CRGBA(0, 207, 133, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(108.0f), gUString);
}
}
@ -110,7 +111,7 @@ CDarkel::DrawMessages()
AsciiToUnicode(gString, gUString);
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(144.0f), gUString);
CFont::SetColor(CRGBA(255, 128, 128, 255));
CFont::SetColor(CRGBA(156, 91, 40, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(143.0f), gUString);
break;
}

View file

@ -155,8 +155,8 @@ CGameLogic::Update()
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverrideHospitalLevel = LEVEL_NONE;
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
CRestart::OverrideHospitalLevel = LEVEL_GENERIC;
CRestart::OverridePoliceStationLevel = LEVEL_GENERIC;
PassTime(720);
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
AfterDeathArrestSetUpShortCutTaxi();
@ -261,8 +261,8 @@ CGameLogic::Update()
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverrideHospitalLevel = LEVEL_NONE;
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
CRestart::OverrideHospitalLevel = LEVEL_GENERIC;
CRestart::OverridePoliceStationLevel = LEVEL_GENERIC;
PassTime(720);
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
AfterDeathArrestSetUpShortCutTaxi();
@ -313,8 +313,8 @@ CGameLogic::Update()
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
CRestart::OverrideHospitalLevel = LEVEL_NONE;
CRestart::OverridePoliceStationLevel = LEVEL_GENERIC;
CRestart::OverrideHospitalLevel = LEVEL_GENERIC;
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
TheCamera.m_fCamShakeForce = 0.0f;

View file

@ -137,6 +137,9 @@ void CGarages::Init(void)
MessageStartTime = 0;
PlayerInGarage = false;
BombsAreFree = false;
#ifdef FIX_BUGS
RespraysAreFree = false;
#endif
CarsCollected = 0;
BankVansCollected = 0;
PoliceCarsCollected = 0;
@ -347,7 +350,7 @@ void CGarage::Update()
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true;
}
else {
CGarages::TriggerMessage("GA_3", -1, 4000, -1); // No more freebies. $1000 to respray!
CGarages::TriggerMessage("GA_3", -1, 4000, -1); // No more freebies. $100 to respray!
m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayFrontEndSound(SOUND_GARAGE_NO_MONEY, 1);
}
@ -400,7 +403,7 @@ void CGarage::Update()
FindPlayerPed()->m_pWanted->Suspend();
}
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE);
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true;
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = false;
#ifdef FIX_BUGS
bool bChangedColour = false;
#else
@ -1096,7 +1099,7 @@ bool CGarage::IsStaticPlayerCarEntirelyInside()
{
if (!FindPlayerVehicle())
return false;
if (!FindPlayerVehicle()->IsCar())
if (!FindPlayerVehicle()->IsCar() && !FindPlayerVehicle()->IsBike())
return false;
if (FindPlayerPed()->GetPedState() != PED_DRIVING)
return false;
@ -1386,6 +1389,7 @@ bool CGarages::IsCarSprayable(CVehicle * pVehicle)
case MI_BARRACKS:
case MI_DODO:
case MI_COACH:
case MI_FBIRANCH:
return false;
default:
break;

View file

@ -269,12 +269,12 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
return true;
case PICKUP_COLLECTABLE1:
CWorld::Players[playerId].m_nCollectedPackages++;
CWorld::Players[playerId].m_nMoney += 1000;
CWorld::Players[playerId].m_nMoney += 100;
if (CWorld::Players[playerId].m_nCollectedPackages == CWorld::Players[playerId].m_nTotalPackages) {
printf("All collectables have been picked up\n");
CGarages::TriggerMessage("CO_ALL", -1, 5000, -1);
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 1000000;
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 100000;
} else
CGarages::TriggerMessage("CO_ONE", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 5000, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);

View file

@ -17,13 +17,13 @@ public:
int8 forwardY;
int8 forwardZ;
int8 wheel;
uint8 gas;
uint8 brake;
int8 gas;
int8 brake;
bool handbrake;
CVector pos;
};
extern char gString[256];;
extern char gString[256];
class CRecordDataForChase
{

View file

@ -170,7 +170,7 @@ static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flyi
void PrintElementsInPtrList(void)
{
for (CPtrNode* node = CWorld::GetBigBuildingList(LEVEL_NONE).first; node; node = node->next) {
for (CPtrNode* node = CWorld::GetBigBuildingList(LEVEL_GENERIC).first; node; node = node->next) {
/* Most likely debug print was present here */
}
}
@ -1143,7 +1143,7 @@ void CReplay::StoreStuffInMem(void)
pWorld1 = new uint8[sizeof(CSector) * NUMSECTORS_X * NUMSECTORS_Y];
memcpy(pWorld1, CWorld::GetSector(0, 0), NUMSECTORS_X * NUMSECTORS_Y * sizeof(CSector));
WorldPtrList = CWorld::GetMovingEntityList().first; // why
BigBuildingPtrList = CWorld::GetBigBuildingList(LEVEL_NONE).first;
BigBuildingPtrList = CWorld::GetBigBuildingList(LEVEL_GENERIC).first;
pPickups = new uint8[sizeof(CPickup) * NUMPICKUPS];
memcpy(pPickups, CPickups::aPickUps, NUMPICKUPS * sizeof(CPickup));
pReferences = new uint8[(sizeof(CReference) * NUMREFERENCES)];
@ -1189,7 +1189,7 @@ void CReplay::RestoreStuffFromMem(void)
delete[] pWorld1;
pWorld1 = nil;
CWorld::GetMovingEntityList().first = WorldPtrList;
CWorld::GetBigBuildingList(LEVEL_NONE).first = BigBuildingPtrList;
CWorld::GetBigBuildingList(LEVEL_GENERIC).first = BigBuildingPtrList;
memcpy(CPickups::aPickUps, pPickups, sizeof(CPickup) * NUMPICKUPS);
delete[] pPickups;
pPickups = nil;
@ -1483,7 +1483,7 @@ void CReplay::StreamAllNecessaryCarsAndPeds(void)
for (int slot = 0; slot < NUM_REPLAYBUFFERS; slot++) {
if (BufferStatus[slot] == REPLAYBUFFER_UNUSED)
continue;
for (int offset = 0; Buffers[slot][offset] != REPLAYPACKET_END; offset += FindSizeOfPacket(Buffers[slot][offset])) {
for (size_t offset = 0; Buffers[slot][offset] != REPLAYPACKET_END; offset += FindSizeOfPacket(Buffers[slot][offset])) {
switch (Buffers[slot][offset]) {
case REPLAYPACKET_VEHICLE:
CStreaming::RequestModel(((tVehicleUpdatePacket*)&Buffers[slot][offset])->mi, 0);
@ -1505,7 +1505,7 @@ void CReplay::FindFirstFocusCoordinate(CVector *coord)
for (int slot = 0; slot < NUM_REPLAYBUFFERS; slot++) {
if (BufferStatus[slot] == REPLAYBUFFER_UNUSED)
continue;
for (int offset = 0; Buffers[slot][offset] != REPLAYPACKET_END; offset += FindSizeOfPacket(Buffers[slot][offset])) {
for (size_t offset = 0; Buffers[slot][offset] != REPLAYPACKET_END; offset += FindSizeOfPacket(Buffers[slot][offset])) {
if (Buffers[slot][offset] == REPLAYPACKET_GENERAL) {
*coord = ((tGeneralPacket*)&Buffers[slot][offset])->player_pos;
return;

View file

@ -24,8 +24,8 @@ uint16 CRestart::NumberOfPoliceRestarts;
void
CRestart::Initialise()
{
OverridePoliceStationLevel = LEVEL_NONE;
OverrideHospitalLevel = LEVEL_NONE;
OverridePoliceStationLevel = LEVEL_GENERIC;
OverrideHospitalLevel = LEVEL_GENERIC;
bFadeInAfterNextArrest = true;
bFadeInAfterNextDeath = true;
OverrideHeading = 0.0f;
@ -86,7 +86,7 @@ CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, f
// find closest point on this level
for (int i = 0; i < NumberOfHospitalRestarts; i++) {
if (CTheZones::GetLevelFromPosition(&HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_NONE ? OverrideHospitalLevel : curlevel)) {
if (CTheZones::GetLevelFromPosition(&HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_GENERIC ? OverrideHospitalLevel : curlevel)) {
float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
if (fMinDist >= dist) {
fMinDist = dist;
@ -133,7 +133,7 @@ CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, flo
// find closest point on this level
for (int i = 0; i < NumberOfPoliceRestarts; i++) {
if (CTheZones::GetLevelFromPosition(&PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_NONE ? OverridePoliceStationLevel : curlevel)) {
if (CTheZones::GetLevelFromPosition(&PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_GENERIC ? OverridePoliceStationLevel : curlevel)) {
float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
if (fMinDist >= dist) {
fMinDist = dist;

View file

@ -67,7 +67,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
eCopType copType = COP_STREET;
switch (pVehicle->GetModelIndex())
{
case MI_FBICAR:
case MI_FBIRANCH:
modelInfoId = MI_FBI;
copType = COP_FBI;
break;
@ -236,7 +236,7 @@ CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2)
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane = 0;
pVehicle->AutoPilot.m_nCruiseSpeed = pVehicle->AutoPilot.m_fMaxTrafficSpeed = 0;
pVehicle->bExtendedRange = true;
if (pVehicle->UsesSiren(pVehicle->GetModelIndex()) && CGeneral::GetRandomNumber() & 1)
if (pVehicle->UsesSiren() && CGeneral::GetRandomNumber() & 1)
pVehicle->m_bSirenOrAlarm = true;
if (pVehicle->GetUp().z > 0.94f) {
CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);

File diff suppressed because it is too large Load diff

View file

@ -1260,7 +1260,7 @@ enum {
COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR_EVEN_MISSION_CAR,
COMMAND_IS_OBJECT_IN_AREA_2D,
COMMAND_IS_OBJECT_IN_AREA_3D,
COMMAND_TASK_TOGGLE_DUCK,
COMMAND_SET_CHAR_CROUCH,
COMMAND_SET_ZONE_CIVILIAN_CAR_INFO,
COMMAND_REQUEST_ANIMATION,
COMMAND_HAS_ANIMATION_LOADED,

View file

@ -39,7 +39,7 @@ extern float fRangePlayerRadius;
extern float fCloseNearClipLimit;
#ifdef FREE_CAM
bool CCamera::bFreeCam;
bool CCamera::bFreeCam = false;
int nPreviousMode = -1;
#endif

View file

@ -193,8 +193,8 @@ CCamera::Init(void)
m_bMusicFading = false;
m_fTimeToFadeMusic = 0.0f;
m_fFLOATingFadeMusic = 0.0f;
m_fMouseAccelHorzntl = 0.003f;
m_fMouseAccelVertical = 0.0025f;
m_fMouseAccelVertical = 0.003f;
m_fMouseAccelHorzntl = 0.0025f;
}
if(FrontEndMenuManager.m_bWantToRestart)
m_fTimeToFadeMusic = 0.0f;
@ -3376,15 +3376,15 @@ CCamera::LoadTrainCamNodes(char const *name)
char token[16] = { 0 };
char filename[16] = { 0 };
uint8 *buf;
int bufpos = 0;
size_t bufpos = 0;
int field = 0;
int tokpos = 0;
char c;
int i;
int len;
size_t len;
strcpy(filename, name);
len = strlen(filename);
len = (int)strlen(filename);
filename[len] = '.';
filename[len+1] = 'd';
filename[len+2] = 'a';
@ -4031,7 +4031,7 @@ bool
CCamera::IsPointVisible(const CVector &center, const CMatrix *mat)
{
RwV3d c;
c = *(RwV3d*)&center;
c = center;
RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix);
if(c.y < CDraw::GetNearClipZ()) return false;
if(c.y > CDraw::GetFarClipZ()) return false;
@ -4046,7 +4046,7 @@ bool
CCamera::IsSphereVisible(const CVector &center, float radius, const CMatrix *mat)
{
RwV3d c;
c = *(RwV3d*)&center;
c = center;
RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix);
if(c.y + radius < CDraw::GetNearClipZ()) return false;
if(c.y - radius > CDraw::GetFarClipZ()) return false;

View file

@ -189,10 +189,11 @@ GetGTA3ImgSize(void)
realpath(gImgNames[0], path);
if (stat(path, &statbuf) == -1) {
// Try case-insensitivity
char *r = (char*)alloca(strlen(gImgNames[0]) + 2);
if (casepath(gImgNames[0], r))
char* real = casepath(gImgNames[0], false);
if (real)
{
realpath(r, path);
realpath(real, path);
free(real);
if (stat(path, &statbuf) != -1)
goto ok;
}
@ -210,7 +211,6 @@ CdStreamShutdown(void)
{
// Destroying semaphores and free(gpReadInfo) will be done at threads
#ifndef ONE_THREAD_PER_CHANNEL
free(gChannelRequestQ.items);
gCdStreamThreadStatus = 2;
sem_post(&gCdStreamSema);
#endif
@ -442,6 +442,7 @@ void *CdStreamThread(void *param)
sem_destroy(&gpReadInfo[i].pDoneSemaphore);
}
sem_destroy(&gCdStreamSema);
free(gChannelRequestQ.items);
#else
sem_destroy(&gpReadInfo[channel].pStartSemaphore);
sem_destroy(&gpReadInfo[channel].pDoneSemaphore);
@ -460,10 +461,11 @@ CdStreamAddImage(char const *path)
// Fix case sensitivity and backslashes.
if (gImgFiles[gNumImages] == -1) {
char *r = (char*)alloca(strlen(path) + 2);
if (casepath(path, r))
char* real = casepath(path, false);
if (real)
{
gImgFiles[gNumImages] = open(r, _gdwCdStreamFlags);
gImgFiles[gNumImages] = open(real, _gdwCdStreamFlags);
free(real);
}
}

View file

@ -23,6 +23,8 @@
#include "Camera.h"
#include "ColStore.h"
//--MIAMI: file done
enum Direction
{
DIR_X_POS,
@ -36,16 +38,14 @@ enum Direction
eLevelName CCollision::ms_collisionInMemory;
CLinkList<CColModel*> CCollision::ms_colModelCache;
//--MIAMI: done
void
CCollision::Init(void)
{
ms_colModelCache.Init(NUMCOLCACHELINKS);
ms_collisionInMemory = LEVEL_NONE;
ms_collisionInMemory = LEVEL_GENERIC;
CColStore::Initialise();
}
//--MIAMI: done
void
CCollision::Shutdown(void)
{
@ -53,7 +53,6 @@ CCollision::Shutdown(void)
CColStore::Shutdown();
}
//--MIAMI: done
void
CCollision::Update(void)
{
@ -70,10 +69,10 @@ GetCollisionInSectorList(CPtrList &list)
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
level = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel()->level;
if(level != LEVEL_NONE)
if(level != LEVEL_GENERIC)
return (eLevelName)level;
}
return LEVEL_NONE;
return LEVEL_GENERIC;
}
//--MIAMI: unused
@ -84,29 +83,29 @@ GetCollisionInSector(CSector &sect)
int level;
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_BUILDINGS]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_BUILDINGS_OVERLAP]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_OBJECTS]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_OBJECTS_OVERLAP]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_DUMMIES]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_DUMMIES_OVERLAP]);
return (eLevelName)level;
}
//--MIAMI: done
void
CCollision::LoadCollisionWhenINeedIt(bool forceChange)
{
}
//--MIAMI: done
void
CCollision::SortOutCollisionAfterLoad(void)
{
CColStore::LoadCollision(TheCamera.GetPosition());
CStreaming::LoadAllRequestedModels(false);
}
void
@ -251,7 +250,7 @@ CCollision::TestVerticalLineBox(const CColLine &line, const CBox &box)
}
bool
CCollision::TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
CCollision::TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
{
float t;
CVector normal;
@ -266,9 +265,9 @@ CCollision::TestLineTriangle(const CColLine &line, const CVector *verts, const C
// find point of intersection
CVector p = line.p0 + (line.p1-line.p0)*t;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
CVector2D vec1, vec2, vec3, vect;
// We do the test in 2D. With the plane direction we
@ -361,15 +360,16 @@ CCollision::TestLineSphere(const CColLine &line, const CColSphere &sph)
bool
CCollision::TestSphereTriangle(const CColSphere &sphere,
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
{
// If sphere and plane don't intersect, no collision
if(Abs(plane.CalcPoint(sphere.center)) > sphere.radius)
float planedist = plane.CalcPoint(sphere.center);
if(Abs(planedist) > sphere.radius)
return false;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
// calculate two orthogonal basis vectors for the triangle
CVector vec2 = vb - va;
@ -393,28 +393,35 @@ CCollision::TestSphereTriangle(const CColSphere &sphere,
int testcase = insideAB + insideAC + insideBC;
float dist = 0.0f;
if(testcase == 1){
switch(testcase){
case 0:
return false; // shouldn't happen
case 1:
// closest to a vertex
if(insideAB) dist = (sphere.center - vc).Magnitude();
else if(insideAC) dist = (sphere.center - vb).Magnitude();
else if(insideBC) dist = (sphere.center - va).Magnitude();
else assert(0);
}else if(testcase == 2){
break;
case 2:
// closest to an edge
// looks like original game as DistToLine manually inlined
if(!insideAB) dist = DistToLine(&va, &vb, &sphere.center);
else if(!insideAC) dist = DistToLine(&va, &vc, &sphere.center);
else if(!insideBC) dist = DistToLine(&vb, &vc, &sphere.center);
else assert(0);
}else if(testcase == 3){
break;
case 3:
// center is in triangle
return true;
}else
assert(0); // front fell off
dist = Abs(planedist);
break;
default:
assert(0);
}
return dist < sphere.radius;
}
//--MIAMI: TODO
bool
CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough, bool ignoreShootThrough)
{
@ -429,25 +436,32 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
if(!TestLineBox(newline, model.boundingBox))
return false;
for(i = 0; i < model.numSpheres; i++)
if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_TRANSPARENT_CLOTH)
if(TestLineSphere(newline, model.spheres[i]))
return true;
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue;
if(TestLineSphere(newline, model.spheres[i]))
return true;
}
for(i = 0; i < model.numBoxes; i++)
if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_TRANSPARENT_CLOTH)
if(TestLineBox(newline, model.boxes[i]))
return true;
for(i = 0; i < model.numBoxes; i++){
if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.boxes[i].surface)) continue;
if(TestLineBox(newline, model.boxes[i]))
return true;
}
CalculateTrianglePlanes(&model);
for(i = 0; i < model.numTriangles; i++)
if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_TRANSPARENT_CLOTH)
if(TestLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i]))
return true;
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
if(TestLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i]))
return true;
}
return false;
}
// TODO: TestPillWithSpheresInColModel, but only called from overloaded CWeapon::FireMelee which isn't used
//
// Process
@ -716,18 +730,19 @@ CCollision::ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CC
return true;
}
//--MIAMI: unused
bool
CCollision::ProcessVerticalLineTriangle(const CColLine &line,
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindist, CStoredCollPoly *poly)
{
float t;
CVector normal;
const CVector &p0 = line.p0;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
// early out bound rect test
if(p0.x < va.x && p0.x < vb.x && p0.x < vc.x) return false;
@ -792,6 +807,7 @@ CCollision::ProcessVerticalLineTriangle(const CColLine &line,
if(CrossProduct2D(vec2-vec1, vect-vec1) < 0.0f) return false;
if(CrossProduct2D(vec3-vec1, vect-vec1) > 0.0f) return false;
if(CrossProduct2D(vec3-vec2, vect-vec2) < 0.0f) return false;
if(t >= mindist) return false;
point.point = p;
point.normal = normal;
point.surfaceA = 0;
@ -817,16 +833,12 @@ CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CCol
return false;
// maybe inlined?
CColTriangle tri;
tri.a = 0;
tri.b = 1;
tri.c = 2;
CColTrianglePlane plane;
plane.Set(poly->verts, tri);
plane.Set(poly->verts[0], poly->verts[1], poly->verts[2]);
const CVector &va = poly->verts[tri.a];
const CVector &vb = poly->verts[tri.b];
const CVector &vc = poly->verts[tri.c];
const CVector &va = poly->verts[0];
const CVector &vb = poly->verts[1];
const CVector &vc = poly->verts[2];
CVector p0 = pos;
CVector p1(pos.x, pos.y, z);
@ -891,8 +903,8 @@ CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CCol
bool
CCollision::ProcessLineTriangle(const CColLine &line ,
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindist)
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindist, CStoredCollPoly *poly)
{
float t;
CVector normal;
@ -910,9 +922,9 @@ CCollision::ProcessLineTriangle(const CColLine &line ,
// find point of intersection
CVector p = line.p0 + (line.p1-line.p0)*t;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
CVector2D vec1, vec2, vec3, vect;
switch(plane.dir){
@ -958,19 +970,26 @@ CCollision::ProcessLineTriangle(const CColLine &line ,
if(CrossProduct2D(vec2-vec1, vect-vec1) < 0.0f) return false;
if(CrossProduct2D(vec3-vec1, vect-vec1) > 0.0f) return false;
if(CrossProduct2D(vec3-vec2, vect-vec2) < 0.0f) return false;
if(t >= mindist) return false;
point.point = p;
point.normal = normal;
point.surfaceA = 0;
point.pieceA = 0;
point.surfaceB = tri.surface;
point.pieceB = 0;
if(poly){
poly->verts[0] = va;
poly->verts[1] = vb;
poly->verts[2] = vc;
poly->valid = true;
}
mindist = t;
return true;
}
bool
CCollision::ProcessSphereTriangle(const CColSphere &sphere,
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindistsq)
{
// If sphere and plane don't intersect, no collision
@ -979,9 +998,9 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
if(Abs(planedist) > sphere.radius || distsq > mindistsq)
return false;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
// calculate two orthogonal basis vectors for the triangle
CVector normal;
@ -1008,25 +1027,33 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
int testcase = insideAB + insideAC + insideBC;
float dist = 0.0f;
CVector p;
if(testcase == 1){
switch(testcase){
case 0:
return false; // shouldn't happen
case 1:
// closest to a vertex
if(insideAB) p = vc;
else if(insideAC) p = vb;
else if(insideBC) p = va;
else assert(0);
dist = (sphere.center - p).Magnitude();
}else if(testcase == 2){
break;
case 2:
// closest to an edge
// looks like original game as DistToLine manually inlined
if(!insideAB) dist = DistToLine(&va, &vb, &sphere.center, p);
else if(!insideAC) dist = DistToLine(&va, &vc, &sphere.center, p);
else if(!insideBC) dist = DistToLine(&vb, &vc, &sphere.center, p);
else assert(0);
}else if(testcase == 3){
break;
case 3:
// center is in triangle
dist = Abs(planedist);
p = sphere.center - normal*planedist;
}else
assert(0); // front fell off
break;
default:
assert(0);
}
if(dist >= sphere.radius || dist*dist >= mindistsq)
return false;
@ -1043,7 +1070,6 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
return true;
}
//--MIAMI: TODO
bool
CCollision::ProcessLineOfSight(const CColLine &line,
const CMatrix &matrix, CColModel &model,
@ -1061,18 +1087,24 @@ CCollision::ProcessLineOfSight(const CColLine &line,
return false;
float coldist = mindist;
for(i = 0; i < model.numSpheres; i++)
if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineSphere(newline, model.spheres[i], point, coldist);
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue;
ProcessLineSphere(newline, model.spheres[i], point, coldist);
}
for(i = 0; i < model.numBoxes; i++)
if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineBox(newline, model.boxes[i], point, coldist);
for(i = 0; i < model.numBoxes; i++){
if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.boxes[i].surface)) continue;
ProcessLineBox(newline, model.boxes[i], point, coldist);
}
CalculateTrianglePlanes(&model);
for(i = 0; i < model.numTriangles; i++)
if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist);
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist);
}
if(coldist < mindist){
point.point = matrix * point.point;
@ -1083,7 +1115,6 @@ CCollision::ProcessLineOfSight(const CColLine &line,
return false;
}
//--MIAMI: TODO
bool
CCollision::ProcessVerticalLine(const CColLine &line,
const CMatrix &matrix, CColModel &model,
@ -1095,31 +1126,33 @@ CCollision::ProcessVerticalLine(const CColLine &line,
// transform line to model space
// Why does the game seem to do this differently than above?
CColLine newline(MultiplyInverse(matrix, line.p0), MultiplyInverse(matrix, line.p1));
newline.p1.x = newline.p0.x;
newline.p1.y = newline.p0.y;
if(!TestVerticalLineBox(newline, model.boundingBox))
if(!TestLineBox(newline, model.boundingBox))
return false;
// BUG? is IsSeeThroughVertical really the right thing? also not checking shoot through
float coldist = mindist;
for(i = 0; i < model.numSpheres; i++)
if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineSphere(newline, model.spheres[i], point, coldist);
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThroughVertical(model.spheres[i].surface)) continue;
ProcessLineSphere(newline, model.spheres[i], point, coldist);
}
for(i = 0; i < model.numBoxes; i++)
if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineBox(newline, model.boxes[i], point, coldist);
for(i = 0; i < model.numBoxes; i++){
if(ignoreSeeThrough && IsSeeThroughVertical(model.boxes[i].surface)) continue;
ProcessLineBox(newline, model.boxes[i], point, coldist);
}
CalculateTrianglePlanes(&model);
TempStoredPoly.valid = false;
for(i = 0; i < model.numTriangles; i++)
if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessVerticalLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist, &TempStoredPoly);
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThroughVertical(model.triangles[i].surface)) continue;
ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist, &TempStoredPoly);
}
if(coldist < mindist){
point.point = matrix * point.point;
point.normal = Multiply3x3(matrix, point.normal);
if(poly && TempStoredPoly.valid){
if(TempStoredPoly.valid && poly){
*poly = TempStoredPoly;
poly->verts[0] = matrix * poly->verts[0];
poly->verts[1] = matrix * poly->verts[1];
@ -1353,6 +1386,15 @@ CCollision::CalculateTrianglePlanes(CColModel *model)
}
}
void
CCollision::RemoveTrianglePlanes(CColModel *model)
{
if(model->trianglePlanes){
ms_colModelCache.Remove(model->GetLinkPtr());
model->RemoveTrianglePlanes();
}
}
void
CCollision::DrawColModel(const CMatrix &mat, const CColModel &colModel)
{
@ -1575,15 +1617,75 @@ CCollision::DrawColModel(const CMatrix &mat, const CColModel &colModel)
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
}
static void
GetSurfaceColor(uint8 surf, uint8 &r, uint8 &g, uint8 &b)
{
// game doesn't do this
r = 255;
g = 128;
b = 0;
switch(CSurfaceTable::GetAdhesionGroup(surf)){
case ADHESIVE_RUBBER:
r = 255;
g = 0;
b = 0;
break;
case ADHESIVE_HARD:
r = 255;
g = 255;
b = 128;
break;
case ADHESIVE_ROAD:
r = 128;
g = 128;
b = 128;
break;
case ADHESIVE_LOOSE:
r = 0;
g = 255;
b = 0;
break;
case ADHESIVE_SAND:
r = 255;
g = 128;
b = 128;
break;
case ADHESIVE_WET:
r = 0;
g = 0;
b = 255;
break;
}
if(surf == SURFACE_SAND || surf == SURFACE_SAND_BEACH){
r = 255;
g = 255;
b = 0;
}
float f = (surf & 0xF)/32.0f + 0.5f;
r *= f;
g *= f;
b *= f;
if(surf == SURFACE_TRANSPARENT_CLOTH || surf == SURFACE_METAL_CHAIN_FENCE ||
surf == SURFACE_TRANSPARENT_STONE || surf == SURFACE_SCAFFOLD_POLE)
if(CTimer::GetFrameCounter() & 1){
r = 0;
g = 0;
b = 0;
}
}
void
CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id)
{
int i;
int s;
float f;
CVector verts[8];
CVector min, max;
int r, g, b;
uint8 r, g, b;
RwImVertexIndex *iptr;
RwIm3DVertex *vptr;
@ -1602,53 +1704,8 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
verts[1] = mat * verts[1];
verts[2] = mat * verts[2];
// game doesn't do this
r = 255;
g = 128;
b = 0;
s = colModel.triangles[i].surface;
f = (s & 0xF)/32.0f + 0.5f;
switch(CSurfaceTable::GetAdhesionGroup(s)){
case ADHESIVE_RUBBER:
r = f * 255.0f;
g = 0;
b = 0;
break;
case ADHESIVE_HARD:
r = f*255.0f;
g = f*255.0f;
b = f*128.0f;
break;
case ADHESIVE_ROAD:
r = f*128.0f;
g = f*128.0f;
b = f*128.0f;
break;
case ADHESIVE_LOOSE:
r = 0;
g = f * 255.0f;
b = 0;
break;
case ADHESIVE_WET:
r = 0;
g = 0;
b = f * 255.0f;
break;
default:
// this doesn't make much sense
r *= f;
g *= f;
b *= f;
}
if(s == SURFACE_TRANSPARENT_CLOTH || s == SURFACE_METAL_CHAIN_FENCE ||
s == SURFACE_TRANSPARENT_STONE || s == SURFACE_SCAFFOLD_POLE)
if(CTimer::GetFrameCounter() & 1){
r = 0;
g = 0;
b = 0;
}
GetSurfaceColor(s, r, g, b);
if(s > SURFACE_METAL_GATE){
r = CGeneral::GetRandomNumber();
@ -1689,47 +1746,7 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
verts[7] = mat * CVector(max.x, max.y, max.z);
s = colModel.boxes[i].surface;
f = (s & 0xF)/32.0f + 0.5f;
switch(CSurfaceTable::GetAdhesionGroup(s)){
case ADHESIVE_RUBBER:
r = f * 255.0f;
g = 0;
b = 0;
break;
case ADHESIVE_HARD:
r = f*255.0f;
g = f*255.0f;
b = f*128.0f;
break;
case ADHESIVE_ROAD:
r = f*128.0f;
g = f*128.0f;
b = f*128.0f;
break;
case ADHESIVE_LOOSE:
r = 0;
g = f * 255.0f;
b = 0;
break;
case ADHESIVE_WET:
r = 0;
g = 0;
b = f * 255.0f;
break;
default:
// this doesn't make much sense
r *= f;
g *= f;
b *= f;
}
if(s == SURFACE_TRANSPARENT_CLOTH || s == SURFACE_METAL_CHAIN_FENCE ||
s == SURFACE_TRANSPARENT_STONE || s == SURFACE_SCAFFOLD_POLE)
if(CTimer::GetFrameCounter() & 1){
r = 0;
g = 0;
b = 0;
}
GetSurfaceColor(s, r, g, b);
RenderBuffer::StartStoring(36, 8, &iptr, &vptr);
RwIm3DVertexSetRGBA(&vptr[0], r, g, b, 255);
@ -1833,7 +1850,7 @@ CColLine::Set(const CVector &p0, const CVector &p1)
}
void
CColTriangle::Set(const CVector *, int a, int b, int c, uint8 surf, uint8 piece)
CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uint8 piece)
{
this->a = a;
this->b = b;
@ -1842,12 +1859,8 @@ CColTriangle::Set(const CVector *, int a, int b, int c, uint8 surf, uint8 piece)
}
void
CColTrianglePlane::Set(const CVector *v, CColTriangle &tri)
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
{
const CVector &va = v[tri.a];
const CVector &vb = v[tri.b];
const CVector &vc = v[tri.c];
normal = CrossProduct(vc-va, vb-va);
normal.Normalise();
dist = DotProduct(normal, va);
@ -1905,6 +1918,7 @@ CColModel::RemoveCollisionVolumes(void)
RwFree(boxes);
RwFree(vertices);
RwFree(triangles);
CCollision::RemoveTrianglePlanes(this);
}
numSpheres = 0;
numLines = 0;
@ -1950,7 +1964,7 @@ CColModel::GetLinkPtr(void)
void
CColModel::GetTrianglePoint(CVector &v, int i) const
{
v = vertices[i];
v = vertices[i].Get();
}
CColModel&
@ -2029,7 +2043,7 @@ CColModel::operator=(const CColModel &other)
if(vertices)
RwFree(vertices);
if(numVerts){
vertices = (CVector*)RwMalloc(numVerts*sizeof(CVector));
vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector));
for(i = 0; i < numVerts; i++)
vertices[i] = other.vertices[i];
}

View file

@ -10,6 +10,19 @@
#define MAX_COLLISION_POINTS 32
#endif
struct CompressedVector
{
#ifdef COMPRESSED_COL_VECTORS
int16 x, y, z;
CVector Get(void) const { return CVector(x, y, z)/128.0f; };
void Set(float x, float y, float z) { this->x = x*128.0f; this->y = y*128.0f; this->z = z*128.0f; };
#else
float x, y, z;
CVector Get(void) const { return CVector(x, y, z); };
void Set(float x, float y, float z) { this->x = x; this->y = y; this->z = z; };
#endif
};
struct CSphere
{
CVector center;
@ -63,7 +76,7 @@ struct CColTriangle
uint16 c;
uint8 surface;
void Set(const CVector *v, int a, int b, int c, uint8 surf, uint8 piece);
void Set(const CompressedVector *v, int a, int b, int c, uint8 surf, uint8 piece);
};
struct CColTrianglePlane
@ -72,7 +85,8 @@ struct CColTrianglePlane
float dist;
uint8 dir;
void Set(const CVector *v, CColTriangle &tri);
void Set(const CVector &va, const CVector &vb, const CVector &vc);
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
void GetNormal(CVector &n) const { n = normal; }
float GetNormalX() const { return normal.x; }
float GetNormalY() const { return normal.y; }
@ -116,7 +130,7 @@ struct CColModel
CColSphere *spheres;
CColLine *lines;
CColBox *boxes;
CVector *vertices;
CompressedVector *vertices;
CColTriangle *triangles;
CColTrianglePlane *trianglePlanes;
@ -148,24 +162,25 @@ public:
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
static void CalculateTrianglePlanes(CColModel *model);
static void RemoveTrianglePlanes(CColModel *model);
// all these return true if there's a collision
static bool TestSphereSphere(const CSphere &s1, const CSphere &s2);
static bool TestSphereBox(const CSphere &sph, const CBox &box);
static bool TestLineBox(const CColLine &line, const CBox &box);
static bool TestVerticalLineBox(const CColLine &line, const CBox &box);
static bool TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineSphere(const CColLine &line, const CColSphere &sph);
static bool TestSphereTriangle(const CColSphere &sphere, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestSphereTriangle(const CColSphere &sphere, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough, bool ignoreShootThrough);
static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq);
static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq);
static bool ProcessLineBox(const CColLine &line, const CColBox &box, CColPoint &point, float &mindist);
static bool ProcessVerticalLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly);
static bool ProcessLineTriangle(const CColLine &line , const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist);
static bool ProcessVerticalLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly);
static bool ProcessLineTriangle(const CColLine &line , const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly = nil);
static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist);
static bool ProcessSphereTriangle(const CColSphere &sph, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
static bool ProcessSphereTriangle(const CColSphere &sph, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough);
static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough, CStoredCollPoly *poly);
static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists);

View file

@ -131,6 +131,7 @@ void CControllerConfigManager::SaveSettings(int32 file)
void CControllerConfigManager::LoadSettings(int32 file)
{
bool bValid = true;
int nVersion = 0;
if (file)
{
@ -139,11 +140,13 @@ void CControllerConfigManager::LoadSettings(int32 file)
if (!strncmp(buff, TopLineEmptyFile, sizeof(TopLineEmptyFile)-1))
bValid = false;
else
else {
CFileMgr::Seek(file, 0, 0);
CFileMgr::Read(file, (char*)&nVersion, sizeof(nVersion));
}
}
if (bValid)
if (bValid && nVersion >= 3)
{
ControlsManager.MakeControllerActionsBlank();
@ -202,6 +205,8 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction (GO_BACK, rsDOWN, KEYBOARD);
SetControllerKeyAssociatedWithAction (GO_BACK, 'S', OPTIONAL_EXTRA);
SetControllerKeyAssociatedWithAction (NETWORK_TALK, 'T', KEYBOARD);
SetControllerKeyAssociatedWithAction (PED_LOOKBEHIND, rsPADEND, KEYBOARD);
SetControllerKeyAssociatedWithAction (PED_LOOKBEHIND, rsCAPSLK, OPTIONAL_EXTRA);
@ -436,6 +441,7 @@ void CControllerConfigManager::InitialiseControllerActionNameArray()
SETACTIONNAME(PED_SPRINT);
SETACTIONNAME(PED_CYCLE_TARGET_LEFT);
SETACTIONNAME(PED_CYCLE_TARGET_RIGHT);
SETACTIONNAME(PED_LOCK_TARGET); // duplicate
SETACTIONNAME(PED_CENTER_CAMERA_BEHIND_PLAYER);
SETACTIONNAME(VEHICLE_LOOKBEHIND);
SETACTIONNAME(PED_DUCK);
@ -1808,23 +1814,23 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
{
switch (action)
{
case CAMERA_CHANGE_VIEW_ALL_SITUATIONS:
case PED_FIREWEAPON:
case GO_LEFT:
case GO_RIGHT:
case CAMERA_CHANGE_VIEW_ALL_SITUATIONS:
case NETWORK_TALK:
case SWITCH_DEBUG_CAM_ON:
case TOGGLE_DPAD:
case SWITCH_DEBUG_CAM_ON:
case TAKE_SCREEN_SHOT:
case SHOW_MOUSE_POINTER_TOGGLE:
return ACTIONTYPE_COMMON;
break;
case PED_LOOKBEHIND:
case PED_CYCLE_WEAPON_LEFT:
case PED_CYCLE_WEAPON_RIGHT:
case PED_CYCLE_WEAPON_LEFT:
case PED_JUMPING:
case PED_SPRINT:
case PED_LOOKBEHIND:
case PED_DUCK:
case PED_ANSWER_PHONE:
case PED_CYCLE_TARGET_LEFT:
@ -1853,13 +1859,13 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
return ACTIONTYPE_VEHICLE_3RDPERSON;
break;
case PED_LOCK_TARGET:
case GO_FORWARD:
case GO_BACK:
case PED_1RST_PERSON_LOOK_LEFT:
case PED_1RST_PERSON_LOOK_RIGHT:
case PED_1RST_PERSON_LOOK_DOWN:
case PED_LOCK_TARGET:
case PED_1RST_PERSON_LOOK_UP:
case PED_1RST_PERSON_LOOK_DOWN:
return ACTIONTYPE_1RST3RDPERSON;
break;

View file

@ -61,6 +61,7 @@ enum e_ControllerAction
SWITCH_DEBUG_CAM_ON,
TAKE_SCREEN_SHOT,
SHOW_MOUSE_POINTER_TOGGLE,
UNKNOWN_ACTION,
MAX_CONTROLLERACTIONS,
};

View file

@ -30,7 +30,8 @@ CDirectory::ReadDirFile(const char *filename)
bool
CDirectory::WriteDirFile(const char *filename)
{
int fd, n;
int fd;
size_t n;
fd = CFileMgr::OpenFileForWriting(filename);
n = CFileMgr::Write(fd, (char*)entries, numEntries*sizeof(DirectoryInfo));
CFileMgr::CloseFile(fd);

View file

@ -189,7 +189,7 @@ CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event)
// --MIAMI: Done
void
CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCare)
CEventList::ReportCrimeForEvent(eEventType type, size_t crimeId, bool copsDontCare)
{
eCrimeType crime;
switch(type){
@ -227,10 +227,10 @@ CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCar
if(CWanted::WorkOutPolicePresence(playerCoors, 14.0f) != 0 ||
CGame::germanGame && (crime == CRIME_SHOOT_PED || crime == CRIME_SHOOT_COP || crime == CRIME_COP_BURNED || crime == CRIME_VEHICLE_BURNED)){
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(crime, playerPedCoors, crimeId, copsDontCare);
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(crime, playerPedCoors, (uint32)crimeId, copsDontCare);
FindPlayerPed()->m_pWanted->SetWantedLevelNoDrop(1);
}else
FindPlayerPed()->m_pWanted->RegisterCrime(crime, playerPedCoors, crimeId, copsDontCare);
FindPlayerPed()->m_pWanted->RegisterCrime(crime, playerPedCoors, (uint32)crimeId, copsDontCare);
if(type == EVENT_ASSAULT_POLICE)
FindPlayerPed()->SetWantedLevelNoDrop(1);

View file

@ -61,7 +61,7 @@ public:
static bool GetEvent(eEventType type, int32 *event);
static void ClearEvent(int32 event);
static bool FindClosestEvent(eEventType type, CVector posn, int32 *event);
static void ReportCrimeForEvent(eEventType type, int32, bool);
static void ReportCrimeForEvent(eEventType type, size_t, bool);
};
extern CEvent gaEvent[NUMEVENTS];

View file

@ -106,7 +106,9 @@ CFileLoader::LoadLevel(const char *filename)
LoadingScreenLoadingFile(line + 4);
LoadScene(line + 4);
}else if(strncmp(line, "SPLASH", 6) == 0){
#ifndef DISABLE_LOADING_SCREEN
LoadSplash(GetRandomSplashScreen());
#endif
}else if(strncmp(line, "CDIMAGE", 7) == 0){
CdStreamAddImage(line + 8);
}
@ -324,13 +326,13 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
int32 numVertices = *(int16*)buf;
buf += 4;
if(numVertices > 0){
model.vertices = (CVector*)RwMalloc(numVertices*sizeof(CVector));
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector));
for(i = 0; i < numVertices; i++){
model.vertices[i] = *(CVector*)buf;
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
#if 0
if(Abs(model.vertices[i].x) >= 256.0f ||
Abs(model.vertices[i].y) >= 256.0f ||
Abs(model.vertices[i].z) >= 256.0f)
if(Abs(*(float*)buf) >= 256.0f ||
Abs(*(float*)(buf+4)) >= 256.0f ||
Abs(*(float*)(buf+8)) >= 256.0f)
printf("%s:Collision volume too big\n", modelname);
#endif
buf += 12;
@ -393,6 +395,16 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
return atomic;
}
#ifdef LIBRW
void
InitClump(RpClump *clump)
{
RpClumpForAllAtomics(clump, ConvertPlatformAtomic, nil);
}
#else
#define InitClump(clump)
#endif
void
CFileLoader::LoadModelFile(const char *filename)
{
@ -404,6 +416,7 @@ CFileLoader::LoadModelFile(const char *filename)
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
clump = RpClumpStreamRead(stream);
if(clump){
InitClump(clump);
RpClumpForAllAtomics(clump, FindRelatedModelInfoCB, clump);
RpClumpDestroy(clump);
}
@ -429,6 +442,7 @@ CFileLoader::LoadClumpFile(const char *filename)
GetNameAndLOD(nodename, name, &n);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){
InitClump(clump);
assert(mi->IsClump());
mi->SetClump(clump);
}else
@ -449,6 +463,7 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id)
clump = RpClumpStreamRead(stream);
if(clump == nil)
return false;
InitClump(clump);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
mi->SetClump(clump);
return true;
@ -476,6 +491,7 @@ CFileLoader::FinishLoadClumpFile(RwStream *stream, uint32 id)
clump = RpClumpGtaStreamRead2(stream);
if(clump){
InitClump(clump);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
mi->SetClump(clump);
return true;
@ -496,6 +512,7 @@ CFileLoader::LoadAtomicFile(RwStream *stream, uint32 id)
clump = RpClumpStreamRead(stream);
if(clump == nil)
return false;
InitClump(clump);
gpRelatedModelInfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
RpClumpForAllAtomics(clump, SetRelatedModelInfoCB, clump);
RpClumpDestroy(clump);
@ -531,6 +548,8 @@ CFileLoader::LoadAtomicFile2Return(const char *filename)
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
clump = RpClumpStreamRead(stream);
if(clump)
InitClump(clump);
RwStreamClose(stream, nil);
return clump;
}
@ -1260,7 +1279,7 @@ CFileLoader::LoadOcclusionVolume(const char *line)
&x, &y, &z,
&width, &length, &height,
&angle);
COcclusion::AddOne(x, y, z, width, length, z + height/2.0f, angle);
COcclusion::AddOne(x, y, z + height/2.0f, width, length, height, angle);
}

View file

@ -4,6 +4,7 @@
#include <direct.h>
#endif
#include "common.h"
#include "crossplatform.h"
#include "FileMgr.h"
@ -31,19 +32,16 @@ static myFILE myfiles[NUMFILES];
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include "crossplatform.h"
#define _getcwd getcwd
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
void mychdir(char const *path)
{
char *r = (char*)alloca(strlen(path) + 2);
if (casepath(path, r))
{
char* r = casepath(path, false);
if (r) {
chdir(r);
}
else
{
free(r);
} else {
errno = ENOENT;
}
}
@ -73,30 +71,7 @@ found:
*p++ = 'b';
*p = '\0';
#if !defined(_WIN32)
char *newPath = strdup(filename);
// Normally casepath() fixes backslashes, but if the mode is sth other than r/rb it will create new file with backslashes on linux, so fix backslashes here
char *nextBs;
while(nextBs = strstr(newPath, "\\")){
*nextBs = '/';
}
#else
const char *newPath = filename;
#endif
myfiles[fd].file = fopen(newPath, realmode);
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32)
if (!myfiles[fd].file) {
char *r = (char*)alloca(strlen(newPath) + 2);
if (casepath(newPath, r))
{
myfiles[fd].file = fopen(r, realmode);
}
}
free(newPath);
#endif
myfiles[fd].file = fcaseopen(filename, realmode);
if(myfiles[fd].file == nil)
return 0;
return fd;
@ -163,7 +138,7 @@ myfgets(char *buf, int len, int fd)
return buf;
}
static int
static size_t
myfread(void *buf, size_t elt, size_t n, int fd)
{
if(myfiles[fd].isText){
@ -184,7 +159,7 @@ myfread(void *buf, size_t elt, size_t n, int fd)
return fread(buf, elt, n, myfiles[fd].file);
}
static int
static size_t
myfwrite(void *buf, size_t elt, size_t n, int fd)
{
if(myfiles[fd].isText){
@ -265,11 +240,11 @@ CFileMgr::SetDirMyDocuments(void)
mychdir(_psGetUserFilesFolder());
}
int
size_t
CFileMgr::LoadFile(const char *file, uint8 *buf, int unused, const char *mode)
{
int fd;
int n, len;
size_t n, len;
fd = myfopen(file, mode);
if(fd == 0)
@ -298,14 +273,14 @@ CFileMgr::OpenFileForWriting(const char *file)
return OpenFile(file, "wb");
}
int
CFileMgr::Read(int fd, const char *buf, int len)
size_t
CFileMgr::Read(int fd, const char *buf, size_t len)
{
return myfread((void*)buf, 1, len, fd);
}
int
CFileMgr::Write(int fd, const char *buf, int len)
size_t
CFileMgr::Write(int fd, const char *buf, size_t len)
{
return myfwrite((void*)buf, 1, len, fd);
}

View file

@ -9,12 +9,12 @@ public:
static void ChangeDir(const char *dir);
static void SetDir(const char *dir);
static void SetDirMyDocuments(void);
static int LoadFile(const char *file, uint8 *buf, int unused, const char *mode);
static size_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode);
static int OpenFile(const char *file, const char *mode);
static int OpenFile(const char *file) { return OpenFile(file, "rb"); }
static int OpenFileForWriting(const char *file);
static int Read(int fd, const char *buf, int len);
static int Write(int fd, const char *buf, int len);
static size_t Read(int fd, const char *buf, size_t len);
static size_t Write(int fd, const char *buf, size_t len);
static bool Seek(int fd, int offset, int whence);
static bool ReadLine(int fd, char *buf, int len);
static int CloseFile(int fd);

File diff suppressed because it is too large Load diff

View file

@ -66,20 +66,23 @@
#define PLAYERSETUP_LIST_BODY_TOP 47
#define PLAYERSETUP_ROW_HEIGHT 9
#define STATS_SLIDE_Y_PER_SECOND 30.0f
#define STATS_ROW_HEIGHT 20.0f
#define STATS_ROW_X_MARGIN 50.0f
#define STATS_BOTTOM_MARGIN 135.0f
#define STATS_TOP_MARGIN 40.0f
#define STATS_TOP_DIMMING_AREA_LENGTH (93.0f - STATS_TOP_MARGIN)
#define STATS_BOTTOM_DIMMING_AREA_LENGTH 55.0f
#define STATS_PUT_BACK_TO_BOTTOM_Y 50.0f
#define STATS_RATING_X 24.0f
#define STATS_RATING_Y 20.0f
#define STATS_ROW_HEIGHT 17.0f
#define STATS_ROW_LEFT_MARGIN 110.0f
#define STATS_ROW_RIGHT_MARGIN 113.0f
#define STATS_TOP_Y 135.0f // Just faded in
#define STATS_BOTTOM_Y 300.0f // Starts to fade out after that
#define STATS_FADING_AREA_LENGTH 50.0f
#define STATS_VISIBLE_START_Y (STATS_TOP_Y - 10.f)
#define STATS_VISIBLE_END_Y (STATS_BOTTOM_Y + 21.f)
#define STATS_RATING_X 320.0f
#define STATS_RATING_Y_1 85.0f
#define STATS_RATING_Y_2 110.0f
#define BRIEFS_TOP_MARGIN 40.0f
#define BRIEFS_LINE_X 50.0f
#define BRIEFS_LINE_HEIGHT 60.0f
#define BRIEFS_TOP_MARGIN 140.0f
#define BRIEFS_BOTTOM_MARGIN 280.0f
#define BRIEFS_LINE_X 100.0f
#define BRIEFS_LINE_HEIGHT 20.0f
#define BRIEFS_LINE_SPACING 10.0f
#define CONTSETUP_STANDARD_ROW_HEIGHT 10.7f
#define CONTSETUP_CLASSIC_ROW_HEIGHT 9.0f
@ -262,17 +265,9 @@ enum eMenuAction
MENUACTION_DYNAMICACOUSTIC,
MENUACTION_MOUSESTEER,
MENUACTION_UNK110,
#ifdef MORE_LANGUAGES
MENUACTION_LANG_PL,
MENUACTION_LANG_RUS,
MENUACTION_LANG_JAP,
#endif
#ifdef IMPROVED_VIDEOMODE
MENUACTION_SCREENMODE,
#endif
#ifdef FREE_CAM
MENUACTION_FREECAM,
#endif
#ifdef LEGACY_MENU_OPTIONS
MENUACTION_CTRLVIBRATION,
MENUACTION_CTRLCONFIG,
@ -477,10 +472,10 @@ public:
int8 m_nPrefsAudio3DProviderIndex;
int8 m_PrefsSpeakers;
int8 m_PrefsDMA;
uint8 m_PrefsSfxVolume;
uint8 m_PrefsMusicVolume;
int8 m_PrefsSfxVolume;
int8 m_PrefsMusicVolume;
uint8 m_PrefsRadioStation;
uint8 field_2C;
uint8 m_PrefsStereoMono; // unused except restore settings
int32 m_nCurrOption;
bool m_bQuitGameNoCD;
bool m_bMenuMapActive;
@ -544,7 +539,7 @@ public:
int32 m_nMouseOldPosY;
int32 m_nHoverOption;
bool m_bShowMouse;
int32 m_nPrevOption;
int32 m_nOptionMouseHovering;
bool m_bStartWaitingForKeyBind;
bool m_bWaitingForNewKeyBind;
bool m_bKeyChangeNotProcessed;
@ -595,7 +590,9 @@ public:
};
bool GetIsMenuActive() {return !!m_bMenuActive;}
static uint8 m_PrefsStereoMono;
#ifdef CUTSCENE_BORDERS_SWITCH
static bool m_PrefsCutsceneBorders;
#endif
#ifndef MASTER
static bool m_PrefsMarketing;
@ -613,7 +610,7 @@ public:
void CheckCodesForControls(int);
bool CheckHover(int x1, int x2, int y1, int y2);
void CheckSliderMovement(int);
void DisplayHelperText();
void DisplayHelperText(char*);
int DisplaySlider(float, float, float, float, float, float, float);
void DoSettingsBeforeStartingAGame();
void DrawStandardMenus(bool);
@ -625,7 +622,7 @@ public:
void DrawBackground(bool transitionCall);
void DrawPlayerSetupScreen();
int FadeIn(int alpha);
void FilterOutColorMarkersFromString(wchar*, CRGBA &);
void FilterOutColorMarkersFromString(wchar*);
int GetStartOptionsCntrlConfigScreens();
void InitialiseChangedLanguageSettings();
void LoadAllTextures();
@ -659,6 +656,7 @@ public:
void ScrollDownListByOne();
void PageUpList(bool);
void PageDownList(bool);
int8 GetPreviousPageOption();
// uint8 GetNumberOfMenuOptions();
};
@ -668,6 +666,6 @@ VALIDATE_SIZE(CMenuManager, 0x688);
#endif
extern CMenuManager FrontEndMenuManager;
extern CMenuScreen aScreens[];
#endif

View file

@ -88,6 +88,7 @@
#include "Zones.h"
#include "Occlusion.h"
#include "debugmenu.h"
#include "Ropes.h"
eLevelName CGame::currLevel;
int32 CGame::currArea;
@ -151,6 +152,10 @@ CGame::InitialiseOnceBeforeRW(void)
return true;
}
#if !defined(LIBRW) && defined(PS2_MATFX)
void ReplaceMatFxCallback();
#endif
bool
CGame::InitialiseRenderWare(void)
{
@ -201,6 +206,8 @@ CGame::InitialiseRenderWare(void)
#else
rw::MatFX::modulateEnvMap = false;
#endif
#elif defined(PS2_MATFX)
ReplaceMatFxCallback();
#endif
CFont::Initialise();
@ -245,23 +252,20 @@ void CGame::ShutdownRenderWare(void)
bool CGame::InitialiseOnceAfterRW(void)
{
TheText.Load();
DMAudio.Initialise();
CTimer::Initialise();
CTempColModels::Initialise();
mod_HandlingManager.Initialise();
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CPedStats::Initialise();
CTimeCycle::Initialise();
DMAudio.Initialise();
if ( DMAudio.GetNum3DProvidersAvailable() == 0 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = -1;
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER;
if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -99 || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 )
if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == AUDIO_PROVIDER_NOT_DETERMINED || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 )
{
FrontEndMenuManager.m_PrefsSpeakers = 0;
int8 provider = DMAudio.AutoDetect3DProviders();
if ( provider != -1 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = provider;
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = DMAudio.AutoDetect3DProviders();
}
DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
@ -316,7 +320,6 @@ bool CGame::Initialise(const char* datFile)
COcclusion::Init();
CCollision::Init();
CSetPieces::Init();
TheText.Load();
CTheZones::Init();
CUserDisplay::Init();
CMessages::Init();
@ -358,9 +361,9 @@ bool CGame::Initialise(const char* datFile)
LoadingScreen("Loading the Game", "Setup streaming", nil);
CStreaming::LoadInitialVehicles();
CStreaming::LoadInitialPeds();
CStreaming::RequestBigBuildings(LEVEL_NONE);
CStreaming::RequestBigBuildings(LEVEL_GENERIC);
CStreaming::LoadAllRequestedModels(false);
printf("Streaming uses %dK of its memory", CStreaming::ms_memoryUsed / 1024);
printf("Streaming uses %zuK of its memory", CStreaming::ms_memoryUsed / 1024); // original modifier was %d
LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen());
CAnimManager::LoadAnimFiles();
CStreaming::LoadInitialWeapons();
@ -401,9 +404,11 @@ bool CGame::Initialise(const char* datFile)
CRubbish::Init();
CClouds::Init();
CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init();
CBridge::Init();
CGarages::Init();
LoadingScreen("Loading the Game", "Position dynamic objects", nil);
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
CTrain::InitTrains();
CPlane::InitPlanes();
@ -414,6 +419,7 @@ bool CGame::Initialise(const char* datFile)
if ( !TheMemoryCard.m_bWantToLoad )
{
#endif
LoadingScreen("Loading the Game", "Start script", nil);
CTheScripts::StartTestScript();
CTheScripts::Process();
TheCamera.Process();
@ -424,6 +430,9 @@ bool CGame::Initialise(const char* datFile)
CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true);
// TODO(Miami)
// DMAudio.SetStartingTrackPositions(1);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
return true;
}
@ -509,7 +518,7 @@ void CGame::ReInitGameObjectVariables(void)
CTimeCycle::Initialise();
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
CStreaming::RequestBigBuildings(LEVEL_NONE);
CStreaming::RequestBigBuildings(LEVEL_GENERIC);
CStreaming::LoadAllRequestedModels(false);
CPed::Initialise();
CEventList::Initialise();
@ -544,6 +553,7 @@ void CGame::ReInitGameObjectVariables(void)
CRemote::Init();
#endif
CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init();
CParticle::ReloadConfig();
@ -647,7 +657,7 @@ void CGame::InitialiseWhenRestarting(void)
CTimer::Initialise();
FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables();
currLevel = LEVEL_NONE;
currLevel = LEVEL_GENERIC;
CCollision::SortOutCollisionAfterLoad();
}
}
@ -716,6 +726,7 @@ void CGame::Process(void)
CGarages::Update();
CRubbish::Update();
CSpecialFX::Update();
CRopes::Update();
CTimeCycle::Update();
if (CReplay::ShouldStandardCameraBeProcessed())
TheCamera.Process();

View file

@ -2,7 +2,7 @@
enum eLevelName {
LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel
LEVEL_NONE = 0,
LEVEL_GENERIC = 0,
LEVEL_BEACH,
LEVEL_MAINLAND
};

View file

@ -108,7 +108,7 @@ public:
if (angle >= TWOPI)
angle -= TWOPI;
return (int)floorf(angle / DEGTORAD(45.0f));
return (int)Floor(angle / DEGTORAD(45.0f));
}
// Unlike usual string comparison functions, these don't care about greater or lesser

View file

@ -1,10 +1,12 @@
#pragma once
#include "common.h"
#include "Frontend.h"
#ifdef PC_MENU
// --MIAMI: Done except commented things
// If you want to add new options, please don't do that here and see CustomFrontendOptionsPopulate in re3.cpp.
CMenuScreen aScreens[] = {
// MENUPAGE_STATS = 0
{ "FET_STA", MENUPAGE_NONE, 3,
{ "FEH_STA", MENUPAGE_NONE, 3,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 190, 320, MENUALIGN_RIGHT,
},
@ -79,11 +81,9 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER,
},
// TODO(Miami): This is still my implementation
// MENUPAGE_MAP = 6
{ "FEH_MAP", MENUPAGE_NONE, 2,
MENUACTION_UNK110, "", SAVESLOT_NONE, 0, 0, 0, 0, // to prevent cross/enter to go back
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 70, 380, MENUALIGN_CENTER,
},
// MENUPAGE_NEW_GAME_RELOAD = 7
@ -343,3 +343,5 @@ CMenuScreen aScreens[] = {
},
#endif
};
#endif

View file

@ -39,6 +39,7 @@
#include "General.h"
#include "Fluff.h"
#include "Gangs.h"
#include "platform.h"
#ifdef GTA_PS2
#include "eetypes.h"
@ -518,9 +519,12 @@ void FlyingFishCheat(void)
bool
CControllerState::CheckForInput(void)
{
return !!LeftStickX || !!LeftStickY || !!RightStickX || !!RightStickY || !!LeftShoulder1 || !!LeftShoulder2 || !!RightShoulder1 || !!RightShoulder2 ||
!!DPadUp || !!DPadDown || !!DPadLeft || !!DPadRight || !!Start || !!Select || !!Square || !!Triangle || !!Cross || !!Circle || !!LeftShock ||
!!RightShock;
return !!RightStickX || !!RightStickY || !!LeftStickX || !!LeftStickY
|| !!DPadUp || !!DPadDown || !!DPadLeft || !!DPadRight
|| !!Triangle || !!Cross || !!Circle || !!Square
|| !!Start || !!Select
|| !!LeftShoulder1 || !!LeftShoulder2 || !!RightShoulder1 || !!RightShoulder2
|| !!LeftShock || !!RightShock;
}
void
@ -668,7 +672,7 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
_InputInitialiseMouse();
_InputInitialiseMouse(!FrontEndMenuManager.m_bMenuActive && _InputMouseNeedsExclusive());
if ( PSGLOBAL(mouse) != nil )
{
@ -718,11 +722,11 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
void CPad::UpdateMouse()
{
#if defined RW_D3D9 || defined RWLIBS
if ( IsForegroundApp() )
{
#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
_InputInitialiseMouse();
_InputInitialiseMouse(!FrontEndMenuManager.m_bMenuActive && _InputMouseNeedsExclusive());
DIMOUSESTATE2 state;
@ -757,7 +761,10 @@ void CPad::UpdateMouse()
OldMouseControllerState = NewMouseControllerState;
NewMouseControllerState = PCTempMouseControllerState;
}
}
#else
if ( IsForegroundApp() && PSGLOBAL(cursorIsInWindow) )
{
double xpos = 1.0f, ypos;
glfwGetCursorPos(PSGLOBAL(window), &xpos, &ypos);
if (xpos == 0.f)
@ -795,8 +802,8 @@ void CPad::UpdateMouse()
OldMouseControllerState = NewMouseControllerState;
NewMouseControllerState = PCTempMouseControllerState;
#endif
}
#endif
}
CControllerState CPad::ReconcileTwoControllersInput(CControllerState const &State1, CControllerState const &State2)
@ -1447,6 +1454,13 @@ void CPad::UpdatePads(void)
#else
CapturePad(0);
#endif
// Improve keyboard input latency part 1
#ifdef FIX_BUGS
OldKeyState = NewKeyState;
NewKeyState = TempKeyState;
#endif
#ifdef DETECT_PAD_INPUT_SWITCH
if (GetPad(0)->PCTempJoyState.CheckForInput())
IsAffectedByController = true;
@ -1468,7 +1482,7 @@ void CPad::UpdatePads(void)
if ( bUpdate )
{
GetPad(0)->Update(0);
GetPad(1)->Update(0);
// GetPad(1)->Update(0); // not in VC
}
#if defined(MASTER) && !defined(XINPUT)
@ -1476,8 +1490,11 @@ void CPad::UpdatePads(void)
GetPad(1)->OldState.Clear();
#endif
// Improve keyboard input latency part 2
#ifndef FIX_BUGS
OldKeyState = NewKeyState;
NewKeyState = TempKeyState;
#endif
}
void CPad::ProcessPCSpecificStuff(void)
@ -3024,7 +3041,7 @@ void CPad::ResetCheats(void)
char *CPad::EditString(char *pStr, int32 nSize)
{
int32 pos = strlen(pStr);
int32 pos = (int32)strlen(pStr);
// letters
for ( int32 i = 0; i < ('Z' - 'A' + 1); i++ )

View file

@ -560,7 +560,7 @@ CPlayerInfo::Process(void)
veh->m_nZoneLevel = LEVEL_IGNORE;
for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
if (veh->pPassengers[i])
veh->pPassengers[i]->m_nZoneLevel = LEVEL_NONE;
veh->pPassengers[i]->m_nZoneLevel = LEVEL_GENERIC;
}
CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
} else {

View file

@ -121,11 +121,11 @@ static_assert(RADAR_TILE_SIZE == (RADAR_SIZE_Y / RADAR_NUM_TILES), "CRadar: not
#define RADAR_MIN_SPEED (0.3f)
#define RADAR_MAX_SPEED (0.9f)
#ifdef MENU_MAP
CRGBA CRadar::ArrowBlipColour1;
CRGBA CRadar::ArrowBlipColour2;
uint16 CRadar::MapLegendCounter;
int16 CRadar::MapLegendList[NUM_MAP_LEGENDS];
#ifdef MAP_ENHANCEMENTS
int CRadar::TargetMarkerId = -1;
CVector CRadar::TargetMarkerPos;
#endif
@ -263,10 +263,9 @@ int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &
uint8 CRadar::CalculateBlipAlpha(float dist)
{
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive)
return 255;
#endif
if (dist <= 1.0f)
return 255;
@ -486,9 +485,7 @@ void CRadar::DrawBlips()
CVector2D in = CVector2D(0.0f, 0.0f);
TransformRadarPointToScreenSpace(out, in);
#ifdef MENU_MAP
if (!FrontEndMenuManager.m_bMenuMapActive) {
#endif
float angle;
if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN)
angle = PI + FindPlayerHeading();
@ -508,9 +505,7 @@ void CRadar::DrawBlips()
LimitRadarPoint(in);
TransformRadarPointToScreenSpace(out, in);
DrawRadarSprite(RADAR_SPRITE_NORTH, out.x, out.y, 255);
#ifdef MENU_MAP
}
#endif
CEntity *blipEntity = nil;
for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
@ -743,14 +738,12 @@ void CRadar::DrawBlips()
break;
}
}
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive) {
CVector2D in, out;
TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift());
TransformRadarPointToScreenSpace(out, in);
DrawYouAreHereSprite(out.x, out.y);
}
#endif
}
}
@ -773,7 +766,8 @@ void CRadar::DrawMap()
m_radarRange = RADAR_MIN_RANGE;
vec2DRadarOrigin = CVector2D(FindPlayerCentreOfWorld_NoSniperShift());
DrawRadarMap();
if (FrontEndMenuManager.m_PrefsRadarMode != 1)
DrawRadarMap();
}
}
@ -784,8 +778,8 @@ void CRadar::DrawRadarMap()
DrawRadarMask();
// top left ist (0, 0)
int x = floorf((vec2DRadarOrigin.x - RADAR_MIN_X) / RADAR_TILE_SIZE);
int y = ceilf((RADAR_NUM_TILES - 1) - (vec2DRadarOrigin.y - RADAR_MIN_Y) / RADAR_TILE_SIZE);
int x = Floor((vec2DRadarOrigin.x - RADAR_MIN_X) / RADAR_TILE_SIZE);
int y = Ceil((RADAR_NUM_TILES - 1) - (vec2DRadarOrigin.y - RADAR_MIN_Y) / RADAR_TILE_SIZE);
StreamRadarSections(x, y);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
@ -898,7 +892,7 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
{
RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive) {
bool alreadyThere = false;
for (int i = 0; i < NUM_MAP_LEGENDS; i++) {
@ -910,7 +904,6 @@ void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
MapLegendCounter++;
}
}
#endif
}
void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha)
@ -1046,10 +1039,10 @@ float CRadar::LimitRadarPoint(CVector2D &point)
float dist, invdist;
dist = point.Magnitude();
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive)
return dist;
#endif
if (dist > 1.0f) {
invdist = 1.0f / dist;
point.x *= invdist;
@ -1130,7 +1123,7 @@ void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
INITSAVEBUF
WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE);
#ifdef MENU_MAP
#ifdef MAP_ENHANCEMENTS
if (TargetMarkerId != -1) {
ClearBlip(TargetMarkerId);
TargetMarkerId = -1;
@ -1276,7 +1269,8 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red,
CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
break;
}
#ifdef MENU_MAP
// TODO(Miami): Map
// VC uses -1 for coords and -2 for entities but meh, I don't want to edit DrawBlips
if (FrontEndMenuManager.m_bMenuMapActive) {
bool alreadyThere = false;
@ -1290,7 +1284,6 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red,
ArrowBlipColour1 = CRGBA(red, green, blue, alpha);
}
}
#endif
}
void CRadar::Shutdown()
@ -1339,7 +1332,7 @@ void CRadar::Shutdown()
void CRadar::StreamRadarSections(const CVector &posn)
{
StreamRadarSections(floorf((2000.0f + posn.x) / 500.0f), ceilf(7.0f - (2000.0f + posn.y) / 500.0f));
StreamRadarSections(Floor((2000.0f + posn.x) / 500.0f), Ceil(7.0f - (2000.0f + posn.y) / 500.0f));
}
void CRadar::StreamRadarSections(int32 x, int32 y)
@ -1402,13 +1395,10 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D
// Radar space goes from -1.0 to 1.0 in x and y, top right is (1.0, 1.0)
void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in)
{
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive) {
out.x = (FrontEndMenuManager.m_fMapCenterX - FrontEndMenuManager.m_fMapSize) + (MENU_MAP_LENGTH / 2 + MENU_MAP_LEFT_OFFSET + in.x) * FrontEndMenuManager.m_fMapSize * MENU_MAP_WIDTH_SCALE * 2.0f / MENU_MAP_LENGTH;
out.y = (FrontEndMenuManager.m_fMapCenterY - FrontEndMenuManager.m_fMapSize) + (MENU_MAP_LENGTH / 2 - MENU_MAP_TOP_OFFSET - in.y) * FrontEndMenuManager.m_fMapSize * MENU_MAP_HEIGHT_SCALE * 2.0f / MENU_MAP_LENGTH;
} else
#endif
{
} else {
#ifdef FIX_BUGS
out.x = (in.x + 1.0f) * 0.5f * SCREEN_SCALE_X(RADAR_WIDTH) + SCREEN_SCALE_X(RADAR_LEFT);
#else
@ -1462,10 +1452,7 @@ void
CRadar::CalculateCachedSinCos()
{
if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED
#ifdef MENU_MAP
|| FrontEndMenuManager.m_bMenuMapActive
#endif
) {
|| FrontEndMenuManager.m_bMenuMapActive ) {
cachedSin = 0.0f;
cachedCos = 1.0f;
} else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
@ -1486,7 +1473,6 @@ CRadar::CalculateCachedSinCos()
}
}
#ifdef MENU_MAP
void
CRadar::InitFrontEndMap()
{
@ -1530,6 +1516,7 @@ CRadar::DrawYouAreHereSprite(float x, float y)
MapLegendList[MapLegendCounter++] = RADAR_SPRITE_CENTRE;
}
#ifdef MAP_ENHANCEMENTS
void
CRadar::ToggleTargetMarker(float x, float y)
{

View file

@ -21,6 +21,8 @@
#define COORDBLIP_MARKER_COLOR_B 242
#define COORDBLIP_MARKER_COLOR_A 255
#define NUM_MAP_LEGENDS 75
#define MENU_MAP_LENGTH_UNIT 1190.0f // in game unit
#define MENU_MAP_WIDTH_SCALE 1.112f // in game unit (originally 1.112494151260504f)
#define MENU_MAP_HEIGHT_SCALE 1.119f // in game unit (originally 1.118714268907563f)
@ -48,10 +50,8 @@ enum eBlipDisplay
enum eRadarSprite
{
#ifdef MENU_MAP
RADAR_SPRITE_ENTITY_BLIP = -2,
RADAR_SPRITE_COORD_BLIP = -1,
#endif
RADAR_SPRITE_NONE = 0,
RADAR_SPRITE_CENTRE,
RADAR_SPRITE_MAP_HERE,
@ -173,17 +173,19 @@ public:
static CSprite2d *RadarSprites[RADAR_SPRITE_COUNT];
static float cachedCos;
static float cachedSin;
#ifdef MENU_MAP
#define NUM_MAP_LEGENDS 75
static CRGBA ArrowBlipColour1;
static CRGBA ArrowBlipColour2;
static int16 MapLegendList[NUM_MAP_LEGENDS];
static uint16 MapLegendCounter;
#ifdef MAP_ENHANCEMENTS
static int TargetMarkerId;
static CVector TargetMarkerPos;
#endif
static void InitFrontEndMap();
static void DrawYouAreHereSprite(float, float);
#ifdef MAP_ENHANCEMENTS
static void ToggleTargetMarker(float, float);
#endif
static uint8 CalculateBlipAlpha(float dist);

173
src/core/Ropes.cpp Normal file
View file

@ -0,0 +1,173 @@
#include "common.h"
#include "Timer.h"
#include "ModelIndices.h"
#include "Streaming.h"
#include "CopPed.h"
#include "Population.h"
#include "RenderBuffer.h"
#include "Camera.h"
#include "Ropes.h"
CRope CRopes::aRopes[8];
RwImVertexIndex RopeIndices[64] = {
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15,
15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23,
23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31,
31, 32 // unused
};
void
CRope::Update(void)
{
int i;
float step = Pow(0.85f, CTimer::GetTimeStep());
if(!m_bWasRegistered && CTimer::GetTimeInMilliseconds() > m_updateTimer){
m_speed[0].z -= 0.0015f*CTimer::GetTimeStep();
m_pos[0] += m_speed[0]*CTimer::GetTimeStep();
}
for(i = 1; i < ARRAY_SIZE(m_pos); i++){
CVector prevPos = m_pos[i];
m_pos[i] += m_speed[i]*step*CTimer::GetTimeStep();
m_pos[i].z -= 0.05f*CTimer::GetTimeStep();
CVector dist = m_pos[i] - m_pos[i-1];
m_pos[i] = m_pos[i-1] + (0.625f/dist.Magnitude())*dist;
m_speed[i] = (m_pos[i] - prevPos)/CTimer::GetTimeStep();
}
if(!m_bWasRegistered && m_pos[0].z < 0.0f)
m_bActive = false;
m_bWasRegistered = false;
}
void
CRope::Render(void)
{
int i;
int numVerts = 0;
if(!TheCamera.IsSphereVisible(m_pos[16], 20.0f))
return;
for(i = 0; i < ARRAY_SIZE(m_pos); i++){
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[i], 128, 128, 128, 100);
RwIm3DVertexSetPos(&TempBufferRenderVertices[i], m_pos[i].x, m_pos[i].y, m_pos[i].z);
}
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
if(RwIm3DTransform(TempBufferRenderVertices, ARRAY_SIZE(m_pos), nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXRGBA)){
#ifdef FIX_BUGS
RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
#else
RwIm3DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
#endif
RwIm3DEnd();
}
}
void
CRopes::Init(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
aRopes[i].m_bActive = false;
}
void
CRopes::Update(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive)
aRopes[i].Update();
}
void
CRopes::Render(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive)
aRopes[i].Render();
}
bool
CRopes::RegisterRope(uintptr id, CVector pos, bool setUpdateTimer)
{
int i, j;
for(i = 0; i < ARRAY_SIZE(aRopes); i++){
if(aRopes[i].m_bActive && aRopes[i].m_id == id){
aRopes[i].m_pos[0] = pos;
aRopes[i].m_speed[0] = CVector(0.0f, 0.0f, 0.0f);
aRopes[i].m_bWasRegistered = true;
return true;
}
}
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(!aRopes[i].m_bActive){
aRopes[i].m_id = id;
aRopes[i].m_pos[0] = pos;
aRopes[i].m_speed[0] = CVector(0.0f, 0.0f, 0.0f);
aRopes[i].m_unk = false;
aRopes[i].m_bWasRegistered = true;
aRopes[i].m_updateTimer = setUpdateTimer ? CTimer::GetTimeInMilliseconds() + 20000 : 0;
for(j = 1; j < ARRAY_SIZE(CRope::m_pos); j++){
if(j & 1)
aRopes[i].m_pos[j] = aRopes[i].m_pos[j-1] + CVector(0.0f, 0.0f, 0.625f);
else
aRopes[i].m_pos[j] = aRopes[i].m_pos[j-1] - CVector(0.0f, 0.0f, 0.625f);
aRopes[i].m_speed[j] = CVector(0.0f, 0.0f, 0.0f);
}
aRopes[i].m_bActive = true;
return true;
}
return false;
}
void
CRopes::SetSpeedOfTopNode(uintptr id, CVector speed)
{
int i;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive && aRopes[i].m_id == id){
aRopes[i].m_speed[0] = speed;
return;
}
}
bool
CRopes::FindCoorsAlongRope(uintptr id, float t, CVector *coors)
{
int i, j;
float f;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive && aRopes[i].m_id == id){
t = (ARRAY_SIZE(CRope::m_pos)-1)*clamp(t, 0.0f, 0.999f);
j = t;
f = t - j;
*coors = (1.0f-f)*aRopes[i].m_pos[j] + f*aRopes[i].m_pos[j+1];
return true;
}
return false;
}
bool
CRopes::CreateRopeWithSwatComingDown(CVector pos)
{
static uint32 ropeId = 0;
if(!CStreaming::HasModelLoaded(MI_SWAT) || !RegisterRope(ropeId+100, pos, true))
return false;
CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_HELI_SWAT, pos);
swat->bUsesCollision = false;
swat->m_pRopeEntity = (CEntity*)1;
swat->m_nRopeID = 100 + ropeId;
CAnimManager::BlendAnimation(swat->GetClump(), ASSOCGRP_STD, ANIM_ABSEIL, 4.0f);
ropeId++;
return true;
}

31
src/core/Ropes.h Normal file
View file

@ -0,0 +1,31 @@
#pragma once
class CRope
{
public:
bool m_bActive;
bool m_bWasRegistered;
bool m_unk;
uintptr m_id;
uint32 m_updateTimer;
CVector m_pos[32];
CVector m_speed[32];
void Update(void);
void Render(void);
};
class CRopes
{
static CRope aRopes[8];
public:
static void Init(void);
static void Update(void);
static void Render(void);
static bool RegisterRope(uintptr id, CVector pos, bool setUpdateTimer);
static void SetSpeedOfTopNode(uintptr id, CVector speed);
static bool FindCoorsAlongRope(uintptr id, float t, CVector *coors);
static bool CreateRopeWithSwatComingDown(CVector pos);
};

View file

@ -21,8 +21,8 @@ int32 CStats::PedsKilledOfThisType[NUM_PEDTYPES];
int32 CStats::TimesDied;
int32 CStats::TimesArrested;
int32 CStats::KillsSinceLastCheckpoint;
int32 CStats::DistanceTravelledInVehicle;
int32 CStats::DistanceTravelledOnFoot;
float CStats::DistanceTravelledInVehicle;
float CStats::DistanceTravelledOnFoot;
int32 CStats::ProgressMade;
int32 CStats::TotalProgressInGame;
int32 CStats::CarsExploded;
@ -49,7 +49,6 @@ int32 CStats::LivesSavedWithAmbulance;
int32 CStats::CriminalsCaught;
int32 CStats::HighestLevelAmbulanceMission;
int32 CStats::FiresExtinguished;
int32 CStats::LongestFlightInDodo;
int32 CStats::TimeTakenDefuseMission;
int32 CStats::TotalNumberKillFrenzies;
int32 CStats::TotalNumberMissions;
@ -58,8 +57,6 @@ int32 CStats::KgsOfExplosivesUsed;
int32 CStats::InstantHitsFiredByPlayer;
int32 CStats::InstantHitsHitByPlayer;
int32 CStats::BestTimeBombDefusal;
int32 CStats::mmRain;
int32 CStats::CarsCrushed;
int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES];
int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES];
int32 CStats::BestPositions[CStats::TOTAL_BEST_POSITIONS];
@ -83,13 +80,11 @@ void CStats::Init()
KgsOfExplosivesUsed = 0;
InstantHitsFiredByPlayer = 0;
InstantHitsHitByPlayer = 0;
CarsCrushed = 0;
HeadsPopped = 0;
TimesArrested = 0;
TimesDied = 0;
DaysPassed = 0;
NumberOfUniqueJumpsFound = 0;
mmRain = 0;
MaximumJumpFlips = 0;
MaximumJumpSpins = 0;
MaximumJumpDistance = 0;
@ -97,7 +92,6 @@ void CStats::Init()
BestStuntJump = 0;
TotalNumberOfUniqueJumps = 0;
Record4x4One = 0;
LongestFlightInDodo = 0;
Record4x4Two = 0;
PassengersDroppedOffWithTaxi = 0;
Record4x4Three = 0;
@ -202,11 +196,6 @@ void CStats::AnotherFireExtinguished()
++FiresExtinguished;
}
void CStats::RegisterLongestFlightInDodo(int32 time)
{
LongestFlightInDodo = Max(LongestFlightInDodo, time);
}
void CStats::RegisterTimeTakenDefuseMission(int32 time)
{
TimeTakenDefuseMission = (TimeTakenDefuseMission && TimeTakenDefuseMission < time) ? TimeTakenDefuseMission : time;
@ -296,12 +285,10 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
sizeof(KgsOfExplosivesUsed) +
sizeof(InstantHitsFiredByPlayer) +
sizeof(InstantHitsHitByPlayer) +
sizeof(CarsCrushed) +
sizeof(HeadsPopped) +
sizeof(TimesArrested) +
sizeof(TimesDied) +
sizeof(DaysPassed) +
sizeof(mmRain) +
sizeof(MaximumJumpDistance) +
sizeof(MaximumJumpHeight) +
sizeof(MaximumJumpFlips) +
@ -327,7 +314,6 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
sizeof(CriminalsCaught) +
sizeof(HighestLevelAmbulanceMission) +
sizeof(FiresExtinguished) +
sizeof(LongestFlightInDodo) +
sizeof(TimeTakenDefuseMission) +
sizeof(NumberKillFrenziesPassed) +
sizeof(TotalNumberKillFrenzies) +
@ -351,12 +337,10 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
CopyToBuf(buf, KgsOfExplosivesUsed);
CopyToBuf(buf, InstantHitsFiredByPlayer);
CopyToBuf(buf, InstantHitsHitByPlayer);
CopyToBuf(buf, CarsCrushed);
CopyToBuf(buf, HeadsPopped);
CopyToBuf(buf, TimesArrested);
CopyToBuf(buf, TimesDied);
CopyToBuf(buf, DaysPassed);
CopyToBuf(buf, mmRain);
CopyToBuf(buf, MaximumJumpDistance);
CopyToBuf(buf, MaximumJumpHeight);
CopyToBuf(buf, MaximumJumpFlips);
@ -382,7 +366,6 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
CopyToBuf(buf, CriminalsCaught);
CopyToBuf(buf, HighestLevelAmbulanceMission);
CopyToBuf(buf, FiresExtinguished);
CopyToBuf(buf, LongestFlightInDodo);
CopyToBuf(buf, TimeTakenDefuseMission);
CopyToBuf(buf, NumberKillFrenziesPassed);
CopyToBuf(buf, TotalNumberKillFrenzies);
@ -415,12 +398,10 @@ void CStats::LoadStats(uint8 *buf, uint32 size)
CopyFromBuf(buf, KgsOfExplosivesUsed);
CopyFromBuf(buf, InstantHitsFiredByPlayer);
CopyFromBuf(buf, InstantHitsHitByPlayer);
CopyFromBuf(buf, CarsCrushed);
CopyFromBuf(buf, HeadsPopped);
CopyFromBuf(buf, TimesArrested);
CopyFromBuf(buf, TimesDied);
CopyFromBuf(buf, DaysPassed);
CopyFromBuf(buf, mmRain);
CopyFromBuf(buf, MaximumJumpDistance);
CopyFromBuf(buf, MaximumJumpHeight);
CopyFromBuf(buf, MaximumJumpFlips);
@ -446,7 +427,6 @@ void CStats::LoadStats(uint8 *buf, uint32 size)
CopyFromBuf(buf, CriminalsCaught);
CopyFromBuf(buf, HighestLevelAmbulanceMission);
CopyFromBuf(buf, FiresExtinguished);
CopyFromBuf(buf, LongestFlightInDodo);
CopyFromBuf(buf, TimeTakenDefuseMission);
CopyFromBuf(buf, NumberKillFrenziesPassed);
CopyFromBuf(buf, TotalNumberKillFrenzies);

View file

@ -25,8 +25,8 @@ public:
static int32 TimesDied;
static int32 TimesArrested;
static int32 KillsSinceLastCheckpoint;
static int32 DistanceTravelledInVehicle;
static int32 DistanceTravelledOnFoot;
static float DistanceTravelledInVehicle;
static float DistanceTravelledOnFoot;
static int32 CarsExploded;
static int32 PeopleKilledByPlayer;
static int32 ProgressMade;
@ -53,7 +53,6 @@ public:
static int32 CriminalsCaught;
static int32 HighestLevelAmbulanceMission;
static int32 FiresExtinguished;
static int32 LongestFlightInDodo;
static int32 TimeTakenDefuseMission;
static int32 TotalNumberKillFrenzies;
static int32 TotalNumberMissions;
@ -62,8 +61,6 @@ public:
static int32 InstantHitsFiredByPlayer;
static int32 InstantHitsHitByPlayer;
static int32 BestTimeBombDefusal;
static int32 mmRain;
static int32 CarsCrushed;
static int32 FastestTimes[TOTAL_FASTEST_TIMES];
static int32 HighestScores[TOTAL_HIGHEST_SCORES];
static int32 BestPositions[TOTAL_BEST_POSITIONS];
@ -90,7 +87,6 @@ public:
static void RegisterLevelAmbulanceMission(int32);
static void AnotherFireExtinguished();
static wchar *FindCriminalRatingString();
static void RegisterLongestFlightInDodo(int32);
static void RegisterTimeTakenDefuseMission(int32);
static void AnotherKillFrenzyPassed();
static void SetTotalNumberKillFrenzies(int32);

View file

@ -44,7 +44,7 @@ int32 CStreaming::ms_oldSectorX;
int32 CStreaming::ms_oldSectorY;
int32 CStreaming::ms_streamingBufferSize;
int8 *CStreaming::ms_pStreamingBuffer[2];
int32 CStreaming::ms_memoryUsed;
size_t CStreaming::ms_memoryUsed;
CStreamingChannel CStreaming::ms_channel[2];
int32 CStreaming::ms_channelError;
int32 CStreaming::ms_numVehiclesLoaded;
@ -61,7 +61,7 @@ uint16 CStreaming::ms_loadedGangCars;
int32 CStreaming::ms_imageOffsets[NUMCDIMAGES];
int32 CStreaming::ms_lastImageRead;
int32 CStreaming::ms_imageSize;
uint32 CStreaming::ms_memoryAvailable;
size_t CStreaming::ms_memoryAvailable;
int32 desiredNumVehiclesLoaded = 12;
@ -200,9 +200,9 @@ CStreaming::Init2(void)
debug("Streaming buffer size is %d sectors", ms_streamingBufferSize);
#define MB (1024*1024)
ms_memoryAvailable = 65*MB;
ms_memoryAvailable = 65 * MB;
desiredNumVehiclesLoaded = 25;
debug("Memory allocated to Streaming is %dMB", ms_memoryAvailable/MB);
debug("Memory allocated to Streaming is %dMB", ms_memoryAvailable / MB);
#undef MB
// find island LODs
@ -723,7 +723,11 @@ CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
n = CPools::GetBuildingPool()->GetSize()-1;
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding && b->m_level == level)
if(b && b->bIsBIGBuilding
#ifndef NO_ISLAND_LOADING
&& b->m_level == level
#endif
)
if(b->bStreamBIGBuilding){
if(CRenderer::ShouldModelBeStreamed(b, pos))
RequestModel(b->GetModelIndex(), 0);
@ -795,6 +799,7 @@ CStreaming::InstanceLoadedModels(const CVector &pos)
void
CStreaming::RequestIslands(eLevelName level)
{
#ifndef NO_ISLAND_LOADING
switch(level){
case LEVEL_MAINLAND:
if(islandLODbeach != -1)
@ -806,6 +811,7 @@ CStreaming::RequestIslands(eLevelName level)
break;
default: break;
}
#endif
}
//--MIAMI: TODO
@ -1010,10 +1016,12 @@ CStreaming::RemoveBuildings(eLevelName level)
void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
#ifndef NO_ISLAND_LOADING
if(level != LEVEL_BEACH)
RemoveBigBuildings(LEVEL_BEACH);
if(level != LEVEL_MAINLAND)
RemoveBigBuildings(LEVEL_MAINLAND);
#endif
RemoveIslandsNotUsed(level);
}
@ -1035,6 +1043,7 @@ DeleteIsland(CEntity *island)
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
#ifndef NO_ISLAND_LOADING
int i;
if(pIslandLODmainlandEntity == nil)
for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
@ -1053,8 +1062,10 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
break;
case LEVEL_BEACH:
DeleteIsland(pIslandLODbeachEntity);
break;
}
#endif // !NO_ISLAND_LOADING
}
//--MIAMI: done
@ -1380,11 +1391,11 @@ CStreaming::StreamVehiclesAndPeds(void)
}
if(FindPlayerPed()->m_pWanted->AreFbiRequired()){
RequestModel(MI_FBICAR, STREAMFLAGS_DONT_REMOVE);
RequestModel(MI_FBIRANCH, STREAMFLAGS_DONT_REMOVE);
RequestModel(MI_FBI, STREAMFLAGS_DONT_REMOVE);
}else{
SetModelIsDeletable(MI_FBICAR);
if(!HasModelLoaded(MI_FBICAR))
SetModelIsDeletable(MI_FBIRANCH);
if(!HasModelLoaded(MI_FBIRANCH))
SetModelIsDeletable(MI_FBI);
}
@ -1594,7 +1605,7 @@ CStreaming::LoadBigBuildingsWhenNeeded(void)
if(CCutsceneMgr::IsCutsceneProcessing())
return;
if(CTheZones::m_CurrLevel == LEVEL_NONE ||
if(CTheZones::m_CurrLevel == LEVEL_GENERIC ||
CTheZones::m_CurrLevel == CGame::currLevel)
return;
@ -1612,7 +1623,7 @@ CStreaming::LoadBigBuildingsWhenNeeded(void)
CGame::TidyUpMemory(true, true);
CReplay::EmptyReplayBuffer();
if(CGame::currLevel != LEVEL_NONE)
if(CGame::currLevel != LEVEL_GENERIC)
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
@ -2374,7 +2385,7 @@ CStreaming::DeleteRwObjectsAfterDeath(const CVector &pos)
}
void
CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
{
int ix, iy;
int x, y;
@ -2549,7 +2560,7 @@ CStreaming::DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y)
}
bool
CStreaming::DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, int32 mem)
CStreaming::DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem)
{
CPtrNode *node;
CEntity *e;
@ -2570,7 +2581,7 @@ CStreaming::DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, int32 mem)
}
bool
CStreaming::DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem)
CStreaming::DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem)
{
CPtrNode *node;
CEntity *e;
@ -2597,7 +2608,7 @@ CStreaming::MakeSpaceFor(int32 size)
// the code still happens to work in that case because ms_memoryAvailable is unsigned
// but it's not nice....
while((uint32)ms_memoryUsed >= ms_memoryAvailable - size)
while(ms_memoryUsed >= ms_memoryAvailable - size)
if(!RemoveLeastUsedModel(STREAMFLAGS_20)){
DeleteRwObjectsBehindCamera(ms_memoryAvailable - size);
return;
@ -2620,16 +2631,16 @@ CStreaming::LoadScene(const CVector &pos)
}
CRenderer::m_loadingPriority = false;
DeleteAllRwObjects();
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = CGame::currLevel;
CGame::currLevel = level;
RemoveUnusedBigBuildings(level);
RequestBigBuildings(level, pos);
RequestBigBuildings(LEVEL_NONE, pos);
RequestBigBuildings(LEVEL_GENERIC, pos);
RemoveIslandsNotUsed(level);
LoadAllRequestedModels(false);
InstanceBigBuildings(level, pos);
InstanceBigBuildings(LEVEL_NONE, pos);
InstanceBigBuildings(LEVEL_GENERIC, pos);
AddModelsToRequestList(pos);
CRadar::StreamRadarSections(pos);
@ -2688,7 +2699,8 @@ CStreaming::UpdateForAnimViewer(void)
if (CStreaming::ms_channelError == -1) {
CStreaming::AddModelsToRequestList(CVector(0.0f, 0.0f, 0.0f));
CStreaming::LoadRequestedModels();
sprintf(gString, "Requested %d, memory size %dK\n", CStreaming::ms_numModelsRequested, 2 * CStreaming::ms_memoryUsed);
// original modifier was %d
sprintf(gString, "Requested %d, memory size %zuK\n", CStreaming::ms_numModelsRequested, 2 * CStreaming::ms_memoryUsed);
}
else {
CStreaming::RetryLoadFile(CStreaming::ms_channelError);

View file

@ -89,7 +89,7 @@ public:
static int32 ms_oldSectorY;
static int32 ms_streamingBufferSize;
static int8 *ms_pStreamingBuffer[2];
static int32 ms_memoryUsed;
static size_t ms_memoryUsed;
static CStreamingChannel ms_channel[2];
static int32 ms_channelError;
static int32 ms_numVehiclesLoaded;
@ -106,7 +106,7 @@ public:
static int32 ms_imageOffsets[NUMCDIMAGES];
static int32 ms_lastImageRead;
static int32 ms_imageSize;
static uint32 ms_memoryAvailable;
static size_t ms_memoryAvailable;
static void Init(void);
static void Init2(void);
@ -193,11 +193,11 @@ public:
static void DeleteFarAwayRwObjects(const CVector &pos);
static void DeleteAllRwObjects(void);
static void DeleteRwObjectsAfterDeath(const CVector &pos);
static void DeleteRwObjectsBehindCamera(int32 mem);
static void DeleteRwObjectsBehindCamera(size_t mem);
static void DeleteRwObjectsInSectorList(CPtrList &list);
static void DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y);
static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, int32 mem);
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem);
static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem);
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem);
static void LoadScene(const CVector &pos);
static void LoadSceneCollision(const CVector &pos);

View file

@ -53,6 +53,41 @@ enum
struct CColPoint;
inline bool
IsSeeThrough(uint8 surfType)
{
switch(surfType)
case SURFACE_GLASS:
case SURFACE_TRANSPARENT_CLOTH:
case SURFACE_METAL_CHAIN_FENCE:
case SURFACE_TRANSPARENT_STONE:
case SURFACE_SCAFFOLD_POLE:
return true;
return false;
}
// I think the necessity of this function is really a bug
inline bool
IsSeeThroughVertical(uint8 surfType)
{
switch(surfType)
case SURFACE_GLASS:
case SURFACE_TRANSPARENT_CLOTH:
return true;
return false;
}
inline bool
IsShootThrough(uint8 surfType)
{
switch(surfType)
case SURFACE_METAL_CHAIN_FENCE:
case SURFACE_TRANSPARENT_STONE:
case SURFACE_SCAFFOLD_POLE:
return true;
return false;
}
class CSurfaceTable
{
static float ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];

View file

@ -37,19 +37,19 @@ CTempColModels::Initialise(void)
#define SET_COLMODEL_SPHERES(colmodel, sphrs)\
colmodel.numSpheres = ARRAY_SIZE(sphrs);\
colmodel.spheres = sphrs;\
colmodel.level = LEVEL_NONE;\
colmodel.level = LEVEL_GENERIC;\
colmodel.ownsCollisionVolumes = false;\
int i;
ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
ms_colModelBBox.level = LEVEL_NONE;
ms_colModelBBox.level = LEVEL_GENERIC;
for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) {
ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
ms_colModelCutObj[i].level = LEVEL_NONE;
ms_colModelCutObj[i].level = LEVEL_GENERIC;
}
// Ped Spheres

View file

@ -74,6 +74,14 @@ CPlaceName::Display()
CHud::SetZoneName(text);
}
void
CPlaceName::ProcessAfterFrontEndShutDown(void)
{
CHud::m_pLastZoneName = nil;
CHud::m_ZoneState = 0;
m_nAdditionalTimer = 250;
}
CCurrentVehicle::CCurrentVehicle()
{
Init();

View file

@ -16,6 +16,7 @@ public:
void Init();
void Process();
void Display();
void ProcessAfterFrontEndShutDown();
};
class CCurrentVehicle

View file

@ -182,7 +182,7 @@ CWanted::RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool po
void
CWanted::RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare)
{
#ifdef FIX_BUGS
#ifdef FIX_SIGNIFICANT_BUGS
if(!AddCrimeToQ(type, id, coors, true, policeDoesntCare))
#else
if(!AddCrimeToQ(type, id, coors, false, policeDoesntCare))

View file

@ -1785,7 +1785,7 @@ CWorld::ClearForRestart(void)
CWorld::Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = GetBigBuildingList(LEVEL_NONE).first; pNode; pNode = pNode->next) {
for(CPtrNode *pNode = GetBigBuildingList(LEVEL_GENERIC).first; pNode; pNode = pNode->next) {
CVehicle *pVehicle = (CVehicle *)pNode->item;
if(pVehicle && pVehicle->IsVehicle() && pVehicle->IsPlane()) {
CWorld::Remove(pVehicle);

View file

@ -93,7 +93,7 @@ CTheZones::Init(void)
InfoZoneArray[0].maxx = 1600.0f;
InfoZoneArray[0].maxy = 2000.0f;
InfoZoneArray[0].maxz = 500.0f;
InfoZoneArray[0].level = LEVEL_NONE;
InfoZoneArray[0].level = LEVEL_GENERIC;
InfoZoneArray[0].type = ZONE_INFO;
strcpy(NavigationZoneArray[0].name, "VICE_C");
@ -103,10 +103,10 @@ CTheZones::Init(void)
NavigationZoneArray[0].maxx = 1600.0f;
NavigationZoneArray[0].maxy = 2000.0f;
NavigationZoneArray[0].maxz = 500.0f;
NavigationZoneArray[0].level = LEVEL_NONE;
NavigationZoneArray[0].type = ZONE_NAVIG;
NavigationZoneArray[0].level = LEVEL_GENERIC;
NavigationZoneArray[0].type = ZONE_DEFAULT;
m_CurrLevel = LEVEL_NONE;
m_CurrLevel = LEVEL_GENERIC;
for(i = 0; i < NUMMAPZONES; i++){
memset(&MapZoneArray[i], 0, sizeof(CZone));
@ -120,7 +120,7 @@ CTheZones::Init(void)
MapZoneArray[0].maxx = 1600.0f;
MapZoneArray[0].maxy = 2000.0f;
MapZoneArray[0].maxz = 500.0f;
MapZoneArray[0].level = LEVEL_NONE;
MapZoneArray[0].level = LEVEL_GENERIC;
}
//--MIAMI: done

View file

@ -17,7 +17,11 @@
#if defined _WIN32 && defined WITHD3D
#include <windows.h>
#ifndef USE_D3D9
#include <d3d8types.h>
#else
#include <d3d9types.h>
#endif
#endif
#include <rwcore.h>
@ -37,6 +41,7 @@
#define HIERNODEINFO(hier) ((hier)->pNodeInfo)
#define HIERNODEID(hier, i) ((hier)->pNodeInfo[i].nodeID)
#define HANIMFRAME(anim, i) ((RwUInt8*)(anim)->pFrames + (i)*(anim)->interpInfo->keyFrameSize)
#define RpHAnimStdInterpFrame RpHAnimStdKeyFrame
#endif
#ifdef RWHALFPIXEL

View file

@ -54,7 +54,7 @@ enum Config {
NUMBOATALPHALIST = 20,
NUMALPHAENTITYLIST = 200,
NUMALPHAUNTERWATERENTITYLIST = 30,
NUMCOLCACHELINKS = 200,
NUMCOLCACHELINKS = 50,
NUMREFERENCES = 800,
// Zones
@ -67,6 +67,7 @@ enum Config {
NUMATTRIBZONES = 704,
NUMOCCLUSIONVOLUMES = 350,
NUMACTIVEOCCLUDERS = 48,
PATHNODESIZE = 4500,
@ -165,6 +166,7 @@ enum Config {
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
# define COMPRESSED_COL_VECTORS
#elif defined GTA_PC
# define GTA3_1_1_PATCH
//# define GTA3_STEAM_PATCH
@ -213,7 +215,10 @@ enum Config {
#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
//#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
//#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
//#define USE_TEXTURE_POOL
#define CUTSCENE_BORDERS_SWITCH
// Water & Particle
#define PC_PARTICLE
@ -242,8 +247,7 @@ enum Config {
//# define PS2_MENU_USEALLPAGEICONS
#else
//# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc.
# define MENU_MAP // VC-like menu map. Make sure you have new menu.txd
# define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
# define MAP_ENHANCEMENTS // Adding waypoint etc.
# define TRIANGLE_BACK_BUTTON
//# define CIRCLE_BACK_BUTTON
//#define CUSTOM_FRONTEND_OPTIONS
@ -257,7 +261,7 @@ enum Config {
//#define MISSION_REPLAY // mobile feature
#endif
//#define SIMPLIER_MISSIONS // apply simplifications from mobile
//#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define SCRIPT_LOG_FILE_LEVEL 1 // 0 == no log, 1 == overwrite every frame, 2 == full log
#ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
@ -270,7 +274,7 @@ enum Config {
// Vehicles
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
//#define REMOVE_TREADABLE_PATHFIND
#define CPLANE_ROTORS // make the rotors of the NPC police heli rotate
// Pickups
//#define MONEY_MESSAGES
@ -286,3 +290,6 @@ enum Config {
// Camera
#define IMPROVED_CAMERA // Better Debug cam, and maybe more in the future
#define FREE_CAM // Rotating cam
// Audio
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot

View file

@ -61,6 +61,8 @@
#include "MemoryCard.h"
#include "SceneEdit.h"
#include "debugmenu.h"
#include "Occlusion.h"
#include "Ropes.h"
GlobalScene Scene;
@ -249,7 +251,11 @@ DoFade(void)
}
// This is CCamera::GetScreenRect in VC
if(TheCamera.m_WideScreenOn){
if(TheCamera.m_WideScreenOn
#ifdef CUTSCENE_BORDERS_SWITCH
&& CMenuManager::m_PrefsCutsceneBorders
#endif
){
float y = SCREEN_HEIGHT/2 * TheCamera.m_ScreenReductionPercentage/100.0f;
rect.left = 0.0f;
rect.right = SCREEN_WIDTH;
@ -299,7 +305,12 @@ PluginAttach(void)
return FALSE;
}
#ifndef LIBRW
if (!RtAnimInitialize())
{
return FALSE;
}
#endif
if( !RpHAnimPluginAttach() )
{
printf("Couldn't attach RpHAnim plugin\n");
@ -464,6 +475,11 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
{
CSprite2d *splash;
#ifdef DISABLE_LOADING_SCREEN
if (str1 && str2)
return;
#endif
#ifndef RANDOMSPLASH
splashscreen = "LOADSC0";
#endif
@ -858,6 +874,7 @@ RenderEffects(void)
CGlass::Render();
CWaterCannons::Render();
CSpecialFX::Render();
CRopes::Render();
CShadows::RenderStaticShadows();
CShadows::RenderStoredShadows();
CSkidmarks::Render();
@ -885,7 +902,11 @@ Render2dStuff(void)
CReplay::Display();
CPickups::RenderPickUpText();
if(TheCamera.m_WideScreenOn)
if(TheCamera.m_WideScreenOn
#ifdef CUTSCENE_BORDERS_SWITCH
&& CMenuManager::m_PrefsCutsceneBorders
#endif
)
TheCamera.DrawBordersForWideScreen();
CPed *player = FindPlayerPed();
@ -930,6 +951,7 @@ Render2dStuff(void)
CGarages::PrintMessages();
CPad::PrintErrorMessage();
CFont::DrawFonts();
COcclusion::Render();
#ifdef DEBUGMENU
DebugMenuRender();

View file

@ -1,94 +0,0 @@
#define WITHWINDOWS
#include "common.h"
#include "patcher.h"
#include <algorithm>
#include <vector>
StaticPatcher *StaticPatcher::ms_head;
StaticPatcher::StaticPatcher(Patcher func)
: m_func(func)
{
m_next = ms_head;
ms_head = this;
}
void
StaticPatcher::Apply()
{
StaticPatcher *current = ms_head;
while(current){
current->Run();
current = current->m_next;
}
ms_head = nil;
}
#ifdef _WIN32
std::vector<uint32> usedAddresses;
static DWORD protect[2];
static uint32 protect_address;
static uint32 protect_size;
void
Protect_internal(uint32 address, uint32 size)
{
protect_address = address;
protect_size = size;
VirtualProtect((void*)address, size, PAGE_EXECUTE_READWRITE, &protect[0]);
}
void
Unprotect_internal(void)
{
VirtualProtect((void*)protect_address, protect_size, protect[0], &protect[1]);
}
void
InjectHook_internal(uint32 address, uint32 hook, int type)
{
if(std::any_of(usedAddresses.begin(), usedAddresses.end(),
[address](uint32 value) { return value == address; })) {
debug("Used address %#06x twice when injecting hook\n", address);
}
usedAddresses.push_back(address);
switch(type){
case PATCH_JUMP:
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &protect[0]);
*(uint8*)address = 0xE9;
break;
case PATCH_CALL:
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &protect[0]);
*(uint8*)address = 0xE8;
break;
default:
VirtualProtect((void*)(address + 1), 4, PAGE_EXECUTE_READWRITE, &protect[0]);
break;
}
*(ptrdiff_t*)(address + 1) = hook - address - 5;
if(type == PATCH_NOTHING)
VirtualProtect((void*)(address + 1), 4, protect[0], &protect[1]);
else
VirtualProtect((void*)address, 5, protect[0], &protect[1]);
}
#else
void
Protect_internal(uint32 address, uint32 size)
{
}
void
Unprotect_internal(void)
{
}
void
InjectHook_internal(uint32 address, uint32 hook, int type)
{
}
#endif

View file

@ -1,144 +0,0 @@
#pragma once
#define WRAPPER __declspec(naked)
#define DEPRECATED __declspec(deprecated)
#define EAXJMP(a) { _asm mov eax, a _asm jmp eax }
#define VARJMP(a) { _asm jmp a }
#define WRAPARG(a) UNREFERENCED_PARAMETER(a)
#include <string.h> //memset
enum
{
PATCH_CALL,
PATCH_JUMP,
PATCH_NOTHING,
};
enum
{
III_10 = 1,
III_11,
III_STEAM,
VC_10,
VC_11,
VC_STEAM
};
extern int gtaversion;
class StaticPatcher
{
private:
using Patcher = void(*)();
Patcher m_func;
StaticPatcher *m_next;
static StaticPatcher *ms_head;
void Run() { m_func(); }
public:
StaticPatcher(Patcher func);
static void Apply();
};
template<typename T>
inline T AddressByVersion(uint32_t addressIII10, uint32_t addressIII11, uint32_t addressIIISteam, uint32_t addressvc10, uint32_t addressvc11, uint32_t addressvcSteam)
{
if(gtaversion == -1){
if(*(uint32_t*)0x5C1E75 == 0xB85548EC) gtaversion = III_10;
else if(*(uint32_t*)0x5C2135 == 0xB85548EC) gtaversion = III_11;
else if(*(uint32_t*)0x5C6FD5 == 0xB85548EC) gtaversion = III_STEAM;
else if(*(uint32_t*)0x667BF5 == 0xB85548EC) gtaversion = VC_10;
else if(*(uint32_t*)0x667C45 == 0xB85548EC) gtaversion = VC_11;
else if(*(uint32_t*)0x666BA5 == 0xB85548EC) gtaversion = VC_STEAM;
else gtaversion = 0;
}
switch(gtaversion){
case III_10:
return (T)addressIII10;
case III_11:
return (T)addressIII11;
case III_STEAM:
return (T)addressIIISteam;
case VC_10:
return (T)addressvc10;
case VC_11:
return (T)addressvc11;
case VC_STEAM:
return (T)addressvcSteam;
default:
return (T)0;
}
}
inline bool
is10(void)
{
return gtaversion == III_10 || gtaversion == VC_10;
}
inline bool
isIII(void)
{
return gtaversion >= III_10 && gtaversion <= III_STEAM;
}
inline bool
isVC(void)
{
return gtaversion >= VC_10 && gtaversion <= VC_STEAM;
}
#define PTRFROMCALL(addr) (uint32_t)(*(uint32_t*)((uint32_t)addr+1) + (uint32_t)addr + 5)
#define INTERCEPT(saved, func, a) \
{ \
saved = PTRFROMCALL(a); \
InjectHook(a, func); \
}
void InjectHook_internal(uint32 address, uint32 hook, int type);
void Protect_internal(uint32 address, uint32 size);
void Unprotect_internal(void);
template<typename T, typename AT> inline void
Patch(AT address, T value)
{
Protect_internal((uint32)address, sizeof(T));
*(T*)address = value;
Unprotect_internal();
}
template<typename AT> inline void
Nop(AT address, unsigned int nCount)
{
Protect_internal((uint32)address, nCount);
memset((void*)address, 0x90, nCount);
Unprotect_internal();
}
template <typename T> inline void
InjectHook(uintptr_t address, T hook, unsigned int nType = PATCH_NOTHING)
{
InjectHook_internal(address, reinterpret_cast<uintptr_t>((void *&)hook), nType);
}
inline void ExtractCall(void *dst, uint32_t a)
{
*(uint32_t*)dst = (uint32_t)(*(uint32_t*)(a+1) + a + 5);
}
template<typename T>
inline void InterceptCall(void *dst, T func, uint32_t a)
{
ExtractCall(dst, a);
InjectHook(a, func);
}
template<typename T>
inline void InterceptVmethod(void *dst, T func, uint32_t a)
{
*(uint32_t*)dst = *(uint32_t*)a;
Patch(a, func);
}
#define STARTPATCHES static StaticPatcher Patcher([](){
#define ENDPATCHES });

View file

@ -2,8 +2,8 @@
#define WITHWINDOWS
#include "common.h"
#include "crossplatform.h"
#include "patcher.h"
#include "Renderer.h"
#include "Occlusion.h"
#include "Credits.h"
#include "Camera.h"
#include "Weather.h"
@ -77,7 +77,6 @@ mysrand(unsigned int seed)
void ReloadFrontendOptions(void)
{
RemoveCustomFrontendOptions();
CustomFrontendOptionsPopulate();
}
@ -135,10 +134,20 @@ void ToggleFreeCam(int8 action)
}
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
void BorderModeChange(int8 displayedValue)
{
CMenuManager::m_PrefsCutsceneBorders = !!displayedValue;
FrontEndMenuManager.SaveSettings();
}
#endif
// Reloaded on language change, so you can use hardcoded wchar* and TheText.Get with peace of mind
void
CustomFrontendOptionsPopulate(void)
{
RemoveCustomFrontendOptions(); // if exist
#ifdef MORE_LANGUAGES
FrontendOptionSetPosition(MENUPAGE_LANGUAGE_SETTINGS);
FrontendOptionAddDynamic(TheText.Get("FEL_POL"), nil, LangPolSelect, nil);
@ -152,16 +161,17 @@ CustomFrontendOptionsPopulate(void)
FrontendOptionAddSelect(TheText.Get("SCRFOR"), screenModes, 2, (int8*)&FrontEndMenuManager.m_nPrefsWindowed, true, ScreenModeChange, nil);
#endif
#ifdef MENU_MAP
FrontendOptionSetPosition(MENUPAGE_PAUSE_MENU, 2);
FrontendOptionAddRedirect(TheText.Get("FEG_MAP"), MENUPAGE_MAP);
#endif
#ifdef FREE_CAM
static const wchar *text = (wchar*)L"TOGGLE FREE CAM";
FrontendOptionSetPosition(MENUPAGE_CONTROLLER_PC, 1);
FrontendOptionAddDynamic(text, nil, ToggleFreeCam, nil);
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
static const wchar *off_on[] = { TheText.Get("FEM_OFF"), TheText.Get("FEM_ON") };
FrontendOptionSetPosition(MENUPAGE_GRAPHICS_SETTINGS, 9);
FrontendOptionAddSelect((const wchar *)L"CUTSCENE BORDERS", off_on, 2, (int8 *)&CMenuManager::m_PrefsCutsceneBorders, false, BorderModeChange, nil);
#endif
}
#endif
@ -252,7 +262,7 @@ FixCar(void)
}
}
#ifdef MENU_MAP
#ifdef MAP_ENHANCEMENTS
static void
TeleportToWaypoint(void)
{
@ -474,6 +484,8 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Spawn", "Spawn PCJ 600", [](){ SpawnCar(MI_PCJ600); });
DebugMenuAddCmd("Spawn", "Spawn Faggio", [](){ SpawnCar(MI_FAGGIO); });
DebugMenuAddCmd("Spawn", "Spawn Freeway", [](){ SpawnCar(MI_FREEWAY); });
DebugMenuAddCmd("Spawn", "Spawn Squalo", [](){ SpawnCar(MI_SQUALO); });
DebugMenuAddCmd("Spawn", "Spawn Skimmer", [](){ SpawnCar(MI_SKIMMER); });
DebugMenuAddVarBool8("Render", "Draw hud", &CHud::m_Wants_To_Draw_Hud, nil);
DebugMenuAddVarBool8("Render", "Backface Culling", &gBackfaceCulling, nil);
@ -483,6 +495,7 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "Frame limiter", &FrontEndMenuManager.m_PrefsFrameLimiter, nil);
DebugMenuAddVarBool8("Render", "VSynch", &FrontEndMenuManager.m_PrefsVsync, nil);
DebugMenuAddVar("Render", "Max FPS", &RsGlobal.maxFPS, nil, 1, 1, 1000, nil);
DebugMenuAddVarBool8("Render", "Occlusion debug", &bDisplayOccDebugStuff, nil);
DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Path Links", &gbShowCarPathsLinks, nil);
@ -497,7 +510,7 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "pad 1 -> pad 2", &CPad::m_bMapPadOneToPadTwo, nil);
DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil);
#ifdef MENU_MAP
#ifdef MAP_ENHANCEMENTS
DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint);
#endif
DebugMenuAddCmd("Debug", "Switch car collision", SwitchCarCollision);

View file

@ -17,7 +17,7 @@ CBuilding::ReplaceWithNewModel(int32 id)
m_modelIndex = id;
if(bIsBIGBuilding)
if(m_level == LEVEL_NONE || m_level == CGame::currLevel)
if(m_level == LEVEL_GENERIC || m_level == CGame::currLevel)
CStreaming::RequestModel(id, STREAMFLAGS_DONT_REMOVE);
}

View file

@ -31,6 +31,7 @@
#include "Ped.h"
#include "Dummy.h"
#include "WindModifiers.h"
#include "Occlusion.h"
//--MIAMI: file almost done (see TODO)
@ -359,8 +360,8 @@ CEntity::SetupBigBuilding(void)
if(mi->m_lodDistances[0] <= 2000.0f)
bStreamBIGBuilding = true;
if(mi->m_lodDistances[0] > 2500.0f || mi->m_ignoreDrawDist)
m_level = LEVEL_NONE;
else if(m_level == LEVEL_NONE)
m_level = LEVEL_GENERIC;
else if(m_level == LEVEL_GENERIC)
printf("%s isn't in a level\n", mi->GetName());
}
@ -619,6 +620,23 @@ CEntity::PruneReferences(void)
}
}
// Clean up the reference from *pent -> 'this'
void
CEntity::CleanUpOldReference(CEntity **pent)
{
CReference* ref, ** lastnextp;
lastnextp = &m_pFirstReference;
for (ref = m_pFirstReference; ref; ref = ref->next) {
if (ref->pentity == pent) {
*lastnextp = ref->next;
ref->next = CReferences::pEmptyList;
CReferences::pEmptyList = ref;
break;
}
lastnextp = &ref->next;
}
}
void
CEntity::UpdateRpHAnim(void)
{
@ -630,7 +648,7 @@ CEntity::UpdateRpHAnim(void)
char buf[256];
if(this == (CEntity*)FindPlayerPed())
for(i = 0; i < hier->numNodes; i++){
RpHAnimStdKeyFrame *kf = (RpHAnimStdKeyFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
RpHAnimStdInterpFrame *kf = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s",
kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real,
kf->t.x, kf->t.y, kf->t.z,
@ -1157,3 +1175,36 @@ bool IsEntityPointerValid(CEntity* pEntity)
}
return false;
}
bool CEntity::IsEntityOccluded(void) {
CVector coors;
float width, height;
if (COcclusion::NumActiveOccluders == 0 || !CalcScreenCoors(GetBoundCentre(), &coors, &width, &height))
return false;
float area = Max(width, height) * GetBoundRadius() * 0.9f;
for (int i = 0; i < COcclusion::NumActiveOccluders; i++) {
if (coors.z - (GetBoundRadius() * 0.85f) > COcclusion::aActiveOccluders[i].radius) {
if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, area)) {
return true;
}
if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) {
CVector min = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.min;
CVector max = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.max;
if (CalcScreenCoors(min, &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
if (CalcScreenCoors(CVector(max.x, max.y, min.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
if (CalcScreenCoors(CVector(max.x, min.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
if (CalcScreenCoors(CVector(min.x, max.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
return true;
}
}
}
return false;
}

View file

@ -156,8 +156,7 @@ public:
bool GetIsOnScreenComplex(void);
bool IsVisible(void) { return m_rwObject && bIsVisible && GetIsOnScreen(); }
bool IsVisibleComplex(void) { return m_rwObject && bIsVisible && GetIsOnScreenComplex(); }
// TODO(MIAMI):
bool IsEntityOccluded(void) { return false; }
bool IsEntityOccluded(void);
int16 GetModelIndex(void) const { return m_modelIndex; }
void UpdateRwFrame(void);
void SetupBigBuilding(void);
@ -169,6 +168,7 @@ public:
void RegisterReference(CEntity **pent);
void ResolveReferences(void);
void PruneReferences(void);
void CleanUpOldReference(CEntity **pent);
#ifdef PED_SKIN
void UpdateRpHAnim(void);

View file

@ -75,7 +75,7 @@ CPhysical::CPhysical(void)
#ifdef FIX_BUGS
m_nSurfaceTouched = SURFACE_DEFAULT;
#endif
m_nZoneLevel = LEVEL_NONE;
m_nZoneLevel = LEVEL_GENERIC;
bIsFrozen = false;
bDontLoadCollision = false;

View file

@ -35,9 +35,9 @@ RwReal RwV3dLength(const RwV3d * in) { return length(*in); }
//void RwV3dAssign(RwV3d * out, const RwV3d * ina);
void RwV3dAdd(RwV3d * out, const RwV3d * ina, const RwV3d * inb) { *out = add(*ina, *inb); }
void RwV3dSub(RwV3d * out, const RwV3d * ina, const RwV3d * inb) { *out = sub(*ina, *inb); }
//void RwV3dScale(RwV3d * out, const RwV3d * in, RwReal scalar);
//void RwV3dIncrementScaled(RwV3d * out, const RwV3d * in, RwReal scalar);
//void RwV3dNegate(RwV3d * out, const RwV3d * in);
void RwV3dScale(RwV3d * out, const RwV3d * in, RwReal scalar) { *out = scale(*in, scalar); }
void RwV3dIncrementScaled(RwV3d * out, const RwV3d * in, RwReal scalar) { *out = add(*out, scale(*in, scalar)); }
void RwV3dNegate(RwV3d * out, const RwV3d * in) { *out = neg(*in); }
RwReal RwV3dDotProduct(const RwV3d * ina, const RwV3d * inb) { return dot(*ina, *inb); }
//void RwV3dCrossProduct(RwV3d * out, const RwV3d * ina, const RwV3d * inb);
RwV3d *RwV3dTransformPoints(RwV3d * pointsOut, const RwV3d * pointsIn, RwInt32 numPoints, const RwMatrix * matrix)
@ -137,7 +137,7 @@ RwCamera *RwCameraCreate(void) { return rw::Camera::create(); }
RwCamera *RwCameraClone(RwCamera * camera) { return camera->clone(); }
RwCamera *RwCameraSetViewOffset(RwCamera *camera, const RwV2d *offset) { camera->setViewOffset(offset); return camera; }
RwCamera *RwCameraSetViewWindow(RwCamera *camera, const RwV2d *viewWindow) { camera->setViewWindow(viewWindow); return camera; }
RwCamera *RwCameraSetProjection(RwCamera *camera, RwCameraProjection projection);
RwCamera *RwCameraSetProjection(RwCamera *camera, RwCameraProjection projection) { camera->projection = projection; return camera; }
RwCamera *RwCameraSetNearClipPlane(RwCamera *camera, RwReal nearClip) { camera->setNearPlane(nearClip); return camera; }
RwCamera *RwCameraSetFarClipPlane(RwCamera *camera, RwReal farClip) { camera->setFarPlane(farClip); return camera; }
RwInt32 RwCameraRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
@ -308,7 +308,7 @@ ConvertTexRaster(rw::Raster *ras)
Image *img = ras->toImage();
ras->destroy();
img->unindex();
img->unpalettize();
ras = Raster::createFromImage(img);
img->destroy();
return ras;
@ -376,23 +376,19 @@ RwStream *RwStreamOpen(RwStreamType type, RwStreamAccessType accessType, const v
file = rwNewT(StreamFile, 1, 0);
memcpy(file, &fakefile, sizeof(StreamFile));
#ifndef _WIN32
// Be case-insensitive and fix backslashes (from https://github.com/OneSadCookie/fcaseopen/)
FILE* first = fopen((char*)pData, "r");
char *r;
if (!first) {
r = (char*)alloca(strlen((char*)pData) + 2);
// Use default path(and pass error handling to librw) if we can't find any match
if (!casepath((char*)pData, r))
r = (char*)pData;
char *r = casepath((char*)pData);
if (r) {
if (file->open((char*)r, mode)) {
free(r);
return file;
}
free(r);
} else
fclose(first);
if(file->open((char*)r, mode))
return file;
#else
if(file->open((char*)pData, mode))
return file;
#endif
{
if (file->open((char*)pData, mode))
return file;
}
rwFree(file);
return nil;
}
@ -856,12 +852,41 @@ RpSkin *RpSkinGeometryGetSkin( RpGeometry *geometry ) { return Skin::get(geometr
RpAtomic *RpSkinAtomicSetHAnimHierarchy( RpAtomic *atomic, RpHAnimHierarchy *hierarchy ) { Skin::setHierarchy(atomic, hierarchy); return atomic; }
RpHAnimHierarchy *RpSkinAtomicGetHAnimHierarchy( const RpAtomic *atomic ) { return Skin::getHierarchy(atomic); }
RwImage *
RtBMPImageWrite(RwImage *image, const RwChar *imageName)
{
#ifndef _WIN32
char *r = casepath(imageName);
if (r) {
rw::writeBMP(image, r);
free(r);
} else {
rw::writeBMP(image, imageName);
}
#else
rw::writeBMP(image, imageName);
#endif
return image;
}
RwImage *
RtBMPImageRead(const RwChar *imageName)
{
#ifndef _WIN32
RwImage *image;
char *r = casepath(imageName);
if (r) {
image = rw::readBMP(r);
free(r);
} else {
image = rw::readBMP(imageName);
}
return image;
RwImage *RtBMPImageWrite(RwImage * image, const RwChar * imageName) { rw::writeBMP(image, imageName); return image; }
RwImage *RtBMPImageRead(const RwChar * imageName) { return rw::readBMP(imageName); }
#else
return rw::readBMP(imageName);
#endif
}
#include "rtquat.h"

View file

@ -17,7 +17,15 @@ struct RpHAnimStdKeyFrame
RtQuat q;
RwV3d t;
};
// same story, this one only exists in later RW versions
// but we need it for 64 bit builds because offset and size differs!
struct RpHAnimStdInterpFrame
{
RpHAnimStdKeyFrame *keyFrame1;
RpHAnimStdKeyFrame *keyFrame2;
RtQuat q;
RwV3d t;
};
enum RpHAnimHierarchyFlag
{
@ -56,7 +64,7 @@ RwBool RpHAnimHierarchyUpdateMatrices(RpHAnimHierarchy *hierarchy);
#define rpHANIMHIERARCHYGETINTERPFRAME( hierarchy, nodeIndex ) \
( (void *)( ( (RwUInt8 *)&(hierarchy->interpolator[1]) + \
((nodeIndex) * \
hierarchy->interpolator->currentAnimKeyFrameSize) ) ) )
hierarchy->interpolator->currentInterpKeyFrameSize) ) ) )
RpHAnimAnimation *RpHAnimAnimationCreate(RwInt32 typeID, RwInt32 numFrames, RwInt32 flags, RwReal duration);

View file

@ -15,3 +15,5 @@ inline float Sqrt(float x) { return sqrtf(x); }
inline float RecipSqrt(float x, float y) { return x/Sqrt(y); }
inline float RecipSqrt(float x) { return RecipSqrt(1.0f, x); }
inline float Pow(float x, float y) { return powf(x, y); }
inline float Floor(float x) { return floorf(x); }
inline float Ceil(float x) { return ceilf(x); }

View file

@ -110,7 +110,7 @@ CPedModelInfo::CreateHitColModelSkinned(RpClump *clump)
max.x = max.y = 0.5f;
max.z = 1.2f;
colmodel->boundingBox.Set(min, max);
colmodel->level = LEVEL_NONE;
colmodel->level = LEVEL_GENERIC;
m_hitColModel = colmodel;
}

View file

@ -89,7 +89,17 @@ RwObjectNameIdAssocation boatIds[] = {
{ "boat_flap_right", BOAT_FLAP_RIGHT, 0 },
{ "boat_rearflap_left", BOAT_REARFLAP_LEFT, 0 },
{ "boat_rearflap_right", BOAT_REARFLAP_RIGHT, 0 },
#ifdef FIX_BUGS
// let's just accept both
{ "windscreen", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST },
{ "windscreen_hi_ok", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST },
#else
#ifdef GTA_PS2
{ "windscreen", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST },
#else
{ "windscreen_hi_ok", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST },
#endif
#endif
{ "ped_frontseat", BOAT_POS_FRONTSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
{ nil, 0, 0 }
};
@ -679,7 +689,11 @@ ChooseComponent(int32 rule, int32 comps)
return COMPRULE_COMPN(comps, n-1);
return -1;
case 4:
#ifdef FIX_BUGS
return CGeneral::GetRandomNumberInRange(0, 6);
#else
return CGeneral::GetRandomNumberInRange(0, 5);
#endif
}
return -1;
}
@ -1081,7 +1095,7 @@ CVehicleModelInfo::SetEnvironmentMapCB(RpAtomic *atomic, void *data)
RpGeometry *geo;
geo = RpAtomicGetGeometry(atomic);
fx = 0;
fx = rpMATFXEFFECTNULL;
RpGeometryForAllMaterials(geo, GetMatFXEffectMaterialCB, &fx);
if(fx != rpMATFXEFFECTNULL){
RpMatFXAtomicEnableEffects(atomic);

View file

@ -170,9 +170,13 @@ CCivilianPed::CivilianAI(void)
}
}
// --MIAMI: Done except comments
void
CCivilianPed::ProcessControl(void)
{
if (CharCreatedBy == TODO_CHAR)
return;
CPed::ProcessControl();
if (bWasPostponed)
@ -198,7 +202,8 @@ CCivilianPed::ProcessControl(void)
// fall through
case PED_SEEK_POS:
if (Seek()) {
if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || IsUseAttractorObjective(m_objective)) && m_pNextPathNode) {
if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_SPRINT_TO_AREA ||
IsUseAttractorObjective(m_objective)) && m_pNextPathNode) {
m_pNextPathNode = nil;
} else if (bRunningToPhone) {
@ -207,10 +212,10 @@ CCivilianPed::ProcessControl(void)
m_phoneId = -1;
} else {
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_REPORTING_CRIME;
m_nPedState = PED_FACE_PHONE;
SetPedState(PED_FACE_PHONE);
}
} else if (m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
if (m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
if (m_pedInObjective && m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
if (m_moved.Magnitude() == 0.0f) {
if (m_pedInObjective->m_nMoveState == PEDMOVE_STILL)
m_fRotationDest = m_pedInObjective->m_fRotationCur;
@ -218,7 +223,8 @@ CCivilianPed::ProcessControl(void)
} else if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT
&& m_pedInObjective && m_pedInObjective->m_nMoveState != PEDMOVE_STILL) {
SetMoveState(m_pedInObjective->m_nMoveState);
} else if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || IsUseAttractorObjective(m_objective)) {
} else if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_SPRINT_TO_AREA ||
IsUseAttractorObjective(m_objective)) {
SetIdle();
} else {
RestorePreviousState();
@ -228,7 +234,7 @@ CCivilianPed::ProcessControl(void)
break;
case PED_FACE_PHONE:
if (FacePhone())
m_nPedState = PED_MAKE_CALL;
SetPedState(PED_MAKE_CALL);
break;
case PED_MAKE_CALL:
if (MakePhonecall())
@ -284,6 +290,8 @@ CCivilianPed::ProcessControl(void)
GetPosition().x - m_pMyVehicle->GetPosition().x, GetPosition().y - m_pMyVehicle->GetPosition().y, 0.0f);
DMAudio.PlayOneShot(m_pMyVehicle->m_audioEntityId, SOUND_CAR_JERK, 0.0f);
m_pMyVehicle->pDriver->Say(SOUND_PED_PLAYER_BEFORESEX);
Say(SOUND_PED_PLAYER_BEFORESEX);
int playerSexFrequency = CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency;
if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney >= 10 && playerSexFrequency > 250) {
@ -300,13 +308,17 @@ CCivilianPed::ProcessControl(void)
} else {
bWanderPathAfterExitingCar = true;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
m_pMyVehicle->pDriver->Say(SOUND_PED_PLAYER_AFTERSEX);
}
} else {
bWanderPathAfterExitingCar = true;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
m_pMyVehicle->pDriver->m_fHealth = CWorld::Players[0].m_nMaxHealth + 25.0f;
ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
m_pMyVehicle->pDriver->Say(SOUND_PED_PLAYER_AFTERSEX);
}
} else {
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
@ -319,6 +331,7 @@ CCivilianPed::ProcessControl(void)
} else {
bWanderPathAfterExitingCar = true;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
}
}
@ -340,6 +353,7 @@ CCivilianPed::ProcessControl(void)
CivilianAI();
if (CharCreatedBy == RANDOM_CHAR) {
// TODO(Miami): EnterVacantNearbyCars();
UseNearbyAttractors();
}

View file

@ -16,6 +16,8 @@
#include "CarCtrl.h"
#include "Renderer.h"
#include "Camera.h"
#include "PedPlacement.h"
#include "Ropes.h"
CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
{
@ -39,12 +41,13 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
m_wepAccuracy = 76;
break;
case COP_SWAT:
case COP_HELI_SWAT:
SetModelIndex(MI_SWAT);
GiveDelayedWeapon(WEAPONTYPE_UZI, 1000);
SetCurrentWeapon(WEAPONTYPE_UZI);
m_fArmour = 50.0f;
m_wepSkills = 32; /* TODO: what is this? seems unused */
m_wepAccuracy = 64;
m_wepAccuracy = 68;
break;
case COP_ARMY:
SetModelIndex(MI_ARMY);
@ -77,14 +80,20 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
field_5FE = 1;
m_bIsDisabledCop = false;
m_attackTimer = 0;
m_bBeatingSuspect = false;
m_bStopAndShootDisabledZone = false;
field_601 = false;
m_bZoneDisabled = false;
field_628 = -1;
m_nRoadblockNode = -1; // TODO(Miami): this will be nil
field_5FF = 0;
m_bThrowsSpikeTrap = false;
m_pRopeEntity = nil;
m_fAbseilPos = 0.0f;
m_bBeatingSuspect = false;
m_nHassleTimer = 0;
field_61C = 0;
field_624 = 0;
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt);
m_pPointGunAt = nil;
}
@ -93,24 +102,17 @@ CCopPed::~CCopPed()
ClearPursuit();
}
// --MIAMI: Done
// Parameter should always be CPlayerPed, but it seems they considered making civilians arrestable at some point
void
CCopPed::SetArrestPlayer(CPed *player)
{
if (!IsPedInControl() || !player)
return;
/*
switch (m_nCopType) {
case COP_FBI:
Say(SOUND_PED_ARREST_FBI);
break;
case COP_SWAT:
Say(SOUND_PED_ARREST_SWAT);
break;
default:
Say(SOUND_PED_ARREST_COP);
break;
} */
player->Say(SOUND_PED_PLAYER_REACTTOCOP);
Say(SOUND_PED_ARREST_COP);
if (player->EnteringCar()) {
if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer)
return;
@ -125,14 +127,14 @@ CCopPed::SetArrestPlayer(CPed *player)
} else if (player->m_nPedState != PED_DIE && player->m_nPedState != PED_DEAD && player->m_nPedState != PED_ARRESTED) {
player->m_nLastPedState = player->m_nPedState;
player->m_nPedState = PED_ARRESTED;
player->SetPedState(PED_ARRESTED);
FindPlayerPed()->m_bCanBeDamaged = false;
((CPlayerPed*)player)->m_pArrestingCop = this;
this->RegisterReference((CEntity**) &((CPlayerPed*)player)->m_pArrestingCop);
}
m_nPedState = PED_ARREST_PLAYER;
SetPedState(PED_ARREST_PLAYER);
SetObjective(OBJECTIVE_NONE);
m_prevObjective = OBJECTIVE_NONE;
bIsPointingGunAt = false;
@ -145,10 +147,11 @@ CCopPed::SetArrestPlayer(CPed *player)
player->m_pMyVehicle->bIsHandbrakeOn = true;
player->m_pMyVehicle->SetStatus(STATUS_PLAYER_DISABLED);
}
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE)
SetCurrentWeapon(WEAPONTYPE_COLT45);
}
// --MIAMI: Done
void
CCopPed::ClearPursuit(void)
{
@ -187,6 +190,7 @@ CCopPed::ClearPursuit(void)
bNotAllowedToDuck = false;
bKindaStayInSamePlace = false;
m_bStopAndShootDisabledZone = false;
field_601 = false;
m_bZoneDisabled = false;
ClearObjective();
if (IsPedInControl()) {
@ -204,10 +208,14 @@ CCopPed::ClearPursuit(void)
}
}
// --MIAMI: Done
// TODO: I don't know why they needed that parameter.
void
CCopPed::SetPursuit(bool ignoreCopLimit)
{
if (CTimer::GetTimeInMilliseconds() < field_61C)
return;
CWanted *wanted = FindPlayerPed()->m_pWanted;
if (m_bIsInPursuit || !IsPedInControl())
return;
@ -233,6 +241,7 @@ CCopPed::SetPursuit(bool ignoreCopLimit)
}
}
// --MIAMI: Done
void
CCopPed::ArrestPlayer(void)
{
@ -298,6 +307,7 @@ CCopPed::ScanForCrimes(void)
}
}
// --MIAMI: Done
void
CCopPed::CopAI(void)
{
@ -315,11 +325,6 @@ CCopPed::CopAI(void)
if (bHitSomethingLastFrame) {
m_bZoneDisabled = true;
m_bIsDisabledCop = true;
#ifdef FIX_BUGS
m_nRoadblockNode = -1;
#else
m_nRoadblockNode = 0;
#endif
bKindaStayInSamePlace = true;
bIsRunning = false;
bNotAllowedToDuck = false;
@ -346,6 +351,27 @@ CCopPed::CopAI(void)
}
if (wantedLevel > 0) {
if (!m_bIsDisabledCop) {
// Turn and shoot the player's vehicle, if possible
if (!m_bIsInPursuit && !GetWeapon()->IsTypeMelee() && FindPlayerVehicle() && m_fDistanceToTarget < CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange) {
if (FindPlayerVehicle()->m_vecMoveSpeed.Magnitude2D() > 0.1f) {
CVector2D distToVeh = GetPosition() - FindPlayerVehicle()->GetPosition();
distToVeh.Normalise();
CVector2D vehSpeed = FindPlayerVehicle()->m_vecMoveSpeed;
vehSpeed.Normalise();
if (DotProduct2D(distToVeh, vehSpeed) > 0.8f) {
SetLookFlag(playerOrHisVeh, true);
SetMoveState(PEDMOVE_STILL);
if (TurnBody()) {
SetAttack(FindPlayerVehicle());
SetShootTimer(CGeneral::GetRandomNumberInRange(500.0f, 1000.0f));
SetAttackTimer(CGeneral::GetRandomNumberInRange(200.0f, 300.0f));
}
} else if (m_nPedState == PED_ATTACK)
RestorePreviousState();
}
}
if (!m_bIsInPursuit || wanted->m_CurrentCops > wanted->m_MaxCops) {
CCopPed *copFarthestToTarget = nil;
float copFarthestToTargetDist = m_fDistanceToTarget;
@ -388,11 +414,14 @@ CCopPed::CopAI(void)
if (wantedLevel > 1 && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
SetCurrentWeapon(WEAPONTYPE_COLT45);
else if (wantedLevel == 1 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && !FindPlayerPed()->m_pCurrentPhysSurface) {
else if (wantedLevel == 1 && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED && !FindPlayerPed()->m_pCurrentPhysSurface) {
// i.e. if player is on top of car, cop will still use colt45.
SetCurrentWeapon(WEAPONTYPE_UNARMED);
SetCurrentWeapon(GetWeaponSlot(WEAPONTYPE_NIGHTSTICK) >= 0 ? WEAPONTYPE_NIGHTSTICK : WEAPONTYPE_UNARMED);
}
if (m_bBeatingSuspect && GetWeapon()->m_eWeaponType == WEAPONTYPE_NIGHTSTICK)
Say(SOUND_PED_PULLOUTWEAPON);
if (FindPlayerVehicle()) {
if (m_bBeatingSuspect) {
--wanted->m_CopsBeatingSuspect;
@ -403,18 +432,18 @@ CCopPed::CopAI(void)
}
return;
}
float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
SetCurrentWeapon(WEAPONTYPE_COLT45);
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
float weaponRange = weaponInfo->m_fRange;
SetLookFlag(playerOrHisVeh, true);
TurnBody();
SetCurrentWeapon(WEAPONTYPE_COLT45);
if (!bIsDucking) {
if (!bIsDucking || bCrouchWhenShooting && GetCrouchFireAnim(weaponInfo)) {
if (m_attackTimer >= CTimer::GetTimeInMilliseconds()) {
if (m_nPedState != PED_ATTACK && m_nPedState != PED_FIGHT && !m_bZoneDisabled) {
CVector targetDist = playerOrHisVeh->GetPosition() - GetPosition();
if (m_fDistanceToTarget > 30.0f) {
CAnimBlendAssociation* crouchShootAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RBLOCK_CSHOOT);
if (crouchShootAssoc)
crouchShootAssoc->blendDelta = -1000.0f;
if (bIsDucking)
ClearDuck();
// Target is coming onto us
if (DotProduct(playerOrHisVeh->m_vecMoveSpeed, targetDist) > 0.0f) {
@ -432,42 +461,23 @@ CCopPed::CopAI(void)
bNotAllowedToDuck = false;
bDuckAndCover = false;
} else {
// VC checks for != nil compared to buggy behaviour of III. I check for != -1 here.
#ifdef VC_PED_PORTS
// TODO(Miami): Roadblock system is still III
float dotProd;
if (m_nRoadblockNode != -1) {
// TODO(MIAMI): check this, i'm only getting this compile here....
CPathNode *roadBlockNode = &ThePaths.m_pathNodes[CRoadBlocks::RoadBlockNodes[m_nRoadblockNode]];
dotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockNode->GetPosition(), GetPosition() - roadBlockNode->GetPosition());
} else
dotProd = -1.0f;
if(dotProd >= 0.0f) {
#else
#ifndef FIX_BUGS
float copRoadDotProd, targetRoadDotProd;
#else
float copRoadDotProd = 1.0f, targetRoadDotProd = 1.0f;
if (m_nRoadblockNode != -1)
#endif
{
CTreadable* roadBlockRoad = ThePaths.m_mapObjects[CRoadBlocks::RoadBlockObjects[m_nRoadblockNode]];
CVector2D roadFwd = roadBlockRoad->GetForward();
copRoadDotProd = DotProduct2D(GetPosition() - roadBlockRoad->GetPosition(), roadFwd);
targetRoadDotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockRoad->GetPosition(), roadFwd);
}
// Roadblock may be towards road's fwd or opposite, so check both
if ((copRoadDotProd >= 0.0f || targetRoadDotProd >= 0.0f)
&& (copRoadDotProd <= 0.0f || targetRoadDotProd <= 0.0f)) {
#endif
bIsPointingGunAt = true;
} else {
if (bIsDucking)
ClearDuck();
m_bIsDisabledCop = false;
bKindaStayInSamePlace = false;
bNotAllowedToDuck = false;
bCrouchWhenShooting = false;
bIsDucking = false;
bDuckAndCover = false;
SetPursuit(false);
}
@ -475,7 +485,6 @@ CCopPed::CopAI(void)
}
} else {
if (m_fDistanceToTarget < weaponRange) {
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
CVector gunPos = weaponInfo->m_vecFireOffset;
TransformToNode(gunPos, PED_HANDR);
@ -484,6 +493,9 @@ CCopPed::CopAI(void)
if (!CWorld::ProcessLineOfSight(gunPos, playerOrHisVeh->GetPosition(), foundCol, foundEnt,
false, true, false, false, true, false, false)
|| foundEnt && foundEnt == playerOrHisVeh) {
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference((CEntity**) &m_pPointGunAt);
m_pPointGunAt = playerOrHisVeh;
if (playerOrHisVeh)
playerOrHisVeh->RegisterReference((CEntity**) &m_pPointGunAt);
@ -491,7 +503,7 @@ CCopPed::CopAI(void)
SetAttack(playerOrHisVeh);
SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000));
}
SetAttackTimer(CGeneral::GetRandomNumberInRange(100, 300));
SetAttackTimer(CGeneral::GetRandomNumberInRange(200, 300));
}
SetMoveState(PEDMOVE_STILL);
}
@ -521,10 +533,8 @@ CCopPed::CopAI(void)
ClearObjective();
SetWanderPath(CGeneral::GetRandomNumber() & 7);
}
}
#ifdef VC_PED_PORTS
else {
if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && CharCreatedBy == RANDOM_CHAR) {
} else {
if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && m_objective != OBJECTIVE_HASSLE_CHAR && CharCreatedBy == RANDOM_CHAR) {
for (int i = 0; i < m_numNearPeds; i++) {
CPed *nearPed = m_nearPeds[i];
if (nearPed->CharCreatedBy == RANDOM_CHAR) {
@ -544,12 +554,30 @@ CCopPed::CopAI(void)
nearPed->bBeingChasedByPolice = true;
return;
}
} else {
if (nearPed->m_nPedType != PEDTYPE_COP && !nearPed->IsPlayer()
&& nearPed->IsPedInControl() && m_nHassleTimer < CTimer::GetTimeInMilliseconds()) {
if (nearPed->m_objective == OBJECTIVE_NONE && nearPed->m_nPedState == PED_WANDER_PATH
&& !nearPed->m_pLookTarget && nearPed->m_lookTimer < CTimer::GetTimeInMilliseconds()) {
if ((GetPosition() - nearPed->GetPosition()).MagnitudeSqr() < sq(5.0f)) {
if (CWorld::GetIsLineOfSightClear(GetPosition(), nearPed->GetPosition(),
true, false, false, false, false, false, false)) {
Say(SOUND_PED_COP_REACTION);
SetObjective(OBJECTIVE_HASSLE_CHAR, nearPed);
nearPed->SetObjective(OBJECTIVE_WAIT_ON_FOOT_FOR_COP, this);
m_nHassleTimer = CTimer::GetTimeInMilliseconds() + 100000;
}
}
}
}
}
}
}
}
}
#endif
}
}
} else {
@ -560,18 +588,35 @@ CCopPed::CopAI(void)
bKindaStayInSamePlace = false;
bNotAllowedToDuck = false;
bCrouchWhenShooting = false;
bIsDucking = false;
bDuckAndCover = false;
if (bIsDucking)
ClearDuck();
if (m_pMyVehicle)
SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
}
}
}
// --MIAMI: Done except commented things
void
CCopPed::ProcessControl(void)
{
if (m_nCopType == COP_HELI_SWAT)
ProcessHeliSwat();
CPed::ProcessControl();
if (m_bThrowsSpikeTrap) {
// TODO(Miami)
/*
if (CGame::currArea != AREA_MALL)
ProcessStingerCop();
*/
return;
}
// TODO(Miami): CStinger::Process
if (bWasPostponed)
return;
@ -603,25 +648,36 @@ CCopPed::ProcessControl(void)
if (IsPedInControl())
SetIdle();
}
/*
if (m_bIsInPursuit) {
if (player->m_nPedState != PED_ARRESTED && !player->DyingOrDead()) {
switch (m_nCopType) {
case COP_FBI:
Say(SOUND_PED_PURSUIT_FBI);
break;
case COP_SWAT:
Say(SOUND_PED_PURSUIT_SWAT);
break;
case COP_ARMY:
Say(SOUND_PED_PURSUIT_ARMY);
break;
default:
Say(SOUND_PED_PURSUIT_COP);
break;
if (player->m_pWanted->m_CurrentCops == 1) {
Say(SOUND_PED_COP_ALONE);
} else {
int numCopsNear = 0;
for (int i = 0; i < player->m_numNearPeds; ++i) {
CPed *nearPed = player->m_nearPeds[i];
if (nearPed->m_nPedType == PEDTYPE_COP && nearPed->m_nPedState != PED_DEAD)
++numCopsNear;
}
if (numCopsNear <= 3) {
Say(SOUND_PED_COP_LITTLECOPSAROUND);
if (!player->bInVehicle) {
CVector distToPlayer = player->GetPosition() - GetPosition();
if (distToPlayer.MagnitudeSqr() < sq(20.0f)) {
player->Say(SOUND_PED_PLAYER_FARFROMCOPS);
if (player->m_nPedState != PED_ATTACK && player->m_nPedState != PED_AIM_GUN) {
player->SetLookFlag(this, false);
player->SetLookTimer(1000);
}
}
}
} else if ((CGeneral::GetRandomNumber() % 16) == 1) {
Say(SOUND_PED_COP_MANYCOPSAROUND);
}
}
}
} */
}
if (IsPedInControl()) {
CopAI();
@ -668,23 +724,10 @@ CCopPed::ProcessControl(void)
RestorePreviousObjective();
} else {
if (player->m_pMyVehicle && player->m_pMyVehicle->m_nNumGettingIn != 0) {
// This is 1.3f when arresting in car without seeking first (in above)
#if defined(VC_PED_PORTS) || defined(FIX_BUGS)
m_distanceToCountSeekDone = 1.3f;
#else
m_distanceToCountSeekDone = 2.0f;
#endif
}
if (bDuckAndCover) {
#if !defined(GTA3_1_1_PATCH) && !defined(VC_PED_PORTS)
if (!bNotAllowedToDuck && Seek()) {
SetMoveState(PEDMOVE_STILL);
SetMoveAnim();
SetPointGunAt(m_pedInObjective);
}
#endif
} else if (Seek()) {
if (!bDuckAndCover && Seek()) {
CVehicle *playerVeh = FindPlayerVehicle();
if (!playerVeh && player && player->EnteringCar()) {
SetArrestPlayer(player);
@ -715,35 +758,100 @@ CCopPed::ProcessControl(void)
}
}
}
if (!m_bStopAndShootDisabledZone)
return;
bool dontShoot = false;
if (GetIsOnScreen()) {
if (((CTimer::GetFrameCounter() + m_randomSeed) & 0x1F) == 17) {
CEntity *foundBuilding = nil;
CColPoint foundCol;
CVector lookPos = GetPosition() + CVector(0.0f, 0.0f, 0.7f);
CVector camPos = TheCamera.GetGameCamPosition();
CWorld::ProcessLineOfSight(camPos, lookPos, foundCol, foundBuilding,
true, false, false, false, false, false, false);
if (m_pPointGunAt)
Say(SOUND_PED_COP_UNK_129);
// He's at least 15.0 far, in disabled zone, collided into somewhere (that's why m_bStopAndShootDisabledZone set),
// and now has building on front of him. He's stupid, we don't need him.
if (foundBuilding) {
FlagToDestroyWhenNextProcessed();
dontShoot = true;
if (m_bStopAndShootDisabledZone) {
bool dontShoot = false;
if (GetIsOnScreen()) {
if (((CTimer::GetFrameCounter() + m_randomSeed) & 0x1F) == 17) {
CEntity* foundBuilding = nil;
CColPoint foundCol;
CVector lookPos = GetPosition() + CVector(0.0f, 0.0f, 0.7f);
CVector camPos = TheCamera.GetGameCamPosition();
CWorld::ProcessLineOfSight(camPos, lookPos, foundCol, foundBuilding,
true, false, false, false, false, false, false);
// He's at least 15.0 far, in disabled zone, collided into somewhere (that's why m_bStopAndShootDisabledZone set),
// and now has building on front of him. He's stupid, we don't need him.
if (foundBuilding) {
FlagToDestroyWhenNextProcessed();
dontShoot = true;
}
}
} else {
FlagToDestroyWhenNextProcessed();
dontShoot = true;
}
if (!dontShoot) {
bStopAndShoot = true;
bKindaStayInSamePlace = true;
bIsPointingGunAt = true;
SetAttack(m_pedInObjective);
}
}
if (field_624 >= 2 && m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT) {
CVector centre = GetPosition() + CVector(0.f, 0.f, 0.65f);
if (CWorld::TestSphereAgainstWorld(centre, 0.35f, this, true, false, false, false, false, false)) {
field_624 = 0;
m_bStopAndShootDisabledZone = true;
ClearPursuit();
SetObjective(OBJECTIVE_NONE);
SetWanderPath(CGeneral::GetRandomNumberInRange(0,8));
field_61C = CTimer::GetTimeInMilliseconds() + 30000;
} else {
field_624 = 0;
if (GetWeapon()->IsTypeMelee()) {
// TODO(Miami): enum
for (int i = 3; i < 7; i++) {
if (HasWeaponSlot(i)) {
SetCurrentWeapon(i);
break;
}
}
SetMoveState(PEDMOVE_STILL);
bStopAndShoot = true;
}
}
} else {
FlagToDestroyWhenNextProcessed();
dontShoot = true;
}
if (!dontShoot) {
bStopAndShoot = true;
bKindaStayInSamePlace = true;
bIsPointingGunAt = true;
SetAttack(m_pedInObjective);
}
} else if (CTimer::GetTimeStep() / 100.f <= m_fDistanceTravelled)
field_624 = 0;
}
// --MIAMI: Done
void
CCopPed::ProcessHeliSwat(void)
{
CVector bestPos = GetPosition();
SetPedState(PED_ABSEIL);
CPedPlacement::FindZCoorForPed(&bestPos);
if (GetPosition().z - 2.0f >= bestPos.z && m_pRopeEntity) {
m_fAbseilPos += 0.003f * CTimer::GetTimeStep();
m_vecMoveSpeed.z = -0.03f;
m_vecTurnSpeed = CVector(0.f, 0.f, (m_randomSeed % 32) * 0.003f - 0.05f);
CPhysical::ApplyTurnSpeed();
GetMatrix().Reorthogonalise();
CVector posOnRope;
if (CRopes::FindCoorsAlongRope(m_nRopeID, m_fAbseilPos, &posOnRope)) {
SetPosition(posOnRope);
} else {
bUsesCollision = true;
m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
SetPedState(PED_IDLE);
m_nCopType = COP_SWAT;
SetInTheAir();
bKnockedUpIntoAir = true;
}
Say(SOUND_PED_COP_HELIPILOTPHRASE);
} else {
bUsesCollision = true;
m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
SetPedState(PED_IDLE);
m_nCopType = COP_SWAT;
SetInTheAir();
bKnockedUpIntoAir = true;
}
}

View file

@ -6,7 +6,8 @@ enum eCopType
COP_STREET = 0,
COP_FBI = 1,
COP_SWAT = 2,
COP_ARMY = 3,
COP_HELI_SWAT = 3,
COP_ARMY = 4,
COP_MIAMIVICE = 5
};
@ -18,13 +19,18 @@ public:
bool m_bIsInPursuit;
bool m_bIsDisabledCop;
int8 field_5FE;
int8 field_5FF;
bool m_bBeatingSuspect;
bool m_bStopAndShootDisabledZone;
bool field_601; // set when police dragging player from car
bool m_bZoneDisabled;
float m_fAbseilPos;
eCopType m_nCopType;
bool m_bThrowsSpikeTrap;
CEntity *m_pRopeEntity; // CHeli or 1
uintptr m_nRopeID;
uint32 m_nHassleTimer;
uint32 field_61C;
int32 field_624;
int8 field_628;
CCopPed(eCopType, int32 modifier = 0);
@ -37,6 +43,7 @@ public:
void ArrestPlayer(void);
void ScanForCrimes(void);
void CopAI(void);
void ProcessHeliSwat(void);
};
#ifndef PED_SKIN

File diff suppressed because it is too large Load diff

View file

@ -30,6 +30,13 @@ struct PedAudioData
int m_nMaxRandomDelayTime;
};
enum
{
ATTACK_IN_PROGRESS,
CANT_ATTACK,
WATCH_UNTIL_HE_DISAPPEARS,
};
enum eFormation
{
FORMATION_UNDEFINED,
@ -98,7 +105,6 @@ enum PedFightMoves
FIGHTMOVE_PUNCHHOOK,
FIGHTMOVE_PUNCHJAB,
FIGHTMOVE_PUNCH,
FIGHTMOVE_BODYBLOW = FIGHTMOVE_PUNCH,
FIGHTMOVE_LONGKICK,
FIGHTMOVE_ROUNDHOUSE,
// Directionals
@ -460,11 +466,9 @@ public:
uint32 bIsDrowning : 1;
uint32 bDrownsInWater : 1;
//uint32 b156_4
uint32 b156_8 : 1;
uint32 bHeldHostageInCar : 1;
uint32 bIsPlayerFriend : 1;
#ifdef VC_PED_PORTS
uint32 bHeadStuckInCollision : 1;
#endif
uint32 bDeadPedInFrontOfCar : 1;
uint32 bStayInCarOnJack : 1;
@ -472,22 +476,21 @@ public:
uint32 bDoomAim : 1;
uint32 bCanBeShotInVehicle : 1;
//uint32 b157_8
//uint32 b157_10
//uint32 b157_20
uint32 bMakeFleeScream : 1;
uint32 bPushedAlongByCar : 1;
uint32 b157_40 : 1;
uint32 bIgnoreThreatsBehindObjects : 1;
uint32 bNeverEverTargetThisPed : 1;
uint32 bCrouchWhenScared : 1;
uint32 bKnockedOffBike : 1;
//uint32 b158_8
uint32 b158_8 : 1;
uint32 b158_10 : 1;
uint32 bBoughtIceCream : 1;
//uint32 b158_40
uint32 b158_40 : 1;
//uint32 b158_80
// our own flags
uint32 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator
uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
uint8 m_gangFlags;
@ -595,8 +598,8 @@ public:
uint8 m_wepAccuracy;
CEntity *m_pPointGunAt;
CVector m_vecHitLastPos;
uint32 m_curFightMove;
uint32 m_lastFightMove;
uint32 m_lastHitState; // TODO(Miami): What's this?
uint8 m_fightButtonPressure;
FightState m_fightState;
bool m_takeAStepAfterAttack;
@ -634,8 +637,8 @@ public:
uint32 m_threatFlags;
uint32 m_threatCheck;
uint32 m_lastThreatCheck;
uint32 m_sayType;
uint32 m_sayTimer;
uint32 m_delayedSoundID;
uint32 m_delayedSoundTimer;
uint32 m_lastSoundStart;
uint32 m_soundStart;
uint16 m_lastQueuedSound;
@ -667,6 +670,7 @@ public:
void AimGun(void);
void KillPedWithCar(CVehicle *veh, float impulse);
void Say(uint16 audio);
void Say(uint16 audio, int32 time);
void SetLookFlag(CEntity* target, bool keepTryingToLook, bool cancelPrevious = false);
void SetLookFlag(float direction, bool keepTryingToLook, bool cancelPrevious = false);
void SetLookTimer(int time);
@ -761,6 +765,8 @@ public:
void SetWaitState(eWaitState, void*);
bool FightStrike(CVector&, bool);
void FightHitPed(CPed*, CVector&, CVector&, int16);
int32 ChooseAttackPlayer(uint8, bool);
int32 ChooseAttackAI(uint8, bool);
int GetLocalDirection(const CVector2D &);
void StartFightDefend(uint8, uint8, uint8);
void PlayHitSound(CPed*);
@ -948,6 +954,8 @@ public:
void ClearWaitState(void);
void Undress(const char*);
void Dress(void);
int32 KillCharOnFootMelee(CVector&, CVector&, CVector&);
int32 KillCharOnFootArmed(CVector&, CVector&, CVector&);
bool HasWeaponSlot(uint8 slot) { return m_weapons[slot].m_eWeaponType != WEAPONTYPE_UNARMED; }
CWeapon& GetWeapon(uint8 slot) { return m_weapons[slot]; }
@ -964,6 +972,7 @@ public:
bool Dying(void) { return m_nPedState == PED_DIE; }
bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
bool OnGround(void) { return m_nPedState == PED_FALL || m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
bool OnGroundOrGettingUp(void) { return OnGround() || m_nPedState == PED_GETUP; }
bool Driving(void) { return m_nPedState == PED_DRIVING; }
bool InVehicle(void) { return bInVehicle && m_pMyVehicle; } // True when ped is sitting/standing in vehicle, not in enter/exit state.
@ -1032,6 +1041,20 @@ public:
else
return (AnimationId)0;
}
static AnimationId GetFinishingAttackAnim(CWeaponInfo* weapon) {
if (!!weapon->m_bFinish3rd)
return ANIM_MELEE_ATTACK_FINISH;
else
return (AnimationId)0;
}
static AnimationId GetSecondFireAnim(CWeaponInfo* weapon) {
if (!!weapon->m_bUse2nd)
return ANIM_WEAPON_FIRE_2ND; // or ANIM_MELEE_ATTACK_2ND
else
return (AnimationId)0;
}
// --
// My additions, because there were many, many instances of that.

View file

@ -70,17 +70,17 @@ const C2dEffect* CVehicleToEffect::ChooseEffect(const CVector& pos) const
if (!m_pVehicle)
return nil;
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetRight()) > 0.0f) {
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
return &m_effects[0];
else
return &m_effects[2];
}
else {
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
return &m_effects[1];
else
return &m_effects[3];
}
else {
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
return &m_effects[0];
else
return &m_effects[2];
}
}
bool CVehicleToEffect::HasThisEffect(C2dEffect* pEffect) const
@ -137,8 +137,8 @@ void CPedAttractorManager::RemoveIceCreamVanEffects(C2dEffect* pEffect)
for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend();) {
if (assoc->GetVehicle() != pVehicle)
return;
size_t total = 0;
for (size_t j = 0; j < NUM_ATTRACTORS_FOR_ICECREAM_VAN; j++) {
uint32 total = 0;
for (uint32 j = 0; j < NUM_ATTRACTORS_FOR_ICECREAM_VAN; j++) {
if (FindAssociatedAttractor(assoc->GetEffect(j), vIceCreamAttractors))
total++;
}
@ -355,13 +355,13 @@ bool CPedAttractor::BroadcastArrival(CPed* pPed)
bool CPedAttractor::BroadcastDeparture(CPed* pPed)
{
int qid = -1;
for (size_t i = 0; i < vWaitingQueue.size(); i++){
for (uint32 i = 0; i < vWaitingQueue.size(); i++){
if (vWaitingQueue[i] == pPed)
qid = i;
}
if (qid < 0)
return false;
for (size_t i = qid + 1; i < vWaitingQueue.size(); i++) {
for (uint32 i = qid + 1; i < vWaitingQueue.size(); i++) {
CVector pos;
float heading;
float time;
@ -401,7 +401,7 @@ bool CPedAttractor::BroadcastDeparture(CPed* pPed)
bool CPedShelterAttractor::BroadcastDeparture(CPed* pPed)
{
int qid = -1;
for (size_t i = 0; i < vWaitingQueue.size(); i++) {
for (uint32 i = 0; i < vWaitingQueue.size(); i++) {
if (vWaitingQueue[i] == pPed)
qid = i;
}

View file

@ -108,8 +108,8 @@ public:
float ComputeDeltaHeading() const;
float ComputeDeltaPos() const;
void ComputeAttractTime(int32 id, bool, float& time) const;
int32 GetNoOfRegisteredPeds() const { return vWaitingQueue.size() + vApproachingQueue.size(); }
int32 ComputeFreeSlot() const { return vWaitingQueue.size(); }
int32 GetNoOfRegisteredPeds() const { return (int32)(vWaitingQueue.size() + vApproachingQueue.size()); }
int32 ComputeFreeSlot() const { return (int32)vWaitingQueue.size(); }
bool IsInQueue(CPed*) const;
bool RegisterPed(CPed*);
bool BroadcastArrival(CPed*);

View file

@ -155,4 +155,14 @@ CPed::Say(uint16 audio)
m_queuedSound = audioToPlay;
}
}
}
// --MIAMI: Done
void
CPed::Say(uint16 audio, int32 time)
{
if (m_delayedSoundID == -1) {
m_delayedSoundID = audio;
m_delayedSoundTimer = CTimer::GetTimeInMilliseconds() + time;
}
}

View file

@ -7,10 +7,11 @@
#include "Sprite.h"
#include "Text.h"
// TODO(Miami)
static char ObjectiveText[][28] = {
"No Obj",
"Wait on Foot",
"Wait on Foot For Cop",
"Flee on Foot Till Safe",
"Guard Spot",
"Guard Area",
@ -21,6 +22,8 @@ static char ObjectiveText[][28] = {
"Flee Char on Foot Till Safe",
"Flee Char on Foot Always",
"GoTo Char on Foot",
"GoTo Char on Foot Walking",
"Hassle Char",
"Follow Char in Formation",
"Leave Car",
"Enter Car as Passenger",
@ -42,10 +45,9 @@ static char ObjectiveText[][28] = {
"Catch Train",
"Buy IceCream",
"Steal Any Car",
"Steal Any Mission Car",
"Mug Char",
#ifdef VC_PED_PORTS
"Leave Car and Die"
#endif
"Leave Car and Die",
};
static char StateText[][18] = {
@ -82,8 +84,14 @@ static char StateText[][18] = {
"Investigate",
"Step away",
"On Fire",
"Sun Bathe",
"Flash",
"Jog",
"Answer Mobile",
"Unknown",
"STATES_NO_AI",
"Abseil",
"Sit",
"Jump",
"Fall",
"GetUp",
@ -106,6 +114,7 @@ static char StateText[][18] = {
"Exit Car",
"Hands Up",
"Arrested",
"Deploying Stinger"
};
static char PersonalityTypeText[][18] = {
@ -283,7 +292,7 @@ CPed::DebugRenderOnePedText(void)
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 255, 0, 255));
CFont::SetBackGroundOnlyTextOn();
CFont::SetFontStyle(0);
CFont::SetFontStyle(1);
AsciiToUnicode(StateText[m_nPedState], gUString);
CFont::PrintString(screenCoords.x, screenCoords.y, gUString);
AsciiToUnicode(ObjectiveText[m_objective], gUString);

View file

@ -4,7 +4,8 @@
#include "PedPlacement.h"
#include "World.h"
void
// --MIAMI: Done
bool
CPedPlacement::FindZCoorForPed(CVector* pos)
{
float zForPed;
@ -32,8 +33,11 @@ CPedPlacement::FindZCoorForPed(CVector* pos)
zForPed = Max(foundColZ, foundColZ2);
if (zForPed > -99.0f)
if (zForPed > -99.0f) {
pos->z = FEET_OFFSET + zForPed;
return true;
}
return false;
}
CEntity*

View file

@ -2,7 +2,7 @@
class CPedPlacement {
public:
static void FindZCoorForPed(CVector* pos);
static bool FindZCoorForPed(CVector* pos);
static CEntity* IsPositionClearOfCars(Const CVector*);
static bool IsPositionClearForPed(const CVector& pos, float radius = -1.0f, int total = -1, CEntity** entities = nil);
};

View file

@ -47,7 +47,7 @@ CPedStats::LoadPedStats(void)
char *buf;
char line[256];
char name[32];
int bp, buflen;
size_t bp, buflen;
int lp, linelen;
int type;
float fleeDist, headingChangeRate, attackStrength, defendWeakness;

View file

@ -43,7 +43,7 @@ CPedType::LoadPedData(void)
char *buf;
char line[256];
char word[32];
int bp, buflen;
size_t bp, buflen;
int lp, linelen;
int type;
uint32 flags;

View file

@ -35,7 +35,7 @@ CPlayerPed::~CPlayerPed()
delete m_pWanted;
}
// --MIAMI: Done except commented out things
// --MIAMI: Done
CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
{
m_fMoveSpeed = 0.0f;
@ -53,10 +53,8 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_nSpeedTimer = 0;
m_bSpeedTimerFlag = false;
// TODO(Miami)
// if (pPointGunAt)
// m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
m_pPointGunAt = nil;
SetPedState(PED_IDLE);
#ifndef FIX_BUGS
@ -69,13 +67,14 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_fAttackButtonCounter = 0.0f;
m_bHaveTargetSelected = false;
m_bHasLockOnTarget = false;
m_bDrunkVisualsWearOff = true;
m_bCanBeDamaged = true;
m_bDrunkVisualsWearOff = false;
m_fWalkAngle = 0.0f;
m_fFPSMoveHeading = 0.0f;
m_pMinigunTopAtomic = nil;
m_fGunSpinSpeed = 0.0;
m_fGunSpinAngle = 0.0;
m_nPadDownPressedInMilliseconds = 0;
m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1;
unused1 = false;
for (int i = 0; i < 6; i++) {
@ -85,17 +84,16 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
}
m_nCheckPlayersIndex = 0;
m_nPadUpPressedInMilliseconds = 0;
m_nPadDownPressedInMilliseconds = 0;
idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles");
}
void CPlayerPed::ClearWeaponTarget()
// --MIAMI: Done
void
CPlayerPed::ClearWeaponTarget()
{
if (m_nPedType == PEDTYPE_PLAYER1) {
// TODO(Miami)
// if (m_pPointGunAt)
// m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
m_pPointGunAt = nil;
TheCamera.ClearPlayerWeaponMode();
@ -784,6 +782,7 @@ CPlayerPed::PlayerControlM16(CPad *padUsed)
GetWeapon()->Update(m_audioEntityId, nil);
}
// --MIAMI: Done
void
CPlayerPed::PlayerControlFighter(CPad *padUsed)
{
@ -809,6 +808,7 @@ CPlayerPed::PlayerControlFighter(CPad *padUsed)
}
}
// --MIAMI: Done
void
CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
{
@ -1814,6 +1814,7 @@ CPlayerPed::PlayIdleAnimations(CPad *padUsed)
}
}
// --MIAMI: Done
void
CPlayerPed::RemovePedFromMeleeList(CPed *ped)
{
@ -1826,6 +1827,100 @@ CPlayerPed::RemovePedFromMeleeList(CPed *ped)
ped->m_attackTimer = 0;
}
// --MIAMI: Done
void
CPlayerPed::GetMeleeAttackCoords(CVector& coords, int8 dir, float dist)
{
coords = GetPosition();
switch (dir) {
case 0:
coords.y += dist;
break;
case 1:
coords.x += Sqrt(3.f / 4.f) * dist;
coords.y += 0.5f * dist;
break;
case 2:
coords.x += Sqrt(3.f / 4.f) * dist;
coords.y -= 0.5f * dist;
break;
case 3:
coords.y -= dist;
break;
case 4:
coords.x -= Sqrt(3.f / 4.f) * dist;
coords.y -= 0.5f * dist;
break;
case 5:
coords.x -= Sqrt(3.f / 4.f) * dist;
coords.y += 0.5f * dist;
break;
default:
break;
}
}
// --MIAMI: Done
int32
CPlayerPed::FindMeleeAttackPoint(CPed *victim, CVector &dist, uint32 &endOfAttackOut)
{
endOfAttackOut = 0;
bool thereIsAnEmptySlot = false;
int dirToAttack = -1;
for (int i = 0; i < ARRAY_SIZE(m_pMeleeList); i++) {
CPed* pedAtThisDir = m_pMeleeList[i];
if (pedAtThisDir) {
if (pedAtThisDir == victim) {
dirToAttack = i;
} else {
if (pedAtThisDir->m_attackTimer > endOfAttackOut)
endOfAttackOut = pedAtThisDir->m_attackTimer;
}
} else {
thereIsAnEmptySlot = true;
}
}
// We don't have victim ped in our melee list
if (dirToAttack == -1 && thereIsAnEmptySlot) {
float angle = Atan2(-dist.x, -dist.y);
float adjustedAngle = angle + DEGTORAD(30.0f);
if (adjustedAngle < 0.f)
adjustedAngle += TWOPI;
int wantedDir = Floor(adjustedAngle / DEGTORAD(60.0f));
// And we have another ped at the direction of victim ped, so store victim to next empty direction to it's real direction. (Bollocks)
if (m_pMeleeList[wantedDir]) {
int closestDirToPreferred = -99;
int preferredDir = wantedDir;
for (int i = 0; i < ARRAY_SIZE(m_pMeleeList); i++) {
if (!m_pMeleeList[i]) {
if (Abs(i - preferredDir) < Abs(closestDirToPreferred - preferredDir))
closestDirToPreferred = i;
}
}
if (closestDirToPreferred > 0)
dirToAttack = closestDirToPreferred;
} else {
// Luckily the direction of victim ped is already empty, good
dirToAttack = wantedDir;
}
if (dirToAttack != -1) {
m_pMeleeList[dirToAttack] = victim;
victim->RegisterReference((CEntity**) &m_pMeleeList[dirToAttack]);
if (endOfAttackOut > CTimer::GetTimeInMilliseconds())
victim->m_attackTimer = endOfAttackOut + CGeneral::GetRandomNumberInRange(1000, 2000);
else
victim->m_attackTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(500, 1000);
}
}
return dirToAttack;
}
#ifdef COMPATIBLE_SAVES
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data));

View file

@ -34,7 +34,7 @@ public:
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];
CPlayerPed* m_pMeleeList[6];
CPed *m_pMeleeList[6]; // reachable peds at each direction(6)
char unused1;
int16 m_nCheckPlayersIndex;
float m_fWalkAngle; //angle between heading and walking direction
@ -85,6 +85,8 @@ public:
bool DoesPlayerWantNewWeapon(eWeaponType, bool);
void PlayIdleAnimations(CPad*);
void RemovePedFromMeleeList(CPed*);
void GetMeleeAttackCoords(CVector&, int8, float);
int32 FindMeleeAttackPoint(CPed*, CVector&, uint32&);
static void SetupPlayerPed(int32);
static void DeactivatePlayerPed(int32);

View file

@ -353,7 +353,7 @@ CPopulation::FindCollisionZoneForCoors(CVector *coors, int *safeZoneOut, eLevelN
}
// Then it's transition area
if (*safeZoneOut >= 0)
*levelOut = LEVEL_NONE;
*levelOut = LEVEL_GENERIC;
else
*levelOut = CTheZones::GetLevelFromPosition(coors);
}
@ -559,16 +559,23 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
CZoneInfo zoneInfo;
CPed *gangLeader = nil;
bool addCop = false;
bool forceAddingCop = false;
CPlayerInfo *playerInfo = &CWorld::Players[CWorld::PlayerInFocus];
CVector playerCentreOfWorld = FindPlayerCentreOfWorld(CWorld::PlayerInFocus);
CTheZones::GetZoneInfoForTimeOfDay(&playerCentreOfWorld, &zoneInfo);
CWanted *wantedInfo = playerInfo->m_pPed->m_pWanted;
if (wantedInfo->m_nWantedLevel > 2) {
if (ms_nNumCop < wantedInfo->m_MaxCops && !playerInfo->m_pPed->bInVehicle
&& (CCarCtrl::NumLawEnforcerCars >= wantedInfo->m_MaximumLawEnforcerVehicles
if (!CGame::IsInInterior() && (CGeneral::GetRandomNumber() % 32 == 0) && FindPlayerVehicle())
forceAddingCop = true;
uint32 maxCops = CGame::IsInInterior() ? wantedInfo->m_MaxCops * 1.6f : wantedInfo->m_MaxCops;
if ((ms_nNumCop < maxCops || forceAddingCop) &&
(!playerInfo->m_pPed->bInVehicle &&
(CCarCtrl::NumLawEnforcerCars >= wantedInfo->m_MaximumLawEnforcerVehicles
|| CCarCtrl::NumRandomCars >= playerInfo->m_nTrafficMultiplier * CCarCtrl::CarDensityMultiplier
|| CCarCtrl::NumFiretrucksOnDuty + CCarCtrl::NumAmbulancesOnDuty + CCarCtrl::NumParkedCars
+ CCarCtrl::NumMissionCars + CCarCtrl::NumLawEnforcerCars + CCarCtrl::NumRandomCars >= CCarCtrl::MaxNumberOfCarsInUse)) {
+ CCarCtrl::NumMissionCars + CCarCtrl::NumLawEnforcerCars + CCarCtrl::NumRandomCars >= CCarCtrl::MaxNumberOfCarsInUse) || forceAddingCop)) {
addCop = true;
minDist = PedCreationDistMultiplier() * MIN_CREATION_DIST;
maxDist = PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE);
@ -693,6 +700,9 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
if (!farEnoughToAdd)
break;
CPed *newPed = AddPed((ePedType)pedTypeToAdd, modelToAdd, generatedCoors);
if (forceAddingCop && newPed->m_nPedType == PEDTYPE_COP)
((CCopPed*)newPed)->m_bThrowsSpikeTrap = true;
newPed->SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
if (i != 0) {
@ -721,10 +731,11 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
}
}
// TODO(Miami)
CPed*
CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
{
int defaultModel = MI_MALE01;
const int defaultModel = MI_MALE01;
int miamiViceIndex = 0;
bool imSureThatModelIsLoaded = true;
CVector coors = FindPlayerCoors();
@ -744,10 +755,6 @@ CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
preferredModel = 0;
pedType = PEDTYPE_EMERGENCY;
break;
case MI_FBICAR:
preferredModel = COP_FBI;
pedType = PEDTYPE_COP;
break;
case MI_POLICE:
case MI_PREDATOR:
preferredModel = COP_STREET;
@ -762,24 +769,24 @@ CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
preferredModel = COP_ARMY;
pedType = PEDTYPE_COP;
break;
case MI_VICECHEE: // TODO(MIAMI): figure out new structure of the function
preferredModel = COP_MIAMIVICE;
case MI_FBIRANCH:
preferredModel = COP_FBI;
pedType = PEDTYPE_COP;
miamiViceIndex = (isDriver ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1);
break;
case MI_TAXI:
case MI_CABBIE:
case MI_ZEBRA:
case MI_KAUFMAN:
if (CGeneral::GetRandomTrueFalse()) {
pedType = PEDTYPE_CIVMALE;
preferredModel = MI_TAXI_D;
default:
if (car->GetModelIndex() == MI_TAXI || car->GetModelIndex() == MI_CABBIE || car->GetModelIndex() == MI_ZEBRA || car->GetModelIndex() == MI_KAUFMAN) {
if (isDriver) {
pedType = PEDTYPE_CIVMALE;
preferredModel = MI_TAXI_D;
break;
}
} else if (car->GetModelIndex() == MI_VICECHEE && car->bIsLawEnforcer) {
preferredModel = COP_MIAMIVICE;
pedType = PEDTYPE_COP;
miamiViceIndex = (isDriver ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1);
break;
}
defaultModel = MI_TAXI_D;
// fall through
default:
int gangOfPed = 0;
imSureThatModelIsLoaded = false;
@ -798,8 +805,12 @@ CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
if (preferredModel == -1)
preferredModel = defaultModel;
if (((CPedModelInfo*)CModelInfo::GetModelInfo(preferredModel))->m_carsCanDrive & (1 << carModelInfo->m_vehicleClass))
break;
if (((CPedModelInfo*)CModelInfo::GetModelInfo(preferredModel))->GetRwObject()) {
if (!car->IsPassenger(preferredModel) && !car->IsDriver(preferredModel)) {
if (((CPedModelInfo*)CModelInfo::GetModelInfo(preferredModel))->m_carsCanDrive & (1 << carModelInfo->m_vehicleClass))
break;
}
}
}
if (i == -1)
preferredModel = defaultModel;

View file

@ -129,12 +129,12 @@ CCredits::Render(void)
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED041"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED042"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED043"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED044"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditSpace(2.0f, lineoffset);
@ -177,14 +177,14 @@ CCredits::Render(void)
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED061"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED062"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED063"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED064"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED065"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED066"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED067"), lineoffset, scrolloffset);
@ -192,16 +192,16 @@ CCredits::Render(void)
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED069"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED070"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED071"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED072"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED073"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED074"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED075"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED076"), lineoffset, scrolloffset);
@ -221,16 +221,16 @@ CCredits::Render(void)
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED085"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED086"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED087"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED088"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED089"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED090"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED091"), lineoffset, scrolloffset);
@ -250,7 +250,7 @@ CCredits::Render(void)
PrintCreditSpace(2.0f, lineoffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED100"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED101"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED102"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED103"), lineoffset, scrolloffset);
@ -261,82 +261,82 @@ CCredits::Render(void)
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED269"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED107"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED108"), lineoffset, scrolloffset);
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED109"), lineoffset, scrolloffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED108"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED109"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED110"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED110"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED111"), lineoffset, scrolloffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED112"), lineoffset, scrolloffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED112"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED113"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED113"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED114"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED114"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED115"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED115"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED116"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED116"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED117"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED117"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED118"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED118"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED119"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED119"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED120"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED120"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED121"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED121"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED122"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED122"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED123"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED123"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED124"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED124"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED125"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED125"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED126"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED126"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED127"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED127"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED128"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED128"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED129"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED129"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED130"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED130"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED131"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED131"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED132"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED132"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED133"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED133"), lineoffset, scrolloffset);
if(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED134"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED134"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED135"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED136"), lineoffset, scrolloffset);
@ -349,7 +349,7 @@ CCredits::Render(void)
PrintCreditText(1.7f, 1.7f, TheText.Get("CRD138A"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRD138B"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED139"), lineoffset, scrolloffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED139"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.7f, 1.0f, TheText.Get("CRED140"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140A"), lineoffset, scrolloffset);
@ -359,12 +359,12 @@ CCredits::Render(void)
PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140E"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED141"), lineoffset, scrolloffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED142"), lineoffset, scrolloffset);
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED143"), lineoffset, scrolloffset);
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0, 1.0, TheText.Get("CRED144"), lineoffset, scrolloffset);
PrintCreditSpace(1.0, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED142"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED143"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditText(1.0f, 1.0f, TheText.Get("CRED144"), lineoffset, scrolloffset);
PrintCreditSpace(1.0f, lineoffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED145"), lineoffset, scrolloffset);
PrintCreditText(1.4f, 1.4f, TheText.Get("CRED146"), lineoffset, scrolloffset);
@ -441,19 +441,19 @@ CCredits::Render(void)
PrintCreditText(1.4f, 1.4f, TheText.Get("CRED241"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED217"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED218"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRD218A"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRD218B"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED219"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED220"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED221"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED222"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED223"), lineoffset, scrolloffset);
@ -462,7 +462,7 @@ CCredits::Render(void)
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED226"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);
PrintCreditText(1.4f, 0.82f, TheText.Get("CRED227"), lineoffset, scrolloffset);
PrintCreditSpace(1.5, lineoffset);
PrintCreditSpace(1.5f, lineoffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED228"), lineoffset, scrolloffset);
PrintCreditText(1.7f, 1.7f, TheText.Get("CRED229"), lineoffset, scrolloffset);
PrintCreditSpace(2.0f, lineoffset);

View file

@ -3,6 +3,7 @@
#include "Draw.h"
#include "Frontend.h"
#include "Camera.h"
#include "CutsceneMgr.h"
#ifdef ASPECT_RATIO_SCALE
float CDraw::ms_fAspectRatio = DEFAULT_ASPECT_RATIO;
@ -61,7 +62,10 @@ void
CDraw::SetFOV(float fov)
{
#ifdef ASPECT_RATIO_SCALE
ms_fScaledFOV = ConvertFOV(fov);
if (!CCutsceneMgr::IsRunning())
ms_fScaledFOV = ConvertFOV(fov);
else
ms_fScaledFOV = fov;
#endif
ms_fFOV = fov;
}

View file

@ -1,11 +1,14 @@
#include "common.h"
#include "main.h"
#include "RenderBuffer.h"
#include "Entity.h"
#include "Fluff.h"
#include "Camera.h"
#include "Sprite.h"
#include "Coronas.h"
#include "Rubbish.h"
#include "Timecycle.h"
#include "General.h"
#include "Timer.h"
#include "Clock.h"
@ -18,6 +21,277 @@
#include "Bones.h"
#include "World.h"
CPlaneTrail CPlaneTrails::aArray[6];
RwImVertexIndex TrailIndices[32] = {
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16
};
void
CPlaneTrail::Init(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(m_time); i++)
m_time[i] = 0;
}
void
CPlaneTrail::Render(float visibility)
{
int i;
int numVerts = 0;
if(!TheCamera.IsSphereVisible(m_pos[0], 1000.0f))
return;
int alpha = visibility*110.0f;
if(alpha == 0)
return;
for(i = 0; i < ARRAY_SIZE(m_pos); i++){
int32 time = CTimer::GetTimeInMilliseconds() - m_time[i];
if(time > 30000)
m_time[i] = 0;
if(m_time[i] != 0){
float fade = (30000.0f - time) / 10000.0f;
fade = Min(fade, 1.0f);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[numVerts], 255, 255, 255, (int)(alpha*fade));
RwIm3DVertexSetPos(&TempBufferRenderVertices[numVerts], m_pos[i].x, m_pos[i].y, m_pos[i].z);
numVerts++;
}
}
if(numVerts > 1){
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
if(RwIm3DTransform(TempBufferRenderVertices, numVerts, nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXRGBA)){
RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, TrailIndices, (numVerts-1)*2);
RwIm3DEnd();
}
}
}
void
CPlaneTrail::RegisterPoint(CVector pos)
{
int i;
bool bNewPoint = false;
if(m_time[0] != 0 && CTimer::GetTimeInMilliseconds() - m_time[0] > 2000){
bNewPoint = true;
for(i = ARRAY_SIZE(m_pos)-1; i > 0; i--){
m_pos[i] = m_pos[i-1];
m_time[i] = m_time[i-1];
}
}
m_pos[0] = pos;
if(bNewPoint || m_time[0] == 0)
m_time[0] = CTimer::GetTimeInMilliseconds();
}
void
CPlaneTrails::Init(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aArray); i++)
aArray[i].Init();
}
void
CPlaneTrails::Update(void)
{
CVector planePos;
planePos.x = 1590.0f * Sin((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
planePos.y = 1200.0f * Cos((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
planePos.z = 550.0f;
RegisterPoint(planePos, 3);
if(CClock::GetHours() > 22 || CClock::GetHours() < 7){
if(CTimer::GetTimeInMilliseconds() & 0x200)
CCoronas::RegisterCorona(101, 255, 0, 0, 255, planePos, 5.0f, 2000.0f,
CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
else
CCoronas::UpdateCoronaCoors(101, planePos, 2000.0f, 0.0f);
}
planePos.x = 1000.0f * Sin((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
planePos.y = -1600.0f * Cos((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
planePos.z = 500.0f;
RegisterPoint(planePos, 4);
if(CClock::GetHours() > 22 || CClock::GetHours() < 7){
if(CTimer::GetTimeInMilliseconds() & 0x200)
CCoronas::RegisterCorona(102, 255, 0, 0, 255, planePos, 5.0f, 2000.0f,
CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
else
CCoronas::UpdateCoronaCoors(102, planePos, 2000.0f, 0.0f);
}
planePos.x = 1100.0f * Cos((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
planePos.y = 700.0f * Sin((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
planePos.z = 600.0f;
RegisterPoint(planePos, 5);
if(CClock::GetHours() > 22 || CClock::GetHours() < 7){
if(CTimer::GetTimeInMilliseconds() & 0x200)
CCoronas::RegisterCorona(103, 255, 0, 0, 255, planePos, 5.0f, 2000.0f,
CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
else
CCoronas::UpdateCoronaCoors(103, planePos, 2000.0f, 0.0f);
}
}
void
CPlaneTrails::Render(void)
{
int i;
float visibility = Min(1.0f-CWeather::Foggyness, 1.0f-CWeather::CloudCoverage);
visibility = Min(visibility, 1.0f-CWeather::Rain);
visibility = Min(Max(Max(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen()), CTimeCycle::GetSkyTopBlue())/256.0f, visibility);
if(visibility > 0.0001f)
for(i = 0; i < ARRAY_SIZE(aArray); i++)
aArray[i].Render(visibility);
}
void
CPlaneTrails::RegisterPoint(CVector pos, uint32 id)
{
aArray[id].RegisterPoint(pos);
}
CPlaneBanner CPlaneBanners::aArray[5];
void
CPlaneBanner::Init(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(m_pos); i++){
m_pos[i].x = i;
m_pos[i].y = 0.0f;
m_pos[i].z = -60.0f;
}
}
void
CPlaneBanner::Update(void)
{
int i;
if(m_pos[0].z > -50.0f){
m_pos[0].z -= 0.05f*CTimer::GetTimeStep();
m_pos[0].z = Max(m_pos[0].z, -100.0f);
for(i = 1; i < ARRAY_SIZE(m_pos); i++){
CVector dist = m_pos[i] - m_pos[i-1];
float len = dist.Magnitude();
if(len > 8.0f)
m_pos[i] = m_pos[i-1] + dist/len*8.0f;
}
}
}
void
CPlaneBanner::Render(void)
{
int i;
if(m_pos[0].z > -50.0f){
float camDist = (TheCamera.GetPosition() - m_pos[0]).Magnitude();
if(TheCamera.IsSphereVisible(m_pos[4], 32.0f) && camDist < 300.0f){
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
int alpha = camDist < 250.0f ? 160 : (300.0f-camDist)/(300.0f-250.0f)*160;
TempBufferVerticesStored += 2;
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[0], 255, 255, 255, alpha);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[1], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&TempBufferRenderVertices[0], m_pos[2].x, m_pos[2].y, m_pos[2].z);
RwIm3DVertexSetPos(&TempBufferRenderVertices[1], m_pos[2].x, m_pos[2].y, m_pos[2].z - 4.0f);
RwIm3DVertexSetU(&TempBufferRenderVertices[0], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[0], 0.0f);
RwIm3DVertexSetU(&TempBufferRenderVertices[1], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[1], 1.0f);
for(i = 2; i < 8; i++){
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+0], 255, 255, 255, alpha);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+1], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+0], m_pos[i].x, m_pos[i].y, m_pos[i].z);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+1], m_pos[i].x, m_pos[i].y, m_pos[i].z - 4.0f);
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+0], (i-2)/5.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+0], 0.0f);
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+1], (i-2)/5.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+1], 1.0f);
TempBufferRenderIndexList[TempBufferIndicesStored+0] = TempBufferVerticesStored-2;
TempBufferRenderIndexList[TempBufferIndicesStored+1] = TempBufferVerticesStored-1;
TempBufferRenderIndexList[TempBufferIndicesStored+2] = TempBufferVerticesStored+1;
TempBufferRenderIndexList[TempBufferIndicesStored+3] = TempBufferVerticesStored-2;
TempBufferRenderIndexList[TempBufferIndicesStored+4] = TempBufferVerticesStored+1;
TempBufferRenderIndexList[TempBufferIndicesStored+5] = TempBufferVerticesStored;
TempBufferVerticesStored += 2;
TempBufferIndicesStored += 6;
}
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[2]));
#ifdef FIX_BUGS
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXUV|rwIM3D_VERTEXRGBA)){
#else
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 0)){
#endif
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
RwIm3DEnd();
}
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
}
}
}
void
CPlaneBanner::RegisterPoint(CVector pos)
{
m_pos[0] = pos;
}
void
CPlaneBanners::Init(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aArray); i++)
aArray[i].Init();
}
void
CPlaneBanners::Update(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aArray); i++)
aArray[i].Update();
}
void
CPlaneBanners::Render(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aArray); i++)
aArray[i].Render();
}
void
CPlaneBanners::RegisterPoint(CVector pos, uint32 id)
{
aArray[id].RegisterPoint(pos);
}
bool CSmokeTrails::CigOn = false;
CSmokeTrail CSmokeTrails::aSmoke[3];
@ -113,7 +387,9 @@ CMovingThing CMovingThings::aMovingThings[NUMMOVINGTHINGS];
void CMovingThings::Init()
{
CPlaneTrails::Init();
CSmokeTrails::Init();
CPlaneBanners::Init();
StartCloseList.m_pNext = &CMovingThings::EndCloseList;
StartCloseList.m_pPrev = nil;
@ -162,14 +438,19 @@ void CMovingThings::Shutdown()
int i;
for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
aScrollBars[i].SetVisibility(false);
/*
for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
aTowerClocks[i].SetVisibility(false);
for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i)
aDigitalClocks[i].SetVisibility(false);
*/
}
void CMovingThings::Update()
{
CPlaneBanners::Update();
CPlaneTrails::Update();
const int TIME_SPAN = 64; // frames to process all aMovingThings
int16 i;
@ -214,6 +495,7 @@ void CMovingThings::Render()
if (aScrollBars[i].IsVisible())
aScrollBars[i].Render();
}
/*
for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
{
if (aTowerClocks[i].IsVisible())
@ -224,8 +506,11 @@ void CMovingThings::Render()
if (aDigitalClocks[i].IsVisible())
aDigitalClocks[i].Render();
}
*/
CPlaneTrails::Render();
CSmokeTrails::Render();
CPlaneBanners::Render();
}
// ---------- CMovingThing ----------
@ -637,7 +922,7 @@ void CScrollBar::Update()
break;
}
m_MessageLength = strlen(m_pMessage);
m_MessageLength = (uint32)strlen(m_pMessage);
m_MessageCurrentChar = 0;
}
@ -934,7 +1219,6 @@ CSmokeTrails::Render(void) {
void
CSmokeTrail::Render(void) {
int numVerts = 0;
RwIm3DVertex TempVertexBuffer[16];
if (TheCamera.IsSphereVisible(m_pos[0], 10.0f)) {
for (int32 i = 0; i < 16; i++) {
@ -949,8 +1233,8 @@ CSmokeTrail::Render(void) {
float posX = (m_pos[i].x + timeSinceSpawned * RandomSmoke[(i - m_seed) & 0xF] * 0.00001f) - offset;
float posY = (m_pos[i].y + timeSinceSpawned * RandomSmoke[(i - m_seed + 5) & 0xF] * 0.00001f) - offset;
float posZ = m_pos[i].z + timeSinceSpawned * 0.0004f;
RwIm3DVertexSetRGBA(&TempVertexBuffer[i], 200, 200, 200, alpha);
RwIm3DVertexSetPos(&TempVertexBuffer[i], posX, posY, posZ);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[i], 200, 200, 200, alpha);
RwIm3DVertexSetPos(&TempBufferRenderVertices[i], posX, posY, posZ);
numVerts++;
}
}
@ -962,7 +1246,7 @@ CSmokeTrail::Render(void) {
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
if (RwIm3DTransform(TempVertexBuffer, numVerts, nil, rwIM3D_VERTEXXYZ | rwIM3D_VERTEXRGBA)) {
if (RwIm3DTransform(TempBufferRenderVertices, numVerts, nil, rwIM3D_VERTEXXYZ | rwIM3D_VERTEXRGBA)) {
RwIm3DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, SmokeTrailIndices, 2 * (numVerts - 1));
RwIm3DEnd();
}
@ -994,13 +1278,12 @@ CSmokeTrails::Update(void) {
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
RwIm3DVertex TempVertexBuffer[2];
RwIm3DVertexSetRGBA(&TempVertexBuffer[0], 255, 255, 255, 255);
RwIm3DVertexSetPos(&TempVertexBuffer[0], startPos.x, startPos.y, startPos.z);
RwIm3DVertexSetRGBA(&TempVertexBuffer[1], 255, 255, 255, 255);
RwIm3DVertexSetPos(&TempVertexBuffer[1], endPos.x, endPos.y, endPos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[0], 255, 255, 255, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[0], startPos.x, startPos.y, startPos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[1], 255, 255, 255, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[1], endPos.x, endPos.y, endPos.z);
if (RwIm3DTransform(TempVertexBuffer, 2, nil, rwIM3D_VERTEXXYZ | rwIM3D_VERTEXRGBA)) {
if (RwIm3DTransform(TempBufferRenderVertices, 2, nil, rwIM3D_VERTEXXYZ | rwIM3D_VERTEXRGBA)) {
RwIm3DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, SmokeTrailIndices, 2);
RwIm3DEnd();
}

View file

@ -2,6 +2,70 @@
#include "common.h"
#include "Vector.h"
// TODO
class CScriptPath
{
public:
};
// TODO
class CScriptPaths
{
public:
};
class CPlaneTrail
{
CVector m_pos[16];
int32 m_time[16];
public:
void Init(void);
void Render(float visibility);
void RegisterPoint(CVector pos);
};
class CPlaneTrails
{
static CPlaneTrail aArray[6]; // NB: 3 CPlanes and 3 hardcoded far away ones
public:
static void Init(void);
static void Update(void);
static void Render(void);
static void RegisterPoint(CVector pos, uint32 id);
};
class CPlaneBanner
{
CVector m_pos[8];
public:
void Init(void);
void Update(void);
void Render(void);
void RegisterPoint(CVector pos);
};
class CPlaneBanners
{
static CPlaneBanner aArray[5];
public:
static void Init(void);
static void Update(void);
static void Render(void);
static void RegisterPoint(CVector pos, uint32 id);
};
// TODO
class CEscalators
{
public:
};
// TODO
class CEscalator
{
public:
};
class CMovingThing
{
public:

View file

@ -1133,7 +1133,11 @@ CFont::ParseToken(wchar *s)
case 'r': SetColor(CRGBA(255, 150, 225, 255)); Details.anonymous_23 = true; break;
case 't': SetColor(CRGBA(86, 212, 146, 255)); Details.anonymous_23 = true; break;
case 'w': SetColor(CRGBA(175, 175, 175, 255)); Details.anonymous_23 = true; break;
#ifdef FIX_BUGS
case 'x': SetColor(CRGBA(0, 255, 255, 255)); Details.anonymous_23 = true; break;
#else
case 'x': SetColor(CRGBA(132, 146, 197, 255)); Details.anonymous_23 = true; break;
#endif
case 'y': SetColor(CRGBA(255, 227, 79, 255)); Details.anonymous_23 = true; break;
}
while(*s != '~') s++;
@ -1208,11 +1212,19 @@ CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold)
color.g = 175;
color.b = 175;
break;
#ifdef FIX_BUGS
case 'x':
color.r = 0;
color.g = 255;
color.b = 255;
break;
#else
case 'x':
color.r = 132;
color.g = 146;
color.b = 197;
break;
#endif
case 'y':
color.r = 255;
color.g = 227;

Some files were not shown because too many files have changed in this diff Show more