- Millorant el sistema de PUSHos

This commit is contained in:
2024-05-22 14:00:42 +02:00
parent c51571e53c
commit 5f06a2ce2f
2 changed files with 105 additions and 84 deletions

View File

@@ -171,6 +171,16 @@ namespace actor
} }
} }
uint8_t push(actor_t *act, uint8_t push)
{
uint8_t result = 0;
if (act->flags & FLAG_PUSHABLE) act->push |= push;
if ( (act->flags & FLAG_REACTIVE) && (act->react_mask & push) ) result = act->react_push;
if (act->flags & FLAG_DEADLY) result |= PUSH_KILL;
return result;
}
void updateUserInput(actor_t *act) void updateUserInput(actor_t *act)
{ {
vec3_t min = room::getMin(); vec3_t min = room::getMin();
@@ -248,8 +258,8 @@ namespace actor
if ( input::keyDown(SDL_SCANCODE_SPACE) && act->pos.y<=max.y && act->pos.y>=min.y && act->pos.x<=max.x && act->pos.x>=min.x && act->react_mask==0 && (act->pos.z==0 || act->below)) if ( input::keyDown(SDL_SCANCODE_SPACE) && act->pos.y<=max.y && act->pos.y>=min.y && act->pos.x<=max.x && act->pos.x>=min.x && act->react_mask==0 && (act->pos.z==0 || act->below))
{ {
// [RZC 14/05/2024] hack usant react_mask i react_push del heroi. Llegir més avall. // [RZC 14/05/2024] hack usant react_mask i react_push del heroi. Llegir més avall.
act->react_mask=1; act->react_mask=1; // =1 estic botant (anant cap amunt)
act->react_push=0; act->react_push=0; // es el comptador de botant, seguirà pujant mentres siga < 8
act->flags &= uint8_t(~FLAG_GRAVITY); act->flags &= uint8_t(~FLAG_GRAVITY);
if (act->below) if (act->below)
{ {
@@ -266,20 +276,23 @@ namespace actor
// que a un xixo. // que a un xixo.
if (act->react_mask) if (act->react_mask)
{ {
// Si topetem en una vora de l'habitació, s'acabat el bot
if (act->pos.x>max.x || act->pos.x<min.x || act->pos.y>max.y || act->pos.y<min.y) act->react_push=8; if (act->pos.x>max.x || act->pos.x<min.x || act->pos.y>max.y || act->pos.y<min.y) act->react_push=8;
// Si encara està botant (react_push < 8)...
if (act->react_push<8) if (act->react_push<8)
{ {
act->pos.z++; act->pos.z++; // seguim pujant
act->react_push++; act->react_push++; // augmentem el comptador de bot
} }
else else // Si ja ha acabat de botar...
{ {
act->react_mask=0; act->react_mask=0; // desactivem la guarda (react_mask=0)
act->flags |= FLAG_GRAVITY; act->flags |= FLAG_GRAVITY; // i reactivem el flag de gravetat
} }
} }
// Que faça l'animació nomes si al final realment s'ha menejat
if (moving) if (moving)
{ {
act->flags |= FLAG_ANIMATED; act->flags |= FLAG_ANIMATED;
@@ -339,7 +352,7 @@ namespace actor
// TODO // TODO
break; break;
} }
act->orient = act->mov_push; if (act->flags & FLAG_ORIENTABLE) act->orient = act->mov_push;
} }
void updateReactive(actor_t *act) void updateReactive(actor_t *act)
@@ -360,7 +373,7 @@ namespace actor
} }
} }
void updatePushable(actor_t *act) void updatePush(actor_t *act)
{ {
if (act->flags & FLAG_REACTIVE) { updateReactive(act); return; } if (act->flags & FLAG_REACTIVE) { updateReactive(act); return; }
@@ -377,6 +390,11 @@ namespace actor
} }
else else
{ {
// Tractament especial del moviment cap amunt: Estem movent, directament,
// TOTS els objectes des d'este cap amunt si son pushables, en compte de
// enviar el flag de push. Ho vem així perque sino la gravetat els tiraria
// avall. De totes formes [TODO] revisar.
// Estem tenint en compte els MOVILS, pero no els REACT
actor_t *now = act; actor_t *now = act;
do { do {
actor::actor_t *other = actor::any_above_me(now); actor::actor_t *other = actor::any_above_me(now);
@@ -390,6 +408,7 @@ namespace actor
actor::setDirty(act); actor::setDirty(act);
} }
act->push &= ~PUSH_ZP;
} }
if (act->push & PUSH_XN) { if (act->push & PUSH_XN) {
@@ -397,22 +416,19 @@ namespace actor
actor::actor_t *other = actor::get_collision(act); actor::actor_t *other = actor::get_collision(act);
if (other || ( act->pos.x<min.x && ( !(room::getDoors()&DOOR_XN) || (act->pos.y!=28) || (act->pos.z!=room::getDoor(XN)*4) || !(act->flags&FLAG_HERO) ) )) if (other || ( act->pos.x<min.x && ( !(room::getDoors()&DOOR_XN) || (act->pos.y!=28) || (act->pos.z!=room::getDoor(XN)*4) || !(act->flags&FLAG_HERO) ) ))
{ {
if (other && other->flags & FLAG_SENSIBLE) other->push |= PUSH_XN; if (other) act->push |= push(other, PUSH_XN);
act->pos.x++; act->pos.x++;
if (act->flags & FLAG_MOVING) changeMoving(act); if (act->flags & FLAG_MOVING) changeMoving(act);
} }
else else
{ {
// Si tenim a algú damunt, el movem també
if (act->above && act->above->flags & FLAG_PUSHABLE) { if (act->above && act->above->flags & FLAG_PUSHABLE) {
if (act->above->push != 0) { push(act->above, PUSH_XN);
updatePushable(act->above);
act->above->push = PUSH_XN;
} else {
act->above->push = PUSH_XN;
updatePushable(act->above);
act->above->push = 0;
}
} }
// Si ja havem atravesat la porta, ens movem a la porta de l'altra costat
// [TODO] que es moga a l'habitació que toca!!!
if (act->pos.x<min.x-4) { if (act->pos.x<min.x-4) {
act->pos.x = max.x; act->pos.x = max.x;
act->pos.z = room::getDoor(XP)*4; act->pos.z = room::getDoor(XP)*4;
@@ -420,6 +436,7 @@ namespace actor
actor::setDirty(act); actor::setDirty(act);
} }
act->push &= ~PUSH_XN;
} }
if (act->push & PUSH_XP) { if (act->push & PUSH_XP) {
@@ -427,22 +444,16 @@ namespace actor
actor::actor_t *other = actor::get_collision(act); actor::actor_t *other = actor::get_collision(act);
if (other || (act->pos.x>max.x && ( !(room::getDoors()&DOOR_XP) || (act->pos.y!=28) || !(act->flags&FLAG_HERO) ) )) if (other || (act->pos.x>max.x && ( !(room::getDoors()&DOOR_XP) || (act->pos.y!=28) || !(act->flags&FLAG_HERO) ) ))
{ {
if (other && other->flags & FLAG_SENSIBLE) other->push |= PUSH_XP; if (other) act->push |= push(other, PUSH_XP);
act->pos.x--; act->pos.x--;
if (act->flags & FLAG_MOVING) changeMoving(act); if (act->flags & FLAG_MOVING) changeMoving(act);
} }
else else
{ {
if (act->above && act->above->flags & FLAG_PUSHABLE) { if (act->above && act->above->flags & FLAG_PUSHABLE) {
if (act->above->push != 0) { push(act->above, PUSH_XP);
updatePushable(act->above);
act->above->push = PUSH_XP;
} else {
act->above->push = PUSH_XP;
updatePushable(act->above);
act->above->push = 0;
}
} }
if (act->pos.x>max.x+4) { if (act->pos.x>max.x+4) {
act->pos.x = min.x; act->pos.x = min.x;
act->pos.z = room::getDoor(XN)*4; act->pos.z = room::getDoor(XN)*4;
@@ -450,6 +461,7 @@ namespace actor
actor::setDirty(act); actor::setDirty(act);
} }
act->push &= ~PUSH_XP;
} }
if (act->push & PUSH_YN) { if (act->push & PUSH_YN) {
@@ -457,22 +469,16 @@ namespace actor
actor::actor_t *other = actor::get_collision(act); actor::actor_t *other = actor::get_collision(act);
if (other || ( act->pos.y<min.y && ( !(room::getDoors()&DOOR_YN) || (act->pos.x!=28) || (act->pos.z!=room::getDoor(XN)*4) || !(act->flags&FLAG_HERO) ) )) if (other || ( act->pos.y<min.y && ( !(room::getDoors()&DOOR_YN) || (act->pos.x!=28) || (act->pos.z!=room::getDoor(XN)*4) || !(act->flags&FLAG_HERO) ) ))
{ {
if (other && other->flags & FLAG_SENSIBLE) other->push |= PUSH_YN; if (other) act->push |= push(other, PUSH_YN);
act->pos.y++; act->pos.y++;
if (act->flags & FLAG_MOVING) changeMoving(act); if (act->flags & FLAG_MOVING) changeMoving(act);
} }
else else
{ {
if (act->above && act->above->flags & FLAG_PUSHABLE) { if (act->above && act->above->flags & FLAG_PUSHABLE) {
if (act->above->push != 0) { push(act->above, PUSH_YN);
updatePushable(act->above);
act->above->push = PUSH_YN;
} else {
act->above->push = PUSH_YN;
updatePushable(act->above);
act->above->push = 0;
}
} }
if (act->pos.y<min.y-4) { if (act->pos.y<min.y-4) {
act->pos.y = max.y; act->pos.y = max.y;
act->pos.z = room::getDoor(YP)*4; act->pos.z = room::getDoor(YP)*4;
@@ -480,6 +486,7 @@ namespace actor
actor::setDirty(act); actor::setDirty(act);
} }
act->push &= ~PUSH_YN;
} }
if (act->push & PUSH_YP) { if (act->push & PUSH_YP) {
@@ -487,22 +494,16 @@ namespace actor
actor::actor_t *other = actor::get_collision(act); actor::actor_t *other = actor::get_collision(act);
if (other || ( act->pos.y>max.y && ( !(room::getDoors()&DOOR_YP) || (act->pos.x!=28) || !(act->flags&FLAG_HERO) ) )) if (other || ( act->pos.y>max.y && ( !(room::getDoors()&DOOR_YP) || (act->pos.x!=28) || !(act->flags&FLAG_HERO) ) ))
{ {
if (other && other->flags & FLAG_SENSIBLE) other->push |= PUSH_YP; if (other) act->push |= push(other, PUSH_YP);
act->pos.y--; act->pos.y--;
if (act->flags & FLAG_MOVING) changeMoving(act); if (act->flags & FLAG_MOVING) changeMoving(act);
} }
else else
{ {
if (act->above && act->above->flags & FLAG_PUSHABLE) { if (act->above && act->above->flags & FLAG_PUSHABLE) {
if (act->above->push != 0) { push(act->above, PUSH_YP);
updatePushable(act->above);
act->above->push = PUSH_YP;
} else {
act->above->push = PUSH_YP;
updatePushable(act->above);
act->above->push = 0;
}
} }
if (act->pos.y>max.y+4) { if (act->pos.y>max.y+4) {
act->pos.y = min.y; act->pos.y = min.y;
act->pos.z = room::getDoor(YN)*4; act->pos.z = room::getDoor(YN)*4;
@@ -510,8 +511,57 @@ namespace actor
actor::setDirty(act); actor::setDirty(act);
} }
act->push &= ~PUSH_YP;
} }
if (act->push & PUSH_ZN) {
// Si estic sobre el piso, no faig res [TODO]: Si no hi ha piso ha de caure
if (act->pos.z == 0) return;
// Si tinc a algú baix...
if (act->below)
{
// ...i encara està baix...
if (is_above(act, act->below)) {
// ...li pase a ell el push, neteje el meu flag, canvie direcció si pertoca i me ane
uint8_t result = push(act->below, PUSH_ZN);
act->push &= ~PUSH_ZN;
if (act->flags & FLAG_MOVING) changeMoving(act);
return;
}
// ... pero si ja no està baix, el desasociem, i seguim el proces
act->below->above = nullptr;
act->below = nullptr;
}
// Busquem si hi ha algú nou baix de mi
actor_t *below = any_below_me(act); // [TODO] Jo crec que açò ho pot fer el propi get_collision()
// Si sí que hi ha...
if (below)
{
// ...el asociem...
act->below = below;
below->above = act;
// ... i li passem el push, netejem el meu flag i gonnem
uint8_t result = push(act->below, PUSH_ZN);
act->push &= ~PUSH_ZN;
if (act->flags & FLAG_MOVING) changeMoving(act);
return;
}
// Si estem dins d'una porta, no caiguem. [TODO] Revisar
if (act->flags&FLAG_HERO && (act->pos.x>max.x || act->pos.x<min.x || act->pos.y>max.y || act->pos.y<min.y) ) return;
// Si arribem fins ací, podem moure la posició
act->pos.z--;
actor::setDirty(act);
}
if ( (act->push & PUSH_KILL) && (act->flags & FLAG_HERO) ) {
//[TODO] Matar al ruiseñor
}
/*
if (act->push & PUSH_ZN) { if (act->push & PUSH_ZN) {
act->pos.z--; act->pos.z--;
actor::actor_t *other = actor::get_collision(act); actor::actor_t *other = actor::get_collision(act);
@@ -526,48 +576,14 @@ namespace actor
actor::setDirty(act); actor::setDirty(act);
} }
} }
*/
}
void updateGravity(actor_t *act)
{
if (act->pos.z == 0) return;
if (act->below)
{
if (is_above(act, act->below)) {
if (act->below->flags & FLAG_REACTIVE) {
act->below->push |= PUSH_ZN;
updateReactive(act->below);
if (act->push) updatePushable(act);
}
return;
}
act->below->above = nullptr;
act->below = nullptr;
}
actor_t *below = any_below_me(act);
if (below)
{
act->below = below;
below->above = act;
if (act->below->flags & FLAG_REACTIVE) {
act->below->push |= PUSH_ZN;
updateReactive(act->below);
if (act->push) updatePushable(act);
}
return;
}
vec3_t min = room::getMin();
vec3_t max = room::getMax();
if (act->flags&FLAG_HERO && (act->pos.x>max.x || act->pos.x<min.x || act->pos.y>max.y || act->pos.y<min.y) ) return;
act->pos.z--;
} }
void update(actor_t *act, const bool update_all) void update(actor_t *act, const bool update_all)
{ {
actor_t *next = act->next; actor_t *next = act->next;
// Actualitzem el frame de l'animació (si no te el flag de animat, no afectarà per a res)
if (act->anim_wait_count==act->anim_wait) { if (act->anim_wait_count==act->anim_wait) {
act->anim_frame=(act->anim_frame+1)%4; act->anim_frame=(act->anim_frame+1)%4;
act->anim_wait_count=0; act->anim_wait_count=0;
@@ -577,12 +593,14 @@ namespace actor
if (act->flags & FLAG_HERO) updateUserInput(act); if (act->flags & FLAG_HERO) updateUserInput(act);
if (act->flags & FLAG_MOVING) updateMoving(act); if (act->flags & FLAG_MOVING) updateMoving(act);
if (act->flags & FLAG_GRAVITY) act->push |= PUSH_ZN;
//if (act->flags & FLAG_PUSHABLE) //if (act->flags & FLAG_PUSHABLE)
updatePushable(act); updatePush(act);
if (act->flags & FLAG_GRAVITY) updateGravity(act); //if (act->flags & FLAG_GRAVITY) updateGravity(act);
//if (act->flags & FLAG_REACTIVE) updateReactive(act); //if (act->flags & FLAG_REACTIVE) updateReactive(act);
act->push = PUSH_NONE; //act->push = PUSH_NONE;
if (update_all && next) update(next); if (update_all && next) update(next);
} }
@@ -817,6 +835,7 @@ namespace actor
if (value==5) return "CCW"; if (value==5) return "CCW";
if (value==6) return "RAND"; if (value==6) return "RAND";
if (value==7) return "HUNT"; if (value==7) return "HUNT";
return "NONE";
} }
void load() void load()

View File

@@ -90,6 +90,8 @@ namespace actor
void reorder(); void reorder();
uint8_t push(actor_t *act, uint8_t push);
void update(actor_t *act, const bool update_all=true); void update(actor_t *act, const bool update_all=true);
void updateEditor(actor_t *act, const bool update_all=true); void updateEditor(actor_t *act, const bool update_all=true);