[FIX]4 leltár teljes hibajavítás

Indította [VIP]Rin the Exorcist, 2018-04-03, 09:13:44

2018-04-03, 09:13:44 Utolsó szerkesztés: 2019-10-14, 09:08:08 Szerző: [VIP]Rin the Exorcist
Sziasztok!

Külföldi fórumokon, meg itt a miénken is több leltárbővítős leírás is van, azonban ezek túlnyomó többsége hibás, így szükségét éreztem annak, hogy legyen legalább egy korrekt.

Alapnak használjuk ezt, mert nem írok le lépésről lépésre mindent, csak a javításokat.

game/exchange.cpp
Kezdésnek vegyük az alábbi sorokat. Itt általában senki sem gondolkodik, csak ész nélkül hozzáírja a további grideket. Alapvetően itt miről is lenne szó? Esetünkben a 4 leltárat szeretnénk külön rácsra helyezni. Ehhez mi kell? A leltár mérete xy-ban, ami alap esetben nem más mint x=5 és y=9. Az 5 már meg is van nekünk, ezzel kezdődik a grid, az y kiszámítása azonban ezek szerint a legtöbbeknek problémát okoz. De egy kis fejszámolással hamar rájöhetünk, hogy az utolsó osztó számmnak annyinak kell lennie, ahány leltárunk van.
Szóval igen, az alap kettest bizony át kell írni...

static CGrid s_grid1(5, INVENTORY_MAX_NUM/5/4);
static CGrid s_grid2(5, INVENTORY_MAX_NUM/5/4);
static CGrid s_grid3(5, INVENTORY_MAX_NUM/5/4);
static CGrid s_grid4(5, INVENTORY_MAX_NUM/5/4);


De igazából felesleges ennyit számolni, amikor a legtöbb helyen amúgy is csak simán megadták az xy értékeket, szóval az alábbi sorokat javasolnám inkább.
static CGrid s_grid1(5, 9);
static CGrid s_grid2(5, 9);
static CGrid s_grid3(5, 9);
static CGrid s_grid4(5, 9);



A következő kicsit lejjebb a for ciklus. Megint nem gondolkodik senki, csak ész nélkül nyomja a ctrl+c/v-t. Mit szeretnénk? Azt hogy az esetünkben 180 sloton végig menjen a ciklus. Tehát ha az alap jimires' rendszert követjük szükségük lesz 4 azaz 4 darab ciklusra, mert ennyi leltárunk van.
Nem kell matekzseninek lenni ahhoz, hogy rájöjjünk, az első megy a 0. elemtől a max leltár negyedéig, magyarán az első oldal végéig, a második megy a negyedétől a feléig, a harmadik a felétől a 3/4-ig, az utolsó pedig innentől a végéig.

for (i = 0; i < INVENTORY_MAX_NUM/4; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

s_grid1.Put(i, 1, item->GetSize());
}
for (i = INVENTORY_MAX_NUM/4; i < INVENTORY_MAX_NUM/2; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

s_grid2.Put(i - INVENTORY_MAX_NUM/4, 1, item->GetSize());
}
for (i = INVENTORY_MAX_NUM/2; i < INVENTORY_MAX_NUM/4*3; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

s_grid3.Put(i - INVENTORY_MAX_NUM/2, 1, item->GetSize());
}
for (i = INVENTORY_MAX_NUM/4*3; i < INVENTORY_MAX_NUM; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

s_grid4.Put(i - INVENTORY_MAX_NUM/4*3, 1, item->GetSize());
}


Persze minek 4 folytatólagos ciklus, amikor egyben is meglehet oldani, így itt is az alábbi verziót javasolnám.
for (i = 0; i < INVENTORY_MAX_NUM; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

if (i < INVENTORY_MAX_NUM/4)
s_grid1.Put(i, 1, item->GetSize());
else if (i < INVENTORY_MAX_NUM/2)
s_grid2.Put(i - INVENTORY_MAX_NUM/4, 1, item->GetSize());
else if (i < INVENTORY_MAX_NUM/4*3)
s_grid3.Put(i - INVENTORY_MAX_NUM/2, 1, item->GetSize());
else
s_grid4.Put(i - INVENTORY_MAX_NUM/4*3, 1, item->GetSize());
}



Amiről pedig mindenki elfeledkezik, kicsivel lejjebb keressük meg ezt a sort:
int iPos = s_grid1.FindBlank(1, item->GetSize());

És az egész else elágazást cseréljük ki erre:
int iPos = s_grid1.FindBlank(1, item->GetSize());

if (iPos >= 0)
s_grid1.Put(iPos, 1, item->GetSize());
else
{
iPos = s_grid2.FindBlank(1, item->GetSize());

if (iPos >= 0)
s_grid2.Put(iPos, 1, item->GetSize());
else
{
iPos = s_grid3.FindBlank(1, item->GetSize());

if (iPos >= 0)
s_grid3.Put(iPos, 1, item->GetSize());
else
{
iPos = s_grid4.FindBlank(1, item->GetSize());

if (iPos >= 0)
s_grid4.Put(iPos, 1, item->GetSize());
else
return false;
}
}
}



Nézzünk most rá kicsit a kliens fájlokra is. Itt már nem konkrét hibákról lesz szó, hanem amolyan szépséghibákról, amik a jövőben kicsit megnehezíthetik az életünket, ha esetleg ismét bővítenénk a leltárrendszerünkön.

uicommon.py
Ha már az indító forrásában egyszer szerepel két változó, amiknek a szorzatával megkapjuk a teljes leltárméretet, akkor miért ne használjuk őket? Így a jövőben itt már semmit sem kell majd módosítanunk.

def Open(self, iPos=None):
if None == iPos or iPos >= player.INVENTORY_PAGE_SIZE * player.INVENTORY_PAGE_COUNT or iPos < 0:
return


uiselectitem.py
Itt is ugyanez a helyzet, tegyük használhatóbbá kliensünket kicsivel.

for i in xrange(player.INVENTORY_PAGE_SIZE * player.INVENTORY_PAGE_COUNT):

inventorywindow.py
Szintén.

EQUIPMENT_START_INDEX = player.INVENTORY_PAGE_SIZE * player.INVENTORY_PAGE_COUNT

beltinventorywindow.py
Itt pedig a szemfülesek biztosan észrevették már, de az alábbi változó teljesen szükségtelen, így kérlek titeket, csak töröljétek ki, és feledkezzünk meg róla.

EQUIPMENT_START_INDEX

Természetesen a kliens módosításokat úgy is lehetne, hogy szintén az indító forrásában van egy változó, ami tárolja szorzat értékét, elég ha csak ezt kijuttatjuk a kliensnek, és már használhatjuk is.
Szerveroldalon pedig írhatnánk konkrét változókat az x és y méreteinek, és mindenhol használhatnánk ezeket, de ezt már rátok bízom! :D

A leírásnak köszönhetően, ha a jövőben még variálnátok a leltár méretét, akkor a téma keretein belül csak a for ciklusban kell majd józan paraszti ésszel átírni az ifeket.





A téma nem támadó jellegű senki felé, és nem is vita céljából jött létre, pusztán azért, amit az elején már említettem.

/Rin
"Tisztelet a kivételnek! Mindig tisztelet a kivételnek!"
"KezdÅ' vagyok, ne nézz le... (:"