diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-05-31 02:25:31 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-05-31 02:25:31 -0300 |
| commit | d7c11b271633ee1f5b58d2b679b50cf95b2826e0 (patch) | |
| tree | c08832dff011660dcc2af748b82d5ab0adf82d97 | |
| parent | 08780dad536eb5d0544eb2ea70e5443dc237976f (diff) | |
| download | game-d7c11b271633ee1f5b58d2b679b50cf95b2826e0.tar.gz game-d7c11b271633ee1f5b58d2b679b50cf95b2826e0.zip | |
done with `crcombat.cc`
| -rw-r--r-- | Makefile | 8 | ||||
| -rw-r--r-- | reference/game.c | 2271 | ||||
| -rw-r--r-- | src/crcombat.cc | 388 | ||||
| -rw-r--r-- | src/crcombat.hh | 20 | ||||
| -rw-r--r-- | src/enums.hh | 16 | ||||
| -rw-r--r-- | src/magic.cc | 88 | ||||
| -rw-r--r-- | src/player.hh | 3 | ||||
| -rw-r--r-- | src/stubs.hh | 1 |
8 files changed, 455 insertions, 2340 deletions
@@ -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); |
