1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-09 12:22:34 +01:00

Merge pull request #449 from husho/pickups

[Ready] Got some pickups working
This commit is contained in:
Daniel Evans 2018-05-25 12:56:11 +01:00 committed by GitHub
commit b7d657b9ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 480 additions and 142 deletions

View File

@ -96,8 +96,6 @@ set(RWENGINE_SOURCES
src/objects/GameObject.hpp src/objects/GameObject.hpp
src/objects/InstanceObject.cpp src/objects/InstanceObject.cpp
src/objects/InstanceObject.hpp src/objects/InstanceObject.hpp
src/objects/ItemPickup.cpp
src/objects/ItemPickup.hpp
src/objects/ObjectTypes.hpp src/objects/ObjectTypes.hpp
src/objects/PickupObject.cpp src/objects/PickupObject.cpp
src/objects/PickupObject.hpp src/objects/PickupObject.hpp

View File

@ -277,6 +277,17 @@ void PlayerController::restartLogic() {
void PlayerController::update(float dt) { void PlayerController::update(float dt) {
restartLogic(); restartLogic();
GameWorld* world = character->engine;
GameState* state = character->engine->state;
if (adrenalineEffect) {
if (world->getGameTime() > adrenalineEffectTime) {
state->basic.timeScale = 1.f;
adrenalineEffect = false;
}
}
CharacterController::update(dt); CharacterController::update(dt);
} }
@ -289,3 +300,12 @@ void PlayerController::jump() {
setNextActivity(std::make_unique<Activities::Jump>()); setNextActivity(std::make_unique<Activities::Jump>());
} }
} }
void PlayerController::activateAdrenalineEffect() {
GameWorld* world = character->engine;
GameState* state = character->engine->state;
adrenalineEffect = true;
adrenalineEffectTime = world->getGameTime() + 20.f;
state->basic.timeScale = 0.3f;
}

View File

@ -14,6 +14,9 @@ class PlayerController : public CharacterController {
bool missionRestartRequired; bool missionRestartRequired;
bool adrenalineEffect;
float adrenalineEffectTime;
bool _enabled; bool _enabled;
enum RestartState { enum RestartState {
@ -59,6 +62,12 @@ public:
glm::vec3 getTargetPosition() override; glm::vec3 getTargetPosition() override;
bool isAdrenalineActive() {
return adrenalineEffect;
};
void activateAdrenalineEffect();
void jump(); void jump();
/** /**

View File

@ -26,7 +26,7 @@
#include "objects/CharacterObject.hpp" #include "objects/CharacterObject.hpp"
#include "objects/CutsceneObject.hpp" #include "objects/CutsceneObject.hpp"
#include "objects/InstanceObject.hpp" #include "objects/InstanceObject.hpp"
#include "objects/ItemPickup.hpp" #include "objects/PickupObject.hpp"
#include "objects/VehicleObject.hpp" #include "objects/VehicleObject.hpp"
#include "render/ViewCamera.hpp" #include "render/ViewCamera.hpp"
@ -360,6 +360,21 @@ PickupObject* GameWorld::createPickup(const glm::vec3& pos, int id, int type) {
// If nothing, create a generic pickup instead of an item pickup // If nothing, create a generic pickup instead of an item pickup
if (it != data->weaponData.end()) { if (it != data->weaponData.end()) {
pickup = new ItemPickup(this, pos, modelInfo, pickuptype, it->get()); pickup = new ItemPickup(this, pos, modelInfo, pickuptype, it->get());
} else if (modelInfo->name == "info" || modelInfo->name == "briefcase" ||
modelInfo->name == "floatpackge1") {
pickup = new DummyPickup(this, pos, modelInfo, pickuptype);
} else if (modelInfo->name == "killfrenzy") {
pickup = new RampagePickup(this, pos, modelInfo, pickuptype);
} else if (modelInfo->name == "health") {
pickup = new HealthPickup(this, pos, modelInfo, pickuptype);
} else if (modelInfo->name == "bodyarmour") {
pickup = new ArmourPickup(this, pos, modelInfo, pickuptype);
} else if (modelInfo->name == "package1") {
pickup = new CollectablePickup(this, pos, modelInfo, pickuptype);
} else if (modelInfo->name == "adrenaline") {
pickup = new AdrenalinePickup(this, pos, modelInfo, pickuptype);
} else if (modelInfo->name == "Money") {
pickup = new MoneyPickup(this, pos, modelInfo, pickuptype, 0);
} else { } else {
RW_UNIMPLEMENTED("Non-weapon pickups"); RW_UNIMPLEMENTED("Non-weapon pickups");
pickup = new PickupObject(this, pos, modelInfo, pickuptype); pickup = new PickupObject(this, pos, modelInfo, pickuptype);

View File

@ -8,7 +8,7 @@ void ScreenText::tick(float dt) {
// Remove all the immedate text // Remove all the immedate text
m_textQueues[static_cast<size_t>(ScreenTextType::Immediate)].clear(); m_textQueues[static_cast<size_t>(ScreenTextType::Immediate)].clear();
for (auto &textQueue : m_textQueues) { for (auto& textQueue : m_textQueues) {
for (unsigned int i = 0; i < textQueue.size();) { for (unsigned int i = 0; i < textQueue.size();) {
auto& big = textQueue[i]; auto& big = textQueue[i];
@ -168,3 +168,18 @@ ScreenTextEntry ScreenTextEntry::makeHelp(const GameStringKey& id,
return {str, {20.f, 20.f}, 2, 18, {0, 0, 0, 255}, {255, 255, 255}, 0, 5000, return {str, {20.f, 20.f}, 2, 18, {0, 0, 0, 255}, {255, 255, 255}, 0, 5000,
0, 35, id}; 0, 35, id};
} }
ScreenTextEntry ScreenTextEntry::makeHiddenPackageText(const GameStringKey& id,
const GameString& str) {
return {str,
{318.f, 138.f},
2,
33,
{2, 2, 0, 0},
{0x59, 0x73, 0x96},
1,
5000,
0,
600,
id};
}

View File

@ -22,8 +22,10 @@ enum class ScreenTextType {
Immediate = 3, Immediate = 3,
/// High priority cutscene text /// High priority cutscene text
HighPriority = 4, HighPriority = 4,
HiddenPackageText = 5,
/// ///
_Count = 5 _Count = 6
}; };
constexpr unsigned int ScreenTypeTextCount = constexpr unsigned int ScreenTypeTextCount =
static_cast<unsigned int>(ScreenTextType::_Count); static_cast<unsigned int>(ScreenTextType::_Count);
@ -67,6 +69,9 @@ struct ScreenTextEntry {
static ScreenTextEntry makeHelp(const GameStringKey& id, static ScreenTextEntry makeHelp(const GameStringKey& id,
const GameString& str); const GameString& str);
static ScreenTextEntry makeHiddenPackageText(const GameStringKey& id,
const GameString& str);
}; };
/** /**

View File

@ -12,6 +12,7 @@
#include <rw/defines.hpp> #include <rw/defines.hpp>
#include "ai/CharacterController.hpp" #include "ai/CharacterController.hpp"
#include "ai/PlayerController.hpp"
#include "engine/Animator.hpp" #include "engine/Animator.hpp"
#include "engine/GameData.hpp" #include "engine/GameData.hpp"
#include "engine/GameState.hpp" #include "engine/GameState.hpp"
@ -197,6 +198,13 @@ glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
} }
} }
if (controller) {
if (static_cast<PlayerController*>(controller)->isAdrenalineActive() &&
movementAnimation == animations->animation(AnimCycle::WalkStart)) {
animationSpeed *= 2;
}
}
// Check if we need to change the animation or change speed // Check if we need to change the animation or change speed
if (animator->getAnimation(AnimIndexMovement) != movementAnimation) { if (animator->getAnimation(AnimIndexMovement) != movementAnimation) {
animator->playAnimation(AnimIndexMovement, movementAnimation, animator->playAnimation(AnimIndexMovement, movementAnimation,

View File

@ -1,53 +0,0 @@
#include "objects/ItemPickup.hpp"
#include "data/WeaponData.hpp"
#include "objects/CharacterObject.hpp"
#include "objects/PickupObject.hpp"
ItemPickup::ItemPickup(GameWorld *world, const glm::vec3 &position,
BaseModelInfo *modelinfo, PickupType type,
WeaponData *item)
: PickupObject(world, position, modelinfo, type), item(item) {
}
bool ItemPickup::onCharacterTouch(CharacterObject *character) {
auto totalRounds = 0;
switch (item->modelID) {
case 173: /* Pistol */
totalRounds = 45;
break;
case 178: /* Uzi */
totalRounds = 125;
break;
case 176: /* Shotgun */
totalRounds = 25;
break;
case 170: /* Grenade */
totalRounds = 5;
break;
case 174: /* Molotov */
totalRounds = 5;
break;
case 181: /* Flame thrower */
totalRounds = 25;
break;
case 171: /* AK */
totalRounds = 150;
break;
case 180: /* M16 */
totalRounds = 300;
break;
case 177: /* Sniper Rifle */
totalRounds = 25;
break;
}
if (getPickupType() == OnStreet || getPickupType() == OnStreetSlow) {
totalRounds /= 5;
}
character->addToInventory(item->inventorySlot, totalRounds);
return true;
}

View File

@ -1,26 +0,0 @@
#ifndef _RWENGINE_ITEMPICKUP_HPP_
#define _RWENGINE_ITEMPICKUP_HPP_
#include <glm/glm.hpp>
#include <objects/PickupObject.hpp>
class BaseModelInfo;
class CharacterObject;
class GameWorld;
struct WeaponData;
/**
* @brief The ItemPickup class
* Inserts an item into a characters inventory on pickup.
*/
class ItemPickup : public PickupObject {
WeaponData* item;
public:
ItemPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type, WeaponData* item);
bool onCharacterTouch(CharacterObject* character) override;
};
#endif

View File

@ -2,13 +2,18 @@
#include <cmath> #include <cmath>
#include <btBulletDynamicsCommon.h>
#include <BulletCollision/CollisionDispatch/btGhostObject.h> #include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <btBulletDynamicsCommon.h>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
#include "ai/PlayerController.hpp"
#include "data/WeaponData.hpp"
#include "engine/GameData.hpp" #include "engine/GameData.hpp"
#include "engine/GameState.hpp"
#include "engine/GameWorld.hpp" #include "engine/GameWorld.hpp"
#include "engine/ScreenText.hpp"
#include "objects/CharacterObject.hpp" #include "objects/CharacterObject.hpp"
#include "objects/PickupObject.hpp"
uint32_t colours[14] = { uint32_t colours[14] = {
0xff0000, // bat, detonator, adrenaline 0xff0000, // bat, detonator, adrenaline
@ -21,10 +26,10 @@ uint32_t colours[14] = {
0x00ff80, // rocket 0x00ff80, // rocket
0x8000ff, // flame 0x8000ff, // flame
0x80ff00, // molotov 0x80ff00, // molotov
0xffffff, // grenade 0xffffff, // grenade. package1, floatpackge1
0x80ff80, // bodyarmour, bribe 0x80ff80, // bodyarmour, bribe
0x0000ff, // info, killfrenzy 0x0000ff, // info, killfrenzy
0xffff00 // health, bonus 0xffff00, // health, bonus
}; };
bool PickupObject::doesRespawn(PickupType type) { bool PickupObject::doesRespawn(PickupType type) {
@ -84,7 +89,7 @@ uint32_t PickupObject::behaviourFlags(PickupType type) {
PickupObject::PickupObject(GameWorld* world, const glm::vec3& position, PickupObject::PickupObject(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type) BaseModelInfo* modelinfo, PickupType type)
: GameObject(world, position, glm::quat{1.0f,0.0f,0.0f,0.0f}, modelinfo) : GameObject(world, position, glm::quat{1.0f, 0.0f, 0.0f, 0.0f}, modelinfo)
, m_ghost(nullptr) , m_ghost(nullptr)
, m_shape(nullptr) , m_shape(nullptr)
, m_enabled(false) , m_enabled(false)
@ -121,7 +126,8 @@ PickupObject::PickupObject(GameWorld* world, const glm::vec3& position,
m_colourId = 8; m_colourId = 8;
else if (modelinfo->name == "molotov") else if (modelinfo->name == "molotov")
m_colourId = 9; m_colourId = 9;
else if (modelinfo->name == "grenade") else if (modelinfo->name == "grenade" || modelinfo->name == "package1" ||
modelinfo->name == "floatpackge1")
m_colourId = 10; m_colourId = 10;
else if (modelinfo->name == "bodyarmour" || modelinfo->name == "bribe") else if (modelinfo->name == "bodyarmour" || modelinfo->name == "bribe")
m_colourId = 11; m_colourId = 11;
@ -134,7 +140,17 @@ PickupObject::PickupObject(GameWorld* world, const glm::vec3& position,
m_corona->particle.position = getPosition(); m_corona->particle.position = getPosition();
m_corona->particle.direction = glm::vec3(0.f, 0.f, 1.f); m_corona->particle.direction = glm::vec3(0.f, 0.f, 1.f);
m_corona->particle.orientation = VisualFX::ParticleData::Camera; m_corona->particle.orientation = VisualFX::ParticleData::Camera;
m_corona->particle.texture = engine->data->findSlotTexture("particle", "coronaringa");
// @todo float package should float on the water
if (m_type == FloatingPackage) {
// verify offset and texture?
m_corona->particle.position += glm::vec3(0.f, 0.f, 0.7f);
m_corona->particle.texture =
engine->data->findSlotTexture("particle", "coronastar");
} else {
m_corona->particle.texture =
engine->data->findSlotTexture("particle", "coronaringa");
}
auto flags = behaviourFlags(m_type); auto flags = behaviourFlags(m_type);
RW_UNUSED(flags); RW_UNUSED(flags);
@ -143,6 +159,7 @@ PickupObject::PickupObject(GameWorld* world, const glm::vec3& position,
"In Vehicle pickup not implemented yet"); "In Vehicle pickup not implemented yet");
setEnabled(true); setEnabled(true);
setCollected(false);
} }
PickupObject::~PickupObject() { PickupObject::~PickupObject() {
@ -156,27 +173,36 @@ PickupObject::~PickupObject() {
} }
void PickupObject::tick(float dt) { void PickupObject::tick(float dt) {
if (isRampage()) {
if (engine->state->scriptOnMissionFlag != nullptr) {
if (*(engine->state->scriptOnMissionFlag) != 0 && isEnabled()) {
setEnabled(false);
} else if (*(engine->state->scriptOnMissionFlag) == 0 &&
!isEnabled()) {
setEnabled(true);
}
}
}
if (!m_enabled) { if (!m_enabled) {
// Check if our type of pickup respawns // Check if our type of pickup respawns
if (doesRespawn(m_type)) { if (doesRespawn(m_type)) {
m_enableTimer -= dt; m_enableTimer -= dt;
if (m_enableTimer <= 0.f) { if (m_enableTimer <= 0.f) {
setEnabled(true); setEnabled(true);
m_collected = false; setCollected(false);
} }
} }
} }
float time = engine->getGameTime(); float time = engine->getGameTime();
float colourValue = 0.5f * (std::sin(time * 3.0664064f) * 0.3f + 0.3f); float colourValue = 0.5f * (std::sin(time * 3.0664064f) * 0.3f + 0.3f);
uint32_t *colour = &colours[m_colourId]; uint32_t* colour = &colours[m_colourId];
float red = (*colour >> 16) & 0xFF; float red = (*colour >> 16) & 0xFF;
float green = (*colour >> 8) & 0xFF; float green = (*colour >> 8) & 0xFF;
float blue = *colour & 0xFF; float blue = *colour & 0xFF;
m_corona->particle.colour = glm::vec4(red / 255.f, m_corona->particle.colour =
green / 255.f, glm::vec4(red / 255.f, green / 255.f, blue / 255.f, 1.f) * colourValue;
blue / 255.f,
1.f) * colourValue;
if (m_enabled) { if (m_enabled) {
// Sort out interactions with things that may or may not be players. // Sort out interactions with things that may or may not be players.
@ -201,8 +227,10 @@ void PickupObject::tick(float dt) {
object->type() == Character) { object->type() == Character) {
CharacterObject* character = CharacterObject* character =
static_cast<CharacterObject*>(object); static_cast<CharacterObject*>(object);
m_collected = onCharacterTouch(character);
setEnabled(!m_collected); if (character->isPlayer()) {
setCollected(onCharacterTouch(character));
setEnabled(!isCollected());
if (!m_enabled) { if (!m_enabled) {
m_enableTimer = respawnTime(m_type); m_enableTimer = respawnTime(m_type);
@ -211,6 +239,7 @@ void PickupObject::tick(float dt) {
} }
} }
} }
}
} }
void PickupObject::setEnabled(bool enabled) { void PickupObject::setEnabled(bool enabled) {
@ -225,3 +254,177 @@ void PickupObject::setEnabled(bool enabled) {
m_enabled = enabled; m_enabled = enabled;
} }
ItemPickup::ItemPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type,
WeaponData* item)
: PickupObject(world, position, modelinfo, type), item(item) {
}
bool ItemPickup::onCharacterTouch(CharacterObject* character) {
auto totalRounds = 0;
switch (item->modelID) {
case 173: /* Pistol */
totalRounds = 45;
break;
case 178: /* Uzi */
totalRounds = 125;
break;
case 176: /* Shotgun */
totalRounds = 25;
break;
case 170: /* Grenade */
totalRounds = 5;
break;
case 174: /* Molotov */
totalRounds = 5;
break;
case 181: /* Flame thrower */
totalRounds = 25;
break;
case 171: /* AK */
totalRounds = 150;
break;
case 180: /* M16 */
totalRounds = 300;
break;
case 177: /* Sniper Rifle */
totalRounds = 25;
break;
}
if (getPickupType() == OnStreet || getPickupType() == OnStreetSlow) {
totalRounds /= 5;
}
character->addToInventory(item->inventorySlot, totalRounds);
return true;
}
DummyPickup::DummyPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type)
: PickupObject(world, position, modelinfo, type) {
}
bool DummyPickup::onCharacterTouch(CharacterObject* character) {
RW_UNUSED(character);
return true;
}
RampagePickup::RampagePickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type)
: PickupObject(world, position, modelinfo, type) {
}
bool RampagePickup::onCharacterTouch(CharacterObject* character) {
RW_UNUSED(character);
if (engine->state->scriptOnMissionFlag == nullptr) {
return false;
}
if (*(engine->state->scriptOnMissionFlag) != 0) {
return false;
}
return true;
}
HealthPickup::HealthPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type)
: PickupObject(world, position, modelinfo, type) {
}
bool HealthPickup::onCharacterTouch(CharacterObject* character) {
if (character->getCurrentState().health >= 100.f) {
return false;
}
character->getCurrentState().health = 100.f;
return true;
}
ArmourPickup::ArmourPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type)
: PickupObject(world, position, modelinfo, type) {
}
bool ArmourPickup::onCharacterTouch(CharacterObject* character) {
if (character->getCurrentState().armour >= 100.f) {
return false;
}
character->getCurrentState().armour = 100.f;
return true;
}
CollectablePickup::CollectablePickup(GameWorld* world,
const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type)
: PickupObject(world, position, modelinfo, type) {
}
bool CollectablePickup::onCharacterTouch(CharacterObject* character) {
RW_UNUSED(character);
GameState* state = engine->state;
if (state->playerInfo.hiddenPackagesCollected ==
state->playerInfo.hiddenPackageCount) {
state->playerInfo.money += 1000000;
const auto gxtEntry = "CO_ALL";
state->text.addText<ScreenTextType::HiddenPackageText>(
ScreenTextEntry::makeHiddenPackageText(
gxtEntry, engine->data->texts.text(gxtEntry)));
} else {
state->playerInfo.hiddenPackagesCollected++;
state->playerInfo.money += 1000;
const auto gxtEntry = "CO_ONE";
auto text = ScreenText::format(
engine->data->texts.text(gxtEntry),
GameStringUtil::fromString(
std::to_string(state->playerInfo.hiddenPackagesCollected)),
GameStringUtil::fromString(
std::to_string(state->playerInfo.hiddenPackageCount)));
state->text.addText<ScreenTextType::HiddenPackageText>(
ScreenTextEntry::makeHiddenPackageText(gxtEntry, text));
}
return true;
}
AdrenalinePickup::AdrenalinePickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type)
: PickupObject(world, position, modelinfo, type) {
}
bool AdrenalinePickup::onCharacterTouch(CharacterObject* character) {
static_cast<PlayerController*>(character->controller)
->activateAdrenalineEffect();
return true;
}
MoneyPickup::MoneyPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type,
uint32_t money)
: PickupObject(world, position, modelinfo, type), money(money) {
}
bool MoneyPickup::onCharacterTouch(CharacterObject* character) {
RW_UNUSED(character);
engine->state->playerInfo.money += money;
return true;
}

View File

@ -44,8 +44,8 @@ public:
static float respawnTime(PickupType type); static float respawnTime(PickupType type);
static uint32_t behaviourFlags(PickupType type); static uint32_t behaviourFlags(PickupType type);
PickupObject(GameWorld* world, const glm::vec3& position, BaseModelInfo *modelinfo, PickupObject(GameWorld* world, const glm::vec3& position,
PickupType type); BaseModelInfo* modelinfo, PickupType type);
~PickupObject() override; ~PickupObject() override;
@ -69,10 +69,18 @@ public:
return m_collected; return m_collected;
} }
void setCollected(bool collected) {
m_collected = collected;
}
PickupType getPickupType() const { PickupType getPickupType() const {
return m_type; return m_type;
} }
virtual bool isRampage() const {
return false;
}
private: private:
btPairCachingGhostObject* m_ghost; btPairCachingGhostObject* m_ghost;
btSphereShape* m_shape; btSphereShape* m_shape;
@ -85,4 +93,108 @@ private:
PickupType m_type; PickupType m_type;
}; };
/**
* @brief The ItemPickup class
* Inserts an item into a characters inventory on pickup.
*/
struct WeaponData;
class ItemPickup : public PickupObject {
WeaponData* item;
public:
ItemPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type, WeaponData* item);
bool onCharacterTouch(CharacterObject* character) override;
};
/**
* @brief The DummyPickup class
*/
class DummyPickup : public PickupObject {
public:
DummyPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type);
bool onCharacterTouch(CharacterObject* character) override;
};
/**
* @brief The RampagePickup class
*/
class RampagePickup : public PickupObject {
public:
RampagePickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type);
bool isRampage() const override {
return true;
}
bool onCharacterTouch(CharacterObject* character) override;
};
/**
* @brief The HealthPickup class
*/
class HealthPickup : public PickupObject {
public:
HealthPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type);
bool onCharacterTouch(CharacterObject* character) override;
};
/**
* @brief The ArmourPickup class
*/
class ArmourPickup : public PickupObject {
public:
ArmourPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type);
bool onCharacterTouch(CharacterObject* character) override;
};
/**
* @brief The CollectablePickup class
*/
class CollectablePickup : public PickupObject {
public:
CollectablePickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type);
bool onCharacterTouch(CharacterObject* character) override;
};
/**
* @brief The AdrenalinePickup class
*/
class AdrenalinePickup : public PickupObject {
public:
AdrenalinePickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type);
bool onCharacterTouch(CharacterObject* character) override;
};
/**
* @brief The MoneyPickup class
*/
class MoneyPickup : public PickupObject {
uint32_t money;
public:
MoneyPickup(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type, uint32_t money);
void setMoney(uint32_t m) {
money = m;
};
bool onCharacterTouch(CharacterObject* character) override;
};
#endif #endif

View File

@ -6021,10 +6021,12 @@ void opcode_0213(const ScriptArguments& args, const ScriptModel model, const Scr
bool opcode_0214(const ScriptArguments& args, const ScriptPickup pickup) { bool opcode_0214(const ScriptArguments& args, const ScriptPickup pickup) {
RW_UNUSED(args); RW_UNUSED(args);
RW_CHECK(pickup != nullptr, "Pickup is null"); RW_CHECK(pickup != nullptr, "Pickup is null");
if (! pickup) { if (!pickup) {
return false; return false;
} }
return pickup->isCollected(); bool collected = pickup->isCollected();
pickup->setCollected(false);
return collected;
} }
/** /**
@ -7802,17 +7804,14 @@ bool opcode_02e0(const ScriptArguments& args, const ScriptCharacter character) {
@arg arg1 @arg arg1
@arg arg2 @arg arg2
@arg arg3 @arg arg3
@arg arg4 @arg money
@arg pickup @arg pickup
*/ */
void opcode_02e1(const ScriptArguments& args, const ScriptFloat arg1, const ScriptFloat arg2, const ScriptFloat arg3, const ScriptInt arg4, ScriptPickup& pickup) { void opcode_02e1(const ScriptArguments& args, ScriptVec3 coord, const ScriptInt money, ScriptPickup& pickup) {
RW_UNIMPLEMENTED_OPCODE(0x02e1); coord = script::getGround(args, coord);
RW_UNUSED(arg1); PickupObject* pickupObj = args.getWorld()->createPickup(coord, args.getWorld()->data->findModelObject("Money"), PickupObject::PickupType::Money);
RW_UNUSED(arg2); static_cast<MoneyPickup*>(pickupObj)->setMoney(money);
RW_UNUSED(arg3); pickup = pickupObj;
RW_UNUSED(arg4);
RW_UNUSED(pickup);
RW_UNUSED(args);
} }
/** /**
@ -7960,9 +7959,8 @@ void opcode_02eb(const ScriptArguments& args) {
@arg coord Coordinates @arg coord Coordinates
*/ */
void opcode_02ec(const ScriptArguments& args, ScriptVec3 coord) { void opcode_02ec(const ScriptArguments& args, ScriptVec3 coord) {
RW_UNIMPLEMENTED_OPCODE(0x02ec); coord = script::getGround(args, coord);
RW_UNUSED(coord); args.getWorld()->createPickup(coord, args.getWorld()->data->findModelObject("package1"), PickupObject::PickupType::Collectable);
RW_UNUSED(args);
} }
/** /**
@ -9514,13 +9512,9 @@ void opcode_035a(const ScriptArguments& args, ScriptFloat& arg1, ScriptFloat& ar
@arg arg3 @arg arg3
@arg pickup @arg pickup
*/ */
void opcode_035b(const ScriptArguments& args, const ScriptFloat arg1, const ScriptFloat arg2, const ScriptFloat arg3, ScriptPickup& pickup) { void opcode_035b(const ScriptArguments& args, ScriptVec3 coord, ScriptPickup& pickup) {
RW_UNIMPLEMENTED_OPCODE(0x035b); coord = script::getGround(args, coord);
RW_UNUSED(arg1); pickup = args.getWorld()->createPickup(coord, args.getWorld()->data->findModelObject("floatpackge1"), PickupObject::PickupType::FloatingPackage);
RW_UNUSED(arg2);
RW_UNUSED(arg3);
RW_UNUSED(pickup);
RW_UNUSED(args);
} }
/** /**

View File

@ -5,21 +5,21 @@
#include "RWGame.hpp" #include "RWGame.hpp"
#include <ai/PlayerController.hpp> #include <ai/PlayerController.hpp>
#include <data/CutsceneData.hpp>
#include <data/Clump.hpp> #include <data/Clump.hpp>
#include <data/CutsceneData.hpp>
#include <data/WeaponData.hpp> #include <data/WeaponData.hpp>
#include <dynamics/CollisionInstance.hpp> #include <dynamics/CollisionInstance.hpp>
#include <dynamics/RaycastCallbacks.hpp> #include <dynamics/RaycastCallbacks.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/ItemPickup.hpp> #include <objects/PickupObject.hpp>
#include <objects/VehicleObject.hpp> #include <objects/VehicleObject.hpp>
#include <script/ScriptMachine.hpp> #include <script/ScriptMachine.hpp>
#include <glm/gtc/constants.hpp> #include <glm/gtc/constants.hpp>
#include <glm/gtx/norm.hpp>
#include <glm/gtx/matrix_major_storage.hpp> #include <glm/gtx/matrix_major_storage.hpp>
#include <glm/gtx/norm.hpp>
#include <BulletCollision/CollisionDispatch/btGhostObject.h> #include <BulletCollision/CollisionDispatch/btGhostObject.h>
@ -55,6 +55,44 @@ void IngameState::startTest() {
itemspawn.x += 2.5f; itemspawn.x += 2.5f;
} }
PickupObject* moneyObj =
getWorld()->createPickup(glm::vec3(276.5f, -604.f, 36.5f),
getWorld()->data->findModelObject("Money"),
PickupObject::PickupType::Money);
static_cast<MoneyPickup*>(moneyObj)->setMoney(100000);
getWorld()->createPickup(glm::vec3(279.f, -604.f, 36.5f),
getWorld()->data->findModelObject("package1"),
PickupObject::PickupType::Collectable);
getWorld()->createPickup(glm::vec3(281.5f, -604.f, 36.5f),
getWorld()->data->findModelObject("health"),
PickupObject::PickupType::OnStreetSlow);
getWorld()->createPickup(glm::vec3(284.f, -604.f, 36.5f),
getWorld()->data->findModelObject("bodyarmour"),
PickupObject::PickupType::OnStreetSlow);
getWorld()->createPickup(glm::vec3(286.5f, -604.f, 36.5f),
getWorld()->data->findModelObject("adrenaline"),
PickupObject::PickupType::OnStreetSlow);
getWorld()->createPickup(glm::vec3(289.f, -604.f, 36.5f),
getWorld()->data->findModelObject("killfrenzy"),
PickupObject::PickupType::Once);
getWorld()->createPickup(glm::vec3(291.5f, -604.f, 36.5f),
getWorld()->data->findModelObject("info"),
PickupObject::PickupType::Once);
getWorld()->createPickup(glm::vec3(294.f, -604.f, 36.5f),
getWorld()->data->findModelObject("briefcase"),
PickupObject::PickupType::Once);
getWorld()->createPickup(glm::vec3(296.5f, -604.f, 36.5f),
getWorld()->data->findModelObject("floatpackge1"),
PickupObject::PickupType::FloatingPackage);
auto carPos = glm::vec3(286.f, -591.f, 37.f); auto carPos = glm::vec3(286.f, -591.f, 37.f);
auto carRot = glm::angleAxis(glm::radians(90.f), glm::vec3(0.f, 0.f, 1.f)); auto carRot = glm::angleAxis(glm::radians(90.f), glm::vec3(0.f, 0.f, 1.f));
// Landstalker, Stinger, Linerunner, Trash, Bobcat // Landstalker, Stinger, Linerunner, Trash, Bobcat
@ -69,7 +107,7 @@ void IngameState::startGame() {
game->startScript("data/main.scm"); game->startScript("data/main.scm");
game->getScriptVM()->startThread(0); game->getScriptVM()->startThread(0);
getWorld()->sound.playBackground(getWorld()->data->getDataPath().string() + getWorld()->sound.playBackground(getWorld()->data->getDataPath().string() +
"/audio/City.wav"); //FIXME: use path "/audio/City.wav"); // FIXME: use path
} }
void IngameState::enter() { void IngameState::enter() {

View File

@ -1,7 +1,6 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <data/WeaponData.hpp> #include <data/WeaponData.hpp>
#include <objects/CharacterObject.hpp> #include <objects/CharacterObject.hpp>
#include <objects/ItemPickup.hpp>
#include <objects/PickupObject.hpp> #include <objects/PickupObject.hpp>
#include "test_Globals.hpp" #include "test_Globals.hpp"
#if RW_TEST_WITH_DATA #if RW_TEST_WITH_DATA
@ -11,7 +10,8 @@ public:
bool picked_up = false; bool picked_up = false;
TestPickup(GameWorld* engine, const glm::vec3& position) TestPickup(GameWorld* engine, const glm::vec3& position)
: PickupObject(engine, position, Global::get().d->modelinfo[0].get(), OnStreet) { : PickupObject(engine, position, Global::get().d->modelinfo[0].get(),
OnStreet) {
} }
bool onCharacterTouch(CharacterObject*) { bool onCharacterTouch(CharacterObject*) {