Skip to content

Commit

Permalink
Remove AList from items
Browse files Browse the repository at this point in the history
Items and ItemList no longer use AList.
ItemLists now statically allocate the Item as well rather than using
pointers to a dynamically allocated item (one less thing to free and
saving the memory footprint of the extra pointer since the item itself
still takes the same memory for the class).
  • Loading branch information
jt-traub committed Oct 8, 2024
1 parent 56fcbeb commit 7ac9d07
Show file tree
Hide file tree
Showing 20 changed files with 491 additions and 640 deletions.
23 changes: 10 additions & 13 deletions aregion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -827,32 +827,29 @@ void ARegion::Kill(Unit *u)
}

if (first) {
// give u's stuff to first
forlist(&u->items) {
Item *i = (Item *) elem;
if (ItemDefs[i->type].type & IT_SHIP &&
first->items.GetNum(i->type) > 0) {
if (first->items.GetNum(i->type) > i->num)
first->items.SetNum(i->type, i->num);
// give u's stuff to first. Since this can modify the list via SetNum, copy thelist
ItemList itemCopy = u->items;
for(auto i: itemCopy) {
if (ItemDefs[i.type].type & IT_SHIP && first->items.GetNum(i.type) > 0) {
if (first->items.GetNum(i.type) > i.num)
first->items.SetNum(i.type, i.num);
continue;
}
if (!IsSoldier(i->type)) {
first->items.SetNum(i->type, first->items.GetNum(i->type) +
i->num);
if (!IsSoldier(i.type)) {
first->items.SetNum(i.type, first->items.GetNum(i.type) + i.num);
// If we're in ocean and not in a structure, make sure that
// the first unit can actually hold the stuff and not drown
// If the item would cause them to drown then they won't
// pick it up.
if (TerrainDefs[type].similar_type == R_OCEAN) {
if (first->object->type == O_DUMMY) {
if (!first->CanReallySwim()) {
first->items.SetNum(i->type,
first->items.GetNum(i->type) - i->num);
first->items.SetNum(i.type, first->items.GetNum(i.type) - i.num);
}
}
}
}
u->items.SetNum(i->type, 0);
u->items.SetNum(i.type, 0);
}
}

Expand Down
135 changes: 53 additions & 82 deletions army.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,17 +219,16 @@ Soldier::Soldier(Unit * u,Object * o,int regtype,int r,int ass)
battleItems = 0;

/* Special case to allow protection from ships */
if (o->IsFleet() && o->capacity < 1 && o->shipno < o->ships.Num()) {
if (o->IsFleet() && o->capacity < 1 && o->shipno < static_cast<int>(o->ships.size())) {
int objectno;

i = 0;
forlist(&o->ships) {
Item *ship = (Item *) elem;
for(auto ship: o->ships) {
if (o->shipno == i) {
abbr = ItemDefs[ship->type].name;
abbr = ItemDefs[ship.type].name;
objectno = LookupObject(&abbr);
if (objectno >= 0 && ObjectDefs[objectno].protect > 0) {
o->capacity = ObjectDefs[objectno].protect * ship->num;
o->capacity = ObjectDefs[objectno].protect * ship.num;
o->type = objectno;
}
o->shipno++;
Expand Down Expand Up @@ -615,11 +614,9 @@ void Soldier::RestoreItems()
{
if (healing && healitem != -1) {
if (healitem == I_HERBS) {
unit->items.SetNum(healitem,
unit->items.GetNum(healitem) + healing);
unit->items.SetNum(healitem, unit->items.GetNum(healitem) + healing);
} else if (healitem == I_HEALPOTION) {
unit->items.SetNum(healitem,
unit->items.GetNum(healitem)+1);
unit->items.SetNum(healitem, unit->items.GetNum(healitem)+1);
}
}
if (weapon != -1)
Expand Down Expand Up @@ -670,7 +667,7 @@ void Soldier::Dead()
unit->SetMen(race,unit->GetMen(race) - 1);
}

Army::Army(Unit * ldr,AList * locs,int regtype,int ass)
Army::Army(Unit *ldr, AList *locs, int regtype, int ass)
{
stats = ArmyStats();

Expand Down Expand Up @@ -720,39 +717,31 @@ Army::Army(Unit * ldr,AList * locs,int regtype,int ass)

Object * obj = ((Location *) elem)->obj;
if (ass) {
forlist(&u->items) {
Item * it = (Item *) elem;
if (it) {
if (ItemDefs[ it->type ].type & IT_MAN) {
soldiers[x] = new Soldier(u, obj, regtype,
it->type, ass);
hitstotal = soldiers[x]->hits;
++x;
goto finished_army;
}
for(auto it: u->items) {
if (ItemDefs[it.type ].type & IT_MAN) {
soldiers[x] = new Soldier(u, obj, regtype, it.type, ass);
hitstotal = soldiers[x]->hits;
++x;
goto finished_army;
}
}
} else {
Item *it = (Item *) u->items.First();
do {
if (IsSoldier(it->type)) {
for (int i = 0; i < it->num; i++) {
ItemType &item = ItemDefs[ it->type ];
for (auto it: u->items) {
if (IsSoldier(it.type)) {
for (int i = 0; i < it.num; i++) {
ItemType& item = ItemDefs[it.type];
if (((item.type & IT_MAN) || (item.flags & ItemType::MANPRODUCE)) && u->GetFlag(FLAG_BEHIND)) {
--y;
soldiers[y] = new Soldier(u, obj, regtype,
it->type);
soldiers[y] = new Soldier(u, obj, regtype, it.type);
hitstotal += soldiers[y]->hits;
} else {
soldiers[x] = new Soldier(u, obj, regtype,
it->type);
soldiers[x] = new Soldier(u, obj, regtype, it.type);
hitstotal += soldiers[x]->hits;
++x;
}
}
}
it = (Item *) u->items.Next(it);
} while(it);
}
}
}

Expand Down Expand Up @@ -811,7 +800,7 @@ void Army::WriteLosses(Battle * b) {
}
}

void Army::GetMonSpoils(ItemList *spoils,int monitem, int free)
void Army::GetMonSpoils(ItemList& spoils, int monitem, int free)
{
if ((Globals->MONSTER_NO_SPOILS > 0) &&
(free >= Globals->MONSTER_SPOILS_RECOVERY)) {
Expand All @@ -828,53 +817,36 @@ void Army::GetMonSpoils(ItemList *spoils,int monitem, int free)
silv *= (Globals->MONSTER_SPOILS_RECOVERY-free);
silv /= Globals->MONSTER_SPOILS_RECOVERY;
}
spoils->SetNum(I_SILVER,spoils->GetNum(I_SILVER) + getrandom(silv));
spoils.SetNum(I_SILVER, spoils.GetNum(I_SILVER) + getrandom(silv));

int thespoil = mp->spoiltype;

if (thespoil == -1) return;
if (thespoil == IT_NORMAL && getrandom(2) && !Globals->SPOILS_NO_TRADE) thespoil = IT_TRADE;

int count = 0;
int i;
for (i=0; i<NITEMS; i++) {
if ((ItemDefs[i].type & thespoil) &&
!(ItemDefs[i].type & IT_SPECIAL) &&
!(ItemDefs[i].type & IT_SHIP) &&
!(ItemDefs[i].type & IT_NEVER_SPOIL) &&
(ItemDefs[i].baseprice <= mp->silver) &&
// collect all viable items from which we will pick one
std::vector<int> viableItems;
for (int i=0; i<NITEMS; i++) {
if ((ItemDefs[i].type & thespoil) && !(ItemDefs[i].type & IT_SPECIAL) && !(ItemDefs[i].type & IT_SHIP) &&
!(ItemDefs[i].type & IT_NEVER_SPOIL) && (ItemDefs[i].baseprice <= mp->silver) &&
!(ItemDefs[i].flags & ItemType::DISABLED)) {
count ++;
}
}
if (count == 0) return;
count = getrandom(count) + 1;

for (i=0; i<NITEMS; i++) {
if ((ItemDefs[i].type & thespoil) &&
!(ItemDefs[i].type & IT_SPECIAL) &&
!(ItemDefs[i].type & IT_SHIP) &&
!(ItemDefs[i].type & IT_NEVER_SPOIL) &&
(ItemDefs[i].baseprice <= mp->silver) &&
!(ItemDefs[i].flags & ItemType::DISABLED)) {
count--;
if (count == 0) {
thespoil = i;
break;
}
viableItems.push_back(i);
}
}

if (viableItems.empty()) return;
int count = getrandom(viableItems.size());
thespoil = viableItems[count];

int val = getrandom(mp->silver * 2);
if ((Globals->MONSTER_NO_SPOILS > 0) && (free > 0)) {
// Adjust for length of monster freedom.
val *= (Globals->MONSTER_SPOILS_RECOVERY-free);
val /= Globals->MONSTER_SPOILS_RECOVERY;
}

spoils->SetNum(thespoil,spoils->GetNum(thespoil) +
(val + getrandom(ItemDefs[thespoil].baseprice)) /
ItemDefs[thespoil].baseprice);
spoils.SetNum(thespoil, spoils.GetNum(thespoil) +
(val + getrandom(ItemDefs[thespoil].baseprice)) / ItemDefs[thespoil].baseprice);
}

void Army::Regenerate(Battle *b)
Expand Down Expand Up @@ -908,7 +880,7 @@ void Army::Regenerate(Battle *b)
}
}

void Army::Lose(Battle *b,ItemList *spoils)
void Army::Lose(Battle *b, ItemList& spoils)
{
WriteLosses(b);
for (int i=0; i<count; i++) {
Expand Down Expand Up @@ -1006,7 +978,7 @@ void Army::DoHealLevel(Battle *b, int level, int rate, int useItems)
}
}

void Army::Win(Battle * b,ItemList * spoils)
void Army::Win(Battle *b, ItemList& spoils)
{
int wintype;

Expand All @@ -1031,9 +1003,8 @@ void Army::Win(Battle * b,ItemList * spoils)
else s->Dead();
}

forlist(spoils) {
Item *i = (Item *) elem;
if (i && na) {
for(auto& i: spoils) {
if (na) {
Unit *u;
int ns;

Expand All @@ -1048,48 +1019,48 @@ void Army::Win(Battle * b,ItemList * spoils)
}

ns = units.size();
if (ItemDefs[i->type].type & IT_SHIP) {
if (ItemDefs[i.type].type & IT_SHIP) {
int t = getrandom(ns);
Unit *u = units[t];
if (u && u->CanGetSpoil(i)) {
u->items.SetNum(i->type, i->num);
u->faction->DiscoverItem(i->type, 0, 1);
i->num = 0;
u->items.SetNum(i.type, i.num);
u->faction->DiscoverItem(i.type, 0, 1);
i.num = 0;
}
break;
}
while (ns > 0 && i->num >= ns) {
while (ns > 0 && i.num >= ns) {
int chunk = 1;
if (!ItemDefs[i->type].weight) {
chunk = i->num / ns;
if (!ItemDefs[i.type].weight) {
chunk = i.num / ns;
}
for (auto iter = units.begin(); iter != units.end();) {
auto u = *iter;
if (u->CanGetSpoil(i)) {
u->items.SetNum(i->type, u->items.GetNum(i->type) + chunk);
u->faction->DiscoverItem(i->type, 0, 1);
i->num -= chunk;
u->items.SetNum(i.type, u->items.GetNum(i.type) + chunk);
u->faction->DiscoverItem(i.type, 0, 1);
i.num -= chunk;
++iter;
} else {
iter = units.erase(iter);
ns--;
}
}
}
while (ns > 0 && i->num > 0) {
while (ns > 0 && i.num > 0) {
int t = getrandom(ns);
u = units[t];
if (u && u->CanGetSpoil(i)) {
u->items.SetNum(i->type, u->items.GetNum(i->type) + 1);
u->faction->DiscoverItem(i->type, 0, 1);
i->num--;
u->items.SetNum(i.type, u->items.GetNum(i.type) + 1);
u->faction->DiscoverItem(i.type, 0, 1);
i.num--;
} else {
std::erase(units, u);
ns = units.size();
}
}
units.clear();
} while (ns > 0 && i->num > 0);
} while (ns > 0 && i.num > 0);
}
}

Expand Down
16 changes: 8 additions & 8 deletions army.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,16 +171,16 @@ class Army
Army(Unit *,AList *,int,int = 0);
~Army();

void WriteLosses(Battle *);
void Lose(Battle *,ItemList *);
void Win(Battle *,ItemList *);
void Tie(Battle *);
void WriteLosses(Battle *b);
void Lose(Battle *b,ItemList &spoils);
void Win(Battle *b,ItemList& spoils);
void Tie(Battle *b);
int CanBeHealed();
void DoHeal(Battle *);
void DoHealLevel(Battle *, int level, int rate, int useItems);
void Regenerate(Battle *);
void DoHeal(Battle *b);
void DoHealLevel(Battle *b, int level, int rate, int useItems);
void Regenerate(Battle *b);

void GetMonSpoils(ItemList *,int, int);
void GetMonSpoils(ItemList& spoils, int monitem, int free);

int Broken();
int NumAlive();
Expand Down
Loading

0 comments on commit 7ac9d07

Please sign in to comment.