All the Stuff(Forgot to commit)

This commit is contained in:
Andre Schweiger 2016-01-01 16:17:37 +01:00
parent 7eb2832f9b
commit 7d08458f3f
22 changed files with 1668 additions and 319 deletions

View file

@ -11,7 +11,7 @@ sfillib by xerpi: https://github.com/xerpi/sfillib
zlib: http://www.zlib.net/ zlib: http://www.zlib.net/
Current Version: Version 1.1 Current Version: Version 1.2
You can do anything with the source code (besides sell it) as long as you give proper credit to the right people. You can do anything with the source code (besides sell it) as long as you give proper credit to the right people.
If you are going to make a mod of this version, be sure to give credit to Markus "Notch" Perrson because he did create the original game after all. If you are going to make a mod of this version, be sure to give credit to Markus "Notch" Perrson because he did create the original game after all.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

View file

@ -79,7 +79,7 @@ Recipe defineRecipe(int item, int amountOrLevel, int numArgs, ...){
void initRecipes(){ void initRecipes(){
curPlace = 0; curPlace = 0;
workbenchRecipes.size = 16; workbenchRecipes.size = 22;
workbenchRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (workbenchRecipes.size)); workbenchRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (workbenchRecipes.size));
workbenchRecipes.recipes[0] = defineRecipe(ITEM_WORKBENCH,1,1,ITEM_WOOD,20); workbenchRecipes.recipes[0] = defineRecipe(ITEM_WORKBENCH,1,1,ITEM_WOOD,20);
workbenchRecipes.recipes[1] = defineRecipe(ITEM_FURNACE,1,1,ITEM_STONE,20); workbenchRecipes.recipes[1] = defineRecipe(ITEM_FURNACE,1,1,ITEM_STONE,20);
@ -87,16 +87,22 @@ void initRecipes(){
workbenchRecipes.recipes[3] = defineRecipe(ITEM_CHEST,1,1,ITEM_WOOD,20); workbenchRecipes.recipes[3] = defineRecipe(ITEM_CHEST,1,1,ITEM_WOOD,20);
workbenchRecipes.recipes[4] = defineRecipe(ITEM_ANVIL,1,1,ITEM_IRONINGOT,5); workbenchRecipes.recipes[4] = defineRecipe(ITEM_ANVIL,1,1,ITEM_IRONINGOT,5);
workbenchRecipes.recipes[5] = defineRecipe(ITEM_LANTERN,1,3,ITEM_WOOD,5,ITEM_SLIME,10,ITEM_GLASS,4); workbenchRecipes.recipes[5] = defineRecipe(ITEM_LANTERN,1,3,ITEM_WOOD,5,ITEM_SLIME,10,ITEM_GLASS,4);
workbenchRecipes.recipes[6] = defineRecipe(TOOL_SWORD,0,1,ITEM_WOOD,5); workbenchRecipes.recipes[6] = defineRecipe(ITEM_LOOM,1,2,ITEM_WOOD,10,ITEM_WOOL,5);
workbenchRecipes.recipes[7] = defineRecipe(TOOL_AXE,0,1,ITEM_WOOD,5); workbenchRecipes.recipes[7] = defineRecipe(TOOL_SWORD,0,1,ITEM_WOOD,5);
workbenchRecipes.recipes[8] = defineRecipe(TOOL_HOE,0,1,ITEM_WOOD,5); workbenchRecipes.recipes[8] = defineRecipe(TOOL_AXE,0,1,ITEM_WOOD,5);
workbenchRecipes.recipes[9] = defineRecipe(TOOL_PICKAXE,0,1,ITEM_WOOD,5); workbenchRecipes.recipes[9] = defineRecipe(TOOL_HOE,0,1,ITEM_WOOD,5);
workbenchRecipes.recipes[10] = defineRecipe(TOOL_SHOVEL,0,1,ITEM_WOOD,5); workbenchRecipes.recipes[10] = defineRecipe(TOOL_PICKAXE,0,1,ITEM_WOOD,5);
workbenchRecipes.recipes[11] = defineRecipe(TOOL_SWORD,1,2,ITEM_WOOD,5,ITEM_STONE,5); workbenchRecipes.recipes[11] = defineRecipe(TOOL_SHOVEL,0,1,ITEM_WOOD,5);
workbenchRecipes.recipes[12] = defineRecipe(TOOL_AXE,1,2,ITEM_WOOD,5,ITEM_STONE,5); workbenchRecipes.recipes[12] = defineRecipe(TOOL_BOW,0,2,ITEM_WOOD,10,ITEM_STRING,1);
workbenchRecipes.recipes[13] = defineRecipe(TOOL_HOE,1,2,ITEM_WOOD,5,ITEM_STONE,5); workbenchRecipes.recipes[13] = defineRecipe(ITEM_ARROW_WOOD,1,2,ITEM_WOOD,2,ITEM_STRING,1);
workbenchRecipes.recipes[14] = defineRecipe(TOOL_PICKAXE,1,2,ITEM_WOOD,5,ITEM_STONE,5); workbenchRecipes.recipes[14] = defineRecipe(TOOL_SWORD,1,2,ITEM_WOOD,5,ITEM_STONE,5);
workbenchRecipes.recipes[15] = defineRecipe(TOOL_SHOVEL,1,2,ITEM_WOOD,5,ITEM_STONE,5); workbenchRecipes.recipes[15] = defineRecipe(TOOL_AXE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
workbenchRecipes.recipes[16] = defineRecipe(TOOL_HOE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
workbenchRecipes.recipes[17] = defineRecipe(TOOL_PICKAXE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
workbenchRecipes.recipes[18] = defineRecipe(TOOL_SHOVEL,1,2,ITEM_WOOD,5,ITEM_STONE,5);
workbenchRecipes.recipes[19] = defineRecipe(ITEM_ARROW_STONE,1,3,ITEM_WOOD,1,ITEM_STONE,1,ITEM_STRING,1);
workbenchRecipes.recipes[20] = defineRecipe(ITEM_WALL_WOOD,1,1,ITEM_WOOD,4);
workbenchRecipes.recipes[21] = defineRecipe(ITEM_WALL_STONE,1,1,ITEM_STONE,4);
anvilRecipes.size = 16; anvilRecipes.size = 16;
anvilRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (anvilRecipes.size)); anvilRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (anvilRecipes.size));
@ -105,17 +111,17 @@ void initRecipes(){
anvilRecipes.recipes[2] = defineRecipe(TOOL_HOE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5); anvilRecipes.recipes[2] = defineRecipe(TOOL_HOE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
anvilRecipes.recipes[3] = defineRecipe(TOOL_PICKAXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5); anvilRecipes.recipes[3] = defineRecipe(TOOL_PICKAXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
anvilRecipes.recipes[4] = defineRecipe(TOOL_SHOVEL,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5); anvilRecipes.recipes[4] = defineRecipe(TOOL_SHOVEL,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
anvilRecipes.recipes[5] = defineRecipe(TOOL_SWORD,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5); anvilRecipes.recipes[5] = defineRecipe(ITEM_ARROW_IRON,1,3,ITEM_WOOD,1,ITEM_IRONINGOT,1,ITEM_STRING,1);
anvilRecipes.recipes[6] = defineRecipe(TOOL_AXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5); anvilRecipes.recipes[6] = defineRecipe(TOOL_SWORD,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
anvilRecipes.recipes[7] = defineRecipe(TOOL_HOE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5); anvilRecipes.recipes[7] = defineRecipe(TOOL_AXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
anvilRecipes.recipes[8] = defineRecipe(TOOL_PICKAXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5); anvilRecipes.recipes[8] = defineRecipe(TOOL_HOE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
anvilRecipes.recipes[9] = defineRecipe(TOOL_SHOVEL,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5); anvilRecipes.recipes[9] = defineRecipe(TOOL_PICKAXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
anvilRecipes.recipes[10] = defineRecipe(TOOL_SWORD,4,2,ITEM_WOOD,5,ITEM_GEM,50); anvilRecipes.recipes[10] = defineRecipe(TOOL_SHOVEL,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
anvilRecipes.recipes[11] = defineRecipe(TOOL_AXE,4,2,ITEM_WOOD,5,ITEM_GEM,50); anvilRecipes.recipes[11] = defineRecipe(ITEM_ARROW_GOLD,1,3,ITEM_WOOD,1,ITEM_GOLDINGOT,1,ITEM_STRING,1);
anvilRecipes.recipes[12] = defineRecipe(TOOL_HOE,4,2,ITEM_WOOD,5,ITEM_GEM,50); anvilRecipes.recipes[12] = defineRecipe(TOOL_BUCKET,0,1,ITEM_IRONINGOT,10);
anvilRecipes.recipes[13] = defineRecipe(TOOL_PICKAXE,4,2,ITEM_WOOD,5,ITEM_GEM,50); anvilRecipes.recipes[13] = defineRecipe(ITEM_ENCHANTER,1,3,ITEM_WOOD,10,ITEM_GOLDINGOT,10,ITEM_GEM,20);
anvilRecipes.recipes[14] = defineRecipe(TOOL_SHOVEL,4,2,ITEM_WOOD,5,ITEM_GEM,50); anvilRecipes.recipes[14] = defineRecipe(ITEM_WALL_IRON,1,1,ITEM_IRONINGOT,2);
anvilRecipes.recipes[15] = defineRecipe(TOOL_BUCKET,0,1,ITEM_IRONINGOT,10); anvilRecipes.recipes[15] = defineRecipe(ITEM_WALL_GOLD,1,1,ITEM_GOLDINGOT,2);
furnaceRecipes.size = 3; furnaceRecipes.size = 3;
furnaceRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (furnaceRecipes.size)); furnaceRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (furnaceRecipes.size));
@ -123,9 +129,27 @@ void initRecipes(){
furnaceRecipes.recipes[1] = defineRecipe(ITEM_GOLDINGOT,1,2,ITEM_GOLDORE,4,ITEM_COAL,1); furnaceRecipes.recipes[1] = defineRecipe(ITEM_GOLDINGOT,1,2,ITEM_GOLDORE,4,ITEM_COAL,1);
furnaceRecipes.recipes[2] = defineRecipe(ITEM_GLASS,1,2,ITEM_SAND,4,ITEM_COAL,1); furnaceRecipes.recipes[2] = defineRecipe(ITEM_GLASS,1,2,ITEM_SAND,4,ITEM_COAL,1);
ovenRecipes.size = 1; ovenRecipes.size = 3;
ovenRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (ovenRecipes.size)); ovenRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (ovenRecipes.size));
ovenRecipes.recipes[0] = defineRecipe(ITEM_BREAD,1,1,ITEM_WHEAT,4); ovenRecipes.recipes[0] = defineRecipe(ITEM_BREAD,1,1,ITEM_WHEAT,4);
ovenRecipes.recipes[1] = defineRecipe(ITEM_PORK_COOKED,1,2,ITEM_PORK_RAW,1,ITEM_COAL,1);
ovenRecipes.recipes[2] = defineRecipe(ITEM_BEEF_COOKED,1,2,ITEM_BEEF_RAW,1,ITEM_COAL,1);
loomRecipes.size = 1;
loomRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (loomRecipes.size));
loomRecipes.recipes[0] = defineRecipe(ITEM_STRING,1,1,ITEM_WOOL,1);
enchanterRecipes.size = 8;
enchanterRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (enchanterRecipes.size));
enchanterRecipes.recipes[0] = defineRecipe(TOOL_SWORD,4,2,ITEM_WOOD,5,ITEM_GEM,50);
enchanterRecipes.recipes[1] = defineRecipe(TOOL_AXE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
enchanterRecipes.recipes[2] = defineRecipe(TOOL_HOE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
enchanterRecipes.recipes[3] = defineRecipe(TOOL_PICKAXE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
enchanterRecipes.recipes[4] = defineRecipe(TOOL_SHOVEL,4,2,ITEM_WOOD,5,ITEM_GEM,50);
enchanterRecipes.recipes[5] = defineRecipe(ITEM_ARROW_GEM,1,3,ITEM_WOOD,1,ITEM_GEM,3,ITEM_STRING,1);
enchanterRecipes.recipes[6] = defineRecipe(ITEM_WALL_GEM,1,1,ITEM_GEM,10);
enchanterRecipes.recipes[7] = defineRecipe(ITEM_WIZARD_SUMMON,1,4,ITEM_CLOUD,100,ITEM_IRONINGOT,10,ITEM_BONE,10,ITEM_LEATHER,10);
} }
/* Free up allocated memory */ /* Free up allocated memory */
@ -134,4 +158,6 @@ void freeRecipes(){
free(ovenRecipes.recipes); free(ovenRecipes.recipes);
free(furnaceRecipes.recipes); free(furnaceRecipes.recipes);
free(anvilRecipes.recipes); free(anvilRecipes.recipes);
free(loomRecipes.recipes);
free(enchanterRecipes.recipes);
} }

View file

@ -26,6 +26,8 @@ RecipeManager workbenchRecipes;
RecipeManager furnaceRecipes; RecipeManager furnaceRecipes;
RecipeManager ovenRecipes; RecipeManager ovenRecipes;
RecipeManager anvilRecipes; RecipeManager anvilRecipes;
RecipeManager loomRecipes;
RecipeManager enchanterRecipes;
void checkCanCraftRecipes(RecipeManager * rm, Inventory * inv); void checkCanCraftRecipes(RecipeManager * rm, Inventory * inv);
void sortRecipes(RecipeManager * rm); void sortRecipes(RecipeManager * rm);

View file

@ -65,6 +65,25 @@ Entity newFurnitureEntity(int itemID,Inventory * invPtr, int x, int y, int level
return e; return e;
} }
Entity newPassiveEntity(int type, int x, int y, int level){
Entity e;
e.type = ENTITY_PASSIVE;
e.level = level;
e.x = x;
e.y = y;
e.hurtTime = 0;
e.xKnockback = 0;
e.yKnockback = 0;
e.passive.mtype = type;
e.passive.health = 20;
e.passive.dir = 0;
e.passive.xa = 0;
e.passive.ya = 0;
e.xr = 4;
e.yr = 3;
e.canPass = false;
return e;
}
Entity newZombieEntity(int lvl, int x, int y, int level){ Entity newZombieEntity(int lvl, int x, int y, int level){
Entity e; Entity e;
@ -75,17 +94,72 @@ Entity newZombieEntity(int lvl, int x, int y, int level){
e.hurtTime = 0; e.hurtTime = 0;
e.xKnockback = 0; e.xKnockback = 0;
e.yKnockback = 0; e.yKnockback = 0;
e.zombie.lvl = lvl; e.hostile.lvl = lvl;
e.zombie.health = lvl * lvl * 10; e.hostile.xa = 0;
e.zombie.dir = 0; e.hostile.ya = 0;
e.hostile.health = lvl * lvl * 10;
e.hostile.dir = 0;
e.xr = 4; e.xr = 4;
e.yr = 3; e.yr = 3;
e.canPass = false; e.canPass = false;
switch(lvl){ switch(lvl){
case 2: e.zombie.color = 0xFF8282CC; break; case 2: e.hostile.color = 0xFF8282CC; break;
case 3: e.zombie.color = 0xFFEFEFEF; break; case 3: e.hostile.color = 0xFFEFEFEF; break;
case 4: e.zombie.color = 0xFFAA6262; break; case 4: e.hostile.color = 0xFFAA6262; break;
default: e.zombie.color = 0xFF95DB95; break; default: e.hostile.color = 0xFF95DB95; break;
}
return e;
}
Entity newSkeletonEntity(int lvl, int x, int y, int level){
Entity e;
e.type = ENTITY_SKELETON;
e.level = level;
e.x = x;
e.y = y;
e.hurtTime = 0;
e.xKnockback = 0;
e.yKnockback = 0;
e.hostile.lvl = lvl;
e.hostile.xa = 0;
e.hostile.ya = 0;
e.hostile.health = lvl * lvl * 10;
e.hostile.dir = 0;
e.hostile.randAttackTime = 0;
e.xr = 4;
e.yr = 3;
e.canPass = false;
switch(lvl){
case 2: e.hostile.color = 0xFFC4C4C4; break;
case 3: e.hostile.color = 0xFFA0A0A0; break;
case 4: e.hostile.color = 0xFF7A7A7A; break;
default: e.hostile.color = 0xFFFFFFFF; break;
}
return e;
}
Entity newKnightEntity(int lvl, int x, int y, int level){
Entity e;
e.type = ENTITY_KNIGHT;
e.level = level;
e.x = x;
e.y = y;
e.hurtTime = 0;
e.xKnockback = 0;
e.yKnockback = 0;
e.hostile.lvl = lvl;
e.hostile.xa = 0;
e.hostile.ya = 0;
e.hostile.health = lvl * lvl * 20;
e.hostile.dir = 0;
e.xr = 4;
e.yr = 3;
e.canPass = false;
switch(lvl){
case 2: e.hostile.color = 0xFF0000C6; break;
case 3: e.hostile.color = 0xFF00A3C6; break;
case 4: e.hostile.color = 0xFF707070; break;
default: e.hostile.color = 0xFFFFFFFF; break;
} }
return e; return e;
} }
@ -141,6 +215,7 @@ Entity newAirWizardEntity(int x, int y, int level){
Entity newSparkEntity(Entity* parent, float xa, float ya){ Entity newSparkEntity(Entity* parent, float xa, float ya){
Entity e; Entity e;
e.type = ENTITY_SPARK; e.type = ENTITY_SPARK;
e.level = parent->level;
e.spark.age = 0; e.spark.age = 0;
e.spark.parent = parent; e.spark.parent = parent;
e.spark.xa = xa; e.spark.xa = xa;
@ -185,13 +260,44 @@ Entity newSmashParticleEntity(int x, int y, int level){
return e; return e;
} }
Entity newArrowEntity(Entity* parent, int itemID, s8 xa, s8 ya, int level){
Entity e;
e.type = ENTITY_ARROW;
e.level = level;
e.arrow.age = 0;
e.arrow.parent = parent;
e.arrow.itemID = itemID;
e.arrow.xa = xa;
e.arrow.ya = ya;
e.x = parent->x;
e.y = parent->y;
e.xr = 2;
e.yr = 2;
e.canPass = false;
e.canSwim = true;
return e;
}
Entity newGlowwormEntity(int x, int y, int level){
Entity e;
e.type = ENTITY_GLOWWORM;
e.level = level;
e.glowworm.xa = 0;
e.glowworm.ya = 0;
e.glowworm.randWalkTime = 0;
e.glowworm.waitTime = 0;
e.x = x;
e.y = y;
e.canPass = true;
return e;
}
void addEntityToList(Entity e, EntityManager* em){ void addEntityToList(Entity e, EntityManager* em){
e.slotNum = em->lastSlot[e.level]; e.slotNum = em->lastSlot[e.level];
em->entities[e.level][em->lastSlot[e.level]] = e; em->entities[e.level][em->lastSlot[e.level]] = e;
++em->lastSlot[e.level]; ++em->lastSlot[e.level];
} }
Entity nullEntity;
void removeEntityFromList(Entity * e,int level,EntityManager* em){ void removeEntityFromList(Entity * e,int level,EntityManager* em){
int i; int i;
if(em->entities[level][e->slotNum].type == ENTITY_TEXTPARTICLE) free(em->entities[level][e->slotNum].textParticle.text); if(em->entities[level][e->slotNum].type == ENTITY_TEXTPARTICLE) free(em->entities[level][e->slotNum].textParticle.text);

View file

@ -13,6 +13,11 @@
#define ENTITY_TEXTPARTICLE 7 #define ENTITY_TEXTPARTICLE 7
#define ENTITY_SMASHPARTICLE 8 #define ENTITY_SMASHPARTICLE 8
#define ENTITY_PLAYER 9 #define ENTITY_PLAYER 9
#define ENTITY_PASSIVE 10
#define ENTITY_ARROW 11
#define ENTITY_SKELETON 12
#define ENTITY_KNIGHT 13
#define ENTITY_GLOWWORM 14
typedef struct Entity Entity; typedef struct Entity Entity;
@ -59,6 +64,16 @@ typedef struct {
s16 oSel; // other selection inside the chest inv. s16 oSel; // other selection inside the chest inv.
} EntityFurniture; } EntityFurniture;
typedef struct {
u8 mtype;
s8 xa;
s8 ya;
s16 health;
s8 dir;
s8 randWalkTime;
s8 walkDist;
} PassiveMob;
typedef struct { typedef struct {
s8 xa; s8 xa;
s8 ya; s8 ya;
@ -67,8 +82,9 @@ typedef struct {
s8 lvl; s8 lvl;
s8 randWalkTime; s8 randWalkTime;
s8 walkDist; s8 walkDist;
s8 randAttackTime;
u32 color; u32 color;
} Zombie; } HostileMob;
typedef struct { typedef struct {
s8 xa; s8 xa;
@ -93,6 +109,14 @@ typedef struct {
s8 spriteAdjust; s8 spriteAdjust;
} AirWizard; } AirWizard;
typedef struct {
Entity* parent;
s16 age;
s16 itemID;
s8 xa;
s8 ya;
} Arrow;
typedef struct { typedef struct {
Entity* parent; Entity* parent;
s16 age; s16 age;
@ -102,6 +126,13 @@ typedef struct {
float yy; float yy;
} Spark; } Spark;
typedef struct {
s8 xa;
s8 ya;
s8 randWalkTime;
s8 waitTime;
} Glowworm;
typedef struct { typedef struct {
float xa; float xa;
float ya; float ya;
@ -133,36 +164,45 @@ struct Entity {
Player p; Player p;
EntityItem entityItem; EntityItem entityItem;
EntityFurniture entityFurniture; EntityFurniture entityFurniture;
Zombie zombie; PassiveMob passive;
HostileMob hostile;
Slime slime; Slime slime;
AirWizard wizard; AirWizard wizard;
Spark spark; Spark spark;
Arrow arrow;
Glowworm glowworm;
TextParticleEntity textParticle; TextParticleEntity textParticle;
SmashParticleEntity smashParticle; SmashParticleEntity smashParticle;
}; };
}; };
typedef struct { typedef struct {
Entity entities[5][1000]; Entity entities[6][1000];
Entity wizardSparks[120]; Entity wizardSparks[120];
s16 lastSlot[5]; s16 lastSlot[6];
Inventory invs[301];//1 for the player, 300 for chests. Inventory invs[301];//1 for the player, 300 for chests.
s16 nextInv; s16 nextInv;
} EntityManager; } EntityManager;
EntityManager eManager; EntityManager eManager;
Entity nullEntity;
s8 currentLevel; s8 currentLevel;
double gaussrand(); double gaussrand();
Entity newItemEntity(Item item, int x, int y, int level); Entity newItemEntity(Item item, int x, int y, int level);
Entity newFurnitureEntity(int itemID,Inventory * invPtr, int x, int y, int level); Entity newFurnitureEntity(int itemID,Inventory * invPtr, int x, int y, int level);
Entity newPassiveEntity(int type, int x, int y, int level);
Entity newZombieEntity(int lvl, int x, int y, int level); Entity newZombieEntity(int lvl, int x, int y, int level);
Entity newSkeletonEntity(int lvl, int x, int y, int level);
Entity newKnightEntity(int lvl, int x, int y, int level);
Entity newSlimeEntity(int lvl, int x, int y, int level); Entity newSlimeEntity(int lvl, int x, int y, int level);
Entity newAirWizardEntity(int x, int y, int level); Entity newAirWizardEntity(int x, int y, int level);
Entity newSparkEntity(Entity* parent, float xa, float ya); Entity newSparkEntity(Entity* parent, float xa, float ya);
Entity newTextParticleEntity(char * str, u32 color, int xa, int ya, int level); Entity newTextParticleEntity(char * str, u32 color, int xa, int ya, int level);
Entity newSmashParticleEntity(int xa, int ya, int level); Entity newSmashParticleEntity(int xa, int ya, int level);
Entity newArrowEntity(Entity* parent, int itemID, s8 xa, s8 ya, int level);
Entity newGlowwormEntity(int x, int y, int level);
void addEntityToList(Entity e, EntityManager* em); void addEntityToList(Entity e, EntityManager* em);
void removeEntityFromList(Entity * e,int level,EntityManager* em); void removeEntityFromList(Entity * e,int level,EntityManager* em);

View file

@ -1,6 +1,6 @@
#include "Globals.h" #include "Globals.h"
char versionText[34] = "Version 1.1"; char versionText[34] = "Version 1.2";
char fpsstr[34]; char fpsstr[34];
u8 currentMenu = 0; u8 currentMenu = 0;
@ -238,10 +238,19 @@ void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){
} }
break; break;
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
e->zombie.health -= damage; case ENTITY_SKELETON:
if(e->zombie.health < 1){ case ENTITY_KNIGHT:
e->hostile.health -= damage;
if(e->hostile.health < 1){
if(e->type == ENTITY_ZOMBIE) {
addItemsToWorld(newItem(ITEM_FLESH,1),e->x+8, e->y+8, (rand()%2) + 1); addItemsToWorld(newItem(ITEM_FLESH,1),e->x+8, e->y+8, (rand()%2) + 1);
player.p.score += 50 * (e->zombie.lvl + 1); } else if(e->type == ENTITY_SKELETON) {
addItemsToWorld(newItem(ITEM_BONE,1),e->x+8, e->y+8, (rand()%2) + 1);
if(rand()%2==0) addItemsToWorld(newItem(ITEM_ARROW_STONE,1),e->x+8, e->y+8, 1);
} else if(e->type == ENTITY_KNIGHT) {
addItemsToWorld(newItem(ITEM_IRONINGOT,1),e->x+8, e->y+8, (rand()%2) + 1);
}
player.p.score += 50 * (e->hostile.lvl + 1);
removeEntityFromList(e,e->level,&eManager); removeEntityFromList(e,e->level,&eManager);
trySpawn(3, currentLevel); trySpawn(3, currentLevel);
return; return;
@ -261,15 +270,35 @@ void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){
e->wizard.health -= damage; e->wizard.health -= damage;
airWizardHealthDisplay = e->wizard.health; airWizardHealthDisplay = e->wizard.health;
if(e->wizard.health < 1){ if(e->wizard.health < 1){
addItemsToWorld(newItem(ITEM_DUNGEON_KEY,1),e->x+8, e->y+8, (rand()%2) + 1);
removeEntityFromList(e,e->level,&eManager); removeEntityFromList(e,e->level,&eManager);
playSound(snd_bossdeath); playSound(snd_bossdeath);
player.p.score += 1000; player.p.score += 1000;
player.p.endTimer = 60; if(!player.p.hasWonSaved) player.p.endTimer = 60;
player.p.hasWon = true; if(!player.p.hasWonSaved) player.p.hasWon = true;
player.p.hasWonSaved = true; player.p.hasWonSaved = true;
return; return;
} }
break; break;
case ENTITY_PASSIVE:
e->passive.health -= damage;
if(e->passive.health < 1){
if(e->passive.mtype==0) {
addItemsToWorld(newItem(ITEM_WOOL,1),e->x+8, e->y+8, (rand()%3) + 1);
} else if(e->passive.mtype==1) {
addItemsToWorld(newItem(ITEM_PORK_RAW,1),e->x+8, e->y+8, (rand()%2) + 1);
} else if(e->passive.mtype==2) {
addItemsToWorld(newItem(ITEM_BEEF_RAW,1),e->x+8, e->y+8, (rand()%2) + 1);
if((rand()%2)==0) {
addItemsToWorld(newItem(ITEM_LEATHER,1),e->x+8, e->y+8, 1);
}
}
player.p.score += 10;
removeEntityFromList(e,e->level,&eManager);
trySpawn(3, currentLevel);
return;
}
break;
} }
switch(dir){ switch(dir){
@ -284,7 +313,9 @@ void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){
} }
break; break;
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
switch(e->zombie.dir){ case ENTITY_SKELETON:
case ENTITY_KNIGHT:
switch(e->hostile.dir){
case 0: e->yKnockback = -10; break; case 0: e->yKnockback = -10; break;
case 1: e->yKnockback = +10; break; case 1: e->yKnockback = +10; break;
case 2: e->xKnockback = +10; break; case 2: e->xKnockback = +10; break;
@ -298,6 +329,14 @@ void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){
case 2: e->xKnockback = +10; break; case 2: e->xKnockback = +10; break;
case 3: e->xKnockback = -10; break; case 3: e->xKnockback = -10; break;
} }
break;
case ENTITY_PASSIVE:
switch(e->passive.dir){
case 0: e->yKnockback = -10; break;
case 1: e->yKnockback = +10; break;
case 2: e->xKnockback = +10; break;
case 3: e->xKnockback = -10; break;
}
break; break;
} }
break; break;
@ -323,7 +362,10 @@ bool ItemVsEntity(Item* item, Entity* e, int dir){
} break; } break;
case TOOL_AXE: case TOOL_AXE:
switch(e->type){ switch(e->type){
case ENTITY_PASSIVE:
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
case ENTITY_SKELETON:
case ENTITY_KNIGHT:
case ENTITY_SLIME: case ENTITY_SLIME:
case ENTITY_AIRWIZARD: case ENTITY_AIRWIZARD:
if(playerUseEnergy(4-item->countLevel)) hurtEntity(e,(item->countLevel + 1) * 2 + (rand()%4),dir,0xFF0000FF); if(playerUseEnergy(4-item->countLevel)) hurtEntity(e,(item->countLevel + 1) * 2 + (rand()%4),dir,0xFF0000FF);
@ -332,7 +374,10 @@ bool ItemVsEntity(Item* item, Entity* e, int dir){
} break; } break;
case TOOL_SWORD: case TOOL_SWORD:
switch(e->type){ switch(e->type){
case ENTITY_PASSIVE:
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
case ENTITY_SKELETON:
case ENTITY_KNIGHT:
case ENTITY_SLIME: case ENTITY_SLIME:
case ENTITY_AIRWIZARD: case ENTITY_AIRWIZARD:
if(playerUseEnergy(4-item->countLevel)) hurtEntity(e,(item->countLevel+1)*3+(rand()%(2+item->countLevel*item->countLevel*2)),dir,0xFF0000FF); if(playerUseEnergy(4-item->countLevel)) hurtEntity(e,(item->countLevel+1)*3+(rand()%(2+item->countLevel*item->countLevel*2)),dir,0xFF0000FF);
@ -341,7 +386,10 @@ bool ItemVsEntity(Item* item, Entity* e, int dir){
} break; } break;
case ITEM_NULL: case ITEM_NULL:
switch(e->type){ switch(e->type){
case ENTITY_PASSIVE:
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
case ENTITY_SKELETON:
case ENTITY_KNIGHT:
case ENTITY_SLIME: case ENTITY_SLIME:
case ENTITY_AIRWIZARD: case ENTITY_AIRWIZARD:
hurtEntity(e,1+rand()%3,dir,0xFF0000FF); hurtEntity(e,1+rand()%3,dir,0xFF0000FF);
@ -351,6 +399,63 @@ bool ItemVsEntity(Item* item, Entity* e, int dir){
return false; return false;
} }
bool playerUseItem() {
if(player.p.activeItem->id == TOOL_BOW) {
int aitemID = 0;
Item * aitem;
Item * item = getItemFromInventory(ITEM_ARROW_WOOD, player.p.inv);
if(item!=NULL) {
aitemID = ITEM_ARROW_WOOD;
aitem = item;
}
item = getItemFromInventory(ITEM_ARROW_STONE, player.p.inv);
if(item!=NULL) {
aitemID = ITEM_ARROW_STONE;
aitem = item;
}
item = getItemFromInventory(ITEM_ARROW_IRON, player.p.inv);
if(item!=NULL) {
aitemID = ITEM_ARROW_IRON;
aitem = item;
}
item = getItemFromInventory(ITEM_ARROW_GOLD, player.p.inv);
if(item!=NULL) {
aitemID = ITEM_ARROW_GOLD;
aitem = item;
}
item = getItemFromInventory(ITEM_ARROW_GEM, player.p.inv);
if(item!=NULL) {
aitemID = ITEM_ARROW_GEM;
aitem = item;
}
if(aitemID!=0) {
--aitem->countLevel;
if (isItemEmpty(aitem)) {
removeItemFromInventory(aitem->slotNum, player.p.inv);
}
switch(player.p.dir) {
case 0:
addEntityToList(newArrowEntity(&player, aitemID, 0, 2, currentLevel), &eManager);
break;
case 1:
addEntityToList(newArrowEntity(&player, aitemID, 0, -2, currentLevel), &eManager);
break;
case 2:
addEntityToList(newArrowEntity(&player, aitemID, -2, 0, currentLevel), &eManager);
break;
case 3:
addEntityToList(newArrowEntity(&player, aitemID, 2, 0, currentLevel), &eManager);
break;
}
return true;
}
}
return false;
}
bool interact(int x0, int y0, int x1, int y1) { bool interact(int x0, int y0, int x1, int y1) {
Entity * es[eManager.lastSlot[currentLevel]]; Entity * es[eManager.lastSlot[currentLevel]];
int eSize = getEntities(es, x0, y0, x1, y1); int eSize = getEntities(es, x0, y0, x1, y1);
@ -365,12 +470,17 @@ bool interact(int x0, int y0, int x1, int y1) {
} }
void EntityVsEntity(Entity* e1, Entity* e2){ void EntityVsEntity(Entity* e1, Entity* e2){
int damage = 1;
switch(e1->type){ switch(e1->type){
case ENTITY_PLAYER: playerEntityInteract(e2); break; case ENTITY_PLAYER: playerEntityInteract(e2); break;
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
case ENTITY_SKELETON:
case ENTITY_KNIGHT:
if(e2->type == ENTITY_PLAYER){ if(e2->type == ENTITY_PLAYER){
hurtEntity(e2, 2, e1->zombie.dir, 0xFFAF00FF); if(e1->type == ENTITY_ZOMBIE) hurtEntity(e2, 2, e1->hostile.dir, 0xFFAF00FF);
switch(e1->zombie.dir){ else if(e1->type == ENTITY_SKELETON) hurtEntity(e2, 1, e1->hostile.dir, 0xFFAF00FF);
else if(e1->type == ENTITY_KNIGHT) hurtEntity(e2, 3, e1->hostile.dir, 0xFFAF00FF);
switch(e1->hostile.dir){
case 0: e1->yKnockback = -4; break; case 0: e1->yKnockback = -4; break;
case 1: e1->yKnockback = +4; break; case 1: e1->yKnockback = +4; break;
case 2: e1->xKnockback = +4; break; case 2: e1->xKnockback = +4; break;
@ -395,6 +505,37 @@ void EntityVsEntity(Entity* e1, Entity* e2){
case ENTITY_SPARK: case ENTITY_SPARK:
if(e2 != e1->spark.parent) hurtEntity(e2, 1, -1, 0xFFAF00FF); if(e2 != e1->spark.parent) hurtEntity(e2, 1, -1, 0xFFAF00FF);
break; break;
case ENTITY_ARROW:
switch(e1->arrow.itemID) {
case ITEM_ARROW_WOOD:
damage = 1 + (rand()%3);
break;
case ITEM_ARROW_STONE:
damage = 2 + (rand()%5);
break;
case ITEM_ARROW_IRON:
damage = 8 + (rand()%9);
break;
case ITEM_ARROW_GOLD:
damage = 16 + (rand()%17);
break;
case ITEM_ARROW_GEM:
damage = 24 + (rand()%17);
break;
}
if(e1->arrow.parent->type == ENTITY_PLAYER) {
if(e2->type != ENTITY_PLAYER) {
hurtEntity(e2, damage, -1, 0xFF0000FF);
removeEntityFromList(e1, e1->level, &eManager);
}
} else {
if(e2->type == ENTITY_PLAYER) {
hurtEntity(e2, damage, -1, 0xFFAF00FF);
removeEntityFromList(e1, e1->level, &eManager);
}
}
break;
} }
} }
@ -405,9 +546,12 @@ bool EntityBlocksEntity(Entity* e1, Entity* e2){
switch(e2->type){ switch(e2->type){
case ENTITY_FURNITURE: case ENTITY_FURNITURE:
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
case ENTITY_SKELETON:
case ENTITY_KNIGHT:
case ENTITY_SLIME: case ENTITY_SLIME:
case ENTITY_AIRWIZARD: case ENTITY_AIRWIZARD:
case ENTITY_PLAYER: case ENTITY_PLAYER:
case ENTITY_PASSIVE:
return true; return true;
break; break;
} }
@ -426,14 +570,20 @@ bool tileIsSolid(int tile, Entity * e){
case TILE_GOLDORE: case TILE_GOLDORE:
case TILE_GEMORE: case TILE_GEMORE:
case TILE_CLOUDCACTUS: case TILE_CLOUDCACTUS:
case TILE_LAVA:
case TILE_WOOD_WALL: case TILE_WOOD_WALL:
case 255: case TILE_STONE_WALL:
case TILE_IRON_WALL:
case TILE_GOLD_WALL:
case TILE_GEM_WALL:
case TILE_DUNGEON_WALL:
return true; return true;
case TILE_LAVA:
case 255:
if(e->type != ENTITY_ARROW) return true;
case TILE_WATER: case TILE_WATER:
if(e != NULL && !e->canSwim) return true; if(e != NULL && !e->canSwim && e->type != ENTITY_ARROW) return true;
case TILE_HOLE: case TILE_HOLE:
if(e != NULL && e->type != ENTITY_PLAYER) return true; if(e != NULL && e->type != ENTITY_PLAYER && e->type != ENTITY_ARROW) return true;
} }
return false; return false;
} }
@ -441,25 +591,32 @@ bool tileIsSolid(int tile, Entity * e){
/* For minimap */ /* For minimap */
u32 getTileColor(int tile){ u32 getTileColor(int tile){
switch(tile){ switch(tile){
case TILE_WATER: return 0x0000FFFF; case TILE_WATER: return SWAP_UINT32(waterColor[0]);
case TILE_LAVA: return 0xFF0000FF; case TILE_LAVA: return SWAP_UINT32(lavaColor[0]);
case TILE_DIRT: return 0x826D6CFF; case TILE_DIRT: return 0x826D6CFF;
case TILE_ROCK: return 0x7F7F7FFF; case TILE_ROCK: return SWAP_UINT32(rockColor[1]);
case TILE_HARDROCK: return 0x5F5F7FFF; case TILE_HARDROCK: return SWAP_UINT32(rockColor[3]);
case TILE_GRASS: return 0x00FF00FF; case TILE_GRASS: return SWAP_UINT32(grassColor);
case TILE_TREE: return 0x007F00FF; case TILE_TREE: return 0x007F00FF;
case TILE_SAND: return 0xFFFF00FF; case TILE_SAND: return SWAP_UINT32(sandColor);
case TILE_CACTUS: return 0x009F00FF; case TILE_CACTUS: return 0x009F00FF;
case TILE_FLOWER: return 0x3FFF00FF; case TILE_FLOWER: return SWAP_UINT32(grassColor);
case TILE_IRONORE: return 0xDC9696FF; case TILE_IRONORE: return SWAP_UINT32(ironColor);
case TILE_GOLDORE: return 0xE5E89AFF; case TILE_GOLDORE: return SWAP_UINT32(goldColor);
case TILE_GEMORE: return 0xDF98DEFF; case TILE_GEMORE: return SWAP_UINT32(gemColor);
case TILE_CLOUD: return 0xFFFFFFFF; case TILE_CLOUD: return 0xFFFFFFFF;
case TILE_CLOUDCACTUS: return 0xAFAFAFFF; case TILE_CLOUDCACTUS: return 0xAFAFAFFF;
case TILE_STAIRS_DOWN: return 0x9F9F9FFF; case TILE_STAIRS_DOWN: return 0x9F9F9FFF;
case TILE_STAIRS_UP: return 0x9F9F9FFF; case TILE_STAIRS_UP: return 0x9F9F9FFF;
case TILE_HOLE: return 0x383838FF; case TILE_HOLE: return 0x383838FF;
case TILE_WOOD_WALL: return 0xC1A55EFF; case TILE_WOOD_WALL: return SWAP_UINT32(woodColor);
case TILE_STONE_WALL: return SWAP_UINT32(rockColor[1]);
case TILE_IRON_WALL: return SWAP_UINT32(ironColor);
case TILE_GOLD_WALL: return SWAP_UINT32(goldColor);
case TILE_GEM_WALL: return SWAP_UINT32(gemColor);
case TILE_DUNGEON_WALL: return SWAP_UINT32(dungeonColor[0]);
case TILE_DUNGEON_FLOOR: return SWAP_UINT32(dungeonColor[1]);
default: return 0x111111FF; default: return 0x111111FF;
} }
} }
@ -475,7 +632,7 @@ void healPlayer(int amount){
s8 itemTileInteract(int tile, Item* item, int x, int y, int px, int py, int dir){ s8 itemTileInteract(int tile, Item* item, int x, int y, int px, int py, int dir){
// Furniture items // Furniture items
if(item->id > 27 && item->id < 34){ if(item->id > 27 && item->id < 51){
if(!tileIsSolid(getTile(x,y), NULL)){ if(!tileIsSolid(getTile(x,y), NULL)){
addEntityToList(newFurnitureEntity(item->id,item->chestPtr, (x<<4)+8, (y<<4)+8, currentLevel), &eManager); addEntityToList(newFurnitureEntity(item->id,item->chestPtr, (x<<4)+8, (y<<4)+8, currentLevel), &eManager);
removeItemFromCurrentInv(item); removeItemFromCurrentInv(item);
@ -491,30 +648,51 @@ s8 itemTileInteract(int tile, Item* item, int x, int y, int px, int py, int dir)
if(player.p.health < 10 && playerUseEnergy(2)){ if(player.p.health < 10 && playerUseEnergy(2)){
healPlayer(1); healPlayer(1);
--item->countLevel; --item->countLevel;
if(item->countLevel < 1){
removeItemFromCurrentInv(item);
player.p.activeItem = &noItem;
}
} }
return 0; return 0;
case ITEM_FLESH: case ITEM_FLESH:
if(player.p.health < 10 && playerUseEnergy(4+(rand()%4))){ if(player.p.health < 10 && playerUseEnergy(4+(rand()%4))){
healPlayer(1); healPlayer(1);
--item->countLevel; --item->countLevel;
if(item->countLevel < 1){
removeItemFromCurrentInv(item);
player.p.activeItem = &noItem;
}
} }
return 0; return 0;
case ITEM_BREAD: case ITEM_BREAD:
if(player.p.health < 10 && playerUseEnergy(3)){ if(player.p.health < 10 && playerUseEnergy(3)){
healPlayer(2); healPlayer(2);
--item->countLevel; --item->countLevel;
if(item->countLevel < 1){
removeItemFromCurrentInv(item);
player.p.activeItem = &noItem;
} }
return 0;
case ITEM_PORK_RAW:
if(player.p.health < 10 && playerUseEnergy(4+(rand()%4))){
healPlayer(1);
--item->countLevel;
}
return 0;
case ITEM_PORK_COOKED:
if(player.p.health < 10 && playerUseEnergy(3)){
healPlayer(3);
--item->countLevel;
}
return 0;
case ITEM_BEEF_RAW:
if(player.p.health < 10 && playerUseEnergy(4+(rand()%4))){
healPlayer(1);
--item->countLevel;
}
return 0;
case ITEM_BEEF_COOKED:
if(player.p.health < 10 && playerUseEnergy(3)){
healPlayer(4);
--item->countLevel;
}
return 0;
//special item
case ITEM_WIZARD_SUMMON:
if(currentLevel==0) {
--item->countLevel;
airWizardHealthDisplay = 2000;
addEntityToList(newAirWizardEntity(630, 820, 0), &eManager);
} }
return 0; return 0;
} }
@ -569,9 +747,25 @@ s8 itemTileInteract(int tile, Item* item, int x, int y, int px, int py, int dir)
setData(rand()%4,x,y); // determines mirroring. setData(rand()%4,x,y); // determines mirroring.
return 1; return 1;
} }
else if(item->id == ITEM_WOOD){ else if(item->id == ITEM_WALL_WOOD){
setTile(TILE_WOOD_WALL,x,y); --item->countLevel; setTile(TILE_WOOD_WALL,x,y); --item->countLevel;
return 1; return 1;
}
else if(item->id == ITEM_WALL_STONE){
setTile(TILE_STONE_WALL,x,y); --item->countLevel;
return 1;
}
else if(item->id == ITEM_WALL_IRON){
setTile(TILE_IRON_WALL,x,y); --item->countLevel;
return 1;
}
else if(item->id == ITEM_WALL_GOLD){
setTile(TILE_GOLD_WALL,x,y); --item->countLevel;
return 1;
}
else if(item->id == ITEM_WALL_GEM){
setTile(TILE_GEM_WALL,x,y); --item->countLevel;
return 1;
} }
else if(item->id == TOOL_SHOVEL && playerUseEnergy(4-item->countLevel)){ else if(item->id == TOOL_SHOVEL && playerUseEnergy(4-item->countLevel)){
if(rand()%5==0)addEntityToList(newItemEntity(newItem(ITEM_SEEDS,1),(x<<4)+8, (y<<4)+8,currentLevel),&eManager); if(rand()%5==0)addEntityToList(newItemEntity(newItem(ITEM_SEEDS,1),(x<<4)+8, (y<<4)+8,currentLevel),&eManager);
@ -590,13 +784,29 @@ s8 itemTileInteract(int tile, Item* item, int x, int y, int px, int py, int dir)
return 1; return 1;
} break; } break;
case TILE_DIRT: case TILE_DIRT:
if(item->id == TOOL_HOE && playerUseEnergy(4-item->countLevel)){ if(item->id == TOOL_HOE && currentLevel==1 && playerUseEnergy(4-item->countLevel)){
setTile(TILE_FARM,x,y); setTile(TILE_FARM,x,y);
return 1; return 1;
} }
else if(item->id == ITEM_WOOD){ else if(item->id == ITEM_WALL_WOOD){
setTile(TILE_WOOD_WALL,x,y); --item->countLevel; setTile(TILE_WOOD_WALL,x,y); --item->countLevel;
return 1; return 1;
}
else if(item->id == ITEM_WALL_STONE){
setTile(TILE_STONE_WALL,x,y); --item->countLevel;
return 1;
}
else if(item->id == ITEM_WALL_IRON){
setTile(TILE_IRON_WALL,x,y); --item->countLevel;
return 1;
}
else if(item->id == ITEM_WALL_GOLD){
setTile(TILE_GOLD_WALL,x,y); --item->countLevel;
return 1;
}
else if(item->id == ITEM_WALL_GEM){
setTile(TILE_GEM_WALL,x,y); --item->countLevel;
return 1;
} }
else if(item->id == ITEM_SAND){ else if(item->id == ITEM_SAND){
setTile(TILE_SAND,x,y); --item->countLevel; setTile(TILE_SAND,x,y); --item->countLevel;
@ -673,6 +883,26 @@ s8 itemTileInteract(int tile, Item* item, int x, int y, int px, int py, int dir)
playerHurtTile(tile, x, y, (rand()%10) + (item->countLevel) * 5 + 10, player.p.dir); playerHurtTile(tile, x, y, (rand()%10) + (item->countLevel) * 5 + 10, player.p.dir);
return 1; return 1;
} break; } break;
case TILE_STONE_WALL:
if(item->id == TOOL_PICKAXE && playerUseEnergy(4-item->countLevel)){
playerHurtTile(tile, x, y, (rand()%10) + (item->countLevel) * 5 + 10, player.p.dir);
return 1;
} break;
case TILE_IRON_WALL:
if(item->id == TOOL_PICKAXE && playerUseEnergy(4-item->countLevel)){
playerHurtTile(tile, x, y, (rand()%10) + (item->countLevel) * 5 + 10, player.p.dir);
return 1;
} break;
case TILE_GOLD_WALL:
if(item->id == TOOL_PICKAXE && playerUseEnergy(4-item->countLevel)){
playerHurtTile(tile, x, y, (rand()%10) + (item->countLevel) * 5 + 10, player.p.dir);
return 1;
} break;
case TILE_GEM_WALL:
if(item->id == TOOL_PICKAXE && playerUseEnergy(4-item->countLevel)){
playerHurtTile(tile, x, y, (rand()%10) + (item->countLevel) * 5 + 10, player.p.dir);
return 1;
} break;
} }
return 0; return 0;
} }
@ -685,6 +915,17 @@ void tickTile(int x, int y){
case TILE_SAPLING_TREE: case TILE_SAPLING_TREE:
setData(++data,x,y); if(data>100){setData(0,x,y); setTile(TILE_TREE,x,y);} setData(++data,x,y); if(data>100){setData(0,x,y); setTile(TILE_TREE,x,y);}
break; break;
case TILE_TREE:
if(eManager.lastSlot[currentLevel]<800 && (daytime>18000 || daytime<5000) && rand()%800==0) {
//check for nearby glowworms
int i = 0;
for (i = 0; i < eManager.lastSlot[currentLevel]; ++i) {
Entity * e = &eManager.entities[currentLevel][i];
if(e->type==ENTITY_GLOWWORM && ((e->x)-(x<<4))*((e->x)-(x<<4))+((e->y)-(y<<4))*((e->y)-(y<<4)) < (2<<4)*(2<<4)) return;
}
addEntityToList(newGlowwormEntity((x<<4)+8,(y<<4)+8,currentLevel), &eManager);
}
break;
case TILE_SAPLING_CACTUS: case TILE_SAPLING_CACTUS:
setData(++data,x,y); if(data>100){setData(0,x,y); setTile(TILE_CACTUS,x,y);} setData(++data,x,y); if(data>100){setData(0,x,y); setTile(TILE_CACTUS,x,y);}
break; break;
@ -705,7 +946,6 @@ void tickTile(int x, int y){
if(getTile(x+1,y)==TILE_WATER || getTile(x-1,y)==TILE_WATER || getTile(x,y+1)==TILE_WATER || getTile(x,y-1)==TILE_WATER) { if(getTile(x+1,y)==TILE_WATER || getTile(x-1,y)==TILE_WATER || getTile(x,y+1)==TILE_WATER || getTile(x,y-1)==TILE_WATER) {
setTile(TILE_ROCK,x,y); setTile(TILE_ROCK,x,y);
setData(0,x,y);
} }
break; break;
case TILE_HOLE: // This makes water flow slightly faster than lava case TILE_HOLE: // This makes water flow slightly faster than lava
@ -723,6 +963,9 @@ void tickTile(int x, int y){
case TILE_SAND: case TILE_SAND:
if(data > 0) setData(--data,x,y); if(data > 0) setData(--data,x,y);
break; break;
case TILE_CLOUD:
if((rand()%24000)==0) setTile(TILE_CLOUDCACTUS,x,y);
break;
} }
} }
@ -786,34 +1029,65 @@ void tickEntity(Entity* e){
case ENTITY_ITEM: tickEntityItem(e); return; case ENTITY_ITEM: tickEntityItem(e); return;
case ENTITY_FURNITURE: return; case ENTITY_FURNITURE: return;
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
case ENTITY_SKELETON:
case ENTITY_KNIGHT:
if (e->hurtTime > 0) e->hurtTime--; if (e->hurtTime > 0) e->hurtTime--;
if (e->zombie.randWalkTime == 0) { if (e->hostile.randWalkTime == 0 && e->type != ENTITY_SKELETON) {
int xd = player.x - e->x; int xd = player.x - e->x;
int yd = player.y - e->y; int yd = player.y - e->y;
if (xd * xd + yd * yd < 50 * 50) { int dist = 50 * 50;
e->zombie.xa = 0; if(e->type == ENTITY_KNIGHT) dist = 80 * 80;
e->zombie.ya = 0;
if (xd < 0) e->zombie.xa = -1; //charge player
if (xd > 0) e->zombie.xa = +1; if (xd * xd + yd * yd < dist) {
if (yd < 0) e->zombie.ya = -1; e->hostile.xa = 0;
if (yd > 0) e->zombie.ya = +1; e->hostile.ya = 0;
if (xd < 0) e->hostile.xa = -1;
if (xd > 0) e->hostile.xa = +1;
if (yd < 0) e->hostile.ya = -1;
if (yd > 0) e->hostile.ya = +1;
} }
} }
if(e->zombie.xa < 0) e->zombie.dir = 2; if(e->hostile.xa < 0) e->hostile.dir = 2;
else if(e->zombie.xa > 0) e->zombie.dir = 3; else if(e->hostile.xa > 0) e->hostile.dir = 3;
if(e->zombie.ya < 0) e->zombie.dir = 1; if(e->hostile.ya < 0) e->hostile.dir = 1;
else if(e->zombie.ya > 0) e->zombie.dir = 0; else if(e->hostile.ya > 0) e->hostile.dir = 0;
if(e->zombie.xa != 0 || e->zombie.ya != 0) e->zombie.walkDist++; if(e->type == ENTITY_SKELETON) {
--(e->hostile.randAttackTime);
if(e->hostile.randAttackTime <= 0) {
e->hostile.randAttackTime = 70 - (e->hostile.lvl * 10);
int aitemID = ITEM_ARROW_WOOD;
if(e->hostile.lvl >= 2) aitemID = ITEM_ARROW_STONE;
switch(e->hostile.dir) {
case 0:
addEntityToList(newArrowEntity(e, aitemID, 0, 2, e->level), &eManager);
break;
case 1:
addEntityToList(newArrowEntity(e, aitemID, 0, -2, e->level), &eManager);
break;
case 2:
addEntityToList(newArrowEntity(e, aitemID, -2, 0, e->level), &eManager);
break;
case 3:
addEntityToList(newArrowEntity(e, aitemID, 2, 0, e->level), &eManager);
break;
}
}
}
if(e->hostile.xa != 0 || e->hostile.ya != 0) e->hostile.walkDist++;
int speed = tickCount & 1; int speed = tickCount & 1;
if (!moveMob(e, e->zombie.xa * speed, e->zombie.ya * speed) || (rand()%100) == 0) { if (!moveMob(e, e->hostile.xa * speed, e->hostile.ya * speed) || (rand()%100) == 0) {
e->zombie.randWalkTime = 60; e->hostile.randWalkTime = 60;
e->zombie.xa = ((rand()%3) - 1) * (rand()%2); e->hostile.xa = ((rand()%3) - 1) * (rand()%2);
e->zombie.ya = ((rand()%3) - 1) * (rand()%2); e->hostile.ya = ((rand()%3) - 1) * (rand()%2);
} }
if (e->zombie.randWalkTime > 0) e->zombie.randWalkTime--; if (e->hostile.randWalkTime > 0) e->hostile.randWalkTime--;
return; return;
case ENTITY_SLIME: case ENTITY_SLIME:
if (e->hurtTime > 0) e->hurtTime--; if (e->hurtTime > 0) e->hurtTime--;
@ -939,6 +1213,74 @@ void tickEntity(Entity* e){
removeEntityFromList(e,e->level,&eManager); removeEntityFromList(e,e->level,&eManager);
} }
return; return;
case ENTITY_ARROW:
e->arrow.age++;
if (e->arrow.age >= 260 || !move(e, e->arrow.xa, e->arrow.ya)) {
removeEntityFromList(e,e->level,&eManager);
return;
}
return;
case ENTITY_PASSIVE:
if (e->hurtTime > 0) e->hurtTime--;
if (e->passive.randWalkTime == 0) {
int xd = player.x - e->x;
int yd = player.y - e->y;
//flee from player
if (xd * xd + yd * yd < 40 * 40) {
e->passive.xa = 0;
e->passive.ya = 0;
if (xd < 0) e->passive.xa = +1;
if (xd > 0) e->passive.xa = -1;
if (yd < 0) e->passive.ya = +1;
if (yd > 0) e->passive.ya = -1;
}
}
if(e->passive.xa < 0) e->passive.dir = 2;
else if(e->passive.xa > 0) e->passive.dir = 3;
if(e->passive.ya < 0) e->passive.dir = 1;
else if(e->passive.ya > 0) e->passive.dir = 0;
if(e->passive.xa != 0 || e->passive.ya != 0) e->passive.walkDist++;
int pspeed = tickCount & 1;
if (!moveMob(e, e->passive.xa * pspeed, e->passive.ya * pspeed) || (rand()%100) == 0) {
e->passive.randWalkTime = 60;
e->passive.xa = ((rand()%3) - 1) * (rand()%2);
e->passive.ya = ((rand()%3) - 1) * (rand()%2);
}
if (e->passive.randWalkTime > 0) e->passive.randWalkTime--;
return;
case ENTITY_GLOWWORM:
if(daytime>5000 && daytime<6000) {
if(rand()%200==0) removeEntityFromList(e,e->level,&eManager);
} else if(daytime>6000 && daytime<18000) {
removeEntityFromList(e,e->level,&eManager);
}
int gspeed = (((tickCount & 0x3) == 3) ? 1 : 0);
if (!moveMob(e, e->glowworm.xa * gspeed, e->glowworm.ya * gspeed) || (e->glowworm.randWalkTime==0) || (rand()%20) == 0) {
if(e->glowworm.randWalkTime != 0) {
e->glowworm.waitTime = 20 + (rand()%60);
}
if(e->glowworm.waitTime == 0 || getTile((e->x)>>4,(e->y)>>4)!=TILE_TREE) {
e->glowworm.randWalkTime = 20;
e->glowworm.xa = ((rand()%3) - 1) * (rand()%2);
e->glowworm.ya = ((rand()%3) - 1) * (rand()%2);
} else {
e->glowworm.xa = 0;
e->glowworm.ya = 0;
}
}
if (e->glowworm.randWalkTime > 0) {
e->glowworm.randWalkTime--;
if(e->glowworm.randWalkTime==0 && (e->glowworm.xa != 0 || e->glowworm.xa != 0)) {
e->glowworm.waitTime = 120 + (rand()%60);
}
} else if (e->glowworm.waitTime > 0) {
e->glowworm.waitTime--;
}
return;
case ENTITY_TEXTPARTICLE: tickEntityTextParticle(e); return; case ENTITY_TEXTPARTICLE: tickEntityTextParticle(e); return;
case ENTITY_SMASHPARTICLE: case ENTITY_SMASHPARTICLE:
++e->smashParticle.age; ++e->smashParticle.age;
@ -959,6 +1301,9 @@ void trySpawn(int count, int level) {
else if (level == 0) { else if (level == 0) {
minLevel = maxLevel = 4; minLevel = maxLevel = 4;
} }
if(level > 4) {
minLevel = maxLevel = 4;
}
int rx = rand()%128; int rx = rand()%128;
int ry = rand()%128; int ry = rand()%128;
@ -968,9 +1313,30 @@ void trySpawn(int count, int level) {
if(level == currentLevel && (ex > player.x-160 && ey > player.y-125 && ex < player.x+160 && ey < player.y+125)) continue; if(level == currentLevel && (ex > player.x-160 && ey > player.y-125 && ex < player.x+160 && ey < player.y+125)) continue;
if (!tileIsSolid(map[level][rx+ry*128],&e)) { if (!tileIsSolid(map[level][rx+ry*128],&e)) {
if(level==1 && (rand()%2)==0) { //passive entities on overworld
e = newPassiveEntity(rand()%3, ex, ey, level);
} else {
int lvl = (rand()%(maxLevel - minLevel + 1)) + minLevel; int lvl = (rand()%(maxLevel - minLevel + 1)) + minLevel;
if ((rand()%2) == 0) e = newSlimeEntity(lvl, ex, ey, level); int randMax = 1;
else e = newZombieEntity(lvl, ex, ey, level);
if(level>1 || level==0) randMax = 2;
if(level>3) randMax = 3;
switch (rand()%(randMax+1)) {
case 0:
e = newSlimeEntity(lvl, ex, ey, level);
break;
case 1:
e = newZombieEntity(lvl, ex, ey, level);
break;
case 2:
e = newSkeletonEntity(lvl, ex, ey, level);
break;
case 3:
e = newKnightEntity(lvl, ex, ey, level);
break;
}
}
addEntityToList(e, &eManager); addEntityToList(e, &eManager);
} }
} }
@ -984,6 +1350,7 @@ int getTile(int x, int y){
void setTile(int id, int x, int y){ void setTile(int id, int x, int y){
if(x < 0 || y < 0 || x > 128 || y > 128) return; if(x < 0 || y < 0 || x > 128 || y > 128) return;
map[currentLevel][x+y*128] = id; map[currentLevel][x+y*128] = id;
data[currentLevel][x+y*128] = 0; //reset data(set again if needed, hopefully this breaks nothing)
sf2d_set_pixel(minimap[currentLevel], x, y, getTileColor(id)); sf2d_set_pixel(minimap[currentLevel], x, y, getTileColor(id));
} }
int getData(int x, int y){ int getData(int x, int y){
@ -1108,7 +1475,8 @@ void playerHurtTile(int tile, int xt, int yt, int damage, int dir){
if(getData(xt,yt) > 0){ if(getData(xt,yt) > 0){
int count = rand() & 1; int count = rand() & 1;
if (getData(xt,yt) >= (rand()%10) + 3) { if (getData(xt,yt) >= (rand()%10) + 3) {
setTile(TILE_DIRT,xt,yt); if(currentLevel!=5) setTile(TILE_DIRT,xt,yt);
else setTile(TILE_DUNGEON_FLOOR,xt,yt);
count += 2; count += 2;
} }
addItemsToWorld(newItem(ITEM_IRONORE,1),(xt<<4)+8,(yt<<4)+8,count); addItemsToWorld(newItem(ITEM_IRONORE,1),(xt<<4)+8,(yt<<4)+8,count);
@ -1122,7 +1490,8 @@ void playerHurtTile(int tile, int xt, int yt, int damage, int dir){
if(getData(xt,yt) > 0){ if(getData(xt,yt) > 0){
int count = rand() & 1; int count = rand() & 1;
if (getData(xt,yt) >= (rand()%10) + 3) { if (getData(xt,yt) >= (rand()%10) + 3) {
setTile(TILE_DIRT,xt,yt); if(currentLevel!=5) setTile(TILE_DIRT,xt,yt);
else setTile(TILE_DUNGEON_FLOOR,xt,yt);
count += 2; count += 2;
} }
addItemsToWorld(newItem(ITEM_GOLDORE,1),(xt<<4)+8,(yt<<4)+8,count); addItemsToWorld(newItem(ITEM_GOLDORE,1),(xt<<4)+8,(yt<<4)+8,count);
@ -1136,7 +1505,8 @@ void playerHurtTile(int tile, int xt, int yt, int damage, int dir){
if(getData(xt,yt) > 0){ if(getData(xt,yt) > 0){
int count = rand() & 1; int count = rand() & 1;
if (getData(xt,yt) >= (rand()%10) + 3) { if (getData(xt,yt) >= (rand()%10) + 3) {
setTile(TILE_DIRT,xt,yt); if(currentLevel!=5) setTile(TILE_DIRT,xt,yt);
else setTile(TILE_DUNGEON_FLOOR,xt,yt);
count += 2; count += 2;
} }
addItemsToWorld(newItem(ITEM_GEM,1),(xt<<4)+8,(yt<<4)+8,count); addItemsToWorld(newItem(ITEM_GEM,1),(xt<<4)+8,(yt<<4)+8,count);
@ -1187,7 +1557,47 @@ void playerHurtTile(int tile, int xt, int yt, int damage, int dir){
setData(getData(xt,yt)+damage,xt,yt); setData(getData(xt,yt)+damage,xt,yt);
if(getData(xt,yt) > 20){ if(getData(xt,yt) > 20){
setTile(TILE_DIRT,xt,yt); setTile(TILE_DIRT,xt,yt);
addItemsToWorld(newItem(ITEM_WOOD,1),(xt<<4)+8,(yt<<4)+8,1); addItemsToWorld(newItem(ITEM_WALL_WOOD,1),(xt<<4)+8,(yt<<4)+8,1);
}
break;
case TILE_STONE_WALL:
sprintf(hurtText, "%d", damage);
addEntityToList(newTextParticleEntity(hurtText,0xFF0000FF,xt<<4,yt<<4,currentLevel), &eManager);
addEntityToList(newSmashParticleEntity(xt<<4,yt<<4,currentLevel), &eManager);
setData(getData(xt,yt)+damage,xt,yt);
if(getData(xt,yt) > 30){
setTile(TILE_DIRT,xt,yt);
addItemsToWorld(newItem(ITEM_WALL_STONE,1),(xt<<4)+8,(yt<<4)+8,1);
}
break;
case TILE_IRON_WALL:
sprintf(hurtText, "%d", damage);
addEntityToList(newTextParticleEntity(hurtText,0xFF0000FF,xt<<4,yt<<4,currentLevel), &eManager);
addEntityToList(newSmashParticleEntity(xt<<4,yt<<4,currentLevel), &eManager);
setData(getData(xt,yt)+damage,xt,yt);
if(getData(xt,yt) > 40){
setTile(TILE_DIRT,xt,yt);
addItemsToWorld(newItem(ITEM_WALL_IRON,1),(xt<<4)+8,(yt<<4)+8,1);
}
break;
case TILE_GOLD_WALL:
sprintf(hurtText, "%d", damage);
addEntityToList(newTextParticleEntity(hurtText,0xFF0000FF,xt<<4,yt<<4,currentLevel), &eManager);
addEntityToList(newSmashParticleEntity(xt<<4,yt<<4,currentLevel), &eManager);
setData(getData(xt,yt)+damage,xt,yt);
if(getData(xt,yt) > 50){
setTile(TILE_DIRT,xt,yt);
addItemsToWorld(newItem(ITEM_WALL_GOLD,1),(xt<<4)+8,(yt<<4)+8,1);
}
break;
case TILE_GEM_WALL:
sprintf(hurtText, "%d", damage);
addEntityToList(newTextParticleEntity(hurtText,0xFF0000FF,xt<<4,yt<<4,currentLevel), &eManager);
addEntityToList(newSmashParticleEntity(xt<<4,yt<<4,currentLevel), &eManager);
setData(getData(xt,yt)+damage,xt,yt);
if(getData(xt,yt) > 60){
setTile(TILE_DIRT,xt,yt);
addItemsToWorld(newItem(ITEM_WALL_GEM,1),(xt<<4)+8,(yt<<4)+8,1);
} }
break; break;
} }
@ -1206,6 +1616,8 @@ void playerAttack(){
int yo = -2; int yo = -2;
int range = 12; int range = 12;
if(playerUseItem()) return;
switch(player.p.dir){ switch(player.p.dir){
case 0: if(interact(player.x - 8, player.y + 4 + yo, player.x + 8, player.y + range + yo)) return; break; case 0: if(interact(player.x - 8, player.y + 4 + yo, player.x + 8, player.y + range + yo)) return; break;
case 1: if(interact(player.x - 8, player.y - range + yo, player.x + 8, player.y - 4 + yo)) return; break; case 1: if(interact(player.x - 8, player.y - range + yo, player.x + 8, player.y - 4 + yo)) return; break;
@ -1259,7 +1671,7 @@ void switchLevel(s8 change){
else if(currentLevel > 1) sf2d_set_clear_color(0xFF666666); //sf2d_set_clear_color(RGBA8(0x66, 0x66, 0x66, 0xFF)); else if(currentLevel > 1) sf2d_set_clear_color(0xFF666666); //sf2d_set_clear_color(RGBA8(0x66, 0x66, 0x66, 0xFF));
else sf2d_set_clear_color(0xFF007F00); //sf2d_set_clear_color(RGBA8(0x00, 0x7F, 0x00, 0xFF)); else sf2d_set_clear_color(0xFF007F00); //sf2d_set_clear_color(RGBA8(0x00, 0x7F, 0x00, 0xFF));
updateMusic(currentLevel); updateMusic(currentLevel, daytime);
} }
bool playerIntersectsEntity(Entity* e){ bool playerIntersectsEntity(Entity* e){
@ -1328,7 +1740,14 @@ void entityTileInteract(Entity*e, int tile, int x, int y){
} }
return; return;
case TILE_SAND: case TILE_SAND:
if(e->type != ENTITY_ARROW && e->type != ENTITY_ITEM) {
setData(10,x,y); setData(10,x,y);
}
return;
case TILE_DUNGEON_ENTRANCE:
if(e->type == ENTITY_PLAYER) {
currentMenu = MENU_DUNGEON;
}
return; return;
} }
} }
@ -1382,6 +1801,18 @@ bool useEntity(Entity* e) {
curChestEntity->entityFurniture.r = 0; curChestEntity->entityFurniture.r = 0;
curChestEntity->entityFurniture.oSel = 0; curChestEntity->entityFurniture.oSel = 0;
currentMenu = MENU_CONTAINER; currentMenu = MENU_CONTAINER;
return true;
case ITEM_LOOM:
currentRecipes = &loomRecipes;
currentMenu = MENU_CRAFTING;
checkCanCraftRecipes(currentRecipes, player.p.inv);
sortRecipes(currentRecipes);
return true;
case ITEM_ENCHANTER:
currentRecipes = &enchanterRecipes;
currentMenu = MENU_CRAFTING;
checkCanCraftRecipes(currentRecipes, player.p.inv);
sortRecipes(currentRecipes);
return true; return true;
} }
} }
@ -1491,10 +1922,95 @@ bool isSwimming(){
void playerSetActiveItem(Item * item) { void playerSetActiveItem(Item * item) {
player.p.activeItem = item; player.p.activeItem = item;
if(player.p.activeItem->id > 27 && player.p.activeItem->id < 34) player.p.isCarrying = true; if(player.p.activeItem->id > 27 && player.p.activeItem->id < 51) player.p.isCarrying = true;
else player.p.isCarrying = false; else player.p.isCarrying = false;
} }
void enterDungeon() {
currentLevel = 5;
createDungeonMap(128, 128, map[5], data[5]);
initMinimapLevel(5, false);
newSeed();
//reset Entities
(&eManager)->lastSlot[5] = 0;
(&eManager)->entities[5][0] = nullEntity;
trySpawn(500, 5);
player.x = ((128/2) << 4) + 8;
player.y = ((128/2) << 4) + 8;
updateMusic(currentLevel, daytime);
}
void leaveDungeon() {
currentLevel = 4;
//reset Entities
(&eManager)->lastSlot[5] = 0;
(&eManager)->entities[5][0] = nullEntity;
player.x = ((128/2) << 4) + 8;
player.y = ((128/2) << 4) + 8;
updateMusic(currentLevel, daytime);
}
void initMinimapLevel(int level, bool loadUpWorld) {
int x;
int y;
//Create Dungeon entrance(not located in mapgen, so it can also be created in old worlds)
if(level==4) {
map[level][64 + 64 * 128] = TILE_DUNGEON_ENTRANCE;
map[level][63 + 64 * 128] = TILE_DIRT;
map[level][65 + 64 * 128] = TILE_DIRT;
map[level][64 + 63 * 128] = TILE_DIRT;
map[level][64 + 65 * 128] = TILE_DIRT;
map[level][63 + 63 * 128] = TILE_DUNGEON_WALL;
map[level][63 + 65 * 128] = TILE_DUNGEON_WALL;
map[level][65 + 63 * 128] = TILE_DUNGEON_WALL;
map[level][65 + 65 * 128] = TILE_DUNGEON_WALL;
}
for (x = 0; x < 128; ++x) {
for (y = 0; y < 128; ++y) {
if (!loadUpWorld) { // generate stairs up when making a new world.
switch (map[level][x + y * 128]) {
case TILE_STAIRS_DOWN:
if(level < 4) {
map[level + 1][x + y * 128] = TILE_STAIRS_UP;
if (level == 0) {
map[level + 1][(x + 1) + y * 128] = TILE_HARDROCK;
map[level + 1][x + (y + 1) * 128] = TILE_HARDROCK;
map[level + 1][(x - 1) + y * 128] = TILE_HARDROCK;
map[level + 1][x + (y - 1) * 128] = TILE_HARDROCK;
map[level + 1][(x + 1) + (y + 1) * 128] = TILE_HARDROCK;
map[level + 1][(x - 1) + (y - 1) * 128] = TILE_HARDROCK;
map[level + 1][(x - 1) + (y + 1) * 128] = TILE_HARDROCK;
map[level + 1][(x + 1) + (y - 1) * 128] = TILE_HARDROCK;
} else {
map[level + 1][(x + 1) + y * 128] = TILE_DIRT;
map[level + 1][x + (y + 1) * 128] = TILE_DIRT;
map[level + 1][(x - 1) + y * 128] = TILE_DIRT;
map[level + 1][x + (y - 1) * 128] = TILE_DIRT;
map[level + 1][(x + 1) + (y + 1) * 128] = TILE_DIRT;
map[level + 1][(x - 1) + (y - 1) * 128] = TILE_DIRT;
map[level + 1][(x - 1) + (y + 1) * 128] = TILE_DIRT;
map[level + 1][(x + 1) + (y - 1) * 128] = TILE_DIRT;
}
}
}
}
/* Minimaps */
sf2d_set_pixel(minimap[level], x, y, getTileColor(map[level][x + y * 128]));
}
}
}
void reloadColors() { void reloadColors() {
dirtColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 0)); dirtColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 0));
dirtColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 1)); dirtColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 1));
@ -1518,4 +2034,11 @@ void reloadColors() {
rockColor[3] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 3)); rockColor[3] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 3));
woodColor = SWAP_UINT32(sf2d_get_pixel(icons, 22, 0)); woodColor = SWAP_UINT32(sf2d_get_pixel(icons, 22, 0));
ironColor = SWAP_UINT32(sf2d_get_pixel(icons, 23, 0));
goldColor = SWAP_UINT32(sf2d_get_pixel(icons, 23, 1));
gemColor = SWAP_UINT32(sf2d_get_pixel(icons, 23, 2));
dungeonColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 0));
dungeonColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 1));
} }

View file

@ -2,6 +2,7 @@
#include <3ds.h> #include <3ds.h>
#include "SaveLoad.h" #include "SaveLoad.h"
#include "Input.h" #include "Input.h"
#include "MapGen.h"
#include "icons2_png.h" #include "icons2_png.h"
#include "Font_png.h" #include "Font_png.h"
@ -24,6 +25,7 @@
#define MENU_LOADGAME 11 #define MENU_LOADGAME 11
#define MENU_SETTINGS_REBIND 12 #define MENU_SETTINGS_REBIND 12
#define MENU_SETTINGS_TP 13 #define MENU_SETTINGS_TP 13
#define MENU_DUNGEON 14
#define TILE_NULL 255 #define TILE_NULL 255
#define TILE_GRASS 0 #define TILE_GRASS 0
@ -48,7 +50,15 @@
#define TILE_HARDROCK 19 #define TILE_HARDROCK 19
#define TILE_CLOUDCACTUS 20 #define TILE_CLOUDCACTUS 20
#define TILE_HOLE 21 #define TILE_HOLE 21
#define TILE_WOOD_WALL 22 #define TILE_WOOD_WALL 22
#define TILE_STONE_WALL 23
#define TILE_IRON_WALL 24
#define TILE_GOLD_WALL 25
#define TILE_GEM_WALL 26
#define TILE_DUNGEON_WALL 27
#define TILE_DUNGEON_FLOOR 28
#define TILE_DUNGEON_ENTRANCE 29
#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24)) #define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))
@ -71,9 +81,9 @@ s16 mScrollX, mScrollY;
sf2d_texture *icons; sf2d_texture *icons;
sf2d_texture *font; sf2d_texture *font;
sf2d_texture *bottombg; sf2d_texture *bottombg;
sf2d_texture * minimap[5]; sf2d_texture * minimap[6];
u8 map[5][128*128]; u8 map[6][128*128];
u8 data[5][128*128]; u8 data[6][128*128];
u32 dirtColor[5]; u32 dirtColor[5];
u32 grassColor; u32 grassColor;
@ -82,6 +92,10 @@ u32 waterColor[2];
u32 lavaColor[2]; u32 lavaColor[2];
u32 rockColor[4]; u32 rockColor[4];
u32 woodColor; u32 woodColor;
u32 ironColor;
u32 goldColor;
u32 gemColor;
u32 dungeonColor[2];
char currentFileName[256]; char currentFileName[256];
extern u8 currentMenu; extern u8 currentMenu;
@ -97,6 +111,8 @@ s16 curInvSel;
bool quitGame; bool quitGame;
s8 currentSelection; s8 currentSelection;
u16 daytime;
void tickTile(int x, int y); void tickTile(int x, int y);
bool tileIsSolid(int tile, Entity * e); bool tileIsSolid(int tile, Entity * e);
@ -131,4 +147,9 @@ bool playerIntersectsEntity(Entity* e);
void playerEntityInteract(Entity* e); void playerEntityInteract(Entity* e);
void playerSetActiveItem(Item * item); void playerSetActiveItem(Item * item);
void enterDungeon();
void leaveDungeon();
void initMinimapLevel(int level, bool loadUpWorld);
void reloadColors(); void reloadColors();

View file

@ -59,7 +59,7 @@ Item newItem(int id, int cLevel){
if(id != ITEM_NULL){ if(id != ITEM_NULL){
if(cLevel > 999) cLevel = 999; if(cLevel > 999) cLevel = 999;
item.countLevel = cLevel; item.countLevel = cLevel;
if(id < 7 || id > 27 || id > 100) item.onlyOne = true; // Tools + Furniture. if(id < 7 || (id > 27 && id < 51) || id > 100) item.onlyOne = true; // Tools + Furniture.
else item.onlyOne = false; else item.onlyOne = false;
} }
item.chestPtr = NULL; item.chestPtr = NULL;
@ -158,12 +158,36 @@ char* getItemName(int itemID, int countLevel){
case ITEM_GLASS: sprintf(currentName,"%d Glass", countLevel); return currentName; case ITEM_GLASS: sprintf(currentName,"%d Glass", countLevel); return currentName;
case ITEM_GEM: sprintf(currentName,"%d Gem", countLevel); return currentName; case ITEM_GEM: sprintf(currentName,"%d Gem", countLevel); return currentName;
case ITEM_SLIME: sprintf(currentName,"%d Slime", countLevel); return currentName; case ITEM_SLIME: sprintf(currentName,"%d Slime", countLevel); return currentName;
case ITEM_LOOM: return "Loom";
case ITEM_ENCHANTER: return "Enchanter";
case ITEM_WALL_WOOD: sprintf(currentName,"%d Wood Wall", countLevel); return currentName;
case ITEM_WALL_STONE: sprintf(currentName,"%d Stone Wall", countLevel); return currentName;
case ITEM_WALL_IRON: sprintf(currentName,"%d Iron Wall", countLevel); return currentName;
case ITEM_WALL_GOLD: sprintf(currentName,"%d Gold Wall", countLevel); return currentName;
case ITEM_WALL_GEM: sprintf(currentName,"%d Gem Wall", countLevel); return currentName;
case ITEM_WOOL: sprintf(currentName,"%d Wool", countLevel); return currentName;
case ITEM_STRING: sprintf(currentName,"%d String", countLevel); return currentName;
case ITEM_PORK_RAW: sprintf(currentName,"%d Raw Pork", countLevel); return currentName;
case ITEM_PORK_COOKED: sprintf(currentName,"%d Cooked Pork", countLevel); return currentName;
case ITEM_BEEF_RAW: sprintf(currentName,"%d Raw Beef", countLevel); return currentName;
case ITEM_BEEF_COOKED: sprintf(currentName,"%d Steak", countLevel); return currentName;
case ITEM_LEATHER: sprintf(currentName,"%d Leather", countLevel); return currentName;
case ITEM_ARROW_WOOD: sprintf(currentName,"%d Wood Arrow", countLevel); return currentName;
case ITEM_ARROW_STONE: sprintf(currentName,"%d Rock Arrow", countLevel); return currentName;
case ITEM_ARROW_IRON: sprintf(currentName,"%d Iron Arrow", countLevel); return currentName;
case ITEM_ARROW_GOLD: sprintf(currentName,"%d Gold Arrow", countLevel); return currentName;
case ITEM_ARROW_GEM: sprintf(currentName,"%d Gem Arrow", countLevel); return currentName;
case ITEM_BONE: sprintf(currentName,"%d Bone", countLevel); return currentName;
case ITEM_DUNGEON_KEY: sprintf(currentName,"%d Dungeon Key", countLevel); return currentName;
case ITEM_WIZARD_SUMMON: sprintf(currentName,"%d Wizard Summon", countLevel); return currentName;
case TOOL_BUCKET: case TOOL_BUCKET:
switch(countLevel){ switch(countLevel){
case 1: return "Water Bucket"; case 1: return "Water Bucket";
case 2: return "Lava Bucket"; case 2: return "Lava Bucket";
default: return "Empty Bucket"; default: return "Empty Bucket";
} }
case TOOL_BOW: return "Bow";
default: return ""; // null default: return ""; // null
} }
} }
@ -238,12 +262,36 @@ char* getBasicItemName(int itemID, int countLevel){
case ITEM_GLASS: return "Glass"; case ITEM_GLASS: return "Glass";
case ITEM_GEM: return "Gem"; case ITEM_GEM: return "Gem";
case ITEM_SLIME: return "Slime"; case ITEM_SLIME: return "Slime";
case ITEM_LOOM: return "Loom";
case ITEM_ENCHANTER: return "Enchanter";
case ITEM_WALL_WOOD: return "Wood Wall";
case ITEM_WALL_STONE: return "Stone Wall";
case ITEM_WALL_IRON: return "Iron Wall";
case ITEM_WALL_GOLD: return "Gold Wall";
case ITEM_WALL_GEM: return "Gem Wall";
case ITEM_WOOL: return "Wool";
case ITEM_STRING: return "String";
case ITEM_PORK_RAW: return "Raw Pork";
case ITEM_PORK_COOKED: return "Cooked Pork";
case ITEM_BEEF_RAW: return "Raw Beef";
case ITEM_BEEF_COOKED: return "Steak";
case ITEM_LEATHER: return "Leather";
case ITEM_ARROW_WOOD: return "Wood Arrow";
case ITEM_ARROW_STONE: return "Rock Arrow";
case ITEM_ARROW_IRON: return "Iron Arrow";
case ITEM_ARROW_GOLD: return "Gold Arrow";
case ITEM_ARROW_GEM: return "Gem Arrow";
case ITEM_BONE: return "Bone";
case ITEM_DUNGEON_KEY: return "Dungeon Key";
case ITEM_WIZARD_SUMMON: return "Wizard Summon";
case TOOL_BUCKET: case TOOL_BUCKET:
switch(countLevel){ switch(countLevel){
case 1: return "Water Bucket"; case 1: return "Water Bucket";
case 2: return "Lava Bucket"; case 2: return "Lava Bucket";
default: return "Empty Bucket"; default: return "Empty Bucket";
} }
case TOOL_BOW: return "Bow";
default: return ""; // null default: return ""; // null
} }

View file

@ -42,7 +42,33 @@
#define ITEM_FURNACE 31 #define ITEM_FURNACE 31
#define ITEM_WORKBENCH 32 #define ITEM_WORKBENCH 32
#define ITEM_LANTERN 33 #define ITEM_LANTERN 33
#define ITEM_LOOM 34
#define ITEM_ENCHANTER 35
#define ITEM_WALL_WOOD 51
#define ITEM_WALL_STONE 52
#define ITEM_WALL_IRON 53
#define ITEM_WALL_GOLD 54
#define ITEM_WALL_GEM 55
#define ITEM_WOOL 56
#define ITEM_STRING 57
#define ITEM_PORK_RAW 58
#define ITEM_PORK_COOKED 59
#define ITEM_BEEF_RAW 60
#define ITEM_BEEF_COOKED 61
#define ITEM_LEATHER 62
#define ITEM_ARROW_WOOD 63
#define ITEM_ARROW_STONE 64
#define ITEM_ARROW_IRON 65
#define ITEM_ARROW_GOLD 66
#define ITEM_ARROW_GEM 67
#define ITEM_BONE 68
#define ITEM_DUNGEON_KEY 69
#define ITEM_WIZARD_SUMMON 70
#define TOOL_BUCKET 101 #define TOOL_BUCKET 101
#define TOOL_BOW 102
typedef struct Inventory Inventory; typedef struct Inventory Inventory;

View file

@ -100,6 +100,21 @@ void createAndValidateUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 *
return; return;
} while (true); } while (true);
} }
void createAndValidateDungeonMap(int w, int h, u8 * map, u8 * data) {
do {
createDungeonMap(w, h, map, data);
int count[256]={[0 ... 255] = 0};
int i = 0;
for (i = 0; i < w * h; ++i)count[map[i] & 0xff]++;
if (count[TILE_DUNGEON_WALL & 0xff] < 100) continue;
if (count[TILE_DUNGEON_FLOOR & 0xff] < 100) continue;
return;
} while (true);
}
void createAndValidateSkyMap(int w, int h, u8 * map, u8 * data) { void createAndValidateSkyMap(int w, int h, u8 * map, u8 * data) {
do { do {
createSkyMap(w, h, map, data); createSkyMap(w, h, map, data);
@ -341,7 +356,151 @@ void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) {
free(noise2); free(noise2);
} }
void createSkyMap(int w, int h, u8 * map, u8 * data) {
void createDungeonRoom(int w, int h, u8 * map, u8 * data) {
int tries;
for(tries=0; tries<100; ++tries) {
int x = 5+(rand()%(w-10));
int y = 5+(rand()%(h-10));
int xr;
int yr;
int wr = 10+(rand()%11);
int hr = 10+(rand()&11);
int xp;
int yp;
int i;
if(x+wr > w-5) wr = (w-5) - x;
if(y+hr > h-5) hr = (h-5) - y;
//check instersection
bool allowed = true;
for(xr = x; xr < x+wr; ++xr) {
for(yr = y; yr < y+hr; ++yr) {
i = xr + yr * w;
//255 for paths so rooms can overlap paths
if(map[i]!=TILE_DUNGEON_WALL && map[i]!=255) {
allowed = false;
break;
}
}
if(!allowed) break;
}
if(!allowed) continue;
//create room
for(xr = x; xr < x+wr; ++xr) {
for(yr = y; yr < y+hr; ++yr) {
i = xr + yr * w;
map[i] = TILE_DUNGEON_FLOOR;
}
}
//Create path back to existing stuff
xp = x;
yp = y;
i = xp + yp * w;
bool checkForFloor = false;
bool xFirst = (rand()%2)==0;
while((checkForFloor && (map[i]!=TILE_DUNGEON_FLOOR && map[i]!=255)) || (!checkForFloor && (map[i]==TILE_DUNGEON_FLOOR || map[i]==255))) {
if(checkForFloor) {
//TODO check for dungeon entrance: if(map[i]==TILE_DUNGEON_ENTRANCE) break;
//make connection
map[i] = 255;
}
//move
if(xFirst) {
if(xp > w/2) --xp;
else if(xp < w/2) ++xp;
else if(yp > h/2) --yp;
else if(yp < h/2) ++yp;
else break;
} else {
if(yp > h/2) --yp;
else if(yp < h/2) ++yp;
else if(xp > w/2) --xp;
else if(xp < w/2) ++xp;
else break;
}
i = xp + yp * w;
//search for end of current room
if(!checkForFloor && (map[i]!=TILE_DUNGEON_FLOOR && map[i]!=255)) checkForFloor = true;
}
//dekorate room
bool lava = (rand()%4)==0;
bool pillars = (rand()%4)==0;
for(xr = x; xr < x+wr; ++xr) {
for(yr = y; yr < y+hr; ++yr) {
i = xr + yr * w;
if(lava && xr > x+1 && xr < x+wr-2 && yr > y+1 && yr < y+hr-2) {
map[i] = TILE_LAVA;
} else if(pillars && xr > x && xr < x+wr-1 && yr > y && yr < y+hr-1 && xr%2 == 0 && yr%2 == 0) {
map[i] = TILE_DUNGEON_WALL;
} else {
if(rand()%50==0) map[i] = TILE_IRONORE + (rand()%3);
}
}
}
break;
}
}
void createDungeonMap(int w, int h, u8 * map, u8 * data) {
int i, x, y;
for(x = 0; x < w; ++x){
for(y = 0; y < w; ++y){
i = x + y * w;
//Startroom
if (x >= (w/2-5) && x <= (w/2+5) && y >= (h/2-5) && y <= (h/2+5) ) {
map[i] = TILE_DUNGEON_FLOOR;
} else {
map[i] = TILE_DUNGEON_WALL;
}
data[i] = 0;
}
}
for(i = 0; i < 40; ++i) {
createDungeonRoom(w, h, map, data);
}
//replace paths with actual dungeon floor
for(x = 0; x < w; ++x){
for(y = 0; y < w; ++y){
i = x + y * w;
if (map[i]==255) {
map[i] = TILE_DUNGEON_FLOOR;
}
}
}
//create entrance
map[w/2 + h/2 * w] = TILE_DUNGEON_ENTRANCE;
map[w/2+1 + h/2 * w] = TILE_DUNGEON_FLOOR;
map[w/2-1 + h/2 * w] = TILE_DUNGEON_FLOOR;
map[w/2 + (h/2+1) * w] = TILE_DUNGEON_FLOOR;
map[w/2 + (h/2-1) * w] = TILE_DUNGEON_FLOOR;
map[w/2+1 + (h/2+1) * w] = TILE_DUNGEON_WALL;
map[w/2+1 + (h/2-1) * w] = TILE_DUNGEON_WALL;
map[w/2-1 + (h/2+1) * w] = TILE_DUNGEON_WALL;
map[w/2-1 + (h/2-1) * w] = TILE_DUNGEON_WALL;
}
void createSkyMap(int w, int h, u8 * map, u8 * data) {
double* noise1 = Noise(w, h, 8); double* noise1 = Noise(w, h, 8);
double* noise2 = Noise(w, h, 8); double* noise2 = Noise(w, h, 8);
int x, y; int x, y;
@ -399,5 +558,5 @@ void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) {
} }
free(noise1); free(noise1);
free(noise2); free(noise2);
} }

View file

@ -15,5 +15,7 @@ void createAndValidateTopMap(int w, int h, u8 * map, u8 * data);
void createTopMap(int w, int h, u8 * map, u8 * data); void createTopMap(int w, int h, u8 * map, u8 * data);
void createAndValidateUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data); void createAndValidateUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data);
void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data); void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data);
void createAndValidateDungeonMap(int w, int h, u8 * map, u8 * data);
void createDungeonMap(int w, int h, u8 * map, u8 * data);
void createAndValidateSkyMap(int w, int h, u8 * map, u8 * data); void createAndValidateSkyMap(int w, int h, u8 * map, u8 * data);
void createSkyMap(int w, int h, u8 * map, u8 * data); void createSkyMap(int w, int h, u8 * map, u8 * data);

View file

@ -366,7 +366,7 @@ void tickMenu(int menu){
currentMenu = MENU_NONE; currentMenu = MENU_NONE;
break; break;
case 1: case 1:
areYouSureSave = true; if(currentLevel!=5) areYouSureSave = true;
break; break;
case 2: case 2:
areYouSure = true; areYouSure = true;
@ -454,7 +454,7 @@ void tickMenu(int menu){
break; break;
case MENU_CONTAINER: case MENU_CONTAINER:
if (k_menu.clicked || k_decline.clicked)currentMenu = MENU_NONE; if (k_menu.clicked || k_decline.clicked) currentMenu = MENU_NONE;
if (k_left.clicked) { if (k_left.clicked) {
curChestEntity->entityFurniture.r = 0; curChestEntity->entityFurniture.r = 0;
@ -494,7 +494,28 @@ void tickMenu(int menu){
removeItemFromCurrentInv(pullItem); removeItemFromCurrentInv(pullItem);
if (curInvSel >= i1->lastSlot) curInvSel = i1->lastSlot - 1; if (curInvSel >= i1->lastSlot) curInvSel = i1->lastSlot - 1;
} }
break;
case MENU_DUNGEON:
if (k_menu.clicked || k_decline.clicked) currentMenu = MENU_NONE;
if(k_accept.clicked) {
if(currentLevel!=5) {
Item * item = getItemFromInventory(ITEM_DUNGEON_KEY, player.p.inv);
if(item!=NULL) {
--item->countLevel;
if(item->countLevel==0) {
removeItemFromCurrentInv(item);
}
enterDungeon();
}
} else {
leaveDungeon();
}
currentMenu = MENU_NONE;
}
break; break;
case MENU_LOADGAME: case MENU_LOADGAME:
@ -999,6 +1020,10 @@ void renderMenu(int menu,int xscr,int yscr){
char* msg = pOptions[i]; char* msg = pOptions[i];
u32 color = 0xFF7F7F7F; u32 color = 0xFF7F7F7F;
if(i == currentSelection) color = 0xFFFFFFFF; if(i == currentSelection) color = 0xFFFFFFFF;
if(i == 1 && currentLevel==5) {
color = 0xFF7F7FFF;
if(i == currentSelection) color = 0xFFAFAFFF;
}
drawTextColor(msg,(400 - (strlen(msg) * 12))/2, (i * 24) + 100, color); drawTextColor(msg,(400 - (strlen(msg) * 12))/2, (i * 24) + 100, color);
} }
@ -1068,6 +1093,8 @@ void renderMenu(int menu,int xscr,int yscr){
renderMenuBackground(xscr,yscr); renderMenuBackground(xscr,yscr);
offsetX = 0;offsetY = 0; offsetX = 0;offsetY = 0;
renderFrame(1,1,24,14,0xFFFF1010); renderFrame(1,1,24,14,0xFFFF1010);
drawTextColor("Inventory",24+1,14+1,0xFF000000);
drawTextColor("Inventory",24,14,0xFF6FE2E2);
renderItemList(player.p.inv, 1,1,24,14, curInvSel); renderItemList(player.p.inv, 1,1,24,14, curInvSel);
sf2d_end_frame(); sf2d_end_frame();
break; break;
@ -1082,8 +1109,14 @@ void renderMenu(int menu,int xscr,int yscr){
offsetX = 0;offsetY = 0; offsetX = 0;offsetY = 0;
renderFrame(15,1,24,4,0xFFFF1010); renderFrame(15,1,24,4,0xFFFF1010);
drawTextColor("Have",248+1,14+1,0xFF000000);
drawTextColor("Have",248,14,0xFF6FE2E2);
renderFrame(15,5,24,14,0xFFFF1010); renderFrame(15,5,24,14,0xFFFF1010);
drawTextColor("Cost",248+1,78+1,0xFF000000);
drawTextColor("Cost",248,78,0xFF6FE2E2);
renderFrame(1,1,14,14,0xFFFF1010); renderFrame(1,1,14,14,0xFFFF1010);
drawTextColor("Crafting",24+1,14+1,0xFF000000);
drawTextColor("Crafting",24,14,0xFF6FE2E2);
renderRecipes(currentRecipes, 1, 1, 14, 14, curInvSel); renderRecipes(currentRecipes, 1, 1, 14, 14, curInvSel);
Recipe* rec = &currentRecipes->recipes[curInvSel]; Recipe* rec = &currentRecipes->recipes[curInvSel];
@ -1119,15 +1152,63 @@ void renderMenu(int menu,int xscr,int yscr){
else {offsetX = 0;offsetY = 0;} else {offsetX = 0;offsetY = 0;}
renderFrame(1,1,14,14,0xFFFF1010); renderFrame(1,1,14,14,0xFFFF1010);
drawTextColor("Chest",24+1,14+1,0xFF000000);
drawTextColor("Chest",24,14,0xFF6FE2E2);
renderItemList(curChestEntity->entityFurniture.inv,1,1,14,14, renderItemList(curChestEntity->entityFurniture.inv,1,1,14,14,
curChestEntity->entityFurniture.r == 0 ? curInvSel : -curChestEntity->entityFurniture.oSel - 1); curChestEntity->entityFurniture.r == 0 ? curInvSel : -curChestEntity->entityFurniture.oSel - 1);
renderFrame(15,1,28,14,0xFFFF1010); renderFrame(15,1,28,14,0xFFFF1010);
drawTextColor("Inventory",248+1,14+1,0xFF000000);
drawTextColor("Inventory",248,14,0xFF6FE2E2);
renderItemList(player.p.inv,15,1,28,14, renderItemList(player.p.inv,15,1,28,14,
curChestEntity->entityFurniture.r == 1 ? curInvSel : -curChestEntity->entityFurniture.oSel - 1); curChestEntity->entityFurniture.r == 1 ? curInvSel : -curChestEntity->entityFurniture.oSel - 1);
offsetX = 0;offsetY = 0; offsetX = 0;offsetY = 0;
sf2d_end_frame(); sf2d_end_frame();
break; break;
case MENU_DUNGEON:
sf2d_start_frame(GFX_TOP, GFX_LEFT);
if(currentLevel == 0){
sf2d_draw_texture_part_scale(minimap[1],(-xscr/3)-256,(-yscr/3)-32,0,0,128,128,12.5,7.5);
sf2d_draw_rectangle(0,0,400,240, 0xAFDFDFDF);
}
offsetX = xscr;offsetY = yscr;
renderMenuBackground(xscr,yscr);
offsetX = 0;offsetY = 0;
renderFrame(1,1,24,14,0xFFFF1010);
if(currentLevel!=5) {
drawTextColor("Dungeon Entrance",24+1,14+1,0xFF000000);
drawTextColor("Dungeon Entrance",24,14,0xFF6FE2E2);
drawText("Warning: ", 32, 32);
drawText("You need a Dungeon Key to ", 32, 56);
drawText("enter and cannot save while ", 32, 72);
drawText("being in the Dungeon! ", 32, 88);
drawText("After leaving you will need ", 32, 112);
drawText("a new Dungeon Key for ", 32, 128);
drawText("entering another Dungeon! ", 32, 144);
drawText(" Enter", 148, 171);
} else {
drawTextColor("Dungeon Exit",24+1,14+1,0xFF000000);
drawTextColor("Dungeon Exit",24,14,0xFF6FE2E2);
drawText("Warning: ", 32, 32);
drawText("The Dungeon and everything ", 32, 56);
drawText("in it will disappear when ", 32, 72);
drawText("you leave it! ", 32, 88);
drawText("You will need a new Dungeon ", 32, 112);
drawText("Key for entering another ", 32, 128);
drawText("Dungeon again! ", 32, 144);
drawText(" Leave", 148, 171);
}
renderButtonIcon(k_accept.input & -k_accept.input, 150, 168, 1);
drawText(" Stay", 148, 195);
renderButtonIcon(k_decline.input & -k_decline.input, 150, 192, 1);
sf2d_end_frame();
break;
case MENU_ABOUT: case MENU_ABOUT:
sf2d_start_frame(GFX_TOP, GFX_LEFT); sf2d_start_frame(GFX_TOP, GFX_LEFT);
sf2d_draw_rectangle(0, 0, 400, 240, 0xFF0C0C0C); //You might think "real" black would be better, but it actually looks better that way sf2d_draw_rectangle(0, 0, 400, 240, 0xFF0C0C0C); //You might think "real" black would be better, but it actually looks better that way

View file

@ -206,24 +206,24 @@ void renderTutorialPage(bool topScreen){
render(132,82,72,152,0); // Bread render(132,82,72,152,0); // Bread
break; break;
case 6: //Mining case 6: //Mining
render16b(23,32,80,0,0,0xFFC8C8DF); // iron ore render16b(23,32,80,0,0,ironColor); // iron ore
render16b(23,52,80,0,0,0xFFB9E8E5); // gold ore render16b(23,52,80,0,0,goldColor); // gold ore
render16b(23,72,80,0,0,0xFFDE98DF); // gem ore render16b(23,72,80,0,0,gemColor); // gem ore
renderb(41,38,88,152,0,0xFFC8C8DF); // Iron ore item renderb(41,38,88,152,0,ironColor); // Iron ore item
renderb(41,58,88,152,0,0xFFB9E8E5); // Gold ore item renderb(41,58,88,152,0,goldColor); // Gold ore item
render(41,78,112,152,0); // Gem item render(41,78,112,152,0); // Gem item
drawText(">",104,74); drawText(">",104,74);
drawText(">",104,114); drawText(">",104,114);
drawText(">",104,154); drawText(">",104,154);
render16(60,32,112,128,0); // Furnace render16(60,32,112,128,0); // Furnace
render16(60,52,112,128,0); // Furnace render16(60,52,112,128,0); // Furnace
render16(60,72,64,128,0); // Anvil render16(60,72,240,128,0); // Enchanter
drawText(">",160,74); drawText(">",160,74);
drawText(">",160,114); drawText(">",160,114);
drawText(">",160,154); drawText(">",160,154);
renderb(88,36,96,152,0,0xFFC8C8DF); // Iron ingot item renderb(88,36,96,152,0,ironColor); // Iron ingot item
renderb(88,56,96,152,0,0xFFB9E8E5); // Gold ingot item renderb(88,56,96,152,0,goldColor); // Gold ingot item
renderb(88,76,152,144,0,0xFFB9E8E5); // Gem Pickaxe renderb(88,76,152,144,0,goldColor); // Gem Pickaxe
drawText(">",200,74); drawText(">",200,74);
drawText(">",200,114); drawText(">",200,114);
render16(106,32,64,128,0); // Anvil render16(106,32,64,128,0); // Anvil

View file

@ -258,20 +258,28 @@ void renderFrame(int x1, int y1, int x2, int y2, u32 bgColor) {
void bakeLights() { void bakeLights() {
playerLightBake = sf2d_create_texture(64, 64, TEXFMT_RGBA8, SF2D_PLACE_RAM); playerLightBake = sf2d_create_texture(64, 64, TEXFMT_RGBA8, SF2D_PLACE_RAM);
lanternLightBake = sf2d_create_texture(128, 128, TEXFMT_RGBA8, lanternLightBake = sf2d_create_texture(128, 128, TEXFMT_RGBA8, SF2D_PLACE_RAM);
SF2D_PLACE_RAM);
glowwormLightBake = sf2d_create_texture(16, 16, TEXFMT_RGBA8, SF2D_PLACE_RAM);
glowwormBigLightBake = sf2d_create_texture(32, 32, TEXFMT_RGBA8, SF2D_PLACE_RAM);
bakeLight(playerLightBake, 32, 32, 32); bakeLight(playerLightBake, 32, 32, 32);
bakeLight(lanternLightBake, 64, 64, 64); bakeLight(lanternLightBake, 64, 64, 64);
bakeLight(glowwormLightBake, 8, 8, 8);
bakeLight(glowwormBigLightBake, 12, 12, 12);
} }
void freeLightBakes() { void freeLightBakes() {
sf2d_free_texture(playerLightBake); sf2d_free_texture(playerLightBake);
sf2d_free_texture(lanternLightBake); sf2d_free_texture(lanternLightBake);
sf2d_free_texture(glowwormLightBake);
sf2d_free_texture(glowwormBigLightBake);
} }
void renderLightsToStencil() { void renderLightsToStencil(bool force, bool invert, bool rplayer) {
if (currentLevel > 1) { if (force || (currentLevel > 1 && currentLevel != 5)) {
GPU_SetDepthTestAndWriteMask(true, GPU_NEVER, 0); GPU_SetDepthTestAndWriteMask(true, GPU_NEVER, 0);
GPU_SetStencilTest(true, GPU_NEVER, 1, 0xFF, 0xFF); GPU_SetStencilTest(true, GPU_NEVER, 1, 0xFF, 0xFF);
GPU_SetStencilOp(GPU_STENCIL_REPLACE, GPU_STENCIL_KEEP, GPU_SetStencilOp(GPU_STENCIL_REPLACE, GPU_STENCIL_KEEP,
@ -279,40 +287,55 @@ void renderLightsToStencil() {
GPU_SetAlphaTest(true, GPU_GREATER, 0); GPU_SetAlphaTest(true, GPU_GREATER, 0);
if(player.p.activeItem->id == ITEM_LANTERN) renderLight(player.x, player.y, lanternLightBake); if(player.p.activeItem->id == ITEM_LANTERN) renderLight(player.x, player.y, lanternLightBake);
else renderLight(player.x, player.y, playerLightBake); else if(rplayer) renderLight(player.x, player.y, playerLightBake);
int i; int i;
for (i = 0; i < eManager.lastSlot[currentLevel]; ++i) { for (i = 0; i < eManager.lastSlot[currentLevel]; ++i) {
Entity e = eManager.entities[currentLevel][i]; Entity e = eManager.entities[currentLevel][i];
if (e.type != ENTITY_FURNITURE)continue; if (e.type == ENTITY_FURNITURE) {
if (e.entityFurniture.itemID == ITEM_LANTERN && e.x > player.x - 160 if (e.entityFurniture.itemID == ITEM_LANTERN && e.x > player.x - 160 && e.y > player.y - 125 && e.x < player.x + 160 && e.y < player.y + 125)
&& e.y > player.y - 125 && e.x < player.x + 160 && e.y < player.y + 125)
renderLight(e.x, e.y, lanternLightBake); renderLight(e.x, e.y, lanternLightBake);
} else if(e.type == ENTITY_GLOWWORM && e.x > player.x - 160 && e.y > player.y - 125 && e.x < player.x + 160 && e.y < player.y + 125) { //TODO could be made smaller becuase of smaller light radius
if(rand()%10==0) continue;
else if(rand()%100==0) renderLight(e.x+4, e.y-4, glowwormBigLightBake);
else renderLight(e.x, e.y, glowwormLightBake);
}
} }
int xo = offsetX >> 4; int xo = offsetX >> 4;
int yo = offsetY >> 4; int yo = offsetY >> 4;
int x, y; int x, y;
//added offset to render lights from lava which is offscreen //added offset to render lights from lava which is offscreen
//TODO: Even this is not performant enough for old 3DS, when there is a lot of lava on screen
for (x = xo-2; x <= 13 + xo+2; ++x) { for (x = xo-2; x <= 13 + xo+2; ++x) {
for (y = yo-2; y <= 8 + yo+2; ++y) for (y = yo-2; y <= 8 + yo+2; ++y) {
if(getTile(x, y) == TILE_LAVA) renderLight(x << 4, y << 4, playerLightBake); if(getTile(x, y) == TILE_LAVA) {
//experimental "speedhack"
if(getTile(x+1,y)==TILE_LAVA && getTile(x-1,y)==TILE_LAVA && getTile(x,y+1)==TILE_LAVA && getTile(x,y-1)==TILE_LAVA) {
if((x+y)%2 == 0) continue;
}
renderLight((x << 4) + 8, (y << 4) + 8, playerLightBake);
}
}
} }
GPU_SetDepthTestAndWriteMask(true, GPU_GEQUAL, GPU_WRITE_ALL); GPU_SetDepthTestAndWriteMask(true, GPU_GEQUAL, GPU_WRITE_ALL);
if(invert) {
GPU_SetStencilTest(true, GPU_EQUAL, 0, 0xFF, 0x0);
} else {
GPU_SetStencilTest(true, GPU_EQUAL, 1, 0xFF, 0x0); GPU_SetStencilTest(true, GPU_EQUAL, 1, 0xFF, 0x0);
}
GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00); GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00);
GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_REPLACE);
GPU_STENCIL_REPLACE);
} }
} }
void resetStencilStuff() { void resetStencilStuff() {
if (currentLevel > 1) { //if (currentLevel > 1) {
GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00);
GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP); GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP);
} //}
} }
void renderLight(int x, int y, sf2d_texture* texture) { void renderLight(int x, int y, sf2d_texture* texture) {
@ -507,13 +530,13 @@ void renderTile(int i, int d, int x, int y) {
render16(x, y, 112, 0, 0); render16(x, y, 112, 0, 0);
break; break;
case TILE_IRONORE: case TILE_IRONORE:
render16b(x, y, 80, 0, 0, 0xFFC8C8DF); render16b(x, y, 80, 0, 0, ironColor);
break; break;
case TILE_GOLDORE: case TILE_GOLDORE:
render16b(x, y, 80, 0, 0, 0xFFB9E8E5); render16b(x, y, 80, 0, 0, goldColor);
break; break;
case TILE_GEMORE: case TILE_GEMORE:
render16b(x, y, 80, 0, 0, 0xFFDE98DF); render16b(x, y, 80, 0, 0, gemColor);
break; break;
case TILE_CLOUD: case TILE_CLOUD:
checkSurrTiles4(x >> 4, y >> 4, TILE_CLOUD); checkSurrTiles4(x >> 4, y >> 4, TILE_CLOUD);
@ -548,6 +571,37 @@ void renderTile(int i, int d, int x, int y) {
renderConnectedTile4(x, y, 0, 32, woodColor); renderConnectedTile4(x, y, 0, 32, woodColor);
break; break;
case TILE_STONE_WALL:
checkSurrTiles4(x >> 4, y >> 4, TILE_STONE_WALL);
renderConnectedTile4(x, y, 128, 32, rockColor[0]);
break;
case TILE_IRON_WALL:
checkSurrTiles4(x >> 4, y >> 4, TILE_IRON_WALL);
renderConnectedTile4(x, y, 128, 32, ironColor);
break;
case TILE_GOLD_WALL:
checkSurrTiles4(x >> 4, y >> 4, TILE_GOLD_WALL);
renderConnectedTile4(x, y, 128, 32, goldColor);
break;
case TILE_GEM_WALL:
checkSurrTiles4(x >> 4, y >> 4, TILE_GEM_WALL);
renderConnectedTile4(x, y, 128, 32, gemColor);
break;
case TILE_DUNGEON_WALL:
checkSurrTiles8(x >> 4, y >> 4, TILE_DUNGEON_WALL);
renderConnectedTile8(x, y, 128, 32, dungeonColor[0]);
break;
case TILE_DUNGEON_FLOOR:
render16b(x, y, 208, 32, 0, dungeonColor[1]);
break;
case TILE_DUNGEON_ENTRANCE:
render16b(x, y, 224 + (currentLevel==5 ? 16 : 0), 32, 0, dungeonColor[0]);
break;
} }
resetSurrTiles(); resetSurrTiles();
@ -746,16 +800,46 @@ void renderPlayer() {
void renderMenuBackground(int xScroll, int yScroll) { void renderMenuBackground(int xScroll, int yScroll) {
sf2d_draw_rectangle(0, 0, 400, 240, 0xFF0C0C0C); //You might think "real" black would be better, but it actually looks better that way sf2d_draw_rectangle(0, 0, 400, 240, 0xFF0C0C0C); //You might think "real" black would be better, but it actually looks better that way
renderLightsToStencil(); renderLightsToStencil(false, false, true);
renderBackground(xScroll, yScroll); renderBackground(xScroll, yScroll);
resetStencilStuff(); resetStencilStuff();
renderDayNight();
}
void renderDayNight() {
if(currentLevel==1 && (daytime<6000 || daytime>18000)) {
int color1 = 0x000C0C0C;
int color2 = 0x00100C0C;
int alpha1 = 0x99;
int alpha2 = 0xDD;
if(daytime>5000 && daytime<6000) {
alpha1 = (alpha1 * (1000-(daytime-5000)))/1000;
alpha2 = (alpha2 * (1000-(daytime-5000)))/1000;
} else if(daytime>18000 && daytime<19000) {
alpha1 = (alpha1 * (daytime-18000))/1000;
alpha2 = (alpha2 * (daytime-18000))/1000;
}
color1 = color1 | (alpha1 << 24);
color2 = color2 | (alpha2 << 24);
sf2d_draw_rectangle(0, 0, 400, 240, color1); //You might think "real" black would be better, but it actually looks better that way
renderLightsToStencil(true, true, false);
sf2d_draw_rectangle(0, 0, 400, 240, color2); //You might think "real" black would be better, but it actually looks better that way
resetStencilStuff();
}
} }
void renderBackground(int xScroll, int yScroll) { void renderBackground(int xScroll, int yScroll) {
if(currentLevel > 0) sf2d_draw_rectangle(0, 0, 400, 240, dirtColor[currentLevel]); // dirt color if(currentLevel == 0) {
else {
sf2d_draw_texture_part_scale(minimap[1], (-xScroll / 3) - 256, (-yScroll / 3) - 32, 0, 0, 128, 128, 12.5, 7.5); sf2d_draw_texture_part_scale(minimap[1], (-xScroll / 3) - 256, (-yScroll / 3) - 32, 0, 0, 128, 128, 12.5, 7.5);
sf2d_draw_rectangle(0, 0, 400, 240, 0xAFDFDFDF); sf2d_draw_rectangle(0, 0, 400, 240, 0xAFDFDFDF);
} else if(currentLevel == 5) {
sf2d_draw_rectangle(0, 0, 400, 240, dungeonColor[1]);
} else {
sf2d_draw_rectangle(0, 0, 400, 240, dirtColor[currentLevel]); // dirt color
} }
int xo = xScroll >> 4; int xo = xScroll >> 4;
int yo = yScroll >> 4; int yo = yScroll >> 4;
@ -862,6 +946,12 @@ void renderFurniture(int itemID, int x, int y) {
case ITEM_LANTERN: case ITEM_LANTERN:
render16(x, y, 144, 128, 0); render16(x, y, 144, 128, 0);
break; break;
case ITEM_LOOM:
render16(x, y, 224, 128, 0);
break;
case ITEM_ENCHANTER:
render16(x, y, 240, 128, 0);
break;
} }
} }
@ -879,24 +969,50 @@ void renderEntity(Entity* e, int x, int y) {
renderFurniture(e->entityFurniture.itemID, x - 8, y - 8); renderFurniture(e->entityFurniture.itemID, x - 8, y - 8);
break; break;
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
switch (e->zombie.dir) { switch (e->hostile.dir) {
case 0: // down case 0: // down
render16b(x - 8, y - 8, 64, 112, render16b(x - 8, y - 8, 64, 112, ((e->hostile.walkDist >> 4) & 1) == 0 ? 0 : 1, e->hostile.color);
((e->zombie.walkDist >> 4) & 1) == 0 ? 0 : 1,
e->zombie.color);
break; break;
case 1: // up case 1: // up
render16b(x - 8, y - 8, 80, 112, render16b(x - 8, y - 8, 80, 112, ((e->hostile.walkDist >> 4) & 1) == 0 ? 0 : 1, e->hostile.color);
((e->zombie.walkDist >> 4) & 1) == 0 ? 0 : 1,
e->zombie.color);
break; break;
case 2: // left case 2: // left
render16b(x - 8, y - 8, 96 + (((e->zombie.walkDist >> 4) & 1) << 4), render16b(x - 8, y - 8, 96 + (((e->hostile.walkDist >> 4) & 1) << 4), 112, 1, e->hostile.color);
112, 1, e->zombie.color);
break; break;
case 3: // right case 3: // right
render16b(x - 8, y - 8, 96 + (((e->zombie.walkDist >> 4) & 1) << 4), render16b(x - 8, y - 8, 96 + (((e->hostile.walkDist >> 4) & 1) << 4), 112, 0, e->hostile.color);
112, 0, e->zombie.color); break;
}
break;
case ENTITY_SKELETON:
switch (e->hostile.dir) {
case 0: // down
render16b(x - 8, y - 8, 0, 80, ((e->hostile.walkDist >> 4) & 1) == 0 ? 0 : 1, e->hostile.color);
break;
case 1: // up
render16b(x - 8, y - 8, 16, 80, ((e->hostile.walkDist >> 4) & 1) == 0 ? 0 : 1, e->hostile.color);
break;
case 2: // left
render16b(x - 8, y - 8, 32 + (((e->hostile.walkDist >> 4) & 1) << 4), 80, 1, e->hostile.color);
break;
case 3: // right
render16b(x - 8, y - 8, 32 + (((e->hostile.walkDist >> 4) & 1) << 4), 80, 0, e->hostile.color);
break;
}
break;
case ENTITY_KNIGHT:
switch (e->hostile.dir) {
case 0: // down
render16b(x - 8, y - 8, 64, 80, ((e->hostile.walkDist >> 4) & 1) == 0 ? 0 : 1, e->hostile.color);
break;
case 1: // up
render16b(x - 8, y - 8, 80, 80, ((e->hostile.walkDist >> 4) & 1) == 0 ? 0 : 1, e->hostile.color);
break;
case 2: // left
render16b(x - 8, y - 8, 96 + (((e->hostile.walkDist >> 4) & 1) << 4), 80, 1, e->hostile.color);
break;
case 3: // right
render16b(x - 8, y - 8, 96 + (((e->hostile.walkDist >> 4) & 1) << 4), 80, 0, e->hostile.color);
break; break;
} }
break; break;
@ -932,6 +1048,22 @@ void renderEntity(Entity* e, int x, int y) {
break; break;
} }
break; break;
case ENTITY_PASSIVE:
switch (e->passive.dir) {
case 0: // down
render16(x - 8, y - 8, (e->passive.mtype*64) + 0, 96, ((e->passive.walkDist >> 4) & 1) == 0 ? 0 : 1);
break;
case 1: // up
render16(x - 8, y - 8, (e->passive.mtype*64) + 16, 96, ((e->passive.walkDist >> 4) & 1) == 0 ? 0 : 1);
break;
case 2: // left
render16(x - 8, y - 8, (e->passive.mtype*64) + 32 + (((e->passive.walkDist >> 4) & 1) << 4), 96, 1);
break;
case 3: // right
render16(x - 8, y - 8, (e->passive.mtype*64) + 32 + (((e->passive.walkDist >> 4) & 1) << 4), 96, 0);
break;
}
break;
case ENTITY_TEXTPARTICLE: case ENTITY_TEXTPARTICLE:
x -= offsetX; x -= offsetX;
y -= offsetY; y -= offsetY;
@ -949,6 +1081,45 @@ void renderEntity(Entity* e, int x, int y) {
return; return;
renderr(x, y, 200, 152, 0, e->spark.age * 0.0349); renderr(x, y, 200, 152, 0, e->spark.age * 0.0349);
break; break;
case ENTITY_ARROW:
if (e->arrow.age >= 200)
if (e->arrow.age / 6 % 2 == 0)
return;
int abits = 0;
int ayp = 168;
if(e->arrow.xa<0) {
abits += 1;
}
if(e->arrow.ya<0) {
ayp += 8;
}
if(e->arrow.ya>0) {
ayp += 8;
abits += 2;
}
switch (e->arrow.itemID) {
case ITEM_ARROW_WOOD:
render(x-2, y-2, 72, ayp, abits);
break;
case ITEM_ARROW_STONE:
render(x-2, y-2, 80, ayp, abits);
break;
case ITEM_ARROW_IRON:
render(x-2, y-2, 88, ayp, abits);
break;
case ITEM_ARROW_GOLD:
render(x-2, y-2, 96, ayp, abits);
break;
case ITEM_ARROW_GEM:
render(x-2, y-2, 104, ayp, abits);
break;
}
break;
case ENTITY_GLOWWORM:
render(x-4, y-4, 224, 112, 0);
break;
} }
} }
@ -1154,16 +1325,16 @@ void renderItemIcon(int itemID, int countLevel, int x, int y) {
renderb(x, y, 88, 152, 0, 0xFF383838); renderb(x, y, 88, 152, 0, 0xFF383838);
break; break;
case ITEM_IRONORE: case ITEM_IRONORE:
renderb(x, y, 88, 152, 0, 0xFF9999BC); renderb(x, y, 88, 152, 0, ironColor);
break; break;
case ITEM_GOLDORE: case ITEM_GOLDORE:
renderb(x, y, 88, 152, 0, 0xFF77CECE); renderb(x, y, 88, 152, 0, goldColor);
break; break;
case ITEM_IRONINGOT: case ITEM_IRONINGOT:
renderb(x, y, 96, 152, 0, 0xFFC8C8DF); renderb(x, y, 96, 152, 0, ironColor);
break; break;
case ITEM_GOLDINGOT: case ITEM_GOLDINGOT:
renderb(x, y, 96, 152, 0, 0xFFBCEAEA); renderb(x, y, 96, 152, 0, goldColor);
break; break;
case ITEM_GLASS: case ITEM_GLASS:
render(x, y, 104, 152, 0); render(x, y, 104, 152, 0);
@ -1171,8 +1342,77 @@ void renderItemIcon(int itemID, int countLevel, int x, int y) {
case ITEM_GEM: case ITEM_GEM:
render(x, y, 112, 152, 0); render(x, y, 112, 152, 0);
break; break;
case ITEM_LOOM:
render(x, y, 120, 160, 0);
break;
case ITEM_ENCHANTER:
render(x, y, 144, 160, 0);
break;
case ITEM_WALL_WOOD:
renderb(x, y, 224, 144, 0, woodColor);
break;
case ITEM_WALL_STONE:
renderb(x, y, 224, 144, 0, rockColor[1]);
break;
case ITEM_WALL_IRON:
renderb(x, y, 224, 144, 0, ironColor);
break;
case ITEM_WALL_GOLD:
renderb(x, y, 224, 144, 0, goldColor);
break;
case ITEM_WALL_GEM:
renderb(x, y, 224, 144, 0, gemColor);
break;
case ITEM_WOOL:
render(x, y, 64, 160, 0);
break;
case ITEM_STRING:
render(x, y, 72, 160, 0);
break;
case ITEM_PORK_RAW:
render(x, y, 80, 160, 0);
break;
case ITEM_PORK_COOKED:
render(x, y, 88, 160, 0);
break;
case ITEM_BEEF_RAW:
render(x, y, 96, 160, 0);
break;
case ITEM_BEEF_COOKED:
render(x, y, 104, 160, 0);
break;
case ITEM_LEATHER:
render(x, y, 112, 160, 0);
break;
case ITEM_ARROW_WOOD:
render(x, y, 72, 168, 0);
break;
case ITEM_ARROW_STONE:
render(x, y, 80, 168, 0);
break;
case ITEM_ARROW_IRON:
render(x, y, 88, 168, 0);
break;
case ITEM_ARROW_GOLD:
render(x, y, 96, 168, 0);
break;
case ITEM_ARROW_GEM:
render(x, y, 104, 168, 0);
break;
case ITEM_BONE:
render(x, y, 128, 160, 0);
break;
case ITEM_DUNGEON_KEY:
render(x, y, 136, 160, 0);
break;
case ITEM_WIZARD_SUMMON:
render(x, y, 152, 160, 0);
break;
case TOOL_BUCKET: case TOOL_BUCKET:
render(x, y, 200 + countLevel * 8, 144, 0); render(x, y, 200 + countLevel * 8, 144, 0);
break; break;
case TOOL_BOW:
render(x, y, 64, 168, 0);
break;
} }
} }

View file

@ -9,6 +9,8 @@
sf2d_texture *playerLightBake; sf2d_texture *playerLightBake;
sf2d_texture *lanternLightBake; sf2d_texture *lanternLightBake;
sf2d_texture *glowwormLightBake;
sf2d_texture *glowwormBigLightBake;
int offsetX, offsetY; int offsetX, offsetY;
void render(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits); void render(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits);
@ -31,11 +33,12 @@ void renderConnectedTile4(int x, int y, u32 xTile, u32 yTile, u32 color);
void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile, u32 color); void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile, u32 color);
void renderBackground(int xScroll, int yScroll); void renderBackground(int xScroll, int yScroll);
void renderMenuBackground(int xScroll, int yScroll); //Renders the darkness void renderMenuBackground(int xScroll, int yScroll); //Renders the darkness
void renderDayNight();
void renderButtonIcon(u32 icon, int x, int y, float scale); void renderButtonIcon(u32 icon, int x, int y, float scale);
void bakeLights(); void bakeLights();
void freeLightBakes(); void freeLightBakes();
void renderLightsToStencil(); void renderLightsToStencil(bool force, bool invert, bool rplayer);
void resetStencilStuff(); void resetStencilStuff();
void bakeLight(sf2d_texture* texture, int x, int y, int r); void bakeLight(sf2d_texture* texture, int x, int y, int r);
void renderLight(int x, int y, sf2d_texture* texture); void renderLight(int x, int y, sf2d_texture* texture);

View file

@ -8,8 +8,12 @@ s16 calculateImportantEntites(EntityManager * eManager, int level){
case ENTITY_AIRWIZARD: case ENTITY_AIRWIZARD:
case ENTITY_SLIME: case ENTITY_SLIME:
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
case ENTITY_SKELETON:
case ENTITY_KNIGHT:
case ENTITY_ITEM: case ENTITY_ITEM:
case ENTITY_FURNITURE: case ENTITY_FURNITURE:
case ENTITY_PASSIVE:
case ENTITY_GLOWWORM:
count++; count++;
break; break;
} }
@ -22,8 +26,12 @@ bool entityIsImportant(Entity * e){
case ENTITY_AIRWIZARD: case ENTITY_AIRWIZARD:
case ENTITY_SLIME: case ENTITY_SLIME:
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
case ENTITY_SKELETON:
case ENTITY_KNIGHT:
case ENTITY_ITEM: case ENTITY_ITEM:
case ENTITY_FURNITURE: case ENTITY_FURNITURE:
case ENTITY_PASSIVE:
case ENTITY_GLOWWORM:
return true; return true;
default: default:
return false; return false;
@ -75,8 +83,10 @@ void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player
fwrite(&eManager->entities[i][j].slime.lvl, sizeof(s8), 1, file); fwrite(&eManager->entities[i][j].slime.lvl, sizeof(s8), 1, file);
break; break;
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
fwrite(&eManager->entities[i][j].zombie.health, sizeof(s16), 1, file); case ENTITY_SKELETON:
fwrite(&eManager->entities[i][j].zombie.lvl, sizeof(s8), 1, file); case ENTITY_KNIGHT:
fwrite(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file);
fwrite(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file);
break; break;
case ENTITY_ITEM: case ENTITY_ITEM:
fwrite(&eManager->entities[i][j].entityItem.item.id, sizeof(s16), 1, file); fwrite(&eManager->entities[i][j].entityItem.item.id, sizeof(s16), 1, file);
@ -87,15 +97,22 @@ void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player
fwrite(&eManager->entities[i][j].entityFurniture.itemID, sizeof(s16), 1, file); fwrite(&eManager->entities[i][j].entityFurniture.itemID, sizeof(s16), 1, file);
int invIndex = eManager->entities[i][j].entityFurniture.inv - eManager->invs; int invIndex = eManager->entities[i][j].entityFurniture.inv - eManager->invs;
fwrite(&invIndex, sizeof(int), 1, file); fwrite(&invIndex, sizeof(int), 1, file);
break;
case ENTITY_PASSIVE:
fwrite(&eManager->entities[i][j].passive.health, sizeof(s16), 1, file);
fwrite(&eManager->entities[i][j].passive.mtype, sizeof(u8), 1, file);
break; break;
} }
} }
} }
// Map Data // Map Data
//Don't write or load dungeon, so only first 5 levels not 6
fwrite(map, sizeof(u8), 128*128*5, file); // Map Tile IDs, 128*128*5 bytes = 80KB fwrite(map, sizeof(u8), 128*128*5, file); // Map Tile IDs, 128*128*5 bytes = 80KB
fwrite(mapData, sizeof(u8), 128*128*5, file); // Map Tile Data (Damage done to trees/rocks, age of wheat & saplings, etc). 80KB fwrite(mapData, sizeof(u8), 128*128*5, file); // Map Tile Data (Damage done to trees/rocks, age of wheat & saplings, etc). 80KB
fwrite(&daytime, sizeof(u16), 1, file);
fclose(file); fclose(file);
} }
@ -195,21 +212,58 @@ int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * m
} }
break; break;
case ENTITY_ZOMBIE: case ENTITY_ZOMBIE:
fread(&eManager->entities[i][j].zombie.health, sizeof(s16), 1, file); fread(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file);
fread(&eManager->entities[i][j].zombie.lvl, sizeof(s8), 1, file); fread(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file);
eManager->entities[i][j].level = i; eManager->entities[i][j].level = i;
eManager->entities[i][j].hurtTime = 0; eManager->entities[i][j].hurtTime = 0;
eManager->entities[i][j].xKnockback = 0; eManager->entities[i][j].xKnockback = 0;
eManager->entities[i][j].yKnockback = 0; eManager->entities[i][j].yKnockback = 0;
eManager->entities[i][j].zombie.dir = 0; eManager->entities[i][j].hostile.dir = 0;
eManager->entities[i][j].xr = 4; eManager->entities[i][j].xr = 4;
eManager->entities[i][j].yr = 3; eManager->entities[i][j].yr = 3;
eManager->entities[i][j].canPass = false; eManager->entities[i][j].canPass = false;
switch(eManager->entities[i][j].zombie.lvl){ switch(eManager->entities[i][j].hostile.lvl){
case 2: eManager->entities[i][j].zombie.color = 0xFF8282CC; break; case 2: eManager->entities[i][j].hostile.color = 0xFF8282CC; break;
case 3: eManager->entities[i][j].zombie.color = 0xFFEFEFEF; break; case 3: eManager->entities[i][j].hostile.color = 0xFFEFEFEF; break;
case 4: eManager->entities[i][j].zombie.color = 0xFFAA6262; break; case 4: eManager->entities[i][j].hostile.color = 0xFFAA6262; break;
default: eManager->entities[i][j].zombie.color = 0xFF95DB95; break; default: eManager->entities[i][j].hostile.color = 0xFF95DB95; break;
}
break;
case ENTITY_SKELETON:
fread(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file);
fread(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file);
eManager->entities[i][j].level = i;
eManager->entities[i][j].hurtTime = 0;
eManager->entities[i][j].xKnockback = 0;
eManager->entities[i][j].yKnockback = 0;
eManager->entities[i][j].hostile.dir = 0;
eManager->entities[i][j].hostile.randAttackTime = 0;
eManager->entities[i][j].xr = 4;
eManager->entities[i][j].yr = 3;
eManager->entities[i][j].canPass = false;
switch(eManager->entities[i][j].hostile.lvl){
case 2: eManager->entities[i][j].hostile.color = 0xFFC4C4C4; break;
case 3: eManager->entities[i][j].hostile.color = 0xFFA0A0A0; break;
case 4: eManager->entities[i][j].hostile.color = 0xFF7A7A7A; break;
default: eManager->entities[i][j].hostile.color = 0xFFFFFFFF; break;
}
break;
case ENTITY_KNIGHT:
fread(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file);
fread(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file);
eManager->entities[i][j].level = i;
eManager->entities[i][j].hurtTime = 0;
eManager->entities[i][j].xKnockback = 0;
eManager->entities[i][j].yKnockback = 0;
eManager->entities[i][j].hostile.dir = 0;
eManager->entities[i][j].xr = 4;
eManager->entities[i][j].yr = 3;
eManager->entities[i][j].canPass = false;
switch(eManager->entities[i][j].hostile.lvl){
case 2: eManager->entities[i][j].hostile.color = 0xFF0000C6; break;
case 3: eManager->entities[i][j].hostile.color = 0xFF00A3C6; break;
case 4: eManager->entities[i][j].hostile.color = 0xFF707070; break;
default: eManager->entities[i][j].hostile.color = 0xFFFFFFFF; break;
} }
break; break;
case ENTITY_ITEM: case ENTITY_ITEM:
@ -239,11 +293,35 @@ int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * m
eManager->entities[i][j].canPass = false; eManager->entities[i][j].canPass = false;
if(eManager->entities[i][j].entityFurniture.itemID == ITEM_LANTERN) eManager->entities[i][j].entityFurniture.r = 8; if(eManager->entities[i][j].entityFurniture.itemID == ITEM_LANTERN) eManager->entities[i][j].entityFurniture.r = 8;
break; break;
case ENTITY_PASSIVE:
fread(&eManager->entities[i][j].passive.health, sizeof(s16), 1, file);
fread(&eManager->entities[i][j].passive.mtype, sizeof(u8), 1, file);
eManager->entities[i][j].level = i;
eManager->entities[i][j].hurtTime = 0;
eManager->entities[i][j].xKnockback = 0;
eManager->entities[i][j].yKnockback = 0;
eManager->entities[i][j].passive.dir = 0;
eManager->entities[i][j].xr = 4;
eManager->entities[i][j].yr = 3;
eManager->entities[i][j].canPass = false;
break;
case ENTITY_GLOWWORM:
eManager->entities[i][j].glowworm.xa = 0;
eManager->entities[i][j].glowworm.ya = 0;
eManager->entities[i][j].glowworm.randWalkTime = 0;
eManager->entities[i][j].glowworm.waitTime = 0;
break;
} }
} }
} }
//Don't write or load dungeon, so only first 5 levels not 6
fread(map, sizeof(u8), 128*128*5, file); fread(map, sizeof(u8), 128*128*5, file);
fread(mapData, sizeof(u8), 128*128*5, file); fread(mapData, sizeof(u8), 128*128*5, file);
//set to startvalue incase file is old and doesn't contain saved time
daytime = 6001;
fread(&daytime, sizeof(u16), 1, file);
fclose(file); fclose(file);
return 0; return 0;
} }

View file

@ -2,6 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "Entity.h" #include "Entity.h"
#include "Globals.h"
void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData); void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData);
int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData); int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData);

View file

@ -20,19 +20,21 @@ void playMusic(Sound snd){
csndPlaySound(10, SOUND_FORMAT_16BIT | SOUND_REPEAT, 44100, 1, 0, snd.buffer, snd.buffer, snd.size); csndPlaySound(10, SOUND_FORMAT_16BIT | SOUND_REPEAT, 44100, 1, 0, snd.buffer, snd.buffer, snd.size);
} }
void updateMusic(int lvl) { void updateMusic(int lvl, int time) {
switch(lvl) { switch(lvl) {
case 0: case 0:
playMusic(music_floor0); playMusic(music_floor0);
break; break;
case 1: case 1:
playMusic(music_floor1); if(time>6000 && time<19000) playMusic(music_floor1);
else playMusic(music_floor1_night);
break; break;
case 2: case 2:
case 3: case 3:
playMusic(music_floor23); playMusic(music_floor23);
break; break;
case 4: case 4:
case 5: //TODO - dungeon needs own music
playMusic(music_floor4); playMusic(music_floor4);
break; break;
} }
@ -50,6 +52,7 @@ void loadSounds() {
loadSound(&music_menu, "resources/music/menu.raw"); loadSound(&music_menu, "resources/music/menu.raw");
loadSound(&music_floor0, "resources/music/floor0.raw"); loadSound(&music_floor0, "resources/music/floor0.raw");
loadSound(&music_floor1, "resources/music/floor1.raw"); loadSound(&music_floor1, "resources/music/floor1.raw");
loadSound(&music_floor1_night, "resources/music/floor1_night.raw");
loadSound(&music_floor23, "resources/music/floor2_3.raw"); loadSound(&music_floor23, "resources/music/floor2_3.raw");
loadSound(&music_floor4, "resources/music/floor4.raw"); loadSound(&music_floor4, "resources/music/floor4.raw");
} }
@ -66,6 +69,7 @@ void freeSounds(){
linearFree(music_menu.buffer); linearFree(music_menu.buffer);
linearFree(music_floor0.buffer); linearFree(music_floor0.buffer);
linearFree(music_floor1.buffer); linearFree(music_floor1.buffer);
linearFree(music_floor1_night.buffer);
linearFree(music_floor23.buffer); linearFree(music_floor23.buffer);
linearFree(music_floor4.buffer); linearFree(music_floor4.buffer);
} }

View file

@ -14,7 +14,7 @@ void loadSound(Sound * snd, char * filename);
void playSound(Sound snd); void playSound(Sound snd);
void playMusic(Sound snd); void playMusic(Sound snd);
void updateMusic(int lvl); void updateMusic(int lvl, int time);
void loadSounds(); void loadSounds();
void freeSounds(); void freeSounds();
@ -30,5 +30,6 @@ Sound snd_craft;
Sound music_menu; Sound music_menu;
Sound music_floor0; Sound music_floor0;
Sound music_floor1; Sound music_floor1;
Sound music_floor1_night;
Sound music_floor23; Sound music_floor23;
Sound music_floor4; Sound music_floor4;

View file

@ -14,41 +14,9 @@
#include "texturepack.h" #include "texturepack.h"
void initMiniMap(bool loadUpWorld) { void initMiniMap(bool loadUpWorld) {
int i, x, y; int i;
for (i = 0; i < 5; ++i) { for (i = 0; i < 5; ++i) {
for (x = 0; x < 128; ++x) { initMinimapLevel(i, loadUpWorld);
for (y = 0; y < 128; ++y) {
if (!loadUpWorld) { // generate stairs up when making a new world.
switch (map[i][x + y * 128]) {
case TILE_STAIRS_DOWN:
map[i + 1][x + y * 128] = TILE_STAIRS_UP;
if (i == 0) {
map[i + 1][(x + 1) + y * 128] = TILE_HARDROCK;
map[i + 1][x + (y + 1) * 128] = TILE_HARDROCK;
map[i + 1][(x - 1) + y * 128] = TILE_HARDROCK;
map[i + 1][x + (y - 1) * 128] = TILE_HARDROCK;
map[i + 1][(x + 1) + (y + 1) * 128] = TILE_HARDROCK;
map[i + 1][(x - 1) + (y - 1) * 128] = TILE_HARDROCK;
map[i + 1][(x - 1) + (y + 1) * 128] = TILE_HARDROCK;
map[i + 1][(x + 1) + (y - 1) * 128] = TILE_HARDROCK;
} else {
map[i + 1][(x + 1) + y * 128] = TILE_DIRT;
map[i + 1][x + (y + 1) * 128] = TILE_DIRT;
map[i + 1][(x - 1) + y * 128] = TILE_DIRT;
map[i + 1][x + (y - 1) * 128] = TILE_DIRT;
map[i + 1][(x + 1) + (y + 1) * 128] = TILE_DIRT;
map[i + 1][(x - 1) + (y - 1) * 128] = TILE_DIRT;
map[i + 1][(x - 1) + (y + 1) * 128] = TILE_DIRT;
map[i + 1][(x + 1) + (y - 1) * 128] = TILE_DIRT;
}
}
}
/* Minimaps */
sf2d_set_pixel(minimap[i], x, y, getTileColor(map[i][x + y * 128]));
}
}
} }
} }
@ -77,12 +45,13 @@ void setupGame(bool loadUpWorld) {
trySpawn(500, i); trySpawn(500, i);
} }
addEntityToList(newAirWizardEntity(630, 820, 0), &eManager); addEntityToList(newAirWizardEntity(630, 820, 0), &eManager);
daytime = 6000;
} else { } else {
initPlayer(); initPlayer();
loadWorld(currentFileName, &eManager, &player, (u8*) map, (u8*) data); loadWorld(currentFileName, &eManager, &player, (u8*) map, (u8*) data);
} }
updateMusic(currentLevel); updateMusic(currentLevel, daytime);
initMiniMap(loadUpWorld); initMiniMap(loadUpWorld);
shouldRenderMap = false; shouldRenderMap = false;
@ -112,6 +81,17 @@ void tick() {
tickTouchMap(); tickTouchMap();
tickTouchQuickSelect(); tickTouchQuickSelect();
++daytime;
//daytime += 20;
if(daytime>=24000) {
daytime -= 24000;
}
if(daytime==6000 && currentLevel==1) {
playMusic(music_floor1);
} else if(daytime==19000 && currentLevel==1) {
playMusic(music_floor1_night);
}
int i; int i;
for (i = 0; i < 324; ++i) { for (i = 0; i < 324; ++i) {
int xx = rand() & 127; int xx = rand() & 127;
@ -130,11 +110,14 @@ void tick() {
else if (yscr > 1912) else if (yscr > 1912)
yscr = 1912; yscr = 1912;
if(eManager.lastSlot[currentLevel]<80) {
trySpawn(1, currentLevel);
}
for (i = 0; i < eManager.lastSlot[currentLevel]; ++i) { for (i = 0; i < eManager.lastSlot[currentLevel]; ++i) {
Entity * e = &eManager.entities[currentLevel][i]; Entity * e = &eManager.entities[currentLevel][i];
if ((e->type != ENTITY_ZOMBIE && e->type != ENTITY_SLIME) if ((e->type != ENTITY_ZOMBIE && e->type != ENTITY_SKELETON && e->type != ENTITY_KNIGHT && e->type != ENTITY_SLIME && e->type != ENTITY_PASSIVE && (e->type == ENTITY_GLOWWORM && (daytime>6000 || daytime<18000)))
|| (e->x > player.x - 160 && e->y > player.y - 125 || (e->x > player.x - 160 && e->y > player.y - 125 && e->x < player.x + 160 && e->y < player.y + 125))
&& e->x < player.x + 160 && e->y < player.y + 125))
tickEntity(e); tickEntity(e);
} }
@ -179,7 +162,7 @@ int main() {
int i; int i;
for (i = 0; i < 5; ++i) { for (i = 0; i < 6; ++i) {
minimap[i] = sf2d_create_texture(128, 128, TEXFMT_RGBA8, minimap[i] = sf2d_create_texture(128, 128, TEXFMT_RGBA8,
SF2D_PLACE_RAM); SF2D_PLACE_RAM);
sf2d_texture_tile32(minimap[i]); sf2d_texture_tile32(minimap[i]);
@ -248,13 +231,17 @@ int main() {
offsetX = xscr; offsetX = xscr;
offsetY = yscr; offsetY = yscr;
sf2d_draw_rectangle(0, 0, 400, 240, 0xFF0C0C0C); //RGBA8(12, 12, 12, 255)); //You might think "real" black would be better, but it actually looks better that way sf2d_draw_rectangle(0, 0, 400, 240, 0xFF0C0C0C); //RGBA8(12, 12, 12, 255)); //You might think "real" black would be better, but it actually looks better that way
renderLightsToStencil();
renderLightsToStencil(false, false, true);
renderBackground(xscr, yscr); renderBackground(xscr, yscr);
renderEntities(player.x, player.y, &eManager); renderEntities(player.x, player.y, &eManager);
renderPlayer(); renderPlayer();
resetStencilStuff(); resetStencilStuff();
renderDayNight();
offsetX = 0; offsetX = 0;
offsetY = 0; offsetY = 0;
@ -290,6 +277,7 @@ int main() {
sf2d_free_texture(minimap[2]); sf2d_free_texture(minimap[2]);
sf2d_free_texture(minimap[3]); sf2d_free_texture(minimap[3]);
sf2d_free_texture(minimap[4]); sf2d_free_texture(minimap[4]);
sf2d_free_texture(minimap[5]);
freeSounds(); freeSounds();
csndExit(); csndExit();
cfguExit(); cfguExit();