- 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();
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();
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];
for (unsigned i = 0; i < pCond->length; i++) {
EVENT evn; evn.index_ = pCond->obj[i].index; evn.type = pCond->obj[i].type;
evn.cmd = pCond->obj[i].cmd; evn.funcID = kCallbackCondition;
EVENT evn;
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);
}

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;
@ -338,9 +338,8 @@ static bool evGetSourceState(int type, int nIndex)
return xwall[nXIndex].state != 0;
case SS_SPRITE:
nXIndex = sprite[nIndex].extra;
assert(nXIndex > 0 && nXIndex < kMaxXSprites);
return xsprite[nXIndex].state != 0;
if (actor->hasX())
return actor->x().state != 0;
}
// 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) {
case kCmdState:
command = evGetSourceState(nType, nIndex) ? kCmdOn : kCmdOff;
command = evGetSourceState(nType, nIndex, actor) ? kCmdOn : kCmdOff;
break;
case kCmdNotState:
command = evGetSourceState(nType, nIndex) ? kCmdOff : kCmdOn;
command = evGetSourceState(nType, nIndex, actor) ? kCmdOff : kCmdOn;
break;
default:
break;
}
EVENT event;
event.actor = nType == SS_SPRITE? &bloodActors[nIndex] : nullptr;
event.actor = actor;
event.index_ = nIndex;
event.type = nType;
event.cmd = command;
@ -482,7 +481,7 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command)
#endif
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)
{
@ -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)
{
assert(command != kCmdCallback);
if (command == kCmdState) command = evGetSourceState(nType, nIndex) ? kCmdOn : kCmdOff;
else if (command == kCmdNotState) command = evGetSourceState(nType, nIndex) ? kCmdOff : kCmdOn;
EVENT evn = {nullptr, (int16_t)nIndex, (int8_t)nType, (int8_t)command, 0, PlayClock + (int)nDelta };
if (command == kCmdState) command = evGetSourceState(nType, nIndex, &bloodActors[nIndex]) ? kCmdOn : kCmdOff;
else if (command == kCmdNotState) command = evGetSourceState(nType, nIndex, &bloodActors[nIndex]) ? kCmdOff : kCmdOn;
EVENT evn = { &bloodActors[nIndex], (int16_t)nIndex, (int8_t)nType, (int8_t)command, 0, PlayClock + (int)nDelta };
queue.insert(evn);
}
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);
}
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)
{
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)
{
evPost_(index, OBJ_SECTOR, nDelta, command);
evPost_(index, SS_SECTOR, nDelta, command);
}
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)
{
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();)
{
if (ev->index_ == index && ev->type == type) ev = queue.erase(ev);
if (ev->isObject(type, actor, index)) ev = queue.erase(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();)
{
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++;
}
}
void evKillActor(DBloodActor* actor)
{
evKill_(actor->s().index, 3);
evKill_(actor, 0, SS_SPRITE);
}
void evKillActor(DBloodActor* actor, CALLBACK_ID cb)
{
evKill_(actor->s().index, 3, cb);
evKill_(actor, 0, SS_SPRITE, cb);
}
void evKillWall(int wal)
{
evKill_(wal, OBJ_WALL);
evKill_(nullptr, wal, SS_WALL);
}
void evKillSector(int sec)
{
evKill_(sec, OBJ_SECTOR);
evKill_(nullptr, sec, SS_SECTOR);
}
// these have no target.
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)
{
evSend(actor->s().index, OBJ_SPRITE, rxId, command);
evSend(actor, 0, SS_SPRITE, rxId, 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)
{
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(gCallback[event.funcID] != nullptr);
if (event.type == OBJ_SPRITE) gCallback[event.funcID](&bloodActors[event.index_], 0);
else gCallback[event.funcID](nullptr, event.index_);
gCallback[event.funcID](event.actor, event.index_);
}
else
{
@ -653,7 +651,7 @@ void evProcess(unsigned int time)
trMessageWall(event.index_, event);
break;
case SS_SPRITE:
trMessageSprite(event.index_, event);
trMessageSprite(event.actor->s().index, event);
break;
}
}
@ -670,9 +668,10 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, EVENT& w, EVENT* d
{
if (arc.BeginObject(keyname))
{
arc("index", w.index_)
("type", w.type)
("command", w.cmd)
arc("type", w.type);
if (w.type != SS_SPRITE) arc("index", w.index_);
else arc("index", w.actor);
arc("command", w.cmd)
("func", w.funcID)
("prio", w.priority)
.EndObject();
@ -684,9 +683,10 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, RXBUCKET& w, RXBUC
{
if (arc.BeginObject(keyname))
{
arc("index", w.rxindex)
("type", w.type)
.EndObject();
arc("type", w.type);
if (w.type != SS_SPRITE) arc("index", w.rxindex);
else arc("index", w.actor);
arc.EndObject();
}
return arc;
}

View file

@ -160,12 +160,14 @@ struct EVENT
{
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 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, 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 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*, CALLBACK_ID a3);

View file

@ -1042,8 +1042,11 @@ void nnExtProcessSuperSprites() {
if (pXCond->data1 >= kCondGameBase && pXCond->data1 < kCondGameMax) {
EVENT evn;
evn.index_ = pXCond->reference; evn.cmd = (int8_t)pXCond->command;
evn.type = OBJ_SPRITE; evn.funcID = kCallbackMax;
evn.index_ = 0;
evn.actor = &bloodActors[pXCond->reference];
evn.cmd = (int8_t)pXCond->command;
evn.type = OBJ_SPRITE;
evn.funcID = kCallbackMax;
useCondition(&sprite[pXCond->reference], pXCond, evn);
} else if (pCond->length > 0) {
@ -1052,8 +1055,20 @@ void nnExtProcessSuperSprites() {
for (unsigned k = 0; k < pCond->length; k++) {
EVENT evn;
evn.index_ = pCond->obj[k].index; evn.cmd = pCond->obj[k].cmd;
evn.type = pCond->obj[k].type; evn.funcID = kCallbackMax;
// temporary mess.
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);
}
@ -4184,11 +4199,9 @@ void modernTypeSendCommand(int nSprite, int destChannel, COMMAND_ID command) {
// this function used by various new modern types.
void modernTypeTrigger(int destObjType, int destObjIndex, EVENT event) {
if (event.type != OBJ_SPRITE) return;
spritetype* pSource = &sprite[event.index_];
if (!xspriRangeIsFine(pSource->extra)) return;
XSPRITE* pXSource = &xsprite[pSource->extra];
if (event.type != OBJ_SPRITE || !event.actor || !event.actor->hasX()) return;
spritetype* pSource = &event.actor->s();
XSPRITE* pXSource = &event.actor->x();
switch (destObjType) {
case OBJ_SECTOR:
@ -4799,13 +4812,13 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
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;
} else if (xspriRangeIsFine(sprite[event.index_].extra)) {
} else if (event.actor && event.actor->hasX()) {
// 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;
case kCmdDudeFlagsSet:
if (!xspriRangeIsFine(sprite[event.index_].extra)) break;
else aiPatrolFlagsMgr(&sprite[event.index_], &xsprite[sprite[event.index_].extra], pSprite, pXSprite, false, true); // initialize patrol dude with possible new flags
if (!event.actor || !event.actor->hasX()) break;
else aiPatrolFlagsMgr(&event.actor->s(), &event.actor->x(), pSprite, pXSprite, false, true); // initialize patrol dude with possible new flags
break;
default:
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) {
auto sourceactor = &bloodActors[pSource->index];
int objType = event.type; int objIndex = event.index_;
int objType = event.type;
int objIndex = event.index_;
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);
// 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
pXSource->targetX = xsprite[sprite[objIndex].extra].targetX;
pXSource->targetY = xsprite[sprite[objIndex].extra].targetY;
pXSource->targetX = event.actor->x().targetX;
pXSource->targetY = event.actor->x().targetY;
}

View file

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