From d7c11b271633ee1f5b58d2b679b50cf95b2826e0 Mon Sep 17 00:00:00 2001 From: fusion32 Date: Sat, 31 May 2025 02:25:31 -0300 Subject: done with `crcombat.cc` --- Makefile | 8 +- reference/game.c | 2271 ------------------------------------------------------ src/crcombat.cc | 388 ++++++++-- src/crcombat.hh | 20 +- src/enums.hh | 16 +- src/magic.cc | 88 ++- src/player.hh | 3 + src/stubs.hh | 1 + 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::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::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); -- cgit v1.2.3