Remaining player commands (#1082)

* reverse remaining player commands

* remove unused import

* fix vehicle type assert
This commit is contained in:
Seemann 2025-05-13 17:06:03 -04:00 committed by GitHub
parent b3325c1915
commit 628093f703
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 83 additions and 61 deletions

View File

@ -13,14 +13,25 @@
namespace notsa { namespace notsa {
namespace script { namespace script {
namespace detail {
// eModelID wrapper that is read either from a static template<typename T, size_t UniqueTag = 0>
// int32 value or UsedObjectArray. struct StrongAlias {
struct Model { T value;
eModelID model;
operator eModelID() const { return model; } auto& operator=(const T& o) {
value = o;
return *this;
}
operator T() const { return value; }
}; };
};
// eModelID wrapper that is read either from a static int32 value or UsedObjectArray.
using Model = detail::StrongAlias<eModelID>;
// uint32 wrapper for reading an unsigned 32-bit integer that can be out of range for int32
using Hash = detail::StrongAlias<uint32>;
namespace detail { namespace detail {
@ -202,7 +213,7 @@ inline T Read(CRunningScript* S) {
#ifdef NOTSA_DEBUG #ifdef NOTSA_DEBUG
if (ptr) { if (ptr) {
if constexpr (detail::is_derived_from_but_not_v<CVehicle, Y>) { if constexpr (detail::is_derived_from_but_not_v<CVehicle, Y>) {
assert(Y::Type == ptr->m_nVehicleType); assert(Y::Type == ptr->m_nVehicleSubType); // check specialized type, in case of e.g. CAutomobile and one of its derived classes: CPlane, CHeli, etc
} else if constexpr (detail::is_derived_from_but_not_v<CTask, Y>) { } else if constexpr (detail::is_derived_from_but_not_v<CTask, Y>) {
assert(Y::Type == ptr->GetTaskType()); assert(Y::Type == ptr->GetTaskType());
} // TODO: Eventually add this for `CEvent` too } // TODO: Eventually add this for `CEvent` too
@ -243,6 +254,8 @@ inline T Read(CRunningScript* S) {
} }
return {static_cast<eModelID>(value)}; return {static_cast<eModelID>(value)};
} else if constexpr (std::is_same_v< T, script::Hash>) {
return { static_cast<uint32>(Read<int32>(S)) };
} }
// If there's an error like "function must return a value" here, // If there's an error like "function must return a value" here,
// that means that no suitable branch was found for `T` // that means that no suitable branch was found for `T`

View File

@ -118,11 +118,6 @@ bool IsPlayerTouchingObjectOnFoot(CPlayerPed& player, CObject& object) {
return player.GetHasCollidedWith(&object); return player.GetHasCollidedWith(&object);
} }
// COMMAND_IS_PLAYER_IN_POSITION_FOR_CONVERSATION - 0x474983
//bool IsPlayerInPositionForConversation(CPed& ped) { // Yes, it's CPed
//
//}
/// ADD_SCORE(0109) /// ADD_SCORE(0109)
void AddScore(CPlayerInfo& player, int32 score) { void AddScore(CPlayerInfo& player, int32 score) {
player.m_nMoney += score; player.m_nMoney += score;
@ -241,7 +236,6 @@ void MakePlayerSafeForCutscene(uint32 playerIdx) {
CCutsceneMgr::ms_cutsceneProcessing = true; CCutsceneMgr::ms_cutsceneProcessing = true;
} }
/// IS_PLAYER_TARGETTING_CHAR(0457) /// IS_PLAYER_TARGETTING_CHAR(0457)
bool IsPlayerTargettingChar(CPlayerPed& player, CPed* target) { bool IsPlayerTargettingChar(CPlayerPed& player, CPed* target) {
CEntity* targetedObject = player.m_pTargetedObject; CEntity* targetedObject = player.m_pTargetedObject;
@ -297,7 +291,7 @@ void SetPlayerCanDoDriveBy(CPlayerInfo& player, bool state) {
/// SET_PLAYER_DRUNKENNESS(052C) /// SET_PLAYER_DRUNKENNESS(052C)
void SetPlayerDrunkenness(CPlayerInfo& player, uint8 intensity) { void SetPlayerDrunkenness(CPlayerInfo& player, uint8 intensity) {
player.m_PlayerData.m_nDrunkenness = intensity; player.m_PlayerData.m_nDrunkenness = intensity;
player.m_PlayerData.m_nFadeDrunkenness = 0; player.m_PlayerData.m_nFadeDrunkenness = 0;
if (!intensity) { if (!intensity) {
CMBlur::ClearDrunkBlur(); CMBlur::ClearDrunkBlur();
@ -321,7 +315,7 @@ void EnsurePlayerHasDriveByWeapon(CPlayerPed& player, uint32 ammo) {
if (!player.bInVehicle) { if (!player.bInVehicle) {
return; return;
} }
const auto type = player.GetWeaponInSlot(eWeaponSlot::SMG).GetType(); const auto type = player.GetWeaponInSlot(eWeaponSlot::SMG).GetType();
if (type != WEAPON_UNARMED) { if (type != WEAPON_UNARMED) {
if (player.GetWeaponInSlot(eWeaponSlot::SMG).GetTotalAmmo() < ammo) { if (player.GetWeaponInSlot(eWeaponSlot::SMG).GetTotalAmmo() < ammo) {
player.SetAmmo(type, ammo); player.SetAmmo(type, ammo);
@ -356,6 +350,32 @@ void DeletePlayer(uint32 playerIdx) {
CPlayerPed::RemovePlayerPed(playerIdx); CPlayerPed::RemovePlayerPed(playerIdx);
} }
/// SET_TWO_PLAYER_CAMERA_MODE(06E0)
void SetTwoPlayerCameraMode(int32 unused) {
TheCamera.StartCooperativeCamMode();
}
/// LIMIT_TWO_PLAYER_DISTANCE(06F1)
void LimitTwoPlayerDistance(float limit) {
CGameLogic::bLimitPlayerDistance = true;
CGameLogic::MaxPlayerDistance = limit;
}
/// RELEASE_TWO_PLAYER_DISTANCE(06F2)
void ReleaseTwoPlayerDistance() {
CGameLogic::bLimitPlayerDistance = false;
}
/// SET_PLAYER_PLAYER_TARGETTING(06F3)
void SetPlayerPlayerTargetting(bool state) {
CGameLogic::bPlayersCannotTargetEachOther = !state;
}
/// SET_PLAYERS_CAN_BE_IN_SEPARATE_CARS(06FA)
void SetPlayersCanBeInSeparateCars(bool state) {
CGameLogic::bPlayersCanBeInSeparateCars = state;
}
/// BUILD_PLAYER_MODEL(070D) /// BUILD_PLAYER_MODEL(070D)
void BuildPlayerModel(CPlayerPed* player) { void BuildPlayerModel(CPlayerPed* player) {
CClothes::RebuildPlayer(player, false); CClothes::RebuildPlayer(player, false);
@ -363,27 +383,25 @@ void BuildPlayerModel(CPlayerPed* player) {
} }
/// GIVE_PLAYER_CLOTHES(0784) /// GIVE_PLAYER_CLOTHES(0784)
// TODO/FIXME: The hashes here should really be `uint32`, void GivePlayerClothes(CPlayerPed& player, notsa::script::Hash textureHash, notsa::script::Hash modelHash, eClothesTexturePart bodyPart) {
// but no can do, because `safe_arithmetic_cast` fails (when casting from the read `int32` to the requested `uint32`)
void GivePlayerClothes(CPlayerPed& player, int32 textureHash, int32 modelHash, eClothesTexturePart bodyPart) {
player.GetClothesDesc()->SetTextureAndModel(textureHash, modelHash, bodyPart); player.GetClothesDesc()->SetTextureAndModel(textureHash, modelHash, bodyPart);
} }
/// PLAYER_ENTERED_BUILDINGSITE_CRANE(079E) /// PLAYER_ENTERED_BUILDINGSITE_CRANE(079E)
void PlayerEnteredBuildingsiteCrane() { void PlayerEnteredBuildingsiteCrane() {
CRopes::PlayerControlsCrane = eControlledCrane::WRECKING_BALL; CRopes::PlayerControlsCrane = eControlledCrane::WRECKING_BALL;
CWaterLevel::m_bWaterFogScript = false; CWaterLevel::m_bWaterFogScript = false;
} }
/// PLAYER_ENTERED_DOCK_CRANE(079D) /// PLAYER_ENTERED_DOCK_CRANE(079D)
void PlayerEnteredDockCrane() { void PlayerEnteredDockCrane() {
CRopes::PlayerControlsCrane = eControlledCrane::MAGNO_CRANE; CRopes::PlayerControlsCrane = eControlledCrane::MAGNO_CRANE;
CWaterLevel::m_bWaterFogScript = false; CWaterLevel::m_bWaterFogScript = false;
} }
/// PLAYER_ENTERED_LAS_VEGAS_CRANE(07FA) /// PLAYER_ENTERED_LAS_VEGAS_CRANE(07FA)
void PlayerEnteredLasVegasCrane() { void PlayerEnteredLasVegasCrane() {
CRopes::PlayerControlsCrane = eControlledCrane::LAS_VEGAS_CRANE; CRopes::PlayerControlsCrane = eControlledCrane::LAS_VEGAS_CRANE;
CWaterLevel::m_bWaterFogScript = false; CWaterLevel::m_bWaterFogScript = false;
} }
@ -394,7 +412,7 @@ void PlayerEnteredQuarryCrane() {
/// PLAYER_LEFT_CRANE(079F) /// PLAYER_LEFT_CRANE(079F)
void PlayerLeftCrane() { void PlayerLeftCrane() {
CRopes::PlayerControlsCrane = eControlledCrane::NONE; CRopes::PlayerControlsCrane = eControlledCrane::NONE;
CWaterLevel::m_bWaterFogScript = true; CWaterLevel::m_bWaterFogScript = true;
} }
@ -423,6 +441,21 @@ bool IsPlayerPerformingStoppie(CPlayerInfo& player) {
return player.m_pPed->bInVehicle && player.m_pPed->m_pVehicle->GetVehicleAppearance() == eVehicleAppearance::VEHICLE_APPEARANCE_BIKE && player.m_nBikeFrontWheelCounter; return player.m_pPed->bInVehicle && player.m_pPed->m_pVehicle->GetVehicleAppearance() == eVehicleAppearance::VEHICLE_APPEARANCE_BIKE && player.m_nBikeFrontWheelCounter;
} }
/// SET_PLAYER_FIRE_BUTTON(0881)
void SetPlayerFireButton(uint32 playerIdx, bool state) {
CPad::GetPad(playerIdx)->bDisablePlayerFireWeapon = !state;
}
/// SET_PLAYER_JUMP_BUTTON(0901)
void SetPlayerJumpButton(uint32 playerIdx, bool state) {
CPad::GetPad(playerIdx)->bDisablePlayerJump = !state;
}
/// HAS_PLAYER_BOUGHT_ITEM(0942)
bool HasPlayerBoughtItem(uint32 itemId) {
return CShopping::HasPlayerBought(itemId);
}
}; };
void notsa::script::commands::player::RegisterHandlers() { void notsa::script::commands::player::RegisterHandlers() {
@ -467,6 +500,11 @@ void notsa::script::commands::player::RegisterHandlers() {
REGISTER_COMMAND_HANDLER(COMMAND_IS_PLAYER_TARGETTING_ANYTHING, IsPlayerTargettingAnything); REGISTER_COMMAND_HANDLER(COMMAND_IS_PLAYER_TARGETTING_ANYTHING, IsPlayerTargettingAnything);
REGISTER_COMMAND_HANDLER(COMMAND_DISABLE_PLAYER_SPRINT, DisablePlayerSprint); REGISTER_COMMAND_HANDLER(COMMAND_DISABLE_PLAYER_SPRINT, DisablePlayerSprint);
REGISTER_COMMAND_HANDLER(COMMAND_DELETE_PLAYER, DeletePlayer); REGISTER_COMMAND_HANDLER(COMMAND_DELETE_PLAYER, DeletePlayer);
REGISTER_COMMAND_HANDLER(COMMAND_SET_TWO_PLAYER_CAMERA_MODE, SetTwoPlayerCameraMode);
REGISTER_COMMAND_HANDLER(COMMAND_LIMIT_TWO_PLAYER_DISTANCE, LimitTwoPlayerDistance);
REGISTER_COMMAND_HANDLER(COMMAND_RELEASE_TWO_PLAYER_DISTANCE, ReleaseTwoPlayerDistance);
REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_PLAYER_TARGETTING, SetPlayerPlayerTargetting);
REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYERS_CAN_BE_IN_SEPARATE_CARS, SetPlayersCanBeInSeparateCars);
REGISTER_COMMAND_HANDLER(COMMAND_BUILD_PLAYER_MODEL, BuildPlayerModel); REGISTER_COMMAND_HANDLER(COMMAND_BUILD_PLAYER_MODEL, BuildPlayerModel);
REGISTER_COMMAND_HANDLER(COMMAND_GIVE_PLAYER_CLOTHES, GivePlayerClothes); REGISTER_COMMAND_HANDLER(COMMAND_GIVE_PLAYER_CLOTHES, GivePlayerClothes);
REGISTER_COMMAND_HANDLER(COMMAND_PLAYER_ENTERED_DOCK_CRANE, PlayerEnteredDockCrane); REGISTER_COMMAND_HANDLER(COMMAND_PLAYER_ENTERED_DOCK_CRANE, PlayerEnteredDockCrane);
@ -484,46 +522,9 @@ void notsa::script::commands::player::RegisterHandlers() {
REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_GROUP_TO_FOLLOW_ALWAYS, SetPlayerGroupToFollowAlways); REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_GROUP_TO_FOLLOW_ALWAYS, SetPlayerGroupToFollowAlways);
REGISTER_COMMAND_HANDLER(COMMAND_SET_SWIM_SPEED, SetSwimSpeed); REGISTER_COMMAND_HANDLER(COMMAND_SET_SWIM_SPEED, SetSwimSpeed);
REGISTER_COMMAND_HANDLER(COMMAND_IS_PLAYER_CLIMBING, IsPlayerClimbing); REGISTER_COMMAND_HANDLER(COMMAND_IS_PLAYER_CLIMBING, IsPlayerClimbing);
REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_FIRE_BUTTON, SetPlayerFireButton);
// TODO: REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_JUMP_BUTTON, SetPlayerJumpButton);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_CAMERA_IN_FRONT_OF_PLAYER, SetCameraInFrontOfPlayer); REGISTER_COMMAND_HANDLER(COMMAND_HAS_PLAYER_BOUGHT_ITEM, HasPlayerBoughtItem);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_HOOKER, SetPlayerHooker);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER, SetJamesCarOnPathToPlayer);
//REGISTER_COMMAND_HANDLER(COMMAND_RESET_HAVOC_CAUSED_BY_PLAYER, ResetHavocCausedByPlayer);
//REGISTER_COMMAND_HANDLER(COMMAND_GET_HAVOC_CAUSED_BY_PLAYER, GetHavocCausedByPlayer);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_CAN_DO_DRIVE_BY, SetPlayerCanDoDriveBy);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_AUTO_AIM, SetPlayerAutoAim);
//REGISTER_COMMAND_HANDLER(COMMAND_CHECK_FOR_PED_MODEL_AROUND_PLAYER, CheckForPedModelAroundPlayer);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_HAS_MET_DEBBIE_HARRY, SetPlayerHasMetDebbieHarry);
//REGISTER_COMMAND_HANDLER(COMMAND_GET_BUS_FARES_COLLECTED_BY_PLAYER, GetBusFaresCollectedByPlayer);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_GANG_ATTACK_PLAYER_WITH_COPS, SetGangAttackPlayerWithCops);
//REGISTER_COMMAND_HANDLER(COMMAND_TASK_PLAYER_ON_FOOT, TaskPlayerOnFoot);
//REGISTER_COMMAND_HANDLER(COMMAND_TASK_PLAYER_IN_CAR, TaskPlayerInCar);
//REGISTER_COMMAND_HANDLER(COMMAND_GET_CLOSEST_BUYABLE_OBJECT_TO_PLAYER, GetClosestBuyableObjectToPlayer);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_TWO_PLAYER_CAMERA_MODE, SetTwoPlayerCameraMode);
//REGISTER_COMMAND_HANDLER(COMMAND_LIMIT_TWO_PLAYER_DISTANCE, LimitTwoPlayerDistance);
//REGISTER_COMMAND_HANDLER(COMMAND_RELEASE_TWO_PLAYER_DISTANCE, ReleaseTwoPlayerDistance);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_PLAYER_TARGETTING, SetPlayerPlayerTargetting);
//REGISTER_COMMAND_HANDLER(COMMAND_CLEAR_TWO_PLAYER_CAMERA_MODE, ClearTwoPlayerCameraMode);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_PASSENGER_CAN_SHOOT, SetPlayerPassengerCanShoot);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYERS_CAN_BE_IN_SEPARATE_CARS, SetPlayersCanBeInSeparateCars);
//REGISTER_COMMAND_HANDLER(COMMAND_SWITCH_PLAYER_CROSSHAIR, SwitchPlayerCrosshair);
//REGISTER_COMMAND_HANDLER(COMMAND_GIVE_PLAYER_TATTOO, GivePlayerTattoo);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_TWO_PLAYER_CAM_MODE_SEPARATE_CARS, SetTwoPlayerCamModeSeparateCars);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_TWO_PLAYER_CAM_MODE_SAME_CAR_SHOOTING, SetTwoPlayerCamModeSameCarShooting);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_TWO_PLAYER_CAM_MODE_SAME_CAR_NO_SHOOTING, SetTwoPlayerCamModeSameCarNoShooting);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_TWO_PLAYER_CAM_MODE_NOT_BOTH_IN_CAR, SetTwoPlayerCamModeNotBothInCar);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_FIRE_BUTTON, SetPlayerFireButton);
//REGISTER_COMMAND_HANDLER(COMMAND_IS_PLAYER_IN_POSITION_FOR_CONVERSATION, IsPlayerInPositionForConversation);
//REGISTER_COMMAND_HANDLER(COMMAND_PLANE_ATTACK_PLAYER_USING_DOG_FIGHT, PlaneAttackPlayerUsingDogFight);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_JUMP_BUTTON, SetPlayerJumpButton);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_CAN_BE_DAMAGED, SetPlayerCanBeDamaged);
//REGISTER_COMMAND_HANDLER(COMMAND_GET_PLAYERS_GANG_IN_CAR_ACTIVE, GetPlayersGangInCarActive);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYERS_GANG_IN_CAR_ACTIVE, SetPlayersGangInCarActive);
//REGISTER_COMMAND_HANDLER(COMMAND_HAS_PLAYER_BOUGHT_ITEM, HasPlayerBoughtItem);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_PLAYER_FIRE_WITH_SHOULDER_BUTTON, SetPlayerFireWithShoulderButton);
//REGISTER_COMMAND_HANDLER(COMMAND_PLAYER_PUT_ON_GOGGLES, PlayerPutOnGoggles);
//REGISTER_COMMAND_HANDLER(COMMAND_SET_RENDER_PLAYER_WEAPON, SetRenderPlayerWeapon);
// -----------------------------[ NOP ]----------------------------- // -----------------------------[ NOP ]-----------------------------
REGISTER_COMMAND_NOP(COMMAND_GIVE_REMOTE_CONTROLLED_CAR_TO_PLAYER); REGISTER_COMMAND_NOP(COMMAND_GIVE_REMOTE_CONTROLLED_CAR_TO_PLAYER);

View File

@ -119,6 +119,13 @@ void AddStuckCarCheckWithWarp(CVehicle& vehicle, float stuckRadius, uint32 time,
CTheScripts::StuckCars.AddCarToCheck(GetVehiclePool()->GetRef(&vehicle), stuckRadius, time, true, stuck, flipped, inWater, numberOfNodesToCheck); CTheScripts::StuckCars.AddCarToCheck(GetVehiclePool()->GetRef(&vehicle), stuckRadius, time, true, stuck, flipped, inWater, numberOfNodesToCheck);
} }
void PlaneAttackPlayerUsingDogFight(CPlane& plane, CPlayerPed& player, float altitude) {
if (plane.m_autoPilot.m_nCarMission != eCarMission::MISSION_PLANE_CRASH_AND_BURN && plane.m_autoPilot.m_nCarMission != eCarMission::MISSION_HELI_CRASH_AND_BURN) {
plane.m_autoPilot.SetCarMission(eCarMission::MISSION_PLANE_DOG_FIGHT_PLAYER);
}
plane.m_minAltitude = altitude;
}
} }
void notsa::script::commands::vehicle::RegisterHandlers() { void notsa::script::commands::vehicle::RegisterHandlers() {
@ -143,6 +150,7 @@ void notsa::script::commands::vehicle::RegisterHandlers() {
REGISTER_COMMAND_HANDLER(COMMAND_ADD_STUCK_CAR_CHECK, AddStuckCarCheck); REGISTER_COMMAND_HANDLER(COMMAND_ADD_STUCK_CAR_CHECK, AddStuckCarCheck);
REGISTER_COMMAND_HANDLER(COMMAND_REMOVE_STUCK_CAR_CHECK, RemoveStuckCarCheck); REGISTER_COMMAND_HANDLER(COMMAND_REMOVE_STUCK_CAR_CHECK, RemoveStuckCarCheck);
REGISTER_COMMAND_HANDLER(COMMAND_ADD_STUCK_CAR_CHECK_WITH_WARP, AddStuckCarCheckWithWarp); REGISTER_COMMAND_HANDLER(COMMAND_ADD_STUCK_CAR_CHECK_WITH_WARP, AddStuckCarCheckWithWarp);
REGISTER_COMMAND_HANDLER(COMMAND_PLANE_ATTACK_PLAYER_USING_DOG_FIGHT, PlaneAttackPlayerUsingDogFight);
REGISTER_COMMAND_UNIMPLEMENTED(COMMAND_IS_TAXI); REGISTER_COMMAND_UNIMPLEMENTED(COMMAND_IS_TAXI);
REGISTER_COMMAND_UNIMPLEMENTED(COMMAND_SWITCH_TAXI_TIMER); REGISTER_COMMAND_UNIMPLEMENTED(COMMAND_SWITCH_TAXI_TIMER);