aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-06-10 19:19:09 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-06-10 19:19:09 -0300
commit81a5d53bc566fe2c678577cb3f3e5cadd0711753 (patch)
tree6423174670804c4ff6660753c9eb826527df2b97
parent699341773dda3ae14a5025b9285bdd05c99bc234 (diff)
downloadgame-81a5d53bc566fe2c678577cb3f3e5cadd0711753.tar.gz
game-81a5d53bc566fe2c678577cb3f3e5cadd0711753.zip
finish `info.cc`
-rw-r--r--reference/game.c800
-rw-r--r--src/common.hh5
-rw-r--r--src/enums.hh2
-rw-r--r--src/info.cc406
-rw-r--r--src/info.hh8
-rw-r--r--src/magic.cc4
-rw-r--r--src/objects.cc22
-rw-r--r--src/stubs.hh4
-rw-r--r--src/util.cc25
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<int>(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<int>(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<typename T>
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<int> 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<int>(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<int>(
+ 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){