Files
aee/source/game/mapa.cpp
T

303 lines
10 KiB
C++

#include "game/mapa.hpp"
#include <algorithm>
#include <cstdlib>
#include "core/jail/jgame.hpp"
#include "core/jail/jinput.hpp"
Mapa::Mapa(Jd8::Surface gfx, Prota* sam) {
this->gfx_ = gfx;
this->sam_ = sam;
this->preparaFondoEstatic();
this->preparaTombes();
this->ultim_vertex_.columna = 255;
this->frame_torxes_ = 0;
this->farao_ = false;
this->clau_ = false;
this->porta_oberta_ = false;
this->nova_momia_ = false;
}
Mapa::~Mapa() {
Jd8::freeSurface(this->fondo_);
}
void Mapa::draw() {
if (Info::ctx.num_piramide != 4) {
switch (sam_->o) {
case 0: // Down
Jd8::blitCKToSurface(sam_->x, sam_->y, this->gfx_, 15, 125 + sam_->frame_pejades, 15, 1, this->fondo_, 255);
break;
case 1: // Up
Jd8::blitCKToSurface(sam_->x, sam_->y + 15, this->gfx_, 0, 125 + (14 - sam_->frame_pejades), 15, 1, this->fondo_, 255);
break;
case 2: // Right
Jd8::blitCKToSurface(sam_->x + 7, sam_->y, this->gfx_, 30 + sam_->frame_pejades, 125, 1, 15, this->fondo_, 255);
break;
case 3: // Left
Jd8::blitCKToSurface(sam_->x + 8, sam_->y, this->gfx_, 45 + (14 - sam_->frame_pejades), 125, 1, 15, this->fondo_, 255);
break;
default:
break;
}
}
Jd8::blit(this->fondo_);
// Pinta tombes
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
Jd8::blitCK(35 + (x * 65), 45 + (y * 35), this->gfx_, this->tombes[x + (y * 4)].x, this->tombes[x + (y * 4)].y, 50, 20, 255);
}
}
Jd8::blitCK(45, 15, this->gfx_, 30 + (this->frame_torxes_ * 25), 80, 25, 15, 255);
Jd8::blitCK(95, 15, this->gfx_, 30 + (this->frame_torxes_ * 25), 80, 25, 15, 255);
Jd8::blitCK(195, 15, this->gfx_, 30 + (this->frame_torxes_ * 25), 80, 25, 15, 255);
Jd8::blitCK(245, 15, this->gfx_, 30 + (this->frame_torxes_ * 25), 80, 25, 15, 255);
};
void Mapa::update() {
if (((sam_->x - 20) % 65 == 0) && ((sam_->y - 30) % 35 == 0) && ((this->ultim_vertex_.columna != (sam_->x - 20) / 65) || (this->ultim_vertex_.fila != (sam_->y - 30) / 35))) {
this->vertex_.columna = (sam_->x - 20) / 65;
this->vertex_.fila = (sam_->y - 30) / 35;
if (this->ultim_vertex_.columna != 255) {
this->comprovaUltimCami();
}
this->ultim_vertex_ = this->vertex_;
}
if (this->porta_oberta_ && sam_->x == 150 && sam_->y == 30) {
if (Ji::keyPressed(SDL_SCANCODE_UP)) {
this->sam_->o = 4;
this->sam_->y -= 15;
}
}
if (Jg::getCycleCounter() % 8 == 0) {
this->frame_torxes_++;
this->frame_torxes_ = this->frame_torxes_ % 4;
}
}
auto Mapa::novaMomia() -> bool {
bool resultat = nova_momia_;
nova_momia_ = false;
return resultat;
}
void Mapa::preparaFondoEstatic() {
// Prepara el fondo esttic de l'habitaci
this->fondo_ = Jd8::newSurface();
if (Info::ctx.num_piramide == 6) {
Jd8::blitToSurface(9, 2, this->gfx_, 227, 185, 92, 7, this->fondo_); // Text "SECRETA"
} else {
Jd8::blitToSurface(9, 2, this->gfx_, 60, 185, 39, 7, this->fondo_); // Text "NIVELL"
Jd8::blitToSurface(72, 6, this->gfx_, 153, 189, 3, 1, this->fondo_); // Ralleta entre num piramide i num habitacio
}
Jd8::blitToSurface(130, 2, this->gfx_, 225, 192, 19, 8, this->fondo_); // Montonet de monedes + signe '='
Jd8::blitToSurface(220, 2, this->gfx_, 160, 185, 48, 7, this->fondo_); // Text "ENERGIA"
if (Info::ctx.diners >= 200) {
Jd8::blitToSurface(175, 3, this->gfx_, 60, 193, 7, 6, this->fondo_);
}
// Pinta taulells
for (int y = 0; y < 11; y++) {
for (int x = 0; x < 19; x++) {
switch (Info::ctx.num_piramide) {
case 1:
Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 0, 80, 15, 15, this->fondo_);
break;
case 2:
Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 25, 95, 15, 15, this->fondo_);
break;
case 3:
Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 40, 95, 15, 15, this->fondo_);
break;
case 4:
Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 175 + ((rand() % 3) * 15), 80, 15, 15, this->fondo_);
break;
case 5:
Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 130, 80, 15, 15, this->fondo_);
break;
case 6:
Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 145, 80, 15, 15, this->fondo_);
break;
default:
break;
}
}
}
// Pinta vores de les parets
Jd8::blitCKToSurface(5, 15, this->gfx_, 30, 110, 15, 15, this->fondo_, 255);
Jd8::blitCKToSurface(295, 15, this->gfx_, 45, 110, 15, 15, this->fondo_, 255);
Jd8::blitCKToSurface(5, 180, this->gfx_, 0, 155, 15, 20, this->fondo_, 255);
Jd8::blitCKToSurface(295, 180, this->gfx_, 15, 155, 15, 20, this->fondo_, 255);
// Pinta parets verticals
for (int i = 0; i < 10; i++) {
Jd8::blitToSurface(5, 30 + (i * 15), this->gfx_, 0, 110, 15, 15, this->fondo_);
Jd8::blitToSurface(295, 30 + (i * 15), this->gfx_, 15, 110, 15, 15, this->fondo_);
}
// Pinta parets hortzintals
for (int i = 0; i < 11; i++) {
Jd8::blitToSurface(20 + (i * 25), 185, this->gfx_, 0, 95, 25, 15, this->fondo_);
Jd8::blitToSurface(20 + (i * 25), 15, this->gfx_, 0, 95, 25, 15, this->fondo_);
}
// Pinta la porta
Jd8::blitCKToSurface(150, 18, this->gfx_, 0, 143, 15, 12, this->fondo_, 255);
if (Info::ctx.num_piramide == 2) {
Jd8::blitToSurface(5, 100, this->gfx_, 30, 140, 15, 15, this->fondo_);
}
}
void swap(Uint8& a, Uint8& b) noexcept {
Uint8 temp = a;
a = b;
b = temp;
}
void Mapa::preparaTombes() {
const Uint8 CONTINGUT = Info::ctx.num_piramide == 6 ? CONTE_DIAMANT : CONTE_RES;
int cx = Info::ctx.num_piramide == 6 ? 270 : 0;
int cy = Info::ctx.num_piramide == 6 ? 50 : 0;
for (auto& tombe : this->tombes) {
tombe.contingut = CONTINGUT;
tombe.oberta = false;
tombe.costat[0] = false;
tombe.costat[1] = false;
tombe.costat[2] = false;
tombe.costat[3] = false;
tombe.x = cx;
tombe.y = cy;
}
if (Info::ctx.num_piramide == 6) {
return;
}
this->tombes[0].contingut = CONTE_FARAO;
this->tombes[1].contingut = CONTE_CLAU;
this->tombes[2].contingut = CONTE_PERGAMI;
this->tombes[3].contingut = CONTE_MOMIA;
for (int i = 4; i < 8; i++) {
this->tombes[i].contingut = CONTE_RES;
}
for (int i = 8; i < 16; i++) {
this->tombes[i].contingut = CONTE_TRESOR;
}
for (int i = 0; i < 50; i++) {
swap(this->tombes[rand() % 16].contingut, this->tombes[rand() % 16].contingut);
}
}
auto minim(Uint8 a, Uint8 b) -> Uint8 {
return (a < b) ? a : b;
}
void Mapa::comprovaUltimCami() {
Uint8 col_aux = abs(this->vertex_.columna - this->ultim_vertex_.columna);
Uint8 fil_aux = abs(this->vertex_.fila - this->ultim_vertex_.fila);
if (col_aux > fil_aux) { // Cam horitzontal
Uint8 cami_fila = this->vertex_.fila;
Uint8 cami_columna = minim(this->vertex_.columna, this->ultim_vertex_.columna);
Sint8 caixa_avall = (cami_fila << 2) + cami_columna;
Sint8 caixa_amunt = caixa_avall - 4;
if (caixa_avall < 16) {
this->tombes[caixa_avall].costat[0] = true;
this->comprovaCaixa(caixa_avall);
}
if (caixa_amunt >= 0) {
this->tombes[caixa_amunt].costat[2] = true;
this->comprovaCaixa(caixa_amunt);
}
} else { // Cam vertical
Uint8 cami_columna = this->vertex_.columna;
Uint8 cami_fila = minim(this->vertex_.fila, this->ultim_vertex_.fila);
Sint8 caixa_dreta = (cami_fila << 2) + cami_columna;
Sint8 caixa_esquerra = caixa_dreta - 1;
if (caixa_dreta <= (cami_fila << 2) + 3) {
this->tombes[caixa_dreta].costat[3] = true;
this->comprovaCaixa(caixa_dreta);
}
if (caixa_esquerra >= (cami_fila << 2)) {
this->tombes[caixa_esquerra].costat[1] = true;
this->comprovaCaixa(caixa_esquerra);
}
}
}
void Mapa::comprovaCaixa(Uint8 num) {
// Si la tomba ja està oberta, no hi ha res que mirar
if (this->tombes[num].oberta) {
return;
}
// Si algun costat encara no està passat, no hi ha res que fer
if (std::any_of(std::begin(this->tombes[num].costat), std::end(this->tombes[num].costat), [](bool c) { return !c; })) {
return;
}
// Sinó, pos la acabem d'obrir
this->tombes[num].oberta = true;
// Comprobem el premi del kinder sorpresa
switch (this->tombes[num].contingut) {
case CONTE_RES:
this->tombes[num].x = 50;
break;
case CONTE_TRESOR:
this->tombes[num].x = 100;
Info::ctx.diners++;
break;
case CONTE_FARAO:
this->tombes[num].x = 150;
this->farao_ = true;
break;
case CONTE_CLAU:
this->tombes[num].x = 200;
this->clau_ = true;
break;
case CONTE_MOMIA:
this->tombes[num].y = 175;
this->nova_momia_ = true;
break;
case CONTE_PERGAMI:
this->tombes[num].x = 250;
this->sam_->pergami = true;
break;
case CONTE_DIAMANT:
this->tombes[num].y = 70;
Info::ctx.diamants++;
Info::ctx.diners += VALOR_DIAMANT;
if (Info::ctx.diamants == 16) {
this->farao_ = this->clau_ = true;
}
break;
default:
break;
}
this->comprovaPorta();
}
void Mapa::comprovaPorta() {
if (this->clau_ && this->farao_) {
Jd8::blitCKToSurface(150, 18, this->gfx_, 15, 143, 15, 12, this->fondo_, 255);
porta_oberta_ = true;
}
}