Browse Source

Add max_size checks when adding missiles to allow for limited size containers

This doesn't handle failed allocations (e.g. if the platform runs out of memory) but makes it easier to use a fixed size container on limited memory devices.
pull/3987/head
ephphatha 4 years ago committed by Anders Jenbo
parent
commit
32d397eb2a
  1. 4
      Source/loadsave.cpp
  2. 8
      Source/missiles.cpp
  3. 2
      Source/missiles.h
  4. 49
      Source/monster.cpp
  5. 10
      Source/portal.cpp

4
Source/loadsave.cpp

@ -715,7 +715,9 @@ void LoadMissile(LoadHelper *file)
missile.var7 = file->NextLE<int32_t>();
missile.limitReached = file->NextBool32();
missile.lastCollisionTargetHash = 0;
Missiles.push_back(missile);
if (Missiles.size() < Missiles.max_size()) {
Missiles.push_back(missile);
}
}
void LoadObject(LoadHelper &file, Object &object)

8
Source/missiles.cpp

@ -2692,9 +2692,11 @@ void AddDiabApoca(Missile &missile, const AddMissileParameter & /*parameter*/)
missile._miDelFlag = true;
}
Missile &AddMissile(Point src, Point dst, Direction midir, missile_id mitype, mienemy_type micaster, int id, int midam, int spllvl, Missile *pParent /*= nullptr*/)
Missile *AddMissile(Point src, Point dst, Direction midir, missile_id mitype, mienemy_type micaster, int id, int midam, int spllvl, Missile *pParent /*= nullptr*/)
{
constexpr int32_t MaxMissiles = std::numeric_limits<int32_t>::max();
if (Missiles.size() >= Missiles.max_size()) {
return nullptr;
}
Missiles.emplace_back(Missile {});
auto &missile = Missiles.back();
@ -2726,7 +2728,7 @@ Missile &AddMissile(Point src, Point dst, Direction midir, missile_id mitype, mi
AddMissileParameter parameter = { dst, midir, pParent };
missileData.mAddProc(missile, parameter);
return missile;
return &missile;
}
void MI_LArrow(Missile &missile)

2
Source/missiles.h

@ -341,7 +341,7 @@ void AddTelekinesis(Missile &missile, const AddMissileParameter &parameter);
void AddBoneSpirit(Missile &missile, const AddMissileParameter &parameter);
void AddRportal(Missile &missile, const AddMissileParameter &parameter);
void AddDiabApoca(Missile &missile, const AddMissileParameter &parameter);
Missile &AddMissile(Point src, Point dst, Direction midir, missile_id mitype, mienemy_type micaster, int id, int midam, int spllvl, Missile *pParent = nullptr);
Missile *AddMissile(Point src, Point dst, Direction midir, missile_id mitype, mienemy_type micaster, int id, int midam, int spllvl, Missile *pParent = nullptr);
void MI_Golem(Missile &missile);
void MI_Manashield(Missile &missile);
void MI_LArrow(Missile &missile);

49
Source/monster.cpp

@ -1616,16 +1616,18 @@ bool MonsterRangedSpecialAttack(int i)
assert(monster.MData != nullptr);
if (monster.AnimInfo.CurrentFrame == monster.MData->mAFNum2 && monster.AnimInfo.TickCounterOfCurrentFrame == 0) {
AddMissile(
monster.position.tile,
monster.enemyPosition,
monster._mdir,
static_cast<missile_id>(monster._mVar1),
TARGET_PLAYERS,
i,
monster._mVar3,
0);
PlayEffect(monster, 3);
if (AddMissile(
monster.position.tile,
monster.enemyPosition,
monster._mdir,
static_cast<missile_id>(monster._mVar1),
TARGET_PLAYERS,
i,
monster._mVar3,
0)
!= nullptr) {
PlayEffect(monster, 3);
}
}
if (monster._mAi == AI_MEGA && monster.AnimInfo.CurrentFrame == monster.MData->mAFNum2) {
@ -2556,11 +2558,12 @@ void RhinoAi(int i)
if (dist >= 5
&& v < 2 * monster._mint + 43
&& LineClear([&monster](Point position) { return IsTileAvailable(monster, position); }, monster.position.tile, { fx, fy })) {
AddMissile(monster.position.tile, { fx, fy }, md, MIS_RHINO, TARGET_PLAYERS, i, 0, 0);
if (monster.MData->snd_special)
PlayEffect(monster, 3);
dMonster[monster.position.tile.x][monster.position.tile.y] = -(i + 1);
monster._mmode = MonsterMode::Charge;
if (AddMissile(monster.position.tile, { fx, fy }, md, MIS_RHINO, TARGET_PLAYERS, i, 0, 0) != nullptr) {
if (monster.MData->snd_special)
PlayEffect(monster, 3);
dMonster[monster.position.tile.x][monster.position.tile.y] = -(i + 1);
monster._mmode = MonsterMode::Charge;
}
} else {
if (dist >= 2) {
v = GenerateRnd(100);
@ -2758,9 +2761,10 @@ void BatAi(int i)
&& (abs(xd) >= 5 || abs(yd) >= 5)
&& v < 4 * monster._mint + 33
&& LineClear([&monster](Point position) { return IsTileAvailable(monster, position); }, monster.position.tile, { fx, fy })) {
AddMissile(monster.position.tile, { fx, fy }, md, MIS_RHINO, TARGET_PLAYERS, i, 0, 0);
dMonster[monster.position.tile.x][monster.position.tile.y] = -(i + 1);
monster._mmode = MonsterMode::Charge;
if (AddMissile(monster.position.tile, { fx, fy }, md, MIS_RHINO, TARGET_PLAYERS, i, 0, 0) != nullptr) {
dMonster[monster.position.tile.x][monster.position.tile.y] = -(i + 1);
monster._mmode = MonsterMode::Charge;
}
} else if (abs(xd) >= 2 || abs(yd) >= 2) {
if ((monster._mVar2 > 20 && v < monster._mint + 13)
|| (IsAnyOf(static_cast<MonsterMode>(monster._mVar1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways)
@ -3026,10 +3030,11 @@ void SnakeAi(int i)
monster._mdir = md;
if (abs(mx) >= 2 || abs(my) >= 2) {
if (abs(mx) < 3 && abs(my) < 3 && LineClear([&monster](Point position) { return IsTileAvailable(monster, position); }, monster.position.tile, { fx, fy }) && static_cast<MonsterMode>(monster._mVar1) != MonsterMode::Charge) {
AddMissile(monster.position.tile, { fx, fy }, md, MIS_RHINO, TARGET_PLAYERS, i, 0, 0);
PlayEffect(monster, 0);
dMonster[monster.position.tile.x][monster.position.tile.y] = -(i + 1);
monster._mmode = MonsterMode::Charge;
if (AddMissile(monster.position.tile, { fx, fy }, md, MIS_RHINO, TARGET_PLAYERS, i, 0, 0) != nullptr) {
PlayEffect(monster, 0);
dMonster[monster.position.tile.x][monster.position.tile.y] = -(i + 1);
monster._mmode = MonsterMode::Charge;
}
} else if (static_cast<MonsterMode>(monster._mVar1) == MonsterMode::Delay || GenerateRnd(100) >= 35 - 2 * monster._mint) {
if (pattern[monster._mgoalvar1] == -1)
md = Left(md);

10
Source/portal.cpp

@ -51,11 +51,13 @@ void AddWarpMissile(int i, Point position)
{
MissilesData[MIS_TOWN].mlSFX = SFX_NONE;
auto &missile = AddMissile({ 0, 0 }, position, Direction::South, MIS_TOWN, TARGET_MONSTERS, i, 0, 0);
SetMissDir(missile, 1);
auto *missile = AddMissile({ 0, 0 }, position, Direction::South, MIS_TOWN, TARGET_MONSTERS, i, 0, 0);
if (missile != nullptr) {
SetMissDir(*missile, 1);
if (currlevel != 0)
missile._mlid = AddLight(missile.position.tile, 15);
if (currlevel != 0)
missile->_mlid = AddLight(missile->position.tile, 15);
}
MissilesData[MIS_TOWN].mlSFX = LS_SENTINEL;
}

Loading…
Cancel
Save