From 0ef9e8970592538adbb2ba274782a88fd89e1a65 Mon Sep 17 00:00:00 2001 From: Andre Schweiger Date: Fri, 5 Feb 2016 18:13:39 +0100 Subject: [PATCH] Rework Tilesheet No more autocoloring! (atleast for Maptiles) --- data/icons2.png | Bin 17867 -> 26192 bytes source/Entity.c | 54 ++++++++++ source/Entity.h | 35 +++++- source/Globals.c | 266 ++++++++++++++++++++++++++++++++++++++++++++-- source/Globals.h | 7 ++ source/Item.c | 4 + source/Item.h | 3 + source/MapGen.c | 63 +++++++++-- source/Menu.c | 101 ++++++++++++------ source/Menu.h | 2 + source/Render.c | 186 ++++++++++++++++++++++---------- source/Render.h | 20 ++-- source/SaveLoad.c | 26 +++++ source/main.c | 33 +++++- 14 files changed, 679 insertions(+), 121 deletions(-) diff --git a/data/icons2.png b/data/icons2.png index 34f7d4016919370e6cc4bc55848ae9a4a911ba13..37a97d631d3963e78001a348651ed1de04b80909 100644 GIT binary patch literal 26192 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 YTX^4k*8=_Fi_Xd8p5K-py?XDz0H`ZDc>n+a literal 17867 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 + e.dragonFire.age = 0; + e.dragonFire.type = type; + e.dragonFire.parent = parent; + e.dragonFire.xa = xa; + e.dragonFire.ya = ya; + e.dragonFire.xx = x; + e.dragonFire.yy = y; + e.x = (int) x; + e.y = (int) y; + e.xr = 3; + e.yr = 3; + e.canPass = true; + return e; +} + +Entity newMagicPillarEntity(int x, int y, int level){ + Entity e; + e.type = ENTITY_MAGIC_PILLAR; + e.level = level; + e.x = x; + e.y = y; + e.xr = 3; + e.yr = 3; + e.canPass = false; + return e; +} + Entity newTextParticleEntity(char * str, u32 color, int x, int y, int level){ Entity e; e.type = ENTITY_TEXTPARTICLE; diff --git a/source/Entity.h b/source/Entity.h index 4a14d66..57df29d 100644 --- a/source/Entity.h +++ b/source/Entity.h @@ -19,6 +19,10 @@ #define ENTITY_KNIGHT 13 #define ENTITY_GLOWWORM 14 +#define ENTITY_DRAGON 15 +#define ENTITY_DRAGONPROJECTILE 16 +#define ENTITY_MAGIC_PILLAR 17 + typedef struct Entity Entity; typedef struct { @@ -109,6 +113,15 @@ typedef struct { s8 spriteAdjust; } AirWizard; +typedef struct { + Entity* parent; + s16 age; + float xa; + float ya; + float xx; + float yy; +} Spark; + typedef struct { Entity* parent; s16 age; @@ -117,14 +130,28 @@ typedef struct { s8 ya; } Arrow; +typedef struct { + s8 xa; + s8 ya; + s16 health; + s8 randWalkTime; + s8 walkDist; + s8 dir; + int attackDelay; + int attackTime; + int attackType; + int animTimer; +} Dragon; + typedef struct { Entity* parent; + u8 type; s16 age; float xa; float ya; float xx; float yy; -} Spark; +} DragonFire; typedef struct { s8 xa; @@ -171,6 +198,8 @@ struct Entity { Spark spark; Arrow arrow; Glowworm glowworm; + Dragon dragon; + DragonFire dragonFire; TextParticleEntity textParticle; SmashParticleEntity smashParticle; }; @@ -178,7 +207,6 @@ struct Entity { typedef struct { Entity entities[6][1000]; - Entity wizardSparks[120]; s16 lastSlot[6]; Inventory invs[301];//1 for the player, 300 for chests. s16 nextInv; @@ -199,6 +227,9 @@ Entity newKnightEntity(int lvl, int x, int y, int level); Entity newSlimeEntity(int lvl, int x, int y, int level); Entity newAirWizardEntity(int x, int y, int level); Entity newSparkEntity(Entity* parent, float xa, float ya); +Entity newDragonEntity(int x, int y, int level); +Entity newDragonFireEntity(Entity* parent, u8 type, int x, int y, float xa, float ya); +Entity newMagicPillarEntity(int x, int y, int level); Entity newTextParticleEntity(char * str, u32 color, 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); diff --git a/source/Globals.c b/source/Globals.c index f53beb8..e52d4a7 100644 --- a/source/Globals.c +++ b/source/Globals.c @@ -1,6 +1,6 @@ #include "Globals.h" -char versionText[34] = "Version 1.2"; +char versionText[34] = "Version 1.2.1"; char fpsstr[34]; u8 currentMenu = 0; @@ -199,7 +199,7 @@ void tickTouchMap(){ } void tickTouchQuickSelect() { - if (currentMenu == 0) { + if (currentMenu == 0 && !shouldRenderMap) { int i = 0; Inventory * inv = player.p.inv; @@ -299,6 +299,17 @@ void hurtEntity(Entity* e, int damage, int dir, u32 hurtColor){ return; } break; + case ENTITY_DRAGON: + e->dragon.health -= damage; + if(e->dragon.health < 1){ + addItemsToWorld(newItem(ITEM_DRAGON_EGG,1),e->x+8, e->y+8, 1); + addItemsToWorld(newItem(ITEM_DRAGON_SCALE,1),e->x+8, e->y+8, (rand()%11) + 10); + removeEntityFromList(e,e->level,&eManager); + playSound(snd_bossdeath); + player.p.score += 1000; + return; + } + break; } switch(dir){ @@ -368,9 +379,14 @@ bool ItemVsEntity(Item* item, Entity* e, int dir){ case ENTITY_KNIGHT: case ENTITY_SLIME: case ENTITY_AIRWIZARD: + case ENTITY_DRAGON: if(playerUseEnergy(4-item->countLevel)) hurtEntity(e,(item->countLevel + 1) * 2 + (rand()%4),dir,0xFF0000FF); else hurtEntity(e,1+rand()%3,dir,0xFF0000FF); return true; + + case ENTITY_MAGIC_PILLAR: + removeEntityFromList(e, e->level, &eManager); + return true; } break; case TOOL_SWORD: switch(e->type){ @@ -380,9 +396,14 @@ bool ItemVsEntity(Item* item, Entity* e, int dir){ case ENTITY_KNIGHT: case ENTITY_SLIME: case ENTITY_AIRWIZARD: + case ENTITY_DRAGON: if(playerUseEnergy(4-item->countLevel)) hurtEntity(e,(item->countLevel+1)*3+(rand()%(2+item->countLevel*item->countLevel*2)),dir,0xFF0000FF); else hurtEntity(e,1+rand()%3,dir,0xFF0000FF); return true; + + case ENTITY_MAGIC_PILLAR: + removeEntityFromList(e, e->level, &eManager); + return true; } break; case ITEM_NULL: switch(e->type){ @@ -392,8 +413,13 @@ bool ItemVsEntity(Item* item, Entity* e, int dir){ case ENTITY_KNIGHT: case ENTITY_SLIME: case ENTITY_AIRWIZARD: + case ENTITY_DRAGON: hurtEntity(e,1+rand()%3,dir,0xFF0000FF); return true; + + case ENTITY_MAGIC_PILLAR: + removeEntityFromList(e, e->level, &eManager); + return true; } break; } return false; @@ -504,6 +530,12 @@ void EntityVsEntity(Entity* e1, Entity* e2){ break; case ENTITY_SPARK: if(e2 != e1->spark.parent) hurtEntity(e2, 1, -1, 0xFFAF00FF); + break; + case ENTITY_DRAGON: + if(e2->type == ENTITY_PLAYER) hurtEntity(e2, 3, e1->dragon.dir, 0xFFAF00FF); + break; + case ENTITY_DRAGONPROJECTILE: + if(e2 != e1->dragonFire.parent) hurtEntity(e2, 1, -1, 0xFFAF00FF); break; case ENTITY_ARROW: switch(e1->arrow.itemID) { @@ -550,8 +582,10 @@ bool EntityBlocksEntity(Entity* e1, Entity* e2){ case ENTITY_KNIGHT: case ENTITY_SLIME: case ENTITY_AIRWIZARD: + case ENTITY_DRAGON: case ENTITY_PLAYER: case ENTITY_PASSIVE: + case ENTITY_MAGIC_PILLAR: return true; break; } @@ -576,6 +610,7 @@ bool tileIsSolid(int tile, Entity * e){ case TILE_GOLD_WALL: case TILE_GEM_WALL: case TILE_DUNGEON_WALL: + case TILE_MAGIC_BARRIER: return true; case TILE_LAVA: case 255: @@ -616,6 +651,7 @@ u32 getTileColor(int tile){ case TILE_GEM_WALL: return SWAP_UINT32(gemColor); case TILE_DUNGEON_WALL: return SWAP_UINT32(dungeonColor[0]); case TILE_DUNGEON_FLOOR: return SWAP_UINT32(dungeonColor[1]); + case TILE_MAGIC_BARRIER: return SWAP_UINT32(dungeonColor[0]); default: return 0x111111FF; } @@ -966,6 +1002,18 @@ void tickTile(int x, int y){ case TILE_CLOUD: if((rand()%24000)==0) setTile(TILE_CLOUDCACTUS,x,y); break; + case TILE_MAGIC_BARRIER: + data = 0; + int i = 0; + for (i = 0; i < eManager.lastSlot[currentLevel]; ++i) { + Entity * e = &eManager.entities[currentLevel][i]; + + if(e->type == ENTITY_MAGIC_PILLAR) { + ++data; + } + } + if(data==0) setTile(TILE_DUNGEON_FLOOR,x,y); + break; } } @@ -1028,6 +1076,7 @@ void tickEntity(Entity* e){ switch(e->type){ case ENTITY_ITEM: tickEntityItem(e); return; case ENTITY_FURNITURE: return; + case ENTITY_MAGIC_PILLAR: return; case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: @@ -1062,6 +1111,17 @@ void tickEntity(Entity* e){ int aitemID = ITEM_ARROW_WOOD; if(e->hostile.lvl >= 2) aitemID = ITEM_ARROW_STONE; + //turn to player when attacking + int xd = player.x - e->x; + int yd = player.y - e->y; + if(xd*xd > yd*yd) { + if (xd < 0) e->hostile.dir = 2; + if (xd > 0) e->hostile.dir = 3; + } else { + if (yd < 0) e->hostile.dir = 1; + if (yd > 0) e->hostile.dir = 0; + } + switch(e->hostile.dir) { case 0: addEntityToList(newArrowEntity(e, aitemID, 0, 2, e->level), &eManager); @@ -1212,10 +1272,141 @@ void tickEntity(Entity* e){ EntityVsEntity(e, &player); removeEntityFromList(e,e->level,&eManager); } + return; + case ENTITY_DRAGON: + if (e->hurtTime > 0) e->hurtTime--; + + e->dragon.animTimer++; + if(e->dragon.animTimer>=20) { + e->dragon.animTimer = 0; + } + + //choose random attack + if (e->dragon.attackDelay > 0) { + e->dragon.attackDelay--; + if (e->dragon.attackDelay <= 0) { + e->wizard.attackType = rand()%2; + e->wizard.attackTime = 121; + } + return; + } + + if (e->dragon.attackTime > 0) { + e->dragon.attackTime--; + + //turn to player when attacking + int xd = player.x - e->x; + int yd = player.y - e->y; + if(xd*xd > yd*yd) { + if (xd < 0) e->dragon.dir = 2; + if (xd > 0) e->dragon.dir = 3; + } else { + if (yd < 0) e->dragon.dir = 1; + if (yd > 0) e->dragon.dir = 0; + } + + switch(e->dragon.attackType) { + case 0: //Firebreathing + if(e->dragon.attackTime%2 == 0) { + float dfdir = 0; + + if(e->dragon.dir==0) dfdir = 1 * 3.141592 / 2; + else if(e->dragon.dir==1) dfdir = 3 * 3.141592 / 2; + else if(e->dragon.dir==2) dfdir = 2 * 3.141592 / 2; + else if(e->dragon.dir==3) dfdir = 0 * 3.141592 / 2; + + dfdir += 0.03141592 * ((rand()%33) - 16); + + addEntityToList(newDragonFireEntity(e, e->dragon.attackType, e->x + cos(dfdir)*14, e->y + sin(dfdir)*14, cos(dfdir), sin(dfdir)), &eManager); + } + break; + case 1: //Firering + if(e->dragon.attackTime%20 == 0) { + int ai = 0; + for(ai = 0; ai < 16; ai++) { + float ddir = (3.141592 * 2 / 16.0) * ai; + float ddist = (140 - e->dragon.attackTime) / 2; + + addEntityToList(newDragonFireEntity(e, e->dragon.attackType, (e->x) + cos(ddir)*ddist, (e->y) + sin(ddir)*ddist, 0, 0), &eManager); + } + } + break; + } + + return; + } + + //TODO - movement copied from airwizard, adjust to better fit dragon + if (e->dragon.randWalkTime == 0) { + int xd = player.x - e->x; + int yd = player.y - e->y; + int dist = xd * xd + yd * yd; + if (dist > 64 * 64) { + e->dragon.xa = 0; + e->dragon.ya = 0; + if (xd < 0) e->dragon.xa = -1; + if (xd > 0) e->dragon.xa = +1; + if (yd < 0) e->dragon.ya = -1; + if (yd > 0) e->dragon.ya = +1; + } else if (dist < 16 * 16) { + e->dragon.xa = 0; + e->dragon.ya = 0; + if (xd < 0) e->dragon.xa = +1; + if (xd > 0) e->dragon.xa = -1; + if (yd < 0) e->dragon.ya = +1; + if (yd > 0) e->dragon.ya = -1; + } + } + + int dSpeed = (tickCount % 4) == 0 ? 0 : 1; + if (!moveMob(e, e->dragon.xa * dSpeed, e->dragon.ya * dSpeed) || (rand()%120) == 0) { + e->dragon.randWalkTime = 30; + e->dragon.xa = ((rand()%3) - 1) * (rand()%2); + e->dragon.ya = ((rand()%3) - 1) * (rand()%2); + } + + if(e->dragon.xa != 0 || e->dragon.ya != 0){ + e->dragon.walkDist++; + } + + if(e->dragon.xa < 0) e->dragon.dir = 2; + else if(e->dragon.xa > 0) e->dragon.dir = 3; + if(e->dragon.ya < 0) e->dragon.dir = 1; + else if(e->dragon.ya > 0) e->dragon.dir = 0; + + //if (e->dragon.randWalkTime > 0) { + // e->dragon.randWalkTime--; + // if (e->dragon.randWalkTime == 0) { + int xd = player.x - e->x; + int yd = player.y - e->y; + if (rand()%12 == 0 && xd * xd + yd * yd < 50 * 50) { + if (e->dragon.attackDelay == 0 && e->dragon.attackTime == 0) e->dragon.attackDelay = 40; + } + // } + //} + + return; + case ENTITY_DRAGONPROJECTILE: + e->dragonFire.age++; + if (e->dragonFire.age >= 30) { + removeEntityFromList(e,e->level,&eManager); + return; + } + e->dragonFire.xx += e->dragonFire.xa; + e->dragonFire.yy += e->dragonFire.ya; + e->x = (int) e->dragonFire.xx; + e->y = (int) e->dragonFire.yy; + + if(intersects(player, e->x + e->dragonFire.xa - e->xr, e->y + e->dragonFire.ya - e->yr, e->x + e->dragonFire.xa + e->xr, e->y + e->dragonFire.ya + e->yr)){ + EntityVsEntity(e, &player); + removeEntityFromList(e,e->level,&eManager); + } return; case ENTITY_ARROW: e->arrow.age++; if (e->arrow.age >= 260 || !move(e, e->arrow.xa, e->arrow.ya)) { + //only drop arrows shot by player + if(e->arrow.parent->type == ENTITY_PLAYER) addItemsToWorld(newItem(e->arrow.itemID,1),e->x+4, e->y+4, 1); removeEntityFromList(e,e->level,&eManager); return; } @@ -1355,7 +1546,7 @@ void setTile(int id, int x, int y){ if(x < 0 || y < 0 || x > 128 || y > 128) return; map[currentLevel][x+y*128] = id; data[currentLevel][x+y*128] = 0; //reset data(set again if needed, hopefully this breaks nothing) - sf2d_set_pixel(minimap[currentLevel], x, y, getTileColor(id)); + sf2d_set_pixel(minimap[currentLevel], x, y, getMinimapColor(currentLevel,x,y)); } int getData(int x, int y){ if(x < 0 || y < 0 || x > 128 || y > 128) return -1; @@ -1676,6 +1867,9 @@ void switchLevel(s8 change){ else sf2d_set_clear_color(0xFF007F00); //sf2d_set_clear_color(RGBA8(0x00, 0x7F, 0x00, 0xFF)); updateMusic(currentLevel, daytime); + + //for level 0 background + updateLevel1Map(); } bool playerIntersectsEntity(Entity* e){ @@ -1918,6 +2112,20 @@ void tickPlayer(){ if(isSwimming()) ++player.p.swimTimer; if(player.p.attackTimer > 0) --player.p.attackTimer; + + //TODO - maybe move to own function + //Update Minimap + int xp; + int yp; + for(xp = (player.x>>4)-5; xp<(player.x>>4)+5; ++xp) { + for(yp = (player.y>>4)-5; yp<(player.y>>4)+5; ++yp) { + if(xp>=0 && xp<128 && yp>=0 && yp<128) { + if(!getMinimapVisible(currentLevel,xp,yp)) { + setMinimapVisible(currentLevel,xp,yp,true); + } + } + } + } } bool isSwimming(){ @@ -1931,13 +2139,25 @@ void playerSetActiveItem(Item * item) { } void enterDungeon() { - currentLevel = 5; - createDungeonMap(128, 128, map[5], data[5]); - initMinimapLevel(5, false); - newSeed(); //reset Entities (&eManager)->lastSlot[5] = 0; (&eManager)->entities[5][0] = nullEntity; + + //create map + currentLevel = 5; + createDungeonMap(128, 128, map[5], data[5]); + + //reset minimap clear state + int xd,yd; + for(xd = 0; xd < 128; ++xd) { + for(yd = 0; yd < 128; ++yd) { + setMinimapVisible(5, xd, yd, false); + } + } + initMinimapLevel(5, false); + newSeed(); + + //spawn new entities trySpawn(500, 5); player.x = ((128/2) << 4) + 8; @@ -1959,6 +2179,24 @@ void leaveDungeon() { updateMusic(currentLevel, daytime); } +void setMinimapVisible(int level, int x, int y, bool visible) { + if(visible) { + minimapData[x + y * 128] = minimapData[x + y * 128] | (1 << level); + } else { + minimapData[x + y * 128] = minimapData[x + y * 128] & (0xFF - (1 << level)); + } + sf2d_set_pixel(minimap[level], x, y, getMinimapColor(level, x, y)); +} + +bool getMinimapVisible(int level, int x, int y) { + return (minimapData[x + y * 128] & (1 << level)) > 0; +} + +u32 getMinimapColor(int level, int x, int y) { + if(getMinimapVisible(level, x, y) || (currentLevel==0 && level==1)) return getTileColor(map[level][x + y * 128]); + else return getTileColor(map[level][x + y * 128]) & 0xFFFFFF00; +} + void initMinimapLevel(int level, bool loadUpWorld) { int x; int y; @@ -2010,11 +2248,23 @@ void initMinimapLevel(int level, bool loadUpWorld) { } /* Minimaps */ - sf2d_set_pixel(minimap[level], x, y, getTileColor(map[level][x + y * 128])); + sf2d_set_pixel(minimap[level], x, y, getMinimapColor(level, x, y)); } } } +void updateLevel1Map() { + int x; + int y; + + for (x = 0; x < 128; ++x) { + for (y = 0; y < 128; ++y) { + sf2d_set_pixel(minimap[1], x, y, getMinimapColor(1, x, y)); + } + } +} + + void reloadColors() { dirtColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 0)); dirtColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 1)); diff --git a/source/Globals.h b/source/Globals.h index fd23ba2..b5a9be6 100644 --- a/source/Globals.h +++ b/source/Globals.h @@ -59,6 +59,7 @@ #define TILE_DUNGEON_WALL 27 #define TILE_DUNGEON_FLOOR 28 #define TILE_DUNGEON_ENTRANCE 29 +#define TILE_MAGIC_BARRIER 30 #define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24)) @@ -84,6 +85,7 @@ sf2d_texture *bottombg; sf2d_texture * minimap[6]; u8 map[6][128*128]; u8 data[6][128*128]; +u8 minimapData[128*128]; u32 dirtColor[5]; u32 grassColor; @@ -101,6 +103,7 @@ char currentFileName[256]; extern u8 currentMenu; extern char fpsstr[]; u8 initGame; +u8 initBGMap; Item noItem; int airWizardHealthDisplay; s16 awX, awY; @@ -150,6 +153,10 @@ void playerSetActiveItem(Item * item); void enterDungeon(); void leaveDungeon(); +void setMinimapVisible(int level, int x, int y, bool visible); +bool getMinimapVisible(int level, int x, int y); +u32 getMinimapColor(int level, int x, int y); void initMinimapLevel(int level, bool loadUpWorld); +void updateLevel1Map(); void reloadColors(); \ No newline at end of file diff --git a/source/Item.c b/source/Item.c index 89e0591..fdfbb1b 100644 --- a/source/Item.c +++ b/source/Item.c @@ -181,6 +181,8 @@ char* getItemName(int itemID, int countLevel){ case ITEM_BONE: sprintf(currentName,"%d Bone", countLevel); return currentName; case ITEM_DUNGEON_KEY: sprintf(currentName,"%d Dungeon Key", countLevel); return currentName; case ITEM_WIZARD_SUMMON: sprintf(currentName,"%d Wizard Summon", countLevel); return currentName; + case ITEM_DRAGON_EGG: sprintf(currentName,"%d Dragon Egg", countLevel); return currentName; + case ITEM_DRAGON_SCALE: sprintf(currentName,"%d Dragon Scale", countLevel); return currentName; case TOOL_BUCKET: switch(countLevel){ case 1: return "Water Bucket"; @@ -285,6 +287,8 @@ char* getBasicItemName(int itemID, int countLevel){ case ITEM_BONE: return "Bone"; case ITEM_DUNGEON_KEY: return "Dungeon Key"; case ITEM_WIZARD_SUMMON: return "Wizard Summon"; + case ITEM_DRAGON_EGG: return "%d Dragon Egg"; + case ITEM_DRAGON_SCALE: return "%d Dragon Scale"; case TOOL_BUCKET: switch(countLevel){ case 1: return "Water Bucket"; diff --git a/source/Item.h b/source/Item.h index 74314e9..490dbc7 100644 --- a/source/Item.h +++ b/source/Item.h @@ -66,6 +66,9 @@ #define ITEM_BONE 68 #define ITEM_DUNGEON_KEY 69 #define ITEM_WIZARD_SUMMON 70 +//TODO - implement icon +#define ITEM_DRAGON_EGG 71 +#define ITEM_DRAGON_SCALE 72 #define TOOL_BUCKET 101 #define TOOL_BOW 102 diff --git a/source/MapGen.c b/source/MapGen.c index 12ffacb..559a834 100644 --- a/source/MapGen.c +++ b/source/MapGen.c @@ -357,12 +357,12 @@ void createUndergroundMap(int w, int h,int depthLevel, u8 * map, u8 * data) { } -void createDungeonRoom(int w, int h, u8 * map, u8 * data) { +void createDungeonRoom(int w, int h, bool dragon, u8 * map, u8 * data) { int tries; for(tries=0; tries<100; ++tries) { - int x = 5+(rand()%(w-10)); - int y = 5+(rand()%(h-10)); + int x = 5+(rand()%(w-10 -10)); + int y = 5+(rand()%(h-10 -10)); int xr; int yr; int wr = 10+(rand()%11); @@ -371,13 +371,21 @@ void createDungeonRoom(int w, int h, u8 * map, u8 * data) { 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; xr < x+wr; ++xr) { - for(yr = y; yr < y+hr; ++yr) { + 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 @@ -400,15 +408,13 @@ void createDungeonRoom(int w, int h, u8 * map, u8 * data) { } //Create path back to existing stuff - xp = x; - yp = y; + 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) { - //TODO check for dungeon entrance: if(map[i]==TILE_DUNGEON_ENTRANCE) break; - //make connection map[i] = 255; } @@ -434,6 +440,23 @@ void createDungeonRoom(int w, int h, u8 * map, u8 * data) { 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; @@ -446,6 +469,23 @@ void createDungeonRoom(int w, int h, u8 * map, u8 * data) { } 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); } } @@ -471,8 +511,11 @@ void createDungeonMap(int w, int h, u8 * map, u8 * data) { } } + //create dragon chamber(only call once and before other rooms) + createDungeonRoom(w, h, true, map, data); + for(i = 0; i < 40; ++i) { - createDungeonRoom(w, h, map, data); + createDungeonRoom(w, h, false, map, data); } //replace paths with actual dungeon floor diff --git a/source/Menu.c b/source/Menu.c index 9f4a0e2..874f1c0 100644 --- a/source/Menu.c +++ b/source/Menu.c @@ -271,6 +271,28 @@ s8 checkPropButtons(){ return -1; } +bool menuHasMapLoaded = false; +float mxscr = 400; +float myscr = 400; +float menuxa = 0; +float menuya = 0; +void initMenus() { + readFiles(); + + if(worldFileCount>0) { + memset(¤tFileName, 0, 255); // reset currentFileName + sprintf(currentFileName,"%s.wld",fileNames[currentSelection]); + + initBGMap = 1; + } else { + initBGMap = 2; + } + + menuHasMapLoaded = true; + menuxa = (rand()%3 - 1) * 0.25; + menuya = (rand()%3 - 1) * 0.25; +} + Item median; void tickMenu(int menu){ switch(menu){ @@ -663,6 +685,27 @@ void tickMenu(int menu){ } break; case MENU_TITLE: + //Map BG + if(menuHasMapLoaded) { + mxscr += menuxa; + myscr += menuya; + + if (mxscr < 16) { + mxscr = 16; + menuxa = -menuxa; + } else if (mxscr > 1832) { + mxscr = 1832; + menuxa = -menuxa; + } + if (myscr < 16) { + myscr = 16; + menuya = -menuya; + } else if (myscr > 1792) { + myscr = 1792; + menuya = -menuya; + } + } + if (k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection=4;} if (k_down.clicked){ ++currentSelection; if(currentSelection > 4)currentSelection=0;} @@ -1140,7 +1183,7 @@ void renderMenu(int menu,int xscr,int yscr){ sf2d_end_frame(); break; - case MENU_CONTAINER: + case MENU_CONTAINER: 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); @@ -1148,18 +1191,18 @@ void renderMenu(int menu,int xscr,int yscr){ } offsetX = xscr;offsetY = yscr; renderMenuBackground(xscr,yscr); - if (curChestEntity->entityFurniture.r == 1){ offsetX = 48;offsetY = 0;} + if (curChestEntity->entityFurniture.r == 1){ offsetX = 48; offsetY = 0;} else {offsetX = 0;offsetY = 0;} - renderFrame(1,1,14,14,0xFFFF1010); + renderFrame(1,1,15,14,0xFFFF1010); drawTextColor("Chest",24+1,14+1,0xFF000000); drawTextColor("Chest",24,14,0xFF6FE2E2); - renderItemList(curChestEntity->entityFurniture.inv,1,1,14,14, + renderItemList(curChestEntity->entityFurniture.inv,1,1,15,14, curChestEntity->entityFurniture.r == 0 ? curInvSel : -curChestEntity->entityFurniture.oSel - 1); - renderFrame(15,1,28,14,0xFFFF1010); - drawTextColor("Inventory",248+1,14+1,0xFF000000); - drawTextColor("Inventory",248,14,0xFF6FE2E2); - renderItemList(player.p.inv,15,1,28,14, + renderFrame(16,1,30,14,0xFFFF1010); + drawTextColor("Inventory",264+1,14+1,0xFF000000); + drawTextColor("Inventory",264,14,0xFF6FE2E2); + renderItemList(player.p.inv,16,1,30,14, curChestEntity->entityFurniture.r == 1 ? curInvSel : -curChestEntity->entityFurniture.oSel - 1); offsetX = 0;offsetY = 0; sf2d_end_frame(); @@ -1296,6 +1339,14 @@ void renderMenu(int menu,int xscr,int yscr){ /* Top Screen */ sf2d_start_frame(GFX_TOP, GFX_LEFT); sf2d_draw_rectangle(0, 0, 400, 240, 0xFF0C0C0C); //You might think "real" black would be better, but it actually looks better that way + //map BG + if(menuHasMapLoaded) { + offsetX = (int) mxscr; offsetY = (int) myscr; + renderBackground((int) mxscr, (int) myscr); + offsetX = 0; offsetY = 0; + + sf2d_draw_rectangle(0, 0, 400, 240, 0xAA0C0C0C); //You might think "real" black would be better, but it actually looks better that way + } renderTitle(76,16); @@ -1303,6 +1354,7 @@ void renderMenu(int menu,int xscr,int yscr){ char* msg = options[i]; u32 color = 0xFF7F7F7F; if(i == currentSelection) color = 0xFFFFFFFF; + drawSizedTextColor(msg,((200 - (strlen(msg) * 8))/2) + 1, (((8 + i) * 20 - 50) >> 1) + 1,2.0, 0xFF000000); drawSizedTextColor(msg,(200 - (strlen(msg) * 8))/2, ((8 + i) * 20 - 50) >> 1,2.0, color); } @@ -1312,34 +1364,18 @@ void renderMenu(int menu,int xscr,int yscr){ /* Bottom Screen */ sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); sf2d_draw_rectangle(0, 0, 320, 240, 0xFF0C0C0C); //You might think "real" black would be better, but it actually looks better that way + //map BG + if(menuHasMapLoaded) { + offsetX = (int) mxscr + 20; offsetY = (int) myscr + 120; + renderBackground((int) mxscr + 20, (int) myscr + 120); + offsetX = 0; offsetY = 0; + + sf2d_draw_rectangle(0, 0, 320, 240, 0xAA0C0C0C); //You might think "real" black would be better, but it actually looks better that way + } int startX = 0, startY = 0;// relative coordinates ftw switch(currentSelection){ case 0: // "Start Game" - startX = 20;startY = 50; - render16(startX,startY+12,0,128,0);//Player(Carrying) - render16(startX,startY,128,128,0);//Workbench - startX = 120;startY = 20; - menuRenderTilePit(startX,startY,176,16,waterColor[0]);// water pit - renderc (startX+8,startY+12,48,160,16,8,0);//Waves - renderc (startX+8,startY+8,0,112,16,8,0);//Player (Top-Half) - startX = 110;startY = 76; - render16 (startX,startY,48,112,0);//Player - renderc (startX+12,startY,40,160,8,16,0);//Slash - render (startX+14,startY+4,152,144,0);//Pickaxe - render16b(startX+18,startY,80,0,0,0xFFAEC6DC);//Iron ore - startX = 40;startY = 90; - render16b (startX,startY,128,112,0,0xFFADFFAD);//Slime - render16 (startX+18,startY,48,112,1);//Player (Mirrored) - renderc (startX+14,startY,32,160,8,16,0);//Slash - render (startX+12,startY+4,104,144,1);//Sword - startX = 64;startY = 40; - menuRenderTilePit(startX,startY,112,16,grassColor);// grass pit - render16 (startX+8,startY+4,0,16,0);//Tree - render (startX+1,startY+14,80,152,0);// Apple - render16 (startX+9,startY+18,16,112,0);//Player - renderc (startX+9,startY+14,16,160,16,8,0);//Slash - drawTextColor("Play minicraft",24,24,0xFF7FFFFF); break; case 1: // "How To Play" startX = 72;startY = 54; @@ -1356,7 +1392,6 @@ void renderMenu(int menu,int xscr,int yscr){ startX = 89;startY = 54; render16(startX+16,startY,48,112,0);//Player render16(startX,startY,160,208,0);//C-PAD right - drawTextColor("Learn the basics",64,24,0xFF7FFFFF); break; case 2: // "Settings" diff --git a/source/Menu.h b/source/Menu.h index 8899882..348fd59 100644 --- a/source/Menu.h +++ b/source/Menu.h @@ -3,6 +3,8 @@ #include "MenuTutorial.h" #include "texturepack.h" +void initMenus(); + void renderMenu(int menu,int xscr,int yscr); void tickMenu(int menu); diff --git a/source/Render.c b/source/Render.c index e51d0e3..dabb407 100644 --- a/source/Render.c +++ b/source/Render.c @@ -142,6 +142,22 @@ void render16s(s32 xp, s32 yp, u32 tile, u8 bits, u32 color) { 16, 16, scaleX, scaleY, color); } +void render32(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits) { + xp -= offsetX; + yp -= offsetY; + int scaleX = 2, scaleY = 2; + if ((bits & 1) > 0) { + scaleX = -2; + xp += 32; + } + if ((bits & 2) > 0) { + scaleY = -2; + yp += 32; + } + sf2d_draw_texture_part_scale(icons, xp << 1, yp << 1, xTile, yTile, 32, 32, + scaleX, scaleY); +} + void renderTitle(int x, int y) { sf2d_draw_texture_part_scale(icons, (x - 26) << 1, y << 1, 0, 240, 104, 16, 2.0, 2.0); // MINICRAFT @@ -392,11 +408,17 @@ bool tur = false; bool tdl = false; bool tdr = false; -void renderDotsWithColor(int x, int y, u8 bits1, u8 bits2, u8 bits3, u8 bits4, u32 color) { - if(tu && tl) renderb(x, y, 0, 0, bits1, color); - if(tu && tr) renderb(x + 8, y, 8, 0, bits2, color); - if(td && tl) renderb(x, y + 8, 0, 8, bits3, color); - if(td && tr) renderb(x + 8, y + 8, 8, 8, bits4, color); +void renderDots(int x, int y, u8 bits1, u8 bits2, u8 bits3, u8 bits4, u32 xTile, u32 yTile) { + //another speedhack for o3DS + if(tu && tl && tr && td) { + render16(x, y, xTile, yTile, bits1); + return; + } + + if(tu && tl) render(x, y, xTile, yTile, bits1); + if(tu && tr) render(x + 8, y, xTile+8, yTile, bits2); + if(td && tl) render(x, y + 8, xTile, yTile+8, bits3); + if(td && tr) render(x + 8, y + 8, xTile+8, yTile+8, bits4); } void resetSurrTiles() { @@ -450,167 +472,194 @@ void renderTile(int i, int d, int x, int y) { checkSurrTiles4(x >> 4, y >> 4, TILE_FLOWER); checkSurrTiles4(x >> 4, y >> 4, TILE_SAPLING_TREE); - renderConnectedTile4(x, y, 112, 16, grassColor); + renderConnectedTile4(x, y, 256, 0); break; case TILE_TREE: renderTile(TILE_GRASS, 0, x, y); checkSurrTiles8(x >> 4, y >> 4, TILE_TREE); - render(x, y, 0+((tu && tl && tul) ? 16 : 0), 16, 0); - render(x+8, y, 8+((tu && tr && tur) ? 16 : 0), 16, 0); - render(x, y+8, 0+((td && tl && tdl) ? 16 : 0), 24, 0); - render(x+8, y+8, 8+((td && tr && tdr) ? 16 : 0), 24, 0); + 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; case TILE_ROCK: checkSurrTiles8(x >> 4, y >> 4, TILE_ROCK); - renderConnectedTile8(x, y, 32, 16, rockColor[0]); + renderConnectedTile8(x, y, 336, 64); break; case TILE_HARDROCK: checkSurrTiles8(x >> 4, y >> 4, TILE_HARDROCK); - renderConnectedTile8(x, y, 32, 16, rockColor[2]); + renderConnectedTile8(x, y, 416, 64); break; case TILE_DIRT: // render dots. if (currentLevel > 1) - render16b(x, y, 0, 0, 0, 0xFF383838); + render16(x, y, 320, 80, 0); else - render16b(x, y, 0, 0, 0, 0xFF8F8FA8); + render16(x, y, 336, 80, 0); break; case TILE_SAND: checkSurrTiles4(x >> 4, y >> 4, TILE_SAND); checkSurrTiles4(x >> 4, y >> 4, TILE_CACTUS); checkSurrTiles4(x >> 4, y >> 4, TILE_SAPLING_CACTUS); - renderConnectedTile4(x, y, 112, 16, sandColor); + renderConnectedTile4(x, y, 320, 0); if (d > 0) { - render16b(x, y, 128, 0, 0, sandColor); + render16(x, y, 336, 48, 0); } break; case TILE_WATER: checkSurrTiles4(x >> 4, y >> 4, TILE_WATER); checkSurrTiles4(x >> 4, y >> 4, TILE_HOLE); - renderConnectedTile4(x, y, 176, 16, waterColor[0]); + renderConnectedTile4(x, y, 384, 0); srand((tickCount + (x / 2 - y) * 4311) / 10); - renderDotsWithColor(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, waterColor[1]); + renderDots(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, 288, 64); break; case TILE_LAVA: checkSurrTiles4(x >> 4, y >> 4, TILE_LAVA); checkSurrTiles4(x >> 4, y >> 4, TILE_HOLE); - renderConnectedTile4(x, y, 176, 16, lavaColor[0]); + renderConnectedTile4(x, y, 448, 0); srand((tickCount + (x / 2 - y) * 4311) / 10); - renderDotsWithColor(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, lavaColor[1]); + renderDots(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, 304, 64); break; case TILE_HOLE: checkSurrTiles4(x >> 4, y >> 4, TILE_HOLE); checkSurrTiles4(x >> 4, y >> 4, TILE_WATER); checkSurrTiles4(x >> 4, y >> 4, TILE_LAVA); - renderConnectedTile4(x, y, 176, 16, 0xFF383838); + renderConnectedTile4(x, y, 256, 16); break; case TILE_CACTUS: renderTile(TILE_SAND, 0, x, y); - render16(x, y, 48, 0, 0); + render16(x, y, 304, 48, 0); break; case TILE_FLOWER: renderTile(TILE_GRASS, 0, x, y); - render16(x, y, 64, 0, getData(x >> 4, y >> 4)); + render16(x, y, 320, 48, getData(x >> 4, y >> 4)); break; case TILE_STAIRS_DOWN: if (currentLevel == 0) renderTile(TILE_CLOUD, 0, x, y); - render16(x, y, 96, 0, 0); + render16(x, y, 256, 64, 0); break; case TILE_STAIRS_UP: - render16(x, y, 112, 0, 0); + render16(x, y, 272, 64, 0); break; case TILE_IRONORE: - render16b(x, y, 80, 0, 0, ironColor); + render16(x, y, 464, 48, 0); break; case TILE_GOLDORE: - render16b(x, y, 80, 0, 0, goldColor); + render16(x, y, 480, 48, 0); break; case TILE_GEMORE: - render16b(x, y, 80, 0, 0, gemColor); + render16(x, y, 496, 48, 0); break; case TILE_CLOUD: checkSurrTiles4(x >> 4, y >> 4, TILE_CLOUD); checkSurrTiles4(x >> 4, y >> 4, TILE_STAIRS_DOWN); checkSurrTiles4(x >> 4, y >> 4, TILE_CLOUDCACTUS); - renderConnectedTile4(x, y, 64, 32, 0xFFFFFFFF); + renderConnectedTile4(x, y, 320, 16); break; case TILE_CLOUDCACTUS: renderTile(TILE_CLOUD, 0, x, y); - render16(x, y, 80, 0, 0); + render16(x, y, 496, 64, 0); break; case TILE_SAPLING_TREE: renderTile(TILE_GRASS, 0, x, y); - render16(x, y, 32, 0, 0); + render16(x, y, 288, 48, 0); break; case TILE_SAPLING_CACTUS: renderTile(TILE_SAND, 0, x, y); - render16(x, y, 32, 0, 0); + render16(x, y, 288, 48, 0); break; case TILE_FARM: - render16(x, y, 144, 0, 0); + render16(x, y, 352, 48, 0); break; case TILE_WHEAT: age = getData(x >> 4, y >> 4) / 20; if (age > 5) age = 5; - render16(x, y, 160 + (age << 4), 0, 0); + render16(x, y, 368 + (age << 4), 48, 0); break; case TILE_WOOD_WALL: checkSurrTiles4(x >> 4, y >> 4, TILE_WOOD_WALL); - renderConnectedTile4(x, y, 0, 32, woodColor); + renderConnectedTile4(x, y, 384, 16); break; case TILE_STONE_WALL: checkSurrTiles4(x >> 4, y >> 4, TILE_STONE_WALL); - renderConnectedTile4(x, y, 128, 32, rockColor[0]); + renderConnectedTile4(x, y, 256, 80); break; case TILE_IRON_WALL: checkSurrTiles4(x >> 4, y >> 4, TILE_IRON_WALL); - renderConnectedTile4(x, y, 128, 32, ironColor); + renderConnectedTile4(x, y, 448, 16); break; case TILE_GOLD_WALL: checkSurrTiles4(x >> 4, y >> 4, TILE_GOLD_WALL); - renderConnectedTile4(x, y, 128, 32, goldColor); + renderConnectedTile4(x, y, 256, 32); break; case TILE_GEM_WALL: checkSurrTiles4(x >> 4, y >> 4, TILE_GEM_WALL); - renderConnectedTile4(x, y, 128, 32, gemColor); + renderConnectedTile4(x, y, 320, 32); break; case TILE_DUNGEON_WALL: checkSurrTiles8(x >> 4, y >> 4, TILE_DUNGEON_WALL); - renderConnectedTile8(x, y, 128, 32, dungeonColor[0]); + renderConnectedTile8(x, y, 384, 32); break; case TILE_DUNGEON_FLOOR: - render16b(x, y, 208, 32, 0, dungeonColor[1]); + render16(x, y, 464, 32, 0); break; case TILE_DUNGEON_ENTRANCE: - render16b(x, y, 224 + (currentLevel==5 ? 16 : 0), 32, 0, dungeonColor[0]); + render16(x, y, 480 + (currentLevel==5 ? 16 : 0), 32, 0); + break; + case TILE_MAGIC_BARRIER: + renderTile(TILE_DUNGEON_FLOOR, 0, x, y); + render16(x, y, 320, 64, 0); + + //draw remaining pillar count + if((player.x - (x+8))*(player.x - (x+8)) + (player.y - (y+8))*(player.y - (y+8)) <= 24*24) { + x -= offsetX; + y -= offsetY; + + int data = 0; + int i = 0; + for (i = 0; i < eManager.lastSlot[currentLevel]; ++i) { + Entity * e = &eManager.entities[currentLevel][i]; + + if(e->type == ENTITY_MAGIC_PILLAR) { + ++data; + } + } + + char currentCount[3]; + sprintf(currentCount,"%d", data); + + drawSizedTextColor(currentCount, x+4 + 1, y+4 + 1, 2, dungeonColor[1]); + drawSizedTextColor(currentCount, x+4, y+4, 2, dungeonColor[0]); + } + break; } resetSurrTiles(); } -void renderConnectedTile4(int x, int y, u32 xTile, u32 yTile, u32 color) { +void renderConnectedTile4(int x, int y, u32 xTile, u32 yTile) { //render complete tile in one piece to reduce strain(added for o3DS) if (tl && tr && tu && td) { - render16b(x, y, xTile+48, yTile, 0, color); + render16(x, y, xTile+48, yTile, 0); return; } @@ -619,16 +668,16 @@ void renderConnectedTile4(int x, int y, u32 xTile, u32 yTile, u32 color) { int u = (tu ? 32 : 0); int d = (td ? 32 : 0); - renderb(x, y, xTile +l+u, yTile, 0, color); - renderb(x+8, y, xTile+8+r+u, yTile, 0, color); - renderb(x, y+8, xTile +l+d, yTile+8, 0, color); - renderb(x+8, y+8, xTile+8+r+d, yTile+8, 0, color); + render(x, y, xTile +l+u, yTile, 0); + render(x+8, y, xTile+8+r+u, yTile, 0); + render(x, y+8, xTile +l+d, yTile+8, 0); + render(x+8, y+8, xTile+8+r+d, yTile+8, 0); } -void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile, u32 color) { +void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile) { //render complete tile in one piece to reduce strain(added for o3DS) if (tl && tr && tu && td && tul && tur && tdl && tdr) { - render16b(x, y, xTile+64, yTile, 0, color); + render16(x, y, xTile+64, yTile, 0); return; } @@ -637,13 +686,15 @@ void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile, u32 color) { int u = (tu ? 32 : 0); int d = (td ? 32 : 0); - renderb(x, y, xTile +l+u+((tl && tu && tul) ? 16 : 0), yTile, 0, color); - renderb(x+8, y, xTile+8+r+u+((tr && tu && tur) ? 16 : 0), yTile, 0, color); - renderb(x, y+8, xTile +l+d+((tl && td && tdl) ? 16 : 0), yTile+8, 0, color); - renderb(x+8, y+8, xTile+8+r+d+((tr && td && tdr) ? 16 : 0), yTile+8, 0, color); + render(x, y, xTile +l+u+((tl && tu && tul) ? 16 : 0), yTile, 0); + render(x+8, y, xTile+8+r+u+((tr && tu && tur) ? 16 : 0), yTile, 0); + render(x, y+8, xTile +l+d+((tl && td && tdl) ? 16 : 0), yTile+8, 0); + render(x+8, y+8, xTile+8+r+d+((tr && td && tdr) ? 16 : 0), yTile+8, 0); } void renderZoomedMap() { + sf2d_draw_rectangle(0, 0, 320, 240, 0xFF0C0C0C); //You might think "real" black would be better, but it actually looks better that way + int mx = mScrollX; int my = mScrollY; if(zoomLevel == 2) mx = 32; @@ -1081,6 +1132,33 @@ void renderEntity(Entity* e, int x, int y) { return; renderr(x, y, 200, 152, 0, e->spark.age * 0.0349); break; + case ENTITY_DRAGON: + //TODO - render dragon(maybe with flying animation) + switch (e->dragon.dir) { + case 0: // down + render32(x - 16, y - 16, 0+(e->dragon.animTimer<10 ? 0 : 64), 256, 2); + break; + case 1: // up + render32(x - 16, y - 16, 0+(e->dragon.animTimer<10 ? 0 : 64), 256, 0); + break; + case 2: // left + render32(x - 16, y - 16, 0+(e->dragon.animTimer<10 ? 0 : 64), 288, 1); + break; + case 3: // right + render32(x - 16, y - 16, 0+(e->dragon.animTimer<10 ? 0 : 64), 288, 0); + break; + } + break; + case ENTITY_DRAGONPROJECTILE: + if(e->dragonFire.type==0) { + renderr(x, y, 0, 320, 0, e->dragonFire.age * 0.349); + } else { + render(x, y, 8, 320 + (e->dragonFire.age/10)*8, 0); + } + break; + case ENTITY_MAGIC_PILLAR: + render16(x - 8, y - 8, 16, 320, 0); + break; case ENTITY_ARROW: if (e->arrow.age >= 200) if (e->arrow.age / 6 % 2 == 0) diff --git a/source/Render.h b/source/Render.h index 85641cd..89f2ef7 100644 --- a/source/Render.h +++ b/source/Render.h @@ -16,21 +16,19 @@ int offsetX, offsetY; void render(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits); void renderb(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits, u32 color); void renderr(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits, float rotate); -void renderc(s32 xp, s32 yp, u32 xTile, u32 yTile, int sizeX, int sizeY, - u8 bits); -void renderbc(s32 xp, s32 yp, u32 xTile, u32 yTile, int sizeX, int sizeY, - u8 bits, u32 color); +void renderc(s32 xp, s32 yp, u32 xTile, u32 yTile, int sizeX, int sizeY, u8 bits); +void renderbc(s32 xp, s32 yp, u32 xTile, u32 yTile, int sizeX, int sizeY, u8 bits, u32 color); void render16(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits); -void render16c(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits, float scaleX, - float scaleY); +void render16c(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits, float scaleX, float scaleY); void render16b(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits, u32 color); void render16s(s32 xp, s32 yp, u32 tile, u8 bits, u32 color); +void render32(s32 xp, s32 yp, u32 xTile, u32 yTile, u8 bits); void renderTitle(int x, int y); void renderFrame(int x1, int y1, int x2, int y2, u32 bgColor); void renderTile(int i, int d, int x, int y); -void renderConnectedTile4(int x, int y, u32 xTile, u32 yTile, u32 color); -void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile, u32 color); +void renderConnectedTile4(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 renderMenuBackground(int xScroll, int yScroll); //Renders the darkness void renderDayNight(); @@ -57,10 +55,8 @@ void renderFurniture(int itemID, int x, int y); void renderEntity(Entity* e, int x, int y); void renderEntities(int x, int y, EntityManager* em); -void renderRecipes(RecipeManager * r, int xo, int yo, int x1, int y1, - int selected); -void renderItemList(Inventory * inv, int xo, int yo, int x1, int y1, - int selected); +void renderRecipes(RecipeManager * r, int xo, int yo, int x1, int y1, int selected); +void renderItemList(Inventory * inv, int xo, int yo, int x1, int y1, int selected); void renderItemWithText(Item* item, int x, int y); void renderItemStuffWithText(int itemID, int itemCL, bool onlyOne, int x, int y); void renderItemWithTextCentered(Item* item, int width, int y); diff --git a/source/SaveLoad.c b/source/SaveLoad.c index 3cca5ca..da49522 100644 --- a/source/SaveLoad.c +++ b/source/SaveLoad.c @@ -14,6 +14,7 @@ s16 calculateImportantEntites(EntityManager * eManager, int level){ case ENTITY_FURNITURE: case ENTITY_PASSIVE: case ENTITY_GLOWWORM: + case ENTITY_DRAGON: count++; break; } @@ -32,6 +33,7 @@ bool entityIsImportant(Entity * e){ case ENTITY_FURNITURE: case ENTITY_PASSIVE: case ENTITY_GLOWWORM: + case ENTITY_DRAGON: return true; default: return false; @@ -101,6 +103,9 @@ void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player case ENTITY_PASSIVE: fwrite(&eManager->entities[i][j].passive.health, sizeof(s16), 1, file); fwrite(&eManager->entities[i][j].passive.mtype, sizeof(u8), 1, file); + break; + case ENTITY_DRAGON: + fwrite(&eManager->entities[i][j].dragon.health, sizeof(s16), 1, file); break; } } @@ -112,6 +117,8 @@ void saveCurrentWorld(char * filename, EntityManager * eManager, Entity * player fwrite(mapData, sizeof(u8), 128*128*5, file); // Map Tile Data (Damage done to trees/rocks, age of wheat & saplings, etc). 80KB fwrite(&daytime, sizeof(u16), 1, file); + + fwrite(minimapData, sizeof(u8), 128*128, file); // Minimap, visibility data 16KB fclose(file); } @@ -311,6 +318,23 @@ int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * m eManager->entities[i][j].glowworm.randWalkTime = 0; eManager->entities[i][j].glowworm.waitTime = 0; break; + case ENTITY_DRAGON: + fread(&eManager->entities[i][j].dragon.health, sizeof(s16), 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].dragon.dir = 0; + eManager->entities[i][j].dragon.attackDelay = 0; + eManager->entities[i][j].dragon.attackTime = 0; + eManager->entities[i][j].dragon.attackType = 0; + eManager->entities[i][j].dragon.animTimer = 0; + eManager->entities[i][j].dragon.xa = 0; + eManager->entities[i][j].dragon.ya = 0; + eManager->entities[i][j].xr = 8; + eManager->entities[i][j].yr = 8; + eManager->entities[i][j].canPass = true; + break; } } } @@ -322,6 +346,8 @@ int loadWorld(char * filename, EntityManager * eManager, Entity * player, u8 * m daytime = 6001; fread(&daytime, sizeof(u16), 1, file); + fread(minimapData, sizeof(u8), 128*128, file); + fclose(file); return 0; } diff --git a/source/main.c b/source/main.c index 7bc8b52..eb1432e 100644 --- a/source/main.c +++ b/source/main.c @@ -13,6 +13,13 @@ #include "Menu.h" #include "texturepack.h" +void initMiniMapData() { + int i; + for(i = 0; i < 128 * 128; ++i) { + minimapData[i] = 0; + } +} + void initMiniMap(bool loadUpWorld) { int i; for (i = 0; i < 5; ++i) { @@ -36,6 +43,8 @@ void setupGame(bool loadUpWorld) { memset(&eManager, 0, sizeof(eManager)); sf2d_set_clear_color(0xFF6C6D82); //sf2d_set_clear_color(RGBA8(0x82, 0x6D, 0x6C, 0xFF)); + initMiniMapData(); + if (!loadUpWorld) { initNewMap(); initPlayer(); @@ -62,6 +71,25 @@ void setupGame(bool loadUpWorld) { initGame = 0; } +void setupBGMap(bool loadUpWorld) { + // Reset entity manager. + memset(&eManager, 0, sizeof(eManager)); + sf2d_set_clear_color(0xFF6C6D82); //sf2d_set_clear_color(RGBA8(0x82, 0x6D, 0x6C, 0xFF)); + + if(!loadUpWorld) { + newSeed(); + createAndValidateTopMap(128, 128, map[1], data[1]); + } else { + loadWorld(currentFileName, &eManager, &player, (u8*) map, (u8*) data); + } + + // Reset entity manager. + memset(&eManager, 0, sizeof(eManager)); + sf2d_set_clear_color(0xFF6C6D82); //sf2d_set_clear_color(RGBA8(0x82, 0x6D, 0x6C, 0xFF)); + + initBGMap = 0; +} + int xscr = 0, yscr = 0; void tick() { if (player.p.isDead) { @@ -147,6 +175,7 @@ int main() { csndInit(); noItem = newItem(ITEM_NULL, 0); + initMenus(); currentMenu = MENU_TITLE; currentSelection = 0; quitGame = false; @@ -163,8 +192,7 @@ int main() { int i; for (i = 0; i < 6; ++i) { - minimap[i] = sf2d_create_texture(128, 128, TEXFMT_RGBA8, - SF2D_PLACE_RAM); + minimap[i] = sf2d_create_texture(128, 128, TEXFMT_RGBA8, SF2D_PLACE_RAM); sf2d_texture_tile32(minimap[i]); } @@ -223,6 +251,7 @@ int main() { if (quitGame) break; if (initGame > 0) setupGame(initGame == 1 ? true : false); + if (initBGMap > 0) setupBGMap(initBGMap == 1 ? true : false); if (currentMenu == 0) { tick();