mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 03:12:36 +01:00
parent
81781a53ed
commit
6d04746222
@ -63,6 +63,8 @@ set(RWENGINE_SOURCES
|
|||||||
src/engine/GameWorld.hpp
|
src/engine/GameWorld.hpp
|
||||||
src/engine/GarageController.cpp
|
src/engine/GarageController.cpp
|
||||||
src/engine/GarageController.hpp
|
src/engine/GarageController.hpp
|
||||||
|
src/engine/Payphone.cpp
|
||||||
|
src/engine/Payphone.hpp
|
||||||
src/engine/SaveGame.cpp
|
src/engine/SaveGame.cpp
|
||||||
src/engine/SaveGame.hpp
|
src/engine/SaveGame.hpp
|
||||||
src/engine/ScreenText.cpp
|
src/engine/ScreenText.cpp
|
||||||
|
@ -4,18 +4,22 @@
|
|||||||
|
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
|
#include "engine/Animator.hpp"
|
||||||
#include "engine/GameState.hpp"
|
#include "engine/GameState.hpp"
|
||||||
#include "engine/GameWorld.hpp"
|
#include "engine/GameWorld.hpp"
|
||||||
#include "objects/CharacterObject.hpp"
|
#include "objects/CharacterObject.hpp"
|
||||||
#include "objects/GameObject.hpp"
|
#include "objects/GameObject.hpp"
|
||||||
#include "objects/VehicleObject.hpp"
|
#include "objects/VehicleObject.hpp"
|
||||||
|
|
||||||
|
class Animator;
|
||||||
|
|
||||||
PlayerController::PlayerController()
|
PlayerController::PlayerController()
|
||||||
: CharacterController()
|
: CharacterController()
|
||||||
, lastRotation(glm::vec3(0.f, 0.f, 0.f))
|
, lastRotation(glm::vec3(0.f, 0.f, 0.f))
|
||||||
, missionRestartRequired(false)
|
, missionRestartRequired(false)
|
||||||
, _enabled(true)
|
, _enabled(true)
|
||||||
, restartState(Alive) {
|
, restartState(Alive)
|
||||||
|
, payphoneState(Left) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::setInputEnabled(bool enabled) {
|
void PlayerController::setInputEnabled(bool enabled) {
|
||||||
@ -275,6 +279,42 @@ void PlayerController::restartLogic() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerController::pickUpPayphone() {
|
||||||
|
payphoneState = PayphoneState::PickingUp;
|
||||||
|
|
||||||
|
character->animator->playAnimation(
|
||||||
|
AnimIndexMovement, character->animations->animation(AnimCycle::PhoneIn),
|
||||||
|
1.f, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerController::hangUpPayphone() {
|
||||||
|
payphoneState = PayphoneState::HangingUp;
|
||||||
|
|
||||||
|
character->animator->playAnimation(
|
||||||
|
AnimIndexMovement,
|
||||||
|
character->animations->animation(AnimCycle::PhoneOut), 1.f, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerController::talkOnPayphone() {
|
||||||
|
payphoneState = PayphoneState::Talking;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerController::leavePayphone() {
|
||||||
|
payphoneState = Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerController::isPickingUpPayphone() const {
|
||||||
|
return payphoneState == PayphoneState::PickingUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerController::isHangingUpPayphone() const {
|
||||||
|
return payphoneState == PayphoneState::HangingUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerController::isTalkingOnPayphone() const {
|
||||||
|
return payphoneState == PayphoneState::Talking;
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerController::update(float dt) {
|
void PlayerController::update(float dt) {
|
||||||
restartLogic();
|
restartLogic();
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
class PlayerController : public CharacterController {
|
class PlayerController : public CharacterController {
|
||||||
|
private:
|
||||||
glm::quat cameraRotation{1.0f, 0.0f, 0.0f, 0.0f};
|
glm::quat cameraRotation{1.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
glm::vec3 direction{};
|
glm::vec3 direction{};
|
||||||
@ -26,6 +27,13 @@ class PlayerController : public CharacterController {
|
|||||||
FadingIn,
|
FadingIn,
|
||||||
} restartState;
|
} restartState;
|
||||||
|
|
||||||
|
enum PayphoneState {
|
||||||
|
Left,
|
||||||
|
Talking,
|
||||||
|
PickingUp,
|
||||||
|
HangingUp,
|
||||||
|
} payphoneState;
|
||||||
|
|
||||||
// handles player respawn logic
|
// handles player respawn logic
|
||||||
void restartLogic();
|
void restartLogic();
|
||||||
|
|
||||||
@ -58,6 +66,22 @@ public:
|
|||||||
// @todo not implemented yet
|
// @todo not implemented yet
|
||||||
bool isBusted() const;
|
bool isBusted() const;
|
||||||
|
|
||||||
|
// Play payphone pick up anim
|
||||||
|
void pickUpPayphone();
|
||||||
|
// Play payphone hang up anim
|
||||||
|
void hangUpPayphone();
|
||||||
|
// Play talking on payphone anim
|
||||||
|
void talkOnPayphone();
|
||||||
|
// Reset any payphone anim
|
||||||
|
void leavePayphone();
|
||||||
|
|
||||||
|
// Is payphone pick up anim playing
|
||||||
|
bool isPickingUpPayphone() const;
|
||||||
|
// Is payphone hang up anim playing
|
||||||
|
bool isHangingUpPayphone() const;
|
||||||
|
// Is talking on payphone anim playing
|
||||||
|
bool isTalkingOnPayphone() const;
|
||||||
|
|
||||||
void update(float dt) override;
|
void update(float dt) override;
|
||||||
|
|
||||||
glm::vec3 getTargetPosition() override;
|
glm::vec3 getTargetPosition() override;
|
||||||
|
@ -459,6 +459,12 @@ GarageInfo* GameWorld::createGarage(const glm::vec3 coord0,
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Payphone* GameWorld::createPayphone(const glm::vec2 coord) {
|
||||||
|
int id = payphones.size();
|
||||||
|
payphones.emplace_back(make_unique<Payphone>(this, id, coord));
|
||||||
|
return payphones.back().get();
|
||||||
|
}
|
||||||
|
|
||||||
void GameWorld::ObjectPool::insert(GameObject* object) {
|
void GameWorld::ObjectPool::insert(GameObject* object) {
|
||||||
if (object->getGameObjectID() == 0) {
|
if (object->getGameObjectID() == 0) {
|
||||||
// Find the lowest free GameObjectID.
|
// Find the lowest free GameObjectID.
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <audio/SoundManager.hpp>
|
#include <audio/SoundManager.hpp>
|
||||||
|
|
||||||
#include <engine/GarageController.hpp>
|
#include <engine/GarageController.hpp>
|
||||||
|
#include <engine/Payphone.hpp>
|
||||||
#include <objects/ObjectTypes.hpp>
|
#include <objects/ObjectTypes.hpp>
|
||||||
|
|
||||||
#include <render/VisualFX.hpp>
|
#include <render/VisualFX.hpp>
|
||||||
@ -35,6 +36,7 @@ struct btDbvtBroadphase;
|
|||||||
|
|
||||||
class GameState;
|
class GameState;
|
||||||
class GarageController;
|
class GarageController;
|
||||||
|
class Payphone;
|
||||||
|
|
||||||
class PlayerController;
|
class PlayerController;
|
||||||
class Logger;
|
class Logger;
|
||||||
@ -151,6 +153,11 @@ public:
|
|||||||
GarageInfo* createGarage(const glm::vec3 coord0, const glm::vec3 coord1,
|
GarageInfo* createGarage(const glm::vec3 coord0, const glm::vec3 coord1,
|
||||||
const int type);
|
const int type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a payphone
|
||||||
|
*/
|
||||||
|
Payphone* createPayphone(const glm::vec2 coord);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys an existing Object
|
* Destroys an existing Object
|
||||||
*/
|
*/
|
||||||
@ -266,6 +273,8 @@ public:
|
|||||||
|
|
||||||
std::vector<std::unique_ptr<GarageController>> garageControllers;
|
std::vector<std::unique_ptr<GarageController>> garageControllers;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Payphone>> payphones;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief getBlipTarget
|
* @brief getBlipTarget
|
||||||
* @param blip
|
* @param blip
|
||||||
|
127
rwengine/src/engine/Payphone.cpp
Normal file
127
rwengine/src/engine/Payphone.cpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#include "engine/Payphone.hpp"
|
||||||
|
|
||||||
|
#include <rw/defines.hpp>
|
||||||
|
|
||||||
|
#include "ai/PlayerController.hpp"
|
||||||
|
|
||||||
|
#include "engine/GameState.hpp"
|
||||||
|
#include "engine/GameWorld.hpp"
|
||||||
|
|
||||||
|
#include "objects/CharacterObject.hpp"
|
||||||
|
#include "objects/GameObject.hpp"
|
||||||
|
#include "objects/InstanceObject.hpp"
|
||||||
|
|
||||||
|
Payphone::Payphone(GameWorld* engine_, const int id_, const glm::vec2 coord)
|
||||||
|
: engine(engine_), id(id_) {
|
||||||
|
// Find payphone object, original game does this differently
|
||||||
|
for (const auto& p : engine->instancePool.objects) {
|
||||||
|
auto o = p.second;
|
||||||
|
if (!o->getModel()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (o->getModelInfo<BaseModelInfo>()->name != "phonebooth1") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (glm::distance(coord, glm::vec2(o->getPosition())) < 2.f) {
|
||||||
|
object = static_cast<InstanceObject*>(o);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message.clear();
|
||||||
|
|
||||||
|
if (object) {
|
||||||
|
position = object->getPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Payphone::enable() {
|
||||||
|
state = State::Ringing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Payphone::disable() {
|
||||||
|
state = State::Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Payphone::isTalking() const {
|
||||||
|
return state == State::Talking;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Payphone::setMessageAndStartRinging(const std::string& m) {
|
||||||
|
state = State::Ringing;
|
||||||
|
message = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Payphone::tick(float dt) {
|
||||||
|
RW_UNUSED(dt);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case State::Idle: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case State::Ringing: {
|
||||||
|
if (glm::distance(
|
||||||
|
position,
|
||||||
|
engine->getPlayer()->getCharacter()->getPosition()) < 1.f) {
|
||||||
|
state = State::PickingUp;
|
||||||
|
|
||||||
|
engine->getPlayer()->pickUpPayphone();
|
||||||
|
|
||||||
|
engine->state->isCinematic = true;
|
||||||
|
engine->getPlayer()->prepareForCutscene();
|
||||||
|
|
||||||
|
engine->getPlayer()->getCharacter()->setHeading(glm::degrees(
|
||||||
|
glm::atan(position.x, position.y) + glm::half_pi<float>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo Do wiggle animation
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case State::PickingUp: {
|
||||||
|
if (!engine->getPlayer()->isPickingUpPayphone()) {
|
||||||
|
state = State::Talking;
|
||||||
|
|
||||||
|
if (!message.empty()) {
|
||||||
|
const auto& text =
|
||||||
|
ScreenText::format(engine->data->texts.text(message));
|
||||||
|
|
||||||
|
engine->state->text.clear<ScreenTextType::HighPriority>();
|
||||||
|
engine->state->text.addText<ScreenTextType::HighPriority>(
|
||||||
|
ScreenTextEntry::makeHighPriority(message, text, 3000));
|
||||||
|
|
||||||
|
message.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
callTimer = engine->getGameTime() + 3.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case State::Talking: {
|
||||||
|
if (callTimer <= engine->getGameTime()) {
|
||||||
|
state = State::HangingUp;
|
||||||
|
|
||||||
|
engine->getPlayer()->hangUpPayphone();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case State::HangingUp: {
|
||||||
|
if (!engine->getPlayer()->isHangingUpPayphone()) {
|
||||||
|
state = State::Idle;
|
||||||
|
|
||||||
|
engine->state->isCinematic = false;
|
||||||
|
engine->getPlayer()->freeFromCutscene();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: { break; }
|
||||||
|
}
|
||||||
|
}
|
49
rwengine/src/engine/Payphone.hpp
Normal file
49
rwengine/src/engine/Payphone.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef _RWENGINE_PAYPHONE_HPP_
|
||||||
|
#define _RWENGINE_PAYPHONE_HPP_
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class PlayerController;
|
||||||
|
|
||||||
|
class GameWorld;
|
||||||
|
class GameState;
|
||||||
|
|
||||||
|
class GameObject;
|
||||||
|
class InstanceObject;
|
||||||
|
class CharacterObject;
|
||||||
|
|
||||||
|
class Payphone {
|
||||||
|
private:
|
||||||
|
InstanceObject* object;
|
||||||
|
glm::vec3 position;
|
||||||
|
GameWorld* engine;
|
||||||
|
float callTimer = 0.f;
|
||||||
|
std::string message;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class State { Idle, Ringing, PickingUp, Talking, HangingUp };
|
||||||
|
|
||||||
|
State state = State::Idle;
|
||||||
|
|
||||||
|
int id;
|
||||||
|
|
||||||
|
int getScriptObjectID() const {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Payphone(GameWorld* engine_, const int id_, const glm::vec2 coord);
|
||||||
|
~Payphone() = default;
|
||||||
|
|
||||||
|
// Makes a payphone ring
|
||||||
|
void enable();
|
||||||
|
// Disables ringing
|
||||||
|
void disable();
|
||||||
|
// Is currently used by player
|
||||||
|
bool isTalking() const;
|
||||||
|
// Sets a message and makes a payphone ring
|
||||||
|
void setMessageAndStartRinging(const std::string& m);
|
||||||
|
void tick(float dt);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -328,11 +328,11 @@ struct Block7Data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Block8Data {
|
struct Block8Data {
|
||||||
BlockDword numPhones;
|
BlockDword numPayphones;
|
||||||
BlockDword numActivePhones;
|
BlockDword numActivePayphones;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Block8Phone {
|
struct Block8Payphone {
|
||||||
glm::vec3 position{};
|
glm::vec3 position{};
|
||||||
BlockDword messagePtr[6];
|
BlockDword messagePtr[6];
|
||||||
BlockDword messageEndTime;
|
BlockDword messageEndTime;
|
||||||
@ -815,25 +815,23 @@ bool SaveGame::loadGame(GameState& state, const std::string& file) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Block 8
|
// Block 8
|
||||||
BlockSize phoneBlockSize;
|
BlockSize payphoneBlockSize;
|
||||||
BLOCK_HEADER(phoneBlockSize)
|
BLOCK_HEADER(payphoneBlockSize)
|
||||||
BlockDword phoneDataSize;
|
BlockDword payphoneDataSize;
|
||||||
READ_VALUE(phoneDataSize)
|
READ_VALUE(payphoneDataSize)
|
||||||
|
|
||||||
Block8Data phoneData;
|
Block8Data payphoneData;
|
||||||
READ_VALUE(phoneData);
|
READ_VALUE(payphoneData);
|
||||||
std::vector<Block8Phone> phones(phoneData.numPhones);
|
std::vector<Block8Payphone> payphones(payphoneData.numPayphones);
|
||||||
for (size_t p = 0; p < phoneData.numPhones; ++p) {
|
for (auto& payphone : payphones) {
|
||||||
Block8Phone& phone = phones[p];
|
READ_VALUE(payphone)
|
||||||
READ_VALUE(phone)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RW_DEBUG
|
#if RW_DEBUG
|
||||||
std::cout << "Phones: " << phoneData.numPhones << std::endl;
|
std::cout << "Payphones: " << payphoneData.numPayphones << std::endl;
|
||||||
for (size_t p = 0; p < phoneData.numPhones; ++p) {
|
for (const auto& payphone : payphones) {
|
||||||
Block8Phone& phone = phones[p];
|
std::cout << " " << uint16_t(payphone.state) << " " << payphone.position.x
|
||||||
std::cout << " " << uint16_t(phone.state) << " " << phone.position.x
|
<< " " << payphone.position.y << " " << payphone.position.z
|
||||||
<< " " << phone.position.y << " " << phone.position.z
|
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1257,6 +1255,11 @@ bool SaveGame::loadGame(GameState& state, const std::string& file) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo restore properly
|
||||||
|
for (const auto& payphone : payphones) {
|
||||||
|
state.world->createPayphone(glm::vec2(payphone.position));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO restore garage data
|
// TODO restore garage data
|
||||||
// http://gtaforums.com/topic/758692-gta-iii-save-file-documentation/
|
// http://gtaforums.com/topic/758692-gta-iii-save-file-documentation/
|
||||||
for (size_t g = 0; g < garageData.garageCount; ++g) {
|
for (size_t g = 0; g < garageData.garageCount; ++g) {
|
||||||
|
@ -122,6 +122,32 @@ void CharacterObject::destroyActor() {
|
|||||||
glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
|
glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
|
||||||
glm::vec3 animTranslate{};
|
glm::vec3 animTranslate{};
|
||||||
|
|
||||||
|
if (controller) {
|
||||||
|
auto c = static_cast<PlayerController*>(controller);
|
||||||
|
|
||||||
|
if (c->isTalkingOnPayphone()) {
|
||||||
|
animator->playAnimation(
|
||||||
|
AnimIndexMovement,
|
||||||
|
animations->animation(AnimCycle::PhoneTalk), 1.f,
|
||||||
|
true);
|
||||||
|
return glm::vec3();
|
||||||
|
}
|
||||||
|
if (c->isPickingUpPayphone()) {
|
||||||
|
if (animator->isCompleted(AnimIndexMovement)) {
|
||||||
|
c->talkOnPayphone();
|
||||||
|
} else {
|
||||||
|
return glm::vec3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c->isHangingUpPayphone()) {
|
||||||
|
if (animator->isCompleted(AnimIndexMovement)) {
|
||||||
|
c->leavePayphone();
|
||||||
|
} else {
|
||||||
|
return glm::vec3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (motionBlockedByActivity) {
|
if (motionBlockedByActivity) {
|
||||||
// Clear any residual motion animation
|
// Clear any residual motion animation
|
||||||
animator->playAnimation(AnimIndexMovement, nullptr, 1.f, false);
|
animator->playAnimation(AnimIndexMovement, nullptr, 1.f, false);
|
||||||
@ -584,8 +610,8 @@ void CharacterObject::resetToAINode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterObject::playActivityAnimation(const AnimationPtr& animation, bool repeat,
|
void CharacterObject::playActivityAnimation(const AnimationPtr& animation,
|
||||||
bool blocked) {
|
bool repeat, bool blocked) {
|
||||||
RW_CHECK(animator != nullptr, "No Animator");
|
RW_CHECK(animator != nullptr, "No Animator");
|
||||||
animator->playAnimation(AnimIndexAction, animation, 1.f, repeat);
|
animator->playAnimation(AnimIndexAction, animation, 1.f, repeat);
|
||||||
motionBlockedByActivity = blocked;
|
motionBlockedByActivity = blocked;
|
||||||
|
@ -220,6 +220,17 @@ ScriptObjectType<GarageInfo> ScriptArguments::getScriptObject(
|
|||||||
return {param.handleValue(), garage};
|
return {param.handleValue(), garage};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
|
ScriptObjectType<Payphone> ScriptArguments::getScriptObject(
|
||||||
|
unsigned int arg) const {
|
||||||
|
auto& param = (*this)[arg];
|
||||||
|
RW_CHECK(param.isLvalue(), "Non lvalue passed as object");
|
||||||
|
auto index = *param.handleValue();
|
||||||
|
RW_CHECK(index >= 0, "Object index is negative");
|
||||||
|
auto& payphones = getWorld()->payphones;
|
||||||
|
auto payphone = payphones.at(size_t(index)).get();
|
||||||
|
return {param.handleValue(), payphone};
|
||||||
|
}
|
||||||
|
template <>
|
||||||
ScriptObjectType<BlipData> ScriptArguments::getScriptObject(
|
ScriptObjectType<BlipData> ScriptArguments::getScriptObject(
|
||||||
unsigned int arg) const {
|
unsigned int arg) const {
|
||||||
auto& param = (*this)[arg];
|
auto& param = (*this)[arg];
|
||||||
|
@ -23,6 +23,7 @@ class ScriptModule;
|
|||||||
struct SCMThread;
|
struct SCMThread;
|
||||||
class GameState;
|
class GameState;
|
||||||
class GameWorld;
|
class GameWorld;
|
||||||
|
class Payphone;
|
||||||
|
|
||||||
typedef uint16_t SCMOpcode;
|
typedef uint16_t SCMOpcode;
|
||||||
typedef char SCMByte;
|
typedef char SCMByte;
|
||||||
@ -105,10 +106,10 @@ struct GarageInfo;
|
|||||||
using ScriptVehicleGenerator = ScriptObjectType<VehicleGenerator>;
|
using ScriptVehicleGenerator = ScriptObjectType<VehicleGenerator>;
|
||||||
using ScriptBlip = ScriptObjectType<BlipData>;
|
using ScriptBlip = ScriptObjectType<BlipData>;
|
||||||
using ScriptGarage = ScriptObjectType<GarageInfo>;
|
using ScriptGarage = ScriptObjectType<GarageInfo>;
|
||||||
|
using ScriptPayphone = ScriptObjectType<Payphone>;
|
||||||
|
|
||||||
/// @todo replace these with real types for sounds etc.
|
/// @todo replace these with real types for sounds etc.
|
||||||
using ScriptSound = ScriptObjectType<int>;
|
using ScriptSound = ScriptObjectType<int>;
|
||||||
using ScriptPhone = ScriptObjectType<int>;
|
|
||||||
using ScriptFire = ScriptObjectType<int>;
|
using ScriptFire = ScriptObjectType<int>;
|
||||||
using ScriptSphere = ScriptObjectType<int>;
|
using ScriptSphere = ScriptObjectType<int>;
|
||||||
|
|
||||||
@ -338,6 +339,9 @@ template <>
|
|||||||
ScriptObjectType<BlipData> ScriptArguments::getScriptObject(
|
ScriptObjectType<BlipData> ScriptArguments::getScriptObject(
|
||||||
unsigned int arg) const;
|
unsigned int arg) const;
|
||||||
template <>
|
template <>
|
||||||
|
ScriptObjectType<Payphone> ScriptArguments::getScriptObject(
|
||||||
|
unsigned int arg) const;
|
||||||
|
template <>
|
||||||
ScriptObjectType<VehicleGenerator> ScriptArguments::getScriptObject(
|
ScriptObjectType<VehicleGenerator> ScriptArguments::getScriptObject(
|
||||||
unsigned int arg) const;
|
unsigned int arg) const;
|
||||||
template <>
|
template <>
|
||||||
|
@ -6604,70 +6604,64 @@ void opcode_0249(const ScriptArguments& args, const ScriptModel model) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief %3d% = create_phone_at %1d% %2d%
|
@brief %3d% = create_payphone_at %1d% %2d%
|
||||||
|
|
||||||
opcode 024a
|
opcode 024a
|
||||||
@arg coord Coordinates
|
@arg coord Coordinates
|
||||||
@arg phone Handle
|
@arg payphone Handle
|
||||||
*/
|
*/
|
||||||
void opcode_024a(const ScriptArguments& args, ScriptVec2 coord, ScriptPhone& phone) {
|
void opcode_024a(const ScriptArguments& args, const ScriptVec2 coord, ScriptPayphone& payphone) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x024a);
|
payphone = args.getWorld()->createPayphone(coord);
|
||||||
RW_UNUSED(coord);
|
|
||||||
RW_UNUSED(phone);
|
|
||||||
RW_UNUSED(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_repeatedly %1d% %2g%
|
@brief text_payphone_repeatedly %1d% %2g%
|
||||||
|
|
||||||
opcode 024b
|
opcode 024b
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
*/
|
*/
|
||||||
void opcode_024b(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2) {
|
void opcode_024b(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x024b);
|
RW_UNIMPLEMENTED_OPCODE(0x024b);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(args);
|
RW_UNUSED(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone %1d% %2g%
|
@brief text_payphone %1d% %2g%
|
||||||
|
|
||||||
opcode 024c
|
opcode 024c
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg text
|
||||||
*/
|
*/
|
||||||
void opcode_024c(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2) {
|
void opcode_024c(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString text) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x024c);
|
|
||||||
RW_UNUSED(phone);
|
|
||||||
RW_UNUSED(arg2);
|
|
||||||
RW_UNUSED(args);
|
RW_UNUSED(args);
|
||||||
|
payphone->setMessageAndStartRinging(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief phone_text_been_displayed %1d%
|
@brief payphone_text_been_displayed %1d%
|
||||||
|
|
||||||
opcode 024d
|
opcode 024d
|
||||||
@arg phone
|
@arg payphone
|
||||||
*/
|
*/
|
||||||
bool opcode_024d(const ScriptArguments& args, const ScriptPhone phone) {
|
bool opcode_024d(const ScriptArguments& args, const ScriptPayphone payphone) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x024d);
|
RW_UNIMPLEMENTED_OPCODE(0x024d);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(args);
|
RW_UNUSED(args);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief disable_phone %1d%
|
@brief disable_payphone %1d%
|
||||||
|
|
||||||
opcode 024e
|
opcode 024e
|
||||||
@arg phone
|
@arg payphone
|
||||||
*/
|
*/
|
||||||
void opcode_024e(const ScriptArguments& args, const ScriptPhone phone) {
|
void opcode_024e(const ScriptArguments& args, const ScriptPayphone payphone) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x024e);
|
|
||||||
RW_UNUSED(phone);
|
|
||||||
RW_UNUSED(args);
|
RW_UNUSED(args);
|
||||||
|
payphone->disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9955,49 +9949,49 @@ void opcode_0377(const ScriptArguments& args, const ScriptCharacter character) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_1string_repeatedly %1d% %2g% %3g%
|
@brief text_payphone_1string_repeatedly %1d% %2g% %3g%
|
||||||
|
|
||||||
opcode 0378
|
opcode 0378
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
*/
|
*/
|
||||||
void opcode_0378(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3) {
|
void opcode_0378(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x0378);
|
RW_UNIMPLEMENTED_OPCODE(0x0378);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(args);
|
RW_UNUSED(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_1string %1d% %2g% %3g%
|
@brief text_payphone_1string %1d% %2g% %3g%
|
||||||
|
|
||||||
opcode 0379
|
opcode 0379
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
*/
|
*/
|
||||||
void opcode_0379(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3) {
|
void opcode_0379(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x0379);
|
RW_UNIMPLEMENTED_OPCODE(0x0379);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(args);
|
RW_UNUSED(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_2strings_repeatedly %1d% %2g% %3g% %4g%
|
@brief text_payphone_2strings_repeatedly %1d% %2g% %3g% %4g%
|
||||||
|
|
||||||
opcode 037a
|
opcode 037a
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
@arg arg4
|
@arg arg4
|
||||||
*/
|
*/
|
||||||
void opcode_037a(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4) {
|
void opcode_037a(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x037a);
|
RW_UNIMPLEMENTED_OPCODE(0x037a);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(arg4);
|
RW_UNUSED(arg4);
|
||||||
@ -10005,17 +9999,17 @@ void opcode_037a(const ScriptArguments& args, const ScriptPhone phone, const Scr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_2strings %1d% %2g% %3g% %4g%
|
@brief text_payphone_2strings %1d% %2g% %3g% %4g%
|
||||||
|
|
||||||
opcode 037b
|
opcode 037b
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
@arg arg4
|
@arg arg4
|
||||||
*/
|
*/
|
||||||
void opcode_037b(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4) {
|
void opcode_037b(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x037b);
|
RW_UNIMPLEMENTED_OPCODE(0x037b);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(arg4);
|
RW_UNUSED(arg4);
|
||||||
@ -10023,18 +10017,18 @@ void opcode_037b(const ScriptArguments& args, const ScriptPhone phone, const Scr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_3strings_repeatedly %1d% %2g% %3g% %4g% %5g%
|
@brief text_payphone_3strings_repeatedly %1d% %2g% %3g% %4g% %5g%
|
||||||
|
|
||||||
opcode 037c
|
opcode 037c
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
@arg arg4
|
@arg arg4
|
||||||
@arg arg5
|
@arg arg5
|
||||||
*/
|
*/
|
||||||
void opcode_037c(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5) {
|
void opcode_037c(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x037c);
|
RW_UNIMPLEMENTED_OPCODE(0x037c);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(arg4);
|
RW_UNUSED(arg4);
|
||||||
@ -10043,18 +10037,18 @@ void opcode_037c(const ScriptArguments& args, const ScriptPhone phone, const Scr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_3strings %1d% %2g% %3g% %4g% %5g%
|
@brief text_payphone_3strings %1d% %2g% %3g% %4g% %5g%
|
||||||
|
|
||||||
opcode 037d
|
opcode 037d
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
@arg arg4
|
@arg arg4
|
||||||
@arg arg5
|
@arg arg5
|
||||||
*/
|
*/
|
||||||
void opcode_037d(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5) {
|
void opcode_037d(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x037d);
|
RW_UNIMPLEMENTED_OPCODE(0x037d);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(arg4);
|
RW_UNUSED(arg4);
|
||||||
@ -10165,19 +10159,19 @@ void opcode_0385(const ScriptArguments& args, const ScriptString gxtEntry0, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_4strings_repeatedly %1d% %2g% %3g% %4g% %5g% %6g%
|
@brief text_payphone_4strings_repeatedly %1d% %2g% %3g% %4g% %5g% %6g%
|
||||||
|
|
||||||
opcode 0386
|
opcode 0386
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
@arg arg4
|
@arg arg4
|
||||||
@arg arg5
|
@arg arg5
|
||||||
@arg arg6
|
@arg arg6
|
||||||
*/
|
*/
|
||||||
void opcode_0386(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5, const ScriptString arg6) {
|
void opcode_0386(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5, const ScriptString arg6) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x0386);
|
RW_UNIMPLEMENTED_OPCODE(0x0386);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(arg4);
|
RW_UNUSED(arg4);
|
||||||
@ -10187,19 +10181,19 @@ void opcode_0386(const ScriptArguments& args, const ScriptPhone phone, const Scr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_4strings %1d% %2g% %3g% %4g% %5g% %6g%
|
@brief text_payphone_4strings %1d% %2g% %3g% %4g% %5g% %6g%
|
||||||
|
|
||||||
opcode 0387
|
opcode 0387
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
@arg arg4
|
@arg arg4
|
||||||
@arg arg5
|
@arg arg5
|
||||||
@arg arg6
|
@arg arg6
|
||||||
*/
|
*/
|
||||||
void opcode_0387(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5, const ScriptString arg6) {
|
void opcode_0387(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5, const ScriptString arg6) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x0387);
|
RW_UNIMPLEMENTED_OPCODE(0x0387);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(arg4);
|
RW_UNUSED(arg4);
|
||||||
@ -10209,10 +10203,10 @@ void opcode_0387(const ScriptArguments& args, const ScriptPhone phone, const Scr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_5strings_repeatedly %1d% %2g% %3g% %4g% %5g% %6g% %7g%
|
@brief text_payphone_5strings_repeatedly %1d% %2g% %3g% %4g% %5g% %6g% %7g%
|
||||||
|
|
||||||
opcode 0388
|
opcode 0388
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
@arg arg4
|
@arg arg4
|
||||||
@ -10220,9 +10214,9 @@ void opcode_0387(const ScriptArguments& args, const ScriptPhone phone, const Scr
|
|||||||
@arg arg6
|
@arg arg6
|
||||||
@arg arg7
|
@arg arg7
|
||||||
*/
|
*/
|
||||||
void opcode_0388(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5, const ScriptString arg6, const ScriptString arg7) {
|
void opcode_0388(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5, const ScriptString arg6, const ScriptString arg7) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x0388);
|
RW_UNIMPLEMENTED_OPCODE(0x0388);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(arg4);
|
RW_UNUSED(arg4);
|
||||||
@ -10233,10 +10227,10 @@ void opcode_0388(const ScriptArguments& args, const ScriptPhone phone, const Scr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief text_phone_5strings %1d% %2g% %3g% %4g% %5g% %6g% %7g%
|
@brief text_payphone_5strings %1d% %2g% %3g% %4g% %5g% %6g% %7g%
|
||||||
|
|
||||||
opcode 0389
|
opcode 0389
|
||||||
@arg phone
|
@arg payphone
|
||||||
@arg arg2
|
@arg arg2
|
||||||
@arg arg3
|
@arg arg3
|
||||||
@arg arg4
|
@arg arg4
|
||||||
@ -10244,9 +10238,9 @@ void opcode_0388(const ScriptArguments& args, const ScriptPhone phone, const Scr
|
|||||||
@arg arg6
|
@arg arg6
|
||||||
@arg arg7
|
@arg arg7
|
||||||
*/
|
*/
|
||||||
void opcode_0389(const ScriptArguments& args, const ScriptPhone phone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5, const ScriptString arg6, const ScriptString arg7) {
|
void opcode_0389(const ScriptArguments& args, const ScriptPayphone payphone, const ScriptString arg2, const ScriptString arg3, const ScriptString arg4, const ScriptString arg5, const ScriptString arg6, const ScriptString arg7) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x0389);
|
RW_UNIMPLEMENTED_OPCODE(0x0389);
|
||||||
RW_UNUSED(phone);
|
RW_UNUSED(payphone);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
RW_UNUSED(arg4);
|
RW_UNUSED(arg4);
|
||||||
@ -11028,16 +11022,14 @@ void opcode_03c1(const ScriptArguments& args, const ScriptPlayer player, ScriptV
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief phone %1d% answered
|
@brief payphone %1d% answered
|
||||||
|
|
||||||
opcode 03c2
|
opcode 03c2
|
||||||
@arg phone
|
@arg payphone
|
||||||
*/
|
*/
|
||||||
bool opcode_03c2(const ScriptArguments& args, const ScriptPhone phone) {
|
bool opcode_03c2(const ScriptArguments& args, const ScriptPayphone payphone) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x03c2);
|
|
||||||
RW_UNUSED(phone);
|
|
||||||
RW_UNUSED(args);
|
RW_UNUSED(args);
|
||||||
return false;
|
return payphone->isTalking();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11819,15 +11811,14 @@ void opcode_0404(const ScriptArguments& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief enable_phone %1d%
|
@brief enable_payphone %1d%
|
||||||
|
|
||||||
opcode 0405
|
opcode 0405
|
||||||
@arg phone Handle
|
@arg payphone Handle
|
||||||
*/
|
*/
|
||||||
void opcode_0405(const ScriptArguments& args, const ScriptPhone phone) {
|
void opcode_0405(const ScriptArguments& args, const ScriptPayphone payphone) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x0405);
|
|
||||||
RW_UNUSED(phone);
|
|
||||||
RW_UNUSED(args);
|
RW_UNUSED(args);
|
||||||
|
payphone->enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12586,16 +12577,15 @@ void opcode_0446(const ScriptArguments& args, const ScriptCharacter character, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief is_player_lifting_a_phone %1d%
|
@brief is_player_lifting_a_payphone %1d%
|
||||||
|
|
||||||
opcode 0447
|
opcode 0447
|
||||||
@arg player Player
|
@arg player Player
|
||||||
*/
|
*/
|
||||||
bool opcode_0447(const ScriptArguments& args, const ScriptPlayer player) {
|
bool opcode_0447(const ScriptArguments& args, const ScriptPlayer player) {
|
||||||
RW_UNIMPLEMENTED_OPCODE(0x0447);
|
|
||||||
RW_UNUSED(player);
|
|
||||||
RW_UNUSED(args);
|
RW_UNUSED(args);
|
||||||
return false;
|
return player->isPickingUpPayphone() || player->isTalkingOnPayphone() ||
|
||||||
|
player->isHangingUpPayphone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -545,6 +545,10 @@ void RWGame::tick(float dt) {
|
|||||||
gc->tick(dt);
|
gc->tick(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& p : world->payphones) {
|
||||||
|
p->tick(dt);
|
||||||
|
}
|
||||||
|
|
||||||
world->destroyQueuedObjects();
|
world->destroyQueuedObjects();
|
||||||
|
|
||||||
state.text.tick(dt);
|
state.text.tick(dt);
|
||||||
|
@ -25,6 +25,7 @@ set(TESTS
|
|||||||
Menu
|
Menu
|
||||||
Object
|
Object
|
||||||
ObjectData
|
ObjectData
|
||||||
|
Payphone
|
||||||
Pickup
|
Pickup
|
||||||
Renderer
|
Renderer
|
||||||
RWBStream
|
RWBStream
|
||||||
|
72
tests/test_Payphone.cpp
Normal file
72
tests/test_Payphone.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <ai/PlayerController.hpp>
|
||||||
|
#include <engine/GameWorld.hpp>
|
||||||
|
#include <engine/Payphone.hpp>
|
||||||
|
#include <objects/CharacterObject.hpp>
|
||||||
|
#include <objects/GameObject.hpp>
|
||||||
|
#include <objects/InstanceObject.hpp>
|
||||||
|
#include "test_Globals.hpp"
|
||||||
|
#if RW_TEST_WITH_DATA
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(PayphoneTests)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_payphone_interaction) {
|
||||||
|
{
|
||||||
|
const auto playerID = 7777;
|
||||||
|
auto character = Global::get().e->createPlayer(
|
||||||
|
{0.f, 0.f, 0.f}, {1.f, 0.f, 0.f, 0.f}, playerID);
|
||||||
|
BOOST_REQUIRE(character != nullptr);
|
||||||
|
|
||||||
|
Global::get().e->state->playerObject = playerID;
|
||||||
|
|
||||||
|
// phonebooth1 from ipl file
|
||||||
|
const auto modelID = 1335;
|
||||||
|
auto payphoneObj = Global::get().e->createInstance(
|
||||||
|
modelID, {1.f, 0.f, 0.f}, {1.f, 0.f, 0.f, 0.f});
|
||||||
|
BOOST_REQUIRE(payphoneObj != nullptr);
|
||||||
|
|
||||||
|
auto payphone = Global::get().e->createPayphone({1.f, 0.f});
|
||||||
|
BOOST_REQUIRE(payphone != nullptr);
|
||||||
|
payphone->setMessageAndStartRinging("");
|
||||||
|
|
||||||
|
auto dt = 0.016f;
|
||||||
|
Global::get().e->state->gameTime += dt;
|
||||||
|
character->tick(dt);
|
||||||
|
payphone->tick(dt);
|
||||||
|
|
||||||
|
BOOST_CHECK(!Global::get().e->getPlayer()->isPickingUpPayphone());
|
||||||
|
|
||||||
|
character->setPosition(character->getPosition() + glm::vec3{0.001f, 0.f, 0.f});
|
||||||
|
|
||||||
|
dt = 0.016f;
|
||||||
|
Global::get().e->state->gameTime += dt;
|
||||||
|
// character->tick(dt);
|
||||||
|
payphone->tick(dt);
|
||||||
|
|
||||||
|
BOOST_CHECK(Global::get().e->getPlayer()->isPickingUpPayphone());
|
||||||
|
BOOST_CHECK(!payphone->isTalking());
|
||||||
|
|
||||||
|
dt = 10.f;
|
||||||
|
Global::get().e->state->gameTime += dt;
|
||||||
|
character->tick(dt);
|
||||||
|
payphone->tick(dt);
|
||||||
|
|
||||||
|
BOOST_CHECK(Global::get().e->getPlayer()->isTalkingOnPayphone());
|
||||||
|
BOOST_CHECK(payphone->isTalking());
|
||||||
|
|
||||||
|
dt = 3.f;
|
||||||
|
Global::get().e->state->gameTime += dt;
|
||||||
|
character->tick(dt);
|
||||||
|
payphone->tick(dt);
|
||||||
|
|
||||||
|
BOOST_CHECK(Global::get().e->getPlayer()->isHangingUpPayphone());
|
||||||
|
BOOST_CHECK(!payphone->isTalking());
|
||||||
|
|
||||||
|
Global::get().e->destroyObject(payphoneObj);
|
||||||
|
Global::get().e->destroyObject(character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user