aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--reference/game.c330
-rw-r--r--src/map.cc6
-rw-r--r--src/map.hh2
-rw-r--r--src/operate.cc213
-rw-r--r--src/stubs.hh5
5 files changed, 211 insertions, 345 deletions
diff --git a/reference/game.c b/reference/game.c
index 2a7f774..3686e32 100644
--- a/reference/game.c
+++ b/reference/game.c
@@ -18375,336 +18375,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
return;
}
-void AnnounceGraphicalEffect(int x,int y,int z,int Type)
-
-{
- TConnection *pTVar1;
- bool bVar2;
- ulong ID;
- ulong CharacterID;
- TPlayer *pTVar3;
- int x_00;
- TPlayer *pl;
- undefined1 local_4c [4];
- TFindCreatures Search;
-
- bVar2 = IsOnMap(x,y,z);
- if (bVar2) {
- TFindCreatures::TFindCreatures((TFindCreatures *)local_4c,0x10,0xe,x,y,1);
- while( true ) {
- CharacterID = TFindCreatures::getNext((TFindCreatures *)local_4c);
- if (CharacterID == 0) break;
- pTVar3 = GetPlayer(CharacterID);
- if ((pTVar3 != (TPlayer *)0x0) &&
- (pTVar1 = (pTVar3->super_TCreature).Connection, pTVar1 != (TConnection *)0x0)) {
- bVar2 = TConnection::IsVisible(pTVar1,x,y,z);
- if (bVar2) {
- pTVar1 = (pTVar3->super_TCreature).Connection;
- SendGraphicalEffect(pTVar1,x_00,(int)pTVar1,x,y);
- }
- }
- }
- }
- return;
-}
-
-
-
-void AnnounceTextualEffect(int x,int y,int z,int Color,char *Text)
-
-{
- TConnection *this;
- bool bVar1;
- ulong ID;
- ulong CharacterID;
- TPlayer *pTVar2;
- TPlayer *pl;
- undefined1 local_4c [4];
- TFindCreatures Search;
-
- bVar1 = IsOnMap(x,y,z);
- if (bVar1) {
- TFindCreatures::TFindCreatures((TFindCreatures *)local_4c,0x10,0xe,x,y,1);
- while( true ) {
- CharacterID = TFindCreatures::getNext((TFindCreatures *)local_4c);
- if (CharacterID == 0) break;
- pTVar2 = GetPlayer(CharacterID);
- if ((pTVar2 != (TPlayer *)0x0) &&
- (this = (pTVar2->super_TCreature).Connection, this != (TConnection *)0x0)) {
- bVar1 = TConnection::IsVisible(this,x,y,z);
- if (bVar1) {
- SendTextualEffect((pTVar2->super_TCreature).Connection,x,y,z,Color,Text);
- }
- }
- }
- }
- return;
-}
-
-
-
-void AnnounceMissile(int sx,int sy,int sz,int zx,int zy,int zz,int Type)
-
-{
- TConnection *pTVar1;
- bool bVar2;
- ulong ID;
- ulong CharacterID;
- TPlayer *pTVar3;
- int iVar4;
- int extraout_EDX;
- int extraout_EDX_00;
- TPlayer *pl;
- int iVar5;
- int iVar6;
- undefined1 local_4c [4];
- TFindCreatures Search;
-
- bVar2 = IsOnMap(sx,sy,sz);
- if (bVar2) {
- bVar2 = IsOnMap(zx,zy,zz);
- if (bVar2) {
- iVar5 = sy - zy;
- iVar4 = -iVar5;
- if (-1 < iVar5) {
- iVar4 = iVar5;
- }
- iVar6 = sx - zx;
- iVar5 = -iVar6;
- if (-1 < iVar6) {
- iVar5 = iVar6;
- }
- TFindCreatures::TFindCreatures
- ((TFindCreatures *)local_4c,iVar5 / 2 + 0x11,iVar4 / 2 + 0xf,(sx + zx) / 2,
- (zy + sy) / 2,1);
-LAB_0808ec90:
- CharacterID = TFindCreatures::getNext((TFindCreatures *)local_4c);
- if (CharacterID != 0) {
- pTVar3 = GetPlayer(CharacterID);
- if ((pTVar3 != (TPlayer *)0x0) &&
- (pTVar1 = (pTVar3->super_TCreature).Connection, pTVar1 != (TConnection *)0x0)) {
- bVar2 = TConnection::IsVisible(pTVar1,sx,sy,sz);
- iVar4 = extraout_EDX;
- if (!bVar2) {
- bVar2 = TConnection::IsVisible
- ((pTVar3->super_TCreature).Connection,zx,zy,zz);
- iVar4 = extraout_EDX_00;
- if (!bVar2) goto LAB_0808ec90;
- }
- pTVar1 = (pTVar3->super_TCreature).Connection;
- SendMissileEffect(pTVar1,iVar4,(int)pTVar1,sx,sy,sz,zx,zy);
- }
- goto LAB_0808ec90;
- }
- }
- }
- return;
-}
-
-
-
-void CheckTopMoveObject(ulong CreatureID,Object *Obj,Object *Ignore)
-
-{
- bool bVar1;
- bool bVar2;
- ulong uVar3;
- undefined4 *puVar4;
- Object *pOVar5;
- Object local_7c [4];
- Object local_6c [4];
- Object local_5c [4];
- Object local_4c;
- Object Help;
- Object local_3c;
- Object Best;
- Object local_2c;
- Object Con;
-
- // try { // try from 0808ed5b to 0808efdb has its CatchHandler @ 0808eff3
- bVar1 = Object::exists(Obj);
- if (!bVar1) {
- error("CheckTopMoveObject: Objekt existiert nicht.\n");
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
-LAB_0808eeb3:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
- }
- if ((CreatureID != 0) && (bVar1 = IsCreaturePlayer(CreatureID), bVar1)) {
- Object::getContainer(&local_2c);
- Object::getObjectType(&local_3c);
- if ((local_3c.ObjectID == 0) &&
- ((Object::getObjectType(&local_3c), local_3c.ObjectID != 99 ||
- (uVar3 = Object::getCreatureID(Obj), uVar3 != CreatureID)))) {
- pOVar5 = local_5c;
- local_3c.ObjectID = NONE.ObjectID;
- local_5c[0].ObjectID = local_2c.ObjectID;
- GetFirstContainerObject(&local_4c);
- local_5c[0].ObjectID = NONE.ObjectID;
- if (local_4c.ObjectID != NONE.ObjectID) {
- do {
- local_6c[0] = (Object)Ignore->ObjectID;
- local_5c[0].ObjectID = NONE.ObjectID;
- if (local_4c.ObjectID != local_6c[0].ObjectID) {
- local_6c[0].ObjectID = NONE.ObjectID;
- bVar1 = false;
- if (local_3c.ObjectID == NONE.ObjectID) {
-LAB_0808ee2b:
- bVar1 = true;
- }
- else {
- Object::getObjectType(local_5c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_5c,UNMOVE);
- if ((!bVar2) &&
- ((Object::getObjectType(local_5c), local_5c[0].ObjectID != 99 ||
- (Object::getObjectType(local_5c), local_5c[0].ObjectID != 99))))
- goto LAB_0808ee2b;
- }
- if (bVar1) {
- local_7c[0].ObjectID = local_4c.ObjectID;
- local_3c.ObjectID = local_4c.ObjectID;
- local_5c[0].ObjectID = local_4c.ObjectID;
- }
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,BANK);
- if (!bVar1) {
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,CLIP);
- if (!bVar1) {
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,BOTTOM);
- if (!bVar1) {
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,TOP);
- if ((!bVar1) &&
- (pOVar5 = &local_4c, Object::getObjectType(local_7c),
- local_7c[0].ObjectID != 99)) break;
- }
- }
- }
- }
- pOVar5 = &local_4c;
- Object::getNextObject(local_6c);
- local_7c[0].ObjectID = local_6c[0].ObjectID;
- local_4c.ObjectID = local_6c[0].ObjectID;
- local_5c[0].ObjectID = NONE.ObjectID;
- } while (local_6c[0].ObjectID != NONE.ObjectID);
- }
- local_7c[0].ObjectID = local_3c.ObjectID;
- local_6c[0].ObjectID = local_3c.ObjectID;
- if (Obj->ObjectID != local_3c.ObjectID) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4,pOVar5);
- *puVar4 = 1;
- goto LAB_0808eeb3;
- }
- }
- }
- return;
-}
-
-
-
-void CheckTopUseObject(ulong CreatureID,Object *Obj)
-
-{
- bool bVar1;
- bool bVar2;
- undefined4 *puVar3;
- Object *pOVar4;
- Object local_7c [4];
- Object local_6c [4];
- Object local_5c [4];
- Object local_4c;
- Object Help;
- Object local_3c;
- Object Best;
- Object local_2c;
- Object Con;
-
- // try { // try from 0808f02b to 0808f27b has its CatchHandler @ 0808f293
- bVar1 = Object::exists(Obj);
- if (!bVar1) {
- error("CheckTopUseObject: Objekt existiert nicht.\n");
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
-LAB_0808f19d:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
- }
- if ((CreatureID != 0) && (bVar1 = IsCreaturePlayer(CreatureID), bVar1)) {
- Object::getContainer(&local_2c);
- Object::getObjectType(&local_3c);
- if (local_3c.ObjectID == 0) {
- pOVar4 = local_5c;
- local_3c.ObjectID = NONE.ObjectID;
- local_5c[0].ObjectID = local_2c.ObjectID;
- GetFirstContainerObject(&local_4c);
- local_5c[0].ObjectID = NONE.ObjectID;
- if (local_4c.ObjectID != NONE.ObjectID) {
- do {
- local_6c[0].ObjectID = NONE.ObjectID;
- bVar1 = false;
- local_5c[0].ObjectID = NONE.ObjectID;
- if (local_3c.ObjectID == NONE.ObjectID) {
-LAB_0808f0cd:
- bVar1 = true;
- }
- else {
- Object::getObjectType(local_5c);
- if (local_5c[0].ObjectID != 99) {
- Object::getObjectType(local_5c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_5c,LIQUIDPOOL);
- if (!bVar2) goto LAB_0808f0cd;
- }
- }
- if (bVar1) {
- local_7c[0].ObjectID = local_4c.ObjectID;
- local_3c.ObjectID = local_4c.ObjectID;
- local_5c[0].ObjectID = local_4c.ObjectID;
- }
- Object::getObjectType(local_7c);
- pOVar4 = (Object *)0x9;
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,FORCEUSE);
- if (bVar1) break;
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,BANK);
- if (!bVar1) {
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,CLIP);
- if (!bVar1) {
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,BOTTOM);
- if (!bVar1) {
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,TOP);
- if ((!bVar1) &&
- (pOVar4 = &local_4c, Object::getObjectType(local_7c),
- local_7c[0].ObjectID != 99)) break;
- }
- }
- }
- pOVar4 = &local_4c;
- Object::getNextObject(local_6c);
- local_7c[0].ObjectID = local_6c[0].ObjectID;
- local_4c.ObjectID = local_6c[0].ObjectID;
- local_5c[0].ObjectID = NONE.ObjectID;
- } while (local_6c[0].ObjectID != NONE.ObjectID);
- }
- local_7c[0].ObjectID = local_3c.ObjectID;
- local_6c[0].ObjectID = local_3c.ObjectID;
- if (Obj->ObjectID != local_3c.ObjectID) {
- puVar3 = (undefined4 *)__cxa_allocate_exception(4,pOVar4);
- *puVar3 = 1;
- goto LAB_0808f19d;
- }
- }
- }
- return;
-}
-
-
-
void CheckTopMultiuseObject(ulong CreatureID,Object *Obj)
{
diff --git a/src/map.cc b/src/map.cc
index 9ce568d..b9085c9 100644
--- a/src/map.cc
+++ b/src/map.cc
@@ -2017,7 +2017,7 @@ int GetObjectPriority(Object Obj){
}else if(ObjType.isCreatureContainer()){
ObjPriority = PRIORITY_CREATURE;
}else{
- ObjPriority = PRIORITY_OTHER;
+ ObjPriority = PRIORITY_LOW;
}
return ObjPriority;
}
@@ -2043,11 +2043,11 @@ void PlaceObject(Object Obj, Object Con, bool Append){
Object Cur(Con.getAttribute(CONTENT));
if(ConType.isMapContainer()){
// TODO(fusion): Review. The loop below was a bit rough but it seems that
- // append is forced for non PRIORITY_CREATURE and PRIORITY_OTHER.
+ // append is forced for non PRIORITY_CREATURE and PRIORITY_LOW.
int ObjPriority = GetObjectPriority(Obj);
Append = Append
|| (ObjPriority != PRIORITY_CREATURE
- && ObjPriority != PRIORITY_OTHER);
+ && ObjPriority != PRIORITY_LOW);
while(Cur != NONE){
int CurPriority = GetObjectPriority(Cur);
diff --git a/src/map.hh b/src/map.hh
index e1a9e22..8989f05 100644
--- a/src/map.hh
+++ b/src/map.hh
@@ -26,7 +26,7 @@ enum : int {
PRIORITY_BOTTOM = 2,
PRIORITY_TOP = 3,
PRIORITY_CREATURE = 4,
- PRIORITY_OTHER = 5,
+ PRIORITY_LOW = 5,
};
struct Object {
diff --git a/src/operate.cc b/src/operate.cc
index a76e723..603cc7f 100644
--- a/src/operate.cc
+++ b/src/operate.cc
@@ -4,7 +4,6 @@
#include "stubs.hh"
// operate.cc
-void CheckTopMoveObject(uint32 CreatureID, Object Obj, Object Ignore);
void CheckMoveObject(uint32 CreatureID, Object Obj, bool Take);
void CheckMapDestination(uint32 CreatureID, Object Obj, Object MapCon);
void CheckDepotSpace(uint32 CreatureID, Object Source, Object Destination, int Count);
@@ -27,6 +26,12 @@ void SeparationEvent(Object Obj, Object Start);
//==================================================================================================
//==================================================================================================
+// TODO(fusion): The radii parameters for `TFindCreatures` are commonly around
+// 16 and 14 for x and y respectively so there is probably some constant involved.
+// Also, since we're talking about radii, these values are quite large when you
+// consider the regular client's viewport dimensions of 15x11 visible fields or
+// 18x14 total fields.
+
void AnnounceMovingCreature(uint32 CreatureID, Object Con){
TCreature *Creature = GetCreature(CreatureID);
if(Creature == NULL){
@@ -37,12 +42,11 @@ void AnnounceMovingCreature(uint32 CreatureID, Object Con){
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 SearchRadiusX = 16 + (std::abs(Creature->posx - ConX) / 2) + 1;
+ int SearchRadiusY = 14 + (std::abs(Creature->posy - ConY) / 2) + 1;
int SearchCenterX = (Creature->posx + ConX) / 2;
int SearchCenterY = (Creature->posy + ConY) / 2;
- TFindCreatures Search(SearchWidth, SearchHeight, SearchCenterX, SearchCenterY, FIND_PLAYERS);
+ TFindCreatures Search(SearchRadiusX, SearchRadiusY, SearchCenterX, SearchCenterY, FIND_PLAYERS);
while(true){
uint32 CharacterID = Search.getNext();
if(CharacterID == 0){
@@ -50,9 +54,11 @@ void AnnounceMovingCreature(uint32 CreatureID, Object Con){
}
TPlayer *Player = GetPlayer(CharacterID);
- if(Player != NULL && Player->Connection != NULL){
- SendMoveCreature(Player->Connection, CreatureID, ConX, ConY, ConZ);
+ if(Player == NULL || Player->Connection == NULL){
+ continue;
}
+
+ SendMoveCreature(Player->Connection, CreatureID, ConX, ConY, ConZ);
}
}
@@ -103,8 +109,11 @@ void AnnounceChangedField(Object Obj, int Type){
}
TPlayer *Player = GetPlayer(CharacterID);
- if(Player == NULL || Player->Connection == NULL
- || !Player->Connection->IsVisible(ObjX, ObjY, ObjZ)){
+ if(Player == NULL || Player->Connection == NULL){
+ continue;
+ }
+
+ if(!Player->Connection->IsVisible(ObjX, ObjY, ObjZ)){
continue;
}
@@ -205,6 +214,187 @@ void AnnounceChangedObject(Object Obj, int Type){
}
}
+void AnnounceGraphicalEffect(int x, int y, int z, int Type){
+ if(!IsOnMap(x, y, z)){
+ return;
+ }
+
+ TFindCreatures Search(16, 14, x, y, FIND_PLAYERS);
+ while(true){
+ uint32 CharacterID = Search.getNext();
+ if(CharacterID == 0){
+ break;
+ }
+
+ TPlayer *Player = GetPlayer(CharacterID);
+ if(Player == NULL || Player->Connection == NULL){
+ continue;
+ }
+
+ if(!Player->Connection->IsVisible(x, y, z)){
+ continue;
+ }
+
+ SendGraphicalEffect(Player->Connection, x, y, z, Type);
+ }
+}
+
+void AnnounceTextualEffect(int x, int y, int z, int Color, const char *Text){
+ if(!IsOnMap(x, y, z)){
+ return;
+ }
+
+ TFindCreatures Search(16, 14, x, y, FIND_PLAYERS);
+ while(true){
+ uint32 CharacterID = Search.getNext();
+ if(CharacterID == 0){
+ break;
+ }
+
+ TPlayer *Player = GetPlayer(CharacterID);
+ if(Player == NULL || Player->Connection == NULL){
+ continue;
+ }
+
+ if(!Player->Connection->IsVisible(x, y, z)){
+ continue;
+ }
+
+ SendTextualEffect(Player->Connection, x, y, z, Color, Text);
+ }
+}
+
+void AnnounceMissile(int OrigX, int OrigY, int OrigZ,
+ int DestX, int DestY, int DestZ, int Type){
+ if(!IsOnMap(OrigX, OrigY, OrigZ) || !IsOnMap(DestX, DestY, DestZ)){
+ return;
+ }
+
+ int SearchRadiusX = 16 + (std::abs(OrigX - DestX) / 2) + 1;
+ int SearchRadiusY = 14 + (std::abs(OrigY - DestY) / 2) + 1;
+ int SearchCenterX = (OrigX + DestX) / 2;
+ int SearchCenterY = (OrigY + DestY) / 2;
+ TFindCreatures Search(SearchRadiusX, SearchRadiusY, SearchCenterX, SearchCenterY, FIND_PLAYERS);
+ while(true){
+ uint32 CharacterID = Search.getNext();
+ if(CharacterID == 0){
+ break;
+ }
+
+ TPlayer *Player = GetPlayer(CharacterID);
+ if(Player == NULL || Player->Connection == NULL){
+ continue;
+ }
+
+ if(!Player->Connection->IsVisible(OrigX, OrigY, OrigY)
+ && !Player->Connection->IsVisible(DestX, DestY, DestZ)){
+ continue;
+ }
+
+ SendMissileEffect(Player->Connection,
+ OrigX, OrigY, OrigY,
+ DestX, DestY, DestZ, Type);
+ }
+}
+
+void CheckTopMoveObject(uint32 CreatureID, Object Obj, Object Ignore){
+ if(!Obj.exists()){
+ error("CheckTopMoveObject: Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(CreatureID == 0 || !IsCreaturePlayer(CreatureID)){
+ return;
+ }
+
+ Object Con = Obj.getContainer();
+ ObjectType ConType = Con.getObjectType();
+ if(!ConType.isMapContainer()){
+ return;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.isCreatureContainer() && Obj.getCreatureID() == CreatureID){
+ return;
+ }
+
+ Object Best = NONE;
+ bool BestIsCreature = false;
+ Object Help = GetFirstContainerObject(Con);
+ while(Help != NONE){
+ if(Help != Ignore){
+ ObjectType HelpType = Help.getObjectType();
+
+ // NOTE(fusion): We're looking for the top move object. The creature
+ // check here makes sure only the first creature found is kept as the
+ // best candidate, since creatures on a map container are in a sequence.
+ if(Best == NONE || (!HelpType.getFlag(UNMOVE) && (!BestIsCreature || !HelpType.isCreatureContainer()))){
+ Best = Help;
+ BestIsCreature = HelpType.isCreatureContainer();
+ }
+
+ // TODO(fusion): This is probably some inlined function to check whether
+ // an object has a low stack priority.
+ if(!HelpType.getFlag(BANK)
+ && !HelpType.getFlag(CLIP)
+ && !HelpType.getFlag(BOTTOM)
+ && !HelpType.getFlag(TOP)
+ && !HelpType.isCreatureContainer()){
+ break;
+ }
+ }
+ Help = Help.getNextObject();
+ }
+
+ if(Obj != Best){
+ throw NOTACCESSIBLE;
+ }
+}
+
+void CheckTopUseObject(uint32 CreatureID, Object Obj){
+ if(!Obj.exists()){
+ error("CheckTopUseObject: Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(CreatureID == 0 || !IsCreaturePlayer(CreatureID)){
+ return;
+ }
+
+ Object Con = Obj.getContainer();
+ ObjectType ConType = Con.getObjectType();
+ if(!ConType.isMapContainer()){
+ return;
+ }
+
+ Object Best = NONE;
+ Object Help = GetFirstContainerObject(Con);
+ while(Help != NONE){
+ ObjectType HelpType = Help.getObjectType();
+ if(Best == NONE || (!HelpType.isCreatureContainer() && !HelpType.getFlag(LIQUIDPOOL))){
+ Best = Help;
+ }
+
+ if(HelpType.getFlag(FORCEUSE)){
+ break;
+ }
+
+ if(!HelpType.getFlag(BANK)
+ && !HelpType.getFlag(CLIP)
+ && !HelpType.getFlag(BOTTOM)
+ && !HelpType.getFlag(TOP)
+ && !HelpType.isCreatureContainer()){
+ break;
+ }
+
+ Help = Help.getNextObject();
+ }
+
+ if(Obj != Best){
+ throw NOTACCESSIBLE;
+ }
+}
+
// TODO(fusion): This could have been a simple return value.
void CheckContainerDestination(Object Obj, Object Con){
Object Help = Con;
@@ -343,6 +533,9 @@ void Move(uint32 CreatureID, Object Obj, Object Con, int Count, bool NoMerge, Ob
error("Move: Übergebenes Objekt existiert nicht mehr.\n");
}
+ // NOTE(fusion): Refresh object type just in case a merge event modified it.
+ ObjType = Obj.getObjectType();
+
int ObjCount = 1;
if(ObjType.getFlag(CUMULATIVE)){
ObjCount = (int)Obj.getAttribute(AMOUNT);
@@ -378,7 +571,7 @@ void Move(uint32 CreatureID, Object Obj, Object Con, int Count, bool NoMerge, Ob
}
}
- // NOTE(fusion): `Obj` becomes the split part while `Remainder`, the remainder.
+ // NOTE(fusion): `Obj` becomes the split part while `Remainder`, the remaining part.
Object Remainder = NONE;
if(Split){
Remainder = Obj;
diff --git a/src/stubs.hh b/src/stubs.hh
index a2c5f25..4104dd3 100644
--- a/src/stubs.hh
+++ b/src/stubs.hh
@@ -86,11 +86,14 @@ 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);
+extern void SendGraphicalEffect(TConnection *Connection, int x, int y, int z, int Type);
+extern void SendTextualEffect(TConnection *Connection, int x, int y, int z, int Color, const char *Text);
+extern void SendMissileEffect(TConnection *Connection, int OrigX, int OrigY, int OrigZ, int DestX, int DestY, int DestZ, int Type);
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 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);