first look at operate.cc
This commit is contained in:
parent
81a5d53bc5
commit
b167d45f88
4
TODO.md
4
TODO.md
@ -1,8 +1,8 @@
|
||||
## TODO NEXT
|
||||
- INFO.CC
|
||||
- OPERATE.CC
|
||||
- HOUSES.CC
|
||||
- CRPLAYER.CC, CRNONPL.CC
|
||||
- CRPLAYER.CC
|
||||
- CRNONPL.CC
|
||||
- MOVEUSE.CC
|
||||
- SENDING.CC
|
||||
- RECEIVING.CC
|
||||
|
||||
455
reference/game.c
455
reference/game.c
@ -20717,461 +20717,6 @@ LAB_080926bf:
|
||||
__cxa_throw(puVar3,&RESULT::typeinfo,0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Move(ulong CreatureID,Object *Obj,Object *Con,int Count,bool NoMerge,Object *Ignore)
|
||||
|
||||
{
|
||||
Object OVar1;
|
||||
bool bVar2;
|
||||
TCreature *cr;
|
||||
ulong uVar3;
|
||||
TCreature *pTVar4;
|
||||
int iVar5;
|
||||
undefined4 *puVar6;
|
||||
TCreature *cr_1;
|
||||
char *Text;
|
||||
Object *pOVar7;
|
||||
Object *Destination;
|
||||
ulong oldCreature;
|
||||
Object *local_94;
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int x_1;
|
||||
int y_1;
|
||||
int z_1;
|
||||
Object Rest;
|
||||
Object local_6c;
|
||||
Object oldCon;
|
||||
Object local_5c [4];
|
||||
Object local_4c [4];
|
||||
Object local_3c;
|
||||
Object Top;
|
||||
Object local_2c [7];
|
||||
|
||||
// try { // try from 0809276c to 08092fab has its CatchHandler @ 08093120
|
||||
bVar2 = Object::exists(Obj);
|
||||
if (bVar2) {
|
||||
bVar2 = Object::exists(Con);
|
||||
if (!bVar2) {
|
||||
error("Move: Zielobjekt existiert nicht.\n");
|
||||
local_2c[0] = (Object)Obj->ObjectID;
|
||||
GetObjectCoordinates(local_2c,&z,&x_1,&y_1);
|
||||
Object::getObjectType(local_2c);
|
||||
error("# Objekt %d an [%d,%d,%d]\n",local_2c[0].ObjectID,z,x_1,y_1);
|
||||
goto LAB_08093028;
|
||||
}
|
||||
Object::getObjectType(local_2c);
|
||||
bVar2 = ObjectType::getFlag((ObjectType *)local_2c,CONTAINER);
|
||||
if (bVar2) {
|
||||
Object::getObjectType(local_2c);
|
||||
pOVar7 = (Object *)0x6;
|
||||
bVar2 = ObjectType::getFlag((ObjectType *)local_2c,CUMULATIVE);
|
||||
if (!bVar2) {
|
||||
LAB_08092800:
|
||||
OVar1.ObjectID = local_3c.ObjectID;
|
||||
if ((!NoMerge) &&
|
||||
(pOVar7 = Con, Object::getObjectType(local_2c),
|
||||
OVar1.ObjectID = local_3c.ObjectID, local_2c[0].ObjectID == 0)) {
|
||||
Object::getObjectType(local_2c);
|
||||
pOVar7 = (Object *)0x6;
|
||||
bVar2 = ObjectType::getFlag((ObjectType *)local_2c,CUMULATIVE);
|
||||
OVar1.ObjectID = local_3c.ObjectID;
|
||||
if (bVar2) {
|
||||
pOVar7 = Obj;
|
||||
Object::getContainer(local_2c);
|
||||
local_3c = (Object)Con->ObjectID;
|
||||
OVar1.ObjectID = local_2c[0].ObjectID;
|
||||
if (local_3c.ObjectID != local_2c[0].ObjectID) {
|
||||
GetObjectCoordinates(&local_3c,(int *)&local_94,&x,&y);
|
||||
GetTopObject((int)&local_3c,(int)local_94,x,(bool)(undefined1)y);
|
||||
local_5c[0] = (Object)NONE.ObjectID;
|
||||
local_4c[0].ObjectID = NONE.ObjectID;
|
||||
pOVar7 = local_94;
|
||||
OVar1.ObjectID = local_3c.ObjectID;
|
||||
if (local_3c.ObjectID != NONE.ObjectID) {
|
||||
local_5c[0] = (Object)Ignore->ObjectID;
|
||||
local_6c.ObjectID = local_3c.ObjectID;
|
||||
z_1 = Obj->ObjectID;
|
||||
// try { // try from 08092ff7 to 08092ffb has its CatchHandler @ 080930df
|
||||
Merge(CreatureID,(Object *)&z_1,&local_6c,Count,local_5c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
local_3c.ObjectID = OVar1.ObjectID;
|
||||
bVar2 = Object::exists(Obj);
|
||||
if (!bVar2) {
|
||||
error(&DAT_080ff6c0,pOVar7);
|
||||
}
|
||||
Object::getObjectType((Object *)&z_1);
|
||||
bVar2 = ObjectType::getFlag((ObjectType *)&z_1,CUMULATIVE);
|
||||
if ((bVar2) && (Count == -1)) {
|
||||
Count = Object::getAttribute(Obj,AMOUNT);
|
||||
}
|
||||
z_1 = Ignore->ObjectID;
|
||||
local_6c = (Object)Obj->ObjectID;
|
||||
CheckTopMoveObject(CreatureID,&local_6c,(Object *)&z_1);
|
||||
Object::getObjectType((Object *)&z_1);
|
||||
bVar2 = z_1 != 0;
|
||||
z_1 = Obj->ObjectID;
|
||||
CheckMoveObject(CreatureID,(Object *)&z_1,bVar2);
|
||||
Object::getObjectType((Object *)&z_1);
|
||||
if (z_1 == 0) {
|
||||
z_1 = Con->ObjectID;
|
||||
local_6c = (Object)Obj->ObjectID;
|
||||
CheckMapDestination(CreatureID,&local_6c,(Object *)&z_1);
|
||||
}
|
||||
else {
|
||||
oldCreature._3_1_ = false;
|
||||
Object::getObjectType((Object *)&z_1);
|
||||
bVar2 = ObjectType::getFlag((ObjectType *)&z_1,CUMULATIVE);
|
||||
if ((bVar2) && (uVar3 = Object::getAttribute(Obj,AMOUNT), Count < (int)uVar3)) {
|
||||
oldCreature._3_1_ = true;
|
||||
}
|
||||
Object::getObjectType((Object *)&z_1);
|
||||
bVar2 = false;
|
||||
if ((0 < z_1) && (z_1 < 0xb)) {
|
||||
bVar2 = true;
|
||||
}
|
||||
if (bVar2) {
|
||||
z_1 = Con->ObjectID;
|
||||
local_6c = (Object)Obj->ObjectID;
|
||||
CheckInventoryDestination(&local_6c,(Object *)&z_1,oldCreature._3_1_);
|
||||
}
|
||||
else {
|
||||
z_1 = Con->ObjectID;
|
||||
local_6c = (Object)Obj->ObjectID;
|
||||
CheckContainerDestination(&local_6c,(Object *)&z_1);
|
||||
}
|
||||
if (oldCreature._3_1_ == false) {
|
||||
z_1 = Obj->ObjectID;
|
||||
iVar5 = CountObjects((Object *)&z_1);
|
||||
local_6c = (Object)Con->ObjectID;
|
||||
pOVar7 = local_5c;
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
Destination = &local_6c;
|
||||
}
|
||||
else {
|
||||
z_1 = Con->ObjectID;
|
||||
iVar5 = 1;
|
||||
local_6c.ObjectID = NONE.ObjectID;
|
||||
pOVar7 = &local_6c;
|
||||
Destination = (Object *)&z_1;
|
||||
}
|
||||
CheckDepotSpace(CreatureID,pOVar7,Destination,iVar5);
|
||||
z_1 = Con->ObjectID;
|
||||
uVar3 = GetObjectCreatureID((Object *)&z_1);
|
||||
if (uVar3 != 0) {
|
||||
z_1 = Obj->ObjectID;
|
||||
CheckWeight(uVar3,(Object *)&z_1,Count);
|
||||
}
|
||||
}
|
||||
z_1 = NONE.ObjectID;
|
||||
Object::getObjectType(&local_6c);
|
||||
bVar2 = ObjectType::getFlag((ObjectType *)&local_6c,CUMULATIVE);
|
||||
if ((bVar2) && (uVar3 = Object::getAttribute(Obj,AMOUNT), Count < (int)uVar3)) {
|
||||
z_1 = Obj->ObjectID;
|
||||
local_6c.ObjectID = z_1;
|
||||
local_5c[0].ObjectID = z_1;
|
||||
local_4c[0].ObjectID = z_1;
|
||||
SplitObject(local_5c,(int)local_4c);
|
||||
local_6c.ObjectID = local_5c[0].ObjectID;
|
||||
Obj->ObjectID = (ulong)local_5c[0];
|
||||
}
|
||||
Object::getContainer(&local_6c);
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
pOVar7 = (Object *)GetObjectCreatureID(local_5c);
|
||||
local_5c[0].ObjectID = local_6c.ObjectID;
|
||||
local_4c[0].ObjectID = local_6c.ObjectID;
|
||||
if (Con->ObjectID != local_6c.ObjectID) {
|
||||
local_3c = (Object)Obj->ObjectID;
|
||||
SeparationEvent(&local_3c,local_4c);
|
||||
}
|
||||
Object::getObjectType(local_5c);
|
||||
if ((local_5c[0].ObjectID != 99) &&
|
||||
(local_5c[0].ObjectID = NONE.ObjectID, z_1 == NONE.ObjectID)) {
|
||||
local_4c[0] = (Object)Obj->ObjectID;
|
||||
AnnounceChangedObject(local_4c,0);
|
||||
local_4c[0] = (Object)Obj->ObjectID;
|
||||
NotifyTrades(local_4c);
|
||||
local_4c[0] = (Object)Obj->ObjectID;
|
||||
iVar5 = CountObjects(local_4c);
|
||||
local_3c = (Object)Obj->ObjectID;
|
||||
NotifyDepot(CreatureID,&local_3c,iVar5);
|
||||
}
|
||||
Object::getObjectType(local_5c);
|
||||
bVar2 = ObjectType::getFlag((ObjectType *)local_5c,CONTAINER);
|
||||
if ((bVar2) && (CreatureID == 0)) {
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
CloseContainer(local_5c,true);
|
||||
}
|
||||
Object::getObjectType(local_5c);
|
||||
if (local_5c[0].ObjectID == 99) {
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
pTVar4 = GetCreature(local_5c);
|
||||
if (pTVar4 == (TCreature *)0x0) {
|
||||
uVar3 = Object::getCreatureID(Obj);
|
||||
error(&DAT_080ff680,uVar3);
|
||||
}
|
||||
else {
|
||||
local_5c[0] = (Object)Con->ObjectID;
|
||||
TCreature::NotifyTurn(pTVar4,local_5c);
|
||||
}
|
||||
local_5c[0] = (Object)Con->ObjectID;
|
||||
uVar3 = Object::getCreatureID(Obj);
|
||||
AnnounceMovingCreature(uVar3,local_5c);
|
||||
}
|
||||
local_5c[0] = (Object)Con->ObjectID;
|
||||
local_4c[0] = (Object)Obj->ObjectID;
|
||||
MoveObject(local_4c,local_5c);
|
||||
Object::getObjectType(local_5c);
|
||||
if (local_5c[0].ObjectID != 99) {
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
AnnounceChangedObject(local_5c,1);
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
NotifyTrades(local_5c);
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
iVar5 = CountObjects(local_5c);
|
||||
local_4c[0] = (Object)Obj->ObjectID;
|
||||
NotifyDepot(CreatureID,local_4c,-iVar5);
|
||||
}
|
||||
local_5c[0].ObjectID = NONE.ObjectID;
|
||||
local_4c[0].ObjectID = NONE.ObjectID;
|
||||
if (z_1 != NONE.ObjectID) {
|
||||
local_4c[0].ObjectID = z_1;
|
||||
AnnounceChangedObject(local_4c,2);
|
||||
local_4c[0].ObjectID = z_1;
|
||||
NotifyTrades(local_4c);
|
||||
}
|
||||
Object::getObjectType(local_5c);
|
||||
if (local_5c[0].ObjectID == 99) {
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
pTVar4 = GetCreature(local_5c);
|
||||
if (pTVar4 == (TCreature *)0x0) {
|
||||
uVar3 = Object::getCreatureID(Obj);
|
||||
error(&DAT_080ff680,uVar3);
|
||||
}
|
||||
else {
|
||||
TCreature::NotifyGo(pTVar4);
|
||||
}
|
||||
}
|
||||
Object::getObjectType(local_5c);
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
NotifyCreature(local_5c[0].ObjectID,pOVar7,SUB41(local_5c,0));
|
||||
Object::getContainer(local_5c);
|
||||
Object::getObjectType(local_4c);
|
||||
local_4c[0] = (Object)Obj->ObjectID;
|
||||
local_3c.ObjectID = local_4c[0].ObjectID;
|
||||
uVar3 = GetObjectCreatureID(&local_3c);
|
||||
NotifyCreature(uVar3,(Object *)uVar3,SUB41(local_4c,0));
|
||||
Object::getObjectType(local_5c);
|
||||
bVar2 = ObjectType::getFlag((ObjectType *)local_5c,CONTAINER);
|
||||
if (bVar2) {
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
CloseContainer(local_5c,false);
|
||||
}
|
||||
local_5c[0] = (Object)Con->ObjectID;
|
||||
local_4c[0].ObjectID = local_6c.ObjectID;
|
||||
local_3c = (Object)Obj->ObjectID;
|
||||
MovementEvent(&local_3c,local_4c,local_5c);
|
||||
local_5c[0] = (Object)Obj->ObjectID;
|
||||
Object::getContainer(local_4c);
|
||||
CollisionEvent(local_5c,local_4c);
|
||||
local_5c[0].ObjectID = local_6c.ObjectID;
|
||||
local_4c[0] = (Object)Obj->ObjectID;
|
||||
NotifyAllCreatures(local_4c,3,local_5c);
|
||||
return;
|
||||
}
|
||||
if (Count != 0) {
|
||||
pOVar7 = (Object *)0x2;
|
||||
uVar3 = Object::getAttribute(Obj,AMOUNT);
|
||||
if (Count <= (int)uVar3) goto LAB_08092800;
|
||||
}
|
||||
// try { // try from 0809300c to 080930cd has its CatchHandler @ 08093120
|
||||
uVar3 = Object::getAttribute(Obj,AMOUNT);
|
||||
error(&DAT_080ff700,Count,uVar3);
|
||||
goto LAB_08093028;
|
||||
}
|
||||
Text = "Move: Zielobjekt ist kein Container.\n";
|
||||
}
|
||||
else {
|
||||
Text = &DAT_080ff7e0;
|
||||
}
|
||||
error(Text);
|
||||
LAB_08093028:
|
||||
puVar6 = (undefined4 *)__cxa_allocate_exception(4);
|
||||
*puVar6 = 0xffffffff;
|
||||
// WARNING: Subroutine does not return
|
||||
__cxa_throw(puVar6,&RESULT::typeinfo,0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Merge(ulong CreatureID,Object *Obj,Object *Dest,int Count,Object *Ignore)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
ulong uVar2;
|
||||
ulong uVar3;
|
||||
undefined4 *puVar4;
|
||||
ulong newCreature;
|
||||
char *Text;
|
||||
ulong oldCreature;
|
||||
Object local_6c [4];
|
||||
Object local_5c [4];
|
||||
Object local_4c;
|
||||
Object Con;
|
||||
Object local_3c;
|
||||
Object oldCon;
|
||||
Object local_2c [7];
|
||||
|
||||
// try { // try from 0809314b to 080936c5 has its CatchHandler @ 080936d1
|
||||
bVar1 = Object::exists(Obj);
|
||||
if (bVar1) {
|
||||
bVar1 = Object::exists(Dest);
|
||||
if (!bVar1) {
|
||||
Text = "Merge: Zielobjekt existiert nicht.\n";
|
||||
goto LAB_080936c1;
|
||||
}
|
||||
Object::getObjectType(local_2c);
|
||||
bVar1 = ObjectType::getFlag((ObjectType *)local_2c,CUMULATIVE);
|
||||
if ((!bVar1) ||
|
||||
((Count != 0 && (uVar2 = Object::getAttribute(Obj,AMOUNT), Count <= (int)uVar2)))) {
|
||||
local_2c[0] = (Object)Dest->ObjectID;
|
||||
if (Obj->ObjectID == local_2c[0].ObjectID) {
|
||||
return;
|
||||
}
|
||||
Object::getObjectType(local_2c);
|
||||
Object::getObjectType(&local_3c);
|
||||
ObjectType::setTypeID((ObjectType *)&local_4c,local_3c.ObjectID);
|
||||
if (local_2c[0].ObjectID == local_4c.ObjectID) {
|
||||
Object::getObjectType(&local_4c);
|
||||
bVar1 = ObjectType::getFlag((ObjectType *)&local_4c,CUMULATIVE);
|
||||
if (bVar1) {
|
||||
if (Count == -1) {
|
||||
Count = Object::getAttribute(Obj,AMOUNT);
|
||||
}
|
||||
uVar2 = Object::getAttribute(Dest,AMOUNT);
|
||||
if (uVar2 + Count < 0x65) {
|
||||
Object::getContainer(&local_4c);
|
||||
local_3c = (Object)Ignore->ObjectID;
|
||||
local_2c[0] = (Object)Obj->ObjectID;
|
||||
CheckTopMoveObject(CreatureID,local_2c,&local_3c);
|
||||
Object::getObjectType(&local_3c);
|
||||
bVar1 = local_3c.ObjectID != 0;
|
||||
local_3c = (Object)Obj->ObjectID;
|
||||
CheckMoveObject(CreatureID,&local_3c,bVar1);
|
||||
Object::getObjectType(&local_3c);
|
||||
if (local_3c.ObjectID == 0) {
|
||||
local_3c.ObjectID = local_4c.ObjectID;
|
||||
local_2c[0] = (Object)Obj->ObjectID;
|
||||
CheckMapDestination(CreatureID,local_2c,&local_3c);
|
||||
}
|
||||
else {
|
||||
local_3c.ObjectID = local_4c.ObjectID;
|
||||
local_2c[0] = (Object)Obj->ObjectID;
|
||||
CheckDepotSpace(CreatureID,local_2c,&local_3c,0);
|
||||
local_3c.ObjectID = local_4c.ObjectID;
|
||||
uVar2 = GetObjectCreatureID(&local_3c);
|
||||
if (uVar2 != 0) {
|
||||
local_3c = (Object)Obj->ObjectID;
|
||||
CheckWeight(uVar2,&local_3c,Count);
|
||||
}
|
||||
}
|
||||
Object::getContainer(&local_3c);
|
||||
local_2c[0] = (Object)Obj->ObjectID;
|
||||
uVar2 = GetObjectCreatureID(local_2c);
|
||||
Object::getObjectType(local_2c);
|
||||
bVar1 = ObjectType::getFlag((ObjectType *)local_2c,MOVEMENTEVENT);
|
||||
if (bVar1) {
|
||||
Object::getObjectType(local_2c);
|
||||
error(&DAT_080ff820,local_2c[0].ObjectID);
|
||||
}
|
||||
Object::getContainer(local_2c);
|
||||
local_5c[0].ObjectID = local_3c.ObjectID;
|
||||
local_6c[0].ObjectID = local_3c.ObjectID;
|
||||
if (local_2c[0].ObjectID != local_3c.ObjectID) {
|
||||
oldCreature = Obj->ObjectID;
|
||||
SeparationEvent((Object *)&oldCreature,local_6c);
|
||||
}
|
||||
uVar3 = Object::getAttribute(Obj,AMOUNT);
|
||||
if (Count < (int)uVar3) {
|
||||
oldCreature = Obj->ObjectID;
|
||||
uVar3 = Object::getAttribute(Obj,AMOUNT);
|
||||
ChangeObject((Object *)&oldCreature,AMOUNT,uVar3 - Count);
|
||||
oldCreature = Obj->ObjectID;
|
||||
AnnounceChangedObject((Object *)&oldCreature,2);
|
||||
oldCreature = Obj->ObjectID;
|
||||
NotifyTrades((Object *)&oldCreature);
|
||||
oldCreature = Dest->ObjectID;
|
||||
uVar3 = Object::getAttribute(Dest,AMOUNT);
|
||||
ChangeObject((Object *)&oldCreature,AMOUNT,uVar3 + Count);
|
||||
}
|
||||
else {
|
||||
oldCreature = Obj->ObjectID;
|
||||
AnnounceChangedObject((Object *)&oldCreature,0);
|
||||
oldCreature = Obj->ObjectID;
|
||||
NotifyTrades((Object *)&oldCreature);
|
||||
oldCreature = Obj->ObjectID;
|
||||
NotifyDepot(CreatureID,(Object *)&oldCreature,1);
|
||||
oldCreature = Dest->ObjectID;
|
||||
local_6c[0] = (Object)Obj->ObjectID;
|
||||
MergeObjects(local_6c,(Object *)&oldCreature);
|
||||
}
|
||||
oldCreature = Dest->ObjectID;
|
||||
AnnounceChangedObject((Object *)&oldCreature,2);
|
||||
oldCreature = Dest->ObjectID;
|
||||
NotifyTrades((Object *)&oldCreature);
|
||||
Object::getObjectType((Object *)&oldCreature);
|
||||
oldCreature = Dest->ObjectID;
|
||||
NotifyCreature(uVar2,(Object *)uVar2,SUB41((Object *)&oldCreature,0));
|
||||
Object::getContainer((Object *)&oldCreature);
|
||||
Object::getObjectType(local_6c);
|
||||
local_6c[0] = (Object)Dest->ObjectID;
|
||||
local_5c[0].ObjectID = local_6c[0].ObjectID;
|
||||
uVar2 = GetObjectCreatureID(local_5c);
|
||||
NotifyCreature(uVar2,(Object *)uVar2,SUB41(local_6c,0));
|
||||
oldCreature = Dest->ObjectID;
|
||||
Object::getContainer(local_6c);
|
||||
CollisionEvent((Object *)&oldCreature,local_6c);
|
||||
oldCreature = NONE.ObjectID;
|
||||
local_6c[0] = (Object)Dest->ObjectID;
|
||||
NotifyAllCreatures(local_6c,2,(Object *)&oldCreature);
|
||||
return;
|
||||
}
|
||||
puVar4 = (undefined4 *)__cxa_allocate_exception(4);
|
||||
*puVar4 = 0x13;
|
||||
}
|
||||
else {
|
||||
puVar4 = (undefined4 *)__cxa_allocate_exception(4);
|
||||
*puVar4 = 0x12;
|
||||
}
|
||||
}
|
||||
else {
|
||||
puVar4 = (undefined4 *)__cxa_allocate_exception(4);
|
||||
*puVar4 = 0x11;
|
||||
}
|
||||
goto LAB_08093635;
|
||||
}
|
||||
error(&DAT_080ff880,Count);
|
||||
}
|
||||
else {
|
||||
Text = &DAT_080ff900;
|
||||
LAB_080936c1:
|
||||
error(Text);
|
||||
}
|
||||
puVar4 = (undefined4 *)__cxa_allocate_exception(4);
|
||||
*puVar4 = 0xffffffff;
|
||||
LAB_08093635:
|
||||
// WARNING: Subroutine does not return
|
||||
__cxa_throw(puVar4,&RESULT::typeinfo,0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Change(Object *Obj,ObjectType *NewType,ulong Value)
|
||||
|
||||
{
|
||||
|
||||
@ -556,7 +556,8 @@ void TCreature::Move(Object Obj, int DestX, int DestY, int DestZ, uint8 Count){
|
||||
::Move(this->ID, Obj, DestCon, MoveCount, false, DestObj);
|
||||
}catch(RESULT r){
|
||||
// NOTE(fusion): Attempt to exchange inventory items.
|
||||
if(DestY < 64 && DestObj != NONE
|
||||
if(DestY >= INVENTORY_FIRST && DestY <= INVENTORY_LAST
|
||||
&& DestObj != NONE
|
||||
&& (r == NOROOM
|
||||
|| r == HANDSNOTFREE
|
||||
|| r == HANDBLOCKED
|
||||
|
||||
272
src/operate.cc
272
src/operate.cc
@ -3,6 +3,26 @@
|
||||
|
||||
#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);
|
||||
void CheckDepotSpace(uint32 CreatureID, Object Source, Object Destination, int Count);
|
||||
void CheckWeight(uint32 CreatureID, Object Obj, int Count);
|
||||
void NotifyCreature(uint32 CreatureID, Object Obj, bool Inventory);
|
||||
void NotifyCreature(uint32 CreatureID, ObjectType Type, bool Inventory);
|
||||
//void NotifyAllCreatures(Object Obj, int Type, Object OldCon);
|
||||
void NotifyTrades(Object Obj);
|
||||
void NotifyDepot(uint32 CreatureID, Object Obj, int Count);
|
||||
void CloseContainer(Object Con, bool Force);
|
||||
|
||||
// moveuse.cc
|
||||
void MovementEvent(Object Obj, Object Start, Object Dest);
|
||||
void CollisionEvent(Object Obj, Object Dest);
|
||||
void SeparationEvent(Object Obj, Object Start);
|
||||
|
||||
|
||||
// TODO(fusion): This could have been a simple return value.
|
||||
void CheckContainerDestination(Object Obj, Object Con){
|
||||
Object Help = Con;
|
||||
@ -81,3 +101,255 @@ void CheckInventoryDestination(Object Obj, Object Con, bool Split){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Move(uint32 CreatureID, Object Obj, Object Con, int Count, bool NoMerge, Object Ignore){
|
||||
if(!Obj.exists()){
|
||||
error("Move: Übergebenes Objekt existiert nicht.\n");
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
if(!Con.exists()){
|
||||
int ObjX, ObjY, ObjZ;
|
||||
ObjectType ObjType = Obj.getObjectType();
|
||||
GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
|
||||
error("Move: Zielobjekt existiert nicht.\n");
|
||||
error("# Objekt %d an [%d,%d,%d]\n", ObjType.TypeID, ObjX, ObjY, ObjZ);
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
ObjectType ConType = Con.getObjectType();
|
||||
if(!ConType.getFlag(CONTAINER)){
|
||||
error("Move: Zielobjekt ist kein Container.\n");
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
ObjectType ObjType = Obj.getObjectType();
|
||||
if(ObjType.getFlag(CUMULATIVE) && (Count == 0 || Count > (int)Obj.getAttribute(AMOUNT))){
|
||||
error("Move: Ungültige Anzahl %d von %d an Teilen bei kumulierbarem Objekt.\n",
|
||||
Count, (int)Obj.getAttribute(AMOUNT));
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
Object OldCon = Obj.getContainer();
|
||||
if(!NoMerge && ConType.isMapContainer()
|
||||
&& ObjType.getFlag(CUMULATIVE)
|
||||
&& OldCon != Con){
|
||||
int ConX, ConY, ConZ;
|
||||
GetObjectCoordinates(Con, &ConX, &ConY, &ConZ);
|
||||
Object Top = GetTopObject(ConX, ConY, ConZ, true);
|
||||
if(Top != NONE){
|
||||
try{
|
||||
Merge(CreatureID, Obj, Top, Count, Ignore);
|
||||
return; // <-- EARLY RETURN IF `Merge` SUCCEEDS.
|
||||
}catch(RESULT r){
|
||||
if(r == DESTROYED){
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(fusion): The only event inside `Merge` that could modify the object
|
||||
// and still throw some non `DESTROYED` error is the separation event.
|
||||
// From what I've seen, it is used exclusively with non CUMULATIVE objects
|
||||
// like depot switches to perform "step out" events but using them with
|
||||
// CUMULATIVE objects could be problematic as the event is triggered on the
|
||||
// whole object which includes both the remainder and moved parts, meaning
|
||||
// that transforming the object then would already make the merge "invalid".
|
||||
|
||||
if(!Obj.exists()){
|
||||
error("Move: Übergebenes Objekt existiert nicht mehr.\n");
|
||||
}
|
||||
|
||||
int ObjCount = 1;
|
||||
if(ObjType.getFlag(CUMULATIVE)){
|
||||
ObjCount = (int)Obj.getAttribute(AMOUNT);
|
||||
}
|
||||
|
||||
if(Count == -1){
|
||||
Count = ObjCount;
|
||||
}
|
||||
|
||||
bool Split = Count < ObjCount;
|
||||
uint32 ObjOwnerID = GetObjectCreatureID(Obj);
|
||||
uint32 ConOwnerID = GetObjectCreatureID(Con);
|
||||
CheckTopMoveObject(CreatureID, Obj, Ignore);
|
||||
if(ConType.isMapContainer()){
|
||||
CheckMoveObject(CreatureID, Obj, false);
|
||||
CheckMapDestination(CreatureID, Obj, Con);
|
||||
}else{
|
||||
CheckMoveObject(CreatureID, Obj, true);
|
||||
if(ConType.isBodyContainer()){
|
||||
CheckInventoryDestination(Obj, Con, Split);
|
||||
}else{
|
||||
CheckContainerDestination(Obj, Con);
|
||||
}
|
||||
|
||||
if(Split){
|
||||
CheckDepotSpace(CreatureID, NONE, Con, 1);
|
||||
}else{
|
||||
CheckDepotSpace(CreatureID, Obj, Con, CountObjects(Obj));
|
||||
}
|
||||
|
||||
if(ConOwnerID != 0){
|
||||
CheckWeight(ConOwnerID, Obj, Count);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(fusion): `Obj` becomes the split part while `Remainder`, the remainder.
|
||||
Object Remainder = NONE;
|
||||
if(Split){
|
||||
Remainder = Obj;
|
||||
Obj = SplitObject(Obj, Count);
|
||||
}
|
||||
|
||||
if(OldCon != Con){
|
||||
SeparationEvent(Obj, OldCon);
|
||||
}
|
||||
|
||||
// TODO(fusion): There is surely a way to reduce these creature checks?
|
||||
// perhaps split them into two linear paths, with a few duplications but
|
||||
// easier to read.
|
||||
|
||||
if(!ObjType.isCreatureContainer() && Remainder == NONE){
|
||||
AnnounceChangedObject(Obj, 0); // OBJECT_DISAPPEAR ?
|
||||
NotifyTrades(Obj);
|
||||
NotifyDepot(CreatureID, Obj, CountObjects(Obj));
|
||||
}
|
||||
|
||||
// TODO(fusion): This could probably be moved to the end of the function
|
||||
// along with the other `CloseContainer`.
|
||||
if(ObjType.getFlag(CONTAINER) && CreatureID == 0){
|
||||
CloseContainer(Obj, true);
|
||||
}
|
||||
|
||||
if(ObjType.isCreatureContainer()){
|
||||
uint32 MovingCreatureID = Obj.getCreatureID();
|
||||
TCreature *Creature = GetCreature(MovingCreatureID);
|
||||
if(Creature != NULL){
|
||||
Creature->NotifyTurn(Con);
|
||||
}else{
|
||||
error("Move: Kreatur mit ungültiger ID %d.\n", MovingCreatureID);
|
||||
}
|
||||
AnnounceMovingCreature(MovingCreatureID, Con);
|
||||
}
|
||||
|
||||
MoveObject(Obj, Con);
|
||||
|
||||
if(!ObjType.isCreatureContainer()){
|
||||
AnnounceChangedObject(Obj, 1); // OBJECT_APPEAR
|
||||
NotifyTrades(Obj);
|
||||
NotifyDepot(CreatureID, Obj, -CountObjects(Obj));
|
||||
}
|
||||
|
||||
if(Remainder != NONE){
|
||||
AnnounceChangedObject(Remainder, 2); // OBJECT_CHANGED
|
||||
NotifyTrades(Remainder);
|
||||
}
|
||||
|
||||
if(ObjType.isCreatureContainer()){
|
||||
uint32 MovingCreatureID = Obj.getCreatureID();
|
||||
TCreature *Creature = GetCreature(MovingCreatureID);
|
||||
if(Creature != NULL){
|
||||
Creature->NotifyGo();
|
||||
}else{
|
||||
error("Move: Kreatur mit ungültiger ID %d.\n", MovingCreatureID);
|
||||
}
|
||||
}
|
||||
|
||||
NotifyCreature(ObjOwnerID, Obj, OldCon.getObjectType().isBodyContainer());
|
||||
NotifyCreature(ConOwnerID, Obj, Con.getObjectType().isBodyContainer());
|
||||
|
||||
if(ObjType.getFlag(CONTAINER)){
|
||||
CloseContainer(Obj, false);
|
||||
}
|
||||
|
||||
MovementEvent(Obj, OldCon, Con);
|
||||
CollisionEvent(Obj, Con);
|
||||
NotifyAllCreatures(Obj, 3, OldCon); // CREATURE_MOVE_STIMULUS_ ?
|
||||
}
|
||||
|
||||
void Merge(uint32 CreatureID, Object Obj, Object Dest, int Count, Object Ignore){
|
||||
if(!Obj.exists()){
|
||||
error("Merge: Übergebenes Objekt existiert nicht.\n");
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
if(!Dest.exists()){
|
||||
error("Merge: Zielobjekt existiert nicht.\n");
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
ObjectType ObjType = Obj.getObjectType();
|
||||
if(ObjType.getFlag(CUMULATIVE) && (Count == 0 || Count > (int)Obj.getAttribute(AMOUNT))){
|
||||
error("Merge: Ungültige Anzahl %d an Teilen bei kumulierbarem Objekt.\n", Count);
|
||||
throw ERROR;
|
||||
}
|
||||
|
||||
if(Obj == Dest){
|
||||
return;
|
||||
}
|
||||
|
||||
if(ObjType != Dest.getObjectType()){
|
||||
throw NOMATCH;
|
||||
}
|
||||
|
||||
if(!ObjType.getFlag(CUMULATIVE)){
|
||||
throw NOTCUMULABLE;
|
||||
}
|
||||
|
||||
int ObjCount = Obj.getAttribute(AMOUNT);
|
||||
int DestCount = Dest.getAttribute(AMOUNT);
|
||||
if(Count == -1){
|
||||
Count = ObjCount;
|
||||
}
|
||||
|
||||
if((Count + DestCount) > 100){
|
||||
throw TOOMANYPARTS;
|
||||
}
|
||||
|
||||
Object DestCon = Dest.getContainer();
|
||||
uint32 DestOwnerID = GetObjectCreatureID(Dest);
|
||||
CheckTopMoveObject(CreatureID, Obj, Ignore);
|
||||
if(DestCon.getObjectType().isMapContainer()){
|
||||
CheckMoveObject(CreatureID, Obj, false);
|
||||
CheckMapDestination(CreatureID, Obj, DestCon);
|
||||
}else{
|
||||
CheckMoveObject(CreatureID, Obj, true);
|
||||
CheckDepotSpace(CreatureID, Obj, DestCon, 0);
|
||||
if(DestOwnerID != 0){
|
||||
CheckWeight(DestOwnerID, Obj, Count);
|
||||
}
|
||||
}
|
||||
|
||||
Object ObjCon = Obj.getContainer();
|
||||
uint32 ObjOwnerID = GetObjectCreatureID(Obj);
|
||||
|
||||
// TODO(fusion): What is even going on here?
|
||||
if(ObjType.getFlag(MOVEMENTEVENT)){
|
||||
error("Merge: Movement-Event für kumulierbares Objekt %d wird nicht ausgelöst.\n", ObjType.TypeID);
|
||||
}
|
||||
|
||||
if(ObjCon != DestCon){
|
||||
SeparationEvent(Obj, ObjCon);
|
||||
}
|
||||
|
||||
if(Count < ObjCount){
|
||||
ChangeObject(Obj, AMOUNT, ObjCount - Count);
|
||||
AnnounceChangedObject(Obj, 2); // OBJECT_CHANGED ?
|
||||
NotifyTrades(Obj);
|
||||
ChangeObject(Dest, AMOUNT, DestCount + Count);
|
||||
}else{
|
||||
AnnounceChangedObject(Obj, 0); // OBJECT_DISAPPEAR ?
|
||||
NotifyTrades(Obj);
|
||||
NotifyDepot(CreatureID, Obj, 1);
|
||||
MergeObjects(Obj, Dest);
|
||||
}
|
||||
|
||||
AnnounceChangedObject(Dest, 2); // OBJECT_CHANGED ?
|
||||
NotifyTrades(Dest);
|
||||
NotifyCreature(ObjOwnerID, Dest, ObjCon.getObjectType().isBodyContainer());
|
||||
NotifyCreature(DestOwnerID, Dest, DestCon.getObjectType().isBodyContainer());
|
||||
CollisionEvent(Dest, DestCon);
|
||||
NotifyAllCreatures(Dest, 2, NONE); // CREATURE_MOVE_STIMULUS_ ?
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user