diff --git a/data/caixes.gif b/data/caixes.gif index 8a5ff1f..8f673a6 100644 Binary files a/data/caixes.gif and b/data/caixes.gif differ diff --git a/data/gat2.gif b/data/gat2.gif index 4dfc353..473c445 100644 Binary files a/data/gat2.gif and b/data/gat2.gif differ diff --git a/data/gifs.txt b/data/gifs.txt index 7676400..09e29dc 100644 --- a/data/gifs.txt +++ b/data/gifs.txt @@ -6,6 +6,7 @@ floor.gif font.gif font2.gif gat.gif +gat2.gif jailgames.gif objectes.gif obrer.gif diff --git a/data/rooms/00.txt b/data/rooms/00.txt index 061bf88..b6554fb 100644 --- a/data/rooms/00.txt +++ b/data/rooms/00.txt @@ -11,15 +11,6 @@ exit-xp: 5 exit-xn: 1 exit-zn: 2 -actor{ - name: PLATFORM00 - bmp: test.gif - bmp-rect: 64 0 32 24 - bmp-offset: 0 24 - pos: 8 28 0 - size: 8 8 4 -} - actor{ name: PLATFORM02 bmp: test.gif @@ -29,6 +20,15 @@ actor{ size: 8 8 4 } +actor{ + name: PLATFORM00 + bmp: test.gif + bmp-rect: 64 0 32 24 + bmp-offset: 0 24 + pos: 8 28 0 + size: 8 8 4 +} + actor{ name: PLATFORM01 bmp: test.gif diff --git a/data/rooms/01.txt b/data/rooms/01.txt index 57dbd60..f0af2d3 100644 --- a/data/rooms/01.txt +++ b/data/rooms/01.txt @@ -43,6 +43,30 @@ actor{ movement: CW } +actor{ + name: TAULA01 + bmp: caixes.gif + bmp-rect: 128 32 32 32 + bmp-offset: 0 32 + pos: 8 24 0 + size: 8 8 8 + orient: YP + flags: ORIENTABLE + movement: CW +} + +actor{ + name: TAULA02 + bmp: caixes.gif + bmp-rect: 160 32 32 32 + bmp-offset: 0 32 + pos: 8 32 0 + size: 8 8 8 + orient: YP + flags: ORIENTABLE + movement: CW +} + actor{ name: ARMARI02 bmp: caixes.gif @@ -64,18 +88,6 @@ actor{ movement: CW } -actor{ - name: TAULA01 - bmp: caixes.gif - bmp-rect: 128 32 32 32 - bmp-offset: 0 32 - pos: 8 24 0 - size: 8 8 8 - orient: YP - flags: ORIENTABLE - movement: CW -} - actor{ name: NES bmp: caixes.gif @@ -87,18 +99,6 @@ actor{ movement: CW } -actor{ - name: TAULA02 - bmp: caixes.gif - bmp-rect: 160 32 32 32 - bmp-offset: 0 32 - pos: 8 32 0 - size: 8 8 8 - orient: YP - flags: ORIENTABLE - movement: CW -} - actor{ name: ROOMBA bmp: caixes.gif @@ -107,6 +107,6 @@ actor{ pos: 40 32 0 size: 8 8 4 orient: YP - flags: MOVING + flags: MOVING DEADLY movement: Y } diff --git a/data/rooms/06.txt b/data/rooms/06.txt index 0877039..6c4b35e 100644 --- a/data/rooms/06.txt +++ b/data/rooms/06.txt @@ -30,15 +30,23 @@ actor{ } actor{ - name: LIFT + name: NEVERA1 bmp: caixes.gif - bmp-rect: 32 32 32 24 - bmp-offset: 0 24 - pos: 56 0 0 - size: 8 8 4 - orient: ZP - flags: MOVING - movement: Z + bmp-rect: 0 96 32 32 + bmp-offset: 0 32 + pos: 32 32 0 + size: 8 8 8 + movement: CW +} + +actor{ + name: NEVERA2 + bmp: caixes.gif + bmp-rect: 32 96 32 32 + bmp-offset: 0 32 + pos: 32 32 8 + size: 8 8 8 + movement: CW } actor{ @@ -94,21 +102,13 @@ actor{ } actor{ - name: NEVERA1 + name: LIFT bmp: caixes.gif - bmp-rect: 0 96 32 32 - bmp-offset: 0 32 - pos: 32 32 0 - size: 8 8 8 - movement: CW -} - -actor{ - name: NEVERA2 - bmp: caixes.gif - bmp-rect: 32 96 32 32 - bmp-offset: 0 32 - pos: 32 32 8 - size: 8 8 8 - movement: CW + bmp-rect: 32 32 32 24 + bmp-offset: 0 24 + pos: 56 0 0 + size: 8 8 4 + orient: ZP + flags: MOVING + movement: Z } diff --git a/data/rooms/08.txt b/data/rooms/08.txt index c83fb44..7af22fe 100644 --- a/data/rooms/08.txt +++ b/data/rooms/08.txt @@ -44,6 +44,18 @@ actor{ movement: CW } +actor{ + name: EXPLOSION + bmp: caixes.gif + bmp-rect: 0 160 18 22 + bmp-offset: -7 38 + pos: 32 32 0 + size: 8 8 4 + anim-cycle: SEQ + flags: ANIMATED + movement: CW +} + actor{ name: P-FILTER bmp: objectes.gif @@ -68,6 +80,18 @@ actor{ movement: CW } +actor{ + name: BOX01 + bmp: caixes.gif + bmp-rect: 0 160 18 22 + bmp-offset: -7 38 + pos: 32 32 5 + size: 8 8 4 + anim-cycle: SEQ + flags: ANIMATED + movement: CW +} + actor{ name: P-TIMER bmp: objectes.gif diff --git a/data/rooms/09.txt b/data/rooms/09.txt index fc98b0b..7838e55 100644 --- a/data/rooms/09.txt +++ b/data/rooms/09.txt @@ -126,14 +126,16 @@ actor{ } actor{ - name: BOX - bmp: test.gif - bmp-rect: 32 0 32 32 - bmp-offset: 0 32 - pos: 32 32 0 + name: GAT + bmp: gat2.gif + bmp-rect: 0 0 24 28 + bmp-offset: -5 30 + pos: 40 32 0 size: 8 8 8 - flags: PUSHABLE INERTIA - movement: CW + orient: XP + anim-wait: 1 + flags: PUSHABLE MOVING ANIMATED ORIENTABLE INERTIA + movement: X } actor{ diff --git a/data/templates.txt b/data/templates.txt index 866636f..e42e576 100644 --- a/data/templates.txt +++ b/data/templates.txt @@ -197,3 +197,15 @@ actor{ size: 1 1 9 movement: CW } + +actor{ + name: EXPLOSION + bmp: caixes.gif + bmp-rect: 0 160 18 22 + bmp-offset: -7 24 + pos: 32 32 0 + size: 8 8 4 + anim-cycle: SEQ + flags: ANIMATED + movement: CW +} diff --git a/source/actor.cpp b/source/actor.cpp index c7bb200..3670da9 100644 --- a/source/actor.cpp +++ b/source/actor.cpp @@ -182,6 +182,24 @@ namespace actor return nullptr; } + actor_t *replaceWithTemplate(actor_t *act, const char *name) + { + if (!act) return nullptr; + actor_t *newactor = createFromTemplate(name); + newactor->pos.x = act->pos.x; + newactor->pos.y = act->pos.y; + newactor->pos.z = act->pos.z; + if (act->prev) act->prev->next = newactor; + if (act==first) first = newactor; + if (act==dirty) dirty = newactor; + if (act->next) act->next->prev = newactor; + newactor->prev = act->prev; + newactor->next = act->next; + act->prev = act->next = nullptr; + remove(act); + return newactor; + } + char tmp[255]; // Li donem al actor un nom únic @@ -440,23 +458,26 @@ namespace actor uint8_t result = 0; if ( (act->flags & FLAG_PUSHABLE) && ( !(source->flags&FLAG_HERO) || (hero::getSkills()&SKILL_GLOVES) ) ) act->push |= push; if ( (act->flags & FLAG_REACTIVE) && (act->react_mask & push) ) result = act->react_push; - if (act->flags & FLAG_DEADLY) result |= PUSH_KILL; + if (source->flags & FLAG_DEADLY) { + result |= PUSH_KILL; + } if (source->flags&FLAG_HERO) { if (act->flags & FLAG_SPECIAL) { - // [TODO 02/07/2024] Fer que faça un fumet o algo al desapareixer les coses if (act->name[0]=='B') { // Es un booster hero::collectBooster(act->name[1]-48, (act->name[3]-48)*10+(act->name[4]-48)); - actor::remove(act); } else if (act->name[0]=='S') { // Es un skill hero::giveSkill(&act->name[2]); - actor::remove(act); } else if ( (act->name[0]=='P') && (hero::getSkills()&SKILL_BAG) ) { // Es una part hero::pickPart(&act->name[2]); - actor::remove(act); + } else { + SDL_assert(false); } + act = actor::replaceWithTemplate(act, "EXPLOSION"); + act->name[0]='_'; + room::cycleColor(1); } } return result; @@ -694,8 +715,17 @@ namespace actor vec3_t min = room::getMin(); vec3_t max = room::getMax(); - //if ((act->flags&FLAG_HERO) && (act->pos.x>max.x || act->pos.xpos.y>max.y || act->pos.ypush & PUSH_KILL) && (act->flags & FLAG_HERO) ) { + actor_t *act = actor::find("HERO"); + act = actor::replaceWithTemplate(act, "EXPLOSION"); + actor_t *act2 = actor::createFromTemplate("EXPLOSION"); + act2->pos = act->pos; act2->pos.z += 8; act2->anim_frame=2; + act->anim_wait = act2->anim_wait = 1; + actor::setDirty(act2); + room::cycleColor(4); + return; + } + int vel = (act->flags&FLAG_HERO) && (hero::getBoostRun()>0) ? 2 : 1; if (act->push & PUSH_ZP) { @@ -708,6 +738,7 @@ namespace actor room::load(room::getExit(ZP)); act->pos.z = 4; actor::setDirty(act); + hero::setFirstPos(); room_changed = true; return; } @@ -728,6 +759,7 @@ namespace actor room::load(room::getExit(ZP)); now->pos.z = 4; actor::setDirty(now); + hero::setFirstPos(); room_changed = true; return; } @@ -748,7 +780,7 @@ namespace actor actor::actor_t *other = actor::get_collision(act); if (other || ( act->pos.xpos.y!=28) || (act->pos.z!=room::getDoor(XN)*4) || !(act->flags&FLAG_HERO) ) )) { - if (other) act->push |= push(act, other, PUSH_XN); + if (other) other->push |= push(act, other, PUSH_XN); act->pos.x+=vel; if (act->flags & FLAG_MOVING) changeMoving(act); if (act->flags & FLAG_INERTIA) act->push = PUSH_NONE; @@ -765,6 +797,7 @@ namespace actor room::load(room::getExit(XN)); act->pos.x = room::getMax().x-4; act->pos.z = room::getDoor(XP)*4; + hero::setFirstPos(); room_changed = true; } @@ -778,7 +811,7 @@ namespace actor actor::actor_t *other = actor::get_collision(act); if (other || ((act->pos.x+act->size.x)>max.x && ( !(room::getDoors()&DOOR_XP) || (act->pos.y!=28) || !(act->flags&FLAG_HERO) ) )) { - if (other) act->push |= push(act, other, PUSH_XP); + if (other) other->push |= push(act, other, PUSH_XP); act->pos.x-=vel; if (act->flags & FLAG_MOVING) changeMoving(act); if (act->flags & FLAG_INERTIA) act->push = PUSH_NONE; @@ -793,6 +826,7 @@ namespace actor room::load(room::getExit(XP)); act->pos.x = room::getMin().x-3; act->pos.z = room::getDoor(XN)*4; + hero::setFirstPos(); room_changed = true; } @@ -806,7 +840,7 @@ namespace actor actor::actor_t *other = actor::get_collision(act); if (other || ( act->pos.ypos.x!=28) || (act->pos.z!=room::getDoor(YN)*4) || !(act->flags&FLAG_HERO) ) )) { - if (other) act->push |= push(act, other, PUSH_YN); + if (other) other->push |= push(act, other, PUSH_YN); act->pos.y+=vel; if (act->flags & FLAG_MOVING) changeMoving(act); if (act->flags & FLAG_INERTIA) act->push = PUSH_NONE; @@ -821,6 +855,7 @@ namespace actor room::load(room::getExit(YN)); act->pos.y = room::getMax().y-4; act->pos.z = room::getDoor(YP)*4; + hero::setFirstPos(); room_changed = true; } @@ -834,7 +869,7 @@ namespace actor actor::actor_t *other = actor::get_collision(act); if (other || ( (act->pos.y+act->size.y)>max.y && ( !(room::getDoors()&DOOR_YP) || (act->pos.x!=28) || !(act->flags&FLAG_HERO) ) )) { - if (other) act->push |= push(act, other, PUSH_YP); + if (other) other->push |= push(act, other, PUSH_YP); act->pos.y-=vel; if (act->flags & FLAG_MOVING) changeMoving(act); if (act->flags & FLAG_INERTIA) act->push = PUSH_NONE; @@ -849,6 +884,7 @@ namespace actor room::load(room::getExit(YP)); act->pos.y = room::getMin().y-3; act->pos.z = room::getDoor(YN)*4; + hero::setFirstPos(); room_changed = true; } @@ -868,6 +904,7 @@ namespace actor room::load(room::getExit(ZN)); act->pos.z = room::getMax().z; actor::setDirty(act); + hero::setFirstPos(); room_changed = true; return; } @@ -878,7 +915,7 @@ namespace actor // ...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 - act->push |= push(act, act->below, PUSH_ZN); + act->below->push |= push(act, act->below, PUSH_ZN); act->push &= ~PUSH_ZN; if ( (act->flags & FLAG_MOVING) && (act->movement==MOV_Z) ) changeMoving(act); return; @@ -898,7 +935,7 @@ namespace actor act->below = below; below->above = act; // ... i li passem el push, netejem el meu flag i gonnem - act->push |= push(act, act->below, PUSH_ZN); + act->below->push |= push(act, act->below, PUSH_ZN); act->push &= ~PUSH_ZN; if ( (act->flags & FLAG_MOVING) && (act->movement==MOV_Z) ) changeMoving(act); return; @@ -913,9 +950,6 @@ namespace actor actor::setDirty(act); } - if ( (act->push & PUSH_KILL) && (act->flags & FLAG_HERO) ) { - //[TODO] Matar al ruiseñor - } /* if (act->push & PUSH_ZN) { act->pos.z--; @@ -942,7 +976,16 @@ namespace actor // 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) { - act->anim_frame=(act->anim_frame+1)%4; + act->anim_frame=act->anim_frame+1; + if (act->anim_frame==4) { + if (act->name[0]=='_') { + actor::remove(act); + return; + } else { + act->anim_frame=0; + } + } + if (act->anim_cycle==2 && act->anim_frame==3) act->anim_frame=0; act->anim_wait_count=0; } else { act->anim_wait_count++; @@ -1283,18 +1326,25 @@ namespace actor int skills = SKILL_NONE; int parts = PART_NONE; bool boosters_collected[100]; + vec3_t first_pos = {0,0,0}; - void init() + void init(const bool complete) { actor::actor_t *hero = actor::create("HERO", {16,32,8}, {8,8,12}, "test.gif", {0,32,20,32}, {-6,38}); hero->flags = FLAG_HERO | FLAG_PUSHABLE | FLAG_GRAVITY | FLAG_ORIENTABLE | FLAG_ANIMATED; actor::setDirty(hero, true); boost_jumps = boost_steps = boost_god = 0; - lives = 8; - skills = SKILL_NONE; - parts = PART_NONE; - for (int i=0; i<100; ++i) boosters_collected[i] = false; + + if (complete) + { + lives = 8; + skills = SKILL_NONE; + parts = PART_NONE; + for (int i=0; i<100; ++i) boosters_collected[i] = false; + } else { + hero->pos = first_pos; + } } int getLives() @@ -1469,5 +1519,11 @@ namespace actor if (z) hero->pos.z = *z; } + void setFirstPos() + { + actor_t *hero = actor::find("HERO"); + first_pos = hero->pos; + } + } } diff --git a/source/actor.h b/source/actor.h index 98fce30..e56f78f 100644 --- a/source/actor.h +++ b/source/actor.h @@ -126,6 +126,8 @@ namespace actor actor_t *createFromFile(char **buffer); + actor_t *replaceWithTemplate(actor_t *act, const char *name); + void setUniqueName(actor_t *act); void saveToFile(FILE *f, actor_t *act); @@ -175,7 +177,8 @@ namespace actor namespace hero { - void init(); + + void init(const bool complete=true); int getLives(); void setLives(int value); @@ -202,5 +205,6 @@ namespace actor int getParts(); void move(int *x, int *y, int *z); + void setFirstPos(); } } \ No newline at end of file diff --git a/source/m_game.cpp b/source/m_game.cpp index 4a6f104..868b43d 100644 --- a/source/m_game.cpp +++ b/source/m_game.cpp @@ -348,6 +348,8 @@ namespace modules actor::hero::dropSkill(val); else actor::hero::giveSkill(val); + + room::cycleColor(1); } } } diff --git a/source/room.cpp b/source/room.cpp index d46042d..c6a76e5 100644 --- a/source/room.cpp +++ b/source/room.cpp @@ -22,6 +22,8 @@ namespace room static int door_height[4]; // Altura de cada porta static int exits[6]; // Habitació destí a la que du cada porta (piso i sostre inclosos) static int color = 0; // Esquema de color de l'habitació + static int original_color = 0; + static int num_color_cycles =0; static int floor_type = 0; // Tile per al piso static int walls_type = 0; // Tile per a les pareds @@ -139,7 +141,8 @@ namespace room // Primer carreguem els valors per defecte inner_w = inner_h = 2; for (int i=0;i<4;++i) door_height[i] = -1; - color = 2; + color = original_color = 2; + num_color_cycles = 0; floor_type = walls_type = doors_type = walldoors_type = 0; for (int i=0;i<6;++i) exits[i] = -1; @@ -179,7 +182,7 @@ namespace room } else if (util::strcomp(key, "color:")) { color = util::stringToInt(file::readString(&buffer), {"purple", "green", "cyan", "yellow", "white"}, {0, 1, 2, 3, 4}); - + original_color = color; } else if (util::strcomp(key, "floor-texture:")) { floor_type = file::readInt(&buffer); } else if (util::strcomp(key, "wall-texture:")) { @@ -272,6 +275,20 @@ namespace room void draw() { + if (num_color_cycles > 0) + { + color++; + if (color>4) color = 0; + if (color==original_color) num_color_cycles--; + if (num_color_cycles==0) { + actor::actor_t * hero = actor::find("HERO"); + if (!hero) { + actor::hero::init(false); + load(current_room); + } + } + } + draw::pushSource(); draw::swapcol(1, color_schemes[color][0]); @@ -417,6 +434,11 @@ namespace room draw::popSource(); } + void cycleColor(int times) + { + num_color_cycles = times; + } + vec3_t getSize() { return size; diff --git a/source/room.h b/source/room.h index 334b215..c7c8000 100644 --- a/source/room.h +++ b/source/room.h @@ -23,6 +23,7 @@ namespace room void update(); void draw(); void draw2(); + void cycleColor(int times); vec3_t getSize(); vec3_t getMin();