1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 06:52:34 +02:00

Various opcodes (#499)

Various opcodes
This commit is contained in:
husho 2018-06-18 07:23:20 +03:00 committed by darkf
parent 1574ebb83c
commit 81781a53ed
7 changed files with 107 additions and 92 deletions

View File

@ -128,7 +128,7 @@ void PlayerController::restart() {
if (!state->playerInfo.thaneOfLibertyCity) {
// @todo implement wanted system
uint8_t wantedLevel = 0;
uint32_t penalty = 0;
int32_t penalty = 0;
switch (wantedLevel) {
case 0:

View File

@ -76,12 +76,12 @@ struct BasicState {
/** Block 16 player info */
struct PlayerInfo {
uint32_t money;
int32_t money;
uint8_t unknown1;
uint32_t unknown2;
uint16_t unknown3;
float unknown4;
uint32_t displayedMoney;
int32_t displayedMoney;
uint32_t hiddenPackagesCollected;
uint32_t hiddenPackageCount;
uint8_t neverTired;

View File

@ -519,8 +519,13 @@ void VehicleObject::tickPhysics(float dt) {
}
bool VehicleObject::isFlipped() const {
auto up = getRotation() * glm::vec3(0.f, 0.f, 1.f);
return up.z <= -0.1f;
auto forward = getRotation() * glm::vec3(0.f, 0.f, 1.f);
return forward.z <= -0.97f;
}
bool VehicleObject::isUpright() const {
auto forward = getRotation() * glm::vec3(0.f, 0.f, 1.f);
return forward.z >= 0.f;
}
float VehicleObject::getVelocity() const {

View File

@ -128,6 +128,8 @@ public:
bool isFlipped() const;
bool isUpright() const;
float getVelocity() const;
void ejectAll();

View File

@ -22,7 +22,13 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
t.programCounter = t.calls[t.stackDepth];
}
}
// There is 02a1 opcode that is used only during "Kingdom Come", which
// basically acts like a wait command, but waiting time can be skipped
// by pressing 'X'? PS2 button
if (t.allowWaitSkip && getState()->input[0].pressed(GameInputState::Jump)) {
t.wakeCounter = 0;
t.allowWaitSkip = false;
}
if (t.wakeCounter > 0) {
t.wakeCounter = std::max(t.wakeCounter - msPassed, 0);
}
@ -211,6 +217,7 @@ void ScriptMachine::startThread(SCMThread::pc_t start, bool mission) {
t.stackDepth = 0;
t.deathOrArrestCheck = true;
t.wastedOrBusted = false;
t.allowWaitSkip = false;
_activeThreads.push_back(t);
}

View File

@ -5,12 +5,12 @@
#include <cstdint>
#include <iomanip>
#include <list>
#include <random>
#include <sstream>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include <random>
#include <type_traits>
#include <script/ScriptTypes.hpp>
@ -27,7 +27,6 @@ class SCMFile;
#define SCM_VARIABLE_SIZE 4
#define SCM_STACK_DEPTH 4
struct SCMException {
virtual ~SCMException() = default;
@ -42,7 +41,9 @@ struct IllegalInstruction : SCMException {
template <class String>
IllegalInstruction(SCMOpcode _opcode, unsigned int _offset,
String&& _thread)
: opcode(_opcode), offset(_offset), thread(std::forward<String>(_thread)) {
: opcode(_opcode)
, offset(_offset)
, thread(std::forward<String>(_thread)) {
}
std::string what() const override {
@ -100,6 +101,8 @@ struct SCMThread {
bool deathOrArrestCheck;
bool wastedOrBusted;
bool allowWaitSkip;
};
/**
@ -160,17 +163,18 @@ public:
debugFlag = flag;
}
template<typename T>
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
getRandomNumber(T min, T max) {
std::uniform_int_distribution<> dist(min, max);
return dist(randomNumberGen);
}
template<typename T>
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
getRandomNumber(T min, T max) {
std::uniform_real_distribution<> dist(static_cast<double>(min), static_cast<double>(max));
std::uniform_real_distribution<> dist(static_cast<double>(min),
static_cast<double>(max));
return dist(randomNumberGen);
}

View File

@ -3013,10 +3013,8 @@ void opcode_0108(const ScriptArguments& args, const ScriptObject object) {
@arg money
*/
void opcode_0109(const ScriptArguments& args, const ScriptPlayer player, const ScriptInt money) {
RW_UNIMPLEMENTED_OPCODE(0x0109);
RW_UNUSED(player);
RW_UNUSED(money);
RW_UNUSED(args);
args.getState()->playerInfo.money += money;
}
/**
@ -3027,11 +3025,8 @@ void opcode_0109(const ScriptArguments& args, const ScriptPlayer player, const S
@arg money
*/
bool opcode_010a(const ScriptArguments& args, const ScriptPlayer player, const ScriptInt money) {
RW_UNIMPLEMENTED_OPCODE(0x010a);
RW_UNUSED(player);
RW_UNUSED(money);
RW_UNUSED(args);
return false;
return args.getState()->playerInfo.money > money;
}
/**
@ -3042,10 +3037,8 @@ bool opcode_010a(const ScriptArguments& args, const ScriptPlayer player, const S
@arg money
*/
void opcode_010b(const ScriptArguments& args, const ScriptPlayer player, ScriptInt& money) {
RW_UNIMPLEMENTED_OPCODE(0x010b);
RW_UNUSED(player);
RW_UNUSED(args);
money = 0;
money = args.getState()->playerInfo.money;
}
/**
@ -3570,14 +3563,16 @@ void opcode_0156(const ScriptArguments& args, const ScriptString arg1, const Scr
opcode 0157
@arg player Player
@arg cameraModeID Camera mode ID
@arg arg3
@arg cameraChangeModeID
*/
void opcode_0157(const ScriptArguments& args, const ScriptPlayer player, const ScriptCamMode cameraModeID, const ScriptChangeCamMode arg3) {
RW_UNIMPLEMENTED_OPCODE(0x0157);
RW_UNUSED(player);
void opcode_0157(const ScriptArguments& args, const ScriptPlayer player,
const ScriptCamMode cameraModeID,
const ScriptChangeCamMode cameraChangeModeID) {
args.getWorld()->state->cameraTarget =
player->getCharacter()->getGameObjectID();
RW_UNUSED(cameraModeID);
RW_UNUSED(arg3);
RW_UNUSED(args);
RW_UNUSED(cameraChangeModeID);
}
/**
@ -3586,14 +3581,16 @@ void opcode_0157(const ScriptArguments& args, const ScriptPlayer player, const S
opcode 0158
@arg vehicle Car/vehicle
@arg cameraModeID Camera mode ID
@arg arg3
@arg cameraChangeModeID
*/
void opcode_0158(const ScriptArguments& args, const ScriptVehicle vehicle, const ScriptCamMode cameraModeID, const ScriptChangeCamMode arg3) {
RW_UNIMPLEMENTED_OPCODE(0x0158);
RW_UNUSED(vehicle);
void opcode_0158(const ScriptArguments& args, const ScriptVehicle vehicle,
const ScriptCamMode cameraModeID,
const ScriptChangeCamMode cameraChangeModeID) {
if (vehicle) {
args.getWorld()->state->cameraTarget = vehicle->getGameObjectID();
}
RW_UNUSED(cameraModeID);
RW_UNUSED(arg3);
RW_UNUSED(args);
RW_UNUSED(cameraChangeModeID);
}
/**
@ -3602,14 +3599,16 @@ void opcode_0158(const ScriptArguments& args, const ScriptVehicle vehicle, const
opcode 0159
@arg character Character/ped
@arg cameraModeID Camera mode ID
@arg arg3
@arg cameraChangeModeID
*/
void opcode_0159(const ScriptArguments& args, const ScriptCharacter character, const ScriptCamMode cameraModeID, const ScriptChangeCamMode arg3) {
void opcode_0159(const ScriptArguments& args, const ScriptCharacter character,
const ScriptCamMode cameraModeID,
const ScriptChangeCamMode cameraChangeModeID) {
if (character) {
args.getWorld()->state->cameraTarget = character->getGameObjectID();
args.getWorld()->state->cameraTarget = character->getGameObjectID();
}
RW_UNUSED(cameraModeID);
RW_UNUSED(arg3);
RW_UNUSED(cameraChangeModeID);
}
/**
@ -3666,12 +3665,10 @@ void opcode_015c(const ScriptArguments& args, const ScriptString areaName, const
@brief set_time_scale %1d%
opcode 015d
@arg arg1
@arg scale
*/
void opcode_015d(const ScriptArguments& args, const ScriptFloat arg1) {
RW_UNIMPLEMENTED_OPCODE(0x015d);
RW_UNUSED(arg1);
RW_UNUSED(args);
void opcode_015d(const ScriptArguments& args, const ScriptFloat scale) {
args.getState()->basic.timeScale = scale;
}
/**
@ -4073,16 +4070,15 @@ bool opcode_0179(const ScriptArguments& args, const ScriptCharacter character, c
@brief set_player %1d% weapon %2d% ammo_to %3d%
opcode 017a
@arg player
@arg arg2
@arg arg3
@arg player
@arg weaponID Weapon ID
@arg arg3
*/
void opcode_017a(const ScriptArguments& args, const ScriptPlayer player, const ScriptWeaponType arg2, const ScriptInt arg3) {
RW_UNIMPLEMENTED_OPCODE(0x017a);
RW_UNUSED(player);
RW_UNUSED(arg2);
RW_UNUSED(arg3);
void opcode_017a(const ScriptArguments& args, const ScriptPlayer player,
const ScriptWeaponType weaponID, const ScriptInt ammo) {
RW_UNUSED(args);
player->getCharacter()->getCurrentState().weapons[weaponID].bulletsTotal =
ammo;
}
/**
@ -4909,18 +4905,21 @@ void opcode_01bd(const ScriptArguments& args, ScriptInt& time) {
@brief set_actor %1d% to_look_at_spot %2d% %3d% %4d%
opcode 01be
@arg character
@arg arg2
@arg arg3
@arg arg4
@arg character
@arg arg2
@arg arg3
@arg arg4
*/
void opcode_01be(const ScriptArguments& args, const ScriptCharacter character, const ScriptFloat arg2, const ScriptFloat arg3, const ScriptFloat arg4) {
RW_UNIMPLEMENTED_OPCODE(0x01be);
RW_UNUSED(character);
RW_UNUSED(arg2);
RW_UNUSED(arg3);
RW_UNUSED(arg4);
void opcode_01be(const ScriptArguments& args, const ScriptCharacter character,
const ScriptVec3 coord) {
RW_UNUSED(args);
GameObject* object = character;
if (character->getCurrentVehicle()) {
object = character->getCurrentVehicle();
}
const auto& pos = object->getPosition() - coord;
object->setHeading(
glm::degrees(glm::atan(pos.x, pos.y) + glm::half_pi<float>()));
}
/**
@ -5923,10 +5922,8 @@ void opcode_020c(const ScriptArguments& args, ScriptVec3 coord, const ScriptExpl
@arg vehicle Car/vehicle
*/
bool opcode_020d(const ScriptArguments& args, const ScriptVehicle vehicle) {
RW_UNIMPLEMENTED_OPCODE(0x020d);
RW_UNUSED(vehicle);
RW_UNUSED(args);
return false;
return vehicle->isUpright();
}
/**
@ -5937,10 +5934,10 @@ bool opcode_020d(const ScriptArguments& args, const ScriptVehicle vehicle) {
@arg character1
*/
void opcode_020e(const ScriptArguments& args, const ScriptCharacter character0, const ScriptCharacter character1) {
RW_UNIMPLEMENTED_OPCODE(0x020e);
RW_UNUSED(character0);
RW_UNUSED(character1);
RW_UNUSED(args);
const auto& pos = character1->getPosition();
character0->setHeading(
glm::degrees(glm::atan(pos.x, pos.y) + glm::half_pi<float>()));
}
/**
@ -5951,10 +5948,10 @@ void opcode_020e(const ScriptArguments& args, const ScriptCharacter character0,
@arg player
*/
void opcode_020f(const ScriptArguments& args, const ScriptCharacter character, const ScriptPlayer player) {
RW_UNIMPLEMENTED_OPCODE(0x020f);
RW_UNUSED(character);
RW_UNUSED(player);
RW_UNUSED(args);
const auto& pos = player->getCharacter()->getPosition();
character->setHeading(
glm::degrees(glm::atan(pos.x, pos.y) + glm::half_pi<float>()));
}
/**
@ -5965,10 +5962,10 @@ void opcode_020f(const ScriptArguments& args, const ScriptCharacter character, c
@arg character Character/ped
*/
void opcode_0210(const ScriptArguments& args, const ScriptPlayer player, const ScriptCharacter character) {
RW_UNIMPLEMENTED_OPCODE(0x0210);
RW_UNUSED(player);
RW_UNUSED(character);
RW_UNUSED(args);
const auto& pos = character->getPosition();
player->getCharacter()->setHeading(
glm::degrees(glm::atan(pos.x, pos.y) + glm::half_pi<float>()));
}
/**
@ -6889,17 +6886,18 @@ bool opcode_02a0(const ScriptArguments& args, const ScriptCharacter character) {
}
/**
@brief
@brief skippable_wait
opcode 02a1
@arg arg1
@arg arg2
@arg time
@arg waitSkip
*/
void opcode_02a1(const ScriptArguments& args, const ScriptInt arg1, const ScriptInt arg2) {
RW_UNIMPLEMENTED_OPCODE(0x02a1);
RW_UNUSED(arg1);
RW_UNUSED(arg2);
RW_UNUSED(args);
void opcode_02a1(const ScriptArguments& args, const ScriptInt time, const ScriptBoolean waitSkip) {
RW_CHECK(time >= 0, "negative wait time is not supported");
auto thread = args.getThread();
// Scripts use wait 0 to yield
thread->wakeCounter = time > 0 ? time : -1;
thread->allowWaitSkip = waitSkip;
}
/**
@ -9594,11 +9592,11 @@ void opcode_0361(const ScriptArguments& args, const ScriptGarage garage) {
@arg character Character/ped
@arg coord Coordinates
*/
void opcode_0362(const ScriptArguments& args, const ScriptCharacter character, ScriptVec3 coord) {
RW_UNIMPLEMENTED_OPCODE(0x0362);
RW_UNUSED(character);
RW_UNUSED(coord);
void opcode_0362(const ScriptArguments& args, const ScriptCharacter character,
ScriptVec3 coord) {
RW_UNUSED(args);
character->setCurrentVehicle(nullptr, 0);
character->setPosition(coord);
}
/**
@ -10593,11 +10591,11 @@ void opcode_039e(const ScriptArguments& args, const ScriptCharacter character, c
@arg vehicle Car/vehicle
@arg coord Coordinates
*/
void opcode_039f(const ScriptArguments& args, const ScriptVehicle vehicle, ScriptVec2 coord) {
RW_UNIMPLEMENTED_OPCODE(0x039f);
RW_UNUSED(vehicle);
RW_UNUSED(coord);
void opcode_039f(const ScriptArguments& args, const ScriptVehicle vehicle,
ScriptVec2 coord) {
RW_UNUSED(args);
vehicle->setHeading(
glm::degrees(glm::atan(coord.x, coord.y) + glm::half_pi<float>()));
}
/**
@ -10909,9 +10907,8 @@ void opcode_03b7(const ScriptArguments& args, const ScriptBoolean arg1) {
@arg player
*/
void opcode_03b8(const ScriptArguments& args, const ScriptPlayer player) {
RW_UNIMPLEMENTED_OPCODE(0x03b8);
RW_UNUSED(player);
RW_UNUSED(args);
player->getCharacter()->clearInventory();
}
/**