From 81a5d53bc566fe2c678577cb3f3e5cadd0711753 Mon Sep 17 00:00:00 2001 From: fusion32 Date: Tue, 10 Jun 2025 19:19:09 -0300 Subject: finish `info.cc` --- reference/game.c | 800 ------------------------------------------------------- src/common.hh | 5 + src/enums.hh | 2 +- src/info.cc | 406 +++++++++++++++++++++++++++- src/info.hh | 8 + src/magic.cc | 4 +- src/objects.cc | 22 -- src/stubs.hh | 4 - src/util.cc | 25 ++ 9 files changed, 446 insertions(+), 830 deletions(-) diff --git a/reference/game.c b/reference/game.c index bb0c72f..c00ab3e 100644 --- a/reference/game.c +++ b/reference/game.c @@ -12327,806 +12327,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority // WARNING: Unknown calling convention -- yet parameter storage is locked -bool SearchFlightField(void) - -{ - TCreature *pTVar1; - TCreature *pTVar2; - int iVar3; - TCreature *Pursuer; - int dy; - int dx; - int iVar4; - TCreature *Fugitive; - ulong in_stack_00000004; - ulong in_stack_00000008; - int *in_stack_0000000c; - int *in_stack_00000010; - int *in_stack_00000014; - char *Text; - int local_4c; - int Try [9]; - - pTVar1 = GetCreature(in_stack_00000004); - if (pTVar1 == (TCreature *)0x0) { - Text = &DAT_080f75c0; - } - else { - pTVar2 = GetCreature(in_stack_00000008); - if (pTVar2 == (TCreature *)0x0) { - Text = "SearchFlightField: Verfolger existiert nicht.\n"; - } - else { - if (pTVar1->posz == pTVar2->posz) { - iVar3 = 0; - do { - Try[iVar3 + -1] = 0; - iVar3 = iVar3 + 1; - } while (iVar3 < 9); - iVar3 = pTVar1->posy - pTVar2->posy; - iVar4 = pTVar1->posx - pTVar2->posx; - if (-1 < iVar4) { - Try[0] = 1; - } - if (iVar3 < 1) { - Try[1] = 3; - } - if (iVar4 < 1) { - Try[2] = 5; - } - if (-1 < iVar3) { - Try[3] = 7; - } - RandomShuffle(Try,4); - if (iVar3 <= iVar4) { - Try[4] = 2; - } - if (iVar4 <= -iVar3) { - Try[5] = 4; - } - if (iVar4 <= iVar3) { - Try[6] = 6; - } - if (SBORROW4(iVar4,-iVar3) == iVar4 + iVar3 < 0) { - Try[7] = 8; - } - RandomShuffle(Try + 4,4); - *in_stack_00000014 = pTVar1->posz; - iVar3 = 0; - do { - iVar4 = Try[iVar3 + -1]; - if (iVar4 == 0) goto LAB_08071259; - switch(iVar4) { - case 1: - iVar4 = pTVar1->posx + 1; - goto LAB_08071212; - case 2: - iVar4 = pTVar1->posx + 1; - break; - case 3: - iVar4 = pTVar1->posx; - break; - case 4: - iVar4 = pTVar1->posx + -1; - break; - case 5: - iVar4 = pTVar1->posx + -1; -LAB_08071212: - *in_stack_0000000c = iVar4; - iVar4 = pTVar1->posy; - goto LAB_0807121d; - case 6: - iVar4 = pTVar1->posx + -1; - goto LAB_080712bc; - case 7: - iVar4 = pTVar1->posx; - goto LAB_080712bc; - case 8: - iVar4 = pTVar1->posx + 1; -LAB_080712bc: - *in_stack_0000000c = iVar4; - iVar4 = pTVar1->posy + 1; - goto LAB_0807121d; - default: - error(&DAT_080f7540,iVar4); - return false; - } - *in_stack_0000000c = iVar4; - iVar4 = pTVar1->posy + -1; -LAB_0807121d: - *in_stack_00000010 = iVar4; - iVar4 = (*pTVar1->_vptr_TCreature[3]) - (pTVar1,*in_stack_0000000c,*in_stack_00000010, - *in_stack_00000014,0,0); - if ((char)iVar4 != '\0') { - return true; - } -LAB_08071259: - iVar3 = iVar3 + 1; - if (8 < iVar3) { - return false; - } - } while( true ); - } - Text = &DAT_080f74e0; - } - } - error(Text); - return false; -} - - - -// WARNING: Variable defined which should be unmapped: TieBreaker - -bool SearchSummonField(int *x,int *y,int *z,int Distance) - -{ - bool bVar1; - bool bVar2; - long lVar3; - int dy; - int iVar4; - int NewTieBreaker; - int dx; - int BestY; - int BestX; - int TieBreaker; - - dx = 0; - BestX = -1; - BestY = 0; - NewTieBreaker = -Distance; - if (-Distance == Distance || NewTieBreaker < Distance) { - do { - iVar4 = -Distance; - if (-Distance == Distance || iVar4 < Distance) { - do { - lVar3 = random(); - if (BestX < lVar3) { - bVar2 = false; - bVar1 = CoordinateFlag(); - if (bVar1) { - bVar2 = CoordinateFlag(); - bVar2 = !bVar2; - } - if ((((bVar2) && (bVar2 = CoordinateFlag(), !bVar2)) && - (bVar2 = IsProtectionZone(), !bVar2)) && - ((bVar2 = IsHouse(NewTieBreaker + *x,*y + iVar4,*z), !bVar2 && - (bVar2 = ThrowPossible(*x,*y,*z,NewTieBreaker + *x,*y + iVar4,*z,0), - bVar2)))) { - BestY = NewTieBreaker + *x; - dx = *y + iVar4; - BestX = lVar3; - } - } - iVar4 = iVar4 + 1; - } while (iVar4 <= Distance); - } - NewTieBreaker = NewTieBreaker + 1; - } while (NewTieBreaker <= Distance); - } - if (BestX != -1) { - *x = BestY; - *y = dx; - } - return BestX != -1; -} - - - -bool ThrowPossible(int sx,int sy,int sz,int zx,int zy,int zz,int Power) - -{ - uint uVar1; - bool bVar2; - bool bVar3; - int iVar4; - int newz; - int z; - int iVar5; - int iVar6; - int *piVar7; - int iVar8; - int zmin; - int iVar9; - int newy; - int iVar10; - uint local_68; - int i; - int local_5c; - int z_1; - int local_54; - int local_50; - Object local_4c; - Object Obj_1; - Object local_2c; - Object Obj; - - iVar5 = sz + -1; - local_5c = sz - Power; - if (local_5c < 0) { - local_5c = 0; - } - do { - if (iVar5 < local_5c) { -LAB_08071587: - if (local_5c <= zz) { - iVar4 = zx - sx; - iVar6 = zy - sy; - iVar5 = zz; - while( true ) { - piVar7 = &zz; - if (sz <= iVar5) { - piVar7 = &sz; - } - if (*piVar7 < local_5c) break; - if ((zx != sx) || (iVar9 = zx, iVar10 = zy, zy != sy)) { - local_68 = 1; - local_50 = -iVar4; - if (-1 < iVar4) { - local_50 = iVar4; - } - local_54 = -iVar6; - if (-1 < iVar6) { - local_54 = iVar6; - } - piVar7 = &local_54; - if (local_54 <= local_50) { - piVar7 = &local_50; - } - iVar10 = *piVar7; - bVar2 = CoordinateFlag(); - if (bVar2) { - local_68 = (uint)(sx <= zx); - } - bVar2 = CoordinateFlag(); - uVar1 = local_68; - if ((bVar2) && (uVar1 = 0, sy <= zy)) { - uVar1 = local_68; - } - while (((int)uVar1 <= iVar10 && (bVar2 = CoordinateFlag(), !bVar2))) { - uVar1 = uVar1 + 1; - } - iVar8 = (iVar10 - uVar1) + 1; - iVar5 = zz; - iVar9 = (int)(zx * (uVar1 - 1) + sx * iVar8) / iVar10; - iVar10 = (int)((uVar1 - 1) * zy + sy * iVar8) / iVar10; - } - iVar8 = local_5c; - if ((local_5c < 0xf) && (local_5c < iVar5)) { - do { - GetFirstObject(); - bVar2 = false; - local_2c.ObjectID = NONE.ObjectID; - if (local_4c.ObjectID != NONE.ObjectID) { - Object::getObjectType(&local_2c); - bVar3 = ObjectType::getFlag((ObjectType *)&local_2c,BANK); - if (bVar3) { - bVar2 = true; - } - } - iVar5 = zz; - } while ((!bVar2) && (iVar8 = iVar8 + 1, iVar8 < zz)); - } - if ((iVar9 == zx) && ((iVar10 == zy && (iVar8 == iVar5)))) { - return true; - } - local_5c = local_5c + 1; - } - } - return false; - } - GetFirstObject(); - bVar2 = false; - local_4c.ObjectID = NONE.ObjectID; - if (local_2c.ObjectID != NONE.ObjectID) { - Object::getObjectType(&local_4c); - bVar3 = ObjectType::getFlag((ObjectType *)&local_4c,BANK); - if (bVar3) { - bVar2 = true; - } - } - if (bVar2) { - local_5c = iVar5 + 1; - goto LAB_08071587; - } - iVar5 = iVar5 + -1; - } while( true ); -} - - - -void GetCreatureLight(ulong CreatureID,int *Brightness,int *Color) - -{ - TSkill *pTVar1; - bool bVar2; - bool bVar3; - TPlayer *pl; - TCreature *pTVar4; - ulong uVar5; - TPlayer *pTVar6; - int *piVar7; - byte bVar8; - TCreature *cr; - int i; - int iVar9; - int local_6c; - int b; - int Blue; - int g; - int Green; - int r; - int Red; - int B; - Object local_4c [4]; - ulong local_3c; - ulong local_2c; - Object Obj; - - pTVar4 = GetCreature(CreatureID); - if (pTVar4 == (TCreature *)0x0) { - error("GetCreatureLight: Kreatur existiert nicht.\n"); - *Brightness = 0; - *Color = 0; - } - else { - *Brightness = 0; - pTVar1 = (pTVar4->super_TSkillBase).Skills[0xf]; - if (pTVar1 != (TSkill *)0x0) { - iVar9 = (*pTVar1->_vptr_TSkill[0xd])(pTVar1); - *Brightness = iVar9; - } - if (pTVar4->Type == PLAYER) { - pTVar6 = GetPlayer(CreatureID); - if (pTVar6 == (TPlayer *)0x0) { - error("CheckRight: Spieler existiert nicht; Right=%d.\n",0x48); - bVar8 = 0; - } - else { - bVar8 = pTVar6->Rights[9] & 1; - } - if (bVar8 != 0) { - B = 7; - piVar7 = &B; - if (6 < *Brightness) { - piVar7 = Brightness; - } - *Brightness = *piVar7; - } - } - iVar9 = 1; - r = *Brightness * 5; - g = *Brightness * 5; - b = *Brightness * 5; - do { - bVar2 = false; - GetBodyObject((ulong)&local_2c,CreatureID); - local_3c = NONE.ObjectID; - local_4c[0].ObjectID = NONE.ObjectID; - if (local_2c != NONE.ObjectID) { - Object::getObjectType(local_4c); - bVar3 = ObjectType::getFlag((ObjectType *)local_4c,LIGHT); - if (bVar3) { - bVar2 = true; - } - } - if (bVar2) { - Object::getObjectType(local_4c); - Red = ObjectType::getAttribute((ObjectType *)local_4c,BRIGHTNESS); - Object::getObjectType(local_4c); - uVar5 = ObjectType::getAttribute((ObjectType *)local_4c,LIGHTCOLOR); - Green = ((int)uVar5 / 0x24) * Red; - Blue = ((int)uVar5 / 6 + ((int)uVar5 / 0x24) * -6) * Red; - local_6c = ((int)uVar5 % 6) * Red; - piVar7 = &Red; - if (Red <= *Brightness) { - piVar7 = Brightness; - } - *Brightness = *piVar7; - piVar7 = &Green; - if (Green <= r) { - piVar7 = &r; - } - r = *piVar7; - piVar7 = &Blue; - if (Blue <= g) { - piVar7 = &g; - } - g = *piVar7; - piVar7 = &local_6c; - if (local_6c <= b) { - piVar7 = &b; - } - b = *piVar7; - } - iVar9 = iVar9 + 1; - } while (iVar9 < 0xb); - iVar9 = *Brightness; - if (iVar9 == 0) { - *Color = 0; - } - else { - *Color = b / iVar9 + (g / iVar9) * 6 + (r / iVar9) * 0x24; - } - } - return; -} - - - -int GetInventoryWeight(ulong CreatureID) - -{ - TCreature *cr; - TCreature *pTVar1; - int iVar2; - Object local_1c [5]; - - pTVar1 = GetCreature(CreatureID); - if (pTVar1 == (TCreature *)0x0) { - error("GetInventoryWeight: Kreatur %d existiert nicht.\n",CreatureID); - iVar2 = 0; - } - else { - GetFirstContainerObject(local_1c); - iVar2 = GetRowWeight(local_1c); - } - return iVar2; -} - - - -bool CheckRight(ulong CharacterID,RIGHT Right) - -{ - TPlayer *pTVar1; - int iVar2; - TPlayer *pl; - char *Text; - RIGHT RVar3; - - pTVar1 = GetPlayer(CharacterID); - if (pTVar1 == (TPlayer *)0x0) { - Text = "CheckRight: Spieler existiert nicht; Right=%d.\n"; - } - else { - if (-1 < (int)Right) { - RVar3 = Right + KICK; - if (-1 < (int)Right) { - RVar3 = Right; - } - iVar2 = (int)RVar3 >> 3; - if (iVar2 < 0xc) { - return (bool)((byte)((int)(uint)pTVar1->Rights[iVar2] >> - ((char)Right - (char)(iVar2 << 3) & 0x1fU)) & 1); - } - } - Text = &DAT_080f76c0; - } - error(Text,Right); - return false; -} - - - -bool CheckBanishmentRight(ulong CharacterID,int Reason,int Action) - -{ - uint uVar1; - bool bVar2; - byte bVar3; - TPlayer *pl; - TPlayer *pTVar4; - TPlayer *pl_1; - int iVar5; - bool bVar7; - char *pcVar8; - undefined4 uVar9; - uint uVar6; - - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 == (TPlayer *)0x0) { - error("CheckBanishmentRight: Spieler existiert nicht.\n"); - return false; - } - bVar7 = false; - if ((-1 < Reason) && (Reason < 0x20)) { - bVar7 = true; - } - if (!bVar7) { - pcVar8 = &DAT_080f7740; - Action = Reason; -LAB_08071c14: - error(pcVar8,Action,CharacterID); - return false; - } - bVar7 = false; - if ((-1 < Action) && (Action < 7)) { - bVar7 = true; - } - if (!bVar7) { - pcVar8 = &DAT_080f7700; - goto LAB_08071c14; - } - uVar1 = Reason + 0x12; - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 == (TPlayer *)0x0) { - pcVar8 = "CheckRight: Spieler existiert nicht; Right=%d.\n"; -LAB_08071c63: - error(pcVar8,uVar1); - bVar3 = 0; - } - else { - if ((int)uVar1 < 0) { -LAB_08071c58: - pcVar8 = &DAT_080f76c0; - goto LAB_08071c63; - } - uVar6 = uVar1; - if (0x7fffffff < uVar1) { - uVar6 = Reason + 0x19; - } - iVar5 = (int)uVar6 >> 3; - if (0xb < iVar5) goto LAB_08071c58; - bVar3 = (byte)((int)(uint)pTVar4->Rights[iVar5] >> - ((char)uVar1 - (char)(iVar5 << 3) & 0x1fU)) & 1; - } - if (bVar3 == 0) { - return false; - } - bVar7 = false; - switch(Action) { - case 0: - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 == (TPlayer *)0x0) { - error("CheckRight: Spieler existiert nicht; Right=%d.\n",1); - bVar7 = false; - } - else { - bVar7 = (bool)((byte)((int)(uint)pTVar4->Rights[0] >> 1) & 1); - } - break; - case 1: - bVar7 = false; - if ((0x11 < (int)uVar1) && (bVar7 = true, 0x1a < (int)uVar1)) { - bVar7 = false; - } - if (!bVar7) { - return false; - } - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 != (TPlayer *)0x0) { - bVar3 = (byte)((int)(uint)pTVar4->Rights[0] >> 2); - goto LAB_08071cf8; - } - uVar9 = 2; - goto LAB_08071d12; - case 2: - bVar7 = false; - if ((0x11 < (int)uVar1) && (bVar7 = true, 0x1a < (int)uVar1)) { - bVar7 = false; - } - if (bVar7) { - return false; - } - goto LAB_08071d3a; - case 3: - bVar7 = false; - if ((0x11 < (int)uVar1) && (bVar7 = true, 0x1a < (int)uVar1)) { - bVar7 = false; - } - if (!bVar7) { - return false; - } - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 == (TPlayer *)0x0) { - error("CheckRight: Spieler existiert nicht; Right=%d.\n",2); - bVar3 = 0; - } - else { - bVar3 = (byte)((int)(uint)pTVar4->Rights[0] >> 2) & 1; - } - if (bVar3 == 0) { - return false; - } -LAB_08071d3a: - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 == (TPlayer *)0x0) { - uVar9 = 4; -LAB_08071d12: - error("CheckRight: Spieler existiert nicht; Right=%d.\n",uVar9); - bVar3 = 0; - } - else { - bVar3 = (byte)((int)(uint)pTVar4->Rights[0] >> 4); -LAB_08071cf8: - bVar3 = bVar3 & 1; - } - bVar7 = bVar3 != 0; - break; - case 4: - bVar7 = false; - if ((0x11 < (int)uVar1) && (bVar7 = true, 0x1a < (int)uVar1)) { - bVar7 = false; - } - if (bVar7) { - return false; - } - goto LAB_08071ddc; - case 5: - bVar7 = false; - if ((0x11 < (int)uVar1) && (bVar7 = true, 0x1a < (int)uVar1)) { - bVar7 = false; - } - if (!bVar7) { - return false; - } - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 == (TPlayer *)0x0) { - error("CheckRight: Spieler existiert nicht; Right=%d.\n",2); - bVar3 = 0; - } - else { - bVar3 = (byte)((int)(uint)pTVar4->Rights[0] >> 2) & 1; - } - if (bVar3 == 0) { - return false; - } -LAB_08071ddc: - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 == (TPlayer *)0x0) { - error("CheckRight: Spieler existiert nicht; Right=%d.\n",4); - bVar3 = 0; - } - else { - bVar3 = (byte)((int)(uint)pTVar4->Rights[0] >> 4) & 1; - } - if (bVar3 == 0) { - return false; - } - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 != (TPlayer *)0x0) { - bVar3 = (byte)((int)(uint)pTVar4->Rights[0] >> 5); - goto LAB_08071cf8; - } - uVar9 = 5; - goto LAB_08071d12; - case 6: - bVar7 = false; - bVar2 = false; - if ((0x1a < (int)uVar1) && (bVar2 = true, 0x2d < (int)uVar1)) { - bVar2 = false; - } - if ((bVar2) || (Reason == 0x1d)) { - pTVar4 = GetPlayer(CharacterID); - if (pTVar4 == (TPlayer *)0x0) { - error("CheckRight: Spieler existiert nicht; Right=%d.\n",3); - bVar3 = 0; - } - else { - bVar3 = (byte)((int)(uint)pTVar4->Rights[0] >> 3) & 1; - } - bVar7 = bVar3 != 0; - } - } - return bVar7; -} - - - -char * GetBanishmentReason(int Reason) - -{ - char *pcVar1; - - switch(Reason) { - case 0: - pcVar1 = "NAME_INSULTING"; - break; - case 1: - pcVar1 = "NAME_SENTENCE"; - break; - case 2: - pcVar1 = "NAME_NONSENSICAL_LETTERS"; - break; - case 3: - pcVar1 = "NAME_BADLY_FORMATTED"; - break; - case 4: - pcVar1 = "NAME_NO_PERSON"; - break; - case 5: - pcVar1 = "NAME_CELEBRITY"; - break; - case 6: - pcVar1 = "NAME_COUNTRY"; - break; - case 7: - pcVar1 = "NAME_FAKE_IDENTITY"; - break; - case 8: - pcVar1 = "NAME_FAKE_POSITION"; - break; - case 9: - pcVar1 = "STATEMENT_INSULTING"; - break; - case 10: - pcVar1 = "STATEMENT_SPAMMING"; - break; - case 0xb: - pcVar1 = "STATEMENT_ADVERT_OFFTOPIC"; - break; - case 0xc: - pcVar1 = "STATEMENT_ADVERT_MONEY"; - break; - case 0xd: - pcVar1 = "STATEMENT_NON_ENGLISH"; - break; - case 0xe: - pcVar1 = "STATEMENT_CHANNEL_OFFTOPIC"; - break; - case 0xf: - pcVar1 = "STATEMENT_VIOLATION_INCITING"; - break; - case 0x10: - pcVar1 = "CHEATING_BUG_ABUSE"; - break; - case 0x11: - pcVar1 = "CHEATING_GAME_WEAKNESS"; - break; - case 0x12: - pcVar1 = "CHEATING_MACRO_USE"; - break; - case 0x13: - pcVar1 = "CHEATING_MODIFIED_CLIENT"; - break; - case 0x14: - pcVar1 = "CHEATING_HACKING"; - break; - case 0x15: - pcVar1 = "CHEATING_MULTI_CLIENT"; - break; - case 0x16: - pcVar1 = "CHEATING_ACCOUNT_TRADING"; - break; - case 0x17: - pcVar1 = "CHEATING_ACCOUNT_SHARING"; - break; - case 0x18: - pcVar1 = "GAMEMASTER_THREATENING"; - break; - case 0x19: - pcVar1 = "GAMEMASTER_PRETENDING"; - break; - case 0x1a: - pcVar1 = "GAMEMASTER_INFLUENCE"; - break; - case 0x1b: - pcVar1 = "GAMEMASTER_FALSE_REPORTS"; - break; - case 0x1c: - pcVar1 = "KILLING_EXCESSIVE_UNJUSTIFIED"; - break; - case 0x1d: - pcVar1 = "DESTRUCTIVE_BEHAVIOUR"; - break; - case 0x1e: - pcVar1 = "SPOILING_AUCTION"; - break; - case 0x1f: - pcVar1 = "INVALID_PAYMENT"; - break; - default: - error(&DAT_080f77c0,Reason); - pcVar1 = ""; - } - return pcVar1; -} - -// WARNING: Unknown calling convention -- yet parameter storage is locked - void _GLOBAL__I__Z7GetName6Object(void) { diff --git a/src/common.hh b/src/common.hh index ded9079..9800e6a 100644 --- a/src/common.hh +++ b/src/common.hh @@ -169,6 +169,11 @@ int stricmp(const char *s1, const char *s2, int Max = INT_MAX); char *findFirst(char *s, char c); char *findLast(char *s, char c); +bool CheckBitIndex(int BitSetBytes, int Index); +bool CheckBit(uint8 *BitSet, int Index); +void SetBit(uint8 *BitSet, int Index); +void ClearBit(uint8 *BitSet, int Index); + template void RandomShuffle(T *Buffer, int Size){ if(Buffer == NULL){ diff --git a/src/enums.hh b/src/enums.hh index 5f7810c..940d19e 100644 --- a/src/enums.hh +++ b/src/enums.hh @@ -91,7 +91,7 @@ enum DamageType: int { // NOTE(fusion): Not in debug symbols. enum Direction: int { - DIRECTION_INVALID = -1, + DIRECTION_NONE = -1, DIRECTION_NORTH = 0, DIRECTION_EAST = 1, DIRECTION_SOUTH = 2, diff --git a/src/info.cc b/src/info.cc index fc1df61..d15f470 100644 --- a/src/info.cc +++ b/src/info.cc @@ -908,7 +908,6 @@ bool SearchSpawnField(int *x, int *y, int *z, int Distance, bool Player){ matrix Map(-Distance, Distance, -Distance, Distance, INT_MAX); *Map.at(0, 0) = 0; - int BestX = 0; int BestY = 0; int BestTieBreaker = -1; @@ -1014,6 +1013,411 @@ bool SearchSpawnField(int *x, int *y, int *z, int Distance, bool Player){ return Result; } +bool SearchFlightField(uint32 FugitiveID, uint32 PursuerID, int *x, int *y, int *z){ + TCreature *Fugitive = GetCreature(FugitiveID); + if(Fugitive == NULL){ + error("SearchFlightField: Flüchtling existiert nicht.\n"); + return false; + } + + TCreature *Pursuer = GetCreature(PursuerID); + if(Pursuer == NULL){ + error("SearchFlightField: Verfolger existiert nicht.\n"); + return false; + } + + if(Fugitive->posz != Pursuer->posz){ + error("SearchFlightField: Flüchtling und Verfolger sind auf verschiedenen Ebenen.\n"); + return false; + } + + // NOTE(fusion): Fugitive's coordinates relative to the pursuer. + int FugitiveX = Fugitive->posx - Pursuer->posx; + int FugitiveY = Fugitive->posy - Pursuer->posy; + + int Try[8] = {}; + for(int i = 0; i < NARRAY(Try); i += 1){ + Try[i] = DIRECTION_NONE; + } + + if(FugitiveY <= 0){ + Try[0] = DIRECTION_NORTH; + } + + if(FugitiveX >= 0){ + Try[1] = DIRECTION_EAST; + } + + if(FugitiveY >= 0){ + Try[2] = DIRECTION_SOUTH; + } + + if(FugitiveX <= 0){ + Try[3] = DIRECTION_WEST; + } + + if(FugitiveX <= 0 && FugitiveY >= 0){ + Try[4] = DIRECTION_SOUTHWEST; + } + + if(FugitiveX >= 0 && FugitiveY >= 0){ + Try[5] = DIRECTION_SOUTHEAST; + } + + if(FugitiveX >= 0 && FugitiveY <= 0){ + Try[6] = DIRECTION_NORTHEAST; + } + + if(FugitiveX <= 0 && FugitiveY <= 0){ + Try[7] = DIRECTION_NORTHWEST; + } + + RandomShuffle(&Try[0], 4); + RandomShuffle(&Try[4], 4); + for(int i = 0; i < NARRAY(Try); i += 1){ + if(Try[i] == DIRECTION_NONE){ + continue; + } + + int FieldX = Fugitive->posx; + int FieldY = Fugitive->posy; + int FieldZ = Fugitive->posz; + switch(Try[i]){ + case DIRECTION_NORTH: FieldY -= 1; break; + case DIRECTION_EAST: FieldX += 1; break; + case DIRECTION_SOUTH: FieldY += 1; break; + case DIRECTION_WEST: FieldX -= 1; break; + case DIRECTION_SOUTHWEST: FieldX -= 1; FieldY += 1; break; + case DIRECTION_SOUTHEAST: FieldX += 1; FieldY += 1; break; + case DIRECTION_NORTHWEST: FieldX -= 1; FieldY -= 1; break; + case DIRECTION_NORTHEAST: FieldX += 1; FieldY -= 1; break; + default:{ + error("SearchFlightField: Ungültige Richtung %d.\n", Try[i]); + return false; + } + } + + if(Fugitive->MovePossible(FieldX, FieldY, FieldZ, false, false)){ + *x = FieldX; + *y = FieldY; + return true; + } + } + + return false; +} + +bool SearchSummonField(int *x, int *y, int *z, int Distance){ + int BestX = 0; + int BestY = 0; + int BestTieBreaker = -1; + for(int OffsetY = -Distance; OffsetY <= Distance; OffsetY += 1) + for(int OffsetX = -Distance; OffsetX <= Distance; OffsetX += 1){ + int TieBreaker = random(0, 99); + if(TieBreaker <= BestTieBreaker){ + continue; + } + + int FieldX = *x + OffsetX; + int FieldY = *y + OffsetY; + int FieldZ = *z; + if(CoordinateFlag(FieldX, FieldY, FieldZ, BANK) + && !CoordinateFlag(FieldX, FieldY, FieldZ, UNPASS) + && !CoordinateFlag(FieldX, FieldY, FieldZ, AVOID) + && !IsProtectionZone(FieldX, FieldY, FieldZ) + && !IsHouse(FieldX, FieldY, FieldZ) + && ThrowPossible(*x, *y, *z, FieldX, FieldY, FieldZ, 0)){ + BestX = FieldX; + BestY = FieldY; + BestTieBreaker = TieBreaker; + } + } + + bool Result = false; + if(BestTieBreaker >= 0){ + *x = BestX; + *y = BestY; + Result = true; + } + + return Result; +} + +bool ThrowPossible(int OrigX, int OrigY, int OrigZ, + int DestX, int DestY, int DestZ, int Power){ + // NOTE(fusion): `MinZ` contains the highest floor we're able to throw. We'll + // iterate from it towards the destination floor, checking the line between the + // origin and destination until we find a valid throwing path (or not). + int MinZ = std::max(OrigZ - Power, 0); + for(int CurZ = OrigZ - 1; CurZ >= MinZ; CurZ -= 1){ + Object Obj = GetFirstObject(OrigX, OrigY, CurZ); + if(Obj != NONE && Obj.getObjectType().getFlag(BANK)){ + MinZ = CurZ + 1; + break; + } + } + + // NOTE(fusion): I'm using `T` as the parameter for the line between the + // origin and destination. + int MaxT = std::max( + std::abs(DestX - OrigX), + std::abs(DestY - OrigX)); + + int StartT = 1; + if((DestX < OrigX && CoordinateFlag(OrigX, OrigY, OrigZ, HOOKEAST)) + || (DestY < OrigY && CoordinateFlag(OrigX, OrigY, OrigZ, HOOKSOUTH))){ + StartT = 0; + } + + while(MinZ <= DestZ){ + int LastX = OrigX; + int LastY = OrigY; + if(DestX != OrigX || DestY != OrigY){ + // NOTE(fusion): Get the current coordinates with linear interpolation. + for(int T = StartT; T <= MaxT; T += 1){ + int CurX = (OrigX * (MaxT - T) + DestX * T) / MaxT; + int CurY = (OrigY * (MaxT - T) + DestY * T) / MaxT; + int CurZ = MinZ; + if(CoordinateFlag(CurX, CurY, CurZ, UNTHROW)){ + break; + } + + LastX = CurX; + LastY = CurY; + } + } + + if(LastX == DestX && LastY == DestY){ + int LastZ = MinZ; + for(; LastZ < DestZ; LastZ += 1){ + Object Obj = GetFirstObject(DestX, DestY, LastZ); + if(Obj != NONE && Obj.getObjectType().getFlag(BANK)){ + break; + } + } + + if(LastZ == DestZ){ + return true; + } + } + + MinZ += 1; + } + + return false; +} + +void GetCreatureLight(uint32 CreatureID, int *Brightness, int *Color){ + TCreature *Creature = GetCreature(CreatureID); + if(Creature == NULL){ + error("GetCreatureLight: Kreatur existiert nicht.\n"); + *Brightness = 0; + *Color = 0; + return; + } + + int OutBrightness = 0; + if(Creature->Skills[SKILL_LIGHT] != NULL){ + OutBrightness = Creature->Skills[SKILL_LIGHT]->TimerValue(); + } + + if(Creature->Type == PLAYER && CheckRight(CreatureID, ILLUMINATE)){ + if(OutBrightness < 7){ + OutBrightness = 7; + } + } + + int OutRed = 5 * OutBrightness; + int OutGreen = 5 * OutBrightness; + int OutBlue = 5 * OutBrightness; + for(int Position = INVENTORY_FIRST; + Position <= INVENTORY_LAST; + Position += 1){ + Object Obj = GetBodyObject(CreatureID, Position); + if(Obj == NONE){ + continue; + } + + ObjectType ObjType = Obj.getObjectType(); + if(!ObjType.getFlag(LIGHT)){ + continue; + } + + int ObjBrightness = (int)ObjType.getAttribute(BRIGHTNESS); + int ObjColor = (int)ObjType.getAttribute(LIGHTCOLOR); + int ObjRed = (ObjColor / 36) * ObjBrightness; + int ObjGreen = (ObjColor % 36 / 6) * ObjBrightness; + int ObjBlue = (ObjColor % 36 % 6) * ObjBrightness; + + if(OutBrightness < ObjBrightness){ + OutBrightness = ObjBrightness; + } + + if(OutRed < ObjRed){ + OutRed = ObjRed; + } + + if(OutGreen < ObjGreen){ + OutGreen = ObjGreen; + } + + if(OutBlue < ObjBlue){ + OutBlue = ObjBlue; + } + } + + int OutColor = 0; + if(OutBrightness > 0){ + OutColor = (OutRed / OutBrightness) * 36 + + (OutGreen / OutBrightness) * 6 + + (OutBlue / OutBrightness); + } + + *Brightness = OutBrightness; + *Color = OutColor; +} + +int GetInventoryWeight(uint32 CreatureID){ + TCreature *Creature = GetCreature(CreatureID); + if(Creature == NULL){ + error("GetInventoryWeight: Kreatur %d existiert nicht.\n", CreatureID); + return 0; + } + + Object Help = GetFirstContainerObject(Creature->CrObject); + return GetRowWeight(Help); +} + +bool CheckRight(uint32 CharacterID, RIGHT Right){ + TPlayer *Player = GetPlayer(CharacterID); + if(Player == NULL){ + error("CheckRight: Spieler existiert nicht; Right=%d.\n", Right); + return false; + } + + if(!CheckBitIndex(NARRAY(Player->Rights), Right)){ + error("CheckRight: Ungültige Rechtnummer %d.\n", Right); + return false; + } + + return CheckBit(Player->Rights, Right); +} + +bool CheckBanishmentRight(uint32 CharacterID, int Reason, int Action){ + TPlayer *Player = GetPlayer(CharacterID); + if(Player == NULL){ + error("CheckBanishmentRight: Spieler existiert nicht.\n"); + return false; + } + + // NOTE(fusion): Banishment rights range from 18 to 49 and match banishment + // reasons exactly when subtracting 18. + + if(Reason < 0 || Reason > 31){ + error("CheckBanishmentRight: Ungültiger Banngrund %d von Spieler %d.\n", + Reason, CharacterID); + return false; + } + + if(Action < 0 || Action > 6){ + error("CheckBanishmentRight: Ungültige Aktion %d von Spieler %d.\n", + Action, CharacterID); + return false; + } + + bool Result = false; + if(CheckRight(CharacterID, (RIGHT)(Reason + 18))){ + bool Name = (Reason >= 0 && Reason <= 8); + bool Statement = (Reason >= 9 && Reason <= 27) || Reason == 29; + switch(Action){ + case 0:{ + Result = CheckRight(CharacterID, NOTATION); + break; + } + + case 1:{ + Result = Name && CheckRight(CharacterID, NAMELOCK); + break; + } + + case 2:{ + Result = !Name && CheckRight(CharacterID, BANISHMENT); + break; + } + + case 3:{ + Result = Name && CheckRight(CharacterID, NAMELOCK) + && CheckRight(CharacterID, BANISHMENT); + break; + } + + case 4:{ + Result = !Name && CheckRight(CharacterID, BANISHMENT) + && CheckRight(CharacterID, FINAL_WARNING); + break; + } + + case 5:{ + Result = Name && CheckRight(CharacterID, NAMELOCK) + && CheckRight(CharacterID, BANISHMENT) + && CheckRight(CharacterID, FINAL_WARNING); + break; + } + + case 6:{ + Result = Statement && CheckRight(CharacterID, STATEMENT_REPORT); + break; + } + } + } + + return Result; +} + +const char *GetBanishmentReason(int Reason){ + const char *Result; + switch(Reason){ + case 0: Result = "NAME_INSULTING"; break; + case 1: Result = "NAME_SENTENCE"; break; + case 2: Result = "NAME_NONSENSICAL_LETTERS"; break; + case 3: Result = "NAME_BADLY_FORMATTED"; break; + case 4: Result = "NAME_NO_PERSON"; break; + case 5: Result = "NAME_CELEBRITY"; break; + case 6: Result = "NAME_COUNTRY"; break; + case 7: Result = "NAME_FAKE_IDENTITY"; break; + case 8: Result = "NAME_FAKE_POSITION"; break; + case 9: Result = "STATEMENT_INSULTING"; break; + case 10: Result = "STATEMENT_SPAMMING"; break; + case 11: Result = "STATEMENT_ADVERT_OFFTOPIC"; break; + case 12: Result = "STATEMENT_ADVERT_MONEY"; break; + case 13: Result = "STATEMENT_NON_ENGLISH"; break; + case 14: Result = "STATEMENT_CHANNEL_OFFTOPIC"; break; + case 15: Result = "STATEMENT_VIOLATION_INCITING"; break; + case 16: Result = "CHEATING_BUG_ABUSE"; break; + case 17: Result = "CHEATING_GAME_WEAKNESS"; break; + case 18: Result = "CHEATING_MACRO_USE"; break; + case 19: Result = "CHEATING_MODIFIED_CLIENT"; break; + case 20: Result = "CHEATING_HACKING"; break; + case 21: Result = "CHEATING_MULTI_CLIENT"; break; + case 22: Result = "CHEATING_ACCOUNT_TRADING"; break; + case 23: Result = "CHEATING_ACCOUNT_SHARING"; break; + case 24: Result = "GAMEMASTER_THREATENING"; break; + case 25: Result = "GAMEMASTER_PRETENDING"; break; + case 26: Result = "GAMEMASTER_INFLUENCE"; break; + case 27: Result = "GAMEMASTER_FALSE_REPORTS"; break; + case 28: Result = "KILLING_EXCESSIVE_UNJUSTIFIED"; break; + case 29: Result = "DESTRUCTIVE_BEHAVIOUR"; break; + case 30: Result = "SPOILING_AUCTION"; break; + case 31: Result = "INVALID_PAYMENT"; break; + default:{ + error("GetBanishmentReason: Ungültiger Verbannungsgrund %d.\n", Reason); + Result = ""; + break; + } + } + return Result; +} + void InitInfo(void){ // no-op } diff --git a/src/info.hh b/src/info.hh index 3cb6399..adf3ce4 100644 --- a/src/info.hh +++ b/src/info.hh @@ -44,6 +44,14 @@ bool FieldPossible(int x, int y, int z, int FieldType); bool SearchFreeField(int *x, int *y, int *z, int Distance, uint16 HouseID, bool Jump); bool SearchLoginField(int *x, int *y, int *z, int Distance, bool Player); bool SearchSpawnField(int *x, int *y, int *z, int Distance, bool Player); +bool SearchFlightField(uint32 FugitiveID, uint32 PursuerID, int *x, int *y, int *z); +bool SearchSummonField(int *x, int *y, int *z, int Distance); +bool ThrowPossible(int OrigX, int OrigY, int OrigZ, + int DestX, int DestY, int DestZ, int Power); +void GetCreatureLight(uint32 CreatureID, int *Brightness, int *Color); +int GetInventoryWeight(uint32 CreatureID); +bool CheckBanishmentRight(uint32 CharacterID, int Reason, int Action); +const char *GetBanishmentReason(int Reason); void InitInfo(void); void ExitInfo(void); diff --git a/src/magic.cc b/src/magic.cc index 28c1aa5..728b681 100644 --- a/src/magic.cc +++ b/src/magic.cc @@ -898,7 +898,7 @@ int GetDirection(int dx, int dy){ }else if(dy > 0){ Result = DIRECTION_SOUTH; }else{ - Result = DIRECTION_INVALID; + Result = DIRECTION_NONE; } }else{ // NOTE(fusion): This function uses the approximate tangent value, avoiding @@ -1242,7 +1242,7 @@ void CreateFieldWall(TCreature *Actor, Object Target, break; } - case DIRECTION_INVALID:{ + case DIRECTION_NONE:{ throw NOROOM; } diff --git a/src/objects.cc b/src/objects.cc index 198a11d..5231fc8 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -254,28 +254,6 @@ static const char InstanceAttributeNames[18][30] = { "RemainingUses", // REMAININGUSES }; -// - -// BITSET Helpers -// ============================================================================= -static inline bool CheckBit(uint8 *Set, int Index){ - int ByteIndex = (int)(Index / 8); - uint8 BitMask = (uint8)(1 << (Index % 8)); - return (Set[ByteIndex] & BitMask) != 0; -} - -static inline void SetBit(uint8 *Set, int Index){ - int ByteIndex = (int)(Index / 8); - uint8 BitMask = (uint8)(1 << (Index % 8)); - Set[ByteIndex] |= BitMask; -} - -static inline void ClearBit(uint8 *Set, int Index){ - int ByteIndex = (int)(Index / 8); - uint8 BitMask = (uint8)(1 << (Index % 8)); - Set[ByteIndex] &= ~BitMask; -} - // ObjectType // ============================================================================= void ObjectType::setTypeID(int TypeID){ diff --git a/src/stubs.hh b/src/stubs.hh index 63615d7..4c1b0cb 100644 --- a/src/stubs.hh +++ b/src/stubs.hh @@ -64,8 +64,6 @@ extern void RefreshCylinders(void); extern void RefreshMap(void); extern void RefreshSector(int SectorX, int SectorY, int SectorZ, const uint8 *Data, int Size); extern void SavePlayerDataOrder(void); -extern bool SearchFlightField(uint32 FugitiveID, uint32 PursuerID, int *x, int *y, int *z); -extern bool SearchSummonField(int *x, int *y, int *z, int Distance); extern void SendAll(void); extern void SendAmbiente(TConnection *Connection); extern void SendClearTarget(TConnection *Connection); @@ -89,8 +87,6 @@ extern void ShowSubownerList(uint16 HouseID, TPlayer *Player, char *Buffer); extern void ShowNameDoor(Object Door, TPlayer *Player, char *Buffer); extern void Talk(uint32 CreatureID, int Mode, const char *Addressee, const char *Text, bool CheckSpamming); extern void TextualEffect(Object Obj, int Color, const char *Text, ...) ATTR_PRINTF(3, 4); -extern bool ThrowPossible(int FromX, int FromY, int FromZ, - int ToX, int ToY, int ToZ, int Power); extern void Turn(uint32 CreatureID, Object Obj); extern void Use(uint32 CreatureID, Object Obj1, Object Object2, uint8 Info); diff --git a/src/util.cc b/src/util.cc index 0982cd7..4a3523b 100644 --- a/src/util.cc +++ b/src/util.cc @@ -167,6 +167,31 @@ char *findLast(char *s, char c){ return Last; } +// BitSet Utility +// ============================================================================= +bool CheckBitIndex(int BitSetBytes, int Index){ + return Index >= 0 && Index < (BitSetBytes * 8); +} + +bool CheckBit(uint8 *BitSet, int Index){ + int ByteIndex = (int)(Index / 8); + uint8 BitMask = (uint8)(1 << (Index % 8)); + return (BitSet[ByteIndex] & BitMask) != 0; +} + +void SetBit(uint8 *BitSet, int Index){ + int ByteIndex = (int)(Index / 8); + uint8 BitMask = (uint8)(1 << (Index % 8)); + BitSet[ByteIndex] |= BitMask; +} + +void ClearBit(uint8 *BitSet, int Index){ + int ByteIndex = (int)(Index / 8); + uint8 BitMask = (uint8)(1 << (Index % 8)); + BitSet[ByteIndex] &= ~BitMask; +} + + // TReadStream // ============================================================================= bool TReadStream::readFlag(void){ -- cgit v1.2.3