From 42959207914208438261810757abea43422a28fe Mon Sep 17 00:00:00 2001 From: fusion32 Date: Tue, 27 May 2025 02:18:40 -0300 Subject: impl RefreshSector and PatchSector (WTF) --- reference/game.c | 666 ------------------------------------------------------- src/common.hh | 2 +- src/map.cc | 403 +++++++++++++++++++++++++++++++++ src/map.hh | 5 +- src/stubs.hh | 5 +- src/util.cc | 2 +- 6 files changed, 411 insertions(+), 672 deletions(-) diff --git a/reference/game.c b/reference/game.c index 5591ba8..b8991a1 100644 --- a/reference/game.c +++ b/reference/game.c @@ -5192,672 +5192,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority return; } -void RefreshSector(int x,int y,int z,TReadStream *Stream) - -{ - int iVar1; - matrix3d *pmVar2; - TSector *Sec; - int iVar3; - TSector **ppTVar4; - uint uVar5; - uint uVar6; - TObject *pTVar7; - int iVar8; - int iVar9; - int xx; - bool bVar10; - char *Con; - int yy; - Object local_5c [4]; - ObjectType local_4c [4]; - Object local_3c [4]; - ulong local_2c; - Object Obj; - - pmVar2 = Sector; - iVar9 = y - Sector->ymin; - iVar3 = z - Sector->zmin; - iVar8 = x - Sector->xmin; - if (((((iVar8 < 0) || (iVar1 = Sector->dx, iVar1 <= iVar8)) || (iVar9 < 0)) || - ((Sector->dy <= iVar9 || (iVar3 < 0)))) || (Sector->dz <= iVar3)) { - error("matrix3d::operator(): Ungueltiger Index %d/%d/%d.\n",iVar8 + Sector->xmin, - iVar9 + Sector->ymin,iVar3 + Sector->zmin); - ppTVar4 = pmVar2->entry; - } - else { - ppTVar4 = Sector->entry + iVar3 * iVar1 * Sector->dy + iVar9 * iVar1 + iVar8; - } - if ((*ppTVar4 != (TSector *)0x0) && (((*ppTVar4)->MapFlags & 1) != 0)) { - Con = "Refreshe Sektor %d/%d/%d ...\n"; - iVar3 = x; - iVar8 = y; - iVar9 = z; - print(); - // try { // try from 0805db63 to 0805dc7f has its CatchHandler @ 0805dcb4 - while (iVar3 = (*Stream->_vptr_TReadStream[6])(Stream,Con,iVar3,iVar8,iVar9), - (char)iVar3 == '\0') { - uVar5 = (*Stream->_vptr_TReadStream[1])(Stream); - uVar6 = (*Stream->_vptr_TReadStream[1])(Stream); - while( true ) { - GetFirstObject(); - while( true ) { - bVar10 = false; - local_3c[0].ObjectID = NONE.ObjectID; - local_4c[0].TypeID = NONE.ObjectID; - if (local_2c != NONE.ObjectID) { - local_5c[0].ObjectID = local_2c; - pTVar7 = AccessObject(local_5c); - ObjectType::setTypeID(local_4c,(pTVar7->Type).TypeID); - bVar10 = local_4c[0].TypeID == 99; - } - if (!bVar10) break; - local_3c[0].ObjectID = local_2c; - pTVar7 = AccessObject(local_3c); - local_5c[0].ObjectID = (pTVar7->NextObject).ObjectID; - local_2c = local_5c[0].ObjectID; - } - local_5c[0].ObjectID = NONE.ObjectID; - if (local_2c == NONE.ObjectID) break; - local_5c[0].ObjectID = local_2c; - DeleteObject(local_5c); - } - iVar3 = y * 0x20 + (uVar6 & 0xff); - iVar8 = z; - GetMapContainer((int)local_5c,x * 0x20 + (uVar5 & 0xff),iVar3); - Con = (char *)local_5c; - LoadObjects(Stream,(Object *)Con); - } - } - return; -} - - - -void PatchSector(int x,int y,int z,bool FullSector,TReadScriptFile *Script,bool SaveHouses) - -{ - TWriteScriptFile *pTVar1; - int iVar2; - TSector *pTVar3; - matrix3d *pmVar4; - char cVar5; - bool bVar6; - byte bVar7; - int result; - int iVar8; - TSector **ppTVar9; - TOKEN TVar10; - TObject *pTVar11; - byte *pbVar12; - int *piVar13; - undefined4 *puVar14; - int iVar15; - int hy; - int iVar16; - int Flags; - bool *pbVar17; - int hx; - int yy_2; - char *pcVar18; - bool bVar19; - undefined1 uVar20; - bool bVar21; - char *pcVar22; - TDynamicWriteBuffer *pTVar23; - bool *local_788c; - int local_7888; - Object *local_7884; - Object *local_7880; - int local_7870; - int yy_1; - int xx_1; - uint uStack_7864; - bool House; - int yy; - int xx; - TSector *Sec; - char local_784c; - bool NewSector; - bool SaveHouses_local; - bool FullSector_local; - char FileNameBak [4096]; - char FileName [4096]; - TWriteScriptFile OUT; - undefined1 local_483c [4]; - TReadScriptFile IN; - undefined1 local_85c [4]; - TReadBuffer ReadBuffer; - undefined1 local_83c [4]; - TReadBuffer ReadBuffer_2; - Object Obj; - bool abStack_81c [4]; - bool FieldTreated [32] [32]; - bool FieldPatched [32] [32]; - - pmVar4 = Sector; - iVar16 = y - Sector->ymin; - iVar8 = z - Sector->zmin; - iVar15 = x - Sector->xmin; - if (((((iVar15 < 0) || (iVar2 = Sector->dx, iVar2 <= iVar15)) || (iVar16 < 0)) || - ((Sector->dy <= iVar16 || (iVar8 < 0)))) || (Sector->dz <= iVar8)) { - // try { // try from 0805dd7d to 0805e502 has its CatchHandler @ 0805f035 - error("matrix3d::operator(): Ungueltiger Index %d/%d/%d.\n",iVar15 + Sector->xmin, - iVar16 + Sector->ymin,iVar8 + Sector->zmin); - ppTVar9 = pmVar4->entry; - } - else { - ppTVar9 = Sector->entry + iVar8 * iVar2 * Sector->dy + iVar16 * iVar2 + iVar15; - } - bVar19 = *ppTVar9 == (TSector *)0x0; - if (bVar19) { - print(); - InitSector(x,y,z); - } - pmVar4 = Sector; - iVar16 = y - Sector->ymin; - iVar8 = z - Sector->zmin; - iVar15 = x - Sector->xmin; - if (((iVar15 < 0) || (iVar2 = Sector->dx, iVar2 <= iVar15)) || - ((iVar16 < 0 || (((Sector->dy <= iVar16 || (iVar8 < 0)) || (Sector->dz <= iVar8)))))) { - error("matrix3d::operator(): Ungueltiger Index %d/%d/%d.\n",iVar15 + Sector->xmin, - iVar16 + Sector->ymin,iVar8 + Sector->zmin); - ppTVar9 = pmVar4->entry; - } - else { - ppTVar9 = Sector->entry + iVar8 * iVar2 * Sector->dy + iVar16 * iVar2 + iVar15; - } - bVar21 = false; - pTVar3 = *ppTVar9; - uStack_7864 = 0xffffffff; - iVar8 = 0; - pbVar17 = FieldPatched[0x1f] + 0x1c; - yy = -1; - do { - iVar15 = 0; - do { - iVar16 = iVar15 + 1; - pbVar17[iVar15 + -0x400] = false; - pbVar17[iVar15 + -0x800] = false; - iVar15 = iVar16; - } while (iVar16 < 0x20); - iVar8 = iVar8 + 1; - pbVar17 = pbVar17 + 0x20; - } while (iVar8 < 0x20); -LAB_0805de50: - TReadScriptFile::nextToken(Script); - TVar10 = Script->Token; - if (TVar10 != ENDOFFILE) { - if (TVar10 == SPECIAL) goto code_r0x0805de6d; - goto LAB_0805de7e; - } - if (FullSector) { - yy_1 = 0; - local_7888 = 0; - do { - local_7870 = 0; - local_7884 = pTVar3->MapCon[yy_1]; - do { - if (abStack_81c[local_7870 + local_7888] == false) { - bVar21 = false; - iVar8 = local_7870 + y * 0x20; - iVar15 = yy_1 + x * 0x20; - // try { // try from 0805ecc9 to 0805efcc has its CatchHandler @ 0805f035 - bVar6 = IsHouse(iVar15,iVar8,z); - if (bVar6) { -LAB_0805ecd6: - bVar21 = true; - } - else { - bVar6 = CoordinateFlag(); - if (bVar6) { - iVar16 = iVar8 + 1; - bVar6 = IsHouse(iVar15 + -1,iVar16,z); - if (((bVar6) || (bVar6 = IsHouse(iVar15,iVar16,z), bVar6)) || - (bVar6 = IsHouse(iVar15 + 1,iVar16,z), bVar6)) goto LAB_0805ecd6; - } - bVar6 = CoordinateFlag(); - if (bVar6) { - iVar15 = iVar15 + 1; - bVar6 = IsHouse(iVar15,iVar8 + -1,z); - if (((bVar6) || (bVar6 = IsHouse(iVar15,iVar8,z), bVar6)) || - (bVar6 = IsHouse(iVar15,iVar8 + 1,z), bVar6)) goto LAB_0805ecd6; - } - } - if (bVar21) { - if (SaveHouses) goto LAB_0805e4c9; - CleanHouseField(x * 0x20 + yy_1,y * 0x20 + local_7870,z); - } - while( true ) { - GetFirstObject(); - while( true ) { - bVar21 = false; - ReadBuffer.Position = NONE.ObjectID; - local_83c = (undefined1 [4])NONE.ObjectID; - if (local_85c != (undefined1 [4])NONE.ObjectID) { - ReadBuffer_2.Position = (int)local_85c; - pTVar11 = AccessObject((Object *)&ReadBuffer_2.Position); - ObjectType::setTypeID - ((ObjectType *)local_83c,(pTVar11->Type).TypeID); - bVar21 = local_83c == (undefined1 [4])0x63; - } - if (!bVar21) break; - ReadBuffer_2.Position = (int)local_85c; - pTVar11 = AccessObject((Object *)&ReadBuffer_2.Position); - local_85c = (undefined1 [4])(pTVar11->NextObject).ObjectID; - } - ReadBuffer.Position = NONE.ObjectID; - if (local_85c == (undefined1 [4])NONE.ObjectID) break; - ReadBuffer.Position = (int)local_85c; - DeleteObject((Object *)&ReadBuffer.Position); - } - local_85c = (undefined1 [4])local_7884->ObjectID; - pTVar11 = AccessObject((Object *)local_85c); - pTVar11->Attributes[3] = pTVar11->Attributes[3] & 0xffff00ff; - FieldTreated[0x1f][local_7870 + local_7888 + 0x1c] = true; - } -LAB_0805e4c9: - local_7870 = local_7870 + 1; - local_7884 = local_7884 + 1; - } while (local_7870 < 0x20); - yy_1 = yy_1 + 1; - local_7888 = local_7888 + 0x20; - } while (yy_1 < 0x20); - } - TReadScriptFile::TReadScriptFile((TReadScriptFile *)local_483c); - // try { // try from 0805e50c to 0805e510 has its CatchHandler @ 0805f02f - TWriteScriptFile::TWriteScriptFile((TWriteScriptFile *)(FileName + 0xffc)); - sprintf(FileNameBak + 0xffc,"%s/%04u-%04u-%02u.sec",ORIGMAPPATH,x,y,z); - pcVar22 = ORIGMAPPATH; - sprintf(&local_784c,"%s/%04u-%04u-%02u.sec~",ORIGMAPPATH,x,y,z); - if (!bVar19) { - TReadScriptFile::open((TReadScriptFile *)local_483c,FileNameBak + 0xffc,(int)pcVar22); - } - pTVar1 = (TWriteScriptFile *)(FileName + 0xffc); - // try { // try from 0805e597 to 0805e9db has its CatchHandler @ 0805f004 - TWriteScriptFile::open(pTVar1,&local_784c,(int)pcVar22); - TWriteScriptFile::writeText(pTVar1,"# Tibia - graphical Multi-User-Dungeon"); - TWriteScriptFile::writeLn(pTVar1); - TWriteScriptFile::writeText(pTVar1,"# Data for sector "); - TWriteScriptFile::writeNumber((TWriteScriptFile *)(FileName + 0xffc),x); - TWriteScriptFile::writeText((TWriteScriptFile *)(FileName + 0xffc),"/"); - pTVar1 = (TWriteScriptFile *)(FileName + 0xffc); - TWriteScriptFile::writeNumber(pTVar1,y); - TWriteScriptFile::writeText(pTVar1,"/"); - TWriteScriptFile::writeNumber(pTVar1,z); - TWriteScriptFile::writeLn(pTVar1); - TWriteScriptFile::writeLn(pTVar1); - pcVar22 = (char *)z; - if (!bVar19) { - yy = -1; - uStack_7864 = 0xffffffff; -LAB_0805e656: - do { - TReadScriptFile::nextToken((TReadScriptFile *)local_483c); - if (local_483c == (undefined1 [4])0x0) goto LAB_0805e958; - if ((local_483c != (undefined1 [4])0x6) || - (cVar5 = TReadScriptFile::getSpecial((TReadScriptFile *)local_483c), cVar5 != ',')) { - if (local_483c == (undefined1 [4])0x4) { - pbVar12 = TReadScriptFile::getBytesequence((TReadScriptFile *)local_483c); - yy = (int)*pbVar12; - uStack_7864 = (uint)pbVar12[1]; - z = 0x3a; - TReadScriptFile::readSymbol((TReadScriptFile *)local_483c,':'); - if (FieldTreated[yy + 0x1f][uStack_7864 + 0x1c] != false) goto LAB_0805e656; - pTVar1 = (TWriteScriptFile *)(FileName + 0xffc); - TWriteScriptFile::writeNumber(pTVar1,yy); - TWriteScriptFile::writeText(pTVar1,"-"); - TWriteScriptFile::writeNumber(pTVar1,uStack_7864); - z = (int)&DAT_080f2ab7; - } - else { - if (local_483c != (undefined1 [4])0x1) { - z = (int)"next map point expected"; -LAB_0805e6ac: - TReadScriptFile::error((TReadScriptFile *)local_483c,(char *)z); - goto LAB_0805e656; - } - uVar20 = yy == -1; - if ((bool)uVar20) { - pcVar22 = "coordinate expected"; - TReadScriptFile::error((TReadScriptFile *)local_483c,"coordinate expected"); - z = (int)pcVar22; - } - pcVar22 = TReadScriptFile::getIdentifier((TReadScriptFile *)local_483c); - iVar8 = 8; - pcVar18 = "refresh"; - do { - if (iVar8 == 0) break; - iVar8 = iVar8 + -1; - uVar20 = *pcVar22 == *pcVar18; - pcVar22 = pcVar22 + 1; - pcVar18 = pcVar18 + 1; - } while ((bool)uVar20); - if ((bool)uVar20) { - if (FieldTreated[yy + 0x1f][uStack_7864 + 0x1c] != false) goto LAB_0805e656; - z = (int)"Refresh, "; - } - else { - pcVar22 = TReadScriptFile::getIdentifier((TReadScriptFile *)local_483c); - iVar8 = 9; - pcVar18 = "nologout"; - do { - if (iVar8 == 0) break; - iVar8 = iVar8 + -1; - uVar20 = *pcVar22 == *pcVar18; - pcVar22 = pcVar22 + 1; - pcVar18 = pcVar18 + 1; - } while ((bool)uVar20); - if ((bool)uVar20) { - if (FieldTreated[yy + 0x1f][uStack_7864 + 0x1c] != false) - goto LAB_0805e656; - z = (int)"NoLogout, "; - } - else { - pcVar22 = TReadScriptFile::getIdentifier((TReadScriptFile *)local_483c); - iVar8 = 0xf; - pcVar18 = "protectionzone"; - do { - if (iVar8 == 0) break; - iVar8 = iVar8 + -1; - uVar20 = *pcVar22 == *pcVar18; - pcVar22 = pcVar22 + 1; - pcVar18 = pcVar18 + 1; - } while ((bool)uVar20); - if (!(bool)uVar20) { - pcVar22 = TReadScriptFile::getIdentifier - ((TReadScriptFile *)local_483c); - iVar8 = 8; - pcVar18 = "content"; - do { - if (iVar8 == 0) break; - iVar8 = iVar8 + -1; - uVar20 = *pcVar22 == *pcVar18; - pcVar22 = pcVar22 + 1; - pcVar18 = pcVar18 + 1; - } while ((bool)uVar20); - if (!(bool)uVar20) { - z = (int)"unknown map flag"; - goto LAB_0805e6ac; - } - TReadScriptFile::readSymbol((TReadScriptFile *)local_483c,'='); - HelpBuffer.super_TWriteBuffer.Position = 0; - pTVar23 = &HelpBuffer; - LoadObjects((TReadScriptFile *)local_483c, - (TWriteStream *)&HelpBuffer,false); - z = (int)pTVar23; - if (FieldTreated[yy + 0x1f][uStack_7864 + 0x1c] == false) { - pTVar1 = (TWriteScriptFile *)(FileName + 0xffc); - TWriteScriptFile::writeText(pTVar1,"Content="); - TReadBuffer::TReadBuffer - ((TReadBuffer *)local_85c, - HelpBuffer.super_TWriteBuffer.Data, - HelpBuffer.super_TWriteBuffer.Position); - z = (int)pTVar1; - SaveObjects((TReadStream *)local_85c,pTVar1); - TWriteScriptFile::writeLn(pTVar1); - } - goto LAB_0805e656; - } - if (FieldTreated[yy + 0x1f][uStack_7864 + 0x1c] != false) - goto LAB_0805e656; - z = (int)"ProtectionZone, "; - } - } - } - TWriteScriptFile::writeText((TWriteScriptFile *)(FileName + 0xffc),(char *)z); - } - } while( true ); - } -LAB_0805e966: - local_788c = FieldPatched[0x1f] + 0x1c; - iVar8 = 0; - do { - iVar15 = 0; - local_7880 = pTVar3->MapCon[iVar8]; - do { - if (local_788c[iVar15 + -0x400] != false) { - pcVar22 = (char *)(x * 0x20 + iVar8); - GetFirstObject(); - ReadBuffer.Position = local_7880->ObjectID; - bVar7 = GetMapContainerFlags((Object *)&ReadBuffer.Position); - ReadBuffer.Position = NONE.ObjectID; - bVar21 = false; - if ((local_85c == (undefined1 [4])NONE.ObjectID) && (bVar7 == 0)) { - bVar21 = true; - } - if (!bVar21) { - TWriteScriptFile::writeNumber((TWriteScriptFile *)(FileName + 0xffc),iVar8); - TWriteScriptFile::writeText((TWriteScriptFile *)(FileName + 0xffc),"-"); - TWriteScriptFile::writeNumber((TWriteScriptFile *)(FileName + 0xffc),iVar15); - pcVar22 = &DAT_080f2ab7; - TWriteScriptFile::writeText((TWriteScriptFile *)(FileName + 0xffc),": "); - if ((bVar7 & 1) != 0) { - pcVar22 = "Refresh, "; - TWriteScriptFile::writeText - ((TWriteScriptFile *)(FileName + 0xffc),"Refresh, "); - } - if ((bVar7 & 2) != 0) { - pcVar22 = "NoLogout, "; - TWriteScriptFile::writeText - ((TWriteScriptFile *)(FileName + 0xffc),"NoLogout, "); - } - if ((bVar7 & 4) != 0) { - pcVar22 = "ProtectionZone, "; - TWriteScriptFile::writeText - ((TWriteScriptFile *)(FileName + 0xffc),"ProtectionZone, "); - } - ReadBuffer.Position = NONE.ObjectID; - local_83c = (undefined1 [4])NONE.ObjectID; - if (local_85c != (undefined1 [4])NONE.ObjectID) { - TWriteScriptFile::writeText - ((TWriteScriptFile *)(FileName + 0xffc),"Content="); - HelpBuffer.super_TWriteBuffer.Position = 0; - local_83c = local_85c; - SaveObjects((Object *)local_83c,(TWriteStream *)&HelpBuffer,false); - TReadBuffer::TReadBuffer - ((TReadBuffer *)local_83c,HelpBuffer.super_TWriteBuffer.Data, - HelpBuffer.super_TWriteBuffer.Position); - pcVar22 = FileName + 0xffc; - SaveObjects((TReadStream *)local_83c,(TWriteScriptFile *)pcVar22); - } - TWriteScriptFile::writeLn((TWriteScriptFile *)(FileName + 0xffc)); - } - } - local_7880 = local_7880 + 1; - iVar15 = iVar15 + 1; - } while (iVar15 < 0x20); - local_788c = local_788c + 0x20; - iVar8 = iVar8 + 1; - } while (iVar8 < 0x20); - TWriteScriptFile::close((TWriteScriptFile *)(FileName + 0xffc),(int)pcVar22); - if (!bVar19) { - unlink(FileNameBak + 0xffc); - } - pcVar22 = FileNameBak + 0xffc; - iVar8 = rename(&local_784c,pcVar22); - if (iVar8 == 0) { - // try { // try from 0805ea0e to 0805ea12 has its CatchHandler @ 0805f02f - TWriteScriptFile::~TWriteScriptFile((TWriteScriptFile *)(FileName + 0xffc),(int)pcVar22); - // try { // try from 0805ea1c to 0805ea20 has its CatchHandler @ 0805f035 - TReadScriptFile::~TReadScriptFile((TReadScriptFile *)local_483c,(int)pcVar22); - return; - } - // try { // try from 0805ea3e to 0805ec96 has its CatchHandler @ 0805f004 - error("PatchSector: Fehler %d beim Umbenennen von %s.\n",iVar8,&local_784c); - piVar13 = __errno_location(); - pcVar22 = strerror(*piVar13); - error("# Fehler %d: %s.\n",*piVar13,pcVar22); - puVar14 = (undefined4 *)__cxa_allocate_exception(4); - *puVar14 = "cannot patch ORIGMAP"; - // WARNING: Subroutine does not return - __cxa_throw(puVar14,char_const*::typeinfo,0); -code_r0x0805de6d: - cVar5 = TReadScriptFile::getSpecial(Script); - if (cVar5 == ',') goto LAB_0805de50; - TVar10 = Script->Token; -LAB_0805de7e: - if (TVar10 != BYTES) { - if (TVar10 == IDENTIFIER) { - uVar20 = yy == -1; - if ((bool)uVar20) { - TReadScriptFile::error(Script,"coordinate expected"); - } - pcVar22 = TReadScriptFile::getIdentifier(Script); - iVar8 = 8; - pcVar18 = "refresh"; - do { - if (iVar8 == 0) break; - iVar8 = iVar8 + -1; - uVar20 = *pcVar22 == *pcVar18; - pcVar22 = pcVar22 + 1; - pcVar18 = pcVar18 + 1; - } while ((bool)uVar20); - if ((bool)uVar20) { - pTVar3->MapFlags = pTVar3->MapFlags | 1; - if ((!bVar21) || (!SaveHouses)) { - local_85c = (undefined1 [4])pTVar3->MapCon[yy][uStack_7864].ObjectID; - pTVar11 = AccessObject((Object *)local_85c); - pTVar11->Attributes[3] = pTVar11->Attributes[3] | 0x100; - } - goto LAB_0805de50; - } - pcVar22 = TReadScriptFile::getIdentifier(Script); - iVar8 = 9; - pcVar18 = "nologout"; - do { - if (iVar8 == 0) break; - iVar8 = iVar8 + -1; - uVar20 = *pcVar22 == *pcVar18; - pcVar22 = pcVar22 + 1; - pcVar18 = pcVar18 + 1; - } while ((bool)uVar20); - if ((bool)uVar20) { - pTVar3->MapFlags = pTVar3->MapFlags | 2; - if ((!bVar21) || (!SaveHouses)) { - local_85c = (undefined1 [4])pTVar3->MapCon[yy][uStack_7864].ObjectID; - pTVar11 = AccessObject((Object *)local_85c); - pTVar11->Attributes[3] = pTVar11->Attributes[3] | 0x200; - } - goto LAB_0805de50; - } - pcVar22 = TReadScriptFile::getIdentifier(Script); - iVar8 = 0xf; - pcVar18 = "protectionzone"; - do { - if (iVar8 == 0) break; - iVar8 = iVar8 + -1; - uVar20 = *pcVar22 == *pcVar18; - pcVar22 = pcVar22 + 1; - pcVar18 = pcVar18 + 1; - } while ((bool)uVar20); - if ((bool)uVar20) { - pTVar3->MapFlags = pTVar3->MapFlags | 4; - if ((!bVar21) || (!SaveHouses)) { - local_85c = (undefined1 [4])pTVar3->MapCon[yy][uStack_7864].ObjectID; - pTVar11 = AccessObject((Object *)local_85c); - pTVar11->Attributes[3] = pTVar11->Attributes[3] | 0x400; - } - goto LAB_0805de50; - } - pcVar22 = TReadScriptFile::getIdentifier(Script); - iVar8 = 8; - pcVar18 = "content"; - do { - if (iVar8 == 0) break; - iVar8 = iVar8 + -1; - uVar20 = *pcVar22 == *pcVar18; - pcVar22 = pcVar22 + 1; - pcVar18 = pcVar18 + 1; - } while ((bool)uVar20); - if ((bool)uVar20) { - TReadScriptFile::readSymbol(Script,'='); - HelpBuffer.super_TWriteBuffer.Position = 0; - if ((bVar21) && (SaveHouses)) { - LoadObjects(Script,(TWriteStream *)&HelpBuffer,true); - } - else { - LoadObjects(Script,(TWriteStream *)&HelpBuffer,false); - TReadBuffer::TReadBuffer - ((TReadBuffer *)local_85c,HelpBuffer.super_TWriteBuffer.Data, - HelpBuffer.super_TWriteBuffer.Position); - GetMapContainer((int)&ReadBuffer.Position,x * 0x20 + yy,y * 0x20 + uStack_7864); - LoadObjects((TReadStream *)local_85c,(Object *)&ReadBuffer.Position); - } - goto LAB_0805de50; - } - pcVar22 = "unknown map flag"; - } - else { - pcVar22 = "next map point expected"; - } - TReadScriptFile::error(Script,pcVar22); - goto LAB_0805de50; - } - pbVar12 = TReadScriptFile::getBytesequence(Script); - yy = (int)*pbVar12; - uStack_7864 = (uint)pbVar12[1]; - FieldTreated[yy - 1][uStack_7864 + 0x1c] = true; - TReadScriptFile::readSymbol(Script,':'); - bVar21 = false; - iVar8 = uStack_7864 + y * 0x20; - iVar15 = yy + x * 0x20; - bVar6 = IsHouse(iVar15,iVar8,z); - if (!bVar6) { - bVar6 = CoordinateFlag(); - if (bVar6) { - iVar16 = iVar8 + 1; - bVar6 = IsHouse(iVar15 + -1,iVar16,z); - if (((bVar6) || (bVar6 = IsHouse(iVar15,iVar16,z), bVar6)) || - (bVar6 = IsHouse(iVar15 + 1,iVar16,z), bVar6)) goto LAB_0805e1c9; - } - bVar6 = CoordinateFlag(); - if (!bVar6) goto LAB_0805e1d0; - iVar15 = iVar15 + 1; - bVar6 = IsHouse(iVar15,iVar8 + -1,z); - if (((!bVar6) && (bVar6 = IsHouse(iVar15,iVar8,z), !bVar6)) && - (bVar6 = IsHouse(iVar15,iVar8 + 1,z), !bVar6)) goto LAB_0805e1d0; - } -LAB_0805e1c9: - bVar21 = true; -LAB_0805e1d0: - if (bVar21) { - if (SaveHouses) goto LAB_0805de50; - CleanHouseField(x * 0x20 + yy,y * 0x20 + uStack_7864,z); - } - while( true ) { - GetFirstObject(); - while( true ) { - bVar6 = false; - local_83c = (undefined1 [4])NONE.ObjectID; - ReadBuffer.Position = NONE.ObjectID; - if (ReadBuffer_2.Position != NONE.ObjectID) { - local_85c = (undefined1 [4])ReadBuffer_2.Position; - pTVar11 = AccessObject((Object *)local_85c); - ObjectType::setTypeID((ObjectType *)&ReadBuffer.Position,(pTVar11->Type).TypeID); - bVar6 = ReadBuffer.Position == 99; - } - if (!bVar6) break; - local_83c = (undefined1 [4])ReadBuffer_2.Position; - pTVar11 = AccessObject((Object *)local_83c); - local_85c = (undefined1 [4])(pTVar11->NextObject).ObjectID; - ReadBuffer_2.Position = (int)local_85c; - } - if (ReadBuffer_2.Position == NONE.ObjectID) break; - local_85c = (undefined1 [4])ReadBuffer_2.Position; - DeleteObject((Object *)local_85c); - } - local_85c = (undefined1 [4])pTVar3->MapCon[yy][uStack_7864].ObjectID; - pTVar11 = AccessObject((Object *)local_85c); - pTVar11->Attributes[3] = pTVar11->Attributes[3] & 0xffff00ff; - FieldTreated[yy + 0x1f][uStack_7864 + 0x1c] = true; - goto LAB_0805de50; -LAB_0805e958: - TReadScriptFile::close((TReadScriptFile *)local_483c,z); - pcVar22 = (char *)z; - goto LAB_0805e966; -} - void __tcf_0(void *param_1) { diff --git a/src/common.hh b/src/common.hh index 58a28c3..bd3ccd7 100644 --- a/src/common.hh +++ b/src/common.hh @@ -181,7 +181,7 @@ struct TReadStream { struct TReadBuffer: TReadStream { // REGULAR FUNCTIONS // ========================================================================= - TReadBuffer(uint8 *Data, int Size); + TReadBuffer(const uint8 *Data, int Size); // VIRTUAL FUNCTIONS // ========================================================================= diff --git a/src/map.cc b/src/map.cc index 6526434..a5b898d 100644 --- a/src/map.cc +++ b/src/map.cc @@ -970,6 +970,7 @@ void LoadSector(const char *FileName, int SectorX, int SectorY, int SectorZ){ OffsetX = (int)SectorOffset[0]; OffsetY = (int)SectorOffset[1]; Script.readSymbol(':'); + // TODO(fusion): Probably check if offsets are within bounds? continue; } @@ -1297,6 +1298,406 @@ void SaveMap(void){ SavingMap = false; } +void RefreshSector(int SectorX, int SectorY, int SectorZ, TReadStream *Stream){ + // TODO(fusion): `matrix3d::at` will return the first entry if the coordinates + // are out of bounds which that is problematic, specially here. + if(SectorX < SectorXMin || SectorXMax < SectorX + || SectorY < SectorYMin || SectorYMax < SectorY + || SectorZ < SectorZMin || SectorZMax < SectorZ){ + error("RefreshSector: Sector %d/%d/%d is out of bounds.", + SectorX, SectorY, SectorZ); + return; + } + + ASSERT(Sector); + TSector *Sec = *Sector->at(SectorX, SectorY, SectorZ); + if(Sec && (Sec->MapFlags & 0x01) != 0){ + print(3, "Refreshe Sektor %d/%d/%d ...\n", SectorX, SectorY, SectorZ); + while(!Stream->eof()){ + uint8 OffsetX = Stream->readByte(); + uint8 OffsetY = Stream->readByte(); + if(OffsetX < 32 && OffsetY < 32){ + Object Con = Sec->MapCon[OffsetX][OffsetY]; + + // TODO(fusion): This loop was done a bit differently but I suppose + // iterating it directly is clearer and as long as we don't access + // the object after `DeleteObject`, it should work the same. + Object Obj = Con.getAttribute(CONTENT); + while(Obj != NONE){ + Object Next = Obj.getNextObject(); + if(!Obj.getObjectType().isCreatureContainer()){ + DeleteObject(Obj); + } + Obj = Next; + } + + LoadObjects(Stream, Con); + } + } + } +} + +void PatchSector(int SectorX, int SectorY, int SectorZ, bool FullSector, + TReadScriptFile *Script, bool SaveHouses){ + if(SectorX < SectorXMin || SectorXMax < SectorX + || SectorY < SectorYMin || SectorYMax < SectorY + || SectorZ < SectorZMin || SectorZMax < SectorZ){ + error("PatchSector: Sector %d/%d/%d is out of bounds.", + SectorX, SectorY, SectorZ); + return; + } + + ASSERT(Sector); + TSector *Sec = *Sector->at(SectorX, SectorY, SectorZ); + bool NewSector = (Sec == NULL); + if(NewSector){ + print(2, "Lege Sektor %d/%d/%d neu an.\n", SectorX, SectorY, SectorZ); + InitSector(SectorX, SectorY, SectorZ); + Sec = *Sector->at(SectorX, SectorY, SectorZ); + ASSERT(Sec != NULL); + } + + bool FieldTreated[32][32] = {}; + bool FieldPatched[32][32] = {}; + + // NOTE(fusion): Step 1. + // Patch fields specified in the input script. House fields are NOT patched + // if `SaveHouses` is set. + { + bool House = false; + int OffsetX = -1; + int OffsetY = -1; + while(true){ + Script->nextToken(); + if(Script->Token == ENDOFFILE){ + break; + } + + if(Script->Token == SPECIAL && Script->getSpecial() == ','){ + continue; + } + + if(Script->Token == BYTES){ + uint8 *SectorOffset = Script->getBytesequence(); + OffsetX = (int)SectorOffset[0]; + OffsetY = (int)SectorOffset[1]; + Script->readSymbol(':'); + + // TODO(fusion): Probably check if offsets are within bounds? + FieldTreated[OffsetX][OffsetY] = true; + int CoordX = SectorX * 32 + OffsetX; + int CoordY = SectorY * 32 + OffsetY; + int CoordZ = SectorZ; + + // TODO(fusion): Maybe some inlined function? + House = IsHouse(CoordX, CoordY, CoordZ); + if(!House && CoordinateFlag(CoordX, CoordY, CoordZ, HOOKSOUTH)){ + House = IsHouse(CoordX - 1, CoordY + 1, CoordZ) + || IsHouse(CoordX, CoordY + 1, CoordZ) + || IsHouse(CoordX + 1, CoordY + 1, CoordZ); + } + if(!House && CoordinateFlag(CoordX, CoordY, CoordZ, HOOKEAST)){ + House = IsHouse(CoordX + 1, CoordY - 1, CoordZ) + || IsHouse(CoordX + 1, CoordY, CoordZ) + || IsHouse(CoordX + 1, CoordY + 1, CoordZ); + } + + if(House){ + if(SaveHouses){ + continue; + } + CleanHouseField(CoordX, CoordY, CoordZ); + } + + // NOTE(fusion): Similar to `RefreshSector`. + Object Con = Sec->MapCon[OffsetX][OffsetY]; + Object Obj = Con.getAttribute(CONTENT); + while(Obj != NONE){ + Object Next = Obj.getNextObject(); + if(!Obj.getObjectType().isCreatureContainer()){ + DeleteObject(Obj); + } + Obj = Next; + } + // NOTE(fusion): Clear map container flags. See note in `GetObjectCoordinates`. + AccessObject(Con)->Attributes[3] &= 0xFFFF00FF; + FieldPatched[OffsetX][OffsetY] = true; + continue; + } + + if(Script->Token != IDENTIFIER){ + Script->error("next map point expected"); + } + + if(OffsetX == -1 || OffsetY == -1){ + Script->error("coordinate expected"); + } + + const char *Identifier = Script->getIdentifier(); + if(strcmp(Identifier, "refresh") == 0){ + Sec->MapFlags |= 1; + if(!House || !SaveHouses){ + AccessObject(Sec->MapCon[OffsetX][OffsetY])->Attributes[3] |= 0x100; + } + }else if(strcmp(Identifier, "nologout") == 0){ + Sec->MapFlags |= 2; + if(!House || !SaveHouses){ + AccessObject(Sec->MapCon[OffsetX][OffsetY])->Attributes[3] |= 0x200; + } + }else if(strcmp(Identifier, "protectionzone") == 0){ + Sec->MapFlags |= 4; + if(!House || !SaveHouses){ + AccessObject(Sec->MapCon[OffsetX][OffsetY])->Attributes[3] |= 0x400; + } + }else if(strcmp(Identifier, "content") == 0){ + Script->readSymbol('='); + HelpBuffer.reset(); + if(!House || !SaveHouses){ + LoadObjects(Script, &HelpBuffer, false); + TReadBuffer ReadBuffer(HelpBuffer.Data, HelpBuffer.Position); + LoadObjects(&ReadBuffer, Sec->MapCon[OffsetX][OffsetY]); + }else{ + // NOTE(fusion): Skip content. + LoadObjects(Script, &HelpBuffer, true); + } + }else{ + Script->error("unknown map flag"); + } + } + } + + // NOTE(fusion): Step 2. + // Patch fields not specified in the input script if `FullSector` is set. + // Note that patching in this case is simply deleting a field's objects. + // House fields are NOT patched if `SaveHouses` is set. + if(FullSector){ + for(int OffsetX = 0; OffsetX < 32; OffsetX += 1) + for(int OffsetY = 0; OffsetY < 32; OffsetY += 1){ + if(FieldTreated[OffsetX][OffsetY]){ + continue; + } + + int CoordX = SectorX * 32 + OffsetX; + int CoordY = SectorY * 32 + OffsetY; + int CoordZ = SectorZ; + + // TODO(fusion): Maybe some inlined function? + bool House = IsHouse(CoordX, CoordY, CoordZ); + if(!House && CoordinateFlag(CoordX, CoordY, CoordZ, HOOKSOUTH)){ + House = IsHouse(CoordX - 1, CoordY + 1, CoordZ) + || IsHouse(CoordX, CoordY + 1, CoordZ) + || IsHouse(CoordX + 1, CoordY + 1, CoordZ); + } + if(!House && CoordinateFlag(CoordX, CoordY, CoordZ, HOOKEAST)){ + House = IsHouse(CoordX + 1, CoordY - 1, CoordZ) + || IsHouse(CoordX + 1, CoordY, CoordZ) + || IsHouse(CoordX + 1, CoordY + 1, CoordZ); + } + + if(House){ + if(SaveHouses){ + continue; + } + CleanHouseField(CoordX, CoordY, CoordZ); + } + + // NOTE(fusion): Same as in the parsing loop above. + Object Con = Sec->MapCon[OffsetX][OffsetY]; + Object Obj = Con.getAttribute(CONTENT); + while(Obj != NONE){ + Object Next = Obj.getNextObject(); + if(!Obj.getObjectType().isCreatureContainer()){ + DeleteObject(Obj); + } + Obj = Next; + } + AccessObject(Con)->Attributes[3] &= 0xFFFF00FF; + FieldPatched[OffsetX][OffsetY] = true; + } + } + + // NOTE(fusion): Step 3. + // Parse original sector file, transfering non patched fields to a new sector file. + char FileName[4096]; + char FileNameBak[4096]; + snprintf(FileName, sizeof(FileName), "%s/%04d-%04d-%02d.sec", + ORIGMAPPATH, SectorX, SectorY, SectorZ); + snprintf(FileNameBak, sizeof(FileNameBak), "%s/%04d-%04d-%02d.sec~", + ORIGMAPPATH, SectorX, SectorY, SectorZ); + + TWriteScriptFile OUT; + OUT.open(FileNameBak); + OUT.writeText("# Tibia - graphical Multi-User-Dungeon"); + OUT.writeLn(); + OUT.writeText("# Data for sector "); + OUT.writeNumber(SectorX); + OUT.writeText("/"); + OUT.writeNumber(SectorY); + OUT.writeText("/"); + OUT.writeNumber(SectorZ); + OUT.writeLn(); + OUT.writeLn(); + + if(!NewSector){ + TReadScriptFile IN; + IN.open(FileName); + + int OffsetX = -1; + int OffsetY = -1; + int AttrCount = 0; + while(true){ + IN.nextToken(); + if(IN.Token == ENDOFFILE){ + IN.close(); + break; + } + + if(IN.Token == SPECIAL && IN.getSpecial() == ','){ + continue; + } + + if(IN.Token == BYTES){ + uint8 *SectorOffset = IN.getBytesequence(); + OffsetX = (int)SectorOffset[0]; + OffsetY = (int)SectorOffset[1]; + IN.readSymbol(':'); + AttrCount = 0; + // TODO(fusion): Probably check if offsets are within bounds? + if(!FieldPatched[OffsetX][OffsetY]){ + OUT.writeNumber(OffsetX); + OUT.writeText("-"); + OUT.writeNumber(OffsetY); + OUT.writeText(": "); + } + continue; + } + + if(IN.Token != IDENTIFIER){ + IN.error("next map point expected"); + } + + if(OffsetX == -1 || OffsetY == -1){ + IN.error("coordinate expected"); + } + + const char *Identifier = IN.getIdentifier(); + if(strcmp(Identifier, "refresh") == 0){ + if(!FieldPatched[OffsetX][OffsetY]){ + if(AttrCount > 0){ + OUT.writeText(", "); + } + OUT.writeText("Refresh"); + AttrCount += 1; + } + }else if(strcmp(Identifier, "nologout") == 0){ + if(!FieldPatched[OffsetX][OffsetY]){ + if(AttrCount > 0){ + OUT.writeText(", "); + } + OUT.writeText("NoLogout"); + AttrCount += 1; + } + }else if(strcmp(Identifier, "protectionzone") == 0){ + if(!FieldPatched[OffsetX][OffsetY]){ + if(AttrCount > 0){ + OUT.writeText(", "); + } + OUT.writeText("ProtectionZone"); + AttrCount += 1; + } + }else if(strcmp(Identifier, "content") == 0){ + IN.readSymbol('='); + HelpBuffer.reset(); + LoadObjects(&IN, &HelpBuffer, false); + if(!FieldPatched[OffsetX][OffsetY]){ + if(AttrCount > 0){ + OUT.writeText(", "); + } + OUT.writeText("Content="); + TReadBuffer ReadBuffer(HelpBuffer.Data, HelpBuffer.Position); + SaveObjects(&ReadBuffer, &OUT); + AttrCount += 1; + } + }else{ + IN.error("unknown map flag"); + } + } + } + + // NOTE(fusion): Step 4. + // Transfer patched fields from memory into the new sector file. + for(int OffsetX = 0; OffsetX < 32; OffsetX += 1) + for(int OffsetY = 0; OffsetY < 32; OffsetY += 1){ + if(!FieldPatched[OffsetX][OffsetY]){ + continue; + } + + Object Con = Sec->MapCon[OffsetX][OffsetY]; + Object First = Con.getAttribute(CONTENT); + uint8 Flags = GetMapContainerFlags(Con); + if(First != NONE || Flags != 0){ + OUT.writeNumber(OffsetX); + OUT.writeText("-"); + OUT.writeNumber(OffsetY); + OUT.writeText(": "); + + int AttrCount = 0; + + if(Flags & 1){ + if(AttrCount > 0){ + OUT.writeText(", "); + } + OUT.writeText("Refresh"); + AttrCount += 1; + } + + if(Flags & 2){ + if(AttrCount > 0){ + OUT.writeText(", "); + } + OUT.writeText("NoLogout"); + AttrCount += 1; + } + + if(Flags & 4){ + if(AttrCount > 0){ + OUT.writeText(", "); + } + OUT.writeText("ProtectionZone"); + AttrCount += 1; + } + + if(First != NONE){ + if(AttrCount > 0){ + OUT.writeText(", "); + } + OUT.writeText("Content="); + HelpBuffer.reset(); + SaveObjects(First, &HelpBuffer, false); + TReadBuffer ReadBuffer(HelpBuffer.Data, HelpBuffer.Position); + SaveObjects(&ReadBuffer, &OUT); + AttrCount += 1; + } + + OUT.writeLn(); + } + } + OUT.close(); + + // NOTE(fusion): Step 5. + // Replace original sector file with the new one. + if(!NewSector){ + unlink(FileName); + } + + if(rename(FileNameBak, FileName) != 0){ + int ErrCode = errno; + error("PatchSector: Fehler %d beim Umbenennen von %s.\n", ErrCode, FileNameBak); + error("# Fehler %d: %s.\n", ErrCode, strerror(ErrCode)); + throw "cannot patch ORIGMAP"; + } +} + void InitMap(void){ ReadMapConfig(); @@ -1429,6 +1830,8 @@ Object CreateObject(void){ return Object(NextObjectID); } +// TODO(fusion): This is only used from `DeleteObject`. Should probably be an +// internal helper. void DestroyObject(Object Obj){ if(!Obj.exists()){ error("DestroyObject: Übergebenes Objekt existiert nicht.\n"); diff --git a/src/map.hh b/src/map.hh index 38aface..3ab919d 100644 --- a/src/map.hh +++ b/src/map.hh @@ -120,8 +120,9 @@ void SaveObjects(Object Obj, TWriteStream *Stream, bool Stop); void SaveObjects(TReadStream *Stream, TWriteScriptFile *Script); void SaveSector(char *FileName, int SectorX, int SectorY, int SectorZ); void SaveMap(void); -//RefreshSector -//PatchSector +void RefreshSector(int SectorX, int SectorY, int SectorZ, TReadStream *Stream); +void PatchSector(int SectorX, int SectorY, int SectorZ, bool FullSector, + TReadScriptFile *Script, bool SaveHouses); void InitMap(void); void ExitMap(bool Save); diff --git a/src/stubs.hh b/src/stubs.hh index 1c3bde0..d0b7d90 100644 --- a/src/stubs.hh +++ b/src/stubs.hh @@ -11,7 +11,7 @@ // IMPORTANT(fusion): These function definitions exist to test compilation. They're // not yet implemented and will cause the linker to fail with unresolved symbols. -typedef void TRefreshSectorFunction(int SectorX, int SectorY, int SectorZ, TReadStream *Stream); +typedef void TRefreshSectorFunction(int SectorX, int SectorY, int SectorZ, const uint8 *Data, int Size); typedef void TSendMailsFunction(TPlayerData *PlayerData); extern void AbortWriter(void); @@ -20,6 +20,7 @@ extern void AnnounceChangedCreature(uint32 CreatureID, int Type); extern void BroadcastMessage(int Mode, const char *Text, ...) ATTR_PRINTF(2, 3); extern void Change(Object Obj, ObjectType NewType, uint32 Value); extern bool CheckRight(uint32 CreatureID, RIGHT Right); +extern void CleanHouseField(int x, int y, int z); extern void CleanupDynamicStrings(void); extern void CreatePlayerList(bool Online); extern void DeleteDynamicString(uint32 Number); @@ -46,7 +47,7 @@ extern void ProcessWriterThreadReplies(void); extern void ReceiveData(void); extern void RefreshCylinders(void); extern void RefreshMap(void); -extern void RefreshSector(int SectorX, int SectorY, int SectorZ, TReadStream *Stream); +extern void RefreshSector(int SectorX, int SectorY, int SectorZ, const uint8 *Data, int Size); extern void SavePlayerDataOrder(void); extern void SendAll(void); extern void SendAmbiente(TConnection *Connection); diff --git a/src/util.cc b/src/util.cc index e0e335b..0982cd7 100644 --- a/src/util.cc +++ b/src/util.cc @@ -228,7 +228,7 @@ void TReadStream::readBytes(uint8 *Buffer, int Count){ // TReadBuffer // ============================================================================= -TReadBuffer::TReadBuffer(uint8 *Data, int Size){ +TReadBuffer::TReadBuffer(const uint8 *Data, int Size){ if(Data == NULL){ error("TReadBuffer::TReadBuffer: data ist NULL.\n"); Size = 0; -- cgit v1.2.3