Proper collision for stacked pushables

Total height is calculated for pushable stacks and used for evaluation in TestBlockPush() and TestBlockPull()
This commit is contained in:
KrysB4k 2020-12-24 03:53:36 +01:00
parent 10b99e0111
commit 5cee62e169

View file

@ -84,7 +84,25 @@ void PushableBlockControl(short itemNumber)
ROOM_INFO* r; ROOM_INFO* r;
int height; int height;
short roomNumber; short roomNumber;
int stackIndex; // used for moving pushables in stack
int stackIndex; // used for stacked pushables
int blockHeight = 1024;
if (item->triggerFlags > 64)
blockHeight = CLICK(item->triggerFlags - 64);
// get total height of stack
stackIndex = item->itemFlags[1];
while (stackIndex != NO_ITEM)
{
auto stackItem = &g_Level.Items[stackIndex];
if (stackItem->triggerFlags > 64)
blockHeight += CLICK(item->triggerFlags - 64);
else
blockHeight += 1024;
stackIndex = stackItem->itemFlags[1];
}
switch (LaraItem->animNumber) switch (LaraItem->animNumber)
{ {
@ -165,10 +183,7 @@ void PushableBlockControl(short itemNumber)
if (objectNum >= ID_PUSHABLE_OBJECT1 && objectNum <= ID_PUSHABLE_OBJECT10) if (objectNum >= ID_PUSHABLE_OBJECT1 && objectNum <= ID_PUSHABLE_OBJECT10)
{ {
if (belowItem->itemFlags[1] == itemNumber) if (belowItem->itemFlags[1] == itemNumber)
{
belowItem->itemFlags[1] = NO_ITEM; belowItem->itemFlags[1] = NO_ITEM;
printf("Unlinked pushable! belowItem.itemFlags[1]: %d\n", belowItem->itemFlags[1]);
}
} }
} }
} }
@ -177,7 +192,7 @@ void PushableBlockControl(short itemNumber)
{ {
if (TrInput & IN_ACTION) if (TrInput & IN_ACTION)
{ {
if (!TestBlockPush(item, 1024, quadrant)) if (!TestBlockPush(item, blockHeight, quadrant))
LaraItem->goalAnimState = LS_STOP; LaraItem->goalAnimState = LS_STOP;
else else
{ {
@ -269,10 +284,7 @@ void PushableBlockControl(short itemNumber)
if (objectNum >= ID_PUSHABLE_OBJECT1 && objectNum <= ID_PUSHABLE_OBJECT10) if (objectNum >= ID_PUSHABLE_OBJECT1 && objectNum <= ID_PUSHABLE_OBJECT10)
{ {
if (belowItem->itemFlags[1] == itemNumber) if (belowItem->itemFlags[1] == itemNumber)
{
belowItem->itemFlags[1] = NO_ITEM; belowItem->itemFlags[1] = NO_ITEM;
printf("Unlinked pushable! belowItem.itemFlags[1]: %d\n", belowItem->itemFlags[1]);
}
} }
} }
@ -282,7 +294,7 @@ void PushableBlockControl(short itemNumber)
{ {
if (TrInput & IN_ACTION) if (TrInput & IN_ACTION)
{ {
if (!TestBlockPull(item, 1024, quadrant)) if (!TestBlockPull(item, blockHeight, quadrant))
LaraItem->goalAnimState = LS_STOP; LaraItem->goalAnimState = LS_STOP;
else else
{ {
@ -337,7 +349,8 @@ void PushableBlockControl(short itemNumber)
AdjustStopperFlag(item, item->itemFlags[0] + 0x8000, 0); AdjustStopperFlag(item, item->itemFlags[0] + 0x8000, 0);
} }
int stackTop = -1; // index of heighest (yPos) pushable in stack
int stackTop = NO_ITEM; // index of heighest (yPos) pushable in stack
int stackYmin = CLICK(256); // set starting height int stackYmin = CLICK(256); // set starting height
//Check for pushable directly below current one in same sector //Check for pushable directly below current one in same sector
@ -369,11 +382,8 @@ void PushableBlockControl(short itemNumber)
} }
// if top pushable in stack was located, link index of current pushable to below pushable via itemFlags[1] // if top pushable in stack was located, link index of current pushable to below pushable via itemFlags[1]
if (stackTop >= 0) if (stackTop != NO_ITEM)
{
g_Level.Items[stackTop].itemFlags[1] = itemNumber; g_Level.Items[stackTop].itemFlags[1] = itemNumber;
printf("Pushable index: %d\nStack top: %d\nstackTop.itemFlags[1]: %d\n", itemNumber, stackTop, g_Level.Items[stackTop].itemFlags[1]);
}
} }
break; break;
} }
@ -386,6 +396,25 @@ void PushableBlockCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
short roomNumber = item->roomNumber; short roomNumber = item->roomNumber;
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos - 256, item->pos.zPos, &roomNumber); FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos - 256, item->pos.zPos, &roomNumber);
int stackIndex; // used for stacked pushables
int blockHeight = 1024;
if (item->triggerFlags > 64)
blockHeight = CLICK(item->triggerFlags - 64);
// get total height of stack
stackIndex = item->itemFlags[1];
while (stackIndex != NO_ITEM)
{
auto stackItem = &g_Level.Items[stackIndex];
if (stackItem->triggerFlags > 64)
blockHeight += CLICK(item->triggerFlags - 64);
else
blockHeight += 1024;
stackIndex = stackItem->itemFlags[1];
}
if ((!(TrInput & IN_ACTION) if ((!(TrInput & IN_ACTION)
|| l->currentAnimState != LS_STOP || l->currentAnimState != LS_STOP
|| l->animNumber != LA_STAND_IDLE || l->animNumber != LA_STAND_IDLE
@ -408,13 +437,13 @@ void PushableBlockCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (TrInput & IN_FORWARD) if (TrInput & IN_FORWARD)
{ {
if (!TestBlockPush(item, 1024, quadrant)) if (!TestBlockPush(item, blockHeight, quadrant))
return; return;
l->goalAnimState = LS_PUSHABLE_PUSH; l->goalAnimState = LS_PUSHABLE_PUSH;
} }
else if (TrInput & IN_BACK) else if (TrInput & IN_BACK)
{ {
if (!TestBlockPull(item, 1024, quadrant)) if (!TestBlockPull(item, blockHeight, quadrant))
return; return;
l->goalAnimState = LS_PUSHABLE_PULL; l->goalAnimState = LS_PUSHABLE_PULL;
} }