diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-06-02 12:07:24 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-06-02 12:16:51 -0300 |
| commit | 3f85ce3cfb46adee8caf890a8369cd7cd7814874 (patch) | |
| tree | 2d12dce7dab39e657b481d1bcd7e9f7177226314 | |
| parent | 189d40706feea796fe9307c915f29d2158769357 (diff) | |
| download | game-3f85ce3cfb46adee8caf890a8369cd7cd7814874.tar.gz game-3f85ce3cfb46adee8caf890a8369cd7cd7814874.zip | |
use `Actor` instead of `Creature` with spell functions
| -rw-r--r-- | reference/game.c | 583 | ||||
| -rw-r--r-- | src/magic.cc | 485 | ||||
| -rw-r--r-- | src/stubs.hh | 1 |
3 files changed, 416 insertions, 653 deletions
diff --git a/reference/game.c b/reference/game.c index aee0dd9..2062902 100644 --- a/reference/game.c +++ b/reference/game.c @@ -20988,589 +20988,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority return;
}
-void KillAllMonsters(TCreature *cr,int EffectNr,int Radius)
-
-{
- bool bVar1;
- int iVar2;
- TCreature *pTVar3;
- undefined4 *puVar4;
- char *pcVar5;
- int dy;
- int local_78;
- int *local_74;
- TCreature *dest;
- int dx;
- int j;
- int i;
- TSkill *local_4c;
- Object Help;
- TSkill *local_2c;
- Object Obj;
-
- if (cr != (TCreature *)0x0) {
- if (((cr->Type != PLAYER) || (bVar1 = CheckRight(cr->ID,CREATE_MONSTERS), bVar1)) &&
- (j = 0, -1 < Radius)) {
- local_74 = &Circle[0].Count;
- local_78 = 0;
- do {
- dx = 0;
- iVar2 = local_78;
- if (0 < *local_74) {
- do {
- // try { // try from 08080c93 to 08080e80 has its CatchHandler @ 08080e81
- bVar1 = ThrowPossible(cr->posx,cr->posy,cr->posz,
- Circle[0].x[iVar2 + dx] + cr->posx,
- Circle[0].y[iVar2 + dx] + cr->posy,cr->posz,0);
- if ((bVar1) && (bVar1 = IsProtectionZone(), !bVar1)) {
- GetFirstObject();
- if (local_2c != (TSkill *)NONE.ObjectID) {
- do {
- dest = (TCreature *)&local_4c;
- local_4c = local_2c;
- Object::getNextObject((Object *)&i);
- iVar2 = i;
- local_2c = (TSkill *)i;
- Object::getObjectType((Object *)&i);
- if (i == 99) {
- i = (int)local_4c;
- pTVar3 = GetCreature((Object *)&i);
- if (pTVar3 == (TCreature *)0x0) {
- error(&DAT_080fae40,dest);
- }
- else if ((cr != pTVar3) && (pTVar3->Type == MONSTER)) {
- pcVar5 = pTVar3->Name;
- print();
- (*(pTVar3->super_TSkillBase).Skills[2]->_vptr_TSkill[2])
- ((pTVar3->super_TSkillBase).Skills[2],0,pcVar5
- );
- (*pTVar3->_vptr_TCreature[2])(pTVar3);
- }
- }
- } while (iVar2 != NONE.ObjectID);
- }
- local_4c = (TSkill *)NONE.ObjectID;
- GraphicalEffect();
- }
- dx = dx + 1;
- iVar2 = j * 0x41;
- } while (dx < *local_74);
- }
- j = j + 1;
- local_74 = local_74 + 0x41;
- local_78 = local_78 + 0x41;
- } while (j <= Radius);
- }
- return;
- }
- error(&DAT_080fae80);
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void CreateField(void)
-
-{
- bool bVar1;
- undefined4 *puVar2;
- int iVar3;
- TCreature *in_stack_00000004;
- Object *in_stack_00000008;
- int in_stack_0000000c;
- int in_stack_00000010;
- int in_stack_00000014;
- char *Text;
- int iVar4;
- bool local_4c;
- int local_48;
- int x;
- int y;
- int z;
- Object local_2c [7];
-
- if (in_stack_00000004 == (TCreature *)0x0) {
- Text = &DAT_080faf00;
- }
- else {
- // try { // try from 08080ec3 to 080810b4 has its CatchHandler @ 080810d2
- bVar1 = Object::exists(in_stack_00000008);
- if (bVar1) {
- local_2c[0].ObjectID = in_stack_00000008->ObjectID;
- GetObjectCoordinates(local_2c,&local_48,&x,&y);
- iVar3 = x;
- iVar4 = y;
- bVar1 = FieldPossible();
- if (bVar1) {
- CheckAffectedPlayers();
- bVar1 = ThrowPossible(in_stack_00000004->posx,in_stack_00000004->posy,
- in_stack_00000004->posz,local_48,x,y,0);
- if (bVar1) {
- iVar3 = 1000;
- if (WorldType != PVP_ENFORCED) {
- iVar3 = 2000;
- }
- CheckMana(in_stack_00000004,in_stack_0000000c,in_stack_00000010,iVar3);
- local_2c[0].ObjectID = in_stack_00000008->ObjectID;
- z = (in_stack_00000004->CrObject).ObjectID;
- Missile((Object *)&z,local_2c,(in_stack_00000014 != 1) + 4);
- local_4c = false;
- if (WorldType == NON_PVP) {
- iVar3 = (*in_stack_00000004->_vptr_TCreature[4])();
- local_4c = (char)iVar3 != '\0';
- }
- CreateField(local_48,x,y,in_stack_00000014,in_stack_00000004->ID,local_4c);
- bVar1 = false;
- if ((0 < in_stack_00000014) && (in_stack_00000014 < 4)) {
- bVar1 = true;
- }
- if (bVar1) {
- TCreature::BlockLogout(in_stack_00000004,0x3c,true);
- }
- return;
- }
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 7;
- }
- else {
- puVar2 = (undefined4 *)__cxa_allocate_exception(4,iVar3,iVar4);
- *puVar2 = 4;
- }
- goto LAB_0808107d;
- }
- Text = &DAT_080faec0;
- }
- error(Text);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
-LAB_0808107d:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void CreateField(void)
-
-{
- bool bVar1;
- undefined4 *puVar2;
- int x;
- int y_00;
- int y;
- int z_00;
- int in_stack_00000004;
- int iVar3;
- undefined4 uVar4;
- int z;
-
- if (in_stack_00000004 == 0) {
- error(&DAT_080faf00);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
-LAB_080811d9:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
- }
- uVar4 = *(undefined4 *)(in_stack_00000004 + 0x278);
- y_00 = *(int *)(in_stack_00000004 + 0x270);
- z_00 = *(int *)(in_stack_00000004 + 0x274);
- iVar3 = *(int *)(in_stack_00000004 + 0x284);
- if (iVar3 == 1) {
- y_00 = y_00 + 1;
- }
- else if (iVar3 < 2) {
- if (iVar3 == 0) {
- z_00 = z_00 + -1;
- }
- }
- else if (iVar3 == 2) {
- z_00 = z_00 + 1;
- }
- else if (iVar3 == 3) {
- y_00 = y_00 + -1;
- }
- if (*(int *)(in_stack_00000004 + 0x28c) == 0) {
- bVar1 = CheckRight(*(ulong *)(in_stack_00000004 + 0x208),ATTACK_EVERYWHERE);
- if (!bVar1) {
- iVar3 = z_00;
- bVar1 = IsProtectionZone();
- if (bVar1) {
- puVar2 = (undefined4 *)__cxa_allocate_exception(4,iVar3,uVar4);
- *puVar2 = 0x2f;
- goto LAB_080811d9;
- }
- }
- }
- // try { // try from 08081162 to 08081221 has its CatchHandler @ 08081236
- GetMapContainer((int)&z,y_00,z_00);
- CreateField();
- return;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void MassCreateField(void)
-
-{
- bool bVar1;
- int iVar2;
- undefined4 *puVar3;
- int iVar4;
- int dx;
- int zx;
- TCreature *in_stack_00000004;
- Object *in_stack_00000008;
- int in_stack_0000000c;
- int in_stack_00000010;
- int in_stack_00000014;
- int in_stack_00000018;
- char *Text;
- int local_64;
- int *local_60;
- bool local_58;
- int local_50;
- int j;
- int i;
- int x;
- int y;
- int z;
- Object local_2c [7];
-
- if (in_stack_00000004 == (TCreature *)0x0) {
- Text = &DAT_080faf80;
- }
- else {
- // try { // try from 08081273 to 08081538 has its CatchHandler @ 08081556
- bVar1 = Object::exists(in_stack_00000008);
- if (bVar1) {
- local_2c[0].ObjectID = in_stack_00000008->ObjectID;
- GetObjectCoordinates(local_2c,&i,&x,&y);
- CheckAffectedPlayers();
- bVar1 = ThrowPossible(in_stack_00000004->posx,in_stack_00000004->posy,
- in_stack_00000004->posz,i,x,y,0);
- if (bVar1) {
- iVar4 = 1000;
- if (WorldType != PVP_ENFORCED) {
- iVar4 = 2000;
- }
- CheckMana(in_stack_00000004,in_stack_0000000c,in_stack_00000010,iVar4);
- if (((in_stack_00000004->posx != i) || (in_stack_00000004->posy != x)) ||
- (in_stack_00000004->posz != y)) {
- local_2c[0].ObjectID = in_stack_00000008->ObjectID;
- z = (in_stack_00000004->CrObject).ObjectID;
- Missile((Object *)&z,local_2c,(in_stack_00000014 != 1) + 4);
- }
- j = 0;
- if (0 < in_stack_00000018) {
- local_60 = &Circle[0].Count;
- local_64 = 0;
- do {
- local_50 = 0;
- iVar4 = local_64;
- if (0 < *local_60) {
- do {
- zx = i + Circle[0].x[iVar4 + local_50];
- iVar4 = x + Circle[0].y[iVar4 + local_50];
- bVar1 = ThrowPossible(i,x,y,zx,iVar4,y,0);
- if ((bVar1) && (bVar1 = IsProtectionZone(), !bVar1)) {
- local_58 = false;
- if (WorldType == NON_PVP) {
- iVar2 = (*in_stack_00000004->_vptr_TCreature[4])();
- local_58 = (char)iVar2 != '\0';
- }
- CreateField(zx,iVar4,y,in_stack_00000014,in_stack_00000004->ID,
- local_58);
- }
- local_50 = local_50 + 1;
- iVar4 = j * 0x41;
- } while (local_50 < *local_60);
- }
- j = j + 1;
- local_60 = local_60 + 0x41;
- local_64 = local_64 + 0x41;
- } while (j < in_stack_00000018);
- }
- bVar1 = false;
- if ((0 < in_stack_00000014) && (in_stack_00000014 < 4)) {
- bVar1 = true;
- }
- if (bVar1) {
- TCreature::BlockLogout(in_stack_00000004,0x3c,true);
- }
- return;
- }
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 7;
- goto LAB_08081515;
- }
- Text = &DAT_080faf40;
- }
- error(Text);
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
-LAB_08081515:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void CreateFieldWall(void)
-
-{
- bool bVar1;
- uint uVar2;
- undefined4 *puVar3;
- int iVar4;
- int dx;
- int iVar5;
- TCreature *in_stack_00000004;
- Object *in_stack_00000008;
- int in_stack_0000000c;
- int in_stack_00000010;
- int in_stack_00000014;
- int in_stack_00000018;
- char *Text;
- int local_80;
- int local_7c;
- int local_78;
- int local_74;
- int local_70;
- int local_6c;
- int local_68;
- int local_5c;
- int i;
- bool Peaceful;
- int Dir;
- int StepY;
- int StepX;
- int x;
- int y;
- int z;
- Object local_2c [7];
-
- if (in_stack_00000004 != (TCreature *)0x0) {
- // try { // try from 08081593 to 08081b48 has its CatchHandler @ 08081b54
- bVar1 = Object::exists(in_stack_00000008);
- if (!bVar1) {
- Text = &DAT_080fb000;
- goto LAB_08081b44;
- }
- local_2c[0].ObjectID = in_stack_00000008->ObjectID;
- GetObjectCoordinates(local_2c,&StepX,&x,&y);
- CheckAffectedPlayers();
- bVar1 = ThrowPossible(in_stack_00000004->posx,in_stack_00000004->posy,
- in_stack_00000004->posz,StepX,x,y,0);
- if (!bVar1) {
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 7;
- goto LAB_080816e6;
- }
- iVar4 = 1000;
- if (WorldType != PVP_ENFORCED) {
- iVar4 = 2000;
- }
- CheckMana(in_stack_00000004,in_stack_0000000c,in_stack_00000010,iVar4);
- iVar4 = in_stack_00000004->posx;
- if (((iVar4 != StepX) || (iVar5 = in_stack_00000004->posy, iVar5 != x)) ||
- (in_stack_00000004->posz != y)) {
- local_2c[0].ObjectID = in_stack_00000008->ObjectID;
- z = (in_stack_00000004->CrObject).ObjectID;
- Missile((Object *)&z,local_2c,(in_stack_00000014 != 1) + 4);
- iVar5 = in_stack_00000004->posy;
- iVar4 = in_stack_00000004->posx;
- }
- uVar2 = Direction(StepX - iVar4,x - iVar5);
- switch(uVar2) {
- case 0:
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 4;
- goto LAB_080816e6;
- case 1:
- case 5:
- StepY = 0;
- break;
- case 2:
- case 6:
- StepY = 1;
- break;
- case 3:
- case 7:
- StepY = 1;
- Dir = 0;
- goto LAB_0808170c;
- case 4:
- case 8:
- StepY = -1;
- break;
- default:
- error(&DAT_080fafc0,uVar2);
- goto LAB_08081ae7;
- }
- Dir = 1;
-LAB_0808170c:
- i._3_1_ = false;
- if ((WorldType == NON_PVP) &&
- (iVar4 = (*in_stack_00000004->_vptr_TCreature[4])(), (char)iVar4 != '\0')) {
- i._3_1_ = true;
- }
- CreateField(StepX,x,y,in_stack_00000014,in_stack_00000004->ID,i._3_1_);
- local_5c = 1;
- if (0 < in_stack_00000018) {
- local_6c = 0;
- local_68 = StepY;
- local_70 = StepY;
- local_74 = Dir;
- local_78 = StepY;
- local_7c = Dir;
- local_80 = StepY;
- do {
- iVar5 = local_80 + StepX;
- iVar4 = local_7c + x;
- bVar1 = ThrowPossible(in_stack_00000004->posx,in_stack_00000004->posy,
- in_stack_00000004->posz,iVar5,iVar4,y,0);
- if ((bVar1) && (bVar1 = IsProtectionZone(), !bVar1)) {
- CreateField(iVar5,iVar4,y,in_stack_00000014,in_stack_00000004->ID,i._3_1_);
- }
- iVar5 = StepX - local_78;
- iVar4 = x - local_74;
- bVar1 = ThrowPossible(in_stack_00000004->posx,in_stack_00000004->posy,
- in_stack_00000004->posz,iVar5,iVar4,y,0);
- if ((bVar1) && (bVar1 = IsProtectionZone(), !bVar1)) {
- CreateField(iVar5,iVar4,y,in_stack_00000014,in_stack_00000004->ID,i._3_1_);
- }
- if ((uVar2 & 1) == 0) {
- iVar5 = local_70 + StepX;
- iVar4 = local_6c + x;
- bVar1 = ThrowPossible(in_stack_00000004->posx,in_stack_00000004->posy,
- in_stack_00000004->posz,iVar5,iVar4,y,0);
- if ((bVar1) && (bVar1 = IsProtectionZone(), !bVar1)) {
- CreateField(iVar5,iVar4,y,in_stack_00000014,in_stack_00000004->ID,i._3_1_);
- }
- iVar5 = StepX - local_68;
- iVar4 = x - (local_5c + -1) * Dir;
- bVar1 = ThrowPossible(in_stack_00000004->posx,in_stack_00000004->posy,
- in_stack_00000004->posz,iVar5,iVar4,y,0);
- if ((bVar1) && (bVar1 = IsProtectionZone(), !bVar1)) {
- CreateField(iVar5,iVar4,y,in_stack_00000014,in_stack_00000004->ID,i._3_1_);
- }
- }
- local_5c = local_5c + 1;
- local_68 = local_68 + StepY;
- local_6c = local_6c + Dir;
- local_70 = local_70 + StepY;
- local_74 = local_74 + Dir;
- local_78 = local_78 + StepY;
- local_7c = local_7c + Dir;
- local_80 = local_80 + StepY;
- } while (local_5c <= in_stack_00000018);
- }
- bVar1 = false;
- if ((0 < in_stack_00000014) && (in_stack_00000014 < 4)) {
- bVar1 = true;
- }
- if (bVar1) {
- TCreature::BlockLogout(in_stack_00000004,0x3c,true);
- }
- return;
- }
- Text = &DAT_080fb040;
-LAB_08081b44:
- error(Text);
-LAB_08081ae7:
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
-LAB_080816e6:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void DeleteField(void)
-
-{
- bool bVar1;
- undefined4 *puVar2;
- TCreature *in_stack_00000004;
- Object *in_stack_00000008;
- int in_stack_0000000c;
- int in_stack_00000010;
- char *Text;
- undefined4 uVar3;
- int local_58;
- int x;
- int y;
- int z;
- ulong local_3c;
- Object Help;
- Object local_2c [7];
-
- if (in_stack_00000004 == (TCreature *)0x0) {
- Text = &DAT_080fb0c0;
- }
- else {
- // try { // try from 08081b90 to 08081d0f has its CatchHandler @ 08081d30
- bVar1 = Object::exists(in_stack_00000008);
- if (bVar1) {
- local_2c[0].ObjectID = in_stack_00000008->ObjectID;
- GetObjectCoordinates(local_2c,&local_58,&x,&y);
- uVar3 = 0;
- bVar1 = FieldPossible();
- if (bVar1) {
- CheckMana(in_stack_00000004,in_stack_0000000c,in_stack_00000010,1000);
- GetFirstObject();
- in_stack_00000008->ObjectID = local_3c;
- if (local_3c != NONE.ObjectID) {
- do {
- local_2c[0].ObjectID = NONE.ObjectID;
- Object::getNextObject((Object *)&z);
- in_stack_00000008->ObjectID = z;
- local_2c[0].ObjectID = z;
- Object::getObjectType((Object *)&z);
- bVar1 = ObjectType::getFlag((ObjectType *)&z,MAGICFIELD);
- if (bVar1) {
- z = local_3c;
- Delete((Object *)&z,-1);
- }
- local_3c = in_stack_00000008->ObjectID;
- } while (local_3c != NONE.ObjectID);
- }
- local_3c = NONE.ObjectID;
- local_2c[0].ObjectID = NONE.ObjectID;
- GraphicalEffect();
- return;
- }
- puVar2 = (undefined4 *)__cxa_allocate_exception(4,x,y,uVar3);
- *puVar2 = 4;
- goto LAB_08081cec;
- }
- Text = &DAT_080fb080;
- }
- error(Text);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
-LAB_08081cec:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
// WARNING: Unknown calling convention -- yet parameter storage is locked
void CleanupField(void)
diff --git a/src/magic.cc b/src/magic.cc index 85dbc11..4c641bb 100644 --- a/src/magic.cc +++ b/src/magic.cc @@ -147,11 +147,7 @@ TFieldImpact::TFieldImpact(TCreature *Actor, int FieldType){ void TFieldImpact::handleField(int x, int y, int z){ TCreature *Actor = this->Actor; if(Actor != NULL){ - bool Peaceful = false; - if(WorldType == NON_PVP){ - Peaceful = Actor->IsPeaceful(); - } - + bool Peaceful = (WorldType == NON_PVP && Actor->IsPeaceful()); CreateField(x, y, z, this->FieldType, Actor->ID, Peaceful); } } @@ -451,7 +447,7 @@ static void ExecuteCircleSpell(int DestX, int DestY, int DestZ, } bool Aggressive = Impact->isAggressive(); - for(int R = 0; R < Radius; R += 1){ + for(int R = 0; R <= Radius; R += 1){ int CirclePoints = Circle[R].Count; for(int Point = 0; Point < CirclePoints; Point += 1){ int FieldX = DestX + Circle[R].x[Point]; @@ -634,20 +630,20 @@ int GetDirection(int dx, int dy){ return Result; } -void CheckSpellbook(TCreature *Creature, int SpellNr){ - if(Creature == NULL){ +void CheckSpellbook(TCreature *Actor, int SpellNr){ + if(Actor == NULL){ error("CheckSpellbook: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } - if(Creature->Type == PLAYER && !CheckRight(Creature->ID, ALL_SPELLS) - && !((TPlayer*)Creature)->SpellKnown(SpellNr)){ + if(Actor->Type == PLAYER && !CheckRight(Actor->ID, ALL_SPELLS) + && !((TPlayer*)Actor)->SpellKnown(SpellNr)){ throw SPELLUNKNOWN; } } -void CheckAccount(TCreature *Creature, int SpellNr){ - if(Creature == NULL){ +void CheckAccount(TCreature *Actor, int SpellNr){ + if(Actor == NULL){ error("CheckAccount: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } @@ -658,20 +654,20 @@ void CheckAccount(TCreature *Creature, int SpellNr){ throw ERROR; } - if(Creature->Type == PLAYER && (SpellList[SpellNr].Flags & 2) != 0 - && !CheckRight(Creature->ID, PREMIUM_ACCOUNT)){ + if(Actor->Type == PLAYER && (SpellList[SpellNr].Flags & 2) != 0 + && !CheckRight(Actor->ID, PREMIUM_ACCOUNT)){ throw NOPREMIUMACCOUNT; } } -void CheckLevel(TCreature *Creature, int SpellNr){ - if(Creature == NULL){ +void CheckLevel(TCreature *Actor, int SpellNr){ + if(Actor == NULL){ error("CheckLevel: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } - if(Creature->Type == PLAYER && !CheckRight(Creature->ID, ALL_SPELLS)){ - TSkill *Level = Creature->Skills[SKILL_LEVEL]; + if(Actor->Type == PLAYER && !CheckRight(Actor->ID, ALL_SPELLS)){ + TSkill *Level = Actor->Skills[SKILL_LEVEL]; if(Level == NULL){ error("CheckLevel: Kein Skill LEVEL.\n"); throw ERROR; @@ -683,14 +679,14 @@ void CheckLevel(TCreature *Creature, int SpellNr){ } } -void CheckRuneLevel(TCreature *Creature, int SpellNr){ - if(Creature == NULL){ +void CheckRuneLevel(TCreature *Actor, int SpellNr){ + if(Actor == NULL){ error("CheckRuneLevel: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } - if(Creature->Type == PLAYER && !CheckRight(Creature->ID, ALL_SPELLS)){ - TSkill *MagicLevel = Creature->Skills[SKILL_MAGIC_LEVEL]; + if(Actor->Type == PLAYER && !CheckRight(Actor->ID, ALL_SPELLS)){ + TSkill *MagicLevel = Actor->Skills[SKILL_MAGIC_LEVEL]; if(MagicLevel == NULL){ error("CheckLevel: Kein Skill MAGLEVEL.\n"); throw ERROR; @@ -702,20 +698,20 @@ void CheckRuneLevel(TCreature *Creature, int SpellNr){ } } -void CheckMagicItem(TCreature *Creature, ObjectType Type){ - if(Creature == NULL){ +void CheckMagicItem(TCreature *Actor, ObjectType Type){ + if(Actor == NULL){ error("CheckMagicObject: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } - if(Creature->Type == PLAYER && !CheckRight(Creature->ID, ALL_SPELLS) - && CountInventoryObjects(Creature->ID, Type, 0) == 0){ + if(Actor->Type == PLAYER && !CheckRight(Actor->ID, ALL_SPELLS) + && CountInventoryObjects(Actor->ID, Type, 0) == 0){ throw MAGICITEM; } } -void CheckRing(TCreature *Creature, int SpellNr){ - if(Creature == NULL){ +void CheckRing(TCreature *Actor, int SpellNr){ + if(Actor == NULL){ error("CheckRing: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } @@ -723,27 +719,27 @@ void CheckRing(TCreature *Creature, int SpellNr){ // TODO(fusion): Not sure why this was present in the original function or // what is the purpose of this function. #if 0 - if(Creature->Type == PLAYER){ - CheckRight(Creature->ID, ALL_SPELLS); + if(Actor->Type == PLAYER){ + CheckRight(Actor->ID, ALL_SPELLS); } #endif } -void CheckAffectedPlayers(TCreature *Creature, int x, int y, int z){ - if(Creature == NULL){ +void CheckAffectedPlayers(TCreature *Actor, int x, int y, int z){ + if(Actor == NULL){ error("CheckAffectedPlayers: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } if(WorldType == NORMAL - && Creature->Type == PLAYER - && Creature->Combat.SecureMode == SECURE_MODE_ENABLED){ + && Actor->Type == PLAYER + && Actor->Combat.SecureMode == SECURE_MODE_ENABLED){ Object Obj = GetFirstObject(x, y, z); while(Obj != NONE){ if(Obj.getObjectType().isCreatureContainer()){ uint32 TargetID = Obj.getCreatureID(); - if(IsCreaturePlayer(TargetID) && Creature->ID != TargetID - && !((TPlayer*)Creature)->IsAttackJustified(TargetID)){ + if(IsCreaturePlayer(TargetID) && Actor->ID != TargetID + && !((TPlayer*)Actor)->IsAttackJustified(TargetID)){ throw SECUREMODE; } } @@ -752,29 +748,29 @@ void CheckAffectedPlayers(TCreature *Creature, int x, int y, int z){ } } -void CheckMana(TCreature *Creature, int ManaPoints, int SoulPoints, int Delay){ - if(Creature == NULL){ +void CheckMana(TCreature *Actor, int ManaPoints, int SoulPoints, int Delay){ + if(Actor == NULL){ error("CheckMana: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } - if(Creature->Type != PLAYER || ManaPoints < 0){ + if(Actor->Type != PLAYER || ManaPoints < 0){ return; } - TSkill *Mana = Creature->Skills[SKILL_MANA]; + TSkill *Mana = Actor->Skills[SKILL_MANA]; if(Mana == NULL){ error("CheckMana: Kein Skill MANA!\n"); throw ERROR; } - TSkill *Soul = Creature->Skills[SKILL_SOUL]; + TSkill *Soul = Actor->Skills[SKILL_SOUL]; if(Soul == NULL){ error("CheckMana: Kein Skill SOULPOINTS!\n"); throw ERROR; } - if(!CheckRight(Creature->ID, UNLIMITED_MANA)){ + if(!CheckRight(Actor->ID, UNLIMITED_MANA)){ if(Mana->Get() < ManaPoints){ throw NOTENOUGHMANA; } @@ -788,23 +784,23 @@ void CheckMana(TCreature *Creature, int ManaPoints, int SoulPoints, int Delay){ } if(ManaPoints > 0){ - Creature->Skills[SKILL_MAGIC_LEVEL]->Increase(ManaPoints); + Actor->Skills[SKILL_MAGIC_LEVEL]->Increase(ManaPoints); } uint32 EarliestSpellTime = ServerMilliseconds + Delay; - if(Creature->EarliestSpellTime < EarliestSpellTime){ - Creature->EarliestSpellTime = EarliestSpellTime; + if(Actor->EarliestSpellTime < EarliestSpellTime){ + Actor->EarliestSpellTime = EarliestSpellTime; } } -int ComputeDamage(TCreature *Creature, int SpellNr, int Damage, int Variation){ +int ComputeDamage(TCreature *Actor, int SpellNr, int Damage, int Variation){ if(Variation != 0){ Damage += random(-Variation, Variation); } - if(Creature != NULL && Creature->Type == PLAYER){ - int Level = Creature->Skills[SKILL_LEVEL]->Get(); - int MagicLevel = Creature->Skills[SKILL_MAGIC_LEVEL]->Get(); + if(Actor != NULL && Actor->Type == PLAYER){ + int Level = Actor->Skills[SKILL_LEVEL]->Get(); + int MagicLevel = Actor->Skills[SKILL_MAGIC_LEVEL]->Get(); int Multiplier = Level * 2 + MagicLevel * 3; if(SpellNr != 0){ if((SpellList[SpellNr].Flags & 4) != 0 && Multiplier > 100){ @@ -830,22 +826,22 @@ bool IsAggressiveSpell(int SpellNr){ return (SpellList[SpellNr].Flags & 1) != 0; } -void MassCombat(TCreature *Creature, Object Target, int ManaPoints, int SoulPoints, +void MassCombat(TCreature *Actor, Object Target, int ManaPoints, int SoulPoints, int Damage, int Effect, int Radius, int DamageType, int Animation){ if(!Target.exists()){ error("MassCombat: Übergebenes Ziel existiert nicht.\n"); throw ERROR; } - if(Creature != NULL){ + if(Actor != NULL){ error("MassCombat: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } int TargetX, TargetY, TargetZ; GetObjectCoordinates(Target, &TargetX, &TargetY, &TargetZ); - CheckAffectedPlayers(Creature, TargetX, TargetY, TargetZ); - if(!ThrowPossible(Creature->posx, Creature->posy, Creature->posz, + CheckAffectedPlayers(Actor, TargetX, TargetY, TargetZ); + if(!ThrowPossible(Actor->posx, Actor->posy, Actor->posz, TargetX, TargetY, TargetZ, 0)){ throw CANNOTTHROW; } @@ -854,16 +850,16 @@ void MassCombat(TCreature *Creature, Object Target, int ManaPoints, int SoulPoin if(WorldType == PVP_ENFORCED){ Delay = 1000; } - CheckMana(Creature, ManaPoints, SoulPoints, Delay); + CheckMana(Actor, ManaPoints, SoulPoints, Delay); - TDamageImpact Impact(Creature, DamageType, Damage, false); - CircleShapeSpell(Creature, TargetX, TargetY, TargetZ, + TDamageImpact Impact(Actor, DamageType, Damage, false); + CircleShapeSpell(Actor, TargetX, TargetY, TargetZ, INT_MAX, Animation, Radius, &Impact, Effect); } -void AngleCombat(TCreature *Creature, int ManaPoints, int SoulPoints, +void AngleCombat(TCreature *Actor, int ManaPoints, int SoulPoints, int Damage, int Effect, int Range, int Angle, int DamageType){ - if(Creature == NULL){ + if(Actor == NULL){ error("AngleCombat: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } @@ -872,20 +868,20 @@ void AngleCombat(TCreature *Creature, int ManaPoints, int SoulPoints, if(WorldType == PVP_ENFORCED || (Range == 1 && Angle == 0)){ Delay = 1000; } - CheckMana(Creature, ManaPoints, SoulPoints, Delay); + CheckMana(Actor, ManaPoints, SoulPoints, Delay); - TDamageImpact Impact(Creature, DamageType, Damage, false); - AngleShapeSpell(Creature, Angle, Range, &Impact, Effect); + TDamageImpact Impact(Actor, DamageType, Damage, false); + AngleShapeSpell(Actor, Angle, Range, &Impact, Effect); } -void Combat(TCreature *Creature, Object Target, int ManaPoints, int SoulPoints, - int Damage,int Effect, int Animation, int DamageType){ +void Combat(TCreature *Actor, Object Target, int ManaPoints, int SoulPoints, + int Damage, int Effect, int Animation, int DamageType){ if(!Target.exists()){ error("Combat: Übergebenes Ziel existiert nicht.\n"); throw ERROR; } - if(Creature == NULL){ + if(Actor == NULL){ error("Combat: Übergebene Kreatur existiert nicht.\n"); throw ERROR; } @@ -900,8 +896,8 @@ void Combat(TCreature *Creature, Object Target, int ManaPoints, int SoulPoints, throw NOCREATURE; } - CheckAffectedPlayers(Creature, TargetX, TargetY, TargetZ); - if(!ThrowPossible(Creature->posx, Creature->posy, Creature->posz, + CheckAffectedPlayers(Actor, TargetX, TargetY, TargetZ); + if(!ThrowPossible(Actor->posx, Actor->posy, Actor->posz, TargetX, TargetY, TargetZ, 0)){ throw CANNOTTHROW; } @@ -910,16 +906,365 @@ void Combat(TCreature *Creature, Object Target, int ManaPoints, int SoulPoints, if(WorldType == PVP_ENFORCED){ Delay = 1000; } - CheckMana(Creature, ManaPoints, SoulPoints, Delay); + CheckMana(Actor, ManaPoints, SoulPoints, Delay); - TDamageImpact Impact(Creature, DamageType, Damage, false); - CircleShapeSpell(Creature, TargetX, TargetY, TargetZ, + TDamageImpact Impact(Actor, DamageType, Damage, false); + CircleShapeSpell(Actor, TargetX, TargetY, TargetZ, INT_MAX, Animation, 0, &Impact, Effect); } // Spell Functions // ============================================================================= -// TODO +void KillAllMonsters(TCreature *Actor, int Effect, int Radius){ + if(Actor == NULL){ + error("KillAllMonsters: Übergebene Kreatur existiert nicht.\n"); + throw ERROR; + } + + if(Actor->Type == PLAYER && !CheckRight(Actor->ID, CREATE_MONSTERS)){ + return; + } + + // TODO(fusion): This is similar to `ExecuteCircleSpell` which makes me think + // there is perhaps a common denominator? + if(Radius >= NARRAY(Circle)){ + Radius = NARRAY(Circle) - 1; + } + + int CenterX = Actor->posx; + int CenterY = Actor->posy; + int CenterZ = Actor->posz; + for(int R = 0; R <= Radius; R += 1){ + int CirclePoints = Circle[R].Count; + for(int Point = 0; Point < CirclePoints; Point += 1){ + int FieldX = CenterX + Circle[R].x[Point]; + int FieldY = CenterY + Circle[R].y[Point]; + int FieldZ = CenterZ; + + if(IsProtectionZone(FieldX, FieldY, FieldZ)){ + continue; + } + + if(!ThrowPossible(CenterX, CenterY, CenterZ, FieldX, FieldY, FieldZ, 0)){ + continue; + } + + Object Obj = GetFirstObject(FieldX, FieldY, FieldZ); + while(Obj != NONE){ + if(Obj.getObjectType().isCreatureContainer()){ + TCreature *Victim = GetCreature(Obj); + if(Victim == NULL){ + error("KillAllMonsters: Ungültige Kreatur.\n"); + }else if(Actor != Victim && Victim->Type == MONSTER){ + print(3, "Töte %s...\n", Victim->Name); + Victim->Skills[SKILL_HITPOINTS]->Set(0); + Victim->Death(); + } + } + Obj = Obj.getNextObject(); + } + + if(Effect != EFFECT_NONE){ + GraphicalEffect(FieldX, FieldY, FieldZ, Effect); + } + } + } +} + +void CreateField(TCreature *Actor, Object Target, int ManaPoints, int SoulPoints, int FieldType){ + if(Actor == NULL){ + error("CreateField: Ungültige Kreatur übergeben.\n"); + throw ERROR; + } + + if(!Target.exists()){ + error("CreateField: Übergebenes Objekt existiert nicht.\n"); + throw ERROR; + } + + int TargetX, TargetY, TargetZ; + GetObjectCoordinates(Target, &TargetX, &TargetY, &TargetZ); + if(!FieldPossible(TargetX, TargetY, TargetZ, FieldType)){ + throw NOROOM; + } + + CheckAffectedPlayers(Actor, TargetX, TargetY, TargetZ); + if(!ThrowPossible(Actor->posx, Actor->posy, Actor->posz, + TargetX, TargetY, TargetZ, 0)){ + throw CANNOTTHROW; + } + + int Delay = 2000; + if(WorldType == PVP_ENFORCED){ + Delay = 1000; + } + CheckMana(Actor, ManaPoints, SoulPoints, Delay); + + int Animation = ANIMATION_ENERGY; + if(FieldType == 1){ + Animation = ANIMATION_FIRE; + } + Missile(Actor->CrObject, Target, Animation); + + bool Peaceful = (WorldType == NON_PVP && Actor->IsPeaceful()); + CreateField(TargetX, TargetY, TargetZ, FieldType, Actor->ID, Peaceful); + + // TODO(fusion): Probably damaging fields? + if(FieldType == 1 || FieldType == 2 || FieldType == 3){ + Actor->BlockLogout(60, true); + } +} + +void CreateField(TCreature *Actor, int ManaPoints, int SoulPoints, int FieldType){ + if(Actor == NULL){ + error("CreateField: Ungültige Kreatur übergeben.\n"); + throw ERROR; + } + + int TargetX = Actor->posx; + int TargetY = Actor->posy; + int TargetZ = Actor->posz; + switch(Actor->Direction){ + case DIRECTION_NORTH: TargetY -= 1; break; + case DIRECTION_EAST: TargetX += 1; break; + case DIRECTION_SOUTH: TargetY += 1; break; + case DIRECTION_WEST: TargetX -= 1; break; + } + + if(Actor->Type == PLAYER && !CheckRight(Actor->ID, ATTACK_EVERYWHERE) + && IsProtectionZone(TargetX, TargetY, TargetZ)){ + throw PROTECTIONZONE; + } + + Object Target = GetMapContainer(TargetX, TargetY, TargetZ); + CreateField(Actor, Target, ManaPoints, SoulPoints, FieldType); +} + +void MassCreateField(TCreature *Actor, Object Target, + int ManaPoints, int SoulPoints, int FieldType, int Radius){ + if(Actor == NULL){ + error("MassCreateField: Ungültige Kreatur übergeben.\n"); + throw ERROR; + } + + if(!Target.exists()){ + error("MassCreateField: Übergebenes Objekt existiert nicht.\n"); + throw ERROR; + } + + int TargetX, TargetY, TargetZ; + GetObjectCoordinates(Target, &TargetX, &TargetY, &TargetZ); + CheckAffectedPlayers(Actor, TargetX, TargetY, TargetZ); + if(!ThrowPossible(Actor->posx, Actor->posy, Actor->posz, + TargetX, TargetY, TargetZ, 0)){ + throw CANNOTTHROW; + } + + int Delay = 2000; + if(WorldType == PVP_ENFORCED){ + Delay = 1000; + } + CheckMana(Actor, ManaPoints, SoulPoints, Delay); + + if(Actor->posx != TargetX || Actor->posy != TargetY || Actor->posz != TargetZ){ + int Animation = ANIMATION_ENERGY; + if(FieldType == 1){ + Animation = ANIMATION_FIRE; + } + Missile(Actor->CrObject, Target, Animation); + } + + // TODO(fusion): Same as `KillAllMonsters`. Perhaps the `ExecuteCircleSpell` + // function is getting inlined and TFieldImpact devirtualized? + if(Radius >= NARRAY(Circle)){ + Radius = NARRAY(Circle) - 1; + } + + bool Peaceful = (WorldType == NON_PVP && Actor->IsPeaceful()); + for(int R = 0; R <= Radius; R += 1){ + int CirclePoints = Circle[R].Count; + for(int Point = 0; Point < CirclePoints; Point += 1){ + int FieldX = TargetX + Circle[R].x[Point]; + int FieldY = TargetY + Circle[R].y[Point]; + int FieldZ = TargetZ; + + if(IsProtectionZone(FieldX, FieldY, FieldZ)){ + continue; + } + + if(!ThrowPossible(TargetX, TargetY, TargetZ, FieldX, FieldY, FieldZ, 0)){ + continue; + } + + CreateField(FieldX, FieldY, FieldZ, FieldType, Actor->ID, Peaceful); + } + } + + if(FieldType == 1 || FieldType == 2 || FieldType == 3){ + Actor->BlockLogout(60, true); + } +} + +void CreateFieldWall(TCreature *Actor, Object Target, + int ManaPoints, int SoulPoints, int FieldType, int Width){ + if(Actor == NULL){ + error("CreateFieldWall: Ungültige Kreatur übergeben.\n"); + throw ERROR; + } + + if(!Target.exists()){ + error("CreateFieldWall: Übergebenes Objekt existiert nicht.\n"); + throw ERROR; + } + + int ActorX = Actor->posx; + int ActorY = Actor->posy; + int ActorZ = Actor->posz; + int TargetX, TargetY, TargetZ; + GetObjectCoordinates(Target, &TargetX, &TargetY, &TargetZ); + CheckAffectedPlayers(Actor, TargetX, TargetY, TargetZ); + if(!ThrowPossible(ActorX, ActorY, ActorZ, TargetX, TargetY, TargetZ, 0)){ + throw CANNOTTHROW; + } + + int Delay = 2000; + if(WorldType == PVP_ENFORCED){ + Delay = 1000; + } + CheckMana(Actor, ManaPoints, SoulPoints, Delay); + + if(ActorX != TargetX || ActorY != TargetY || ActorZ != TargetZ){ + int Animation = ANIMATION_ENERGY; + if(FieldType == 1){ + Animation = ANIMATION_FIRE; + } + Missile(Actor->CrObject, Target, Animation); + } + + int StepX, StepY; + int Direction = GetDirection(TargetX - ActorX, TargetY - ActorY); + switch(Direction){ + case DIRECTION_NORTH: + case DIRECTION_SOUTH:{ + StepX = 1; + StepY = 0; + break; + } + + case DIRECTION_EAST: + case DIRECTION_WEST:{ + StepX = 0; + StepY = 1; + break; + } + + case DIRECTION_SOUTHWEST: + case DIRECTION_NORTHEAST:{ + StepX = 1; + StepY = 1; + break; + } + + case DIRECTION_SOUTHEAST: + case DIRECTION_NORTHWEST:{ + StepX = -1; + StepY = 1; + break; + } + + case DIRECTION_INVALID:{ + throw NOROOM; + } + + default:{ + error("CreateFieldWall: Ungültige Richtung %d.\n", Direction); + throw ERROR; + } + } + + bool Peaceful = (WorldType == NON_PVP && Actor->IsPeaceful()); + CreateField(TargetX, TargetY, TargetZ, FieldType, Actor->ID, Peaceful); + for(int i = 1; i <= Width; i += 1){ + // NOTE(fusion): Forward. + { + int FieldX = TargetX + i * StepX; + int FieldY = TargetY + i * StepY; + int FieldZ = TargetZ; + if(ThrowPossible(ActorX, ActorY, ActorZ, FieldX, FieldY, FieldZ, 0) + && !IsProtectionZone(FieldX, FieldY, FieldZ)){ + CreateField(FieldX, FieldY, FieldZ, FieldType, Actor->ID, Peaceful); + } + } + + // NOTE(fusion): Forward diagonal. + if(StepX != 0 && StepY != 0){ + int FieldX = TargetX + i * StepX; + int FieldY = TargetY + (i - 1) * StepY; + int FieldZ = TargetZ; + if(ThrowPossible(ActorX, ActorY, ActorZ, FieldX, FieldY, FieldZ, 0) + && !IsProtectionZone(FieldX, FieldY, FieldZ)){ + CreateField(FieldX, FieldY, FieldZ, FieldType, Actor->ID, Peaceful); + } + } + + // NOTE(fusion): Backward. + { + int FieldX = TargetX - i * StepX; + int FieldY = TargetY - i * StepY; + int FieldZ = TargetZ; + if(ThrowPossible(ActorX, ActorY, ActorZ, FieldX, FieldY, FieldZ, 0) + && !IsProtectionZone(FieldX, FieldY, FieldZ)){ + CreateField(FieldX, FieldY, FieldZ, FieldType, Actor->ID, Peaceful); + } + } + + // NOTE(fusion): Backward Diagonal. + if(StepX != 0 && StepY != 0){ + int FieldX = TargetX - i * StepX; + int FieldY = TargetY - (i - 1) * StepY; + int FieldZ = TargetZ; + if(ThrowPossible(ActorX, ActorY, ActorZ, FieldX, FieldY, FieldZ, 0) + && !IsProtectionZone(FieldX, FieldY, FieldZ)){ + CreateField(FieldX, FieldY, FieldZ, FieldType, Actor->ID, Peaceful); + } + } + } + + if(FieldType == 1 || FieldType == 2 || FieldType == 3){ + Actor->BlockLogout(60, true); + } +} + +void DeleteField(TCreature *Actor, Object Target, int ManaPoints, int SoulPoints){ + if(Actor == NULL){ + error("DeleteField: Ungültige Kreatur übergeben.\n"); + throw ERROR; + } + + if(!Target.exists()){ + error("DeleteField: Übergebenes Objekt existiert nicht.\n"); + throw ERROR; + } + + int TargetX, TargetY, TargetZ; + GetObjectCoordinates(Target, &TargetX, &TargetY, &TargetZ); + if(!FieldPossible(TargetX, TargetY, TargetZ, 0)){ + throw NOROOM; + } + + CheckMana(Actor, ManaPoints, SoulPoints, 1000); + + Object Obj = GetFirstObject(TargetX, TargetY, TargetZ); + while(Obj != NONE){ + Object Next = Obj.getNextObject(); + if(Obj.getObjectType().getFlag(MAGICFIELD)){ + Delete(Obj, -1); + } + Obj = Next; + } + + GraphicalEffect(TargetX, TargetY, TargetZ, EFFECT_POFF); +} // Magic Init Functions // ============================================================================= diff --git a/src/stubs.hh b/src/stubs.hh index c254ec7..0d7bbd0 100644 --- a/src/stubs.hh +++ b/src/stubs.hh @@ -32,6 +32,7 @@ extern void CreateMonster(int Race, int x, int y, int z, int Home, uint32 Master extern void CreatePlayerList(bool Online); extern void CreatePool(Object Con, ObjectType Type, uint32 Value); extern void Delete(Object Obj, int Count); +extern bool FieldPossible(int x, int y, int z, int FieldType); extern Object GetBodyObject(uint32 CreatureID, int Position); extern TCreature *GetCreature(uint32 CreatureID); extern TCreature *GetCreature(Object Obj); |
