Reputation: 128
I'm having some problems with polymorphism I have a superclass of CEntity, and a subclass of unit type, I am dynamic casting and removing and emplacing a new entity of the dynamic casts type at its place, I have the opposite problem of my previous question.
Problem is the values being set are not changing, it remains with default values, it appeared to work before but now it has stopped working, I'm not sure what has caused the issue.
specifically buildsetup, sets the x-y-z values of the unit subclass's x,y,z, but when I look inside the vector the values remain unchanged, this is strange because it does actually manage to change the values for whether the unit is alive or not.
void builder(int no, string in , int top, int bot, CTeam &team, string owner, string original)
{
for (int i = top; i <= bot; i++)
{
EntityUnit* a;
a = dynamic_cast<EntityUnit*>(AWorld.EntitiesVector[i]);
a->unit_alive;
if (a->unit_alive == false)
{
float x = Player.returncity_add().cit_ret_X();
float y = Player.returncity_add().cit_ret_Y();
float z = Player.returncity_add().cit_ret_Z();
cout << "X:" << x;
cout << "Y:" << y;
cout << "Z:" << z;
float cost = MainAB.UnitTemplates[no]->UDRetCost();
float health = MainAB.UnitTemplates[no]->UDRetMaxHealth();
float damage = MainAB.UnitTemplates[no]->UDRetStrength();
float speed = MainAB.UnitTemplates[no]->UDRetSpeed();
float buildtime = MainAB.UnitTemplates[no]->UDRetBuildTime();
int popcost = MainAB.UnitTemplates[no]->UDRetPop();
a->set_owner(owner);
setmodel(i, x, y, z); // takes an xyz by ref and sets the model
to them then changes the model's localz by -10
Units[i]->SetSkin(setskin(owner, original));
a->BuildSetup(x, y, z, health, damage, speed, buildtime, cost, popcost);
team.inc_popcount(a->UDRetPop());
a->set_unit_alive(true);
sBuildUnit.play();
AWorld.EntitiesVector.erase(AWorld.EntitiesVector.begin() + i);
AWorld.EntitiesVector.emplace(AWorld.EntitiesVector.begin() + i, new EntityUnit(a));
AWorld.EntitiesVector[i]->set_x(x);
AWorld.EntitiesVector[i]->set_y(y);
AWorld.EntitiesVector[i]->set_z(z);
break;
}
}
Entity build setup
void EntityUnit::BuildSetup(float x, float y, float z,float _health, float _damage, float _speed, float _buildtime, float _cost, int _popcost)
{
unit_x = x;
unit_y = y;
unit_z = z;
unit_health[0] = _health;
unit_health[1] = _health;
unit_damage = _damage;
speed = _speed;
buildtime = _buildtime;
cost = _cost;
CUnitType = NA;
pop_req = _popcost;
}
After static debugging it, it most definately emplaces a new unit with the updated -is_alive, and while a's values change at the point of unitbuild, when its emplaced all x,y,z's return to 9999, which was what it was when they were pushed on the vector.
Upvotes: 1
Views: 421
Reputation: 128
Ok, Apparently the problem was it was totally unnecessary to erase/emplace, as I get what you mean now returning a pointer, it edited the value... odd it didn't work last time.
Upvotes: 0
Reputation: 32727
When you call
AWorld.EntitiesVector.erase(AWorld.EntitiesVector.begin() + i);
you destroy the object pointed to by a
. The subsequent reference to it on the next line is Undefined Behavior, and anything is possible.
I'm not sure why you erase the entity, then try to put a new one in the same place. If you structure your code right you should be able to just reuse the existing entity (pointed to by a) without the erase and emplace calls.
Upvotes: 2