Compare commits

..

20 Commits
v1.05 ... v1.06

Author SHA1 Message Date
c955543d31 Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/jaildoctors_dilemma 2022-11-22 16:44:27 +01:00
fae8e2d82c Actualizado Makefile 2022-11-22 16:44:23 +01:00
ff7b825cbb Actualizar 'README.md' 2022-11-22 16:39:39 +01:00
09ed0105e9 Cambiada la ubicación del fichero config.txt a la carpeta de sistema 2022-11-22 16:26:58 +01:00
07ae93fd3a Actualizado Makefile 2022-11-22 14:11:17 +01:00
72fb30b927 Actualizado Makefile 2022-11-22 13:59:41 +01:00
8d37f31a08 Cambiada una frase de castellano a ingles en el fichero de estadisticas 2022-11-22 13:35:15 +01:00
e6fb412c4d Fix: La pantalla de Game Over no mostraba Tu peor pesadilla 2022-11-22 13:34:33 +01:00
10c29eb547 Actualizado Makefile 2022-11-22 13:20:13 +01:00
1f9e36dc93 Actualizado info.plist 2022-11-22 13:07:12 +01:00
c114884de1 FIx: El logo se formaba mal despues de haber toqueteado cosas de la clase Sprite 2022-11-22 13:05:34 +01:00
d6a366555d Actualizado Makefile 2022-11-22 12:53:56 +01:00
fd0d8a05fe Actualizado Makefile 2022-11-22 12:45:47 +01:00
79d610a7d9 Actualizado Makefile 2022-11-22 12:42:25 +01:00
9060e1c92a Añadida carpeta de sistema para el modo debug 2022-11-22 12:38:09 +01:00
0d586c0827 Ya funcionan las estadísticas online 2022-11-22 10:42:30 +01:00
fd0bebf533 Trabajando en las estadisticas online 2022-11-18 20:06:07 +01:00
2665b93b70 Añadida Tu peor pesadilla a la pantalla de Game Over 2022-11-18 16:07:33 +01:00
c35be7d21c Empezado a escribir datos de estadisticas en el servidor 2022-11-19 12:07:36 +01:00
bc84968b23 Ya funcionan las notificaciones 2022-11-19 10:28:15 +01:00
19 changed files with 471 additions and 157 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,5 @@
.vscode .vscode
*config.txt *data/config/config.txt
*stats.txt *stats.txt
*.DS_Store *.DS_Store
thumbs.db thumbs.db

View File

@@ -2,7 +2,7 @@ executable = jaildoctors_dilemma
source = source/*.cpp source/common/*.cpp source = source/*.cpp source/common/*.cpp
appName = JailDoctor's Dilemma appName = JailDoctor's Dilemma
releaseFolder = jdd_release releaseFolder = jdd_release
version = v1.05 version = v1.06
# Release names # Release names
windowsRelease = $(executable)-$(version)-win32-x64.zip windowsRelease = $(executable)-$(version)-win32-x64.zip
@@ -12,31 +12,30 @@ linuxRelease = $(executable)-$(version)-linux.tar.gz
windows: windows:
@echo off @echo off
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o $(executable).exe g++ $(source) -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o "$(executable).exe"
strip -s -R .comment -R .gnu.version $(executable).exe --strip-unneeded strip -s -R .comment -R .gnu.version "$(executable).exe" --strip-unneeded
windows_debug:
@echo off
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o "$(executable)_debug.exe"
strip -s -R .comment -R .gnu.version "$(executable)_debug.exe" --strip-unneeded
windows_release: windows_release:
@echo off @echo off
# Remove data # Create release folder
powershell if (Test-Path $(releaseFolder)) {Remove-Item $(releaseFolder) -Recurse -Force} powershell if (Test-Path "$(releaseFolder)") {Remove-Item "$(releaseFolder)" -Recurse -Force}
powershell if (-not (Test-Path "$(releaseFolder)")) {New-Item "$(releaseFolder)" -ItemType Directory}
# Create folders # Prepare data folder
powershell if (-not (Test-Path $(releaseFolder))) {New-Item $(releaseFolder) -ItemType Directory}
# Copy data
powershell Copy-Item -Path "data" -Destination "$(releaseFolder)" -recurse -Force powershell Copy-Item -Path "data" -Destination "$(releaseFolder)" -recurse -Force
powershell Copy-Item "LICENSE" -Destination "$(releaseFolder)"
powershell Copy-Item "README.md" -Destination "$(releaseFolder)"
powershell Copy-Item "release/SDL2.dll" -Destination "$(releaseFolder)"
# Remove data
powershell if (Test-Path "$(releaseFolder)\data\room\map.world") {Remove-Item "$(releaseFolder)\data\room\map.world" -Recurse -Force} powershell if (Test-Path "$(releaseFolder)\data\room\map.world") {Remove-Item "$(releaseFolder)\data\room\map.world" -Recurse -Force}
powershell if (Test-Path "$(releaseFolder)\data\room\standard.tsx") {Remove-Item "$(releaseFolder)\data\room\standard.tsx" -Recurse -Force} powershell if (Test-Path "$(releaseFolder)\data\room\standard.tsx") {Remove-Item "$(releaseFolder)\data\room\standard.tsx" -Recurse -Force}
powershell if (Test-Path "$(releaseFolder)\data\config") {Remove-Item "$(releaseFolder)\data\config" -Recurse -Force}
# Copy root files
# Create data powershell Copy-Item "LICENSE" -Destination "$(releaseFolder)"
powershell if (-not (Test-Path "$(releaseFolder)\data\config")) {New-Item "$(releaseFolder)\data\config" -ItemType Directory} powershell Copy-Item "README.md" -Destination "$(releaseFolder)"
powershell Copy-Item "release\SDL2.dll" -Destination "$(releaseFolder)"
# Build # Build
g++ $(source) -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o "$(releaseFolder)/$(executable).exe" g++ $(source) -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o "$(releaseFolder)/$(executable).exe"
@@ -47,13 +46,16 @@ windows_release:
powershell Compress-Archive -Path "$(releaseFolder)"/* -DestinationPath $(windowsRelease) powershell Compress-Archive -Path "$(releaseFolder)"/* -DestinationPath $(windowsRelease)
# Remove folder # Remove folder
powershell if (Test-Path $(releaseFolder)) {Remove-Item $(releaseFolder) -Recurse -Force} powershell if (Test-Path "$(releaseFolder)") {Remove-Item "$(releaseFolder)" -Recurse -Force}
macos: macos:
clang++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -o $(executable)_macos clang++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -o "$(executable)"
macos_debug:
clang++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -o "$(executable)_debug"
macos_release: macos_release:
# Remove data and possible data # Remove data and possible data from previous builds
rm -rdf "$(releaseFolder)" rm -rdf "$(releaseFolder)"
rm -rdf Frameworks rm -rdf Frameworks
rm -f tmp.dmg rm -f tmp.dmg
@@ -74,10 +76,6 @@ macos_release:
# Delete data # Delete data
rm -f "$(releaseFolder)/$(appName).app/Contents/Resources/data/room/map.world" rm -f "$(releaseFolder)/$(appName).app/Contents/Resources/data/room/map.world"
rm -f "$(releaseFolder)/$(appName).app/Contents/Resources/data/room/standard.tsx" rm -f "$(releaseFolder)/$(appName).app/Contents/Resources/data/room/standard.tsx"
rm -rdf "$(releaseFolder)/$(appName).app/Contents/Resources/data/config"
# Create folders
mkdir -p "$(releaseFolder)/$(appName).app/Contents/Resources/data/config"
# Copy files # Copy files
cp release/*.icns "$(releaseFolder)/$(appName).app/Contents/Resources" cp release/*.icns "$(releaseFolder)/$(appName).app/Contents/Resources"
@@ -106,36 +104,36 @@ macos_release:
rm -rdf "$(releaseFolder)" rm -rdf "$(releaseFolder)"
linux: linux:
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o $(executable)_linux g++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o "$(executable)"
strip -s -R .comment -R .gnu.version $(executable)_linux --strip-unneeded strip -s -R .comment -R .gnu.version "$(executable)" --strip-unneeded
linux_debug:
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o "$(executable)_debug"
strip -s -R .comment -R .gnu.version "$(executable)_debug" --strip-unneeded
linux_release: linux_release:
# Remove data # Remove data
rm -rdf $(releaseFolder) rm -rdf "$(releaseFolder)"
# Create folders # Create folders
mkdir -p $(releaseFolder) mkdir -p "$(releaseFolder)"
# Copy data # Copy data
cp -R data $(releaseFolder) cp -R data "$(releaseFolder)"
cp LICENSE $(releaseFolder) cp LICENSE "$(releaseFolder)"
cp README.md $(releaseFolder) cp README.md "$(releaseFolder)"
# Delete data # Delete data
rm -f "$(releaseFolder)/data/room/map.world" rm -f "$(releaseFolder)/data/room/map.world"
rm -f "$(releaseFolder)/data/room/standard.tsx" rm -f "$(releaseFolder)/data/room/standard.tsx"
rm -rdf "$(releaseFolder)/data/config"
# Create folders
mkdir -p "$(releaseFolder)/data/config"
# Build # Build
g++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o $(releaseFolder)/$(executable) g++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o "$(releaseFolder)/$(executable)"
strip -s -R .comment -R .gnu.version $(releaseFolder)/$(executable) --strip-unneeded strip -s -R .comment -R .gnu.version "$(releaseFolder)/$(executable)" --strip-unneeded
# Pack files # Pack files
rm -f $(linuxRelease) rm -f "$(linuxRelease)"
cd $(releaseFolder) && tar -czvf ../$(linuxRelease) * cd "$(releaseFolder)" && tar -czvf "../$(linuxRelease)" *
# Remove data # Remove data
rm -rdf $(releaseFolder) rm -rdf "$(releaseFolder)"

View File

@@ -1,37 +1,85 @@
# JailDoctor's Dilemma # JailDoctor's Dilemma
JailDoc es un Jailer. A los Jailers les gusta empezar proyectos. A nadie le gusta terminarlos. Los Jailers viven en la Jail. A la Jail va uno a empezar proyectos. A la Jail va uno a enseñar sus proyectos. A la Jail va uno a aprender como empezar nuevos proyectos. A la Jail va uno a ayudar a sus compañeros a que empiecen nuevos proyectos. JailDoc es un Jailer. A los Jailers les gusta empezar proyectos. A nadie le gusta terminarlos. Los Jailers viven en la Jail. A la Jail va uno a empezar proyectos. A la Jail va uno a enseñar sus proyectos. A la Jail va uno a aprender como empezar nuevos proyectos. A la Jail va uno a ayudar a sus compañeros a que empiecen nuevos proyectos.
![JailDoctor's Dilemma - Title screen](https://php.sustancia.synology.me/images/jdd_title.png) ![JailDoctor's Dilemma - Title screen](https://php.sustancia.synology.me/images/jdd_title.png)
JailDoc es un Jailer destacado entre los Jailers. Tiene más proyectos empezados que nadie y es el que más ayuda a que los demas empiecen los suyos. JailDoc es un Jailer destacado entre los Jailers. Tiene más proyectos empezados que nadie y es el que más ayuda a que los demas empiecen los suyos.
Un día, ocurrió algo. Alguien terminó un proyecto. Alguien liberó el *Puzzle Jail Facker*. Algún desaprensivo. Un día, ocurrió algo. Alguien terminó un proyecto. Alguien liberó el *Puzzle Jail Facker*. Algún desaprensivo.
Esto hizo que JailDoc decidiera terminar y entregar uno de sus proyectos, pero, ¿cual? ¿JailBattle? ¿Sigmasuá? ¿Calculín Doom? Menudo dilema. JailDoc se arremangó y decidió finalizar y entregar todos sus proyectos inacabados. ¿Lo logrará? Esto hizo que JailDoc decidiera terminar y entregar uno de sus proyectos, pero, ¿cual? ¿JailBattle? ¿Sigmasuá? ¿Calculín Doom? Menudo dilema. JailDoc se arremangó y decidió finalizar y entregar todos sus proyectos inacabados. ¿Lo logrará?
## Jugabilidad ## Jugabilidad
Ayuda a JailDoc a recuperar las partes de su proyecto que estan desperdigadas por cualquier lugar del Universo Jailer. Hay mas de **150 piezas** desperdigadas por **60 pantallas**. Algunas son un paseo, pero en otras tendras que calcular muy bien tus movimientos si no quieres acabar como un arounder del montón. Ayuda a JailDoc a recuperar las partes de su proyecto que estan desperdigadas por cualquier lugar del Universo Jailer. Hay mas de **150 piezas** desperdigadas por **60 pantallas**. Algunas son un paseo, pero en otras tendras que calcular muy bien tus movimientos si no quieres acabar como un arounder del montón.
![JailDoctor's Dilemma - Gameplay](https://php.sustancia.synology.me/images/jdd_game1.png) ![JailDoctor's Dilemma - Gameplay](https://php.sustancia.synology.me/images/jdd_game1.png)
Cuando consigas recuperar gran parte de las piezas desperdigadas, dirigete a la Jail a mostrar a los Jailers como se termina un proyecto. Ten en cuenta que Bry no te dejará entrar. Solo aquellos que han realizado un *Fire Effect* o un *Facedor de Tornejos* son dignos de tal privilegio. Cuando consigas recuperar gran parte de las piezas desperdigadas, dirigete a la Jail a mostrar a los Jailers como se termina un proyecto. Ten en cuenta que Bry no te dejará entrar. Solo aquellos que han realizado un *Fire Effect* o un *Facedor de Tornejos* son dignos de tal privilegio.
## Controles ## Controles
El juego permite tanto el uso del teclado como de un mando de control. Las teclas para manejar el juego son las siguientes: El juego permite tanto el uso del teclado como de un mando de control. Las teclas para manejar el juego son las siguientes:
- **Cursores**: Para mover a izquierda o derecha a JailDoc y para saltar
- **Tecla M**: Activa o desactiva la música
- **Tecla P**: Pone en pausa el juego - **Cursores**: Para mover a izquierda o derecha a JailDoc y para saltar
- **Tecla ESC**: Sale del juego si estas jugando. Sale del programa en cualquier otra circunstancia
- **Tecla F**: Cambia a modo de pantalla completa o de ventana - **Tecla M**: Activa o desactiva la música
- **Teclas F1 a F4**: Cambian el tamaño de la ventana
- **Tecla B**: Activa o desactiva el borde de colores de la pantalla cuando el programa se ejecuta en modo de ventana - **Tecla P**: Pone en pausa el juego
- **Tecla ESC**: Sale del juego si estas jugando. Sale del programa en cualquier otra circunstancia
- **Tecla F**: Cambia a modo de pantalla completa o de ventana
- **Teclas F1 a F4**: Cambian el tamaño de la ventana
- **Tecla B**: Activa o desactiva el borde de colores de la pantalla cuando el programa se ejecuta en modo de ventana
![JailDoctor's Dilemma - Gameplay](https://php.sustancia.synology.me/images/jdd_game2.png) ![JailDoctor's Dilemma - Gameplay](https://php.sustancia.synology.me/images/jdd_game2.png)
## Datos del programa
El programa guarda automáticamente la configuración del modo de video y las estadísticas de juego en tu carpeta personal del sistema. Esta carpeta tiene una ubicación distinta en función del sistema operativo que utilices.
En **Windows** se encuentra en:
`C:\Users\<nombre_de_usuario>\AppData\Roaming\jaildoctors_dilemma`
En **MacOS** se encuentra en:
`~/Library/Application Support/jaildoctors_dilemma`
En **Linux** se encuentra en:
`~/.jaildoctors_dilemma`
En la carpeta está el fichero de configuración `config.txt` donde se puede modificar la configuración para conectarse al servicio online y los ficheros `stats.csv` y `stats_buffer.csv` con información de las estadisticas de juego.
## Agradecimientos ## Agradecimientos
Agradecimientos como siempre a todos los Jailers por motivarme a hacer el juego y ayudarme en los momentos de duda a la hora de escribir el código. Y, como siempre, en especial a JailDoc por su unidad de Jail_Audio y cualquier otro código/ayuda/enseñanzas que haya necesitado para terminar el programa. Agradecimientos como siempre a todos los Jailers por motivarme a hacer el juego y ayudarme en los momentos de duda a la hora de escribir el código. Y, como siempre, en especial a JailDoc por su unidad de Jail_Audio y cualquier otro código/ayuda/enseñanzas que haya necesitado para terminar el programa.
Si no me he descontado, este es el cuarto juego que consigo crear. Si no me he descontado, este es el cuarto juego que consigo crear.
*13 de noviembre de 2022, JailDesigner* *13 de noviembre de 2022, JailDesigner*

View File

@@ -27,7 +27,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0.0</string> <string>1.0.6</string>
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>
<true/> <true/>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View File

@@ -136,18 +136,13 @@ void Notify::showText(std::string text)
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
n.texture->setBlendMode(SDL_BLENDMODE_BLEND); n.texture->setBlendMode(SDL_BLENDMODE_BLEND);
this->text->writeDX(TXT_CENTER | TXT_STROKE, width / 2, despV, text, 1, {255, 255, 255}, 1, {0, 0, 0}); this->text->writeDX(TXT_CENTER | TXT_STROKE, width / 2, despV, text, 1, {255, 255, 255}, 1, {0, 0, 0});
SDL_SetRenderTarget(renderer, nullptr);
// Crea el sprite // Crea el sprite
n.sprite = new Sprite(n.rect, n.texture, renderer); n.sprite = new Sprite(n.rect, n.texture, renderer);
// Añade la notificación a la lista // Añade la notificación a la lista
notifications.push_back(n); notifications.push_back(n);
//std::cout << "Notification " << notifications.size() << std::endl;
//std::cout << "width " << width << std::endl;
//std::cout << "height " << height << std::endl;
//std::cout << "offset " << offset << std::endl;
//std::cout << "desp " << despH << std::endl;
} }
// Indica si hay notificaciones activas // Indica si hay notificaciones activas
@@ -157,6 +152,6 @@ bool Notify::active()
{ {
return true; return true;
} }
return false; return false;
} }

View File

@@ -356,12 +356,12 @@ void Screen::showText(std::string text)
// Dibuja las notificaciones // Dibuja las notificaciones
void Screen::renderNotifications() void Screen::renderNotifications()
{ {
//if (!notifyActive) if (!notifyActive)
//{ {
// return; return;
//} }
//SDL_RenderSetLogicalSize(renderer, windowWidth * options->windowSize, windowHeight * options->windowSize); SDL_RenderSetLogicalSize(renderer, windowWidth * 2, windowHeight * 2);
notify->render(); notify->render();
//SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight); SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight);
} }

View File

@@ -18,7 +18,7 @@ Sprite::Sprite(int x, int y, int w, int h, Texture *texture, SDL_Renderer *rende
this->texture = texture; this->texture = texture;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
spriteClip = {x, y, w, h}; spriteClip = {0, 0, w, h};
// Inicializa variables // Inicializa variables
enabled = true; enabled = true;
@@ -41,7 +41,7 @@ Sprite::Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer)
this->texture = texture; this->texture = texture;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
spriteClip = {x, y, w, h}; spriteClip = {0, 0, w, h};
// Inicializa variables // Inicializa variables
enabled = true; enabled = true;
@@ -83,8 +83,8 @@ int Sprite::getHeight()
// Establece la posición del objeto // Establece la posición del objeto
void Sprite::setPos(SDL_Rect rect) void Sprite::setPos(SDL_Rect rect)
{ {
x = rect.x; this->x = rect.x;
y = rect.y; this->y = rect.y;
} }
// Establece el valor de la variable // Establece el valor de la variable
@@ -166,6 +166,12 @@ void Sprite::setRenderer(SDL_Renderer *renderer)
this->renderer = renderer; this->renderer = renderer;
} }
// Obten el valor de la variable
SDL_Renderer *Sprite::getRenderer()
{
return renderer;
}
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setEnabled(bool value) void Sprite::setEnabled(bool value)
{ {

View File

@@ -81,6 +81,9 @@ public:
// Establece el valor de la variable // Establece el valor de la variable
void setRenderer(SDL_Renderer *renderer); void setRenderer(SDL_Renderer *renderer);
// Obten el valor de la variable
SDL_Renderer *getRenderer();
// Establece el valor de la variable // Establece el valor de la variable
void setEnabled(bool value); void setEnabled(bool value);

View File

@@ -81,6 +81,14 @@ struct online_t
int score; // Puntuación almacenada online int score; // Puntuación almacenada online
}; };
// Estructura para almacenar estadísticas
struct op_stats_t
{
int rooms; // Cantidad de habitaciones visitadas
int items; // Cantidad de items obtenidos
std::string worstNightmare; // Habitación con más muertes acumuladas
};
// Estructura con todas las opciones de configuración del programa // Estructura con todas las opciones de configuración del programa
struct options_t struct options_t
{ {
@@ -97,8 +105,7 @@ struct options_t
palette_e palette; // Paleta de colores a usar en el juego palette_e palette; // Paleta de colores a usar en el juego
bool console; // Indica si ha de mostrar información por la consola de texto bool console; // Indica si ha de mostrar información por la consola de texto
cheat_t cheat; // Contiene trucos y ventajas para el juego cheat_t cheat; // Contiene trucos y ventajas para el juego
int rooms; // Cantidad de habitaciones visitadas op_stats_t stats; // Datos con las estadisticas de juego
int items; // Cantidad de items obtenidos
online_t online; // Datos del servicio online online_t online; // Datos del servicio online
}; };

View File

@@ -18,11 +18,11 @@ Director::Director(int argc, char *argv[])
section.subsection = SUBSECTION_LOGO_TO_INTRO; section.subsection = SUBSECTION_LOGO_TO_INTRO;
#ifdef DEBUG #ifdef DEBUG
section.name = SECTION_PROG_GAME; section.name = SECTION_PROG_LOGO;
#endif #endif
// Crea e inicializa las opciones del programa // Crea e inicializa las opciones del programa
iniOptions(); initOptions();
// Comprueba los parametros del programa // Comprueba los parametros del programa
checkProgramArguments(argc, argv); checkProgramArguments(argc, argv);
@@ -59,7 +59,7 @@ Director::Director(int argc, char *argv[])
music = JA_LoadMusic(asset->get("title.ogg").c_str()); music = JA_LoadMusic(asset->get("title.ogg").c_str());
// Inicializa los servicios online // Inicializa los servicios online
//initOnline(); initOnline();
} }
Director::~Director() Director::~Director()
@@ -116,23 +116,11 @@ void Director::initOnline()
return; return;
} }
// Obten las estadisticas online
const int points = jscore::getUserPoints(options->online.gameID, options->online.jailerID);
if (points == 0)
{ // Fallo de conexión o no hay registros
screen->showText("No se ha podido obtener la puntuacion online");
std::cout << "No se ha podido obtener la puntuacion online" << std::endl;
}
else
{
options->online.score = points;
}
} }
} }
// Crea e inicializa las opciones del programa // Crea e inicializa las opciones del programa
void Director::iniOptions() void Director::initOptions()
{ {
// Crea el puntero a la estructura de opciones // Crea el puntero a la estructura de opciones
options = new options_t; options = new options_t;
@@ -156,14 +144,18 @@ void Director::iniOptions()
options->cheat.invincible = false; options->cheat.invincible = false;
options->cheat.jailEnabled = false; options->cheat.jailEnabled = false;
options->cheat.altSkin = false; options->cheat.altSkin = false;
options->rooms = 0; options->stats.rooms = 0;
options->items = 0; options->stats.items = 0;
// Online // Online
options->online.enabled = false; options->online.enabled = false;
options->online.server = ""; options->online.server = "jaildoctor.duckdns.org";
options->online.port = 0; options->online.port = 9911;
#ifdef DEBUG
options->online.gameID = "jaildoctors_dilemma_test"; options->online.gameID = "jaildoctors_dilemma_test";
#else
options->online.gameID = "jaildoctors_dilemma";
#endif
options->online.jailerID = ""; options->online.jailerID = "";
} }
@@ -359,16 +351,22 @@ bool Director::saveConfig()
// Crea la carpeta del sistema donde guardar datos // Crea la carpeta del sistema donde guardar datos
void Director::createSystemFolder() void Director::createSystemFolder()
{ {
#ifdef DEBUG
const std::string folderName = "jaildoctors_dilemma_debug";
#else
const std::string folderName = "jaildoctors_dilemma";
#endif
#ifdef _WIN32 #ifdef _WIN32
systemFolder = std::string(getenv("APPDATA")) + "/jaildoctors_dilemma"; systemFolder = std::string(getenv("APPDATA")) + "/" + folderName;
#elif __APPLE__ #elif __APPLE__
struct passwd *pw = getpwuid(getuid()); struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir; const char *homedir = pw->pw_dir;
systemFolder = std::string(homedir) + "/Library/Application Support/jaildoctors_dilemma"; systemFolder = std::string(homedir) + "/Library/Application Support/" + folderName;
#elif __linux__ #elif __linux__
struct passwd *pw = getpwuid(getuid()); struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir; const char *homedir = pw->pw_dir;
systemFolder = std::string(homedir) + "/.jaildoctors_dilemma"; systemFolder = std::string(homedir) + "/." + folderName;
#endif #endif
struct stat st = {0}; struct stat st = {0};
@@ -388,12 +386,15 @@ void Director::createSystemFolder()
case EACCES: case EACCES:
printf("the parent directory does not allow write"); printf("the parent directory does not allow write");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
case EEXIST: case EEXIST:
printf("pathname already exists"); printf("pathname already exists");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
case ENAMETOOLONG: case ENAMETOOLONG:
printf("pathname is too long"); printf("pathname is too long");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
default: default:
perror("mkdir"); perror("mkdir");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@@ -1224,9 +1225,12 @@ bool Director::setFileList()
asset->add(prefix + "/data/font/debug.png", t_font); asset->add(prefix + "/data/font/debug.png", t_font);
asset->add(prefix + "/data/font/debug.txt", t_font); asset->add(prefix + "/data/font/debug.txt", t_font);
// Configuración // Datos
asset->add(prefix + "/data/input/gamecontrollerdb.txt", t_data); asset->add(prefix + "/data/input/gamecontrollerdb.txt", t_data);
asset->add(prefix + "/data/config/config.txt", t_data, false);
// Ficheros de sistema
asset->add(systemFolder + "/config.txt", t_data, false, true);
asset->add(systemFolder + "/stats_buffer.csv", t_data, false, true);
asset->add(systemFolder + "/stats.csv", t_data, false, true); asset->add(systemFolder + "/stats.csv", t_data, false, true);
// Habitaciones // Habitaciones

View File

@@ -51,12 +51,12 @@ private:
section_t section; // Sección y subsección actual del programa; section_t section; // Sección y subsección actual del programa;
std::string systemFolder; // Carpeta del sistema donde guardar datos std::string systemFolder; // Carpeta del sistema donde guardar datos
// Crea e inicializa las opciones del programa
void initOptions();
// Inicializa los servicios online // Inicializa los servicios online
void initOnline(); void initOnline();
// Crea e inicializa las opciones del programa
void iniOptions();
// Comprueba los parametros del programa // Comprueba los parametros del programa
void checkProgramArguments(int argc, char *argv[]); void checkProgramArguments(int argc, char *argv[]);

View File

@@ -21,9 +21,9 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
this->options = options; this->options = options;
#ifdef DEBUG #ifdef DEBUG
currentRoom = "02.room"; currentRoom = "01.room";
const int x1 = 20; const int x1 = 25;
const int y1 = 6; const int y1 = 13;
spawnPoint = {x1 * 8, y1 * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL}; spawnPoint = {x1 * 8, y1 * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
#endif #endif
@@ -40,13 +40,15 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer); text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer);
music = JA_LoadMusic(asset->get("game.ogg").c_str()); music = JA_LoadMusic(asset->get("game.ogg").c_str());
deathSound = JA_LoadSound(asset->get("death.wav").c_str()); deathSound = JA_LoadSound(asset->get("death.wav").c_str());
stats = new Stats(asset->get("stats.csv")); stats = new Stats(asset->get("stats.csv"), asset->get("stats_buffer.csv"), options);
stats->addVisit(room->getName());
// Inicializa el resto de variables // Inicializa el resto de variables
ticks = 0; ticks = 0;
ticksSpeed = 15; ticksSpeed = 15;
board.lives = 9; board.lives = 9;
#ifdef DEBUG
board.lives = 0;
#endif
board.items = 0; board.items = 0;
board.rooms = 1; board.rooms = 1;
board.music = true; board.music = true;
@@ -57,6 +59,8 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
blackScreen = false; blackScreen = false;
blackScreenCounter = 0; blackScreenCounter = 0;
totalItems = getTotalItems(); totalItems = getTotalItems();
initStats();
stats->addVisit(room->getName());
section.name = SECTION_PROG_GAME; section.name = SECTION_PROG_GAME;
section.subsection = 0; section.subsection = 0;
@@ -348,7 +352,7 @@ bool Game::changeRoom(std::string file)
{ {
// Incrementa el contador de habitaciones visitadas // Incrementa el contador de habitaciones visitadas
board.rooms++; board.rooms++;
options->rooms = board.rooms; options->stats.rooms = board.rooms;
// Actualiza las estadisticas // Actualiza las estadisticas
stats->addVisit(room->getName()); stats->addVisit(room->getName());
@@ -619,4 +623,18 @@ void Game::checkRestoringJail()
board.lives++; board.lives++;
JA_PlaySound(deathSound); JA_PlaySound(deathSound);
} }
}
// Inicializa el diccionario de las estadísticas
void Game::initStats()
{
std::vector<res_room_t> *rooms = new std::vector<res_room_t>;
rooms = resource->getAllRooms();
for (auto room : *rooms)
{
stats->addDictionary(room.room->number, room.room->name);
}
stats->init();
} }

View File

@@ -130,6 +130,9 @@ private:
// Da vidas al jugador cuando está en la Jail // Da vidas al jugador cuando está en la Jail
void checkRestoringJail(); void checkRestoringJail();
// Inicializa el diccionario de las estadísticas
void initStats();
public: public:
// Constructor // Constructor
Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Input *input, Debug *debug); Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Input *input, Debug *debug);

View File

@@ -28,9 +28,9 @@ GameOver::GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, A
iniFade = 310; iniFade = 310;
fadeLenght = 20; fadeLenght = 20;
playerSprite->setPosX(GAMECANVAS_CENTER_X + 10); playerSprite->setPosX(GAMECANVAS_CENTER_X + 10);
playerSprite->setPosY(GAMECANVAS_CENTER_Y - 10); playerSprite->setPosY(30);
tvSprite->setPosX(GAMECANVAS_CENTER_X - tvSprite->getAnimationClip(0, 0).w - 10); tvSprite->setPosX(GAMECANVAS_CENTER_X - tvSprite->getAnimationClip(0, 0).w - 10);
tvSprite->setPosY(GAMECANVAS_CENTER_Y - 10); tvSprite->setPosY(30);
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
@@ -82,6 +82,8 @@ void GameOver::update()
// Dibuja el final en pantalla // Dibuja el final en pantalla
void GameOver::render() void GameOver::render()
{ {
const int y = 32;
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen->start(); screen->start();
@@ -89,16 +91,22 @@ void GameOver::render()
screen->clean(); screen->clean();
// Escribe el texto de GAME OVER // Escribe el texto de GAME OVER
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, GAMECANVAS_CENTER_Y - 40, "G A M E O V E R", 1, color); text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y, "G A M E O V E R", 1, color);
// Dibuja los sprites // Dibuja los sprites
playerSprite->setPosY(y + 30);
tvSprite->setPosY(y + 30);
renderSprites(); renderSprites();
// Escribe el texto con las habitaciones y los items // Escribe el texto con las habitaciones y los items
const std::string itemsTxt = std::to_string(options->items / 100) + std::to_string((options->items % 100) / 10) + std::to_string(options->items % 10); const std::string itemsTxt = std::to_string(options->stats.items / 100) + std::to_string((options->stats.items % 100) / 10) + std::to_string(options->stats.items % 10);
const std::string roomsTxt = std::to_string(options->rooms / 100) + std::to_string((options->rooms % 100) / 10) + std::to_string(options->rooms % 10); const std::string roomsTxt = std::to_string(options->stats.rooms / 100) + std::to_string((options->stats.rooms % 100) / 10) + std::to_string(options->stats.rooms % 10);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, GAMECANVAS_CENTER_Y + 40, "ITEMS: " + itemsTxt, 1, color); text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 80, "ITEMS: " + itemsTxt, 1, color);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, GAMECANVAS_CENTER_Y + 55, "ROOMS: " + roomsTxt, 1, color); text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 90, "ROOMS: " + roomsTxt, 1, color);
// Escribe el texto con "Tu peor pesadilla"
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 110, "YOUR WORST NIGHTMARE IS", 1, color);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 120, options->stats.worstNightmare, 1, color);
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->blit(); screen->blit();

View File

@@ -19,9 +19,11 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
sprite2->setSpriteClip(0, 0, texture2->getWidth(), texture2->getHeight()); sprite2->setSpriteClip(0, 0, texture2->getWidth(), texture2->getHeight());
texture2->setColor(0, 0, 0); texture2->setColor(0, 0, 0);
// Crea los sprites de cada linea
for (int i = 0; i < texture->getHeight(); ++i) for (int i = 0; i < texture->getHeight(); ++i)
{ {
sprite.push_back(new Sprite(0, i, texture->getWidth(), 1, texture, renderer)); sprite.push_back(new Sprite(0, i, texture->getWidth(), 1, texture, renderer));
sprite.back()->setSpriteClip(0, i, texture->getWidth(), 1);
if (i % 2 == 0) if (i % 2 == 0)
{ {
sprite.at(i)->setPosX(256 + (i * 3)); sprite.at(i)->setPosX(256 + (i * 3));

View File

@@ -63,7 +63,9 @@ room_t loadRoomFile(std::string file_path, bool verbose)
room.itemColor2 = "magenta"; room.itemColor2 = "magenta";
room.autoSurfaceDirection = 1; room.autoSurfaceDirection = 1;
const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1); const std::string fileName = file_path.substr(file_path.find_last_of("\\/") + 1);
room.number = fileName.substr(0, fileName.find_last_of("."));
std::string line; std::string line;
std::ifstream file(file_path); std::ifstream file(file_path);
@@ -94,7 +96,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
{ {
if (verbose) if (verbose)
{ {
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; std::cout << "Warning: file " << fileName.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
} }
} }
} while (line != "[/enemy]"); } while (line != "[/enemy]");
@@ -123,7 +125,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
{ {
if (verbose) if (verbose)
{ {
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; std::cout << "Warning: file " << fileName.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
} }
} }
@@ -143,7 +145,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
{ {
if (verbose) if (verbose)
{ {
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; std::cout << "Warning: file " << fileName.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
} }
} }
} }
@@ -152,7 +154,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
// Cierra el fichero // Cierra el fichero
if (verbose) if (verbose)
{ {
std::cout << "Room loaded: " << filename.c_str() << std::endl; std::cout << "Room loaded: " << fileName.c_str() << std::endl;
} }
file.close(); file.close();
} }
@@ -160,7 +162,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
else else
{ {
{ {
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl; std::cout << "Warning: Unable to open " << fileName.c_str() << " file" << std::endl;
} }
} }
@@ -400,6 +402,7 @@ Room::Room(room_t *room, SDL_Renderer *renderer, Screen *screen, Asset *asset, o
this->debug = debug; this->debug = debug;
this->options = options; this->options = options;
number = room->number;
name = room->name; name = room->name;
bgColor = room->bgColor; bgColor = room->bgColor;
borderColor = room->borderColor; borderColor = room->borderColor;
@@ -824,7 +827,7 @@ bool Room::itemCollision(SDL_Rect &rect)
items.erase(items.begin() + i); items.erase(items.begin() + i);
JA_PlaySound(itemSound); JA_PlaySound(itemSound);
*itemsPicked = *itemsPicked + 1; *itemsPicked = *itemsPicked + 1;
options->items = *itemsPicked; options->stats.items = *itemsPicked;
return true; return true;
} }
} }

View File

@@ -36,6 +36,7 @@ struct aTile_t
struct room_t struct room_t
{ {
std::string number; // Numero de la habitación
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
std::string bgColor; // Color de fondo de la habitación std::string bgColor; // Color de fondo de la habitación
std::string borderColor; // Color del borde de la pantalla std::string borderColor; // Color del borde de la pantalla
@@ -89,6 +90,7 @@ private:
options_t *options; // Puntero a las opciones del juego options_t *options; // Puntero a las opciones del juego
// Variables // Variables
std::string number; // Numero de la habitación
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
std::string bgColor; // Color de fondo de la habitación std::string bgColor; // Color de fondo de la habitación
std::string borderColor; // Color del borde de la pantalla std::string borderColor; // Color del borde de la pantalla

View File

@@ -1,33 +1,66 @@
#include "common/jscore.h"
#include "stats.h" #include "stats.h"
#include <iostream> #include <algorithm>
#include <fstream> #include <fstream>
#include <iostream>
#include <sstream> #include <sstream>
// Constructor // Constructor
Stats::Stats(std::string file) Stats::Stats(std::string file, std::string buffer, options_t *options)
{ {
this->options = options;
bufferPath = buffer;
filePath = file; filePath = file;
bufferList.clear();
list.clear(); list.clear();
loadFromFile(); dictionary.clear();
} }
// Destructor // Destructor
Stats::~Stats() Stats::~Stats()
{ {
#ifndef DEBUG // Vuelca los datos del buffer en la lista de estadisticas
saveToFile(); updateListFromBuffer();
#endif
// Calcula cual es la habitación con más muertes
checkWorstNightmare();
// Guarda las estadísticas
saveToServer();
saveToFile(bufferPath, bufferList);
saveToFile(filePath, list);
bufferList.clear();
list.clear(); list.clear();
dictionary.clear();
}
// Inicializador
// Se debe llamar a este procediiento una vez se haya creado el diccionario numero-nombre
void Stats::init()
{
loadFromFile(bufferPath, bufferList);
loadFromFile(filePath, list);
if (options->online.enabled)
{
loadFromServer();
}
// Vuelca los datos del buffer en la lista de estadisticas
updateListFromBuffer();
} }
// Añade una muerte a las estadisticas // Añade una muerte a las estadisticas
void Stats::addDeath(std::string name) void Stats::addDeath(std::string name)
{ {
// Normaliza el nombre
// std::replace(name.begin(), name.end(), ' ', '_');
// Primero busca si ya hay una entrada con ese nombre // Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name); const int index = findByName(name, bufferList);
if (index != -1) if (index != -1)
{ {
list.at(index).died++; bufferList.at(index).died++;
} }
// En caso contrario crea la entrada // En caso contrario crea la entrada
@@ -37,18 +70,21 @@ void Stats::addDeath(std::string name)
item.name = name; item.name = name;
item.visited = 0; item.visited = 0;
item.died = 1; item.died = 1;
list.push_back(item); bufferList.push_back(item);
} }
} }
// Añade una visita a las estadisticas // Añade una visita a las estadisticas
void Stats::addVisit(std::string name) void Stats::addVisit(std::string name)
{ {
// Normaliza el nombre
// std::replace(name.begin(), name.end(), ' ', '_');
// Primero busca si ya hay una entrada con ese nombre // Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name); const int index = findByName(name, bufferList);
if (index != -1) if (index != -1)
{ {
list.at(index).visited++; bufferList.at(index).visited++;
} }
// En caso contrario crea la entrada // En caso contrario crea la entrada
@@ -58,12 +94,12 @@ void Stats::addVisit(std::string name)
item.name = name; item.name = name;
item.visited = 1; item.visited = 1;
item.died = 0; item.died = 0;
list.push_back(item); bufferList.push_back(item);
} }
} }
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int Stats::findByName(std::string name) int Stats::findByName(std::string name, std::vector<stats_t> &list)
{ {
int i = 0; int i = 0;
@@ -80,8 +116,10 @@ int Stats::findByName(std::string name)
} }
// Carga las estadisticas desde un fichero // Carga las estadisticas desde un fichero
bool Stats::loadFromFile() bool Stats::loadFromFile(std::string filePath, std::vector<stats_t> &list)
{ {
list.clear();
// Indicador de éxito en la carga // Indicador de éxito en la carga
bool success = true; bool success = true;
@@ -125,29 +163,68 @@ bool Stats::loadFromFile()
// El fichero no existe // El fichero no existe
else else
{ // Crea el fichero con los valores por defecto { // Crea el fichero con los valores por defecto
saveToFile(); saveToFile(filePath, list);
} }
return success; return success;
} }
// Carga las estadisticas desde un servidor
void Stats::loadFromServer()
{
// Limpia los datos del servidor
// eraseServerData();
list.clear();
std::string data;
if (options->online.enabled)
{
data = jscore::getUserData(options->online.gameID, options->online.jailerID);
}
std::stringstream ss(data);
std::string tmp;
int count = 0;
for (int i = 0; i < (int)data.size(); ++i)
{
if (data[i] == ';')
{
count++;
}
}
while (count > 0)
{
stats_t stat;
// Obtiene el nombre
getline(ss, tmp, ';');
stat.name = numberToName(tmp);
// Obtiene las visitas
getline(ss, tmp, ';');
stat.visited = std::stoi(tmp);
// Obtiene las muertes
getline(ss, tmp, ';');
stat.died = std::stoi(tmp);
list.push_back(stat);
count = count - 3;
}
}
// Guarda las estadisticas en un fichero // Guarda las estadisticas en un fichero
void Stats::saveToFile() void Stats::saveToFile(std::string filePath, std::vector<stats_t> &list)
{ {
// Crea y abre el fichero de texto // Crea y abre el fichero de texto
std::ofstream file(filePath); std::ofstream file(filePath);
if (file.good())
{
std::cout << filePath << " open for writing" << std::endl;
}
else
{
std::cout << filePath << " can't be opened" << std::endl;
}
// Escribe en el fichero // Escribe en el fichero
file << "# NOMBRE DE LA HABITACION;VISITAS;MUERTES" << std::endl; file << "# ROOM NAME;VISITS;DEATHS" << std::endl;
for (auto item : list) for (auto item : list)
{ {
file << item.name << ";" << item.visited << ";" << item.died << std::endl; file << item.name << ";" << item.visited << ";" << item.died << std::endl;
@@ -155,4 +232,104 @@ void Stats::saveToFile()
// Cierra el fichero // Cierra el fichero
file.close(); file.close();
}
// Guarda las estadisticas en un servidor
void Stats::saveToServer()
{
std::string data = "";
if (options->online.enabled)
{
for (auto item : list)
{
data = data + nameToNumber(item.name) + ";" + std::to_string(item.visited) + ";" + std::to_string(item.died) + ";";
}
jscore::setUserData(options->online.gameID, options->online.jailerID, data);
}
}
// Calcula cual es la habitación con más muertes
void Stats::checkWorstNightmare()
{
int deaths = 0;
for (auto item : list)
{
if (item.died > deaths)
{
deaths = item.died;
options->stats.worstNightmare = item.name;
}
}
}
// Añade una entrada al diccionario
void Stats::addDictionary(std::string number, std::string name)
{
dictionary.push_back({number, name});
}
// Obtiene el nombre de una habitación a partir del número
std::string Stats::numberToName(std::string number)
{
for (auto l : dictionary)
{
if (l.number == number)
{
return l.name;
}
}
return "";
}
// Obtiene el número de una habitación a partir del nombre
std::string Stats::nameToNumber(std::string name)
{
for (auto l : dictionary)
{
if (l.name == name)
{
return l.number;
}
}
return "";
}
// Vuelca los datos del buffer en la lista de estadisticas
void Stats::updateListFromBuffer()
{
// Actualiza list desde bufferList
for (auto buffer : bufferList)
{
int index = findByName(buffer.name, list);
if (index != -1)
{ // Encontrado. Aumenta sus estadisticas
list.at(index).visited += buffer.visited;
list.at(index).died += buffer.died;
}
else
{ // En caso contrario crea la entrada
stats_t item;
item.name = buffer.name;
item.visited = buffer.visited;
item.died = buffer.died;
list.push_back(item);
}
}
// Sube los datos al servidor
if (options->online.enabled)
{
saveToServer();
bufferList.clear();
}
saveToFile(bufferPath, bufferList);
saveToFile(filePath, list);
}
// Limpia los datos del servidor
void Stats::eraseServerData()
{
jscore::setUserData(options->online.gameID, options->online.jailerID, "");
} }

View File

@@ -7,41 +7,81 @@
#ifndef STATS_H #ifndef STATS_H
#define STATS_H #define STATS_H
struct stats_t
{
std::string name; // Nombre de la habitación donde se encuentra el objeto
int visited; // Cuenta las veces que se ha visitado una habitación
int died; // Cuenta las veces que se ha muerto en una habitación
};
class Stats class Stats
{ {
private: private:
struct stats_t
{
std::string name; // Nombre de la habitación
int visited; // Cuenta las veces que se ha visitado una habitación
int died; // Cuenta las veces que se ha muerto en una habitación
};
struct stats_dictionary_t
{
std::string number; // Numero de la habitación
std::string name; // Nombre de la habitación
};
// Punteros y objetos
options_t *options;
// Variables // Variables
std::vector<stats_t> list; // Lista con las estadisticas por habitación std::vector<stats_dictionary_t> dictionary; // Lista con la equivalencia nombre-numero de habitacion
std::string filePath; // Fichero con las estadísticas std::vector<stats_t> bufferList; // Lista con las estadisticas temporales por habitación
std::vector<stats_t> list; // Lista con las estadisticas completas por habitación
std::string bufferPath; // Fichero con las estadísticas temporales
std::string filePath; // Fichero con las estadísticas completas
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int findByName(std::string name); int findByName(std::string name, std::vector<stats_t> &list);
// Carga las estadisticas desde un fichero // Carga las estadisticas desde un fichero
bool loadFromFile(); bool loadFromFile(std::string filePath, std::vector<stats_t> &list);
// Carga las estadisticas desde un servidor
void loadFromServer();
// Guarda las estadisticas en un fichero // Guarda las estadisticas en un fichero
void saveToFile(); void saveToFile(std::string filePath, std::vector<stats_t> &list);
// Guarda las estadisticas en un servidor
void saveToServer();
// Calcula cual es la habitación con más muertes
void checkWorstNightmare();
// Obtiene el nombre de una habitación a partir del número
std::string numberToName(std::string number);
// Obtiene el número de una habitación a partir del nombre
std::string nameToNumber(std::string name);
// Vuelca los datos del buffer en la lista de estadisticas
void updateListFromBuffer();
// Limpia los datos del servidor
void eraseServerData();
public: public:
// Constructor // Constructor
Stats(std::string file); Stats(std::string file, std::string buffer, options_t *options);
// Destructor // Destructor
~Stats(); ~Stats();
// Inicializador
// Se debe llamar a este procediiento una vez se haya creado el diccionario numero-nombre
void init();
// Añade una muerte a las estadisticas // Añade una muerte a las estadisticas
void addDeath(std::string name); void addDeath(std::string name);
// Añade una visita a las estadisticas // Añade una visita a las estadisticas
void addVisit(std::string name); void addVisit(std::string name);
// Añade una entrada al diccionario
void addDictionary(std::string number, std::string name);
}; };
#endif #endif