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.
This commit is contained in:
parent
d3c42544a6
commit
32d397eb2a
5 changed files with 42 additions and 31 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ void AddTelekinesis(Missile &missile, const AddMissileParameter ¶meter);
|
|||
void AddBoneSpirit(Missile &missile, const AddMissileParameter ¶meter);
|
||||
void AddRportal(Missile &missile, const AddMissileParameter ¶meter);
|
||||
void AddDiabApoca(Missile &missile, const AddMissileParameter ¶meter);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue