- migrated EVENT to use its actor pointer.

This commit is contained in:
Christoph Oelckers 2021-08-27 12:03:11 +02:00
parent f430c28f88
commit 2396c89fb9
6 changed files with 96 additions and 74 deletions

View file

@ -1512,7 +1512,7 @@ DBloodActor* getNextIncarnation(DBloodActor* actor)
XSPRITE* pXSprite = &actor->x(); XSPRITE* pXSprite = &actor->x();
for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++)
{ {
if (rxBucket[i].type != OBJ_SPRITE) continue; if (rxBucket[i].type != SS_SPRITE) continue;
auto rxactor = rxBucket[i].GetActor(); auto rxactor = rxBucket[i].GetActor();
if (actor != rxactor && rxactor->s().statnum == kStatInactive) return rxactor; if (actor != rxactor && rxactor->s().statnum == kStatInactive) return rxactor;
} }

View file

@ -741,8 +741,20 @@ void callbackCondition(DBloodActor* actor, int)
TRCONDITION* pCond = &gCondition[pXSprite->sysData1]; TRCONDITION* pCond = &gCondition[pXSprite->sysData1];
for (unsigned i = 0; i < pCond->length; i++) { for (unsigned i = 0; i < pCond->length; i++) {
EVENT evn; evn.index_ = pCond->obj[i].index; evn.type = pCond->obj[i].type; EVENT evn;
evn.cmd = pCond->obj[i].cmd; evn.funcID = kCallbackCondition; evn.type = pCond->obj[i].type;
if (evn.type == SS_SPRITE)
{
evn.index_ = 0;
evn.actor = &bloodActors[pCond->obj[i].index];
}
else
{
evn.actor = nullptr;
evn.index_ = pCond->obj[i].index;
}
evn.cmd = pCond->obj[i].cmd;
evn.funcID = kCallbackCondition;
useCondition(&sprite[pXSprite->reference], pXSprite, evn); useCondition(&sprite[pXSprite->reference], pXSprite, evn);
} }

View file

@ -321,7 +321,7 @@ void evInit()
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static bool evGetSourceState(int type, int nIndex) static bool evGetSourceState(int type, int nIndex, DBloodActor* actor)
{ {
int nXIndex; int nXIndex;
@ -338,9 +338,8 @@ static bool evGetSourceState(int type, int nIndex)
return xwall[nXIndex].state != 0; return xwall[nXIndex].state != 0;
case SS_SPRITE: case SS_SPRITE:
nXIndex = sprite[nIndex].extra; if (actor->hasX())
assert(nXIndex > 0 && nXIndex < kMaxXSprites); return actor->x().state != 0;
return xsprite[nXIndex].state != 0;
} }
// shouldn't reach this point // shouldn't reach this point
@ -353,21 +352,21 @@ static bool evGetSourceState(int type, int nIndex)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void evSend(int nIndex, int nType, int rxId, COMMAND_ID command) void evSend(DBloodActor* actor, int nIndex, int nType, int rxId, COMMAND_ID command)
{ {
switch (command) { switch (command) {
case kCmdState: case kCmdState:
command = evGetSourceState(nType, nIndex) ? kCmdOn : kCmdOff; command = evGetSourceState(nType, nIndex, actor) ? kCmdOn : kCmdOff;
break; break;
case kCmdNotState: case kCmdNotState:
command = evGetSourceState(nType, nIndex) ? kCmdOff : kCmdOn; command = evGetSourceState(nType, nIndex, actor) ? kCmdOff : kCmdOn;
break; break;
default: default:
break; break;
} }
EVENT event; EVENT event;
event.actor = nType == SS_SPRITE? &bloodActors[nIndex] : nullptr; event.actor = actor;
event.index_ = nIndex; event.index_ = nIndex;
event.type = nType; event.type = nType;
event.cmd = command; event.cmd = command;
@ -482,7 +481,7 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command)
#endif #endif
for (int i = bucketHead[rxId]; i < bucketHead[rxId + 1]; i++) for (int i = bucketHead[rxId]; i < bucketHead[rxId + 1]; i++)
{ {
if (event.type != rxBucket[i].type || (event.type != OBJ_SPRITE && event.index_ != rxBucket[i].rxindex) || (event.type == OBJ_SPRITE && event.actor != rxBucket[i].GetActor())) if (!event.isObject(rxBucket[i].type, rxBucket[i].actor, rxBucket[i].rxindex))
{ {
switch (rxBucket[i].type) switch (rxBucket[i].type)
{ {
@ -518,42 +517,42 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command)
void evPost_(int nIndex, int nType, unsigned int nDelta, COMMAND_ID command) void evPost_(int nIndex, int nType, unsigned int nDelta, COMMAND_ID command)
{ {
assert(command != kCmdCallback); assert(command != kCmdCallback);
if (command == kCmdState) command = evGetSourceState(nType, nIndex) ? kCmdOn : kCmdOff; if (command == kCmdState) command = evGetSourceState(nType, nIndex, &bloodActors[nIndex]) ? kCmdOn : kCmdOff;
else if (command == kCmdNotState) command = evGetSourceState(nType, nIndex) ? kCmdOff : kCmdOn; else if (command == kCmdNotState) command = evGetSourceState(nType, nIndex, &bloodActors[nIndex]) ? kCmdOff : kCmdOn;
EVENT evn = {nullptr, (int16_t)nIndex, (int8_t)nType, (int8_t)command, 0, PlayClock + (int)nDelta }; EVENT evn = { &bloodActors[nIndex], (int16_t)nIndex, (int8_t)nType, (int8_t)command, 0, PlayClock + (int)nDelta };
queue.insert(evn); queue.insert(evn);
} }
void evPost_(int nIndex, int nType, unsigned int nDelta, CALLBACK_ID callback) void evPost_(int nIndex, int nType, unsigned int nDelta, CALLBACK_ID callback)
{ {
EVENT evn = {nullptr, (int16_t)nIndex, (int8_t)nType, kCmdCallback, (int16_t)callback, PlayClock + (int)nDelta }; EVENT evn = {&bloodActors[nIndex], (int16_t)nIndex, (int8_t)nType, kCmdCallback, (int16_t)callback, PlayClock + (int)nDelta };
queue.insert(evn); queue.insert(evn);
} }
void evPostActor(DBloodActor* actor, unsigned int nDelta, COMMAND_ID command) void evPostActor(DBloodActor* actor, unsigned int nDelta, COMMAND_ID command)
{ {
evPost_(actor->s().index, OBJ_SPRITE, nDelta, command); evPost_(actor->s().index, SS_SPRITE, nDelta, command);
} }
void evPostActor(DBloodActor* actor, unsigned int nDelta, CALLBACK_ID callback) void evPostActor(DBloodActor* actor, unsigned int nDelta, CALLBACK_ID callback)
{ {
evPost_(actor->s().index, OBJ_SPRITE, nDelta, callback); evPost_(actor->s().index, SS_SPRITE, nDelta, callback);
} }
void evPostSector(int index, unsigned int nDelta, COMMAND_ID command) void evPostSector(int index, unsigned int nDelta, COMMAND_ID command)
{ {
evPost_(index, OBJ_SECTOR, nDelta, command); evPost_(index, SS_SECTOR, nDelta, command);
} }
void evPostSector(int index, unsigned int nDelta, CALLBACK_ID callback) void evPostSector(int index, unsigned int nDelta, CALLBACK_ID callback)
{ {
evPost_(index, OBJ_SECTOR, nDelta, callback); evPost_(index, SS_SECTOR, nDelta, callback);
} }
void evPostWall(int index, unsigned int nDelta, COMMAND_ID command) void evPostWall(int index, unsigned int nDelta, COMMAND_ID command)
{ {
evPost_(index, OBJ_WALL, nDelta, command); evPost_(index, SS_WALL, nDelta, command);
} }
@ -563,63 +562,63 @@ void evPostWall(int index, unsigned int nDelta, COMMAND_ID command)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void evKill_(int index, int type) void evKill_(DBloodActor* actor, int index, int type)
{ {
for (auto ev = queue.begin(); ev != queue.end();) for (auto ev = queue.begin(); ev != queue.end();)
{ {
if (ev->index_ == index && ev->type == type) ev = queue.erase(ev); if (ev->isObject(type, actor, index)) ev = queue.erase(ev);
else ev++; else ev++;
} }
} }
void evKill_(int index, int type, CALLBACK_ID cb) void evKill_(DBloodActor* actor, int index, int type, CALLBACK_ID cb)
{ {
for (auto ev = queue.begin(); ev != queue.end();) for (auto ev = queue.begin(); ev != queue.end();)
{ {
if (ev->index_ == index && ev->type == type && ev->funcID == cb) ev = queue.erase(ev); if (ev->isObject(type, actor, index) && ev->funcID == cb) ev = queue.erase(ev);
else ev++; else ev++;
} }
} }
void evKillActor(DBloodActor* actor) void evKillActor(DBloodActor* actor)
{ {
evKill_(actor->s().index, 3); evKill_(actor, 0, SS_SPRITE);
} }
void evKillActor(DBloodActor* actor, CALLBACK_ID cb) void evKillActor(DBloodActor* actor, CALLBACK_ID cb)
{ {
evKill_(actor->s().index, 3, cb); evKill_(actor, 0, SS_SPRITE, cb);
} }
void evKillWall(int wal) void evKillWall(int wal)
{ {
evKill_(wal, OBJ_WALL); evKill_(nullptr, wal, SS_WALL);
} }
void evKillSector(int sec) void evKillSector(int sec)
{ {
evKill_(sec, OBJ_SECTOR); evKill_(nullptr, sec, SS_SECTOR);
} }
// these have no target. // these have no target.
void evSendGame(int rxId, COMMAND_ID command) void evSendGame(int rxId, COMMAND_ID command)
{ {
evSend(0, 0, rxId, command); evSend(nullptr, 0, 0, rxId, command);
} }
void evSendActor(DBloodActor* actor, int rxId, COMMAND_ID command) void evSendActor(DBloodActor* actor, int rxId, COMMAND_ID command)
{ {
evSend(actor->s().index, OBJ_SPRITE, rxId, command); evSend(actor, 0, SS_SPRITE, rxId, command);
} }
void evSendSector(int index, int rxId, COMMAND_ID command) void evSendSector(int index, int rxId, COMMAND_ID command)
{ {
evSend(index, OBJ_SECTOR, rxId, command); evSend(nullptr, index, SS_SECTOR, rxId, command);
} }
void evSendWall(int index, int rxId, COMMAND_ID command) void evSendWall(int index, int rxId, COMMAND_ID command)
{ {
evSend(index, OBJ_WALL, rxId, command); evSend(nullptr, index, SS_WALL, rxId, command);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -639,8 +638,7 @@ void evProcess(unsigned int time)
{ {
assert(event.funcID < kCallbackMax); assert(event.funcID < kCallbackMax);
assert(gCallback[event.funcID] != nullptr); assert(gCallback[event.funcID] != nullptr);
if (event.type == OBJ_SPRITE) gCallback[event.funcID](&bloodActors[event.index_], 0); gCallback[event.funcID](event.actor, event.index_);
else gCallback[event.funcID](nullptr, event.index_);
} }
else else
{ {
@ -653,7 +651,7 @@ void evProcess(unsigned int time)
trMessageWall(event.index_, event); trMessageWall(event.index_, event);
break; break;
case SS_SPRITE: case SS_SPRITE:
trMessageSprite(event.index_, event); trMessageSprite(event.actor->s().index, event);
break; break;
} }
} }
@ -670,9 +668,10 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, EVENT& w, EVENT* d
{ {
if (arc.BeginObject(keyname)) if (arc.BeginObject(keyname))
{ {
arc("index", w.index_) arc("type", w.type);
("type", w.type) if (w.type != SS_SPRITE) arc("index", w.index_);
("command", w.cmd) else arc("index", w.actor);
arc("command", w.cmd)
("func", w.funcID) ("func", w.funcID)
("prio", w.priority) ("prio", w.priority)
.EndObject(); .EndObject();
@ -684,9 +683,10 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, RXBUCKET& w, RXBUC
{ {
if (arc.BeginObject(keyname)) if (arc.BeginObject(keyname))
{ {
arc("index", w.rxindex) arc("type", w.type);
("type", w.type) if (w.type != SS_SPRITE) arc("index", w.rxindex);
.EndObject(); else arc("index", w.actor);
arc.EndObject();
} }
return arc; return arc;
} }

View file

@ -160,12 +160,14 @@ struct EVENT
{ {
return priority < other.priority; return priority < other.priority;
} }
bool isObject(int type, DBloodActor* actor, int index) const
{
return (this->type == type && (this->type != SS_SPRITE ? (this->index_ == index) : (this->actor == actor)));
}
}; };
void evInit(void); void evInit(void);
void evSend(int nIndex, int nType, int rxId, COMMAND_ID command);
//void evPost(int nIndex, int nType, unsigned int nDelta, COMMAND_ID command);
//void evPost(int nIndex, int nType, unsigned int nDelta, CALLBACK_ID callback);
void evPostActor(DBloodActor*, unsigned int nDelta, COMMAND_ID command); void evPostActor(DBloodActor*, unsigned int nDelta, COMMAND_ID command);
void evPostActor(DBloodActor*, unsigned int nDelta, CALLBACK_ID callback); void evPostActor(DBloodActor*, unsigned int nDelta, CALLBACK_ID callback);
@ -173,8 +175,6 @@ void evPostSector(int index, unsigned int nDelta, COMMAND_ID command);
void evPostSector(int index, unsigned int nDelta, CALLBACK_ID callback); void evPostSector(int index, unsigned int nDelta, CALLBACK_ID callback);
void evProcess(unsigned int nTime); void evProcess(unsigned int nTime);
void evKill_(int a1, int a2);
void evKill_(int a1, int a2, CALLBACK_ID a3);
void evKillActor(DBloodActor*); void evKillActor(DBloodActor*);
void evKillActor(DBloodActor*, CALLBACK_ID a3); void evKillActor(DBloodActor*, CALLBACK_ID a3);

View file

@ -1042,8 +1042,11 @@ void nnExtProcessSuperSprites() {
if (pXCond->data1 >= kCondGameBase && pXCond->data1 < kCondGameMax) { if (pXCond->data1 >= kCondGameBase && pXCond->data1 < kCondGameMax) {
EVENT evn; EVENT evn;
evn.index_ = pXCond->reference; evn.cmd = (int8_t)pXCond->command; evn.index_ = 0;
evn.type = OBJ_SPRITE; evn.funcID = kCallbackMax; evn.actor = &bloodActors[pXCond->reference];
evn.cmd = (int8_t)pXCond->command;
evn.type = OBJ_SPRITE;
evn.funcID = kCallbackMax;
useCondition(&sprite[pXCond->reference], pXCond, evn); useCondition(&sprite[pXCond->reference], pXCond, evn);
} else if (pCond->length > 0) { } else if (pCond->length > 0) {
@ -1052,8 +1055,20 @@ void nnExtProcessSuperSprites() {
for (unsigned k = 0; k < pCond->length; k++) { for (unsigned k = 0; k < pCond->length; k++) {
EVENT evn; EVENT evn;
evn.index_ = pCond->obj[k].index; evn.cmd = pCond->obj[k].cmd; // temporary mess.
evn.type = pCond->obj[k].type; evn.funcID = kCallbackMax; if (pCond->obj[k].type == OBJ_SPRITE)
{
evn.actor = &bloodActors[pCond->obj[k].type];
evn.index_ = 0;
}
else
{
evn.actor = nullptr;
evn.index_ = pCond->obj[k].index;
}
evn.cmd = pCond->obj[k].cmd;
evn.type = pCond->obj[k].type;
evn.funcID = kCallbackMax;
useCondition(&sprite[pXCond->reference], pXCond, evn); useCondition(&sprite[pXCond->reference], pXCond, evn);
} }
@ -4184,11 +4199,9 @@ void modernTypeSendCommand(int nSprite, int destChannel, COMMAND_ID command) {
// this function used by various new modern types. // this function used by various new modern types.
void modernTypeTrigger(int destObjType, int destObjIndex, EVENT event) { void modernTypeTrigger(int destObjType, int destObjIndex, EVENT event) {
if (event.type != OBJ_SPRITE) return; if (event.type != OBJ_SPRITE || !event.actor || !event.actor->hasX()) return;
spritetype* pSource = &sprite[event.index_]; spritetype* pSource = &event.actor->s();
XSPRITE* pXSource = &event.actor->x();
if (!xspriRangeIsFine(pSource->extra)) return;
XSPRITE* pXSource = &xsprite[pSource->extra];
switch (destObjType) { switch (destObjType) {
case OBJ_SECTOR: case OBJ_SECTOR:
@ -4799,13 +4812,13 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
if (event.type != OBJ_SPRITE) { if (event.type != OBJ_SPRITE) {
viewSetSystemMessage("Only sprites could use command #%d", event.cmd); viewSetSystemMessage("Only sprites can use command #%d", event.cmd);
return true; return true;
} else if (xspriRangeIsFine(sprite[event.index_].extra)) { } else if (event.actor && event.actor->hasX()) {
// copy dude flags from the source to destination sprite // copy dude flags from the source to destination sprite
aiPatrolFlagsMgr(&sprite[event.index_], &xsprite[sprite[event.index_].extra], pSprite, pXSprite, true, false); aiPatrolFlagsMgr(&event.actor->s(), &event.actor->x(), pSprite, pXSprite, true, false);
} }
@ -4832,8 +4845,8 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
} }
break; break;
case kCmdDudeFlagsSet: case kCmdDudeFlagsSet:
if (!xspriRangeIsFine(sprite[event.index_].extra)) break; if (!event.actor || !event.actor->hasX()) break;
else aiPatrolFlagsMgr(&sprite[event.index_], &xsprite[sprite[event.index_].extra], pSprite, pXSprite, false, true); // initialize patrol dude with possible new flags else aiPatrolFlagsMgr(&event.actor->s(), &event.actor->x(), pSprite, pXSprite, false, true); // initialize patrol dude with possible new flags
break; break;
default: default:
if (!pXSprite->state) evPostActor(actor, 0, kCmdOn); if (!pXSprite->state) evPostActor(actor, 0, kCmdOn);
@ -5371,10 +5384,10 @@ void useSequentialTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState) {
int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) { int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) {
auto sourceactor = &bloodActors[pSource->index]; auto sourceactor = &bloodActors[pSource->index];
int objType = event.type;
int objType = event.type; int objIndex = event.index_; int objIndex = event.index_;
bool srcIsCondition = false; bool srcIsCondition = false;
if (objType == OBJ_SPRITE && objIndex != pSource->index) if (objType == OBJ_SPRITE && event.actor != sourceactor)
srcIsCondition = (sprite[objIndex].type == kModernCondition || sprite[objIndex].type == kModernConditionFalse); srcIsCondition = (sprite[objIndex].type == kModernCondition || sprite[objIndex].type == kModernConditionFalse);
// if it's a tracking condition, it must ignore all the commands sent from objects // if it's a tracking condition, it must ignore all the commands sent from objects
@ -5385,8 +5398,8 @@ int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) {
} else { // or grab serials of objects from previous conditions } else { // or grab serials of objects from previous conditions
pXSource->targetX = xsprite[sprite[objIndex].extra].targetX; pXSource->targetX = event.actor->x().targetX;
pXSource->targetY = xsprite[sprite[objIndex].extra].targetY; pXSource->targetY = event.actor->x().targetY;
} }

View file

@ -189,9 +189,7 @@ unsigned int GetSourceBusy(EVENT a1)
} }
case 3: case 3:
{ {
int nXIndex = sprite[nIndex].extra; return a1.actor && a1.actor->hasX() ? a1.actor->x().busy : false;
assert(nXIndex > 0 && nXIndex < kMaxXSprites);
return xsprite[nXIndex].busy;
} }
} }
return 0; return 0;
@ -1698,12 +1696,11 @@ void LinkSprite(int nSprite, XSPRITE *pXSprite, EVENT event) {
switch (pSprite->type) { switch (pSprite->type) {
case kSwitchCombo: case kSwitchCombo:
{ {
if (event.type == 3) if (event.type == OBJ_SPRITE)
{ {
int nSprite2 = event.index_; auto actor2 = event.actor;
int nXSprite2 = sprite[nSprite2].extra;
assert(nXSprite2 > 0 && nXSprite2 < kMaxXSprites); pXSprite->data1 = actor2 && actor2->hasX()? actor2->x().data1 : 0;
pXSprite->data1 = xsprite[nXSprite2].data1;
if (pXSprite->data1 == pXSprite->data2) if (pXSprite->data1 == pXSprite->data2)
SetSpriteState(nSprite, pXSprite, 1); SetSpriteState(nSprite, pXSprite, 1);
else else