diff --git a/rwengine/src/ai/CharacterController.cpp b/rwengine/src/ai/CharacterController.cpp index f6d413d7..bdeab1ec 100644 --- a/rwengine/src/ai/CharacterController.cpp +++ b/rwengine/src/ai/CharacterController.cpp @@ -674,7 +674,7 @@ bool Activities::UseItem::update(CharacterObject *character, }; auto world = character->engine; - const auto &weapon = world->data->weaponData.at(itemslot); + auto weapon = &world->data->weaponData.at(itemslot); auto &state = character->getCurrentState().weapons[itemslot]; auto &animator = character->animator; auto shootcycle = find_cycle(weapon->animation1); @@ -712,7 +712,7 @@ bool Activities::UseItem::update(CharacterObject *character, if (currenttime >= firetime && !fired) { state.bulletsClip--; - Weapon::fireHitscan(weapon.get(), character); + Weapon::fireHitscan(weapon, character); fired = true; } if (currenttime > loopend) { @@ -739,7 +739,7 @@ bool Activities::UseItem::update(CharacterObject *character, if (currID >= firetime && !fired) { state.bulletsClip--; - Weapon::fireProjectile(weapon.get(), character, power); + Weapon::fireProjectile(weapon, character, power); fired = true; } if (animator->isCompleted(AnimIndexAction)) { diff --git a/rwengine/src/engine/GameData.hpp b/rwengine/src/engine/GameData.hpp index 3017ada0..5f14a64b 100644 --- a/rwengine/src/engine/GameData.hpp +++ b/rwengine/src/engine/GameData.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -315,7 +316,7 @@ public: */ std::map> dynamicObjectData; - std::vector> weaponData; + std::vector weaponData; /** * Pedstrian type stats diff --git a/rwengine/src/engine/GameWorld.cpp b/rwengine/src/engine/GameWorld.cpp index 5e56472b..06b9615c 100644 --- a/rwengine/src/engine/GameWorld.cpp +++ b/rwengine/src/engine/GameWorld.cpp @@ -386,11 +386,11 @@ PickupObject* GameWorld::createPickup(const glm::vec3& pos, int id, int type) { auto it = std::find_if( data->weaponData.begin(), data->weaponData.end(), - [=](const std::shared_ptr& x) { return x->modelID == id; }); + [=](const auto& x) { return x.modelID == id; }); // If nothing, create a generic pickup instead of an item pickup if (it != data->weaponData.end()) { - pickup = std::make_unique(this, pos, modelInfo, pickuptype, it->get()); + pickup = std::make_unique(this, pos, modelInfo, pickuptype, *it); } else if (modelInfo->name == "info" || modelInfo->name == "briefcase" || modelInfo->name == "floatpackge1") { pickup = std::make_unique(this, pos, modelInfo, pickuptype); diff --git a/rwengine/src/items/Weapon.hpp b/rwengine/src/items/Weapon.hpp index c3da0f77..72e4ac46 100644 --- a/rwengine/src/items/Weapon.hpp +++ b/rwengine/src/items/Weapon.hpp @@ -5,8 +5,8 @@ class CharacterObject; struct WeaponData; namespace Weapon { -void fireProjectile(WeaponData* wepon, CharacterObject* character, float force); -void fireHitscan(WeaponData* wepon, CharacterObject* character); +void fireProjectile(WeaponData* weapon, CharacterObject* character, float force); +void fireHitscan(WeaponData *weapon, CharacterObject* character); } #endif diff --git a/rwengine/src/loaders/GenericDATLoader.cpp b/rwengine/src/loaders/GenericDATLoader.cpp index e769806a..520dc48b 100644 --- a/rwengine/src/loaders/GenericDATLoader.cpp +++ b/rwengine/src/loaders/GenericDATLoader.cpp @@ -62,7 +62,7 @@ void GenericDATLoader::loadDynamicObjects(const std::string& name, } void GenericDATLoader::loadWeapons(const std::string& name, - WeaponDataPtrs& weaponData) { + std::vector& weaponData) { std::ifstream dfile(name.c_str()); if (dfile.is_open()) { @@ -73,59 +73,59 @@ void GenericDATLoader::loadWeapons(const std::string& name, if (linebuffer[0] == '#') continue; std::stringstream ss(linebuffer); - auto data = std::make_shared(); - ss >> data->name; - if (data->name == "ENDWEAPONDATA") continue; + WeaponData data{}; + ss >> data.name; + if (data.name == "ENDWEAPONDATA") continue; // Skip lines with blank names (probably an empty line). - if (std::find_if(data->name.begin(), data->name.end(), ::isalnum) == - std::end(data->name)) { + if (std::find_if(data.name.begin(), data.name.end(), ::isalnum) == + std::end(data.name)) { continue; } - std::transform(data->name.begin(), data->name.end(), - data->name.begin(), ::tolower); + std::transform(data.name.begin(), data.name.end(), + data.name.begin(), ::tolower); std::string firetype; ss >> firetype; if (firetype == "MELEE") { - data->fireType = WeaponData::MELEE; + data.fireType = WeaponData::MELEE; } else if (firetype == "INSTANT_HIT") { - data->fireType = WeaponData::INSTANT_HIT; + data.fireType = WeaponData::INSTANT_HIT; } else if (firetype == "PROJECTILE") { - data->fireType = WeaponData::PROJECTILE; + data.fireType = WeaponData::PROJECTILE; } - ss >> data->hitRange; - ss >> data->fireRate; - ss >> data->reloadMS; - ss >> data->clipSize; - ss >> data->damage; - ss >> data->speed; - ss >> data->meleeRadius; - ss >> data->lifeSpan; - ss >> data->spread; - ss >> data->fireOffset.x; - ss >> data->fireOffset.y; - ss >> data->fireOffset.z; - ss >> data->animation1; - std::transform(data->animation1.begin(), data->animation1.end(), - data->animation1.begin(), ::tolower); - ss >> data->animation2; - std::transform(data->animation2.begin(), data->animation2.end(), - data->animation2.begin(), ::tolower); - ss >> data->animLoopStart; - ss >> data->animLoopEnd; - ss >> data->animFirePoint; - ss >> data->animCrouchFirePoint; - ss >> data->modelID; - ss >> data->flags; + ss >> data.hitRange; + ss >> data.fireRate; + ss >> data.reloadMS; + ss >> data.clipSize; + ss >> data.damage; + ss >> data.speed; + ss >> data.meleeRadius; + ss >> data.lifeSpan; + ss >> data.spread; + ss >> data.fireOffset.x; + ss >> data.fireOffset.y; + ss >> data.fireOffset.z; + ss >> data.animation1; + std::transform(data.animation1.begin(), data.animation1.end(), + data.animation1.begin(), ::tolower); + ss >> data.animation2; + std::transform(data.animation2.begin(), data.animation2.end(), + data.animation2.begin(), ::tolower); + ss >> data.animLoopStart; + ss >> data.animLoopEnd; + ss >> data.animFirePoint; + ss >> data.animCrouchFirePoint; + ss >> data.modelID; + ss >> data.flags; RW_CHECK(ss.eof() || ss.good(), "Loading weapon data file " << name << " failed"); - data->inventorySlot = slotNum++; + data.inventorySlot = slotNum++; - weaponData.push_back(data); + weaponData.push_back(std::move(data)); } } } diff --git a/rwengine/src/loaders/GenericDATLoader.hpp b/rwengine/src/loaders/GenericDATLoader.hpp index 6724e382..e14ab8d8 100644 --- a/rwengine/src/loaders/GenericDATLoader.hpp +++ b/rwengine/src/loaders/GenericDATLoader.hpp @@ -11,9 +11,6 @@ typedef std::shared_ptr DynamicObjectDataPtr; typedef std::map DynamicObjectDataPtrs; struct WeaponData; -typedef std::shared_ptr WeaponDataPtr; -typedef std::vector WeaponDataPtrs; - struct VehicleInfo; typedef std::shared_ptr VehicleInfoPtr; typedef std::map VehicleInfoPtrs; @@ -23,7 +20,8 @@ public: void loadDynamicObjects(const std::string& name, DynamicObjectDataPtrs& data); - void loadWeapons(const std::string& name, WeaponDataPtrs& weaponData); + void loadWeapons(const std::string& name, + std::vector& weaponData); void loadHandling(const std::string& name, VehicleInfoPtrs& vehicleData); }; diff --git a/rwengine/src/objects/PickupObject.cpp b/rwengine/src/objects/PickupObject.cpp index e3638a5f..bb494f85 100644 --- a/rwengine/src/objects/PickupObject.cpp +++ b/rwengine/src/objects/PickupObject.cpp @@ -273,14 +273,14 @@ void PickupObject::setEnabled(bool enabled) { ItemPickup::ItemPickup(GameWorld* world, const glm::vec3& position, BaseModelInfo* modelinfo, PickupType type, - WeaponData* item) - : PickupObject(world, position, modelinfo, type), item(item) { + const WeaponData& p_item) + : PickupObject(world, position, modelinfo, type), item(p_item) { } bool ItemPickup::onPlayerTouch() { auto totalRounds = 0; - switch (item->modelID) { + switch (item.modelID) { case 173: /* Pistol */ totalRounds = 45; break; @@ -316,7 +316,7 @@ bool ItemPickup::onPlayerTouch() { auto character = engine->getPlayer()->getCharacter(); - character->addToInventory(item->inventorySlot, totalRounds); + character->addToInventory(item.inventorySlot, totalRounds); return true; } diff --git a/rwengine/src/objects/PickupObject.hpp b/rwengine/src/objects/PickupObject.hpp index 68f4c4f1..f8e57b69 100644 --- a/rwengine/src/objects/PickupObject.hpp +++ b/rwengine/src/objects/PickupObject.hpp @@ -138,11 +138,11 @@ private: struct WeaponData; class ItemPickup : public PickupObject { - WeaponData* item; + const WeaponData& item; public: ItemPickup(GameWorld* world, const glm::vec3& position, - BaseModelInfo* modelinfo, PickupType type, WeaponData* item); + BaseModelInfo* modelinfo, PickupType type, const WeaponData& p_item); bool onPlayerTouch() override; }; diff --git a/rwengine/src/objects/ProjectileObject.hpp b/rwengine/src/objects/ProjectileObject.hpp index cd9a52ce..261ad745 100644 --- a/rwengine/src/objects/ProjectileObject.hpp +++ b/rwengine/src/objects/ProjectileObject.hpp @@ -25,13 +25,13 @@ public: }; struct ProjectileInfo { - ProjectileInfo(ProjectileType p_type, glm::vec3 p_direction, - float p_velocity, float p_time, WeaponData* p_weapon) - : type(p_type) - , direction(p_direction) - , velocity(p_velocity) - , time(p_time) - , weapon(p_weapon) { + ProjectileInfo(ProjectileType type, glm::vec3 direction, + float velocity, float time, WeaponData* weapon) + : type(type) + , direction(direction) + , velocity(velocity) + , time(time) + , weapon(weapon) { } ProjectileType type; glm::vec3 direction{}; diff --git a/rwengine/src/render/ObjectRenderer.cpp b/rwengine/src/render/ObjectRenderer.cpp index f1405559..11750ea1 100644 --- a/rwengine/src/render/ObjectRenderer.cpp +++ b/rwengine/src/render/ObjectRenderer.cpp @@ -236,15 +236,15 @@ void ObjectRenderer::renderCharacter(CharacterObject* pedestrian, auto item = pedestrian->getActiveItem(); const auto& weapon = pedestrian->engine->data->weaponData[item]; - if (weapon->modelID == -1) { + if (weapon.modelID == -1) { return; // No model for this item } auto handFrame = pedestrian->getClump()->findFrame("srhand"); if (handFrame) { auto simple = - m_world->data->findModelInfo(weapon->modelID); - RW_CHECK(simple, "Failed to read modelinfo using " << weapon->modelID); + m_world->data->findModelInfo(weapon.modelID); + RW_CHECK(simple, "Failed to read modelinfo using " << weapon.modelID); auto itematomic = simple->getAtomic(0); renderAtomic(itematomic, handFrame->getWorldTransform(), nullptr, outList); diff --git a/rwgame/HUDDrawer.cpp b/rwgame/HUDDrawer.cpp index 8bd75915..961a5fdb 100644 --- a/rwgame/HUDDrawer.cpp +++ b/rwgame/HUDDrawer.cpp @@ -183,11 +183,11 @@ void HUDDrawer::drawPlayerInfo(PlayerController* player, GameWorld* world, #endif auto item = player->getCharacter()->getActiveItem(); - auto weapon = world->data->weaponData[item]; + const auto& weapon = world->data->weaponData[item]; std::string itemTextureName = "fist"; - if (weapon && weapon->modelID > 0) { + if (weapon.modelID > 0) { auto model = - world->data->findModelInfo(weapon->modelID); + world->data->findModelInfo(weapon.modelID); if (model != nullptr) { itemTextureName = model->name; } @@ -209,13 +209,13 @@ void HUDDrawer::drawPlayerInfo(PlayerController* player, GameWorld* world, glm::vec4(iconX, iconY, hudParameters.uiWeaponSize, hudParameters.uiWeaponSize)); } - if (weapon->fireType != WeaponData::MELEE) { + if (weapon.fireType != WeaponData::MELEE) { const CharacterState& cs = player->getCharacter()->getCurrentState(); const CharacterWeaponSlot& slotInfo = cs.weapons[cs.currentWeapon]; // In weapon.dat clip size of 0 or 1000+ indicates no reload // Clip size of 1 is being visually omitted as well - bool noClip = weapon->clipSize < 2 || weapon->clipSize > 999; + bool noClip = weapon.clipSize < 2 || weapon.clipSize > 999; uint32_t displayBulletsTotal = slotInfo.bulletsTotal; diff --git a/rwgame/states/DebugState.cpp b/rwgame/states/DebugState.cpp index c3939eaa..a1a26bc9 100644 --- a/rwgame/states/DebugState.cpp +++ b/rwgame/states/DebugState.cpp @@ -218,7 +218,7 @@ std::shared_ptr DebugState::createWeaponMenu() { kDebugFont, kDebugEntryHeight); for (int i = 1; i < kMaxInventorySlots; ++i) { - auto& name = getWorld()->data->weaponData[i]->name; + auto& name = getWorld()->data->weaponData[i].name; menu->lambda(name, [=] { giveItem(i); }); } diff --git a/rwgame/states/IngameState.cpp b/rwgame/states/IngameState.cpp index 08f81611..4b9b486d 100644 --- a/rwgame/states/IngameState.cpp +++ b/rwgame/states/IngameState.cpp @@ -53,7 +53,7 @@ void IngameState::startTest() { glm::vec3 itemspawn(276.5f, -609.f, 36.5f); for (unsigned int i = 1; i < getWorld()->data->weaponData.size(); ++i) { auto& item = getWorld()->data->weaponData[i]; - getWorld()->createPickup(itemspawn, item->modelID, + getWorld()->createPickup(itemspawn, item.modelID, PickupObject::OnStreet); itemspawn.x += 2.5f; } diff --git a/tests/test_Data.cpp b/tests/test_Data.cpp index 1fbe9b9c..24eb500b 100644 --- a/tests/test_Data.cpp +++ b/tests/test_Data.cpp @@ -13,33 +13,33 @@ BOOST_AUTO_TEST_SUITE(DataTests) #if RW_TEST_WITH_DATA BOOST_AUTO_TEST_CASE(test_weapon_dat) { GenericDATLoader l; - WeaponDataPtrs weaponData; + std::vector weaponData; l.loadWeapons(Global::get().getGamePath() + "/data/weapon.dat", weaponData); BOOST_ASSERT(weaponData.size() > 0); - WeaponDataPtr data = weaponData[0]; + const auto& data = weaponData.front(); - BOOST_CHECK(data->fireType == WeaponData::MELEE); - BOOST_CHECK(data->hitRange == 2.8f); - BOOST_CHECK(data->fireRate == 750); - BOOST_CHECK(data->reloadMS == 300); - BOOST_CHECK(data->clipSize == 1000); - BOOST_CHECK(data->damage == 8); - BOOST_CHECK(data->speed == -1.f); - BOOST_CHECK(data->meleeRadius == 0.5f); - BOOST_CHECK(data->lifeSpan == -1.0f); - BOOST_CHECK(data->spread == -1.0f); - BOOST_CHECK(data->fireOffset == glm::vec3(0.1f, 0.65f, 0.2f)); - BOOST_CHECK(data->animation1 == "fightppunch"); - BOOST_CHECK(data->animation2 == "kick_floor"); - BOOST_CHECK(data->animLoopStart == 0); - BOOST_CHECK(data->animLoopEnd == 99); - BOOST_CHECK(data->animFirePoint == 12); - BOOST_CHECK(data->animCrouchFirePoint == 12); - BOOST_CHECK(data->modelID == -1); - BOOST_CHECK(data->flags == 0); + BOOST_CHECK(data.fireType == WeaponData::MELEE); + BOOST_CHECK(data.hitRange == 2.8f); + BOOST_CHECK(data.fireRate == 750); + BOOST_CHECK(data.reloadMS == 300); + BOOST_CHECK(data.clipSize == 1000); + BOOST_CHECK(data.damage == 8); + BOOST_CHECK(data.speed == -1.f); + BOOST_CHECK(data.meleeRadius == 0.5f); + BOOST_CHECK(data.lifeSpan == -1.0f); + BOOST_CHECK(data.spread == -1.0f); + BOOST_CHECK(data.fireOffset == glm::vec3(0.1f, 0.65f, 0.2f)); + BOOST_CHECK(data.animation1 == "fightppunch"); + BOOST_CHECK(data.animation2 == "kick_floor"); + BOOST_CHECK(data.animLoopStart == 0); + BOOST_CHECK(data.animLoopEnd == 99); + BOOST_CHECK(data.animFirePoint == 12); + BOOST_CHECK(data.animCrouchFirePoint == 12); + BOOST_CHECK(data.modelID == -1); + BOOST_CHECK(data.flags == 0); } BOOST_AUTO_TEST_CASE(test_dynamic_dat_loader) { diff --git a/tests/test_Pickup.cpp b/tests/test_Pickup.cpp index 7109e50b..90e04ae3 100644 --- a/tests/test_Pickup.cpp +++ b/tests/test_Pickup.cpp @@ -68,8 +68,8 @@ BOOST_AUTO_TEST_CASE(test_item_pickup) { BOOST_REQUIRE(character != nullptr); Global::get().e->state->playerObject = objectID; - auto pistol = Global::get().d->weaponData[1].get(); - auto model = Global::get().d->modelinfo[pistol->modelID].get(); + const auto& pistol = Global::get().d->weaponData.at(1); + auto model = Global::get().d->modelinfo.at(pistol.modelID).get(); ItemPickup* p = new ItemPickup(Global::get().e, {30.f, 0.f, 0.f}, model, PickupObject::OnStreet, pistol); @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(test_item_pickup) { auto& inventory = character->getCurrentState().weapons; BOOST_CHECK(std::any_of(std::begin(inventory), std::end(inventory), [&](const CharacterWeaponSlot& i) { - return i.weaponId == pistol->inventorySlot; + return i.weaponId == pistol.inventorySlot; })); Global::get().e->destroyObject(p); diff --git a/tests/test_Weapon.cpp b/tests/test_Weapon.cpp index 3cf6f958..ccacda4d 100644 --- a/tests/test_Weapon.cpp +++ b/tests/test_Weapon.cpp @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(TestProjectile) { auto character = Global::get().e->createPedestrian(1, {25.f, 0.f, 0.f}); BOOST_REQUIRE(character != nullptr); - auto wepdata = Global::get().e->data->weaponData[5].get(); + auto wepdata = &Global::get().e->data->weaponData.at(5); auto projectile = new ProjectileObject( Global::get().e, {26.f, 1.f, 10.f}, @@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE(TestProjectile) { auto character = Global::get().e->createPedestrian(1, {25.f, 0.f, 0.f}); BOOST_REQUIRE(character != nullptr); - auto wepdata = Global::get().e->data->weaponData[6].get(); + auto wepdata = &Global::get().e->data->weaponData.at(6); auto projectile = new ProjectileObject( Global::get().e, {26.f, 1.f, 10.f}, @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(TestProjectile) { auto character = Global::get().e->createPedestrian(1, {25.f, 0.f, 0.f}); BOOST_REQUIRE(character != nullptr); - auto wepdata = Global::get().e->data->weaponData[7].get(); + auto wepdata = &Global::get().e->data->weaponData.at(7); auto projectile = new ProjectileObject( Global::get().e, {26.f, 1.f, 10.f},