aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--reference/game.c323
-rw-r--r--src/connection.hh1
-rw-r--r--src/cr.hh7
-rw-r--r--src/cract.cc6
-rw-r--r--src/crmain.cc5
-rw-r--r--src/crskill.cc21
-rw-r--r--src/magic.cc5
-rw-r--r--src/operate.cc196
-rw-r--r--src/operate.hh15
-rw-r--r--src/stubs.hh15
10 files changed, 247 insertions, 347 deletions
diff --git a/reference/game.c b/reference/game.c
index 213e714..2a7f774 100644
--- a/reference/game.c
+++ b/reference/game.c
@@ -18375,329 +18375,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
return;
}
-
-
-void AnnounceMovingCreature(ulong CreatureID,Object *Con)
-
-{
- TConnection *Connection;
- TCreature *pTVar1;
- int iVar2;
- ulong CharacterID;
- TPlayer *pTVar3;
- int iVar4;
- int iVar5;
- TCreature *cr;
- int local_68;
- int x;
- int y;
- int z;
- TFindCreatures Search;
- Object local_2c [7];
-
- pTVar1 = GetCreature(CreatureID);
- if (pTVar1 == (TCreature *)0x0) {
- error("AnnounceMovingCreature: Kreatur %d existiert nicht.\n",CreatureID);
- }
- else {
- local_2c[0] = (Object)Con->ObjectID;
- GetObjectCoordinates(local_2c,&local_68,&x,&y);
- iVar4 = x - pTVar1->posy;
- iVar2 = -iVar4;
- if (-1 < iVar4) {
- iVar2 = iVar4;
- }
- iVar5 = local_68 - pTVar1->posx;
- iVar4 = -iVar5;
- if (-1 < iVar5) {
- iVar4 = iVar5;
- }
- TFindCreatures::TFindCreatures
- ((TFindCreatures *)&z,iVar4 / 2 + 0x11,iVar2 / 2 + 0xf,
- (local_68 + pTVar1->posx) / 2,(x + pTVar1->posy) / 2,1);
- while( true ) {
- CharacterID = TFindCreatures::getNext((TFindCreatures *)&z);
- if (CharacterID == 0) break;
- pTVar3 = GetPlayer(CharacterID);
- if ((pTVar3 != (TPlayer *)0x0) &&
- (Connection = (pTVar3->super_TCreature).Connection, Connection != (TConnection *)0x0)
- ) {
- SendMoveCreature(Connection,CreatureID,local_68,x,y);
- }
- }
- }
- return;
-}
-
-
-
-void AnnounceChangedCreature(ulong CreatureID,int Type)
-
-{
- TKnownCreature *pTVar1;
- TConnection *this;
- bool bVar2;
- TCreature *pTVar3;
- TKnownCreature *KnownCreature;
- TConnection *Connection;
- TCreature *cr;
-
- pTVar3 = GetCreature(CreatureID);
- if (pTVar3 == (TCreature *)0x0) {
- error("AnnounceChangedCreature: Kreatur %d existiert nicht (Type=%d).\n",CreatureID,Type);
- }
- else {
- for (pTVar1 = pTVar3->FirstKnowingConnection; pTVar1 != (TKnownCreature *)0x0;
- pTVar1 = pTVar1->Next) {
- this = pTVar1->Connection;
- if ((this->State == CONNECTION_GAME) && (pTVar1->State != KNOWNCREATURE_OUTDATED)) {
- bVar2 = TConnection::IsVisible(this,pTVar3->posx,pTVar3->posy,pTVar3->posz);
- if (bVar2) {
- switch(Type) {
- case 1:
- SendCreatureHealth(this,CreatureID);
- break;
- case 2:
- SendCreatureLight(this,CreatureID);
- break;
- case 3:
- SendCreatureOutfit(this,CreatureID);
- break;
- case 4:
- SendCreatureSpeed(this,CreatureID);
- break;
- case 5:
- SendCreatureSkull(this,CreatureID);
- break;
- case 6:
- SendCreatureParty(this,CreatureID);
- }
- }
- else {
- pTVar1->State = KNOWNCREATURE_OUTDATED;
- }
- }
- }
- }
- return;
-}
-
-
-
-void AnnounceChangedField(Object *Obj,int Type)
-
-{
- TConnection *this;
- bool bVar1;
- ulong ID;
- ulong CharacterID;
- TPlayer *pTVar2;
- TPlayer *pl;
- int local_68;
- int x;
- int y;
- int z;
- TFindCreatures Search;
- Object local_2c [7];
-
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- local_2c[0] = (Object)Obj->ObjectID;
- GetObjectCoordinates(local_2c,&local_68,&x,&y);
- TFindCreatures::TFindCreatures((TFindCreatures *)&z,0x10,0xe,local_68,x,1);
-LAB_0808e5c0:
- CharacterID = TFindCreatures::getNext((TFindCreatures *)&z);
- if (CharacterID != 0) {
- pTVar2 = GetPlayer(CharacterID);
- if (((pTVar2 != (TPlayer *)0x0) &&
- (this = (pTVar2->super_TCreature).Connection, this != (TConnection *)0x0)) &&
- (bVar1 = TConnection::IsVisible(this,local_68,x,y), bVar1)) {
- if (Type != 1) {
- if (Type < 2) {
- if (Type == 0) {
- local_2c[0] = (Object)Obj->ObjectID;
- SendDeleteField((pTVar2->super_TCreature).Connection,local_68,x,y,
- local_2c);
- goto LAB_0808e5c0;
- }
- }
- else if (Type == 2) {
- local_2c[0] = (Object)Obj->ObjectID;
- SendChangeField((pTVar2->super_TCreature).Connection,local_68,x,y,local_2c);
- goto LAB_0808e5c0;
- }
- error(&DAT_080fee80,Type);
- return;
- }
- local_2c[0] = (Object)Obj->ObjectID;
- SendAddField((pTVar2->super_TCreature).Connection,local_68,x,y,local_2c);
- }
- goto LAB_0808e5c0;
- }
- }
- else {
- error(&DAT_080fee40);
- }
- return;
-}
-
-
-
-void AnnounceChangedContainer(Object *Obj,int Type)
-
-{
- bool bVar1;
- ulong ID;
- ulong CharacterID;
- TPlayer *Window;
- TPlayer *pl;
- int con;
- int ContNr;
- int iVar2;
- Object local_6c [4];
- Object local_5c [4];
- undefined1 local_4c [4];
- TFindCreatures Search;
-
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- local_5c[0] = (Object)Obj->ObjectID;
- TFindCreatures::TFindCreatures((TFindCreatures *)local_4c,1,1,local_5c,1);
- while (CharacterID = TFindCreatures::getNext((TFindCreatures *)local_4c), CharacterID != 0)
- {
- Window = GetPlayer(CharacterID);
- if ((Window != (TPlayer *)0x0) &&
- ((Window->super_TCreature).Connection != (TConnection *)0x0)) {
- ContNr = 0;
- do {
- iVar2 = ContNr;
- TPlayer::GetOpenContainer((TPlayer *)local_5c,(int)Window);
- Object::getContainer(local_6c);
- if (local_5c[0].ObjectID == local_6c[0].ObjectID) {
- if (Type == 1) {
- local_6c[0] = (Object)Obj->ObjectID;
- SendCreateInContainer
- ((Window->super_TCreature).Connection,ContNr,local_6c);
- }
- else if (Type < 2) {
- if (Type != 0) goto LAB_0808e7c7;
- local_6c[0] = (Object)Obj->ObjectID;
- SendDeleteInContainer
- ((Window->super_TCreature).Connection,ContNr,local_6c);
- }
- else {
- if (Type != 2) {
-LAB_0808e7c7:
- error(&DAT_080fef00,Type,iVar2);
- return;
- }
- local_6c[0] = (Object)Obj->ObjectID;
- SendChangeInContainer
- ((Window->super_TCreature).Connection,ContNr,local_6c);
- }
- }
- ContNr = ContNr + 1;
- } while (ContNr < 0x10);
- }
- }
- }
- else {
- error(&DAT_080feec0);
- }
- return;
-}
-
-
-
-void AnnounceChangedInventory(Object *Obj,int Type)
-
-{
- bool bVar1;
- ulong id;
- TCreature *pTVar2;
- int iVar3;
- TCreature *cr;
- char *Text;
- Object local_3c [4];
- Object local_2c [7];
-
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- local_2c[0] = (Object)Obj->ObjectID;
- id = GetObjectCreatureID(local_2c);
- pTVar2 = GetCreature(id);
- if (pTVar2 != (TCreature *)0x0) {
- if (pTVar2->Type != PLAYER) {
- return;
- }
- if (Type != 0) {
- if ((-1 < Type) && (Type < 3)) {
- local_3c[0] = (Object)Obj->ObjectID;
- local_2c[0].ObjectID = local_3c[0].ObjectID;
- iVar3 = GetObjectBodyPosition(local_3c);
- SendSetInventory(pTVar2->Connection,iVar3,local_2c);
- return;
- }
- error(&DAT_080fef80,Type);
- return;
- }
- local_2c[0] = (Object)Obj->ObjectID;
- iVar3 = GetObjectBodyPosition(local_2c);
- SendDeleteInventory(pTVar2->Connection,iVar3);
- return;
- }
- Text = "AnnounceChangedInventory: Objekt liegt in keinem Inventory.\n";
- }
- else {
- Text = &DAT_080fef40;
- }
- error(Text);
- return;
-}
-
-
-
-void AnnounceChangedObject(Object *Obj,int Type)
-
-{
- bool bVar1;
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c [7];
-
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- Object::getContainer(local_2c);
- Object::getObjectType(local_3c);
- if (local_3c[0].ObjectID == 0) {
- local_3c[0] = (Object)Obj->ObjectID;
- AnnounceChangedField(local_3c,Type);
- }
- else {
- Object::getContainer(local_3c);
- Object::getObjectType(local_4c);
- bVar1 = false;
- if ((0 < (int)local_4c[0].ObjectID) && ((int)local_4c[0].ObjectID < 0xb)) {
- bVar1 = true;
- }
- if (bVar1) {
- local_4c[0] = (Object)Obj->ObjectID;
- AnnounceChangedInventory(local_4c,Type);
- }
- else {
- local_4c[0] = (Object)Obj->ObjectID;
- AnnounceChangedContainer(local_4c,Type);
- }
- }
- }
- else {
- error(&DAT_080ff000);
- }
- return;
-}
-
-
-
void AnnounceGraphicalEffect(int x,int y,int z,int Type)
{
diff --git a/src/connection.hh b/src/connection.hh
index d3a53df..ec79a6e 100644
--- a/src/connection.hh
+++ b/src/connection.hh
@@ -15,6 +15,7 @@ struct TKnownCreature {
struct TConnection {
void Logout(int Delay, bool StopFight);
+ bool IsVisible(int x, int y, int z);
// DATA
// =================
diff --git a/src/cr.hh b/src/cr.hh
index 92521bd..162cb68 100644
--- a/src/cr.hh
+++ b/src/cr.hh
@@ -403,6 +403,13 @@ struct TCombat{
// TFindCreatures
// =============================================================================
+enum : int {
+ FIND_PLAYERS = 0x01,
+ FIND_NPCS = 0x02,
+ FIND_MONSTERS = 0x04,
+ FIND_ALL = FIND_PLAYERS | FIND_NPCS | FIND_MONSTERS,
+};
+
struct TFindCreatures {
TFindCreatures(int RadiusX, int RadiusY, int CenterX, int CenterY, int Mask);
TFindCreatures(int RadiusX, int RadiusY, uint32 CreatureID, int Mask);
diff --git a/src/cract.cc b/src/cract.cc
index d6fd2ee..325fbdc 100644
--- a/src/cract.cc
+++ b/src/cract.cc
@@ -395,7 +395,7 @@ void TCreature::Go(int DestX, int DestY, int DestZ){
void TCreature::Rotate(int Direction){
this->Direction = Direction;
- AnnounceChangedObject(this->CrObject, 2); // OBJECT_CHANGED ?
+ AnnounceChangedObject(this->CrObject, OBJECT_CHANGED);
}
void TCreature::Rotate(TCreature *Target){
@@ -1561,7 +1561,7 @@ void TCreature::NotifyChangeInventory(void){
SkillsChanged = true;
Skill->DAct = NewDelta[SkillNr];
if(SkillNr == SKILL_GO_STRENGTH){
- AnnounceChangedCreature(this->ID, 4); // CREATURE_GO_STRENGTH_CHANGED ?
+ AnnounceChangedCreature(this->ID, CREATURE_SPEED_CHANGED);
}else if(SkillNr == SKILL_ILLUSION){
if(NewDelta[SKILL_ILLUSION] > 0){
if(this->Outfit.OutfitID != 0 || this->Outfit.ObjectType != 0){
@@ -1574,7 +1574,7 @@ void TCreature::NotifyChangeInventory(void){
}else if(Skill->TimerValue() == 0){
this->Outfit = this->OrgOutfit;
}
- AnnounceChangedCreature(this->ID, 3); // CREATURE_OUTFIT_CHANGED ?
+ AnnounceChangedCreature(this->ID, CREATURE_OUTFIT_CHANGED);
}
}
}
diff --git a/src/crmain.cc b/src/crmain.cc
index 00cd3e2..52a7c13 100644
--- a/src/crmain.cc
+++ b/src/crmain.cc
@@ -2,6 +2,7 @@
#include "config.hh"
#include "enums.hh"
#include "info.hh"
+#include "operate.hh"
#include "stubs.hh"
@@ -590,7 +591,7 @@ int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){
&& this->Outfit.ObjectType == 0){
this->SetTimer(SKILL_ILLUSION, 0, 0, 0, -1);
this->Outfit = this->OrgOutfit;
- AnnounceChangedCreature(this->ID, 3); // CREATURE_OUTFIT_CHANGED ?
+ AnnounceChangedCreature(this->ID, CREATURE_OUTFIT_CHANGED);
NotifyAllCreatures(this->CrObject, 2, NONE); // CREATURE_APPEAR ?
}
@@ -834,7 +835,7 @@ int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){
}
}
- AnnounceChangedCreature(this->ID, 1); // CREATURE_HITPOINTS_CHANGED ?
+ AnnounceChangedCreature(this->ID, CREATURE_HEALTH_CHANGED);
return Damage;
}
diff --git a/src/crskill.cc b/src/crskill.cc
index b1a9d42..f400dc9 100644
--- a/src/crskill.cc
+++ b/src/crskill.cc
@@ -1,4 +1,5 @@
#include "cr.hh"
+#include "operate.hh"
#include "stubs.hh"
@@ -350,7 +351,7 @@ bool TSkillLevel::Jump(int Range){
this->Master->Skills[SKILL_GO_STRENGTH ]->Advance(Range);
this->Master->Skills[SKILL_CARRY_STRENGTH]->Advance(Range);
- AnnounceChangedCreature(this->Master->ID, 4);
+ AnnounceChangedCreature(this->Master->ID, CREATURE_SPEED_CHANGED);
this->Master->Combat.CheckCombatValues();
if(this->Master->Type == PLAYER){
@@ -691,7 +692,7 @@ void TSkillHitpoints::Set(int Value){
if(Master->Type == PLAYER){
SendPlayerData(Master->Connection);
}
- AnnounceChangedCreature(Master->ID, 1);
+ AnnounceChangedCreature(Master->ID, CREATURE_HEALTH_CHANGED);
}
}
@@ -734,7 +735,7 @@ bool TSkillGoStrength::SetTimer(int Cycle, int Count, int MaxCount, int Addition
if(Master->Type == PLAYER){
((TPlayer*)Master)->CheckState();
}
- AnnounceChangedCreature(Master->ID, 4);
+ AnnounceChangedCreature(Master->ID, CREATURE_SPEED_CHANGED);
return true;
}
@@ -754,7 +755,7 @@ void TSkillGoStrength::Event(int Range){
if(this->SkNr == SKILL_GO_STRENGTH && Master->Type == PLAYER){
((TPlayer*)Master)->CheckState();
}
- AnnounceChangedCreature(Master->ID, 4);
+ AnnounceChangedCreature(Master->ID, CREATURE_SPEED_CHANGED);
}
// TSkillCarryStrength
@@ -903,9 +904,9 @@ bool TSkillLight::SetTimer(int Cycle, int Count, int MaxCount, int AdditionalVal
// TODO(fusion): The decompiled function had this logic, but WTF.
// if(GetCreature(Master->ID) != NULL){
- // AnnounceChangedCreature(Master->ID, 2);
+ // AnnounceChangedCreature(Master->ID, CREATURE_LIGHT_CHANGED);
// }
- AnnounceChangedCreature(Master->ID, 2);
+ AnnounceChangedCreature(Master->ID, CREATURE_LIGHT_CHANGED);
return true;
}
@@ -916,7 +917,7 @@ void TSkillLight::Event(int Range){
return;
}
- AnnounceChangedCreature(Master->ID, 2);
+ AnnounceChangedCreature(Master->ID, CREATURE_LIGHT_CHANGED);
}
// TSkillIllusion
@@ -938,9 +939,9 @@ bool TSkillIllusion::SetTimer(int Cycle, int Count, int MaxCount, int Additional
// TODO(fusion): The decompiled function had this logic, but WTF.
// if(GetCreature(Master->ID) != NULL){
- // AnnounceChangedCreature(Master->ID, 3);
+ // AnnounceChangedCreature(Master->ID, CREATURE_OUTFIT_CHANGED);
// }
- AnnounceChangedCreature(Master->ID, 3);
+ AnnounceChangedCreature(Master->ID, CREATURE_OUTFIT_CHANGED);
return true;
}
@@ -954,7 +955,7 @@ void TSkillIllusion::Event(int Range){
if(this->Get() <= 0){
Master->Outfit = Master->OrgOutfit;
- AnnounceChangedCreature(Master->ID, 3);
+ AnnounceChangedCreature(Master->ID, CREATURE_OUTFIT_CHANGED);
NotifyAllCreatures(Master->CrObject, 2, NONE);
}
}
diff --git a/src/magic.cc b/src/magic.cc
index 728b681..6cff8bc 100644
--- a/src/magic.cc
+++ b/src/magic.cc
@@ -1,6 +1,7 @@
#include "magic.hh"
#include "config.hh"
#include "info.hh"
+#include "operate.hh"
#include "stubs.hh"
@@ -1503,7 +1504,7 @@ void Teleport(TCreature *Actor, const char *Param){
GraphicalEffect(DestX, DestY, DestZ, EFFECT_ENERGY);
}else if(MDGoStrength != Actor->Skills[SKILL_GO_STRENGTH]->MDAct){
Actor->Skills[SKILL_GO_STRENGTH]->SetMDAct(MDGoStrength);
- AnnounceChangedCreature(Actor->ID, 4); // CREATURE_GO_STRENGTH_CHANGED ?
+ AnnounceChangedCreature(Actor->ID, CREATURE_SPEED_CHANGED);
GraphicalEffect(DestX, DestY, DestZ, EFFECT_MAGIC_BLUE);
}
}
@@ -2399,7 +2400,7 @@ void CancelInvisibility(TCreature *Actor, Object Target, int ManaPoints, int Sou
Victim->SetTimer(SKILL_ILLUSION, 0, 0, 0, -1);
if(Victim->Skills[SKILL_ILLUSION]->Get() == 0){
Victim->Outfit = Victim->OrgOutfit;
- AnnounceChangedCreature(Victim->ID, 3); // CREATURE_OUTFIT_CHANGED ?
+ AnnounceChangedCreature(Victim->ID, CREATURE_OUTFIT_CHANGED);
NotifyAllCreatures(Victim->CrObject, 2, NONE); // CREATURE_APPEAR ?
}else{
Effect = EFFECT_BLOCK_HIT;
diff --git a/src/operate.cc b/src/operate.cc
index 041d663..a76e723 100644
--- a/src/operate.cc
+++ b/src/operate.cc
@@ -4,7 +4,6 @@
#include "stubs.hh"
// operate.cc
-void AnnounceMovingCreature(uint32 CreatureID, Object Con);
void CheckTopMoveObject(uint32 CreatureID, Object Obj, Object Ignore);
void CheckMoveObject(uint32 CreatureID, Object Obj, bool Take);
void CheckMapDestination(uint32 CreatureID, Object Obj, Object MapCon);
@@ -23,6 +22,189 @@ void CollisionEvent(Object Obj, Object Dest);
void SeparationEvent(Object Obj, Object Start);
+//==================================================================================================
+//==================================================================================================
+//==================================================================================================
+//==================================================================================================
+
+void AnnounceMovingCreature(uint32 CreatureID, Object Con){
+ TCreature *Creature = GetCreature(CreatureID);
+ if(Creature == NULL){
+ error("AnnounceMovingCreature: Kreatur %d existiert nicht.\n", CreatureID);
+ return;
+ }
+
+ int ConX, ConY, ConZ;
+ GetObjectCoordinates(Con, &ConX, &ConY, &ConZ);
+
+ // TODO(fusion): 17 and 15 are probably related to the client's viewport dimensions.
+ int SearchWidth = 17 + std::abs(Creature->posx - ConX) / 2;
+ int SearchHeight = 15 + std::abs(Creature->posy - ConY) / 2;
+ int SearchCenterX = (Creature->posx + ConX) / 2;
+ int SearchCenterY = (Creature->posy + ConY) / 2;
+ TFindCreatures Search(SearchWidth, SearchHeight, SearchCenterX, SearchCenterY, FIND_PLAYERS);
+ while(true){
+ uint32 CharacterID = Search.getNext();
+ if(CharacterID == 0){
+ break;
+ }
+
+ TPlayer *Player = GetPlayer(CharacterID);
+ if(Player != NULL && Player->Connection != NULL){
+ SendMoveCreature(Player->Connection, CreatureID, ConX, ConY, ConZ);
+ }
+ }
+}
+
+void AnnounceChangedCreature(uint32 CreatureID, int Type){
+ TCreature *Creature = GetCreature(CreatureID);
+ if(Creature == NULL){
+ error("AnnounceChangedCreature: Kreatur %d existiert nicht (Type=%d).\n", CreatureID, Type);
+ return;
+ }
+
+ for(TKnownCreature *KnownCreature = Creature->FirstKnowingConnection;
+ KnownCreature != NULL;
+ KnownCreature = KnownCreature->Next){
+ TConnection *KnowingConnection = KnownCreature->Connection;
+ if(KnowingConnection->State != CONNECTION_GAME
+ || KnownCreature->State == KNOWNCREATURE_OUTDATED){
+ continue;
+ }
+
+ if(KnowingConnection->IsVisible(Creature->posx, Creature->posy, Creature->posz)){
+ switch(Type){
+ case CREATURE_HEALTH_CHANGED: SendCreatureHealth(KnowingConnection, CreatureID); break;
+ case CREATURE_LIGHT_CHANGED: SendCreatureLight(KnowingConnection, CreatureID); break;
+ case CREATURE_OUTFIT_CHANGED: SendCreatureOutfit(KnowingConnection, CreatureID); break;
+ case CREATURE_SPEED_CHANGED: SendCreatureSpeed(KnowingConnection, CreatureID); break;
+ case CREATURE_SKULL_CHANGED: SendCreatureSkull(KnowingConnection, CreatureID); break;
+ case CREATURE_PARTY_CHANGED: SendCreatureParty(KnowingConnection, CreatureID); break;
+ }
+ }else{
+ KnownCreature->State = KNOWNCREATURE_OUTDATED;
+ }
+ }
+}
+
+void AnnounceChangedField(Object Obj, int Type){
+ if(!Obj.exists()){
+ error("AnnounceChangedField: Übergebenes Objekt existiert nicht.\n");
+ return;
+ }
+
+ int ObjX, ObjY, ObjZ;
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ TFindCreatures Search(16, 14, ObjX, ObjY, FIND_PLAYERS);
+ while(true){
+ uint32 CharacterID = Search.getNext();
+ if(CharacterID == 0){
+ break;
+ }
+
+ TPlayer *Player = GetPlayer(CharacterID);
+ if(Player == NULL || Player->Connection == NULL
+ || !Player->Connection->IsVisible(ObjX, ObjY, ObjZ)){
+ continue;
+ }
+
+ switch(Type){
+ case OBJECT_DELETED: SendDeleteField(Player->Connection, ObjX, ObjY, ObjZ, Obj); break;
+ case OBJECT_CREATED: SendAddField(Player->Connection, ObjX, ObjY, ObjZ, Obj); break;
+ case OBJECT_CHANGED: SendChangeField(Player->Connection, ObjX, ObjY, ObjZ, Obj); break;
+ default:{
+ error("AnnounceChangedField: Ungültiger Typ %d.\n", Type);
+ return;
+ }
+ }
+ }
+}
+
+void AnnounceChangedContainer(Object Obj, int Type){
+ if(!Obj.exists()){
+ error("AnnounceChangedContainer: Übergebenes Objekt existiert nicht.\n");
+ return;
+ }
+
+ Object Con = Obj.getContainer();
+ TFindCreatures Search(1, 1, Obj, FIND_PLAYERS);
+ while(true){
+ uint32 CharacterID = Search.getNext();
+ if(CharacterID == 0){
+ break;
+ }
+
+ TPlayer *Player = GetPlayer(CharacterID);
+ if(Player == NULL || Player->Connection == NULL){
+ continue;
+ }
+
+ for(int ContainerNr = 0;
+ ContainerNr <= NARRAY(Player->OpenContainer);
+ ContainerNr += 1){
+ if(Player->GetOpenContainer(ContainerNr) != Con){
+ continue;
+ }
+
+ switch(Type){
+ case OBJECT_DELETED: SendDeleteInContainer(Player->Connection, ContainerNr, Obj); break;
+ case OBJECT_CREATED: SendCreateInContainer(Player->Connection, ContainerNr, Obj); break;
+ case OBJECT_CHANGED: SendChangeInContainer(Player->Connection, ContainerNr, Obj); break;
+ default:{
+ error("AnnounceChangedContainer: Ungültiger Typ %d.\n", Type);
+ return;
+ }
+ }
+ }
+ }
+}
+
+void AnnounceChangedInventory(Object Obj, int Type){
+ if(!Obj.exists()){
+ error("AnnounceChangedInventory: Übergebenes Objekt existiert nicht.\n");
+ return;
+ }
+
+ uint32 OwnerID = GetObjectCreatureID(Obj);
+ TCreature *Creature = GetCreature(OwnerID);
+ if(Creature == NULL){
+ error("AnnounceChangedInventory: Objekt liegt in keinem Inventory.\n");
+ return;
+ }
+
+ if(Creature->Type != PLAYER){
+ return;
+ }
+
+ int Position = GetObjectBodyPosition(Obj);
+ switch(Type){
+ case OBJECT_DELETED: SendDeleteInventory(Creature->Connection, Position); break;
+ case OBJECT_CREATED: SendSetInventory(Creature->Connection, Position, Obj); break;
+ case OBJECT_CHANGED: SendSetInventory(Creature->Connection, Position, Obj); break;
+ default:{
+ error("AnnounceChangedInventory: Ungültiger Typ %d.\n", Type);
+ return;
+ }
+ }
+}
+
+void AnnounceChangedObject(Object Obj, int Type){
+ if(!Obj.exists()){
+ error("AnnounceChangedObject: Übergebenes Objekt existiert nicht.\n");
+ return;
+ }
+
+ Object Con = Obj.getContainer();
+ ObjectType ConType = Con.getObjectType();
+ if(ConType.isMapContainer()){
+ AnnounceChangedField(Obj, Type);
+ }else if(ConType.isBodyContainer()){
+ AnnounceChangedInventory(Obj, Type);
+ }else{
+ AnnounceChangedContainer(Obj, Type);
+ }
+}
+
// TODO(fusion): This could have been a simple return value.
void CheckContainerDestination(Object Obj, Object Con){
Object Help = Con;
@@ -212,7 +394,7 @@ void Move(uint32 CreatureID, Object Obj, Object Con, int Count, bool NoMerge, Ob
// easier to read.
if(!ObjType.isCreatureContainer() && Remainder == NONE){
- AnnounceChangedObject(Obj, 0); // OBJECT_DISAPPEAR ?
+ AnnounceChangedObject(Obj, OBJECT_DELETED);
NotifyTrades(Obj);
NotifyDepot(CreatureID, Obj, CountObjects(Obj));
}
@@ -237,13 +419,13 @@ void Move(uint32 CreatureID, Object Obj, Object Con, int Count, bool NoMerge, Ob
MoveObject(Obj, Con);
if(!ObjType.isCreatureContainer()){
- AnnounceChangedObject(Obj, 1); // OBJECT_APPEAR
+ AnnounceChangedObject(Obj, OBJECT_CREATED);
NotifyTrades(Obj);
NotifyDepot(CreatureID, Obj, -CountObjects(Obj));
}
if(Remainder != NONE){
- AnnounceChangedObject(Remainder, 2); // OBJECT_CHANGED
+ AnnounceChangedObject(Remainder, OBJECT_CHANGED);
NotifyTrades(Remainder);
}
@@ -336,17 +518,17 @@ void Merge(uint32 CreatureID, Object Obj, Object Dest, int Count, Object Ignore)
if(Count < ObjCount){
ChangeObject(Obj, AMOUNT, ObjCount - Count);
- AnnounceChangedObject(Obj, 2); // OBJECT_CHANGED ?
+ AnnounceChangedObject(Obj, OBJECT_CHANGED);
NotifyTrades(Obj);
ChangeObject(Dest, AMOUNT, DestCount + Count);
}else{
- AnnounceChangedObject(Obj, 0); // OBJECT_DISAPPEAR ?
+ AnnounceChangedObject(Obj, OBJECT_DELETED);
NotifyTrades(Obj);
NotifyDepot(CreatureID, Obj, 1);
MergeObjects(Obj, Dest);
}
- AnnounceChangedObject(Dest, 2); // OBJECT_CHANGED ?
+ AnnounceChangedObject(Dest, OBJECT_CHANGED);
NotifyTrades(Dest);
NotifyCreature(ObjOwnerID, Dest, ObjCon.getObjectType().isBodyContainer());
NotifyCreature(DestOwnerID, Dest, DestCon.getObjectType().isBodyContainer());
diff --git a/src/operate.hh b/src/operate.hh
index 6270ec7..de7b54d 100644
--- a/src/operate.hh
+++ b/src/operate.hh
@@ -4,6 +4,21 @@
#include "common.hh"
#include "map.hh"
+enum : int {
+ CREATURE_HEALTH_CHANGED = 1,
+ CREATURE_LIGHT_CHANGED = 2,
+ CREATURE_OUTFIT_CHANGED = 3,
+ CREATURE_SPEED_CHANGED = 4,
+ CREATURE_SKULL_CHANGED = 5,
+ CREATURE_PARTY_CHANGED = 6,
+};
+
+enum : int {
+ OBJECT_DELETED = 0,
+ OBJECT_CREATED = 1,
+ OBJECT_CHANGED = 2,
+};
+
void CheckContainerDestination(Object Obj, Object Con);
void CheckInventoryDestination(Object Obj, Object Con, bool Split);
diff --git a/src/stubs.hh b/src/stubs.hh
index 4c1b0cb..a2c5f25 100644
--- a/src/stubs.hh
+++ b/src/stubs.hh
@@ -69,6 +69,20 @@ extern void SendAmbiente(TConnection *Connection);
extern void SendClearTarget(TConnection *Connection);
extern void SendCloseContainer(TConnection *Connection, int ContainerNr);
extern void SendCloseTrade(TConnection *Connection);
+extern void SendCreatureHealth(TConnection *Connection, uint32 CreatureID);
+extern void SendCreatureLight(TConnection *Connection, uint32 CreatureID);
+extern void SendCreatureOutfit(TConnection *Connection, uint32 CreatureID);
+extern void SendCreatureSpeed(TConnection *Connection, uint32 CreatureID);
+extern void SendCreatureSkull(TConnection *Connection, uint32 CreatureID);
+extern void SendCreatureParty(TConnection *Connection, uint32 CreatureID);
+extern void SendDeleteField(TConnection *Connection, int x, int y, int z, Object Obj);
+extern void SendAddField(TConnection *Connection, int x, int y, int z, Object Obj);
+extern void SendChangeField(TConnection *Connection, int x, int y, int z, Object Obj);
+extern void SendDeleteInContainer(TConnection *Connection, int ContainerNr, Object Obj);
+extern void SendCreateInContainer(TConnection *Connection, int ContainerNr, Object Obj);
+extern void SendChangeInContainer(TConnection *Connection, int ContainerNr, Object Obj);
+extern void SendDeleteInventory(TConnection *Connection, int Position);
+extern void SendSetInventory(TConnection *Connection, int Position, Object Obj);
extern void SendEditList(TConnection *Connection, uint8 ListType, uint32 ID, const char *Text);
extern void SendFullScreen(TConnection *Connection);
extern void SendFloors(TConnection *Connection, bool Up);
@@ -76,6 +90,7 @@ extern void SendRow(TConnection *Connection, int Direction);
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);
+void SendMoveCreature(TConnection *Connection, uint32 CreatureID, int x, int y, int z);
extern void SendPlayerData(TConnection *Connection);
extern void SendPlayerSkills(TConnection *Connection);
extern void SendPlayerState(TConnection *Connection, uint8 State);