aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--reference/game.c2271
-rw-r--r--src/crcombat.cc388
-rw-r--r--src/crcombat.hh20
-rw-r--r--src/enums.hh16
-rw-r--r--src/magic.cc88
-rw-r--r--src/player.hh3
-rw-r--r--src/stubs.hh1
8 files changed, 455 insertions, 2340 deletions
diff --git a/Makefile b/Makefile
index c2e87d3..2b03278 100644
--- a/Makefile
+++ b/Makefile
@@ -13,9 +13,9 @@ else
CFLAGS += -O2
endif
-HEADERS = $(SRCDIR)/common.hh $(SRCDIR)/config.hh $(SRCDIR)/connection.hh $(SRCDIR)/containers.hh $(SRCDIR)/creature.hh $(SRCDIR)/crcombat.hh $(SRCDIR)/crskill.hh $(SRCDIR)/enums.hh $(SRCDIR)/map.hh $(SRCDIR)/monster.hh $(SRCDIR)/objects.hh $(SRCDIR)/player.hh $(SRCDIR)/script.hh $(SRCDIR)/thread.hh
+HEADERS = $(SRCDIR)/common.hh $(SRCDIR)/config.hh $(SRCDIR)/connection.hh $(SRCDIR)/containers.hh $(SRCDIR)/creature.hh $(SRCDIR)/crcombat.hh $(SRCDIR)/crskill.hh $(SRCDIR)/enums.hh $(SRCDIR)/magic.hh $(SRCDIR)/map.hh $(SRCDIR)/monster.hh $(SRCDIR)/objects.hh $(SRCDIR)/player.hh $(SRCDIR)/script.hh $(SRCDIR)/thread.hh
-$(BUILDDIR)/$(OUTPUTEXE): $(BUILDDIR)/config.obj $(BUILDDIR)/creature.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/crskill.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/player.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)/creature.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/crskill.obj $(BUILDDIR)/magic.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/player.obj $(BUILDDIR)/script.obj $(BUILDDIR)/shm.obj $(BUILDDIR)/strings.obj $(BUILDDIR)/thread.obj $(BUILDDIR)/time.obj $(BUILDDIR)/util.obj
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
$(BUILDDIR)/config.obj: $(SRCDIR)/config.cc $(HEADERS)
@@ -34,6 +34,10 @@ $(BUILDDIR)/crskill.obj: $(SRCDIR)/crskill.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
+$(BUILDDIR)/magic.obj: $(SRCDIR)/magic.cc $(HEADERS)
+ @mkdir -p $(@D)
+ $(CC) -c $(CFLAGS) -o $@ $<
+
$(BUILDDIR)/main.obj: $(SRCDIR)/main.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
diff --git a/reference/game.c b/reference/game.c
index 55287d4..b5b2520 100644
--- a/reference/game.c
+++ b/reference/game.c
@@ -39021,130 +39021,6 @@ void ExitKillStatistics(void)
return;
}
-
-
-// DWARF original prototype: void TCreature(TCreature * this)
-
-void __thiscall TCreature::TCreature(TCreature *this)
-
-{
- int i;
- int iVar1;
-
- TSkillBase::TSkillBase(&this->super_TSkillBase);
- this->_vptr_TCreature = (_func_int_varargs **)&PTR__TCreature_08127be8;
- // try { // try from 0809ef0c to 0809ef41 has its CatchHandler @ 0809f0a0
- TCombat::TCombat(&this->Combat);
- (this->CrObject).ObjectID = 0;
- vector<TToDoEntry>::vector(&this->ToDoList,0,0x14,10);
- this->LoggingOut = false;
- this->Connection = (TConnection *)0x0;
- this->ID = 0;
- this->NextChainCreature = 0;
- this->EarliestLogoutRound = 0;
- this->NextHashEntry = (TCreature *)0x0;
- this->EarliestProtectionZoneRound = 0;
- this->EarliestYellRound = 0;
- this->EarliestTradeChannelRound = 0;
- this->EarliestSpellTime = 0;
- this->EarliestMultiuseTime = 0;
- this->EarliestWalkTime = 0;
- this->LifeEndRound = 0;
- this->ActToDo = 0;
- this->NrToDo = 0;
- this->NextWakeup = 0;
- this->starty = 0;
- this->posx = 0;
- this->posy = 0;
- this->posz = 0;
- this->Radius = 0x7fffffff;
- this->startz = 0;
- iVar1 = 0;
- this->LogoutAllowed = false;
- this->Stop = false;
- this->LockToDo = false;
- this->Direction = 0;
- this->startx = 0;
- this->IsDead = false;
- this->LoseInventory = 2;
- (this->Combat).Master = this;
- do {
- // try { // try from 0809f041 to 0809f045 has its CatchHandler @ 0809f088
- TSkillBase::NewSkill(&this->super_TSkillBase,(ushort)iVar1,this);
- iVar1 = iVar1 + 1;
- } while (iVar1 < 0x19);
- this->Murderer[0] = '\0';
- this->FireDamageOrigin = 0;
- this->FirstKnowingConnection = (TKnownCreature *)0x0;
- this->SummonedCreatures = 0;
- this->PoisonDamageOrigin = 0;
- this->EnergyDamageOrigin = 0;
- return;
-}
-
-
-
-// DWARF original prototype: void TCreature(TCreature * this)
-
-void __thiscall TCreature::TCreature(TCreature *this)
-
-{
- int i;
- int iVar1;
-
- TSkillBase::TSkillBase(&this->super_TSkillBase);
- this->_vptr_TCreature = (_func_int_varargs **)&PTR__TCreature_08127be8;
- // try { // try from 0809f0ec to 0809f121 has its CatchHandler @ 0809f280
- TCombat::TCombat(&this->Combat);
- (this->CrObject).ObjectID = 0;
- vector<TToDoEntry>::vector(&this->ToDoList,0,0x14,10);
- this->LoggingOut = false;
- this->ID = 0;
- this->Connection = (TConnection *)0x0;
- this->NextHashEntry = (TCreature *)0x0;
- this->NextChainCreature = 0;
- this->EarliestLogoutRound = 0;
- this->EarliestTradeChannelRound = 0;
- this->EarliestYellRound = 0;
- this->EarliestSpellTime = 0;
- this->EarliestWalkTime = 0;
- this->EarliestMultiuseTime = 0;
- this->LifeEndRound = 0;
- this->NrToDo = 0;
- this->EarliestProtectionZoneRound = 0;
- this->ActToDo = 0;
- this->posx = 0;
- this->posy = 0;
- this->NextWakeup = 0;
- this->posz = 0;
- this->Direction = 0;
- this->startx = 0;
- this->Radius = 0x7fffffff;
- iVar1 = 0;
- this->LogoutAllowed = false;
- this->Stop = false;
- this->LockToDo = false;
- this->starty = 0;
- this->startz = 0;
- this->IsDead = false;
- this->LoseInventory = 2;
- (this->Combat).Master = this;
- do {
- // try { // try from 0809f221 to 0809f225 has its CatchHandler @ 0809f268
- TSkillBase::NewSkill(&this->super_TSkillBase,(ushort)iVar1,this);
- iVar1 = iVar1 + 1;
- } while (iVar1 < 0x19);
- this->Murderer[0] = '\0';
- this->FirstKnowingConnection = (TKnownCreature *)0x0;
- this->SummonedCreatures = 0;
- this->FireDamageOrigin = 0;
- this->PoisonDamageOrigin = 0;
- this->EnergyDamageOrigin = 0;
- return;
-}
-
-
-
// DWARF original prototype: void ~TCreature(TCreature * this, int __in_chrg)
void __thiscall TCreature::~TCreature(TCreature *this,int __in_chrg)
@@ -47358,75 +47234,6 @@ LAB_080ad830:
}
-
-// DWARF original prototype: uchar GetRealProfession(TPlayer * this)
-
-uchar __thiscall TPlayer::GetRealProfession(TPlayer *this)
-
-{
- return (this->super_TCreature).Profession;
-}
-
-
-
-// DWARF original prototype: uchar GetEffectiveProfession(TPlayer * this)
-
-uchar __thiscall TPlayer::GetEffectiveProfession(TPlayer *this)
-
-{
- byte bVar1;
-
- bVar1 = (this->super_TCreature).Profession;
- if (9 < bVar1) {
- bVar1 = bVar1 - 10;
- }
- return bVar1;
-}
-
-
-
-// DWARF original prototype: uchar GetActiveProfession(TPlayer * this)
-
-uchar __thiscall TPlayer::GetActiveProfession(TPlayer *this)
-
-{
- bool bVar1;
- byte bVar2;
-
- bVar1 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (bVar1) {
- bVar2 = (this->super_TCreature).Profession;
- }
- else {
- bVar2 = (this->super_TCreature).Profession;
- if (9 < bVar2) {
- bVar2 = bVar2 - 10;
- }
- }
- return bVar2;
-}
-
-
-
-// DWARF original prototype: bool GetActivePromotion(TPlayer * this)
-
-bool __thiscall TPlayer::GetActivePromotion(TPlayer *this)
-
-{
- bool bVar1;
-
- bVar1 = CheckRight((this->super_TCreature).ID,PREMIUM_ACCOUNT);
- if (bVar1) {
- bVar1 = 9 < (this->super_TCreature).Profession;
- }
- else {
- bVar1 = false;
- }
- return bVar1;
-}
-
-
-
// DWARF original prototype: bool SpellKnown(TPlayer * this, int SpellNumber)
bool __thiscall TPlayer::SpellKnown(TPlayer *this,int SpellNumber)
@@ -58419,20 +58226,6 @@ void __thiscall TCreature::Turn(TCreature *this,Object *Obj)
__cxa_throw(puVar2,&RESULT::typeinfo,0);
}
-
-
-// DWARF original prototype: void Attack(TCreature * this)
-
-void __thiscall TCreature::Attack(TCreature *this)
-
-{
- // try { // try from 080c0a51 to 080c0a55 has its CatchHandler @ 080c0a60
- TCombat::Attack(&this->Combat);
- return;
-}
-
-
-
// DWARF original prototype: void NotifyGo(TCreature * this)
void __thiscall TCreature::NotifyGo(TCreature *this)
@@ -60111,2069 +59904,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
return;
}
-
-
-// DWARF original prototype: void TCombat(TCombat * this)
-
-void __thiscall TCombat::TCombat(TCombat *this)
-
-{
- int iVar1;
- TCombatEntry *pTVar2;
-
- (this->Shield).ObjectID = 0;
- (this->Close).ObjectID = 0;
- (this->Missile).ObjectID = 0;
- (this->Throw).ObjectID = 0;
- (this->Wand).ObjectID = 0;
- (this->Ammo).ObjectID = 0;
- this->Master = (TCreature *)0x0;
- this->AttackDest = 0;
- this->EarliestAttackTime = 0;
- this->EarliestDefendTime = 0;
- this->LastDefendTime = 0;
- this->LatestAttackTime = 0;
- pTVar2 = this->CombatList;
- for (iVar1 = 0x3c; iVar1 != 0; iVar1 = iVar1 + -1) {
- pTVar2->ID = 0;
- pTVar2 = (TCombatEntry *)&pTVar2->Damage;
- }
- this->ActCombatEntry = 0;
- this->CombatDamage = 0;
- this->LearningPoints = 0;
- (this->Missile).ObjectID = ::NONE.ObjectID;
- (this->Wand).ObjectID = ::NONE.ObjectID;
- (this->Close).ObjectID = ::NONE.ObjectID;
- (this->Shield).ObjectID = ::NONE.ObjectID;
- (this->Throw).ObjectID = ::NONE.ObjectID;
- (this->Ammo).ObjectID = ::NONE.ObjectID;
- this->Fist = false;
- this->AttackMode = '\x02';
- this->ChaseMode = '\0';
- this->SecureMode = '\x01';
- return;
-}
-
-
-
-// DWARF original prototype: void TCombat(TCombat * this)
-
-void __thiscall TCombat::TCombat(TCombat *this)
-
-{
- int iVar1;
- TCombatEntry *pTVar2;
-
- (this->Shield).ObjectID = 0;
- (this->Close).ObjectID = 0;
- (this->Missile).ObjectID = 0;
- (this->Throw).ObjectID = 0;
- (this->Wand).ObjectID = 0;
- (this->Ammo).ObjectID = 0;
- this->Master = (TCreature *)0x0;
- this->AttackDest = 0;
- this->EarliestAttackTime = 0;
- this->EarliestDefendTime = 0;
- this->LastDefendTime = 0;
- this->LatestAttackTime = 0;
- pTVar2 = this->CombatList;
- for (iVar1 = 0x3c; iVar1 != 0; iVar1 = iVar1 + -1) {
- pTVar2->ID = 0;
- pTVar2 = (TCombatEntry *)&pTVar2->Damage;
- }
- this->ActCombatEntry = 0;
- this->CombatDamage = 0;
- this->LearningPoints = 0;
- (this->Missile).ObjectID = ::NONE.ObjectID;
- (this->Wand).ObjectID = ::NONE.ObjectID;
- (this->Close).ObjectID = ::NONE.ObjectID;
- (this->Shield).ObjectID = ::NONE.ObjectID;
- (this->Throw).ObjectID = ::NONE.ObjectID;
- (this->Ammo).ObjectID = ::NONE.ObjectID;
- this->Fist = false;
- this->AttackMode = '\x02';
- this->ChaseMode = '\0';
- this->SecureMode = '\x01';
- return;
-}
-
-
-
-// DWARF original prototype: void CanToDoAttack(TCombat * this)
-
-void __thiscall TCombat::CanToDoAttack(TCombat *this)
-
-{
- char cVar1;
- bool bVar2;
- int Distance;
- TCreature *pTVar3;
- int iVar4;
- TConnection *Connection;
- undefined4 *puVar5;
- byte bVar6;
- int Mode;
- TPlayer *this_00;
- TCreature *pTVar7;
- TCreature *dfd;
- int local_48;
- int x;
- int y;
- int z;
- Object local_2c [7];
-
- if (this->AttackDest == 0) {
- return;
- }
- // try { // try from 080c40e9 to 080c43eb has its CatchHandler @ 080c4403
- pTVar3 = GetCreature(this->AttackDest);
- if (pTVar3 == (TCreature *)0x0) {
-LAB_080c428d:
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- Connection = this->Master->Connection;
-LAB_080c42a6:
- SendClearTarget(Connection);
- }
- }
- else {
- this_00 = (TPlayer *)this->Master;
- if (this_00 == (TPlayer *)0x0) {
- error("TCombat::CanAttack: Kein Master gesetzt!\n");
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0xffffffff;
- goto LAB_080c42c0;
- }
- if (((this_00->super_TCreature).Type != PLAYER) || (pTVar3->Type == PLAYER)) {
-LAB_080c413c:
- if (this->Following == false) {
- cVar1 = '\0';
- if (((((this_00->super_TCreature).Type == PLAYER) && (pTVar3->Type == PLAYER)) &&
- (this->SecureMode == '\x01')) && (WorldType == NORMAL)) {
- bVar2 = TPlayer::IsAttackJustified(this_00,pTVar3->ID);
- if (!bVar2) {
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- SendClearTarget(this->Master->Connection);
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x3a;
- goto LAB_080c42c0;
- }
- cVar1 = this->Following;
- this_00 = (TPlayer *)this->Master;
- }
- if ((cVar1 == '\0') && (WorldType == NON_PVP)) {
- iVar4 = (*(this_00->super_TCreature)._vptr_TCreature[4])(this_00);
- if (((char)iVar4 != '\0') &&
- (iVar4 = (*pTVar3->_vptr_TCreature[4])(pTVar3), (char)iVar4 != '\0')) {
- pTVar7 = this->Master;
- if (pTVar7->Type == PLAYER) {
- bVar2 = CheckRight(pTVar7->ID,ATTACK_EVERYWHERE);
- if (bVar2) goto LAB_080c42e4;
- pTVar7 = this->Master;
- }
- this->AttackDest = 0;
- if (pTVar7->Type == PLAYER) {
- SendClearTarget(pTVar7->Connection);
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x2b;
- goto LAB_080c42c0;
- }
-LAB_080c42e4:
- this_00 = (TPlayer *)this->Master;
- }
- }
- local_2c[0].ObjectID = (pTVar3->CrObject).ObjectID;
- z = (this_00->super_TCreature).CrObject.ObjectID;
- iVar4 = ObjectDistance((Object *)&z,local_2c);
- if (iVar4 < 9) {
- if (this->Following == false) {
- bVar6 = this->ChaseMode;
- }
- else {
- bVar6 = 1;
- }
- if (bVar6 == 1) {
- if (iVar4 < 2) {
- return;
- }
- iVar4 = 3;
- }
- else {
- if (bVar6 < 2) {
- return;
- }
- if (bVar6 != 2) {
- return;
- }
- if (iVar4 < 4) {
- bVar2 = SearchFlightField();
- if (!bVar2) {
- return;
- }
- iVar4 = 0x7fffffff;
- bVar2 = true;
- goto LAB_080c4201;
- }
- if (iVar4 < 5) {
- return;
- }
- iVar4 = iVar4 + -4;
- }
- bVar2 = false;
- y = pTVar3->posz;
- x = pTVar3->posy;
- local_48 = pTVar3->posx;
-LAB_080c4201:
- TCreature::ToDoGo(this->Master,local_48,x,y,bVar2,iVar4);
- return;
- }
- goto LAB_080c428d;
- }
- bVar2 = false;
- if (((pTVar3->Outfit).OutfitID == 0) && ((pTVar3->Outfit).field_1.ObjectType == 0)) {
- bVar2 = true;
- }
- if (!bVar2) goto LAB_080c413c;
- this->AttackDest = 0;
- if ((this_00->super_TCreature).Type == PLAYER) {
- Connection = (this_00->super_TCreature).Connection;
- goto LAB_080c42a6;
- }
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x25;
-LAB_080c42c0:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar5,&RESULT::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: int GetDistance(TCombat * this)
-
-int __thiscall TCombat::GetDistance(TCombat *this)
-
-{
- bool bVar1;
- int range;
- int iVar2;
-
- bVar1 = false;
- iVar2 = 0;
- if (((this->Close).ObjectID != ::NONE.ObjectID) || (this->Fist != false)) {
- bVar1 = true;
- }
- if (bVar1) {
- iVar2 = 1;
- }
- else if ((this->Throw).ObjectID == ::NONE.ObjectID) {
- bVar1 = false;
- if (((this->Missile).ObjectID != ::NONE.ObjectID) ||
- ((this->Wand).ObjectID != ::NONE.ObjectID)) {
- bVar1 = true;
- }
- if (bVar1) {
- iVar2 = 3;
- }
- }
- else {
- iVar2 = 2;
- }
- return iVar2;
-}
-
-
-
-// DWARF original prototype: void Attack(TCombat * this)
-
-void __thiscall TCombat::Attack(TCombat *this)
-
-{
- bool bVar1;
- uchar uVar2;
- TCreature *this_00;
- TConnection *pTVar3;
- int iVar4;
- int iVar5;
- int iVar6;
- undefined4 *puVar7;
- ulong *puVar8;
- int disty;
- TPlayer *pTVar9;
- uint uVar10;
- TCreature *dfd;
- int iVar11;
- int distx;
- int range;
- int distance;
- uint local_40;
- Object local_3c [4];
- Object local_2c [7];
-
- if (this->AttackDest == 0) {
- return;
- }
- if (this->Following != false) {
- return;
- }
- // try { // try from 080c44d3 to 080c495b has its CatchHandler @ 080c4961
- this_00 = GetCreature(this->AttackDest);
- if (this_00 == (TCreature *)0x0) {
-LAB_080c4892:
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- pTVar3 = this->Master->Connection;
-LAB_080c48ab:
- SendClearTarget(pTVar3);
- }
-LAB_080c48b3:
- puVar7 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar7 = 0x25;
- goto LAB_080c4776;
- }
- pTVar9 = (TPlayer *)this->Master;
- if (pTVar9 == (TPlayer *)0x0) {
- error("TCombat::CanAttack: Kein Master gesetzt!\n");
-LAB_080c478e:
- puVar7 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar7 = 0xffffffff;
- goto LAB_080c4776;
- }
- if ((this->LatestAttackTime != 0) && (this->LatestAttackTime < RoundNr)) {
- this->AttackDest = 0;
- if ((pTVar9->super_TCreature).Type != PLAYER) {
- return;
- }
- pTVar3 = (pTVar9->super_TCreature).Connection;
- goto LAB_080c4514;
- }
- if (((pTVar9->super_TCreature).Type == PLAYER) && (this_00->Type != PLAYER)) {
- bVar1 = false;
- if (((this_00->Outfit).OutfitID == 0) && ((this_00->Outfit).field_1.ObjectType == 0)) {
- bVar1 = true;
- }
- if (!bVar1) goto LAB_080c4558;
- this->AttackDest = 0;
- if ((pTVar9->super_TCreature).Type == PLAYER) {
- pTVar3 = (pTVar9->super_TCreature).Connection;
- goto LAB_080c48ab;
- }
- goto LAB_080c48b3;
- }
-LAB_080c4558:
- if (((((pTVar9->super_TCreature).Type == PLAYER) && (this_00->Type == PLAYER)) &&
- (this->SecureMode == '\x01')) && (WorldType == NORMAL)) {
- bVar1 = TPlayer::IsAttackJustified(pTVar9,this_00->ID);
- if (!bVar1) {
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- SendClearTarget(this->Master->Connection);
- }
- puVar7 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar7 = 0x3a;
- goto LAB_080c4776;
- }
- pTVar9 = (TPlayer *)this->Master;
- }
- local_2c[0].ObjectID = (this_00->CrObject).ObjectID;
- local_3c[0].ObjectID = (pTVar9->super_TCreature).CrObject.ObjectID;
- iVar4 = ObjectDistance(local_3c,local_2c);
- iVar5 = GetDistance(this);
- if (8 < iVar4) goto LAB_080c4892;
- pTVar9 = (TPlayer *)this->Master;
- if (((pTVar9->super_TCreature).Type == PLAYER) && (this_00->Type == PLAYER)) {
- uVar2 = TPlayer::GetRealProfession(pTVar9);
- if ((uVar2 != '\0') || (bVar1 = CheckRight(this->Master->ID,ATTACK_EVERYWHERE), bVar1)) {
- pTVar9 = (TPlayer *)this->Master;
- goto LAB_080c45cc;
- }
-LAB_080c4829:
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- SendClearTarget(this->Master->Connection);
- }
- puVar7 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar7 = 0x2b;
- goto LAB_080c4776;
- }
-LAB_080c45cc:
- if ((pTVar9->super_TCreature).Type == PLAYER) {
- bVar1 = CheckRight((pTVar9->super_TCreature).ID,NO_ATTACK);
- if (bVar1) goto LAB_080c4829;
- pTVar9 = (TPlayer *)this->Master;
- }
- iVar11 = (pTVar9->super_TCreature).posz;
- iVar6 = this->Master->posy;
- bVar1 = IsProtectionZone();
- if (!bVar1) {
- iVar11 = this_00->posz;
- iVar6 = this_00->posy;
- bVar1 = IsProtectionZone();
- if (!bVar1) {
- iVar11 = this->Master->posx - this_00->posx;
- iVar6 = -iVar11;
- if (-1 < iVar11) {
- iVar6 = iVar11;
- }
- uVar10 = this->Master->posy - this_00->posy;
- if (0x7fffffff < uVar10) {
- uVar10 = -uVar10;
- }
- TCreature::BlockLogout(this->Master,0x3c,this_00->Type == PLAYER);
- TCreature::BlockLogout(this_00,0x3c,false);
- if (((((TPlayer *)this->Master)->super_TCreature).Type == PLAYER) &&
- (this_00->Type == PLAYER)) {
- TPlayer::RecordAttack((TPlayer *)this->Master,this_00->ID);
- }
- local_40 = ServerMilliseconds + 200;
- puVar8 = &local_40;
- if (ServerMilliseconds + 200 <= this->EarliestAttackTime) {
- puVar8 = &this->EarliestAttackTime;
- }
- this->EarliestAttackTime = *puVar8;
- if (iVar5 == 1) {
- if (1 < iVar4) {
-LAB_080c4764:
- puVar7 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar7 = 0x29;
- goto LAB_080c4776;
- }
- CloseAttack(this,this_00);
- }
- else {
- if ((iVar5 < 1) || (3 < iVar5)) goto LAB_080c478e;
- if ((7 < iVar6) || (5 < (int)uVar10)) goto LAB_080c4764;
- RangeAttack(this,this_00);
- }
- distance = ServerMilliseconds + 2000;
- puVar8 = (ulong *)&distance;
- if (ServerMilliseconds + 2000 <= this->EarliestAttackTime) {
- puVar8 = &this->EarliestAttackTime;
- }
- this->EarliestAttackTime = *puVar8;
- if (this_00->IsDead == false) {
- return;
- }
- this->AttackDest = 0;
- if (this->Master->Type != PLAYER) {
- return;
- }
- pTVar3 = this->Master->Connection;
-LAB_080c4514:
- SendClearTarget(pTVar3);
- return;
- }
- }
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- SendClearTarget(this->Master->Connection);
- }
- puVar7 = (undefined4 *)__cxa_allocate_exception(4,iVar6,iVar11);
- *puVar7 = 0x2f;
-LAB_080c4776:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar7,&RESULT::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void SetAttackDest(TCombat * this, ulong dfd, bool Follow)
-
-void __thiscall TCombat::SetAttackDest(TCombat *this,ulong dfd,bool Follow)
-
-{
- bool bVar1;
- uchar uVar2;
- TCreature *pTVar3;
- int iVar4;
- undefined4 *puVar5;
- TConnection *pTVar6;
- TPlayer *this_00;
- int iVar7;
- TCreature *cr;
- Object OStack_3c;
- bool Follow_local;
- Object local_2c [7];
-
- if ((this->AttackDest == dfd) && (this->Following == Follow)) {
- return;
- }
- if (dfd == 0) {
- pTVar3 = this->Master;
- }
- else {
- pTVar3 = this->Master;
- if (dfd != pTVar3->ID) {
- // try { // try from 080c49be to 080c4e17 has its CatchHandler @ 080c4e52
- pTVar3 = GetCreature(dfd);
- if (pTVar3 == (TCreature *)0x0) {
- this->AttackDest = 0;
- if (this->Master->Type != PLAYER) {
- return;
- }
- pTVar6 = this->Master->Connection;
- goto LAB_080c4e10;
- }
- if (Follow) {
- this_00 = (TPlayer *)this->Master;
- }
- else {
- this_00 = (TPlayer *)this->Master;
- if (((((this_00->super_TCreature).Type == PLAYER) && (pTVar3->Type == PLAYER)) &&
- (this->SecureMode == '\x01')) && (WorldType == NORMAL)) {
- bVar1 = TPlayer::IsAttackJustified(this_00,pTVar3->ID);
- if (!bVar1) {
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- SendClearTarget(this->Master->Connection);
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x3a;
- goto LAB_080c4ba7;
- }
- this_00 = (TPlayer *)this->Master;
- }
- if (!Follow) {
- if ((this_00->super_TCreature).Type == PLAYER) {
- bVar1 = CheckRight((this_00->super_TCreature).ID,ATTACK_EVERYWHERE);
- if (!bVar1) {
- iVar4 = pTVar3->posz;
- iVar7 = pTVar3->posy;
- bVar1 = IsProtectionZone();
- if (!bVar1) {
- iVar4 = this->Master->posz;
- iVar7 = this->Master->posy;
- bVar1 = IsProtectionZone();
- if (!bVar1) goto LAB_080c4cec;
- }
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- SendClearTarget(this->Master->Connection);
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4,iVar7,iVar4);
- *puVar5 = 0x2f;
- goto LAB_080c4ba7;
- }
-LAB_080c4cec:
- this_00 = (TPlayer *)this->Master;
- }
- if (!Follow) {
- if ((this_00->super_TCreature).Type == PLAYER) {
- bVar1 = CheckRight((this_00->super_TCreature).ID,NO_ATTACK);
- if (!bVar1) {
- this_00 = (TPlayer *)this->Master;
- goto LAB_080c4a23;
- }
-LAB_080c4c8f:
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- pTVar6 = this->Master->Connection;
-LAB_080c4bef:
- SendClearTarget(pTVar6);
- }
-LAB_080c4bf7:
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x2b;
- goto LAB_080c4ba7;
- }
-LAB_080c4a23:
- if (!Follow) {
- if (((this_00->super_TCreature).Type == PLAYER) &&
- (pTVar3->Type == PLAYER)) {
- uVar2 = TPlayer::GetRealProfession(this_00);
- if ((uVar2 == '\0') &&
- (bVar1 = CheckRight(this->Master->ID,ATTACK_EVERYWHERE), !bVar1))
- goto LAB_080c4c8f;
- this_00 = (TPlayer *)this->Master;
- }
- if (!Follow) {
- if (WorldType == NON_PVP) {
- iVar4 = (*(this_00->super_TCreature)._vptr_TCreature[4])
- (this_00);
- if (((char)iVar4 == '\0') ||
- (iVar4 = (*pTVar3->_vptr_TCreature[4])(pTVar3),
- (char)iVar4 == '\0')) {
-LAB_080c4c1c:
- this_00 = (TPlayer *)this->Master;
- goto LAB_080c4a57;
- }
- this_00 = (TPlayer *)this->Master;
- if ((this_00->super_TCreature).Type == PLAYER) {
- bVar1 = CheckRight((this_00->super_TCreature).ID,
- ATTACK_EVERYWHERE);
- if (bVar1) goto LAB_080c4c1c;
- this_00 = (TPlayer *)this->Master;
- }
- }
- else {
-LAB_080c4a57:
- if ((Follow) || (pTVar3->Type != NPC)) goto LAB_080c4a6d;
- }
- this->AttackDest = 0;
- if ((this_00->super_TCreature).Type == PLAYER) {
- pTVar6 = (this_00->super_TCreature).Connection;
- goto LAB_080c4bef;
- }
- goto LAB_080c4bf7;
- }
- }
- }
- }
- }
-LAB_080c4a6d:
- if (((this_00->super_TCreature).Type == PLAYER) && (pTVar3->Type != PLAYER)) {
- bVar1 = false;
- if (((pTVar3->Outfit).OutfitID == 0) && ((pTVar3->Outfit).field_1.ObjectType == 0))
- {
- bVar1 = true;
- }
- if (!bVar1) goto LAB_080c4aa8;
- this->AttackDest = 0;
- if ((this_00->super_TCreature).Type == PLAYER) {
- pTVar6 = (this_00->super_TCreature).Connection;
- goto LAB_080c4b8d;
- }
- }
- else {
-LAB_080c4aa8:
- local_2c[0].ObjectID = (pTVar3->CrObject).ObjectID;
- OStack_3c.ObjectID = (this_00->super_TCreature).CrObject.ObjectID;
- iVar4 = ObjectDistance(&stack0xffffffc4,local_2c);
- if (iVar4 < 9) {
- this->AttackDest = dfd;
- this->Following = Follow;
- if (Follow) {
- return;
- }
- (*pTVar3->_vptr_TCreature[10])(pTVar3,this->Master->ID);
- TCreature::BlockLogout(this->Master,0x3c,pTVar3->Type == PLAYER);
- if (((((TPlayer *)this->Master)->super_TCreature).Type == PLAYER) &&
- (pTVar3->Type == PLAYER)) {
- TPlayer::RecordAttack((TPlayer *)this->Master,pTVar3->ID);
- }
- this->LatestAttackTime = 0;
- return;
- }
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- pTVar6 = this->Master->Connection;
-LAB_080c4b8d:
- SendClearTarget(pTVar6);
- }
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x25;
-LAB_080c4ba7:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar5,&RESULT::typeinfo,0);
- }
- }
- this->AttackDest = 0;
- if (pTVar3->Type != PLAYER) {
- return;
- }
- pTVar6 = pTVar3->Connection;
-LAB_080c4e10:
- SendClearTarget(pTVar6);
- return;
-}
-
-
-
-// DWARF original prototype: void SetAttackMode(TCombat * this, uchar b)
-
-void __thiscall TCombat::SetAttackMode(TCombat *this,uchar b)
-
-{
- uint uVar1;
- ulong *puVar2;
- uint local_10;
-
- if ((byte)(b - 1) < 3) {
- if (b != this->AttackMode) {
- local_10 = ServerMilliseconds + 2000;
- puVar2 = &local_10;
- if (ServerMilliseconds + 2000 <= this->EarliestAttackTime) {
- puVar2 = &this->EarliestAttackTime;
- }
- uVar1 = *puVar2;
- this->AttackMode = b;
- this->EarliestAttackTime = uVar1;
- }
- }
- else {
- error(&DAT_081073c0,b);
- }
- return;
-}
-
-
-
-// DWARF original prototype: void SetChaseMode(TCombat * this, uchar b)
-
-void __thiscall TCombat::SetChaseMode(TCombat *this,uchar b)
-
-{
- if (b < 2) {
- this->ChaseMode = b;
- return;
- }
- error(&DAT_08107400);
- return;
-}
-
-
-
-// DWARF original prototype: void SetSecureMode(TCombat * this, uchar b)
-
-void __thiscall TCombat::SetSecureMode(TCombat *this,uchar b)
-
-{
- if (b < 2) {
- this->SecureMode = b;
- return;
- }
- error(&DAT_08107440);
- return;
-}
-
-
-
-// DWARF original prototype: void StopAttack(TCombat * this, int Delay)
-
-void __thiscall TCombat::StopAttack(TCombat *this,int Delay)
-
-{
- if (Delay == 0) {
- this->AttackDest = 0;
- if (this->Master->Type == PLAYER) {
- SendClearTarget(this->Master->Connection);
- return;
- }
- }
- else {
- this->LatestAttackTime = Delay + RoundNr;
- }
- return;
-}
-
-
-
-// DWARF original prototype: void DelayAttack(TCombat * this, int Milliseconds)
-
-void __thiscall TCombat::DelayAttack(TCombat *this,int Milliseconds)
-
-{
- ulong *puVar1;
- uint local_c;
-
- local_c = ServerMilliseconds + Milliseconds;
- puVar1 = &local_c;
- if (ServerMilliseconds + Milliseconds <= this->EarliestAttackTime) {
- puVar1 = &this->EarliestAttackTime;
- }
- this->EarliestAttackTime = *puVar1;
- return;
-}
-
-
-
-// DWARF original prototype: void CheckCombatValues(TCombat * this)
-
-void __thiscall TCombat::CheckCombatValues(TCombat *this)
-
-{
- bool bVar1;
- ulong uVar2;
- ulong uVar3;
- ulong uVar4;
- ulong uVar5;
- ulong uVar6;
- bool bVar7;
- ulong *puVar8;
- uint uStack_e0;
- bool OldFist;
- ulong local_dc;
- ulong local_cc;
- ulong local_bc;
- ulong local_ac;
- ulong local_9c;
- ulong local_8c;
- ulong local_7c;
- ulong local_6c;
- Object OldAmmo;
- Object OldThrow;
- Object OldShield;
- Object OldClose;
- Object OldWand;
- Object OldMissile;
-
- uVar2 = (this->Missile).ObjectID;
- uVar3 = (this->Wand).ObjectID;
- uVar4 = (this->Close).ObjectID;
- uVar5 = (this->Shield).ObjectID;
- uVar6 = (this->Throw).ObjectID;
- local_6c = (this->Ammo).ObjectID;
- bVar1 = this->Fist;
- GetWeapon(this);
- GetAmmo(this);
- local_7c = (this->Missile).ObjectID;
- bVar7 = false;
- local_8c = local_7c;
- if (uVar2 == local_7c) {
- local_8c = (this->Wand).ObjectID;
- local_9c = local_8c;
- if (uVar3 == local_8c) {
- local_9c = (this->Close).ObjectID;
- local_ac = local_9c;
- if (uVar4 == local_9c) {
- local_ac = (this->Shield).ObjectID;
- local_bc = local_ac;
- if (uVar5 == local_ac) {
- local_bc = (this->Throw).ObjectID;
- local_cc = local_bc;
- if (uVar6 == local_bc) {
- local_cc = (this->Ammo).ObjectID;
- local_dc = local_cc;
- if ((local_6c == local_cc) && (bVar1 == this->Fist)) goto LAB_080c5092;
- }
- }
- }
- }
- }
- bVar7 = true;
-LAB_080c5092:
- if (bVar7) {
- uStack_e0 = ServerMilliseconds + 2000;
- puVar8 = &stack0xffffff20;
- if (ServerMilliseconds + 2000 <= this->EarliestAttackTime) {
- puVar8 = &this->EarliestAttackTime;
- }
- this->EarliestAttackTime = *puVar8;
- }
- return;
-}
-
-
-
-// DWARF original prototype: ushort GetArmorStrength(TCombat * this)
-
-ushort __thiscall TCombat::GetArmorStrength(TCombat *this)
-
-{
- bool bVar1;
- uint uVar2;
- int iVar3;
- ulong uVar4;
- int i;
- ulong uVar5;
- uint local_40;
- ushort Value;
- Object local_2c;
- Object Obj;
-
- uVar5 = 1;
- local_40 = 0;
- do {
- GetBodyObject((ulong)&local_2c,this->Master->ID);
- bVar1 = Object::exists(&local_2c);
- if (bVar1) {
- Object::getObjectType((Object *)&Value);
- bVar1 = ObjectType::getFlag((ObjectType *)&Value,CLOTHES);
- if (bVar1) {
- Object::getObjectType((Object *)&Value);
- uVar4 = ObjectType::getAttribute((ObjectType *)&Value,BODYPOSITION);
- if (uVar4 == uVar5) {
- Object::getObjectType((Object *)&Value);
- bVar1 = ObjectType::getFlag((ObjectType *)&Value,ARMOR);
- if (bVar1) {
- Object::getObjectType((Object *)&Value);
- uVar4 = ObjectType::getAttribute((ObjectType *)&Value,ARMORVALUE);
- local_40 = uVar4 + local_40 & 0xffff;
- }
- }
- }
- }
- uVar5 = uVar5 + 1;
- } while ((int)uVar5 < 0xb);
- uVar2 = (ushort)RaceData[this->Master->Race].Armor + local_40;
- local_40 = uVar2 & 0xffff;
- if (1 < (ushort)uVar2) {
- iVar3 = rand();
- local_40 = (local_40 >> 1) + iVar3 % (int)(local_40 >> 1) & 0xffff;
- }
- return (ushort)local_40;
-}
-
-
-
-// DWARF original prototype: void AddDamageToCombatList(TCombat * this, ulong atk, ushort Damage)
-
-void __thiscall TCombat::AddDamageToCombatList(TCombat *this,ulong atk,ushort Damage)
-
-{
- ulong *puVar1;
- ulong uVar2;
- TCombat *pTVar3;
- int iVar4;
- int i;
- int iVar5;
- uint uVar6;
-
- uVar2 = RoundNr;
- iVar5 = 0;
- uVar6 = (uint)Damage;
- this->CombatDamage = this->CombatDamage + uVar6;
- pTVar3 = this;
- do {
- if (pTVar3->CombatList[0].ID == atk) {
- puVar1 = &pTVar3->CombatList[0].Damage;
- *puVar1 = *puVar1 + uVar6;
- pTVar3->CombatList[0].TimeStamp = uVar2;
- return;
- }
- iVar5 = iVar5 + 1;
- pTVar3 = (TCombat *)&pTVar3->LastDefendTime;
- } while (iVar5 < 0x14);
- this->CombatList[this->ActCombatEntry].ID = atk;
- this->CombatList[this->ActCombatEntry].Damage = uVar6;
- this->CombatList[this->ActCombatEntry].TimeStamp = RoundNr;
- iVar4 = this->ActCombatEntry + 1;
- iVar5 = 0;
- if (iVar4 != 0x14) {
- iVar5 = iVar4;
- }
- this->ActCombatEntry = iVar5;
- return;
-}
-
-
-
-// DWARF original prototype: void DistributeExperiencePoints(TCombat * this, ulong Exp)
-
-void __thiscall TCombat::DistributeExperiencePoints(TCombat *this,ulong Exp)
-
-{
- TSkill *pTVar1;
- bool bVar2;
- TPlayer *this_00;
- uint uVar3;
- int iVar4;
- uint uVar5;
- char *pcVar6;
- ulong uVar7;
- ulong uVar8;
- int iVar9;
- int iVar10;
- int LevelMurderer;
- int Rest;
- uint uVar11;
- int Amount;
- TCombat *pTVar12;
- TCreature *cr;
- char *pcVar13;
- char *pcVar14;
- int Interval;
- int LevelVictim;
- int local_30;
- int i;
-
- pcVar13 = "%s ist gestorben. Verteile %ld EXP...\n";
- pcVar14 = this->Master->Name;
- uVar11 = Exp;
- print();
- if (this->CombatDamage != 0) {
- local_30 = 0x13;
- pTVar12 = this;
- do {
- this_00 = (TPlayer *)GetCreature(pTVar12->CombatList[0].ID);
- if ((this_00 != (TPlayer *)0x0) && ((this_00->super_TCreature).IsDead == false)) {
- uVar3 = (Exp * pTVar12->CombatList[0].Damage) / this->CombatDamage;
- if (((((TPlayer *)this->Master)->super_TCreature).Type == PLAYER) &&
- ((this_00->super_TCreature).Type == PLAYER)) {
- pcVar13 = (char *)0x1;
- uVar7 = TPlayer::GetPartyLeader((TPlayer *)this->Master,true);
- if (uVar7 != 0) {
- uVar7 = TPlayer::GetPartyLeader((TPlayer *)this->Master,true);
- pcVar13 = (char *)0x1;
- uVar8 = TPlayer::GetPartyLeader(this_00,true);
- if (uVar7 == uVar8) goto LAB_080c536f;
- }
- iVar9 = TSkill::Get((this->Master->super_TSkillBase).Skills[0]);
- iVar10 = TSkill::Get((this_00->super_TCreature).super_TSkillBase.Skills[0]);
- iVar4 = (iVar9 * 0xb) / 10;
- if (iVar4 <= iVar10) goto LAB_080c536f;
- pcVar13 = &DAT_08107558;
- pcVar14 = (this_00->super_TCreature).Name;
- uVar3 = (int)((iVar4 - iVar10) * uVar3) / iVar9;
- uVar11 = uVar3;
- print();
- }
- if (uVar3 != 0) {
- pcVar6 = pcVar14;
- if ((this_00->super_TCreature).Type == PLAYER) {
- iVar4 = TSkill::Get((this_00->super_TCreature).super_TSkillBase.Skills[0]);
- pcVar6 = pcVar14;
- if (iVar4 <= (int)uVar3) {
- bVar2 = TPlayer::GetActivePromotion(this_00);
- uVar5 = 0x78;
- if (bVar2) {
- uVar5 = 0xf;
- }
- pcVar6 = (char *)(0xf0 / (ulonglong)(longlong)(int)uVar5);
- pTVar1 = (this_00->super_TCreature).super_TSkillBase.Skills[0x16];
- iVar4 = (*pTVar1->_vptr_TSkill[0xd])(pTVar1,pcVar13,pcVar14,uVar11);
- uVar11 = iVar4 % (int)uVar5;
- if (iVar4 % (int)uVar5 == 0) {
- uVar11 = uVar5;
- }
- TSkillBase::SetTimer(&(this_00->super_TCreature).super_TSkillBase);
- }
- }
- (*(this_00->super_TCreature).super_TSkillBase.Skills[0]->_vptr_TSkill[3])
- ((this_00->super_TCreature).super_TSkillBase.Skills[0],uVar3,pcVar6,
- uVar11);
- pcVar13 = (char *)0xd7;
- pcVar14 = "%d";
- TextualEffect();
- uVar11 = uVar3;
- }
- }
-LAB_080c536f:
- pTVar12 = (TCombat *)&pTVar12->LastDefendTime;
- local_30 = local_30 + -1;
- } while (-1 < local_30);
- }
- return;
-}
-
-
-
-// DWARF original prototype: ulong GetDamageByCreature(TCombat * this, ulong CreatureID)
-
-ulong __thiscall TCombat::GetDamageByCreature(TCombat *this,ulong CreatureID)
-
-{
- int i;
- int iVar1;
-
- iVar1 = 0;
- do {
- if (this->CombatList[0].ID == CreatureID) {
- return this->CombatList[0].Damage;
- }
- iVar1 = iVar1 + 1;
- this = (TCombat *)&this->LastDefendTime;
- } while (iVar1 < 0x14);
- return 0;
-}
-
-
-
-// DWARF original prototype: ulong GetMostDangerousAttacker(TCombat * this)
-
-ulong __thiscall TCombat::GetMostDangerousAttacker(TCombat *this)
-
-{
- uint uVar1;
- int i;
- int iVar2;
- int Limitation;
- ulong MaximumDamage;
- uint uVar3;
- ulong Attacker;
- ulong uVar4;
-
- iVar2 = 0x13;
- uVar4 = 0;
- uVar3 = 0;
- do {
- if (((int)(RoundNr - 0x3c) < this->CombatList[0].TimeStamp) &&
- (uVar1 = this->CombatList[0].Damage, uVar3 < uVar1)) {
- uVar4 = this->CombatList[0].ID;
- uVar3 = uVar1;
- }
- this = (TCombat *)&this->LastDefendTime;
- iVar2 = iVar2 + -1;
- } while (-1 < iVar2);
- return uVar4;
-}
-
-
-
-// DWARF original prototype: int TypeToSkill(TCombat * this, int type)
-
-int __thiscall TCombat::TypeToSkill(TCombat *this,int type)
-
-{
- int iVar1;
-
- iVar1 = 0xb;
- switch(type) {
- case 0:
- iVar1 = 0xb;
- break;
- case 1:
- iVar1 = 8;
- break;
- case 2:
- iVar1 = 9;
- break;
- case 3:
- iVar1 = 10;
- break;
- case 4:
- iVar1 = 6;
- break;
- case 5:
- case 6:
- iVar1 = 7;
- }
- return iVar1;
-}
-
-
-
-// DWARF original prototype: void GetWeapon(TCombat * this)
-
-void __thiscall TCombat::GetWeapon(TCombat *this)
-
-{
- bool bVar1;
- byte bVar2;
- int iVar3;
- ulong uVar4;
- int local_50;
- int Hand;
- Object local_3c;
- Object Obj;
- Object local_2c [7];
-
- (this->Missile).ObjectID = ::NONE.ObjectID;
- (this->Wand).ObjectID = ::NONE.ObjectID;
- (this->Close).ObjectID = ::NONE.ObjectID;
- (this->Shield).ObjectID = ::NONE.ObjectID;
- (this->Throw).ObjectID = ::NONE.ObjectID;
- local_2c[0].ObjectID = ::NONE.ObjectID;
- (this->Ammo).ObjectID = ::NONE.ObjectID;
- this->Fist = true;
- local_3c.ObjectID = (this->Master->CrObject).ObjectID;
- bVar1 = Object::exists(&local_3c);
- if (bVar1) {
- local_50 = 5;
- do {
- GetBodyObject((ulong)&local_3c,this->Master->ID);
- local_2c[0].ObjectID = ::NONE.ObjectID;
- if (local_3c.ObjectID != ::NONE.ObjectID) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,RESTRICTLEVEL);
- if (bVar1) {
- iVar3 = TSkill::Get((this->Master->super_TSkillBase).Skills[0]);
- Object::getObjectType(local_2c);
- uVar4 = ObjectType::getAttribute((ObjectType *)local_2c,MINIMUMLEVEL);
- if (iVar3 < (int)uVar4) goto LAB_080c5626;
- }
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,RESTRICTPROFESSION);
- if ((bVar1) && (this->Master->Type == PLAYER)) {
- Object::getObjectType(local_2c);
- uVar4 = ObjectType::getAttribute((ObjectType *)local_2c,PROFESSIONS);
- bVar2 = TPlayer::GetEffectiveProfession((TPlayer *)this->Master);
- if ((1 << (bVar2 & 0x1f) & uVar4) == 0) goto LAB_080c5626;
- }
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,SHIELD);
- if (bVar1) {
- Hand = local_3c.ObjectID;
- (this->Shield).ObjectID = local_3c.ObjectID;
- local_2c[0].ObjectID = local_3c.ObjectID;
- }
- Object::getObjectType((Object *)&Hand);
- bVar1 = ObjectType::getFlag((ObjectType *)&Hand,BOW);
- if (bVar1) {
- local_2c[0].ObjectID = local_3c.ObjectID;
- (this->Missile).ObjectID = local_3c.ObjectID;
- Hand = local_3c.ObjectID;
- this->Fist = false;
- }
- Object::getObjectType((Object *)&Hand);
- bVar1 = ObjectType::getFlag((ObjectType *)&Hand,WAND);
- if (bVar1) {
- local_2c[0].ObjectID = local_3c.ObjectID;
- (this->Wand).ObjectID = local_3c.ObjectID;
- Hand = local_3c.ObjectID;
- this->Fist = false;
- }
- Object::getObjectType((Object *)&Hand);
- bVar1 = ObjectType::getFlag((ObjectType *)&Hand,THROW);
- if (bVar1) {
- local_2c[0].ObjectID = local_3c.ObjectID;
- (this->Throw).ObjectID = local_3c.ObjectID;
- Hand = local_3c.ObjectID;
- this->Fist = false;
- }
- Object::getObjectType((Object *)&Hand);
- bVar1 = ObjectType::getFlag((ObjectType *)&Hand,WEAPON);
- if (bVar1) {
- Hand = local_3c.ObjectID;
- (this->Close).ObjectID = local_3c.ObjectID;
- this->Fist = false;
- local_2c[0].ObjectID = Hand;
- }
- }
-LAB_080c5626:
- local_50 = local_50 + 1;
- } while (local_50 < 7);
- }
- else {
- error("TCombat::GetWeapon: Kreatur-Objekt existiert nicht.\n");
- }
- return;
-}
-
-
-
-// DWARF original prototype: void GetAmmo(TCombat * this)
-
-void __thiscall TCombat::GetAmmo(TCombat *this)
-
-{
- bool bVar1;
- bool bVar2;
- ulong uVar3;
- ulong uVar4;
- Object local_4c [4];
- Object local_3c [4];
- ulong local_2c;
-
- local_2c = ::NONE.ObjectID;
- local_3c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Missile).ObjectID == ::NONE.ObjectID) {
- uVar3 = (this->Throw).ObjectID;
- if (uVar3 != ::NONE.ObjectID) {
- (this->Ammo).ObjectID = uVar3;
- return;
- }
- uVar3 = (this->Wand).ObjectID;
- if (uVar3 == ::NONE.ObjectID) {
- return;
- }
- (this->Ammo).ObjectID = uVar3;
- return;
- }
- GetBodyObject((ulong)local_4c,this->Master->ID);
- (this->Ammo).ObjectID = local_4c[0].ObjectID;
- bVar1 = false;
- local_4c[0].ObjectID = ::NONE.ObjectID;
- local_3c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Ammo).ObjectID != ::NONE.ObjectID) {
- Object::getObjectType(local_3c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_3c,AMMO);
- if (bVar2) {
- Object::getObjectType(local_3c);
- uVar3 = ObjectType::getAttribute((ObjectType *)local_3c,AMMOTYPE);
- Object::getObjectType(local_3c);
- uVar4 = ObjectType::getAttribute((ObjectType *)local_3c,BOWAMMOTYPE);
- if (uVar3 == uVar4) goto LAB_080c58ea;
- }
- bVar1 = true;
- }
-LAB_080c58ea:
- if (bVar1) {
- (this->Ammo).ObjectID = ::NONE.ObjectID;
- }
- return;
-}
-
-
-
-// DWARF original prototype: void CloseAttack(TCombat * this, TCreature * dfd)
-
-void __thiscall TCombat::CloseAttack(TCombat *this,TCreature *dfd)
-
-{
- TSkill *pTVar1;
- bool bVar2;
- bool bVar3;
- short sVar4;
- int Poison;
- int iVar5;
- int iVar6;
- long Damage_00;
- ulong uVar7;
- int Damage;
- int Attack;
- int iVar8;
- int Defend;
- Object local_4c [4];
- ulong local_3c;
- ushort local_20;
- short local_1e;
- ushort Type;
- short Value;
-
- // try { // try from 080c59a6 to 080c5bf2 has its CatchHandler @ 080c5c88
- GetAttackValue(this);
- pTVar1 = (this->Master->super_TSkillBase).Skills[local_20];
- if (this->AttackMode == '\x01') {
- local_1e = (short)((local_1e * 2) / 10) + local_1e;
- }
- else if (this->AttackMode == '\x03') {
- local_1e = local_1e - (short)((local_1e * 4) / 10);
- }
- iVar5 = (*pTVar1->_vptr_TSkill[8])(pTVar1,(int)local_1e,(uint)(0 < this->LearningPoints));
- local_1e = (short)iVar5;
- if (0 < this->LearningPoints) {
- this->LearningPoints = this->LearningPoints + -1;
- }
- iVar8 = (int)local_1e;
- sVar4 = GetDefendDamage(&dfd->Combat);
- iVar5 = iVar8 - sVar4;
- if (iVar5 < 0) {
- iVar5 = 0;
- }
- iVar5 = TCreature::Damage(dfd,this->Master,iVar5,1);
- if (0 < iVar5) {
- this->LearningPoints = 0x1e;
- }
- iVar6 = GetRacePoison(this->Master->Race);
- if ((iVar6 != 0) &&
- ((0 < iVar5 || ((sVar4 < iVar8 && (iVar5 = rand(), iVar5 == (iVar5 / 5) * 5)))))) {
- GetRacePoison(this->Master->Race);
- GetRacePoison(this->Master->Race);
- Damage_00 = random();
- if ((0 < Damage_00) &&
- (TCreature::Damage(dfd,this->Master,Damage_00,0x20), dfd->Type == PLAYER)) {
- SendMessage(dfd->Connection,0x15,"You are poisoned.");
- }
- }
- bVar2 = false;
- local_3c = ::NONE.ObjectID;
- local_4c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Close).ObjectID != ::NONE.ObjectID) {
- Object::getObjectType(local_4c);
- bVar3 = ObjectType::getFlag((ObjectType *)local_4c,WEAROUT);
- if (bVar3) {
- bVar2 = true;
- }
- }
- if (bVar2) {
- uVar7 = Object::getAttribute(&this->Close,REMAININGUSES);
- if (uVar7 < 2) {
- Object::getObjectType((Object *)&Defend);
- uVar7 = ObjectType::getAttribute((ObjectType *)&Defend,WEAROUTTARGET);
- ObjectType::setTypeID((ObjectType *)local_4c,uVar7);
- Defend = (this->Close).ObjectID;
- Change((Object *)&Defend,(ObjectType *)local_4c,0);
- CheckCombatValues(this);
- }
- else {
- uVar7 = Object::getAttribute(&this->Close,REMAININGUSES);
- local_4c[0].ObjectID = (this->Close).ObjectID;
- Change(local_4c,REMAININGUSES,uVar7 - 1);
- }
- }
- return;
-}
-
-
-
-// DWARF original prototype: void RangeAttack(TCombat * this, TCreature * dfd)
-
-void __thiscall TCombat::RangeAttack(TCombat *this,TCreature *dfd)
-
-{
- TSkill *pTVar1;
- Object OVar2;
- bool bVar3;
- bool bVar4;
- int Damage;
- int iVar5;
- ulong uVar6;
- uint uVar7;
- long lVar8;
- undefined4 *puVar9;
- ulong uVar10;
- ulong uVar11;
- int *piVar12;
- RESULT r;
- int Attack;
- Object *this_00;
- TYPEATTRIBUTE Attribute;
- undefined4 uVar13;
- char local_f1;
- ulong uStack_f0;
- bool Hit;
- int EffectStrength;
- int SpecialEffect;
- int Fragility;
- int AnimType;
- int DamageType;
- int DiffLvl;
- int local_d4;
- int local_d0;
- int x;
- int y;
- int z;
- int local_c0;
- int local_bc;
- int local_b8;
- int local_b4;
- int local_b0;
- undefined1 local_ac [4];
- TDamageImpact Impact;
- ushort local_80;
- short local_7e;
- ushort Type;
- short Value;
- Object local_6c [4];
- Object local_5c [4];
- Object local_4c [4];
- ulong local_3c;
- ulong local_2c;
- Object Drop;
-
- local_2c = 0;
- local_3c = ::NONE.ObjectID;
- local_5c[0].ObjectID = (this->Wand).ObjectID;
- if (local_5c[0].ObjectID == ::NONE.ObjectID) {
- local_5c[0].ObjectID = ::NONE.ObjectID;
- local_4c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Missile).ObjectID == ::NONE.ObjectID) {
- _Type = ::NONE.ObjectID;
- this_00 = local_6c;
- local_6c[0].ObjectID = ::NONE.ObjectID;
- uVar6 = (this->Throw).ObjectID;
- if (uVar6 == ::NONE.ObjectID) {
- puVar9 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar9 = 0xffffffff;
- goto LAB_080c66b1;
- }
- DamageType = 0x4b;
- (this->Ammo).ObjectID = uVar6;
- iVar5 = this->Master->posx - dfd->posx;
- local_c0 = -iVar5;
- if (-1 < iVar5) {
- local_c0 = iVar5;
- }
- iVar5 = this->Master->posy - dfd->posy;
- z = -iVar5;
- if (-1 < iVar5) {
- z = iVar5;
- }
- piVar12 = &z;
- if (z <= local_c0) {
- piVar12 = &local_c0;
- }
- local_6c[0].ObjectID = uVar6;
- local_4c[0].ObjectID = uVar6;
- // try { // try from 080c5d84 to 080c5edd has its CatchHandler @ 080c6b00
- Object::getObjectType(this_00);
- uVar6 = ObjectType::getAttribute((ObjectType *)this_00,THROWRANGE);
- if ((int)uVar6 < *piVar12) goto LAB_080c66c9;
- Object::getObjectType(this_00);
- Fragility = ObjectType::getAttribute((ObjectType *)this_00,THROWMISSILE);
- Object::getObjectType(this_00);
- SpecialEffect = ObjectType::getAttribute((ObjectType *)this_00,THROWFRAGILITY);
- Object::getObjectType(this_00);
- EffectStrength = ObjectType::getAttribute((ObjectType *)this_00,THROWSPECIALEFFECT);
- Object::getObjectType(this_00);
- Attribute = THROWEFFECTSTRENGTH;
- }
- else {
- uVar13 = 10;
- DamageType = 0x5a;
- uVar6 = this->Master->ID;
- GetBodyObject((ulong)local_6c,uVar6);
- (this->Ammo).ObjectID = local_6c[0].ObjectID;
- bVar3 = false;
- local_6c[0].ObjectID = ::NONE.ObjectID;
- local_4c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Ammo).ObjectID != ::NONE.ObjectID) {
- Object::getObjectType(local_4c);
- uVar6 = 0x3c;
- bVar4 = ObjectType::getFlag((ObjectType *)local_4c,AMMO);
- if (bVar4) {
- Object::getObjectType(local_4c);
- uVar10 = ObjectType::getAttribute((ObjectType *)local_4c,AMMOTYPE);
- Object::getObjectType(local_4c);
- uVar6 = 0x27;
- uVar11 = ObjectType::getAttribute((ObjectType *)local_4c,BOWAMMOTYPE);
- if (uVar10 == uVar11) goto LAB_080c6742;
- }
- bVar3 = true;
- }
-LAB_080c6742:
- OVar2.ObjectID = ::NONE.ObjectID;
- if (bVar3) {
- _Type = ::NONE.ObjectID;
- (this->Ammo).ObjectID = ::NONE.ObjectID;
- local_4c[0].ObjectID = OVar2.ObjectID;
- }
- bVar3 = Object::exists(&this->Ammo);
- if (!bVar3) {
- puVar9 = (undefined4 *)__cxa_allocate_exception(4,uVar6,uVar13);
- *puVar9 = 0x26;
- goto LAB_080c66b1;
- }
- iVar5 = this->Master->posx - dfd->posx;
- local_b8 = -iVar5;
- if (-1 < iVar5) {
- local_b8 = iVar5;
- }
- iVar5 = this->Master->posy - dfd->posy;
- local_bc = -iVar5;
- if (-1 < iVar5) {
- local_bc = iVar5;
- }
- piVar12 = &local_bc;
- if (local_bc <= local_b8) {
- piVar12 = &local_b8;
- }
- Object::getObjectType((Object *)&Type);
- uVar6 = ObjectType::getAttribute((ObjectType *)&Type,BOWRANGE);
- if ((int)uVar6 < *piVar12) goto LAB_080c66c9;
- Object::getObjectType((Object *)&Type);
- Fragility = ObjectType::getAttribute((ObjectType *)&Type,AMMOMISSILE);
- SpecialEffect = 100;
- Object::getObjectType((Object *)&Type);
- EffectStrength = ObjectType::getAttribute((ObjectType *)&Type,AMMOSPECIALEFFECT);
- Object::getObjectType((Object *)&Type);
- this_00 = (Object *)&Type;
- Attribute = AMMOEFFECTSTRENGTH;
- }
- AnimType = 1;
- uStack_f0 = ObjectType::getAttribute((ObjectType *)this_00,Attribute);
- }
- else {
- DamageType = 0;
- (this->Ammo).ObjectID = local_5c[0].ObjectID;
- iVar5 = this->Master->posx - dfd->posx;
- local_b0 = -iVar5;
- if (-1 < iVar5) {
- local_b0 = iVar5;
- }
- iVar5 = this->Master->posy - dfd->posy;
- local_b4 = -iVar5;
- if (-1 < iVar5) {
- local_b4 = iVar5;
- }
- piVar12 = &local_b4;
- if (local_b4 <= local_b0) {
- piVar12 = &local_b0;
- }
- local_4c[0].ObjectID = local_5c[0].ObjectID;
- Object::getObjectType(local_5c);
- uVar6 = ObjectType::getAttribute((ObjectType *)local_5c,WANDRANGE);
- if ((int)uVar6 < *piVar12) {
-LAB_080c66c9:
- puVar9 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar9 = 0x29;
- goto LAB_080c66b1;
- }
- Object::getObjectType(local_5c);
- AnimType = ObjectType::getAttribute((ObjectType *)local_5c,WANDDAMAGETYPE);
- Object::getObjectType(local_5c);
- Fragility = ObjectType::getAttribute((ObjectType *)local_5c,WANDMISSILE);
- SpecialEffect = 0;
- EffectStrength = 0;
- uStack_f0 = 0;
- }
- _Type = (dfd->CrObject).ObjectID;
- GetObjectCoordinates((Object *)&Type,&local_d0,&x,&y);
- bVar3 = ThrowPossible(this->Master->posx,this->Master->posy,this->Master->posz,local_d0,x,y,0);
- if (!bVar3) {
- puVar9 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar9 = 0x2a;
-LAB_080c66b1:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar9,&RESULT::typeinfo,0);
- }
- _Type = ::NONE.ObjectID;
- local_6c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Wand).ObjectID == ::NONE.ObjectID) {
- iVar5 = this->Master->posx - dfd->posx;
- local_d4 = -iVar5;
- if (-1 < iVar5) {
- local_d4 = iVar5;
- }
- iVar5 = this->Master->posy - dfd->posy;
- DiffLvl = -iVar5;
- if (-1 < iVar5) {
- DiffLvl = iVar5;
- }
- piVar12 = &DiffLvl;
- if (DiffLvl <= local_d4) {
- piVar12 = &local_d4;
- }
- iVar5 = *piVar12;
- if (iVar5 < 2) {
- iVar5 = 5;
- }
- iVar5 = (*(this->Master->super_TSkillBase).Skills[7]->_vptr_TSkill[9])
- ((this->Master->super_TSkillBase).Skills[7],iVar5 * 0xf,DamageType,
- (uint)(0 < this->LearningPoints));
- local_f1 = (char)iVar5;
- if (0 < this->LearningPoints) {
- this->LearningPoints = this->LearningPoints + -1;
- }
- }
- else {
- // try { // try from 080c5f0a to 080c5f42 has its CatchHandler @ 080c6a3c
- Object::getObjectType(local_6c);
- uVar6 = ObjectType::getAttribute((ObjectType *)local_6c,WANDMANACONSUMPTION);
- CheckMana(this->Master,uVar6,0,0);
- local_f1 = '\x01';
- }
- _Type = ::NONE.ObjectID;
- local_6c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Wand).ObjectID == ::NONE.ObjectID) {
- if (local_f1 != '\0') {
- local_4c[0].ObjectID = (dfd->CrObject).ObjectID;
- GetMapContainer(local_5c);
- local_2c = local_5c[0].ObjectID;
- local_6c[0].ObjectID = local_5c[0].ObjectID;
- GetObjectCoordinates(local_6c,&local_d0,&x,&y);
- GetAttackValue(this);
- pTVar1 = (this->Master->super_TSkillBase).Skills[local_80];
- if (this->AttackMode == '\x01') {
- local_7e = (short)((local_7e * 2) / 10) + local_7e;
- }
- else if (this->AttackMode == '\x03') {
- local_7e = local_7e - (short)(((int)local_7e << 2) / 10);
- }
- iVar5 = (*pTVar1->_vptr_TSkill[8])
- (pTVar1,(int)local_7e,(uint)(0 < this->LearningPoints));
- if (0 < this->LearningPoints) {
- this->LearningPoints = this->LearningPoints + -1;
- }
- local_6c[0].ObjectID = ::NONE.ObjectID;
- local_5c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Shield).ObjectID != ::NONE.ObjectID) {
- GetDefendDamage(&dfd->Combat);
- }
- iVar5 = TCreature::Damage(dfd,this->Master,(int)(short)iVar5,AnimType);
- if (0 < iVar5) {
- this->LearningPoints = 0x1e;
- }
- goto LAB_080c60be;
- }
- local_6c[0].ObjectID = (dfd->CrObject).ObjectID;
- // try { // try from 080c5f9b to 080c60ea has its CatchHandler @ 080c6b00
- GetObjectCoordinates(local_6c,&local_d0,&x,&y);
- uVar7 = this->Master->posx - dfd->posx;
- if (0x7fffffff < uVar7) {
- uVar7 = -uVar7;
- }
- if ((int)uVar7 < 2) {
- uVar7 = this->Master->posy - dfd->posy;
- if (0x7fffffff < uVar7) {
- uVar7 = -uVar7;
- }
- if (1 < (int)uVar7) goto LAB_080c5fc4;
- }
- else {
-LAB_080c5fc4:
- iVar5 = rand();
- local_d0 = iVar5 % 3 + local_d0 + -1;
- iVar5 = rand();
- x = iVar5 % 3 + x + -1;
- }
- bVar3 = false;
- bVar4 = CoordinateFlag();
- if (bVar4) {
- bVar3 = CoordinateFlag();
- bVar3 = !bVar3;
- }
- if ((!bVar3) ||
- (bVar3 = ThrowPossible(this->Master->posx,this->Master->posy,this->Master->posz,local_d0,
- x,y,0), !bVar3)) {
- local_d0 = dfd->posx;
- x = dfd->posy;
- y = dfd->posz;
- }
- GetMapContainer((int)local_5c,local_d0,x);
- }
- else {
- Object::getObjectType(local_6c);
- uVar6 = ObjectType::getAttribute((ObjectType *)local_6c,WANDATTACKSTRENGTH);
- Object::getObjectType(local_6c);
- ObjectType::getAttribute((ObjectType *)local_6c,WANDATTACKVARIATION);
- Object::getObjectType(local_6c);
- ObjectType::getAttribute((ObjectType *)local_6c,WANDATTACKVARIATION);
- lVar8 = random();
- iVar5 = TCreature::Damage(dfd,this->Master,lVar8 + uVar6,AnimType);
- if (0 < iVar5) {
- this->LearningPoints = 0x1e;
- }
- local_4c[0].ObjectID = (dfd->CrObject).ObjectID;
- GetMapContainer(local_5c);
- }
- local_2c = local_5c[0].ObjectID;
-LAB_080c60be:
- _Type = local_2c;
- local_6c[0].ObjectID = (this->Master->CrObject).ObjectID;
- Missile(local_6c,(Object *)&Type,Fragility);
- if (EffectStrength == 1) {
- if (local_f1 != '\0') {
- TCreature::Damage(dfd,this->Master,uStack_f0,0x20);
- }
- }
- else if (EffectStrength == 2) {
- // try { // try from 080c61e3 to 080c6a18 has its CatchHandler @ 080c6b00
- iVar5 = ComputeDamage(this->Master,0,uStack_f0,uStack_f0);
- TDamageImpact::TDamageImpact((TDamageImpact *)local_ac,this->Master,1,iVar5,false);
- _Type = local_2c;
- GetObjectCoordinates((Object *)&Type,&local_d0,&x,&y);
- CircleShapeSpell(this->Master,local_d0,x,y,0x7fffffff,0,2,(TImpact *)local_ac,7);
- }
- _Type = ::NONE.ObjectID;
- if ((this->Wand).ObjectID == ::NONE.ObjectID) {
- // try { // try from 080c6129 to 080c614e has its CatchHandler @ 080c6aab
- lVar8 = random();
- if (lVar8 < SpecialEffect) {
- local_6c[0].ObjectID = (this->Ammo).ObjectID;
- Delete(local_6c,1);
- }
- else {
- local_6c[0].ObjectID = ::NONE.ObjectID;
- local_5c[0].ObjectID = local_2c;
- local_4c[0].ObjectID = (this->Ammo).ObjectID;
- // try { // try from 080c61c1 to 080c61c5 has its CatchHandler @ 080c6aab
- Move(0,local_4c,local_5c,1,false,local_6c);
- }
- if (local_f1 == '\0') {
- // try { // try from 080c617d to 080c6181 has its CatchHandler @ 080c6b00
- GraphicalEffect();
- }
- }
- return;
-}
-
-
-
-// DWARF original prototype: void GetAttackValue(TCombat * this, short * Value, ushort * Skill)
-
-void __thiscall TCombat::GetAttackValue(TCombat *this)
-
-{
- ulong uVar1;
- undefined2 uVar2;
- Object *this_00;
- ushort Type;
- uint uVar3;
- undefined2 *in_stack_00000008;
- undefined2 *in_stack_0000000c;
- TYPEATTRIBUTE Attribute;
- Object local_6c [4];
- ulong local_5c;
- Object local_4c [4];
- Object local_3c [4];
- ulong local_2c;
-
- this_00 = local_3c;
- *in_stack_00000008 = 0;
- local_2c = ::NONE.ObjectID;
- local_3c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Close).ObjectID == ::NONE.ObjectID) {
- this_00 = local_4c;
- local_4c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Throw).ObjectID != ::NONE.ObjectID) {
- uVar3 = 6;
- Object::getObjectType(this_00);
- Attribute = THROWATTACKVALUE;
- goto LAB_080c6c20;
- }
- if ((this->Wand).ObjectID != ::NONE.ObjectID) {
- uVar3 = 0;
- *in_stack_00000008 = 0;
- goto LAB_080c6b79;
- }
- local_5c = ::NONE.ObjectID;
- this_00 = local_6c;
- local_6c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Missile).ObjectID != ::NONE.ObjectID) {
- Object::getObjectType(this_00);
- Attribute = AMMOATTACKVALUE;
- uVar3 = 5;
- goto LAB_080c6c20;
- }
- uVar3 = 0;
- uVar2 = (undefined2)RaceData[this->Master->Race].Attack;
- }
- else {
- Object::getObjectType(this_00);
- uVar1 = ObjectType::getAttribute((ObjectType *)this_00,WEAPONTYPE);
- uVar3 = uVar1 & 0xffff;
- Object::getObjectType(this_00);
- Attribute = WEAPONATTACKVALUE;
-LAB_080c6c20:
- uVar1 = ObjectType::getAttribute((ObjectType *)this_00,Attribute);
- uVar2 = (undefined2)uVar1;
- }
- *in_stack_00000008 = uVar2;
-LAB_080c6b79:
- uVar2 = 0xb;
- switch(uVar3) {
- case 0:
- uVar2 = 0xb;
- break;
- case 1:
- uVar2 = 8;
- break;
- case 2:
- uVar2 = 9;
- break;
- case 3:
- uVar2 = 10;
- break;
- case 4:
- uVar2 = 6;
- break;
- case 5:
- case 6:
- uVar2 = 7;
- }
- *in_stack_0000000c = uVar2;
- return;
-}
-
-
-
-// DWARF original prototype: void GetDefendValue(TCombat * this, short * Value, ushort * Skill)
-
-void __thiscall TCombat::GetDefendValue(TCombat *this)
-
-{
- ulong uVar1;
- undefined2 uVar2;
- Object *this_00;
- ushort Type;
- uint uVar3;
- undefined2 *in_stack_00000008;
- undefined2 *in_stack_0000000c;
- TYPEATTRIBUTE Attribute;
- Object local_5c [4];
- Object local_4c [4];
- Object local_3c [4];
- ulong local_2c;
-
- this_00 = local_3c;
- *in_stack_00000008 = 0;
- local_2c = ::NONE.ObjectID;
- local_3c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Shield).ObjectID == ::NONE.ObjectID) {
- this_00 = local_4c;
- local_4c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Close).ObjectID != ::NONE.ObjectID) {
- Object::getObjectType(this_00);
- uVar1 = ObjectType::getAttribute((ObjectType *)this_00,WEAPONTYPE);
- uVar3 = uVar1 & 0xffff;
- Object::getObjectType(this_00);
- Attribute = WEAPONDEFENDVALUE;
- goto LAB_080c6d9c;
- }
- this_00 = local_5c;
- local_5c[0].ObjectID = ::NONE.ObjectID;
- if ((this->Throw).ObjectID != ::NONE.ObjectID) {
- uVar3 = 6;
- Object::getObjectType(this_00);
- Attribute = THROWDEFENDVALUE;
- goto LAB_080c6d9c;
- }
- if ((this->Missile).ObjectID != ::NONE.ObjectID) {
- uVar3 = 5;
- *in_stack_00000008 = 0;
- goto LAB_080c6d01;
- }
- uVar3 = 0;
- uVar2 = (undefined2)RaceData[this->Master->Race].Defend;
- }
- else {
- uVar3 = 4;
- Object::getObjectType(this_00);
- Attribute = SHIELDDEFENDVALUE;
-LAB_080c6d9c:
- uVar1 = ObjectType::getAttribute((ObjectType *)this_00,Attribute);
- uVar2 = (undefined2)uVar1;
- }
- *in_stack_00000008 = uVar2;
-LAB_080c6d01:
- uVar2 = 0xb;
- switch(uVar3) {
- case 0:
- uVar2 = 0xb;
- break;
- case 1:
- uVar2 = 8;
- break;
- case 2:
- uVar2 = 9;
- break;
- case 3:
- uVar2 = 10;
- break;
- case 4:
- uVar2 = 6;
- break;
- case 5:
- case 6:
- uVar2 = 7;
- }
- *in_stack_0000000c = uVar2;
- return;
-}
-
-
-
-// WARNING: Variable defined which should be unmapped: Type
-// DWARF original prototype: short GetAttackDamage(TCombat * this)
-
-short __thiscall TCombat::GetAttackDamage(TCombat *this)
-
-{
- TSkill *pTVar1;
- int iVar2;
- TSkill *sk;
- ushort local_14;
- short local_12;
- ushort Type;
- short Value;
-
- GetAttackValue(this);
- pTVar1 = (this->Master->super_TSkillBase).Skills[local_14];
- if (this->AttackMode == '\x01') {
- local_12 = (short)((local_12 * 2) / 10) + local_12;
- }
- else if (this->AttackMode == '\x03') {
- local_12 = local_12 - (short)((local_12 * 4) / 10);
- }
- iVar2 = (*pTVar1->_vptr_TSkill[8])(pTVar1,(int)local_12,(uint)(0 < this->LearningPoints));
- if (0 < this->LearningPoints) {
- this->LearningPoints = this->LearningPoints + -1;
- }
- return (short)iVar2;
-}
-
-
-
-// DWARF original prototype: short GetDefendDamage(TCombat * this)
-
-short __thiscall TCombat::GetDefendDamage(TCombat *this)
-
-{
- Object *this_00;
- TSkill *pTVar1;
- short sVar2;
- uchar Tac;
- uchar uVar3;
- bool bVar4;
- bool bVar5;
- int iVar6;
- ulong uVar7;
- undefined4 uVar8;
- TSkill *sk;
- Object local_5c [4];
- ulong local_4c;
- Object local_3c [7];
- undefined4 local_20;
- ushort Type;
- short Value;
-
- if (ServerMilliseconds < this->EarliestDefendTime) {
- return 0;
- }
- this->EarliestDefendTime = this->LastDefendTime + 2000;
- this->LastDefendTime = ServerMilliseconds;
- GetDefendValue(this);
- pTVar1 = (this->Master->super_TSkillBase).Skills[local_20 & 0xffff];
- if (((this->Following == false) && (this->AttackDest != 0)) ||
- (ServerMilliseconds < this->EarliestAttackTime)) {
- uVar3 = this->AttackMode;
- }
- else {
- uVar3 = '\x03';
- }
- sVar2 = (short)local_20;
- if (uVar3 == '\x01') {
- local_20 = CONCAT22(local_20._2_2_ - (short)(((int)local_20._2_2_ << 2) / 10),
- (short)local_20);
- }
- else if (uVar3 == '\x03') {
- local_20 = CONCAT22((short)(((int)local_20._2_2_ << 3) / 10) + local_20._2_2_,
- (short)local_20);
- }
- if (sVar2 != 0) {
- uVar8 = 0;
- local_3c[0].ObjectID = ::NONE.ObjectID;
- local_4c = ::NONE.ObjectID;
- if (((this->Shield).ObjectID != ::NONE.ObjectID) && (0 < this->LearningPoints)) {
- uVar8 = 1;
- }
- iVar6 = (*pTVar1->_vptr_TSkill[8])(pTVar1,(int)local_20._2_2_,uVar8);
- bVar4 = false;
- local_20 = CONCAT22((short)iVar6,(short)local_20);
- uVar7 = (this->Shield).ObjectID;
- if ((uVar7 != ::NONE.ObjectID) && (0 < this->LearningPoints)) {
- bVar4 = true;
- }
- if (bVar4) {
- this->LearningPoints = this->LearningPoints + -1;
- }
- bVar4 = false;
- this_00 = &this->Shield;
- local_4c = ::NONE.ObjectID;
- local_3c[0].ObjectID = ::NONE.ObjectID;
- if (uVar7 != ::NONE.ObjectID) {
- Object::getObjectType(local_3c);
- bVar5 = ObjectType::getFlag((ObjectType *)local_3c,WEAROUT);
- if (bVar5) {
- bVar4 = true;
- }
- }
- if (bVar4) {
- uVar7 = Object::getAttribute(this_00,REMAININGUSES);
- if (uVar7 < 2) {
- Object::getObjectType(local_5c);
- uVar7 = ObjectType::getAttribute((ObjectType *)local_5c,WEAROUTTARGET);
- ObjectType::setTypeID((ObjectType *)local_3c,uVar7);
- local_5c[0].ObjectID = (this->Shield).ObjectID;
- Change(local_5c,(ObjectType *)local_3c,0);
- bVar4 = Object::exists(this_00);
- if (bVar4) {
- Object::getObjectType(local_5c);
- bVar4 = ObjectType::getFlag((ObjectType *)local_5c,SHIELD);
- if (bVar4) goto LAB_080c7009;
- }
- CheckCombatValues(this);
- }
- else {
- uVar7 = Object::getAttribute(this_00,REMAININGUSES);
- local_3c[0].ObjectID = (this->Shield).ObjectID;
- Change(local_3c,REMAININGUSES,uVar7 - 1);
- }
- }
- }
-LAB_080c7009:
- return local_20._2_2_;
-}
-
-
-
-// DWARF original prototype: void ActivateLearning(TCombat * this)
-
-void __thiscall TCombat::ActivateLearning(TCombat *this)
-
-{
- this->LearningPoints = 0x1e;
- return;
-}
-
-
-
// WARNING: Unknown calling convention -- yet parameter storage is locked
void _GLOBAL__I__ZN7TCombatC2Ev(void)
@@ -85164,4 +82894,3 @@ void _fini(void)
return;
}
-
diff --git a/src/crcombat.cc b/src/crcombat.cc
index 256f056..7ad7534 100644
--- a/src/crcombat.cc
+++ b/src/crcombat.cc
@@ -1,4 +1,5 @@
#include "creature.hh"
+#include "monster.hh"
#include "player.hh"
#include "config.hh"
#include "magic.hh"
@@ -13,7 +14,7 @@ TCombat::TCombat(void){
this->LatestAttackTime = 0;
this->AttackMode = ATTACK_MODE_BALANCED;
this->ChaseMode = CHASE_MODE_NONE;
- this->SecureMode = 1;
+ this->SecureMode = SECURE_MODE_ENABLED;
this->AttackDest = 0;
this->Following = false;
this->Shield = NONE;
@@ -147,6 +148,164 @@ void TCombat::CheckCombatValues(void){
}
}
+static int WeaponTypeToSkill(int WeaponType){
+ int Result = SKILL_FIST;
+ switch(WeaponType){
+ case WEAPON_NONE: Result = SKILL_FIST; break;
+ case WEAPON_SWORD: Result = SKILL_SWORD; break;
+ case WEAPON_CLUB: Result = SKILL_CLUB; break;
+ case WEAPON_AXE: Result = SKILL_AXE; break;
+ case WEAPON_SHIELD: Result = SKILL_SHIELDING; break;
+ case WEAPON_AMMO: ATTR_FALLTHROUGH;
+ case WEAPON_THROW: Result = SKILL_DISTANCE; break;
+ }
+ return Result;
+}
+
+void TCombat::GetAttackValue(int *Value, int *SkillNr){
+ int AttackValue;
+ int WeaponType;
+ if(this->Close != NONE){
+ ObjectType CloseType = this->Close.getObjectType();
+ AttackValue = (int)CloseType.getAttribute(WEAPONATTACKVALUE);
+ WeaponType = (int)CloseType.getAttribute(WEAPONTYPE);
+ }else if(this->Missile != NONE){
+ ObjectType AmmoType = this->Ammo.getObjectType();
+ AttackValue = (int)AmmoType.getAttribute(AMMOATTACKVALUE);
+ WeaponType = WEAPON_AMMO;
+ }else if(this->Throw != NONE){
+ ObjectType ThrowType = this->Throw.getObjectType();
+ AttackValue = (int)ThrowType.getAttribute(THROWATTACKVALUE);
+ WeaponType = WEAPON_THROW;
+ }else if(this->Wand != NONE){
+ AttackValue = 0;
+ WeaponType = WEAPON_NONE;
+ }else{
+ AttackValue = RaceData[this->Master->Race].Attack;
+ WeaponType = WEAPON_NONE;
+ }
+
+ *Value = AttackValue;
+ *SkillNr = WeaponTypeToSkill(WeaponType);
+}
+
+void TCombat::GetDefendValue(int *Value, int *SkillNr){
+ int DefenseValue;
+ int WeaponType;
+ if(this->Shield != NONE){
+ ObjectType ShieldType = this->Shield.getObjectType();
+ DefenseValue = (int)ShieldType.getAttribute(SHIELDDEFENDVALUE);
+ WeaponType = WEAPON_SHIELD;
+ }else if(this->Close != NONE){
+ ObjectType CloseType = this->Close.getObjectType();
+ DefenseValue = (int)CloseType.getAttribute(WEAPONDEFENDVALUE);
+ WeaponType = (int)CloseType.getAttribute(WEAPONTYPE);
+ }else if(this->Throw != NONE){
+ ObjectType ThrowType = this->Throw.getObjectType();
+ DefenseValue = (int)ThrowType.getAttribute(THROWDEFENDVALUE);
+ WeaponType = WEAPON_THROW;
+ }else if(this->Missile != NONE){
+ // TODO(fusion): This might be correct. Having a bow equipped will reduce
+ // your defense to zero but having a wand equipped will give you base defense.
+ DefenseValue = 0;
+ WeaponType = WEAPON_AMMO;
+ }else{
+ DefenseValue = RaceData[this->Master->Race].Defend;
+ WeaponType = WEAPON_NONE;
+ }
+
+ *Value = DefenseValue;
+ *SkillNr = WeaponTypeToSkill(WeaponType);
+}
+
+int TCombat::GetAttackDamage(void){
+ int MaxValue, SkillNr;
+ this->GetAttackValue(&MaxValue, &SkillNr);
+ if(this->AttackMode == ATTACK_MODE_OFFENSIVE){
+ MaxValue += (MaxValue * 2) / 10;
+ }else if(this->AttackMode == ATTACK_MODE_DEFENSIVE){
+ MaxValue -= (MaxValue * 4) / 10;
+ }
+
+ TSkill *Skill = this->Master->Skills[SkillNr];
+ int Result = Skill->ProbeValue(MaxValue, this->LearningPoints > 0);
+ if(this->LearningPoints > 0){
+ this->LearningPoints -= 1;
+ }
+ return Result;
+}
+
+int TCombat::GetDefendDamage(void){
+ if(this->EarliestDefendTime > ServerMilliseconds){
+ return 0;
+ }
+
+ this->EarliestDefendTime = this->LastDefendTime + 2000;
+ this->LastDefendTime = ServerMilliseconds;
+
+ int AttackMode = this->AttackMode;
+ if(this->Following || this->AttackDest == 0){
+ AttackMode = ATTACK_MODE_DEFENSIVE;
+ }
+
+ int MaxValue, SkillNr;
+ this->GetDefendValue(&MaxValue, &SkillNr);
+ if(AttackMode == ATTACK_MODE_OFFENSIVE){
+ MaxValue -= (MaxValue * 4) / 10;
+ }else if(AttackMode == ATTACK_MODE_DEFENSIVE){
+ MaxValue += (MaxValue * 8) / 10;
+ }
+
+ TSkill *Skill = this->Master->Skills[SkillNr];
+ bool Increase = (this->Shield != NONE && this->LearningPoints > 0);
+ int Result = Skill->ProbeValue(MaxValue, Increase);
+ if(Increase){
+ this->LearningPoints -= 1;
+ }
+
+ Object Shield = this->Shield;
+ if(Shield != NONE){
+ ObjectType ShieldType = Shield.getObjectType();
+ if(ShieldType.getFlag(WEAROUT)){
+ uint32 RemainingUses = Shield.getAttribute(REMAININGUSES);
+ if(RemainingUses > 1){
+ Change(Shield, REMAININGUSES, RemainingUses - 1);
+ }else{
+ ObjectType WearOutType = ShieldType.getAttribute(WEAROUTTARGET);
+ Change(Shield, WearOutType, 0);
+ // TODO(fusion): Probably just check anyways, to be sure.
+ if(!Shield.exists() || !WearOutType.getFlag(SHIELD)){
+ this->CheckCombatValues();
+ }
+ }
+ }
+ }
+
+ return Result;
+}
+
+int TCombat::GetArmorStrength(void){
+ // TODO(fusion): We're iterating over inventory slots. Make it clearer?
+ int Armor = 0;
+ TCreature *Master = this->Master;
+ for(int Position = 1; Position <= 10; Position += 1){
+ Object Obj = GetBodyObject(Master->ID, Position);
+ if(Obj.exists()){
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.getFlag(CLOTHES) && ObjType.getFlag(ARMOR)
+ && (int)ObjType.getAttribute(BODYPOSITION) == Position){
+ Armor += (int)ObjType.getAttribute(ARMORVALUE);
+ }
+ }
+ }
+
+ Armor += RaceData[Master->Race].Armor;
+ if(Armor >= 2){
+ Armor = (Armor / 2) + rand() % (Armor / 2);
+ }
+ return Armor;
+}
+
int TCombat::GetDistance(void){
int Distance = 0;
if(this->Close != NONE || this->Fist){
@@ -159,6 +318,42 @@ int TCombat::GetDistance(void){
return Distance;
}
+void TCombat::ActivateLearning(void){
+ this->LearningPoints = 30;
+}
+
+void TCombat::SetAttackMode(uint8 AttackMode){
+ if(AttackMode != ATTACK_MODE_OFFENSIVE
+ && AttackMode != ATTACK_MODE_BALANCED
+ && AttackMode != ATTACK_MODE_DEFENSIVE){
+ error("TCombat::SetAttackMode: Ungültiger Angriffsmodus %d.\n", AttackMode);
+ return;
+ }
+
+ if(this->AttackMode != AttackMode){
+ this->DelayAttack(2000);
+ this->AttackMode = AttackMode;
+ }
+}
+
+void TCombat::SetChaseMode(uint8 ChaseMode){
+ if(ChaseMode != CHASE_MODE_NONE && ChaseMode != CHASE_MODE_CLOSE){
+ error("TCombat::SetChaseMode: Ungültiger Verfolgungsmodus %d.\n", ChaseMode);
+ return;
+ }
+
+ this->ChaseMode = ChaseMode;
+}
+
+void TCombat::SetSecureMode(uint8 SecureMode){
+ if(SecureMode != SECURE_MODE_DISABLED && SecureMode != SECURE_MODE_ENABLED){
+ error("TCombat::SetSecureMode: Ungültiger Sicherheitsmodus %d.\n", SecureMode);
+ return;
+ }
+
+ this->SecureMode = SecureMode;
+}
+
void TCombat::SetAttackDest(uint32 TargetID, bool Follow){
if(this->AttackDest == TargetID && this->Following == Follow){
return;
@@ -178,8 +373,8 @@ void TCombat::SetAttackDest(uint32 TargetID, bool Follow){
if(!Follow){
if(Master->Type == PLAYER && Target->Type == PLAYER){
- if(this->SecureMode == 1 && WorldType == NORMAL
- && !((TPlayer*)Master)->IsAttackJustified(TargetID)){
+ if(this->SecureMode == SECURE_MODE_ENABLED && WorldType == NORMAL
+ && !((TPlayer*)Master)->IsAttackJustified(TargetID)){
this->StopAttack(0);
throw SECUREMODE;
}
@@ -275,8 +470,8 @@ void TCombat::CanToDoAttack(void){
if(!this->Following){
if(Master->Type == PLAYER && Target->Type == PLAYER){
- if(this->SecureMode == 1 && WorldType == NORMAL
- && !((TPlayer*)Master)->IsAttackJustified(Target->ID)){
+ if(this->SecureMode == SECURE_MODE_ENABLED && WorldType == NORMAL
+ && !((TPlayer*)Master)->IsAttackJustified(Target->ID)){
this->StopAttack(0);
throw SECUREMODE;
}
@@ -319,6 +514,24 @@ void TCombat::CanToDoAttack(void){
}
}
+void TCombat::StopAttack(int Delay){
+ if(Delay == 0){
+ this->AttackDest = 0;
+ if(this->Master->Type == PLAYER){
+ SendClearTarget(this->Master->Connection);
+ }
+ }else{
+ this->LatestAttackTime = RoundNr + Delay;
+ }
+}
+
+void TCombat::DelayAttack(int Milliseconds){
+ uint32 EarliestAttackTime = ServerMilliseconds + Milliseconds;
+ if(this->EarliestAttackTime < EarliestAttackTime){
+ this->EarliestAttackTime = EarliestAttackTime;
+ }
+}
+
void TCombat::Attack(void){
if(this->AttackDest == 0 || this->Following){
return;
@@ -352,8 +565,8 @@ void TCombat::Attack(void){
}
if(Master->Type == PLAYER && Target->Type == PLAYER){
- if(this->SecureMode == 1 && WorldType == NORMAL
- && !((TPlayer*)Master)->IsAttackJustified(Target->ID)){
+ if(this->SecureMode == SECURE_MODE_ENABLED && WorldType == NORMAL
+ && !((TPlayer*)Master)->IsAttackJustified(Target->ID)){
this->StopAttack(0);
throw SECUREMODE;
}
@@ -436,49 +649,17 @@ void TCombat::Attack(void){
}
}
-void TCombat::StopAttack(int Delay){
- if(Delay == 0){
- this->AttackDest = 0;
- if(this->Master->Type == PLAYER){
- SendClearTarget(this->Master->Connection);
- }
- }else{
- this->LatestAttackTime = RoundNr + Delay;
- }
-}
-
-void TCombat::DelayAttack(int Milliseconds){
- uint32 EarliestAttackTime = ServerMilliseconds + Milliseconds;
- if(this->EarliestAttackTime < EarliestAttackTime){
- this->EarliestAttackTime = EarliestAttackTime;
- }
-}
-
void TCombat::CloseAttack(TCreature *Target){
- int Attack;
- uint16 SkillNr;
- this->GetAttackValue(&Attack, &SkillNr);
- if(this->AttackMode == ATTACK_MODE_OFFENSIVE){
- Attack += (Attack * 2) / 10;
- }else if(this->AttackMode == ATTACK_MODE_DEFENSIVE){
- Attack -= (Attack * 4) / 10;
- }
-
- TCreature *Master = this->Master;
- Attack = Master->Skills[SkillNr]->ProbeValue(Attack, this->LearningPoints > 0);
- if(this->LearningPoints > 0){
- this->LearningPoints -= 1;
- }
-
+ int Attack = this->GetAttackDamage();
int Defense = Target->Combat.GetDefendDamage();
int Damage = Attack - Defense;
if(Damage < 0){
Damage = 0;
}
- int DamageDone = Target->Damage(Master, Damage, 1); // DAMAGE_PHYSICAL ?
+ int DamageDone = Target->Damage(Master, Damage, DAMAGE_PHYSICAL);
if(DamageDone > 0){
- this->LearningPoints = 30;
+ this->ActivateLearning();
}
int Poison = GetRacePoison(Master->Race);
@@ -547,7 +728,7 @@ void TCombat::WandAttack(TCreature *Target){
int Damage = AttackStrength + random(-AttackVariation, AttackVariation);
if(Target->Damage(Master, Damage, DamageType) > 0){
- this->LearningPoints = 30;
+ this->ActivateLearning();
}
::Missile(Master->CrObject, Target->CrObject, AnimType);
@@ -617,29 +798,18 @@ void TCombat::DistanceAttack(TCreature *Target){
int DropY = Target->posy;
int DropZ = Target->posz;
if(Hit){
- int Attack;
- uint16 SkillNr;
- this->GetAttackValue(&Attack, &SkillNr);
- if(this->AttackMode == ATTACK_MODE_OFFENSIVE){
- Attack += (Attack * 2) / 10;
- }else if(this->AttackMode == ATTACK_MODE_DEFENSIVE){
- Attack -= (Attack * 4) / 10;
- }
-
- Attack = Master->Skills[SkillNr]->ProbeValue(Attack, this->LearningPoints > 0);
- if(this->LearningPoints > 0){
- this->LearningPoints -= 1;
- }
+ int Attack = this->GetAttackDamage();
// TODO(fusion): This doesn't make any sense. The disassembly looks
// correct but I feel we're missing something here. Or maybe defense
- // doesn't work with ranged attacks but worn them out?
+ // doesn't work with ranged attacks but worn them out? But then only
+ // if the attacker is wearing a shield? This is a probably a bug.
if(this->Shield != NONE){
Target->Combat.GetDefendDamage();
}
if(Target->Damage(Master, Attack, DamageType) > 0){
- this->LearningPoints = 30;
+ this->ActivateLearning();
}
}else{
if(DistanceX > 1 || DistanceY > 1){
@@ -679,3 +849,105 @@ void TCombat::DistanceAttack(TCreature *Target){
GraphicalEffect(DropX, DropY, DropZ, EFFECT_POFF);
}
}
+
+void TCombat::AddDamageToCombatList(uint32 Attacker, uint32 Damage){
+ this->CombatDamage += Damage;
+ for(int i = 0; i < NARRAY(this->CombatList); i += 1){
+ if(this->CombatList[i].ID == Attacker){
+ this->CombatList[i].Damage += Damage;
+ this->CombatList[i].TimeStamp = RoundNr;
+ return;
+ }
+ }
+
+ int NextEntryIndex = this->ActCombatEntry;
+ this->CombatList[NextEntryIndex].ID = Attacker;
+ this->CombatList[NextEntryIndex].Damage = Damage;
+ this->CombatList[NextEntryIndex].TimeStamp = RoundNr;
+
+ NextEntryIndex += 1;
+ if(NextEntryIndex >= NARRAY(this->CombatList)){
+ NextEntryIndex = 0;
+ }
+ this->ActCombatEntry = NextEntryIndex;
+}
+
+uint32 TCombat::GetDamageByCreature(uint32 CreatureID){
+ uint32 Damage = 0;
+ for(int i = 0; i < NARRAY(this->CombatList); i += 1){
+ if(this->CombatList[i].ID == CreatureID){
+ Damage = this->CombatList[i].Damage;
+ break;
+ }
+ }
+ return Damage;
+}
+
+uint32 TCombat::GetMostDangerousAttacker(void){
+ uint32 Attacker = 0;
+ uint32 MaxDamage = 0;
+ for(int i = 0; i < NARRAY(this->CombatList); i += 1){
+ if((RoundNr - this->CombatList[i].TimeStamp) < 60
+ && this->CombatList[i].Damage > MaxDamage){
+ Attacker = this->CombatList[i].ID;
+ MaxDamage = this->CombatList[i].Damage;
+ }
+ }
+ return Attacker;
+}
+
+void TCombat::DistributeExperiencePoints(uint32 Exp){
+ TCreature *Master = this->Master;
+ print(3, "%s ist gestorben. Verteile %u EXP...\n", Master->Name, Exp);
+ if(this->CombatDamage == 0){
+ return;
+ }
+
+ for(int i = 0; i < NARRAY(this->CombatList); i += 1){
+ TCreature *Attacker = GetCreature(this->CombatList[i].ID);
+ if(Attacker == NULL || Attacker->IsDead){
+ continue;
+ }
+
+ int Amount = (int)((Exp * this->CombatList[i].Damage) / this->CombatDamage);
+ if(Master->Type == PLAYER && Attacker->Type == PLAYER){
+ if(((TPlayer*)Master)->GetPartyLeader(true) == ((TPlayer*)Attacker)->GetPartyLeader(true)){
+ continue;
+ }
+
+ int MasterLevel = Master->Skills[SKILL_LEVEL]->Get();
+ int AttackerLevel = Attacker->Skills[SKILL_LEVEL]->Get();
+ int MaxLevel = (MasterLevel * 11) / 10;
+ if(AttackerLevel < MaxLevel){
+ Amount = ((MaxLevel - AttackerLevel) * Amount) / MasterLevel;
+ }else{
+ Amount = 0;
+ }
+ }
+
+ if(Amount > 0){
+ if(Attacker->Type == PLAYER){
+ // NOTE(fusion): Enable soul regeneration.
+ int AttackerLevel = Attacker->Skills[SKILL_LEVEL]->Get();
+ if(Amount >= AttackerLevel){
+ int Interval = 120;
+ if(((TPlayer*)Attacker)->GetActivePromotion()){
+ Interval = 15;
+ }
+
+ int Count = Attacker->Skills[SKILL_SOUL]->TimerValue() % Interval;
+ if(Count == 0){
+ Count = Interval;
+ }
+
+ Attacker->SetTimer(SKILL_SOUL, (240 / Interval), Count, Interval, -1);
+ }
+ }
+
+ Attacker->Skills[0]->Increase(Amount);
+ TextualEffect(Attacker->CrObject, 0xD7, "%d", Amount);
+ }
+ }
+}
+
+
diff --git a/src/crcombat.hh b/src/crcombat.hh
index bd22584..b5db3c3 100644
--- a/src/crcombat.hh
+++ b/src/crcombat.hh
@@ -6,7 +6,7 @@ struct TCreature;
struct TCombatEntry{
uint32 ID;
uint32 Damage;
- int TimeStamp;
+ uint32 TimeStamp;
};
struct TCombat{
@@ -16,17 +16,29 @@ struct TCombat{
void GetWeapon(void);
void GetAmmo(void);
void CheckCombatValues(void);
- int GetDistance(void);
- void GetAttackValue(int *Attack, uint16 *SkillNr);
+ void GetAttackValue(int *Value, int *SkillNr);
+ void GetDefendValue(int *Value, int *SkillNr);
+ int GetAttackDamage(void);
int GetDefendDamage(void);
+ int GetArmorStrength(void);
+ int GetDistance(void);
+ void ActivateLearning(void);
+ void SetAttackMode(uint8 AttackMode);
+ void SetChaseMode(uint8 ChaseMode);
+ void SetSecureMode(uint8 SecureMode);
void SetAttackDest(uint32 TargetID, bool Follow);
void CanToDoAttack(void);
- void Attack(void);
void StopAttack(int Delay);
void DelayAttack(int Milliseconds);
+ void Attack(void);
void CloseAttack(TCreature *Target);
void DistanceAttack(TCreature *Target);
void WandAttack(TCreature *Target);
+ void AddDamageToCombatList(uint32 Attacker, uint32 Damage);
+ uint32 GetDamageByCreature(uint32 CreatureID);
+ uint32 GetMostDangerousAttacker(void);
+ void DistributeExperiencePoints(uint32 Exp);
+
// DATA
// =========================================================================
diff --git a/src/enums.hh b/src/enums.hh
index d8f5816..4081dce 100644
--- a/src/enums.hh
+++ b/src/enums.hh
@@ -25,7 +25,6 @@ enum AnimationType: int {
// NOTE(fusion): Not in debug symbols.
enum AttackMode: uint8 {
- ATTACK_MODE_NONE = 0,
ATTACK_MODE_OFFENSIVE = 1,
ATTACK_MODE_BALANCED = 2,
ATTACK_MODE_DEFENSIVE = 3,
@@ -360,6 +359,11 @@ enum RIGHT: int {
NO_STATISTICS = 81,
};
+enum SecureMode: uint8 {
+ SECURE_MODE_DISABLED = 0,
+ SECURE_MODE_ENABLED = 1,
+};
+
// NOTE(fusion): Not in debug symbols.
enum Skill: int {
SKILL_LEVEL = 0,
@@ -556,4 +560,14 @@ enum TWorldType: int {
PVP_ENFORCED = 2,
};
+enum WeaponType: int {
+ WEAPON_NONE = 0,
+ WEAPON_SWORD = 1,
+ WEAPON_CLUB = 2,
+ WEAPON_AXE = 3,
+ WEAPON_SHIELD = 4,
+ WEAPON_AMMO = 5,
+ WEAPON_THROW = 6,
+};
+
#endif //TIBIA_ENUMS_HH_
diff --git a/src/magic.cc b/src/magic.cc
index f8f0505..5d6acad 100644
--- a/src/magic.cc
+++ b/src/magic.cc
@@ -1,6 +1,63 @@
#include "magic.hh"
+#include "config.hh"
#include "creature.hh"
+#include "stubs.hh"
+
+static const char SpellSyllable[51][6] = {
+ "",
+ "al",
+ "ad",
+ "ex",
+ "ut",
+ "om",
+ "para",
+ "ana",
+ "evo",
+ "ori",
+ "mort",
+ "lux",
+ "liber",
+ "vita",
+ "flam",
+ "pox",
+ "hur",
+ "moe",
+ "ani",
+ "ina",
+ "eta",
+ "amo",
+ "hora",
+ "gran",
+ "cogni",
+ "res",
+ "mas",
+ "vis",
+ "som",
+ "aqua",
+ "frigo",
+ "tera",
+ "ura",
+ "sio",
+ "grav",
+ "ito",
+ "pan",
+ "vid",
+ "isa",
+ "iva",
+ "con",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+};
+
// TImpact
// =============================================================================
void TImpact::handleField(int a, int b, int c){
@@ -17,7 +74,7 @@ bool TImpact::isAggressive(void){
// TDamageImpact
// =============================================================================
-void TDamageImpact::TDamageImpact(TCreature *Actor, int DamageType, int Power, bool AllowDefense){
+TDamageImpact::TDamageImpact(TCreature *Actor, int DamageType, int Power, bool AllowDefense){
if(Actor == NULL){
error("TDamageImpact::TDamageImpact: Actor ist NULL.\n");
}
@@ -28,6 +85,26 @@ void TDamageImpact::TDamageImpact(TCreature *Actor, int DamageType, int Power, b
this->AllowDefense = AllowDefense;
}
+void TDamageImpact::handleCreature(TCreature *Victim){
+ if(Victim == NULL){
+ error("TDamageImpact::handleCreature: Opfer existiert nicht.\n");
+ return;
+ }
+
+ TCreature *Actor = this->Actor;
+ if(Actor != NULL && Actor != Victim){
+ if(WorldType != NON_PVP || !Actor->IsPeaceful() || !Victim->IsPeaceful()){
+ int DamageType = this->DamageType;
+ int Damage = this->Power;
+ if(DamageType == DAMAGE_PHYSICAL && this->AllowDefense){
+ // TODO(fusion): Shouldn't we clamp `Damage` to zero?
+ Damage -= Victim->Combat.GetDefendDamage();
+ }
+ Victim->Damage(Actor, Damage, DamageType);
+ }
+ }
+}
+
// Magic Related Functions
// =============================================================================
void CheckMana(TCreature *Creature, int ManaPoints, int SoulPoints, int Delay){
@@ -36,8 +113,9 @@ void CheckMana(TCreature *Creature, int ManaPoints, int SoulPoints, int Delay){
throw ERROR;
}
- if(Creature->Type != PLAYER || ManaPoints < 0)
+ if(Creature->Type != PLAYER || ManaPoints < 0){
return;
+ }
TSkill *Mana = Creature->Skills[SKILL_MANA];
if(Mana == NULL){
@@ -52,11 +130,13 @@ void CheckMana(TCreature *Creature, int ManaPoints, int SoulPoints, int Delay){
}
if(!CheckRight(Creature->ID, UNLIMITED_MANA)){
- if(Mana->Get() < ManaPoints)
+ if(Mana->Get() < ManaPoints){
throw NOTENOUGHMANA;
+ }
- if(Soul->Get() < SoulPoints)
+ if(Soul->Get() < SoulPoints){
throw NOTENOUGHSOULPOINTS;
+ }
Mana->Change(-ManaPoints);
Soul->Change(-SoulPoints);
diff --git a/src/player.hh b/src/player.hh
index 815289e..33ca7c3 100644
--- a/src/player.hh
+++ b/src/player.hh
@@ -72,6 +72,9 @@ struct TPlayer: TCreature {
uint8 GetEffectiveProfession(void);
uint8 GetActiveProfession(void);
bool GetActivePromotion(void);
+
+ uint32 GetPartyLeader(bool CheckFormer);
+
bool IsAttackJustified(uint32 Victim);
void RecordAttack(uint32 Victim);
diff --git a/src/stubs.hh b/src/stubs.hh
index 622e588..d3cfcd0 100644
--- a/src/stubs.hh
+++ b/src/stubs.hh
@@ -65,6 +65,7 @@ extern void SendMessage(TConnection *Connection, int Mode, const char *Text, ...
extern void SendPlayerData(TConnection *Connection);
extern void SendPlayerSkills(TConnection *Connection);
extern void SendPlayerState(TConnection *Connection, uint8 State);
+extern void TextualEffect(Object Obj, int Color, const char *Text, ...) ATTR_PRINTF(3, 4);
extern bool ThrowPossible(int FromX, int FromY, int FromZ,
int ToX, int ToY, int ToZ, int Power);
extern void WriteKillStatistics(void);