impl Cron and most map.cc functions
This commit is contained in:
parent
fbb392953c
commit
ad1f181454
2
TODO.md
2
TODO.md
@ -10,7 +10,7 @@
|
||||
The decompiled file has ~115K lines of C. If we take ~15K lines to be rubbish, this can be round to ~100K. Considering a low estimate of 200 lines per day, the whole process could take up to 500 days which is quite a bit but not impossible. Now considering a high estimate of 1K lines per day, it could take 100 days which is also quite a bit.
|
||||
|
||||
## TODO AFTER FIRST PASS
|
||||
- Trim some rough edges.
|
||||
- Trim rough edges.
|
||||
- Avoid unsafe libc functions like `strcpy`, `strncpy`, `strcat`, `sprintf` etc...
|
||||
- Handle connections inline with `poll`/`epoll` (probably?).
|
||||
- Remove exceptions.
|
||||
|
||||
881
reference/game.c
881
reference/game.c
@ -5192,887 +5192,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
|
||||
return;
|
||||
}
|
||||
|
||||
void CronMove(int Destination,int Source)
|
||||
|
||||
{
|
||||
int iVar1;
|
||||
uint uVar2;
|
||||
TCronEntry *pTVar3;
|
||||
TCronEntry *pTVar4;
|
||||
TCronEntry *Entry;
|
||||
undefined8 local_34;
|
||||
int iStack_30;
|
||||
|
||||
pTVar3 = vector<TCronEntry>::operator()(&CronEntry,Destination);
|
||||
pTVar4 = vector<TCronEntry>::operator()(&CronEntry,Source);
|
||||
(pTVar3->Obj).ObjectID = (pTVar4->Obj).ObjectID;
|
||||
pTVar3->RoundNr = pTVar4->RoundNr;
|
||||
iVar1 = pTVar4->Next;
|
||||
pTVar3->Previous = pTVar4->Previous;
|
||||
pTVar3->Next = iVar1;
|
||||
pTVar3 = vector<TCronEntry>::operator()(&CronEntry,Destination);
|
||||
if (pTVar3->Next != -1) {
|
||||
pTVar4 = vector<TCronEntry>::operator()(&CronEntry,pTVar3->Next);
|
||||
pTVar4->Previous = Destination;
|
||||
}
|
||||
if (pTVar3->Previous != -1) {
|
||||
pTVar4 = vector<TCronEntry>::operator()(&CronEntry,pTVar3->Previous);
|
||||
iVar1 = pTVar3->Previous;
|
||||
pTVar4->Next = Destination;
|
||||
if (iVar1 != -1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
uVar2 = (pTVar3->Obj).ObjectID;
|
||||
CronHashTable
|
||||
[uVar2 + ((uVar2 - (int)((ulonglong)uVar2 * 0x200401 >> 0x20) >> 1) + iStack_30 >> 10) * -0x7ff]
|
||||
= Destination;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CronHeapify(int Position)
|
||||
|
||||
{
|
||||
int i;
|
||||
TCronEntry *pTVar1;
|
||||
TCronEntry *pTVar2;
|
||||
int Father;
|
||||
int iVar3;
|
||||
|
||||
while (Position != 1) {
|
||||
pTVar1 = vector<TCronEntry>::operator()(&CronEntry,Position);
|
||||
iVar3 = Position / 2;
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,iVar3);
|
||||
if (pTVar2->RoundNr <= pTVar1->RoundNr) break;
|
||||
CronMove(0,Position);
|
||||
CronMove(Position,iVar3);
|
||||
CronMove(iVar3,0);
|
||||
Position = iVar3;
|
||||
}
|
||||
while( true ) {
|
||||
iVar3 = Position * 2;
|
||||
if (CronEntries < iVar3) {
|
||||
return;
|
||||
}
|
||||
i = iVar3 + 1;
|
||||
if (i <= CronEntries) {
|
||||
pTVar1 = vector<TCronEntry>::operator()(&CronEntry,i);
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,iVar3);
|
||||
if (pTVar1->RoundNr < pTVar2->RoundNr) {
|
||||
iVar3 = i;
|
||||
}
|
||||
}
|
||||
pTVar1 = vector<TCronEntry>::operator()(&CronEntry,Position);
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,iVar3);
|
||||
if (pTVar1->RoundNr <= pTVar2->RoundNr) break;
|
||||
CronMove(0,Position);
|
||||
CronMove(Position,iVar3);
|
||||
CronMove(iVar3,0);
|
||||
Position = iVar3;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CronSet(Object *Obj,ulong Delay)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
int i;
|
||||
TCronEntry *pTVar2;
|
||||
ulong Position;
|
||||
uint uVar3;
|
||||
|
||||
bVar1 = false;
|
||||
if (Obj->ObjectID != 0) {
|
||||
uVar3 = Obj->ObjectID & HashTableMask;
|
||||
if (HashTableType[uVar3] == '\x02') {
|
||||
UnswapSector(HashTableData[uVar3]);
|
||||
}
|
||||
if ((HashTableType[uVar3] == '\x01') && (*(ulong *)HashTableData[uVar3] == Obj->ObjectID)) {
|
||||
bVar1 = true;
|
||||
}
|
||||
else {
|
||||
bVar1 = false;
|
||||
}
|
||||
}
|
||||
if (bVar1) {
|
||||
CronEntries = CronEntries + 1;
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,CronEntries);
|
||||
(pTVar2->Obj).ObjectID = Obj->ObjectID;
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,CronEntries);
|
||||
pTVar2->RoundNr = Delay + RoundNr;
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,CronEntries);
|
||||
pTVar2->Previous = -1;
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,CronEntries);
|
||||
pTVar2->Next = CronHashTable[Obj->ObjectID % 0x7ff];
|
||||
i = CronEntries;
|
||||
CronHashTable[Obj->ObjectID % 0x7ff] = CronEntries;
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,i);
|
||||
if (pTVar2->Next != -1) {
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,CronEntries);
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,pTVar2->Next);
|
||||
pTVar2->Previous = CronEntries;
|
||||
}
|
||||
CronHeapify(CronEntries);
|
||||
}
|
||||
else {
|
||||
error(&DAT_080f1480);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CronDelete(int Position)
|
||||
|
||||
{
|
||||
uint uVar1;
|
||||
int iVar2;
|
||||
bool bVar3;
|
||||
TCronEntry *pTVar4;
|
||||
TCronEntry *pTVar5;
|
||||
TCronEntry *Entry;
|
||||
undefined8 local_1c;
|
||||
int iStack_18;
|
||||
|
||||
bVar3 = false;
|
||||
if ((0 < Position) && (Position <= CronEntries)) {
|
||||
bVar3 = true;
|
||||
}
|
||||
if (!bVar3) {
|
||||
error(&DAT_080f14c0,Position);
|
||||
return;
|
||||
}
|
||||
pTVar4 = vector<TCronEntry>::operator()(&CronEntry,Position);
|
||||
if (pTVar4->Next != -1) {
|
||||
pTVar5 = vector<TCronEntry>::operator()(&CronEntry,pTVar4->Next);
|
||||
pTVar5->Previous = pTVar4->Previous;
|
||||
}
|
||||
if (pTVar4->Previous != -1) {
|
||||
pTVar5 = vector<TCronEntry>::operator()(&CronEntry,pTVar4->Previous);
|
||||
iVar2 = pTVar4->Previous;
|
||||
pTVar5->Next = pTVar4->Next;
|
||||
if (iVar2 != -1) goto LAB_08057e24;
|
||||
}
|
||||
uVar1 = (pTVar4->Obj).ObjectID;
|
||||
CronHashTable
|
||||
[uVar1 + ((uVar1 - (int)((ulonglong)uVar1 * 0x200401 >> 0x20) >> 1) + iStack_18 >> 10) * -0x7ff]
|
||||
= pTVar4->Next;
|
||||
LAB_08057e24:
|
||||
iVar2 = CronEntries;
|
||||
CronEntries = CronEntries + -1;
|
||||
if (CronEntries < Position) {
|
||||
return;
|
||||
}
|
||||
CronMove(Position,iVar2);
|
||||
CronHeapify(Position);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WARNING: Unknown calling convention -- yet parameter storage is locked
|
||||
|
||||
Object CronCheck(void)
|
||||
|
||||
{
|
||||
Object OVar1;
|
||||
TCronEntry *pTVar2;
|
||||
ulong *in_stack_00000004;
|
||||
|
||||
OVar1.ObjectID = NONE.ObjectID;
|
||||
if ((CronEntries != 0) &&
|
||||
(pTVar2 = vector<TCronEntry>::operator()(&CronEntry,1), OVar1 = NONE,
|
||||
pTVar2->RoundNr <= RoundNr)) {
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,1);
|
||||
OVar1.ObjectID = (pTVar2->Obj).ObjectID;
|
||||
}
|
||||
*in_stack_00000004 = OVar1.ObjectID;
|
||||
return (Object)(ulong)in_stack_00000004;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ulong CronInfo(Object *Obj,bool Delete)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
TCronEntry *pTVar2;
|
||||
int Position;
|
||||
uint uVar3;
|
||||
int i;
|
||||
ulong uVar4;
|
||||
char *Text;
|
||||
undefined8 local_44;
|
||||
int iStack_40;
|
||||
bool Delete_local;
|
||||
|
||||
bVar1 = false;
|
||||
if (Obj->ObjectID != 0) {
|
||||
uVar3 = Obj->ObjectID & HashTableMask;
|
||||
if (HashTableType[uVar3] == '\x02') {
|
||||
UnswapSector(HashTableData[uVar3]);
|
||||
}
|
||||
if ((HashTableType[uVar3] == '\x01') && (*(ulong *)HashTableData[uVar3] == Obj->ObjectID)) {
|
||||
bVar1 = true;
|
||||
}
|
||||
else {
|
||||
bVar1 = false;
|
||||
}
|
||||
}
|
||||
if (bVar1) {
|
||||
uVar3 = Obj->ObjectID;
|
||||
i = CronHashTable
|
||||
[uVar3 + ((uVar3 - (int)((ulonglong)uVar3 * 0x200401 >> 0x20) >> 1) + iStack_40 >> 10) *
|
||||
-0x7ff];
|
||||
while (i != -1) {
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,i);
|
||||
if ((pTVar2->Obj).ObjectID == Obj->ObjectID) {
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,i);
|
||||
uVar4 = pTVar2->RoundNr - RoundNr;
|
||||
if ((int)uVar4 < 1) {
|
||||
uVar4 = 1;
|
||||
}
|
||||
if (!Delete) {
|
||||
return uVar4;
|
||||
}
|
||||
CronDelete(i);
|
||||
return uVar4;
|
||||
}
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,i);
|
||||
i = pTVar2->Next;
|
||||
}
|
||||
Text = "CronInfo: Objekt ist nicht im Cron-System eingetragen.\n";
|
||||
}
|
||||
else {
|
||||
Text = &DAT_080f1540;
|
||||
}
|
||||
error(Text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ulong CronStop(Object *Obj)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
ulong uVar2;
|
||||
ulong Position;
|
||||
uint uVar3;
|
||||
Object local_1c [4];
|
||||
|
||||
bVar1 = false;
|
||||
if (Obj->ObjectID != 0) {
|
||||
uVar3 = Obj->ObjectID & HashTableMask;
|
||||
if (HashTableType[uVar3] == '\x02') {
|
||||
UnswapSector(HashTableData[uVar3]);
|
||||
}
|
||||
if ((HashTableType[uVar3] == '\x01') && (*(ulong *)HashTableData[uVar3] == Obj->ObjectID)) {
|
||||
bVar1 = true;
|
||||
}
|
||||
else {
|
||||
bVar1 = false;
|
||||
}
|
||||
}
|
||||
if (bVar1) {
|
||||
local_1c[0] = (Object)Obj->ObjectID;
|
||||
uVar2 = CronInfo(local_1c,true);
|
||||
}
|
||||
else {
|
||||
error(&DAT_080f1580);
|
||||
uVar2 = 0;
|
||||
}
|
||||
return uVar2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CronExpire(Object *Obj,int Delay)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
TObject *pTVar2;
|
||||
ulong Position;
|
||||
uint uVar3;
|
||||
Object local_3c [4];
|
||||
Object local_2c [7];
|
||||
|
||||
bVar1 = false;
|
||||
if (Obj->ObjectID != 0) {
|
||||
uVar3 = Obj->ObjectID & HashTableMask;
|
||||
if (HashTableType[uVar3] == '\x02') {
|
||||
UnswapSector(HashTableData[uVar3]);
|
||||
}
|
||||
if ((HashTableType[uVar3] == '\x01') && (*(ulong *)HashTableData[uVar3] == Obj->ObjectID)) {
|
||||
bVar1 = true;
|
||||
}
|
||||
else {
|
||||
bVar1 = false;
|
||||
}
|
||||
}
|
||||
if (bVar1) {
|
||||
local_3c[0] = (Object)Obj->ObjectID;
|
||||
pTVar2 = AccessObject(local_3c);
|
||||
ObjectType::setTypeID((ObjectType *)local_2c,(pTVar2->Type).TypeID);
|
||||
bVar1 = ObjectType::getFlag((ObjectType *)local_2c,EXPIRE);
|
||||
if (bVar1) {
|
||||
if (Delay == -1) {
|
||||
local_2c[0] = (Object)Obj->ObjectID;
|
||||
pTVar2 = AccessObject(local_2c);
|
||||
ObjectType::setTypeID((ObjectType *)local_3c,(pTVar2->Type).TypeID);
|
||||
Delay = ObjectType::getAttribute((ObjectType *)local_3c,TOTALEXPIRETIME);
|
||||
}
|
||||
local_3c[0] = (Object)Obj->ObjectID;
|
||||
CronSet(local_3c,Delay);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(&DAT_080f15c0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CronChange(Object *Obj,int NewDelay)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
TCronEntry *pTVar2;
|
||||
int Position;
|
||||
uint uVar3;
|
||||
int i;
|
||||
char *Text;
|
||||
|
||||
bVar1 = false;
|
||||
if (Obj->ObjectID != 0) {
|
||||
uVar3 = Obj->ObjectID & HashTableMask;
|
||||
if (HashTableType[uVar3] == '\x02') {
|
||||
UnswapSector(HashTableData[uVar3]);
|
||||
}
|
||||
if ((HashTableType[uVar3] == '\x01') && (*(ulong *)HashTableData[uVar3] == Obj->ObjectID)) {
|
||||
bVar1 = true;
|
||||
}
|
||||
else {
|
||||
bVar1 = false;
|
||||
}
|
||||
}
|
||||
if (bVar1) {
|
||||
i = CronHashTable[Obj->ObjectID % 0x7ff];
|
||||
while (i != -1) {
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,i);
|
||||
if ((pTVar2->Obj).ObjectID == Obj->ObjectID) {
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,i);
|
||||
pTVar2->RoundNr = NewDelay + RoundNr;
|
||||
CronHeapify(i);
|
||||
return;
|
||||
}
|
||||
pTVar2 = vector<TCronEntry>::operator()(&CronEntry,i);
|
||||
i = pTVar2->Next;
|
||||
}
|
||||
Text = "CronChange: Objekt ist nicht im Cron-System eingetragen.\n";
|
||||
}
|
||||
else {
|
||||
Text = &DAT_080f1640;
|
||||
}
|
||||
error(Text);
|
||||
return;
|
||||
}
|
||||
|
||||
// WARNING: Unknown calling convention -- yet parameter storage is locked
|
||||
|
||||
Object GetFirstSpecObject(void)
|
||||
|
||||
{
|
||||
TObject *pTVar1;
|
||||
ulong *in_stack_00000004;
|
||||
int *in_stack_00000014;
|
||||
Object local_5c [4];
|
||||
ObjectType local_4c [4];
|
||||
Object local_3c [4];
|
||||
ulong local_2c;
|
||||
Object Obj;
|
||||
|
||||
GetFirstObject();
|
||||
if (local_2c != NONE.ObjectID) {
|
||||
do {
|
||||
local_4c[0].TypeID = NONE.ObjectID;
|
||||
local_3c[0].ObjectID = local_2c;
|
||||
pTVar1 = AccessObject(local_3c);
|
||||
ObjectType::setTypeID(local_4c,(pTVar1->Type).TypeID);
|
||||
ObjectType::setTypeID((ObjectType *)local_3c,*in_stack_00000014);
|
||||
if (local_4c[0].TypeID == local_3c[0].ObjectID) {
|
||||
*in_stack_00000004 = local_2c;
|
||||
return (Object)(ulong)in_stack_00000004;
|
||||
}
|
||||
local_5c[0].ObjectID = local_2c;
|
||||
pTVar1 = AccessObject(local_5c);
|
||||
local_2c = (pTVar1->NextObject).ObjectID;
|
||||
} while (local_2c != NONE.ObjectID);
|
||||
}
|
||||
*in_stack_00000004 = NONE.ObjectID;
|
||||
return (Object)(ulong)in_stack_00000004;
|
||||
}
|
||||
|
||||
bool IsOnMap(int x,int y,int z)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
int sx;
|
||||
int iVar2;
|
||||
bool bVar3;
|
||||
|
||||
iVar2 = x + 0x1f;
|
||||
if (-1 < x) {
|
||||
iVar2 = x;
|
||||
}
|
||||
if (0x7fffffff < (uint)y) {
|
||||
y = y + 0x1f;
|
||||
}
|
||||
bVar1 = false;
|
||||
bVar3 = false;
|
||||
if ((SectorXMin <= iVar2 >> 5) && (bVar1 = true, SectorXMax < iVar2 >> 5)) {
|
||||
bVar1 = false;
|
||||
}
|
||||
if (bVar1) {
|
||||
bVar1 = false;
|
||||
if ((SectorYMin <= y >> 5) && (bVar1 = true, SectorYMax < y >> 5)) {
|
||||
bVar1 = false;
|
||||
}
|
||||
if (bVar1) {
|
||||
bVar1 = false;
|
||||
if ((SectorZMin <= z) && (bVar1 = true, SectorZMax < z)) {
|
||||
bVar1 = bVar3;
|
||||
}
|
||||
if (bVar1 != false) {
|
||||
bVar3 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bVar3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WARNING: Unknown calling convention -- yet parameter storage is locked
|
||||
|
||||
bool CoordinateFlag(void)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
TObject *pTVar2;
|
||||
FLAG in_stack_00000010;
|
||||
Object local_5c [4];
|
||||
ObjectType local_4c [4];
|
||||
Object local_3c [4];
|
||||
ulong local_2c;
|
||||
Object Obj;
|
||||
|
||||
GetFirstObject();
|
||||
if (local_2c != NONE.ObjectID) {
|
||||
do {
|
||||
local_4c[0].TypeID = NONE.ObjectID;
|
||||
local_3c[0].ObjectID = local_2c;
|
||||
pTVar2 = AccessObject(local_3c);
|
||||
ObjectType::setTypeID(local_4c,(pTVar2->Type).TypeID);
|
||||
bVar1 = ObjectType::getFlag(local_4c,in_stack_00000010);
|
||||
if (bVar1) {
|
||||
return true;
|
||||
}
|
||||
local_5c[0].ObjectID = local_2c;
|
||||
pTVar2 = AccessObject(local_5c);
|
||||
local_2c = (pTVar2->NextObject).ObjectID;
|
||||
} while (local_2c != NONE.ObjectID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool IsPremiumArea(int x,int y,int param_3)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
int iVar2;
|
||||
int iVar3;
|
||||
|
||||
iVar2 = x + 0x1f;
|
||||
if (-1 < x) {
|
||||
iVar2 = x;
|
||||
}
|
||||
iVar2 = iVar2 >> 5;
|
||||
if (0x7fffffff < (uint)y) {
|
||||
y = y + 0x1f;
|
||||
}
|
||||
bVar1 = true;
|
||||
iVar3 = y >> 5;
|
||||
if ((((iVar2 < 0x40c) && ((iVar2 < 0x408 || (bVar1 = true, 0x3e6 < iVar3)))) &&
|
||||
((iVar2 < 0x406 || (bVar1 = true, iVar3 < 0x3f0)))) &&
|
||||
(((iVar2 < 0x405 || (bVar1 = true, iVar3 < 0x3f1)) &&
|
||||
((iVar2 < 0x3fe || (bVar1 = true, iVar3 < 0x3f6)))))) {
|
||||
bVar1 = 0x3f7 < iVar3;
|
||||
}
|
||||
return bVar1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WARNING: Unknown calling convention -- yet parameter storage is locked
|
||||
|
||||
bool IsProtectionZone(void)
|
||||
|
||||
{
|
||||
byte bVar1;
|
||||
bool bVar2;
|
||||
int in_stack_00000004;
|
||||
int in_stack_00000008;
|
||||
Object local_2c [4];
|
||||
ulong local_1c;
|
||||
Object Con;
|
||||
|
||||
GetMapContainer((int)&local_1c,in_stack_00000004,in_stack_00000008);
|
||||
bVar2 = false;
|
||||
if (local_1c != NONE.ObjectID) {
|
||||
local_2c[0].ObjectID = local_1c;
|
||||
bVar1 = GetMapContainerFlags(local_2c);
|
||||
bVar2 = (bool)(bVar1 >> 2 & 1);
|
||||
}
|
||||
return bVar2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WARNING: Unknown calling convention -- yet parameter storage is locked
|
||||
|
||||
bool IsNoLogoutField(void)
|
||||
|
||||
{
|
||||
byte bVar1;
|
||||
bool bVar2;
|
||||
int in_stack_00000004;
|
||||
int in_stack_00000008;
|
||||
Object local_2c [4];
|
||||
ulong local_1c;
|
||||
Object Con;
|
||||
|
||||
GetMapContainer((int)&local_1c,in_stack_00000004,in_stack_00000008);
|
||||
bVar2 = false;
|
||||
if (local_1c != NONE.ObjectID) {
|
||||
local_2c[0].ObjectID = local_1c;
|
||||
bVar1 = GetMapContainerFlags(local_2c);
|
||||
bVar2 = (bool)(bVar1 >> 1 & 1);
|
||||
}
|
||||
return bVar2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool IsHouse(int x,int y,int z)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
short sVar2;
|
||||
TObject *pTVar3;
|
||||
Object local_3c [4];
|
||||
Object local_2c;
|
||||
Object Con;
|
||||
|
||||
GetMapContainer((int)&local_2c,x,y);
|
||||
local_3c[0].ObjectID = NONE.ObjectID;
|
||||
if (local_2c.ObjectID != NONE.ObjectID) {
|
||||
bVar1 = Object::exists(&local_2c);
|
||||
if (bVar1) {
|
||||
local_3c[0].ObjectID = local_2c.ObjectID;
|
||||
pTVar3 = AccessObject(local_3c);
|
||||
sVar2 = *(short *)((int)pTVar3->Attributes + 0xe);
|
||||
goto LAB_0805b121;
|
||||
}
|
||||
error(&DAT_080f20a0,x,y,z);
|
||||
}
|
||||
sVar2 = 0;
|
||||
LAB_0805b121:
|
||||
return sVar2 != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ushort GetHouseID(int x,int y,int z)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
TObject *pTVar2;
|
||||
ushort uVar3;
|
||||
ulong Position;
|
||||
uint uVar4;
|
||||
Object local_3c [4];
|
||||
uint local_2c;
|
||||
Object Con;
|
||||
|
||||
GetMapContainer((int)&local_2c,x,y);
|
||||
uVar3 = 0;
|
||||
local_3c[0].ObjectID = NONE.ObjectID;
|
||||
if (local_2c != NONE.ObjectID) {
|
||||
bVar1 = false;
|
||||
if (local_2c != 0) {
|
||||
uVar4 = local_2c & HashTableMask;
|
||||
if (HashTableType[uVar4] == '\x02') {
|
||||
UnswapSector(HashTableData[uVar4]);
|
||||
}
|
||||
if ((HashTableType[uVar4] == '\x01') && (*(uint *)HashTableData[uVar4] == local_2c)) {
|
||||
bVar1 = true;
|
||||
}
|
||||
else {
|
||||
bVar1 = false;
|
||||
}
|
||||
}
|
||||
if (bVar1) {
|
||||
local_3c[0].ObjectID = local_2c;
|
||||
pTVar2 = AccessObject(local_3c);
|
||||
uVar3 = *(ushort *)((int)pTVar2->Attributes + 0xe);
|
||||
}
|
||||
else {
|
||||
error(&DAT_080f20a0,x,y,z);
|
||||
uVar3 = 0;
|
||||
}
|
||||
}
|
||||
return uVar3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SetHouseID(int x,int y,int z,ushort ID)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
bool bVar2;
|
||||
ushort uVar3;
|
||||
TObject *pTVar4;
|
||||
int sy;
|
||||
int iVar5;
|
||||
int sx;
|
||||
int iVar6;
|
||||
ulong Position;
|
||||
uint uVar7;
|
||||
ushort ID_local;
|
||||
uint local_2c;
|
||||
Object Con;
|
||||
|
||||
iVar6 = x;
|
||||
if (0x7fffffff < (uint)x) {
|
||||
iVar6 = x + 0x1f;
|
||||
}
|
||||
iVar5 = y;
|
||||
if (0x7fffffff < (uint)y) {
|
||||
iVar5 = y + 0x1f;
|
||||
}
|
||||
bVar1 = false;
|
||||
bVar2 = false;
|
||||
if ((SectorXMin <= iVar6 >> 5) && (bVar1 = true, SectorXMax < iVar6 >> 5)) {
|
||||
bVar1 = false;
|
||||
}
|
||||
if (bVar1) {
|
||||
bVar1 = false;
|
||||
if ((SectorYMin <= iVar5 >> 5) && (bVar1 = true, SectorYMax < iVar5 >> 5)) {
|
||||
bVar1 = false;
|
||||
}
|
||||
if (bVar1) {
|
||||
bVar1 = false;
|
||||
if ((SectorZMin <= z) && (bVar1 = true, SectorZMax < z)) {
|
||||
bVar1 = bVar2;
|
||||
}
|
||||
if (bVar1) {
|
||||
bVar2 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!bVar2) {
|
||||
return;
|
||||
}
|
||||
iVar6 = z;
|
||||
GetMapContainer((int)&local_2c,x,y);
|
||||
bVar1 = false;
|
||||
_ID_local = NONE.ObjectID;
|
||||
if (local_2c != NONE.ObjectID) {
|
||||
bVar2 = false;
|
||||
if (local_2c != 0) {
|
||||
uVar7 = local_2c & HashTableMask;
|
||||
if (HashTableType[uVar7] == '\x02') {
|
||||
UnswapSector(HashTableData[uVar7]);
|
||||
}
|
||||
if ((HashTableType[uVar7] == '\x01') && (*(uint *)HashTableData[uVar7] == local_2c)) {
|
||||
bVar2 = true;
|
||||
}
|
||||
else {
|
||||
bVar2 = false;
|
||||
}
|
||||
}
|
||||
if (bVar2) goto LAB_0805b36c;
|
||||
}
|
||||
bVar1 = true;
|
||||
LAB_0805b36c:
|
||||
if (bVar1) {
|
||||
print();
|
||||
}
|
||||
else {
|
||||
uVar3 = GetHouseID(x,y,z);
|
||||
if (uVar3 == 0) {
|
||||
_ID_local = local_2c;
|
||||
pTVar4 = AccessObject((Object *)&ID_local);
|
||||
pTVar4->Attributes[3] = pTVar4->Attributes[3] + (uint)ID * 0x10000;
|
||||
}
|
||||
else {
|
||||
error(&DAT_080f2160,y,z,iVar6);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GetDepotNumber(char *Town)
|
||||
|
||||
{
|
||||
TDepotInfo *s1;
|
||||
int iVar1;
|
||||
int i;
|
||||
int i_00;
|
||||
|
||||
if (Town == (char *)0x0) {
|
||||
error("GetDepotNumber: Town ist NULL.\n");
|
||||
}
|
||||
else if ((*Town != '\0') && (i_00 = DepotInfo.min, DepotInfo.min <= DepotInfo.max)) {
|
||||
do {
|
||||
s1 = vector<TDepotInfo>::operator()(&DepotInfo,i_00);
|
||||
iVar1 = stricmp(s1->Town,Town,-1);
|
||||
if (iVar1 == 0) {
|
||||
return i_00;
|
||||
}
|
||||
i_00 = i_00 + 1;
|
||||
} while (i_00 <= DepotInfo.max);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char * GetDepotName(int DepotNumber)
|
||||
|
||||
{
|
||||
TDepotInfo *pTVar1;
|
||||
char *Text;
|
||||
|
||||
if ((DepotNumber < DepotInfo.min) || (DepotInfo.max < DepotNumber)) {
|
||||
Text = &DAT_080f21c0;
|
||||
}
|
||||
else {
|
||||
pTVar1 = vector<TDepotInfo>::operator()(&DepotInfo,DepotNumber);
|
||||
if (pTVar1 != (TDepotInfo *)0x0) {
|
||||
pTVar1 = vector<TDepotInfo>::operator()(&DepotInfo,DepotNumber);
|
||||
return pTVar1->Town;
|
||||
}
|
||||
Text = &DAT_080f2200;
|
||||
}
|
||||
error(Text,DepotNumber);
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WARNING: Variable defined which should be unmapped: PremiumAccount_local
|
||||
|
||||
int GetDepotSize(int DepotNumber,bool PremiumAccount)
|
||||
|
||||
{
|
||||
int iVar1;
|
||||
TDepotInfo *pTVar2;
|
||||
bool PremiumAccount_local;
|
||||
|
||||
if ((DepotNumber < DepotInfo.min) || (DepotInfo.max < DepotNumber)) {
|
||||
error(&DAT_080f2240,DepotNumber);
|
||||
iVar1 = 1;
|
||||
}
|
||||
else {
|
||||
pTVar2 = vector<TDepotInfo>::operator()(&DepotInfo,DepotNumber);
|
||||
if (pTVar2->Size < 1) {
|
||||
pTVar2 = vector<TDepotInfo>::operator()(&DepotInfo,DepotNumber);
|
||||
error(&DAT_080f2280,pTVar2->Size,DepotNumber);
|
||||
pTVar2 = vector<TDepotInfo>::operator()(&DepotInfo,DepotNumber);
|
||||
pTVar2->Size = 1;
|
||||
}
|
||||
if (PremiumAccount) {
|
||||
pTVar2 = vector<TDepotInfo>::operator()(&DepotInfo,DepotNumber);
|
||||
iVar1 = pTVar2->Size * 2;
|
||||
}
|
||||
else {
|
||||
pTVar2 = vector<TDepotInfo>::operator()(&DepotInfo,DepotNumber);
|
||||
iVar1 = pTVar2->Size;
|
||||
}
|
||||
}
|
||||
return iVar1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GetStartPosition(int *x,int *y,int *z,bool Newbie)
|
||||
|
||||
{
|
||||
int iVar1;
|
||||
|
||||
if (Newbie) {
|
||||
*x = NewbieStartPositionX;
|
||||
*y = NewbieStartPositionY;
|
||||
iVar1 = NewbieStartPositionZ;
|
||||
}
|
||||
else {
|
||||
*x = VeteranStartPositionX;
|
||||
*y = VeteranStartPositionY;
|
||||
iVar1 = VeteranStartPositionZ;
|
||||
}
|
||||
*z = iVar1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WARNING: Unknown calling convention -- yet parameter storage is locked
|
||||
|
||||
bool GetMarkPosition(void)
|
||||
|
||||
{
|
||||
TMark *pTVar1;
|
||||
int iVar2;
|
||||
int i;
|
||||
int i_00;
|
||||
char *in_stack_00000004;
|
||||
int *in_stack_00000008;
|
||||
int *in_stack_0000000c;
|
||||
int *in_stack_00000010;
|
||||
|
||||
i_00 = 0;
|
||||
if (0 < Marks) {
|
||||
do {
|
||||
pTVar1 = vector<TMark>::operator()(&Mark,i_00);
|
||||
iVar2 = stricmp(pTVar1->Name,in_stack_00000004,-1);
|
||||
if (iVar2 == 0) {
|
||||
pTVar1 = vector<TMark>::operator()(&Mark,i_00);
|
||||
*in_stack_00000008 = pTVar1->x;
|
||||
pTVar1 = vector<TMark>::operator()(&Mark,i_00);
|
||||
*in_stack_0000000c = pTVar1->y;
|
||||
pTVar1 = vector<TMark>::operator()(&Mark,i_00);
|
||||
*in_stack_00000010 = pTVar1->z;
|
||||
return true;
|
||||
}
|
||||
i_00 = i_00 + 1;
|
||||
} while (i_00 < Marks);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RefreshSector(int x,int y,int z,TReadStream *Stream)
|
||||
|
||||
{
|
||||
|
||||
383
src/map.cc
383
src/map.cc
@ -38,8 +38,6 @@ static int CronHashTable[2047];
|
||||
static int CronEntries;
|
||||
|
||||
static vector<TDepotInfo> DepotInfo(0, 4, 5);
|
||||
static int Depots;
|
||||
|
||||
static vector<TMark> Mark(0, 4, 5);
|
||||
static int Marks;
|
||||
|
||||
@ -142,6 +140,204 @@ void Object::setAttribute(INSTANCEATTRIBUTE Attribute, uint32 Value){
|
||||
AccessObject(*this)->Attributes[AttributeOffset] = Value;
|
||||
}
|
||||
|
||||
// Cron Management
|
||||
// =============================================================================
|
||||
static void CronMove(int Destination, int Source){
|
||||
TCronEntry *DestEntry = CronEntry.at(Destination);
|
||||
*DestEntry = *CronEntry.at(Source);
|
||||
|
||||
if(DestEntry->Next != -1){
|
||||
CronEntry.at(DestEntry->Next)->Previous = Destination;
|
||||
}
|
||||
|
||||
if(DestEntry->Previous != -1){
|
||||
CronEntry.at(DestEntry->Previous)->Next = Destination;
|
||||
}else{
|
||||
CronHashTable[DestEntry->Obj.ObjectID % NARRAY(CronHashTable)] = Destination;
|
||||
}
|
||||
}
|
||||
|
||||
static void CronHeapify(int Position){
|
||||
while(Position > 1){
|
||||
int Parent = Position / 2;
|
||||
TCronEntry *CurrentEntry = CronEntry.at(Position);
|
||||
TCronEntry *ParentEntry = CronEntry.at(Parent);
|
||||
if(ParentEntry->RoundNr <= CurrentEntry->RoundNr){
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE(fusion): This is emulating a swap, using position 0 as the
|
||||
// temporary value. It is needed to maintain hash table links valid.
|
||||
CronMove(0, Position);
|
||||
CronMove(Position, Parent);
|
||||
CronMove(Parent, 0);
|
||||
|
||||
Position = Parent;
|
||||
}
|
||||
|
||||
// IMPORTANT(fusion): This is different from `priority_queue::deleteMin` as
|
||||
// the last element is still in the heap and needs to be considered.
|
||||
int Last = CronEntries;
|
||||
while(true){
|
||||
int Smallest = Position * 2;
|
||||
if(Smallest > Last){
|
||||
break;
|
||||
}
|
||||
|
||||
TCronEntry *SmallestEntry = CronEntry.at(Smallest);
|
||||
if((Smallest + 1) <= Last){
|
||||
TCronEntry *OtherEntry = CronEntry.at(Smallest + 1);
|
||||
if(OtherEntry->RoundNr < SmallestEntry->RoundNr){
|
||||
SmallestEntry = OtherEntry;
|
||||
Smallest += 1;
|
||||
}
|
||||
}
|
||||
|
||||
TCronEntry *CurrentEntry = CronEntry.at(Position);
|
||||
if(CurrentEntry->RoundNr <= SmallestEntry->RoundNr){
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE(fusion): Same in the first loop.
|
||||
CronMove(0, Position);
|
||||
CronMove(Position, Smallest);
|
||||
CronMove(Smallest, 0);
|
||||
|
||||
Position = Smallest;
|
||||
}
|
||||
}
|
||||
|
||||
static void CronSet(Object Obj, uint32 Delay){
|
||||
if(!Obj.exists()){
|
||||
error("CronSet: Übergebenes Objekt existiert nicht.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(fusion): We don't check if the object is already in the table.
|
||||
|
||||
CronEntries += 1;
|
||||
|
||||
int Position = CronEntries;
|
||||
TCronEntry *Entry = CronEntry.at(Position);
|
||||
Entry->Obj = Obj;
|
||||
Entry->RoundNr = RoundNr + Delay;
|
||||
Entry->Previous = -1;
|
||||
Entry->Next = CronHashTable[Obj.ObjectID % NARRAY(CronHashTable)];
|
||||
if(Entry->Next != -1){
|
||||
CronEntry.at(Entry->Next)->Previous = Position;
|
||||
}
|
||||
|
||||
CronHeapify(Position);
|
||||
}
|
||||
|
||||
static void CronDelete(int Position){
|
||||
if(Position < 1 || Position > CronEntries){
|
||||
error("CronDelete: Ungültige Position %d.\n", Position);
|
||||
return;
|
||||
}
|
||||
|
||||
TCronEntry *Entry = CronEntry.at(Position);
|
||||
|
||||
if(Entry->Next != -1){
|
||||
CronEntry.at(Entry->Next)->Previous = Entry->Previous;
|
||||
}
|
||||
|
||||
if(Entry->Previous != -1){
|
||||
CronEntry.at(Entry->Previous)->Next = Entry->Next;
|
||||
}else{
|
||||
CronHashTable[Entry->Obj.ObjectID % NARRAY(CronHashTable)] = Entry->Next;
|
||||
}
|
||||
|
||||
int Last = CronEntries;
|
||||
CronEntries -= 1;
|
||||
if(Position != Last){
|
||||
CronMove(Position, Last);
|
||||
CronHeapify(Position);
|
||||
}
|
||||
}
|
||||
|
||||
Object CronCheck(void){
|
||||
Object Obj = NONE;
|
||||
if(CronEntries != 0){
|
||||
TCronEntry *Entry = CronEntry.at(1);
|
||||
if(Entry->RoundNr <= RoundNr){
|
||||
Obj = Entry->Obj;
|
||||
}
|
||||
}
|
||||
return Obj;
|
||||
}
|
||||
|
||||
void CronExpire(Object Obj, int Delay){
|
||||
if(!Obj.exists()){
|
||||
error("CronExpire: Übergebenes Objekt existiert nicht.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectType ObjType = Obj.getObjectType();
|
||||
if(ObjType.getFlag(EXPIRE)){
|
||||
if(Delay == -1){
|
||||
CronSet(Obj, ObjType.getAttribute(TOTALEXPIRETIME));
|
||||
}else{
|
||||
CronSet(Obj, (uint32)Delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CronChange(Object Obj, int NewDelay){
|
||||
if(!Obj.exists()){
|
||||
error("CronChange: Übergebenes Objekt existiert nicht.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int Position = CronHashTable[Obj.ObjectID % NARRAY(CronHashTable)];
|
||||
while(Position != -1){
|
||||
TCronEntry *Entry = CronEntry.at(Position);
|
||||
if(Entry->Obj == Obj){
|
||||
Entry->RoundNr = RoundNr + NewDelay;
|
||||
CronHeapify(Position);
|
||||
return;
|
||||
}
|
||||
Position = Entry->Next;
|
||||
}
|
||||
|
||||
error("CronChange: Objekt ist nicht im Cron-System eingetragen.\n");
|
||||
}
|
||||
|
||||
uint32 CronInfo(Object Obj, bool Delete){
|
||||
if(!Obj.exists()){
|
||||
error("CronInfo: Übergebenes Objekt existiert nicht.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Position = CronHashTable[Obj.ObjectID % NARRAY(CronHashTable)];
|
||||
while(Position != -1){
|
||||
TCronEntry *Entry = CronEntry.at(Position);
|
||||
if(Entry->Obj == Obj){
|
||||
uint32 Remaining = 1;
|
||||
if(Entry->RoundNr < RoundNr){
|
||||
Remaining = Entry->RoundNr - RoundNr;
|
||||
}
|
||||
if(Delete){
|
||||
CronDelete(Position);
|
||||
}
|
||||
return Remaining;
|
||||
}
|
||||
Position = Entry->Next;
|
||||
}
|
||||
|
||||
error("CronInfo: Objekt ist nicht im Cron-System eingetragen.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 CronStop(Object Obj){
|
||||
if(!Obj.exists()){
|
||||
error("CronStop: Übergebenes Objekt existiert nicht.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CronInfo(Obj, true);
|
||||
}
|
||||
|
||||
// Map Management
|
||||
// =============================================================================
|
||||
static void ReadMapConfig(void){
|
||||
@ -161,7 +357,6 @@ static void ReadMapConfig(void){
|
||||
VeteranStartPositionZ = 0;
|
||||
HashTableSize = 0x100000;
|
||||
Marks = 0;
|
||||
Depots = 0;
|
||||
|
||||
char FileName[4096];
|
||||
snprintf(FileName, sizeof(FileName), "%s/map.dat", DATAPATH);
|
||||
@ -1772,6 +1967,17 @@ Object GetFirstObject(int x, int y, int z){
|
||||
}
|
||||
}
|
||||
|
||||
Object GetFirstSpecObject(int x, int y, int z, ObjectType Type){
|
||||
Object Obj = GetFirstObject(x, y, z);
|
||||
while(Obj != NONE){
|
||||
if(Obj.getObjectType() == Type){
|
||||
break;
|
||||
}
|
||||
Obj = Obj.getNextObject();
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
uint8 GetMapContainerFlags(Object Obj){
|
||||
if(!Obj.exists() || !Obj.getObjectType().isMapContainer()){
|
||||
error("GetMapContainerFlags: Objekt ist kein MapContainer.\n");
|
||||
@ -1810,3 +2016,174 @@ void GetObjectCoordinates(Object Obj, int *x, int *y, int *z){
|
||||
// holds its house id.
|
||||
*z = AccessObject(Obj)->Attributes[3] & 0xFF;
|
||||
}
|
||||
|
||||
bool CoordinateFlag(int x, int y, int z, FLAG Flag){
|
||||
bool Result = false;
|
||||
Object Obj = GetFirstObject(x, y, z);
|
||||
while(Obj != NONE){
|
||||
if(Obj.getObjectType().getFlag(Flag)){
|
||||
Result = true;
|
||||
break;
|
||||
}
|
||||
Obj = Obj.getNextObject();
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool IsOnMap(int x, int y, int z){
|
||||
int SectorX = x / 32;
|
||||
int SectorY = y / 32;
|
||||
int SectorZ = z;
|
||||
|
||||
return SectorXMin <= SectorX && SectorX <= SectorXMax
|
||||
&& SectorYMin <= SectorY && SectorY <= SectorYMax
|
||||
&& SectorZMin <= SectorZ && SectorZ <= SectorZMax;
|
||||
}
|
||||
|
||||
bool IsPremiumArea(int x, int y, int z){
|
||||
int SectorX = x / 32;
|
||||
int SectorY = y / 32;
|
||||
|
||||
// TODO(fusion): This is checking if the position lies within certain bounding
|
||||
// boxes but it is difficult to unwind the condition due to optimizations. The
|
||||
// best way to understand the outline of the region is to plot this function.
|
||||
bool Result = true;
|
||||
if(SectorX < 0x40C
|
||||
&& (SectorX < 0x408 || SectorY > 0x3E6)
|
||||
&& (SectorX < 0x406 || SectorY < 0x3F0)
|
||||
&& (SectorX < 0x405 || SectorY < 0x3F1)
|
||||
&& (SectorX < 0x3FE || SectorY < 0x3F6)){
|
||||
Result = SectorY > 0x3F7;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool IsNoLogoutField(int x, int y, int z){
|
||||
bool Result = false;
|
||||
Object Con = GetMapContainer(x, y, z);
|
||||
if(Con != NONE){
|
||||
Result = (GetMapContainerFlags(Con) & 0x02) != 0;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool IsProtectionZone(int x, int y, int z){
|
||||
bool Result = false;
|
||||
Object Con = GetMapContainer(x, y, z);
|
||||
if(Con != NONE){
|
||||
Result = (GetMapContainerFlags(Con) & 0x04) != 0;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool IsHouse(int x, int y, int z){
|
||||
return GetHouseID(x, y, z) != 0;
|
||||
}
|
||||
|
||||
uint16 GetHouseID(int x, int y, int z){
|
||||
Object Con = GetMapContainer(x, y, z);
|
||||
if(Con == NONE){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!Con.exists()){
|
||||
error("GetHouseID: Kartencontainer für Punkt [%d,%d,%d] existiert nicht.\n", x, y, z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE(fusion): See note in `GetObjectCoordinates`.
|
||||
return (uint16)(AccessObject(Con)->Attributes[3] >> 16);
|
||||
}
|
||||
|
||||
void SetHouseID(int x, int y, int z, uint16 ID){
|
||||
if(!IsOnMap(x, y, z)){
|
||||
return;
|
||||
}
|
||||
|
||||
Object Con = GetMapContainer(x, y, z);
|
||||
if(Con == NONE || !Con.exists()){
|
||||
error("SetHouseID: Kartencontainer für Punkt [%d,%d,%d] existiert nicht.\n", x, y, z);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(fusion): See note in `GetObjectCoordinates`.
|
||||
uint16 PrevID = (uint16)(AccessObject(Con)->Attributes[3] >> 16);
|
||||
if(PrevID != 0){
|
||||
error("SetHouseID: Feld [%d,%d,%d] gehört schon zu einem Haus.\n", x, y, z);
|
||||
return;
|
||||
}
|
||||
|
||||
AccessObject(Con)->Attributes[3] |= ((uint32)ID << 16);
|
||||
}
|
||||
|
||||
int GetDepotNumber(const char *Town){
|
||||
if(Town == NULL){
|
||||
error("GetDepotNumber: Town ist NULL.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(int DepotNumber = DepotInfo.min;
|
||||
DepotNumber <= DepotInfo.max;
|
||||
DepotNumber += 1){
|
||||
if(stricmp(DepotInfo.at(DepotNumber)->Town, Town) == 0){
|
||||
return DepotNumber;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *GetDepotName(int DepotNumber){
|
||||
if(DepotNumber < DepotInfo.min || DepotNumber > DepotInfo.max){
|
||||
error("GetDepotName: Ungültiger Name für Depot %d.\n", DepotNumber);
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
return DepotInfo.at(DepotNumber)->Town;
|
||||
}
|
||||
|
||||
int GetDepotSize(int DepotNumber, bool PremiumAccount){
|
||||
if(DepotNumber < DepotInfo.min || DepotNumber > DepotInfo.max){
|
||||
error("GetDepotSize: Ungültige Depotnummer %d.\n", DepotNumber);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TDepotInfo *Info = DepotInfo.at(DepotNumber);
|
||||
if(Info->Size < 1){
|
||||
error("GetDepotSize: Ungültige Depotgröße %d für Depot %d.\n", Info->Size, DepotNumber);
|
||||
Info->Size = 1;
|
||||
}
|
||||
|
||||
int Size = Info->Size;
|
||||
if(PremiumAccount){
|
||||
Size *= 2;
|
||||
}
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
||||
bool GetMarkPosition(const char *Name, int *x, int *y, int *z){
|
||||
bool Result = false;
|
||||
for(int i = 0; i < Marks; i += 1){
|
||||
TMark *MarkPointer = Mark.at(i);
|
||||
if(stricmp(MarkPointer->Name, Name) == 0){
|
||||
*x = MarkPointer->x;
|
||||
*y = MarkPointer->y;
|
||||
*z = MarkPointer->z;
|
||||
Result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
void GetStartPosition(int *x, int *y, int *z, bool Newbie){
|
||||
if(Newbie){
|
||||
*x = NewbieStartPositionX;
|
||||
*y = NewbieStartPositionY;
|
||||
*z = NewbieStartPositionZ;
|
||||
}else{
|
||||
*x = VeteranStartPositionX;
|
||||
*y = VeteranStartPositionY;
|
||||
*z = VeteranStartPositionZ;
|
||||
}
|
||||
}
|
||||
|
||||
35
src/map.hh
35
src/map.hh
@ -99,6 +99,13 @@ struct TCronEntry {
|
||||
int Next;
|
||||
};
|
||||
|
||||
// NOTE(fusion): Cron management functions. Most for internal use.
|
||||
Object CronCheck(void);
|
||||
void CronExpire(Object Obj, int Delay);
|
||||
void CronChange(Object Obj, int NewDelay);
|
||||
uint32 CronInfo(Object Obj, bool Delete);
|
||||
uint32 CronStop(Object Obj);
|
||||
|
||||
// NOTE(fusion): Map management functions. Most for internal use.
|
||||
void SwapObject(TWriteBinaryFile *File, Object Obj, uint32 FileNumber);
|
||||
void SwapSector(void);
|
||||
@ -140,21 +147,21 @@ Object GetContainerObject(Object Con, int Index);
|
||||
Object GetMapContainer(int x, int y, int z);
|
||||
Object GetMapContainer(Object Obj);
|
||||
Object GetFirstObject(int x, int y, int z);
|
||||
//GetFirstSpecObject
|
||||
Object GetFirstSpecObject(int x, int y, int z, ObjectType Type);
|
||||
uint8 GetMapContainerFlags(Object Obj);
|
||||
//CoordinateFlag
|
||||
void GetObjectCoordinates(Object Obj, int *x, int *y, int *z);
|
||||
//IsOnMap
|
||||
//IsPremiumArea
|
||||
//IsProtectionZone
|
||||
//IsNoLogoutField
|
||||
//IsHouse
|
||||
//GetHouseID
|
||||
//SetHouseID
|
||||
//GetDepotNumber
|
||||
//GetDepotName
|
||||
//GetDepotSize
|
||||
//GetStartPosition
|
||||
//GetMarkPosition
|
||||
bool CoordinateFlag(int x, int y, int z, FLAG Flag);
|
||||
bool IsOnMap(int x, int y, int z);
|
||||
bool IsPremiumArea(int x, int y, int z);
|
||||
bool IsNoLogoutField(int x, int y, int z);
|
||||
bool IsProtectionZone(int x, int y, int z);
|
||||
bool IsHouse(int x, int y, int z);
|
||||
uint16 GetHouseID(int x, int y, int z);
|
||||
void SetHouseID(int x, int y, int z, uint16 ID);
|
||||
int GetDepotNumber(const char *Town);
|
||||
const char *GetDepotName(int DepotNumber);
|
||||
int GetDepotSize(int DepotNumber, bool PremiumAccount);
|
||||
bool GetMarkPosition(const char *Name, int *x, int *y, int *z);
|
||||
void GetStartPosition(int *x, int *y, int *z, bool Newbie);
|
||||
|
||||
#endif //TIBIA_MAP_HH_
|
||||
|
||||
@ -22,16 +22,11 @@ extern void Change(Object Obj, ObjectType NewType, uint32 Value);
|
||||
extern bool CheckRight(uint32 CreatureID, RIGHT Right);
|
||||
extern void CleanupDynamicStrings(void);
|
||||
extern void CreatePlayerList(bool Online);
|
||||
extern void CronChange(Object Obj, int NewDelay);
|
||||
extern void CronExpire(Object Obj, int Delay);
|
||||
extern uint32 CronInfo(Object Obj, bool Delete);
|
||||
extern uint32 CronStop(Object Obj);
|
||||
extern void DeleteDynamicString(uint32 Number);
|
||||
extern TCreature *GetCreature(uint32 CreatureID);
|
||||
extern const char *GetDynamicString(uint32 Number);
|
||||
extern TConnection *GetFirstConnection(void);
|
||||
extern TConnection *GetNextConnection(void);
|
||||
extern bool IsProtectionZone(int x, int y, int z);
|
||||
extern void Log(const char *ProtocolName, const char *Text, ...) ATTR_PRINTF(2, 3);
|
||||
extern void LogoutAllPlayers(void);
|
||||
extern void Move(uint32 CreatureID, Object Obj, Object Con, int Count, bool NoMerge, Object Ignore);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user