Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove AList from items #223

Merged
merged 1 commit into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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