mirror of
https://github.com/rwengine/openrw.git
synced 2024-10-06 09:07:19 +02:00
Avoid dynamic allocations of WeaponData
This commit is contained in:
parent
2c0356d8b7
commit
dce5257eb3
@ -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)) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <data/AnimGroup.hpp>
|
||||
#include <data/ModelData.hpp>
|
||||
#include <data/PedData.hpp>
|
||||
#include <data/WeaponData.hpp>
|
||||
#include <data/Weather.hpp>
|
||||
#include <data/ZoneData.hpp>
|
||||
#include <fonts/GameTexts.hpp>
|
||||
@ -315,7 +316,7 @@ public:
|
||||
*/
|
||||
std::map<std::string, std::shared_ptr<DynamicObjectData>> dynamicObjectData;
|
||||
|
||||
std::vector<std::shared_ptr<WeaponData>> weaponData;
|
||||
std::vector<WeaponData> weaponData;
|
||||
|
||||
/**
|
||||
* Pedstrian type stats
|
||||
|
@ -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<WeaponData>& 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<ItemPickup>(this, pos, modelInfo, pickuptype, it->get());
|
||||
pickup = std::make_unique<ItemPickup>(this, pos, modelInfo, pickuptype, *it);
|
||||
} else if (modelInfo->name == "info" || modelInfo->name == "briefcase" ||
|
||||
modelInfo->name == "floatpackge1") {
|
||||
pickup = std::make_unique<DummyPickup>(this, pos, modelInfo, pickuptype);
|
||||
|
@ -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
|
||||
|
@ -62,7 +62,7 @@ void GenericDATLoader::loadDynamicObjects(const std::string& name,
|
||||
}
|
||||
|
||||
void GenericDATLoader::loadWeapons(const std::string& name,
|
||||
WeaponDataPtrs& weaponData) {
|
||||
std::vector<WeaponData>& 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<WeaponData>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,9 +11,6 @@ typedef std::shared_ptr<DynamicObjectData> DynamicObjectDataPtr;
|
||||
typedef std::map<std::string, DynamicObjectDataPtr> DynamicObjectDataPtrs;
|
||||
|
||||
struct WeaponData;
|
||||
typedef std::shared_ptr<WeaponData> WeaponDataPtr;
|
||||
typedef std::vector<WeaponDataPtr> WeaponDataPtrs;
|
||||
|
||||
struct VehicleInfo;
|
||||
typedef std::shared_ptr<VehicleInfo> VehicleInfoPtr;
|
||||
typedef std::map<std::string, VehicleInfoPtr> 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>& weaponData);
|
||||
|
||||
void loadHandling(const std::string& name, VehicleInfoPtrs& vehicleData);
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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{};
|
||||
|
@ -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<SimpleModelInfo>(weapon->modelID);
|
||||
RW_CHECK(simple, "Failed to read modelinfo using " << weapon->modelID);
|
||||
m_world->data->findModelInfo<SimpleModelInfo>(weapon.modelID);
|
||||
RW_CHECK(simple, "Failed to read modelinfo using " << weapon.modelID);
|
||||
auto itematomic = simple->getAtomic(0);
|
||||
renderAtomic(itematomic, handFrame->getWorldTransform(), nullptr,
|
||||
outList);
|
||||
|
@ -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<SimpleModelInfo>(weapon->modelID);
|
||||
world->data->findModelInfo<SimpleModelInfo>(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;
|
||||
|
||||
|
@ -218,7 +218,7 @@ std::shared_ptr<Menu> 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); });
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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> 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) {
|
||||
|
@ -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);
|
||||
|
@ -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},
|
||||
|
Loading…
Reference in New Issue
Block a user