aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-06-06 19:36:18 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-06-06 19:36:18 -0300
commit76f6ecb7c809c6e93447efb91bdf50f2a9d50d6b (patch)
treeece58733660361874acc912208d6482d639e556e
parent850fa1c0e128a4fe05ffdbdabc9dad25a7530a3f (diff)
downloadgame-76f6ecb7c809c6e93447efb91bdf50f2a9d50d6b.tar.gz
game-76f6ecb7c809c6e93447efb91bdf50f2a9d50d6b.zip
some work on `crmain.cc` and `cract.cc` + merge creature headers
-rw-r--r--Makefile6
-rw-r--r--TODO.md12
-rw-r--r--reference/game.c3443
-rw-r--r--reference/types.hh32
-rw-r--r--src/connection.hh84
-rw-r--r--src/containers.hh4
-rw-r--r--src/cr.hh77
-rw-r--r--src/cract.cc809
-rw-r--r--src/crcombat.cc6
-rw-r--r--src/crmain.cc581
-rw-r--r--src/crskill.cc12
-rw-r--r--src/magic.cc7
-rw-r--r--src/map.cc28
-rw-r--r--src/map.hh15
-rw-r--r--src/stubs.hh12
15 files changed, 1553 insertions, 3575 deletions
diff --git a/Makefile b/Makefile
index c958d5b..e3acc48 100644
--- a/Makefile
+++ b/Makefile
@@ -15,13 +15,17 @@ endif
HEADERS = $(SRCDIR)/common.hh $(SRCDIR)/config.hh $(SRCDIR)/connection.hh $(SRCDIR)/containers.hh $(SRCDIR)/cr.hh $(SRCDIR)/enums.hh $(SRCDIR)/info.hh $(SRCDIR)/magic.hh $(SRCDIR)/map.hh $(SRCDIR)/objects.hh $(SRCDIR)/script.hh $(SRCDIR)/stubs.hh $(SRCDIR)/thread.hh
-$(BUILDDIR)/$(OUTPUTEXE): $(BUILDDIR)/config.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/crmain.obj $(BUILDDIR)/crplayer.obj $(BUILDDIR)/crskill.obj $(BUILDDIR)/info.obj $(BUILDDIR)/magic.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/script.obj $(BUILDDIR)/shm.obj $(BUILDDIR)/strings.obj $(BUILDDIR)/thread.obj $(BUILDDIR)/time.obj $(BUILDDIR)/util.obj
+$(BUILDDIR)/$(OUTPUTEXE): $(BUILDDIR)/config.obj $(BUILDDIR)/cract.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/crmain.obj $(BUILDDIR)/crplayer.obj $(BUILDDIR)/crskill.obj $(BUILDDIR)/info.obj $(BUILDDIR)/magic.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/script.obj $(BUILDDIR)/shm.obj $(BUILDDIR)/strings.obj $(BUILDDIR)/thread.obj $(BUILDDIR)/time.obj $(BUILDDIR)/util.obj
$(CC) -c $(CFLAGS) $(LFLAGS) -o $@ $^
$(BUILDDIR)/config.obj: $(SRCDIR)/config.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
+$(BUILDDIR)/cract.obj: $(SRCDIR)/cract.cc $(HEADERS)
+ @mkdir -p $(@D)
+ $(CC) -c $(CFLAGS) -o $@ $<
+
$(BUILDDIR)/crcombat.obj: $(SRCDIR)/crcombat.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
diff --git a/TODO.md b/TODO.md
index e237083..12dc857 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,8 +1,12 @@
## TODO NEXT
-- merge creature headers into a single one CR.HH
- - this should help preventing dependency cycles and centralize creature data
- structures and globals in a single place
-- CRMAIN.CC, CRPLAYER.CC, CRNONPL.CC, CRACT.CC
+- CRACT.CC
+- CRMAIN.CC
+ - TCreature::CreatureMoveStimulus
+ - FINDCREATURES
+ - KILL STATS
+ - RACE
+ - RAIDS
+- CRPLAYER.CC, CRNONPL.CC
- HOUSES.CC
- INFO.CC
- OPERATE.CC
diff --git a/reference/game.c b/reference/game.c
index 9fbabaf..65f96be 100644
--- a/reference/game.c
+++ b/reference/game.c
@@ -29623,370 +29623,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
return;
}
-
-
-TCreature * GetCreature(ulong id)
-
-{
- TCreature *pTVar1;
- ulong m;
-
- if ((id != 0) && (pTVar1 = HashList[id % 1000], pTVar1 != (TCreature *)0x0)) {
- if (pTVar1->ID == id) {
- return pTVar1;
- }
- for (pTVar1 = pTVar1->NextHashEntry; pTVar1 != (TCreature *)0x0;
- pTVar1 = pTVar1->NextHashEntry) {
- if (pTVar1->ID == id) {
- return pTVar1;
- }
- }
- }
- return (TCreature *)0x0;
-}
-
-
-
-TCreature * GetCreature(Object *Obj)
-
-{
- ulong id;
- TCreature *pTVar1;
-
- id = Object::getCreatureID(Obj);
- pTVar1 = GetCreature(id);
- return pTVar1;
-}
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void ProcessSkills(void)
-
-{
- TCreature *pTVar1;
- TCreature *cr;
- TCreature **ppTVar2;
- int i;
- int i_00;
-
- i_00 = 0;
- if (0 < FirstFreeCreature) {
- do {
- ppTVar2 = vector<TCreature*>::operator()(&CreatureList,i_00);
- pTVar1 = *ppTVar2;
- if (pTVar1 == (TCreature *)0x0) {
- error("ProcessSkills: Kreatur %d existiert nicht.\n",i_00);
- }
- else if ((pTVar1->super_TSkillBase).FirstFreeTimer != 0) {
- TSkillBase::ProcessSkills(&pTVar1->super_TSkillBase);
- }
- i_00 = i_00 + 1;
- } while (i_00 < FirstFreeCreature);
- }
- return;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void ProcessCreatures(void)
-
-{
- TPlayer *this;
- bool bVar1;
- TCreature **ppTVar2;
- int iVar3;
- uint uVar4;
- CreatureType CVar5;
- TCreature *cr;
- int i;
- int i_00;
-
- i_00 = 0;
- if (0 < FirstFreeCreature) {
- do {
- ppTVar2 = vector<TCreature*>::operator()(&CreatureList,i_00);
- this = (TPlayer *)*ppTVar2;
- if (this == (TPlayer *)0x0) {
- error("ProcessCreatures: Kreatur %d existiert nicht.\n",i_00);
- }
- else {
- iVar3 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[0xe]);
- if ((((iVar3 < 1) ||
- (uVar4 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[0xe]),
- RoundNr % uVar4 != 0)) || ((this->super_TCreature).IsDead != false)) ||
- (bVar1 = IsProtectionZone(), bVar1)) {
-LAB_0809e093:
- if ((this->super_TCreature).Type == PLAYER) {
- CVar5 = PLAYER;
- if ((this->super_TCreature).Connection != (TConnection *)0x0) {
- TPlayer::CheckState(this);
- CVar5 = (this->super_TCreature).Type;
- }
- if (((CVar5 == PLAYER) &&
- (uVar4 = (this->super_TCreature).EarliestLogoutRound, uVar4 != 0)) &&
- (uVar4 <= RoundNr)) {
- TPlayer::ClearPlayerkillingMarks(this);
- (this->super_TCreature).EarliestLogoutRound = 0;
- }
- }
- }
- else {
- TSkill::Change((this->super_TCreature).super_TSkillBase.Skills[2],1);
- TSkill::Change((this->super_TCreature).super_TSkillBase.Skills[3],4);
- if ((this->super_TCreature).Type == PLAYER) {
- SendPlayerData((this->super_TCreature).Connection);
- goto LAB_0809e093;
- }
- }
- if (((this->super_TCreature).IsDead == false) &&
- (iVar3 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[2]),
- iVar3 < 1)) {
- error("ProcessCreatures: Kreatur %s ist nicht tot, obwohl sie keine HP mehr hat.\n"
- ,(this->super_TCreature).Name);
- (*(this->super_TCreature)._vptr_TCreature[2])(this);
- }
- if (((this->super_TCreature).LoggingOut != false) &&
- (iVar3 = TCreature::LogoutPossible((TCreature *)this), iVar3 == 0)) {
- if (((this->super_TCreature).IsDead != false) &&
- (iVar3 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[2]),
- 0 < iVar3)) {
- error("ProcessCreatures: Kreatur %s hat HP, obwohl sie tot ist.\n",
- (this->super_TCreature).Name);
- (*(this->super_TCreature).super_TSkillBase.Skills[2]->_vptr_TSkill[2])
- ((this->super_TCreature).super_TSkillBase.Skills[2],0);
- }
- if (this != (TPlayer *)0x0) {
- (*(this->super_TCreature)._vptr_TCreature[1])(this);
- }
- i_00 = i_00 + -1;
- }
- }
- i_00 = i_00 + 1;
- } while (i_00 < FirstFreeCreature);
- }
- return;
-}
-
-
-
-void MoveCreatures(int Delay)
-
-{
- uint uVar1;
- ulong id;
- bool Found;
- TCreature *this;
- priority_queue_entry<> *ppVar2;
- ulong CreatureID;
- ulong ExecutionTime;
-
- ServerMilliseconds = ServerMilliseconds + Delay;
- while( true ) {
- if (ToDoQueue.Entries == 0) {
- return;
- }
- ppVar2 = vector<>::operator()(ToDoQueue.Entry,1);
- uVar1 = ppVar2->Key;
- ppVar2 = vector<>::operator()(ToDoQueue.Entry,1);
- id = ppVar2->Data;
- if (ServerMilliseconds < uVar1) break;
- priority_queue<>::deleteMin(&ToDoQueue);
- this = GetCreature(id);
- if (this != (TCreature *)0x0) {
- TCreature::Execute(this);
- }
- }
- return;
-}
-
-
-
-// WARNING: Variable defined which should be unmapped: blockx
-
-void DeleteChainCreature(TCreature *cr)
-
-{
- ulong id;
- matrix<> *pmVar1;
- ulong ID;
- uint uVar2;
- uint uVar3;
- int iVar4;
- ulong *puVar5;
- TCreature *pTVar6;
- TCreature *Help;
- int iVar7;
- int blocky;
- int blockx;
-
- pmVar1 = FirstChainCreature;
- if (cr == (TCreature *)0x0) {
- cr = (TCreature *)&DAT_08101a00;
-LAB_0809e38b:
- error((char *)cr);
- return;
- }
- uVar2 = cr->posx;
- if (0x7fffffff < uVar2) {
- uVar2 = uVar2 + 0xf;
- }
- uVar3 = cr->posy;
- if (0x7fffffff < uVar3) {
- uVar3 = uVar3 + 0xf;
- }
- iVar4 = ((int)uVar3 >> 4) - FirstChainCreature->ymin;
- iVar7 = ((int)uVar2 >> 4) - FirstChainCreature->xmin;
- if ((((iVar7 < 0) || (FirstChainCreature->dx <= iVar7)) || (iVar4 < 0)) ||
- (FirstChainCreature->dy <= iVar4)) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar7 + FirstChainCreature->xmin,
- iVar4 + FirstChainCreature->ymin);
- puVar5 = pmVar1->entry;
- }
- else {
- puVar5 = FirstChainCreature->entry + iVar7 + iVar4 * FirstChainCreature->dx;
- }
- pmVar1 = FirstChainCreature;
- id = *puVar5;
- if (id == cr->ID) {
- iVar4 = ((int)uVar3 >> 4) - FirstChainCreature->ymin;
- iVar7 = ((int)uVar2 >> 4) - FirstChainCreature->xmin;
- if (((iVar7 < 0) || (FirstChainCreature->dx <= iVar7)) ||
- ((iVar4 < 0 || (FirstChainCreature->dy <= iVar4)))) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar7 + FirstChainCreature->xmin,
- iVar4 + FirstChainCreature->ymin);
- puVar5 = pmVar1->entry;
- }
- else {
- puVar5 = FirstChainCreature->entry + iVar7 + iVar4 * FirstChainCreature->dx;
- }
- *puVar5 = cr->NextChainCreature;
- }
- else {
- do {
- if (id == 0) {
- cr = (TCreature *)s_DeleteChainCreature__Kreatur_nic_08101980;
- goto LAB_0809e38b;
- }
- pTVar6 = GetCreature(id);
- if (pTVar6 == (TCreature *)0x0) {
- cr = (TCreature *)s_DeleteChainCreature__Kreatur_exi_081019c0;
- goto LAB_0809e38b;
- }
- id = pTVar6->NextChainCreature;
- } while (id != cr->ID);
- pTVar6->NextChainCreature = cr->NextChainCreature;
- }
- return;
-}
-
-
-
-// WARNING: Variable defined which should be unmapped: cr_local
-
-void InsertChainCreature(TCreature *cr,int newx,int newy)
-
-{
- matrix<> *pmVar1;
- int iVar2;
- ulong *puVar3;
- int iVar4;
- int blocky;
- int blockx;
- TCreature *cr_local;
-
- pmVar1 = FirstChainCreature;
- if (cr == (TCreature *)0x0) {
- error(&DAT_08101a00);
- return;
- }
- if (newx == 0) {
- newx = cr->posx;
- if (0x7fffffff < (uint)newx) {
- newx = newx + 0xf;
- }
- }
- else if (0x7fffffff < (uint)newx) {
- newx = newx + 0xf;
- }
- if (newy == 0) {
- newy = cr->posy;
- if (0x7fffffff < (uint)newy) {
- newy = newy + 0xf;
- }
- }
- else if (0x7fffffff < (uint)newy) {
- newy = newy + 0xf;
- }
- iVar2 = (newy >> 4) - FirstChainCreature->ymin;
- iVar4 = (newx >> 4) - FirstChainCreature->xmin;
- if ((((iVar4 < 0) || (FirstChainCreature->dx <= iVar4)) || (iVar2 < 0)) ||
- (FirstChainCreature->dy <= iVar2)) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar4 + FirstChainCreature->xmin,
- iVar2 + FirstChainCreature->ymin);
- puVar3 = pmVar1->entry;
- }
- else {
- puVar3 = FirstChainCreature->entry + iVar4 + iVar2 * FirstChainCreature->dx;
- }
- cr->NextChainCreature = *puVar3;
- pmVar1 = FirstChainCreature;
- iVar2 = (newy >> 4) - FirstChainCreature->ymin;
- iVar4 = (newx >> 4) - FirstChainCreature->xmin;
- if (((iVar4 < 0) || (FirstChainCreature->dx <= iVar4)) ||
- ((iVar2 < 0 || (FirstChainCreature->dy <= iVar2)))) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar4 + FirstChainCreature->xmin,
- iVar2 + FirstChainCreature->ymin);
- puVar3 = pmVar1->entry;
- }
- else {
- puVar3 = FirstChainCreature->entry + iVar4 + iVar2 * FirstChainCreature->dx;
- }
- *puVar3 = cr->ID;
- return;
-}
-
-
-
-void MoveChainCreature(TCreature *cr,int newx,int newy)
-
-{
- uint uVar1;
- int iVar2;
-
- if (cr == (TCreature *)0x0) {
- error(&DAT_08101a00);
- return;
- }
- uVar1 = cr->posx;
- if (0x7fffffff < uVar1) {
- uVar1 = uVar1 + 0xf;
- }
- iVar2 = newx + 0xf;
- if (-1 < newx) {
- iVar2 = newx;
- }
- if ((int)uVar1 >> 4 == iVar2 >> 4) {
- uVar1 = cr->posy;
- if (0x7fffffff < uVar1) {
- uVar1 = uVar1 + 0xf;
- }
- iVar2 = newy + 0xf;
- if (-1 < newy) {
- iVar2 = newy;
- }
- if ((int)uVar1 >> 4 == iVar2 >> 4) {
- return;
- }
- }
- DeleteChainCreature(cr);
- InsertChainCreature(cr,newx,newy);
- return;
-}
-
-
-
// DWARF original prototype: void TFindCreatures(TFindCreatures * this, int radx, int rady, int x,
// int y, int Mask)
@@ -30459,1088 +30095,6 @@ void ExitKillStatistics(void)
return;
}
-// DWARF original prototype: void ~TCreature(TCreature * this, int __in_chrg)
-
-void __thiscall TCreature::~TCreature(TCreature *this,int __in_chrg)
-
-{
- TKnownCreature *pTVar1;
- TToDoEntry *pTVar2;
- bool bVar3;
- bool bVar4;
- RESULT r_2;
- ObjectType *pOVar5;
- TCreature **ppTVar6;
- TCreature **ppTVar7;
- long lVar8;
- ulong Value;
- RESULT r;
- TKnownCreature *KnownCreature;
- int iVar9;
- int i_1;
- Object *pOVar10;
- char *in_stack_fffffef8;
- char *__src;
- Object local_ec;
- char s [128];
- Object Corpse;
- Object local_5c;
- Object Obj;
- ObjectType local_4c;
- ObjectType CorpseType;
- Object local_3c;
- Object Obj_1;
- Object local_2c [7];
-
- this->_vptr_TCreature = (_func_int_varargs **)&PTR__TCreature_08127be8;
- if (this->IsDead != false) {
- iVar9 = this->Race;
- if (RaceData[iVar9].Blood == BT_BLOOD) {
- GetSpecialObject((SPECIALMEANING)local_2c);
- local_4c.TypeID = (this->CrObject).ObjectID;
- GetMapContainer(&local_3c);
- CreatePool();
- iVar9 = this->Race;
- }
- if (RaceData[iVar9].Blood == BT_SLIME) {
- // try { // try from 0809f7ce to 0809f85d has its CatchHandler @ 0809f869
- GetSpecialObject((SPECIALMEANING)&local_4c);
- local_2c[0].ObjectID = (this->CrObject).ObjectID;
- GetMapContainer(&local_3c);
- CreatePool();
- iVar9 = this->Race;
- }
- if (this->Sex == 1) {
- pOVar5 = &RaceData[iVar9].MaleCorpse;
- }
- else {
- pOVar5 = &RaceData[iVar9].FemaleCorpse;
- }
- // try { // try from 0809f31c to 0809f4ab has its CatchHandler @ 0809f957
- ObjectType::setTypeID(&local_4c,pOVar5->TypeID);
- bVar3 = ObjectType::getFlag(&local_4c,MAGICFIELD);
- if (bVar3) {
- GetFirstObject();
- local_5c = (Object)::NONE.ObjectID;
- local_2c[0].ObjectID = local_5c.ObjectID;
- if (local_3c.ObjectID != ::NONE.ObjectID) {
- do {
- local_5c.ObjectID = local_3c.ObjectID;
- local_2c[0].ObjectID = ::NONE.ObjectID;
- Object::getNextObject((Object *)(s + 0x7c));
- local_3c.ObjectID._0_1_ = s[0x7c];
- local_3c.ObjectID._1_1_ = s[0x7d];
- local_3c.ObjectID._2_1_ = s[0x7e];
- local_3c.ObjectID._3_1_ = s[0x7f];
- local_2c[0].ObjectID._0_1_ = s[0x7c];
- local_2c[0].ObjectID._1_1_ = s[0x7d];
- local_2c[0].ObjectID._2_1_ = s[0x7e];
- local_2c[0].ObjectID._3_1_ = s[0x7f];
- Object::getObjectType((Object *)(s + 0x7c));
- bVar3 = ObjectType::getFlag((ObjectType *)(s + 0x7c),MAGICFIELD);
- if (bVar3) {
- s[0x7c] = (undefined1)local_5c.ObjectID;
- s[0x7d] = local_5c.ObjectID._1_1_;
- s[0x7e] = local_5c.ObjectID._2_1_;
- s[0x7f] = local_5c.ObjectID._3_1_;
- // try { // try from 0809f7a4 to 0809f7a8 has its CatchHandler @ 0809f8d4
- Delete((Object *)(s + 0x7c),-1);
- }
- local_2c[0].ObjectID = ::NONE.ObjectID;
- local_5c.ObjectID = ::NONE.ObjectID;
- } while (local_3c.ObjectID != ::NONE.ObjectID);
- }
- }
- ObjectType::setTypeID((ObjectType *)&local_5c,local_4c.TypeID);
- GetMapContainer((int)&local_3c,this->posx,this->posy);
- Create((Object *)(s + 0x7c),(ObjectType *)&local_3c,(ulong)&local_5c);
- in_stack_fffffef8 = "Tod von %s: LoseInventory=%d.\n";
- Log("game","Tod von %s: LoseInventory=%d.\n",this->Name,this->LoseInventory);
- if (this->Type == PLAYER) {
- sprintf((char *)&local_ec,"You recognize %s",this->Name);
- if (this->Murderer[0] != '\0') {
- if (this->Sex == 1) {
- __src = ". He ";
- }
- else {
- __src = ". She ";
- }
- strcat((char *)&local_ec,__src);
- strcat((char *)&local_ec,"was killed by ");
- strcat((char *)&local_ec,this->Murderer);
- }
- Value = AddDynamicString((char *)&local_ec);
- in_stack_fffffef8 = (char *)0x9;
- local_5c.ObjectID._0_1_ = s[0x7c];
- local_5c.ObjectID._1_1_ = s[0x7d];
- local_5c.ObjectID._2_1_ = s[0x7e];
- local_5c.ObjectID._3_1_ = s[0x7f];
- Change(&local_5c,TEXTSTRING,Value);
- }
- if (this->LoseInventory != 0) {
- iVar9 = 1;
- do {
- in_stack_fffffef8 = (char *)this->ID;
- GetBodyObject((ulong)&local_5c,(int)in_stack_fffffef8);
- local_3c.ObjectID = ::NONE.ObjectID;
- if (local_5c.ObjectID != ::NONE.ObjectID) {
- if (this->LoseInventory != 2) {
- Object::getObjectType(&local_3c);
- bVar3 = ObjectType::getFlag((ObjectType *)&local_3c,CONTAINER);
- if (!bVar3) {
- in_stack_fffffef8 = (char *)0x9;
- // try { // try from 0809f63b to 0809f76e has its CatchHandler @ 0809f957
- lVar8 = random();
- if (lVar8 != 0) goto LAB_0809f487;
- }
- }
- local_3c.ObjectID = ::NONE.ObjectID;
- local_ec.ObjectID = local_5c.ObjectID;
- in_stack_fffffef8 = (char *)&local_ec;
- local_2c[0].ObjectID._0_1_ = s[0x7c];
- local_2c[0].ObjectID._1_1_ = s[0x7d];
- local_2c[0].ObjectID._2_1_ = s[0x7e];
- local_2c[0].ObjectID._3_1_ = s[0x7f];
- ::Move(0,(Object *)in_stack_fffffef8,local_2c,-1,false,&local_3c);
- }
-LAB_0809f487:
- iVar9 = iVar9 + 1;
- } while (iVar9 < 0xb);
- }
- if ((this->Type == PLAYER) && (this->LoseInventory != 2)) {
- TPlayer::SaveInventory((TPlayer *)this);
- }
- }
- bVar3 = false;
- local_ec.ObjectID = ::NONE.ObjectID;
- s[0x7c] = (undefined1)::NONE.ObjectID;
- s[0x7d] = ::NONE.ObjectID._1_1_;
- s[0x7e] = ::NONE.ObjectID._2_1_;
- s[0x7f] = ::NONE.ObjectID._3_1_;
- if (((this->CrObject).ObjectID != ::NONE.ObjectID) &&
- (bVar4 = Object::exists(&this->CrObject), bVar4)) {
- bVar3 = true;
- }
- if (bVar3) {
- DelOnMap(this);
- }
- ToDoClear(this);
- if ((this->Type == PLAYER) && (this->Connection != (TConnection *)0x0)) {
- in_stack_fffffef8 = (char *)0x1e;
- TConnection::Logout(this->Connection,0x1e,true);
- }
- pOVar10 = (Object *)0x0;
- if (0 < FirstFreeCreature) {
- do {
- in_stack_fffffef8 = (char *)pOVar10;
- ppTVar6 = vector<TCreature*>::operator()(&CreatureList,(int)pOVar10);
- if (*ppTVar6 == this) {
- ppTVar6 = vector<TCreature*>::operator()(&CreatureList,(int)pOVar10);
- ppTVar7 = vector<TCreature*>::operator()(&CreatureList,FirstFreeCreature + -1);
- *ppTVar6 = *ppTVar7;
- in_stack_fffffef8 = (char *)(FirstFreeCreature + -1);
- ppTVar6 = vector<TCreature*>::operator()(&CreatureList,(int)in_stack_fffffef8);
- *ppTVar6 = (TCreature *)0x0;
- FirstFreeCreature = FirstFreeCreature + -1;
- }
- pOVar10 = (Object *)((int)&pOVar10->ObjectID + 1);
- } while ((int)pOVar10 < FirstFreeCreature);
- }
- if (this->ID != 0) {
- DelID(this);
- }
- for (pTVar1 = this->FirstKnowingConnection; pTVar1 != (TKnownCreature *)0x0;
- pTVar1 = pTVar1->Next) {
- pOVar10 = (Object *)this->ID;
- if ((Object *)pTVar1->CreatureID != pOVar10) {
- error("TCreature::~TCreature: Verkettungsfehler bei Kreatur %lu.\n");
- in_stack_fffffef8 = (char *)pOVar10;
- }
- pTVar1->State = KNOWNCREATURE_FREE;
- }
- pTVar2 = (this->ToDoList).entry;
- if (pTVar2 != (TToDoEntry *)0x0) {
- operator_delete__(pTVar2);
- }
- TSkillBase::~TSkillBase(&this->super_TSkillBase,(int)in_stack_fffffef8);
- return;
-}
-
-
-
-// DWARF original prototype: void ~TCreature(TCreature * this, int __in_chrg)
-
-void __thiscall TCreature::~TCreature(TCreature *this,int __in_chrg)
-
-{
- TKnownCreature *pTVar1;
- TToDoEntry *pTVar2;
- bool bVar3;
- bool bVar4;
- RESULT r_2;
- ObjectType *pOVar5;
- TCreature **ppTVar6;
- TCreature **ppTVar7;
- long lVar8;
- ulong Value;
- RESULT r;
- TKnownCreature *KnownCreature;
- int iVar9;
- int i_1;
- Object *pOVar10;
- char *in_stack_fffffef8;
- char *__src;
- Object local_ec;
- char s [128];
- Object Corpse;
- Object local_5c;
- Object Obj;
- ObjectType local_4c;
- ObjectType CorpseType;
- Object local_3c;
- Object Obj_1;
- Object local_2c [7];
-
- this->_vptr_TCreature = (_func_int_varargs **)&PTR__TCreature_08127be8;
- if (this->IsDead != false) {
- iVar9 = this->Race;
- if (RaceData[iVar9].Blood == BT_BLOOD) {
- GetSpecialObject((SPECIALMEANING)local_2c);
- local_4c.TypeID = (this->CrObject).ObjectID;
- GetMapContainer(&local_3c);
- CreatePool();
- iVar9 = this->Race;
- }
- if (RaceData[iVar9].Blood == BT_SLIME) {
- // try { // try from 0809fe8e to 0809ff1d has its CatchHandler @ 0809ff29
- GetSpecialObject((SPECIALMEANING)&local_4c);
- local_2c[0].ObjectID = (this->CrObject).ObjectID;
- GetMapContainer(&local_3c);
- CreatePool();
- iVar9 = this->Race;
- }
- if (this->Sex == 1) {
- pOVar5 = &RaceData[iVar9].MaleCorpse;
- }
- else {
- pOVar5 = &RaceData[iVar9].FemaleCorpse;
- }
- // try { // try from 0809f9dc to 0809fb6b has its CatchHandler @ 080a0017
- ObjectType::setTypeID(&local_4c,pOVar5->TypeID);
- bVar3 = ObjectType::getFlag(&local_4c,MAGICFIELD);
- if (bVar3) {
- GetFirstObject();
- local_5c = (Object)::NONE.ObjectID;
- local_2c[0].ObjectID = local_5c.ObjectID;
- if (local_3c.ObjectID != ::NONE.ObjectID) {
- do {
- local_5c.ObjectID = local_3c.ObjectID;
- local_2c[0].ObjectID = ::NONE.ObjectID;
- Object::getNextObject((Object *)(s + 0x7c));
- local_3c.ObjectID._0_1_ = s[0x7c];
- local_3c.ObjectID._1_1_ = s[0x7d];
- local_3c.ObjectID._2_1_ = s[0x7e];
- local_3c.ObjectID._3_1_ = s[0x7f];
- local_2c[0].ObjectID._0_1_ = s[0x7c];
- local_2c[0].ObjectID._1_1_ = s[0x7d];
- local_2c[0].ObjectID._2_1_ = s[0x7e];
- local_2c[0].ObjectID._3_1_ = s[0x7f];
- Object::getObjectType((Object *)(s + 0x7c));
- bVar3 = ObjectType::getFlag((ObjectType *)(s + 0x7c),MAGICFIELD);
- if (bVar3) {
- s[0x7c] = (undefined1)local_5c.ObjectID;
- s[0x7d] = local_5c.ObjectID._1_1_;
- s[0x7e] = local_5c.ObjectID._2_1_;
- s[0x7f] = local_5c.ObjectID._3_1_;
- // try { // try from 0809fe64 to 0809fe68 has its CatchHandler @ 0809ff94
- Delete((Object *)(s + 0x7c),-1);
- }
- local_2c[0].ObjectID = ::NONE.ObjectID;
- local_5c.ObjectID = ::NONE.ObjectID;
- } while (local_3c.ObjectID != ::NONE.ObjectID);
- }
- }
- ObjectType::setTypeID((ObjectType *)&local_5c,local_4c.TypeID);
- GetMapContainer((int)&local_3c,this->posx,this->posy);
- Create((Object *)(s + 0x7c),(ObjectType *)&local_3c,(ulong)&local_5c);
- in_stack_fffffef8 = "Tod von %s: LoseInventory=%d.\n";
- Log("game","Tod von %s: LoseInventory=%d.\n",this->Name,this->LoseInventory);
- if (this->Type == PLAYER) {
- sprintf((char *)&local_ec,"You recognize %s",this->Name);
- if (this->Murderer[0] != '\0') {
- if (this->Sex == 1) {
- __src = ". He ";
- }
- else {
- __src = ". She ";
- }
- strcat((char *)&local_ec,__src);
- strcat((char *)&local_ec,"was killed by ");
- strcat((char *)&local_ec,this->Murderer);
- }
- Value = AddDynamicString((char *)&local_ec);
- in_stack_fffffef8 = (char *)0x9;
- local_5c.ObjectID._0_1_ = s[0x7c];
- local_5c.ObjectID._1_1_ = s[0x7d];
- local_5c.ObjectID._2_1_ = s[0x7e];
- local_5c.ObjectID._3_1_ = s[0x7f];
- Change(&local_5c,TEXTSTRING,Value);
- }
- if (this->LoseInventory != 0) {
- iVar9 = 1;
- do {
- in_stack_fffffef8 = (char *)this->ID;
- GetBodyObject((ulong)&local_5c,(int)in_stack_fffffef8);
- local_3c.ObjectID = ::NONE.ObjectID;
- if (local_5c.ObjectID != ::NONE.ObjectID) {
- if (this->LoseInventory != 2) {
- Object::getObjectType(&local_3c);
- bVar3 = ObjectType::getFlag((ObjectType *)&local_3c,CONTAINER);
- if (!bVar3) {
- in_stack_fffffef8 = (char *)0x9;
- // try { // try from 0809fcfb to 0809fe2e has its CatchHandler @ 080a0017
- lVar8 = random();
- if (lVar8 != 0) goto LAB_0809fb47;
- }
- }
- local_3c.ObjectID = ::NONE.ObjectID;
- local_ec.ObjectID = local_5c.ObjectID;
- in_stack_fffffef8 = (char *)&local_ec;
- local_2c[0].ObjectID._0_1_ = s[0x7c];
- local_2c[0].ObjectID._1_1_ = s[0x7d];
- local_2c[0].ObjectID._2_1_ = s[0x7e];
- local_2c[0].ObjectID._3_1_ = s[0x7f];
- ::Move(0,(Object *)in_stack_fffffef8,local_2c,-1,false,&local_3c);
- }
-LAB_0809fb47:
- iVar9 = iVar9 + 1;
- } while (iVar9 < 0xb);
- }
- if ((this->Type == PLAYER) && (this->LoseInventory != 2)) {
- TPlayer::SaveInventory((TPlayer *)this);
- }
- }
- bVar3 = false;
- local_ec.ObjectID = ::NONE.ObjectID;
- s[0x7c] = (undefined1)::NONE.ObjectID;
- s[0x7d] = ::NONE.ObjectID._1_1_;
- s[0x7e] = ::NONE.ObjectID._2_1_;
- s[0x7f] = ::NONE.ObjectID._3_1_;
- if (((this->CrObject).ObjectID != ::NONE.ObjectID) &&
- (bVar4 = Object::exists(&this->CrObject), bVar4)) {
- bVar3 = true;
- }
- if (bVar3) {
- DelOnMap(this);
- }
- ToDoClear(this);
- if ((this->Type == PLAYER) && (this->Connection != (TConnection *)0x0)) {
- in_stack_fffffef8 = (char *)0x1e;
- TConnection::Logout(this->Connection,0x1e,true);
- }
- pOVar10 = (Object *)0x0;
- if (0 < FirstFreeCreature) {
- do {
- in_stack_fffffef8 = (char *)pOVar10;
- ppTVar6 = vector<TCreature*>::operator()(&CreatureList,(int)pOVar10);
- if (*ppTVar6 == this) {
- ppTVar6 = vector<TCreature*>::operator()(&CreatureList,(int)pOVar10);
- ppTVar7 = vector<TCreature*>::operator()(&CreatureList,FirstFreeCreature + -1);
- *ppTVar6 = *ppTVar7;
- in_stack_fffffef8 = (char *)(FirstFreeCreature + -1);
- ppTVar6 = vector<TCreature*>::operator()(&CreatureList,(int)in_stack_fffffef8);
- *ppTVar6 = (TCreature *)0x0;
- FirstFreeCreature = FirstFreeCreature + -1;
- }
- pOVar10 = (Object *)((int)&pOVar10->ObjectID + 1);
- } while ((int)pOVar10 < FirstFreeCreature);
- }
- if (this->ID != 0) {
- DelID(this);
- }
- for (pTVar1 = this->FirstKnowingConnection; pTVar1 != (TKnownCreature *)0x0;
- pTVar1 = pTVar1->Next) {
- pOVar10 = (Object *)this->ID;
- if ((Object *)pTVar1->CreatureID != pOVar10) {
- error("TCreature::~TCreature: Verkettungsfehler bei Kreatur %lu.\n");
- in_stack_fffffef8 = (char *)pOVar10;
- }
- pTVar1->State = KNOWNCREATURE_FREE;
- }
- pTVar2 = (this->ToDoList).entry;
- if (pTVar2 != (TToDoEntry *)0x0) {
- operator_delete__(pTVar2);
- }
- TSkillBase::~TSkillBase(&this->super_TSkillBase,(int)in_stack_fffffef8);
- return;
-}
-
-
-
-// DWARF original prototype: void ~TCreature(TCreature * this, int __in_chrg)
-
-void __thiscall TCreature::~TCreature(TCreature *this,int __in_chrg)
-
-{
- TKnownCreature *pTVar1;
- TToDoEntry *pTVar2;
- bool bVar3;
- bool bVar4;
- RESULT r_2;
- ObjectType *pOVar5;
- TCreature **ppTVar6;
- TCreature **ppTVar7;
- long lVar8;
- ulong Value;
- RESULT r;
- TKnownCreature *KnownCreature;
- int iVar9;
- int i_1;
- Object *pOVar10;
- char *in_stack_fffffef8;
- char *__src;
- Object local_ec;
- char s [128];
- Object Corpse;
- Object local_5c;
- Object Obj;
- ObjectType local_4c;
- ObjectType CorpseType;
- Object local_3c;
- Object Obj_1;
- Object local_2c [7];
-
- this->_vptr_TCreature = (_func_int_varargs **)&PTR__TCreature_08127be8;
- if (this->IsDead != false) {
- iVar9 = this->Race;
- if (RaceData[iVar9].Blood == BT_BLOOD) {
- GetSpecialObject((SPECIALMEANING)local_2c);
- local_4c.TypeID = (this->CrObject).ObjectID;
- GetMapContainer(&local_3c);
- CreatePool();
- iVar9 = this->Race;
- }
- if (RaceData[iVar9].Blood == BT_SLIME) {
- // try { // try from 080a054e to 080a05dd has its CatchHandler @ 080a05e9
- GetSpecialObject((SPECIALMEANING)&local_4c);
- local_2c[0].ObjectID = (this->CrObject).ObjectID;
- GetMapContainer(&local_3c);
- CreatePool();
- iVar9 = this->Race;
- }
- if (this->Sex == 1) {
- pOVar5 = &RaceData[iVar9].MaleCorpse;
- }
- else {
- pOVar5 = &RaceData[iVar9].FemaleCorpse;
- }
- // try { // try from 080a009c to 080a022b has its CatchHandler @ 080a06d7
- ObjectType::setTypeID(&local_4c,pOVar5->TypeID);
- bVar3 = ObjectType::getFlag(&local_4c,MAGICFIELD);
- if (bVar3) {
- GetFirstObject();
- local_5c = (Object)::NONE.ObjectID;
- local_2c[0].ObjectID = local_5c.ObjectID;
- if (local_3c.ObjectID != ::NONE.ObjectID) {
- do {
- local_5c.ObjectID = local_3c.ObjectID;
- local_2c[0].ObjectID = ::NONE.ObjectID;
- Object::getNextObject((Object *)(s + 0x7c));
- local_3c.ObjectID._0_1_ = s[0x7c];
- local_3c.ObjectID._1_1_ = s[0x7d];
- local_3c.ObjectID._2_1_ = s[0x7e];
- local_3c.ObjectID._3_1_ = s[0x7f];
- local_2c[0].ObjectID._0_1_ = s[0x7c];
- local_2c[0].ObjectID._1_1_ = s[0x7d];
- local_2c[0].ObjectID._2_1_ = s[0x7e];
- local_2c[0].ObjectID._3_1_ = s[0x7f];
- Object::getObjectType((Object *)(s + 0x7c));
- bVar3 = ObjectType::getFlag((ObjectType *)(s + 0x7c),MAGICFIELD);
- if (bVar3) {
- s[0x7c] = (undefined1)local_5c.ObjectID;
- s[0x7d] = local_5c.ObjectID._1_1_;
- s[0x7e] = local_5c.ObjectID._2_1_;
- s[0x7f] = local_5c.ObjectID._3_1_;
- // try { // try from 080a0524 to 080a0528 has its CatchHandler @ 080a0654
- Delete((Object *)(s + 0x7c),-1);
- }
- local_2c[0].ObjectID = ::NONE.ObjectID;
- local_5c.ObjectID = ::NONE.ObjectID;
- } while (local_3c.ObjectID != ::NONE.ObjectID);
- }
- }
- ObjectType::setTypeID((ObjectType *)&local_5c,local_4c.TypeID);
- GetMapContainer((int)&local_3c,this->posx,this->posy);
- Create((Object *)(s + 0x7c),(ObjectType *)&local_3c,(ulong)&local_5c);
- in_stack_fffffef8 = "Tod von %s: LoseInventory=%d.\n";
- Log("game","Tod von %s: LoseInventory=%d.\n",this->Name,this->LoseInventory);
- if (this->Type == PLAYER) {
- sprintf((char *)&local_ec,"You recognize %s",this->Name);
- if (this->Murderer[0] != '\0') {
- if (this->Sex == 1) {
- __src = ". He ";
- }
- else {
- __src = ". She ";
- }
- strcat((char *)&local_ec,__src);
- strcat((char *)&local_ec,"was killed by ");
- strcat((char *)&local_ec,this->Murderer);
- }
- Value = AddDynamicString((char *)&local_ec);
- in_stack_fffffef8 = (char *)0x9;
- local_5c.ObjectID._0_1_ = s[0x7c];
- local_5c.ObjectID._1_1_ = s[0x7d];
- local_5c.ObjectID._2_1_ = s[0x7e];
- local_5c.ObjectID._3_1_ = s[0x7f];
- Change(&local_5c,TEXTSTRING,Value);
- }
- if (this->LoseInventory != 0) {
- iVar9 = 1;
- do {
- in_stack_fffffef8 = (char *)this->ID;
- GetBodyObject((ulong)&local_5c,(int)in_stack_fffffef8);
- local_3c.ObjectID = ::NONE.ObjectID;
- if (local_5c.ObjectID != ::NONE.ObjectID) {
- if (this->LoseInventory != 2) {
- Object::getObjectType(&local_3c);
- bVar3 = ObjectType::getFlag((ObjectType *)&local_3c,CONTAINER);
- if (!bVar3) {
- in_stack_fffffef8 = (char *)0x9;
- // try { // try from 080a03bc to 080a04ee has its CatchHandler @ 080a06d7
- lVar8 = random();
- if (lVar8 != 0) goto LAB_080a0207;
- }
- }
- local_3c.ObjectID = ::NONE.ObjectID;
- local_ec.ObjectID = local_5c.ObjectID;
- in_stack_fffffef8 = (char *)&local_ec;
- local_2c[0].ObjectID._0_1_ = s[0x7c];
- local_2c[0].ObjectID._1_1_ = s[0x7d];
- local_2c[0].ObjectID._2_1_ = s[0x7e];
- local_2c[0].ObjectID._3_1_ = s[0x7f];
- ::Move(0,(Object *)in_stack_fffffef8,local_2c,-1,false,&local_3c);
- }
-LAB_080a0207:
- iVar9 = iVar9 + 1;
- } while (iVar9 < 0xb);
- }
- if ((this->Type == PLAYER) && (this->LoseInventory != 2)) {
- TPlayer::SaveInventory((TPlayer *)this);
- }
- }
- bVar3 = false;
- local_ec.ObjectID = ::NONE.ObjectID;
- s[0x7c] = (undefined1)::NONE.ObjectID;
- s[0x7d] = ::NONE.ObjectID._1_1_;
- s[0x7e] = ::NONE.ObjectID._2_1_;
- s[0x7f] = ::NONE.ObjectID._3_1_;
- if (((this->CrObject).ObjectID != ::NONE.ObjectID) &&
- (bVar4 = Object::exists(&this->CrObject), bVar4)) {
- bVar3 = true;
- }
- if (bVar3) {
- DelOnMap(this);
- }
- ToDoClear(this);
- if ((this->Type == PLAYER) && (this->Connection != (TConnection *)0x0)) {
- in_stack_fffffef8 = (char *)0x1e;
- TConnection::Logout(this->Connection,0x1e,true);
- }
- pOVar10 = (Object *)0x0;
- if (0 < FirstFreeCreature) {
- do {
- in_stack_fffffef8 = (char *)pOVar10;
- ppTVar6 = vector<TCreature*>::operator()(&CreatureList,(int)pOVar10);
- if (*ppTVar6 == this) {
- ppTVar6 = vector<TCreature*>::operator()(&CreatureList,(int)pOVar10);
- ppTVar7 = vector<TCreature*>::operator()(&CreatureList,FirstFreeCreature + -1);
- *ppTVar6 = *ppTVar7;
- in_stack_fffffef8 = (char *)(FirstFreeCreature + -1);
- ppTVar6 = vector<TCreature*>::operator()(&CreatureList,(int)in_stack_fffffef8);
- *ppTVar6 = (TCreature *)0x0;
- FirstFreeCreature = FirstFreeCreature + -1;
- }
- pOVar10 = (Object *)((int)&pOVar10->ObjectID + 1);
- } while ((int)pOVar10 < FirstFreeCreature);
- }
- if (this->ID != 0) {
- DelID(this);
- }
- for (pTVar1 = this->FirstKnowingConnection; pTVar1 != (TKnownCreature *)0x0;
- pTVar1 = pTVar1->Next) {
- pOVar10 = (Object *)this->ID;
- if ((Object *)pTVar1->CreatureID != pOVar10) {
- error("TCreature::~TCreature: Verkettungsfehler bei Kreatur %lu.\n");
- in_stack_fffffef8 = (char *)pOVar10;
- }
- pTVar1->State = KNOWNCREATURE_FREE;
- }
- pTVar2 = (this->ToDoList).entry;
- if (pTVar2 != (TToDoEntry *)0x0) {
- operator_delete__(pTVar2);
- }
- TSkillBase::~TSkillBase(&this->super_TSkillBase,(int)in_stack_fffffef8);
- operator_delete(this);
- return;
-}
-
-
-
-// DWARF original prototype: void SetID(TCreature * this, ulong CharacterID)
-
-void __thiscall TCreature::SetID(TCreature *this,ulong CharacterID)
-
-{
- TCreature *pTVar1;
- ulong m;
- uint uVar2;
- int iVar3;
- char *Text;
- ulong uVar4;
-
- if (this->ID != 0) {
- error("TCreature::SetID: ID ist schon gesetzt.\n");
- }
- if (CharacterID == 0) {
- iVar3 = 0;
- this->ID = NextCreatureID;
- NextCreatureID = NextCreatureID + 1;
- do {
- pTVar1 = GetCreature(this->ID);
- if (pTVar1 == (TCreature *)0x0) goto LAB_080a0775;
- iVar3 = iVar3 + 1;
- error("TCreature::SetID: Doppelte Nonplayer-ID %d gefunden.\n",this->ID);
- this->ID = NextCreatureID;
- NextCreatureID = NextCreatureID + 1;
- } while (iVar3 < 0x11);
- uVar4 = this->ID;
- Text = "TCreature::SetID: 16x hintereinander doppelte ID. Verwende nun doppelte ID %d\n";
- }
- else {
- this->ID = CharacterID;
- pTVar1 = GetCreature(CharacterID);
- if (pTVar1 == (TCreature *)0x0) goto LAB_080a0775;
- uVar4 = this->ID;
- Text = "TCreature::SetID: Doppelte Character-ID %d gefunden.\n";
- }
- error(Text,uVar4);
-LAB_080a0775:
- uVar2 = this->ID % 1000;
- this->NextHashEntry = HashList[uVar2];
- HashList[uVar2] = this;
- return;
-}
-
-
-
-// DWARF original prototype: void DelID(TCreature * this)
-
-void __thiscall TCreature::DelID(TCreature *this)
-
-{
- uint uVar1;
- TCreature *pTVar2;
- uint uVar3;
- TCreature *pTVar4;
- TCreature *pTVar5;
- ulong m;
- TCreature *ocr;
- TCreature *pTVar6;
- char *Text;
-
- uVar1 = this->ID;
- pTVar2 = HashList[uVar1 % 1000];
- if (pTVar2 == (TCreature *)0x0) {
- Text = "TCreature::DelID: Hasheintrag nicht gefunden id = %d\n";
- }
- else {
- uVar3 = pTVar2->ID;
- if (uVar3 == uVar1) {
- HashList[uVar1 % 1000] = pTVar2->NextHashEntry;
- return;
- }
- pTVar4 = pTVar2->NextHashEntry;
- pTVar6 = (TCreature *)0x0;
- while (pTVar4 != (TCreature *)0x0) {
- pTVar5 = pTVar2->NextHashEntry;
- uVar3 = pTVar5->ID;
- pTVar6 = pTVar2;
- if (uVar3 == uVar1) goto LAB_080a0867;
- pTVar2 = pTVar5;
- pTVar4 = pTVar5->NextHashEntry;
- }
- pTVar5 = pTVar2;
- if (uVar3 == uVar1) {
-LAB_080a0867:
- pTVar6->NextHashEntry = pTVar5->NextHashEntry;
- return;
- }
- Text = "TCreature::DelID: id=%d nicht gefunden.\n";
- }
- error(Text,uVar1);
- return;
-}
-
-
-
-// DWARF original prototype: void SetInCrList(TCreature * this)
-
-void __thiscall TCreature::SetInCrList(TCreature *this)
-
-{
- TCreature **ppTVar1;
-
- ppTVar1 = vector<TCreature*>::operator()(&CreatureList,FirstFreeCreature);
- FirstFreeCreature = FirstFreeCreature + 1;
- *ppTVar1 = this;
- return;
-}
-
-
-
-// DWARF original prototype: void DelInCrList(TCreature * this)
-
-void __thiscall TCreature::DelInCrList(TCreature *this)
-
-{
- TCreature **ppTVar1;
- TCreature **ppTVar2;
- int i;
- int i_00;
-
- i_00 = 0;
- if (0 < FirstFreeCreature) {
- do {
- ppTVar1 = vector<TCreature*>::operator()(&CreatureList,i_00);
- if (*ppTVar1 == this) {
- ppTVar1 = vector<TCreature*>::operator()(&CreatureList,i_00);
- ppTVar2 = vector<TCreature*>::operator()(&CreatureList,FirstFreeCreature + -1);
- *ppTVar1 = *ppTVar2;
- ppTVar1 = vector<TCreature*>::operator()(&CreatureList,FirstFreeCreature + -1);
- *ppTVar1 = (TCreature *)0x0;
- FirstFreeCreature = FirstFreeCreature + -1;
- }
- i_00 = i_00 + 1;
- } while (i_00 < FirstFreeCreature);
- }
- return;
-}
-
-
-
-// WARNING: Variable defined which should be unmapped: StopFight_local
-// DWARF original prototype: void StartLogout(TCreature * this, bool Force, bool StopFight)
-
-void __thiscall TCreature::StartLogout(TCreature *this,bool Force,bool StopFight)
-
-{
- bool bVar1;
- int Delay;
- bool StopFight_local;
-
- this->LoggingOut = true;
- if ((Force) || (bVar1 = LagDetected(), bVar1)) {
- this->LogoutAllowed = true;
- }
- if ((this->Type == PLAYER) && (this->Connection != (TConnection *)0x0)) {
- TConnection::Logout(this->Connection,0,true);
- }
- Delay = 0;
- if (!StopFight) {
- Delay = 0x3c;
- }
- TCombat::StopAttack(&this->Combat,Delay);
- return;
-}
-
-
-
-// DWARF original prototype: int LogoutPossible(TCreature * this)
-
-int __thiscall TCreature::LogoutPossible(TCreature *this)
-
-{
- bool bVar1;
-
- if (((this->LogoutAllowed == false) && (bVar1 = GameEnding(), !bVar1)) &&
- (this->IsDead == false)) {
- if ((RoundNr < this->EarliestLogoutRound) && (bVar1 = LagDetected(), !bVar1)) {
- return 1;
- }
- bVar1 = IsNoLogoutField();
- if (bVar1) {
- return 2;
- }
- this->LogoutAllowed = true;
- }
- return 0;
-}
-
-
-
-// WARNING: Variable defined which should be unmapped: BlockProtectionZone_local
-// DWARF original prototype: void BlockLogout(TCreature * this, int Delay, bool BlockProtectionZone)
-
-void __thiscall TCreature::BlockLogout(TCreature *this,int Delay,bool BlockProtectionZone)
-
-{
- uint uVar1;
- bool bVar2;
- ulong Round;
- uint uVar3;
- char local_d;
- bool BlockProtectionZone_local;
-
- local_d = BlockProtectionZone;
- if (WorldType == NON_PVP) {
- local_d = '\0';
- }
- if ((this->Type == PLAYER) && (bVar2 = CheckRight(this->ID,NO_LOGOUT_BLOCK), !bVar2)) {
- if (local_d == '\0') {
- uVar3 = this->EarliestProtectionZoneRound;
- if (((uVar3 < RoundNr) && (this->Type == PLAYER)) &&
- (this->Connection == (TConnection *)0x0)) {
- return;
- }
- }
- else {
- uVar3 = this->EarliestProtectionZoneRound;
- }
- uVar1 = Delay + RoundNr;
- if (((local_d != '\0') || (RoundNr < uVar3)) && (uVar3 < uVar1)) {
- this->EarliestProtectionZoneRound = uVar1;
- }
- if (this->EarliestLogoutRound < uVar1) {
- this->EarliestLogoutRound = uVar1;
- }
- TPlayer::CheckState((TPlayer *)this);
- return;
- }
- return;
-}
-
-
-
-// DWARF original prototype: int GetHealth(TCreature * this)
-
-int __thiscall TCreature::GetHealth(TCreature *this)
-
-{
- TSkill *this_00;
- int iVar1;
- uint uVar2;
- int iVar3;
- int MaxHitpoints;
- TSkill *sk;
-
- this_00 = (this->super_TSkillBase).Skills[2];
- iVar3 = this_00->Max;
- if (iVar3 < 1) {
- if (this->IsDead == false) {
- error("TCreature::GetHealth: MaxHitpoints von %s ist %d, obwohl sie nicht tot ist.\n",
- this->Name,iVar3);
- }
- uVar2 = 0;
- }
- else {
- iVar1 = TSkill::Get(this_00);
- uVar2 = (iVar1 * 100) / iVar3;
- if ((int)uVar2 < 1) {
- iVar3 = TSkill::Get(this_00);
- uVar2 = (uint)(iVar3 != 0);
- }
- }
- return uVar2;
-}
-
-
-
-// DWARF original prototype: int GetSpeed(TCreature * this)
-
-int __thiscall TCreature::GetSpeed(TCreature *this)
-
-{
- TSkill *this_00;
- int iVar1;
-
- this_00 = (this->super_TSkillBase).Skills[4];
- if (this_00 == (TSkill *)0x0) {
- error("TCreature::GetSpeed: Kein Skill GOSTRENGTH vorhanden.\n");
- iVar1 = 0;
- }
- else {
- iVar1 = TSkill::Get(this_00);
- iVar1 = iVar1 * 2 + 0x50;
- }
- return iVar1;
-}
-
-
-
-// DWARF original prototype: void Death(TCreature * this)
-
-void __thiscall TCreature::Death(TCreature *this)
-
-{
- this->IsDead = true;
- this->LoggingOut = true;
- return;
-}
-
-// WARNING: Variable defined which should be unmapped: Execute_local
-// DWARF original prototype: bool MovePossible(TCreature * this, int x, int y, int z, bool Execute,
-// bool Jump)
-
-bool __thiscall TCreature::MovePossible(TCreature *this,int x,int y,int z,bool Execute,bool Jump)
-
-{
- bool bVar1;
- bool local_18;
- bool Execute_local;
-
- if (Jump) {
- local_18 = JumpPossible(x,y,z,false);
- }
- else {
- local_18 = false;
- // try { // try from 080a2053 to 080a20dd has its CatchHandler @ 080a20e7
- bVar1 = CoordinateFlag();
- if (bVar1) {
- local_18 = CoordinateFlag();
- local_18 = !local_18;
- }
- }
- bVar1 = false;
- if (local_18 != false) {
- if ((!Execute) && (bVar1 = CoordinateFlag(), bVar1)) {
- return false;
- }
- bVar1 = true;
- }
- return bVar1;
-}
-
-
-
-// DWARF original prototype: void TRaceData(TRaceData * this)
-
-void __thiscall TRaceData::TRaceData(TRaceData *this)
-
-{
- int i;
- int iVar1;
-
- ObjectType::setTypeID(&this->MaleCorpse,0);
- ObjectType::setTypeID(&this->FemaleCorpse,0);
- vector<TSkillData>::vector(&this->Skill,1,5,5);
- // try { // try from 080a2181 to 080a2185 has its CatchHandler @ 080a22e4
- vector<>::vector(&this->Talk,1,5,5,0);
- // try { // try from 080a21a7 to 080a21ab has its CatchHandler @ 080a22e0
- vector<TItemData>::vector(&this->Item,1,5,5);
- // try { // try from 080a21cd to 080a21d1 has its CatchHandler @ 080a22a0
- vector<TSpellData>::vector(&this->Spell,1,5,5);
- this->Name[0] = '\0';
- iVar1 = 1;
- this->Article[0] = '\0';
- (this->Outfit).OutfitID = 0;
- (this->Outfit).field_1 = (anon_union_4_2_730cd3ca_for_TOutfit_2)0x0;
- this->Blood = BT_BLOOD;
- this->ExperiencePoints = 0;
- this->FleeThreshold = 0;
- this->Attack = 0;
- this->Defend = 0;
- this->Armor = 0;
- this->Poison = 0;
- this->SummonCost = 0;
- this->LoseTarget = 0;
- this->Strategy[0] = 100;
- do {
- this->Strategy[iVar1] = 0;
- iVar1 = iVar1 + 1;
- } while (iVar1 < 4);
- this->KickBoxes = false;
- this->KickCreatures = false;
- this->SeeInvisible = false;
- this->Unpushable = false;
- this->DistanceFighting = false;
- this->NoSummon = false;
- this->NoIllusion = false;
- this->NoConvince = false;
- this->NoBurning = false;
- this->NoPoison = false;
- this->NoEnergy = false;
- this->NoHit = false;
- this->NoLifeDrain = false;
- this->NoParalyze = false;
- this->Skills = 0;
- this->Talks = 0;
- this->Items = 0;
- this->Spells = 0;
- return;
-}
-
-
-
-// DWARF original prototype: void TRaceData(TRaceData * this)
-
-void __thiscall TRaceData::TRaceData(TRaceData *this)
-
-{
- int i;
- int iVar1;
-
- ObjectType::setTypeID(&this->MaleCorpse,0);
- ObjectType::setTypeID(&this->FemaleCorpse,0);
- vector<TSkillData>::vector(&this->Skill,1,5,5);
- // try { // try from 080a2371 to 080a2375 has its CatchHandler @ 080a24d4
- vector<>::vector(&this->Talk,1,5,5,0);
- // try { // try from 080a2397 to 080a239b has its CatchHandler @ 080a24d0
- vector<TItemData>::vector(&this->Item,1,5,5);
- // try { // try from 080a23bd to 080a23c1 has its CatchHandler @ 080a2490
- vector<TSpellData>::vector(&this->Spell,1,5,5);
- this->Name[0] = '\0';
- iVar1 = 1;
- this->Article[0] = '\0';
- (this->Outfit).OutfitID = 0;
- (this->Outfit).field_1 = (anon_union_4_2_730cd3ca_for_TOutfit_2)0x0;
- this->Blood = BT_BLOOD;
- this->ExperiencePoints = 0;
- this->FleeThreshold = 0;
- this->Attack = 0;
- this->Defend = 0;
- this->Armor = 0;
- this->Poison = 0;
- this->SummonCost = 0;
- this->LoseTarget = 0;
- this->Strategy[0] = 100;
- do {
- this->Strategy[iVar1] = 0;
- iVar1 = iVar1 + 1;
- } while (iVar1 < 4);
- this->KickBoxes = false;
- this->KickCreatures = false;
- this->SeeInvisible = false;
- this->Unpushable = false;
- this->DistanceFighting = false;
- this->NoSummon = false;
- this->NoIllusion = false;
- this->NoConvince = false;
- this->NoBurning = false;
- this->NoPoison = false;
- this->NoEnergy = false;
- this->NoHit = false;
- this->NoLifeDrain = false;
- this->NoParalyze = false;
- this->Skills = 0;
- this->Talks = 0;
- this->Items = 0;
- this->Spells = 0;
- return;
-}
-
-
-
char * GetRaceName(int Race)
{
@@ -33734,64 +32288,6 @@ LAB_080a4d67:
} while( true );
}
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void InitCr(void)
-
-{
- int i;
- matrix<> *this;
- int iVar1;
-
- // try { // try from 080a5106 to 080a510a has its CatchHandler @ 080a51e0
- this = (matrix<> *)operator_new(0x14);
- // try { // try from 080a5148 to 080a514c has its CatchHandler @ 080a51b0
- matrix<>::matrix(this,SectorXMin * 2,SectorXMax * 2 + 1,SectorYMin * 2,SectorYMax * 2 + 1,0);
- NextCreatureID = 0x40000000;
- FirstChainCreature = this;
- // try { // try from 080a515d to 080a517c has its CatchHandler @ 080a51e0
- LoadRaces();
- LoadMonsterRaids();
- FirstFreeCreature = 0;
- InitPlayer();
- InitCrskill();
- InitNonplayer();
- iVar1 = 0;
- do {
- KilledCreatures[iVar1] = 0;
- KilledPlayers[iVar1] = 0;
- iVar1 = iVar1 + 1;
- } while (iVar1 < 0x200);
- return;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void ExitCr(void)
-
-{
- matrix<> *pmVar1;
-
- WriteKillStatistics();
- ExitPlayer();
- ExitNonplayer();
- ExitCrskill();
- pmVar1 = FirstChainCreature;
- if (FirstChainCreature != (matrix<> *)0x0) {
- if (FirstChainCreature->entry != (ulong *)0x0) {
- operator_delete__(FirstChainCreature->entry);
- }
- operator_delete(pmVar1);
- }
- return;
-}
-
-
-
void __tcf_0(void *param_1)
{
@@ -33880,67 +32376,6 @@ void _GLOBAL__I_HashList(void)
return;
}
-
-
-// DWARF original prototype: bool IsPeaceful(TCreature * this)
-
-bool __thiscall TCreature::IsPeaceful(TCreature *this)
-
-{
- return true;
-}
-
-
-
-// DWARF original prototype: ulong GetMaster(TCreature * this)
-
-ulong __thiscall TCreature::GetMaster(TCreature *this)
-
-{
- return 0;
-}
-
-
-
-// DWARF original prototype: void TalkStimulus(TCreature * this, ulong param_1, char * param_2)
-
-void __thiscall TCreature::TalkStimulus(TCreature *this,ulong param_1,char *param_2)
-
-{
- return;
-}
-
-
-
-// DWARF original prototype: void DamageStimulus(TCreature * this, ulong param_1, int param_2, int
-// param_3)
-
-void __thiscall TCreature::DamageStimulus(TCreature *this,ulong param_1,int param_2,int param_3)
-
-{
- return;
-}
-
-
-
-// DWARF original prototype: void IdleStimulus(TCreature * this)
-
-void __thiscall TCreature::IdleStimulus(TCreature *this)
-
-{
- return;
-}
-
-
-
-// DWARF original prototype: void AttackStimulus(TCreature * this, ulong param_1)
-
-void __thiscall TCreature::AttackStimulus(TCreature *this,ulong param_1)
-
-{
- return;
-}
-
void __static_initialization_and_destruction_0(int __initialize_p,int __priority)
{
@@ -47534,763 +45969,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
return;
}
-
-
-// DWARF original prototype: void TShortway(TShortway * this, TCreature * cr, int VisibleX, int
-// VisibleY)
-
-void __thiscall TShortway::TShortway(TShortway *this,TCreature *cr,int VisibleX,int VisibleY)
-
-{
- matrix<> *this_00;
-
- this->Map = (matrix<> *)0x0;
- if (cr == (TCreature *)0x0) {
- error(&DAT_08106b80);
- return;
- }
- if ((((0 < VisibleX) && (0 < VisibleY)) && (VisibleX < 0x65)) && (VisibleY < 0x65)) {
- this->cr = cr;
- this->VisibleX = VisibleX;
- this->VisibleY = VisibleY;
- this->StartX = cr->posx;
- this->StartY = cr->posy;
- this->StartZ = cr->posz;
- this_00 = (matrix<> *)operator_new(0x14);
- // try { // try from 080bdfe3 to 080bdfe7 has its CatchHandler @ 080be019
- matrix<>::matrix(this_00,~VisibleX,VisibleX + 1,~VisibleY,VisibleY + 1);
- this->Map = this_00;
- FillMap(this);
- return;
- }
- error(&DAT_08106b40);
- return;
-}
-
-
-
-// DWARF original prototype: void TShortway(TShortway * this, TCreature * cr, int VisibleX, int
-// VisibleY)
-
-void __thiscall TShortway::TShortway(TShortway *this,TCreature *cr,int VisibleX,int VisibleY)
-
-{
- matrix<> *this_00;
-
- this->Map = (matrix<> *)0x0;
- if (cr == (TCreature *)0x0) {
- error(&DAT_08106b80);
- return;
- }
- if ((((0 < VisibleX) && (0 < VisibleY)) && (VisibleX < 0x65)) && (VisibleY < 0x65)) {
- this->cr = cr;
- this->VisibleX = VisibleX;
- this->VisibleY = VisibleY;
- this->StartX = cr->posx;
- this->StartY = cr->posy;
- this->StartZ = cr->posz;
- this_00 = (matrix<> *)operator_new(0x14);
- // try { // try from 080be0f3 to 080be0f7 has its CatchHandler @ 080be129
- matrix<>::matrix(this_00,~VisibleX,VisibleX + 1,~VisibleY,VisibleY + 1);
- this->Map = this_00;
- FillMap(this);
- return;
- }
- error(&DAT_08106b40);
- return;
-}
-
-
-
-// DWARF original prototype: void ~TShortway(TShortway * this, int __in_chrg)
-
-void __thiscall TShortway::~TShortway(TShortway *this,int __in_chrg)
-
-{
- matrix<> *pmVar1;
-
- pmVar1 = this->Map;
- if (pmVar1 != (matrix<> *)0x0) {
- if (pmVar1->entry != (TShortwayPoint *)0x0) {
- operator_delete__(pmVar1->entry);
- }
- operator_delete(pmVar1);
- return;
- }
- return;
-}
-
-
-
-// DWARF original prototype: void ~TShortway(TShortway * this, int __in_chrg)
-
-void __thiscall TShortway::~TShortway(TShortway *this,int __in_chrg)
-
-{
- matrix<> *pmVar1;
-
- pmVar1 = this->Map;
- if (pmVar1 != (matrix<> *)0x0) {
- if (pmVar1->entry != (TShortwayPoint *)0x0) {
- operator_delete__(pmVar1->entry);
- }
- operator_delete(pmVar1);
- return;
- }
- return;
-}
-
-
-
-// DWARF original prototype: void FillMap(TShortway * this)
-
-void __thiscall TShortway::FillMap(TShortway *this)
-
-{
- matrix<> *pmVar1;
- bool bVar2;
- int iVar3;
- int iVar4;
- TShortwayPoint *pTVar5;
- ulong uVar6;
- uint uVar7;
- int iVar8;
- uint uVar9;
- int x_1;
- uint uVar10;
- int y;
- int iVar11;
- ulong local_44;
- int Waypoints;
- int x;
- Object local_2c;
- Object Obj;
-
- this->MinWaypoints = 1000;
- uVar7 = this->VisibleX;
- Waypoints = -uVar7;
- if (-uVar7 == uVar7 || SBORROW4(Waypoints,uVar7) != (int)(uVar7 * -2) < 0) {
- uVar9 = this->VisibleY;
- do {
- iVar11 = -uVar9;
- if (-uVar9 == uVar9 || iVar11 < (int)uVar9) {
- do {
- local_44 = 0xffffffff;
- iVar4 = this->StartZ;
- GetFirstObject();
- bVar2 = Object::exists(&local_2c);
- if (bVar2) {
- Object::getObjectType((Object *)&x);
- bVar2 = ObjectType::getFlag((ObjectType *)&x,BANK);
- if (bVar2) {
- Object::getObjectType((Object *)&x);
- bVar2 = ObjectType::getFlag((ObjectType *)&x,UNPASS);
- if (!bVar2) {
- Object::getObjectType((Object *)&x);
- local_44 = ObjectType::getAttribute((ObjectType *)&x,WAYPOINTS);
- if (local_44 == 0) {
- Object::getObjectType((Object *)&x);
- error(&DAT_08106bc0,0,x);
- local_44 = 0xffffffff;
- }
- iVar4 = this->StartZ;
- iVar3 = (*this->cr->_vptr_TCreature[3])
- (this->cr,Waypoints + this->StartX,
- this->StartY + iVar11,iVar4,0,0);
- uVar6 = 0xffffffff;
- if ((char)iVar3 != '\0') {
- uVar6 = local_44;
- }
- local_44 = uVar6;
- if ((0 < (int)uVar6) && ((int)uVar6 < this->MinWaypoints)) {
- this->MinWaypoints = uVar6;
- }
- }
- }
- }
- pmVar1 = this->Map;
- iVar3 = iVar11 - pmVar1->ymin;
- iVar8 = Waypoints - pmVar1->xmin;
- if ((((iVar8 < 0) || (pmVar1->dx <= iVar8)) || (iVar3 < 0)) ||
- (pmVar1->dy <= iVar3)) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar8 + pmVar1->xmin,
- iVar3 + pmVar1->ymin,iVar4);
- pTVar5 = pmVar1->entry;
- }
- else {
- pTVar5 = pmVar1->entry + iVar3 * pmVar1->dx + iVar8;
- }
- pTVar5->Waypoints = local_44;
- pmVar1 = this->Map;
- iVar3 = iVar11 - pmVar1->ymin;
- iVar8 = Waypoints - pmVar1->xmin;
- if (((iVar8 < 0) || (pmVar1->dx <= iVar8)) ||
- ((iVar3 < 0 || (pmVar1->dy <= iVar3)))) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar8 + pmVar1->xmin,
- iVar3 + pmVar1->ymin,iVar4);
- pTVar5 = pmVar1->entry;
- }
- else {
- pTVar5 = pmVar1->entry + iVar3 * pmVar1->dx + iVar8;
- }
- pTVar5->x = Waypoints;
- pmVar1 = this->Map;
- iVar4 = iVar11 - pmVar1->ymin;
- iVar3 = Waypoints - pmVar1->xmin;
- if (((iVar3 < 0) || (pmVar1->dx <= iVar3)) ||
- ((iVar4 < 0 || (pmVar1->dy <= iVar4)))) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar3 + pmVar1->xmin,
- iVar4 + pmVar1->ymin);
- pTVar5 = pmVar1->entry;
- }
- else {
- pTVar5 = pmVar1->entry + iVar4 * pmVar1->dx + iVar3;
- }
- pTVar5->y = iVar11;
- iVar11 = iVar11 + 1;
- uVar9 = this->VisibleY;
- } while (iVar11 <= (int)uVar9);
- uVar7 = this->VisibleX;
- }
- Waypoints = Waypoints + 1;
- } while (Waypoints <= (int)uVar7);
- }
- else {
- uVar9 = this->VisibleY;
- }
- uVar10 = ~uVar7;
- if ((int)uVar10 <= (int)(uVar7 + 1)) {
- while( true ) {
- pmVar1 = this->Map;
- iVar11 = ~uVar9 - pmVar1->ymin;
- iVar4 = uVar10 - pmVar1->xmin;
- if ((((iVar4 < 0) || (pmVar1->dx <= iVar4)) || (iVar11 < 0)) || (pmVar1->dy <= iVar11))
- {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar4 + pmVar1->xmin,
- iVar11 + pmVar1->ymin);
- pTVar5 = pmVar1->entry;
- }
- else {
- pTVar5 = pmVar1->entry + iVar11 * pmVar1->dx + iVar4;
- }
- pTVar5->Waypoints = -1;
- pmVar1 = this->Map;
- iVar11 = (this->VisibleY + 1) - pmVar1->ymin;
- iVar4 = uVar10 - pmVar1->xmin;
- if (((iVar4 < 0) || (pmVar1->dx <= iVar4)) || ((iVar11 < 0 || (pmVar1->dy <= iVar11))))
- {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar4 + pmVar1->xmin,
- iVar11 + pmVar1->ymin);
- pTVar5 = pmVar1->entry;
- }
- else {
- pTVar5 = pmVar1->entry + iVar11 * pmVar1->dx + iVar4;
- }
- pTVar5->Waypoints = -1;
- uVar10 = uVar10 + 1;
- uVar7 = this->VisibleX;
- if ((int)(uVar7 + 1) < (int)uVar10) break;
- uVar9 = this->VisibleY;
- }
- uVar9 = this->VisibleY;
- }
- iVar11 = -uVar9;
- if (-uVar9 == uVar9 || iVar11 < (int)uVar9) {
- while( true ) {
- pmVar1 = this->Map;
- iVar4 = iVar11 - pmVar1->ymin;
- iVar3 = ~uVar7 - pmVar1->xmin;
- if (((iVar3 < 0) || (pmVar1->dx <= iVar3)) || ((iVar4 < 0 || (pmVar1->dy <= iVar4)))) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar3 + pmVar1->xmin,
- iVar4 + pmVar1->ymin);
- pTVar5 = pmVar1->entry;
- }
- else {
- pTVar5 = pmVar1->entry + iVar4 * pmVar1->dx + iVar3;
- }
- pTVar5->Waypoints = -1;
- pmVar1 = this->Map;
- iVar4 = iVar11 - pmVar1->ymin;
- iVar3 = (this->VisibleX + 1) - pmVar1->xmin;
- if ((((iVar3 < 0) || (pmVar1->dx <= iVar3)) || (iVar4 < 0)) || (pmVar1->dy <= iVar4)) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar3 + pmVar1->xmin,
- iVar4 + pmVar1->ymin);
- pTVar5 = pmVar1->entry;
- }
- else {
- pTVar5 = pmVar1->entry + iVar4 * pmVar1->dx + iVar3;
- }
- pTVar5->Waypoints = -1;
- iVar11 = iVar11 + 1;
- if (this->VisibleY < iVar11) break;
- uVar7 = this->VisibleX;
- }
- }
- return;
-}
-
-
-
-// WARNING: Variable defined which should be unmapped: x
-// DWARF original prototype: void ClearMap(TShortway * this)
-
-void __thiscall TShortway::ClearMap(TShortway *this)
-
-{
- matrix<> *pmVar1;
- int iVar2;
- TShortwayPoint *pTVar3;
- int iVar4;
- int y;
- int iVar5;
- int local_14;
- int x;
-
- iVar2 = this->VisibleX;
- local_14 = -iVar2;
- if (-iVar2 == iVar2 || SBORROW4(local_14,iVar2) != iVar2 * -2 < 0) {
- iVar4 = this->VisibleY;
- do {
- iVar5 = -iVar4;
- if (-iVar4 == iVar4 || iVar5 < iVar4) {
- do {
- pmVar1 = this->Map;
- iVar2 = iVar5 - pmVar1->ymin;
- iVar4 = local_14 - pmVar1->xmin;
- if ((((iVar4 < 0) || (pmVar1->dx <= iVar4)) || (iVar2 < 0)) ||
- (pmVar1->dy <= iVar2)) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar4 + pmVar1->xmin,
- iVar2 + pmVar1->ymin);
- pTVar3 = pmVar1->entry;
- }
- else {
- pTVar3 = pmVar1->entry + iVar2 * pmVar1->dx + iVar4;
- }
- pTVar3->Predecessor = (TShortwayPoint *)0x0;
- pmVar1 = this->Map;
- iVar2 = iVar5 - pmVar1->ymin;
- iVar4 = local_14 - pmVar1->xmin;
- if (((iVar4 < 0) || (pmVar1->dx <= iVar4)) ||
- ((iVar2 < 0 || (pmVar1->dy <= iVar2)))) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar4 + pmVar1->xmin,
- iVar2 + pmVar1->ymin);
- pTVar3 = pmVar1->entry;
- }
- else {
- pTVar3 = pmVar1->entry + iVar2 * pmVar1->dx + iVar4;
- }
- pTVar3->NextToExpand = (TShortwayPoint *)0x0;
- pmVar1 = this->Map;
- iVar2 = iVar5 - pmVar1->ymin;
- iVar4 = local_14 - pmVar1->xmin;
- if (((iVar4 < 0) || (pmVar1->dx <= iVar4)) ||
- ((iVar2 < 0 || (pmVar1->dy <= iVar2)))) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar4 + pmVar1->xmin,
- iVar2 + pmVar1->ymin);
- pTVar3 = pmVar1->entry;
- }
- else {
- pTVar3 = pmVar1->entry + iVar2 * pmVar1->dx + iVar4;
- }
- pTVar3->Waylength = 0x7fffffff;
- pmVar1 = this->Map;
- iVar2 = iVar5 - pmVar1->ymin;
- iVar4 = local_14 - pmVar1->xmin;
- if ((((iVar4 < 0) || (pmVar1->dx <= iVar4)) || (iVar2 < 0)) ||
- (pmVar1->dy <= iVar2)) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar4 + pmVar1->xmin,
- iVar2 + pmVar1->ymin);
- pTVar3 = pmVar1->entry;
- }
- else {
- pTVar3 = pmVar1->entry + iVar2 * pmVar1->dx + iVar4;
- }
- pTVar3->Heuristic = 0x7fffffff;
- iVar5 = iVar5 + 1;
- iVar4 = this->VisibleY;
- } while (iVar5 <= iVar4);
- iVar2 = this->VisibleX;
- }
- local_14 = local_14 + 1;
- } while (local_14 <= iVar2);
- }
- this->FirstToExpand = (TShortwayPoint *)0x0;
- return;
-}
-
-
-
-// DWARF original prototype: bool Calculate(TShortway * this, int DestX, int DestY, bool MustReach,
-// int MaxSteps)
-
-bool __thiscall
-TShortway::Calculate(TShortway *this,int DestX,int DestY,bool MustReach,int MaxSteps)
-
-{
- matrix<> *pmVar1;
- int iVar2;
- int iVar3;
- int iVar4;
- TCreature *this_00;
- bool bVar5;
- int iVar6;
- int iVar7;
- int iVar8;
- TShortwayPoint *pTVar9;
- TToDoEntry *pTVar10;
- int iVar11;
- TShortwayPoint *pTVar12;
- TShortwayPoint *local_4c;
- TShortwayPoint *Search;
- int dy;
- int dx;
- bool MustReach_local;
- TToDoEntry TD;
-
- if (this->Map == (matrix<> *)0x0) {
- error("TShortway::Calculate: Karte existiert nicht.\n");
- }
- else {
- iVar6 = DestX - this->StartX;
- iVar7 = DestY - this->StartY;
- iVar8 = -iVar6;
- if (-1 < iVar6) {
- iVar8 = iVar6;
- }
- if (iVar8 <= this->VisibleX) {
- iVar8 = -iVar7;
- if (-1 < iVar7) {
- iVar8 = iVar7;
- }
- if (iVar8 <= this->VisibleY) {
- if ((iVar6 == 0) && (iVar7 == 0)) {
- return true;
- }
- ClearMap(this);
- pmVar1 = this->Map;
- iVar8 = iVar7 - pmVar1->ymin;
- iVar11 = iVar6 - pmVar1->xmin;
- if ((((iVar11 < 0) || (pmVar1->dx <= iVar11)) || (iVar8 < 0)) ||
- (pmVar1->dy <= iVar8)) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar11 + pmVar1->xmin,
- iVar8 + pmVar1->ymin);
- pTVar9 = pmVar1->entry;
- }
- else {
- pTVar9 = pmVar1->entry + iVar8 * pmVar1->dx + iVar11;
- }
- pTVar9->Waylength = 0;
- pmVar1 = this->Map;
- iVar8 = iVar7 - pmVar1->ymin;
- iVar11 = iVar6 - pmVar1->xmin;
- if (((iVar11 < 0) || (pmVar1->dx <= iVar11)) ||
- ((iVar8 < 0 || (pmVar1->dy <= iVar8)))) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar11 + pmVar1->xmin,
- iVar8 + pmVar1->ymin);
- pTVar9 = pmVar1->entry;
- }
- else {
- pTVar9 = pmVar1->entry + iVar8 * pmVar1->dx + iVar11;
- }
- this->FirstToExpand = pTVar9;
- while (pTVar9 != (TShortwayPoint *)0x0) {
- Expand(this,pTVar9);
- pTVar9 = this->FirstToExpand;
- }
- pmVar1 = this->Map;
- iVar11 = -pmVar1->xmin;
- iVar8 = -pmVar1->ymin;
- if (((pmVar1->xmin < 1) && (iVar11 < pmVar1->dx)) &&
- ((pmVar1->ymin < 1 && (iVar8 < pmVar1->dy)))) {
- pTVar9 = pmVar1->entry + iVar8 * pmVar1->dx + iVar11;
- }
- else {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar11 + pmVar1->xmin,0);
- pTVar9 = pmVar1->entry;
- }
- if (pTVar9->Waylength != 0x7fffffff) {
- pmVar1 = this->Map;
- iVar11 = -pmVar1->xmin;
- iVar8 = -pmVar1->ymin;
- if ((((pmVar1->xmin < 1) && (iVar11 < pmVar1->dx)) && (pmVar1->ymin < 1)) &&
- (iVar8 < pmVar1->dy)) {
- local_4c = pmVar1->entry + iVar8 * pmVar1->dx + iVar11;
- }
- else {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar11 + pmVar1->xmin
- ,0);
- local_4c = pmVar1->entry;
- }
- if ((local_4c->Predecessor != (TShortwayPoint *)0x0) &&
- (pTVar9 = local_4c->Predecessor, 0 < MaxSteps)) {
- while ((pTVar12 = pTVar9, MustReach ||
- ((2 < (local_4c->x - iVar6) + 1U || (2 < (local_4c->y - iVar7) + 1U))
- ))) {
- iVar8 = pTVar12->x;
- iVar11 = this->StartX;
- iVar2 = this->StartY;
- iVar3 = pTVar12->y;
- iVar4 = this->StartZ;
- this_00 = this->cr;
- if ((this_00->LockToDo != false) &&
- ((bVar5 = TCreature::ToDoClear(this_00), bVar5 &&
- (this_00->Type == PLAYER)))) {
- SendSnapback(this_00->Connection);
- }
- pTVar10 = vector<TToDoEntry>::operator()
- (&this_00->ToDoList,this_00->NrToDo);
- pTVar10->Code = TDGo;
- (pTVar10->field_1).Go.x = iVar8 + iVar11;
- (pTVar10->field_1).Go.y = iVar3 + iVar2;
- (pTVar10->field_1).Go.z = iVar4;
- (pTVar10->field_1).Move.z = TD.field_1.Go.z;
- (pTVar10->field_1).Move.Count = TD.field_1.Move.z;
- this_00->NrToDo = this_00->NrToDo + 1;
- MaxSteps = MaxSteps + -1;
- if (pTVar12->Predecessor == (TShortwayPoint *)0x0) {
- return true;
- }
- pTVar9 = pTVar12->Predecessor;
- local_4c = pTVar12;
- if (MaxSteps < 1) {
- return true;
- }
- }
- }
- return true;
- }
- }
- }
- }
- return false;
-}
-
-
-
-// WARNING: Variable defined which should be unmapped: this_local
-// DWARF original prototype: void Expand(TShortway * this, TShortwayPoint * Node)
-
-void __thiscall TShortway::Expand(TShortway *this,TShortwayPoint *Node)
-
-{
- matrix<> *pmVar1;
- int iVar2;
- TShortwayPoint *pTVar3;
- uint uVar4;
- TShortwayPoint *Search_1;
- TShortwayPoint *pTVar5;
- TShortwayPoint *Search;
- int iVar6;
- int iVar7;
- TShortwayPoint *pTVar8;
- uint uVar9;
- int Waylength;
- int iVar10;
- int local_24;
- int y;
- int x;
- int BasicWaylength;
- TShortwayPoint *Node_local;
- TShortway *this_local;
-
- if (Node == (TShortwayPoint *)0x0) {
- error(&DAT_08106c80);
- return;
- }
- this->FirstToExpand = Node->NextToExpand;
- iVar6 = Node->Waypoints + Node->Waylength;
- pmVar1 = this->Map;
- iVar7 = -pmVar1->xmin;
- iVar2 = -pmVar1->ymin;
- if ((((pmVar1->xmin < 1) && (iVar7 < pmVar1->dx)) && (pmVar1->ymin < 1)) && (iVar2 < pmVar1->dy)
- ) {
- pTVar3 = pmVar1->entry + iVar2 * pmVar1->dx + iVar7;
- }
- else {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar7 + pmVar1->xmin,0);
- pTVar3 = pmVar1->entry;
- }
- if (iVar6 < pTVar3->Waylength) {
- y = -1;
- do {
- local_24 = -1;
- do {
- if ((y != 0) || (local_24 != 0)) {
- pmVar1 = this->Map;
- iVar2 = (local_24 + Node->y) - pmVar1->ymin;
- iVar7 = (y + Node->x) - pmVar1->xmin;
- if (((iVar7 < 0) || ((pmVar1->dx <= iVar7 || (iVar2 < 0)))) ||
- (pmVar1->dy <= iVar2)) {
- error("matrix::operator(): Ungueltiger Index %d/%d.\n",iVar7 + pmVar1->xmin,
- iVar2 + pmVar1->ymin);
- pTVar3 = pmVar1->entry;
- }
- else {
- pTVar3 = pmVar1->entry + iVar2 * pmVar1->dx + iVar7;
- }
- iVar2 = -y;
- if (-1 < y) {
- iVar2 = y;
- }
- iVar7 = -local_24;
- if (-1 < local_24) {
- iVar7 = local_24;
- }
- iVar10 = iVar6;
- if (iVar2 + iVar7 != 1) {
- iVar10 = iVar6 + Node->Waypoints * 2;
- }
- if (iVar10 < pTVar3->Waylength) {
- pTVar3->Waylength = iVar10;
- uVar9 = pTVar3->x;
- pTVar3->Predecessor = Node;
- if (((uVar9 != 0) || (pTVar3->y != 0)) &&
- (iVar2 = pTVar3->Waypoints, iVar2 != -1)) {
- if (pTVar3->Heuristic != 0x7fffffff) {
- pTVar5 = this->FirstToExpand;
- if (pTVar5 == pTVar3) {
- this->FirstToExpand = pTVar3->NextToExpand;
- }
- else {
- for (pTVar8 = pTVar5->NextToExpand;
- pTVar8 != (TShortwayPoint *)0x0;
- pTVar8 = pTVar8->NextToExpand) {
- if (pTVar8 == pTVar3) {
- if (pTVar8 != (TShortwayPoint *)0x0) {
- pTVar5->NextToExpand = pTVar3->NextToExpand;
- goto LAB_080bedc6;
- }
- break;
- }
- pTVar5 = pTVar8;
- }
- error(
- "TShortway::Expand: Knoten steht nicht in der ExpandList.\n"
- );
- }
- uVar9 = pTVar3->x;
- iVar2 = pTVar3->Waypoints;
- }
-LAB_080bedc6:
- uVar4 = pTVar3->y;
- if (0x7fffffff < uVar9) {
- uVar9 = -uVar9;
- }
- if (0x7fffffff < uVar4) {
- uVar4 = -uVar4;
- }
- iVar2 = ((uVar4 - 1) + uVar9) * this->MinWaypoints + iVar2 + iVar10;
- pTVar3->Heuristic = iVar2;
- pTVar5 = this->FirstToExpand;
- if ((pTVar5 == (TShortwayPoint *)0x0) || (iVar2 <= pTVar5->Heuristic)) {
- pTVar3->NextToExpand = pTVar5;
- this->FirstToExpand = pTVar3;
- }
- else {
- pTVar8 = pTVar5->NextToExpand;
- if ((pTVar8 != (TShortwayPoint *)0x0) && (pTVar8->Heuristic < iVar2)
- ) {
- do {
- pTVar5 = pTVar8;
- pTVar8 = pTVar5->NextToExpand;
- if (pTVar8 == (TShortwayPoint *)0x0) break;
- } while (pTVar8->Heuristic < pTVar3->Heuristic);
- }
- pTVar3->NextToExpand = pTVar8;
- pTVar5->NextToExpand = pTVar3;
- }
- }
- }
- }
- local_24 = local_24 + 1;
- } while (local_24 < 2);
- y = y + 1;
- } while (y < 2);
- }
- return;
-}
-
-
-
-// DWARF original prototype: bool SetOnMap(TCreature * this)
-
-bool __thiscall TCreature::SetOnMap(TCreature *this)
-
-{
- int *z;
- int *y;
- int *x;
- bool bVar1;
- bool bVar2;
- ushort HouseID;
- ushort HouseID_00;
- bool NoRoom;
- ObjectType local_5c [4];
- ObjectType local_4c [4];
- Object local_3c [4];
- ulong local_2c;
- Object Obj;
-
- z = &this->posz;
- y = &this->posy;
- x = &this->posx;
- bVar1 = SearchLoginField(x,y,z,1,this->Type == PLAYER);
- bVar1 = !bVar1;
- if (bVar1) {
- bVar2 = IsHouse(this->posx,this->posy,this->posz);
- if (bVar2) {
- HouseID_00 = GetHouseID(this->posx,this->posy,this->posz);
- GetExitPosition(HouseID_00,x,y,z);
- bVar1 = SearchLoginField(x,y,z,1,this->Type == PLAYER);
- bVar1 = !bVar1;
- }
- if (bVar1) {
- this->posx = this->startx;
- this->posy = this->starty;
- this->posz = this->startz;
- }
- }
- GetMapContainer((int)&local_2c,this->posx,this->posy);
- bVar1 = local_2c != ::NONE.ObjectID;
- local_3c[0].ObjectID = ::NONE.ObjectID;
- if (bVar1) {
- // try { // try from 080befa5 to 080befcc has its CatchHandler @ 080bf0a5
- ObjectType::setTypeID(local_4c,99);
- local_5c[0].TypeID = local_2c;
- Create(local_3c,local_5c,(ulong)local_4c);
- }
- else {
- error(&DAT_08106cc0,this->posx,this->posy,this->posz);
- }
- return bVar1;
-}
-
-
-
-// DWARF original prototype: bool DelOnMap(TCreature * this)
-
-bool __thiscall TCreature::DelOnMap(TCreature *this)
-
-{
- RESULT r;
- Object local_4c [4];
- ulong local_3c;
- ulong local_2c;
- Object Help;
-
- local_3c = ::NONE.ObjectID;
- local_4c[0].ObjectID = (this->CrObject).ObjectID;
- if (local_4c[0].ObjectID != ::NONE.ObjectID) {
- (this->CrObject).ObjectID = ::NONE.ObjectID;
- local_2c = local_4c[0].ObjectID;
- // try { // try from 080bf180 to 080bf184 has its CatchHandler @ 080bf187
- Delete(local_4c,-1);
- }
- return true;
-}
-
-
-
// DWARF original prototype: void Go(TCreature * this, int x, int y, int z)
void __thiscall TCreature::Go(TCreature *this,int x,int y,int z)
@@ -49496,174 +47174,6 @@ LAB_080c12f2:
return;
}
-
-
-// WARNING: Type propagation algorithm not settling
-// DWARF original prototype: void CreatureMoveStimulus(TCreature * this, ulong CreatureID, int Type)
-
-void __thiscall TCreature::CreatureMoveStimulus(TCreature *this,ulong CreatureID,int Type)
-
-{
- vector<TToDoEntry> *this_00;
- uint uVar1;
- bool bVar2;
- TToDoEntry *pTVar3;
- TCreature *pTVar4;
- int iVar5;
- int *piVar6;
- int Delay_1;
- int Delay;
- int local_64;
- int local_60;
- undefined1 local_5c [4];
- TToDoEntry TD;
- Object local_3c [4];
- Object local_2c [7];
-
- if (((((CreatureID != this->ID) && (CreatureID != 0)) &&
- (CreatureID == (this->Combat).AttackDest)) && ((Type == 2 && (this->LockToDo != false))))
- && ((this->IsDead == false && (this->ActToDo < this->NrToDo)))) {
- this_00 = &this->ToDoList;
- pTVar3 = vector<TToDoEntry>::operator()(this_00,this->ActToDo);
- if ((pTVar3->Code == TDAttack) && ((this->Combat).ChaseMode == '\x01')) {
- uVar1 = (this->Combat).EarliestAttackTime;
- if ((ServerMilliseconds < uVar1) && (200 < (int)(uVar1 - ServerMilliseconds))) {
- pTVar4 = GetCreature((this->Combat).AttackDest);
- if (pTVar4 != (TCreature *)0x0) {
- local_2c[0].ObjectID = (pTVar4->CrObject).ObjectID;
- local_3c[0].ObjectID = (this->CrObject).ObjectID;
- iVar5 = ObjectDistance(local_3c,local_2c);
- if (1 < iVar5) {
- bVar2 = ToDoClear(this);
- if ((bVar2) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- local_5c = (undefined1 [4])0x0;
- TD.Code = ServerMilliseconds + 200;
- if (this->LockToDo != false) {
- // try { // try from 080c16d0 to 080c16fb has its CatchHandler @ 080c19b4
- bVar2 = ToDoClear(this);
- if ((bVar2) && (this->Type == PLAYER)) {
- // try { // try from 080c184b to 080c184f has its CatchHandler @ 080c19b4
- SendSnapback(this->Connection);
- }
- }
- pTVar3 = vector<TToDoEntry>::operator()(this_00,this->NrToDo);
- pTVar3->Code = (ToDoType)local_5c;
- (pTVar3->field_1).Move.Obj = TD.Code;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar3->field_1 + 4))->Time =
- (ulong)TD.field_1.Wait.Time;
- (pTVar3->field_1).Go.z = TD.field_1.Go.y;
- (pTVar3->field_1).Move.z = TD.field_1.Go.z;
- (pTVar3->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- // try { // try from 080c1728 to 080c17c0 has its CatchHandler @ 080c1868
- TCombat::CanToDoAttack(&this->Combat);
- iVar5 = TCombat::GetDistance(&this->Combat);
- if (iVar5 != 1) {
- local_5c = (undefined1 [4])0x0;
- TD.Code = ServerMilliseconds + 100;
- if (this->LockToDo != false) {
- bVar2 = ToDoClear(this);
- if ((bVar2) && (this->Type == PLAYER)) {
- // try { // try from 080c1838 to 080c183c has its CatchHandler @ 080c1868
- SendSnapback(this->Connection);
- }
- }
- pTVar3 = vector<TToDoEntry>::operator()(this_00,this->NrToDo);
- pTVar3->Code = (ToDoType)local_5c;
- (pTVar3->field_1).Move.Obj = TD.Code;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar3->field_1 + 4))->Time
- = (ulong)TD.field_1.Wait.Time;
- (pTVar3->field_1).Go.z = TD.field_1.Go.y;
- (pTVar3->field_1).Move.z = TD.field_1.Go.z;
- (pTVar3->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- }
- local_5c = (undefined1 [4])0x7;
- ToDoAdd(this,(TToDoEntry *)local_5c);
- if (this->NrToDo != 0) {
- this->LockToDo = true;
- this->ActToDo = 0;
- // try { // try from 080c17e1 to 080c181c has its CatchHandler @ 080c19b4
- local_60 = CalculateDelay(this);
- local_64 = 1;
- piVar6 = &local_64;
- if (0 < local_60) {
- piVar6 = &local_60;
- }
- iVar5 = *piVar6;
- priority_queue<>::insert(&ToDoQueue);
- this->NextWakeup = iVar5 + ServerMilliseconds;
- }
- }
- }
- }
- }
- }
- return;
-}
-
-
-
-// DWARF original prototype: int CalculateDelay(TCreature * this)
-
-int __thiscall TCreature::CalculateDelay(TCreature *this)
-
-{
- ToDoType TVar1;
- uint uVar2;
- TToDoEntry *pTVar3;
- ToDoType TVar4;
- int *piVar5;
- uint uVar6;
- int local_34;
- int local_30 [2];
- TToDoEntry TD;
-
- pTVar3 = vector<TToDoEntry>::operator()(&this->ToDoList,this->ActToDo);
- TVar1 = pTVar3->Code;
- TD.Code = (pTVar3->field_1).Move.Obj;
- TD.field_1.Wait.Time = (anon_struct_4_1_898373eb_for_Wait)(pTVar3->field_1).Go.y;
- TD.field_1.Go.y = (pTVar3->field_1).Go.z;
- TD.field_1.Go.z = (pTVar3->field_1).Move.z;
- TD.field_1.Move.z = (pTVar3->field_1).Move.Count;
- if ((TVar1 == TDGo) && (ServerMilliseconds < this->EarliestWalkTime)) {
- return this->EarliestWalkTime - ServerMilliseconds;
- }
- if (((TVar1 != TDUse) || (TD.field_1.Go.x == 0)) ||
- (TVar4 = this->EarliestMultiuseTime, TVar4 <= ServerMilliseconds)) {
- if (TVar1 == TDAttack) {
- uVar2 = (this->Combat).EarliestAttackTime;
- if (ServerMilliseconds < uVar2) {
- uVar6 = this->EarliestSpellTime;
-LAB_080c1a7f:
- local_30[0] = uVar2 - ServerMilliseconds;
- local_34 = uVar6 - ServerMilliseconds;
- piVar5 = &local_34;
- if ((int)(uVar6 - ServerMilliseconds) <= local_30[0]) {
- piVar5 = local_30;
- }
- return *piVar5;
- }
- uVar6 = this->EarliestSpellTime;
- if (ServerMilliseconds < uVar6) goto LAB_080c1a7f;
- }
- if ((TVar1 != TDWait) ||
- ((this->EarliestWalkTime <= ServerMilliseconds && (TD.Code <= ServerMilliseconds)))) {
- return 0;
- }
- pTVar3 = &TD;
- if (TD.Code <= this->EarliestWalkTime) {
- pTVar3 = (TToDoEntry *)&this->EarliestWalkTime;
- }
- TVar4 = pTVar3->Code;
- }
- return TVar4 - ServerMilliseconds;
-}
-
-
-
// DWARF original prototype: void Execute(TCreature * this)
void __thiscall TCreature::Execute(TCreature *this)
@@ -49796,959 +47306,6 @@ LAB_080c1d33:
} while( true );
}
-
-
-// WARNING: Variable defined which should be unmapped: SnapbackNecessary
-// DWARF original prototype: bool ToDoClear(TCreature * this)
-
-bool __thiscall TCreature::ToDoClear(TCreature *this)
-
-{
- TToDoEntry *pTVar1;
- TToDoEntry *TD;
- int i;
- int i_00;
- bool local_11;
- bool SnapbackNecessary;
-
- local_11 = false;
- if (0 < this->NrToDo) {
- i_00 = 0;
- do {
- pTVar1 = vector<TToDoEntry>::operator()(&this->ToDoList,i_00);
- switch(pTVar1->Code) {
- case TDGo:
- if (this->ActToDo <= i_00) {
- local_11 = true;
- }
- break;
- case TDTalk:
- DeleteDynamicString((pTVar1->field_1).Move.Obj);
- DeleteDynamicString((pTVar1->field_1).Talk.Addressee);
- break;
- case TDChangeState:
- if ((this->ActToDo <= i_00) && (this->Type == NPC)) {
- ChangeNPCState(this,(pTVar1->field_1).Go.x,false);
- }
- }
- i_00 = i_00 + 1;
- } while (i_00 < this->NrToDo);
- }
- this->LockToDo = false;
- this->ActToDo = 0;
- this->NrToDo = 0;
- this->Stop = false;
- return local_11;
-}
-
-
-
-// DWARF original prototype: void ToDoStop(TCreature * this)
-
-void __thiscall TCreature::ToDoStop(TCreature *this)
-
-{
- if (this->LockToDo == false) {
- if (this->Type == PLAYER) {
- SendSnapback(this->Connection);
- return;
- }
- }
- else {
- this->Stop = true;
- }
- return;
-}
-
-
-
-// DWARF original prototype: void ToDoAdd(TCreature * this, TToDoEntry * TD)
-
-void __thiscall TCreature::ToDoAdd(TCreature *this,TToDoEntry *TD)
-
-{
- bool bVar1;
- TToDoEntry *pTVar2;
-
- if (this->LockToDo != false) {
- bVar1 = ToDoClear(this);
- if ((bVar1) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- pTVar2 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar2->Code = TD->Code;
- (pTVar2->field_1).Wait.Time = (TD->field_1).Wait.Time;
- (pTVar2->field_1).Go.y = (TD->field_1).Go.y;
- (pTVar2->field_1).Go.z = (TD->field_1).Go.z;
- (pTVar2->field_1).Move.z = (TD->field_1).Move.z;
- (pTVar2->field_1).Move.Count = (TD->field_1).Move.Count;
- this->NrToDo = this->NrToDo + 1;
- return;
-}
-
-
-
-// DWARF original prototype: void ToDoStart(TCreature * this)
-
-void __thiscall TCreature::ToDoStart(TCreature *this)
-
-{
- int iVar1;
- int *piVar2;
- int Delay;
- int local_14;
- int local_10;
-
- if (this->NrToDo != 0) {
- this->LockToDo = true;
- this->ActToDo = 0;
- local_10 = CalculateDelay(this);
- piVar2 = &local_14;
- if (0 < local_10) {
- piVar2 = &local_10;
- }
- local_14 = 1;
- iVar1 = *piVar2;
- priority_queue<>::insert(&ToDoQueue);
- this->NextWakeup = iVar1 + ServerMilliseconds;
- }
- return;
-}
-
-
-
-// WARNING: Type propagation algorithm not settling
-// DWARF original prototype: void ToDoYield(TCreature * this)
-
-void __thiscall TCreature::ToDoYield(TCreature *this)
-
-{
- ulong uVar1;
- TToDoEntry *pTVar2;
- TToDoEntry TD;
-
- uVar1 = ServerMilliseconds;
- if (this->LockToDo == false) {
- pTVar2 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar2->Code = TDWait;
- (pTVar2->field_1).Move.Obj = uVar1;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar2->field_1 + 4))->Time =
- (ulong)TD.field_1.Wait.Time;
- (pTVar2->field_1).Go.z = TD.field_1.Go.y;
- (pTVar2->field_1).Move.z = TD.field_1.Go.z;
- (pTVar2->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- ToDoStart(this);
- }
- return;
-}
-
-
-
-// WARNING: Type propagation algorithm not settling
-// DWARF original prototype: void ToDoWait(TCreature * this, int Delay)
-
-void __thiscall TCreature::ToDoWait(TCreature *this,int Delay)
-
-{
- bool bVar1;
- int iVar2;
- TToDoEntry *pTVar3;
- TToDoEntry TD;
-
- iVar2 = Delay + ServerMilliseconds;
- if (this->LockToDo != false) {
- bVar1 = ToDoClear(this);
- if ((bVar1) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- pTVar3 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar3->Code = TDWait;
- (pTVar3->field_1).Go.x = iVar2;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar3->field_1 + 4))->Time =
- (ulong)TD.field_1.Wait.Time;
- (pTVar3->field_1).Go.z = TD.field_1.Go.y;
- (pTVar3->field_1).Move.z = TD.field_1.Go.z;
- (pTVar3->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
-}
-
-
-
-// DWARF original prototype: void ToDoTalk(TCreature * this, int Mode, char * Addressee, char *
-// Text, bool CheckSpamming)
-
-void __thiscall TCreature::ToDoTalk(TCreature *this)
-
-{
- bool bVar1;
- ulong uVar2;
- TToDoEntry *pTVar3;
- int in_stack_00000008;
- char *in_stack_0000000c;
- char *in_stack_00000010;
- undefined1 in_stack_00000014;
- TToDoEntry TD;
-
- if (in_stack_0000000c == (char *)0x0) {
- TD.field_1.Go.y = 0;
- }
- else {
- TD.field_1.Trade.Partner = AddDynamicString(in_stack_0000000c);
- }
- TD.field_1.Go.z._0_1_ = in_stack_00000014;
- if (in_stack_00000010 == (char *)0x0) {
- error("TCreature::ToDoTalk: Text ist NULL bei %s.\n",this->Name);
- }
- uVar2 = AddDynamicString(in_stack_00000010);
- if (uVar2 == 0) {
- error("TCreature::ToDoTalk: TD.Text ist Null bei %s.\n",this->Name);
- }
- if (this->LockToDo != false) {
- bVar1 = ToDoClear(this);
- if ((bVar1) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- pTVar3 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar3->Code = TDTalk;
- (pTVar3->field_1).Move.Obj = uVar2;
- (pTVar3->field_1).Go.y = in_stack_00000008;
- (pTVar3->field_1).Go.z = TD.field_1.Go.y;
- (pTVar3->field_1).Move.z = TD.field_1.Go.z;
- (pTVar3->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
-}
-
-
-
-// WARNING: Type propagation algorithm not settling
-// DWARF original prototype: void ToDoChangeState(TCreature * this, int NewState)
-
-void __thiscall TCreature::ToDoChangeState(TCreature *this,int NewState)
-
-{
- bool bVar1;
- TToDoEntry *pTVar2;
- TToDoEntry TD;
-
- if (this->LockToDo != false) {
- bVar1 = ToDoClear(this);
- if ((bVar1) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- pTVar2 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar2->Code = TDChangeState;
- (pTVar2->field_1).Go.x = NewState;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar2->field_1 + 4))->Time =
- (ulong)TD.field_1.Wait.Time;
- (pTVar2->field_1).Go.z = TD.field_1.Go.y;
- (pTVar2->field_1).Move.z = TD.field_1.Go.z;
- (pTVar2->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
-}
-
-
-
-// DWARF original prototype: void ToDoGo(TCreature * this, int DestX, int DestY, int DestZ, bool
-// Dest, int MaxSteps)
-
-void __thiscall
-TCreature::ToDoGo(TCreature *this,int DestX,int DestY,int DestZ,bool Dest,int MaxSteps)
-
-{
- vector<TToDoEntry> *this_00;
- bool bVar1;
- undefined4 *puVar2;
- TToDoEntry *pTVar3;
- int dx;
- uint uVar4;
- int dy;
- uint uVar5;
- undefined1 local_6c [3];
- bool Dest_local;
- TShortway Shortway;
- TToDoEntry TD;
-
- if (this->posz < DestZ) {
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0x18;
- }
- else {
- if (this->posz <= DestZ) {
- if (this->LockToDo != false) {
- this_00 = &this->ToDoList;
- pTVar3 = vector<TToDoEntry>::operator()(this_00,this->NrToDo + -1);
- if ((((pTVar3->Code == TDGo) &&
- (pTVar3 = vector<TToDoEntry>::operator()(this_00,this->NrToDo + -1),
- (pTVar3->field_1).Go.x == DestX)) &&
- (pTVar3 = vector<TToDoEntry>::operator()(this_00,this->NrToDo + -1),
- (pTVar3->field_1).Go.y == DestY)) &&
- (pTVar3 = vector<TToDoEntry>::operator()(this_00,this->NrToDo + -1),
- (pTVar3->field_1).Go.z == DestZ)) {
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0;
- goto LAB_080c2810;
- }
- }
- uVar5 = DestY - this->posy;
- uVar4 = DestX - this->posx;
- if (((uVar4 != 0) || (uVar5 != 0)) && ((Dest || ((2 < uVar4 + 1 || (2 < uVar5 + 1))))))
- {
- if (0x7fffffff < uVar4) {
- uVar4 = -uVar4;
- }
- if (0x7fffffff < uVar5) {
- uVar5 = -uVar5;
- }
- if (uVar5 + uVar4 == 1) {
- if (((this->LockToDo != false) && (bVar1 = ToDoClear(this), bVar1)) &&
- (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- // try { // try from 080c272a to 080c2827 has its CatchHandler @ 080c2870
- pTVar3 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar3->Code = TDGo;
- (pTVar3->field_1).Go.x = DestX;
- (pTVar3->field_1).Go.y = DestY;
- (pTVar3->field_1).Go.z = DestZ;
- (pTVar3->field_1).Move.z = TD.field_1.Go.z;
- (pTVar3->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- }
- else {
- // try { // try from 080c2660 to 080c2664 has its CatchHandler @ 080c2870
- TShortway::TShortway
- ((TShortway *)local_6c,this,(uint)(this->Type != PLAYER) * 3 + 7,
- (uint)(this->Type != PLAYER) * 3 + 7);
- // try { // try from 080c2685 to 080c26f4 has its CatchHandler @ 080c2850
- bVar1 = TShortway::Calculate((TShortway *)local_6c,DestX,DestY,Dest,MaxSteps);
- if (!bVar1) {
- ToDoClear(this);
- if (this->Type == PLAYER) {
- SendSnapback(this->Connection);
- }
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0x2c;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
- }
- TShortway::~TShortway((TShortway *)local_6c,DestX);
- }
- }
- return;
- }
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0x17;
- }
-LAB_080c2810:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Type propagation algorithm not settling
-// DWARF original prototype: void ToDoRotate(TCreature * this, int Direction)
-
-void __thiscall TCreature::ToDoRotate(TCreature *this,int Direction)
-
-{
- bool bVar1;
- TToDoEntry *pTVar2;
- undefined4 *puVar3;
- TToDoEntry TD;
-
- if (Direction < 4) {
- if (this->LockToDo != false) {
- bVar1 = ToDoClear(this);
- if ((bVar1) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- // try { // try from 080c28c4 to 080c294f has its CatchHandler @ 080c2950
- pTVar2 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar2->Code = TDRotate;
- (pTVar2->field_1).Go.x = Direction;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar2->field_1 + 4))->Time =
- (ulong)TD.field_1.Wait.Time;
- (pTVar2->field_1).Go.z = TD.field_1.Go.y;
- (pTVar2->field_1).Move.z = TD.field_1.Go.z;
- (pTVar2->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
- }
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void ToDoMove(TCreature * this, int sx, int sy, int sz, ObjectType *
-// Type, uchar RNum, int zx, int zy, int zz, uchar Count)
-
-void __thiscall
-TCreature::ToDoMove(TCreature *this,int sx,int sy,int sz,ObjectType *Type,uchar RNum,int zx,int zy,
- int zz,uchar Count)
-
-{
- bool bVar1;
- TCreature *pTVar2;
- int iVar3;
- TToDoEntry *pTVar4;
- undefined4 *puVar5;
- ObjectType *Type_00;
- ulong x;
- int iVar6;
- int iVar7;
- Object *pOVar8;
- uchar Count_local;
- TToDoEntry TD;
- Object local_4c [4];
- Object local_3c;
- Object Dest;
- Object local_2c;
- Object Obj;
-
- // try { // try from 080c299f to 080c2c56 has its CatchHandler @ 080c2c90
- ObjectType::setTypeID((ObjectType *)&local_3c,Type->TypeID);
- Type_00 = (ObjectType *)(uint)RNum;
- x = this->ID;
- iVar3 = sx;
- iVar6 = sy;
- iVar7 = sz;
- pOVar8 = &local_3c;
- GetObject((ulong)&local_2c,x,sx,sy,sz,Type_00);
- bVar1 = Object::exists(&local_2c);
- if (bVar1) {
- if (sx != 0xffff) {
- if (this->posz < sz) {
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x18;
- goto LAB_080c2be8;
- }
- if (sz < this->posz) {
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x17;
- goto LAB_080c2be8;
- }
- local_3c.ObjectID = local_2c.ObjectID;
- bVar1 = ObjectInRange(this->ID,&local_3c,1);
- if (!bVar1) {
- Type_00 = (ObjectType *)0x7fffffff;
- iVar7 = 0;
- ToDoGo(this,sx,sy,sz,false,0x7fffffff);
- }
- }
- Object::getObjectType(&local_3c);
- if (local_3c.ObjectID != 99) {
- iVar3 = 100;
-LAB_080c2b08:
- ToDoWait(this,iVar3);
- if (((this->LockToDo != false) && (bVar1 = ToDoClear(this), bVar1)) &&
- (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- pTVar4 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar4->Code = TDMove;
- (pTVar4->field_1).Wait.Time = local_2c.ObjectID;
- (pTVar4->field_1).Go.y = zx;
- (pTVar4->field_1).Go.z = zy;
- (pTVar4->field_1).Move.z = zz;
- *(uint *)((int)&pTVar4->field_1 + 0x10) = (uint)Count;
- this->NrToDo = this->NrToDo + 1;
- return;
- }
- x = zx;
- iVar3 = zy;
- iVar6 = zz;
- GetFirstObject();
- bVar1 = Object::exists(&local_3c);
- if (bVar1) {
- Object::getObjectType(local_4c);
- x = 0;
- bVar1 = ObjectType::getFlag((ObjectType *)local_4c,BANK);
- if (bVar1) {
- Object::getObjectType(local_4c);
- ObjectType::getAttribute((ObjectType *)local_4c,WAYPOINTS);
- local_4c[0].ObjectID = local_2c.ObjectID;
- pTVar2 = GetCreature(local_4c);
- if (pTVar2 != (TCreature *)0x0) {
- if (ServerMilliseconds < pTVar2->EarliestWalkTime) {
- iVar3 = (pTVar2->EarliestWalkTime - ServerMilliseconds) + 1000;
- }
- else {
- iVar3 = 1000;
- }
- goto LAB_080c2b08;
- }
- error("TCreature::ToDoMove: Kreatur existiert nicht.\n");
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0xffffffff;
- goto LAB_080c2be8;
- }
- }
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4,x,iVar3,iVar6,iVar7,Type_00,pOVar8);
- *puVar5 = 1;
-LAB_080c2be8:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar5,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Type propagation algorithm not settling
-// DWARF original prototype: void ToDoMove(TCreature * this, Object * Obj, int zx, int zy, int zz,
-// uchar Count)
-
-void __thiscall TCreature::ToDoMove(TCreature *this,Object *Obj,int zx,int zy,int zz,uchar Count)
-
-{
- bool bVar1;
- TToDoEntry *pTVar2;
- undefined4 *puVar3;
- int Delay;
- int iStack_68;
- uchar Count_local;
- int x;
- int y;
- int z;
- TToDoEntry TD;
- Object local_3c [4];
- Object local_2c [7];
-
- // try { // try from 080c2cd2 to 080c2e61 has its CatchHandler @ 080c2e62
- bVar1 = Object::exists(Obj);
- if (!bVar1) {
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 1;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
- }
- local_2c[0] = (Object)Obj->ObjectID;
- bVar1 = ObjectInRange(this->ID,local_2c,1);
- if (!bVar1) {
- local_3c[0] = (Object)Obj->ObjectID;
- GetObjectCoordinates(local_3c,&stack0xffffff98,&x,&y);
- ToDoGo(this,iStack_68,x,y,false,0x7fffffff);
- }
- Object::getObjectType(local_3c);
- Delay = 1000;
- if (local_3c[0].ObjectID != 99) {
- Delay = 100;
- }
- ToDoWait(this,Delay);
- z = 3;
- TD.Code = Obj->ObjectID;
- TD.field_1.Move.z = (int)Count;
- TD.field_1.Go.x = zx;
- TD.field_1.Go.y = zy;
- TD.field_1.Go.z = zz;
- if (((this->LockToDo != false) && (bVar1 = ToDoClear(this), bVar1)) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- pTVar2 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar2->Code = z;
- (pTVar2->field_1).Move.Obj = TD.Code;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar2->field_1 + 4))->Time =
- (ulong)TD.field_1.Wait.Time;
- (pTVar2->field_1).Go.z = TD.field_1.Go.y;
- (pTVar2->field_1).Move.z = TD.field_1.Go.z;
- (pTVar2->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
-}
-
-
-
-// DWARF original prototype: void ToDoTrade(TCreature * this, int x, int y, int z, ObjectType *
-// Type, uchar RNum, ulong TradePartner)
-
-void __thiscall
-TCreature::ToDoTrade
- (TCreature *this,int x,int y,int z,ObjectType *Type,uchar RNum,ulong TradePartner)
-
-{
- bool bVar1;
- TCreature *pTVar2;
- TToDoEntry *pTVar3;
- undefined4 *puVar4;
- char *Text;
- Object *this_00;
- TToDoEntry TD;
- Object local_3c [4];
- Object local_2c;
- Object Obj;
-
- this_00 = &local_2c;
- // try { // try from 080c2ea5 to 080c3132 has its CatchHandler @ 080c3185
- ObjectType::setTypeID((ObjectType *)local_3c,Type->TypeID);
- GetObject((ulong)this_00,this->ID,x,y,z,(ObjectType *)(uint)RNum);
- bVar1 = Object::exists(this_00);
- if (!bVar1) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 1;
- goto LAB_080c30bb;
- }
- Object::getObjectType(local_3c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_3c,UNMOVE);
- if (bVar1) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 2;
- goto LAB_080c30bb;
- }
- Object::getObjectType(local_3c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_3c,TAKE);
- if (!bVar1) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 3;
- goto LAB_080c30bb;
- }
- Object::getObjectType(local_3c);
- if (local_3c[0].ObjectID == 99) {
- Text = "TCreature::ToDoTrade: Objekt ist eine Kreatur.\n";
-LAB_080c312e:
- error(Text,this_00);
- }
- else {
- if (TradePartner == 0) {
- Text = "TCreature::ToDoTrade: Handelspartner ist Null.\n";
- goto LAB_080c312e;
- }
- pTVar2 = GetCreature(TradePartner);
- if (pTVar2 == (TCreature *)0x0) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x1b;
- goto LAB_080c30bb;
- }
- if (pTVar2->Type == PLAYER) {
- if (x == 0xffff) {
-LAB_080c2fd4:
- if (this->LockToDo != false) {
- bVar1 = ToDoClear(this);
- if ((bVar1) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- pTVar3 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar3->Code = TDTrade;
- (pTVar3->field_1).Wait.Time = local_2c.ObjectID;
- (pTVar3->field_1).Trade.Partner = TradePartner;
- (pTVar3->field_1).Go.z = TD.field_1.Go.y;
- (pTVar3->field_1).Move.z = TD.field_1.Go.z;
- (pTVar3->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
- }
- if (this->posz < z) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x18;
- }
- else {
- if (this->posz <= z) {
- local_3c[0].ObjectID = local_2c.ObjectID;
- bVar1 = ObjectInRange(this->ID,local_3c,1);
- if (!bVar1) {
- ToDoGo(this,x,y,z,false,0x7fffffff);
- }
- goto LAB_080c2fd4;
- }
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x17;
- }
- goto LAB_080c30bb;
- }
- error("TCreature::ToDoTrade: Handelspartner von %s ist kein Spieler.\n",this->Name);
- }
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
-LAB_080c30bb:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void ToDoUse(TCreature * this, uchar Count, int x1, int y1, int z1,
-// ObjectType * Type1, uchar RNum1, uchar Dummy, int x2, int y2, int z2, ObjectType * Type2, uchar
-// RNum2)
-
-void __thiscall
-TCreature::ToDoUse(TCreature *this,uchar Count,int x1,int y1,int z1,ObjectType *Type1,uchar RNum1,
- uchar Dummy,int x2,int y2,int z2,ObjectType *Type2,uchar RNum2)
-
-{
- Object OVar1;
- Object OVar2;
- bool bVar3;
- TToDoEntry *pTVar4;
- undefined4 *puVar5;
- uchar RNum2_local;
- uchar Dummy_local;
- uchar Count_local;
- TToDoEntry TD;
- Object local_6c [4];
- ulong local_5c [4];
- ObjectType local_4c [4];
- Object local_3c;
- Object Obj2;
- Object local_2c;
- Object Obj1;
-
- local_3c.ObjectID = 0;
- local_2c.ObjectID = 0;
- // try { // try from 080c31ee to 080c3453 has its CatchHandler @ 080c3473
- ObjectType::setTypeID((ObjectType *)local_6c,Type1->TypeID);
- GetObject((ulong)local_5c,this->ID,x1,y1,z1,(ObjectType *)(uint)RNum1);
- local_2c.ObjectID = local_5c[0];
- local_4c[0].TypeID = local_5c[0];
- bVar3 = Object::exists(&local_2c);
- if (bVar3) {
- if (Count < 2) {
- local_5c[0] = ::NONE.ObjectID;
- local_3c.ObjectID = ::NONE.ObjectID;
- local_6c[0].ObjectID = ::NONE.ObjectID;
- }
- else {
- ObjectType::setTypeID(local_4c,Type2->TypeID);
- GetObject((ulong)local_5c,this->ID,x2,y2,z2,(ObjectType *)(uint)RNum2);
- local_3c.ObjectID = local_5c[0];
- local_6c[0].ObjectID = local_5c[0];
- bVar3 = Object::exists(&local_3c);
- if (!bVar3) goto LAB_080c345c;
- }
- if (x1 == 0xffff) {
-LAB_080c32b4:
- ToDoWait(this,100);
- OVar2.ObjectID = local_2c.ObjectID;
- OVar1.ObjectID = local_3c.ObjectID;
- if (this->LockToDo != false) {
- bVar3 = ToDoClear(this);
- if ((bVar3) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- pTVar4 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar4->Code = TDUse;
- (pTVar4->field_1).Wait.Time = OVar2.ObjectID;
- (pTVar4->field_1).Go.y = OVar1.ObjectID;
- *(uint *)((int)&pTVar4->field_1 + 8) = (uint)Dummy;
- (pTVar4->field_1).Move.z = TD.field_1.Go.z;
- (pTVar4->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
- }
- if (this->posz < z1) {
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x18;
- }
- else {
- if (this->posz <= z1) {
- local_6c[0].ObjectID = local_2c.ObjectID;
- bVar3 = ObjectInRange(this->ID,local_6c,1);
- if (!bVar3) {
- ToDoGo(this,x1,y1,z1,false,0x7fffffff);
- }
- goto LAB_080c32b4;
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x17;
- }
- }
- else {
-LAB_080c345c:
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 1;
- }
- // WARNING: Subroutine does not return
- __cxa_throw(puVar5,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Type propagation algorithm not settling
-// DWARF original prototype: void ToDoUse(TCreature * this, uchar Count, Object * Obj1, Object *
-// Obj2)
-
-void __thiscall TCreature::ToDoUse(TCreature *this,uchar Count,Object *Obj1,Object *Obj2)
-
-{
- Object OVar1;
- bool bVar2;
- TToDoEntry *pTVar3;
- undefined4 *puVar4;
- int iStack_68;
- uchar Count_local;
- int x;
- int y;
- int z;
- TToDoEntry TD;
- Object local_3c [4];
- Object local_2c [7];
-
- // try { // try from 080c34b5 to 080c3640 has its CatchHandler @ 080c3641
- bVar2 = Object::exists(Obj1);
- OVar1 = ::NONE;
- if (bVar2) {
- if (Count < 2) {
- Obj2->ObjectID = (ulong)::NONE;
- local_2c[0].ObjectID = OVar1.ObjectID;
- }
- else {
- bVar2 = Object::exists(Obj2);
- if (!bVar2) goto LAB_080c3617;
- }
- local_3c[0] = (Object)Obj1->ObjectID;
- bVar2 = ObjectInRange(this->ID,local_3c,1);
- if (!bVar2) {
- local_2c[0] = (Object)Obj1->ObjectID;
- GetObjectCoordinates(local_2c,&stack0xffffff98,&x,&y);
- ToDoGo(this,iStack_68,x,y,false,0x7fffffff);
- }
- ToDoWait(this,100);
- z = 5;
- TD.Code = Obj1->ObjectID;
- TD.field_1.Go.y = (int)Count;
- TD.field_1.Wait.Time = (anon_struct_4_1_898373eb_for_Wait)Obj2->ObjectID;
- if (this->LockToDo != false) {
- bVar2 = ToDoClear(this);
- if ((bVar2) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- pTVar3 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar3->Code = z;
- (pTVar3->field_1).Move.Obj = TD.Code;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar3->field_1 + 4))->Time =
- (ulong)TD.field_1.Wait.Time;
- (pTVar3->field_1).Go.z = TD.field_1.Go.y;
- (pTVar3->field_1).Move.z = TD.field_1.Go.z;
- (pTVar3->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
- }
-LAB_080c3617:
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 1;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Type propagation algorithm not settling
-// DWARF original prototype: void ToDoTurn(TCreature * this, int x, int y, int z, ObjectType * Type,
-// uchar RNum)
-
-void __thiscall TCreature::ToDoTurn(TCreature *this,int x,int y,int z,ObjectType *Type,uchar RNum)
-
-{
- bool bVar1;
- TToDoEntry *pTVar2;
- undefined4 *puVar3;
- TToDoEntry TD;
- Object local_3c [4];
- Object local_2c;
- Object Obj;
-
- // try { // try from 080c3685 to 080c382e has its CatchHandler @ 080c3857
- ObjectType::setTypeID((ObjectType *)local_3c,Type->TypeID);
- GetObject((ulong)&local_2c,this->ID,x,y,z,(ObjectType *)(uint)RNum);
- bVar1 = Object::exists(&local_2c);
- if (bVar1) {
- if (x == 0xffff) {
-LAB_080c3721:
- ToDoWait(this,100);
- if (this->LockToDo != false) {
- bVar1 = ToDoClear(this);
- if ((bVar1) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- pTVar2 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar2->Code = TDTurn;
- (pTVar2->field_1).Wait.Time = local_2c.ObjectID;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar2->field_1 + 4))->Time =
- (ulong)TD.field_1.Wait.Time;
- (pTVar2->field_1).Go.z = TD.field_1.Go.y;
- (pTVar2->field_1).Move.z = TD.field_1.Go.z;
- (pTVar2->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
- }
- if (this->posz < z) {
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0x18;
- }
- else {
- if (this->posz <= z) {
- local_3c[0].ObjectID = local_2c.ObjectID;
- bVar1 = ObjectInRange(this->ID,local_3c,1);
- if (!bVar1) {
- ToDoGo(this,x,y,z,false,0x7fffffff);
- }
- goto LAB_080c3721;
- }
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0x17;
- }
- }
- else {
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 1;
- }
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Type propagation algorithm not settling
-// DWARF original prototype: void ToDoAttack(TCreature * this)
-
-void __thiscall TCreature::ToDoAttack(TCreature *this)
-
-{
- bool bVar1;
- int iVar2;
- TToDoEntry *pTVar3;
- TToDoEntry TD;
-
- // try { // try from 080c3888 to 080c3928 has its CatchHandler @ 080c3930
- TCombat::CanToDoAttack(&this->Combat);
- iVar2 = TCombat::GetDistance(&this->Combat);
- if (iVar2 != 1) {
- ToDoWait(this,100);
- }
- if (this->LockToDo != false) {
- bVar1 = ToDoClear(this);
- if ((bVar1) && (this->Type == PLAYER)) {
- SendSnapback(this->Connection);
- }
- }
- pTVar3 = vector<TToDoEntry>::operator()(&this->ToDoList,this->NrToDo);
- pTVar3->Code = TDAttack;
- (pTVar3->field_1).Move.Obj = TD.Code;
- ((anon_struct_4_1_898373eb_for_Wait *)((int)&pTVar3->field_1 + 4))->Time =
- (ulong)TD.field_1.Wait.Time;
- (pTVar3->field_1).Go.z = TD.field_1.Go.y;
- (pTVar3->field_1).Move.z = TD.field_1.Go.z;
- (pTVar3->field_1).Move.Count = TD.field_1.Move.z;
- this->NrToDo = this->NrToDo + 1;
- return;
-}
-
-
-
// WARNING: Unknown calling convention -- yet parameter storage is locked
void _GLOBAL__I__ZN9TShortwayC2EP9TCreatureii(void)
diff --git a/reference/types.hh b/reference/types.hh
index 6840fc3..42caab1 100644
--- a/reference/types.hh
+++ b/reference/types.hh
@@ -1,15 +1,9 @@
struct TXTEASymmetricKey {
int (**_vptr.TXTEASymmetricKey)(...); // VTABLE?
- uint8 m_SymmetricKey[16];
+ uchar m_SymmetricKey[16];
};
-
-// NOTE(fusion): Some minimal processing up until here. Then I realized the file would be huge.
-//==================================================================================================
-//==================================================================================================
-//==================================================================================================
-
struct TDatabasePoolConnection {
TDatabaseConnectionPool *DatabaseConnectionPool;
TDatabaseConnection *DatabaseConnection;
@@ -131,16 +125,6 @@ struct TDelayedMail {
int PacketSize;
};
-struct TShortwayPoint {
- int x;
- int y;
- int Waypoints;
- int Waylength;
- int Heuristic;
- struct TShortwayPoint *Predecessor;
- struct TShortwayPoint *NextToExpand;
-};
-
struct TMonsterhome {
int Race;
int x;
@@ -153,8 +137,6 @@ struct TMonsterhome {
int Timer;
};
-
-
struct TChannel {
ulong Moderator;
char ModeratorName[30];
@@ -394,15 +376,3 @@ struct TRSAPrivateKey {
struct vlong m_DP;
struct vlong m_DQ;
};
-
-struct TShortway {
- struct matrix<TShortwayPoint> *Map;
- struct TShortwayPoint *FirstToExpand;
- struct TCreature *cr;
- int VisibleX;
- int VisibleY;
- int StartX;
- int StartY;
- int StartZ;
- int MinWaypoints;
-};
diff --git a/src/connection.hh b/src/connection.hh
index 2eafcde..d3a53df 100644
--- a/src/connection.hh
+++ b/src/connection.hh
@@ -7,50 +7,54 @@
struct TConnection;
struct TKnownCreature {
- KNOWNCREATURESTATE State;
- uint32 CreatureID;
- TKnownCreature *Next;
- TConnection *Connection;
+ KNOWNCREATURESTATE State;
+ uint32 CreatureID;
+ TKnownCreature *Next;
+ TConnection *Connection;
};
struct TConnection {
- uint8 InData[2048];
- int InDataSize;
- bool SigIOPending;
- bool WaitingForACK;
- uint8 OutData[16384];
- uint8 field5_0x4806;
- uint8 field6_0x4807;
- int NextToSend;
- int NextToCommit;
- int NextToWrite;
- bool Overflow;
- bool WillingToSend;
- uint8 field12_0x4816;
- uint8 field13_0x4817;
- TConnection *NextSendingConnection;
- uint32 RandomSeed;
+ void Logout(int Delay, bool StopFight);
+
+ // DATA
+ // =================
+ uint8 InData[2048];
+ int InDataSize;
+ bool SigIOPending;
+ bool WaitingForACK;
+ uint8 OutData[16384];
+ uint8 field5_0x4806;
+ uint8 field6_0x4807;
+ int NextToSend;
+ int NextToCommit;
+ int NextToWrite;
+ bool Overflow;
+ bool WillingToSend;
+ uint8 field12_0x4816;
+ uint8 field13_0x4817;
+ TConnection *NextSendingConnection;
+ uint32 RandomSeed;
CONNECTIONSTATE State;
- pid_t PID;
- int Socket;
- char IPAddress[16];
- // TXTEASymmetricKey SymmetricKey; // TODO
- bool ConnectionIsOk;
- bool ClosingIsDelayed;
- uint8 field23_0x4852;
- uint8 field24_0x4853;
- uint32 TimeStamp;
- uint32 TimeStampAction;
- int TerminalType;
- int TerminalVersion;
- int TerminalOffsetX;
- int TerminalOffsetY;
- int TerminalWidth;
- int TerminalHeight;
- uint32 CharacterID;
- char Name[31];
- uint8 field35_0x4897;
- TKnownCreature KnownCreatureTable[150];
+ pid_t PID;
+ int Socket;
+ char IPAddress[16];
+ // TXTEASymmetricKey SymmetricKey; // TODO
+ bool ConnectionIsOk;
+ bool ClosingIsDelayed;
+ uint8 field23_0x4852;
+ uint8 field24_0x4853;
+ uint32 TimeStamp;
+ uint32 TimeStampAction;
+ int TerminalType;
+ int TerminalVersion;
+ int TerminalOffsetX;
+ int TerminalOffsetY;
+ int TerminalWidth;
+ int TerminalHeight;
+ uint32 CharacterID;
+ char Name[31];
+ uint8 field35_0x4897;
+ TKnownCreature KnownCreatureTable[150];
};
#endif // TIBIA_CONNECTION_HH_
diff --git a/src/containers.hh b/src/containers.hh
index 2533445..fafe5b7 100644
--- a/src/containers.hh
+++ b/src/containers.hh
@@ -137,10 +137,10 @@ struct priority_queue{
delete Entry;
}
- void insert(K Key, T *Data){
+ void insert(K Key, T Data){
this->Entries += 1;
int CurrentIndex = this->Entries;
- *this->Entry->at(CurrentIndex) = {Key, *Data};
+ *this->Entry->at(CurrentIndex) = {Key, Data};
while(CurrentIndex > 1){
int ParentIndex = CurrentIndex / 2;
priority_queue_entry<K, T> *Current = this->Entry->at(CurrentIndex);
diff --git a/src/cr.hh b/src/cr.hh
index dc9bd7b..8f8e0de 100644
--- a/src/cr.hh
+++ b/src/cr.hh
@@ -421,7 +421,7 @@ struct TToDoEntry {
} Turn;
struct{
- uint32 Text; // POINTER? Probably a reference from `AddDynamicString`?
+ uint32 Text;
int Mode;
uint32 Addressee;
bool CheckSpamming;
@@ -434,12 +434,45 @@ struct TToDoEntry {
};
struct TCreature: TSkillBase {
+ // crmain.cc
TCreature(void);
- void Attack(void);
- int Damage(TCreature *Attacker, int Damage, int DamageType);
+ void SetID(uint32 CharacterID);
+ void DelID(void);
+ void SetInCrList(void);
+ void DelInCrList(void);
void StartLogout(bool Force, bool StopFight);
+ int LogoutPossible(void);
void BlockLogout(int Delay, bool BlockProtectionZone);
- void ToDoGo(int DestX, int DestY, int DestZ, bool Dest, int MaxSteps);
+ int GetHealth(void);
+ int GetSpeed(void);
+ int Damage(TCreature *Attacker, int Damage, int DamageType);
+
+ // cract.cc
+ bool SetOnMap(void);
+ bool DelOnMap(void);
+ void Attack(void);
+ void Execute(void);
+ uint32 CalculateDelay(void);
+ bool ToDoClear(void);
+ void ToDoAdd(TToDoEntry TD);
+ void ToDoStop(void);
+ void ToDoStart(void);
+ void ToDoYield(void);
+ void ToDoWait(int Delay);
+ void ToDoGo(int DestX, int DestY, int DestZ, bool MustReach, int MaxSteps);
+ void ToDoRotate(int Direction);
+ void ToDoMove(int ObjX, int ObjY, int ObjZ, ObjectType Type, uint8 RNum,
+ int DestX, int DestY, int DestZ, uint8 Count);
+ void ToDoMove(Object Obj, int DestX, int DestY, int DestZ, uint8 Count);
+ void ToDoTrade(int ObjX, int ObjY, int ObjZ, ObjectType Type, uint8 RNum,
+ uint32 TradePartner);
+ void ToDoUse(uint8 Count, int ObjX1, int ObjY1, int ObjZ1, ObjectType Type1, uint8 RNum1,
+ uint8 Dummy, int ObjX2, int ObjY2, int ObjZ2, ObjectType Type2, uint8 RNum2);
+ void ToDoUse(uint8 Count, Object Obj1, Object Obj2);
+ void ToDoTurn(int ObjX, int ObjY, int ObjZ, ObjectType Type, uint8 RNum);
+ void ToDoAttack(void);
+ void ToDoTalk(int Mode, const char *Addressee, const char *Text, bool CheckSpamming);
+ void ToDoChangeState(int NewState);
// VIRTUAL FUNCTIONS
// =================
@@ -613,6 +646,9 @@ struct TPlayer: TCreature {
void CheckState(void);
+ void ClearPlayerkillingMarks(void);
+ void SaveInventory(void);
+
// VIRTUAL FUNCTIONS
// =================
// TODO
@@ -658,19 +694,42 @@ struct TPlayer: TCreature {
uint32 AddresseesTimes[20];
};
-// Creature API
+// crmain.cc
// =============================================================================
#define MAX_RACES 512
-
-// crmain.cc
extern TRaceData RaceData[MAX_RACES];
extern int KilledCreatures[MAX_RACES];
extern int KilledPlayers[MAX_RACES];
+extern priority_queue<uint32, uint32> ToDoQueue;
-// TODO(fusion): These probably belong elsewhere but we should come back to
-// this when we're wrapping up creature files.
bool IsCreaturePlayer(uint32 CreatureID);
+TCreature *GetCreature(uint32 CreatureID);
+TCreature *GetCreature(Object Obj);
+void InsertChainCreature(TCreature *Creature, int CoordX, int CoordY);
+void DeleteChainCreature(TCreature *Creature);
+void MoveChainCreature(TCreature *Creature, int CoordX, int CoordY);
+void ProcessCreatures(void);
+void ProcessSkills(void);
+void MoveCreatures(int Delay);
+
void AddKillStatistics(int AttackerRace, int DefenderRace);
+
+bool IsRaceValid(int Race);
int GetRaceByName(const char *RaceName);
+// crnonpl.cc
+// =============================================================================
+void InitNonplayer();
+void ExitNonplayer();
+
+// crplayer.cc
+// =============================================================================
+void InitPlayer(void);
+void ExitPlayer(void);
+
+// crskill.cc
+// =============================================================================
+void InitCrskill(void);
+void ExitCrskill(void);
+
#endif //TIBIA_CREATURE_HH_
diff --git a/src/cract.cc b/src/cract.cc
new file mode 100644
index 0000000..cfbbe95
--- /dev/null
+++ b/src/cract.cc
@@ -0,0 +1,809 @@
+#include "cr.hh"
+
+#include "stubs.hh"
+
+// TShortway
+// =============================================================================
+struct TShortwayPoint {
+ TShortwayPoint(void){
+ this->x = 0;
+ this->y = 0;
+ this->Waypoints = -1;
+ this->Waylength = -1;
+ this->Heuristic = -1;
+ this->Predecessor = NULL;
+ this->NextToExpand = NULL;
+ }
+
+ int x;
+ int y;
+ int Waypoints;
+ int Waylength;
+ int Heuristic;
+ TShortwayPoint *Predecessor;
+ TShortwayPoint *NextToExpand;
+};
+
+struct TShortway{
+ TShortway(TCreature *Creature, int VisibleX, int VisibleY);
+ ~TShortway(void);
+ void FillMap(void);
+ void ClearMap(void);
+ void Expand(TShortwayPoint *Node);
+ bool Calculate(int DestX, int DestY, bool MustReach, int MaxSteps);
+
+ // DATA
+ // =================
+ matrix<TShortwayPoint> *Map;
+ TShortwayPoint *FirstToExpand;
+ TCreature *Creature;
+ int VisibleX;
+ int VisibleY;
+ int StartX;
+ int StartY;
+ int StartZ;
+ int MinWaypoints;
+};
+
+TShortway::TShortway(TCreature *Creature, int VisibleX, int VisibleY){
+ if(Creature == NULL){
+ error("TShortway::TShortway: Übergebene Kreatur ist NULL.\n");
+ return;
+ }
+
+ if(VisibleX < 1 || VisibleX > 100 || VisibleY < 1 || VisibleY > 100){
+ error("TShortway::TShortway: Ungültiger Sichtbarkeitsbereich %d*%d.\n", VisibleX, VisibleY);
+ return;
+ }
+
+ this->Creature = Creature;
+ this->VisibleX = VisibleX;
+ this->VisibleY = VisibleY;
+ this->StartX = Creature->posx;
+ this->StartY = Creature->posy;
+ this->StartZ = Creature->posz;
+ this->Map = new matrix<TShortwayPoint>(
+ -(VisibleX + 1), +(VisibleX + 1),
+ -(VisibleY + 1), +(VisibleY + 1));
+ this->FillMap();
+}
+
+TShortway::~TShortway(void){
+ if(this->Map != NULL){
+ delete this->Map;
+ }
+}
+
+void TShortway::FillMap(void){
+ this->MinWaypoints = 1000;
+
+ for(int X = -this->VisibleX; X <= this->VisibleX; X += 1)
+ for(int Y = -this->VisibleY; Y <= this->VisibleY; Y += 1){
+ int FieldX = this->StartX + X;
+ int FieldY = this->StartY + Y;
+ int FieldZ = this->StartZ;
+
+ int Waypoints = -1;
+ Object Obj = GetFirstObject(FieldX, FieldY, FieldZ);
+ if(Obj.exists()){
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.getFlag(BANK) && !ObjType.getFlag(UNPASS)){
+ Waypoints = (int)ObjType.getAttribute(WAYPOINTS);
+ if(Waypoints == 0){
+ error("TShortway::FillMap: Ungültiger Wegpunkte-Wert %d für Bank %d.\n",
+ Waypoints, ObjType.TypeID);
+ Waypoints = -1;
+ }
+
+ if(!this->Creature->MovePossible(FieldX, FieldY, FieldZ, false, false)){
+ Waypoints = -1;
+ }
+
+ if(Waypoints > 0 && Waypoints < this->MinWaypoints){
+ this->MinWaypoints = Waypoints;
+ }
+ }
+ }
+
+ TShortwayPoint *Node = this->Map->at(X, Y);
+ Node->x = X;
+ Node->y = Y;
+ Node->Waypoints = Waypoints;
+ }
+}
+
+void TShortway::ClearMap(void){
+ for(int X = -this->VisibleX; X <= this->VisibleX; X += 1)
+ for(int Y = -this->VisibleY; Y <= this->VisibleY; Y += 1){
+ TShortwayPoint *Node = this->Map->at(X, Y);
+ Node->Waylength = INT_MAX;
+ Node->Heuristic = INT_MAX;
+ Node->Predecessor = NULL;
+ Node->NextToExpand = NULL;
+ }
+}
+
+void TShortway::Expand(TShortwayPoint *Node){
+ if(Node == NULL){
+ error("TShortway::Expand: Übergebener Knoten ist NULL.\n");
+ return;
+ }
+
+ this->FirstToExpand = Node->NextToExpand;
+
+ int MinNeighborWaylength = Node->Waylength + Node->Waypoints;
+ if(MinNeighborWaylength >= this->Map->at(0, 0)->Waylength){
+ return;
+ }
+
+ for(int OffsetX = -1; OffsetX <= 1; OffsetX += 1)
+ for(int OffsetY = -1; OffsetY <= 1; OffsetY += 1){
+ if(OffsetX == 0 && OffsetY == 0){
+ continue;
+ }
+
+ TShortwayPoint *Neighbor = this->Map->at(Node->x + OffsetX, Node->y + OffsetY);
+
+ // NOTE(fusion): The minimum neighbor waylength already contains the cost
+ // of a single step. Diagonal steps are three times more expensive so we
+ // add waypoints two more times.
+ int NeighborWaylength = MinNeighborWaylength;
+ if(OffsetX != 0 && OffsetY != 0){
+ NeighborWaylength += Node->Waylength * 2;
+ }
+
+ if(NeighborWaylength < Neighbor->Waylength){
+ Neighbor->Waylength = NeighborWaylength;
+ Neighbor->Predecessor = Node;
+ if((Neighbor->x != 0 || Neighbor->y != 0) && Neighbor->Waypoints != -1){
+ // NOTE(fusion): Remove from expand list if it was already expanded upon.
+ if(Neighbor->Heuristic != INT_MAX){
+ TShortwayPoint *Prev = NULL;
+ TShortwayPoint *Cur = this->FirstToExpand;
+ while(Cur != NULL && Cur != Neighbor){
+ Prev = Cur;
+ Cur = Cur->NextToExpand;
+ }
+
+ if(Cur != Neighbor){
+ error("TShortway::Expand: Knoten steht nicht in der ExpandList.\n");
+ }else if(Prev == NULL){
+ this->FirstToExpand = Neighbor->NextToExpand;
+ }else{
+ Prev->NextToExpand = Neighbor->NextToExpand;
+ }
+ }
+
+ // NOTE(fusion): Compute heuristic using the manhattan distance.
+ int Distance = std::abs(Neighbor->x) + std::abs(Neighbor->y);
+ Neighbor->Heuristic = Neighbor->Waylength
+ + Neighbor->Waypoints * 1
+ + this->MinWaypoints * (Distance - 1);
+
+ // NOTE(fusion): Insert into expand list.
+ {
+ TShortwayPoint *Prev = NULL;
+ TShortwayPoint *Cur = this->FirstToExpand;
+ while(Cur != NULL && Cur->Heuristic < Neighbor->Heuristic){
+ Prev = Cur;
+ Cur = Cur->NextToExpand;
+ }
+
+ if(Prev == NULL){
+ this->FirstToExpand = Neighbor;
+ }else{
+ Prev->NextToExpand = Neighbor;
+ }
+ Neighbor->NextToExpand = Cur;
+ }
+ }
+ }
+ }
+}
+
+bool TShortway::Calculate(int DestX, int DestY, bool MustReach, int MaxSteps){
+ if(this->Map == NULL){
+ error("TShortway::Calculate: Karte existiert nicht.\n");
+ return false;
+ }
+
+ // NOTE(fusion): Transform dest to relative coordinates.
+ DestX -= this->StartX;
+ DestY -= this->StartY;
+
+ // NOTE(fusion): Check if already at destination.
+ if(DestX == 0 && DestY == 0){
+ return true;
+ }
+
+ // NOTE(fusion): Check if out of range.
+ if(std::abs(DestX) > this->VisibleX || std::abs(DestY) > this->VisibleY){
+ return false;
+ }
+
+ // NOTE(fusion): Find shortest path from the destination to the origin.
+ this->ClearMap();
+ this->FirstToExpand = this->Map->at(DestX, DestY);
+ this->FirstToExpand->Waylength = 0;
+ while(this->FirstToExpand != NULL){
+ this->Expand(this->FirstToExpand);
+ }
+
+ // NOTE(fusion): Check if the origin was reached from the destination.
+ TShortwayPoint *Node = this->Map->at(0, 0);
+ if(Node->Waylength == INT_MAX){
+ return false;
+ }
+
+ // NOTE(fusion): Walk back from the origin to reconstruct the path.
+ Node = Node->Predecessor;
+ while(Node != NULL && MaxSteps > 0){
+ int MaxDistance = std::max<int>(
+ std::abs(Node->x - DestX),
+ std::abs(Node->y - DestY));
+ if(!MustReach && MaxDistance <= 1){
+ break;
+ }
+
+ TToDoEntry TD = {};
+ TD.Code = TDGo;
+ TD.Go.x = this->StartX + Node->x;
+ TD.Go.y = this->StartY + Node->y;
+ TD.Go.z = this->StartZ;
+ Creature->ToDoAdd(TD);
+
+ Node = Node->Predecessor;
+ MaxSteps -= 1;
+ }
+
+ return true;
+}
+
+// TCreature
+// =============================================================================
+bool TCreature::SetOnMap(void){
+ int LoginX = this->posx;
+ int LoginY = this->posy;
+ int LoginZ = this->posz;
+ bool Player = (this->Type == PLAYER);
+ if(!SearchLoginField(&LoginX, &LoginY, &LoginZ, 1, Player)){
+ bool Found = false;
+ if(IsHouse(LoginX, LoginY, LoginZ)){
+ uint16 HouseID = GetHouseID(LoginX, LoginY, LoginZ);
+ GetExitPosition(HouseID, &LoginX, &LoginY, &LoginZ);
+ Found = SearchLoginField(&LoginX, &LoginY, &LoginZ, 1, Player);
+ }
+
+ if(!Found){
+ LoginX = this->startx;
+ LoginY = this->starty;
+ LoginZ = this->startz;
+ }
+ }
+
+ Object Con = GetMapContainer(LoginX, LoginY, LoginZ);
+ if(Con == NONE){
+ error("TCreature::SetOnMap: Kartencontainer für Punkt [%d,%d,%d] existiert nicht.\n",
+ LoginX, LoginY, LoginZ);
+ return false;
+ }
+
+ this->posx = LoginX;
+ this->posy = LoginY;
+ this->posz = LoginZ;
+
+ // NOTE(fusion): `Create` automatically sets `this->CrObject` and creates
+ // its body container slots.
+ bool Result = true;
+ try{
+ Create(Con, TYPEID_CREATURE_CONTAINER, this->ID);
+ }catch(RESULT r){
+ error("TCreature::SetOnMap: Kann Kreatur nicht setzen ([%d,%d,%d] - Exception %d).\n",
+ LoginX, LoginY, LoginZ, r);
+ if(this->Type == PLAYER){
+ SendResult(this->Connection, r);
+ }
+ Result = false;
+ }
+ return Result;
+}
+
+bool TCreature::DelOnMap(void){
+ Object Obj = this->CrObject;
+ if(Obj == NONE){
+ return true;
+ }
+
+ // TODO(fusion): I feel `Delete` should also manage `this->CrObject` automatically.
+ bool Result = true;
+ this->CrObject = NONE;
+ try{
+ Delete(Obj, -1);
+ }catch(RESULT r){
+ error("TCreature::DelOnMap: Error Deleting CreatureObject: %d\n", r);
+ Result = false;
+ }
+ return Result;
+}
+
+void TCreature::Attack(void){
+ this->Combat.Attack();
+}
+
+//void TCreature::Execute(void);
+
+uint32 TCreature::CalculateDelay(void){
+ uint32 Delay = 0;
+ TToDoEntry *TD = this->ToDoList.at(this->ActToDo);
+ switch(TD->Code){
+ case TDWait:{
+ // TODO(fusion): I'm not sure about having `EarliestWalkTime` here.
+ uint32 WaitTime = TD->Wait.Time;
+ if(WaitTime < this->EarliestWalkTime){
+ WaitTime = this->EarliestWalkTime;
+ }
+
+ if(WaitTime > ServerMilliseconds){
+ Delay = WaitTime - ServerMilliseconds;
+ }
+ break;
+ }
+
+ case TDGo:{
+ if(this->EarliestWalkTime > ServerMilliseconds){
+ Delay = this->EarliestWalkTime - ServerMilliseconds;
+ }
+ break;
+ }
+
+ case TDUse:{
+ if(TD->Use.Obj2 != 0){
+ if(this->EarliestMultiuseTime > ServerMilliseconds){
+ Delay = this->EarliestMultiuseTime - ServerMilliseconds;
+ }
+ }
+ break;
+ }
+
+ case TDAttack:{
+ uint32 EarliestAttackTime = this->Combat.EarliestAttackTime;
+ if(EarliestAttackTime < this->EarliestSpellTime){
+ EarliestAttackTime = this->EarliestSpellTime;
+ }
+
+ if(EarliestAttackTime > ServerMilliseconds){
+ Delay = EarliestAttackTime - ServerMilliseconds;
+ }
+ break;
+ }
+
+ default:{
+ break;
+ }
+ }
+ return Delay;
+}
+
+bool TCreature::ToDoClear(void){
+ bool SnapbackNecessary = false;
+ for(int i = 0; i < this->NrToDo; i += 1){
+ TToDoEntry *TD = this->ToDoList.at(i);
+ switch(TD->Code){
+ case TDGo:{
+ if(this->ActToDo <= i){
+ SnapbackNecessary = true;
+ }
+ break;
+ }
+
+ case TDTalk:{
+ DeleteDynamicString(TD->Talk.Text);
+ DeleteDynamicString(TD->Talk.Addressee);
+ break;
+ }
+
+ case TDChangeState:{
+ if(this->ActToDo <= i && this->Type == NPC){
+ ChangeNPCState(this, TD->ChangeState.NewState, false);
+ }
+ break;
+ }
+
+ default:{
+ break;
+ }
+ }
+ }
+
+ this->LockToDo = false;
+ this->ActToDo = 0;
+ this->NrToDo = 0;
+ this->Stop = false;
+ return SnapbackNecessary;
+}
+
+void TCreature::ToDoAdd(TToDoEntry TD){
+ if(this->LockToDo){
+ if(this->ToDoClear() && this->Type == PLAYER){
+ SendSnapback(this->Connection);
+ }
+ }
+
+ *this->ToDoList.at(this->NrToDo) = TD;
+ this->NrToDo += 1;
+}
+
+void TCreature::ToDoStop(void){
+ if(this->LockToDo){
+ this->Stop = true;
+ }else if(this->Type == PLAYER){
+ SendSnapback(this->Connection);
+ }
+}
+
+void TCreature::ToDoStart(void){
+ if(this->NrToDo != 0){
+ this->LockToDo = true;
+ this->ActToDo = 0;
+
+ uint32 Delay = this->CalculateDelay();
+ if(Delay < 1){
+ Delay = 1;
+ }
+
+ uint32 NextWakeup = ServerMilliseconds + Delay;
+ ToDoQueue.insert(NextWakeup, this->ID);
+ this->NextWakeup = NextWakeup;
+ }
+}
+
+void TCreature::ToDoYield(void){
+ if(!this->LockToDo){
+ this->ToDoWait(0);
+ this->ToDoStart();
+ }
+}
+
+void TCreature::ToDoWait(int Delay){
+ TToDoEntry TD = {};
+ TD.Code = TDWait;
+ TD.Wait.Time = ServerMilliseconds + Delay;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoGo(int DestX, int DestY, int DestZ, bool MustReach, int MaxSteps){
+ if(this->posz < DestZ){
+ throw DOWNSTAIRS;
+ }else if(this->posz > DestZ){
+ throw UPSTAIRS;
+ }
+
+ if(this->LockToDo){
+ TToDoEntry *Last = this->ToDoList.at(this->NrToDo - 1);
+ if(Last->Code == TDGo
+ && Last->Go.x == DestX
+ && Last->Go.y == DestY
+ && Last->Go.z == DestZ){
+ // TODO(fusion): Why? Shouldn't we just return here?
+ throw NOERROR;
+ }
+ }
+
+ int DistanceX = std::abs(DestX - this->posx);
+ int DistanceY = std::abs(DestY - this->posy);
+ int MaxDistance = std::max<int>(DistanceX, DistanceY);
+ if(MaxDistance == 0 || (!MustReach && MaxDistance <= 1)){
+ return;
+ }
+
+ // NOTE(fusion): The number of steps between two points is the same as the
+ // their manhattan distance, if we exclude diagonal movement. We can skip
+ // the path finder if we know we're step away from the destination.
+ if(DistanceX + DistanceY == 1){
+ TToDoEntry TD = {};
+ TD.Code = TDGo;
+ TD.Go.x = DestX;
+ TD.Go.y = DestY;
+ TD.Go.z = DestZ;
+ this->ToDoAdd(TD);
+ }else{
+ int VisibleX = (this->Type == PLAYER) ? 7 : 10;
+ int VisibleY = (this->Type == PLAYER) ? 7 : 10;
+ TShortway Shortway(this, VisibleX, VisibleY);
+ if(!Shortway.Calculate(DestX, DestY, MustReach, MaxSteps)){
+ this->ToDoClear();
+ if(this->Type == PLAYER){
+ SendSnapback(this->Connection);
+ }
+ throw NOWAY;
+ }
+ }
+}
+
+void TCreature::ToDoRotate(int Direction){
+ if(Direction != DIRECTION_NORTH
+ && Direction != DIRECTION_EAST
+ && Direction != DIRECTION_SOUTH
+ && Direction != DIRECTION_WEST){
+ throw ERROR;
+ }
+
+ TToDoEntry TD = {};
+ TD.Code = TDRotate;
+ TD.Rotate.Direction = Direction;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoMove(int ObjX, int ObjY, int ObjZ, ObjectType Type, uint8 RNum,
+ int DestX, int DestY, int DestZ, uint8 Count){
+ Object Obj = GetObject(this->ID, ObjX, ObjY, ObjZ, RNum, Type);
+ if(!Obj.exists()){
+ throw NOTACCESSIBLE;
+ }
+
+ // TODO(fusion): This could be an inlined function.
+ if(ObjX != 0xFFFF){ // SPECIAL_COORDINATE ?
+ if(this->posz > ObjZ){
+ throw UPSTAIRS;
+ }else if(this->posz < ObjZ){
+ throw DOWNSTAIRS;
+ }
+
+ if(!ObjectInRange(this->ID, Obj, 1)){
+ this->ToDoGo(ObjX, ObjY, ObjZ, false, INT_MAX);
+ }
+ }
+
+ int Delay = 100;
+ if(Obj.getObjectType().isCreatureContainer()){
+ Object DestBank = GetFirstObject(DestX, DestY, DestZ);
+ if(DestBank == NONE || !DestBank.getObjectType().getFlag(BANK)){
+ throw NOTACCESSIBLE;
+ }
+
+ TCreature *Creature = GetCreature(Obj);
+ if(Creature == NULL){
+ error("TCreature::ToDoMove: Kreatur existiert nicht.\n");
+ throw ERROR;
+ }
+
+ Delay = 1000;
+ if(this->EarliestWalkTime > ServerMilliseconds){
+ Delay += (int)(this->EarliestWalkTime - ServerMilliseconds);
+ }
+ }
+
+ this->ToDoWait(Delay);
+
+ TToDoEntry TD = {};
+ TD.Code = TDMove;
+ TD.Move.Obj = Obj.ObjectID;
+ TD.Move.x = DestX;
+ TD.Move.y = DestY;
+ TD.Move.z = DestZ;
+ TD.Move.Count = Count;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoMove(Object Obj, int DestX, int DestY, int DestZ, uint8 Count){
+ if(!Obj.exists()){
+ throw NOTACCESSIBLE;
+ }
+
+ if(!ObjectInRange(this->ID, Obj, 1)){
+ this->ToDoGo(DestX, DestY, DestZ, false, INT_MAX);
+ }
+
+ int Delay = 100;
+ if(Obj.getObjectType().isCreatureContainer()){
+ // TODO(fusion): We don't add the delay until the earliest walk time
+ // like in the other variant above.
+ Delay = 1000;
+ }
+
+ this->ToDoWait(Delay);
+
+ TToDoEntry TD = {};
+ TD.Code = TDMove;
+ TD.Move.Obj = Obj.ObjectID;
+ TD.Move.x = DestX;
+ TD.Move.y = DestY;
+ TD.Move.z = DestZ;
+ TD.Move.Count = Count;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoTrade(int ObjX, int ObjY, int ObjZ, ObjectType Type, uint8 RNum,
+ uint32 TradePartner){
+ Object Obj = GetObject(this->ID, ObjX, ObjY, ObjZ, RNum, Type);
+ if(!Obj.exists()){
+ throw NOTACCESSIBLE;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.getFlag(UNMOVE)){
+ throw NOTMOVABLE;
+ }
+
+ if(!ObjType.getFlag(TAKE)){
+ throw NOTTAKABLE;
+ }
+
+ if(ObjType.isCreatureContainer()){
+ error("TCreature::ToDoTrade: Objekt ist eine Kreatur.\n");
+ throw ERROR;
+ }
+
+ if(TradePartner == 0){
+ error("TCreature::ToDoTrade: Handelspartner ist Null.\n");
+ throw ERROR;
+ }
+
+ TCreature *Creature = GetCreature(TradePartner);
+ if(Creature == NULL){
+ throw PLAYERNOTONLINE;
+ }
+
+ if(Creature->Type != PLAYER){
+ error("TCreature::ToDoTrade: Handelspartner von %s ist kein Spieler.\n", this->Name);
+ throw ERROR;
+ }
+
+ // TODO(fusion): This could be an inlined function.
+ if(ObjX != 0xFFFF){ // SPECIAL_COORDINATE ?
+ if(this->posz > ObjZ){
+ throw UPSTAIRS;
+ }else if(this->posz < ObjZ){
+ throw DOWNSTAIRS;
+ }
+
+ if(!ObjectInRange(this->ID, Obj, 1)){
+ this->ToDoGo(ObjX, ObjY, ObjZ, false, INT_MAX);
+ }
+ }
+
+ TToDoEntry TD = {};
+ TD.Code = TDTrade;
+ TD.Trade.Obj = Obj.ObjectID;
+ TD.Trade.Partner = TradePartner;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoUse(uint8 Count, int ObjX1, int ObjY1, int ObjZ1, ObjectType Type1, uint8 RNum1,
+ uint8 Dummy, int ObjX2, int ObjY2, int ObjZ2, ObjectType Type2, uint8 RNum2){
+ Object Obj1 = GetObject(this->ID, ObjX1, ObjY1, ObjZ1, RNum1, Type1);
+ if(!Obj1.exists()){
+ throw NOTACCESSIBLE;
+ }
+
+ Object Obj2 = NONE;
+ if(Count >= 2){
+ Obj2 = GetObject(this->ID, ObjX2, ObjY2, ObjZ2, RNum2, Type2);
+ if(!Obj2.exists()){
+ throw NOTACCESSIBLE;
+ }
+ }
+
+ // TODO(fusion): This could be an inlined function.
+ if(ObjX1 != 0xFFFF){ // SPECIAL_COORDINATE ?
+ if(this->posz > ObjZ1){
+ throw UPSTAIRS;
+ }else if(this->posz < ObjZ1){
+ throw DOWNSTAIRS;
+ }
+
+ if(!ObjectInRange(this->ID, Obj1, 1)){
+ this->ToDoGo(ObjX1, ObjY1, ObjZ1, false, INT_MAX);
+ }
+ }
+
+ this->ToDoWait(100);
+
+ TToDoEntry TD = {};
+ TD.Code = TDUse;
+ TD.Use.Obj1 = Obj1.ObjectID;
+ TD.Use.Obj2 = Obj2.ObjectID;
+ // TODO(fusion): This is the value sent by the client on single object use
+ // that contains the next free container index.
+ TD.Use.Dummy = Dummy;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoUse(uint8 Count, Object Obj1, Object Obj2){
+ if(!Obj1.exists()){
+ throw NOTACCESSIBLE;
+ }
+
+ if(Count <= 1){
+ Obj2 = NONE;
+ }else if(!Obj2.exists()){
+ throw NOTACCESSIBLE;
+ }
+
+ if(!ObjectInRange(this->ID, Obj1, 1)){
+ int ObjX1, ObjY1, ObjZ1;
+ GetObjectCoordinates(Obj1, &ObjX1, &ObjY1, &ObjZ1);
+ this->ToDoGo(ObjX1, ObjY1, ObjZ1, false, INT_MAX);
+ }
+
+ this->ToDoWait(100);
+
+ TToDoEntry TD = {};
+ TD.Code = TDUse;
+ TD.Use.Obj1 = Obj1.ObjectID;
+ TD.Use.Obj2 = Obj2.ObjectID;
+ // TODO(fusion): Not sure why we set this value at all.
+ TD.Use.Dummy = Count;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoTurn(int ObjX, int ObjY, int ObjZ, ObjectType Type, uint8 RNum){
+ Object Obj = GetObject(this->ID, ObjX, ObjY, ObjZ, RNum, Type);
+ if(!Obj.exists()){
+ throw NOTACCESSIBLE;
+ }
+
+ // TODO(fusion): This could be an inlined function.
+ if(ObjX != 0xFFFF){ // SPECIAL_COORDINATE ?
+ if(this->posz > ObjZ){
+ throw UPSTAIRS;
+ }else if(this->posz < ObjZ){
+ throw DOWNSTAIRS;
+ }
+
+ if(!ObjectInRange(this->ID, Obj, 1)){
+ this->ToDoGo(ObjX, ObjY, ObjZ, false, INT_MAX);
+ }
+ }
+
+ this->ToDoWait(100);
+
+ TToDoEntry TD = {};
+ TD.Code = TDTurn;
+ TD.Turn.Obj = Obj.ObjectID;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoAttack(void){
+ this->Combat.CanToDoAttack();
+ if(this->Combat.GetDistance() != 1){
+ this->ToDoWait(100);
+ }
+
+ TToDoEntry TD = {};
+ TD.Code = TDAttack;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoTalk(int Mode, const char *Addressee, const char *Text, bool CheckSpamming){
+ TToDoEntry TD = {};
+
+ if(Text == NULL || Text[0] == 0){
+ error("TCreature::ToDoTalk: Text ist NULL bei %s.\n", this->Name);
+
+ // TODO(fusion): The original code would attempt to call `AddDynamicString`
+ // even after this check but it doesn't check whether `Text` is NULL and
+ // calls `strlen` immediately on it which could be a problem.
+ TD.Talk.Text = 0;
+ }else{
+ TD.Talk.Text = AddDynamicString(Text);
+ }
+
+ if(Addressee == NULL){
+ TD.Talk.Addressee = 0;
+ }else{
+ TD.Talk.Addressee = AddDynamicString(Addressee);
+ }
+
+ TD.Code = TDTalk;
+ TD.Talk.Mode = Mode;
+ TD.Talk.CheckSpamming = CheckSpamming;
+ this->ToDoAdd(TD);
+}
+
+void TCreature::ToDoChangeState(int NewState){
+ TToDoEntry TD = {};
+ TD.Code = TDChangeState;
+ TD.ChangeState.NewState = NewState;
+ this->ToDoAdd(TD);
+}
diff --git a/src/crcombat.cc b/src/crcombat.cc
index 9edfe9b..dd732e3 100644
--- a/src/crcombat.cc
+++ b/src/crcombat.cc
@@ -307,11 +307,11 @@ int TCombat::GetArmorStrength(void){
int TCombat::GetDistance(void){
int Distance = 0;
if(this->Close != NONE || this->Fist){
- Distance = 1;
+ Distance = 1; // DISTANCE_CLOSE ?
}else if(this->Throw != NONE){
- Distance = 2;
+ Distance = 2; // DISTANCE_THROW ?
}else if(this->Missile != NONE || this->Wand != NONE){
- Distance = 3;
+ Distance = 3; // DISTANCE_RANGE ?
}
return Distance;
}
diff --git a/src/crmain.cc b/src/crmain.cc
index d962bf9..49348d8 100644
--- a/src/crmain.cc
+++ b/src/crmain.cc
@@ -1,22 +1,23 @@
#include "cr.hh"
+#include "config.hh"
#include "enums.hh"
+#include "info.hh"
#include "stubs.hh"
-static uint32 NextCreatureID;
-static matrix<uint32> *FirstChainCreature;
-static TCreature *HashList[1000];
-
-static int FirstFreeCreature;
-static vector<TCreature*> CreatureList(0, 10000, 1000);
-
-static priority_queue<uint32, uint32> ToDoQueue(5000, 1000);
-//static priority_queue<uint32, TAttackWave*> AttackWaveQueue(100, 100);
-
TRaceData RaceData[MAX_RACES];
int KilledCreatures[MAX_RACES];
int KilledPlayers[MAX_RACES];
+priority_queue<uint32, uint32> ToDoQueue(5000, 1000);
+//priority_queue<uint32, TAttackWave*> AttackWaveQueue(100, 100);
+
+static uint32 NextCreatureID;
+static int FirstFreeCreature;
+static TCreature *HashList[1000];
+static matrix<uint32> *FirstChainCreature;
+static vector<TCreature*> CreatureList(0, 10000, 1000);
+
// TCreature
// =============================================================================
TCreature::TCreature(void) :
@@ -67,8 +68,286 @@ TCreature::TCreature(void) :
}
}
-void TCreature::Attack(void){
- this->Combat.Attack();
+TCreature::~TCreature(void){
+ // TODO(fusion): Bruuhh... these exceptions...
+ if(this->IsDead){
+ int Race = this->Race;
+ int PoolLiquid = LIQUID_NONE;
+ if(RaceData[Race].Blood == BT_BLOOD){
+ PoolLiquid = LIQUID_BLOOD;
+ }else if(RaceData[Race].Blood == BT_SLIME){
+ PoolLiquid = LIQUID_SLIME;
+ }
+
+ if(PoolLiquid != LIQUID_NONE){
+ try{
+ CreatePool(GetMapContainer(this->CrObject),
+ GetSpecialObject(BLOOD_POOL),
+ PoolLiquid);
+ }catch(RESULT r){
+ if(r != NOROOM && r != DESTROYED){
+ error("TCreature::~TCreature: Kann Blutlache nicht setzen (Exc %d, Pos [%d,%d,%d]).\n",
+ r, this->posx, this->posy, this->posz);
+ }
+ }
+ }
+
+ ObjectType CorpseType = (this->Sex == 1) // MALE ?
+ ? RaceData[Race].MaleCorpse
+ : RaceData[Race].FemaleCorpse;
+
+ if(CorpseType.getFlag(MAGICFIELD)){
+ Object Obj = GetFirstObject(this->posx, this->posy, this->posz);
+ while(Obj != NONE){
+ Object Next = Obj.getNextObject();
+ if(Obj.getObjectType().getFlag(MAGICFIELD)){
+ try{
+ Delete(Obj, -1);
+ }catch(RESULT r){
+ error("TCreature::~TCreature: Exception %d beim Löschen eines Feldes.\n", r);
+ }
+ }
+ Obj = Next;
+ }
+ }
+
+ try{
+ Object Con = GetMapContainer(this->posx, this->posy, this->posz);
+ Object Corpse = Create(Con, CorpseType, 0);
+ Log("game", "Tod von %s: LoseInventory=%d.\n", this->Name, this->LoseInventory);
+
+ if(this->Type == PLAYER){
+ char Help[128];
+ sprintf(Help, "You recognize %s", this->Name);
+ if(this->Murderer[0] != 0){
+ if(this->Sex == 1){ // MALE ?
+ strcat(Help, ". He was killed by ");
+ }else{
+ strcat(Help, ". She was killed by ");
+ }
+ strcat(Help, this->Murderer);
+ }
+ Change(Corpse, TEXTSTRING, AddDynamicString(Help));
+ }
+
+ if(this->LoseInventory != 0){ // LOSE_INVENTORY_NONE ?
+ for(int Position = 1; Position <= 10; Position += 1){
+ Object Item = GetBodyObject(this->ID, Position);
+ if(Item == NONE){
+ continue;
+ }
+
+ if(this->LoseInventory != 2 // LOSE_INVENTORY_ALL ?
+ && !Item.getObjectType().getFlag(CONTAINER)
+ && random(0, 9) != 0){
+ continue;
+ }
+
+ Move(0, Item, Corpse, -1, false, NONE);
+ }
+ }
+
+ if(this->Type == PLAYER && this->LoseInventory != 2){ // LOSE_INVENTORY_ALL ?
+ ((TPlayer*)this)->SaveInventory();
+ }
+ }catch(RESULT r){
+ error("TCreature::~TCreature: Kann Leiche/Inventory nicht ablegen (Exc %d, Pos [%d,%d,%d], %s).\n",
+ r, this->posx, this->posy, this->posz, this->Name);
+ }
+ }
+
+ if(this->CrObject != NONE && this->CrObject.exists()){
+ this->DelOnMap();
+ }
+
+ this->ToDoClear();
+
+ if(this->Type == PLAYER && this->Connection != NULL){
+ this->Connection->Logout(30, true);
+ }
+
+ this->DelInCrList();
+
+ if(this->ID != 0){
+ this->DelID();
+ }
+
+ for(TKnownCreature *KnownCreature = this->FirstKnowingConnection;
+ KnownCreature != NULL;
+ KnownCreature = KnownCreature->Next){
+ if(KnownCreature->CreatureID != this->ID){
+ error("TCreature::~TCreature: Verkettungsfehler bei Kreatur %u.\n", this->ID);
+ }
+ KnownCreature->State = KNOWNCREATURE_FREE;
+ }
+}
+
+void TCreature::SetID(uint32 CharacterID){
+ if(this->ID != 0){
+ error("TCreature::SetID: ID ist schon gesetzt.\n");
+ }
+
+ uint32 CreatureID = 0;
+ if(CharacterID == 0){
+ bool Found = false;
+ for(int Attempts = 0; Attempts < 16; Attempts += 1){
+ CreatureID = NextCreatureID++;
+ if(GetCreature(CreatureID) == NULL){
+ Found = true;
+ break;
+ }
+ }
+
+ if(!Found){
+ error("TCreature::SetID: 16x hintereinander doppelte ID."
+ " Verwende nun doppelte ID %d\n", CreatureID);
+ }
+ }else{
+ CreatureID = CharacterID;
+ if(GetCreature(CreatureID) != NULL){
+ error("TCreature::SetID: Doppelte Character-ID %d gefunden.\n", CharacterID);
+ }
+ }
+
+ uint32 ListIndex = CreatureID % NARRAY(HashList);
+ this->ID = CreatureID;
+ this->NextHashEntry = HashList[ListIndex];
+ HashList[ListIndex] = this;
+}
+
+void TCreature::DelID(void){
+ uint32 ListIndex = this->ID % NARRAY(HashList);
+ TCreature *First = HashList[ListIndex];
+ if(First == NULL){
+ error("TCreature::DelID: Hasheintrag nicht gefunden id = %d\n", this->ID);
+ return;
+ }
+
+ if(First->ID == this->ID){
+ HashList[ListIndex] = this->NextHashEntry;
+ }else{
+ TCreature *Prev = First;
+ TCreature *Current = First->NextHashEntry;
+ while(true){
+ if(Current == NULL){
+ error("TCreature::DelID: id=%d nicht gefunden.\n", this->ID);
+ return;
+ }
+
+ if(Current->ID == this->ID){
+ Prev->NextHashEntry = this->NextHashEntry;
+ break;
+ }
+
+ Prev = Current;
+ Current = Current->NextHashEntry;
+ }
+ }
+}
+
+void TCreature::SetInCrList(void){
+ *CreatureList.at(FirstFreeCreature) = this;
+ FirstFreeCreature += 1;
+}
+
+void TCreature::DelInCrList(void){
+ // TODO(fusion): See note in `ProcessCreatures`.
+ for(int Index = 0; Index < FirstFreeCreature; Index += 1){
+ TCreature **Current = CreatureList.at(Index);
+ if(*Current == this){
+ TCreature **Last = CreatureList.at(FirstFreeCreature - 1);
+ *Current = *Last;
+ *Last = NULL;
+ FirstFreeCreature -= 1;
+
+ // TODO(fusion): The original function wouldn't break here. Maybe it
+ // is possible to have duplicates in `CreatureList`?
+ //break;
+ }
+ }
+}
+
+void TCreature::StartLogout(bool Force, bool StopFight){
+ this->LoggingOut = true;
+ if(Force || LagDetected()){
+ this->LogoutAllowed = true;
+ }
+
+ if(this->Type == PLAYER && this->Connection != NULL){
+ this->Connection->Logout(0, true);
+ }
+
+ this->Combat.StopAttack(StopFight ? 0 : 60);
+}
+
+int TCreature::LogoutPossible(void){
+ if(!this->LogoutAllowed && !this->IsDead && !GameEnding()){
+ if(this->EarliestLogoutRound > RoundNr && !LagDetected()){
+ return 1; // LOGOUT_COMBAT ?
+ }
+
+ if(IsNoLogoutField(this->posx, this->posy, this->posz)){
+ return 2; // LOGOUT_FIELD ?
+ }
+
+ this->LogoutAllowed = true;
+ }
+
+ return 0; // LOGOUT_OK ?
+}
+
+void TCreature::BlockLogout(int Delay, bool BlockProtectionZone){
+ if(WorldType == NON_PVP){
+ BlockProtectionZone = false;
+ }
+
+ if(this->Type == PLAYER && !CheckRight(this->ID, NO_LOGOUT_BLOCK)){
+ if(BlockProtectionZone || this->EarliestProtectionZoneRound > RoundNr){
+ uint32 EarliestProtectionZoneRound = RoundNr + Delay;
+ if(this->EarliestProtectionZoneRound < EarliestProtectionZoneRound){
+ this->EarliestProtectionZoneRound = EarliestProtectionZoneRound;
+ }
+ }else if(this->Connection == NULL){
+ // NOTE(fusion): This is a failsafe to avoid extending the earliest
+ // logout round of a player that got disconnected in combat.
+ return;
+ }
+
+ uint32 EarliestLogoutRound = RoundNr + Delay;
+ if(this->EarliestLogoutRound < EarliestLogoutRound){
+ this->EarliestLogoutRound = EarliestLogoutRound;
+ }
+
+ ((TPlayer*)this)->CheckState();
+ }
+}
+
+int TCreature::GetHealth(void){
+ int MaxHitPoints = this->Skills[SKILL_HITPOINTS]->Max;
+ if(MaxHitPoints <= 0){
+ if(!this->IsDead){
+ error("TCreature::GetHealth: MaxHitpoints von %s ist %d, obwohl sie nicht tot ist.\n",
+ this->Name, MaxHitPoints);
+ }
+ return 0;
+ }
+
+ int CurrentHitPoints = this->Skills[SKILL_HITPOINTS]->Get();
+ int Health = CurrentHitPoints * 100 / MaxHitPoints;
+ if(Health <= 0){
+ Health = (int)(CurrentHitPoints != 0);
+ }
+ return Health;
+}
+
+int TCreature::GetSpeed(void){
+ TSkill *GoStrength = this->Skills[SKILL_GO_STRENGTH];
+ if(GoStrength == NULL){
+ error("TCreature::GetSpeed: Kein Skill GOSTRENGTH vorhanden.\n");
+ return 0;
+ }
+
+ return GoStrength->Get() * 2 + 80;
}
int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){
@@ -462,13 +741,143 @@ int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){
return Damage;
}
+void TCreature::Death(void){
+ this->IsDead = true;
+ this->LoggingOut = true;
+}
+
+bool TCreature::MovePossible(int x, int y, int z, bool Execute, bool Jump){
+ bool Result;
+
+ if(Jump){
+ Result = JumpPossible(x, y, z, false);
+ }else{
+ Result = CoordinateFlag(x, y, z, BANK)
+ && !CoordinateFlag(x, y, z, UNPASS);
+ }
+
+ if(Result && !Execute && CoordinateFlag(x, y, z, AVOID)){
+ Result = false;
+ }
+
+ return Result;
+}
+
+bool TCreature::IsPeaceful(void){
+ return true;
+}
+
+uint32 TCreature::GetMaster(void){
+ return 0;
+}
+
+void TCreature::TalkStimulus(uint32 SpeakerID, const char *Text){
+ // no-op
+}
+
+void TCreature::DamageStimulus(uint32 AttackerID, int Damage, int DamageType){
+ // no-op
+}
+
+void TCreature::IdleStimulus(void){
+ // no-op
+}
+
+void TCreature::CreatureMoveStimulus(uint32 CreatureID, int Type){
+ if(CreatureID == 0 || CreatureID == this->ID
+ || this->IsDead
+ || this->Combat.AttackDest != CreatureID
+ || this->Combat.ChaseMode != CHASE_MODE_CLOSE
+ || this->Combat.EarliestAttackTime <= (ServerMilliseconds + 200)){
+ return;
+ }
+
+ // TODO(fusion): Find out what `Type` is here.
+ if(Type != 2 // STIMULUS_TYPE??
+ || !this->LockToDo
+ || this->ActToDo >= this->NrToDo
+ || this->ToDoList.at(this->ActToDo)->Code != TDAttack){
+ return;
+ }
+
+ TCreature *Target = GetCreature(this->Combat.AttackDest);
+ if(Target == NULL){
+ return;
+ }
+
+ int Distance = ObjectDistance(this->CrObject, Target->CrObject);
+ if(Distance <= 1){
+ return;
+ }
+
+ // TODO(fusion): Review this.
+ try{
+ if(this->ToDoClear() && this->Type == PLAYER){
+ SendSnapback(this->Connection);
+ }
+ this->ToDoWait(200);
+ this->ToDoAttack();
+ this->ToDoStart();
+ }catch(RESULT r){
+ if(this->Type == PLAYER){
+ SendResult(this->Connection, r);
+ }
+ this->ToDoClear();
+ this->ToDoWait(this->Combat.EarliestAttackTime);
+ this->ToDoStart();
+ }
+}
+
+void TCreature::AttackStimulus(uint32 AttackerID){
+ // no-op
+}
+
// Creature Management
// =============================================================================
bool IsCreaturePlayer(uint32 CreatureID){
return CreatureID < 0x40000000;
}
-//
+TCreature *GetCreature(uint32 CreatureID){
+ if(CreatureID == 0){
+ return NULL;
+ }
+
+ TCreature *Creature = HashList[CreatureID % NARRAY(HashList)];
+ while(Creature != NULL && Creature->ID != CreatureID){
+ Creature = Creature->NextHashEntry;
+ }
+
+ return Creature;
+}
+
+TCreature *GetCreature(Object Obj){
+ return GetCreature(Obj.getCreatureID());
+}
+
+void InsertChainCreature(TCreature *Creature, int CoordX, int CoordY){
+ if(Creature == NULL){
+ // TODO(fusion): Maybe a typo on the name of the function? I thought it
+ // could be some type of macro because there was no function name mismatch
+ // until now.
+ error("DeleteChainCreature: Übegebene Kreatur existiert nicht.\n");
+ return;
+ }
+
+ if(CoordX == 0){
+ CoordX = Creature->posx;
+ }
+
+ if(CoordY == 0){
+ CoordY = Creature->posy;
+ }
+
+ int ChainX = CoordX / 16;
+ int ChainY = CoordY / 16;
+ uint32 *FirstID = FirstChainCreature->at(ChainX, ChainY);
+ Creature->NextChainCreature = *FirstID;
+ *FirstID = Creature->ID;
+}
void DeleteChainCreature(TCreature *Creature){
if(Creature == NULL){
@@ -479,9 +888,9 @@ void DeleteChainCreature(TCreature *Creature){
// NOTE(fusion): All creatures in each 16x16 region form a creature linked
// list, despite its current floor. Whether that is a good idea is a whole
// other matter.
- int BlockX = Creature->posx / 16;
- int BlockY = Creature->posy / 16;
- uint32 *FirstID = FirstChainCreature->at(BlockX, BlockY);
+ int ChainX = Creature->posx / 16;
+ int ChainY = Creature->posy / 16;
+ uint32 *FirstID = FirstChainCreature->at(ChainX, ChainY);
if(*FirstID == Creature->ID){
*FirstID = Creature->NextChainCreature;
@@ -509,8 +918,112 @@ void DeleteChainCreature(TCreature *Creature){
}
}
+void MoveChainCreature(TCreature *Creature, int CoordX, int CoordY){
+ if(Creature == NULL){
+ error("DeleteChainCreature: Übegebene Kreatur existiert nicht.\n");
+ return;
+ }
+
+ int NewChainX = CoordX / 16;
+ int NewChainY = CoordY / 16;
+ int OldChainX = Creature->posx / 16;
+ int OldChainY = Creature->posy / 16;
+
+ if(NewChainX != OldChainX || NewChainY != OldChainY){
+ DeleteChainCreature(Creature);
+ InsertChainCreature(Creature, CoordX, CoordY);
+ }
+}
+
+void ProcessCreatures(void){
+ for(int Index = 0; Index < FirstFreeCreature; Index += 1){
+ TCreature *Creature = *CreatureList.at(Index);
+ if(Creature == NULL){
+ error("ProcessCreatures: Kreatur %d existiert nicht.\n", Index);
+ continue;
+ }
+
+ // TODO(fusion): It is weird that we do check the connection all the time
+ // and most of the time it is redundant because functions will check if
+ // it's NULL before attempting anything.
+
+ int FoodRegen = Creature->Skills[SKILL_FED]->Get();
+ if(FoodRegen > 0 && (RoundNr % FoodRegen) == 0 && !Creature->IsDead
+ && !IsProtectionZone(Creature->posx, Creature->posy, Creature->posz)){
+ Creature->Skills[SKILL_HITPOINTS]->Change(1);
+ Creature->Skills[SKILL_MANA]->Change(4);
+ if(Creature->Type == PLAYER){
+ SendPlayerData(Creature->Connection);
+ }
+ }
+
+ if(Creature->Type == PLAYER){
+ if(Creature->Connection != NULL){
+ ((TPlayer*)Creature)->CheckState();
+ }
+
+ if(Creature->EarliestLogoutRound != 0 && Creature->EarliestLogoutRound <= RoundNr){
+ ((TPlayer*)Creature)->ClearPlayerkillingMarks();
+ Creature->EarliestLogoutRound = 0;
+ }
+ }
+
+ if(!Creature->IsDead && Creature->Skills[SKILL_HITPOINTS]->Get() <= 0){
+ error("ProcessCreatures: Kreatur %s ist nicht tot, obwohl sie keine HP mehr hat.\n", Creature->Name);
+ Creature->Death();
+ }
+
+ if(Creature->LoggingOut && Creature->LogoutPossible() == 0){ // LOGOUT_POSSIBLE ?
+ if(Creature->IsDead && Creature->Skills[SKILL_HITPOINTS]->Get() > 0){
+ error("ProcessCreatures: Kreatur %s hat HP, obwohl sie tot ist.\n", Creature->Name);
+ Creature->Skills[SKILL_HITPOINTS]->Set(0);
+ }
+
+ // TODO(fusion): Creatures are removed from `CreatureList` with a swap
+ // and pop. Since we're iterating it RIGHT NOW, we need to process the
+ // the current index AGAIN because it'll now contain the creature that
+ // was previously at the end of the list. The annoying part here is that
+ // this removal occurs implicitly in the creature's destructor.
+ delete Creature;
+ Index -= 1;
+ }
+ }
+}
+
+void ProcessSkills(void){
+ for(int Index = 0; Index < FirstFreeCreature; Index += 1){
+ TCreature *Creature = *CreatureList.at(Index);
+ if(Creature == NULL){
+ error("ProcessSkills: Kreatur %d existiert nicht.\n", Index);
+ continue;
+ }
+
+ Creature->ProcessSkills();
+ }
+}
+
+void MoveCreatures(int Delay){
+ ServerMilliseconds += Delay;
+ while(ToDoQueue.Entries > 0){
+ auto Entry = *ToDoQueue.Entry->at(1);
+ uint32 ExecutionTime = Entry.Key;
+ uint32 CreatureID = Entry.Data;
+ if(ExecutionTime > ServerMilliseconds){
+ break;
+ }
+
+ ToDoQueue.deleteMin();
+ TCreature *Creature = GetCreature(CreatureID);
+ if(Creature != NULL){
+ Creature->Execute();
+ }
+ }
+}
+
// Kill Statistics
// =============================================================================
+void InitKillStatistics(void);//TODO
+void ExitKillStatistics(void);//TODO
void AddKillStatistics(int AttackerRace, int DefenderRace){
// NOTE(fusion): I think the race name can be "human" only for players,
// which means we're probably tracking how many creatures are killed by
@@ -572,9 +1085,13 @@ TRaceData::TRaceData(void) :
this->Spells = 0;
}
+bool IsRaceValid(int Race){
+ return Race >= 1 && Race < MAX_RACES;
+}
+
int GetRaceByName(const char *RaceName){
int Result = 0;
- for(int Race = 1; Race < NARRAY(RaceData); Race += 1){
+ for(int Race = 1; Race < MAX_RACES; Race += 1){
if(stricmp(RaceName, RaceData[Race].Name) == 0){
Result = Race;
break;
@@ -583,7 +1100,35 @@ int GetRaceByName(const char *RaceName){
return Result;
}
-// Raid
+void LoadRaces(void); //TODO
+
+// Monster Raid
// =============================================================================
+void LoadMonsterRaids(void); //TODO
+// Initialization
+// =============================================================================
+void InitCr(void){
+ NextCreatureID = 0x40000000;
+ FirstFreeCreature = 0;
+ FirstChainCreature = new matrix<uint32>(
+ SectorXMin * 2, SectorXMax * 2 + 1,
+ SectorYMin * 2, SectorYMax * 2 + 1,
+ 0);
+ LoadRaces();
+ LoadMonsterRaids();
+ InitCrskill();
+ InitPlayer();
+ InitNonplayer();
+ InitKillStatistics();
+}
+
+void ExitCr(void){
+ ExitKillStatistics();
+ ExitPlayer();
+ ExitNonplayer();
+ ExitCrskill();
+
+ delete FirstChainCreature;
+}
diff --git a/src/crskill.cc b/src/crskill.cc
index d2eb067..8e259a8 100644
--- a/src/crskill.cc
+++ b/src/crskill.cc
@@ -1159,7 +1159,7 @@ bool TSkillBase::NewSkill(uint16 SkillNo, TCreature *Creature){
}
bool TSkillBase::SetSkills(int Race){
- if(Race < 0 || Race >= NARRAY(RaceData)){
+ if(!IsRaceValid(Race)){
error("TSkillBase::SetSkills: Ungültige Rassennummer %d.\n", Race);
return false;
}
@@ -1250,3 +1250,13 @@ void TSkillBase::DelTimer(uint16 SkNr){
}
}
}
+
+// Initialization
+//==============================================================================
+void InitCrskill(void){
+ // no-op
+}
+
+void ExitCrskill(void){
+ // no-op
+}
diff --git a/src/magic.cc b/src/magic.cc
index ea1ba73..53ec1da 100644
--- a/src/magic.cc
+++ b/src/magic.cc
@@ -372,8 +372,7 @@ TSummonImpact::TSummonImpact(TCreature *Actor, int Race, int Maximum){
error("TSummonImpact::TSummonImpact: Actor ist NULL.\n");
}
- // TODO(fusion): I think there might be a `IsRaceValid` function that was inlined.
- if(Race < 0 || Race >= NARRAY(RaceData)){
+ if(!IsRaceValid(Race)){
error("TSummonImpact::TSummonImpact: Ungültige Rassennummer %d.\n", Race);
}
@@ -387,7 +386,7 @@ void TSummonImpact::handleField(int x, int y, int z){
int Race = this->Race;
int Maximum = this->Maximum;
if(Actor != NULL
- && Race >= 0 && Race < NARRAY(RaceData)
+ && IsRaceValid(Race)
&& Actor->SummonedCreatures < Maximum){
int x, y, z;
if(SearchSummonField(&x, &y, &z, 2)){
@@ -1870,7 +1869,7 @@ void SummonCreature(TCreature *Actor, int ManaPoints, int Race, bool God){
throw ERROR;
}
- if(Race < 1 || Race >= NARRAY(RaceData)){
+ if(!IsRaceValid(Race)){
error("SummonCreature: Ungültige Rassennummer %d übergeben.\n", Race);
throw ERROR;
}
diff --git a/src/map.cc b/src/map.cc
index d3336c3..9ce568d 100644
--- a/src/map.cc
+++ b/src/map.cc
@@ -8,21 +8,21 @@
#include <dirent.h>
-static int OBCount;
-static int SectorXMin;
-static int SectorXMax;
-static int SectorYMin;
-static int SectorYMax;
-static int SectorZMin;
-static int SectorZMax;
-static int RefreshedCylinders;
-static int NewbieStartPositionX;
-static int NewbieStartPositionY;
-static int NewbieStartPositionZ;
-static int VeteranStartPositionX;
-static int VeteranStartPositionY;
-static int VeteranStartPositionZ;
+int SectorXMin;
+int SectorXMax;
+int SectorYMin;
+int SectorYMax;
+int SectorZMin;
+int SectorZMax;
+int RefreshedCylinders;
+int NewbieStartPositionX;
+int NewbieStartPositionY;
+int NewbieStartPositionZ;
+int VeteranStartPositionX;
+int VeteranStartPositionY;
+int VeteranStartPositionZ;
+static int OBCount;
static matrix3d<TSector*> *Sector;
static TObjectBlock **ObjectBlock;
static TObject *FirstFreeObject;
diff --git a/src/map.hh b/src/map.hh
index eafcb1a..e1a9e22 100644
--- a/src/map.hh
+++ b/src/map.hh
@@ -97,6 +97,21 @@ struct TCronEntry {
int Next;
};
+// NOTE(fusion): Map config values.
+extern int SectorXMin;
+extern int SectorXMax;
+extern int SectorYMin;
+extern int SectorYMax;
+extern int SectorZMin;
+extern int SectorZMax;
+extern int RefreshedCylinders;
+extern int NewbieStartPositionX;
+extern int NewbieStartPositionY;
+extern int NewbieStartPositionZ;
+extern int VeteranStartPositionX;
+extern int VeteranStartPositionY;
+extern int VeteranStartPositionZ;
+
// NOTE(fusion): Cron management functions. Most for internal use.
Object CronCheck(void);
void CronExpire(Object Obj, int Delay);
diff --git a/src/stubs.hh b/src/stubs.hh
index 030f502..fa7f0d2 100644
--- a/src/stubs.hh
+++ b/src/stubs.hh
@@ -18,6 +18,7 @@ extern void AbortWriter(void);
extern void AnnounceChangedCreature(uint32 CreatureID, int Type);
extern void BroadcastMessage(int Mode, const char *Text, ...) ATTR_PRINTF(2, 3);
extern void Change(Object Obj, ObjectType NewType, uint32 Value);
+extern void ChangeNPCState(TCreature *Npc, int NewState, bool Stimulus);
extern void CharacterDeathOrder(TCreature *Creature, int OldLevel,
uint32 Offender, const char *Remark, bool Unjustified);
extern bool CheckRight(uint32 CreatureID, RIGHT Right);
@@ -33,11 +34,11 @@ extern void CreatePool(Object Con, ObjectType Type, uint32 Value);
extern void Delete(Object Obj, int Count);
extern bool FieldPossible(int x, int y, int z, int FieldType);
extern Object GetBodyObject(uint32 CreatureID, int Position);
-extern TCreature *GetCreature(uint32 CreatureID);
-extern TCreature *GetCreature(Object Obj);
+extern void GetExitPosition(uint16 HouseID, int *x, int *y, int *z);
extern TConnection *GetFirstConnection(void);
extern TConnection *GetNextConnection(void);
extern const char *GetName(Object Obj);
+extern Object GetObject(uint32 CreatureID, int x, int y, int z, int RNum, ObjectType Type);
extern TPlayer *GetPlayer(uint32 CreatureID);
extern bool GetRaceNoConvince(int Race);
extern bool GetRaceNoIllusion(int Race);
@@ -51,25 +52,24 @@ extern void GraphicalEffect(Object Obj, int Type);
extern int IdentifyPlayer(const char *Name, bool ExactMatch, bool IgnoreGamemasters, TPlayer **Player);
extern void InitLog(const char *ProtocolName);
extern void KickGuest(uint16 HouseID, TPlayer *Host, TPlayer *Guest);
+extern bool LagDetected(void);
extern void LoadMonsterRaid(const char *FileName, int Start,
bool *Type, int *Date, int *Interval, int *Duration);
extern void Log(const char *ProtocolName, const char *Text, ...) ATTR_PRINTF(2, 3);
extern void LogoutAllPlayers(void);
extern void Missile(Object Start, Object Dest, int Type);
extern void Move(uint32 CreatureID, Object Obj, Object Con, int Count, bool NoMerge, Object Ignore);
-extern void MoveCreatures(int Delay);
extern void NetLoadCheck(void);
extern void NetLoadSummary(void);
extern void NotifyAllCreatures(Object Obj, int Type, Object OldCon);
extern int ObjectDistance(Object Obj1, Object Obj2);
+extern bool ObjectInRange(uint32 CreatureID, Object Obj, int Range);
extern void ProcessCommunicationControl(void);
extern void ProcessConnections(void);
-extern void ProcessCreatures(void);
extern void ProcessCronSystem(void);
extern void ProcessMonsterhomes(void);
extern void ProcessMonsterRaids(void);
extern void ProcessReaderThreadReplies(TRefreshSectorFunction *RefreshSector, TSendMailsFunction *SendMails);
-extern void ProcessSkills(void);
extern void ProcessWriterThreadReplies(void);
extern void ReceiveData(void);
extern void RefreshCylinders(void);
@@ -77,6 +77,7 @@ 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 SearchLoginField(int *x, int *y, int *z, int Distance, bool Player);
extern bool SearchSummonField(int *x, int *y, int *z, int Distance);
extern void SendAll(void);
extern void SendAmbiente(TConnection *Connection);
@@ -89,6 +90,7 @@ extern void SendPlayerData(TConnection *Connection);
extern void SendPlayerSkills(TConnection *Connection);
extern void SendPlayerState(TConnection *Connection, uint8 State);
extern void SendResult(TConnection *Connection, RESULT r);
+extern void SendSnapback(TConnection *Connection);
extern void ShowGuestList(uint16 HouseID, TPlayer *Player, char *Buffer);
extern void ShowSubownerList(uint16 HouseID, TPlayer *Player, char *Buffer);
extern void ShowNameDoor(Object Door, TPlayer *Player, char *Buffer);