aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-06-04 00:55:23 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-06-04 00:55:23 -0300
commitf898f3bb674b8d7d28ebf170769a78485f2464cf (patch)
tree53e1646583931ec63f21aa61ec9bfb5994145eb4
parentdbee845a5cfb6ca419604ac984d1845440f76007 (diff)
downloadgame-f898f3bb674b8d7d28ebf170769a78485f2464cf.tar.gz
game-f898f3bb674b8d7d28ebf170769a78485f2464cf.zip
more spells
-rw-r--r--reference/game.c1269
-rw-r--r--src/info.hh5
-rw-r--r--src/magic.cc682
-rw-r--r--src/player.hh5
-rw-r--r--src/stubs.hh11
5 files changed, 682 insertions, 1290 deletions
diff --git a/reference/game.c b/reference/game.c
index b469c0e..15b71f3 100644
--- a/reference/game.c
+++ b/reference/game.c
@@ -20852,1275 +20852,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
return;
}
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void CreatureIllusion(void)
-
-{
- bool bVar1;
- char *pcVar2;
- int iVar3;
- undefined4 *puVar4;
- int i;
- int iVar5;
- int Race;
- int Race_00;
- TCreature *in_stack_00000004;
- int in_stack_00000008;
- int in_stack_0000000c;
- char *in_stack_00000010;
- Object local_3c [6];
- int local_24;
- anon_union_4_2_730cd3ca_for_TOutfit_2 local_20;
-
- if (in_stack_00000004 == (TCreature *)0x0) {
- pcVar2 = &DAT_080fc0c0;
- }
- else {
- if (in_stack_00000010 != (char *)0x0) {
- iVar5 = 1;
- do {
- // try { // try from 08085c5f to 08085db2 has its CatchHandler @ 08085dd0
- pcVar2 = GetRaceName(iVar5);
- iVar3 = stricmp(in_stack_00000010,pcVar2,-1);
- Race_00 = iVar5;
- if (iVar3 == 0) break;
- iVar5 = iVar5 + 1;
- Race_00 = 0;
- } while (iVar5 < 0x200);
- if (Race_00 == 0) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x19;
- }
- else {
- bVar1 = GetRaceNoIllusion(Race_00);
- if (!bVar1) {
- CheckMana(in_stack_00000004,in_stack_00000008,in_stack_0000000c,1000);
- iVar5 = TSkill::Get((in_stack_00000004->super_TSkillBase).Skills[0x10]);
- if (iVar5 == 0) {
- GetRaceOutfit((int)&local_24);
- (in_stack_00000004->Outfit).OutfitID = local_24;
- (in_stack_00000004->Outfit).field_1 = local_20;
- TSkillBase::SetTimer(&in_stack_00000004->super_TSkillBase);
- }
- local_3c[0].ObjectID = (in_stack_00000004->CrObject).ObjectID;
- GraphicalEffect(local_3c,0xd);
- return;
- }
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 1;
- }
- goto LAB_08085d6e;
- }
- pcVar2 = &DAT_080fc080;
- }
- error(pcVar2);
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
-LAB_08085d6e:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void ObjectIllusion(void)
-
-{
- bool bVar1;
- int iVar2;
- ulong uVar3;
- undefined4 *puVar4;
- TCreature *in_stack_00000004;
- int in_stack_00000008;
- int in_stack_0000000c;
- Object *in_stack_00000010;
- char *Text;
- Object local_2c [7];
-
- if (in_stack_00000004 == (TCreature *)0x0) {
- Text = &DAT_080fc140;
- }
- else {
- // try { // try from 08085e10 to 08085f85 has its CatchHandler @ 08085fa3
- bVar1 = Object::exists(in_stack_00000010);
- if (bVar1) {
- Object::getObjectType(local_2c);
- if (local_2c[0].ObjectID != 99) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,UNMOVE);
- if (!bVar1) {
- CheckMana(in_stack_00000004,in_stack_00000008,in_stack_0000000c,1000);
- iVar2 = TSkill::Get((in_stack_00000004->super_TSkillBase).Skills[0x10]);
- if (iVar2 == 0) {
- (in_stack_00000004->Outfit).OutfitID = 0;
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,DISGUISE);
- if (bVar1) {
- Object::getObjectType(local_2c);
- uVar3 = ObjectType::getAttribute((ObjectType *)local_2c,DISGUISETARGET);
- local_2c[0].ObjectID._0_2_ = (ushort)uVar3;
- }
- else {
- Object::getObjectType(local_2c);
- }
- (in_stack_00000004->Outfit).field_1.ObjectType =
- (ushort)local_2c[0].ObjectID;
- TSkillBase::SetTimer(&in_stack_00000004->super_TSkillBase);
- }
- local_2c[0].ObjectID = (in_stack_00000004->CrObject).ObjectID;
- GraphicalEffect(local_2c,0xd);
- return;
- }
- }
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 2;
- goto LAB_08085f62;
- }
- Text = &DAT_080fc100;
- }
- error(Text);
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
-LAB_08085f62:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-void ChangeData(TCreature *cr,char *Param)
-
-{
- bool bVar1;
- uint Value;
- char *pcVar2;
- undefined4 *puVar3;
- INSTANCEATTRIBUTE Attribute;
- Object local_6c [4];
- Object local_5c [4];
- Object local_4c [4];
- ulong local_3c;
- Object Obj2;
- ulong local_2c;
- Object Obj;
-
- if (cr == (TCreature *)0x0) {
- pcVar2 = &DAT_080fc260;
- }
- else if (Param == (char *)0x0) {
- pcVar2 = &DAT_080fc220;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 08086004 to 080863b4 has its CatchHandler @ 080863c7
- bVar1 = CheckRight(cr->ID,CREATE_OBJECTS);
- if (bVar1) {
- GetBodyObject((ulong)&local_2c,cr->ID);
- GetBodyObject((ulong)&local_3c,cr->ID);
- bVar1 = false;
- local_4c[0].ObjectID = NONE.ObjectID;
- local_5c[0].ObjectID = NONE.ObjectID;
- if ((local_2c != NONE.ObjectID) &&
- (local_6c[0].ObjectID = NONE.ObjectID, local_3c != NONE.ObjectID)) {
- bVar1 = true;
- }
- if (bVar1) {
- SendMessage(cr->Connection,0x17,"First drop one object.");
- }
- else {
- if (local_3c != NONE.ObjectID) {
- local_4c[0].ObjectID = local_3c;
- local_2c = local_3c;
- }
- local_6c[0].ObjectID = NONE.ObjectID;
- local_5c[0].ObjectID = local_4c[0].ObjectID;
- if (local_2c == NONE.ObjectID) {
- GetFirstObject();
- local_2c = local_4c[0].ObjectID;
- bVar1 = local_4c[0].ObjectID != NONE.ObjectID;
- local_5c[0].ObjectID = NONE.ObjectID;
- local_4c[0].ObjectID = NONE.ObjectID;
- if (bVar1) {
- do {
- local_5c[0].ObjectID = NONE.ObjectID;
- local_4c[0].ObjectID = NONE.ObjectID;
- Object::getObjectType(local_5c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_5c,KEYDOOR);
- if (bVar1) break;
- Object::getNextObject(local_4c);
- local_2c = local_4c[0].ObjectID;
- local_5c[0] = (Object)NONE.ObjectID;
- bVar1 = local_4c[0].ObjectID != NONE.ObjectID;
- local_4c[0].ObjectID = local_5c[0].ObjectID;
- } while (bVar1);
- }
- }
- if (local_2c != NONE.ObjectID) {
- local_6c[0].ObjectID = NONE.ObjectID;
- Value = __strtol_internal(Param,0,10,0);
- Object::getObjectType(local_6c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_6c,LIQUIDCONTAINER);
- if (bVar1) {
- Attribute = CONTAINERLIQUIDTYPE;
- }
- else {
- Object::getObjectType(local_6c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_6c,KEY);
- if ((bVar1) && (Value != 0)) {
- Attribute = KEYNUMBER;
- }
- else {
- Object::getObjectType(local_6c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_6c,KEYDOOR);
- if ((bVar1) && (Value != 0)) {
- Attribute = KEYHOLENUMBER;
- }
- else {
- Object::getObjectType(local_6c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_6c,CUMULATIVE);
- if (((bVar1) && (Value != 0)) && (Value < 0x65)) {
- Attribute = AMOUNT;
- }
- else {
- Object::getObjectType(local_6c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_6c,RUNE);
- if (((!bVar1) || (Value == 0)) || (99 < Value)) {
- local_6c[0].ObjectID = local_2c;
- pcVar2 = GetName(local_6c);
- SendMessage(cr->Connection,0x17,
- "You can\'t change %s in this way.",pcVar2);
- return;
- }
- Attribute = CHARGES;
- }
- }
- }
- }
- local_6c[0].ObjectID = local_2c;
- Change(local_6c,Attribute,Value);
- local_6c[0].ObjectID = (cr->CrObject).ObjectID;
- GraphicalEffect(local_6c,0xf);
- }
- }
- }
- return;
- }
- pcVar2 = "ChangeData: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(pcVar2);
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void EnchantObject(void)
-
-{
- bool bVar1;
- undefined4 *puVar2;
- bool bVar3;
- TCreature *in_stack_00000004;
- int in_stack_00000008;
- int in_stack_0000000c;
- int *in_stack_00000010;
- int *in_stack_00000014;
- ulong Position;
- undefined4 uVar4;
- Object local_9c [4];
- Object local_8c [4];
- ulong local_7c [4];
- Object local_6c [4];
- ObjectType local_5c [4];
- Object local_4c [4];
- ulong local_3c;
- ulong local_2c;
- Object Obj;
-
- if (in_stack_00000004 == (TCreature *)0x0) {
- error(&DAT_080fc2a0);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
- goto LAB_08086535;
- }
- // try { // try from 08086418 to 080865e9 has its CatchHandler @ 08086601
- GetBodyObject((ulong)&local_2c,in_stack_00000004->ID);
- bVar1 = false;
- local_3c = NONE.ObjectID;
- if (local_2c == NONE.ObjectID) {
-LAB_08086438:
- bVar1 = true;
- }
- else {
- Object::getObjectType(local_4c);
- ObjectType::setTypeID(local_5c,*in_stack_00000010);
- ObjectType::setTypeID((ObjectType *)local_6c,local_5c[0].TypeID);
- if (local_4c[0].ObjectID != local_6c[0].ObjectID) goto LAB_08086438;
- }
- if (!bVar1) goto LAB_0808644c;
- uVar4 = 6;
- Position = in_stack_00000004->ID;
- GetBodyObject((ulong)local_7c,Position);
- bVar1 = false;
- local_2c = local_7c[0];
- bVar3 = local_7c[0] == NONE.ObjectID;
- local_6c[0].ObjectID = local_7c[0];
- local_7c[0] = NONE.ObjectID;
- if (bVar3) {
-LAB_0808650f:
- local_8c[0].ObjectID = Position;
- bVar1 = true;
- }
- else {
- Object::getObjectType(local_6c);
- ObjectType::setTypeID((ObjectType *)local_8c,*in_stack_00000010);
- ObjectType::setTypeID((ObjectType *)local_9c,local_8c[0].ObjectID);
- Position = local_8c[0].ObjectID;
- if (local_6c[0].ObjectID != local_9c[0].ObjectID) goto LAB_0808650f;
- }
- if (bVar1) {
- puVar2 = (undefined4 *)__cxa_allocate_exception(4,local_8c[0].ObjectID,uVar4);
- *puVar2 = 0x22;
-LAB_08086535:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
- }
-LAB_0808644c:
- CheckMana(in_stack_00000004,in_stack_00000008,in_stack_0000000c,1000);
- ObjectType::setTypeID((ObjectType *)local_9c,*in_stack_00000014);
- local_8c[0].ObjectID = local_2c;
- Change(local_8c,(ObjectType *)local_9c,0);
- local_9c[0].ObjectID = (in_stack_00000004->CrObject).ObjectID;
- GraphicalEffect(local_9c,0xf);
- return;
-}
-
-
-
-void Convince(TCreature *master,TCreature *slave)
-
-{
- bool bVar1;
- int Mana;
- int iVar2;
- undefined4 *puVar3;
- int Delay;
- Object local_2c [7];
-
- if (slave->Type == MONSTER) {
- if ((master->Type == PLAYER) && (1 < master->SummonedCreatures)) {
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0x38;
- goto LAB_08086716;
- }
- if (WorldType == NON_PVP) {
- iVar2 = (*master->_vptr_TCreature[4])(master);
- if ((char)iVar2 != '\0') {
- iVar2 = (*slave->_vptr_TCreature[4])(slave);
- if ((char)iVar2 != '\0') goto LAB_08086750;
- }
- }
- // try { // try from 0808666f to 08086747 has its CatchHandler @ 08086778
- bVar1 = GetRaceNoConvince(slave->Race);
- if (!bVar1) {
- iVar2 = GetRaceSummonCost(slave->Race);
- Delay = 1000;
- if (WorldType != PVP_ENFORCED) {
- Delay = 2000;
- }
- CheckMana(master,iVar2,0,Delay);
- ConvinceMonster(master,slave);
- local_2c[0].ObjectID = (master->CrObject).ObjectID;
- GraphicalEffect(local_2c,0xd);
- local_2c[0].ObjectID = (slave->CrObject).ObjectID;
- GraphicalEffect(local_2c,10);
- return;
- }
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 1;
- }
- else {
-LAB_08086750:
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0x2b;
- }
-LAB_08086716:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void Challenge(void)
-
-{
- bool bVar1;
- TCreature *Monster;
- int dy;
- int iVar2;
- int dx;
- int zx;
- TCreature *in_stack_00000004;
- int in_stack_00000008;
- int in_stack_0000000c;
- int in_stack_00000010;
- int iVar3;
- ObjectType *pOVar4;
- int local_60;
- int *local_5c;
- int local_54;
- int j;
- int i;
- ObjectType local_3c [4];
- ulong local_2c;
- Object Obj;
-
- // try { // try from 080867b5 to 08086931 has its CatchHandler @ 08086937
- CheckMana(in_stack_00000004,in_stack_00000008,in_stack_0000000c,1000);
- j = 0;
- if (-1 < in_stack_00000010) {
- local_5c = &Circle[0].Count;
- local_60 = 0;
- do {
- local_54 = 0;
- iVar2 = local_60;
- if (0 < *local_5c) {
- do {
- zx = in_stack_00000004->posx + Circle[0].x[iVar2 + local_54];
- iVar2 = in_stack_00000004->posy + Circle[0].y[iVar2 + local_54];
- bVar1 = ThrowPossible(in_stack_00000004->posx,in_stack_00000004->posy,
- in_stack_00000004->posz,zx,iVar2,in_stack_00000004->posz,0
- );
- if (bVar1) {
- GraphicalEffect();
- ObjectType::setTypeID(local_3c,99);
- pOVar4 = local_3c;
- iVar3 = in_stack_00000004->posz;
- GetFirstSpecObject();
- i = NONE.ObjectID;
- local_3c[0].TypeID = NONE.ObjectID;
- if (local_2c != NONE.ObjectID) {
- i = local_2c;
- Monster = GetCreature((Object *)&i);
- if (Monster == (TCreature *)0x0) {
- error(&DAT_080fc2e0,zx,iVar2,iVar3,pOVar4);
- }
- else if (Monster->Type == MONSTER) {
- ChallengeMonster(in_stack_00000004,Monster);
- }
- }
- }
- local_54 = local_54 + 1;
- iVar2 = j * 0x41;
- } while (local_54 < *local_5c);
- }
- j = j + 1;
- local_5c = local_5c + 0x41;
- local_60 = local_60 + 0x41;
- } while (j <= in_stack_00000010);
- }
- return;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void FindPerson(void)
-
-{
- int iVar1;
- bool bVar2;
- int iVar3;
- undefined4 *puVar4;
- int *piVar5;
- TConnection *pTVar6;
- TCreature *in_stack_00000004;
- int in_stack_00000008;
- int in_stack_0000000c;
- char *in_stack_00000010;
- char *pcVar7;
- char *pcVar8;
- int Distance;
- int local_34;
- TPlayer *local_30;
- TPlayer *Opp;
-
- if (in_stack_00000004 == (TCreature *)0x0) {
- pcVar7 = &DAT_080fc440;
- }
- else if (in_stack_00000010 == (char *)0x0) {
- pcVar7 = &DAT_080fc400;
- }
- else if (in_stack_00000004->Type == PLAYER) {
- // try { // try from 08086994 to 08086c19 has its CatchHandler @ 08086cb8
- bVar2 = CheckRight(in_stack_00000004->ID,READ_GAMEMASTER_CHANNEL);
- iVar3 = IdentifyPlayer(in_stack_00000010,false,!bVar2,&local_30);
- if (iVar3 == -1) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x1b;
- goto LAB_08086c02;
- }
- if (iVar3 == -2) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x1c;
- goto LAB_08086c02;
- }
- if (local_30 != (TPlayer *)0x0) {
- CheckMana(in_stack_00000004,in_stack_00000008,in_stack_0000000c,1000);
- iVar3 = (local_30->super_TCreature).posx - in_stack_00000004->posx;
- local_34 = -iVar3;
- if (-1 < iVar3) {
- local_34 = iVar3;
- }
- iVar3 = (local_30->super_TCreature).posy - in_stack_00000004->posy;
- Distance = -iVar3;
- if (-1 < iVar3) {
- Distance = iVar3;
- }
- piVar5 = &Distance;
- if (Distance <= local_34) {
- piVar5 = &local_34;
- }
- iVar1 = *piVar5;
- if (iVar1 < 5) {
- iVar3 = (local_30->super_TCreature).posz;
- if (iVar3 < in_stack_00000004->posz) {
- pTVar6 = in_stack_00000004->Connection;
- pcVar7 = "%s is above you.";
- }
- else if (in_stack_00000004->posz < iVar3) {
- pTVar6 = in_stack_00000004->Connection;
- pcVar7 = "%s is below you.";
- }
- else {
- pTVar6 = in_stack_00000004->Connection;
- pcVar7 = "%s is standing next to you.";
- }
- SendMessage(pTVar6,0x16,pcVar7,(local_30->super_TCreature).Name);
- goto LAB_08086a85;
- }
- iVar3 = Direction((local_30->super_TCreature).posx - in_stack_00000004->posx,iVar3);
- switch(iVar3) {
- default:
- pcVar7 = "FindPerson: Richtung ist Null.\n";
- goto LAB_08086beb;
- case 1:
- pcVar7 = "east";
- break;
- case 2:
- pcVar7 = "north-east";
- break;
- case 3:
- pcVar7 = "north";
- break;
- case 4:
- pcVar7 = "north-west";
- break;
- case 5:
- pcVar7 = "west";
- break;
- case 6:
- pcVar7 = "south-west";
- break;
- case 7:
- pcVar7 = "south";
- break;
- case 8:
- pcVar7 = "south-east";
- }
- if (iVar1 < 100) {
- iVar3 = (local_30->super_TCreature).posz;
- if (iVar3 < in_stack_00000004->posz) {
- pTVar6 = in_stack_00000004->Connection;
- pcVar8 = "%s is on a higher level to the %s.";
- }
- else if (in_stack_00000004->posz < iVar3) {
- pTVar6 = in_stack_00000004->Connection;
- pcVar8 = "%s is on a lower level to the %s.";
- }
- else {
- pTVar6 = in_stack_00000004->Connection;
- pcVar8 = "%s is to the %s.";
- }
- SendMessage(pTVar6,0x16,pcVar8,(local_30->super_TCreature).Name,pcVar7);
- }
- else {
- pcVar8 = "very ";
- if (iVar1 < 0xfb) {
- pcVar8 = "";
- }
- SendMessage(in_stack_00000004->Connection,0x16,"%s is %sfar to the %s.",
- (local_30->super_TCreature).Name,pcVar8,pcVar7);
- }
-LAB_08086a85:
- Opp = (TPlayer *)(in_stack_00000004->CrObject).ObjectID;
- GraphicalEffect((Object *)&Opp,0xd);
- return;
- }
- pcVar7 = "FindPerson: Opp ist NULL.\n";
- }
- else {
- pcVar7 = "FindPerson: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
-LAB_08086beb:
- error(pcVar7);
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
-LAB_08086c02:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-void GetPosition(TCreature *cr)
-
-{
- bool bVar1;
- undefined4 *puVar2;
- char *Text;
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fc4e0;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 08086cff to 08086d83 has its CatchHandler @ 08086d90
- bVar1 = CheckRight(cr->ID,SHOW_COORDINATE);
- if (bVar1) {
- SendMessage(cr->Connection,0x13,"Your position is [%d,%d,%d].",cr->posx,cr->posy,
- cr->posz);
- }
- return;
- }
- Text = "GetPosition: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(Text);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
-void GetQuestValue(TCreature *cr,char *Param)
-
-{
- bool bVar1;
- int Number;
- int iVar2;
- undefined4 *puVar3;
- char *Text;
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fc5a0;
-LAB_08086e9c:
- error(Text);
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
- }
- if (Param == (char *)0x0) {
- error("GetQuestValue: Param ist NULL.\n");
- }
- else {
- if (cr->Type != PLAYER) {
- Text = "GetQuestValue: Zauberspruch kann nur von Spielern angewendet werden.\n";
- goto LAB_08086e9c;
- }
- // try { // try from 08086df1 to 08086ed6 has its CatchHandler @ 08086ee5
- bVar1 = CheckRight(cr->ID,CHANGE_SKILLS);
- if (bVar1) {
- Number = __strtol_internal(Param,0,10,0);
- bVar1 = false;
- if ((-1 < Number) && (Number < 500)) {
- bVar1 = true;
- }
- if (bVar1) {
- iVar2 = TPlayer::GetQuestValue((TPlayer *)cr,Number);
- SendMessage(cr->Connection,0x16,"Quest value %d is %d.",Number,iVar2);
- }
- else {
- SendMessage(cr->Connection,0x17,"Invalid quest number.");
- }
- }
- }
- return;
-}
-
-
-
-void SetQuestValue(TCreature *cr,char *Param1,char *Param2)
-
-{
- bool bVar1;
- int Number;
- int Value;
- undefined4 *puVar2;
- char *pcVar3;
-
- if (cr == (TCreature *)0x0) {
- pcVar3 = &DAT_080fc6c0;
-LAB_08087027:
- error(pcVar3);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
- }
- if (Param1 == (char *)0x0) {
- pcVar3 = "SetQuestValue: Param1 ist NULL.\n";
- }
- else {
- if (Param2 != (char *)0x0) {
- if (cr->Type == PLAYER) {
- // try { // try from 08086f4f to 08087061 has its CatchHandler @ 08087080
- bVar1 = CheckRight(cr->ID,CHANGE_SKILLS);
- if (!bVar1) {
- return;
- }
- Number = __strtol_internal(Param1,0,10,0);
- Value = __strtol_internal(Param2,0,10,0);
- bVar1 = false;
- if ((-1 < Number) && (Number < 500)) {
- bVar1 = true;
- }
- if (!bVar1) {
- SendMessage(cr->Connection,0x17,"Invalid quest number.");
- return;
- }
- TPlayer::SetQuestValue((TPlayer *)cr,Number,Value);
- SendMessage(cr->Connection,0x16,"Quest value %d set to %d.",Number,Value);
- return;
- }
- pcVar3 = "SetQuestValue: Zauberspruch kann nur von Spielern angewendet werden.\n";
- goto LAB_08087027;
- }
- pcVar3 = "SetQuestValue: Param2 ist NULL.\n";
- }
- error(pcVar3);
- return;
-}
-
-
-
-void ClearQuestValues(TCreature *cr)
-
-{
- bool bVar1;
- undefined4 *puVar2;
- int i;
- int Number;
- char *Text;
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fc760;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 080870d2 to 0808715f has its CatchHandler @ 08087170
- bVar1 = CheckRight(cr->ID,CHANGE_SKILLS);
- if (bVar1) {
- Number = 0;
- do {
- TPlayer::SetQuestValue((TPlayer *)cr,Number,0);
- Number = Number + 1;
- } while (Number < 500);
- SendMessage(cr->Connection,0x16,"All quest values deleted.");
- }
- return;
- }
- Text = "ClearQuestValues: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(Text);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
-void CreateKnowledge(TCreature *cr,char *Param1,char *Param2)
-
-{
- bool bVar1;
- uint uVar2;
- uint uVar3;
- TSkill *pTVar4;
- undefined4 *puVar5;
- long k;
- _func_int_varargs **pp_Var6;
- char *Text;
- Object local_2c [7];
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fc840;
- }
- else if (Param1 == (char *)0x0) {
- Text = &DAT_080fc800;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 080871d7 to 080872c2 has its CatchHandler @ 080872d5
- bVar1 = CheckRight(cr->ID,CHANGE_SKILLS);
- if (bVar1) {
- uVar2 = __strtol_internal(Param1,0,10,0);
- if (Param2 == (char *)0x0) {
- uVar3 = 0;
- }
- else {
- uVar3 = __strtol_internal(Param2,0,10,0);
- }
- if (((int)uVar2 < 1) || (Param2 != (char *)0x0)) {
- if (0x18 < uVar2) {
- return;
- }
- if ((int)uVar3 < 1) {
- return;
- }
- pp_Var6 = (cr->super_TSkillBase).Skills[uVar2]->_vptr_TSkill;
- pTVar4 = (cr->super_TSkillBase).Skills[uVar2];
- uVar2 = uVar3;
- }
- else {
- pTVar4 = (cr->super_TSkillBase).Skills[0];
- pp_Var6 = pTVar4->_vptr_TSkill;
- }
- (*pp_Var6[3])(pTVar4,uVar2);
- local_2c[0].ObjectID = (cr->CrObject).ObjectID;
- GraphicalEffect(local_2c,0xf);
- }
- return;
- }
- Text = "CreateKnowledge: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(Text);
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar5,&RESULT::typeinfo,0);
-}
-
-
-
-void ChangeProfession(TCreature *cr,char *Param)
-
-{
- bool bVar1;
- uchar uVar2;
- byte bVar3;
- int iVar4;
- undefined4 *puVar5;
- char *Text;
- Object local_1c [4];
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fc920;
- }
- else if (Param == (char *)0x0) {
- Text = &DAT_080fc8e0;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 08087331 to 08087525 has its CatchHandler @ 08087538
- bVar1 = CheckRight(cr->ID,CHANGE_PROFESSION);
- if (!bVar1) {
- return;
- }
- iVar4 = stricmp(Param,"male",-1);
- if (iVar4 == 0) {
- cr->Sex = 1;
- }
- else {
- iVar4 = stricmp(Param,"female",-1);
- if (iVar4 == 0) {
- cr->Sex = 2;
- }
- else {
- iVar4 = stricmp(Param,"none",-1);
- if (iVar4 == 0) {
- TPlayer::ClearProfession((TPlayer *)cr);
- }
- else {
- iVar4 = stricmp(Param,"knight",-1);
- if (iVar4 == 0) {
- TPlayer::ClearProfession((TPlayer *)cr);
- uVar2 = '\x01';
- }
- else {
- iVar4 = stricmp(Param,"paladin",-1);
- if (iVar4 == 0) {
- TPlayer::ClearProfession((TPlayer *)cr);
- uVar2 = '\x02';
- }
- else {
- iVar4 = stricmp(Param,"sorcerer",-1);
- if (iVar4 == 0) {
- TPlayer::ClearProfession((TPlayer *)cr);
- uVar2 = '\x03';
- }
- else {
- iVar4 = stricmp(Param,"druid",-1);
- if (iVar4 == 0) {
- TPlayer::ClearProfession((TPlayer *)cr);
- uVar2 = '\x04';
- }
- else {
- iVar4 = stricmp(Param,"promote",-1);
- if (iVar4 != 0) {
- return;
- }
- uVar2 = TPlayer::GetRealProfession((TPlayer *)cr);
- if (uVar2 == '\0') {
- return;
- }
- bVar3 = TPlayer::GetRealProfession((TPlayer *)cr);
- if (9 < bVar3) {
- return;
- }
- uVar2 = '\n';
- }
- }
- }
- }
- TPlayer::SetProfession((TPlayer *)cr,uVar2);
- }
- }
- }
- local_1c[0].ObjectID = (cr->CrObject).ObjectID;
- GraphicalEffect(local_1c,0xd);
- return;
- }
- Text = "ChangeProfession: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(Text);
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar5,&RESULT::typeinfo,0);
-}
-
-
-
-void EditGuests(TCreature *cr)
-
-{
- ushort HouseID_00;
- undefined4 *puVar1;
- ushort HouseID;
- char *Text;
- char local_101c [4];
- char Buffer [4096];
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fc9c0;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 08087598 to 0808761b has its CatchHandler @ 08087640
- HouseID_00 = GetHouseID(cr->posx,cr->posy,cr->posz);
- if (HouseID_00 != 0) {
- ShowGuestList(HouseID_00,(TPlayer *)cr,local_101c);
- SendEditList(cr->Connection,'\x01',(uint)HouseID_00,local_101c);
- return;
- }
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = 1;
- goto LAB_080875f8;
- }
- Text = "EditGuests: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(Text);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = 0xffffffff;
-LAB_080875f8:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,&RESULT::typeinfo,0);
-}
-
-
-
-void EditSubowners(TCreature *cr)
-
-{
- ushort HouseID_00;
- undefined4 *puVar1;
- ushort HouseID;
- char *Text;
- char local_101c [4];
- char Buffer [4096];
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fca60;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 080876a8 to 0808772b has its CatchHandler @ 08087750
- HouseID_00 = GetHouseID(cr->posx,cr->posy,cr->posz);
- if (HouseID_00 != 0) {
- ShowSubownerList(HouseID_00,(TPlayer *)cr,local_101c);
- SendEditList(cr->Connection,'\x02',(uint)HouseID_00,local_101c);
- return;
- }
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = 1;
- goto LAB_08087708;
- }
- Text = "EditSubowners: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(Text);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = 0xffffffff;
-LAB_08087708:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Variable defined which should be unmapped: Guest
-
-void KickGuest(TCreature *cr,char *Name)
-
-{
- bool bVar1;
- ushort HouseID_00;
- int Result;
- int iVar2;
- undefined4 *puVar3;
- ushort HouseID;
- char *Text;
- TPlayer *local_10;
- TPlayer *Guest;
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fcb40;
- }
- else if (Name == (char *)0x0) {
- Text = &DAT_080fcb00;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 080877b1 to 0808788b has its CatchHandler @ 080878b2
- bVar1 = CheckRight(cr->ID,READ_GAMEMASTER_CHANNEL);
- iVar2 = IdentifyPlayer(Name,false,!bVar1,&local_10);
- if (iVar2 == -1) {
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0x1b;
- }
- else if (iVar2 == -2) {
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0x1c;
- }
- else {
- HouseID_00 = GetHouseID((local_10->super_TCreature).posx,
- (local_10->super_TCreature).posy,
- (local_10->super_TCreature).posz);
- if (HouseID_00 != 0) {
- KickGuest(HouseID_00,(TPlayer *)cr,local_10);
- return;
- }
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 1;
- }
- goto LAB_08087840;
- }
- Text = "KickGuest(magic): Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(Text);
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
-LAB_08087840:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-void EditNameDoor(TCreature *cr)
-
-{
- bool bVar1;
- undefined4 *puVar2;
- int y;
- int iVar3;
- int x;
- char *pcVar4;
- int iVar5;
- int iVar6;
- int iVar7;
- int z;
- char Buffer [4096];
- Object local_4c [4];
- Object local_3c [4];
- ulong local_2c;
- Object Door;
-
- if (cr == (TCreature *)0x0) {
- pcVar4 = &DAT_080fcbe0;
- }
- else {
- if (cr->Type == PLAYER) {
- iVar3 = cr->posy;
- iVar7 = cr->posz;
- iVar5 = iVar3;
- iVar6 = iVar7;
- // try { // try from 08087925 to 08087b48 has its CatchHandler @ 08087b66
- GetFirstObject();
- local_3c[0].ObjectID = NONE.ObjectID;
- if (local_2c != NONE.ObjectID) {
- do {
- local_4c[0].ObjectID = NONE.ObjectID;
- local_3c[0].ObjectID = NONE.ObjectID;
- Object::getObjectType(local_4c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_4c,NAMEDOOR);
- if (bVar1) break;
- Object::getNextObject(local_3c);
- local_2c = local_3c[0].ObjectID;
- bVar1 = local_3c[0].ObjectID != NONE.ObjectID;
- local_3c[0].ObjectID = NONE.ObjectID;
- } while (bVar1);
- }
- local_4c[0].ObjectID = NONE.ObjectID;
- if (local_2c == NONE.ObjectID) {
- iVar5 = cr->Direction;
- if (iVar5 != 1) {
- if (iVar5 < 2) {
- if (iVar5 == 0) {
- iVar3 = iVar3 + -1;
- }
- }
- else if (iVar5 == 2) {
- iVar3 = iVar3 + 1;
- }
- }
- GetFirstObject();
- local_2c._0_1_ = Buffer[0xffc];
- local_2c._1_1_ = Buffer[0xffd];
- local_2c._2_1_ = Buffer[0xffe];
- local_2c._3_1_ = Buffer[0xfff];
- local_3c[0].ObjectID = NONE.ObjectID;
- iVar5 = iVar3;
- iVar6 = iVar7;
- if (Buffer._4092_4_ != NONE.ObjectID) {
- do {
- Buffer._4092_4_ = NONE.ObjectID;
- local_3c[0].ObjectID = NONE.ObjectID;
- Object::getObjectType((Object *)(Buffer + 0xffc));
- bVar1 = ObjectType::getFlag((ObjectType *)(Buffer + 0xffc),NAMEDOOR);
- iVar5 = iVar3;
- iVar6 = iVar7;
- if (bVar1) break;
- Object::getNextObject(local_3c);
- local_2c = local_3c[0].ObjectID;
- bVar1 = local_3c[0].ObjectID != NONE.ObjectID;
- local_3c[0].ObjectID = NONE.ObjectID;
- iVar5 = iVar3;
- iVar6 = iVar7;
- } while (bVar1);
- }
- }
- if (local_2c != NONE.ObjectID) {
- Buffer._4092_4_ = local_2c;
- ShowNameDoor((Object *)(Buffer + 0xffc),(TPlayer *)cr,(char *)&z);
- SendEditList(cr->Connection,'\x03',local_2c,(char *)&z);
- return;
- }
- pcVar4 = "Keine NameDoor gefunden.\n";
- Buffer._4092_4_ = NONE.ObjectID;
- print();
- puVar2 = (undefined4 *)__cxa_allocate_exception(4,pcVar4,iVar5,iVar6);
- *puVar2 = 1;
- goto LAB_08087ae7;
- }
- pcVar4 = "EditNameDoor: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(pcVar4);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
-LAB_08087ae7:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
-void Notation(TCreature *cr,char *Name,char *Comment)
-
-{
- undefined4 *puVar1;
- char *Text;
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fcd40;
- }
- else if (Name == (char *)0x0) {
- Text = &DAT_080fcd00;
- }
- else if (Comment == (char *)0x0) {
- Text = &DAT_080fccc0;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 08087bc2 to 08087c00 has its CatchHandler @ 08087c20
- SendMessage(cr->Connection,0x17,
- "Spell is not available any more. Press Ctrl+Y for the dialog.");
- return;
- }
- Text = "Notation: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(Text);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,&RESULT::typeinfo,0);
-}
-
-
-
-void NameLock(TCreature *cr,char *Name)
-
-{
- undefined4 *puVar1;
- char *Text;
-
- if (cr == (TCreature *)0x0) {
- Text = &DAT_080fce20;
- }
- else if (Name == (char *)0x0) {
- Text = &DAT_080fcde0;
- }
- else {
- if (cr->Type == PLAYER) {
- // try { // try from 08087c77 to 08087cb5 has its CatchHandler @ 08087cc8
- SendMessage(cr->Connection,0x17,
- "Spell is not available any more. Press Ctrl+Y for the dialog.");
- return;
- }
- Text = "NameLock: Zauberspruch kann nur von Spielern angewendet werden.\n";
- }
- error(Text);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,&RESULT::typeinfo,0);
-}
-
-
-
void BanishAccount(TCreature *cr,char *Name,int param_3,char *Reason)
{
diff --git a/src/info.hh b/src/info.hh
index f94ef0e..d3bd625 100644
--- a/src/info.hh
+++ b/src/info.hh
@@ -6,6 +6,11 @@
// TODO(fusion): Probably move to `houses.hh` when we implement it?
constexpr uint16 HOUSEID_ANY = 0xFFFF;
+enum HouseList: uint8 {
+ GUESTLIST = 1,
+ SUBOWNERLIST = 2,
+ DOORLIST = 3,
+};
bool JumpPossible(int x, int y, int z, bool AvoidPlayers);
bool SearchFreeField(int *x, int *y, int *z, int Distance, uint16 HouseID, bool Jump);
diff --git a/src/magic.cc b/src/magic.cc
index 6c890ea..87de8f1 100644
--- a/src/magic.cc
+++ b/src/magic.cc
@@ -847,10 +847,7 @@ void MassCombat(TCreature *Actor, Object Target, int ManaPoints, int SoulPoints,
throw CANNOTTHROW;
}
- int Delay = 2000;
- if(WorldType == PVP_ENFORCED){
- Delay = 1000;
- }
+ int Delay = (WorldType == PVP_ENFORCED) ? 1000 : 2000;
CheckMana(Actor, ManaPoints, SoulPoints, Delay);
TDamageImpact Impact(Actor, DamageType, Damage, false);
@@ -903,10 +900,7 @@ void Combat(TCreature *Actor, Object Target, int ManaPoints, int SoulPoints,
throw CANNOTTHROW;
}
- int Delay = 2000;
- if(WorldType == PVP_ENFORCED){
- Delay = 1000;
- }
+ int Delay = (WorldType == PVP_ENFORCED) ? 1000 : 2000;
CheckMana(Actor, ManaPoints, SoulPoints, Delay);
TDamageImpact Impact(Actor, DamageType, Damage, false);
@@ -995,10 +989,7 @@ void CreateField(TCreature *Actor, Object Target, int ManaPoints, int SoulPoints
throw CANNOTTHROW;
}
- int Delay = 2000;
- if(WorldType == PVP_ENFORCED){
- Delay = 1000;
- }
+ int Delay = (WorldType == PVP_ENFORCED) ? 1000 : 2000;
CheckMana(Actor, ManaPoints, SoulPoints, Delay);
int Animation = ANIMATION_ENERGY;
@@ -1062,10 +1053,7 @@ void MassCreateField(TCreature *Actor, Object Target,
throw CANNOTTHROW;
}
- int Delay = 2000;
- if(WorldType == PVP_ENFORCED){
- Delay = 1000;
- }
+ int Delay = (WorldType == PVP_ENFORCED) ? 1000 : 2000;
CheckMana(Actor, ManaPoints, SoulPoints, Delay);
if(Actor->posx != TargetX || Actor->posy != TargetY || Actor->posz != TargetZ){
@@ -1128,10 +1116,7 @@ void CreateFieldWall(TCreature *Actor, Object Target,
throw CANNOTTHROW;
}
- int Delay = 2000;
- if(WorldType == PVP_ENFORCED){
- Delay = 1000;
- }
+ int Delay = (WorldType == PVP_ENFORCED) ? 1000 : 2000;
CheckMana(Actor, ManaPoints, SoulPoints, Delay);
if(ActorX != TargetX || ActorY != TargetY || ActorZ != TargetZ){
@@ -1816,7 +1801,7 @@ void SummonCreature(TCreature *Actor, int ManaPoints, int Race, bool God){
throw NOTACCESSIBLE;
}
- if(Actor->SummonedCreatures > 1){
+ if(Actor->SummonedCreatures >= 2){
throw TOOMANYSLAVES;
}
}
@@ -2367,6 +2352,661 @@ void CancelInvisibility(TCreature *Actor, Object Target, int ManaPoints, int Sou
}
}
+void CreatureIllusion(TCreature *Actor, const char *RaceName, int ManaPoints, int SoulPoints, int Duration){
+ if(Actor == NULL){
+ error("CreatureIllusion: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(RaceName == NULL){
+ error("CreatureIllusion: Ungültiger Rassenname übergeben.\n");
+ throw ERROR;
+ }
+
+ int Race = GetRaceByName(RaceName);
+ if(Race == 0){
+ throw CREATURENOTEXISTING;
+ }
+
+ if(GetRaceNoIllusion(Race)){
+ throw NOTACCESSIBLE;
+ }
+
+ CheckMana(Actor, ManaPoints, SoulPoints, 1000);
+ if(Actor->Skills[SKILL_ILLUSION]->Get() == 0){
+ Actor->Outfit = GetRaceOutfit(Race);
+ Actor->SetTimer(SKILL_ILLUSION, 1, Duration, Duration, -1);
+ }
+
+ GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_BLUE);
+}
+
+void ObjectIllusion(TCreature *Actor, Object Target, int ManaPoints, int SoulPoints, int Duration){
+ if(Actor == NULL){
+ error("ObjectIllusion: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(!Target.exists()){
+ error("ObjectIllusion: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType TargetType = Target.getObjectType();
+ if(TargetType.isCreatureContainer() || TargetType.getFlag(UNMOVE)){
+ throw NOTMOVABLE;
+ }
+
+ CheckMana(Actor, ManaPoints, SoulPoints, 1000);
+ if(Actor->Skills[SKILL_ILLUSION]->Get() == 0){
+ Actor->Outfit.OutfitID = 0;
+ if(TargetType.getFlag(DISGUISE)){
+ Actor->Outfit.ObjectType = (uint16)TargetType.getAttribute(DISGUISETARGET);
+ }else{
+ Actor->Outfit.ObjectType = (uint16)TargetType.TypeID;
+ }
+ Actor->SetTimer(SKILL_ILLUSION, 1, Duration, Duration, -1);
+ }
+
+ GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_BLUE);
+}
+
+void ChangeData(TCreature *Actor, const char *Param){
+ if(Actor == NULL){
+ error("ChangeData: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Param == NULL){
+ error("ChangeData: Ungültiger Parameter übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("ChangeData: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ if(!CheckRight(Actor->ID, CREATE_OBJECTS)){
+ return;
+ }
+
+ Object RightHand = GetBodyObject(Actor->ID, 5); // RIGHTHAND ?
+ Object LeftHand = GetBodyObject(Actor->ID, 6); // LEFTHAND ?
+ if(RightHand != NONE && LeftHand != NONE){
+ SendMessage(Actor->Connection, TALK_FAILURE_MESSAGE, "First drop one object.");
+ return;
+ }
+
+ Object Obj = RightHand;
+ if(Obj == NONE){
+ Obj = LeftHand;
+ }
+
+ if(Obj == NONE){
+ Obj = GetFirstObject(Actor->posx, Actor->posy, Actor->posz);
+ while(Obj != NONE){
+ if(Obj.getObjectType().getFlag(KEYDOOR)){
+ break;
+ }
+ Obj = Obj.getNextObject();
+ }
+ }
+
+ if(Obj != NONE){
+ int Attribute = -1;
+ int Value = atoi(Param);
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.getFlag(LIQUIDCONTAINER)){
+ Attribute = CONTAINERLIQUIDTYPE;
+ }else if(ObjType.getFlag(KEY)){
+ if(Value > 0){
+ Attribute = KEYNUMBER;
+ }
+ }else if(ObjType.getFlag(KEYDOOR)){
+ if(Value > 0){
+ Attribute = KEYHOLENUMBER;
+ }
+ }else if(ObjType.getFlag(CUMULATIVE)){
+ if(Value > 0 && Value <= 100){
+ Attribute = AMOUNT;
+ }
+ }else if(ObjType.getFlag(RUNE)){
+ if(Value > 0 && Value <= 99){
+ Attribute = CHARGES;
+ }
+ }
+
+ if(Attribute != -1){
+ Change(Obj, Attribute, Value);
+ GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_GREEN);
+ }else{
+ SendMessage(Actor->Connection, TALK_FAILURE_MESSAGE,
+ "You can\'t change %s in this way.", GetName(Obj));
+ }
+ }
+}
+
+void EnchantObject(TCreature *Actor, int ManaPoints, int SoulPoints, ObjectType OldType, ObjectType NewType){
+ if(Actor == NULL){
+ error("EnchantObject: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ Object Obj = GetBodyObject(Actor->ID, 5); // RIGHTHAND ?
+ if(Obj == NONE || Obj.getObjectType() != OldType){
+ Obj = GetBodyObject(Actor->ID, 6); // LEFTHAND ?
+ if(Obj == NONE || Obj.getObjectType() != OldType){
+ throw MAGICITEM;
+ }
+ }
+
+ CheckMana(Actor, ManaPoints, SoulPoints, 1000);
+ Change(Obj, NewType, 0);
+ GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_GREEN);
+}
+
+void Convince(TCreature *Actor, TCreature *Target){
+ // TODO(fusion): All of a sudden we're not checking if `Actor` is NULL?
+
+ if(Target->Type != MONSTER){
+ throw ATTACKNOTALLOWED;
+ }
+
+ if(Actor->Type == PLAYER && Actor->SummonedCreatures >= 2){
+ throw TOOMANYSLAVES;
+ }
+
+ if(WorldType == NON_PVP && Actor->IsPeaceful() && Target->IsPeaceful()){
+ throw ATTACKNOTALLOWED;
+ }
+
+ if(GetRaceNoConvince(Target->Race)){
+ throw NOTACCESSIBLE;
+ }
+
+ int SummonCost = GetRaceSummonCost(Target->Race);
+ int Delay = (WorldType == PVP_ENFORCED) ? 1000 : 2000;
+ CheckMana(Actor, SummonCost, 0, Delay);
+ ConvinceMonster(Actor, Target);
+ GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_BLUE);
+ GraphicalEffect(Target->posx, Target->posy, Target->posz, EFFECT_BONE_HIT);
+}
+
+void Challenge(TCreature *Actor, int ManaPoints, int SoulPoints, int Radius){
+ // TODO(fusion): All of a sudden we're not checking if `Actor` is NULL?
+ CheckMana(Actor, ManaPoints, SoulPoints, 1000);
+
+ // TODO(fusion): Same as `KillAllMonsters`.
+ if(Radius >= NARRAY(Circle)){
+ Radius = NARRAY(Circle) - 1;
+ }
+
+ int ActorX = Actor->posx;
+ int ActorY = Actor->posx;
+ int ActorZ = Actor->posx;
+ for(int R = 0; R <= Radius; R += 1){
+ int CirclePoints = Circle[R].Count;
+ for(int Point = 0; Point < CirclePoints; Point += 1){
+ int FieldX = ActorX + Circle[R].x[Point];
+ int FieldY = ActorY + Circle[R].y[Point];
+ int FieldZ = ActorZ;
+
+ if(!ThrowPossible(ActorX, ActorY, ActorZ, FieldX, FieldY, FieldZ, 0)){
+ continue;
+ }
+
+ GraphicalEffect(FieldX, FieldY, FieldZ, EFFECT_MAGIC_BLUE);
+ Object Obj = GetFirstSpecObject(FieldX, FieldY, FieldZ, TYPEID_CREATURE_CONTAINER);
+ if(Obj != NONE){
+ TCreature *Victim = GetCreature(Obj);
+ if(Victim == NULL){
+ error("Challenge: Ungültige Kreatur.\n");
+ }else if(Victim->Type == MONSTER){
+ ChallengeMonster(Actor, Victim);
+ }
+ }
+ }
+ }
+}
+
+void FindPerson(TCreature *Actor, const char *TargetName, int ManaPoints, int SoulPoints){
+ // TODO(fusion): And we're back.
+ if(Actor == NULL){
+ error("FindPerson: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(TargetName == NULL){
+ error("FindPerson: Ungültiger Name übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("FindPerson: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Target;
+ bool IgnoreGamemasters = !CheckRight(Actor->ID, READ_GAMEMASTER_CHANNEL);
+ switch(IdentifyPlayer(TargetName, false, IgnoreGamemasters, &Target)){
+ default:
+ case 0: break; // PLAYERFOUND ?
+ case -1: throw PLAYERNOTONLINE;
+ case -2: throw NAMEAMBIGUOUS;
+ }
+
+ if(Target == NULL){
+ error("FindPerson: Opp ist NULL.\n");
+ throw ERROR;
+ }
+
+ CheckMana(Actor, ManaPoints, SoulPoints, 1000);
+
+ int Distance = std::max<int>(
+ std::abs(Actor->posx - Target->posx),
+ std::abs(Actor->posy - Target->posy));
+ if(Distance <= 4){
+ if(Actor->posz > Target->posz){
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "%s is above you.", Target->Name);
+ }else if(Actor->posz < Target->posz){
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "%s is below you.", Target->Name);
+ }else{
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "%s is standing next to you.", Target->Name);
+ }
+ }else{
+ const char *Direction = "";
+ switch(GetDirection(Target->posx - Actor->posx, Target->posy - Actor->posy)){
+ case DIRECTION_NORTH: Direction = "north"; break;
+ case DIRECTION_EAST: Direction = "east"; break;
+ case DIRECTION_SOUTH: Direction = "south"; break;
+ case DIRECTION_WEST: Direction = "west"; break;
+ case DIRECTION_SOUTHWEST: Direction = "south-west"; break;
+ case DIRECTION_SOUTHEAST: Direction = "south-east"; break;
+ case DIRECTION_NORTHWEST: Direction = "north-west"; break;
+ case DIRECTION_NORTHEAST: Direction = "north-east"; break;
+ default:{
+ error("FindPerson: Richtung ist Null.\n");
+ throw ERROR;
+ }
+ }
+
+ if(Distance <= 99){
+ if(Actor->posz > Target->posz){
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "%s is on a higher level to the %s.", Target->Name, Direction);
+ }else if(Actor->posz < Target->posz){
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "%s is on a lower level to the %s.", Target->Name, Direction);
+ }else{
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "%s is to the %s.", Target->Name, Direction);
+ }
+ }else if(Distance <= 250){
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "%s is far to the %s.", Target->Name, Direction);
+ }else{
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "%s is very far to the %s.", Target->Name, Direction);
+ }
+ }
+
+ GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_BLUE);
+}
+
+void GetPosition(TCreature *Actor){
+ if(Actor == NULL){
+ error("GetPosition: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("GetPosition: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ if(CheckRight(Actor->ID, SHOW_COORDINATE)){
+ SendMessage(Actor->Connection, TALK_EVENT_MESSAGE,
+ "Your position is [%d,%d,%d].",
+ Actor->posx, Actor->posy, Actor->posz);
+ }
+}
+
+void GetQuestValue(TCreature *Actor, const char *Param){
+ if(Actor == NULL){
+ error("GetQuestValue: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Param == NULL){
+ error("GetQuestValue: Param ist NULL.\n");
+ return; // TODO(fusion): Why don't we throw here?
+ }
+
+ if(Actor->Type != PLAYER){
+ error("GetQuestValue: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ if(CheckRight(Actor->ID, CHANGE_SKILLS)){
+ int QuestNumber = atoi(Param);
+ if(QuestNumber >= 0 && QuestNumber < NARRAY(TPlayer::QuestValues)){
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "Quest value %d is %d.",
+ QuestNumber, ((TPlayer*)Actor)->GetQuestValue(QuestNumber));
+ }else{
+ SendMessage(Actor->Connection, TALK_FAILURE_MESSAGE, "Invalid quest number.");
+ }
+ }
+}
+
+void SetQuestValue(TCreature *Actor, const char *Param1, const char *Param2){
+ if(Actor == NULL){
+ error("SetQuestValue: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Param1 == NULL){
+ error("SetQuestValue: Param1 ist NULL.\n");
+ return; // TODO(fusion): Why don't we throw here?
+ }
+
+ if(Param2 == NULL){
+ error("SetQuestValue: Param2 ist NULL.\n");
+ return; // TODO(fusion): Why don't we throw here?
+ }
+
+ if(Actor->Type != PLAYER){
+ error("SetQuestValue: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ if(CheckRight(Actor->ID, CHANGE_SKILLS)){
+ int QuestNumber = atoi(Param1);
+ int QuestValue = atoi(Param2);
+ if(QuestNumber >= 0 && QuestNumber < NARRAY(TPlayer::QuestValues)){
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE,
+ "Quest value %d set to %d.", QuestNumber, QuestValue);
+ }else{
+ SendMessage(Actor->Connection, TALK_FAILURE_MESSAGE, "Invalid quest number.");
+ }
+ }
+}
+
+void ClearQuestValues(TCreature *Actor){
+ if(Actor == NULL){
+ error("ClearQuestValues: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("ClearQuestValues: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ if(CheckRight(Actor->ID, CHANGE_SKILLS)){
+ for(int QuestNumber = 0;
+ QuestNumber < NARRAY(TPlayer::QuestValues);
+ QuestNumber += 1){
+ ((TPlayer*)Actor)->SetQuestValue(QuestNumber, 0);
+ }
+ SendMessage(Actor->Connection, TALK_INFO_MESSAGE, "All quest values deleted.");
+ }
+}
+
+void CreateKnowledge(TCreature *Actor, const char *Param1, const char *Param2){
+ if(Actor == NULL){
+ error("CreateKnowledge: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Param1 == NULL){
+ error("CreateKnowledge: Ungültiger Parameter 1 übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("CreateKnowledge: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ if(CheckRight(Actor->ID, CHANGE_SKILLS)){
+ int Skill = (Param2 != NULL) ? atoi(Param1) : 0;
+ int Amount = (Param2 != NULL) ? atoi(Param2) : atoi(Param1);
+ if(Skill < 0 || Skill >= NARRAY(Actor->Skills) || Amount < 1){
+ return;
+ }
+ Actor->Skills[Skill]->Increase(Amount);
+ GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_GREEN);
+ }
+}
+
+void ChangeProfession(TCreature *Actor, const char *Param){
+ if(Actor == NULL){
+ error("ChangeProfession: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Param == NULL){
+ error("ChangeProfession: Ungültigen Parameter übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("ChangeProfession: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ if(!CheckRight(Actor->ID, CHANGE_PROFESSION)){
+ return;
+ }
+
+ if(stricmp(Param, "male") == 0){
+ Actor->Sex = 1;
+ }else if(stricmp(Param, "female") == 0){
+ Actor->Sex = 2;
+ }else if(stricmp(Param, "none") == 0){
+ ((TPlayer*)Actor)->ClearProfession();
+ }else if(stricmp(Param, "knight") == 0){
+ ((TPlayer*)Actor)->ClearProfession();
+ ((TPlayer*)Actor)->SetProfession(PROFESSION_KNIGHT);
+ }else if(stricmp(Param, "paladin") == 0){
+ ((TPlayer*)Actor)->ClearProfession();
+ ((TPlayer*)Actor)->SetProfession(PROFESSION_PALADIN);
+ }else if(stricmp(Param, "sorcerer") == 0){
+ ((TPlayer*)Actor)->ClearProfession();
+ ((TPlayer*)Actor)->SetProfession(PROFESSION_SORCERER);
+ }else if(stricmp(Param, "druid") == 0){
+ ((TPlayer*)Actor)->ClearProfession();
+ ((TPlayer*)Actor)->SetProfession(PROFESSION_DRUID);
+ }else if(stricmp(Param, "promotion") == 0){
+ // TODO(fusion): Probably some inlined function to check whether the
+ // player is already promoted.
+ uint8 RealProfession = ((TPlayer*)Actor)->GetRealProfession();
+ if(RealProfession == 0 || RealProfession >= 10){
+ return;
+ }
+
+ // NOTE(fusion): Using the value 10 with `TPlayer::SetProfession` will
+ // cause the player to be promoted.
+ ((TPlayer*)Actor)->SetProfession(10);
+ }else{
+ return;
+ }
+
+ GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_BLUE);
+}
+
+void EditGuests(TCreature *Actor){
+ if(Actor == NULL){
+ error("EditGuests: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("EditGuests: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ uint16 HouseID = GetHouseID(Actor->posx, Actor->posy, Actor->posz);
+ if(HouseID == 0){
+ throw NOTACCESSIBLE;
+ }
+
+ // TODO(fusion): Now this can be problematic. If we don't sanitize house
+ // lists to be under 4KB, we can easily get a buffer overflow here.
+ char GuestList[4096];
+ ShowGuestList(HouseID, (TPlayer*)Actor, GuestList);
+ SendEditList(Actor->Connection, GUESTLIST, HouseID, GuestList);
+}
+
+void EditSubowners(TCreature *Actor){
+ if(Actor == NULL){
+ error("EditSubowners: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("EditSubowners: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ uint16 HouseID = GetHouseID(Actor->posx, Actor->posy, Actor->posz);
+ if(HouseID == 0){
+ throw NOTACCESSIBLE;
+ }
+
+ // TODO(fusion): Now this can be problematic. If we don't sanitize house
+ // lists to be under 4KB, we can easily get a buffer overflow here.
+ char SubOwnerList[4096];
+ ShowSubownerList(HouseID, (TPlayer*)Actor, SubOwnerList);
+ SendEditList(Actor->Connection, SUBOWNERLIST, HouseID, SubOwnerList);
+}
+
+void EditNameDoor(TCreature *Actor){
+ if(Actor == NULL){
+ error("EditNameDoor: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("EditNameDoor: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ int DoorX = Actor->posx;
+ int DoorY = Actor->posy;
+ int DoorZ = Actor->posz;
+ Object Obj = GetFirstObject(DoorX, DoorY, DoorZ);
+ while(Obj != NONE){
+ if(Obj.getObjectType().getFlag(NAMEDOOR)){
+ break;
+ }
+ Obj = Obj.getNextObject();
+ }
+
+ if(Obj == NONE){
+ // TODO(fusion): This is probably an inlined function `TCreature::GetForwardPosition`.
+ switch(Actor->Direction){
+ case DIRECTION_NORTH: DoorY -= 1; break;
+ case DIRECTION_EAST: DoorX += 1; break;
+ case DIRECTION_SOUTH: DoorY += 1; break;
+ case DIRECTION_WEST: DoorX -= 1; break;
+ }
+
+ // TODO(fusion): This could be some inlined function to retrieve the
+ // first object with a given flag.
+ Obj = GetFirstObject(DoorX, DoorY, DoorZ);
+ while(Obj != NONE){
+ if(Obj.getObjectType().getFlag(NAMEDOOR)){
+ break;
+ }
+ Obj = Obj.getNextObject();
+ }
+ }
+
+ if(Obj == NONE){
+ print(3, "Keine NameDoor gefunden.\n");
+ throw NOTACCESSIBLE;
+ }
+
+ char DoorList[4096];
+ ShowNameDoor(Obj, (TPlayer*)Actor, DoorList);
+ SendEditList(Actor->Connection, DOORLIST, Obj.ObjectID, DoorList);
+}
+
+void KickGuest(TCreature *Actor, const char *GuestName){
+ if(Actor == NULL){
+ error("KickGuest(magic): Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(GuestName == NULL){
+ error("KickGuest(magic): Ungültigen Gast übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("KickGuest(magic): Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Guest;
+ bool IgnoreGamemasters = !CheckRight(Actor->ID, READ_GAMEMASTER_CHANNEL);
+ switch(IdentifyPlayer(GuestName, false, IgnoreGamemasters, &Guest)){
+ default:
+ case 0: break; // PLAYERFOUND ?
+ case -1: throw PLAYERNOTONLINE;
+ case -2: throw NAMEAMBIGUOUS;
+ }
+
+ uint16 HouseID = GetHouseID(Guest->posx, Guest->posy, Guest->posz);
+ if(HouseID == 0){
+ throw NOTACCESSIBLE;
+ }
+
+ KickGuest(HouseID, (TPlayer*)Actor, Guest);
+}
+
+void Notation(TCreature *Actor, const char *Name, const char *Comment){
+ if(Actor == NULL){
+ error("Notation: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Name == NULL){
+ error("Notation: Ungültiger Name übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Comment == NULL){
+ error("Notation: Ungültige Bemerkung übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("Notation: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ SendMessage(Actor->Connection, TALK_FAILURE_MESSAGE,
+ "Spell is not available any more. Press Ctrl+Y for the dialog.");
+}
+
+void NameLock(TCreature *Actor, const char *Name){
+ if(Actor == NULL){
+ error("NameLock: Ungültige Kreatur übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Name == NULL){
+ error("NameLock: Ungültiger Name übergeben.\n");
+ throw ERROR;
+ }
+
+ if(Actor->Type != PLAYER){
+ error("NameLock: Zauberspruch kann nur von Spielern angewendet werden.\n");
+ throw ERROR;
+ }
+
+ SendMessage(Actor->Connection, TALK_FAILURE_MESSAGE,
+ "Spell is not available any more. Press Ctrl+Y for the dialog.");
+}
+
// Magic Init Functions
// =============================================================================
static void InitCircles(void){
diff --git a/src/player.hh b/src/player.hh
index a0ae9e1..0731f11 100644
--- a/src/player.hh
+++ b/src/player.hh
@@ -72,6 +72,11 @@ struct TPlayer: TCreature {
uint8 GetEffectiveProfession(void);
uint8 GetActiveProfession(void);
bool GetActivePromotion(void);
+ void ClearProfession(void);
+ void SetProfession(uint8 Profession);
+
+ int GetQuestValue(int Number);
+ void SetQuestValue(int Number, int Value);
uint32 GetPartyLeader(bool CheckFormer);
diff --git a/src/stubs.hh b/src/stubs.hh
index 3e69990..6013a17 100644
--- a/src/stubs.hh
+++ b/src/stubs.hh
@@ -26,6 +26,8 @@ extern void CircleShapeSpell(TCreature *Actor, int DestX, int DestY, int DestZ,
int Range, int Animation, int Radius, TImpact *Impact, int Effect);
extern void CleanHouseField(int x, int y, int z);
extern int ComputeDamage(TCreature *Creature, int SpellNr, int Damage, int Variation);
+extern void ConvinceMonster(TCreature *Master, TCreature *Slave);
+extern void ChallengeMonster(TCreature *Challenger, TCreature *Monster);
extern int CountInventoryObjects(uint32 CreatureID, ObjectType Type, uint32 Value);
extern Object CreateAtCreature(uint32 CreatureID, ObjectType Type, uint32 Value);
extern void CreateField(int x, int y, int z, int FieldType, uint32 Owner, bool Peaceful);
@@ -39,15 +41,20 @@ extern TCreature *GetCreature(uint32 CreatureID);
extern TCreature *GetCreature(Object Obj);
extern TConnection *GetFirstConnection(void);
extern TConnection *GetNextConnection(void);
+extern const char *GetName(Object Obj);
extern TPlayer *GetPlayer(uint32 CreatureID);
+extern bool GetRaceNoConvince(int Race);
+extern bool GetRaceNoIllusion(int Race);
extern bool GetRaceNoParalyze(int Race);
extern bool GetRaceNoSummon(int Race);
+extern TOutfit GetRaceOutfit(int Race);
extern int GetRacePoison(int Race);
extern int GetRaceSummonCost(int Race);
extern void GraphicalEffect(int x, int y, int z, int Type);
extern void GraphicalEffect(Object Obj, int Type);
extern int IdentifyPlayer(const char *Name, bool ExactMatch, bool IgnoreGamemasters, TPlayer **Player);
extern void InitLog(const char *ProtocolName);
+extern void KickGuest(uint16 HouseID, TPlayer *Host, TPlayer *Guest);
extern void LoadMonsterRaid(const char *FileName, int Start,
bool *Type, int *Date, int *Interval, int *Duration);
extern void Log(const char *ProtocolName, const char *Text, ...) ATTR_PRINTF(2, 3);
@@ -78,12 +85,16 @@ extern bool SearchSummonField(int *x, int *y, int *z, int Distance);
extern void SendAll(void);
extern void SendAmbiente(TConnection *Connection);
extern void SendClearTarget(TConnection *Connection);
+extern void SendEditList(TConnection *Connection, uint8 ListType, uint32 ID, const char *Text);
extern void SendMails(TPlayerData *PlayerData);
extern void SendMarkCreature(TConnection *Connection, uint32 CreatureID, int Color);
extern void SendMessage(TConnection *Connection, int Mode, const char *Text, ...) ATTR_PRINTF(3, 4);
extern void SendPlayerData(TConnection *Connection);
extern void SendPlayerSkills(TConnection *Connection);
extern void SendPlayerState(TConnection *Connection, uint8 State);
+extern void ShowGuestList(uint16 HouseID, TPlayer *Player, char *Buffer);
+extern void ShowSubownerList(uint16 HouseID, TPlayer *Player, char *Buffer);
+extern void ShowNameDoor(Object Door, TPlayer *Player, char *Buffer);
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);