1
0
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:
Filip Gawin 2018-11-08 00:26:38 +01:00
parent 2c0356d8b7
commit dce5257eb3
16 changed files with 98 additions and 99 deletions

View File

@ -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)) {

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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));
}
}
}

View File

@ -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);
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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{};

View File

@ -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);

View File

@ -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;

View File

@ -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); });
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);

View File

@ -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},