Started work on new update
Added some small new map generation features Added "NPCs" and "Quests" (atleast a first experiment for them) Added magic compass to make search for stairs leass annoying Added mostly visual season and weather effects
This commit is contained in:
parent
f6e2d30ab6
commit
3699414dcd
19 changed files with 1324 additions and 253 deletions
BIN
data/icons2.png
BIN
data/icons2.png
Binary file not shown.
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 32 KiB |
|
@ -104,7 +104,7 @@ void initRecipes(){
|
||||||
workbenchRecipes.recipes[20] = defineRecipe(ITEM_WALL_WOOD,1,1,ITEM_WOOD,4);
|
workbenchRecipes.recipes[20] = defineRecipe(ITEM_WALL_WOOD,1,1,ITEM_WOOD,4);
|
||||||
workbenchRecipes.recipes[21] = defineRecipe(ITEM_WALL_STONE,1,1,ITEM_STONE,4);
|
workbenchRecipes.recipes[21] = defineRecipe(ITEM_WALL_STONE,1,1,ITEM_STONE,4);
|
||||||
|
|
||||||
anvilRecipes.size = 16;
|
anvilRecipes.size = 17;
|
||||||
anvilRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (anvilRecipes.size));
|
anvilRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (anvilRecipes.size));
|
||||||
anvilRecipes.recipes[0] = defineRecipe(TOOL_SWORD,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
anvilRecipes.recipes[0] = defineRecipe(TOOL_SWORD,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||||
anvilRecipes.recipes[1] = defineRecipe(TOOL_AXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
anvilRecipes.recipes[1] = defineRecipe(TOOL_AXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||||
|
@ -122,6 +122,7 @@ void initRecipes(){
|
||||||
anvilRecipes.recipes[13] = defineRecipe(ITEM_ENCHANTER,1,3,ITEM_WOOD,10,ITEM_GOLDINGOT,10,ITEM_GEM,20);
|
anvilRecipes.recipes[13] = defineRecipe(ITEM_ENCHANTER,1,3,ITEM_WOOD,10,ITEM_GOLDINGOT,10,ITEM_GEM,20);
|
||||||
anvilRecipes.recipes[14] = defineRecipe(ITEM_WALL_IRON,1,1,ITEM_IRONINGOT,2);
|
anvilRecipes.recipes[14] = defineRecipe(ITEM_WALL_IRON,1,1,ITEM_IRONINGOT,2);
|
||||||
anvilRecipes.recipes[15] = defineRecipe(ITEM_WALL_GOLD,1,1,ITEM_GOLDINGOT,2);
|
anvilRecipes.recipes[15] = defineRecipe(ITEM_WALL_GOLD,1,1,ITEM_GOLDINGOT,2);
|
||||||
|
anvilRecipes.recipes[16] = defineRecipe(ITEM_COIN,3,1,ITEM_IRONINGOT,1);
|
||||||
|
|
||||||
furnaceRecipes.size = 3;
|
furnaceRecipes.size = 3;
|
||||||
furnaceRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (furnaceRecipes.size));
|
furnaceRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (furnaceRecipes.size));
|
||||||
|
@ -139,7 +140,7 @@ void initRecipes(){
|
||||||
loomRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (loomRecipes.size));
|
loomRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (loomRecipes.size));
|
||||||
loomRecipes.recipes[0] = defineRecipe(ITEM_STRING,1,1,ITEM_WOOL,1);
|
loomRecipes.recipes[0] = defineRecipe(ITEM_STRING,1,1,ITEM_WOOL,1);
|
||||||
|
|
||||||
enchanterRecipes.size = 8;
|
enchanterRecipes.size = 7;
|
||||||
enchanterRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (enchanterRecipes.size));
|
enchanterRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (enchanterRecipes.size));
|
||||||
enchanterRecipes.recipes[0] = defineRecipe(TOOL_SWORD,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
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[1] = defineRecipe(TOOL_AXE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||||
|
@ -148,7 +149,6 @@ void initRecipes(){
|
||||||
enchanterRecipes.recipes[4] = defineRecipe(TOOL_SHOVEL,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[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[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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ RecipeManager anvilRecipes;
|
||||||
RecipeManager loomRecipes;
|
RecipeManager loomRecipes;
|
||||||
RecipeManager enchanterRecipes;
|
RecipeManager enchanterRecipes;
|
||||||
|
|
||||||
|
Recipe defineRecipe(int item, int amountOrLevel, int numArgs, ...);
|
||||||
|
|
||||||
void checkCanCraftRecipes(RecipeManager * rm, Inventory * inv);
|
void checkCanCraftRecipes(RecipeManager * rm, Inventory * inv);
|
||||||
void sortRecipes(RecipeManager * rm);
|
void sortRecipes(RecipeManager * rm);
|
||||||
bool craftItem(RecipeManager * rm, Recipe* r, Inventory* inv);
|
bool craftItem(RecipeManager * rm, Recipe* r, Inventory* inv);
|
||||||
|
|
|
@ -346,6 +346,22 @@ Entity newGlowwormEntity(int x, int y, int level){
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Entity newNPCEntity(int type, int x, int y, int level){
|
||||||
|
Entity e;
|
||||||
|
e.type = ENTITY_NPC;
|
||||||
|
e.level = level;
|
||||||
|
e.x = x;
|
||||||
|
e.y = y;
|
||||||
|
e.hurtTime = 0;
|
||||||
|
e.xKnockback = 0;
|
||||||
|
e.yKnockback = 0;
|
||||||
|
e.npc.type = type;
|
||||||
|
e.xr = 4;
|
||||||
|
e.yr = 3;
|
||||||
|
e.canPass = false;
|
||||||
|
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;
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#define ENTITY_DRAGONPROJECTILE 16
|
#define ENTITY_DRAGONPROJECTILE 16
|
||||||
#define ENTITY_MAGIC_PILLAR 17
|
#define ENTITY_MAGIC_PILLAR 17
|
||||||
|
|
||||||
|
#define ENTITY_NPC 18
|
||||||
|
|
||||||
typedef struct Entity Entity;
|
typedef struct Entity Entity;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -160,6 +162,10 @@ typedef struct {
|
||||||
s8 waitTime;
|
s8 waitTime;
|
||||||
} Glowworm;
|
} Glowworm;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 type;
|
||||||
|
} NPC;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float xa;
|
float xa;
|
||||||
float ya;
|
float ya;
|
||||||
|
@ -200,6 +206,7 @@ struct Entity {
|
||||||
Glowworm glowworm;
|
Glowworm glowworm;
|
||||||
Dragon dragon;
|
Dragon dragon;
|
||||||
DragonFire dragonFire;
|
DragonFire dragonFire;
|
||||||
|
NPC npc;
|
||||||
TextParticleEntity textParticle;
|
TextParticleEntity textParticle;
|
||||||
SmashParticleEntity smashParticle;
|
SmashParticleEntity smashParticle;
|
||||||
};
|
};
|
||||||
|
@ -234,6 +241,7 @@ 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 newArrowEntity(Entity* parent, int itemID, s8 xa, s8 ya, int level);
|
||||||
Entity newGlowwormEntity(int x, int y, int level);
|
Entity newGlowwormEntity(int x, int y, int level);
|
||||||
|
Entity newNPCEntity(int type, 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);
|
||||||
|
|
||||||
|
|
133
source/Globals.c
133
source/Globals.c
|
@ -1,6 +1,6 @@
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
char versionText[34] = "Version 1.2.2";
|
char versionText[34] = "Version 1.3.0";
|
||||||
char fpsstr[34];
|
char fpsstr[34];
|
||||||
u8 currentMenu = 0;
|
u8 currentMenu = 0;
|
||||||
|
|
||||||
|
@ -217,6 +217,7 @@ void tickTouchQuickSelect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){
|
void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){
|
||||||
|
if (TESTGODMODE && e->type==ENTITY_PLAYER) return;
|
||||||
if (e->hurtTime > 0) return;
|
if (e->hurtTime > 0) return;
|
||||||
int xd = player.x - e->x;
|
int xd = player.x - e->x;
|
||||||
int yd = player.y - e->y;
|
int yd = player.y - e->y;
|
||||||
|
@ -252,7 +253,7 @@ void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){
|
||||||
}
|
}
|
||||||
player.p.score += 50 * (e->hostile.lvl + 1);
|
player.p.score += 50 * (e->hostile.lvl + 1);
|
||||||
removeEntityFromList(e,e->level,&eManager);
|
removeEntityFromList(e,e->level,&eManager);
|
||||||
trySpawn(3, currentLevel);
|
if(currentLevel != 5) trySpawn(3, currentLevel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -262,7 +263,7 @@ void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){
|
||||||
addItemsToWorld(newItem(ITEM_SLIME,1),e->x+8, e->y+8, (rand()%2) + 1);
|
addItemsToWorld(newItem(ITEM_SLIME,1),e->x+8, e->y+8, (rand()%2) + 1);
|
||||||
player.p.score += 25 * (e->slime.lvl + 1);
|
player.p.score += 25 * (e->slime.lvl + 1);
|
||||||
removeEntityFromList(e,e->level,&eManager);
|
removeEntityFromList(e,e->level,&eManager);
|
||||||
trySpawn(3, currentLevel);
|
if(currentLevel != 5) trySpawn(3, currentLevel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -270,7 +271,7 @@ 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);
|
addItemsToWorld(newItem(ITEM_MAGIC_DUST,1),e->x+8, e->y+8, (rand()%2) + 2);
|
||||||
removeEntityFromList(e,e->level,&eManager);
|
removeEntityFromList(e,e->level,&eManager);
|
||||||
playSound(snd_bossdeath);
|
playSound(snd_bossdeath);
|
||||||
player.p.score += 1000;
|
player.p.score += 1000;
|
||||||
|
@ -295,7 +296,7 @@ void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){
|
||||||
}
|
}
|
||||||
player.p.score += 10;
|
player.p.score += 10;
|
||||||
removeEntityFromList(e,e->level,&eManager);
|
removeEntityFromList(e,e->level,&eManager);
|
||||||
trySpawn(3, currentLevel);
|
if(currentLevel != 5) trySpawn(3, currentLevel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -546,16 +547,16 @@ void EntityVsEntity(Entity* e1, Entity* e2){
|
||||||
damage = 1 + (rand()%3);
|
damage = 1 + (rand()%3);
|
||||||
break;
|
break;
|
||||||
case ITEM_ARROW_STONE:
|
case ITEM_ARROW_STONE:
|
||||||
damage = 2 + (rand()%5);
|
damage = 2 + (rand()%4);
|
||||||
break;
|
break;
|
||||||
case ITEM_ARROW_IRON:
|
case ITEM_ARROW_IRON:
|
||||||
damage = 8 + (rand()%9);
|
damage = 8 + (rand()%9);
|
||||||
break;
|
break;
|
||||||
case ITEM_ARROW_GOLD:
|
case ITEM_ARROW_GOLD:
|
||||||
damage = 16 + (rand()%17);
|
damage = 16 + (rand()%9);
|
||||||
break;
|
break;
|
||||||
case ITEM_ARROW_GEM:
|
case ITEM_ARROW_GEM:
|
||||||
damage = 24 + (rand()%17);
|
damage = 24 + (rand()%9);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,6 +590,7 @@ bool EntityBlocksEntity(Entity* e1, Entity* e2){
|
||||||
case ENTITY_PLAYER:
|
case ENTITY_PLAYER:
|
||||||
case ENTITY_PASSIVE:
|
case ENTITY_PASSIVE:
|
||||||
case ENTITY_MAGIC_PILLAR:
|
case ENTITY_MAGIC_PILLAR:
|
||||||
|
case ENTITY_NPC:
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -599,9 +601,12 @@ bool EntityBlocksEntity(Entity* e1, Entity* e2){
|
||||||
|
|
||||||
bool tileIsSolid(int tile, Entity * e){
|
bool tileIsSolid(int tile, Entity * e){
|
||||||
switch(tile){
|
switch(tile){
|
||||||
case TILE_TREE:
|
|
||||||
case TILE_ROCK:
|
case TILE_ROCK:
|
||||||
case TILE_HARDROCK:
|
case TILE_HARDROCK:
|
||||||
|
case TILE_MAGIC_BARRIER:
|
||||||
|
case TILE_DUNGEON_WALL:
|
||||||
|
return true;
|
||||||
|
case TILE_TREE:
|
||||||
case TILE_CACTUS:
|
case TILE_CACTUS:
|
||||||
case TILE_IRONORE:
|
case TILE_IRONORE:
|
||||||
case TILE_GOLDORE:
|
case TILE_GOLDORE:
|
||||||
|
@ -612,9 +617,10 @@ bool tileIsSolid(int tile, Entity * e){
|
||||||
case TILE_IRON_WALL:
|
case TILE_IRON_WALL:
|
||||||
case TILE_GOLD_WALL:
|
case TILE_GOLD_WALL:
|
||||||
case TILE_GEM_WALL:
|
case TILE_GEM_WALL:
|
||||||
case TILE_DUNGEON_WALL:
|
case TILE_BOOKSHELVES:
|
||||||
case TILE_MAGIC_BARRIER:
|
case TILE_MUSHROOM_BROWN:
|
||||||
return true;
|
case TILE_MUSHROOM_RED:
|
||||||
|
if(e->type != ENTITY_DRAGON) return true;
|
||||||
case TILE_LAVA:
|
case TILE_LAVA:
|
||||||
case 255:
|
case 255:
|
||||||
if(e->type != ENTITY_ARROW) return true;
|
if(e->type != ENTITY_ARROW) return true;
|
||||||
|
@ -655,6 +661,12 @@ u32 getTileColor(int tile){
|
||||||
case TILE_DUNGEON_WALL: return SWAP_UINT32(dungeonColor[0]);
|
case TILE_DUNGEON_WALL: return SWAP_UINT32(dungeonColor[0]);
|
||||||
case TILE_DUNGEON_FLOOR: return SWAP_UINT32(dungeonColor[1]);
|
case TILE_DUNGEON_FLOOR: return SWAP_UINT32(dungeonColor[1]);
|
||||||
case TILE_MAGIC_BARRIER: return SWAP_UINT32(dungeonColor[0]);
|
case TILE_MAGIC_BARRIER: return SWAP_UINT32(dungeonColor[0]);
|
||||||
|
case TILE_BOOKSHELVES: return SWAP_UINT32(woodColor);
|
||||||
|
case TILE_WOOD_FLOOR: return SWAP_UINT32(woodColor);
|
||||||
|
case TILE_MYCELIUM: return SWAP_UINT32(myceliumColor);
|
||||||
|
case TILE_MUSHROOM_BROWN: return SWAP_UINT32(mushroomColor);
|
||||||
|
case TILE_MUSHROOM_RED: return SWAP_UINT32(mushroomColor);
|
||||||
|
case TILE_ICE: return SWAP_UINT32(iceColor);
|
||||||
|
|
||||||
default: return 0x111111FF;
|
default: return 0x111111FF;
|
||||||
}
|
}
|
||||||
|
@ -806,6 +818,11 @@ s8 itemTileInteract(int tile, Item* item, int x, int y, int px, int py, int dir)
|
||||||
setTile(TILE_GEM_WALL,x,y); --item->countLevel;
|
setTile(TILE_GEM_WALL,x,y); --item->countLevel;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else if(item->id == ITEM_BOOKSHELVES){
|
||||||
|
setTile(TILE_BOOKSHELVES,x,y); --item->countLevel;
|
||||||
|
data[currentLevel][x+y*128] = rand()%3;
|
||||||
|
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);
|
||||||
setTile(TILE_DIRT,x,y);
|
setTile(TILE_DIRT,x,y);
|
||||||
|
@ -847,6 +864,15 @@ s8 itemTileInteract(int tile, Item* item, int x, int y, int px, int py, int dir)
|
||||||
setTile(TILE_GEM_WALL,x,y); --item->countLevel;
|
setTile(TILE_GEM_WALL,x,y); --item->countLevel;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else if(item->id == ITEM_BOOKSHELVES){
|
||||||
|
setTile(TILE_BOOKSHELVES,x,y); --item->countLevel;
|
||||||
|
data[currentLevel][x+y*128] = rand()%3;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if(item->id == ITEM_WOOD) {
|
||||||
|
setTile(TILE_WOOD_FLOOR,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;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -942,6 +968,16 @@ 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_BOOKSHELVES:
|
||||||
|
if(item->id == TOOL_AXE && playerUseEnergy(4-item->countLevel)){
|
||||||
|
playerHurtTile(tile, x, y, (rand()%10) + (item->countLevel) * 5 + 10, player.p.dir);
|
||||||
|
return 1;
|
||||||
|
} break;
|
||||||
|
case TILE_WOOD_FLOOR:
|
||||||
|
if(item->id == TOOL_AXE && playerUseEnergy(4-item->countLevel)){
|
||||||
|
addEntityToList(newItemEntity(newItem(ITEM_WOOD,1), (x<<4)+8, (y<<4)+8, currentLevel), &eManager);
|
||||||
|
setTile(TILE_DIRT,x,y);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -952,7 +988,7 @@ void tickTile(int x, int y){
|
||||||
|
|
||||||
switch(tile){
|
switch(tile){
|
||||||
case TILE_SAPLING_TREE:
|
case TILE_SAPLING_TREE:
|
||||||
setData(++data,x,y); if(data>100){setData(0,x,y); setTile(TILE_TREE,x,y);}
|
if(season!=3) setData(++data,x,y); if(data>100){setData(0,x,y); setTile(TILE_TREE,x,y);}
|
||||||
break;
|
break;
|
||||||
case TILE_TREE:
|
case TILE_TREE:
|
||||||
if(eManager.lastSlot[currentLevel]<800 && (daytime>18000 || daytime<5000) && rand()%800==0) {
|
if(eManager.lastSlot[currentLevel]<800 && (daytime>18000 || daytime<5000) && rand()%800==0) {
|
||||||
|
@ -966,16 +1002,22 @@ void tickTile(int x, int y){
|
||||||
}
|
}
|
||||||
break;
|
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);}
|
if(season!=3) setData(++data,x,y); if(data>100){setData(0,x,y); setTile(TILE_CACTUS,x,y);}
|
||||||
break;
|
break;
|
||||||
case TILE_WHEAT:
|
case TILE_WHEAT:
|
||||||
if(data<100)setData(++data,x,y);
|
if(data<100 && season!=3) setData(++data,x,y);
|
||||||
break;
|
break;
|
||||||
case TILE_WATER:
|
case TILE_WATER:
|
||||||
if(getTile(x+1,y)==TILE_HOLE) setTile(TILE_WATER,x+1,y);
|
if(getTile(x+1,y)==TILE_HOLE) setTile(TILE_WATER,x+1,y);
|
||||||
if(getTile(x-1,y)==TILE_HOLE) setTile(TILE_WATER,x-1,y);
|
if(getTile(x-1,y)==TILE_HOLE) setTile(TILE_WATER,x-1,y);
|
||||||
if(getTile(x,y+1)==TILE_HOLE) setTile(TILE_WATER,x,y+1);
|
if(getTile(x,y+1)==TILE_HOLE) setTile(TILE_WATER,x,y+1);
|
||||||
if(getTile(x,y-1)==TILE_HOLE) setTile(TILE_WATER,x,y-1);
|
if(getTile(x,y-1)==TILE_HOLE) setTile(TILE_WATER,x,y-1);
|
||||||
|
if(currentLevel==1 && season==3 && rand()%12==0) {
|
||||||
|
if(getTile(x+1,y)!=TILE_WATER) setTile(TILE_ICE,x,y);
|
||||||
|
if(getTile(x-1,y)!=TILE_WATER) setTile(TILE_ICE,x,y);
|
||||||
|
if(getTile(x,y+1)!=TILE_WATER) setTile(TILE_ICE,x,y);
|
||||||
|
if(getTile(x,y-1)!=TILE_WATER) setTile(TILE_ICE,x,y);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TILE_LAVA:
|
case TILE_LAVA:
|
||||||
if(getTile(x+1,y)==TILE_HOLE) setTile(TILE_LAVA,x+1,y);
|
if(getTile(x+1,y)==TILE_HOLE) setTile(TILE_LAVA,x+1,y);
|
||||||
|
@ -1016,7 +1058,13 @@ void tickTile(int x, int y){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(data==0) setTile(TILE_DUNGEON_FLOOR,x,y);
|
if(data==0) setTile(TILE_DUNGEON_FLOOR,x,y);
|
||||||
|
setData(rand()%2,x,y);
|
||||||
break;
|
break;
|
||||||
|
case TILE_ICE:
|
||||||
|
if(season!=3) {
|
||||||
|
setTile(TILE_WATER,x,y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1109,7 +1157,7 @@ void tickEntity(Entity* e){
|
||||||
if(e->type == ENTITY_SKELETON) {
|
if(e->type == ENTITY_SKELETON) {
|
||||||
--(e->hostile.randAttackTime);
|
--(e->hostile.randAttackTime);
|
||||||
if(e->hostile.randAttackTime <= 0) {
|
if(e->hostile.randAttackTime <= 0) {
|
||||||
e->hostile.randAttackTime = 70 - (e->hostile.lvl * 10);
|
e->hostile.randAttackTime = 80 - (e->hostile.lvl * 5);
|
||||||
|
|
||||||
int aitemID = ITEM_ARROW_WOOD;
|
int aitemID = ITEM_ARROW_WOOD;
|
||||||
if(e->hostile.lvl >= 2) aitemID = ITEM_ARROW_STONE;
|
if(e->hostile.lvl >= 2) aitemID = ITEM_ARROW_STONE;
|
||||||
|
@ -1617,6 +1665,8 @@ void initPlayer(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerHurtTile(int tile, int xt, int yt, int damage, int dir){
|
void playerHurtTile(int tile, int xt, int yt, int damage, int dir){
|
||||||
|
if(TESTGODMODE) damage = 99;
|
||||||
|
|
||||||
char hurtText[11];
|
char hurtText[11];
|
||||||
switch(tile){
|
switch(tile){
|
||||||
case TILE_TREE:
|
case TILE_TREE:
|
||||||
|
@ -1798,11 +1848,21 @@ void playerHurtTile(int tile, int xt, int yt, int damage, int dir){
|
||||||
addItemsToWorld(newItem(ITEM_WALL_GEM,1),(xt<<4)+8,(yt<<4)+8,1);
|
addItemsToWorld(newItem(ITEM_WALL_GEM,1),(xt<<4)+8,(yt<<4)+8,1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TILE_BOOKSHELVES:
|
||||||
|
sprintf(hurtText, "%d", damage);
|
||||||
|
addEntityToList(newTextParticleEntity(hurtText,0xFF0000FF,xt<<4,yt<<4,currentLevel), &eManager);
|
||||||
|
addEntityToList(newSmashParticleEntity(xt<<4,yt<<4,currentLevel), &eManager);
|
||||||
|
|
||||||
|
if(currentLevel!=5) setTile(TILE_DIRT,xt,yt);
|
||||||
|
else setTile(TILE_DUNGEON_FLOOR,xt,yt);
|
||||||
|
addItemsToWorld(newItem(ITEM_BOOKSHELVES,1),(xt<<4)+8,(yt<<4)+8,1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool playerUseEnergy(int amount){
|
bool playerUseEnergy(int amount){
|
||||||
|
if(TESTGODMODE) return true;
|
||||||
if(amount > player.p.stamina) return false;
|
if(amount > player.p.stamina) return false;
|
||||||
player.p.stamina -= amount;
|
player.p.stamina -= amount;
|
||||||
return true;
|
return true;
|
||||||
|
@ -1974,24 +2034,28 @@ bool useEntity(Entity* e) {
|
||||||
switch(e->entityFurniture.itemID){
|
switch(e->entityFurniture.itemID){
|
||||||
case ITEM_WORKBENCH:
|
case ITEM_WORKBENCH:
|
||||||
currentRecipes = &workbenchRecipes;
|
currentRecipes = &workbenchRecipes;
|
||||||
|
currentCraftTitle = "Crafting";
|
||||||
currentMenu = MENU_CRAFTING;
|
currentMenu = MENU_CRAFTING;
|
||||||
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
||||||
sortRecipes(currentRecipes);
|
sortRecipes(currentRecipes);
|
||||||
return true;
|
return true;
|
||||||
case ITEM_FURNACE:
|
case ITEM_FURNACE:
|
||||||
currentRecipes = &furnaceRecipes;
|
currentRecipes = &furnaceRecipes;
|
||||||
|
currentCraftTitle = "Crafting";
|
||||||
currentMenu = MENU_CRAFTING;
|
currentMenu = MENU_CRAFTING;
|
||||||
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
||||||
sortRecipes(currentRecipes);
|
sortRecipes(currentRecipes);
|
||||||
return true;
|
return true;
|
||||||
case ITEM_OVEN:
|
case ITEM_OVEN:
|
||||||
currentRecipes = &ovenRecipes;
|
currentRecipes = &ovenRecipes;
|
||||||
|
currentCraftTitle = "Crafting";
|
||||||
currentMenu = MENU_CRAFTING;
|
currentMenu = MENU_CRAFTING;
|
||||||
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
||||||
sortRecipes(currentRecipes);
|
sortRecipes(currentRecipes);
|
||||||
return true;
|
return true;
|
||||||
case ITEM_ANVIL:
|
case ITEM_ANVIL:
|
||||||
currentRecipes = &anvilRecipes;
|
currentRecipes = &anvilRecipes;
|
||||||
|
currentCraftTitle = "Crafting";
|
||||||
currentMenu = MENU_CRAFTING;
|
currentMenu = MENU_CRAFTING;
|
||||||
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
||||||
sortRecipes(currentRecipes);
|
sortRecipes(currentRecipes);
|
||||||
|
@ -2005,17 +2069,22 @@ bool useEntity(Entity* e) {
|
||||||
return true;
|
return true;
|
||||||
case ITEM_LOOM:
|
case ITEM_LOOM:
|
||||||
currentRecipes = &loomRecipes;
|
currentRecipes = &loomRecipes;
|
||||||
|
currentCraftTitle = "Crafting";
|
||||||
currentMenu = MENU_CRAFTING;
|
currentMenu = MENU_CRAFTING;
|
||||||
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
||||||
sortRecipes(currentRecipes);
|
sortRecipes(currentRecipes);
|
||||||
return true;
|
return true;
|
||||||
case ITEM_ENCHANTER:
|
case ITEM_ENCHANTER:
|
||||||
currentRecipes = &enchanterRecipes;
|
currentRecipes = &enchanterRecipes;
|
||||||
|
currentCraftTitle = "Crafting";
|
||||||
currentMenu = MENU_CRAFTING;
|
currentMenu = MENU_CRAFTING;
|
||||||
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
||||||
sortRecipes(currentRecipes);
|
sortRecipes(currentRecipes);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else if(e->type == ENTITY_NPC) {
|
||||||
|
openNPCMenu(e->npc.type);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2088,7 +2157,7 @@ void tickPlayer(){
|
||||||
|
|
||||||
if (swimming && player.p.swimTimer % 60 == 0) {
|
if (swimming && player.p.swimTimer % 60 == 0) {
|
||||||
if (player.p.stamina > 0) {
|
if (player.p.stamina > 0) {
|
||||||
--player.p.stamina;
|
if(!TESTGODMODE) --player.p.stamina;
|
||||||
} else {
|
} else {
|
||||||
hurtEntity(&player,1,-1,0xFFAF00FF);
|
hurtEntity(&player,1,-1,0xFFAF00FF);
|
||||||
}
|
}
|
||||||
|
@ -2101,7 +2170,7 @@ void tickPlayer(){
|
||||||
|
|
||||||
if(k_attack.clicked){
|
if(k_attack.clicked){
|
||||||
if (player.p.stamina != 0) {
|
if (player.p.stamina != 0) {
|
||||||
player.p.stamina--;
|
if(!TESTGODMODE) player.p.stamina--;
|
||||||
player.p.staminaRecharge = 0;
|
player.p.staminaRecharge = 0;
|
||||||
playerAttack();
|
playerAttack();
|
||||||
//addEntityToList(newSlimeEntity(1,200,600,1), &eManager);
|
//addEntityToList(newSlimeEntity(1,200,600,1), &eManager);
|
||||||
|
@ -2148,7 +2217,7 @@ void enterDungeon() {
|
||||||
|
|
||||||
//create map
|
//create map
|
||||||
currentLevel = 5;
|
currentLevel = 5;
|
||||||
createDungeonMap(128, 128, map[5], data[5]);
|
createAndValidateDungeonMap(128, 128, 5, map[5], data[5]);
|
||||||
|
|
||||||
//reset minimap clear state
|
//reset minimap clear state
|
||||||
int xd,yd;
|
int xd,yd;
|
||||||
|
@ -2160,11 +2229,11 @@ void enterDungeon() {
|
||||||
initMinimapLevel(5, false);
|
initMinimapLevel(5, false);
|
||||||
newSeed();
|
newSeed();
|
||||||
|
|
||||||
|
player.x = ((128/2) << 4) + 8;
|
||||||
|
player.y = ((128/2) << 4) + 8;
|
||||||
|
|
||||||
//spawn new entities
|
//spawn new entities
|
||||||
trySpawn(500, 5);
|
trySpawn(500, 5);
|
||||||
|
|
||||||
player.x = ((128/2) << 4) + 8;
|
|
||||||
player.y = ((128/2) << 4) + 8;
|
|
||||||
|
|
||||||
updateMusic(currentLevel, daytime);
|
updateMusic(currentLevel, daytime);
|
||||||
}
|
}
|
||||||
|
@ -2203,6 +2272,9 @@ u32 getMinimapColor(int level, int x, int y) {
|
||||||
void initMinimapLevel(int level, bool loadUpWorld) {
|
void initMinimapLevel(int level, bool loadUpWorld) {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
bool calculateCompass;
|
||||||
|
|
||||||
|
calculateCompass = ((!loadUpWorld) || (compassData[level][2] = 0)) && level<5;
|
||||||
|
|
||||||
//Create Dungeon entrance(not located in mapgen, so it can also be created in old worlds)
|
//Create Dungeon entrance(not located in mapgen, so it can also be created in old worlds)
|
||||||
if(level==4) {
|
if(level==4) {
|
||||||
|
@ -2248,6 +2320,18 @@ void initMinimapLevel(int level, bool loadUpWorld) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(calculateCompass) {
|
||||||
|
//choose one stair down and store for magic compass
|
||||||
|
switch (map[level][x + y * 128]) {
|
||||||
|
case TILE_STAIRS_DOWN:
|
||||||
|
case TILE_DUNGEON_ENTRANCE:
|
||||||
|
compassData[level][2] = compassData[level][2] + 1;
|
||||||
|
if((compassData[level][2]==1) || (rand()%(compassData[level][2])==0)) {
|
||||||
|
compassData[level][0] = x;
|
||||||
|
compassData[level][1] = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Minimaps */
|
/* Minimaps */
|
||||||
|
@ -2276,6 +2360,8 @@ void reloadColors() {
|
||||||
dirtColor[4] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 4));
|
dirtColor[4] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 4));
|
||||||
|
|
||||||
grassColor = SWAP_UINT32(sf2d_get_pixel(icons, 17, 0));
|
grassColor = SWAP_UINT32(sf2d_get_pixel(icons, 17, 0));
|
||||||
|
myceliumColor = SWAP_UINT32(sf2d_get_pixel(icons, 17, 1));
|
||||||
|
mushroomColor = SWAP_UINT32(sf2d_get_pixel(icons, 17, 2));
|
||||||
|
|
||||||
sandColor = SWAP_UINT32(sf2d_get_pixel(icons, 18, 0));
|
sandColor = SWAP_UINT32(sf2d_get_pixel(icons, 18, 0));
|
||||||
|
|
||||||
|
@ -2298,4 +2384,7 @@ void reloadColors() {
|
||||||
|
|
||||||
dungeonColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 0));
|
dungeonColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 0));
|
||||||
dungeonColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 1));
|
dungeonColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 1));
|
||||||
|
|
||||||
|
snowColor = SWAP_UINT32(sf2d_get_pixel(icons, 25, 0));
|
||||||
|
iceColor = SWAP_UINT32(sf2d_get_pixel(icons, 25, 1));
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
#include "SaveLoad.h"
|
#include "SaveLoad.h"
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
#include "MapGen.h"
|
#include "MapGen.h"
|
||||||
|
#include "Quests.h"
|
||||||
|
|
||||||
#include "icons2_png.h"
|
#include "icons2_png.h"
|
||||||
#include "Font_png.h"
|
#include "Font_png.h"
|
||||||
|
@ -26,6 +27,13 @@
|
||||||
#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 MENU_DUNGEON 14
|
||||||
|
#define MENU_NPC 15
|
||||||
|
|
||||||
|
#define NPC_GIRL 0
|
||||||
|
#define NPC_PRIEST 1
|
||||||
|
#define NPC_FARMER 2
|
||||||
|
#define NPC_LIBRARIAN 3
|
||||||
|
#define NPC_DWARF 4
|
||||||
|
|
||||||
#define TILE_NULL 255
|
#define TILE_NULL 255
|
||||||
#define TILE_GRASS 0
|
#define TILE_GRASS 0
|
||||||
|
@ -60,9 +68,18 @@
|
||||||
#define TILE_DUNGEON_FLOOR 28
|
#define TILE_DUNGEON_FLOOR 28
|
||||||
#define TILE_DUNGEON_ENTRANCE 29
|
#define TILE_DUNGEON_ENTRANCE 29
|
||||||
#define TILE_MAGIC_BARRIER 30
|
#define TILE_MAGIC_BARRIER 30
|
||||||
|
#define TILE_BOOKSHELVES 31
|
||||||
|
#define TILE_WOOD_FLOOR 32
|
||||||
|
#define TILE_MYCELIUM 33
|
||||||
|
#define TILE_MUSHROOM_BROWN 34
|
||||||
|
#define TILE_MUSHROOM_RED 35
|
||||||
|
#define TILE_ICE 36
|
||||||
|
|
||||||
#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))
|
||||||
|
|
||||||
|
//TODO: Dont forget to change back
|
||||||
|
#define TESTGODMODE true
|
||||||
|
|
||||||
bool screenShot;
|
bool screenShot;
|
||||||
int loadedtp;
|
int loadedtp;
|
||||||
|
|
||||||
|
@ -86,6 +103,7 @@ sf2d_texture * minimap[6];
|
||||||
u8 map[6][128*128];
|
u8 map[6][128*128];
|
||||||
u8 data[6][128*128];
|
u8 data[6][128*128];
|
||||||
u8 minimapData[128*128];
|
u8 minimapData[128*128];
|
||||||
|
u8 compassData[6][3];
|
||||||
|
|
||||||
u32 dirtColor[5];
|
u32 dirtColor[5];
|
||||||
u32 grassColor;
|
u32 grassColor;
|
||||||
|
@ -98,6 +116,10 @@ u32 ironColor;
|
||||||
u32 goldColor;
|
u32 goldColor;
|
||||||
u32 gemColor;
|
u32 gemColor;
|
||||||
u32 dungeonColor[2];
|
u32 dungeonColor[2];
|
||||||
|
u32 myceliumColor;
|
||||||
|
u32 mushroomColor;
|
||||||
|
u32 snowColor;
|
||||||
|
u32 iceColor;
|
||||||
|
|
||||||
char currentFileName[256];
|
char currentFileName[256];
|
||||||
extern u8 currentMenu;
|
extern u8 currentMenu;
|
||||||
|
@ -110,11 +132,15 @@ s16 awX, awY;
|
||||||
u32 tickCount;
|
u32 tickCount;
|
||||||
RecipeManager* currentRecipes;
|
RecipeManager* currentRecipes;
|
||||||
Entity* curChestEntity;
|
Entity* curChestEntity;
|
||||||
|
char* currentCraftTitle;
|
||||||
s16 curInvSel;
|
s16 curInvSel;
|
||||||
bool quitGame;
|
bool quitGame;
|
||||||
s8 currentSelection;
|
s8 currentSelection;
|
||||||
|
|
||||||
u16 daytime;
|
u16 daytime;
|
||||||
|
int day;
|
||||||
|
u8 season;
|
||||||
|
bool rain;
|
||||||
|
|
||||||
void tickTile(int x, int y);
|
void tickTile(int x, int y);
|
||||||
bool tileIsSolid(int tile, Entity * e);
|
bool tileIsSolid(int tile, Entity * e);
|
||||||
|
|
|
@ -183,6 +183,9 @@ char* getItemName(int itemID, int countLevel){
|
||||||
case ITEM_WIZARD_SUMMON: sprintf(currentName,"%d Wizard Summon", countLevel); return currentName;
|
case ITEM_WIZARD_SUMMON: sprintf(currentName,"%d Wizard Summon", countLevel); return currentName;
|
||||||
case ITEM_DRAGON_EGG: sprintf(currentName,"%d Dragon Egg", countLevel); return currentName;
|
case ITEM_DRAGON_EGG: sprintf(currentName,"%d Dragon Egg", countLevel); return currentName;
|
||||||
case ITEM_DRAGON_SCALE: sprintf(currentName,"%d Dragon Scale", countLevel); return currentName;
|
case ITEM_DRAGON_SCALE: sprintf(currentName,"%d Dragon Scale", countLevel); return currentName;
|
||||||
|
case ITEM_BOOKSHELVES: sprintf(currentName,"%d Bookshelves", countLevel); return currentName;
|
||||||
|
case ITEM_MAGIC_DUST: sprintf(currentName,"%d Magic Dust", countLevel); return currentName;
|
||||||
|
case ITEM_COIN: sprintf(currentName,"%d Coins", countLevel); return currentName;
|
||||||
case TOOL_BUCKET:
|
case TOOL_BUCKET:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Water Bucket";
|
case 1: return "Water Bucket";
|
||||||
|
@ -190,6 +193,7 @@ char* getItemName(int itemID, int countLevel){
|
||||||
default: return "Empty Bucket";
|
default: return "Empty Bucket";
|
||||||
}
|
}
|
||||||
case TOOL_BOW: return "Bow";
|
case TOOL_BOW: return "Bow";
|
||||||
|
case TOOL_MAGIC_COMPASS: return "Magic Compass";
|
||||||
default: return ""; // null
|
default: return ""; // null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,8 +291,11 @@ char* getBasicItemName(int itemID, int countLevel){
|
||||||
case ITEM_BONE: return "Bone";
|
case ITEM_BONE: return "Bone";
|
||||||
case ITEM_DUNGEON_KEY: return "Dungeon Key";
|
case ITEM_DUNGEON_KEY: return "Dungeon Key";
|
||||||
case ITEM_WIZARD_SUMMON: return "Wizard Summon";
|
case ITEM_WIZARD_SUMMON: return "Wizard Summon";
|
||||||
case ITEM_DRAGON_EGG: return "%d Dragon Egg";
|
case ITEM_DRAGON_EGG: return "Dragon Egg";
|
||||||
case ITEM_DRAGON_SCALE: return "%d Dragon Scale";
|
case ITEM_DRAGON_SCALE: return "Dragon Scale";
|
||||||
|
case ITEM_BOOKSHELVES: return "Bookshelves";
|
||||||
|
case ITEM_MAGIC_DUST: return "Magic Dust";
|
||||||
|
case ITEM_COIN: return "Coin";
|
||||||
case TOOL_BUCKET:
|
case TOOL_BUCKET:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Water Bucket";
|
case 1: return "Water Bucket";
|
||||||
|
@ -296,6 +303,7 @@ char* getBasicItemName(int itemID, int countLevel){
|
||||||
default: return "Empty Bucket";
|
default: return "Empty Bucket";
|
||||||
}
|
}
|
||||||
case TOOL_BOW: return "Bow";
|
case TOOL_BOW: return "Bow";
|
||||||
|
case TOOL_MAGIC_COMPASS: return "Magic Compass";
|
||||||
default: return ""; // null
|
default: return ""; // null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,9 +68,13 @@
|
||||||
#define ITEM_WIZARD_SUMMON 70
|
#define ITEM_WIZARD_SUMMON 70
|
||||||
#define ITEM_DRAGON_EGG 71
|
#define ITEM_DRAGON_EGG 71
|
||||||
#define ITEM_DRAGON_SCALE 72
|
#define ITEM_DRAGON_SCALE 72
|
||||||
|
#define ITEM_BOOKSHELVES 73
|
||||||
|
#define ITEM_MAGIC_DUST 74
|
||||||
|
#define ITEM_COIN 75
|
||||||
|
|
||||||
#define TOOL_BUCKET 101
|
#define TOOL_BUCKET 101
|
||||||
#define TOOL_BOW 102
|
#define TOOL_BOW 102
|
||||||
|
#define TOOL_MAGIC_COMPASS 103
|
||||||
|
|
||||||
typedef struct Inventory Inventory;
|
typedef struct Inventory Inventory;
|
||||||
|
|
||||||
|
|
568
source/MapGen.c
568
source/MapGen.c
|
@ -3,6 +3,9 @@
|
||||||
int w = 0;
|
int w = 0;
|
||||||
int h = 0;
|
int h = 0;
|
||||||
|
|
||||||
|
u8 randomTile[] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 2};
|
||||||
|
int randomTileSize = 10;
|
||||||
|
|
||||||
float nextFloat(){
|
float nextFloat(){
|
||||||
return (float)rand()/RAND_MAX;
|
return (float)rand()/RAND_MAX;
|
||||||
}
|
}
|
||||||
|
@ -64,9 +67,14 @@ void newSeed(){
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
void createAndValidateTopMap(int w, int h, u8 * map, u8 * data) {
|
//TODO: Will need to reset entity manager if generation is retried
|
||||||
|
void createAndValidateTopMap(int w, int h, int level, u8 * map, u8 * data) {
|
||||||
do {
|
do {
|
||||||
createTopMap(w, h, map, data);
|
//reset Entities
|
||||||
|
(&eManager)->lastSlot[level] = 0;
|
||||||
|
(&eManager)->entities[level][0] = nullEntity;
|
||||||
|
|
||||||
|
createTopMap(w, h, level, map, data);
|
||||||
|
|
||||||
int count[256]={[0 ... 255] = 0};
|
int count[256]={[0 ... 255] = 0};
|
||||||
int i;
|
int i;
|
||||||
|
@ -81,9 +89,13 @@ void createAndValidateTopMap(int w, int h, u8 * map, u8 * data) {
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createAndValidateUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) {
|
void createAndValidateUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 * data) {
|
||||||
do {
|
do {
|
||||||
createUndergroundMap(w, h, depthLevel, map, data);
|
//reset Entities
|
||||||
|
(&eManager)->lastSlot[level] = 0;
|
||||||
|
(&eManager)->entities[level][0] = nullEntity;
|
||||||
|
|
||||||
|
createUndergroundMap(w, h, depthLevel, level, map, data);
|
||||||
|
|
||||||
int count[256]={[0 ... 255] = 0};
|
int count[256]={[0 ... 255] = 0};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -92,7 +104,7 @@ void createAndValidateUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 *
|
||||||
if (count[TILE_DIRT & 0xff] < 100) continue;
|
if (count[TILE_DIRT & 0xff] < 100) continue;
|
||||||
switch(depthLevel){
|
switch(depthLevel){
|
||||||
case 1: if (count[TILE_IRONORE & 0xff] < 20) continue; break;
|
case 1: if (count[TILE_IRONORE & 0xff] < 20) continue; break;
|
||||||
case 2: if (count[TILE_GOLDORE & 0xff] < 20) continue; break;
|
case 2: if (count[TILE_GOLDORE & 0xff] < 20 || count[TILE_MYCELIUM & 0xff] < 40) continue; break;
|
||||||
case 3: if (count[TILE_GEMORE & 0xff] < 20) continue; break;
|
case 3: if (count[TILE_GEMORE & 0xff] < 20) continue; break;
|
||||||
}
|
}
|
||||||
if (depthLevel < 3) if (count[TILE_STAIRS_DOWN & 0xff] < 2) continue;
|
if (depthLevel < 3) if (count[TILE_STAIRS_DOWN & 0xff] < 2) continue;
|
||||||
|
@ -101,9 +113,13 @@ void createAndValidateUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 *
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createAndValidateDungeonMap(int w, int h, u8 * map, u8 * data) {
|
void createAndValidateDungeonMap(int w, int h, int level, u8 * map, u8 * data) {
|
||||||
do {
|
do {
|
||||||
createDungeonMap(w, h, map, data);
|
//reset Entities
|
||||||
|
(&eManager)->lastSlot[level] = 0;
|
||||||
|
(&eManager)->entities[level][0] = nullEntity;
|
||||||
|
|
||||||
|
createDungeonMap(w, h, level, map, data);
|
||||||
|
|
||||||
int count[256]={[0 ... 255] = 0};
|
int count[256]={[0 ... 255] = 0};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -115,9 +131,13 @@ void createAndValidateDungeonMap(int w, int h, u8 * map, u8 * data) {
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createAndValidateSkyMap(int w, int h, u8 * map, u8 * data) {
|
void createAndValidateSkyMap(int w, int h, int level, u8 * map, u8 * data) {
|
||||||
do {
|
do {
|
||||||
createSkyMap(w, h, map, data);
|
//reset Entities
|
||||||
|
(&eManager)->lastSlot[level] = 0;
|
||||||
|
(&eManager)->entities[level][0] = nullEntity;
|
||||||
|
|
||||||
|
createSkyMap(w, h, level, map, data);
|
||||||
|
|
||||||
int count[256]={[0 ... 255] = 0};
|
int count[256]={[0 ... 255] = 0};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -131,7 +151,7 @@ void createAndValidateSkyMap(int w, int h, u8 * map, u8 * data) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void createTopMap(int w, int h, u8 * map, u8 * data) {
|
void createTopMap(int w, int h, int level, u8 * map, u8 * data) {
|
||||||
double* mnoise1 = Noise(w, h, 16);
|
double* mnoise1 = Noise(w, h, 16);
|
||||||
double* mnoise2 = Noise(w, h, 16);
|
double* mnoise2 = Noise(w, h, 16);
|
||||||
double* mnoise3 = Noise(w, h, 16);
|
double* mnoise3 = Noise(w, h, 16);
|
||||||
|
@ -185,6 +205,8 @@ void createTopMap(int w, int h, u8 * map, u8 * data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createVillage(w, h, level, map, data);
|
||||||
|
|
||||||
for (i = 0; i < w * h / 400; ++i) {
|
for (i = 0; i < w * h / 400; ++i) {
|
||||||
x = rand()%w;
|
x = rand()%w;
|
||||||
y = rand()%h;
|
y = rand()%h;
|
||||||
|
@ -254,7 +276,7 @@ void createTopMap(int w, int h, u8 * map, u8 * data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) {
|
void createUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 * data) {
|
||||||
double* mnoise1 = Noise(w, h, 16);
|
double* mnoise1 = Noise(w, h, 16);
|
||||||
double* mnoise2 = Noise(w, h, 16);
|
double* mnoise2 = Noise(w, h, 16);
|
||||||
double* mnoise3 = Noise(w, h, 16);
|
double* mnoise3 = Noise(w, h, 16);
|
||||||
|
@ -270,7 +292,8 @@ void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) {
|
||||||
double* noise1 = Noise(w, h, 32);
|
double* noise1 = Noise(w, h, 32);
|
||||||
double* noise2 = Noise(w, h, 32);
|
double* noise2 = Noise(w, h, 32);
|
||||||
|
|
||||||
int x, y;
|
int x,y,i,j,k,xx,yy;
|
||||||
|
|
||||||
for(x = 0; x < w; ++x){
|
for(x = 0; x < w; ++x){
|
||||||
for(y = 0; y < w; ++y){
|
for(y = 0; y < w; ++y){
|
||||||
int i = x + y * w;
|
int i = x + y * w;
|
||||||
|
@ -307,7 +330,37 @@ void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int i,j;
|
|
||||||
|
if(depthLevel==3) {
|
||||||
|
createDwarfHouse(w, h, level, map, data);
|
||||||
|
} else if(depthLevel==2) {
|
||||||
|
for (i = 0; i < w * h / 5400; ++i) {
|
||||||
|
int xs = rand()%w;
|
||||||
|
int ys = rand()%h;
|
||||||
|
for (k = 0; k < 10; ++k) {
|
||||||
|
x = xs + (rand()%13) - 6;
|
||||||
|
y = ys + (rand()%13) - 6;
|
||||||
|
for (j = 0; j < 100; ++j) {
|
||||||
|
int xo = x + (rand()%5) - (rand()%5);
|
||||||
|
int yo = y + (rand()%5) - (rand()%5);
|
||||||
|
for (yy = yo - 1;yy <= yo + 1; ++yy){
|
||||||
|
for(xx = xo - 1; xx <= xo + 1; ++xx){
|
||||||
|
if (xx >= 0 && yy >= 0 && xx < w && yy < h) {
|
||||||
|
if (map[xx + yy * w] == TILE_DIRT) {
|
||||||
|
map[xx + yy * w] = TILE_MYCELIUM;
|
||||||
|
if(rand()%20==0) {
|
||||||
|
map[xx + yy * w] = TILE_MUSHROOM_BROWN + rand()%2; //BROWN or RED (=BROWN+1)
|
||||||
|
data[xx + yy * w] = rand()%2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < w * h / 400; ++i) {
|
for (i = 0; i < w * h / 400; ++i) {
|
||||||
int x = rand()%w;
|
int x = rand()%w;
|
||||||
int y = rand()%h;
|
int y = rand()%h;
|
||||||
|
@ -357,145 +410,9 @@ void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void createDungeonRoom(int w, int h, bool dragon, u8 * map, u8 * data) {
|
void createDungeonMap(int w, int h, int level, u8 * map, u8 * data) {
|
||||||
int tries;
|
hasNPC = false;
|
||||||
|
|
||||||
for(tries=0; tries<100; ++tries) {
|
|
||||||
int x = 5+(rand()%(w-10 -10));
|
|
||||||
int y = 5+(rand()%(h-10 -10));
|
|
||||||
int xr;
|
|
||||||
int yr;
|
|
||||||
int wr = 10+(rand()%11);
|
|
||||||
int hr = 10+(rand()&11);
|
|
||||||
int xp;
|
|
||||||
int yp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
//create Dragonroom
|
|
||||||
if(dragon) {
|
|
||||||
wr = 20;
|
|
||||||
hr = 20;
|
|
||||||
x = 5 + (rand()%2)*(w-5*2-wr);
|
|
||||||
y = 5 + (rand()%2)*(h-5*2-hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
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-1; xr < x+wr+1; ++xr) {
|
|
||||||
for(yr = y-1; yr < y+hr+1; ++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 + wr/2;
|
|
||||||
yp = y + hr/2;
|
|
||||||
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) {
|
|
||||||
//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 dragon room
|
|
||||||
if(dragon) {
|
|
||||||
for(xr = x; xr < x+wr; ++xr) {
|
|
||||||
for(yr = y; yr < y+hr; ++yr) {
|
|
||||||
i = xr + yr * w;
|
|
||||||
|
|
||||||
if((xr==x+1 || xr==x+wr-2 || yr==y+1 || yr==y+hr-2) && (xr!=x && xr!=x+wr-1 && yr!=y && yr!=y+hr-1)) {
|
|
||||||
map[i] = TILE_MAGIC_BARRIER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//add Dragon Entity
|
|
||||||
addEntityToList(newDragonEntity((x+wr/2) << 4, (y+hr/2) << 4, 5), &eManager);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//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 {
|
|
||||||
//add magic pillars for dragon barrier
|
|
||||||
if(xr==x+wr/2 && yr==y+hr/2) {
|
|
||||||
int pcount = 0;
|
|
||||||
int i = 0;
|
|
||||||
for (i = 0; i < eManager.lastSlot[5]; ++i) {
|
|
||||||
Entity * e = &eManager.entities[5][i];
|
|
||||||
|
|
||||||
if(e->type == ENTITY_MAGIC_PILLAR) {
|
|
||||||
++pcount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(pcount<8) {
|
|
||||||
addEntityToList(newMagicPillarEntity((xr << 4) + 8, (yr << 4) + 8, 5), &eManager);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
int i, x, y;
|
||||||
for(x = 0; x < w; ++x){
|
for(x = 0; x < w; ++x){
|
||||||
for(y = 0; y < w; ++y){
|
for(y = 0; y < w; ++y){
|
||||||
|
@ -504,18 +421,19 @@ void createDungeonMap(int w, int h, u8 * map, u8 * data) {
|
||||||
//Startroom
|
//Startroom
|
||||||
if (x >= (w/2-5) && x <= (w/2+5) && y >= (h/2-5) && y <= (h/2+5) ) {
|
if (x >= (w/2-5) && x <= (w/2+5) && y >= (h/2-5) && y <= (h/2+5) ) {
|
||||||
map[i] = TILE_DUNGEON_FLOOR;
|
map[i] = TILE_DUNGEON_FLOOR;
|
||||||
|
data[i] = randomTile[rand()%randomTileSize];
|
||||||
} else {
|
} else {
|
||||||
map[i] = TILE_DUNGEON_WALL;
|
map[i] = TILE_DUNGEON_WALL;
|
||||||
|
data[i] = 0;
|
||||||
}
|
}
|
||||||
data[i] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//create dragon chamber(only call once and before other rooms)
|
//create dragon chamber(only call once and before other rooms)
|
||||||
createDungeonRoom(w, h, true, map, data);
|
createDungeonRoom(w, h, true, level, map, data);
|
||||||
|
|
||||||
for(i = 0; i < 40; ++i) {
|
for(i = 0; i < 40; ++i) {
|
||||||
createDungeonRoom(w, h, false, map, data);
|
createDungeonRoom(w, h, false, level, map, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
//replace paths with actual dungeon floor
|
//replace paths with actual dungeon floor
|
||||||
|
@ -525,6 +443,7 @@ void createDungeonMap(int w, int h, u8 * map, u8 * data) {
|
||||||
|
|
||||||
if (map[i]==255) {
|
if (map[i]==255) {
|
||||||
map[i] = TILE_DUNGEON_FLOOR;
|
map[i] = TILE_DUNGEON_FLOOR;
|
||||||
|
data[i] = randomTile[rand()%randomTileSize];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -543,7 +462,7 @@ void createDungeonMap(int w, int h, u8 * map, u8 * data) {
|
||||||
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) {
|
void createSkyMap(int w, int h, int level, 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;
|
||||||
|
@ -602,4 +521,341 @@ void createSkyMap(int w, int h, u8 * map, u8 * data) {
|
||||||
free(noise1);
|
free(noise1);
|
||||||
free(noise2);
|
free(noise2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//"Subgenerators"
|
||||||
|
void findFeatureLocation(int fw, int fh, int * accepted, int aLength, int maxTries, int w, int h, u8 * map, u8 * data) {
|
||||||
|
int leastNonFitting = fw * fh;
|
||||||
|
int tries;
|
||||||
|
|
||||||
|
//find the location with the least non fitting tiles out of some randomly tried ones
|
||||||
|
for(tries=0; tries<maxTries; ++tries) {
|
||||||
|
int x = rand()%(w-fw);
|
||||||
|
int y = rand()%(h-fh);
|
||||||
|
int nonFitting = 0;
|
||||||
|
int xp;
|
||||||
|
int yp;
|
||||||
|
int i;
|
||||||
|
int a;
|
||||||
|
bool fits;
|
||||||
|
|
||||||
|
for(xp=x; xp<x+fw; ++xp) {
|
||||||
|
for(yp=y; yp<y+fh; ++yp) {
|
||||||
|
i = xp + yp * w;
|
||||||
|
|
||||||
|
fits = false;
|
||||||
|
for(a=0; a<aLength; ++a) {
|
||||||
|
if(map[i]==accepted[a]) {
|
||||||
|
fits = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!fits) {
|
||||||
|
nonFitting++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nonFitting<leastNonFitting) {
|
||||||
|
featureX = x;
|
||||||
|
featureY = y;
|
||||||
|
leastNonFitting = nonFitting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void createVillageHouse(int hid, int x, int y, int hw, int hh, int ex, int ey, int w, int h, int level, u8 * map, u8 * data) {
|
||||||
|
//create wall and floor
|
||||||
|
int xp = x;
|
||||||
|
int yp = y;
|
||||||
|
for(xp=x; xp<x+hw; ++xp) {
|
||||||
|
for(yp=y; yp<y+hh; ++yp) {
|
||||||
|
if(xp==x || xp==x+hw-1 || yp==y || yp==y+hh-1) map[xp + yp * w] = TILE_WOOD_WALL;
|
||||||
|
else map[xp + yp * w] = TILE_WOOD_FLOOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//recreate entrance
|
||||||
|
map[ex + ey * w] = TILE_WOOD_FLOOR;
|
||||||
|
|
||||||
|
//create npcs
|
||||||
|
if(hid==0) {
|
||||||
|
addEntityToList(newNPCEntity(NPC_GIRL, (x+hw/2) << 4, (y+hh/2) << 4, level), &eManager);
|
||||||
|
} else if(hid==1) {
|
||||||
|
addEntityToList(newNPCEntity(NPC_PRIEST, (x+hw/2) << 4, (y+hh/2) << 4, level), &eManager);
|
||||||
|
} else if(hid==2) {
|
||||||
|
addEntityToList(newNPCEntity(NPC_FARMER, (x+hw/2) << 4, (y+hh/2) << 4, level), &eManager);
|
||||||
|
//TODO: maybe create farm?
|
||||||
|
for(xp=x; xp<x+hw; ++xp) {
|
||||||
|
map[xp + yp * w] = TILE_WHEAT;
|
||||||
|
map[xp + (yp+1) * w] = TILE_WHEAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//add Latern Entity
|
||||||
|
int loffx = -12;
|
||||||
|
int loffy = -12;
|
||||||
|
if(hid==2) loffx = 12;
|
||||||
|
addEntityToList(newFurnitureEntity(ITEM_LANTERN, NULL, ((x+hw/2) << 4) + loffx, ((y+hh/2) << 4) + loffy, level), &eManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void createVillage(int w, int h, int level, u8 * map, u8 * data) {
|
||||||
|
int vw = 17;
|
||||||
|
int vh = 17;
|
||||||
|
int accepted[] = {TILE_GRASS};
|
||||||
|
findFeatureLocation(vw, vh, accepted, 1, 500, w, h, map, data);
|
||||||
|
|
||||||
|
int x = featureX;
|
||||||
|
int y = featureY;
|
||||||
|
int cx = x + vw/2;
|
||||||
|
int cy = y + vh/2;
|
||||||
|
int px;
|
||||||
|
int py;
|
||||||
|
|
||||||
|
int hw;
|
||||||
|
int hh;
|
||||||
|
int hx;
|
||||||
|
int hy;
|
||||||
|
int ex;
|
||||||
|
int ey;
|
||||||
|
|
||||||
|
//"well" in the middle
|
||||||
|
map[(cx-1) + (cy-1) * w] = TILE_SAND;
|
||||||
|
map[(cx+0) + (cy-1) * w] = TILE_SAND;
|
||||||
|
map[(cx+1) + (cy-1) * w] = TILE_SAND;
|
||||||
|
map[(cx-1) + (cy+0) * w] = TILE_SAND;
|
||||||
|
map[(cx+0) + (cy+0) * w] = TILE_WATER;
|
||||||
|
map[(cx+1) + (cy+0) * w] = TILE_SAND;
|
||||||
|
map[(cx-1) + (cy+1) * w] = TILE_SAND;
|
||||||
|
map[(cx+0) + (cy+1) * w] = TILE_SAND;
|
||||||
|
map[(cx+1) + (cy+1) * w] = TILE_SAND;
|
||||||
|
|
||||||
|
//"paths" outwards leading to the "houses"
|
||||||
|
//left
|
||||||
|
px = cx-1;
|
||||||
|
py = cy-1 + rand()%3;
|
||||||
|
while(px>x) {
|
||||||
|
map[px + py * w] = TILE_SAND;
|
||||||
|
--px;
|
||||||
|
}
|
||||||
|
hw = 4 + rand()%2;
|
||||||
|
hh = 4 + rand()%2;
|
||||||
|
hx = px + 1;
|
||||||
|
hy = py - hh + 2 + rand()%(hh-2);
|
||||||
|
ex = px + hw;
|
||||||
|
ey = py;
|
||||||
|
createVillageHouse(0, hx, hy, hw, hh, ex, ey, w, h, level, map, data);
|
||||||
|
|
||||||
|
//top
|
||||||
|
px = cx-1 + rand()%3;
|
||||||
|
py = cy-1;
|
||||||
|
while(py>y) {
|
||||||
|
map[px + py * w] = TILE_SAND;
|
||||||
|
--py;
|
||||||
|
}
|
||||||
|
hw = 5 + rand()%2;
|
||||||
|
hh = 4 + rand()%2;
|
||||||
|
hx = px - hw + 2 + rand()%(hw-2);
|
||||||
|
hy = py + 1;
|
||||||
|
ex = px;
|
||||||
|
ey = py+hh;
|
||||||
|
createVillageHouse(1, hx, hy, hw, hh, ex, ey, w, h, level, map, data);
|
||||||
|
|
||||||
|
//right
|
||||||
|
px = cx+1;
|
||||||
|
py = cy-1 + rand()%3;
|
||||||
|
while(px<x+vw) {
|
||||||
|
map[px + py * w] = TILE_SAND;
|
||||||
|
++px;
|
||||||
|
}
|
||||||
|
hw = 4 + rand()%2;
|
||||||
|
hh = 4 + rand()%2;
|
||||||
|
hx = px - hw;
|
||||||
|
hy = py - hh + 2 + rand()%(hh-2);
|
||||||
|
ex = px - hw;
|
||||||
|
ey = py;
|
||||||
|
createVillageHouse(2, hx, hy, hw, hh, ex, ey, w, h, level, map, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void createDwarfHouse(int w, int h, int level, u8 * map, u8 * data) {
|
||||||
|
int vw = 7;
|
||||||
|
int vh = 7;
|
||||||
|
int accepted[] = {TILE_ROCK};
|
||||||
|
findFeatureLocation(vw, vh, accepted, 1, 500, w, h, map, data);
|
||||||
|
|
||||||
|
int x = featureX;
|
||||||
|
int y = featureY;
|
||||||
|
int xp;
|
||||||
|
int yp;
|
||||||
|
|
||||||
|
for(xp=x; xp<x+vw; ++xp) {
|
||||||
|
for(yp=y; yp<y+vh; ++yp) {
|
||||||
|
if(xp==x || xp==x+vw-1 || yp==y || yp==y+vh-1) map[xp + yp * w] = TILE_STONE_WALL;
|
||||||
|
else map[xp + yp * w] = TILE_DIRT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//entrance
|
||||||
|
xp = x+vw/2;
|
||||||
|
map[xp + (yp-1) * w] = TILE_DIRT;
|
||||||
|
|
||||||
|
//pillars
|
||||||
|
map[(x+2) + (y+2) * w] = TILE_STONE_WALL;
|
||||||
|
map[(x+vw-1-2) + (y+2) * w] = TILE_STONE_WALL;
|
||||||
|
|
||||||
|
addEntityToList(newNPCEntity(NPC_DWARF, ((x+vw/2) << 4) + 8, (y+vh/2) << 4, level), &eManager);
|
||||||
|
|
||||||
|
|
||||||
|
addEntityToList(newFurnitureEntity(ITEM_LANTERN, NULL, (x+1+1) << 4, (y+1+3) << 4, level), &eManager);
|
||||||
|
addEntityToList(newFurnitureEntity(ITEM_LANTERN, NULL, (x+vw-1-1) << 4, (y+1+3) << 4, level), &eManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data) {
|
||||||
|
int tries;
|
||||||
|
|
||||||
|
for(tries=0; tries<100; ++tries) {
|
||||||
|
int x = 5+(rand()%(w-10 -10));
|
||||||
|
int y = 5+(rand()%(h-10 -10));
|
||||||
|
int xr;
|
||||||
|
int yr;
|
||||||
|
int wr = 10+(rand()%11);
|
||||||
|
int hr = 10+(rand()&11);
|
||||||
|
int xp;
|
||||||
|
int yp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
//create Dragonroom
|
||||||
|
if(dragon) {
|
||||||
|
wr = 20;
|
||||||
|
hr = 20;
|
||||||
|
x = 5 + (rand()%2)*(w-5*2-wr);
|
||||||
|
y = 5 + (rand()%2)*(h-5*2-hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
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-1; xr < x+wr+1; ++xr) {
|
||||||
|
for(yr = y-1; yr < y+hr+1; ++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;
|
||||||
|
data[i] = randomTile[rand()%randomTileSize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create path back to existing stuff
|
||||||
|
xp = x + wr/2;
|
||||||
|
yp = y + hr/2;
|
||||||
|
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) {
|
||||||
|
//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 dragon room
|
||||||
|
if(dragon) {
|
||||||
|
for(xr = x; xr < x+wr; ++xr) {
|
||||||
|
for(yr = y; yr < y+hr; ++yr) {
|
||||||
|
i = xr + yr * w;
|
||||||
|
|
||||||
|
if((xr==x+1 || xr==x+wr-2 || yr==y+1 || yr==y+hr-2) && (xr!=x && xr!=x+wr-1 && yr!=y && yr!=y+hr-1)) {
|
||||||
|
map[i] = TILE_MAGIC_BARRIER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//add Dragon Entity
|
||||||
|
addEntityToList(newDragonEntity((x+wr/2) << 4, (y+hr/2) << 4, level), &eManager);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//dekorate room
|
||||||
|
bool lava = (rand()%4)==0;
|
||||||
|
bool pillars = (rand()%4)==0;
|
||||||
|
bool books = (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;
|
||||||
|
data[i] = 0;
|
||||||
|
} 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;
|
||||||
|
data[i] = 0;
|
||||||
|
} else if(books && (xr>x && xr<x+wr-1 && yr>y && yr<y+hr-1 && yr%2==0)) {
|
||||||
|
map[i] = TILE_BOOKSHELVES;
|
||||||
|
data[i] = rand()%3;
|
||||||
|
if(!hasNPC && rand()%50) {
|
||||||
|
hasNPC = true;
|
||||||
|
addEntityToList(newNPCEntity(NPC_LIBRARIAN, (xr << 4) + 8, ((yr+1) << 4) + 8, level), &eManager);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//add magic pillars for dragon barrier
|
||||||
|
if(xr==x+wr/2 && yr==y+hr/2) {
|
||||||
|
int pcount = 0;
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0; i < eManager.lastSlot[5]; ++i) {
|
||||||
|
Entity * e = &eManager.entities[5][i];
|
||||||
|
|
||||||
|
if(e->type == ENTITY_MAGIC_PILLAR) {
|
||||||
|
++pcount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(pcount<8) {
|
||||||
|
addEntityToList(newMagicPillarEntity((xr << 4) + 8, (yr << 4) + 8, level), &eManager);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rand()%50==0) map[i] = TILE_IRONORE + (rand()%3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,21 @@ float nextFloat();
|
||||||
double sample(double * values, int x, int y);
|
double sample(double * values, int x, int y);
|
||||||
double * Noise(int w, int h, int featureSize);
|
double * Noise(int w, int h, int featureSize);
|
||||||
void newSeed();
|
void newSeed();
|
||||||
void createAndValidateTopMap(int w, int h, u8 * map, u8 * data);
|
void createAndValidateTopMap(int w, int h, int level, u8 * map, u8 * data);
|
||||||
void createTopMap(int w, int h, u8 * map, u8 * data);
|
void createTopMap(int w, int h, int level, u8 * map, u8 * data);
|
||||||
void createAndValidateUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data);
|
void createAndValidateUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 * data);
|
||||||
void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data);
|
void createUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 * data);
|
||||||
void createAndValidateDungeonMap(int w, int h, u8 * map, u8 * data);
|
void createAndValidateDungeonMap(int w, int h, int level, u8 * map, u8 * data);
|
||||||
void createDungeonMap(int w, int h, u8 * map, u8 * data);
|
void createDungeonMap(int w, int h, int level, u8 * map, u8 * data);
|
||||||
void createAndValidateSkyMap(int w, int h, u8 * map, u8 * data);
|
void createAndValidateSkyMap(int w, int h, int level, u8 * map, u8 * data);
|
||||||
void createSkyMap(int w, int h, u8 * map, u8 * data);
|
void createSkyMap(int w, int h, int level, u8 * map, u8 * data);
|
||||||
|
|
||||||
|
int featureX;
|
||||||
|
int featureY;
|
||||||
|
void findFeatureLocation(int fw, int fh, int * accepted, int aLength, int maxTries, int w, int h, u8 * map, u8 * data);
|
||||||
|
|
||||||
|
void createVillage(int w, int h, int level, u8 * map, u8 * data);
|
||||||
|
void createDwarfHouse(int w, int h, int level, u8 * map, u8 * data);
|
||||||
|
|
||||||
|
bool hasNPC;
|
||||||
|
void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data);
|
|
@ -531,7 +531,9 @@ void tickMenu(int menu){
|
||||||
}
|
}
|
||||||
|
|
||||||
enterDungeon();
|
enterDungeon();
|
||||||
}
|
} else if(TESTGODMODE) {
|
||||||
|
enterDungeon();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
leaveDungeon();
|
leaveDungeon();
|
||||||
}
|
}
|
||||||
|
@ -755,6 +757,9 @@ void tickMenu(int menu){
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case MENU_NPC:
|
||||||
|
tickNPCMenu();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1158,8 +1163,8 @@ void renderMenu(int menu,int xscr,int yscr){
|
||||||
drawTextColor("Cost",248+1,78+1,0xFF000000);
|
drawTextColor("Cost",248+1,78+1,0xFF000000);
|
||||||
drawTextColor("Cost",248,78,0xFF6FE2E2);
|
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(currentCraftTitle,24+1,14+1,0xFF000000);
|
||||||
drawTextColor("Crafting",24,14,0xFF6FE2E2);
|
drawTextColor(currentCraftTitle,24,14,0xFF6FE2E2);
|
||||||
renderRecipes(currentRecipes, 1, 1, 14, 14, curInvSel);
|
renderRecipes(currentRecipes, 1, 1, 14, 14, curInvSel);
|
||||||
|
|
||||||
Recipe* rec = ¤tRecipes->recipes[curInvSel];
|
Recipe* rec = ¤tRecipes->recipes[curInvSel];
|
||||||
|
@ -1420,7 +1425,20 @@ void renderMenu(int menu,int xscr,int yscr){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sf2d_end_frame();
|
sf2d_end_frame();
|
||||||
break;
|
break;
|
||||||
|
case MENU_NPC:
|
||||||
|
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;
|
||||||
|
|
||||||
|
renderNPCMenu(xscr, yscr);
|
||||||
|
sf2d_end_frame();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "MenuTutorial.h"
|
#include "MenuTutorial.h"
|
||||||
#include "texturepack.h"
|
#include "texturepack.h"
|
||||||
|
#include "Quests.h"
|
||||||
|
|
||||||
void initMenus();
|
void initMenus();
|
||||||
|
|
||||||
|
|
417
source/Quests.c
Normal file
417
source/Quests.c
Normal file
|
@ -0,0 +1,417 @@
|
||||||
|
#include "Quests.h"
|
||||||
|
|
||||||
|
u8 currentNPC;
|
||||||
|
|
||||||
|
int currentNPCMenu;
|
||||||
|
int currentNPCVal;
|
||||||
|
|
||||||
|
int currentTalkSel;
|
||||||
|
bool currentTalkDone;
|
||||||
|
int currentTalkOptions;
|
||||||
|
char * currentTalkOption0;
|
||||||
|
char * currentTalkOption1;
|
||||||
|
char * currentTalkOption2;
|
||||||
|
char * currentTalk0;
|
||||||
|
char * currentTalk1;
|
||||||
|
char * currentTalk2;
|
||||||
|
char * currentTalk3;
|
||||||
|
char * currentTalk4;
|
||||||
|
char * currentTalk5;
|
||||||
|
|
||||||
|
void initQuests() {
|
||||||
|
questManager.size = 2;
|
||||||
|
questManager.questlines = (Questline*)malloc(sizeof(Questline) * (questManager.size));
|
||||||
|
|
||||||
|
priestTrades.size = 5;
|
||||||
|
priestTrades.recipes = (Recipe*)malloc(sizeof(Recipe) * (priestTrades.size));
|
||||||
|
priestTrades.recipes[0] = defineRecipe(ITEM_DUNGEON_KEY,1,1,ITEM_MAGIC_DUST,2);
|
||||||
|
priestTrades.recipes[1] = defineRecipe(ITEM_WIZARD_SUMMON,1,4,ITEM_CLOUD,100,ITEM_IRONINGOT,10,ITEM_BONE,10,ITEM_LEATHER,10);
|
||||||
|
priestTrades.recipes[2] = defineRecipe(TOOL_MAGIC_COMPASS,1,2,ITEM_IRONINGOT,10,ITEM_GLASS,5);
|
||||||
|
priestTrades.recipes[3] = defineRecipe(ITEM_COIN,1,1,ITEM_SLIME,5);
|
||||||
|
priestTrades.recipes[4] = defineRecipe(ITEM_COIN,1,1,ITEM_FLESH,5);
|
||||||
|
|
||||||
|
farmerTrades.size = 7;
|
||||||
|
farmerTrades.recipes = (Recipe*)malloc(sizeof(Recipe) * (farmerTrades.size));
|
||||||
|
farmerTrades.recipes[0] = defineRecipe(ITEM_WHEAT,5,1,ITEM_COIN,3);
|
||||||
|
farmerTrades.recipes[1] = defineRecipe(ITEM_BREAD,1,1,ITEM_COIN,3);
|
||||||
|
farmerTrades.recipes[2] = defineRecipe(ITEM_APPLE,2,1,ITEM_COIN,4);
|
||||||
|
farmerTrades.recipes[3] = defineRecipe(ITEM_ACORN,3,1,ITEM_COIN,1);
|
||||||
|
farmerTrades.recipes[4] = defineRecipe(ITEM_SEEDS,4,1,ITEM_COIN,2);
|
||||||
|
farmerTrades.recipes[5] = defineRecipe(ITEM_COIN,2,1,ITEM_SEEDS,5);
|
||||||
|
farmerTrades.recipes[6] = defineRecipe(ITEM_COIN,1,1,ITEM_ACORN,5);
|
||||||
|
|
||||||
|
dwarfTrades.size = 2;
|
||||||
|
dwarfTrades.recipes = (Recipe*)malloc(sizeof(Recipe) * (dwarfTrades.size));
|
||||||
|
dwarfTrades.recipes[0] = defineRecipe(ITEM_IRONINGOT,4,1,ITEM_GOLDINGOT,1);
|
||||||
|
dwarfTrades.recipes[1] = defineRecipe(ITEM_GOLDINGOT,2,1,ITEM_GEM,1);
|
||||||
|
//TODO: Trade Dragon Scales for something really nice
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetQuests() {
|
||||||
|
int i;
|
||||||
|
for(i=0; i<questManager.size; ++i) {
|
||||||
|
questManager.questlines[i].currentQuest = 0;
|
||||||
|
questManager.questlines[i].currentQuestDone = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeQuests() {
|
||||||
|
free(questManager.questlines);
|
||||||
|
free(priestTrades.recipes);
|
||||||
|
free(farmerTrades.recipes);
|
||||||
|
free(dwarfTrades.recipes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void openNPCMenu(int npc) {
|
||||||
|
currentNPC = npc;
|
||||||
|
currentNPCVal = 0;
|
||||||
|
currentMenu = MENU_NPC;
|
||||||
|
currentNPCMenu = NPC_MENU_TALK;
|
||||||
|
|
||||||
|
currentTalkSel = 0;
|
||||||
|
currentTalkDone = false;
|
||||||
|
currentTalkOptions = 1;
|
||||||
|
currentTalkOption0 = "Bye";
|
||||||
|
currentTalkOption1 = "";
|
||||||
|
currentTalkOption2 = "";
|
||||||
|
currentTalk0 = "";
|
||||||
|
currentTalk1 = "";
|
||||||
|
currentTalk2 = "";
|
||||||
|
currentTalk3 = "";
|
||||||
|
currentTalk4 = "";
|
||||||
|
currentTalk5 = "";
|
||||||
|
|
||||||
|
//TODO: Handle upon currentNPC as well as the fitting quest progress
|
||||||
|
switch(currentNPC) {
|
||||||
|
case NPC_GIRL:
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NPC_PRIEST:
|
||||||
|
currentTalkOptions = 3;
|
||||||
|
currentTalkOption1 = "Trade";
|
||||||
|
currentTalkOption2 = "Why are you so few?";
|
||||||
|
|
||||||
|
currentTalk0 = "Welcome to our small village";
|
||||||
|
currentTalk1 = "I am the leader of our group.";
|
||||||
|
currentTalk2 = "If you have anything usefull";
|
||||||
|
currentTalk3 = "for us I might be able to";
|
||||||
|
currentTalk4 = "provide something nice in";
|
||||||
|
currentTalk5 = "exchange.";
|
||||||
|
break;
|
||||||
|
case NPC_FARMER:
|
||||||
|
currentTalkOptions = 2;
|
||||||
|
currentTalkOption0 = "Maybe some other time";
|
||||||
|
currentTalkOption1 = "Trade";
|
||||||
|
|
||||||
|
currentTalk0 = "Hello friend!";
|
||||||
|
currentTalk1 = "Nice seeing somebody else";
|
||||||
|
currentTalk2 = "visit my little farm.";
|
||||||
|
currentTalk3 = "Interested in buying some";
|
||||||
|
currentTalk4 = "fresh farm goods?";
|
||||||
|
currentTalk5 = "";
|
||||||
|
break;
|
||||||
|
case NPC_LIBRARIAN:
|
||||||
|
currentTalkOptions = 2;
|
||||||
|
currentTalkOption0 = "Nothing";
|
||||||
|
currentTalkOption1 = "What are you doing here?";
|
||||||
|
if(questManager.questlines[1].currentQuest==1) {
|
||||||
|
currentTalkOptions = 3;
|
||||||
|
currentTalkOption2 = "Dwarvish language";
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTalk0 = "Oh hello?";
|
||||||
|
currentTalk1 = "You must be quite brave";
|
||||||
|
currentTalk2 = "or stupid to be walking";
|
||||||
|
currentTalk3 = "around in this dungeon.";
|
||||||
|
currentTalk4 = "";
|
||||||
|
currentTalk5 = "Who can I help you?";
|
||||||
|
break;
|
||||||
|
case NPC_DWARF:
|
||||||
|
if(questManager.questlines[1].currentQuest<=1) {
|
||||||
|
questManager.questlines[1].currentQuest = 1;
|
||||||
|
|
||||||
|
currentTalkOptions = 1;
|
||||||
|
currentTalkOption0 = "?";
|
||||||
|
|
||||||
|
currentTalk0 = "Dwo neal bet reck da lo";
|
||||||
|
currentTalk1 = "dhum don lir lugn at el";
|
||||||
|
currentTalk2 = "nur tor erno ur yo trad";
|
||||||
|
currentTalk3 = "thra so tir kho ukk tin";
|
||||||
|
currentTalk4 = "hel dro ic";
|
||||||
|
currentTalk5 = "";
|
||||||
|
//TODO: set to 2 once translation book has been bought from librarian(can only be done once it is 1, so the dwarf has been found once)
|
||||||
|
} else if(questManager.questlines[1].currentQuest==2) {
|
||||||
|
currentTalkOptions = 2;
|
||||||
|
currentTalkOption0 = "Not really";
|
||||||
|
currentTalkOption1 = "Trade";
|
||||||
|
|
||||||
|
currentTalk0 = "How are ya?";
|
||||||
|
currentTalk1 = "Pretty unusal meeting a";
|
||||||
|
currentTalk2 = "human down here.";
|
||||||
|
currentTalk3 = "";
|
||||||
|
currentTalk4 = "have something valuable";
|
||||||
|
currentTalk5 = "to trade?";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tickTalkMenu() {
|
||||||
|
if (k_menu.clicked || k_decline.clicked) currentMenu = MENU_NONE;
|
||||||
|
|
||||||
|
if (k_up.clicked){ ++currentTalkSel; if(currentTalkSel >= currentTalkOptions) currentTalkSel=0;}
|
||||||
|
if (k_down.clicked){ --currentTalkSel; if(currentTalkSel < 0) currentTalkSel=currentTalkOptions-1;}
|
||||||
|
|
||||||
|
if(k_accept.clicked){
|
||||||
|
currentTalkDone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tickNPCMenu() {
|
||||||
|
//TODO: Handle upon currentNPC as well as the fitting quest progress
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK) tickTalkMenu();
|
||||||
|
|
||||||
|
|
||||||
|
switch(currentNPC) {
|
||||||
|
case NPC_GIRL:
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NPC_PRIEST:
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK && currentTalkDone) {
|
||||||
|
if(currentNPCVal==0) {
|
||||||
|
if(currentTalkSel==0) {
|
||||||
|
currentMenu = MENU_NONE;
|
||||||
|
} else if(currentTalkSel==1) {
|
||||||
|
currentRecipes = &priestTrades;
|
||||||
|
currentCraftTitle = "Trading";
|
||||||
|
currentMenu = MENU_CRAFTING;
|
||||||
|
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
||||||
|
sortRecipes(currentRecipes);
|
||||||
|
} else if(currentTalkSel==2) {
|
||||||
|
currentNPCVal = 1;
|
||||||
|
|
||||||
|
currentTalkSel = 0;
|
||||||
|
currentTalkDone = false;
|
||||||
|
currentTalkOptions = 1;
|
||||||
|
currentTalkOption0 = "...";
|
||||||
|
|
||||||
|
currentTalk0 = "For quite some time now this";
|
||||||
|
currentTalk1 = "village has been tyrannized";
|
||||||
|
currentTalk2 = "by a powerfull Air Wizard.";
|
||||||
|
currentTalk3 = "We are the only ones who";
|
||||||
|
currentTalk4 = "still have not given up";
|
||||||
|
currentTalk5 = "our old homes.";
|
||||||
|
}
|
||||||
|
} else if(currentNPCVal==1) {
|
||||||
|
if(currentTalkSel==0) {
|
||||||
|
currentNPCVal = 2;
|
||||||
|
|
||||||
|
currentTalkSel = 0;
|
||||||
|
currentTalkDone = false;
|
||||||
|
currentTalkOptions = 1;
|
||||||
|
currentTalkOption0 = "...";
|
||||||
|
|
||||||
|
currentTalk0 = "Most of the time the wizard";
|
||||||
|
currentTalk1 = "hides somewhere in the";
|
||||||
|
currentTalk2 = "cloudes. They can only be";
|
||||||
|
currentTalk3 = "reached by a stairwell";
|
||||||
|
currentTalk4 = "protected by an almost";
|
||||||
|
currentTalk5 = "undestroyable stone barrier.";
|
||||||
|
}
|
||||||
|
} else if(currentNPCVal==2) {
|
||||||
|
if(currentTalkSel==0) {
|
||||||
|
currentNPCVal = 3;
|
||||||
|
|
||||||
|
currentTalkSel = 0;
|
||||||
|
currentTalkDone = false;
|
||||||
|
currentTalkOptions = 1;
|
||||||
|
currentTalkOption0 = "...";
|
||||||
|
|
||||||
|
currentTalk0 = "I am guessing you would ";
|
||||||
|
currentTalk1 = "need tools atleast as";
|
||||||
|
currentTalk2 = "strong as diamonds to be";
|
||||||
|
currentTalk3 = "able to destroy it.";
|
||||||
|
currentTalk4 = "";
|
||||||
|
currentTalk5 = "";
|
||||||
|
}
|
||||||
|
} else if(currentNPCVal==3) {
|
||||||
|
if(currentTalkSel==0) {
|
||||||
|
currentNPCVal = 4;
|
||||||
|
|
||||||
|
currentTalkSel = 0;
|
||||||
|
currentTalkDone = false;
|
||||||
|
currentTalkOptions = 2;
|
||||||
|
currentTalkOption0 = "Let me do it!";
|
||||||
|
currentTalkOption1 = "I am not sure";
|
||||||
|
|
||||||
|
currentTalk0 = "I am willing to give an";
|
||||||
|
currentTalk1 = "ancient artifact passed";
|
||||||
|
currentTalk2 = "down over generations to";
|
||||||
|
currentTalk3 = "anybody who manages to";
|
||||||
|
currentTalk4 = "chase the wizard away and";
|
||||||
|
currentTalk5 = "come back with proof.";
|
||||||
|
}
|
||||||
|
} else if(currentNPCVal==4) {
|
||||||
|
currentMenu = MENU_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NPC_FARMER:
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK && currentTalkDone) {
|
||||||
|
if(currentNPCVal==0) {
|
||||||
|
if(currentTalkSel==0) {
|
||||||
|
currentMenu = MENU_NONE;
|
||||||
|
} else if(currentTalkSel==1) {
|
||||||
|
currentRecipes = &farmerTrades;
|
||||||
|
currentCraftTitle = "Trading";
|
||||||
|
currentMenu = MENU_CRAFTING;
|
||||||
|
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
||||||
|
sortRecipes(currentRecipes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NPC_LIBRARIAN:
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK && currentTalkDone) {
|
||||||
|
if(currentNPCVal==0) {
|
||||||
|
if(currentTalkSel==0) {
|
||||||
|
currentMenu = MENU_NONE;
|
||||||
|
} else if(currentTalkSel==1) {
|
||||||
|
currentNPCVal = 2;
|
||||||
|
|
||||||
|
currentTalkSel = 0;
|
||||||
|
currentTalkDone = false;
|
||||||
|
currentTalkOptions = 1;
|
||||||
|
currentTalkOption0 = "Ok";
|
||||||
|
|
||||||
|
currentTalk0 = "The books in this dungeon";
|
||||||
|
currentTalk1 = "house secrets that cannot be";
|
||||||
|
currentTalk2 = "found anywhere else in the";
|
||||||
|
currentTalk3 = "world. So I came to study";
|
||||||
|
currentTalk4 = "them. Most are written in";
|
||||||
|
currentTalk5 = "an ancient language.";
|
||||||
|
} else if(currentTalkSel==2) {
|
||||||
|
currentNPCVal = 1;
|
||||||
|
|
||||||
|
currentTalkSel = 0;
|
||||||
|
currentTalkDone = false;
|
||||||
|
currentTalkOptions = 2;
|
||||||
|
currentTalkOption0 = "I need to think about it";
|
||||||
|
currentTalkOption1 = "Here they are";
|
||||||
|
|
||||||
|
currentTalk0 = "So you have met a dwarf but";
|
||||||
|
currentTalk1 = "had a little communication";
|
||||||
|
currentTalk2 = "problem? I do have a dwarvish";
|
||||||
|
currentTalk3 = "translation book but I havent";
|
||||||
|
currentTalk4 = "read it yet. For 10 Gold bars";
|
||||||
|
currentTalk5 = "I will give it to you anyway.";
|
||||||
|
}
|
||||||
|
} else if(currentNPCVal==1) {
|
||||||
|
if(currentTalkSel==0) {
|
||||||
|
currentMenu = MENU_NONE;
|
||||||
|
} else if(currentTalkSel==1) {
|
||||||
|
currentNPCVal = 2;
|
||||||
|
|
||||||
|
currentTalkSel = 0;
|
||||||
|
currentTalkDone = false;
|
||||||
|
currentTalkOptions = 1;
|
||||||
|
currentTalkOption0 = "";
|
||||||
|
|
||||||
|
if(countItemInv(ITEM_GOLDINGOT,0,player.p.inv)>=10) {
|
||||||
|
//remove gold from player inventory
|
||||||
|
//TODO: Maybe I should make a generic substract items method sometime
|
||||||
|
Item* item = getItemFromInventory(ITEM_GOLDINGOT, player.p.inv);
|
||||||
|
item->countLevel -= 10;
|
||||||
|
if(item->countLevel < 1) removeItemFromInventory(item->slotNum, player.p.inv);
|
||||||
|
|
||||||
|
questManager.questlines[1].currentQuest = 2;
|
||||||
|
|
||||||
|
currentTalk0 = "Thank you these will be";
|
||||||
|
currentTalk1 = "really helpfull.";
|
||||||
|
currentTalk2 = "Here take this book with";
|
||||||
|
currentTalk3 = "it you should be able to";
|
||||||
|
currentTalk4 = "easily understand anything";
|
||||||
|
currentTalk5 = "a dwarf can say.";
|
||||||
|
|
||||||
|
currentTalkOption0 = "Thanks";
|
||||||
|
} else {
|
||||||
|
currentTalk0 = "You do not seem to have";
|
||||||
|
currentTalk1 = "enough Gold Bars with you.";
|
||||||
|
currentTalk2 = "";
|
||||||
|
currentTalk3 = "Ask again when you have";
|
||||||
|
currentTalk4 = "collected the 10 Bars.";
|
||||||
|
currentTalk5 = "";
|
||||||
|
|
||||||
|
currentTalkOption0 = "Ok";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(currentNPCVal==2) {
|
||||||
|
if(currentTalkSel==0) {
|
||||||
|
currentMenu = MENU_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NPC_DWARF:
|
||||||
|
if(questManager.questlines[1].currentQuest<=1) {
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK && currentTalkDone) {
|
||||||
|
if(currentNPCVal==0) currentMenu = MENU_NONE;
|
||||||
|
}
|
||||||
|
} else if(questManager.questlines[1].currentQuest==2) {
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK && currentTalkDone) {
|
||||||
|
if(currentTalkSel==0) {
|
||||||
|
currentMenu = MENU_NONE;
|
||||||
|
} else if(currentTalkSel==1) {
|
||||||
|
currentRecipes = &dwarfTrades;
|
||||||
|
currentCraftTitle = "Trading";
|
||||||
|
currentMenu = MENU_CRAFTING;
|
||||||
|
checkCanCraftRecipes(currentRecipes, player.p.inv);
|
||||||
|
sortRecipes(currentRecipes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderTalkMenu(char * name) {
|
||||||
|
renderFrame(1,1,24,14,0xFFFF1010);
|
||||||
|
drawTextColor(name,24+1,14+1,0xFF000000);
|
||||||
|
drawTextColor(name,24,14,0xFF6FE2E2);
|
||||||
|
|
||||||
|
drawText(currentTalk0, 32, 32);
|
||||||
|
drawText(currentTalk1, 32, 48);
|
||||||
|
drawText(currentTalk2, 32, 64);
|
||||||
|
drawText(currentTalk3, 32, 80);
|
||||||
|
drawText(currentTalk4, 32, 96);
|
||||||
|
drawText(currentTalk5, 32, 112);
|
||||||
|
|
||||||
|
if(currentTalkOptions>=3) drawText(currentTalkOption2, 64, 147);
|
||||||
|
if(currentTalkOptions>=2) drawText(currentTalkOption1, 64, 171);
|
||||||
|
if(currentTalkOptions>=1) drawText(currentTalkOption0, 64, 195);
|
||||||
|
|
||||||
|
if(currentTalkOptions>=3 && currentTalkSel==2) drawText(">", 48, 147);
|
||||||
|
if(currentTalkOptions>=2 && currentTalkSel==1) drawText(">", 48, 171);
|
||||||
|
if(currentTalkOptions>=1 && currentTalkSel==0) drawText(">", 48, 195);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderNPCMenu(int xscr, int yscr) {
|
||||||
|
//TODO: Handle upon currentNPC as well as the fitting quest progress
|
||||||
|
switch(currentNPC) {
|
||||||
|
case NPC_GIRL:
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK) renderTalkMenu("TODO");
|
||||||
|
break;
|
||||||
|
case NPC_PRIEST:
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK) renderTalkMenu("Priest Brom");
|
||||||
|
break;
|
||||||
|
case NPC_FARMER:
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK) renderTalkMenu("Farmer Garrow");
|
||||||
|
break;
|
||||||
|
case NPC_LIBRARIAN:
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK) renderTalkMenu("Librarian Ajihad");
|
||||||
|
break;
|
||||||
|
case NPC_DWARF:
|
||||||
|
if(currentNPCMenu==NPC_MENU_TALK) renderTalkMenu("Dwarf Orik");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
32
source/Quests.h
Normal file
32
source/Quests.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "render.h"
|
||||||
|
#include "Crafting.h"
|
||||||
|
|
||||||
|
#define NPC_MENU_TALK 0
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int currentQuest;
|
||||||
|
bool currentQuestDone;
|
||||||
|
} Questline;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int size;
|
||||||
|
Questline * questlines;
|
||||||
|
} QuestlineManager;
|
||||||
|
|
||||||
|
QuestlineManager questManager;
|
||||||
|
|
||||||
|
RecipeManager priestTrades;
|
||||||
|
RecipeManager farmerTrades;
|
||||||
|
RecipeManager dwarfTrades;
|
||||||
|
|
||||||
|
void initQuests();
|
||||||
|
void resetQuests();
|
||||||
|
void freeQuests();
|
||||||
|
|
||||||
|
void openNPCMenu(int npc);
|
||||||
|
|
||||||
|
void renderNPCMenu(int xscr, int yscr);
|
||||||
|
void tickNPCMenu();
|
156
source/Render.c
156
source/Render.c
|
@ -472,22 +472,39 @@ void renderTile(int i, int d, int x, int y) {
|
||||||
checkSurrTiles4(x >> 4, y >> 4, TILE_FLOWER);
|
checkSurrTiles4(x >> 4, y >> 4, TILE_FLOWER);
|
||||||
checkSurrTiles4(x >> 4, y >> 4, TILE_SAPLING_TREE);
|
checkSurrTiles4(x >> 4, y >> 4, TILE_SAPLING_TREE);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 256, 0);
|
if(currentLevel==1 && season==3) renderConnectedTile4(x, y, 256, 112);
|
||||||
|
else if(currentLevel==1 && season==2) renderConnectedTile4(x, y, 256, 128);
|
||||||
|
else renderConnectedTile4(x, y, 256, 0);
|
||||||
break;
|
break;
|
||||||
case TILE_TREE:
|
case TILE_TREE:
|
||||||
renderTile(TILE_GRASS, 0, x, y);
|
renderTile(TILE_GRASS, 0, x, y);
|
||||||
|
|
||||||
checkSurrTiles8(x >> 4, y >> 4, TILE_TREE);
|
checkSurrTiles8(x >> 4, y >> 4, TILE_TREE);
|
||||||
|
|
||||||
render(x, y, 256+((tu && tl && tul) ? 16 : 0), 48, 0);
|
if(season==2) {
|
||||||
render(x+8, y, 264+((tu && tr && tur) ? 16 : 0), 48, 0);
|
render(x, y, 352+((tu && tl && tul) ? 16 : 0), 96, 0);
|
||||||
render(x, y+8, 256+((td && tl && tdl) ? 16 : 0), 56, 0);
|
render(x+8, y, 360+((tu && tr && tur) ? 16 : 0), 96, 0);
|
||||||
render(x+8, y+8, 264+((td && tr && tdr) ? 16 : 0), 56, 0);
|
render(x, y+8, 352+((td && tl && tdl) ? 16 : 0), 104, 0);
|
||||||
|
render(x+8, y+8, 360+((td && tr && tdr) ? 16 : 0), 104, 0);
|
||||||
|
} else if(season==3) {
|
||||||
|
render(x, y, 352+((tu && tl && tul) ? 16 : 0), 112, 0);
|
||||||
|
render(x+8, y, 360+((tu && tr && tur) ? 16 : 0), 112, 0);
|
||||||
|
render(x, y+8, 352+((td && tl && tdl) ? 16 : 0), 120, 0);
|
||||||
|
render(x+8, y+8, 360+((td && tr && tdr) ? 16 : 0), 120, 0);
|
||||||
|
} else {
|
||||||
|
render(x, y, 256+((tu && tl && tul) ? 16 : 0), 48, 0);
|
||||||
|
render(x+8, y, 264+((tu && tr && tur) ? 16 : 0), 48, 0);
|
||||||
|
render(x, y+8, 256+((td && tl && tdl) ? 16 : 0), 56, 0);
|
||||||
|
render(x+8, y+8, 264+((td && tr && tdr) ? 16 : 0), 56, 0);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TILE_ROCK:
|
case TILE_ROCK:
|
||||||
checkSurrTiles8(x >> 4, y >> 4, TILE_ROCK);
|
checkSurrTiles8(x >> 4, y >> 4, TILE_ROCK);
|
||||||
renderConnectedTile8(x, y, 336, 64);
|
if(currentLevel>1)
|
||||||
|
renderConnectedTile8(x, y, 256, 96);
|
||||||
|
else
|
||||||
|
renderConnectedTile8(x, y, 336, 64);
|
||||||
break;
|
break;
|
||||||
case TILE_HARDROCK:
|
case TILE_HARDROCK:
|
||||||
checkSurrTiles8(x >> 4, y >> 4, TILE_HARDROCK);
|
checkSurrTiles8(x >> 4, y >> 4, TILE_HARDROCK);
|
||||||
|
@ -504,15 +521,20 @@ void renderTile(int i, int d, int x, int y) {
|
||||||
checkSurrTiles4(x >> 4, y >> 4, TILE_CACTUS);
|
checkSurrTiles4(x >> 4, y >> 4, TILE_CACTUS);
|
||||||
checkSurrTiles4(x >> 4, y >> 4, TILE_SAPLING_CACTUS);
|
checkSurrTiles4(x >> 4, y >> 4, TILE_SAPLING_CACTUS);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 320, 0);
|
if(currentLevel==1 && season==3) {
|
||||||
|
renderConnectedTile4(x, y, 256, 112);
|
||||||
|
} else {
|
||||||
|
renderConnectedTile4(x, y, 320, 0);
|
||||||
|
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
render16(x, y, 336, 48, 0);
|
render16(x, y, 336, 48, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TILE_WATER:
|
case TILE_WATER:
|
||||||
checkSurrTiles4(x >> 4, y >> 4, TILE_WATER);
|
checkSurrTiles4(x >> 4, y >> 4, TILE_WATER);
|
||||||
checkSurrTiles4(x >> 4, y >> 4, TILE_HOLE);
|
checkSurrTiles4(x >> 4, y >> 4, TILE_HOLE);
|
||||||
|
checkSurrTiles4(x >> 4, y >> 4, TILE_ICE);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 384, 0);
|
renderConnectedTile4(x, y, 384, 0);
|
||||||
|
|
||||||
|
@ -541,7 +563,8 @@ void renderTile(int i, int d, int x, int y) {
|
||||||
break;
|
break;
|
||||||
case TILE_FLOWER:
|
case TILE_FLOWER:
|
||||||
renderTile(TILE_GRASS, 0, x, y);
|
renderTile(TILE_GRASS, 0, x, y);
|
||||||
render16(x, y, 320, 48, getData(x >> 4, y >> 4));
|
if(currentLevel==1 && season==3) render16(x, y, 320, 112, getData(x >> 4, y >> 4));
|
||||||
|
else render16(x, y, 320, 48, getData(x >> 4, y >> 4));
|
||||||
break;
|
break;
|
||||||
case TILE_STAIRS_DOWN:
|
case TILE_STAIRS_DOWN:
|
||||||
if (currentLevel == 0)
|
if (currentLevel == 0)
|
||||||
|
@ -619,14 +642,14 @@ void renderTile(int i, int d, int x, int y) {
|
||||||
renderConnectedTile8(x, y, 384, 32);
|
renderConnectedTile8(x, y, 384, 32);
|
||||||
break;
|
break;
|
||||||
case TILE_DUNGEON_FLOOR:
|
case TILE_DUNGEON_FLOOR:
|
||||||
render16(x, y, 464, 32, 0);
|
render16(x, y, 464 + d*16, 32, 0);
|
||||||
break;
|
break;
|
||||||
case TILE_DUNGEON_ENTRANCE:
|
case TILE_DUNGEON_ENTRANCE:
|
||||||
render16(x, y, 480 + (currentLevel==5 ? 16 : 0), 32, 0);
|
render16(x, y, 352 + (currentLevel==5 ? 16 : 0), 80, 0);
|
||||||
break;
|
break;
|
||||||
case TILE_MAGIC_BARRIER:
|
case TILE_MAGIC_BARRIER:
|
||||||
renderTile(TILE_DUNGEON_FLOOR, 0, x, y);
|
renderTile(TILE_DUNGEON_FLOOR, 0, x, y);
|
||||||
render16(x, y, 320, 64, 0);
|
render16(x, y, 320, 64, getData(x >> 4, y >> 4));
|
||||||
|
|
||||||
//draw remaining pillar count
|
//draw remaining pillar count
|
||||||
if((player.x - (x+8))*(player.x - (x+8)) + (player.y - (y+8))*(player.y - (y+8)) <= 24*24) {
|
if((player.x - (x+8))*(player.x - (x+8)) + (player.y - (y+8))*(player.y - (y+8)) <= 24*24) {
|
||||||
|
@ -650,6 +673,38 @@ void renderTile(int i, int d, int x, int y) {
|
||||||
drawSizedTextColor(currentCount, x+4, y+4, 2, dungeonColor[0]);
|
drawSizedTextColor(currentCount, x+4, y+4, 2, dungeonColor[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case TILE_BOOKSHELVES:
|
||||||
|
checkSurrTiles4(x >> 4, y >> 4, TILE_BOOKSHELVES);
|
||||||
|
|
||||||
|
renderConnectedTile4(x, y, 384, 80 + d*16);
|
||||||
|
break;
|
||||||
|
case TILE_WOOD_FLOOR:
|
||||||
|
render16(x, y, 336, 96, 0);
|
||||||
|
break;
|
||||||
|
case TILE_MYCELIUM:
|
||||||
|
checkSurrTiles4(x >> 4, y >> 4, TILE_MYCELIUM);
|
||||||
|
checkSurrTiles4(x >> 4, y >> 4, TILE_MUSHROOM_BROWN);
|
||||||
|
checkSurrTiles4(x >> 4, y >> 4, TILE_MUSHROOM_RED);
|
||||||
|
|
||||||
|
if(currentLevel==1 && season==3) renderConnectedTile4(x, y, 256, 112);
|
||||||
|
else renderConnectedTile4(x, y, 448, 80);
|
||||||
|
break;
|
||||||
|
case TILE_MUSHROOM_BROWN:
|
||||||
|
renderTile(TILE_MYCELIUM, 0, x, y);
|
||||||
|
render16(x, y, 448 + (d&0x1)*16, 96, 0);
|
||||||
|
break;
|
||||||
|
case TILE_MUSHROOM_RED:
|
||||||
|
renderTile(TILE_MYCELIUM, 0, x, y);
|
||||||
|
render16(x, y, 480 + (d&0x1)*16, 96, 0);
|
||||||
|
break;
|
||||||
|
case TILE_ICE:
|
||||||
|
renderTile(TILE_WATER, 0, x, y);
|
||||||
|
//checkSurrTiles4(x >> 4, y >> 4, TILE_WATER);
|
||||||
|
//checkSurrTiles4(x >> 4, y >> 4, TILE_HOLE);
|
||||||
|
checkSurrTiles4(x >> 4, y >> 4, TILE_ICE);
|
||||||
|
|
||||||
|
renderConnectedTile4(x, y, 448, 112);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,6 +913,40 @@ void renderMenuBackground(int xScroll, int yScroll) {
|
||||||
renderDayNight();
|
renderDayNight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderWeather(int xScroll, int yScroll) {
|
||||||
|
if(currentLevel==1) {
|
||||||
|
if(season==3) {
|
||||||
|
int xp = -128 + ((tickCount>>2) - xScroll*2)%128;
|
||||||
|
int yp = -128 + ((tickCount>>1) - yScroll*2)%128;
|
||||||
|
int xp2 = 0 - ((tickCount>>2) + xScroll*2)%128;
|
||||||
|
int yp2 = -128 + ((tickCount>>1)+64 - yScroll*2)%128;
|
||||||
|
int xt;
|
||||||
|
int yt;
|
||||||
|
for(xt=0; xt<4; ++xt) {
|
||||||
|
for(yt=0; yt<3; ++yt) {
|
||||||
|
sf2d_draw_texture_part_scale(icons, xp + xt*128, yp + yt*128, 192, 0, 64, 64, 2, 2);
|
||||||
|
sf2d_draw_texture_part_scale(icons, xp2 + xt*128, yp2 + yt*128, 192, 0, 64, 64, 2, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rain) {
|
||||||
|
int xp = -((xScroll*2)%128);
|
||||||
|
int yp = -128 + ((tickCount<<2) - yScroll*2)%128;
|
||||||
|
int xp2 = -((xScroll*2+8)%128);
|
||||||
|
int yp2 = -128 + ((tickCount<<1)+64 - yScroll*2)%128;
|
||||||
|
int xt;
|
||||||
|
int yt;
|
||||||
|
for(xt=0; xt<4; ++xt) {
|
||||||
|
for(yt=0; yt<3; ++yt) {
|
||||||
|
sf2d_draw_texture_part_scale(icons, xp + xt*128, yp + yt*128, 128, 0, 64, 64, 2, 2);
|
||||||
|
sf2d_draw_texture_part_scale(icons, xp2 + xt*128, yp2 + yt*128, 128, 0, 64, 64, 2, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void renderDayNight() {
|
void renderDayNight() {
|
||||||
if(currentLevel==1 && (daytime<6000 || daytime>18000)) {
|
if(currentLevel==1 && (daytime<6000 || daytime>18000)) {
|
||||||
int color1 = 0x000C0C0C;
|
int color1 = 0x000C0C0C;
|
||||||
|
@ -1197,6 +1286,8 @@ void renderEntity(Entity* e, int x, int y) {
|
||||||
case ENTITY_GLOWWORM:
|
case ENTITY_GLOWWORM:
|
||||||
render(x-4, y-4, 224, 112, 0);
|
render(x-4, y-4, 224, 112, 0);
|
||||||
break;
|
break;
|
||||||
|
case ENTITY_NPC:
|
||||||
|
render16(x - 8, y - 8, (e->npc.type*16) + 0, 64, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,8 +1335,7 @@ void renderItemList(Inventory * inv, int xo, int yo, int x1, int y1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderRecipes(RecipeManager * r, int xo, int yo, int x1, int y1,
|
void renderRecipes(RecipeManager * r, int xo, int yo, int x1, int y1, int selected) {
|
||||||
int selected) {
|
|
||||||
int size = r->size;
|
int size = r->size;
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
return;
|
return;
|
||||||
|
@ -1265,16 +1355,16 @@ void renderRecipes(RecipeManager * r, int xo, int yo, int x1, int y1,
|
||||||
int i, col;
|
int i, col;
|
||||||
for (i = 0; i < i1; ++i) {
|
for (i = 0; i < i1; ++i) {
|
||||||
int x = (1 + xo) << 4, y = (i + 1 + yo) << 4;
|
int x = (1 + xo) << 4, y = (i + 1 + yo) << 4;
|
||||||
renderItemIcon(r->recipes[i + io].itemResult,
|
renderItemIcon(r->recipes[i + io].itemResult, r->recipes[i + io].itemAmountLevel, x >> 1, y >> 1);
|
||||||
r->recipes[i + io].itemAmountLevel, x >> 1, y >> 1);
|
|
||||||
if (r->recipes[i + io].canCraft)
|
if (r->recipes[i + io].canCraft)
|
||||||
col = 0xFFFFFFFF;
|
col = 0xFFFFFFFF;
|
||||||
else
|
else
|
||||||
col = 0xFF7F7F7F;
|
col = 0xFF7F7F7F;
|
||||||
drawTextColor(
|
if(r->recipes[i + io].itemAmountLevel==1) {
|
||||||
getBasicItemName(r->recipes[i + io].itemResult,
|
drawTextColor(getBasicItemName(r->recipes[i + io].itemResult, r->recipes[i + io].itemAmountLevel), x + 18, y + 2, col);
|
||||||
r->recipes[i + io].itemAmountLevel), x + 18, y + 2,
|
} else {
|
||||||
col);
|
drawTextColor(getItemName(r->recipes[i + io].itemResult, r->recipes[i + io].itemAmountLevel), x + 18, y + 2, col);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int yy = selected + 1 - io + yo;
|
int yy = selected + 1 - io + yo;
|
||||||
|
@ -1317,6 +1407,8 @@ void renderItemWithTextCentered(Item* item, int width, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderItemIcon(int itemID, int countLevel, int x, int y) {
|
void renderItemIcon(int itemID, int countLevel, int x, int y) {
|
||||||
|
int xd;
|
||||||
|
int yd;
|
||||||
switch (itemID) {
|
switch (itemID) {
|
||||||
case ITEM_NULL:
|
case ITEM_NULL:
|
||||||
return;
|
return;
|
||||||
|
@ -1491,11 +1583,31 @@ void renderItemIcon(int itemID, int countLevel, int x, int y) {
|
||||||
case ITEM_DRAGON_SCALE:
|
case ITEM_DRAGON_SCALE:
|
||||||
render(x, y, 168, 160, 0);
|
render(x, y, 168, 160, 0);
|
||||||
break;
|
break;
|
||||||
|
case ITEM_BOOKSHELVES:
|
||||||
|
render(x, y, 232, 144, 0);
|
||||||
|
break;
|
||||||
|
case ITEM_MAGIC_DUST:
|
||||||
|
render(x, y, 200, 152, 0);
|
||||||
|
break;
|
||||||
|
case ITEM_COIN:
|
||||||
|
render(x, y, 208, 152, 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:
|
case TOOL_BOW:
|
||||||
render(x, y, 64, 168, 0);
|
render(x, y, 64, 168, 0);
|
||||||
break;
|
break;
|
||||||
|
case TOOL_MAGIC_COMPASS:
|
||||||
|
xd = compassData[currentLevel][0] - (player.x>>4);
|
||||||
|
yd = compassData[currentLevel][1] - (player.y>>4);
|
||||||
|
if(abs(yd)>abs(xd)) {
|
||||||
|
if(yd<0) render(x, y, 112, 168, 0);
|
||||||
|
else render(x, y, 120, 168, 0);
|
||||||
|
} else {
|
||||||
|
if(xd<0) render(x, y, 128, 168, 0);
|
||||||
|
else render(x, y, 136, 168, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ void renderConnectedTile4(int x, int y, u32 xTile, u32 yTile);
|
||||||
void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile);
|
void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile);
|
||||||
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 renderWeather(int xScroll, int yScroll);
|
||||||
void renderDayNight();
|
void renderDayNight();
|
||||||
void renderButtonIcon(u32 icon, int x, int y, float scale);
|
void renderButtonIcon(u32 icon, int x, int y, float scale);
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,5 @@
|
||||||
#include "SaveLoad.h"
|
#include "SaveLoad.h"
|
||||||
|
|
||||||
s16 calculateImportantEntites(EntityManager * eManager, int level){
|
|
||||||
int i;
|
|
||||||
s16 count = 0;
|
|
||||||
for(i = 0; i < eManager->lastSlot[level]; ++i){
|
|
||||||
switch(eManager->entities[level][i].type){
|
|
||||||
case ENTITY_AIRWIZARD:
|
|
||||||
case ENTITY_SLIME:
|
|
||||||
case ENTITY_ZOMBIE:
|
|
||||||
case ENTITY_SKELETON:
|
|
||||||
case ENTITY_KNIGHT:
|
|
||||||
case ENTITY_ITEM:
|
|
||||||
case ENTITY_FURNITURE:
|
|
||||||
case ENTITY_PASSIVE:
|
|
||||||
case ENTITY_GLOWWORM:
|
|
||||||
case ENTITY_DRAGON:
|
|
||||||
count++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool entityIsImportant(Entity * e){
|
bool entityIsImportant(Entity * e){
|
||||||
switch(e->type){
|
switch(e->type){
|
||||||
case ENTITY_AIRWIZARD:
|
case ENTITY_AIRWIZARD:
|
||||||
|
@ -34,12 +12,24 @@ bool entityIsImportant(Entity * e){
|
||||||
case ENTITY_PASSIVE:
|
case ENTITY_PASSIVE:
|
||||||
case ENTITY_GLOWWORM:
|
case ENTITY_GLOWWORM:
|
||||||
case ENTITY_DRAGON:
|
case ENTITY_DRAGON:
|
||||||
|
case ENTITY_NPC:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s16 calculateImportantEntites(EntityManager * eManager, int level){
|
||||||
|
int i;
|
||||||
|
s16 count = 0;
|
||||||
|
for(i = 0; i < eManager->lastSlot[level]; ++i){
|
||||||
|
if(entityIsImportant(&eManager->entities[level][i])){
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData){
|
void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player, u8 * map, u8 * mapData){
|
||||||
FILE * file = fopen(filename, "wb");
|
FILE * file = fopen(filename, "wb");
|
||||||
int i,j;
|
int i,j;
|
||||||
|
@ -107,6 +97,9 @@ void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player
|
||||||
case ENTITY_DRAGON:
|
case ENTITY_DRAGON:
|
||||||
fwrite(&eManager->entities[i][j].dragon.health, sizeof(s16), 1, file);
|
fwrite(&eManager->entities[i][j].dragon.health, sizeof(s16), 1, file);
|
||||||
break;
|
break;
|
||||||
|
case ENTITY_NPC:
|
||||||
|
fwrite(&eManager->entities[i][j].npc.type, sizeof(u8), 1, file);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,6 +113,25 @@ void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player
|
||||||
|
|
||||||
fwrite(minimapData, sizeof(u8), 128*128, file); // Minimap, visibility data 16KB
|
fwrite(minimapData, sizeof(u8), 128*128, file); // Minimap, visibility data 16KB
|
||||||
|
|
||||||
|
//Quest Data
|
||||||
|
fwrite(&questManager.size, sizeof(int), 1, file);
|
||||||
|
for(i = 0; i < questManager.size; ++i) {
|
||||||
|
fwrite(&(questManager.questlines[i].currentQuest), sizeof(int), 1, file);
|
||||||
|
fwrite(&(questManager.questlines[i].currentQuestDone), sizeof(bool), 1, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Compass Data
|
||||||
|
for(i=0; i<6; ++i) {
|
||||||
|
fwrite(&(compassData[i][0]), sizeof(u8), 1, file); //x of choosen stair
|
||||||
|
fwrite(&(compassData[i][1]), sizeof(u8), 1, file); //y of choosen stair
|
||||||
|
fwrite(&(compassData[i][2]), sizeof(u8), 1, file); //count
|
||||||
|
}
|
||||||
|
|
||||||
|
//Day/season Data
|
||||||
|
fwrite(&day, sizeof(int), 1, file);
|
||||||
|
fwrite(&season, sizeof(u8), 1, file);
|
||||||
|
fwrite(&rain, sizeof(bool), 1, file);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,6 +347,16 @@ int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * m
|
||||||
eManager->entities[i][j].yr = 8;
|
eManager->entities[i][j].yr = 8;
|
||||||
eManager->entities[i][j].canPass = true;
|
eManager->entities[i][j].canPass = true;
|
||||||
break;
|
break;
|
||||||
|
case ENTITY_NPC:
|
||||||
|
fread(&eManager->entities[i][j].npc.type, 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].xr = 4;
|
||||||
|
eManager->entities[i][j].yr = 3;
|
||||||
|
eManager->entities[i][j].canPass = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,6 +369,40 @@ int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * m
|
||||||
fread(&daytime, sizeof(u16), 1, file);
|
fread(&daytime, sizeof(u16), 1, file);
|
||||||
|
|
||||||
fread(minimapData, sizeof(u8), 128*128, file);
|
fread(minimapData, sizeof(u8), 128*128, file);
|
||||||
|
|
||||||
|
//Quest Data
|
||||||
|
int qsize = 0;
|
||||||
|
fread(&qsize, sizeof(int), 1, file);
|
||||||
|
for(i = 0; i < qsize; ++i) {
|
||||||
|
fread(&(questManager.questlines[i].currentQuest), sizeof(int), 1, file);
|
||||||
|
fread(&(questManager.questlines[i].currentQuestDone), sizeof(bool), 1, file);
|
||||||
|
}
|
||||||
|
//fill missing questlines with "no progress done"
|
||||||
|
for(i = qsize; i < questManager.size; ++i) {
|
||||||
|
questManager.questlines[i].currentQuest = 0;
|
||||||
|
questManager.questlines[i].currentQuestDone = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Compass Data
|
||||||
|
//reset incase it is missing in the save
|
||||||
|
for(i=0; i<6; ++i) {
|
||||||
|
compassData[i][0] = 0; //x of choosen stair
|
||||||
|
compassData[i][1] = 0; //y of choosen stair
|
||||||
|
compassData[i][2] = 0; //count
|
||||||
|
}
|
||||||
|
for(i=0; i<6; ++i) {
|
||||||
|
fread(&(compassData[i][0]), sizeof(u8), 1, file); //x of choosen stair
|
||||||
|
fread(&(compassData[i][1]), sizeof(u8), 1, file); //y of choosen stair
|
||||||
|
fread(&(compassData[i][2]), sizeof(u8), 1, file); //count
|
||||||
|
}
|
||||||
|
|
||||||
|
//Day/season Data
|
||||||
|
day = 0;
|
||||||
|
season = 0;
|
||||||
|
rain = false;
|
||||||
|
fread(&day, sizeof(int), 1, file);
|
||||||
|
fread(&season, sizeof(u8), 1, file);
|
||||||
|
fread(&rain, sizeof(bool), 1, file);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "texturepack.h"
|
#include "texturepack.h"
|
||||||
|
|
||||||
|
// TODO: Dungeon is way to difficult
|
||||||
|
// -> Skeleton arrows are slower, do a little less damage
|
||||||
|
// -> Or instead of less damage, implement a simple armor system
|
||||||
|
|
||||||
void initMiniMapData() {
|
void initMiniMapData() {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 128 * 128; ++i) {
|
for(i = 0; i < 128 * 128; ++i) {
|
||||||
|
@ -29,11 +33,11 @@ void initMiniMap(bool loadUpWorld) {
|
||||||
|
|
||||||
void initNewMap() {
|
void initNewMap() {
|
||||||
newSeed();
|
newSeed();
|
||||||
createAndValidateSkyMap(128, 128, map[0], data[0]);
|
createAndValidateSkyMap(128, 128, 0, map[0], data[0]);
|
||||||
createAndValidateTopMap(128, 128, map[1], data[1]);
|
createAndValidateTopMap(128, 128, 1, map[1], data[1]);
|
||||||
createAndValidateUndergroundMap(128, 128, 1, map[2], data[2]);
|
createAndValidateUndergroundMap(128, 128, 1, 2, map[2], data[2]);
|
||||||
createAndValidateUndergroundMap(128, 128, 2, map[3], data[3]);
|
createAndValidateUndergroundMap(128, 128, 2, 3, map[3], data[3]);
|
||||||
createAndValidateUndergroundMap(128, 128, 3, map[4], data[4]);
|
createAndValidateUndergroundMap(128, 128, 3, 4, map[4], data[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupGame(bool loadUpWorld) {
|
void setupGame(bool loadUpWorld) {
|
||||||
|
@ -48,6 +52,7 @@ void setupGame(bool loadUpWorld) {
|
||||||
if (!loadUpWorld) {
|
if (!loadUpWorld) {
|
||||||
initNewMap();
|
initNewMap();
|
||||||
initPlayer();
|
initPlayer();
|
||||||
|
resetQuests();
|
||||||
airWizardHealthDisplay = 2000;
|
airWizardHealthDisplay = 2000;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 5; ++i) {
|
for (i = 0; i < 5; ++i) {
|
||||||
|
@ -55,8 +60,12 @@ void setupGame(bool loadUpWorld) {
|
||||||
}
|
}
|
||||||
addEntityToList(newAirWizardEntity(630, 820, 0), &eManager);
|
addEntityToList(newAirWizardEntity(630, 820, 0), &eManager);
|
||||||
daytime = 6000;
|
daytime = 6000;
|
||||||
|
day = 0;
|
||||||
|
season = 0;
|
||||||
|
rain = false;
|
||||||
} else {
|
} else {
|
||||||
initPlayer();
|
initPlayer();
|
||||||
|
resetQuests();
|
||||||
loadWorld(currentFileName, &eManager, &player, (u8*) map, (u8*) data);
|
loadWorld(currentFileName, &eManager, &player, (u8*) map, (u8*) data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +87,7 @@ void setupBGMap(bool loadUpWorld) {
|
||||||
|
|
||||||
if(!loadUpWorld) {
|
if(!loadUpWorld) {
|
||||||
newSeed();
|
newSeed();
|
||||||
createAndValidateTopMap(128, 128, map[1], data[1]);
|
createAndValidateTopMap(128, 128, 1, map[1], data[1]);
|
||||||
} else {
|
} else {
|
||||||
loadWorld(currentFileName, &eManager, &player, (u8*) map, (u8*) data);
|
loadWorld(currentFileName, &eManager, &player, (u8*) map, (u8*) data);
|
||||||
}
|
}
|
||||||
|
@ -113,6 +122,14 @@ void tick() {
|
||||||
//daytime += 20;
|
//daytime += 20;
|
||||||
if(daytime>=24000) {
|
if(daytime>=24000) {
|
||||||
daytime -= 24000;
|
daytime -= 24000;
|
||||||
|
++day;
|
||||||
|
//TODO: maybe make season length not as hardcoded + make the transition better (fade to black and back maybe?)
|
||||||
|
if(day%7==0) {
|
||||||
|
++season;
|
||||||
|
if(season==4) season = 0;
|
||||||
|
}
|
||||||
|
rain = false;
|
||||||
|
if(season!=3 && rand()%5==0) rain = true;
|
||||||
}
|
}
|
||||||
if(daytime==6000 && currentLevel==1) {
|
if(daytime==6000 && currentLevel==1) {
|
||||||
playMusic(music_floor1);
|
playMusic(music_floor1);
|
||||||
|
@ -138,25 +155,20 @@ void tick() {
|
||||||
else if (yscr > 1912)
|
else if (yscr > 1912)
|
||||||
yscr = 1912;
|
yscr = 1912;
|
||||||
|
|
||||||
if(eManager.lastSlot[currentLevel]<80) {
|
if(eManager.lastSlot[currentLevel]<80 && currentLevel != 5) {
|
||||||
trySpawn(1, currentLevel);
|
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_SKELETON && e->type != ENTITY_KNIGHT && e->type != ENTITY_SLIME && e->type != ENTITY_PASSIVE && (e->type == ENTITY_GLOWWORM && (daytime>6000 || daytime<18000)))
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearScreen(int* data, u8 fill, int size) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < size / 4; ++i)
|
|
||||||
data[i] = 0xFF000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
char debugText[34];
|
char debugText[34];
|
||||||
char bossHealthText[34];
|
char bossHealthText[34];
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -243,6 +255,7 @@ int main() {
|
||||||
|
|
||||||
tickCount = 0;
|
tickCount = 0;
|
||||||
initRecipes();
|
initRecipes();
|
||||||
|
initQuests();
|
||||||
while (aptMainLoop()) {
|
while (aptMainLoop()) {
|
||||||
++tickCount;
|
++tickCount;
|
||||||
hidScanInput();
|
hidScanInput();
|
||||||
|
@ -266,6 +279,7 @@ int main() {
|
||||||
renderBackground(xscr, yscr);
|
renderBackground(xscr, yscr);
|
||||||
renderEntities(player.x, player.y, &eManager);
|
renderEntities(player.x, player.y, &eManager);
|
||||||
renderPlayer();
|
renderPlayer();
|
||||||
|
renderWeather(xscr, yscr);
|
||||||
|
|
||||||
resetStencilStuff();
|
resetStencilStuff();
|
||||||
|
|
||||||
|
@ -299,6 +313,7 @@ int main() {
|
||||||
|
|
||||||
stopMusic();
|
stopMusic();
|
||||||
|
|
||||||
|
freeQuests();
|
||||||
freeRecipes();
|
freeRecipes();
|
||||||
|
|
||||||
freeLightBakes();
|
freeLightBakes();
|
||||||
|
|
Loading…
Add table
Reference in a new issue