Kabosu - Creando cosas
Publicado: 2024-02-12 (actualizado 2024-10-04)
Etiquetas: Java, Juegos, Proyectos, Reto de la Paella
Actualizado el día 2024-10-04 para corregir unos pocos errores ortográficos.
Una vez añadido el sprite de la paella al Shattered Pixel Dungeon tal y cómo expliqué en el artículo anterior. Lo siguiente es añadir el ítem al juego con su característica principal: solo aparece los domingos.
Crear un alimento parece sencillo. Hay que crear una clase que extienda Food
. Eso hace que herede que todos los comportamientos de Ration
, que es el alimento por defecto, así que sólo hay que cambiar el sprite. Aquí está la nueva clase core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/Paella.java
public class Paella extends Food {
{
image = ItemSpriteSheet.PAELLA;
}
}
Para saber qué otros sitios hay que modificar hago una búsqueda rápida del código.
$ grep -r FOOD .
La mayoría de resultados están en el directorio de comida pero FOOD
también aparecen el fichero Level.java
. Parece que es la clase en la que se generan los niveles del juego en la función create
:
public void create() {
Random.pushGenerator( Dungeon.seedCurDepth() );
if (!Dungeon.bossLevel() && Dungeon.branch == 0) {
addItemToSpawn(Generator.random(Generator.Category.FOOD));
...
Lo primero que hace la función es añadir un ítem de comida a cada nivel si no es un nivel de boss. Supongo que es para asegurar que cada nivel tiene al menos algo de comer.
Yo quiero que la paella solo salga en domingo así que hay que comprobar la fecha de alguna forma. Ojeando el código he visto que hay algunas comidas especiales que solo aparecen en determinadas fiestas: Pascua, el año nuevo lunar, la semana del Orgullo... Esos días o semanas están definidos en el fichero Holiday.java
. Añado ahí mi función para saber si es domingo.
public static boolean isSunday() {
LocalDate today = LocalDate.now();
DayOfWeek dayOfWeek = today.getDayOfWeek();
return DayOfWeek.SUNDAY.equals(dayOfWeek);
}
En el segundo artículo de este reto ya hablé de la clase Generator
en la que hay un array llamado FOOD
que contiene los alimentos que pueden salir en el juego. Voy a añadir ahí la paella pero solo si es domingo.
if (!Holiday.isSunday()) {
FOOD.classes = new Class<?>[]{
Food.class,
Pasty.class,
MysteryMeat.class};
FOOD.defaultProbs = new float[]{ 4, 1, 0};
} else {
FOOD.classes = new Class<?>[]{
Food.class,
Pasty.class,
MysteryMeat.class,
Paella.class };
FOOD.defaultProbs = new float[]{ 4, 1, 0, 100 };
}
Entiendo que el array defaultProbs
representa los pesos de cada ítem dentro del generador aleatorio. Yo quiero que la paella salga bastante si es domingo así que le he puesto un número bastante grande. Si no es domingo la paella no aparece, que no somos guiris.
Con los cambios que he hecho hasta ahora espero que, si es domingo, el alimento que aparece en cada nivel sea una paella con el 95% de probabilidad. Para poder probarlo mejor voy a hacer que si es domingo aparezcan en el nivel muchas paellas. Modifico el código de Level.java
que he enseñado más arriba para que los domingos añada muchos alimentos a cada nivel.
public void create() {
Random.pushGenerator( Dungeon.seedCurDepth() );
if (!Dungeon.bossLevel() && Dungeon.branch == 0) {
addItemToSpawn(Generator.random(Generator.Category.FOOD));
if (Holiday.isSunday()) {
addItemToSpawn(Generator.random(Generator.Category.FOOD));
addItemToSpawn(Generator.random(Generator.Category.FOOD));
addItemToSpawn(Generator.random(Generator.Category.FOOD));
addItemToSpawn(Generator.random(Generator.Category.FOOD));
addItemToSpawn(Generator.random(Generator.Category.FOOD));
addItemToSpawn(Generator.random(Generator.Category.FOOD));
addItemToSpawn(Generator.random(Generator.Category.FOOD));
}
...
Pues ya estaría el ítem. Ahora a probar y ver que todo funciona. Esta vez sí que he guardado los cambios en los ficheros.
La paella aparece múltiples veces en cada nivel. A veces varias de ellas en la misma habitación. ¡Misión cumplida!
Justo cuando iba a dar el reto por concluido me he dado cuenta de que al mostrar la información de la paella aparece la descripción de Ration
. Claro, se me ha olvidado añadir el texto propio de la paella.
No parece que se definan los textos en la clase Paella
así que busco la cadena que me ha aparecido para encontrar el fichero que necesito modificar:
$ grep -r "Nothing fancy" .
./core/src/main/assets/messages/items/items.properties:items.food.food.desc=Nothing fancy here: dried meat, some biscuits - things like that.
En properties.items
están todas las cadenas de texto relativas a los ítems. Incluyendo descripciones de todos los alimentos. Basándome en las cadenas de stewedmeat
creo las de la paella
.
items.food.paella.name=Paella
items.food.paella.eat_msg=You ate best paella in the whole dungeon. It even had socarrat!
items.food.paella.desc=A paella with bomba rice, chicken, garrofó, bachoqueta and all the standard ingredients. No chorizo or peas allowed.
Ahora, tras recompilar el juego, ya aparece la descripción de la paella en el inventario y el mensaje personalizado al comerla.
Un detalle del que me he dado cuenta: el juego permite guardar partida y parece que genera los niveles al iniciarse así que realmente mi ítem no va aparecer solo los domingos si no que va a aparecer en partidas empezadas en domingo. Es una sutil diferencia.
Los artículos de este reto son estos: