diff --git a/3dslink.exe b/3dslink.exe deleted file mode 100644 index db6fa0c..0000000 Binary files a/3dslink.exe and /dev/null differ diff --git a/3dstool.exe b/3dstool.exe deleted file mode 100644 index 3bd996b..0000000 Binary files a/3dstool.exe and /dev/null differ diff --git a/bannertool.exe b/bannertool.exe deleted file mode 100644 index da68252..0000000 Binary files a/bannertool.exe and /dev/null differ diff --git a/build.bat b/build.bat index 02cc9e8..c0d9181 100755 --- a/build.bat +++ b/build.bat @@ -2,9 +2,9 @@ echo Building 3DSX/ELF/SMDH... make echo Creating banner... -bannertool.exe makebanner -i icons-banners/banner.png -a icons-banners/audio.wav -o icons-banners/banner.bnr +bannertool makebanner -i icons-banners/banner.png -a icons-banners/audio.wav -o icons-banners/banner.bnr echo Creating icon... -bannertool.exe makesmdh -s "Minicraft3DS" -l "3DS Homebrew port of Notch's ludum dare game 'Minicraft', updated." -p "Davideesk/Andre111/ElijahZAwesome" -i icons-banners/icon.png -o icons-banners/icon.icn +bannertool makesmdh -s "Minicraft3DS" -l "3DS Homebrew port of Notch's ludum dare game 'Minicraft', updated." -p "Davideesk/Andre111/ElijahZAwesome" -i icons-banners/icon.png -o icons-banners/icon.icn echo Creating ROMFS... 3dstool -cvtf romfs icons-banners/romfs.bin --romfs-dir romfs/ echo Creating CIA... @@ -14,4 +14,4 @@ makerom -f cci -o result/Minicraft3DS.3ds -DAPP_ENCRYPTED=true -rsf icons-banner echo Cleaning Up... del /s result\Minicraft3DS.elf del /s result\Minicraft3DS.smdh -pause \ No newline at end of file +pause diff --git a/ctrtool.exe b/ctrtool.exe deleted file mode 100644 index a6a35f8..0000000 Binary files a/ctrtool.exe and /dev/null differ diff --git a/data/icons.png b/data/icons.png new file mode 100755 index 0000000..184fbd2 Binary files /dev/null and b/data/icons.png differ diff --git a/data/icons2.png b/data/icons2.png deleted file mode 100755 index 377c8f5..0000000 Binary files a/data/icons2.png and /dev/null differ diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 957a02d..0000000 --- a/docs/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Minicraft3DS -3DS Homebrew port of Notch's ludum dare game "Minicraft" -Current Version: Version 1.6.1 - ----------- - -**Download:** - -If you just want to download the game prebuilt check the releases tab in Github: -https://github.com/ElijahZAwesome/Minicraft3DS/releases -For building the game yourself look below. - - ----------- - - -**Dependencies:** - -For building and installing the dependencies look below. - -ctrulib by smea: https://github.com/smealum/ctrulib -citro3d by fincs: https://github.com/fincs/citro3d -sf2dlib by xerpi: https://github.com/xerpi/sf2dlib -sfillib by xerpi: https://github.com/xerpi/sfillib -zlib: http://www.zlib.net/ - - ----------- - - -**Building:** - -**1. Install devkitARM by devkitPro** -- On Windows download https://sourceforge.net/projects/devkitpro/files/Automated%20Installer/ -- And install atleast Minimal System and devkitARM -- This includes make, ctrulib and citro3d - -**2. Install zlib, libjpeg-turbo and libpng** -- Download 3DS-Portlibs: https://github.com/devkitPro/3ds_portlibs -- Run these commands: - -``` - make zlib - make install-zlib - make libjpeg-turbo - make libpng - make install -``` - -**3. Install sf2dlib** -- Download https://github.com/xerpi/sf2dlib -- In the libsf2d directory run these commands: -``` - make - make install -``` -**4. Install sfillib** -- Download https://github.com/xerpi/sfillib -- In the libsfil directory run these commands: -``` - make - make install -``` - -**5. You can now build Minicraft3DS 3dsx, elf, cia, and 3ds files by running the build.bat file.** - - ----------- - - -You can do anything with the source code (besides sell it) as long as you give proper credit to the right people. -If you are going to make a mod of this version, be sure to give credit to Markus "Notch" Perrson because he did create the original game after all. - -# Misc - -This source code is subject to a lot of change for better optimization/cleanliness. - -Forum thread: https://gbatemp.net/threads/release-new-minicraft3ds-fork-v1-4.494947/ diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 55625f5..0000000 --- a/docs/_config.yml +++ /dev/null @@ -1,4 +0,0 @@ -theme: jekyll-theme-cayman -title: Minicraft3DS -description: A 2D Homebrew for 3DS -show_downloads: true diff --git a/ignore_3dstool.txt b/ignore_3dstool.txt deleted file mode 100644 index e69de29..0000000 diff --git a/makerom.exe b/makerom.exe deleted file mode 100644 index 3c7ee62..0000000 Binary files a/makerom.exe and /dev/null differ diff --git a/run in Citra.bat b/run in Citra.bat deleted file mode 100644 index bf237b2..0000000 --- a/run in Citra.bat +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -echo Building 3DSX/ELF/SMDH... -make -echo Running in citra -%localappdata%/Citra/canary-mingw/citra-qt.exe result/Minicraft3DS.3dsx \ No newline at end of file diff --git a/source/Crafting.c b/source/Crafting.c index 25ea746..cc9867e 100755 --- a/source/Crafting.c +++ b/source/Crafting.c @@ -1,132 +1,132 @@ #include "Crafting.h" void cloneRecipeManager(RecipeManager *from, RecipeManager *to) { - //free old manager recipes - free(to->recipes); - - //copy over recipes - to->size = from->size; - to->recipes = (Recipe*)malloc(sizeof(Recipe) * to->size); - memcpy(to->recipes, from->recipes, sizeof(Recipe) * to->size); + //free old manager recipes + free(to->recipes); + + //copy over recipes + to->size = from->size; + to->recipes = (Recipe*)malloc(sizeof(Recipe) * to->size); + memcpy(to->recipes, from->recipes, sizeof(Recipe) * to->size); } void checkCanCraftRecipes(RecipeManager * rm, Inventory * inv){ - int i, j; - for(i = 0; i < rm->size; i++){ - rm->recipes[i].canCraft = true; - for(j = 0; j < rm->recipes[i].numOfCosts; j++){ - if(countItemInv(rm->recipes[i].costs[j].costItem,0,inv) < rm->recipes[i].costs[j].costAmount){ - rm->recipes[i].canCraft = false; - } - } - } + int i, j; + for(i = 0; i < rm->size; i++){ + rm->recipes[i].canCraft = true; + for(j = 0; j < rm->recipes[i].numOfCosts; j++){ + if(countItemInv(rm->recipes[i].costs[j].costItem,0,inv) < rm->recipes[i].costs[j].costAmount){ + rm->recipes[i].canCraft = false; + } + } + } } int compareCanCraft(const void * ra, const void * rb) { - Recipe* r1 = (Recipe*)ra; - Recipe* r2 = (Recipe*)rb; + Recipe* r1 = (Recipe*)ra; + Recipe* r2 = (Recipe*)rb; if (r1->canCraft && !r2->canCraft) return -1; - if (!r1->canCraft && r2->canCraft) return 1; + if (!r1->canCraft && r2->canCraft) return 1; return r1->order - r2->order; // Needed for stable sorting. } void sortRecipes(RecipeManager * rm){ - qsort(rm->recipes,rm->size,sizeof(Recipe),compareCanCraft); + qsort(rm->recipes,rm->size,sizeof(Recipe),compareCanCraft); } void deductCost(Cost c, Inventory * inv){ - Item* item = getItemFromInventory(c.costItem, inv); - if(!item->onlyOne){ - item->countLevel -= c.costAmount; - if(item->countLevel < 1) removeItemFromInventory(item->slotNum, inv); - } else { - removeItemFromInventory(item->slotNum, inv); - } + Item* item = getItemFromInventory(c.costItem, inv); + if(!item->onlyOne){ + item->countLevel -= c.costAmount; + if(item->countLevel < 1) removeItemFromInventory(item->slotNum, inv); + } else { + removeItemFromInventory(item->slotNum, inv); + } } bool craftItem(RecipeManager * rm, Recipe* r, Inventory* inv){ - if(r->canCraft){ - int i; - for(i=0;inumOfCosts;++i) deductCost(r->costs[i], inv); - Item item = newItem(r->itemResult,r->itemAmountLevel); - - if(!item.onlyOne && countItemInv(item.id,item.countLevel,inv) > 0){ - getItemFromInventory(item.id, inv)->countLevel += r->itemAmountLevel; - } else{ - pushItemToInventoryFront(item, inv); - } - checkCanCraftRecipes(rm, inv); - sortRecipes(rm); - return true; - } - return false; + if(r->canCraft){ + int i; + for(i=0;inumOfCosts;++i) deductCost(r->costs[i], inv); + Item item = newItem(r->itemResult,r->itemAmountLevel); + + if(!item.onlyOne && countItemInv(item.id,item.countLevel,inv) > 0){ + getItemFromInventory(item.id, inv)->countLevel += r->itemAmountLevel; + } else{ + pushItemToInventoryFront(item, inv); + } + checkCanCraftRecipes(rm, inv); + sortRecipes(rm); + return true; + } + return false; } Cost newCost(int i, int c){ - Cost nc; - nc.costItem = i; - nc.costAmount = c; - return nc; + Cost nc; + nc.costItem = i; + nc.costAmount = c; + return nc; } u8 curPlace = 0; Recipe defineRecipe(int item, int amountOrLevel, int numArgs, ...){ - Recipe r; - r.itemResult = item; - r.itemAmountLevel = amountOrLevel; - r.numOfCosts = numArgs; - int i; - va_list al; - numArgs <<= 1; // Did this to get rid of a warning. - va_start(al,numArgs); - for(i=0;i 300) return; - e->entityFurniture.inv = &eManager.invs[eManager.nextInv]; - eManager.nextInv++; + if(eManager.nextInv > 300) return; + e->entityFurniture.inv = &eManager.invs[eManager.nextInv]; + eManager.nextInv++; } Entity newFurnitureEntity(int itemID,Inventory * invPtr, int x, int y, int level){ - Entity e; - e.type = ENTITY_FURNITURE; - e.level = level; - e.x = x; - e.y = y; - e.xr = 3; - e.yr = 3; - e.entityFurniture.itemID = itemID; - e.canPass = false; - if(itemID == ITEM_LANTERN) e.entityFurniture.r = 8; - else if(itemID == ITEM_CHEST){ - if(invPtr == NULL)assignInventory(&e); - else e.entityFurniture.inv = invPtr; - } - return e; + Entity e; + e.type = ENTITY_FURNITURE; + e.level = level; + e.x = x; + e.y = y; + e.xr = 3; + e.yr = 3; + e.entityFurniture.itemID = itemID; + e.canPass = false; + if(itemID == ITEM_LANTERN) e.entityFurniture.r = 8; + else if(itemID == ITEM_CHEST){ + if(invPtr == NULL)assignInventory(&e); + else e.entityFurniture.inv = invPtr; + } + return e; } Entity newPassiveEntity(int type, int x, int y, int level){ Entity e; - e.type = ENTITY_PASSIVE; - e.level = level; - e.x = x; - e.y = y; - e.hurtTime = 0; - e.xKnockback = 0; - e.yKnockback = 0; - e.passive.mtype = type; - e.passive.health = 20; - e.passive.dir = 0; + e.type = ENTITY_PASSIVE; + e.level = level; + e.x = x; + e.y = y; + e.hurtTime = 0; + e.xKnockback = 0; + e.yKnockback = 0; + e.passive.mtype = type; + e.passive.health = 20; + e.passive.dir = 0; e.passive.xa = 0; e.passive.ya = 0; - e.xr = 4; - e.yr = 3; - e.canPass = false; - return e; + e.xr = 4; + e.yr = 3; + e.canPass = false; + return e; } Entity newZombieEntity(int lvl, int x, int y, int level){ - Entity e; - e.type = ENTITY_ZOMBIE; - e.level = level; - e.x = x; - e.y = y; - e.hurtTime = 0; - e.xKnockback = 0; - e.yKnockback = 0; - e.hostile.lvl = lvl; + Entity e; + e.type = ENTITY_ZOMBIE; + e.level = level; + e.x = x; + e.y = y; + e.hurtTime = 0; + e.xKnockback = 0; + e.yKnockback = 0; + e.hostile.lvl = lvl; e.hostile.xa = 0; e.hostile.ya = 0; - e.hostile.health = lvl * lvl * 10; - e.hostile.dir = 0; - e.xr = 4; - e.yr = 3; - e.canPass = false; - switch(lvl){ - case 2: e.hostile.color = 0xFF8282CC; break; - case 3: e.hostile.color = 0xFFEFEFEF; break; - case 4: e.hostile.color = 0xFFAA6262; break; - default: e.hostile.color = 0xFF95DB95; break; - } - return e; + e.hostile.health = lvl * lvl * 10; + e.hostile.dir = 0; + e.xr = 4; + e.yr = 3; + e.canPass = false; + switch(lvl){ + case 2: e.hostile.color = 0xFF8282CC; break; + case 3: e.hostile.color = 0xFFEFEFEF; break; + case 4: e.hostile.color = 0xFFAA6262; break; + default: e.hostile.color = 0xFF95DB95; break; + } + return e; } Entity newSkeletonEntity(int lvl, int x, int y, int level){ - Entity e; - e.type = ENTITY_SKELETON; - e.level = level; - e.x = x; - e.y = y; - e.hurtTime = 0; - e.xKnockback = 0; - e.yKnockback = 0; - e.hostile.lvl = lvl; + Entity e; + e.type = ENTITY_SKELETON; + e.level = level; + e.x = x; + e.y = y; + e.hurtTime = 0; + e.xKnockback = 0; + e.yKnockback = 0; + e.hostile.lvl = lvl; e.hostile.xa = 0; e.hostile.ya = 0; - e.hostile.health = lvl * lvl * 10; - e.hostile.dir = 0; + e.hostile.health = lvl * lvl * 10; + e.hostile.dir = 0; e.hostile.randAttackTime = 0; - e.xr = 4; - e.yr = 3; - e.canPass = false; - switch(lvl){ - case 2: e.hostile.color = 0xFFC4C4C4; break; - case 3: e.hostile.color = 0xFFA0A0A0; break; - case 4: e.hostile.color = 0xFF7A7A7A; break; - default: e.hostile.color = 0xFFFFFFFF; break; - } - return e; + e.xr = 4; + e.yr = 3; + e.canPass = false; + switch(lvl){ + case 2: e.hostile.color = 0xFFC4C4C4; break; + case 3: e.hostile.color = 0xFFA0A0A0; break; + case 4: e.hostile.color = 0xFF7A7A7A; break; + default: e.hostile.color = 0xFFFFFFFF; break; + } + return e; } Entity newKnightEntity(int lvl, int x, int y, int level){ - Entity e; - e.type = ENTITY_KNIGHT; - e.level = level; - e.x = x; - e.y = y; - e.hurtTime = 0; - e.xKnockback = 0; - e.yKnockback = 0; - e.hostile.lvl = lvl; + Entity e; + e.type = ENTITY_KNIGHT; + e.level = level; + e.x = x; + e.y = y; + e.hurtTime = 0; + e.xKnockback = 0; + e.yKnockback = 0; + e.hostile.lvl = lvl; e.hostile.xa = 0; e.hostile.ya = 0; - e.hostile.health = lvl * lvl * 20; - e.hostile.dir = 0; - e.xr = 4; - e.yr = 3; - e.canPass = false; - switch(lvl){ - case 2: e.hostile.color = 0xFF0000C6; break; - case 3: e.hostile.color = 0xFF00A3C6; break; - case 4: e.hostile.color = 0xFF707070; break; - default: e.hostile.color = 0xFFFFFFFF; break; - } - return e; + e.hostile.health = lvl * lvl * 20; + e.hostile.dir = 0; + e.xr = 4; + e.yr = 3; + e.canPass = false; + switch(lvl){ + case 2: e.hostile.color = 0xFF0000C6; break; + case 3: e.hostile.color = 0xFF00A3C6; break; + case 4: e.hostile.color = 0xFF707070; break; + default: e.hostile.color = 0xFFFFFFFF; break; + } + return e; } Entity newSlimeEntity(int lvl, int x, int y, int level){ - Entity e; - e.type = ENTITY_SLIME; - e.level = level; - e.x = x; - e.y = y; - e.hurtTime = 0; - e.xKnockback = 0; - e.yKnockback = 0; - e.slime.lvl = lvl; - e.slime.xa = 0; - e.slime.ya = 0; - e.slime.dir = 0; - e.slime.health = lvl * lvl * 5; - e.xr = 4; - e.yr = 3; - e.canPass = false; - switch(lvl){ - case 2: e.slime.color = 0xFF8282CC; break; - case 3: e.slime.color = 0xFFEFEFEF; break; - case 4: e.slime.color = 0xFFAA6262; break; - default: e.slime.color = 0xFF95DB95; break; - } - return e; + Entity e; + e.type = ENTITY_SLIME; + e.level = level; + e.x = x; + e.y = y; + e.hurtTime = 0; + e.xKnockback = 0; + e.yKnockback = 0; + e.slime.lvl = lvl; + e.slime.xa = 0; + e.slime.ya = 0; + e.slime.dir = 0; + e.slime.health = lvl * lvl * 5; + e.xr = 4; + e.yr = 3; + e.canPass = false; + switch(lvl){ + case 2: e.slime.color = 0xFF8282CC; break; + case 3: e.slime.color = 0xFFEFEFEF; break; + case 4: e.slime.color = 0xFFAA6262; break; + default: e.slime.color = 0xFF95DB95; break; + } + return e; } Entity newAirWizardEntity(int x, int y, int level){ - Entity e; - e.type = ENTITY_AIRWIZARD; - e.level = level; - e.x = x; - e.y = y; - e.hurtTime = 0; - e.xKnockback = 0; - e.yKnockback = 0; - e.wizard.dir = 0; - e.wizard.health = 2000; + Entity e; + e.type = ENTITY_AIRWIZARD; + e.level = level; + e.x = x; + e.y = y; + e.hurtTime = 0; + e.xKnockback = 0; + e.yKnockback = 0; + e.wizard.dir = 0; + e.wizard.health = 2000; e.wizard.attackDelay = 0; e.wizard.attackTime = 0; e.wizard.attackType = 0; - e.wizard.xa = 0; - e.wizard.ya = 0; - e.xr = 4; - e.yr = 3; - e.canPass = true; - return e; + e.wizard.xa = 0; + e.wizard.ya = 0; + e.xr = 4; + e.yr = 3; + e.canPass = true; + return e; } Entity newSparkEntity(Entity* parent, float xa, float ya){ - Entity e; - e.type = ENTITY_SPARK; + Entity e; + e.type = ENTITY_SPARK; e.level = parent->level; - e.spark.age = 0; - e.spark.parent = parent; - e.spark.xa = xa; - e.spark.ya = ya; - e.spark.xx = parent->x; - e.spark.yy = parent->y; - e.xr = 3; - e.yr = 3; - e.canPass = true; - return e; + e.spark.age = 0; + e.spark.parent = parent; + e.spark.xa = xa; + e.spark.ya = ya; + e.spark.xx = parent->x; + e.spark.yy = parent->y; + e.xr = 3; + e.yr = 3; + e.canPass = true; + return e; } Entity newDragonEntity(int x, int y, int level) { Entity e; e.type = ENTITY_DRAGON; - e.level = level; - e.x = x; - e.y = y; - e.hurtTime = 0; - e.xKnockback = 0; - e.yKnockback = 0; - e.dragon.dir = 0; - e.dragon.health = 2000; + e.level = level; + e.x = x; + e.y = y; + e.hurtTime = 0; + e.xKnockback = 0; + e.yKnockback = 0; + e.dragon.dir = 0; + e.dragon.health = 2000; e.dragon.attackDelay = 0; e.dragon.attackTime = 0; e.dragon.attackType = 0; e.dragon.animTimer = 0; - e.dragon.xa = 0; - e.dragon.ya = 0; - e.xr = 8; - e.yr = 8; - e.canPass = false; + e.dragon.xa = 0; + e.dragon.ya = 0; + e.xr = 8; + e.yr = 8; + e.canPass = false; return e; } Entity newDragonFireEntity(Entity* parent, u8 type, int x, int y, float xa, float ya) { Entity e; - e.type = ENTITY_DRAGONPROJECTILE; + e.type = ENTITY_DRAGONPROJECTILE; e.level = parent->level; - e.dragonFire.age = 0; + 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.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; + 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.type = ENTITY_MAGIC_PILLAR; e.level = level; e.x = x; e.y = y; - e.xr = 3; - e.yr = 3; - e.canPass = false; - return e; + 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; - e.level = level; - e.textParticle.color = color; - e.textParticle.age = 0; - e.textParticle.text = (char*)calloc(strlen(str),sizeof(char)); - strncpy(e.textParticle.text,str,strlen(str)); - e.x = x; - e.y = y; - e.canPass = true; + Entity e; + e.type = ENTITY_TEXTPARTICLE; + e.level = level; + e.textParticle.color = color; + e.textParticle.age = 0; + e.textParticle.text = (char*)calloc(strlen(str),sizeof(char)); + strncpy(e.textParticle.text,str,strlen(str)); + e.x = x; + e.y = y; + e.canPass = true; e.textParticle.xx = x; e.textParticle.yy = y; e.textParticle.zz = 2; e.textParticle.xa = gaussrand(false) * 0.3; e.textParticle.ya = gaussrand(false) * 0.2; e.textParticle.za = ((float)rand() / RAND_MAX) * 0.7 + 2; - - return e; + + return e; } Entity newSmashParticleEntity(int x, int y, int level){ - Entity e; - e.type = ENTITY_SMASHPARTICLE; - e.level = level; - e.smashParticle.age = 0; - e.x = x; - e.y = y; - e.canPass = true; + Entity e; + e.type = ENTITY_SMASHPARTICLE; + e.level = level; + e.smashParticle.age = 0; + e.x = x; + e.y = y; + e.canPass = true; playSoundPositioned(snd_monsterHurt, e.level, e.x, e.y); //TODO: This is a wierd location for the effect - return e; + return e; } Entity newArrowEntity(Entity* parent, int itemID, s8 xa, s8 ya, int level){ Entity e; - e.type = ENTITY_ARROW; + e.type = ENTITY_ARROW; e.level = level; - e.arrow.age = 0; - e.arrow.parent = parent; + e.arrow.age = 0; + e.arrow.parent = parent; e.arrow.itemID = itemID; - e.arrow.xa = xa; - e.arrow.ya = ya; - e.x = parent->x; - e.y = parent->y; - e.xr = 2; - e.yr = 2; - e.canPass = false; + e.arrow.xa = xa; + e.arrow.ya = ya; + e.x = parent->x; + e.y = parent->y; + e.xr = 2; + e.yr = 2; + e.canPass = false; e.canSwim = true; - return e; + return e; } Entity newGlowwormEntity(int x, int y, int level){ - Entity e; - e.type = ENTITY_GLOWWORM; - e.level = level; + Entity e; + e.type = ENTITY_GLOWWORM; + e.level = level; e.glowworm.xa = 0; e.glowworm.ya = 0; e.glowworm.randWalkTime = 0; e.glowworm.waitTime = 0; e.x = x; - e.y = y; - e.canPass = true; - return e; + e.y = y; + e.canPass = true; + 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; + 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){ - e.slotNum = em->lastSlot[e.level]; - em->entities[e.level][em->lastSlot[e.level]] = e; - ++em->lastSlot[e.level]; + e.slotNum = em->lastSlot[e.level]; + em->entities[e.level][em->lastSlot[e.level]] = e; + ++em->lastSlot[e.level]; } void removeEntityFromList(Entity * e,int level,EntityManager* em){ - int i; - if(em->entities[level][e->slotNum].type == ENTITY_TEXTPARTICLE) free(em->entities[level][e->slotNum].textParticle.text); - for(i = e->slotNum; i < em->lastSlot[level];++i){ - em->entities[level][i] = em->entities[level][i + 1]; // Move the items down. - em->entities[level][i].slotNum = i; - } - em->lastSlot[level]--; - em->entities[level][em->lastSlot[level]] = nullEntity; // Make the last slot null. + int i; + if(em->entities[level][e->slotNum].type == ENTITY_TEXTPARTICLE) free(em->entities[level][e->slotNum].textParticle.text); + for(i = e->slotNum; i < em->lastSlot[level];++i){ + em->entities[level][i] = em->entities[level][i + 1]; // Move the items down. + em->entities[level][i].slotNum = i; + } + em->lastSlot[level]--; + em->entities[level][em->lastSlot[level]] = nullEntity; // Make the last slot null. } diff --git a/source/Entity.h b/source/Entity.h index 2f4c647..c21f5e1 100755 --- a/source/Entity.h +++ b/source/Entity.h @@ -30,89 +30,89 @@ typedef struct Entity Entity; typedef struct _plrd PlayerData; //in order to not include Player.h and cause all sorts of problems typedef struct { - s8 ax; - s8 ay; - u8 dir; - s8 health; - s8 stamina; - s8 staminaRecharge; - s8 staminaRechargeDelay; - s8 attackTimer; - u8 spawnTrigger; - bool isDead; - bool hasWon; - bool hasWonSaved; - s8 endTimer; - s16 walkDist; - bool isCarrying; - bool isSwimming; - int swimTimer; + s8 ax; + s8 ay; + u8 dir; + s8 health; + s8 stamina; + s8 staminaRecharge; + s8 staminaRechargeDelay; + s8 attackTimer; + u8 spawnTrigger; + bool isDead; + bool hasWon; + bool hasWonSaved; + s8 endTimer; + s16 walkDist; + bool isCarrying; + bool isSwimming; + int swimTimer; int regenTimer; int strengthTimer; int swimBreathTimer; int speedTimer; int score; - PlayerData *data; + PlayerData *data; } Player; typedef struct { - float xa; - float ya; - float za; - float xx; - float yy; - float zz; - s16 age; - Item item; + float xa; + float ya; + float za; + float xx; + float yy; + float zz; + s16 age; + Item item; } EntityItem; typedef struct { - s16 itemID; - bool active; - s8 r; // light radius for lantern. - Inventory* inv; // Points to chest inventory. + s16 itemID; + bool active; + s8 r; // light radius for lantern. + Inventory* inv; // Points to chest inventory. } EntityFurniture; typedef struct { u8 mtype; s8 xa; - s8 ya; + s8 ya; s16 health; - s8 dir; - s8 randWalkTime; - s8 walkDist; + s8 dir; + s8 randWalkTime; + s8 walkDist; } PassiveMob; typedef struct { - s8 xa; - s8 ya; - s16 health; - s8 dir; - s8 lvl; - s8 randWalkTime; - s8 walkDist; + s8 xa; + s8 ya; + s16 health; + s8 dir; + s8 lvl; + s8 randWalkTime; + s8 walkDist; s8 randAttackTime; - u32 color; + u32 color; } HostileMob; typedef struct { - s8 xa; - s8 ya; - s16 health; - s8 lvl; - s8 dir; - s8 jumpTime; - u32 color; + s8 xa; + s8 ya; + s16 health; + s8 lvl; + s8 dir; + s8 jumpTime; + u32 color; } Slime; typedef struct { - s8 xa; - s8 ya; - s16 health; - s8 randWalkTime; - s8 walkDist; - s8 dir; + s8 xa; + s8 ya; + s16 health; + s8 randWalkTime; + s8 walkDist; + s8 dir; int attackDelay; int attackTime; int attackType; @@ -120,12 +120,12 @@ typedef struct { } AirWizard; typedef struct { - Entity* parent; - s16 age; - float xa; - float ya; - float xx; - float yy; + Entity* parent; + s16 age; + float xa; + float ya; + float xx; + float yy; } Spark; typedef struct { @@ -137,12 +137,12 @@ typedef struct { } Arrow; typedef struct { - s8 xa; - s8 ya; - s16 health; - s8 randWalkTime; - s8 walkDist; - s8 dir; + s8 xa; + s8 ya; + s16 health; + s8 randWalkTime; + s8 walkDist; + s8 dir; int attackDelay; int attackTime; int attackType; @@ -150,19 +150,19 @@ typedef struct { } Dragon; typedef struct { - Entity* parent; + Entity* parent; u8 type; - s16 age; - float xa; - float ya; - float xx; - float yy; + s16 age; + float xa; + float ya; + float xx; + float yy; } DragonFire; typedef struct { - s8 xa; - s8 ya; - s8 randWalkTime; + s8 xa; + s8 ya; + s8 randWalkTime; s8 waitTime; } Glowworm; @@ -171,56 +171,56 @@ typedef struct { } NPC; typedef struct { - float xa; - float ya; - float za; - float xx; - float yy; - float zz; - s16 age; - char* text; - int color; + float xa; + float ya; + float za; + float xx; + float yy; + float zz; + s16 age; + char* text; + int color; } TextParticleEntity; typedef struct { - s16 age; + s16 age; } SmashParticleEntity; struct Entity { - s16 x; - s16 y; - s8 xKnockback,yKnockback; - u8 xr,yr; - u8 type; - u8 level; - s8 hurtTime; - s16 slotNum; // Read-only. Do not mess with this. - bool canPass; - bool canSwim; - union { - Player p; - EntityItem entityItem; - EntityFurniture entityFurniture; + s16 x; + s16 y; + s8 xKnockback,yKnockback; + u8 xr,yr; + u8 type; + u8 level; + s8 hurtTime; + s16 slotNum; // Read-only. Do not mess with this. + bool canPass; + bool canSwim; + union { + Player p; + EntityItem entityItem; + EntityFurniture entityFurniture; PassiveMob passive; - HostileMob hostile; - Slime slime; - AirWizard wizard; - Spark spark; + HostileMob hostile; + Slime slime; + AirWizard wizard; + Spark spark; Arrow arrow; Glowworm glowworm; Dragon dragon; DragonFire dragonFire; - NPC npc; - TextParticleEntity textParticle; - SmashParticleEntity smashParticle; - }; + NPC npc; + TextParticleEntity textParticle; + SmashParticleEntity smashParticle; + }; }; typedef struct { - Entity entities[6][1000]; - s16 lastSlot[6]; - Inventory invs[300]; - s16 nextInv; + Entity entities[6][1000]; + s16 lastSlot[6]; + Inventory invs[300]; + s16 nextInv; } EntityManager; EntityManager eManager; @@ -246,6 +246,3 @@ 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 removeEntityFromList(Entity * e,int level,EntityManager* em); - - - diff --git a/source/Globals.c b/source/Globals.c index 1dcf91c..9e278fe 100755 --- a/source/Globals.c +++ b/source/Globals.c @@ -7,8 +7,8 @@ char fpsstr[34]; u8 currentMenu = 0; void addItemsToWorld(Item item, s8 level, int x, int y, int count){ - int i; - for(i = 0; i < count; ++i) addEntityToList(newItemEntity(item, x, y, level), &eManager); + int i; + for(i = 0; i < count; ++i) addEntityToList(newItemEntity(item, x, y, level), &eManager); } bool intersects(Entity e,int x0, int y0, int x1, int y1) { @@ -16,24 +16,24 @@ bool intersects(Entity e,int x0, int y0, int x1, int y1) { } int getEntities(Entity **result, s8 level, int x0, int y0, int x1, int y1) { - int i, last = 0; + int i, last = 0; for (i = 0; i < eManager.lastSlot[level]; ++i) { - Entity* e = &eManager.entities[level][i]; + Entity* e = &eManager.entities[level][i]; if (intersects(*e, x0, y0, x1, y1)){ - result[last] = e; - ++last; - } + result[last] = e; + ++last; + } } return last; } void removeSimilarElements(Entity **arr1, int arr1Size, Entity **arr2, int arr2Size){ - int i,j; - for(i=0;ilevel]]; Entity * isInside[eManager.lastSlot[e->level]]; - int wasSize = getEntities(wasInside, e->level, e->x - e->xr, e->y - e->yr, e->x + e->xr, e->y + e->yr); + int wasSize = getEntities(wasInside, e->level, e->x - e->xr, e->y - e->yr, e->x + e->xr, e->y + e->yr); int isSize = getEntities(isInside, e->level, e->x + xa - e->xr, e->y + ya - e->yr, e->x + xa + e->xr, e->y + ya + e->yr); int i; - + for (i = 0; i < isSize; ++i) { Entity * ent = isInside[i]; if (ent == e || ent == NULL) continue; EntityVsEntity(e, ent); } if(e->type != ENTITY_PLAYER){ - for(int i=0; ilevel && intersects(players[i].entity, e->x + xa - e->xr, e->y + ya - e->yr, e->x + xa + e->xr, e->y + ya + e->yr)){ - EntityVsEntity(e, &(players[i].entity)); - } - } - } + for(int i=0; ilevel && intersects(players[i].entity, e->x + xa - e->xr, e->y + ya - e->yr, e->x + xa + e->xr, e->y + ya + e->yr)){ + EntityVsEntity(e, &(players[i].entity)); + } + } + } removeSimilarElements(wasInside, wasSize, isInside, isSize); - + for (i = 0; i < isSize; ++i) { Entity * ent = isInside[i]; if (ent == e || ent == NULL) continue; if (EntityBlocksEntity(e, ent)) return false; } - - if(e->x + xa > 0 && e->x + xa < 2048) e->x += xa; + + if(e->x + xa > 0 && e->x + xa < 2048) e->x += xa; if(e->y + ya > 0 && e->y + ya < 2048) e->y += ya; return true; } @@ -102,55 +102,55 @@ bool move(Entity* e, int xa, int ya) { } bool moveMob(Entity* e, int xa, int ya){ - if (e->xKnockback < 0) { - move2(e, -1, 0); - e->xKnockback++; - } - if (e->xKnockback > 0) { - move2(e, 1, 0); - e->xKnockback--; - } - if (e->yKnockback < 0) { - move2(e, 0, -1); - e->yKnockback++; - } - if (e->yKnockback > 0) { - move2(e, 0, 1); - e->yKnockback--; - } - if (e->hurtTime > 0) return true; - return move(e, xa, ya); + if (e->xKnockback < 0) { + move2(e, -1, 0); + e->xKnockback++; + } + if (e->xKnockback > 0) { + move2(e, 1, 0); + e->xKnockback--; + } + if (e->yKnockback < 0) { + move2(e, 0, -1); + e->yKnockback++; + } + if (e->yKnockback > 0) { + move2(e, 0, 1); + e->yKnockback--; + } + if (e->hurtTime > 0) return true; + return move(e, xa, ya); } void hurtEntity(Entity *e, int damage, int dir, u32 hurtColor, Entity *damager){ - if (shouldRenderDebug && e->type==ENTITY_PLAYER) return; - if (e->hurtTime > 0) return; + if (shouldRenderDebug && e->type==ENTITY_PLAYER) return; + if (e->hurtTime > 0) return; playSoundPositioned(snd_monsterHurt, e->level, e->x, e->y); - char hurtText[11]; - sprintf(hurtText, "%d", damage); - addEntityToList(newTextParticleEntity(hurtText, hurtColor, e->x, e->y, e->level), &eManager); - - int i; - - // In hindsight I should've made a generic Mob struct, but whatever. ¯\_(-.-)_/¯ - switch(e->type){ - case ENTITY_PLAYER: - e->p.health -= damage; - if(e->p.health < 1){ - playSoundPositioned(snd_bossdeath, e->level, e->x, e->y); - e->p.endTimer = 60; - e->p.isDead = true; - e->hurtTime = 10; - return; - } - break; - case ENTITY_ZOMBIE: + char hurtText[11]; + sprintf(hurtText, "%d", damage); + addEntityToList(newTextParticleEntity(hurtText, hurtColor, e->x, e->y, e->level), &eManager); + + int i; + + // In hindsight I should've made a generic Mob struct, but whatever. �\_(-.-)_/� + switch(e->type){ + case ENTITY_PLAYER: + e->p.health -= damage; + if(e->p.health < 1){ + playSoundPositioned(snd_bossdeath, e->level, e->x, e->y); + e->p.endTimer = 60; + e->p.isDead = true; + e->hurtTime = 10; + return; + } + break; + case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: - e->hostile.health -= damage; - if(e->hostile.health < 1){ - if(e->type == ENTITY_ZOMBIE) { + e->hostile.health -= damage; + if(e->hostile.health < 1){ + if(e->type == ENTITY_ZOMBIE) { addItemsToWorld(newItem(ITEM_FLESH,1), e->level, e->x+8, e->y+8, (rand()%2) + 1); } else if(e->type == ENTITY_SKELETON) { addItemsToWorld(newItem(ITEM_BONE,1), e->level, e->x+8, e->y+8, (rand()%2) + 1); @@ -158,42 +158,42 @@ void hurtEntity(Entity *e, int damage, int dir, u32 hurtColor, Entity *damager){ } else if(e->type == ENTITY_KNIGHT) { addItemsToWorld(newItem(ITEM_IRONINGOT,1), e->level, e->x+8, e->y+8, (rand()%2) + 1); } - if(damager!=NULL && damager->type==ENTITY_PLAYER) damager->p.data->score += 50 * (e->hostile.lvl + 1); - removeEntityFromList(e, e->level, &eManager); - if(e->level != 5) trySpawn(3, e->level); - return; - } - break; - case ENTITY_SLIME: - e->slime.health -= damage; - if(e->slime.health < 1){ - addItemsToWorld(newItem(ITEM_SLIME,1), e->level, e->x+8, e->y+8, (rand()%2) + 1); - if(damager!=NULL && damager->type==ENTITY_PLAYER) damager->p.data->score += 25 * (e->slime.lvl + 1); - removeEntityFromList(e, e->level, &eManager); - if(e->level != 5) trySpawn(3, e->level); - return; - } - break; - case ENTITY_AIRWIZARD: - e->wizard.health -= damage; - airWizardHealthDisplay = e->wizard.health; - if(e->wizard.health < 1){ + if(damager!=NULL && damager->type==ENTITY_PLAYER) damager->p.data->score += 50 * (e->hostile.lvl + 1); + removeEntityFromList(e, e->level, &eManager); + if(e->level != 5) trySpawn(3, e->level); + return; + } + break; + case ENTITY_SLIME: + e->slime.health -= damage; + if(e->slime.health < 1){ + addItemsToWorld(newItem(ITEM_SLIME,1), e->level, e->x+8, e->y+8, (rand()%2) + 1); + if(damager!=NULL && damager->type==ENTITY_PLAYER) damager->p.data->score += 25 * (e->slime.lvl + 1); + removeEntityFromList(e, e->level, &eManager); + if(e->level != 5) trySpawn(3, e->level); + return; + } + break; + case ENTITY_AIRWIZARD: + e->wizard.health -= damage; + airWizardHealthDisplay = e->wizard.health; + if(e->wizard.health < 1){ addItemsToWorld(newItem(ITEM_MAGIC_DUST,1), e->level, e->x+8, e->y+8, (rand()%2) + 2); - removeEntityFromList(e,e->level,&eManager); - playSound(snd_bossdeath); - - for(i=0; ipassive.health -= damage; - if(e->passive.health < 1){ + removeEntityFromList(e,e->level,&eManager); + playSound(snd_bossdeath); + + for(i=0; ipassive.health -= damage; + if(e->passive.health < 1){ if(e->passive.mtype==0) { addItemsToWorld(newItem(ITEM_WOOL,1), e->level, e->x+8, e->y+8, (rand()%3) + 1); } else if(e->passive.mtype==1) { @@ -204,216 +204,216 @@ void hurtEntity(Entity *e, int damage, int dir, u32 hurtColor, Entity *damager){ addItemsToWorld(newItem(ITEM_LEATHER,1), e->level, e->x+8, e->y+8, 1); } } - if(damager!=NULL && damager->type==ENTITY_PLAYER) damager->p.data->score += 10; - removeEntityFromList(e, e->level, &eManager); - if(e->level != 5) trySpawn(3, e->level); - return; - } + if(damager!=NULL && damager->type==ENTITY_PLAYER) damager->p.data->score += 10; + removeEntityFromList(e, e->level, &eManager); + if(e->level != 5) trySpawn(3, e->level); + return; + } break; - case ENTITY_DRAGON: - e->dragon.health -= damage; - if(e->dragon.health < 1){ + case ENTITY_DRAGON: + e->dragon.health -= damage; + if(e->dragon.health < 1){ addItemsToWorld(newItem(ITEM_DRAGON_EGG,1), e->level, e->x+8, e->y+8, 1); addItemsToWorld(newItem(ITEM_DRAGON_SCALE,1), e->level, e->x+8, e->y+8, (rand()%11) + 10); - removeEntityFromList(e, e->level, &eManager); - playSound(snd_bossdeath); - for(i=0; ilevel, &eManager); + playSound(snd_bossdeath); + for(i=0; itype){ - case ENTITY_PLAYER: - switch(e->p.dir){ - case 0: e->yKnockback = -10; break; - case 1: e->yKnockback = +10; break; - case 2: e->xKnockback = +10; break; - case 3: e->xKnockback = -10; break; - } - break; - case ENTITY_ZOMBIE: + case -1: + switch(e->type){ + case ENTITY_PLAYER: + switch(e->p.dir){ + case 0: e->yKnockback = -10; break; + case 1: e->yKnockback = +10; break; + case 2: e->xKnockback = +10; break; + case 3: e->xKnockback = -10; break; + } + break; + case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: - switch(e->hostile.dir){ - case 0: e->yKnockback = -10; break; - case 1: e->yKnockback = +10; break; - case 2: e->xKnockback = +10; break; - case 3: e->xKnockback = -10; break; - } - break; - case ENTITY_SLIME: - switch(e->slime.dir){ - case 0: e->yKnockback = -10; break; - case 1: e->yKnockback = +10; break; - case 2: e->xKnockback = +10; break; - case 3: e->xKnockback = -10; break; - } - break; + switch(e->hostile.dir){ + case 0: e->yKnockback = -10; break; + case 1: e->yKnockback = +10; break; + case 2: e->xKnockback = +10; break; + case 3: e->xKnockback = -10; break; + } + break; + case ENTITY_SLIME: + switch(e->slime.dir){ + case 0: e->yKnockback = -10; break; + case 1: e->yKnockback = +10; break; + case 2: e->xKnockback = +10; break; + case 3: e->xKnockback = -10; break; + } + break; case ENTITY_PASSIVE: - switch(e->passive.dir){ - case 0: e->yKnockback = -10; break; - case 1: e->yKnockback = +10; break; - case 2: e->xKnockback = +10; break; - case 3: e->xKnockback = -10; break; - } - break; - } - break; - case 0: e->yKnockback = +10; break; - case 1: e->yKnockback = -10; break; - case 2: e->xKnockback = -10; break; - case 3: e->xKnockback = +10; break; - } + switch(e->passive.dir){ + case 0: e->yKnockback = -10; break; + case 1: e->yKnockback = +10; break; + case 2: e->xKnockback = +10; break; + case 3: e->xKnockback = -10; break; + } + break; + } + break; + case 0: e->yKnockback = +10; break; + case 1: e->yKnockback = -10; break; + case 2: e->xKnockback = -10; break; + case 3: e->xKnockback = +10; break; + } e->hurtTime = 10; } bool ItemVsEntity(PlayerData *pd, Item *item, Entity *e, int dir) { - //TODO: Too much duplicated code - switch(item->id){ - case ITEM_POWGLOVE: - if(e->type == ENTITY_FURNITURE){ - //Important: close all crafting windows using this furniture (only applies to chest) or else they will write invalid memory - for(int i=0; ientityFurniture.itemID,0); - if(e->entityFurniture.itemID == ITEM_CHEST) nItem.chestPtr = e->entityFurniture.inv; - pushItemToInventoryFront(nItem, &(pd->inventory)); - - removeEntityFromList(e, e->level, &eManager); - pd->activeItem = &(pd->inventory.items[0]); - pd->entity.p.isCarrying = true; - return true; - } break; - case TOOL_AXE: - switch(e->type){ + //TODO: Too much duplicated code + switch(item->id){ + case ITEM_POWGLOVE: + if(e->type == ENTITY_FURNITURE){ + //Important: close all crafting windows using this furniture (only applies to chest) or else they will write invalid memory + for(int i=0; ientityFurniture.itemID,0); + if(e->entityFurniture.itemID == ITEM_CHEST) nItem.chestPtr = e->entityFurniture.inv; + pushItemToInventoryFront(nItem, &(pd->inventory)); + + removeEntityFromList(e, e->level, &eManager); + pd->activeItem = &(pd->inventory.items[0]); + pd->entity.p.isCarrying = true; + return true; + } break; + case TOOL_AXE: + switch(e->type){ case ENTITY_PASSIVE: - case ENTITY_ZOMBIE: + case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: - case ENTITY_SLIME: - case ENTITY_AIRWIZARD: + case ENTITY_SLIME: + case ENTITY_AIRWIZARD: case ENTITY_DRAGON: - if(playerUseEnergy(pd, 4-item->countLevel)) hurtEntity(e, (item->countLevel + 1) * 2 + (rand()%4), dir, 0xFF0000FF, &(pd->entity)); - else hurtEntity(e, 1+rand()%3, dir, 0xFF0000FF, &(pd->entity)); - return true; - + if(playerUseEnergy(pd, 4-item->countLevel)) hurtEntity(e, (item->countLevel + 1) * 2 + (rand()%4), dir, 0xFF0000FF, &(pd->entity)); + else hurtEntity(e, 1+rand()%3, dir, 0xFF0000FF, &(pd->entity)); + return true; + case ENTITY_MAGIC_PILLAR: - playSoundPositioned(snd_monsterHurt, e->level, e->x, e->y); - + playSoundPositioned(snd_monsterHurt, e->level, e->x, e->y); + removeEntityFromList(e, e->level, &eManager); return true; - } break; - case TOOL_SWORD: - switch(e->type){ + } break; + case TOOL_SWORD: + switch(e->type){ case ENTITY_PASSIVE: - case ENTITY_ZOMBIE: + case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: - case ENTITY_SLIME: - case ENTITY_AIRWIZARD: + case ENTITY_SLIME: + case ENTITY_AIRWIZARD: case ENTITY_DRAGON: - if(playerUseEnergy(pd, 4-item->countLevel)) hurtEntity(e, (item->countLevel+1)*3+(rand()%(2+item->countLevel*item->countLevel*2)), dir, 0xFF0000FF, &(pd->entity)); - else hurtEntity(e, 1+rand()%3, dir, 0xFF0000FF, &(pd->entity)); - return true; - + if(playerUseEnergy(pd, 4-item->countLevel)) hurtEntity(e, (item->countLevel+1)*3+(rand()%(2+item->countLevel*item->countLevel*2)), dir, 0xFF0000FF, &(pd->entity)); + else hurtEntity(e, 1+rand()%3, dir, 0xFF0000FF, &(pd->entity)); + return true; + case ENTITY_MAGIC_PILLAR: - playSoundPositioned(snd_monsterHurt, e->level, e->x, e->y); - + playSoundPositioned(snd_monsterHurt, e->level, e->x, e->y); + removeEntityFromList(e, e->level, &eManager); return true; - } break; - case ITEM_NULL: - switch(e->type){ + } break; + case ITEM_NULL: + switch(e->type){ case ENTITY_PASSIVE: - case ENTITY_ZOMBIE: + case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: - case ENTITY_SLIME: - case ENTITY_AIRWIZARD: + case ENTITY_SLIME: + case ENTITY_AIRWIZARD: case ENTITY_DRAGON: - hurtEntity(e, 1+rand()%3, dir, 0xFF0000FF, &(pd->entity)); - return true; - + hurtEntity(e, 1+rand()%3, dir, 0xFF0000FF, &(pd->entity)); + return true; + case ENTITY_MAGIC_PILLAR: - playSoundPositioned(snd_monsterHurt, e->level, e->x, e->y); - + playSoundPositioned(snd_monsterHurt, e->level, e->x, e->y); + removeEntityFromList(e, e->level, &eManager); return true; - } break; - } - return false; + } break; + } + return false; } void EntityVsEntity(Entity* e1, Entity* e2){ int damage = 1; - switch(e1->type){ - case ENTITY_PLAYER: playerEntityInteract(e1->p.data, e2); break; - case ENTITY_ZOMBIE: + switch(e1->type){ + case ENTITY_PLAYER: playerEntityInteract(e1->p.data, e2); break; + case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: - if(e2->type == ENTITY_PLAYER){ - if(e1->type == ENTITY_ZOMBIE) hurtEntity(e2, 2, e1->hostile.dir, 0xFFAF00FF, e1); + if(e2->type == ENTITY_PLAYER){ + if(e1->type == ENTITY_ZOMBIE) hurtEntity(e2, 2, e1->hostile.dir, 0xFFAF00FF, e1); else if(e1->type == ENTITY_SKELETON) hurtEntity(e2, 1, e1->hostile.dir, 0xFFAF00FF, e1); else if(e1->type == ENTITY_KNIGHT) hurtEntity(e2, 3, e1->hostile.dir, 0xFFAF00FF, e1); - switch(e1->hostile.dir){ - case 0: e1->yKnockback = -4; break; - case 1: e1->yKnockback = +4; break; - case 2: e1->xKnockback = +4; break; - case 3: e1->xKnockback = -4; break; - } - } - break; - case ENTITY_SLIME: - if(e2->type == ENTITY_PLAYER){ - hurtEntity(e2, 1, e1->slime.dir, 0xFFAF00FF, e1); - switch(e1->slime.dir){ - case 0: e1->yKnockback = -4; break; - case 1: e1->yKnockback = +4; break; - case 2: e1->xKnockback = +4; break; - case 3: e1->xKnockback = -4; break; - } - } - break; - case ENTITY_AIRWIZARD: - if(e2->type == ENTITY_PLAYER) hurtEntity(e2, 3, e1->wizard.dir, 0xFFAF00FF, e1); - break; - case ENTITY_SPARK: - if(e2 != e1->spark.parent) hurtEntity(e2, 1, -1, 0xFFAF00FF, e1); - break; + switch(e1->hostile.dir){ + case 0: e1->yKnockback = -4; break; + case 1: e1->yKnockback = +4; break; + case 2: e1->xKnockback = +4; break; + case 3: e1->xKnockback = -4; break; + } + } + break; + case ENTITY_SLIME: + if(e2->type == ENTITY_PLAYER){ + hurtEntity(e2, 1, e1->slime.dir, 0xFFAF00FF, e1); + switch(e1->slime.dir){ + case 0: e1->yKnockback = -4; break; + case 1: e1->yKnockback = +4; break; + case 2: e1->xKnockback = +4; break; + case 3: e1->xKnockback = -4; break; + } + } + break; + case ENTITY_AIRWIZARD: + if(e2->type == ENTITY_PLAYER) hurtEntity(e2, 3, e1->wizard.dir, 0xFFAF00FF, e1); + break; + case ENTITY_SPARK: + if(e2 != e1->spark.parent) hurtEntity(e2, 1, -1, 0xFFAF00FF, e1); + break; case ENTITY_DRAGON: - if(e2->type == ENTITY_PLAYER) hurtEntity(e2, 3, e1->dragon.dir, 0xFFAF00FF, e1); - break; - case ENTITY_DRAGONPROJECTILE: - if(e2 != e1->dragonFire.parent) hurtEntity(e2, 1, -1, 0xFFAF00FF, e1); - break; + if(e2->type == ENTITY_PLAYER) hurtEntity(e2, 3, e1->dragon.dir, 0xFFAF00FF, e1); + break; + case ENTITY_DRAGONPROJECTILE: + if(e2 != e1->dragonFire.parent) hurtEntity(e2, 1, -1, 0xFFAF00FF, e1); + break; case ENTITY_ARROW: switch(e1->arrow.itemID) { - case ITEM_ARROW_WOOD: + case ITEM_ARROW_WOOD: damage = 1 + (rand()%3); break; - case ITEM_ARROW_STONE: + case ITEM_ARROW_STONE: damage = 2 + (rand()%4); break; - case ITEM_ARROW_IRON: + case ITEM_ARROW_IRON: damage = 8 + (rand()%9); break; - case ITEM_ARROW_GOLD: + case ITEM_ARROW_GOLD: damage = 16 + (rand()%9); break; - case ITEM_ARROW_GEM: + case ITEM_ARROW_GEM: damage = 24 + (rand()%9); break; } - + if(e1->arrow.parent->type == ENTITY_PLAYER) { if(e2->type != ENTITY_PLAYER) { hurtEntity(e2, damage, -1, 0xFF0000FF, e1); @@ -426,87 +426,87 @@ void EntityVsEntity(Entity* e1, Entity* e2){ } } break; - } + } } bool EntityBlocksEntity(Entity* e1, Entity* e2){ - switch(e1->type){ - case ENTITY_PLAYER: - case ENTITY_FURNITURE: - switch(e2->type){ - case ENTITY_FURNITURE: - case ENTITY_ZOMBIE: + switch(e1->type){ + case ENTITY_PLAYER: + case ENTITY_FURNITURE: + switch(e2->type){ + case ENTITY_FURNITURE: + case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: - case ENTITY_SLIME: - case ENTITY_AIRWIZARD: + case ENTITY_SLIME: + case ENTITY_AIRWIZARD: case ENTITY_DRAGON: - case ENTITY_PLAYER: + case ENTITY_PLAYER: case ENTITY_PASSIVE: case ENTITY_MAGIC_PILLAR: - case ENTITY_NPC: - return true; - break; - } - break; - } - return false; + case ENTITY_NPC: + return true; + break; + } + break; + } + return false; } bool tileIsSolid(int tile, Entity * e){ - switch(tile){ - case TILE_ROCK: - case TILE_HARDROCK: + switch(tile){ + case TILE_ROCK: + case TILE_HARDROCK: case TILE_MAGIC_BARRIER: - case TILE_DUNGEON_WALL: - return true; - case TILE_TREE: - case TILE_CACTUS: - case TILE_IRONORE: - case TILE_GOLDORE: - case TILE_GEMORE: - case TILE_CLOUDCACTUS: - case TILE_WOOD_WALL: - case TILE_STONE_WALL: - case TILE_IRON_WALL: - case TILE_GOLD_WALL: - case TILE_GEM_WALL: - case TILE_BOOKSHELVES: - case TILE_MUSHROOM_BROWN: - case TILE_MUSHROOM_RED: - if(e->type != ENTITY_DRAGON) return true; - case TILE_LAVA: - case 255: + case TILE_DUNGEON_WALL: + return true; + case TILE_TREE: + case TILE_CACTUS: + case TILE_IRONORE: + case TILE_GOLDORE: + case TILE_GEMORE: + case TILE_CLOUDCACTUS: + case TILE_WOOD_WALL: + case TILE_STONE_WALL: + case TILE_IRON_WALL: + case TILE_GOLD_WALL: + case TILE_GEM_WALL: + case TILE_BOOKSHELVES: + case TILE_MUSHROOM_BROWN: + case TILE_MUSHROOM_RED: + if(e->type != ENTITY_DRAGON) return true; + case TILE_LAVA: + case 255: if(e->type != ENTITY_ARROW) return true; - case TILE_WATER: - if(e != NULL && !e->canSwim && e->type != ENTITY_ARROW) return true; - case TILE_HOLE: - if(e != NULL && e->type != ENTITY_PLAYER && e->type != ENTITY_ARROW) return true; - } - return false; + case TILE_WATER: + if(e != NULL && !e->canSwim && e->type != ENTITY_ARROW) return true; + case TILE_HOLE: + if(e != NULL && e->type != ENTITY_PLAYER && e->type != ENTITY_ARROW) return true; + } + return false; } /* For minimap */ u32 getTileColor(int tile){ - switch(tile){ - case TILE_WATER: return SWAP_UINT32(waterColor[0]); - case TILE_LAVA: return SWAP_UINT32(lavaColor[0]); - case TILE_DIRT: return 0x826D6CFF; - case TILE_ROCK: return SWAP_UINT32(rockColor[1]); - case TILE_HARDROCK: return SWAP_UINT32(rockColor[3]); - case TILE_GRASS: return SWAP_UINT32(grassColor); - case TILE_TREE: return 0x007F00FF; - case TILE_SAND: return SWAP_UINT32(sandColor); - case TILE_CACTUS: return 0x009F00FF; - case TILE_FLOWER: return SWAP_UINT32(grassColor); - case TILE_IRONORE: return SWAP_UINT32(ironColor); - case TILE_GOLDORE: return SWAP_UINT32(goldColor); - case TILE_GEMORE: return SWAP_UINT32(gemColor); - case TILE_CLOUD: return 0xFFFFFFFF; - case TILE_CLOUDCACTUS: return 0xAFAFAFFF; - case TILE_STAIRS_DOWN: return 0x9F9F9FFF; - case TILE_STAIRS_UP: return 0x9F9F9FFF; - case TILE_HOLE: return 0x383838FF; + switch(tile){ + case TILE_WATER: return SWAP_UINT32(waterColor[0]); + case TILE_LAVA: return SWAP_UINT32(lavaColor[0]); + case TILE_DIRT: return 0x826D6CFF; + case TILE_ROCK: return SWAP_UINT32(rockColor[1]); + case TILE_HARDROCK: return SWAP_UINT32(rockColor[3]); + case TILE_GRASS: return SWAP_UINT32(grassColor); + case TILE_TREE: return 0x007F00FF; + case TILE_SAND: return SWAP_UINT32(sandColor); + case TILE_CACTUS: return 0x009F00FF; + case TILE_FLOWER: return SWAP_UINT32(grassColor); + case TILE_IRONORE: return SWAP_UINT32(ironColor); + case TILE_GOLDORE: return SWAP_UINT32(goldColor); + case TILE_GEMORE: return SWAP_UINT32(gemColor); + case TILE_CLOUD: return 0xFFFFFFFF; + case TILE_CLOUDCACTUS: return 0xAFAFAFFF; + case TILE_STAIRS_DOWN: return 0x9F9F9FFF; + case TILE_STAIRS_UP: return 0x9F9F9FFF; + case TILE_HOLE: return 0x383838FF; case TILE_WOOD_WALL: return SWAP_UINT32(woodColor); case TILE_STONE_WALL: return SWAP_UINT32(rockColor[1]); case TILE_IRON_WALL: return SWAP_UINT32(ironColor); @@ -517,247 +517,247 @@ u32 getTileColor(int tile){ 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; - } + 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; + } } s8 itemTileInteract(int tile, PlayerData *pd, Item *item, s8 level, int x, int y, int px, int py, int dir){ - - // Furniture items - if(item->id > 27 && item->id < 51){ - if(!tileIsSolid(getTile(level, x, y), NULL)){ - addEntityToList(newFurnitureEntity(item->id, item->chestPtr, (x<<4)+8, (y<<4)+8, level), &eManager); - removeItemFromCurrentInv(item); - pd->activeItem = &noItem; - return 2; - } - return 0; - } - - switch(tile){ - case TILE_TREE: - if(item->id == TOOL_AXE && playerUseEnergy(pd, 4-item->countLevel)){ - playerHurtTile(pd, tile, level, x, y, (rand()%10) + (item->countLevel) * 5 + 10, pd->entity.p.dir); - return 1; - } break; - case TILE_ROCK: - case TILE_HARDROCK: - if(item->id == TOOL_PICKAXE && playerUseEnergy(pd, 4-item->countLevel)){ - playerHurtTile(pd, tile, level, x, y, (rand()%10) + (item->countLevel) * 5 + 10, pd->entity.p.dir); - return 1; - } break; - case TILE_IRONORE: - case TILE_GOLDORE: - case TILE_GEMORE: - case TILE_CLOUDCACTUS: - if(item->id == TOOL_PICKAXE && playerUseEnergy(pd, 4-item->countLevel)){ - playerHurtTile(pd, tile, level, x, y, 1, pd->entity.p.dir); - return 1; - } break; - case TILE_GRASS: - if(item->id == TOOL_HOE && playerUseEnergy(pd, 4-item->countLevel)){ - setTile(TILE_FARM, level, x, y); - return 1; - } - else if(item->id == ITEM_ACORN){ - setTile(TILE_SAPLING_TREE, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_FLOWER){ - setTile(TILE_FLOWER, level, x, y); --item->countLevel; + + // Furniture items + if(item->id > 27 && item->id < 51){ + if(!tileIsSolid(getTile(level, x, y), NULL)){ + addEntityToList(newFurnitureEntity(item->id, item->chestPtr, (x<<4)+8, (y<<4)+8, level), &eManager); + removeItemFromCurrentInv(item); + pd->activeItem = &noItem; + return 2; + } + return 0; + } + + switch(tile){ + case TILE_TREE: + if(item->id == TOOL_AXE && playerUseEnergy(pd, 4-item->countLevel)){ + playerHurtTile(pd, tile, level, x, y, (rand()%10) + (item->countLevel) * 5 + 10, pd->entity.p.dir); + return 1; + } break; + case TILE_ROCK: + case TILE_HARDROCK: + if(item->id == TOOL_PICKAXE && playerUseEnergy(pd, 4-item->countLevel)){ + playerHurtTile(pd, tile, level, x, y, (rand()%10) + (item->countLevel) * 5 + 10, pd->entity.p.dir); + return 1; + } break; + case TILE_IRONORE: + case TILE_GOLDORE: + case TILE_GEMORE: + case TILE_CLOUDCACTUS: + if(item->id == TOOL_PICKAXE && playerUseEnergy(pd, 4-item->countLevel)){ + playerHurtTile(pd, tile, level, x, y, 1, pd->entity.p.dir); + return 1; + } break; + case TILE_GRASS: + if(item->id == TOOL_HOE && playerUseEnergy(pd, 4-item->countLevel)){ + setTile(TILE_FARM, level, x, y); + return 1; + } + else if(item->id == ITEM_ACORN){ + setTile(TILE_SAPLING_TREE, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_FLOWER){ + setTile(TILE_FLOWER, level, x, y); --item->countLevel; setData(rand()%4, level, x, y); // determines mirroring. - return 1; - } - else if(item->id == ITEM_WALL_WOOD){ - setTile(TILE_WOOD_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_WALL_STONE){ - setTile(TILE_STONE_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_WALL_IRON){ - setTile(TILE_IRON_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_WALL_GOLD){ - setTile(TILE_GOLD_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_WALL_GEM){ - setTile(TILE_GEM_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_BOOKSHELVES){ - setTile(TILE_BOOKSHELVES, level, x, y); --item->countLevel; - setData(rand()%3, level, x, y); //determines sprite - return 1; - } - else if(item->id == TOOL_SHOVEL && playerUseEnergy(pd, 4-item->countLevel)){ - if(rand()%5==0) addItemsToWorld(newItem(ITEM_SEEDS,1), level, (x<<4)+8, (y<<4)+8, 1); - setTile(TILE_DIRT, level, x, y); - return 1; - } break; - case TILE_SAND: - if(item->id == ITEM_CACTUS){ - setTile(TILE_SAPLING_CACTUS, level, x, y); - --item->countLevel; - return 1; - } - else if(item->id == TOOL_SHOVEL && playerUseEnergy(pd, 4-item->countLevel)){ - addItemsToWorld(newItem(ITEM_SAND,1), level, (x<<4)+8, (y<<4)+8, 1); - setTile(TILE_DIRT, level, x, y); - return 1; - } break; - case TILE_DIRT: - if(item->id == TOOL_HOE && pd->entity.level==1 && playerUseEnergy(pd, 4-item->countLevel)){ - setTile(TILE_FARM, level, x, y); - return 1; - } - else if(item->id == ITEM_WALL_WOOD){ - setTile(TILE_WOOD_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_WALL_STONE){ - setTile(TILE_STONE_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_WALL_IRON){ - setTile(TILE_IRON_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_WALL_GOLD){ - setTile(TILE_GOLD_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_WALL_GEM){ - setTile(TILE_GEM_WALL, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_BOOKSHELVES){ - setTile(TILE_BOOKSHELVES, level, x, y); --item->countLevel; - setData(rand()%3, level, x, y); //determines sprite - return 1; - } - else if(item->id == ITEM_WOOD) { - setTile(TILE_WOOD_FLOOR, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == ITEM_SAND){ - setTile(TILE_SAND, level, x, y); --item->countLevel; - return 1; - } - else if(item->id == TOOL_SHOVEL && playerUseEnergy(pd, 4-item->countLevel)){ - addItemsToWorld(newItem(ITEM_DIRT,1), level, (x<<4)+8, (y<<4)+8, 1); - setTile(TILE_HOLE, level, x, y); - return 1; - } break; - case TILE_HOLE: + return 1; + } + else if(item->id == ITEM_WALL_WOOD){ + setTile(TILE_WOOD_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_WALL_STONE){ + setTile(TILE_STONE_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_WALL_IRON){ + setTile(TILE_IRON_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_WALL_GOLD){ + setTile(TILE_GOLD_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_WALL_GEM){ + setTile(TILE_GEM_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_BOOKSHELVES){ + setTile(TILE_BOOKSHELVES, level, x, y); --item->countLevel; + setData(rand()%3, level, x, y); //determines sprite + return 1; + } + else if(item->id == TOOL_SHOVEL && playerUseEnergy(pd, 4-item->countLevel)){ + if(rand()%5==0) addItemsToWorld(newItem(ITEM_SEEDS,1), level, (x<<4)+8, (y<<4)+8, 1); + setTile(TILE_DIRT, level, x, y); + return 1; + } break; + case TILE_SAND: + if(item->id == ITEM_CACTUS){ + setTile(TILE_SAPLING_CACTUS, level, x, y); + --item->countLevel; + return 1; + } + else if(item->id == TOOL_SHOVEL && playerUseEnergy(pd, 4-item->countLevel)){ + addItemsToWorld(newItem(ITEM_SAND,1), level, (x<<4)+8, (y<<4)+8, 1); + setTile(TILE_DIRT, level, x, y); + return 1; + } break; + case TILE_DIRT: + if(item->id == TOOL_HOE && pd->entity.level==1 && playerUseEnergy(pd, 4-item->countLevel)){ + setTile(TILE_FARM, level, x, y); + return 1; + } + else if(item->id == ITEM_WALL_WOOD){ + setTile(TILE_WOOD_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_WALL_STONE){ + setTile(TILE_STONE_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_WALL_IRON){ + setTile(TILE_IRON_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_WALL_GOLD){ + setTile(TILE_GOLD_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_WALL_GEM){ + setTile(TILE_GEM_WALL, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_BOOKSHELVES){ + setTile(TILE_BOOKSHELVES, level, x, y); --item->countLevel; + setData(rand()%3, level, x, y); //determines sprite + return 1; + } + else if(item->id == ITEM_WOOD) { + setTile(TILE_WOOD_FLOOR, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == ITEM_SAND){ + setTile(TILE_SAND, level, x, y); --item->countLevel; + return 1; + } + else if(item->id == TOOL_SHOVEL && playerUseEnergy(pd, 4-item->countLevel)){ + addItemsToWorld(newItem(ITEM_DIRT,1), level, (x<<4)+8, (y<<4)+8, 1); + setTile(TILE_HOLE, level, x, y); + return 1; + } break; + case TILE_HOLE: if(item->id == ITEM_DIRT){ - setTile(TILE_DIRT, level, x, y); - --item->countLevel; - return 1; + setTile(TILE_DIRT, level, x, y); + --item->countLevel; + return 1; } else if(item->id == TOOL_BUCKET && item->countLevel == 1 && playerUseEnergy(pd, 4)) { setTile(TILE_WATER, level, x, y); item->countLevel = 0; - } + } else if(item->id == TOOL_BUCKET && item->countLevel == 2 && playerUseEnergy(pd, 4)) { setTile(TILE_LAVA, level, x, y); item->countLevel = 0; - } break; - case TILE_WATER: + } break; + case TILE_WATER: if(item->id == ITEM_DIRT){ - setTile(TILE_DIRT, level, x, y); - --item->countLevel; - return 1; + setTile(TILE_DIRT, level, x, y); + --item->countLevel; + return 1; } else if(item->id == TOOL_BUCKET && item->countLevel == 0 && playerUseEnergy(pd, 4)) { setTile(TILE_HOLE, level, x, y); item->countLevel = 1; - } break; - case TILE_LAVA: - if(item->id == ITEM_DIRT){ - setTile(TILE_DIRT, level, x, y); - --item->countLevel; - return 1; - } + } break; + case TILE_LAVA: + if(item->id == ITEM_DIRT){ + setTile(TILE_DIRT, level, x, y); + --item->countLevel; + return 1; + } else if(item->id == TOOL_BUCKET && item->countLevel == 0 && playerUseEnergy(pd, 4)) { setTile(TILE_HOLE, level, x, y); item->countLevel = 2; - } break; - case TILE_NULL: - if(item->id == ITEM_CLOUD){ - setTile(TILE_CLOUD, level, x, y); - --item->countLevel; - return 1; - } break; - case TILE_FARM: - if(item->id == ITEM_SEEDS){ - setTile(TILE_WHEAT, level, x, y); - setData(0, level, x, y); - --item->countLevel; - return 1; - } break; - case TILE_WHEAT: - if(item->id == TOOL_HOE){ - if(getData(level, x, y) > -1){ - int age = getData(level, x, y); - int count = (rand() % 2); - if(age >= 80) count = (rand()%2) + 1; - addItemsToWorld(newItem(ITEM_SEEDS,1), level, (x<<4)+8, (y<<4)+8, count); - count = 0; - if(age == 100) count = (rand()%3) + 2; - else if(age >= 80) count = (rand()%2) + 1; - addItemsToWorld(newItem(ITEM_WHEAT,1), level, (x<<4)+8, (y<<4)+8, count); - setTile(TILE_DIRT, level, x, y); - } - } break; + } break; + case TILE_NULL: + if(item->id == ITEM_CLOUD){ + setTile(TILE_CLOUD, level, x, y); + --item->countLevel; + return 1; + } break; + case TILE_FARM: + if(item->id == ITEM_SEEDS){ + setTile(TILE_WHEAT, level, x, y); + setData(0, level, x, y); + --item->countLevel; + return 1; + } break; + case TILE_WHEAT: + if(item->id == TOOL_HOE){ + if(getData(level, x, y) > -1){ + int age = getData(level, x, y); + int count = (rand() % 2); + if(age >= 80) count = (rand()%2) + 1; + addItemsToWorld(newItem(ITEM_SEEDS,1), level, (x<<4)+8, (y<<4)+8, count); + count = 0; + if(age == 100) count = (rand()%3) + 2; + else if(age >= 80) count = (rand()%2) + 1; + addItemsToWorld(newItem(ITEM_WHEAT,1), level, (x<<4)+8, (y<<4)+8, count); + setTile(TILE_DIRT, level, x, y); + } + } break; case TILE_WOOD_WALL: - case TILE_BOOKSHELVES: - if(item->id == TOOL_AXE && playerUseEnergy(pd, 4-item->countLevel)){ - playerHurtTile(pd, tile, level, x, y, (rand()%10) + (item->countLevel) * 5 + 10, pd->entity.p.dir); - return 1; - } break; + case TILE_BOOKSHELVES: + if(item->id == TOOL_AXE && playerUseEnergy(pd, 4-item->countLevel)){ + playerHurtTile(pd, tile, level, x, y, (rand()%10) + (item->countLevel) * 5 + 10, pd->entity.p.dir); + return 1; + } break; case TILE_STONE_WALL: case TILE_IRON_WALL: case TILE_GOLD_WALL: case TILE_GEM_WALL: - if(item->id == TOOL_PICKAXE && playerUseEnergy(pd, 4-item->countLevel)){ - playerHurtTile(pd, tile, level, x, y, (rand()%10) + (item->countLevel) * 5 + 10, pd->entity.p.dir); - return 1; - } break; - case TILE_WOOD_FLOOR: - if(item->id == TOOL_AXE && playerUseEnergy(pd, 4-item->countLevel)){ - addItemsToWorld(newItem(ITEM_WOOD,1), level, (x<<4)+8, (y<<4)+8, 1); - setTile(TILE_DIRT, level, x, y); - } break; - } - return 0; + if(item->id == TOOL_PICKAXE && playerUseEnergy(pd, 4-item->countLevel)){ + playerHurtTile(pd, tile, level, x, y, (rand()%10) + (item->countLevel) * 5 + 10, pd->entity.p.dir); + return 1; + } break; + case TILE_WOOD_FLOOR: + if(item->id == TOOL_AXE && playerUseEnergy(pd, 4-item->countLevel)){ + addItemsToWorld(newItem(ITEM_WOOD,1), level, (x<<4)+8, (y<<4)+8, 1); + setTile(TILE_DIRT, level, x, y); + } break; + } + return 0; } void tickTile(s8 level, int x, int y){ - int tile = getTile(level, x, y); - int data = getData(level, x, y); - - switch(tile){ - case TILE_SAPLING_TREE: - if(worldData.season!=3) { - setData(++data, level, x, y); + int tile = getTile(level, x, y); + int data = getData(level, x, y); + + switch(tile){ + case TILE_SAPLING_TREE: + if(worldData.season!=3) { + setData(++data, level, x, y); if(data>100){setData(0, level, x, y); setTile(TILE_TREE, level, x, y);} } - break; + break; case TILE_TREE: if(eManager.lastSlot[level]<800 && (worldData.daytime>18000 || worldData.daytime<5000) && rand()%800==0) { //check for nearby glowworms - //TODO: This should really use getEntities + //TODO: This should really use getEntities int i = 0; for (i = 0; i < eManager.lastSlot[level]; ++i) { Entity * e = &eManager.entities[level][i]; @@ -766,49 +766,49 @@ void tickTile(s8 level, int x, int y){ addEntityToList(newGlowwormEntity((x<<4)+8, (y<<4)+8, level), &eManager); } break; - case TILE_SAPLING_CACTUS: - if(worldData.season!=3) { - setData(++data, level, x, y); + case TILE_SAPLING_CACTUS: + if(worldData.season!=3) { + setData(++data, level, x, y); if(data>100){setData(0, level, x, y); setTile(TILE_CACTUS, level, x, y);} } - break; - case TILE_WHEAT: - if(data<100 && worldData.season!=3) setData(++data, level, x, y); - break; - case TILE_WATER: - if(getTile(level, x+1, y)==TILE_HOLE) setTile(TILE_WATER, level, x+1, y); - if(getTile(level, x-1, y)==TILE_HOLE) setTile(TILE_WATER, level, x-1, y); - if(getTile(level, x, y+1)==TILE_HOLE) setTile(TILE_WATER, level, x, y+1); - if(getTile(level, x, y-1)==TILE_HOLE) setTile(TILE_WATER, level, x, y-1); - if(level==1 && worldData.season==3 && rand()%12==0) { - if(getTile(level, x+1, y)!=TILE_WATER) setTile(TILE_ICE, level, x, y); - if(getTile(level, x-1, y)!=TILE_WATER) setTile(TILE_ICE, level, x, y); - if(getTile(level, x, y+1)!=TILE_WATER) setTile(TILE_ICE, level, x, y); - if(getTile(level, x, y-1)!=TILE_WATER) setTile(TILE_ICE, level, x, y); - } - break; - case TILE_LAVA: - if(getTile(level, x+1, y)==TILE_HOLE) setTile(TILE_LAVA, level, x+1, y); - if(getTile(level, x-1, y)==TILE_HOLE) setTile(TILE_LAVA, level, x-1, y); - if(getTile(level, x, y+1)==TILE_HOLE) setTile(TILE_LAVA, level, x, y+1); - if(getTile(level, x, y-1)==TILE_HOLE) setTile(TILE_LAVA, level, x, y-1); - + break; + case TILE_WHEAT: + if(data<100 && worldData.season!=3) setData(++data, level, x, y); + break; + case TILE_WATER: + if(getTile(level, x+1, y)==TILE_HOLE) setTile(TILE_WATER, level, x+1, y); + if(getTile(level, x-1, y)==TILE_HOLE) setTile(TILE_WATER, level, x-1, y); + if(getTile(level, x, y+1)==TILE_HOLE) setTile(TILE_WATER, level, x, y+1); + if(getTile(level, x, y-1)==TILE_HOLE) setTile(TILE_WATER, level, x, y-1); + if(level==1 && worldData.season==3 && rand()%12==0) { + if(getTile(level, x+1, y)!=TILE_WATER) setTile(TILE_ICE, level, x, y); + if(getTile(level, x-1, y)!=TILE_WATER) setTile(TILE_ICE, level, x, y); + if(getTile(level, x, y+1)!=TILE_WATER) setTile(TILE_ICE, level, x, y); + if(getTile(level, x, y-1)!=TILE_WATER) setTile(TILE_ICE, level, x, y); + } + break; + case TILE_LAVA: + if(getTile(level, x+1, y)==TILE_HOLE) setTile(TILE_LAVA, level, x+1, y); + if(getTile(level, x-1, y)==TILE_HOLE) setTile(TILE_LAVA, level, x-1, y); + if(getTile(level, x, y+1)==TILE_HOLE) setTile(TILE_LAVA, level, x, y+1); + if(getTile(level, x, y-1)==TILE_HOLE) setTile(TILE_LAVA, level, x, y-1); + if(getTile(level, x+1, y)==TILE_WATER || getTile(level, x-1, y)==TILE_WATER || getTile(level, x, y+1)==TILE_WATER || getTile(level, x, y-1)==TILE_WATER) { setTile(TILE_ROCK, level, x, y); } - break; - case TILE_HOLE: // This makes water flow slightly faster than lava - if(getTile(level, x+1, y)==TILE_WATER) setTile(TILE_WATER, level, x, y); - if(getTile(level, x-1, y)==TILE_WATER) setTile(TILE_WATER, level, x, y); - if(getTile(level, x, y+1)==TILE_WATER) setTile(TILE_WATER, level, x, y); - if(getTile(level, x, y-1)==TILE_WATER) setTile(TILE_WATER, level, x, y); - break; - case TILE_GRASS: - if(getTile(level, x+1, y)==TILE_DIRT) if((rand()%25) == 0) setTile(TILE_GRASS, level, x+1, y); - if(getTile(level, x-1, y)==TILE_DIRT) if((rand()%25) == 0) setTile(TILE_GRASS, level, x-1, y); - if(getTile(level, x, y+1)==TILE_DIRT) if((rand()%25) == 0) setTile(TILE_GRASS, level, x, y+1); - if(getTile(level, x, y-1)==TILE_DIRT) if((rand()%25) == 0) setTile(TILE_GRASS, level, x, y-1); - break; + break; + case TILE_HOLE: // This makes water flow slightly faster than lava + if(getTile(level, x+1, y)==TILE_WATER) setTile(TILE_WATER, level, x, y); + if(getTile(level, x-1, y)==TILE_WATER) setTile(TILE_WATER, level, x, y); + if(getTile(level, x, y+1)==TILE_WATER) setTile(TILE_WATER, level, x, y); + if(getTile(level, x, y-1)==TILE_WATER) setTile(TILE_WATER, level, x, y); + break; + case TILE_GRASS: + if(getTile(level, x+1, y)==TILE_DIRT) if((rand()%25) == 0) setTile(TILE_GRASS, level, x+1, y); + if(getTile(level, x-1, y)==TILE_DIRT) if((rand()%25) == 0) setTile(TILE_GRASS, level, x-1, y); + if(getTile(level, x, y+1)==TILE_DIRT) if((rand()%25) == 0) setTile(TILE_GRASS, level, x, y+1); + if(getTile(level, x, y-1)==TILE_DIRT) if((rand()%25) == 0) setTile(TILE_GRASS, level, x, y-1); + break; case TILE_SAND: if(data > 0) setData(--data, level, x, y); break; @@ -820,130 +820,130 @@ void tickTile(s8 level, int x, int y){ int i = 0; for (i = 0; i < eManager.lastSlot[level]; ++i) { Entity * e = &eManager.entities[level][i]; - + if(e->type == ENTITY_MAGIC_PILLAR) { ++data; } } if(data==0) setTile(TILE_DUNGEON_FLOOR, level, x, y); - setData(rand()%2, level, x, y); + setData(rand()%2, level, x, y); break; - case TILE_ICE: - if(worldData.season!=3) { - setTile(TILE_WATER, level, x, y); - } - break; - } - + case TILE_ICE: + if(worldData.season!=3) { + setTile(TILE_WATER, level, x, y); + } + break; + } + } void tickEntityItem(Entity* e){ - ++e->entityItem.age; - if(e->entityItem.age == 630){ - removeEntityFromList(e, e->level, &eManager); - /* - Programming pro tip: - Remember to put a return statement after you remove the entity, - or else your going to have a very bad time like I did. - */ - return; - } - e->entityItem.xx += e->entityItem.xa; - e->entityItem.yy += e->entityItem.ya; - e->entityItem.zz += e->entityItem.za; - if (e->entityItem.zz < 0) { - e->entityItem.zz = 0; - e->entityItem.za *= -0.5; - e->entityItem.xa *= 0.6; - e->entityItem.ya *= 0.6; - } - e->entityItem.za -= 0.15; - int ox = e->x; - int oy = e->y; - int nx = (int) e->entityItem.xx; - int ny = (int) e->entityItem.yy; - int expectedx = nx - e->x; - int expectedy = ny - e->y; - move(e, nx - e->x, ny - e->y); - int gotx = e->x - ox; - int goty = e->y - oy; - e->entityItem.xx += gotx - expectedx; - e->entityItem.yy += goty - expectedy; + ++e->entityItem.age; + if(e->entityItem.age == 630){ + removeEntityFromList(e, e->level, &eManager); + /* + Programming pro tip: + Remember to put a return statement after you remove the entity, + or else your going to have a very bad time like I did. + */ + return; + } + e->entityItem.xx += e->entityItem.xa; + e->entityItem.yy += e->entityItem.ya; + e->entityItem.zz += e->entityItem.za; + if (e->entityItem.zz < 0) { + e->entityItem.zz = 0; + e->entityItem.za *= -0.5; + e->entityItem.xa *= 0.6; + e->entityItem.ya *= 0.6; + } + e->entityItem.za -= 0.15; + int ox = e->x; + int oy = e->y; + int nx = (int) e->entityItem.xx; + int ny = (int) e->entityItem.yy; + int expectedx = nx - e->x; + int expectedy = ny - e->y; + move(e, nx - e->x, ny - e->y); + int gotx = e->x - ox; + int goty = e->y - oy; + e->entityItem.xx += gotx - expectedx; + e->entityItem.yy += goty - expectedy; } void tickEntityTextParticle(Entity* e){ - ++e->textParticle.age; - if(e->textParticle.age == 60){ - removeEntityFromList(e, e->level, &eManager); - return; - } - e->textParticle.xx += e->textParticle.xa; - e->textParticle.yy += e->textParticle.ya; - e->textParticle.zz += e->textParticle.za; - if (e->textParticle.zz < 0) { - e->textParticle.zz = 0; - e->textParticle.za *= -0.5; - e->textParticle.xa *= 0.6; - e->textParticle.ya *= 0.6; - } - e->textParticle.za -= 0.15; - e->x = (int) e->textParticle.xx; - e->y = (int) e->textParticle.yy; + ++e->textParticle.age; + if(e->textParticle.age == 60){ + removeEntityFromList(e, e->level, &eManager); + return; + } + e->textParticle.xx += e->textParticle.xa; + e->textParticle.yy += e->textParticle.ya; + e->textParticle.zz += e->textParticle.za; + if (e->textParticle.zz < 0) { + e->textParticle.zz = 0; + e->textParticle.za *= -0.5; + e->textParticle.xa *= 0.6; + e->textParticle.ya *= 0.6; + } + e->textParticle.za -= 0.15; + e->x = (int) e->textParticle.xx; + e->y = (int) e->textParticle.yy; } void tickEntity(Entity* e){ - PlayerData *nearestPlayer = getNearestPlayer(e->level, e->x, e->y); - switch(e->type){ - case ENTITY_ITEM: tickEntityItem(e); return; - case ENTITY_FURNITURE: return; + PlayerData *nearestPlayer = getNearestPlayer(e->level, e->x, e->y); + 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: - if (e->hurtTime > 0) e->hurtTime--; - if (e->hostile.randWalkTime == 0 && e->type != ENTITY_SKELETON && nearestPlayer!=NULL) { - int xd = nearestPlayer->entity.x - e->x; - int yd = nearestPlayer->entity.y - e->y; + case ENTITY_ZOMBIE: + case ENTITY_SKELETON: + case ENTITY_KNIGHT: + if (e->hurtTime > 0) e->hurtTime--; + if (e->hostile.randWalkTime == 0 && e->type != ENTITY_SKELETON && nearestPlayer!=NULL) { + int xd = nearestPlayer->entity.x - e->x; + int yd = nearestPlayer->entity.y - e->y; int dist = 50 * 50; if(e->type == ENTITY_KNIGHT) dist = 80 * 80; - + //charge player - if (xd * xd + yd * yd < dist) { - e->hostile.xa = 0; - e->hostile.ya = 0; - if (xd < 0) e->hostile.xa = -1; - if (xd > 0) e->hostile.xa = +1; - if (yd < 0) e->hostile.ya = -1; - if (yd > 0) e->hostile.ya = +1; - } - } - - if(e->hostile.xa < 0) e->hostile.dir = 2; - else if(e->hostile.xa > 0) e->hostile.dir = 3; - if(e->hostile.ya < 0) e->hostile.dir = 1; - else if(e->hostile.ya > 0) e->hostile.dir = 0; - + if (xd * xd + yd * yd < dist) { + e->hostile.xa = 0; + e->hostile.ya = 0; + if (xd < 0) e->hostile.xa = -1; + if (xd > 0) e->hostile.xa = +1; + if (yd < 0) e->hostile.ya = -1; + if (yd > 0) e->hostile.ya = +1; + } + } + + if(e->hostile.xa < 0) e->hostile.dir = 2; + else if(e->hostile.xa > 0) e->hostile.dir = 3; + if(e->hostile.ya < 0) e->hostile.dir = 1; + else if(e->hostile.ya > 0) e->hostile.dir = 0; + if(e->type == ENTITY_SKELETON) { --(e->hostile.randAttackTime); if(e->hostile.randAttackTime <= 0) { e->hostile.randAttackTime = 80 - (e->hostile.lvl * 5); - + int aitemID = ITEM_ARROW_WOOD; if(e->hostile.lvl >= 2) aitemID = ITEM_ARROW_STONE; - + //turn to player when attacking - if(nearestPlayer!=NULL) { - int xd = nearestPlayer->entity.x - e->x; - int yd = nearestPlayer->entity.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; - } - } - + if(nearestPlayer!=NULL) { + int xd = nearestPlayer->entity.x - e->x; + int yd = nearestPlayer->entity.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); @@ -960,189 +960,189 @@ void tickEntity(Entity* e){ } } } - - if(e->hostile.xa != 0 || e->hostile.ya != 0) e->hostile.walkDist++; - int speed = syncTickCount & 1; - if (!moveMob(e, e->hostile.xa * speed, e->hostile.ya * speed) || (rand()%100) == 0) { - e->hostile.randWalkTime = 60; - e->hostile.xa = ((rand()%3) - 1) * (rand()%2); - e->hostile.ya = ((rand()%3) - 1) * (rand()%2); - } - if (e->hostile.randWalkTime > 0) e->hostile.randWalkTime--; - return; - case ENTITY_SLIME: - if (e->hurtTime > 0) e->hurtTime--; - - if (!moveMob(e, e->slime.xa, e->slime.ya) || (rand()%10) == 0) { - if (e->slime.jumpTime <= -10) { - e->slime.xa = ((rand()%3) - 1); - e->slime.ya = ((rand()%3) - 1); - - if(nearestPlayer!=NULL) { - int xd = nearestPlayer->entity.x - e->x; - int yd = nearestPlayer->entity.y - e->y; - if (xd * xd + yd * yd < 50 * 50) { - if (xd < 0) e->slime.xa = -1; - if (xd > 0) e->slime.xa = +1; - if (yd < 0) e->slime.ya = -1; - if (yd > 0) e->slime.ya = +1; - } - } - - if (e->slime.xa != 0 || e->slime.ya != 0) e->slime.jumpTime = 10; - } - } - - if(e->slime.xa < 0) e->slime.dir = 2; - else if(e->slime.xa > 0) e->slime.dir = 3; - if(e->slime.ya < 0) e->slime.dir = 1; - else if(e->slime.ya > 0) e->slime.dir = 0; - - if (e->slime.jumpTime > -10) e->slime.jumpTime--; - if(e->slime.jumpTime == 0){ - e->slime.xa = 0; - e->slime.ya = 0; - } - return; - case ENTITY_AIRWIZARD: - if (e->hurtTime > 0) e->hurtTime--; - - if (e->wizard.attackDelay > 0) { - e->wizard.dir = (e->wizard.attackDelay - 45) / 4 % 4; - e->wizard.dir = (e->wizard.dir * 2 % 4) + (e->wizard.dir / 2); - if (e->wizard.attackDelay < 45) e->wizard.dir = 0; - e->wizard.attackDelay--; - if (e->wizard.attackDelay <= 0) { - e->wizard.attackType = 0; - if (e->wizard.health < 1000) e->wizard.attackType = 1; - if (e->wizard.health < 200) e->wizard.attackType = 2; - e->wizard.attackTime = 120; - } - return; - } - - if (e->wizard.attackTime > 0) { - e->wizard.attackTime--; - float dir = e->wizard.attackTime * 0.25 * (e->wizard.attackTime % 2 * 2 - 1); - float speed = (0.7) + (e->wizard.attackType+1) * 0.2; - addEntityToList(newSparkEntity(e, cos(dir) * speed, sin(dir) * speed), &eManager); - return; - } - - if (e->wizard.randWalkTime == 0 && nearestPlayer!=NULL) { - int xd = nearestPlayer->entity.x - e->x; - int yd = nearestPlayer->entity.y - e->y; - int dist = xd * xd + yd * yd; - if (dist > 80 * 80) { - e->wizard.xa = 0; - e->wizard.ya = 0; - if (xd < 0) e->wizard.xa = -1; - if (xd > 0) e->wizard.xa = +1; - if (yd < 0) e->wizard.ya = -1; - if (yd > 0) e->wizard.ya = +1; - } else if (dist < 24 * 24) { - e->wizard.xa = 0; - e->wizard.ya = 0; - if (xd < 0) e->wizard.xa = +1; - if (xd > 0) e->wizard.xa = -1; - if (yd < 0) e->wizard.ya = +1; - if (yd > 0) e->wizard.ya = -1; - } - } - - int wSpeed = (syncTickCount % 4) == 0 ? 0 : 1; - if (!moveMob(e, e->wizard.xa * wSpeed, e->wizard.ya * wSpeed) || (rand()%100) == 0) { - e->wizard.randWalkTime = 30; - e->wizard.xa = ((rand()%3) - 1) * (rand()%2); - e->wizard.ya = ((rand()%3) - 1) * (rand()%2); - } - - if(e->wizard.xa != 0 || e->wizard.ya != 0){ - e->wizard.walkDist++; - awX = e->x; - awY = e->y; - } - - if(e->wizard.xa < 0) e->wizard.dir = 2; - else if(e->wizard.xa > 0) e->wizard.dir = 3; - if(e->wizard.ya < 0) e->wizard.dir = 1; - else if(e->wizard.ya > 0) e->wizard.dir = 0; - - if (e->wizard.randWalkTime > 0) { - e->wizard.randWalkTime--; - if (e->wizard.randWalkTime == 0 && nearestPlayer!=NULL) { - int xd = nearestPlayer->entity.x - e->x; - int yd = nearestPlayer->entity.y - e->y; - if (rand()%4 == 0 && xd * xd + yd * yd < 50 * 50) { - if (e->wizard.attackDelay == 0 && e->wizard.attackTime == 0) e->wizard.attackDelay = 120; - } - } - } - - return; - case ENTITY_SPARK: - e->spark.age++; - if (e->spark.age >= 260) { - removeEntityFromList(e, e->level, &eManager); - return; - } - e->spark.xx += e->spark.xa; - e->spark.yy += e->spark.ya; - e->x = (int) e->spark.xx; - e->y = (int) e->spark.yy; - - if(nearestPlayer!=NULL && intersects(nearestPlayer->entity, e->x + e->spark.xa - e->xr, e->y + e->spark.ya - e->yr, e->x + e->spark.xa + e->xr, e->y + e->spark.ya + e->yr)){ - EntityVsEntity(e, &(nearestPlayer->entity)); - removeEntityFromList(e, e->level, &eManager); - } - return; + if(e->hostile.xa != 0 || e->hostile.ya != 0) e->hostile.walkDist++; + + int speed = syncTickCount & 1; + if (!moveMob(e, e->hostile.xa * speed, e->hostile.ya * speed) || (rand()%100) == 0) { + e->hostile.randWalkTime = 60; + e->hostile.xa = ((rand()%3) - 1) * (rand()%2); + e->hostile.ya = ((rand()%3) - 1) * (rand()%2); + } + if (e->hostile.randWalkTime > 0) e->hostile.randWalkTime--; + return; + case ENTITY_SLIME: + if (e->hurtTime > 0) e->hurtTime--; + + if (!moveMob(e, e->slime.xa, e->slime.ya) || (rand()%10) == 0) { + if (e->slime.jumpTime <= -10) { + e->slime.xa = ((rand()%3) - 1); + e->slime.ya = ((rand()%3) - 1); + + if(nearestPlayer!=NULL) { + int xd = nearestPlayer->entity.x - e->x; + int yd = nearestPlayer->entity.y - e->y; + if (xd * xd + yd * yd < 50 * 50) { + if (xd < 0) e->slime.xa = -1; + if (xd > 0) e->slime.xa = +1; + if (yd < 0) e->slime.ya = -1; + if (yd > 0) e->slime.ya = +1; + } + } + + if (e->slime.xa != 0 || e->slime.ya != 0) e->slime.jumpTime = 10; + } + } + + if(e->slime.xa < 0) e->slime.dir = 2; + else if(e->slime.xa > 0) e->slime.dir = 3; + if(e->slime.ya < 0) e->slime.dir = 1; + else if(e->slime.ya > 0) e->slime.dir = 0; + + if (e->slime.jumpTime > -10) e->slime.jumpTime--; + if(e->slime.jumpTime == 0){ + e->slime.xa = 0; + e->slime.ya = 0; + } + return; + case ENTITY_AIRWIZARD: + if (e->hurtTime > 0) e->hurtTime--; + + if (e->wizard.attackDelay > 0) { + e->wizard.dir = (e->wizard.attackDelay - 45) / 4 % 4; + e->wizard.dir = (e->wizard.dir * 2 % 4) + (e->wizard.dir / 2); + if (e->wizard.attackDelay < 45) e->wizard.dir = 0; + e->wizard.attackDelay--; + if (e->wizard.attackDelay <= 0) { + e->wizard.attackType = 0; + if (e->wizard.health < 1000) e->wizard.attackType = 1; + if (e->wizard.health < 200) e->wizard.attackType = 2; + e->wizard.attackTime = 120; + } + return; + } + + if (e->wizard.attackTime > 0) { + e->wizard.attackTime--; + float dir = e->wizard.attackTime * 0.25 * (e->wizard.attackTime % 2 * 2 - 1); + float speed = (0.7) + (e->wizard.attackType+1) * 0.2; + addEntityToList(newSparkEntity(e, cos(dir) * speed, sin(dir) * speed), &eManager); + return; + } + + if (e->wizard.randWalkTime == 0 && nearestPlayer!=NULL) { + int xd = nearestPlayer->entity.x - e->x; + int yd = nearestPlayer->entity.y - e->y; + int dist = xd * xd + yd * yd; + if (dist > 80 * 80) { + e->wizard.xa = 0; + e->wizard.ya = 0; + if (xd < 0) e->wizard.xa = -1; + if (xd > 0) e->wizard.xa = +1; + if (yd < 0) e->wizard.ya = -1; + if (yd > 0) e->wizard.ya = +1; + } else if (dist < 24 * 24) { + e->wizard.xa = 0; + e->wizard.ya = 0; + if (xd < 0) e->wizard.xa = +1; + if (xd > 0) e->wizard.xa = -1; + if (yd < 0) e->wizard.ya = +1; + if (yd > 0) e->wizard.ya = -1; + } + } + + int wSpeed = (syncTickCount % 4) == 0 ? 0 : 1; + if (!moveMob(e, e->wizard.xa * wSpeed, e->wizard.ya * wSpeed) || (rand()%100) == 0) { + e->wizard.randWalkTime = 30; + e->wizard.xa = ((rand()%3) - 1) * (rand()%2); + e->wizard.ya = ((rand()%3) - 1) * (rand()%2); + } + + if(e->wizard.xa != 0 || e->wizard.ya != 0){ + e->wizard.walkDist++; + awX = e->x; + awY = e->y; + } + + if(e->wizard.xa < 0) e->wizard.dir = 2; + else if(e->wizard.xa > 0) e->wizard.dir = 3; + if(e->wizard.ya < 0) e->wizard.dir = 1; + else if(e->wizard.ya > 0) e->wizard.dir = 0; + + if (e->wizard.randWalkTime > 0) { + e->wizard.randWalkTime--; + if (e->wizard.randWalkTime == 0 && nearestPlayer!=NULL) { + int xd = nearestPlayer->entity.x - e->x; + int yd = nearestPlayer->entity.y - e->y; + if (rand()%4 == 0 && xd * xd + yd * yd < 50 * 50) { + if (e->wizard.attackDelay == 0 && e->wizard.attackTime == 0) e->wizard.attackDelay = 120; + } + } + } + + return; + case ENTITY_SPARK: + e->spark.age++; + if (e->spark.age >= 260) { + removeEntityFromList(e, e->level, &eManager); + return; + } + e->spark.xx += e->spark.xa; + e->spark.yy += e->spark.ya; + e->x = (int) e->spark.xx; + e->y = (int) e->spark.yy; + + if(nearestPlayer!=NULL && intersects(nearestPlayer->entity, e->x + e->spark.xa - e->xr, e->y + e->spark.ya - e->yr, e->x + e->spark.xa + e->xr, e->y + e->spark.ya + e->yr)){ + EntityVsEntity(e, &(nearestPlayer->entity)); + removeEntityFromList(e, e->level, &eManager); + } + return; case ENTITY_DRAGON: if (e->hurtTime > 0) e->hurtTime--; - + e->dragon.animTimer++; if(e->dragon.animTimer>=4*4) { e->dragon.animTimer = 0; } - + //choose random attack if (e->dragon.attackDelay > 0) { - e->dragon.attackDelay--; - if (e->dragon.attackDelay <= 0) { + e->dragon.attackDelay--; + if (e->dragon.attackDelay <= 0) { e->dragon.attackType = rand()%2; - e->dragon.attackTime = 121; + e->dragon.attackTime = 121; } return; } - + if (e->dragon.attackTime > 0) { - e->dragon.attackTime--; - + e->dragon.attackTime--; + //turn to player when attacking - if(nearestPlayer!=NULL) { - int xd = nearestPlayer->entity.x - e->x; - int yd = nearestPlayer->entity.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; - } - } - + if(nearestPlayer!=NULL) { + int xd = nearestPlayer->entity.x - e->x; + int yd = nearestPlayer->entity.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; @@ -1152,124 +1152,124 @@ void tickEntity(Entity* e){ 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 && nearestPlayer!=NULL) { - int xd = nearestPlayer->entity.x - e->x; - int yd = nearestPlayer->entity.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 = (syncTickCount % 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) { - if(nearestPlayer!=NULL) { - int xd = nearestPlayer->entity.x - e->x; - int yd = nearestPlayer->entity.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; - } - } - // } - //} - + int xd = nearestPlayer->entity.x - e->x; + int yd = nearestPlayer->entity.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 = (syncTickCount % 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) { + if(nearestPlayer!=NULL) { + int xd = nearestPlayer->entity.x - e->x; + int yd = nearestPlayer->entity.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(nearestPlayer!=NULL && intersects(nearestPlayer->entity, 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, &(nearestPlayer->entity)); - 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)) { + 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(nearestPlayer!=NULL && intersects(nearestPlayer->entity, 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, &(nearestPlayer->entity)); + 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->level, e->x+4, e->y+4, 1); - removeEntityFromList(e, e->level, &eManager); - return; - } - return; - case ENTITY_PASSIVE: - if (e->hurtTime > 0) e->hurtTime--; - if (e->passive.randWalkTime == 0 && nearestPlayer!=NULL) { - int xd = nearestPlayer->entity.x - e->x; - int yd = nearestPlayer->entity.y - e->y; + removeEntityFromList(e, e->level, &eManager); + return; + } + return; + case ENTITY_PASSIVE: + if (e->hurtTime > 0) e->hurtTime--; + if (e->passive.randWalkTime == 0 && nearestPlayer!=NULL) { + int xd = nearestPlayer->entity.x - e->x; + int yd = nearestPlayer->entity.y - e->y; //flee from player - if (xd * xd + yd * yd < 40 * 40) { - e->passive.xa = 0; - e->passive.ya = 0; - if (xd < 0) e->passive.xa = +1; - if (xd > 0) e->passive.xa = -1; - if (yd < 0) e->passive.ya = +1; - if (yd > 0) e->passive.ya = -1; - } - } - - if(e->passive.xa < 0) e->passive.dir = 2; - else if(e->passive.xa > 0) e->passive.dir = 3; - if(e->passive.ya < 0) e->passive.dir = 1; - else if(e->passive.ya > 0) e->passive.dir = 0; - - if(e->passive.xa != 0 || e->passive.ya != 0) e->passive.walkDist++; + if (xd * xd + yd * yd < 40 * 40) { + e->passive.xa = 0; + e->passive.ya = 0; + if (xd < 0) e->passive.xa = +1; + if (xd > 0) e->passive.xa = -1; + if (yd < 0) e->passive.ya = +1; + if (yd > 0) e->passive.ya = -1; + } + } - int pspeed = syncTickCount & 1; - if (!moveMob(e, e->passive.xa * pspeed, e->passive.ya * pspeed) || (rand()%100) == 0) { - e->passive.randWalkTime = 60; - e->passive.xa = ((rand()%3) - 1) * (rand()%2); - e->passive.ya = ((rand()%3) - 1) * (rand()%2); - } - if (e->passive.randWalkTime > 0) e->passive.randWalkTime--; - return; + if(e->passive.xa < 0) e->passive.dir = 2; + else if(e->passive.xa > 0) e->passive.dir = 3; + if(e->passive.ya < 0) e->passive.dir = 1; + else if(e->passive.ya > 0) e->passive.dir = 0; + + if(e->passive.xa != 0 || e->passive.ya != 0) e->passive.walkDist++; + + int pspeed = syncTickCount & 1; + if (!moveMob(e, e->passive.xa * pspeed, e->passive.ya * pspeed) || (rand()%100) == 0) { + e->passive.randWalkTime = 60; + e->passive.xa = ((rand()%3) - 1) * (rand()%2); + e->passive.ya = ((rand()%3) - 1) * (rand()%2); + } + if (e->passive.randWalkTime > 0) e->passive.randWalkTime--; + return; case ENTITY_GLOWWORM: if(worldData.daytime>5000 && worldData.daytime<6000) { if(rand()%200==0) { @@ -1280,9 +1280,9 @@ void tickEntity(Entity* e){ removeEntityFromList(e, e->level, &eManager); return; } - - int gspeed = (((syncTickCount & 0x3) == 3) ? 1 : 0); - if (!moveMob(e, e->glowworm.xa * gspeed, e->glowworm.ya * gspeed) || (e->glowworm.randWalkTime==0) || (rand()%20) == 0) { + + int gspeed = (((syncTickCount & 0x3) == 3) ? 1 : 0); + if (!moveMob(e, e->glowworm.xa * gspeed, e->glowworm.ya * gspeed) || (e->glowworm.randWalkTime==0) || (rand()%20) == 0) { if(e->glowworm.randWalkTime != 0) { e->glowworm.waitTime = 20 + (rand()%60); } @@ -1294,8 +1294,8 @@ void tickEntity(Entity* e){ e->glowworm.xa = 0; e->glowworm.ya = 0; } - } - if (e->glowworm.randWalkTime > 0) { + } + if (e->glowworm.randWalkTime > 0) { e->glowworm.randWalkTime--; if(e->glowworm.randWalkTime==0 && (e->glowworm.xa != 0 || e->glowworm.xa != 0)) { e->glowworm.waitTime = 120 + (rand()%60); @@ -1304,20 +1304,20 @@ void tickEntity(Entity* e){ e->glowworm.waitTime--; } return; - case ENTITY_TEXTPARTICLE: tickEntityTextParticle(e); return; - case ENTITY_SMASHPARTICLE: - ++e->smashParticle.age; - if(e->smashParticle.age > 10) removeEntityFromList(e, e->level, &eManager); - return; - } + case ENTITY_TEXTPARTICLE: tickEntityTextParticle(e); return; + case ENTITY_SMASHPARTICLE: + ++e->smashParticle.age; + if(e->smashParticle.age > 10) removeEntityFromList(e, e->level, &eManager); + return; + } } void trySpawn(int count, int level) { - int i, j; + int i, j; for (i = 0; i < count; i++) { - if(eManager.lastSlot[level] > 900) continue; + if(eManager.lastSlot[level] > 900) continue; Entity e; - + int minLevel = 1; int maxLevel = 1; if (level > 0) maxLevel = level; @@ -1327,28 +1327,28 @@ void trySpawn(int count, int level) { if(level > 4) { minLevel = maxLevel = 4; } - - int rx = rand()%128; - int ry = rand()%128; - int ex = (rx<<4)+8; - int ey = (ry<<4)+8; - - //do not spawn near players - for(j = 0; j players[j].entity.x-160 && ey > players[j].entity.y-125 && ex < players[j].entity.x+160 && ey < players[j].entity.y+125)) continue; - } - - //spawn if tile is free + + int rx = rand()%128; + int ry = rand()%128; + int ex = (rx<<4)+8; + int ey = (ry<<4)+8; + + //do not spawn near players + for(j = 0; j players[j].entity.x-160 && ey > players[j].entity.y-125 && ex < players[j].entity.x+160 && ey < players[j].entity.y+125)) continue; + } + + //spawn if tile is free if (!tileIsSolid(worldData.map[level][rx+ry*128],&e)) { if(level==1 && (rand()%2)==0) { //passive entities on overworld e = newPassiveEntity(rand()%3, ex, ey, level); } else { int lvl = (rand()%(maxLevel - minLevel + 1)) + minLevel; int randMax = 1; - + if(level>1 || level==0) randMax = 2; if(level>3) randMax = 3; - + switch (rand()%(randMax+1)) { case 0: e = newSlimeEntity(lvl, ex, ey, level); @@ -1370,233 +1370,233 @@ void trySpawn(int count, int level) { } int getTile(s8 level, int x, int y){ - if(x < 0 || y < 0 || x > 128 || y > 128) return -1; - return worldData.map[level][x+y*128]; + if(x < 0 || y < 0 || x > 128 || y > 128) return -1; + return worldData.map[level][x+y*128]; } void setTile(int id, s8 level, int x, int y){ - if(x < 0 || y < 0 || x > 128 || y > 128) return; - worldData.map[level][x+y*128] = id; + if(x < 0 || y < 0 || x > 128 || y > 128) return; + worldData.map[level][x+y*128] = id; worldData.data[level][x+y*128] = 0; //reset data(set again if needed, hopefully this breaks nothing) - - sf2d_set_pixel(minimap[level], x, y, getMinimapColor(getLocalPlayer(), level, x, y)); + + sf2d_set_pixel(minimap[level], x, y, getMinimapColor(getLocalPlayer(), level, x, y)); } int getData(s8 level, int x, int y){ - if(x < 0 || y < 0 || x > 128 || y > 128) return -1; - return worldData.data[level][x+y*128]; + if(x < 0 || y < 0 || x > 128 || y > 128) return -1; + return worldData.data[level][x+y*128]; } void setData(int id, s8 level, int x, int y){ - if(x < 0 || y < 0 || x > 128 || y > 128) return; - worldData.data[level][x+y*128] = id; + if(x < 0 || y < 0 || x > 128 || y > 128) return; + worldData.data[level][x+y*128] = id; } void addSmashParticles(s8 level, int x, int y, int damage) { - char hurtText[11]; - sprintf(hurtText, "%d", damage); - addEntityToList(newTextParticleEntity(hurtText, 0xFF0000FF, x, y, level), &eManager); - addEntityToList(newSmashParticleEntity(x, y, level), &eManager); + char hurtText[11]; + sprintf(hurtText, "%d", damage); + addEntityToList(newTextParticleEntity(hurtText, 0xFF0000FF, x, y, level), &eManager); + addEntityToList(newSmashParticleEntity(x, y, level), &eManager); } void damageAndBreakTile(s8 level, int xt, int yt, int damage, int maxDamage, int replaceTile, int numItems, ...) { - int i; - - //damage indicator - addSmashParticles(level, xt<<4, yt<<4, damage); - - //do damage - setData(getData(level, xt, yt)+damage, level, xt, yt); + int i; - //tile has been destroyed - if(getData(level, xt, yt)>maxDamage) { - setTile(replaceTile, level, xt, yt); - - //drop items - va_list al; - numItems<<=1; //each item is the item+count, moved up here to get rid of warning - va_start(al, numItems); - numItems>>=1; - for(i=0; imaxDamage) { + setTile(replaceTile, level, xt, yt); + + //drop items + va_list al; + numItems<<=1; //each item is the item+count, moved up here to get rid of warning + va_start(al, numItems); + numItems>>=1; + for(i=0; iactiveItem->id != TOOL_PICKAXE || pd->activeItem->countLevel < 4) && !shouldRenderDebug) damage = 0; - damageAndBreakTile(level, xt, yt, damage, 200, TILE_DIRT, 2, newItem(ITEM_STONE,1), rand()%4+1, newItem(ITEM_COAL,1), rand()%2); - break; - case TILE_IRONORE: - case TILE_GOLDORE: - case TILE_GEMORE: - if(pd->activeItem->id != TOOL_PICKAXE) damage = 0; - addSmashParticles(level, xt<<4, yt<<4, damage); - setData(getData(level, xt, yt)+damage, level, xt, yt); - if(getData(level, xt, yt) > 0){ - int count = rand() & 1; - if (getData(level, xt, yt) >= (rand()%10) + 3) { + + //TODO: Most of this can be combined a lot + switch(tile){ + case TILE_TREE: + if(rand()%120==0)addEntityToList(newItemEntity(newItem(ITEM_APPLE,1), (xt<<4)+8,(yt<<4)+8, level), &eManager); + damageAndBreakTile(level, xt, yt, damage, 20, TILE_GRASS, 2, newItem(ITEM_WOOD,1), rand()%2+1, newItem(ITEM_ACORN,1), rand()%2); + break; + case TILE_CACTUS: + damageAndBreakTile(level, xt, yt, damage, 10, TILE_SAND, 1, newItem(ITEM_CACTUS,1), rand()%2+1); + break; + case TILE_ROCK: + damageAndBreakTile(level, xt, yt, damage, 50, TILE_DIRT, 2, newItem(ITEM_STONE,1), rand()%4+1, newItem(ITEM_COAL,1), rand()%2); + break; + case TILE_HARDROCK: + if((pd->activeItem->id != TOOL_PICKAXE || pd->activeItem->countLevel < 4) && !shouldRenderDebug) damage = 0; + damageAndBreakTile(level, xt, yt, damage, 200, TILE_DIRT, 2, newItem(ITEM_STONE,1), rand()%4+1, newItem(ITEM_COAL,1), rand()%2); + break; + case TILE_IRONORE: + case TILE_GOLDORE: + case TILE_GEMORE: + if(pd->activeItem->id != TOOL_PICKAXE) damage = 0; + addSmashParticles(level, xt<<4, yt<<4, damage); + setData(getData(level, xt, yt)+damage, level, xt, yt); + if(getData(level, xt, yt) > 0){ + int count = rand() & 1; + if (getData(level, xt, yt) >= (rand()%10) + 3) { if(level!=5) setTile(TILE_DIRT, level, xt, yt); else setTile(TILE_DUNGEON_FLOOR, level, xt, yt); - count += 2; - } - if(tile==TILE_IRONORE) addItemsToWorld(newItem(ITEM_IRONORE,1), level, (xt<<4)+8, (yt<<4)+8, count); - if(tile==TILE_GOLDORE) addItemsToWorld(newItem(ITEM_GOLDORE,1), level, (xt<<4)+8, (yt<<4)+8, count); - if(tile==TILE_GEMORE) addItemsToWorld(newItem(ITEM_GEM,1), level, (xt<<4)+8, (yt<<4)+8, count); - } break; - case TILE_CLOUDCACTUS: - if(pd->activeItem->id != TOOL_PICKAXE) damage = 0; - addSmashParticles(level, xt<<4, yt<<4, damage); - setData(getData(level, xt, yt)+damage, level, xt, yt); - if(getData(level, xt, yt) > 0){ - int count = rand() % 3; - if (getData(level, xt, yt) >= (rand()%10) + 3) { - setTile(TILE_CLOUD, level, xt, yt); - count += 3; - } - addItemsToWorld(newItem(ITEM_CLOUD,1), level, (xt<<4)+8, (yt<<4)+8, count); - } break; - case TILE_FARM: + count += 2; + } + if(tile==TILE_IRONORE) addItemsToWorld(newItem(ITEM_IRONORE,1), level, (xt<<4)+8, (yt<<4)+8, count); + if(tile==TILE_GOLDORE) addItemsToWorld(newItem(ITEM_GOLDORE,1), level, (xt<<4)+8, (yt<<4)+8, count); + if(tile==TILE_GEMORE) addItemsToWorld(newItem(ITEM_GEM,1), level, (xt<<4)+8, (yt<<4)+8, count); + } break; + case TILE_CLOUDCACTUS: + if(pd->activeItem->id != TOOL_PICKAXE) damage = 0; + addSmashParticles(level, xt<<4, yt<<4, damage); + setData(getData(level, xt, yt)+damage, level, xt, yt); + if(getData(level, xt, yt) > 0){ + int count = rand() % 3; + if (getData(level, xt, yt) >= (rand()%10) + 3) { + setTile(TILE_CLOUD, level, xt, yt); + count += 3; + } + addItemsToWorld(newItem(ITEM_CLOUD,1), level, (xt<<4)+8, (yt<<4)+8, count); + } break; + case TILE_FARM: setTile(TILE_DIRT, level, xt, yt); - break; - case TILE_SAPLING_TREE: + break; + case TILE_SAPLING_TREE: setTile(TILE_GRASS, level, xt, yt); - break; - case TILE_SAPLING_CACTUS: + break; + case TILE_SAPLING_CACTUS: setTile(TILE_SAND, level, xt, yt); - break; - case TILE_WHEAT: - if(getData(level, xt, yt) > -1){ - int age = getData(level, xt, yt); - int count = (rand() % 2); - if(age >= 80) count = (rand()%2) + 1; - addItemsToWorld(newItem(ITEM_SEEDS,1), level, (xt<<4)+8, (yt<<4)+8, count); - count = 0; - if(age == 100) count = (rand()%3) + 2; - else if(age >= 80) count = (rand()%2) + 1; - addItemsToWorld(newItem(ITEM_WHEAT,1), level, (xt<<4)+8, (yt<<4)+8, count); + break; + case TILE_WHEAT: + if(getData(level, xt, yt) > -1){ + int age = getData(level, xt, yt); + int count = (rand() % 2); + if(age >= 80) count = (rand()%2) + 1; + addItemsToWorld(newItem(ITEM_SEEDS,1), level, (xt<<4)+8, (yt<<4)+8, count); + count = 0; + if(age == 100) count = (rand()%3) + 2; + else if(age >= 80) count = (rand()%2) + 1; + addItemsToWorld(newItem(ITEM_WHEAT,1), level, (xt<<4)+8, (yt<<4)+8, count); setTile(TILE_DIRT, level, xt, yt); - } break; - case TILE_FLOWER: + } break; + case TILE_FLOWER: setTile(TILE_GRASS, level, xt,yt); - addItemsToWorld(newItem(ITEM_FLOWER,1), level, (xt<<4)+8, (yt<<4)+8, 1); - break; + addItemsToWorld(newItem(ITEM_FLOWER,1), level, (xt<<4)+8, (yt<<4)+8, 1); + break; case TILE_WOOD_WALL: - damageAndBreakTile(level, xt, yt, damage, 20, TILE_DIRT, 1, newItem(ITEM_WALL_WOOD,1), 1); + damageAndBreakTile(level, xt, yt, damage, 20, TILE_DIRT, 1, newItem(ITEM_WALL_WOOD,1), 1); break; case TILE_STONE_WALL: - damageAndBreakTile(level, xt, yt, damage, 30, TILE_DIRT, 1, newItem(ITEM_WALL_STONE,1), 1); + damageAndBreakTile(level, xt, yt, damage, 30, TILE_DIRT, 1, newItem(ITEM_WALL_STONE,1), 1); break; case TILE_IRON_WALL: - damageAndBreakTile(level, xt, yt, damage, 40, TILE_DIRT, 1, newItem(ITEM_WALL_IRON,1), 1); + damageAndBreakTile(level, xt, yt, damage, 40, TILE_DIRT, 1, newItem(ITEM_WALL_IRON,1), 1); break; case TILE_GOLD_WALL: - damageAndBreakTile(level, xt, yt, damage, 50, TILE_DIRT, 1, newItem(ITEM_WALL_GOLD,1), 1); + damageAndBreakTile(level, xt, yt, damage, 50, TILE_DIRT, 1, newItem(ITEM_WALL_GOLD,1), 1); break; case TILE_GEM_WALL: - damageAndBreakTile(level, xt, yt, damage, 60, TILE_DIRT, 1, newItem(ITEM_WALL_GEM,1), 1); + damageAndBreakTile(level, xt, yt, damage, 60, TILE_DIRT, 1, newItem(ITEM_WALL_GEM,1), 1); break; - case TILE_BOOKSHELVES: - addSmashParticles(level, xt<<4, yt<<4, damage); - if(level!=5) setTile(TILE_DIRT, level, xt, yt); - else setTile(TILE_DUNGEON_FLOOR, level, xt, yt); - addItemsToWorld(newItem(ITEM_BOOKSHELVES,1), level, (xt<<4)+8, (yt<<4)+8, 1); + case TILE_BOOKSHELVES: + addSmashParticles(level, xt<<4, yt<<4, damage); + if(level!=5) setTile(TILE_DIRT, level, xt, yt); + else setTile(TILE_DUNGEON_FLOOR, level, xt, yt); + addItemsToWorld(newItem(ITEM_BOOKSHELVES,1), level, (xt<<4)+8, (yt<<4)+8, 1); break; - } - + } + } void switchLevel(PlayerData *pd, s8 change){ - pd->entity.level+=change; - if(pd->entity.level > 4) pd->entity.level = 0; else if(pd->entity.level < 0) pd->entity.level = 4; - - if(pd==getLocalPlayer()) { - if(pd->entity.level == 1) sf2d_set_clear_color(0xFF6C6D82); - else if(pd->entity.level > 1) sf2d_set_clear_color(0xFF666666); - else sf2d_set_clear_color(0xFF007F00); + pd->entity.level+=change; + if(pd->entity.level > 4) pd->entity.level = 0; else if(pd->entity.level < 0) pd->entity.level = 4; + + if(pd==getLocalPlayer()) { + if(pd->entity.level == 1) sf2d_set_clear_color(0xFF6C6D82); + else if(pd->entity.level > 1) sf2d_set_clear_color(0xFF666666); + else sf2d_set_clear_color(0xFF007F00); } - + //for level 0 background updateLevel1Map(); } void playerEntityInteract(PlayerData *pd, Entity* e){ - switch(e->type){ - case ENTITY_ITEM: - if(e->entityItem.age > 30){ - addItemToInventory(e->entityItem.item, &(pd->inventory)); - removeEntityFromList(e, e->level, &eManager); - playSoundPositioned(snd_pickup, pd->entity.level, pd->entity.x, pd->entity.y); - pd->score++; - } - break; - case ENTITY_FURNITURE: - switch(pd->entity.p.dir){ - case 0: if(pd->entity.y < e->y) move(e, 0, 2); break; - case 1: if(pd->entity.y > e->y) move(e, 0, -2); break; - case 2: if(pd->entity.x > e->x) move(e, -2, 0); break; - case 3: if(pd->entity.x < e->x) move(e, 2, 0); break; - } - break; - } + switch(e->type){ + case ENTITY_ITEM: + if(e->entityItem.age > 30){ + addItemToInventory(e->entityItem.item, &(pd->inventory)); + removeEntityFromList(e, e->level, &eManager); + playSoundPositioned(snd_pickup, pd->entity.level, pd->entity.x, pd->entity.y); + pd->score++; + } + break; + case ENTITY_FURNITURE: + switch(pd->entity.p.dir){ + case 0: if(pd->entity.y < e->y) move(e, 0, 2); break; + case 1: if(pd->entity.y > e->y) move(e, 0, -2); break; + case 2: if(pd->entity.x > e->x) move(e, -2, 0); break; + case 3: if(pd->entity.x < e->x) move(e, 2, 0); break; + } + break; + } } void entityTileInteract(Entity*e, int tile, s8 level, int x, int y){ - switch(tile){ - case TILE_STAIRS_DOWN: - if(e->type == ENTITY_PLAYER){ - switchLevel(e->p.data, 1); - e->x = (x << 4) + 8; - e->y = (y << 4) + 8; - } + switch(tile){ + case TILE_STAIRS_DOWN: + if(e->type == ENTITY_PLAYER){ + switchLevel(e->p.data, 1); + e->x = (x << 4) + 8; + e->y = (y << 4) + 8; + } return; - case TILE_STAIRS_UP: - if(e->type == ENTITY_PLAYER){ - switchLevel(e->p.data, -1); - e->x = (x << 4) + 8; - e->y = (y << 4) + 8; - } + case TILE_STAIRS_UP: + if(e->type == ENTITY_PLAYER){ + switchLevel(e->p.data, -1); + e->x = (x << 4) + 8; + e->y = (y << 4) + 8; + } return; - case TILE_CACTUS: if(e->type == ENTITY_PLAYER) hurtEntity(e ,1, -1, 0xFFAF00FF, NULL); return; - case TILE_LAVA: if(e->type == ENTITY_PLAYER) hurtEntity(e, 1, -1, 0xFFAF00FF, NULL); return; - case TILE_WHEAT: - if(e->type == ENTITY_PLAYER || e->type == ENTITY_ZOMBIE){ - if(getData(level, x, y) > -1 && rand()%20 == 0){ - int age = getData(level, x, y); - int count = (rand() % 2); - if(age >= 80) count = (rand()%2) + 1; - addItemsToWorld(newItem(ITEM_SEEDS,1), level, (x<<4)+8, (y<<4)+8, count); - count = 0; - if(age == 100) count = (rand()%3) + 2; - else if(age >= 80) count = (rand()%2) + 1; - addItemsToWorld(newItem(ITEM_WHEAT,1), level, (x<<4)+8, (y<<4)+8, count); - setTile(TILE_DIRT, level, x, y); - } - } + case TILE_CACTUS: if(e->type == ENTITY_PLAYER) hurtEntity(e ,1, -1, 0xFFAF00FF, NULL); return; + case TILE_LAVA: if(e->type == ENTITY_PLAYER) hurtEntity(e, 1, -1, 0xFFAF00FF, NULL); return; + case TILE_WHEAT: + if(e->type == ENTITY_PLAYER || e->type == ENTITY_ZOMBIE){ + if(getData(level, x, y) > -1 && rand()%20 == 0){ + int age = getData(level, x, y); + int count = (rand() % 2); + if(age >= 80) count = (rand()%2) + 1; + addItemsToWorld(newItem(ITEM_SEEDS,1), level, (x<<4)+8, (y<<4)+8, count); + count = 0; + if(age == 100) count = (rand()%3) + 2; + else if(age >= 80) count = (rand()%2) + 1; + addItemsToWorld(newItem(ITEM_WHEAT,1), level, (x<<4)+8, (y<<4)+8, count); + setTile(TILE_DIRT, level, x, y); + } + } + return; + case TILE_FARM: + if(e->type == ENTITY_PLAYER || e->type == ENTITY_ZOMBIE){ + if(rand()%20 == 0) setTile(TILE_DIRT, level, x, y); + } return; - case TILE_FARM: - if(e->type == ENTITY_PLAYER || e->type == ENTITY_ZOMBIE){ - if(rand()%20 == 0) setTile(TILE_DIRT, level, x, y); - } - return; case TILE_SAND: if(e->type != ENTITY_ARROW && e->type != ENTITY_ITEM) { setData(10, level, x, y); @@ -1607,102 +1607,102 @@ void entityTileInteract(Entity*e, int tile, s8 level, int x, int y){ e->p.data->ingameMenu = MENU_DUNGEON; } return; - } + } } bool intersectsEntity(int x, int y, int r, Entity* e){ - return (x < e->x + e->xr && x + r > e->x && y < e->y + e->yr && y + r > e->y); + return (x < e->x + e->xr && x + r > e->x && y < e->y + e->yr && y + r > e->y); } void openCraftingMenu(PlayerData *pd, RecipeManager *rm, char *title) { - pd->currentCraftTitle = title; - pd->ingameMenu = MENU_CRAFTING; - - cloneRecipeManager(rm, &(pd->currentRecipes)); - checkCanCraftRecipes(&(pd->currentRecipes), &(pd->inventory)); - sortRecipes(&(pd->currentRecipes)); + pd->currentCraftTitle = title; + pd->ingameMenu = MENU_CRAFTING; + + cloneRecipeManager(rm, &(pd->currentRecipes)); + checkCanCraftRecipes(&(pd->currentRecipes), &(pd->inventory)); + sortRecipes(&(pd->currentRecipes)); } bool useEntity(PlayerData *pd, Entity* e) { - if(e->type == ENTITY_FURNITURE){ - switch(e->entityFurniture.itemID){ - case ITEM_WORKBENCH: - openCraftingMenu(pd, &workbenchRecipes, "Crafting"); - return true; - case ITEM_FURNACE: - openCraftingMenu(pd, &furnaceRecipes, "Smelting"); - return true; - case ITEM_OVEN: - openCraftingMenu(pd, &ovenRecipes, "Cooking"); - return true; - case ITEM_ANVIL: - openCraftingMenu(pd, &anvilRecipes, "Smithing"); - return true; - case ITEM_LOOM: - openCraftingMenu(pd, &loomRecipes, "Crafting"); - return true; + if(e->type == ENTITY_FURNITURE){ + switch(e->entityFurniture.itemID){ + case ITEM_WORKBENCH: + openCraftingMenu(pd, &workbenchRecipes, "Crafting"); + return true; + case ITEM_FURNACE: + openCraftingMenu(pd, &furnaceRecipes, "Smelting"); + return true; + case ITEM_OVEN: + openCraftingMenu(pd, &ovenRecipes, "Cooking"); + return true; + case ITEM_ANVIL: + openCraftingMenu(pd, &anvilRecipes, "Smithing"); + return true; + case ITEM_LOOM: + openCraftingMenu(pd, &loomRecipes, "Crafting"); + return true; case ITEM_ENCHANTER: - openCraftingMenu(pd, &enchanterRecipes, "Enchanting"); - return true; + openCraftingMenu(pd, &enchanterRecipes, "Enchanting"); + return true; case ITEM_POTION_MAKER: - openCraftingMenu(pd, &potionMakerRecipes, "Brewing"); - return true; - case ITEM_CHEST: - pd->curChestEntity = e; - pd->ingameMenuInvSel = 0; - pd->ingameMenuInvSelOther = 0; - pd->curChestEntityR = 0; - pd->ingameMenu = MENU_CONTAINER; - return true; - } - } else if(e->type == ENTITY_NPC) { - openNPCMenu(pd, e->npc.type); - return true; - } - return false; + openCraftingMenu(pd, &potionMakerRecipes, "Brewing"); + return true; + case ITEM_CHEST: + pd->curChestEntity = e; + pd->ingameMenuInvSel = 0; + pd->ingameMenuInvSelOther = 0; + pd->curChestEntityR = 0; + pd->ingameMenu = MENU_CONTAINER; + return true; + } + } else if(e->type == ENTITY_NPC) { + openNPCMenu(pd, e->npc.type); + return true; + } + return false; } bool isWater(s8 level, int xt, int yt){ - return getTile(level, xt, yt)==TILE_WATER; + return getTile(level, xt, yt)==TILE_WATER; } bool dungeonActive() { - //check if dungeon already exists (ie someone is in there) - int i; - for(i = 0; i < playerCount; i++) { - if(players[i].entity.level==5) { - return true; - } - } - return false; + //check if dungeon already exists (ie someone is in there) + int i; + for(i = 0; i < playerCount; i++) { + if(players[i].entity.level==5) { + return true; + } + } + return false; } void enterDungeon(PlayerData *pd) { - //create new one if needed - if(!dungeonActive()) { - //reset Entities - (&eManager)->lastSlot[5] = 0; - (&eManager)->entities[5][0] = nullEntity; - - //create map - createAndValidateDungeonMap(128, 128, 5, worldData.map[5], worldData.data[5]); - - //reset minimap clear state - int xd,yd; - for(xd = 0; xd < 128; ++xd) { - for(yd = 0; yd < 128; ++yd) { - setMinimapVisible(pd, 5, xd, yd, false); - } - } - initMinimapLevel(pd, 5); - - //spawn new entities - trySpawn(500, 5); - } - - + //create new one if needed + if(!dungeonActive()) { + //reset Entities + (&eManager)->lastSlot[5] = 0; + (&eManager)->entities[5][0] = nullEntity; + + //create map + createAndValidateDungeonMap(128, 128, 5, worldData.map[5], worldData.data[5]); + + //reset minimap clear state + int xd,yd; + for(xd = 0; xd < 128; ++xd) { + for(yd = 0; yd < 128; ++yd) { + setMinimapVisible(pd, 5, xd, yd, false); + } + } + initMinimapLevel(pd, 5); + + //spawn new entities + trySpawn(500, 5); + } + + pd->entity.level = 5; - pd->entity.x = ((128/2) << 4) + 8; + pd->entity.x = ((128/2) << 4) + 8; pd->entity.y = ((128/2) << 4) + 8; } @@ -1710,13 +1710,13 @@ void leaveDungeon(PlayerData *pd) { pd->entity.level = 4; pd->entity.x = ((128/2) << 4) + 8; pd->entity.y = ((128/2) << 4) + 8; - - //clear dungeon if empty - if(!dungeonActive()) { - //reset Entities - (&eManager)->lastSlot[5] = 0; - (&eManager)->entities[5][0] = nullEntity; - } + + //clear dungeon if empty + if(!dungeonActive()) { + //reset Entities + (&eManager)->lastSlot[5] = 0; + (&eManager)->entities[5][0] = nullEntity; + } } void setMinimapVisible(PlayerData *pd, int level, int x, int y, bool visible) { @@ -1725,8 +1725,8 @@ void setMinimapVisible(PlayerData *pd, int level, int x, int y, bool visible) { } else { pd->minimapData[x + y * 128] = pd->minimapData[x + y * 128] & (0xFF - (1 << level)); } - - if(pd==getLocalPlayer()) sf2d_set_pixel(minimap[level], x, y, getMinimapColor(pd, level, x, y)); + + if(pd==getLocalPlayer()) sf2d_set_pixel(minimap[level], x, y, getMinimapColor(pd, level, x, y)); } bool getMinimapVisible(PlayerData *pd, int level, int x, int y) { @@ -1741,9 +1741,9 @@ u32 getMinimapColor(PlayerData *pd, int level, int x, int y) { void initMinimapLevel(PlayerData *pd, int level) { int x; int y; - - if(pd!=getLocalPlayer()) return; - + + if(pd!=getLocalPlayer()) return; + for (x = 0; x < 128; ++x) { for (y = 0; y < 128; ++y) { /* Minimaps */ @@ -1753,43 +1753,43 @@ void initMinimapLevel(PlayerData *pd, int level) { } void updateLevel1Map() { - initMinimapLevel(getLocalPlayer(), 1); + initMinimapLevel(getLocalPlayer(), 1); } void reloadColors() { - dirtColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 0)); - dirtColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 1)); - dirtColor[2] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 2)); - dirtColor[3] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 3)); - dirtColor[4] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 4)); - - 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)); + dirtColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 0)); + dirtColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 1)); + dirtColor[2] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 2)); + dirtColor[3] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 3)); + dirtColor[4] = SWAP_UINT32(sf2d_get_pixel(icons, 16, 4)); - sandColor = SWAP_UINT32(sf2d_get_pixel(icons, 18, 0)); - - waterColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 19, 0)); - waterColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 19, 1)); - - lavaColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 20, 0)); - lavaColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 20, 1)); - - rockColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 0)); - rockColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 1)); - rockColor[2] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 2)); - rockColor[3] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 3)); - - woodColor = SWAP_UINT32(sf2d_get_pixel(icons, 22, 0)); - - ironColor = SWAP_UINT32(sf2d_get_pixel(icons, 23, 0)); - goldColor = SWAP_UINT32(sf2d_get_pixel(icons, 23, 1)); - gemColor = SWAP_UINT32(sf2d_get_pixel(icons, 23, 2)); - - dungeonColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 0)); - dungeonColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 1)); - - snowColor = SWAP_UINT32(sf2d_get_pixel(icons, 25, 0)); - iceColor = SWAP_UINT32(sf2d_get_pixel(icons, 25, 1)); -} \ No newline at end of file + 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)); + + waterColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 19, 0)); + waterColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 19, 1)); + + lavaColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 20, 0)); + lavaColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 20, 1)); + + rockColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 0)); + rockColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 1)); + rockColor[2] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 2)); + rockColor[3] = SWAP_UINT32(sf2d_get_pixel(icons, 21, 3)); + + woodColor = SWAP_UINT32(sf2d_get_pixel(icons, 22, 0)); + + ironColor = SWAP_UINT32(sf2d_get_pixel(icons, 23, 0)); + goldColor = SWAP_UINT32(sf2d_get_pixel(icons, 23, 1)); + gemColor = SWAP_UINT32(sf2d_get_pixel(icons, 23, 2)); + + dungeonColor[0] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 0)); + dungeonColor[1] = SWAP_UINT32(sf2d_get_pixel(icons, 24, 1)); + + snowColor = SWAP_UINT32(sf2d_get_pixel(icons, 25, 0)); + iceColor = SWAP_UINT32(sf2d_get_pixel(icons, 25, 1)); +} diff --git a/source/Globals.h b/source/Globals.h index 3d9850d..e8a6170 100755 --- a/source/Globals.h +++ b/source/Globals.h @@ -7,7 +7,7 @@ #include "MapGen.h" #include "Quests.h" -#include "icons2_png.h" +#include "icons_png.h" #include "player_png.h" #include "Font_png.h" #include "bottombg_png.h" @@ -142,15 +142,15 @@ bool quitGame; s8 currentSelection; typedef struct _worldData { - u8 map[6][128*128]; - u8 data[6][128*128]; - - u16 daytime; - int day; - u8 season; - bool rain; - - u8 compassData[6][3]; + u8 map[6][128*128]; + u8 data[6][128*128]; + + u16 daytime; + int day; + u8 season; + bool rain; + + u8 compassData[6][3]; } WorldData; WorldData worldData; @@ -201,4 +201,4 @@ u32 getMinimapColor(PlayerData *pd, int level, int x, int y); void initMinimapLevel(PlayerData *pd, int level); void updateLevel1Map(); -void reloadColors(); \ No newline at end of file +void reloadColors(); diff --git a/source/Ingame.c b/source/Ingame.c index 825342b..74080b0 100644 --- a/source/Ingame.c +++ b/source/Ingame.c @@ -17,53 +17,53 @@ bool stallAreYouSure; //generates stairs up and creates compass data void generatePass2() { - int level, x, y; - - for (level = 0; level < 5; ++level) { - for (x = 0; x < 128; ++x) { - for (y = 0; y < 128; ++y) { + int level, x, y; - //generate stairs up matching stairs down - switch (worldData.map[level][x + y * 128]) { - case TILE_STAIRS_DOWN: - if(level < 4) { - worldData.map[level + 1][x + y * 128] = TILE_STAIRS_UP; - if (level == 0) { - worldData.map[level + 1][(x + 1) + y * 128] = TILE_HARDROCK; - worldData.map[level + 1][x + (y + 1) * 128] = TILE_HARDROCK; - worldData.map[level + 1][(x - 1) + y * 128] = TILE_HARDROCK; - worldData.map[level + 1][x + (y - 1) * 128] = TILE_HARDROCK; - worldData.map[level + 1][(x + 1) + (y + 1) * 128] = TILE_HARDROCK; - worldData.map[level + 1][(x - 1) + (y - 1) * 128] = TILE_HARDROCK; - worldData.map[level + 1][(x - 1) + (y + 1) * 128] = TILE_HARDROCK; - worldData.map[level + 1][(x + 1) + (y - 1) * 128] = TILE_HARDROCK; - } else { - worldData.map[level + 1][(x + 1) + y * 128] = TILE_DIRT; - worldData.map[level + 1][x + (y + 1) * 128] = TILE_DIRT; - worldData.map[level + 1][(x - 1) + y * 128] = TILE_DIRT; - worldData.map[level + 1][x + (y - 1) * 128] = TILE_DIRT; - worldData.map[level + 1][(x + 1) + (y + 1) * 128] = TILE_DIRT; - worldData.map[level + 1][(x - 1) + (y - 1) * 128] = TILE_DIRT; - worldData.map[level + 1][(x - 1) + (y + 1) * 128] = TILE_DIRT; - worldData.map[level + 1][(x + 1) + (y - 1) * 128] = TILE_DIRT; - } - } - } - - //calculate compass data - //choose one stair down and store for magic compass - switch (worldData.map[level][x + y * 128]) { - case TILE_STAIRS_DOWN: - case TILE_DUNGEON_ENTRANCE: - worldData.compassData[level][2] = worldData.compassData[level][2] + 1; - if((worldData.compassData[level][2]==1) || (rand()%(worldData.compassData[level][2])==0)) { - worldData.compassData[level][0] = x; - worldData.compassData[level][1] = y; - } - } - } - } - } + for (level = 0; level < 5; ++level) { + for (x = 0; x < 128; ++x) { + for (y = 0; y < 128; ++y) { + + //generate stairs up matching stairs down + switch (worldData.map[level][x + y * 128]) { + case TILE_STAIRS_DOWN: + if(level < 4) { + worldData.map[level + 1][x + y * 128] = TILE_STAIRS_UP; + if (level == 0) { + worldData.map[level + 1][(x + 1) + y * 128] = TILE_HARDROCK; + worldData.map[level + 1][x + (y + 1) * 128] = TILE_HARDROCK; + worldData.map[level + 1][(x - 1) + y * 128] = TILE_HARDROCK; + worldData.map[level + 1][x + (y - 1) * 128] = TILE_HARDROCK; + worldData.map[level + 1][(x + 1) + (y + 1) * 128] = TILE_HARDROCK; + worldData.map[level + 1][(x - 1) + (y - 1) * 128] = TILE_HARDROCK; + worldData.map[level + 1][(x - 1) + (y + 1) * 128] = TILE_HARDROCK; + worldData.map[level + 1][(x + 1) + (y - 1) * 128] = TILE_HARDROCK; + } else { + worldData.map[level + 1][(x + 1) + y * 128] = TILE_DIRT; + worldData.map[level + 1][x + (y + 1) * 128] = TILE_DIRT; + worldData.map[level + 1][(x - 1) + y * 128] = TILE_DIRT; + worldData.map[level + 1][x + (y - 1) * 128] = TILE_DIRT; + worldData.map[level + 1][(x + 1) + (y + 1) * 128] = TILE_DIRT; + worldData.map[level + 1][(x - 1) + (y - 1) * 128] = TILE_DIRT; + worldData.map[level + 1][(x - 1) + (y + 1) * 128] = TILE_DIRT; + worldData.map[level + 1][(x + 1) + (y - 1) * 128] = TILE_DIRT; + } + } + } + + //calculate compass data + //choose one stair down and store for magic compass + switch (worldData.map[level][x + y * 128]) { + case TILE_STAIRS_DOWN: + case TILE_DUNGEON_ENTRANCE: + worldData.compassData[level][2] = worldData.compassData[level][2] + 1; + if((worldData.compassData[level][2]==1) || (rand()%(worldData.compassData[level][2])==0)) { + worldData.compassData[level][0] = x; + worldData.compassData[level][1] = y; + } + } + } + } + } } void initNewMap() { @@ -72,7 +72,7 @@ void initNewMap() { createAndValidateUndergroundMap(128, 128, 1, 2, worldData.map[2], worldData.data[2]); createAndValidateUndergroundMap(128, 128, 2, 3, worldData.map[3], worldData.data[3]); createAndValidateUndergroundMap(128, 128, 3, 4, worldData.map[4], worldData.data[4]); - generatePass2(); + generatePass2(); } void initMiniMap(PlayerData *pd) { @@ -83,297 +83,297 @@ void initMiniMap(PlayerData *pd) { } void startGame(bool load, char *filename) { - // Reset entity manager. + // Reset entity manager. memset(&eManager, 0, sizeof(eManager)); - - // Reset players - for(int i=0; i 1) { shouldRenderDebug = false; } - - if (!load) { - initNewMap(); - airWizardHealthDisplay = 2000; - int i; - for (i = 0; i < 5; ++i) { - trySpawn(500, i); - } - addEntityToList(newAirWizardEntity(630, 820, 0), &eManager); - worldData.daytime = 6000; - worldData.day = 0; - worldData.season = 0; - worldData.rain = false; - } else { - if(!loadWorld(filename, &eManager, &worldData, players, playerCount)) { - //TODO: What do? - networkDisconnect(); - - sf2d_set_clear_color(0xFF); - currentSelection = 0; - currentMenu = MENU_TITLE; - } - } - - // Spawn players - for(int i=0; ientity.level, getLocalPlayer()->entity.x, getLocalPlayer()->entity.y); + int i; - //win/death menus - for(i=0; ientity.level, getLocalPlayer()->entity.x, getLocalPlayer()->entity.y); - //update worldData (daytime,season and weather) - ++worldData.daytime; - if(worldData.daytime>=24000) { - worldData.daytime -= 24000; - ++worldData.day; - //TODO: maybe make season length not as hardcoded + make the transition better (fade to black and back maybe?) - if(worldData.day%7==0) { - ++worldData.season; - if(worldData.season==4) worldData.season = 0; - } - worldData.rain = false; - if(worldData.season!=3 && rand()%5==0) worldData.rain = true; - } - - //update music - updateMusic(getLocalPlayer()->entity.level, worldData.daytime); - - //for every active level - s8 level; - for(level = 0; level < 6; level++) { - bool hasPlayer = false; - for(i=0; i=24000) { + worldData.daytime -= 24000; + ++worldData.day; + //TODO: maybe make season length not as hardcoded + make the transition better (fade to black and back maybe?) + if(worldData.day%7==0) { + ++worldData.season; + if(worldData.season==4) worldData.season = 0; + } + worldData.rain = false; + if(worldData.season!=3 && rand()%5==0) worldData.rain = true; + } - - //for every active level - for(level = 0; level < 6; level++) { - if(level==5 && !dungeonActive()) continue; - - bool hasPlayer = false; - for(i=0; ix, e->y); - - //should never happen, but just for safety to prevent hard crashes - if(p==NULL) continue; - - 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) - || (e->type == ENTITY_GLOWWORM && (worldData.daytime>6000 || worldData.daytime<18000)) - || (e->x > p->entity.x - 160 && e->y > p->entity.y - 125 && e->x < p->entity.x + 160 && e->y < p->entity.y + 125)) { - tickEntity(e); - } - } - } - - stallCounter = 0; + //update music + updateMusic(getLocalPlayer()->entity.level, worldData.daytime); + + //for every active level + s8 level; + for(level = 0; level < 6; level++) { + bool hasPlayer = false; + for(i=0; ix, e->y); + + //should never happen, but just for safety to prevent hard crashes + if(p==NULL) continue; + + 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) + || (e->type == ENTITY_GLOWWORM && (worldData.daytime>6000 || worldData.daytime<18000)) + || (e->x > p->entity.x - 160 && e->y > p->entity.y - 125 && e->x < p->entity.x + 160 && e->y < p->entity.y + 125)) { + tickEntity(e); + } + } + } + + stallCounter = 0; } void tickGame() { - synchronizerTick(&syncedTick); - - - if(synchronizerIsRunning()) { - stallCounter++; - //game stalled -> most likely a player disconnected -> present option to exit game - if(stallCounter>=STALL_TIME) { - if(stallCounter==STALL_TIME) stallAreYouSure = false; - - //scan local inputs, because synchronizer only updates them when not stalled - hidScanInput(); - tickKeys(&localInputs, hidKeysHeld(), hidKeysDown()); - - if (localInputs.k_accept.clicked) { - if(stallAreYouSure) { - //create backup save - if(playerLocalID==0) { - char backupSaveFileName[256+32]; - backupSaveFileName[0] = '\0'; - - strncat(backupSaveFileName, currentFileName, strlen(currentFileName)-4); - strcat(backupSaveFileName, ".exit.msv"); - - saveWorld(backupSaveFileName, &eManager, &worldData, players, playerCount); - } - - exitGame(); - } else { - stallAreYouSure = true; - } - } - if (localInputs.k_decline.clicked) { - stallAreYouSure = false; - } - } - } + synchronizerTick(&syncedTick); + + + if(synchronizerIsRunning()) { + stallCounter++; + //game stalled -> most likely a player disconnected -> present option to exit game + if(stallCounter>=STALL_TIME) { + if(stallCounter==STALL_TIME) stallAreYouSure = false; + + //scan local inputs, because synchronizer only updates them when not stalled + hidScanInput(); + tickKeys(&localInputs, hidKeysHeld(), hidKeysDown()); + + if (localInputs.k_accept.clicked) { + if(stallAreYouSure) { + //create backup save + if(playerLocalID==0) { + char backupSaveFileName[256+32]; + backupSaveFileName[0] = '\0'; + + strncat(backupSaveFileName, currentFileName, strlen(currentFileName)-4); + strcat(backupSaveFileName, ".exit.msv"); + + saveWorld(backupSaveFileName, &eManager, &worldData, players, playerCount); + } + + exitGame(); + } else { + stallAreYouSure = true; + } + } + if (localInputs.k_decline.clicked) { + stallAreYouSure = false; + } + } + } } //for rendering -> move to a better place int xscr = 0, yscr = 0; void renderGame() { - //Important: all code called from this function should never affect game state! - sf2d_start_frame(GFX_TOP, GFX_LEFT); + //Important: all code called from this function should never affect game state! + sf2d_start_frame(GFX_TOP, GFX_LEFT); - int xscr = getLocalPlayer()->entity.x - 100; - int yscr = getLocalPlayer()->entity.y - 56; - if (xscr < 16) - xscr = 16; - else if (xscr > 1832) - xscr = 1832; - if (yscr < 16) - yscr = 16; - else if (yscr > 1912) - yscr = 1912; - - - offsetX = xscr; - offsetY = yscr; - sf2d_draw_rectangle(0, 0, 400, 240, 0xFF0C0C0C); //RGBA8(12, 12, 12, 255)); //You might think "real" black would be better, but it actually looks better that way - - renderLightsToStencil(getLocalPlayer(), false, false, true); + int xscr = getLocalPlayer()->entity.x - 100; + int yscr = getLocalPlayer()->entity.y - 56; + if (xscr < 16) + xscr = 16; + else if (xscr > 1832) + xscr = 1832; + if (yscr < 16) + yscr = 16; + else if (yscr > 1912) + yscr = 1912; - renderBackground(getLocalPlayer()->entity.level, xscr, yscr); - renderEntities(getLocalPlayer()->entity.level, getLocalPlayer()->entity.x, getLocalPlayer()->entity.y, &eManager); - for(int i=0; ientity.level, xscr, yscr); - - resetStencilStuff(); - - renderDayNight(getLocalPlayer()); - - offsetX = 0; - offsetY = 0; - - if(shouldRenderDebug){ - sprintf(fpsstr, " FPS: %.0f, X:%d, Y:%d, E:%d", sf2d_get_fps(), getLocalPlayer()->entity.x, getLocalPlayer()->entity.y, eManager.lastSlot[getLocalPlayer()->entity.level]); - drawText(fpsstr, 2, 225); - } - - if(getLocalPlayer()->ingameMenu != MENU_NONE) { - ingameMenuRender(getLocalPlayer(), getLocalPlayer()->ingameMenu); - } - - //game stalled -> most likely a player disconnected -> present option to exit game - if(stallCounter>STALL_TIME) { - renderFrame(1,1,24,14,0xFF1010AF); - drawText("Waiting for a long time", (400 - (23 * 12))/2, 32); - - char text[50]; - sprintf(text, "Last response %is ago", stallCounter/60); - drawText(text, (400 - (strlen(text) * 12))/2, 64); - if(playerLocalID==0) { - drawText("Press to leave the game", (400 - (25 * 12))/2, 160); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 120, 157, 1); - - drawText("A backup save will be created", (400 - (29 * 12))/2, 192); - } else { - drawText("Press to leave the game", (400 - (25 * 12))/2, 192); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 120, 189, 1); - } - - if(stallAreYouSure){ - renderFrame(6,5,19,10,0xFF10108F); - - drawText("Are you sure?",122,96); - drawText(" Yes", 164, 117); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 166, 114, 1); - drawText(" No", 170, 133); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 166, 130, 1); - } - } - - sf2d_end_frame(); + offsetX = xscr; + offsetY = yscr; + sf2d_draw_rectangle(0, 0, 400, 240, 0xFF0C0C0C); //RGBA8(12, 12, 12, 255)); //You might think "real" black would be better, but it actually looks better that way - sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); - if(!players[playerLocalID].mapShouldRender){ - sf2d_draw_texture(bottombg, 0, 0); - renderGui(getLocalPlayer()); - } else { - renderZoomedMap(getLocalPlayer()); - } - sf2d_end_frame(); + renderLightsToStencil(getLocalPlayer(), false, false, true); + + renderBackground(getLocalPlayer()->entity.level, xscr, yscr); + renderEntities(getLocalPlayer()->entity.level, getLocalPlayer()->entity.x, getLocalPlayer()->entity.y, &eManager); + for(int i=0; ientity.level, xscr, yscr); + + resetStencilStuff(); + + renderDayNight(getLocalPlayer()); + + offsetX = 0; + offsetY = 0; + + if(shouldRenderDebug){ + sprintf(fpsstr, " FPS: %.0f, X:%d, Y:%d, E:%d", sf2d_get_fps(), getLocalPlayer()->entity.x, getLocalPlayer()->entity.y, eManager.lastSlot[getLocalPlayer()->entity.level]); + drawText(fpsstr, 2, 225); + } + + if(getLocalPlayer()->ingameMenu != MENU_NONE) { + ingameMenuRender(getLocalPlayer(), getLocalPlayer()->ingameMenu); + } + + //game stalled -> most likely a player disconnected -> present option to exit game + if(stallCounter>STALL_TIME) { + renderFrame(1,1,24,14,0xFF1010AF); + drawText("Waiting for a long time", (400 - (23 * 12))/2, 32); + + char text[50]; + sprintf(text, "Last response %is ago", stallCounter/60); + drawText(text, (400 - (strlen(text) * 12))/2, 64); + + if(playerLocalID==0) { + drawText("Press to leave the game", (400 - (25 * 12))/2, 160); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 120, 157, 1); + + drawText("A backup save will be created", (400 - (29 * 12))/2, 192); + } else { + drawText("Press to leave the game", (400 - (25 * 12))/2, 192); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 120, 189, 1); + } + + if(stallAreYouSure){ + renderFrame(6,5,19,10,0xFF10108F); + + drawText("Are you sure?",122,96); + drawText(" Yes", 164, 117); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 166, 114, 1); + drawText(" No", 170, 133); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 166, 130, 1); + } + } + + sf2d_end_frame(); + + sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); + if(!players[playerLocalID].mapShouldRender){ + sf2d_draw_texture(bottombg, 0, 0); + renderGui(getLocalPlayer()); + } else { + renderZoomedMap(getLocalPlayer()); + } + sf2d_end_frame(); } void exitGame() { - networkDisconnect(); - synchronizerReset(); - - sf2d_set_clear_color(0xFF); - currentSelection = 0; - currentMenu = MENU_TITLE; - - playMusic(&music_menu); + networkDisconnect(); + synchronizerReset(); + + sf2d_set_clear_color(0xFF); + currentSelection = 0; + currentMenu = MENU_TITLE; + + playMusic(&music_menu); } diff --git a/source/IngameMenu.c b/source/IngameMenu.c index cfe6b63..d134ee7 100644 --- a/source/IngameMenu.c +++ b/source/IngameMenu.c @@ -10,104 +10,104 @@ char pOptions[][24] = {"Return to game", "Save Progress", "Exit to title"}; void ingameMenuTick(PlayerData *pd, int menu) { - switch(menu) { - case MENU_PAUSED: - if(!pd->ingameMenuAreYouSure && !pd->ingameMenuAreYouSureSave){ - if (pd->ingameMenuTimer > 0) --pd->ingameMenuTimer; - if (pd->inputs.k_pause.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE; - if (pd->inputs.k_up.clicked) { --pd->ingameMenuSelection; if(pd->ingameMenuSelection < 0) pd->ingameMenuSelection=2; } - if (pd->inputs.k_down.clicked) { ++pd->ingameMenuSelection; if(pd->ingameMenuSelection > 2) pd->ingameMenuSelection=0; } - if (pd->inputs.k_accept.clicked){ - switch(pd->ingameMenuSelection){ - case 0: - pd->ingameMenu = MENU_NONE; - break; - case 1: - if(!dungeonActive()) pd->ingameMenuAreYouSureSave = true; - break; - case 2: - pd->ingameMenuAreYouSure = true; - break; - } - } - } else if(pd->ingameMenuAreYouSureSave) { - if (pd->inputs.k_accept.clicked){ - pd->ingameMenuTimer = 60; - - if(playerLocalID==0) { - saveWorld(currentFileName, &eManager, &worldData, players, playerCount); - } - pd->ingameMenuAreYouSureSave = false; - pd->ingameMenuAreYouSure = false; - } else if (pd->inputs.k_decline.clicked){ - pd->ingameMenuAreYouSureSave = false; - pd->ingameMenuAreYouSure = false; - } - } else if(pd->ingameMenuAreYouSure) { - if (pd->inputs.k_accept.clicked){ - pd->ingameMenuAreYouSure = false; - pd->ingameMenuAreYouSureSave = false; - - exitGame(); - } else if (pd->inputs.k_decline.clicked){ - pd->ingameMenuAreYouSure = false; - pd->ingameMenuAreYouSureSave = false; - } - } - break; - case MENU_INVENTORY: - if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked){ - pd->ingameMenu = MENU_NONE; - pd->activeItem = &noItem; - pd->entity.p.isCarrying = false; - } - if (pd->inputs.k_accept.clicked){ // Select item from inventory - if(pd->inventory.lastSlot!=0){ - Item median = pd->inventory.items[pd->ingameMenuInvSel]; // create copy of item. - removeItemFromInventory(pd->ingameMenuInvSel, &(pd->inventory)); // remove original - pushItemToInventoryFront(median, &(pd->inventory)); // add copy to front + switch(menu) { + case MENU_PAUSED: + if(!pd->ingameMenuAreYouSure && !pd->ingameMenuAreYouSureSave){ + if (pd->ingameMenuTimer > 0) --pd->ingameMenuTimer; + if (pd->inputs.k_pause.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE; + if (pd->inputs.k_up.clicked) { --pd->ingameMenuSelection; if(pd->ingameMenuSelection < 0) pd->ingameMenuSelection=2; } + if (pd->inputs.k_down.clicked) { ++pd->ingameMenuSelection; if(pd->ingameMenuSelection > 2) pd->ingameMenuSelection=0; } + if (pd->inputs.k_accept.clicked){ + switch(pd->ingameMenuSelection){ + case 0: + pd->ingameMenu = MENU_NONE; + break; + case 1: + if(!dungeonActive()) pd->ingameMenuAreYouSureSave = true; + break; + case 2: + pd->ingameMenuAreYouSure = true; + break; + } + } + } else if(pd->ingameMenuAreYouSureSave) { + if (pd->inputs.k_accept.clicked){ + pd->ingameMenuTimer = 60; + + if(playerLocalID==0) { + saveWorld(currentFileName, &eManager, &worldData, players, playerCount); + } + pd->ingameMenuAreYouSureSave = false; + pd->ingameMenuAreYouSure = false; + } else if (pd->inputs.k_decline.clicked){ + pd->ingameMenuAreYouSureSave = false; + pd->ingameMenuAreYouSure = false; + } + } else if(pd->ingameMenuAreYouSure) { + if (pd->inputs.k_accept.clicked){ + pd->ingameMenuAreYouSure = false; + pd->ingameMenuAreYouSureSave = false; + + exitGame(); + } else if (pd->inputs.k_decline.clicked){ + pd->ingameMenuAreYouSure = false; + pd->ingameMenuAreYouSureSave = false; + } + } + break; + case MENU_INVENTORY: + if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked){ + pd->ingameMenu = MENU_NONE; + pd->activeItem = &noItem; + pd->entity.p.isCarrying = false; + } + if (pd->inputs.k_accept.clicked){ // Select item from inventory + if(pd->inventory.lastSlot!=0){ + Item median = pd->inventory.items[pd->ingameMenuInvSel]; // create copy of item. + removeItemFromInventory(pd->ingameMenuInvSel, &(pd->inventory)); // remove original + pushItemToInventoryFront(median, &(pd->inventory)); // add copy to front playerSetActiveItem(pd, &(pd->inventory.items[0])); // active item = copy. - } - pd->ingameMenu = MENU_NONE; - } - if (pd->inputs.k_up.clicked) { --pd->ingameMenuInvSel; if(pd->ingameMenuInvSel < 0)pd->ingameMenuInvSel=pd->inventory.lastSlot-1; } - if (pd->inputs.k_down.clicked) { ++pd->ingameMenuInvSel; if(pd->ingameMenuInvSel > pd->inventory.lastSlot-1)pd->ingameMenuInvSel=0; } - break; - - case MENU_CRAFTING: - if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE; - if (pd->inputs.k_accept.clicked){ - if(craftItem(&(pd->currentRecipes), &(pd->currentRecipes.recipes[pd->ingameMenuInvSel]), &(pd->inventory))){ - playSoundPositioned(snd_craft, pd->entity.level, pd->entity.x, pd->entity.y); - //reset active item pointer, because it could posibly point to garbage now - pd->activeItem = &noItem; - } - } - if (pd->inputs.k_up.clicked) { --pd->ingameMenuInvSel; if(pd->ingameMenuInvSel < 0)pd->ingameMenuInvSel=pd->currentRecipes.size-1; } - if (pd->inputs.k_down.clicked) { ++pd->ingameMenuInvSel; if(pd->ingameMenuInvSel > pd->currentRecipes.size-1)pd->ingameMenuInvSel=0; } - break; - - case MENU_WIN: - if (pd->inputs.k_accept.clicked){ - pd->ingameMenu = MENU_NONE; - pd->entity.p.hasWon = false; - } - break; - case MENU_LOSE: - if (pd->inputs.k_accept.clicked){ - pd->ingameMenu = MENU_NONE; - pd->entity.p.isDead = false; - pd->entity.p.health = 10; - pd->entity.level = 1; - playerSpawn(pd); - //TODO: This canceled to main menu, but what should I do in multiplayer? - } - pd->entity.hurtTime = 10; - break; - - case MENU_CONTAINER: + } + pd->ingameMenu = MENU_NONE; + } + if (pd->inputs.k_up.clicked) { --pd->ingameMenuInvSel; if(pd->ingameMenuInvSel < 0)pd->ingameMenuInvSel=pd->inventory.lastSlot-1; } + if (pd->inputs.k_down.clicked) { ++pd->ingameMenuInvSel; if(pd->ingameMenuInvSel > pd->inventory.lastSlot-1)pd->ingameMenuInvSel=0; } + break; + + case MENU_CRAFTING: if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE; - + if (pd->inputs.k_accept.clicked){ + if(craftItem(&(pd->currentRecipes), &(pd->currentRecipes.recipes[pd->ingameMenuInvSel]), &(pd->inventory))){ + playSoundPositioned(snd_craft, pd->entity.level, pd->entity.x, pd->entity.y); + //reset active item pointer, because it could posibly point to garbage now + pd->activeItem = &noItem; + } + } + if (pd->inputs.k_up.clicked) { --pd->ingameMenuInvSel; if(pd->ingameMenuInvSel < 0)pd->ingameMenuInvSel=pd->currentRecipes.size-1; } + if (pd->inputs.k_down.clicked) { ++pd->ingameMenuInvSel; if(pd->ingameMenuInvSel > pd->currentRecipes.size-1)pd->ingameMenuInvSel=0; } + break; + + case MENU_WIN: + if (pd->inputs.k_accept.clicked){ + pd->ingameMenu = MENU_NONE; + pd->entity.p.hasWon = false; + } + break; + case MENU_LOSE: + if (pd->inputs.k_accept.clicked){ + pd->ingameMenu = MENU_NONE; + pd->entity.p.isDead = false; + pd->entity.p.health = 10; + pd->entity.level = 1; + playerSpawn(pd); + //TODO: This canceled to main menu, but what should I do in multiplayer? + } + pd->entity.hurtTime = 10; + break; + + case MENU_CONTAINER: + if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE; + if (pd->inputs.k_left.clicked) { pd->curChestEntityR = 0; int tmp = pd->ingameMenuInvSel; @@ -120,7 +120,7 @@ void ingameMenuTick(PlayerData *pd, int menu) { pd->ingameMenuInvSel = pd->ingameMenuInvSelOther; pd->ingameMenuInvSelOther = tmp; } - + Inventory* i1 = pd->curChestEntityR == 1 ? &(pd->inventory) : pd->curChestEntity->entityFurniture.inv; Inventory* i2 = pd->curChestEntityR == 0 ? &(pd->inventory) : pd->curChestEntity->entityFurniture.inv; int len = i1->lastSlot; @@ -131,7 +131,7 @@ void ingameMenuTick(PlayerData *pd, int menu) { if (len == 0) pd->ingameMenuInvSel = 0; if (pd->ingameMenuInvSel < 0) pd->ingameMenuInvSel += len; if (pd->ingameMenuInvSel >= len) pd->ingameMenuInvSel -= len; - + if(pd->inputs.k_accept.clicked && len > 0){ Item* pullItem = &i1->items[pd->ingameMenuInvSel]; Item pushItem = newItem(pullItem->id, pullItem->countLevel); @@ -146,11 +146,11 @@ void ingameMenuTick(PlayerData *pd, int menu) { removeItemFromCurrentInv(pullItem); if (pd->ingameMenuInvSel >= i1->lastSlot) pd->ingameMenuInvSel = i1->lastSlot - 1; } - break; - + break; + case MENU_DUNGEON: if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE; - + if(pd->inputs.k_accept.clicked) { if(pd->entity.level!=5) { Item * item = getItemFromInventory(ITEM_DUNGEON_KEY, &(pd->inventory)); @@ -159,68 +159,68 @@ void ingameMenuTick(PlayerData *pd, int menu) { if(item->countLevel==0) { removeItemFromCurrentInv(item); } - + enterDungeon(pd); } else if(shouldRenderDebug) { - enterDungeon(pd); - } + enterDungeon(pd); + } } else { leaveDungeon(pd); } - + pd->ingameMenu = MENU_NONE; } break; - - case MENU_NPC: - tickNPCMenu(pd); - break; - - case MENU_CHARACTER_CUSTOMIZE: - if (pd->inputs.k_up.clicked) { --pd->ingameMenuSelection; if(pd->ingameMenuSelection < 0) pd->ingameMenuSelection=6; } - if (pd->inputs.k_down.clicked) { ++pd->ingameMenuSelection; if(pd->ingameMenuSelection > 6) pd->ingameMenuSelection=0; } - - u8 wrap = 0; - wrap = wrap - 1; - - pd->entity.p.health = 10; - pd->entity.hurtTime = 10; - - //head - if(pd->ingameMenuSelection==0) { - if (pd->inputs.k_left.clicked) { --pd->sprite.head; if(pd->sprite.head == wrap) pd->sprite.head=PLAYER_SPRITE_HEAD_COUNT-1; } - if (pd->inputs.k_right.clicked) { ++pd->sprite.head; if(pd->sprite.head > PLAYER_SPRITE_HEAD_COUNT-1) pd->sprite.head=0; } - //eyes - } else if(pd->ingameMenuSelection==1) { - if (pd->inputs.k_left.clicked) { --pd->sprite.eyes; if(pd->sprite.eyes == wrap) pd->sprite.eyes=PLAYER_SPRITE_EYES_COUNT-1; } - if (pd->inputs.k_right.clicked) { ++pd->sprite.eyes; if(pd->sprite.eyes > PLAYER_SPRITE_EYES_COUNT-1) pd->sprite.eyes=0; } - //body - } else if(pd->ingameMenuSelection==2) { - if (pd->inputs.k_left.clicked) { --pd->sprite.body; if(pd->sprite.body == wrap) pd->sprite.body=PLAYER_SPRITE_BODY_COUNT-1; } - if (pd->inputs.k_right.clicked) { ++pd->sprite.body; if(pd->sprite.body > PLAYER_SPRITE_BODY_COUNT-1) pd->sprite.body=0; } - //arms - } else if(pd->ingameMenuSelection==3) { - if (pd->inputs.k_left.clicked) { --pd->sprite.arms; if(pd->sprite.arms == wrap) pd->sprite.arms=PLAYER_SPRITE_ARMS_COUNT-1; } - if (pd->inputs.k_right.clicked) { ++pd->sprite.arms; if(pd->sprite.arms > PLAYER_SPRITE_ARMS_COUNT-1) pd->sprite.arms=0; } - //legs - } else if(pd->ingameMenuSelection==4) { - if (pd->inputs.k_left.clicked) { --pd->sprite.legs; if(pd->sprite.legs == wrap) pd->sprite.legs=PLAYER_SPRITE_LEGS_COUNT-1; } - if (pd->inputs.k_right.clicked) { ++pd->sprite.legs; if(pd->sprite.legs > PLAYER_SPRITE_LEGS_COUNT-1) pd->sprite.legs=0; } - //rotation - } else if(pd->ingameMenuSelection==5) { - if (pd->inputs.k_left.clicked) { --pd->entity.p.dir; if(pd->entity.p.dir == wrap) pd->entity.p.dir=3; } - if (pd->inputs.k_right.clicked) { ++pd->entity.p.dir; if(pd->entity.p.dir > 3) pd->entity.p.dir=0; } - //done - } else if(pd->ingameMenuSelection==6) { - if(pd->inputs.k_accept.clicked) { - //TODO: are you sure dialog? - pd->ingameMenu = 0; - pd->ingameMenuSelection = 0; - pd->sprite.choosen = true; - } - } - break; - } + + case MENU_NPC: + tickNPCMenu(pd); + break; + + case MENU_CHARACTER_CUSTOMIZE: + if (pd->inputs.k_up.clicked) { --pd->ingameMenuSelection; if(pd->ingameMenuSelection < 0) pd->ingameMenuSelection=6; } + if (pd->inputs.k_down.clicked) { ++pd->ingameMenuSelection; if(pd->ingameMenuSelection > 6) pd->ingameMenuSelection=0; } + + u8 wrap = 0; + wrap = wrap - 1; + + pd->entity.p.health = 10; + pd->entity.hurtTime = 10; + + //head + if(pd->ingameMenuSelection==0) { + if (pd->inputs.k_left.clicked) { --pd->sprite.head; if(pd->sprite.head == wrap) pd->sprite.head=PLAYER_SPRITE_HEAD_COUNT-1; } + if (pd->inputs.k_right.clicked) { ++pd->sprite.head; if(pd->sprite.head > PLAYER_SPRITE_HEAD_COUNT-1) pd->sprite.head=0; } + //eyes + } else if(pd->ingameMenuSelection==1) { + if (pd->inputs.k_left.clicked) { --pd->sprite.eyes; if(pd->sprite.eyes == wrap) pd->sprite.eyes=PLAYER_SPRITE_EYES_COUNT-1; } + if (pd->inputs.k_right.clicked) { ++pd->sprite.eyes; if(pd->sprite.eyes > PLAYER_SPRITE_EYES_COUNT-1) pd->sprite.eyes=0; } + //body + } else if(pd->ingameMenuSelection==2) { + if (pd->inputs.k_left.clicked) { --pd->sprite.body; if(pd->sprite.body == wrap) pd->sprite.body=PLAYER_SPRITE_BODY_COUNT-1; } + if (pd->inputs.k_right.clicked) { ++pd->sprite.body; if(pd->sprite.body > PLAYER_SPRITE_BODY_COUNT-1) pd->sprite.body=0; } + //arms + } else if(pd->ingameMenuSelection==3) { + if (pd->inputs.k_left.clicked) { --pd->sprite.arms; if(pd->sprite.arms == wrap) pd->sprite.arms=PLAYER_SPRITE_ARMS_COUNT-1; } + if (pd->inputs.k_right.clicked) { ++pd->sprite.arms; if(pd->sprite.arms > PLAYER_SPRITE_ARMS_COUNT-1) pd->sprite.arms=0; } + //legs + } else if(pd->ingameMenuSelection==4) { + if (pd->inputs.k_left.clicked) { --pd->sprite.legs; if(pd->sprite.legs == wrap) pd->sprite.legs=PLAYER_SPRITE_LEGS_COUNT-1; } + if (pd->inputs.k_right.clicked) { ++pd->sprite.legs; if(pd->sprite.legs > PLAYER_SPRITE_LEGS_COUNT-1) pd->sprite.legs=0; } + //rotation + } else if(pd->ingameMenuSelection==5) { + if (pd->inputs.k_left.clicked) { --pd->entity.p.dir; if(pd->entity.p.dir == wrap) pd->entity.p.dir=3; } + if (pd->inputs.k_right.clicked) { ++pd->entity.p.dir; if(pd->entity.p.dir > 3) pd->entity.p.dir=0; } + //done + } else if(pd->ingameMenuSelection==6) { + if(pd->inputs.k_accept.clicked) { + //TODO: are you sure dialog? + pd->ingameMenu = 0; + pd->ingameMenuSelection = 0; + pd->sprite.choosen = true; + } + } + break; + } } @@ -229,291 +229,291 @@ bool rev = true; char scoreText[15]; void ingameMenuRender(PlayerData *pd, int menu) { - int i; - - switch(menu) { - case MENU_PAUSED: - renderFrame(1,1,24,14,0xFF1010AF); - drawText("Paused",164,32); - for(i = 3; i >= 0; --i){ - char* msg = pOptions[i]; - u32 color = 0xFF7F7F7F; - if(i == pd->ingameMenuSelection) color = 0xFFFFFFFF; - if((i == 1 && dungeonActive())) { - color = 0xFF7F7FFF; - if(i == pd->ingameMenuSelection) color = 0xFFAFAFFF; - } - drawTextColor(msg,(400 - (strlen(msg) * 12))/2, (i * 24) + 88, color); - } - - if(pd->ingameMenuTimer > 0) drawTextColor("Game Saved!", (400-(11*12))/2, 64,0xFF20FF20); - - if(pd->ingameMenuAreYouSure || pd->ingameMenuAreYouSureSave){ - if(pd->ingameMenuAreYouSure)renderFrame(6,5,19,10,0xFF10108F); - else renderFrame(6,5,19,10,0xFF108F10); - - drawText("Are you sure?",122,96); - drawText(" Yes", 164, 117); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 166, 114, 1); - drawText(" No", 170, 133); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 166, 130, 1); - } - break; - case MENU_WIN: - renderFrame(5,3,21,12,0xFFFF1010); - if(!rev){ opacity+=5; if(opacity == 255) rev = true; } - else { opacity-=5; if(opacity == 100) rev = false; } - sprintf(scoreText,"Score: %d", pd->score); - drawTextColor("You Win!",158,76,0x0000AFAF + (opacity << 24)); - drawText(scoreText, 200-((strlen(scoreText)-1)*6), 100); - drawText("Press to continue", 96, 150); - renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 166, 148, 1); - - //printf("0x%08X",localInputs.k_attack.input & -localInputs.k_attack.input); - break; - case MENU_LOSE: - renderFrame(5,3,21,12,0xFFFF1010); - if(!rev){ opacity+=5; if(opacity == 255) rev = true; } - else { opacity-=5; if(opacity == 100) rev = false; } - sprintf(scoreText,"Score: %d", pd->score); - drawTextColor("You DIED!",158,76,0x000000AF + (opacity << 24)); - drawText(scoreText, 200-((strlen(scoreText)-1)*6), 100); - drawText("Press to continue", 96, 150); - renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 166, 148, 1); - //printf("0x%08X",localInputs.k_attack.input & -localInputs.k_attack.input); - break; - case MENU_INVENTORY: - renderFrame(1,1,24,14,0xFFFF1010); - drawTextColor("Inventory",24+1,14+1,0xFF000000); - drawTextColor("Inventory",24,14,0xFF6FE2E2); - renderItemList(&(pd->inventory), 1,1,24,14, pd->ingameMenuInvSel); - break; - case MENU_CRAFTING: - renderFrame(15,1,24,4,0xFFFF1010); - drawTextColor("Have",248+1,14+1,0xFF000000); - drawTextColor("Have",248,14,0xFF6FE2E2); - renderFrame(15,5,24,14,0xFFFF1010); - drawTextColor("Cost",248+1,78+1,0xFF000000); - drawTextColor("Cost",248,78,0xFF6FE2E2); - renderFrame(1,1,14,14,0xFFFF1010); - drawTextColor(pd->currentCraftTitle,24+1,14+1,0xFF000000); - drawTextColor(pd->currentCraftTitle,24,14,0xFF6FE2E2); - renderRecipes(&(pd->currentRecipes), 1, 1, 14, 14, pd->ingameMenuInvSel); - - Recipe* rec = &(pd->currentRecipes.recipes[pd->ingameMenuInvSel]); - renderItemIcon(rec->itemResult,rec->itemAmountLevel,128,16); - char craftText[12]; - sprintf(craftText, "%d", countItemInv(rec->itemResult, rec->itemAmountLevel, &(pd->inventory))); - drawText(craftText,274,34); - - if(rec->numOfCosts > 0){ - int i; - for(i = 0; i < rec->numOfCosts; i++){ - int amnt = countItemInv(rec->costs[i].costItem,0, &(pd->inventory)); - int ttlCst = rec->costs[i].costAmount; - int col = 0xFFFFFFFF; if(amntcosts[i].costItem,1,128,48+(i*8)); - sprintf(craftText,"%d/%d",amnt,ttlCst); - drawTextColor(craftText,274,96+(i*18),col); - } - } - break; - - case MENU_CONTAINER: - if (pd->curChestEntityR == 1){ offsetX = 48; offsetY = 0;} - else {offsetX = 0; offsetY = 0;} - - renderFrame(1,1,15,14,0xFFFF1010); - drawTextColor("Chest",24+1,14+1,0xFF000000); - drawTextColor("Chest",24,14,0xFF6FE2E2); - renderItemList(pd->curChestEntity->entityFurniture.inv,1,1,15,14, - pd->curChestEntityR == 0 ? pd->ingameMenuInvSel : -pd->ingameMenuInvSelOther - 1); - renderFrame(16,1,30,14,0xFFFF1010); - drawTextColor("Inventory",264+1,14+1,0xFF000000); - drawTextColor("Inventory",264,14,0xFF6FE2E2); - renderItemList(&(pd->inventory),16,1,30,14, - pd->curChestEntityR == 1 ? pd->ingameMenuInvSel : -pd->ingameMenuInvSelOther - 1); - offsetX = 0;offsetY = 0; - break; - - case MENU_DUNGEON: - renderFrame(1,1,24,14,0xFFFF1010); - if(pd->entity.level!=5) { - drawTextColor("Dungeon Entrance",24+1,14+1,0xFF000000); - drawTextColor("Dungeon Entrance",24,14,0xFF6FE2E2); - - drawText("Warning: ", 32, 32); - drawText("You need a Dungeon Key to ", 32, 56); - drawText("enter and cannot save while ", 32, 72); - drawText("being in the Dungeon! ", 32, 88); - drawText("After leaving you will need ", 32, 112); - drawText("a new Dungeon Key for ", 32, 128); - drawText("entering another Dungeon! ", 32, 144); - - drawText(" Enter", 148, 171); - } else { - drawTextColor("Dungeon Exit",24+1,14+1,0xFF000000); - drawTextColor("Dungeon Exit",24,14,0xFF6FE2E2); - - drawText("Warning: ", 32, 32); - drawText("The Dungeon and everything ", 32, 56); - drawText("in it will disappear when ", 32, 72); - drawText("you leave it! ", 32, 88); - drawText("You will need a new Dungeon ", 32, 112); - drawText("Key for entering another ", 32, 128); - drawText("Dungeon again! ", 32, 144); - - drawText(" Leave", 148, 171); - } - - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 150, 168, 1); - drawText(" Stay", 148, 195); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 150, 192, 1); + int i; + + switch(menu) { + case MENU_PAUSED: + renderFrame(1,1,24,14,0xFF1010AF); + drawText("Paused",164,32); + for(i = 3; i >= 0; --i){ + char* msg = pOptions[i]; + u32 color = 0xFF7F7F7F; + if(i == pd->ingameMenuSelection) color = 0xFFFFFFFF; + if((i == 1 && dungeonActive())) { + color = 0xFF7F7FFF; + if(i == pd->ingameMenuSelection) color = 0xFFAFAFFF; + } + drawTextColor(msg,(400 - (strlen(msg) * 12))/2, (i * 24) + 88, color); + } + + if(pd->ingameMenuTimer > 0) drawTextColor("Game Saved!", (400-(11*12))/2, 64,0xFF20FF20); + + if(pd->ingameMenuAreYouSure || pd->ingameMenuAreYouSureSave){ + if(pd->ingameMenuAreYouSure)renderFrame(6,5,19,10,0xFF10108F); + else renderFrame(6,5,19,10,0xFF108F10); + + drawText("Are you sure?",122,96); + drawText(" Yes", 164, 117); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 166, 114, 1); + drawText(" No", 170, 133); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 166, 130, 1); + } break; - - case MENU_NPC: - renderNPCMenu(&(pd->npcMenuData)); - break; - - case MENU_CHARACTER_CUSTOMIZE: - renderFrame(1,1,24,14,0xFFFF1010); - drawTextColor("Character",24+1,14+1,0xFF000000); - drawTextColor("Character",24,14,0xFF6FE2E2); - - drawText("Head: ", 32, 56); - drawText("Eyes: ", 32, 72); - drawText("Body: ", 32, 88); - drawText("Arms: ", 32, 104); - drawText("Legs: ", 32, 120); - drawText("Rot.: ", 32, 144); - - //for the dynamic part - char display[30]; - - sprintf(display, pd->ingameMenuSelection==0 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.head+1, PLAYER_SPRITE_HEAD_COUNT); - drawText(display, 96, 56); - sprintf(display, pd->ingameMenuSelection==1 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.eyes+1, PLAYER_SPRITE_EYES_COUNT); - drawText(display, 96, 72); - sprintf(display, pd->ingameMenuSelection==2 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.body+1, PLAYER_SPRITE_BODY_COUNT); - drawText(display, 96, 88); - sprintf(display, pd->ingameMenuSelection==3 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.arms+1, PLAYER_SPRITE_ARMS_COUNT); - drawText(display, 96, 104); - sprintf(display, pd->ingameMenuSelection==4 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.legs+1, PLAYER_SPRITE_LEGS_COUNT); - drawText(display, 96, 120); - sprintf(display, pd->ingameMenuSelection==5 ? "< %02i/%02i >" : " %02i/%02i ", pd->entity.p.dir+1, 4); - drawText(display, 96, 144); - sprintf(display, pd->ingameMenuSelection==6 ? "< Done >" : " Done "); - drawText(display, 96, 172); - - int oox = offsetX; - int ooy = offsetY; - int osx = playerScale; - - renderFrame(13,3,22,12,0xFF909090); - //move player sprite to 0/0 - offsetX = pd->entity.x - 8; - offsetY = pd->entity.y - 8; - //move to where I want it - offsetX -= 108; - offsetY -= 28; - playerScale = 8; - renderPlayer(pd); - - offsetX = oox; - offsetY = ooy; - playerScale = osx; - break; - } + case MENU_WIN: + renderFrame(5,3,21,12,0xFFFF1010); + if(!rev){ opacity+=5; if(opacity == 255) rev = true; } + else { opacity-=5; if(opacity == 100) rev = false; } + sprintf(scoreText,"Score: %d", pd->score); + drawTextColor("You Win!",158,76,0x0000AFAF + (opacity << 24)); + drawText(scoreText, 200-((strlen(scoreText)-1)*6), 100); + drawText("Press to continue", 96, 150); + renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 166, 148, 1); + + //printf("0x%08X",localInputs.k_attack.input & -localInputs.k_attack.input); + break; + case MENU_LOSE: + renderFrame(5,3,21,12,0xFFFF1010); + if(!rev){ opacity+=5; if(opacity == 255) rev = true; } + else { opacity-=5; if(opacity == 100) rev = false; } + sprintf(scoreText,"Score: %d", pd->score); + drawTextColor("You DIED!",158,76,0x000000AF + (opacity << 24)); + drawText(scoreText, 200-((strlen(scoreText)-1)*6), 100); + drawText("Press to continue", 96, 150); + renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 166, 148, 1); + //printf("0x%08X",localInputs.k_attack.input & -localInputs.k_attack.input); + break; + case MENU_INVENTORY: + renderFrame(1,1,24,14,0xFFFF1010); + drawTextColor("Inventory",24+1,14+1,0xFF000000); + drawTextColor("Inventory",24,14,0xFF6FE2E2); + renderItemList(&(pd->inventory), 1,1,24,14, pd->ingameMenuInvSel); + break; + case MENU_CRAFTING: + renderFrame(15,1,24,4,0xFFFF1010); + drawTextColor("Have",248+1,14+1,0xFF000000); + drawTextColor("Have",248,14,0xFF6FE2E2); + renderFrame(15,5,24,14,0xFFFF1010); + drawTextColor("Cost",248+1,78+1,0xFF000000); + drawTextColor("Cost",248,78,0xFF6FE2E2); + renderFrame(1,1,14,14,0xFFFF1010); + drawTextColor(pd->currentCraftTitle,24+1,14+1,0xFF000000); + drawTextColor(pd->currentCraftTitle,24,14,0xFF6FE2E2); + renderRecipes(&(pd->currentRecipes), 1, 1, 14, 14, pd->ingameMenuInvSel); + + Recipe* rec = &(pd->currentRecipes.recipes[pd->ingameMenuInvSel]); + renderItemIcon(rec->itemResult,rec->itemAmountLevel,128,16); + char craftText[12]; + sprintf(craftText, "%d", countItemInv(rec->itemResult, rec->itemAmountLevel, &(pd->inventory))); + drawText(craftText,274,34); + + if(rec->numOfCosts > 0){ + int i; + for(i = 0; i < rec->numOfCosts; i++){ + int amnt = countItemInv(rec->costs[i].costItem,0, &(pd->inventory)); + int ttlCst = rec->costs[i].costAmount; + int col = 0xFFFFFFFF; if(amntcosts[i].costItem,1,128,48+(i*8)); + sprintf(craftText,"%d/%d",amnt,ttlCst); + drawTextColor(craftText,274,96+(i*18),col); + } + } + break; + + case MENU_CONTAINER: + if (pd->curChestEntityR == 1){ offsetX = 48; offsetY = 0;} + else {offsetX = 0; offsetY = 0;} + + renderFrame(1,1,15,14,0xFFFF1010); + drawTextColor("Chest",24+1,14+1,0xFF000000); + drawTextColor("Chest",24,14,0xFF6FE2E2); + renderItemList(pd->curChestEntity->entityFurniture.inv,1,1,15,14, + pd->curChestEntityR == 0 ? pd->ingameMenuInvSel : -pd->ingameMenuInvSelOther - 1); + renderFrame(16,1,30,14,0xFFFF1010); + drawTextColor("Inventory",264+1,14+1,0xFF000000); + drawTextColor("Inventory",264,14,0xFF6FE2E2); + renderItemList(&(pd->inventory),16,1,30,14, + pd->curChestEntityR == 1 ? pd->ingameMenuInvSel : -pd->ingameMenuInvSelOther - 1); + offsetX = 0;offsetY = 0; + break; + + case MENU_DUNGEON: + renderFrame(1,1,24,14,0xFFFF1010); + if(pd->entity.level!=5) { + drawTextColor("Dungeon Entrance",24+1,14+1,0xFF000000); + drawTextColor("Dungeon Entrance",24,14,0xFF6FE2E2); + + drawText("Warning: ", 32, 32); + drawText("You need a Dungeon Key to ", 32, 56); + drawText("enter and cannot save while ", 32, 72); + drawText("being in the Dungeon! ", 32, 88); + drawText("After leaving you will need ", 32, 112); + drawText("a new Dungeon Key for ", 32, 128); + drawText("entering another Dungeon! ", 32, 144); + + drawText(" Enter", 148, 171); + } else { + drawTextColor("Dungeon Exit",24+1,14+1,0xFF000000); + drawTextColor("Dungeon Exit",24,14,0xFF6FE2E2); + + drawText("Warning: ", 32, 32); + drawText("The Dungeon and everything ", 32, 56); + drawText("in it will disappear when ", 32, 72); + drawText("you leave it! ", 32, 88); + drawText("You will need a new Dungeon ", 32, 112); + drawText("Key for entering another ", 32, 128); + drawText("Dungeon again! ", 32, 144); + + drawText(" Leave", 148, 171); + } + + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 150, 168, 1); + drawText(" Stay", 148, 195); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 150, 192, 1); + break; + + case MENU_NPC: + renderNPCMenu(&(pd->npcMenuData)); + break; + + case MENU_CHARACTER_CUSTOMIZE: + renderFrame(1,1,24,14,0xFFFF1010); + drawTextColor("Character",24+1,14+1,0xFF000000); + drawTextColor("Character",24,14,0xFF6FE2E2); + + drawText("Head: ", 32, 56); + drawText("Eyes: ", 32, 72); + drawText("Body: ", 32, 88); + drawText("Arms: ", 32, 104); + drawText("Legs: ", 32, 120); + drawText("Rot.: ", 32, 144); + + //for the dynamic part + char display[30]; + + sprintf(display, pd->ingameMenuSelection==0 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.head+1, PLAYER_SPRITE_HEAD_COUNT); + drawText(display, 96, 56); + sprintf(display, pd->ingameMenuSelection==1 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.eyes+1, PLAYER_SPRITE_EYES_COUNT); + drawText(display, 96, 72); + sprintf(display, pd->ingameMenuSelection==2 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.body+1, PLAYER_SPRITE_BODY_COUNT); + drawText(display, 96, 88); + sprintf(display, pd->ingameMenuSelection==3 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.arms+1, PLAYER_SPRITE_ARMS_COUNT); + drawText(display, 96, 104); + sprintf(display, pd->ingameMenuSelection==4 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.legs+1, PLAYER_SPRITE_LEGS_COUNT); + drawText(display, 96, 120); + sprintf(display, pd->ingameMenuSelection==5 ? "< %02i/%02i >" : " %02i/%02i ", pd->entity.p.dir+1, 4); + drawText(display, 96, 144); + sprintf(display, pd->ingameMenuSelection==6 ? "< Done >" : " Done "); + drawText(display, 96, 172); + + int oox = offsetX; + int ooy = offsetY; + int osx = playerScale; + + renderFrame(13,3,22,12,0xFF909090); + //move player sprite to 0/0 + offsetX = pd->entity.x - 8; + offsetY = pd->entity.y - 8; + //move to where I want it + offsetX -= 108; + offsetY -= 28; + playerScale = 8; + renderPlayer(pd); + + offsetX = oox; + offsetY = ooy; + playerScale = osx; + break; + } } //touch menu void tickTouchMap(PlayerData *pd){ - if(pd->mapShouldRender){ - if(pd->inputs.k_touch.px > 0 || pd->inputs.k_touch.py > 0){ - // Plus/Minus zoom button - if(pd->inputs.k_touch.py > 204 && pd->inputs.k_touch.py < 232){ - if(pd->inputs.k_touch.px > 284 && pd->inputs.k_touch.px < 312){ - if(pd->mapZoomLevel > 4) return; - if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){ - pd->mapZoomLevel += 2; - pd->mapScrollX -= (50 * (pd->mapZoomLevel/2)); - pd->mapScrollY -= (40 * (pd->mapZoomLevel/2)); - pd->touchIsChangingSize = true; - sprintf(pd->mapText, "x%d", pd->mapZoomLevel); - } - if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel); - else if(pd->mapScrollX > 0) pd->mapScrollX = 0; - if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel); - else if(pd->mapScrollY > 0) pd->mapScrollY = 0; - return; - } else if(pd->inputs.k_touch.px > 256 && pd->inputs.k_touch.px < 284){ - if(pd->mapZoomLevel < 4) return; - if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){ - pd->mapScrollX += (50 * (pd->mapZoomLevel/2)); - pd->mapScrollY += (40 * (pd->mapZoomLevel/2)); - pd->mapZoomLevel -= 2; - pd->touchIsChangingSize = true; - sprintf(pd->mapText, "x%d", pd->mapZoomLevel); - } - if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel); - else if(pd->mapScrollX > 0) pd->mapScrollX = 0; - if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel); - else if(pd->mapScrollY > 0) pd->mapScrollY = 0; - return; - } - } else if(pd->inputs.k_touch.py > 8 && pd->inputs.k_touch.py < 40 && pd->inputs.k_touch.px > 284 && pd->inputs.k_touch.px < 312){ - // Exit Button - if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){ - pd->mapShouldRender = false; - return; - } - } - - if(!pd->touchIsDraggingMap){ - pd->touchLastX = pd->inputs.k_touch.px; - pd->touchLastY = pd->inputs.k_touch.py; - } - if(pd->mapZoomLevel > 2){ - int dx = pd->touchLastX - pd->inputs.k_touch.px; - if(dx > 1 || dx < -1){ - pd->mapScrollX -= dx; - if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel); - else if(pd->mapScrollX > 0) pd->mapScrollX = 0; - } - pd->touchLastX = pd->inputs.k_touch.px; - } - - int dy = pd->touchLastY - pd->inputs.k_touch.py; - if(dy > 1 || dy < -1){ - pd->mapScrollY -= dy; - if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel); - else if(pd->mapScrollY > 0) pd->mapScrollY = 0; - } - pd->touchLastY = pd->inputs.k_touch.py; - pd->touchIsDraggingMap = true; - } else { - pd->touchIsDraggingMap = false; - pd->touchIsChangingSize = false; - } - } else { - // touch minimap to bring up zoomed map. - if(pd->inputs.k_touch.py > 100 && pd->inputs.k_touch.py < 228 && pd->inputs.k_touch.px > 10 && pd->inputs.k_touch.px < 142){ - pd->mapShouldRender = true; - } - } + if(pd->mapShouldRender){ + if(pd->inputs.k_touch.px > 0 || pd->inputs.k_touch.py > 0){ + // Plus/Minus zoom button + if(pd->inputs.k_touch.py > 204 && pd->inputs.k_touch.py < 232){ + if(pd->inputs.k_touch.px > 284 && pd->inputs.k_touch.px < 312){ + if(pd->mapZoomLevel > 4) return; + if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){ + pd->mapZoomLevel += 2; + pd->mapScrollX -= (50 * (pd->mapZoomLevel/2)); + pd->mapScrollY -= (40 * (pd->mapZoomLevel/2)); + pd->touchIsChangingSize = true; + sprintf(pd->mapText, "x%d", pd->mapZoomLevel); + } + if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel); + else if(pd->mapScrollX > 0) pd->mapScrollX = 0; + if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel); + else if(pd->mapScrollY > 0) pd->mapScrollY = 0; + return; + } else if(pd->inputs.k_touch.px > 256 && pd->inputs.k_touch.px < 284){ + if(pd->mapZoomLevel < 4) return; + if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){ + pd->mapScrollX += (50 * (pd->mapZoomLevel/2)); + pd->mapScrollY += (40 * (pd->mapZoomLevel/2)); + pd->mapZoomLevel -= 2; + pd->touchIsChangingSize = true; + sprintf(pd->mapText, "x%d", pd->mapZoomLevel); + } + if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel); + else if(pd->mapScrollX > 0) pd->mapScrollX = 0; + if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel); + else if(pd->mapScrollY > 0) pd->mapScrollY = 0; + return; + } + } else if(pd->inputs.k_touch.py > 8 && pd->inputs.k_touch.py < 40 && pd->inputs.k_touch.px > 284 && pd->inputs.k_touch.px < 312){ + // Exit Button + if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){ + pd->mapShouldRender = false; + return; + } + } + + if(!pd->touchIsDraggingMap){ + pd->touchLastX = pd->inputs.k_touch.px; + pd->touchLastY = pd->inputs.k_touch.py; + } + if(pd->mapZoomLevel > 2){ + int dx = pd->touchLastX - pd->inputs.k_touch.px; + if(dx > 1 || dx < -1){ + pd->mapScrollX -= dx; + if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel); + else if(pd->mapScrollX > 0) pd->mapScrollX = 0; + } + pd->touchLastX = pd->inputs.k_touch.px; + } + + int dy = pd->touchLastY - pd->inputs.k_touch.py; + if(dy > 1 || dy < -1){ + pd->mapScrollY -= dy; + if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel); + else if(pd->mapScrollY > 0) pd->mapScrollY = 0; + } + pd->touchLastY = pd->inputs.k_touch.py; + pd->touchIsDraggingMap = true; + } else { + pd->touchIsDraggingMap = false; + pd->touchIsChangingSize = false; + } + } else { + // touch minimap to bring up zoomed map. + if(pd->inputs.k_touch.py > 100 && pd->inputs.k_touch.py < 228 && pd->inputs.k_touch.px > 10 && pd->inputs.k_touch.px < 142){ + pd->mapShouldRender = true; + } + } } void tickTouchQuickSelect(PlayerData *pd) { if (pd->ingameMenu == MENU_NONE && !pd->mapShouldRender) { int i = 0; Inventory * inv = &(pd->inventory); - + for (i = 0; i < 8; ++i) { if((inv->lastSlot) > i) { int xip = i % 4; int yip = i / 4; - + if(pd->inputs.k_touch.py > 72*2+yip*21*2 && pd->inputs.k_touch.py < 72*2+yip*21*2+21*2 && pd->inputs.k_touch.px > 76*2+xip*21*2 && pd->inputs.k_touch.px < 76*2+xip*21*2+21*2) { playerSetActiveItem(pd, &inv->items[i]); } @@ -523,6 +523,6 @@ void tickTouchQuickSelect(PlayerData *pd) { } void ingameMenuTickTouch(PlayerData *pd) { - tickTouchMap(pd); - tickTouchQuickSelect(pd); + tickTouchMap(pd); + tickTouchQuickSelect(pd); } diff --git a/source/Input.c b/source/Input.c index d35bfc0..021958f 100755 --- a/source/Input.c +++ b/source/Input.c @@ -1,55 +1,55 @@ #include "Input.h" void toggleKey(Key* key, bool held, bool down){ - key->down = held; + key->down = held; key->clicked = down; } - + void tickKeys(Inputs *inputs, u32 held, u32 down){ - hidTouchRead(&(inputs->k_touch)); // Update touch position - toggleKey(&(inputs->k_up), held & localInputs.k_up.input, down & localInputs.k_up.input); - toggleKey(&(inputs->k_down), held & localInputs.k_down.input, down & localInputs.k_down.input); - toggleKey(&(inputs->k_left), held & localInputs.k_left.input, down & localInputs.k_left.input); - toggleKey(&(inputs->k_right), held & localInputs.k_right.input, down & localInputs.k_right.input); - toggleKey(&(inputs->k_pause), held & localInputs.k_pause.input, down & localInputs.k_pause.input); - toggleKey(&(inputs->k_attack), held & localInputs.k_attack.input, down & localInputs.k_attack.input); - toggleKey(&(inputs->k_menu), held & localInputs.k_menu.input, down & localInputs.k_menu.input); - toggleKey(&(inputs->k_accept), held & localInputs.k_accept.input, down & localInputs.k_accept.input); - toggleKey(&(inputs->k_decline), held & localInputs.k_decline.input, down & localInputs.k_decline.input); - toggleKey(&(inputs->k_delete), held & localInputs.k_delete.input, down & localInputs.k_delete.input); - toggleKey(&(inputs->k_menuNext), held & localInputs.k_menuNext.input, down & localInputs.k_menuNext.input); - toggleKey(&(inputs->k_menuPrev), held & localInputs.k_menuPrev.input, down & localInputs.k_menuPrev.input); + hidTouchRead(&(inputs->k_touch)); // Update touch position + toggleKey(&(inputs->k_up), held & localInputs.k_up.input, down & localInputs.k_up.input); + toggleKey(&(inputs->k_down), held & localInputs.k_down.input, down & localInputs.k_down.input); + toggleKey(&(inputs->k_left), held & localInputs.k_left.input, down & localInputs.k_left.input); + toggleKey(&(inputs->k_right), held & localInputs.k_right.input, down & localInputs.k_right.input); + toggleKey(&(inputs->k_pause), held & localInputs.k_pause.input, down & localInputs.k_pause.input); + toggleKey(&(inputs->k_attack), held & localInputs.k_attack.input, down & localInputs.k_attack.input); + toggleKey(&(inputs->k_menu), held & localInputs.k_menu.input, down & localInputs.k_menu.input); + toggleKey(&(inputs->k_accept), held & localInputs.k_accept.input, down & localInputs.k_accept.input); + toggleKey(&(inputs->k_decline), held & localInputs.k_decline.input, down & localInputs.k_decline.input); + toggleKey(&(inputs->k_delete), held & localInputs.k_delete.input, down & localInputs.k_delete.input); + toggleKey(&(inputs->k_menuNext), held & localInputs.k_menuNext.input, down & localInputs.k_menuNext.input); + toggleKey(&(inputs->k_menuPrev), held & localInputs.k_menuPrev.input, down & localInputs.k_menuPrev.input); } void resetKeys(Inputs *inputs) { - (inputs->k_touch).px = -1; - (inputs->k_touch).py = -1; - - toggleKey(&(inputs->k_up), false, false); - toggleKey(&(inputs->k_down), false, false); - toggleKey(&(inputs->k_left), false, false); - toggleKey(&(inputs->k_right), false, false); - toggleKey(&(inputs->k_pause), false, false); - toggleKey(&(inputs->k_attack), false, false); - toggleKey(&(inputs->k_menu), false, false); - toggleKey(&(inputs->k_accept), false, false); - toggleKey(&(inputs->k_decline), false, false); - toggleKey(&(inputs->k_delete), false, false); - toggleKey(&(inputs->k_menuNext), false, false); - toggleKey(&(inputs->k_menuPrev), false, false); + (inputs->k_touch).px = -1; + (inputs->k_touch).py = -1; + + toggleKey(&(inputs->k_up), false, false); + toggleKey(&(inputs->k_down), false, false); + toggleKey(&(inputs->k_left), false, false); + toggleKey(&(inputs->k_right), false, false); + toggleKey(&(inputs->k_pause), false, false); + toggleKey(&(inputs->k_attack), false, false); + toggleKey(&(inputs->k_menu), false, false); + toggleKey(&(inputs->k_accept), false, false); + toggleKey(&(inputs->k_decline), false, false); + toggleKey(&(inputs->k_delete), false, false); + toggleKey(&(inputs->k_menuNext), false, false); + toggleKey(&(inputs->k_menuPrev), false, false); } void resetClicked(Inputs *inputs) { - inputs->k_up.clicked = false; - inputs->k_down.clicked = false; - inputs->k_left.clicked = false; - inputs->k_right.clicked = false; - inputs->k_pause.clicked = false; - inputs->k_attack.clicked = false; - inputs->k_menu.clicked = false; - inputs->k_accept.clicked = false; - inputs->k_decline.clicked = false; - inputs->k_delete.clicked = false; - inputs->k_menuNext.clicked = false; - inputs->k_menuPrev.clicked = false; + inputs->k_up.clicked = false; + inputs->k_down.clicked = false; + inputs->k_left.clicked = false; + inputs->k_right.clicked = false; + inputs->k_pause.clicked = false; + inputs->k_attack.clicked = false; + inputs->k_menu.clicked = false; + inputs->k_accept.clicked = false; + inputs->k_decline.clicked = false; + inputs->k_delete.clicked = false; + inputs->k_menuNext.clicked = false; + inputs->k_menuPrev.clicked = false; } diff --git a/source/Input.h b/source/Input.h index ad11742..f439a52 100755 --- a/source/Input.h +++ b/source/Input.h @@ -9,20 +9,20 @@ typedef struct { } Key; typedef struct { - Key k_null; - Key k_up; - Key k_down; - Key k_left; - Key k_right; - Key k_attack; - Key k_menu; - Key k_pause; - Key k_accept; - Key k_decline; - Key k_delete; - Key k_menuNext; - Key k_menuPrev; - touchPosition k_touch; + Key k_null; + Key k_up; + Key k_down; + Key k_left; + Key k_right; + Key k_attack; + Key k_menu; + Key k_pause; + Key k_accept; + Key k_decline; + Key k_delete; + Key k_menuNext; + Key k_menuPrev; + touchPosition k_touch; } Inputs; Inputs localInputs; diff --git a/source/Item.c b/source/Item.c index b482a8d..4fa342b 100755 --- a/source/Item.c +++ b/source/Item.c @@ -3,168 +3,168 @@ char currentName[16]; bool isItemEmpty(Item* item) { - if(item->id < 6 || item->id > 100 || item->onlyOne == true) return false; - if(item->countLevel < 1) return true; - return false; + if(item->id < 6 || item->id > 100 || item->onlyOne == true) return false; + if(item->countLevel < 1) return true; + return false; } void pushItemToInventoryFront(Item item, Inventory * inv) { - if(inv->lastSlot < 300) ++inv->lastSlot; - int i; - for(i = inv->lastSlot;i > 0;--i){ - inv->items[i] = inv->items[i-1]; // Move the items up the list. - inv->items[i].slotNum = i; - } - item.invPtr = (int*)inv; - inv->items[0] = item; - inv->items[0].slotNum = 0; - + if(inv->lastSlot < 300) ++inv->lastSlot; + int i; + for(i = inv->lastSlot;i > 0;--i){ + inv->items[i] = inv->items[i-1]; // Move the items up the list. + inv->items[i].slotNum = i; + } + item.invPtr = (int*)inv; + inv->items[0] = item; + inv->items[0].slotNum = 0; + } void addItemToInventory(Item item, Inventory * inv) { - if(!item.onlyOne){ - int i; - for(i = 0;i < inv->lastSlot;++i){ //Search inventory if item already exists. - if(inv->items[i].id == item.id){ - inv->items[i].countLevel+=item.countLevel; - return; - } - } - } - - item.slotNum = inv->lastSlot; - item.invPtr = (int*)inv; - inv->items[inv->lastSlot] = item; - ++inv->lastSlot; + if(!item.onlyOne){ + int i; + for(i = 0;i < inv->lastSlot;++i){ //Search inventory if item already exists. + if(inv->items[i].id == item.id){ + inv->items[i].countLevel+=item.countLevel; + return; + } + } + } + + item.slotNum = inv->lastSlot; + item.invPtr = (int*)inv; + inv->items[inv->lastSlot] = item; + ++inv->lastSlot; } void removeItemFromCurrentInv(Item* item) { - removeItemFromInventory(item->slotNum, (Inventory*)item->invPtr); + removeItemFromInventory(item->slotNum, (Inventory*)item->invPtr); } Item nullItem; void removeItemFromInventory(int slot, Inventory * inv) { - int i; - for(i = slot;i < inv->lastSlot - 1;++i){ - inv->items[i] = inv->items[i + 1]; // Move the items down. - inv->items[i].slotNum--; - } - --inv->lastSlot; - inv->items[inv->lastSlot] = nullItem; // Make the last slot null. + int i; + for(i = slot;i < inv->lastSlot - 1;++i){ + inv->items[i] = inv->items[i + 1]; // Move the items down. + inv->items[i].slotNum--; + } + --inv->lastSlot; + inv->items[inv->lastSlot] = nullItem; // Make the last slot null. } Item newItem(int id, int cLevel) { - Item item; - item.id = id; - if(id != ITEM_NULL){ - if(cLevel > 999) cLevel = 999; - item.countLevel = cLevel; - if(id < 7 || (id > 27 && id < 51) || id > 100) item.onlyOne = true; // Tools + Furniture. - else item.onlyOne = false; - } - item.chestPtr = NULL; - return item; + Item item; + item.id = id; + if(id != ITEM_NULL){ + if(cLevel > 999) cLevel = 999; + item.countLevel = cLevel; + if(id < 7 || (id > 27 && id < 51) || id > 100) item.onlyOne = true; // Tools + Furniture. + else item.onlyOne = false; + } + item.chestPtr = NULL; + return item; } Item* getItemFromInventory(int itemID, Inventory * inv) { - int i; - for(i = 0;i < inv->lastSlot;++i){ - if(inv->items[i].id == itemID){ - return &inv->items[i]; - } - } - return (Item*)NULL; + int i; + for(i = 0;i < inv->lastSlot;++i){ + if(inv->items[i].id == itemID){ + return &inv->items[i]; + } + } + return (Item*)NULL; } int countItemInv(int itemID, int level, Inventory* inv) { - int i, count = 0; - for(i = 0;i < inv->lastSlot;++i){ - if(inv->items[i].id == itemID){ - if(inv->items[i].onlyOne){ - if(level == inv->items[i].countLevel) count++; - } else count += inv->items[i].countLevel; - } - } - return count; + int i, count = 0; + for(i = 0;i < inv->lastSlot;++i){ + if(inv->items[i].id == itemID){ + if(inv->items[i].onlyOne){ + if(level == inv->items[i].countLevel) count++; + } else count += inv->items[i].countLevel; + } + } + return count; } - + char* getItemName(int itemID, int countLevel) { - switch(itemID){ - case TOOL_SHOVEL: - switch(countLevel){ - case 1: return "Rock Shovel"; - case 2: return "Iron Shovel"; - case 3: return "Gold Shovel"; - case 4: return "Gem Shovel"; - default: return "Wood Shovel"; - } - case TOOL_HOE: - switch(countLevel){ - case 1: return "Rock Hoe"; - case 2: return "Iron Hoe"; - case 3: return "Gold Hoe"; - case 4: return "Gem Hoe"; - default: return "Wood Hoe"; - } - case TOOL_SWORD: - switch(countLevel){ - case 1: return "Rock Sword"; - case 2: return "Iron Sword"; - case 3: return "Gold Sword"; - case 4: return "Gem Sword"; - default: return "Wood Sword"; - } - case TOOL_PICKAXE: - switch(countLevel){ - case 1: return "Rock Pickaxe"; - case 2: return "Iron Pickaxe"; - case 3: return "Gold Pickaxe"; - case 4: return "Gem Pickaxe"; - default: return "Wood Pickaxe"; - } - case TOOL_AXE: - switch(countLevel){ - case 1: return "Rock Axe"; - case 2: return "Iron Axe"; - case 3: return "Gold Axe"; - case 4: return "Gem Axe"; - default: return "Wood Axe"; - } - case ITEM_ANVIL: return "Anvil"; - case ITEM_CHEST: return "Chest"; - case ITEM_OVEN: return "Oven"; - case ITEM_FURNACE: return "Furnace"; - case ITEM_WORKBENCH: return "Workbench"; + switch(itemID){ + case TOOL_SHOVEL: + switch(countLevel){ + case 1: return "Rock Shovel"; + case 2: return "Iron Shovel"; + case 3: return "Gold Shovel"; + case 4: return "Gem Shovel"; + default: return "Wood Shovel"; + } + case TOOL_HOE: + switch(countLevel){ + case 1: return "Rock Hoe"; + case 2: return "Iron Hoe"; + case 3: return "Gold Hoe"; + case 4: return "Gem Hoe"; + default: return "Wood Hoe"; + } + case TOOL_SWORD: + switch(countLevel){ + case 1: return "Rock Sword"; + case 2: return "Iron Sword"; + case 3: return "Gold Sword"; + case 4: return "Gem Sword"; + default: return "Wood Sword"; + } + case TOOL_PICKAXE: + switch(countLevel){ + case 1: return "Rock Pickaxe"; + case 2: return "Iron Pickaxe"; + case 3: return "Gold Pickaxe"; + case 4: return "Gem Pickaxe"; + default: return "Wood Pickaxe"; + } + case TOOL_AXE: + switch(countLevel){ + case 1: return "Rock Axe"; + case 2: return "Iron Axe"; + case 3: return "Gold Axe"; + case 4: return "Gem Axe"; + default: return "Wood Axe"; + } + case ITEM_ANVIL: return "Anvil"; + case ITEM_CHEST: return "Chest"; + case ITEM_OVEN: return "Oven"; + case ITEM_FURNACE: return "Furnace"; + case ITEM_WORKBENCH: return "Workbench"; case ITEM_POTION_MAKER: return "Potion Maker"; - case ITEM_LANTERN: return "Lantern"; - case ITEM_POWGLOVE: return "Power Glove"; - case ITEM_FLOWER: sprintf(currentName,"%d Flower", countLevel); return currentName; - case ITEM_WOOD: sprintf(currentName,"%d Wood", countLevel); return currentName; - case ITEM_STONE: sprintf(currentName,"%d Stone", countLevel); return currentName; - case ITEM_SAND: sprintf(currentName,"%d Sand", countLevel); return currentName; - case ITEM_DIRT: sprintf(currentName,"%d Dirt", countLevel); return currentName; - case ITEM_CLOUD: sprintf(currentName,"%d Cloud", countLevel); return currentName; - case ITEM_ACORN: sprintf(currentName,"%d Acorn", countLevel); return currentName; - case ITEM_CACTUS: sprintf(currentName,"%d Cactus", countLevel); return currentName; - case ITEM_SEEDS: sprintf(currentName,"%d Seeds", countLevel); return currentName; - case ITEM_WHEAT: sprintf(currentName,"%d Wheat", countLevel); return currentName; - case ITEM_FLESH: sprintf(currentName,"%d Flesh", countLevel); return currentName; - case ITEM_BREAD: sprintf(currentName,"%d Bread", countLevel); return currentName; - case ITEM_APPLE: sprintf(currentName,"%d Apple", countLevel); return currentName; + case ITEM_LANTERN: return "Lantern"; + case ITEM_POWGLOVE: return "Power Glove"; + case ITEM_FLOWER: sprintf(currentName,"%d Flower", countLevel); return currentName; + case ITEM_WOOD: sprintf(currentName,"%d Wood", countLevel); return currentName; + case ITEM_STONE: sprintf(currentName,"%d Stone", countLevel); return currentName; + case ITEM_SAND: sprintf(currentName,"%d Sand", countLevel); return currentName; + case ITEM_DIRT: sprintf(currentName,"%d Dirt", countLevel); return currentName; + case ITEM_CLOUD: sprintf(currentName,"%d Cloud", countLevel); return currentName; + case ITEM_ACORN: sprintf(currentName,"%d Acorn", countLevel); return currentName; + case ITEM_CACTUS: sprintf(currentName,"%d Cactus", countLevel); return currentName; + case ITEM_SEEDS: sprintf(currentName,"%d Seeds", countLevel); return currentName; + case ITEM_WHEAT: sprintf(currentName,"%d Wheat", countLevel); return currentName; + case ITEM_FLESH: sprintf(currentName,"%d Flesh", countLevel); return currentName; + case ITEM_BREAD: sprintf(currentName,"%d Bread", countLevel); return currentName; + case ITEM_APPLE: sprintf(currentName,"%d Apple", countLevel); return currentName; case ITEM_GOLD_APPLE: sprintf(currentName,"%d Golden Apple", countLevel); return currentName; case ITEM_STRENGTH_POTION: sprintf(currentName,"%d Strength Potion", countLevel); return currentName; case ITEM_SPEED_POTION: sprintf(currentName,"%d Speed Potion", countLevel); return currentName; case ITEM_REGEN_POTION: sprintf(currentName,"%d Regen Potion", countLevel); return currentName; case ITEM_SWIM_BREATH_POTION: sprintf(currentName,"%d Swim Potion", countLevel); return currentName; - case ITEM_COAL: sprintf(currentName,"%d Coal", countLevel); return currentName; - case ITEM_IRONORE: sprintf(currentName,"%d Iron ore", countLevel); return currentName; - case ITEM_GOLDORE: sprintf(currentName,"%d Gold ore", countLevel); return currentName; - case ITEM_IRONINGOT: sprintf(currentName,"%d Iron ingot", countLevel); return currentName; - case ITEM_GOLDINGOT: sprintf(currentName,"%d Gold ingot", countLevel); return currentName; - case ITEM_GLASS: sprintf(currentName,"%d Glass", countLevel); return currentName; - case ITEM_GEM: sprintf(currentName,"%d Gem", countLevel); return currentName; - case ITEM_SLIME: sprintf(currentName,"%d Slime", countLevel); return currentName; - + case ITEM_COAL: sprintf(currentName,"%d Coal", countLevel); return currentName; + case ITEM_IRONORE: sprintf(currentName,"%d Iron ore", countLevel); return currentName; + case ITEM_GOLDORE: sprintf(currentName,"%d Gold ore", countLevel); return currentName; + case ITEM_IRONINGOT: sprintf(currentName,"%d Iron ingot", countLevel); return currentName; + case ITEM_GOLDINGOT: sprintf(currentName,"%d Gold ingot", countLevel); return currentName; + case ITEM_GLASS: sprintf(currentName,"%d Glass", countLevel); return currentName; + case ITEM_GEM: sprintf(currentName,"%d Gem", countLevel); return currentName; + case ITEM_SLIME: sprintf(currentName,"%d Slime", countLevel); return currentName; + case ITEM_LOOM: return "Loom"; case ITEM_ENCHANTER: return "Enchanter"; case ITEM_WALL_WOOD: sprintf(currentName,"%d Wood Wall", countLevel); return currentName; @@ -190,93 +190,93 @@ char* getItemName(int itemID, int countLevel) { 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_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 ITEM_MAGIC_DUST: sprintf(currentName,"%d Magic Dust", countLevel); return currentName; + case ITEM_COIN: sprintf(currentName,"%d Coins", countLevel); return currentName; case TOOL_BUCKET: switch(countLevel){ - case 1: return "Water Bucket"; - case 2: return "Lava Bucket"; - default: return "Empty Bucket"; - } + case 1: return "Water Bucket"; + case 2: return "Lava Bucket"; + default: return "Empty Bucket"; + } case TOOL_BOW: return "Bow"; - case TOOL_MAGIC_COMPASS: return "Magic Compass"; - default: return ""; // null - } + case TOOL_MAGIC_COMPASS: return "Magic Compass"; + default: return ""; // null + } } - + char* getBasicItemName(int itemID, int countLevel) { - switch(itemID){ - case TOOL_SHOVEL: - switch(countLevel){ - case 1: return "Rock Shovel"; - case 2: return "Iron Shovel"; - case 3: return "Gold Shovel"; - case 4: return "Gem Shovel"; - default: return "Wood Shovel"; - } - case TOOL_HOE: - switch(countLevel){ - case 1: return "Rock Hoe"; - case 2: return "Iron Hoe"; - case 3: return "Gold Hoe"; - case 4: return "Gem Hoe"; - default: return "Wood Hoe"; - } - case TOOL_SWORD: - switch(countLevel){ - case 1: return "Rock Sword"; - case 2: return "Iron Sword"; - case 3: return "Gold Sword"; - case 4: return "Gem Sword"; - default: return "Wood Sword"; - } - case TOOL_PICKAXE: - switch(countLevel){ - case 1: return "Rock Pickaxe"; - case 2: return "Iron Pickaxe"; - case 3: return "Gold Pickaxe"; - case 4: return "Gem Pickaxe"; - default: return "Wood Pickaxe"; - } - case TOOL_AXE: - switch(countLevel){ - case 1: return "Rock Axe"; - case 2: return "Iron Axe"; - case 3: return "Gold Axe"; - case 4: return "Gem Axe"; - default: return "Wood Axe"; - } - case ITEM_ANVIL: return "Anvil"; - case ITEM_CHEST: return "Chest"; - case ITEM_OVEN: return "Oven"; - case ITEM_FURNACE: return "Furnace"; - case ITEM_WORKBENCH: return "Workbench"; + switch(itemID){ + case TOOL_SHOVEL: + switch(countLevel){ + case 1: return "Rock Shovel"; + case 2: return "Iron Shovel"; + case 3: return "Gold Shovel"; + case 4: return "Gem Shovel"; + default: return "Wood Shovel"; + } + case TOOL_HOE: + switch(countLevel){ + case 1: return "Rock Hoe"; + case 2: return "Iron Hoe"; + case 3: return "Gold Hoe"; + case 4: return "Gem Hoe"; + default: return "Wood Hoe"; + } + case TOOL_SWORD: + switch(countLevel){ + case 1: return "Rock Sword"; + case 2: return "Iron Sword"; + case 3: return "Gold Sword"; + case 4: return "Gem Sword"; + default: return "Wood Sword"; + } + case TOOL_PICKAXE: + switch(countLevel){ + case 1: return "Rock Pickaxe"; + case 2: return "Iron Pickaxe"; + case 3: return "Gold Pickaxe"; + case 4: return "Gem Pickaxe"; + default: return "Wood Pickaxe"; + } + case TOOL_AXE: + switch(countLevel){ + case 1: return "Rock Axe"; + case 2: return "Iron Axe"; + case 3: return "Gold Axe"; + case 4: return "Gem Axe"; + default: return "Wood Axe"; + } + case ITEM_ANVIL: return "Anvil"; + case ITEM_CHEST: return "Chest"; + case ITEM_OVEN: return "Oven"; + case ITEM_FURNACE: return "Furnace"; + case ITEM_WORKBENCH: return "Workbench"; case ITEM_POTION_MAKER: return "Potion Maker"; - case ITEM_LANTERN: return "Lantern"; - case ITEM_POWGLOVE: return "Power Glove"; - case ITEM_FLOWER: return "Flower"; - case ITEM_WOOD: return "Wood"; - case ITEM_STONE: return "Stone"; - case ITEM_SAND: return "Sand"; - case ITEM_DIRT: return "Dirt"; - case ITEM_CLOUD: return "Cloud"; - case ITEM_ACORN: return "Acorn"; - case ITEM_CACTUS: return "Cactus"; - case ITEM_SEEDS: return "Seeds"; - case ITEM_WHEAT: return "Wheat"; - case ITEM_FLESH: return "Flesh"; - case ITEM_BREAD: return "Bread"; - case ITEM_APPLE: return "Apple"; - case ITEM_GOLD_APPLE: return "Gold Apple"; - case ITEM_COAL: return "Coal"; - case ITEM_IRONORE: return "Iron ore"; - case ITEM_GOLDORE: return "Gold ore"; - case ITEM_IRONINGOT: return "Iron ingot"; - case ITEM_GOLDINGOT: return "Gold ingot"; - case ITEM_GLASS: return "Glass"; - case ITEM_GEM: return "Gem"; - case ITEM_SLIME: return "Slime"; - + case ITEM_LANTERN: return "Lantern"; + case ITEM_POWGLOVE: return "Power Glove"; + case ITEM_FLOWER: return "Flower"; + case ITEM_WOOD: return "Wood"; + case ITEM_STONE: return "Stone"; + case ITEM_SAND: return "Sand"; + case ITEM_DIRT: return "Dirt"; + case ITEM_CLOUD: return "Cloud"; + case ITEM_ACORN: return "Acorn"; + case ITEM_CACTUS: return "Cactus"; + case ITEM_SEEDS: return "Seeds"; + case ITEM_WHEAT: return "Wheat"; + case ITEM_FLESH: return "Flesh"; + case ITEM_BREAD: return "Bread"; + case ITEM_APPLE: return "Apple"; + case ITEM_GOLD_APPLE: return "Gold Apple"; + case ITEM_COAL: return "Coal"; + case ITEM_IRONORE: return "Iron ore"; + case ITEM_GOLDORE: return "Gold ore"; + case ITEM_IRONINGOT: return "Iron ingot"; + case ITEM_GOLDINGOT: return "Gold ingot"; + case ITEM_GLASS: return "Glass"; + case ITEM_GEM: return "Gem"; + case ITEM_SLIME: return "Slime"; + case ITEM_LOOM: return "Loom"; case ITEM_ENCHANTER: return "Enchanter"; case ITEM_WALL_WOOD: return "Wood Wall"; @@ -302,21 +302,21 @@ char* getBasicItemName(int itemID, int countLevel) { case ITEM_DRAGON_EGG: return "Dragon Egg"; 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 ITEM_MAGIC_DUST: return "Magic Dust"; + case ITEM_COIN: return "Coin"; case ITEM_STRENGTH_POTION: return "Strength Potion"; case ITEM_SPEED_POTION: return "Speed Potion"; case ITEM_REGEN_POTION: return "Regen Potion"; case ITEM_SWIM_BREATH_POTION: return "Water Potion"; case TOOL_BUCKET: switch(countLevel){ - case 1: return "Water Bucket"; - case 2: return "Lava Bucket"; - default: return "Empty Bucket"; - } + case 1: return "Water Bucket"; + case 2: return "Lava Bucket"; + default: return "Empty Bucket"; + } case TOOL_BOW: return "Bow"; - case TOOL_MAGIC_COMPASS: return "Magic Compass"; - default: return ""; // null - } - + case TOOL_MAGIC_COMPASS: return "Magic Compass"; + default: return ""; // null + } + } diff --git a/source/Item.h b/source/Item.h index d4cf89f..0faf059 100755 --- a/source/Item.h +++ b/source/Item.h @@ -87,17 +87,17 @@ typedef struct Inventory Inventory; typedef struct { - s16 id; - s16 countLevel; // Count for items, Level for tools. - s16 slotNum; // Read-only. Do not mess with this. - bool onlyOne; - int* invPtr; // pointer to current inventory. - Inventory * chestPtr; // pointer to chest inventory for chest item. + s16 id; + s16 countLevel; // Count for items, Level for tools. + s16 slotNum; // Read-only. Do not mess with this. + bool onlyOne; + int* invPtr; // pointer to current inventory. + Inventory * chestPtr; // pointer to chest inventory for chest item. } Item; struct Inventory { - Item items[300]; // Maximum of 300 slots in every inventory. - s16 lastSlot; // lastSlot can also be used to read the size of the inventory. + Item items[300]; // Maximum of 300 slots in every inventory. + s16 lastSlot; // lastSlot can also be used to read the size of the inventory. }; bool isItemEmpty(Item* item); diff --git a/source/MapGen.c b/source/MapGen.c index e2e6bb9..49e5438 100755 --- a/source/MapGen.c +++ b/source/MapGen.c @@ -7,7 +7,7 @@ u8 randomTile[] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 2}; int randomTileSize = 10; float nextFloat(){ - return (float)rand()/RAND_MAX; + return (float)rand()/RAND_MAX; } double sample(double * values, int x, int y) { @@ -15,72 +15,72 @@ double sample(double * values, int x, int y) { } double * Noise(int width, int height, int featureSize) { - w = width; - h = height; - double * values = malloc(sizeof(double) * w * h); - int x, y; - for(x = 0; x < w; x+=featureSize){ - for(y = 0; y < w; y+=featureSize){ - values[(x & (w - 1)) + (y & (h - 1)) * w] = nextFloat() * 2 - 1; - } - } + w = width; + h = height; + double * values = malloc(sizeof(double) * w * h); + int x, y; + for(x = 0; x < w; x+=featureSize){ + for(y = 0; y < w; y+=featureSize){ + values[(x & (w - 1)) + (y & (h - 1)) * w] = nextFloat() * 2 - 1; + } + } - int stepSize = featureSize; - double scale = 1.0 / w; - double scaleMod = 1; - do { - int halfStep = stepSize / 2; - for(x = 0; x < w; x+=stepSize){ - for(y = 0; y < w; y+=stepSize){ - double a = sample(values,x, y); - double b = sample(values,x + stepSize, y); - double c = sample(values,x, y + stepSize); - double d = sample(values,x + stepSize, y + stepSize); + int stepSize = featureSize; + double scale = 1.0 / w; + double scaleMod = 1; + do { + int halfStep = stepSize / 2; + for(x = 0; x < w; x+=stepSize){ + for(y = 0; y < w; y+=stepSize){ + double a = sample(values,x, y); + double b = sample(values,x + stepSize, y); + double c = sample(values,x, y + stepSize); + double d = sample(values,x + stepSize, y + stepSize); - double e = (a + b + c + d) / 4.0 + (nextFloat() * 2 - 1) * stepSize * scale; - values[((x + halfStep) & (w - 1)) + ((y + halfStep) & (h - 1)) * w] = e; - } - } - for(x = 0; x < w; x+=stepSize){ - for(y = 0; y < w; y+=stepSize){ - double a = sample(values,x, y); - double b = sample(values,x + stepSize, y); - double c = sample(values,x, y + stepSize); - double d = sample(values,x + halfStep, y + halfStep); - double e = sample(values,x + halfStep, y - halfStep); - double f = sample(values,x - halfStep, y + halfStep); - double H = (a + b + d + e) / 4.0 + (nextFloat() * 2 - 1) * stepSize * scale * 0.5; - double g = (a + c + d + f) / 4.0 + (nextFloat() * 2 - 1) * stepSize * scale * 0.5; - values[((x + halfStep) & (w - 1)) + (y & (h - 1)) * w] = H; - values[(x & (w - 1)) + ((y + halfStep) & (h - 1)) * w] = g; - } - } - - stepSize /= 2; - scale *= (scaleMod + 0.8); - scaleMod *= 0.3; - } while (stepSize > 1); - return values; + double e = (a + b + c + d) / 4.0 + (nextFloat() * 2 - 1) * stepSize * scale; + values[((x + halfStep) & (w - 1)) + ((y + halfStep) & (h - 1)) * w] = e; + } + } + for(x = 0; x < w; x+=stepSize){ + for(y = 0; y < w; y+=stepSize){ + double a = sample(values,x, y); + double b = sample(values,x + stepSize, y); + double c = sample(values,x, y + stepSize); + double d = sample(values,x + halfStep, y + halfStep); + double e = sample(values,x + halfStep, y - halfStep); + double f = sample(values,x - halfStep, y + halfStep); + double H = (a + b + d + e) / 4.0 + (nextFloat() * 2 - 1) * stepSize * scale * 0.5; + double g = (a + c + d + f) / 4.0 + (nextFloat() * 2 - 1) * stepSize * scale * 0.5; + values[((x + halfStep) & (w - 1)) + (y & (h - 1)) * w] = H; + values[(x & (w - 1)) + ((y + halfStep) & (h - 1)) * w] = g; + } + } + + stepSize /= 2; + scale *= (scaleMod + 0.8); + scaleMod *= 0.3; + } while (stepSize > 1); + return values; } - + //TODO: Will need to reset entity manager if generation is retried void createAndValidateTopMap(int w, int h, int level, u8 * map, u8 * data) { do { - //reset Entities - (&eManager)->lastSlot[level] = 0; - (&eManager)->entities[level][0] = nullEntity; - + //reset Entities + (&eManager)->lastSlot[level] = 0; + (&eManager)->entities[level][0] = nullEntity; + createTopMap(w, h, level, map, data); int count[256]={[0 ... 255] = 0}; - int i; - for (i = 0; i < w * h; ++i) count[map[i] & 0xff]++; + int i; + for (i = 0; i < w * h; ++i) count[map[i] & 0xff]++; if (count[TILE_ROCK & 0xff] < 100) continue; if (count[TILE_SAND & 0xff] < 100) continue; if (count[TILE_GRASS & 0xff] < 100) continue; if (count[TILE_TREE & 0xff] < 100) continue; if (count[TILE_STAIRS_DOWN & 0xff] < 2) continue; - + return; } while (true); } @@ -88,23 +88,23 @@ void createAndValidateTopMap(int w, int h, int level, u8 * map, u8 * data) { void createAndValidateUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 * data) { do { //reset Entities - (&eManager)->lastSlot[level] = 0; - (&eManager)->entities[level][0] = nullEntity; - + (&eManager)->lastSlot[level] = 0; + (&eManager)->entities[level][0] = nullEntity; + createUndergroundMap(w, h, depthLevel, level, map, data); - + int count[256]={[0 ... 255] = 0}; - int i = 0; - for (i = 0; i < w * h; ++i)count[map[i] & 0xff]++; + int i = 0; + for (i = 0; i < w * h; ++i)count[map[i] & 0xff]++; if (count[TILE_ROCK & 0xff] < 100) continue; if (count[TILE_DIRT & 0xff] < 100) continue; switch(depthLevel){ - case 1: if (count[TILE_IRONORE & 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 1: if (count[TILE_IRONORE & 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; + } if (depthLevel < 3) if (count[TILE_STAIRS_DOWN & 0xff] < 2) continue; - + return; } while (true); } @@ -112,17 +112,17 @@ void createAndValidateUndergroundMap(int w, int h, int depthLevel, int level, u8 void createAndValidateDungeonMap(int w, int h, int level, u8 * map, u8 * data) { do { //reset Entities - (&eManager)->lastSlot[level] = 0; - (&eManager)->entities[level][0] = nullEntity; - + (&eManager)->lastSlot[level] = 0; + (&eManager)->entities[level][0] = nullEntity; + createDungeonMap(w, h, level, map, data); - + int count[256]={[0 ... 255] = 0}; - int i = 0; - for (i = 0; i < w * h; ++i)count[map[i] & 0xff]++; + int i = 0; + for (i = 0; i < w * h; ++i)count[map[i] & 0xff]++; if (count[TILE_DUNGEON_WALL & 0xff] < 100) continue; if (count[TILE_DUNGEON_FLOOR & 0xff] < 100) continue; - + return; } while (true); } @@ -130,35 +130,35 @@ void createAndValidateDungeonMap(int w, int h, int level, u8 * map, u8 * data) { void createAndValidateSkyMap(int w, int h, int level, u8 * map, u8 * data) { do { //reset Entities - (&eManager)->lastSlot[level] = 0; - (&eManager)->entities[level][0] = nullEntity; - + (&eManager)->lastSlot[level] = 0; + (&eManager)->entities[level][0] = nullEntity; + createSkyMap(w, h, level, map, data); - + int count[256]={[0 ... 255] = 0}; - int i = 0; - for (i = 0; i < w * h; ++i)count[map[i] & 0xff]++; + int i = 0; + for (i = 0; i < w * h; ++i)count[map[i] & 0xff]++; if (count[TILE_CLOUD & 0xff] < 1600) continue; if (count[TILE_STAIRS_DOWN & 0xff] < 2) continue; - + return; } while (true); } - - - + + + void createTopMap(int w, int h, int level, u8 * map, u8 * data) { double* mnoise1 = Noise(w, h, 16); double* mnoise2 = Noise(w, h, 16); double* mnoise3 = Noise(w, h, 16); double* noise1 = Noise(w, h, 32); double* noise2 = Noise(w, h, 32); - + int x,y,i,j,k,xx,yy; - + for(x = 0; x < w; ++x){ - for(y = 0; y < w; ++y){ - int i = x + y * w; + for(y = 0; y < w; ++y){ + int i = x + y * w; double val = fabs(noise1[i] - noise2[i]) * 3 - 2; double mval = fabs(mnoise1[i] - mnoise2[i]); @@ -172,7 +172,7 @@ void createTopMap(int w, int h, int level, u8 * map, u8 * data) { dist = dist * dist * dist * dist; dist = dist * dist * dist * dist; val = val + 1 - dist * 20; //-2 before to -21.0 after - + if (val < -0.5) { map[i] = TILE_WATER; } else if (val > 0.5 && mval < -1) { @@ -180,10 +180,10 @@ void createTopMap(int w, int h, int level, u8 * map, u8 * data) { } else { map[i] = TILE_GRASS; } - } - } - - for (i = 0; i < w * h / 2800; ++i) { + } + } + + for (i = 0; i < w * h / 2800; ++i) { int xs = rand()%w; int ys = rand()%h; for (k = 0; k < 10; ++k) { @@ -192,18 +192,18 @@ void createTopMap(int w, int h, int level, u8 * map, u8 * data) { 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 (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_GRASS) map[xx + yy * w] = TILE_SAND; - } - } - } + } + } + } } } - - createVillage(w, h, level, map, data); - - for (i = 0; i < w * h / 400; ++i) { + + createVillage(w, h, level, map, data); + + for (i = 0; i < w * h / 400; ++i) { x = rand()%w; y = rand()%h; for (j = 0; j < 200; ++j) { @@ -216,8 +216,8 @@ void createTopMap(int w, int h, int level, u8 * map, u8 * data) { } } } - - for (i = 0; i < w * h / 800; ++i) { + + for (i = 0; i < w * h / 800; ++i) { x = rand()%w; y = rand()%h; for (j = 0; j < 30;++j) { @@ -229,10 +229,10 @@ void createTopMap(int w, int h, int level, u8 * map, u8 * data) { data[xx + yy * w] = rand()%4; // determines mirroring. } } - + } } - + for (i = 0; i < w * h / 100; ++i) { xx = rand()%w; yy = rand()%h; @@ -242,14 +242,14 @@ void createTopMap(int w, int h, int level, u8 * map, u8 * data) { } } } - - int sCount, attempts = 0; + + int sCount, attempts = 0; for (sCount = 0; sCount < 4;) { xx = rand()%w; yy = rand()%h; if (xx >= 0 && yy >= 0 && xx < w && yy < h) { - if (map[xx + yy * w] == TILE_ROCK) - { + if (map[xx + yy * w] == TILE_ROCK) + { map[xx + yy * w] = TILE_STAIRS_DOWN; map[xx + (yy+1) * w] = TILE_ROCK; map[(xx+1) + yy * w] = TILE_ROCK; @@ -259,40 +259,40 @@ void createTopMap(int w, int h, int level, u8 * map, u8 * data) { map[(xx+1) + (yy+1) * w] = TILE_ROCK; map[(xx+1) + (yy-1) * w] = TILE_ROCK; map[(xx-1) + (yy+1) * w] = TILE_ROCK; - ++sCount; + ++sCount; } } if(attempts < (w*h/100)) ++attempts; else break; } - free(mnoise1); - free(mnoise2); - free(mnoise3); - free(noise1); - free(noise2); - return; + free(mnoise1); + free(mnoise2); + free(mnoise3); + free(noise1); + free(noise2); + return; } void createUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 * data) { double* mnoise1 = Noise(w, h, 16); double* mnoise2 = Noise(w, h, 16); double* mnoise3 = Noise(w, h, 16); - + double* nnoise1 = Noise(w, h, 16); double* nnoise2 = Noise(w, h, 16); double* nnoise3 = Noise(w, h, 16); - + double* wnoise1 = Noise(w, h, 16); double* wnoise2 = Noise(w, h, 16); double* wnoise3 = Noise(w, h, 16); - + double* noise1 = Noise(w, h, 32); double* noise2 = Noise(w, h, 32); - + int x,y,i,j,k,xx,yy; - + for(x = 0; x < w; ++x){ - for(y = 0; y < w; ++y){ - int i = x + y * w; + for(y = 0; y < w; ++y){ + int i = x + y * w; double val = fabs(noise1[i] - noise2[i]) * 3 - 2; @@ -301,7 +301,7 @@ void createUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 double nval = fabs(nnoise1[i] - nnoise2[i]); nval = fabs(nval - nnoise3[i]) * 3 - 2; - + double wval = fabs(wnoise1[i] - wnoise2[i]); wval = fabs(nval - wnoise3[i]) * 3 - 2; @@ -313,7 +313,7 @@ void createUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 dist = dist * dist * dist * dist; dist = dist * dist * dist * dist; val = val + 1 - dist * 20; - + if (val > -2 && wval < -2.0 + (depthLevel) / 2 * 3) { if (depthLevel > 2) map[i] = TILE_LAVA; @@ -324,43 +324,43 @@ void createUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 } else { map[i] = TILE_ROCK; } - } - } - - //generate dwarf house - if(depthLevel==3) { - createDwarfHouse(w, h, level, map, data); - //generate mushroom patches - } 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; - } - } - } - } - } - } - } - } - } - - //generate ores - for (i = 0; i < w * h / 400; ++i) { + } + } + + //generate dwarf house + if(depthLevel==3) { + createDwarfHouse(w, h, level, map, data); + //generate mushroom patches + } 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; + } + } + } + } + } + } + } + } + } + + //generate ores + for (i = 0; i < w * h / 400; ++i) { int x = rand()%w; int y = rand()%h; for(j = 0; j < 30; ++j) { @@ -373,15 +373,15 @@ void createUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 } } } - - //generate stairs down - if (depthLevel < 3){ - int sCount, attempts = 0; + + //generate stairs down + if (depthLevel < 3){ + int sCount, attempts = 0; for (sCount = 0; sCount < 4;) { int xx = rand()%w; int yy = rand()%h; if (xx >= 0 && yy >= 0 && xx < w && yy < h) { - if (map[xx + yy * w] == TILE_ROCK){ + if (map[xx + yy * w] == TILE_ROCK){ map[xx + yy * w] = TILE_STAIRS_DOWN; map[xx + (yy+1) * w] = TILE_ROCK; map[(xx+1) + yy * w] = TILE_ROCK; @@ -392,44 +392,44 @@ void createUndergroundMap(int w, int h, int depthLevel, int level, u8 * map, u8 map[(xx+1) + (yy-1) * w] = TILE_ROCK; map[(xx-1) + (yy+1) * w] = TILE_ROCK; ++sCount; - } + } } if(attempts < (w*h/100)) ++attempts; else break; } - } - - //generate dungeon entrance - if(depthLevel==3) { - map[w/2+0 + (h/2+0) * w] = TILE_DUNGEON_ENTRANCE; - - map[w/2-1 + (h/2+0) * w] = TILE_DIRT; - map[w/2+1 + (h/2+0) * w] = TILE_DIRT; - map[w/2+0 + (h/2-1) * w] = TILE_DIRT; - map[w/2+1 + (h/2+1) * w] = TILE_DIRT; - - map[w/2-1 + (h/2-1) * w] = TILE_DUNGEON_WALL; - map[w/2-1 + (h/2+1) * w] = TILE_DUNGEON_WALL; - map[w/2+1 + (h/2-1) * w] = TILE_DUNGEON_WALL; - map[w/2+1 + (h/2+1) * w] = TILE_DUNGEON_WALL; - } - - free(mnoise1); - free(mnoise2); - free(mnoise3); - free(nnoise1); - free(nnoise2); - free(nnoise3); - free(wnoise1); - free(wnoise2); - free(wnoise3); - free(noise1); - free(noise2); - + } + + //generate dungeon entrance + if(depthLevel==3) { + map[w/2+0 + (h/2+0) * w] = TILE_DUNGEON_ENTRANCE; + + map[w/2-1 + (h/2+0) * w] = TILE_DIRT; + map[w/2+1 + (h/2+0) * w] = TILE_DIRT; + map[w/2+0 + (h/2-1) * w] = TILE_DIRT; + map[w/2+1 + (h/2+1) * w] = TILE_DIRT; + + map[w/2-1 + (h/2-1) * w] = TILE_DUNGEON_WALL; + map[w/2-1 + (h/2+1) * w] = TILE_DUNGEON_WALL; + map[w/2+1 + (h/2-1) * w] = TILE_DUNGEON_WALL; + map[w/2+1 + (h/2+1) * w] = TILE_DUNGEON_WALL; + } + + free(mnoise1); + free(mnoise2); + free(mnoise3); + free(nnoise1); + free(nnoise2); + free(nnoise3); + free(wnoise1); + free(wnoise2); + free(wnoise3); + free(noise1); + free(noise2); + } void createDungeonMap(int w, int h, int level, u8 * map, u8 * data) { - hasNPC = false; - + hasNPC = false; + int i, x, y; for(x = 0; x < w; ++x){ for(y = 0; y < w; ++y){ @@ -438,21 +438,21 @@ void createDungeonMap(int w, int h, int level, u8 * map, u8 * data) { //Startroom if (x >= (w/2-5) && x <= (w/2+5) && y >= (h/2-5) && y <= (h/2+5) ) { map[i] = TILE_DUNGEON_FLOOR; - data[i] = randomTile[rand()%randomTileSize]; + data[i] = randomTile[rand()%randomTileSize]; } else { map[i] = TILE_DUNGEON_WALL; - data[i] = 0; + data[i] = 0; } } } - + //create dragon chamber(only call once and before other rooms) createDungeonRoom(w, h, true, level, map, data); - + for(i = 0; i < 40; ++i) { createDungeonRoom(w, h, false, level, map, data); } - + //replace paths with actual dungeon floor for(x = 0; x < w; ++x){ for(y = 0; y < w; ++y){ @@ -460,19 +460,19 @@ void createDungeonMap(int w, int h, int level, u8 * map, u8 * data) { if (map[i]==255) { map[i] = TILE_DUNGEON_FLOOR; - data[i] = randomTile[rand()%randomTileSize]; + data[i] = randomTile[rand()%randomTileSize]; } } } - + //create entrance map[w/2 + h/2 * w] = TILE_DUNGEON_ENTRANCE; - + map[w/2+1 + h/2 * w] = TILE_DUNGEON_FLOOR; map[w/2-1 + h/2 * w] = TILE_DUNGEON_FLOOR; map[w/2 + (h/2+1) * w] = TILE_DUNGEON_FLOOR; map[w/2 + (h/2-1) * w] = TILE_DUNGEON_FLOOR; - + map[w/2+1 + (h/2+1) * w] = TILE_DUNGEON_WALL; map[w/2+1 + (h/2-1) * w] = TILE_DUNGEON_WALL; map[w/2-1 + (h/2+1) * w] = TILE_DUNGEON_WALL; @@ -498,7 +498,7 @@ void createSkyMap(int w, int h, int level, u8 * map, u8 * data) { dist = dist * dist * dist * dist; val = -val * 1 - 2.2; val = val + 1 - dist * 20; - + if (val < -0.25) { map[i] = -1; // render nothing } else { @@ -519,7 +519,7 @@ void createSkyMap(int w, int h, int level, u8 * map, u8 * data) { int xx = rand()%w; int yy = rand()%h; if (xx >= 0 && yy >= 0 && xx < w && yy < h) { - if (map[xx + yy * w] == TILE_CLOUD) + if (map[xx + yy * w] == TILE_CLOUD) { map[xx + yy * w] = TILE_STAIRS_DOWN; map[xx + (yy+1) * w] = TILE_CLOUD; @@ -541,195 +541,195 @@ void createSkyMap(int w, int h, int level, u8 * map, u8 * data) { //"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; triesx) { - 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(pxx) { + 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 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; @@ -767,17 +767,17 @@ void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data 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]; + data[i] = randomTile[rand()%randomTileSize]; } } - + //Create path back to existing stuff xp = x + wr/2; yp = y + hr/2; @@ -789,7 +789,7 @@ void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data //make connection map[i] = 255; } - + //move if(xFirst) { if(xp > w/2) --xp; @@ -804,30 +804,30 @@ void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data 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; @@ -835,20 +835,20 @@ void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data 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; + 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 && xry && yrx && xry && yrtype == ENTITY_MAGIC_PILLAR) { ++pcount; } @@ -866,13 +866,12 @@ void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data } continue; } - + if(rand()%50==0) map[i] = TILE_IRONORE + (rand()%3); } } } - + break; } } - diff --git a/source/MapGen.h b/source/MapGen.h index 22fe6e3..8e11015 100755 --- a/source/MapGen.h +++ b/source/MapGen.h @@ -26,4 +26,4 @@ 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); \ No newline at end of file +void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data); diff --git a/source/Menu.c b/source/Menu.c index 2b37975..d150bbf 100755 --- a/source/Menu.c +++ b/source/Menu.c @@ -9,12 +9,12 @@ char setOptions[][24] = {"Rebind Buttons", "Texture packs", "Test Features: ", // Rebind buttons menu (Settings) int keys[] = { - KEY_A,KEY_B,KEY_X,KEY_Y, - KEY_CPAD_UP,KEY_CPAD_DOWN,KEY_CPAD_LEFT,KEY_CPAD_RIGHT, - KEY_DUP, KEY_DDOWN, KEY_DLEFT, KEY_DRIGHT, - KEY_CSTICK_UP,KEY_CSTICK_DOWN,KEY_CSTICK_LEFT,KEY_CSTICK_RIGHT, - KEY_L,KEY_R,KEY_ZL,KEY_ZR, - KEY_START,KEY_SELECT + KEY_A,KEY_B,KEY_X,KEY_Y, + KEY_CPAD_UP,KEY_CPAD_DOWN,KEY_CPAD_LEFT,KEY_CPAD_RIGHT, + KEY_DUP, KEY_DDOWN, KEY_DLEFT, KEY_DRIGHT, + KEY_CSTICK_UP,KEY_CSTICK_DOWN,KEY_CSTICK_LEFT,KEY_CSTICK_RIGHT, + KEY_L,KEY_R,KEY_ZL,KEY_ZR, + KEY_START,KEY_SELECT }; int keyProp[12] = {[0 ... 11] = 0}; bool areYouSure = false; @@ -45,236 +45,236 @@ s16 tpFileCount = 0; s8 isLoadingTP = 0; void readFiles(){ - memset(&fileNames, 0, sizeof(fileNames)); // reset fileNames - worldFileCount = 0; - DIR * d; - struct dirent * dir; - d = opendir("."); - if (d){ - while ((dir = readdir(d)) != NULL) { - if (strncmp(dir->d_name+strlen(dir->d_name)-4, ".msv", 4) == 0) { // Check if filename contains ".msv" - strncpy(fileNames[worldFileCount], dir->d_name, strlen(dir->d_name)-4); - //TODO: This no longer works, update for new format: - //FILE * file = fopen(dir->d_name, "rb"); - //fread(&fileScore[worldFileCount],sizeof(int), 1, file); - //fread(&fileWin[worldFileCount],sizeof(bool), 1, file); - //fclose(file); - fileScore[worldFileCount] = 0; - fileWin[worldFileCount] = false; - - ++worldFileCount; - } - } - closedir(d); - } + memset(&fileNames, 0, sizeof(fileNames)); // reset fileNames + worldFileCount = 0; + DIR * d; + struct dirent * dir; + d = opendir("."); + if (d){ + while ((dir = readdir(d)) != NULL) { + if (strncmp(dir->d_name+strlen(dir->d_name)-4, ".msv", 4) == 0) { // Check if filename contains ".msv" + strncpy(fileNames[worldFileCount], dir->d_name, strlen(dir->d_name)-4); + //TODO: This no longer works, update for new format: + //FILE * file = fopen(dir->d_name, "rb"); + //fread(&fileScore[worldFileCount],sizeof(int), 1, file); + //fread(&fileWin[worldFileCount],sizeof(bool), 1, file); + //fclose(file); + fileScore[worldFileCount] = 0; + fileWin[worldFileCount] = false; + + ++worldFileCount; + } + } + closedir(d); + } } void readTPFiles(){ - memset(&tpFileNames, 0, sizeof(tpFileNames)); // reset tp fileNames - memset(&tpFileComment, 0, sizeof(tpFileComment)); // reset zip comments - tpFileCount = 1; // 0 = default. - DIR * d; - struct dirent * dir; - d = opendir("./texturepacks/"); - if (d){ - while ((dir = readdir(d)) != NULL) { - if (strstr(dir->d_name, ".zip") != NULL) { // Check if filename contains ".zip" - strncpy(tpFileNames[tpFileCount], dir->d_name, strlen(dir->d_name)-4); - - char fullDirName[256]; - sprintf(fullDirName,"./texturepacks/%s",dir->d_name); - //int err = - getTexturePackComment(fullDirName, tpFileComment[tpFileCount]); - /* - if(err > 0){ - char errorText[10]; - sprintf(errorText,"err:%d",err); - strncpy(tpFileComment[tpFileCount], errorText, strlen(errorText)); - }*/ - ++tpFileCount; - } - } - closedir(d); - } + memset(&tpFileNames, 0, sizeof(tpFileNames)); // reset tp fileNames + memset(&tpFileComment, 0, sizeof(tpFileComment)); // reset zip comments + tpFileCount = 1; // 0 = default. + DIR * d; + struct dirent * dir; + d = opendir("./texturepacks/"); + if (d){ + while ((dir = readdir(d)) != NULL) { + if (strstr(dir->d_name, ".zip") != NULL) { // Check if filename contains ".zip" + strncpy(tpFileNames[tpFileCount], dir->d_name, strlen(dir->d_name)-4); + + char fullDirName[256]; + sprintf(fullDirName,"./texturepacks/%s",dir->d_name); + //int err = + getTexturePackComment(fullDirName, tpFileComment[tpFileCount]); + /* + if(err > 0){ + char errorText[10]; + sprintf(errorText,"err:%d",err); + strncpy(tpFileComment[tpFileCount], errorText, strlen(errorText)); + }*/ + ++tpFileCount; + } + } + closedir(d); + } } s8 checkFileNameForErrors(){ - int length = strlen(fileNames[worldFileCount]); - if(length < 1)return 1; // Error: Length cannot be 0. - int i; - bool isGood = false; - for(i=0; i < length; ++i){ if(isalnum((int)fileNames[worldFileCount][i])) isGood = true; } - if(!isGood) return 2; // Error: Filename must contain atleast one letter or number. - - DIR * d; - struct dirent * dir; - d = opendir("."); - if (d){ - while ((dir = readdir(d)) != NULL) { - if (strstr(dir->d_name, ".msv") != NULL) { // Check if filename contains ".msv" - char cmprFile[256]; - strncpy(cmprFile, dir->d_name, strlen(dir->d_name)-4); - if(strncmp(fileNames[worldFileCount],cmprFile,strlen(fileNames[worldFileCount])) == 0) return 3; // Error: Filename cannot already exist. - } - } - closedir(d); - } - - return 0; // No errors found! + int length = strlen(fileNames[worldFileCount]); + if(length < 1)return 1; // Error: Length cannot be 0. + int i; + bool isGood = false; + for(i=0; i < length; ++i){ if(isalnum((int)fileNames[worldFileCount][i])) isGood = true; } + if(!isGood) return 2; // Error: Filename must contain atleast one letter or number. + + DIR * d; + struct dirent * dir; + d = opendir("."); + if (d){ + while ((dir = readdir(d)) != NULL) { + if (strstr(dir->d_name, ".msv") != NULL) { // Check if filename contains ".msv" + char cmprFile[256]; + strncpy(cmprFile, dir->d_name, strlen(dir->d_name)-4); + if(strncmp(fileNames[worldFileCount],cmprFile,strlen(fileNames[worldFileCount])) == 0) return 3; // Error: Filename cannot already exist. + } + } + closedir(d); + } + + return 0; // No errors found! } void addToFileName(char * c){ - strncat(fileNames[worldFileCount], c, 1); + strncat(fileNames[worldFileCount], c, 1); } /* Keypad */ void doTouchButton(){ - int xVal = localInputs.k_touch.px, yVal = localInputs.k_touch.py; - int strLength = strlen(fileNames[worldFileCount]); - if(yVal >= 60 && yVal < 80){ // 0 to 9 - if(xVal >= 4 && xVal < 4+16){ touchX = 4; if(strLength < 24)addToFileName("1");} - else if(xVal >= 36 && xVal < 4+32+16){ touchX = 36; if(strLength < 24)addToFileName("2");} - else if(xVal >= 68 && xVal < 4+64+16){ touchX = 68; if(strLength < 24)addToFileName("3");} - else if(xVal >= 100 && xVal < 4+96+16){ touchX = 100; if(strLength < 24)addToFileName("4");} - else if(xVal >= 132 && xVal < 4+128+16){ touchX = 132; if(strLength < 24)addToFileName("5");} - else if(xVal >= 164 && xVal < 4+160+16){ touchX = 164; if(strLength < 24)addToFileName("6");} - else if(xVal >= 196 && xVal < 4+192+16){ touchX = 196; if(strLength < 24)addToFileName("7");} - else if(xVal >= 228 && xVal < 4+224+16){ touchX = 228; if(strLength < 24)addToFileName("8");} - else if(xVal >= 260 && xVal < 4+256+16){ touchX = 260; if(strLength < 24)addToFileName("9");} - else if(xVal >= 292 && xVal < 4+288+16){ touchX = 292; if(strLength < 24)addToFileName("0");} - else return; - touchY = 56; - touchW = 22; - touchH = 22; - touchDelay = 6; - isTouching = true; - } else if(yVal >= 80 && yVal < 100){ // Q to P - if(xVal >= 4 && xVal < 4+16){ touchX = 4; if(strLength < 24)addToFileName("Q");} - else if(xVal >= 36 && xVal < 4+32+16){ touchX = 36; if(strLength < 24)addToFileName("W");} - else if(xVal >= 68 && xVal < 4+64+16){ touchX = 68; if(strLength < 24)addToFileName("E");} - else if(xVal >= 100 && xVal < 4+96+16){ touchX = 100; if(strLength < 24)addToFileName("R");} - else if(xVal >= 132 && xVal < 4+128+16){ touchX = 132; if(strLength < 24)addToFileName("T");} - else if(xVal >= 164 && xVal < 4+160+16){ touchX = 164; if(strLength < 24)addToFileName("Y");} - else if(xVal >= 196 && xVal < 4+192+16){ touchX = 196; if(strLength < 24)addToFileName("U");} - else if(xVal >= 228 && xVal < 4+224+16){ touchX = 228; if(strLength < 24)addToFileName("I");} - else if(xVal >= 260 && xVal < 4+256+16){ touchX = 260; if(strLength < 24)addToFileName("O");} - else if(xVal >= 292 && xVal < 4+288+16){ touchX = 292; if(strLength < 24)addToFileName("P");} - else return; - touchY = 76; - touchW = 22; - touchH = 22; - touchDelay = 6; - isTouching = true; - } else if(yVal >= 100 && yVal < 120){ // A to L - if(xVal >= 20 && xVal < 36){ touchX = 20; if(strLength < 24)addToFileName("A");} - else if(xVal >= 52 && xVal < 68){ touchX = 52; if(strLength < 24)addToFileName("S");} - else if(xVal >= 84 && xVal < 100){ touchX = 84; if(strLength < 24)addToFileName("D");} - else if(xVal >= 116 && xVal < 132){ touchX = 116; if(strLength < 24)addToFileName("F");} - else if(xVal >= 148 && xVal < 164){ touchX = 148; if(strLength < 24)addToFileName("G");} - else if(xVal >= 180 && xVal < 196){ touchX = 180; if(strLength < 24)addToFileName("H");} - else if(xVal >= 212 && xVal < 230){ touchX = 212; if(strLength < 24)addToFileName("J");} - else if(xVal >= 244 && xVal < 262){ touchX = 244; if(strLength < 24)addToFileName("K");} - else if(xVal >= 276 && xVal < 294){ touchX = 276; if(strLength < 24)addToFileName("L");} - else return; - touchY = 96; - touchW = 22; - touchH = 22; - touchDelay = 6; - isTouching = true; - } else if(yVal >= 120 && yVal < 140){ // Z to M - if(xVal >= 52 && xVal < 68){ touchX = 52; if(strLength < 24)addToFileName("Z");} - else if(xVal >= 84 && xVal < 100){ touchX = 84; if(strLength < 24)addToFileName("X");} - else if(xVal >= 116 && xVal < 132){ touchX = 116; if(strLength < 24)addToFileName("C");} - else if(xVal >= 148 && xVal < 164){ touchX = 148; if(strLength < 24)addToFileName("V");} - else if(xVal >= 180 && xVal < 196){ touchX = 180; if(strLength < 24)addToFileName("B");} - else if(xVal >= 212 && xVal < 230){ touchX = 212; if(strLength < 24)addToFileName("N");} - else if(xVal >= 244 && xVal < 262){ touchX = 244; if(strLength < 24)addToFileName("M");} - else return; - touchY = 116; - touchW = 22; - touchH = 22; - touchDelay = 6; - isTouching = true; - } else if(yVal >= 140 && yVal < 160){ // SPACE and BACKSPACE - if(xVal >= 32 && xVal < 112){ - touchX = 32; - touchW = 16*5+14; - if(strLength < 24)addToFileName("_"); // Underscores don't appear in the game. - } - else if(xVal >= 148 && xVal < 262){ - if(strLength <= 0) return; - touchX = 148; - touchW = 16*9+8; - fileNames[worldFileCount][strLength-1] = '\0'; - } - else return; - touchY = 136; - touchH = 22; - touchDelay = 6; - isTouching = true; - } - errorFileName = 0; + int xVal = localInputs.k_touch.px, yVal = localInputs.k_touch.py; + int strLength = strlen(fileNames[worldFileCount]); + if(yVal >= 60 && yVal < 80){ // 0 to 9 + if(xVal >= 4 && xVal < 4+16){ touchX = 4; if(strLength < 24)addToFileName("1");} + else if(xVal >= 36 && xVal < 4+32+16){ touchX = 36; if(strLength < 24)addToFileName("2");} + else if(xVal >= 68 && xVal < 4+64+16){ touchX = 68; if(strLength < 24)addToFileName("3");} + else if(xVal >= 100 && xVal < 4+96+16){ touchX = 100; if(strLength < 24)addToFileName("4");} + else if(xVal >= 132 && xVal < 4+128+16){ touchX = 132; if(strLength < 24)addToFileName("5");} + else if(xVal >= 164 && xVal < 4+160+16){ touchX = 164; if(strLength < 24)addToFileName("6");} + else if(xVal >= 196 && xVal < 4+192+16){ touchX = 196; if(strLength < 24)addToFileName("7");} + else if(xVal >= 228 && xVal < 4+224+16){ touchX = 228; if(strLength < 24)addToFileName("8");} + else if(xVal >= 260 && xVal < 4+256+16){ touchX = 260; if(strLength < 24)addToFileName("9");} + else if(xVal >= 292 && xVal < 4+288+16){ touchX = 292; if(strLength < 24)addToFileName("0");} + else return; + touchY = 56; + touchW = 22; + touchH = 22; + touchDelay = 6; + isTouching = true; + } else if(yVal >= 80 && yVal < 100){ // Q to P + if(xVal >= 4 && xVal < 4+16){ touchX = 4; if(strLength < 24)addToFileName("Q");} + else if(xVal >= 36 && xVal < 4+32+16){ touchX = 36; if(strLength < 24)addToFileName("W");} + else if(xVal >= 68 && xVal < 4+64+16){ touchX = 68; if(strLength < 24)addToFileName("E");} + else if(xVal >= 100 && xVal < 4+96+16){ touchX = 100; if(strLength < 24)addToFileName("R");} + else if(xVal >= 132 && xVal < 4+128+16){ touchX = 132; if(strLength < 24)addToFileName("T");} + else if(xVal >= 164 && xVal < 4+160+16){ touchX = 164; if(strLength < 24)addToFileName("Y");} + else if(xVal >= 196 && xVal < 4+192+16){ touchX = 196; if(strLength < 24)addToFileName("U");} + else if(xVal >= 228 && xVal < 4+224+16){ touchX = 228; if(strLength < 24)addToFileName("I");} + else if(xVal >= 260 && xVal < 4+256+16){ touchX = 260; if(strLength < 24)addToFileName("O");} + else if(xVal >= 292 && xVal < 4+288+16){ touchX = 292; if(strLength < 24)addToFileName("P");} + else return; + touchY = 76; + touchW = 22; + touchH = 22; + touchDelay = 6; + isTouching = true; + } else if(yVal >= 100 && yVal < 120){ // A to L + if(xVal >= 20 && xVal < 36){ touchX = 20; if(strLength < 24)addToFileName("A");} + else if(xVal >= 52 && xVal < 68){ touchX = 52; if(strLength < 24)addToFileName("S");} + else if(xVal >= 84 && xVal < 100){ touchX = 84; if(strLength < 24)addToFileName("D");} + else if(xVal >= 116 && xVal < 132){ touchX = 116; if(strLength < 24)addToFileName("F");} + else if(xVal >= 148 && xVal < 164){ touchX = 148; if(strLength < 24)addToFileName("G");} + else if(xVal >= 180 && xVal < 196){ touchX = 180; if(strLength < 24)addToFileName("H");} + else if(xVal >= 212 && xVal < 230){ touchX = 212; if(strLength < 24)addToFileName("J");} + else if(xVal >= 244 && xVal < 262){ touchX = 244; if(strLength < 24)addToFileName("K");} + else if(xVal >= 276 && xVal < 294){ touchX = 276; if(strLength < 24)addToFileName("L");} + else return; + touchY = 96; + touchW = 22; + touchH = 22; + touchDelay = 6; + isTouching = true; + } else if(yVal >= 120 && yVal < 140){ // Z to M + if(xVal >= 52 && xVal < 68){ touchX = 52; if(strLength < 24)addToFileName("Z");} + else if(xVal >= 84 && xVal < 100){ touchX = 84; if(strLength < 24)addToFileName("X");} + else if(xVal >= 116 && xVal < 132){ touchX = 116; if(strLength < 24)addToFileName("C");} + else if(xVal >= 148 && xVal < 164){ touchX = 148; if(strLength < 24)addToFileName("V");} + else if(xVal >= 180 && xVal < 196){ touchX = 180; if(strLength < 24)addToFileName("B");} + else if(xVal >= 212 && xVal < 230){ touchX = 212; if(strLength < 24)addToFileName("N");} + else if(xVal >= 244 && xVal < 262){ touchX = 244; if(strLength < 24)addToFileName("M");} + else return; + touchY = 116; + touchW = 22; + touchH = 22; + touchDelay = 6; + isTouching = true; + } else if(yVal >= 140 && yVal < 160){ // SPACE and BACKSPACE + if(xVal >= 32 && xVal < 112){ + touchX = 32; + touchW = 16*5+14; + if(strLength < 24)addToFileName("_"); // Underscores don't appear in the game. + } + else if(xVal >= 148 && xVal < 262){ + if(strLength <= 0) return; + touchX = 148; + touchW = 16*9+8; + fileNames[worldFileCount][strLength-1] = '\0'; + } + else return; + touchY = 136; + touchH = 22; + touchDelay = 6; + isTouching = true; + } + errorFileName = 0; } void switchGameBut(bool left, int buttonID){ - int id; - for(id = 0; id < 7; ++id){ - if(keyProp[id] & buttonID){ - keyProp[id] ^= buttonID; // Toggle buttonID bit - if(left){ - int id2 = id -1; - if (id2 < 0) return; - keyProp[id2] ^= buttonID; - } else { - int id2 = id+1; - if (id2 > 6) return; - keyProp[id2] ^= buttonID; - } - return; - } - } - if(left) keyProp[6] ^= buttonID; - else keyProp[0] ^= buttonID; - + int id; + for(id = 0; id < 7; ++id){ + if(keyProp[id] & buttonID){ + keyProp[id] ^= buttonID; // Toggle buttonID bit + if(left){ + int id2 = id -1; + if (id2 < 0) return; + keyProp[id2] ^= buttonID; + } else { + int id2 = id+1; + if (id2 > 6) return; + keyProp[id2] ^= buttonID; + } + return; + } + } + if(left) keyProp[6] ^= buttonID; + else keyProp[0] ^= buttonID; + } void switchMenuBut(bool left, int buttonID){ - int id; - for(id = 0; id < 12; ++id){ - if(id > 3 && id < 7) continue; - if(keyProp[id] & buttonID){ - keyProp[id] ^= buttonID; // Toggle buttonID bit - if(left){ - int id2 = id - 1; - if (id2 == 6) id2 = 3; - if (id2 < 0) return; - keyProp[id2] ^= buttonID; - } else { - int id2 = id+1; - if (id2 == 4) id2 = 7; - if (id2 > 11) return; - keyProp[id2] ^= buttonID; - } - return; - } - } - if(left) keyProp[11] ^= buttonID; - else keyProp[0] ^= buttonID; + int id; + for(id = 0; id < 12; ++id){ + if(id > 3 && id < 7) continue; + if(keyProp[id] & buttonID){ + keyProp[id] ^= buttonID; // Toggle buttonID bit + if(left){ + int id2 = id - 1; + if (id2 == 6) id2 = 3; + if (id2 < 0) return; + keyProp[id2] ^= buttonID; + } else { + int id2 = id+1; + if (id2 == 4) id2 = 7; + if (id2 > 11) return; + keyProp[id2] ^= buttonID; + } + return; + } + } + if(left) keyProp[11] ^= buttonID; + else keyProp[0] ^= buttonID; } s8 checkPropButtons(){ - if(keyProp[0] == 0) return 0; - if(keyProp[1] == 0) return 1; - if(keyProp[2] == 0) return 2; - if(keyProp[3] == 0) return 3; - if(keyProp[4] == 0) return 4; - if(keyProp[5] == 0) return 5; - if(keyProp[6] == 0) return 6; - if(keyProp[7] == 0) return 7; - if(keyProp[8] == 0) return 8; - if(keyProp[9] == 0) return 9; - if(keyProp[10] == 0) return 10; - if(keyProp[11] == 0) return 11; - return -1; + if(keyProp[0] == 0) return 0; + if(keyProp[1] == 0) return 1; + if(keyProp[2] == 0) return 2; + if(keyProp[3] == 0) return 3; + if(keyProp[4] == 0) return 4; + if(keyProp[5] == 0) return 5; + if(keyProp[6] == 0) return 6; + if(keyProp[7] == 0) return 7; + if(keyProp[8] == 0) return 8; + if(keyProp[9] == 0) return 9; + if(keyProp[10] == 0) return 10; + if(keyProp[11] == 0) return 11; + return -1; } bool menuHasMapLoaded = false; @@ -284,292 +284,292 @@ float menuxa = 0; float menuya = 0; void initMenus() { readFiles(); - + if(worldFileCount>0) { memset(¤tFileName, 0, 255); // reset currentFileName - sprintf(currentFileName,"%s.msv",fileNames[currentSelection]); - + sprintf(currentFileName,"%s.msv",fileNames[currentSelection]); + initBGMap = 1; } else { initBGMap = 2; } - + menuHasMapLoaded = true; - while(menuxa==0) menuxa = (rand()%3 - 1) * 0.25; + while(menuxa==0) menuxa = (rand()%3 - 1) * 0.25; while(menuya==0) menuya = (rand()%3 - 1) * 0.25; } Item median; void tickMenu(int menu){ - switch(menu){ - case MENU_SETTINGS_REBIND: - if(!bindOpt){ - if(!selBut){ - if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection=21;} - if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection > 21)currentSelection=0;} - if (localInputs.k_left.clicked){ left = true;} - if (localInputs.k_right.clicked){ left = false;} - } else { - if (localInputs.k_left.clicked){ - if(left)switchGameBut(true,keys[currentSelection]); - else switchMenuBut(true,keys[currentSelection]); - } else if (localInputs.k_right.clicked) { - if(left)switchGameBut(false,keys[currentSelection]); - else switchMenuBut(false,keys[currentSelection]); - } - } - - if (localInputs.k_accept.clicked) selBut = !selBut; - if (localInputs.k_decline.clicked){ - bindOpt = true; - curSaveSel = 0; - } - } else { - if (localInputs.k_up.clicked){ --curSaveSel; if(curSaveSel < 0)curSaveSel=2;} - if (localInputs.k_down.clicked){ ++curSaveSel; if(curSaveSel > 2)curSaveSel=0;} - if (localInputs.k_decline.clicked){ - bindOpt = false; - errorBut = -1; - } - if (localInputs.k_accept.clicked){ - switch(curSaveSel){ - case 0: // Exit and save - if(checkPropButtons() == -1){ - localInputs.k_up.input = keyProp[0]; - localInputs.k_down.input = keyProp[1]; - localInputs.k_left.input = keyProp[2]; - localInputs.k_right.input = keyProp[3]; - localInputs.k_attack.input = keyProp[4]; - localInputs.k_menu.input = keyProp[5]; - localInputs.k_pause.input = keyProp[6]; - localInputs.k_accept.input = keyProp[7]; - localInputs.k_decline.input = keyProp[8]; - localInputs.k_delete.input = keyProp[9]; - localInputs.k_menuNext.input = keyProp[10]; - localInputs.k_menuPrev.input = keyProp[11]; - - FILE *fs=fopen("btnSave.bin","wb"); - fwrite(keyProp,sizeof(int),12,fs); - fclose(fs); - - currentSelection = 0; - currentMenu = MENU_SETTINGS; - errorBut = -1; - } else errorBut = checkPropButtons(); - break; - case 1: // Exit and DON'T save - currentSelection = 0; - currentMenu = MENU_SETTINGS; - errorBut = -1; - break; - case 2: // reset defaults - keyProp[0] = KEY_DUP | KEY_CPAD_UP | KEY_CSTICK_UP; - keyProp[1] = KEY_DDOWN | KEY_CPAD_DOWN | KEY_CSTICK_DOWN; - keyProp[2] = KEY_DLEFT | KEY_CPAD_LEFT | KEY_CSTICK_LEFT; - keyProp[3] = KEY_DRIGHT | KEY_CPAD_RIGHT | KEY_CSTICK_RIGHT; - keyProp[4] = KEY_A | KEY_B | KEY_L | KEY_ZR; - keyProp[5] = KEY_X | KEY_Y | KEY_R | KEY_ZL; - keyProp[6] = KEY_START; - keyProp[7] = KEY_A; - keyProp[8] = KEY_B; - keyProp[9] = KEY_X; - keyProp[10] = KEY_R; - keyProp[11] = KEY_L; - bindOpt = false; - errorBut = -1; - break; - } - } - } - break; - - case MENU_ABOUT: - if (localInputs.k_decline.clicked) currentMenu = MENU_TITLE; - break; + switch(menu){ + case MENU_SETTINGS_REBIND: + if(!bindOpt){ + if(!selBut){ + if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection=21;} + if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection > 21)currentSelection=0;} + if (localInputs.k_left.clicked){ left = true;} + if (localInputs.k_right.clicked){ left = false;} + } else { + if (localInputs.k_left.clicked){ + if(left)switchGameBut(true,keys[currentSelection]); + else switchMenuBut(true,keys[currentSelection]); + } else if (localInputs.k_right.clicked) { + if(left)switchGameBut(false,keys[currentSelection]); + else switchMenuBut(false,keys[currentSelection]); + } + } + + if (localInputs.k_accept.clicked) selBut = !selBut; + if (localInputs.k_decline.clicked){ + bindOpt = true; + curSaveSel = 0; + } + } else { + if (localInputs.k_up.clicked){ --curSaveSel; if(curSaveSel < 0)curSaveSel=2;} + if (localInputs.k_down.clicked){ ++curSaveSel; if(curSaveSel > 2)curSaveSel=0;} + if (localInputs.k_decline.clicked){ + bindOpt = false; + errorBut = -1; + } + if (localInputs.k_accept.clicked){ + switch(curSaveSel){ + case 0: // Exit and save + if(checkPropButtons() == -1){ + localInputs.k_up.input = keyProp[0]; + localInputs.k_down.input = keyProp[1]; + localInputs.k_left.input = keyProp[2]; + localInputs.k_right.input = keyProp[3]; + localInputs.k_attack.input = keyProp[4]; + localInputs.k_menu.input = keyProp[5]; + localInputs.k_pause.input = keyProp[6]; + localInputs.k_accept.input = keyProp[7]; + localInputs.k_decline.input = keyProp[8]; + localInputs.k_delete.input = keyProp[9]; + localInputs.k_menuNext.input = keyProp[10]; + localInputs.k_menuPrev.input = keyProp[11]; + + FILE *fs=fopen("btnSave.bin","wb"); + fwrite(keyProp,sizeof(int),12,fs); + fclose(fs); + + currentSelection = 0; + currentMenu = MENU_SETTINGS; + errorBut = -1; + } else errorBut = checkPropButtons(); + break; + case 1: // Exit and DON'T save + currentSelection = 0; + currentMenu = MENU_SETTINGS; + errorBut = -1; + break; + case 2: // reset defaults + keyProp[0] = KEY_DUP | KEY_CPAD_UP | KEY_CSTICK_UP; + keyProp[1] = KEY_DDOWN | KEY_CPAD_DOWN | KEY_CSTICK_DOWN; + keyProp[2] = KEY_DLEFT | KEY_CPAD_LEFT | KEY_CSTICK_LEFT; + keyProp[3] = KEY_DRIGHT | KEY_CPAD_RIGHT | KEY_CSTICK_RIGHT; + keyProp[4] = KEY_A | KEY_B; + keyProp[5] = KEY_X | KEY_Y; + keyProp[6] = KEY_START; + keyProp[7] = KEY_A; + keyProp[8] = KEY_B; + keyProp[9] = KEY_X; + keyProp[10] = KEY_R | KEY_ZR; + keyProp[11] = KEY_L | KEY_ZL; + bindOpt = false; + errorBut = -1; + break; + } + } + } + break; + + case MENU_ABOUT: + if (localInputs.k_decline.clicked) currentMenu = MENU_TITLE; + break; /* case MENU_ARMOR: - if (k_delete.clicked || k_decline.clicked){ - currentMenu = MENU_NONE; - player.p.activeItem = &noItem; - player.p.isCarrying = false; - } - if (k_accept.clicked){ // Select item from inventory - if(player.p.inv->lastSlot!=0){ - median = player.p.inv->items[curInvSel]; // create copy of item. - removeItemFromInventory(curInvSel, player.p.inv); // remove original - pushItemToInventoryFront(median, player.p.inv); // add copy to front + if (k_delete.clicked || k_decline.clicked){ + currentMenu = MENU_NONE; + player.p.activeItem = &noItem; + player.p.isCarrying = false; + } + if (k_accept.clicked){ // Select item from inventory + if(player.p.inv->lastSlot!=0){ + median = player.p.inv->items[curInvSel]; // create copy of item. + removeItemFromInventory(curInvSel, player.p.inv); // remove original + pushItemToInventoryFront(median, player.p.inv); // add copy to front playerSetActiveItem(&player.p.inv->items[0]); // active item = copy. - } - currentMenu = MENU_NONE; - } - if (k_up.clicked){ --curInvSel; if(curInvSel < 0)curInvSel=player.p.inv->lastSlot-1;} - if (k_down.clicked){ ++curInvSel; if(curInvSel > player.p.inv->lastSlot-1)curInvSel=0;} - break; + } + currentMenu = MENU_NONE; + } + if (k_up.clicked){ --curInvSel; if(curInvSel < 0)curInvSel=player.p.inv->lastSlot-1;} + if (k_down.clicked){ ++curInvSel; if(curInvSel > player.p.inv->lastSlot-1)curInvSel=0;} + break; */ - - case MENU_LOADGAME: - if(!enteringName && !areYouSure){ // World select - if (localInputs.k_decline.clicked){ - if(toMultiplayer) { - currentMenu = MENU_MULTIPLAYER_HOST; - } else { - currentMenu = MENU_TITLE; - currentSelection = 0; - } - } - if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection = worldFileCount;} - if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection > worldFileCount)currentSelection=0;} - - if(localInputs.k_delete.clicked){ - if(currentSelection < worldFileCount) areYouSure = true; - } - - if(localInputs.k_accept.clicked){ - if(currentSelection == worldFileCount){ - - enteringName = true; - } else { - memset(¤tFileName, 0, 255); // reset currentFileName - sprintf(currentFileName, "%s.msv", fileNames[currentSelection]); - playSound(snd_test); - if(toMultiplayer) { - initMPGame = 2; - } else { - initGame = 1; - } - currentMenu = MENU_LOADING; - } - } - } else if (areYouSure){ - if (localInputs.k_decline.clicked || localInputs.k_delete.clicked) areYouSure = false; - if (localInputs.k_accept.clicked){ - sprintf(currentFileName,"%s.msv",fileNames[currentSelection]); - remove(currentFileName); - readFiles(); - enteringName = false; - areYouSure = false; - memset(¤tFileName, 0, 255); // reset currentFileName - } - } else { // Enter new world name. - if(localInputs.k_decline.clicked) enteringName = false; - if(localInputs.k_accept.clicked && errorFileName == 0){ - errorFileName = checkFileNameForErrors(); - if(errorFileName == 0){ // If no errors are found with the filename, then start a new game! - memset(¤tFileName, 0, 255); // reset currentFileName - sprintf(currentFileName, "%s.msv", fileNames[worldFileCount]); - currentMenu = MENU_LOADING; - playSound(snd_test); - if(toMultiplayer) { - initMPGame = 2; - } else { - initGame = 1; - } - ++worldFileCount; - currentMenu = MENU_LOADING; - } - } - if((localInputs.k_touch.px != 0 || localInputs.k_touch.py != 0) && touchDelay == 0){ - if(!isTouching)doTouchButton(); - } - else if(localInputs.k_touch.px == 0 || localInputs.k_touch.py == 0) isTouching = false; - if(touchDelay > 0) --touchDelay; - } - break; - case MENU_SETTINGS_TP: - - if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection = tpFileCount-1;} - if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection > tpFileCount-1)currentSelection=0;} - if (localInputs.k_decline.clicked){ - if(isLoadingTP < 1){ - currentMenu = MENU_SETTINGS; - currentSelection = 1; - } - } - if (localInputs.k_accept.clicked){ - - if(currentSelection > 0){ - isLoadingTP = 4; - } else { - icons = sfil_load_PNG_buffer(icons2_png, SF2D_PLACE_RAM); - reloadColors(); - font = sfil_load_PNG_buffer(Font_png, SF2D_PLACE_RAM); - bottombg = sfil_load_PNG_buffer(bottombg_png, SF2D_PLACE_RAM); - currentMenu = MENU_SETTINGS; - currentSelection = 1; - remove("lastTP.bin"); - } - } - break; - - case MENU_SETTINGS: - if (localInputs.k_up.clicked){ - --currentSelection; - if(currentSelection == 3 && !((MODEL_3DS & 6) != 0)) --currentSelection; - if(currentSelection < 0)currentSelection=4; - } - if (localInputs.k_down.clicked){ - ++currentSelection; - if(currentSelection == 3 && !((MODEL_3DS & 6) != 0)) ++currentSelection; - if(currentSelection > 4)currentSelection=0; - } - if(localInputs.k_decline.clicked){ - currentMenu = MENU_TITLE; - currentSelection = 4; - } - if(localInputs.k_accept.clicked){ - switch(currentSelection){ - case 0: - keyProp[0] = localInputs.k_up.input; - keyProp[1] = localInputs.k_down.input; - keyProp[2] = localInputs.k_left.input; - keyProp[3] = localInputs.k_right.input; - keyProp[4] = localInputs.k_attack.input; - keyProp[5] = localInputs.k_menu.input; - keyProp[6] = localInputs.k_pause.input; - keyProp[7] = localInputs.k_accept.input; - keyProp[8] = localInputs.k_decline.input; - keyProp[9] = localInputs.k_delete.input; - keyProp[10] = localInputs.k_menuNext.input; - keyProp[11] = localInputs.k_menuPrev.input; - left = true; - selBut = false; - bindOpt = false; - currentSelection = 0; - currentMenu = MENU_SETTINGS_REBIND; - break; - case 1: - readTPFiles(); - currentMenu = MENU_SETTINGS_TP; - currentSelection = 0; - break; - case 2: - shouldRenderDebug = !shouldRenderDebug; // toggle option - break; - case 3: - if((MODEL_3DS & 6) != 0){ // detect if user is using a New 3DS - shouldSpeedup = !shouldSpeedup; // toggle option - osSetSpeedupEnable(shouldSpeedup); - } - break; - case 4: - if(true){ - FILE * fset = fopen("settings.bin","wb"); - fwrite(&shouldRenderDebug,sizeof(bool),1,fset); - fwrite(&shouldSpeedup,sizeof(bool),1,fset); - fclose(fset); - } - currentMenu = MENU_TITLE; - currentSelection = 2; - break; - } - } - break; - case MENU_TITLE: + + case MENU_LOADGAME: + if(!enteringName && !areYouSure){ // World select + if (localInputs.k_decline.clicked){ + if(toMultiplayer) { + currentMenu = MENU_MULTIPLAYER_HOST; + } else { + currentMenu = MENU_TITLE; + currentSelection = 0; + } + } + if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection = worldFileCount;} + if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection > worldFileCount)currentSelection=0;} + + if(localInputs.k_delete.clicked){ + if(currentSelection < worldFileCount) areYouSure = true; + } + + if(localInputs.k_accept.clicked){ + if(currentSelection == worldFileCount){ + + enteringName = true; + } else { + memset(¤tFileName, 0, 255); // reset currentFileName + sprintf(currentFileName, "%s.msv", fileNames[currentSelection]); + playSound(snd_test); + if(toMultiplayer) { + initMPGame = 2; + } else { + initGame = 1; + } + currentMenu = MENU_LOADING; + } + } + } else if (areYouSure){ + if (localInputs.k_decline.clicked || localInputs.k_delete.clicked) areYouSure = false; + if (localInputs.k_accept.clicked){ + sprintf(currentFileName,"%s.msv",fileNames[currentSelection]); + remove(currentFileName); + readFiles(); + enteringName = false; + areYouSure = false; + memset(¤tFileName, 0, 255); // reset currentFileName + } + } else { // Enter new world name. + if(localInputs.k_decline.clicked) enteringName = false; + if(localInputs.k_accept.clicked && errorFileName == 0){ + errorFileName = checkFileNameForErrors(); + if(errorFileName == 0){ // If no errors are found with the filename, then start a new game! + memset(¤tFileName, 0, 255); // reset currentFileName + sprintf(currentFileName, "%s.msv", fileNames[worldFileCount]); + currentMenu = MENU_LOADING; + playSound(snd_test); + if(toMultiplayer) { + initMPGame = 2; + } else { + initGame = 1; + } + ++worldFileCount; + currentMenu = MENU_LOADING; + } + } + if((localInputs.k_touch.px != 0 || localInputs.k_touch.py != 0) && touchDelay == 0){ + if(!isTouching)doTouchButton(); + } + else if(localInputs.k_touch.px == 0 || localInputs.k_touch.py == 0) isTouching = false; + if(touchDelay > 0) --touchDelay; + } + break; + case MENU_SETTINGS_TP: + + if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection = tpFileCount-1;} + if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection > tpFileCount-1)currentSelection=0;} + if (localInputs.k_decline.clicked){ + if(isLoadingTP < 1){ + currentMenu = MENU_SETTINGS; + currentSelection = 1; + } + } + if (localInputs.k_accept.clicked){ + + if(currentSelection > 0){ + isLoadingTP = 4; + } else { + icons = sfil_load_PNG_buffer(icons_png, SF2D_PLACE_RAM); + reloadColors(); + font = sfil_load_PNG_buffer(Font_png, SF2D_PLACE_RAM); + bottombg = sfil_load_PNG_buffer(bottombg_png, SF2D_PLACE_RAM); + currentMenu = MENU_SETTINGS; + currentSelection = 1; + remove("lastTP.bin"); + } + } + break; + + case MENU_SETTINGS: + if (localInputs.k_up.clicked){ + --currentSelection; + if(currentSelection == 3 && !((MODEL_3DS & 6) != 0)) --currentSelection; + if(currentSelection < 0)currentSelection=4; + } + if (localInputs.k_down.clicked){ + ++currentSelection; + if(currentSelection == 3 && !((MODEL_3DS & 6) != 0)) ++currentSelection; + if(currentSelection > 4)currentSelection=0; + } + if(localInputs.k_decline.clicked){ + currentMenu = MENU_TITLE; + currentSelection = 4; + } + if(localInputs.k_accept.clicked){ + switch(currentSelection){ + case 0: + keyProp[0] = localInputs.k_up.input; + keyProp[1] = localInputs.k_down.input; + keyProp[2] = localInputs.k_left.input; + keyProp[3] = localInputs.k_right.input; + keyProp[4] = localInputs.k_attack.input; + keyProp[5] = localInputs.k_menu.input; + keyProp[6] = localInputs.k_pause.input; + keyProp[7] = localInputs.k_accept.input; + keyProp[8] = localInputs.k_decline.input; + keyProp[9] = localInputs.k_delete.input; + keyProp[10] = localInputs.k_menuNext.input; + keyProp[11] = localInputs.k_menuPrev.input; + left = true; + selBut = false; + bindOpt = false; + currentSelection = 0; + currentMenu = MENU_SETTINGS_REBIND; + break; + case 1: + readTPFiles(); + currentMenu = MENU_SETTINGS_TP; + currentSelection = 0; + break; + case 2: + shouldRenderDebug = !shouldRenderDebug; // toggle option + break; + case 3: + if((MODEL_3DS & 6) != 0){ // detect if user is using a New 3DS + shouldSpeedup = !shouldSpeedup; // toggle option + osSetSpeedupEnable(shouldSpeedup); + } + break; + case 4: + if(true){ + FILE * fset = fopen("settings.bin","wb"); + fwrite(&shouldRenderDebug,sizeof(bool),1,fset); + fwrite(&shouldSpeedup,sizeof(bool),1,fset); + fclose(fset); + } + currentMenu = MENU_TITLE; + currentSelection = 2; + break; + } + } + break; + case MENU_TITLE: //Map BG if(menuHasMapLoaded) { mxscr += menuxa; myscr += menuya; - + if (mxscr < 16) { mxscr = 16; menuxa = -menuxa; @@ -585,152 +585,152 @@ void tickMenu(int menu){ menuya = -menuya; } } - - if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection=6;} - if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection > 6)currentSelection=0;} - - if(localInputs.k_accept.clicked){ - switch(currentSelection){ - case 0: - toMultiplayer = false; - currentMenu = MENU_LOADGAME; - readFiles(); - currentSelection = 0; - enteringName = false; - areYouSure = false; - break; - case 1: - if(networkHost()) { - toMultiplayer = true; - currentMenu = MENU_MULTIPLAYER_HOST; - currentSelection = 0; - } - break; - case 2: - networkScan(); - currentMenu = MENU_MULTIPLAYER_JOIN; - currentSelection = 0; - menuScanTimer = 0; - break; - case 3: - sprintf(pageText,"Page: %d/%d",pageNum+1,maxPageNum+1); - currentMenu = MENU_TUTORIAL; - break; - case 4: - currentSelection = 0; - currentMenu = MENU_SETTINGS; - break; - case 5: - currentMenu = MENU_ABOUT; - break; - case 6: - quitGame = true; - break; - } - - } - break; - case MENU_TUTORIAL: - if(localInputs.k_decline.clicked){ - currentSelection = 3; - currentMenu = MENU_TITLE; - } - if(localInputs.k_menuNext.clicked){ - if(pageNum < maxPageNum){ - ++pageNum; - sprintf(pageText,"Page: %d/%d",pageNum+1,maxPageNum+1); - } - } - if(localInputs.k_menuPrev.clicked){ - if(pageNum > 0){ - --pageNum; - sprintf(pageText,"Page: %d/%d",pageNum+1,maxPageNum+1); - } - } - - break; - case MENU_MULTIPLAYER_HOST: - if (localInputs.k_decline.clicked){ - networkDisconnect(); - - currentMenu = MENU_TITLE; - currentSelection = 1; - } - - if(localInputs.k_accept.clicked){ - if(networkGetNodeCount()>1) { - currentMenu = MENU_LOADGAME; - readFiles(); - currentSelection = 0; - enteringName = false; - areYouSure = false; - } - } - break; - case MENU_MULTIPLAYER_JOIN: - if(menuScanTimer>0) { - menuScanTimer--; - } else { - networkScan(); - menuScanTimer = 30; - } - if(currentSelection >= networkGetScanCount()) currentSelection=networkGetScanCount()-1; - if(currentSelection < 0) currentSelection = 0; - - if (localInputs.k_decline.clicked){ - currentMenu = MENU_TITLE; - currentSelection = 2; - } - if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0) currentSelection = (networkGetScanCount()>0 ? networkGetScanCount()-1 : 0);} - if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection >= networkGetScanCount()) currentSelection=0;} - - if(localInputs.k_accept.clicked){ - if(networkGetScanCount()!=0) { - for(int t=0; t<10; t++) { //try to connect multiple times, because it will not work the first try every time - if(networkConnect(currentSelection)) { - currentMenu = MENU_MULTIPLAYER_WAIT; - currentSelection = 0; - break; - } - } - } - } - break; - case MENU_MULTIPLAYER_WAIT: - if (localInputs.k_decline.clicked){ - networkDisconnect(); - - currentMenu = MENU_TITLE; - currentSelection = 2; - } - break; - } - + + if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection=6;} + if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection > 6)currentSelection=0;} + + if(localInputs.k_accept.clicked){ + switch(currentSelection){ + case 0: + toMultiplayer = false; + currentMenu = MENU_LOADGAME; + readFiles(); + currentSelection = 0; + enteringName = false; + areYouSure = false; + break; + case 1: + if(networkHost()) { + toMultiplayer = true; + currentMenu = MENU_MULTIPLAYER_HOST; + currentSelection = 0; + } + break; + case 2: + networkScan(); + currentMenu = MENU_MULTIPLAYER_JOIN; + currentSelection = 0; + menuScanTimer = 0; + break; + case 3: + sprintf(pageText,"Page: %d/%d",pageNum+1,maxPageNum+1); + currentMenu = MENU_TUTORIAL; + break; + case 4: + currentSelection = 0; + currentMenu = MENU_SETTINGS; + break; + case 5: + currentMenu = MENU_ABOUT; + break; + case 6: + quitGame = true; + break; + } + + } + break; + case MENU_TUTORIAL: + if(localInputs.k_decline.clicked){ + currentSelection = 3; + currentMenu = MENU_TITLE; + } + if(localInputs.k_menuNext.clicked){ + if(pageNum < maxPageNum){ + ++pageNum; + sprintf(pageText,"Page: %d/%d",pageNum+1,maxPageNum+1); + } + } + if(localInputs.k_menuPrev.clicked){ + if(pageNum > 0){ + --pageNum; + sprintf(pageText,"Page: %d/%d",pageNum+1,maxPageNum+1); + } + } + + break; + case MENU_MULTIPLAYER_HOST: + if (localInputs.k_decline.clicked){ + networkDisconnect(); + + currentMenu = MENU_TITLE; + currentSelection = 1; + } + + if(localInputs.k_accept.clicked){ + if(networkGetNodeCount()>1) { + currentMenu = MENU_LOADGAME; + readFiles(); + currentSelection = 0; + enteringName = false; + areYouSure = false; + } + } + break; + case MENU_MULTIPLAYER_JOIN: + if(menuScanTimer>0) { + menuScanTimer--; + } else { + networkScan(); + menuScanTimer = 30; + } + if(currentSelection >= networkGetScanCount()) currentSelection=networkGetScanCount()-1; + if(currentSelection < 0) currentSelection = 0; + + if (localInputs.k_decline.clicked){ + currentMenu = MENU_TITLE; + currentSelection = 2; + } + if (localInputs.k_up.clicked){ --currentSelection; if(currentSelection < 0) currentSelection = (networkGetScanCount()>0 ? networkGetScanCount()-1 : 0);} + if (localInputs.k_down.clicked){ ++currentSelection; if(currentSelection >= networkGetScanCount()) currentSelection=0;} + + if(localInputs.k_accept.clicked){ + if(networkGetScanCount()!=0) { + for(int t=0; t<10; t++) { //try to connect multiple times, because it will not work the first try every time + if(networkConnect(currentSelection)) { + currentMenu = MENU_MULTIPLAYER_WAIT; + currentSelection = 0; + break; + } + } + } + } + break; + case MENU_MULTIPLAYER_WAIT: + if (localInputs.k_decline.clicked){ + networkDisconnect(); + + currentMenu = MENU_TITLE; + currentSelection = 2; + } + break; + } + } char scoreText[15]; char * getButtonFunctionGame(int key){ - if(keyProp[0] & key) return "Move up"; - if(keyProp[1] & key) return "Move down"; - if(keyProp[2] & key) return "Move left"; - if(keyProp[3] & key) return "Move right"; - if(keyProp[4] & key) return "Attack"; - if(keyProp[5] & key) return "Toggle Menu"; - if(keyProp[6] & key) return "Pause"; - return "Nothing"; + if(keyProp[0] & key) return "Move up"; + if(keyProp[1] & key) return "Move down"; + if(keyProp[2] & key) return "Move left"; + if(keyProp[3] & key) return "Move right"; + if(keyProp[4] & key) return "Attack"; + if(keyProp[5] & key) return "Toggle Menu"; + if(keyProp[6] & key) return "Pause"; + return "Nothing"; } char * getButtonFunctionMenu(int key){ - if(keyProp[0] & key) return "Up"; - if(keyProp[1] & key) return "Down"; - if(keyProp[2] & key) return "Left"; - if(keyProp[3] & key) return "Right"; - if(keyProp[7] & key) return "Accept"; - if(keyProp[8] & key) return "Decline"; - if(keyProp[9] & key) return "Delete"; - if(keyProp[10] & key) return "Next"; - if(keyProp[11] & key) return "Previous"; - return "Nothing"; + if(keyProp[0] & key) return "Up"; + if(keyProp[1] & key) return "Down"; + if(keyProp[2] & key) return "Left"; + if(keyProp[3] & key) return "Right"; + if(keyProp[7] & key) return "Accept"; + if(keyProp[8] & key) return "Decline"; + if(keyProp[9] & key) return "Delete"; + if(keyProp[10] & key) return "Next"; + if(keyProp[11] & key) return "Previous"; + return "Nothing"; } @@ -741,243 +741,243 @@ char guiText3[] = "Z X C V B N M"; char guiText4[] = " SPACE BACKSPACE"; void renderMenu(int menu,int xscr,int yscr){ - int i = 0; - switch(menu){ - case MENU_TUTORIAL: - sf2d_start_frame(GFX_TOP, GFX_LEFT); + int i = 0; + switch(menu){ + case MENU_TUTORIAL: + 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 - - renderTutorialPage(true); - sf2d_end_frame(); - sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); + + renderTutorialPage(true); + sf2d_end_frame(); + 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 - - renderTutorialPage(false); - sf2d_end_frame(); - break; - case MENU_SETTINGS_TP: - offsetX = 0;offsetY = (currentSelection * 40) - 48; - sf2d_start_frame(GFX_TOP, GFX_LEFT); + + renderTutorialPage(false); + sf2d_end_frame(); + break; + case MENU_SETTINGS_TP: + offsetX = 0;offsetY = (currentSelection * 40) - 48; + 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 - - drawText("Texture Packs",122,-16); - for(i = 0; i < tpFileCount; ++i){ - int color = 0xFF923232; - char * text = tpFileNames[i]; - char * cmtText = tpFileComment[i]; - if(i == 0){ - text = "Default"; - cmtText = "Regular look of the game"; - color = 0xFF921060; - } - if(i != currentSelection) color &= 0x7FFFFFFF; // Darken color. - else if(areYouSure)color = 0xFF1010DF; - - renderFrame(1,i*5,24,(i*5)+5,color); - drawText(text,(400-(strlen(text)*12))/2,i*80+16); - - if(strlen(cmtText) > 29){ - char cmtTxt1[30],cmtTxt2[30]; - strncpy(cmtTxt1, cmtText, 29); - strncpy(cmtTxt2, cmtText + 29, strlen(cmtText)-29); - drawTextColor(cmtTxt1,(400-(strlen(cmtTxt1)*12))/2,i*80+36,0xFFAFAFAF); - drawTextColor(cmtTxt2,(400-(strlen(cmtTxt2)*12))/2,i*80+50,0xFFAFAFAF); - } else { - drawTextColor(cmtText,(400-(strlen(cmtText)*12))/2,i*80+43,0xFFAFAFAF); - } - } - offsetX = 0;offsetY = 0; - if(isLoadingTP > 0){ - --isLoadingTP; - renderFrame(1,5,24,9,0xFF666666); - drawTextColor("Loading Texture pack...",(400-(23*12))/2,108,0xFF10FFFF); - if(isLoadingTP == 0){ - char fullDirName[256]; - sprintf(fullDirName,"texturepacks/%s.zip",tpFileNames[currentSelection]); - loadedtp = loadTexturePack(fullDirName); - - FILE * fs=fopen("lastTP.bin","w"); - fprintf(fs,"%s", fullDirName); - fclose(fs); - - currentMenu = MENU_SETTINGS; - currentSelection = 1; - } - } - sf2d_end_frame(); - sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); + + drawText("Texture Packs",122,-16); + for(i = 0; i < tpFileCount; ++i){ + int color = 0xFF923232; + char * text = tpFileNames[i]; + char * cmtText = tpFileComment[i]; + if(i == 0){ + text = "Default"; + cmtText = "Regular look of the game"; + color = 0xFF921060; + } + if(i != currentSelection) color &= 0x7FFFFFFF; // Darken color. + else if(areYouSure)color = 0xFF1010DF; + + renderFrame(1,i*5,24,(i*5)+5,color); + drawText(text,(400-(strlen(text)*12))/2,i*80+16); + + if(strlen(cmtText) > 29){ + char cmtTxt1[30],cmtTxt2[30]; + strncpy(cmtTxt1, cmtText, 29); + strncpy(cmtTxt2, cmtText + 29, strlen(cmtText)-29); + drawTextColor(cmtTxt1,(400-(strlen(cmtTxt1)*12))/2,i*80+36,0xFFAFAFAF); + drawTextColor(cmtTxt2,(400-(strlen(cmtTxt2)*12))/2,i*80+50,0xFFAFAFAF); + } else { + drawTextColor(cmtText,(400-(strlen(cmtText)*12))/2,i*80+43,0xFFAFAFAF); + } + } + offsetX = 0;offsetY = 0; + if(isLoadingTP > 0){ + --isLoadingTP; + renderFrame(1,5,24,9,0xFF666666); + drawTextColor("Loading Texture pack...",(400-(23*12))/2,108,0xFF10FFFF); + if(isLoadingTP == 0){ + char fullDirName[256]; + sprintf(fullDirName,"texturepacks/%s.zip",tpFileNames[currentSelection]); + loadedtp = loadTexturePack(fullDirName); + + FILE * fs=fopen("lastTP.bin","w"); + fprintf(fs,"%s", fullDirName); + fclose(fs); + + currentMenu = MENU_SETTINGS; + currentSelection = 1; + } + } + sf2d_end_frame(); + 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 - - drawText("Press to select", 58, 100); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 128, 98, 1); - drawText("Press to return", 58, 150); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 148, 1); - sf2d_end_frame(); - break; - case MENU_LOADGAME: - 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 - - if(!enteringName){ // World select - offsetX = 0;offsetY = (currentSelection * 32) - 48; - drawText("Select a file",122,-16); - for(i = 0; i < worldFileCount + 1; ++i){ - int color = 0xFF921020; - char * text = fileNames[i]; - if(i == worldFileCount){ - text = "Generate New World"; - color = 0xFF209210; - } - if(i != currentSelection) color &= 0xFF7F7F7F; // Darken color. - else { - if(areYouSure)color = 0xFF1010DF; - } - - char scoreText[24]; - sprintf(scoreText,"Score: %d",fileScore[i]); - - renderFrame(1,i*4,24,(i*4)+4,color); - if(i != worldFileCount){ - drawText(text,(400-(strlen(text)*12))/2,i*64+12); - drawText(scoreText,(400-(strlen(scoreText)*12))/2,i*64+32); - } else { - drawText(text,(400-(strlen(text)*12))/2,i*64+24); - } - if(fileWin[i] && i != worldFileCount) render16(18,i*32+8,24,208,0); // Render crown - } - offsetX = 0;offsetY = 0; - } else { // Enter new world name. - drawText("Enter a name",128,16); - drawText(fileNames[worldFileCount],(400-(strlen(fileNames[worldFileCount])*12))/2, 48); - - if(errorFileName > 0){ - switch(errorFileName){// Error: Filename cannot already exist. - case 1: drawTextColor("ERROR: Length cannot be 0!",(400-26*12)/2,200,0xFF1010AF); break; - case 2: drawTextColor("ERROR: You need Letters/Numbers!",(400-32*12)/2,200,0xFF1010AF); break; - case 3: drawTextColor("ERROR: Filename already exists!",(400-31*12)/2,200,0xFF1010AF); break; - } - } - } - sf2d_end_frame(); - 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 - - if(!enteringName){ // World select - if(!areYouSure){ - drawTextColor("Load World",100,12,0xFF3FFFFF); - drawText("Press or to scroll", 28, 50); - renderButtonIcon(localInputs.k_up.input & -localInputs.k_up.input, 98, 48, 1); - renderButtonIcon(localInputs.k_down.input & -localInputs.k_down.input, 160, 48, 1); - drawText("Press to load world", (320-21*12)/2, 100); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 104, 98, 1); - drawText("Press to return", 58, 150); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 148, 1); - if(currentSelection != worldFileCount){ - drawText("Press to delete",(320-17*12)/2, 200); - renderButtonIcon(localInputs.k_delete.input & -localInputs.k_delete.input, 128, 198, 1); - } - } else { - drawTextColor("Delete File?",88,12,0xFF3F3FFF); - drawText("Press to confirm", (320-18*12)/2, 100); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 122, 98, 1); - drawText("Press to return", 58, 150); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 148, 1); - } - - } else { // Draw the "keyboard" - drawTextColor("Touch the keypad below",(320-22*12)/2,12,0xFF33FFFF); - - sf2d_draw_rectangle(0, 50, 320, 110, 0xFF7F7FBF); - - if(touchDelay > 0){ - sf2d_draw_rectangle(touchX, touchY, touchW, touchH, 0xFF0000AF); - } - - drawSizedText(guiText0,4, 60, 2); - drawSizedText(guiText1,4, 80, 2); - drawSizedText(guiText2,12, 100, 2); - drawSizedText(guiText3,28, 120, 2); - drawSizedText(guiText4,12, 140, 2); - - drawText("Press to confirm", (320-18*12)/2, 180); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 122, 178, 1); - drawText("Press to return", 58, 210); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 208, 1); - } - sf2d_end_frame(); - break; - case MENU_SETTINGS_REBIND: - sf2d_start_frame(GFX_TOP, GFX_LEFT); + + drawText("Press to select", 58, 100); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 128, 98, 1); + drawText("Press to return", 58, 150); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 148, 1); + sf2d_end_frame(); + break; + case MENU_LOADGAME: + 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 - - drawTextColor("Rebind Buttons",116,12,0xFF00AFAF); - drawText("Button",16,32); - drawText("Game",140,32); - drawText("Menus",280,32); - - char gameButText[34]; - char menuButText[34]; - - for(i = 0; i < 5; ++i){ - if((currentSelection-2) + i > 21 || (currentSelection-2) + i < 0) continue; - renderButtonIcon(keys[(currentSelection-2) + i], 16, (i * 18) + 30, 2); - int ccol = 0xFF7F7F7F; - - sprintf(gameButText,"%s",getButtonFunctionGame(keys[(currentSelection-2) + i])); - sprintf(menuButText,"%s",getButtonFunctionMenu(keys[(currentSelection-2) + i])); - - if(i == 2){ - if(!selBut)ccol = 0xFFFFFFFF; - else{ - ccol = 0xFF00FF00; - if(left)sprintf(gameButText,"<%s>",getButtonFunctionGame(keys[(currentSelection-2) + i])); - else sprintf(menuButText,"<%s>",getButtonFunctionMenu(keys[(currentSelection-2) + i])); - } - } - if(left){ - drawTextColor(gameButText, 112, (i * 33) + 80, ccol); - drawTextColor(menuButText, 280, (i * 33) + 80, 0xFF7F7F7F); - } else { - drawTextColor(gameButText, 112, (i * 33) + 80, 0xFF7F7F7F); - drawTextColor(menuButText, 280, (i * 33) + 80, ccol); - } - } - if(bindOpt){ - renderFrame(1,1,24,14,0xFFBF1010); - drawTextColor("Save changes?",122,32,0xFF00AFAF); - for(i = 2; i >= 0; --i){ - char* msg = keybOptions[i]; - u32 color = 0xFF4F4F4F; - if(i == curSaveSel) color = 0xFFFFFFFF; - drawTextColor(msg,(400 - (strlen(msg) * 12))/2, (i * 24) + 92, color); - } - drawText("Press to return", 98, 190); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 168, 188, 1); - - if(errorBut >= 0 && errorBut < 12){ - char errorText[30]; - switch(errorBut){ - case 0: sprintf(errorText, "Error: Missing 'Move up'"); break; - case 1: sprintf(errorText, "Error: Missing 'Move down'"); break; - case 2: sprintf(errorText, "Error: Missing 'Move right'"); break; - case 3: sprintf(errorText, "Error: Missing 'Move left'"); break; - case 4: sprintf(errorText, "Error: Missing 'Attack'"); break; - case 5: sprintf(errorText, "Error: Missing 'Toggle Menu'"); break; - case 6: sprintf(errorText, "Error: Missing 'Pause'"); break; - case 7: sprintf(errorText, "Error: Missing 'Accept'"); break; - case 8: sprintf(errorText, "Error: Missing 'Decline'"); break; - case 9: sprintf(errorText, "Error: Missing 'Delete'"); break; - case 10: sprintf(errorText, "Error: Missing 'Next'"); break; - case 11: sprintf(errorText, "Error: Missing 'Previous'"); break; - } - drawTextColor(errorText,(400 - (strlen(errorText) * 12))/2,50,0xFF0000FF); - } - - } - sf2d_end_frame(); - sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); + + if(!enteringName){ // World select + offsetX = 0;offsetY = (currentSelection * 32) - 48; + drawText("Select a file",122,-16); + for(i = 0; i < worldFileCount + 1; ++i){ + int color = 0xFF921020; + char * text = fileNames[i]; + if(i == worldFileCount){ + text = "Generate New World"; + color = 0xFF209210; + } + if(i != currentSelection) color &= 0xFF7F7F7F; // Darken color. + else { + if(areYouSure)color = 0xFF1010DF; + } + + char scoreText[24]; + sprintf(scoreText,"Score: %d",fileScore[i]); + + renderFrame(1,i*4,24,(i*4)+4,color); + if(i != worldFileCount){ + drawText(text,(400-(strlen(text)*12))/2,i*64+12); + drawText(scoreText,(400-(strlen(scoreText)*12))/2,i*64+32); + } else { + drawText(text,(400-(strlen(text)*12))/2,i*64+24); + } + if(fileWin[i] && i != worldFileCount) render16(18,i*32+8,24,208,0); // Render crown + } + offsetX = 0;offsetY = 0; + } else { // Enter new world name. + drawText("Enter a name",128,16); + drawText(fileNames[worldFileCount],(400-(strlen(fileNames[worldFileCount])*12))/2, 48); + + if(errorFileName > 0){ + switch(errorFileName){// Error: Filename cannot already exist. + case 1: drawTextColor("ERROR: Length cannot be 0!",(400-26*12)/2,200,0xFF1010AF); break; + case 2: drawTextColor("ERROR: You need Letters/Numbers!",(400-32*12)/2,200,0xFF1010AF); break; + case 3: drawTextColor("ERROR: Filename already exists!",(400-31*12)/2,200,0xFF1010AF); break; + } + } + } + sf2d_end_frame(); + 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 - + + if(!enteringName){ // World select + if(!areYouSure){ + drawTextColor("Load World",100,12,0xFF3FFFFF); + drawText("Press or to scroll", 28, 50); + renderButtonIcon(localInputs.k_up.input & -localInputs.k_up.input, 98, 48, 1); + renderButtonIcon(localInputs.k_down.input & -localInputs.k_down.input, 160, 48, 1); + drawText("Press to load world", (320-21*12)/2, 100); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 104, 98, 1); + drawText("Press to return", 58, 150); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 148, 1); + if(currentSelection != worldFileCount){ + drawText("Press to delete",(320-17*12)/2, 200); + renderButtonIcon(localInputs.k_delete.input & -localInputs.k_delete.input, 128, 198, 1); + } + } else { + drawTextColor("Delete File?",88,12,0xFF3F3FFF); + drawText("Press to confirm", (320-18*12)/2, 100); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 122, 98, 1); + drawText("Press to return", 58, 150); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 148, 1); + } + + } else { // Draw the "keyboard" + drawTextColor("Touch the keypad below",(320-22*12)/2,12,0xFF33FFFF); + + sf2d_draw_rectangle(0, 50, 320, 110, 0xFF7F7FBF); + + if(touchDelay > 0){ + sf2d_draw_rectangle(touchX, touchY, touchW, touchH, 0xFF0000AF); + } + + drawSizedText(guiText0,4, 60, 2); + drawSizedText(guiText1,4, 80, 2); + drawSizedText(guiText2,12, 100, 2); + drawSizedText(guiText3,28, 120, 2); + drawSizedText(guiText4,12, 140, 2); + + drawText("Press to confirm", (320-18*12)/2, 180); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 122, 178, 1); + drawText("Press to return", 58, 210); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 208, 1); + } + sf2d_end_frame(); + break; + case MENU_SETTINGS_REBIND: + 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 + + drawTextColor("Rebind Buttons",116,12,0xFF00AFAF); + drawText("Button",16,32); + drawText("Game",140,32); + drawText("Menus",280,32); + + char gameButText[34]; + char menuButText[34]; + + for(i = 0; i < 5; ++i){ + if((currentSelection-2) + i > 21 || (currentSelection-2) + i < 0) continue; + renderButtonIcon(keys[(currentSelection-2) + i], 16, (i * 18) + 30, 2); + int ccol = 0xFF7F7F7F; + + sprintf(gameButText,"%s",getButtonFunctionGame(keys[(currentSelection-2) + i])); + sprintf(menuButText,"%s",getButtonFunctionMenu(keys[(currentSelection-2) + i])); + + if(i == 2){ + if(!selBut)ccol = 0xFFFFFFFF; + else{ + ccol = 0xFF00FF00; + if(left)sprintf(gameButText,"<%s>",getButtonFunctionGame(keys[(currentSelection-2) + i])); + else sprintf(menuButText,"<%s>",getButtonFunctionMenu(keys[(currentSelection-2) + i])); + } + } + if(left){ + drawTextColor(gameButText, 112, (i * 33) + 80, ccol); + drawTextColor(menuButText, 280, (i * 33) + 80, 0xFF7F7F7F); + } else { + drawTextColor(gameButText, 112, (i * 33) + 80, 0xFF7F7F7F); + drawTextColor(menuButText, 280, (i * 33) + 80, ccol); + } + } + if(bindOpt){ + renderFrame(1,1,24,14,0xFFBF1010); + drawTextColor("Save changes?",122,32,0xFF00AFAF); + for(i = 2; i >= 0; --i){ + char* msg = keybOptions[i]; + u32 color = 0xFF4F4F4F; + if(i == curSaveSel) color = 0xFFFFFFFF; + drawTextColor(msg,(400 - (strlen(msg) * 12))/2, (i * 24) + 92, color); + } + drawText("Press to return", 98, 190); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 168, 188, 1); + + if(errorBut >= 0 && errorBut < 12){ + char errorText[30]; + switch(errorBut){ + case 0: sprintf(errorText, "Error: Missing 'Move up'"); break; + case 1: sprintf(errorText, "Error: Missing 'Move down'"); break; + case 2: sprintf(errorText, "Error: Missing 'Move right'"); break; + case 3: sprintf(errorText, "Error: Missing 'Move left'"); break; + case 4: sprintf(errorText, "Error: Missing 'Attack'"); break; + case 5: sprintf(errorText, "Error: Missing 'Toggle Menu'"); break; + case 6: sprintf(errorText, "Error: Missing 'Pause'"); break; + case 7: sprintf(errorText, "Error: Missing 'Accept'"); break; + case 8: sprintf(errorText, "Error: Missing 'Decline'"); break; + case 9: sprintf(errorText, "Error: Missing 'Delete'"); break; + case 10: sprintf(errorText, "Error: Missing 'Next'"); break; + case 11: sprintf(errorText, "Error: Missing 'Previous'"); break; + } + drawTextColor(errorText,(400 - (strlen(errorText) * 12))/2,50,0xFF0000FF); + } + + } + sf2d_end_frame(); + 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 + if(!selBut){ drawText("Press to select", 58, 80); renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 128, 78, 1); @@ -992,307 +992,307 @@ void renderMenu(int menu,int xscr,int yscr){ drawText("Press to return", 58, 150); renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 148, 1); } - sf2d_end_frame(); - break; - - case MENU_ABOUT: - sf2d_start_frame(GFX_TOP, GFX_LEFT); + sf2d_end_frame(); + break; + + case MENU_ABOUT: + 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 - - drawText("About Minicraft",110,12); - drawSizedText("Minicraft was made by Markus Persson for the",24,36,1.0); - drawSizedText("22'nd ludum dare competition in december 2011.",16,48,1.0); - drawSizedText("it is dedicated to my father. <3",72,60,1.0); - drawSizedText("- Markus \"Notch\" Persson",104,76,1.0); - - drawTextColor("3DS Homebrew Edition",74,120,0xFF00FF00); - drawSizedTextColor("This port was made by David Benepe (Davideesk)",16,144,1.0,0xFF00FF00); - drawSizedTextColor("just for fun in September/October 2015.",44,156,1.0,0xFF00FF00); + + drawText("About Minicraft",110,12); + drawSizedText("Minicraft was made by Markus Persson for the",24,36,1.0); + drawSizedText("22'nd ludum dare competition in december 2011.",16,48,1.0); + drawSizedText("it is dedicated to my father. <3",72,60,1.0); + drawSizedText("- Markus \"Notch\" Persson",104,76,1.0); + + drawTextColor("3DS Homebrew Edition",74,120,0xFF00FF00); + drawSizedTextColor("This port was made by David Benepe (Davideesk)",16,144,1.0,0xFF00FF00); + drawSizedTextColor("just for fun in September/October 2015.",44,156,1.0,0xFF00FF00); drawSizedTextColor("Modded by Andre Schweiger (andre111) and ",44,168,1.0,0xFF00FF00); drawSizedTextColor("Elijah Bansley (ElijahZAwesome)",71,180,1.0,0xFF00FF00); - drawSizedTextColor("TY Notch for creating a fun game to remake!",28,192,1.0,0xFF00FF00); - sf2d_end_frame(); - 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 - + drawSizedTextColor("TY Notch for creating a fun game to remake!",28,192,1.0,0xFF00FF00); + sf2d_end_frame(); + 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 + drawTextColor("Special Thanks to:",52,12,0xFF7F7FFF); - drawTextColor("Smea",136,50,0xFF2020FF); - drawSizedTextColor("for ctrulib",116,70,1.0,0xFF2020FF); - drawTextColor("Xerpi",130,100,0xFFFF2020); - drawSizedTextColor("for sf2dlib",116,120,1.0,0xFFFF2020); + drawTextColor("Smea",136,50,0xFF2020FF); + drawSizedTextColor("for ctrulib",116,70,1.0,0xFF2020FF); + drawTextColor("Xerpi",130,100,0xFFFF2020); + drawSizedTextColor("for sf2dlib",116,120,1.0,0xFFFF2020); drawTextColor("Music from",100,150,0xFF20FF20); - drawSizedTextColor("opengameart.org/content/",64,170,1.0,0xFF20FF20); + drawSizedTextColor("opengameart.org/content/",64,170,1.0,0xFF20FF20); drawSizedTextColor("generic-8-bit-jrpg-soundtrack",48,180,1.0,0xFF20FF20); - - drawText("Press to return", 58, 220); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 218, 1); - sf2d_end_frame(); - break; - case MENU_SETTINGS: - sf2d_start_frame(GFX_TOP, GFX_LEFT); + + drawText("Press to return", 58, 220); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 218, 1); + sf2d_end_frame(); + break; + case MENU_SETTINGS: + 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 - - drawText("Settings",(400-(8*12))/2,30); - for(i = 4; i >= 0; --i){ - char* msg = setOptions[i]; - u32 color = 0xFF7F7F7F; - if(i == currentSelection) color = 0xFFFFFFFF; - if(i == 2){ - if(shouldRenderDebug) drawSizedTextColor("On",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF00DF00); - else drawSizedTextColor("Off",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF0000DF); - } else if(i == 3){ - - if((MODEL_3DS & 6) != 0){ // detect if user is using a New 3DS - if(shouldSpeedup) drawSizedTextColor("On",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF00DF00); - else drawSizedTextColor("Off",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF0000DF); - } else { - color = 0xFF3F3F3F; - drawSizedTextColor("Off",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF3F3F3F); - } - } - drawSizedTextColor(msg,(200 - (strlen(msg) * 8))/2, ((8 + i) * 32 - 190) >> 1,2.0, color); - } - sf2d_end_frame(); - 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 - + + drawText("Settings",(400-(8*12))/2,30); + for(i = 4; i >= 0; --i){ + char* msg = setOptions[i]; + u32 color = 0xFF7F7F7F; + if(i == currentSelection) color = 0xFFFFFFFF; + if(i == 2){ + if(shouldRenderDebug) drawSizedTextColor("On",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF00DF00); + else drawSizedTextColor("Off",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF0000DF); + } else if(i == 3){ + + if((MODEL_3DS & 6) != 0){ // detect if user is using a New 3DS + if(shouldSpeedup) drawSizedTextColor("On",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF00DF00); + else drawSizedTextColor("Off",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF0000DF); + } else { + color = 0xFF3F3F3F; + drawSizedTextColor("Off",142, ((8 + i) * 32 - 190) >> 1,2.0, 0xFF3F3F3F); + } + } + drawSizedTextColor(msg,(200 - (strlen(msg) * 8))/2, ((8 + i) * 32 - 190) >> 1,2.0, color); + } + sf2d_end_frame(); + 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 + switch(currentSelection){ - case 0: - drawTextColor("Change the controls",(320 - (19 * 12))/2,24,0xFF7FFFFF); - break; - case 1: - drawTextColor("Change the game's art",(320 - (21 * 12))/2,24,0xFF7FFFFF); - break; - case 2: - drawTextColor("Enable Testing Features.",(320 - (22 * 12))/2,24,0xFF7FFFFF); - break; - case 3: - drawTextColor("Use the N3DS 804mhz mode",(320 - (24 * 12))/2,24,0xFF7FFFFF); - break; - case 4: - drawTextColor("Back to the titlescreen",(320 - (23 * 12))/2,24,0xFF7FFFFF); - break; - } - drawText("Press to select", 58, 100); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 128, 98, 1); - drawText("Press to return", 58, 150); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 148, 1); - sf2d_end_frame(); - break; - case MENU_TITLE: - /* Top Screen */ - sf2d_start_frame(GFX_TOP, GFX_LEFT); + case 0: + drawTextColor("Change the controls",(320 - (19 * 12))/2,24,0xFF7FFFFF); + break; + case 1: + drawTextColor("Change the game's art",(320 - (21 * 12))/2,24,0xFF7FFFFF); + break; + case 2: + drawTextColor("Enable Testing Features.",(320 - (22 * 12))/2,24,0xFF7FFFFF); + break; + case 3: + drawTextColor("Use the N3DS 804mhz mode",(320 - (24 * 12))/2,24,0xFF7FFFFF); + break; + case 4: + drawTextColor("Back to the titlescreen",(320 - (23 * 12))/2,24,0xFF7FFFFF); + break; + } + drawText("Press to select", 58, 100); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 128, 98, 1); + drawText("Press to return", 58, 150); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 128, 148, 1); + sf2d_end_frame(); + break; + case MENU_TITLE: + /* 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(1, (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,8); - - for(i = 6; i >= 0; --i){ - char* msg = options[i]; - u32 color = 0xFF7F7F7F; - if(i == currentSelection) color = 0xFFFFFFFF; - drawSizedTextColor(msg,((200 - (strlen(msg) * 8))/2) + 1, (((8 + i) * 20 - 74) >> 1) + 1,2.0, 0xFF000000); - drawSizedTextColor(msg,(200 - (strlen(msg) * 8))/2, ((8 + i) * 20 - 74) >> 1,2.0, color); - } - - drawText(versionText,2,225); - sf2d_end_frame(); - - /* Bottom Screen */ - sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); + + renderTitle(76,8); + + for(i = 6; i >= 0; --i){ + char* msg = options[i]; + u32 color = 0xFF7F7F7F; + if(i == currentSelection) color = 0xFFFFFFFF; + drawSizedTextColor(msg,((200 - (strlen(msg) * 8))/2) + 1, (((8 + i) * 20 - 74) >> 1) + 1,2.0, 0xFF000000); + drawSizedTextColor(msg,(200 - (strlen(msg) * 8))/2, ((8 + i) * 20 - 74) >> 1,2.0, color); + } + + drawText(versionText,2,225); + sf2d_end_frame(); + + /* 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(1, (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" - break; - case 1: // "Host Game" - drawTextColor("Host local multiplayer",(320 - (22 * 12))/2,24,0xFF7FFFFF); - break; - case 2: // "Join Game" - drawTextColor("Join local multiplayer",(320 - (22 * 12))/2,24,0xFF7FFFFF); - break; - case 3: // "How To Play" - startX = 72;startY = 54; - render16(startX,startY,96,208,0);//C-PAD - startX = 72;startY = 37; - render16(startX,startY-16,16,112,0);//Player - render16(startX,startY,112,208,0);//C-PAD up - startX = 72;startY = 71; - render16(startX,startY+16,0,112,0);//Player - render16(startX,startY,144,208,0);//C-PAD down - startX = 39;startY = 54; - render16(startX,startY,48,112,1);//Player - render16(startX+16,startY,128,208,0);//C-PAD left - 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 4: // "Settings" - drawTextColor("Modify the game's feel",(320 - (22 * 12))/2,24,0xFF7FFFFF); - renderc(48,48,0,112,64,32,0); - break; - case 5: // "About" - drawTextColor("Who made this game?",(320 - (19 * 12))/2,24,0xFF7FFFFF); - - // Secret code ;) - //drawSizedText("497420776173206e6f746368",(320 - (24 * 8))/2,80,1); - //drawSizedText("506f727465642062792044617669646565736b",(320 - (38 * 8))/2,88,1); - //drawSizedText("576879207265616420746869733f",(320 - (28 * 8))/2,96,1); - //drawSizedText("596f75207761737465642074696d65",(320 - (30 * 8))/2,104,1); - //drawSizedText("4861204861204861204861204861",(320 - (28 * 8))/2,112,1); - //drawSizedText("5468652063616b652069732061206c6965",(320 - (34 * 8))/2,120,1); - //drawSizedText("4044617669646565736b2074776974746572",(320 - (36 * 8))/2,128,1); - //drawSizedText("3533363536333732363537343231",(320 - (28 * 8))/2,136,1); - //drawSizedText("4c69617220746578742062656c6f77",(320 - (30 * 8))/2,144,1); - //drawSizedText("(Totally not a secret code or anything)",4,160,1); - - break; - case 6: // "Exit" - drawTextColor("Exit to the home menu",(320 - (21 * 12))/2,24,0xFF7FFFFF); - drawTextColor("(bye-bye)",(320 - (9 * 12))/2,100,0xFF7FFFFF); - break; - } - sf2d_end_frame(); - break; - case MENU_MULTIPLAYER_HOST: - 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 - - networkUpdateStatus(); - drawText("Connected Players",98,8); - int j = 0; - int lastj = 0; - for(i = 0; i", 64, 110); - renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 44, 92, 1); - renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 44, 108, 1); - renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 44, 125, 1); - break; - case 3: // Furniture - sf2d_draw_rectangle(64, 48, 192, 32, grassColor); - renderc(32,24,64,128,96,16,0);//Furniture entities - - renderFurniture(ITEM_WORKBENCH, 50,60); - render16(50,46,0,112,0);//Player-down - renderc(50,58,16,160,16,8,2);//Slash - render(54,58,56,152,0);//Power glove - - render16(92,56,0,128,0);//Player(Carrying) - render16(92,44,128,128,0);//Workbench - break; - case 4: // Crafting - renderFrame(11,3,19,6,0xFFFF1010); - renderFrame(11,7,19,12,0xFFFF1010); - renderFrame(1,3,10,12,0xFFFF1010); - renderItemStuffWithText(TOOL_AXE,0,true,28,64); - renderItemIcon(TOOL_AXE, 0, 94, 32); - drawText("0", 206, 66); - renderItemIcon(ITEM_WOOD, 0, 94, 64); - drawText("16/5", 206, 130); - break; - case 5: // Farming (Bottom screen) - renderc(24,16,352,48,112,16,0); // Wheat Stages - - render16(20,40,352,48,0); // Farm Tile - render16(36,40,448,48,0); // Wheat Tile - render16(52,40,448,48,0); // Wheat Tile - render16(20,54,16,112,0); // Player (Up) - renderc(20,50,16,160,16,8,0); // Slash (Up) - render(19,45,40,152,0); // Seeds - render(26,39,48,152,0); // Wheat1 - render(29,44,48,152,0); // Wheat2 - - renderc(72,40,352,48,32,16,0); // Farm Tile + Seeded Wheat Tile - render16(72,54,16,112,0); // Player (Up) - renderc(72,50,16,160,16,8,0); // Slash (Up) - render(76,48,40,152,0); // Seeds - - sf2d_draw_rectangle(216, 80, 32, 32, dirtColor[1]); // Dirt color for grass - render16(108, 40, 256, 0, 0); // Grass - render16(124, 40,352,48,0); // Farm Tile - render16(108,54,16,112,0); // Player (Up) - renderc(108,50,16,160,16,8,0); // Slash (Up) - render(112,48,72,144,0); // Gem Hoe - - sf2d_draw_rectangle(112, 156, 32, 32, dirtColor[1]); // Dirt color for grass - render16(56, 78, 256, 0, 0); // Grass - sf2d_draw_rectangle(80, 156, 32, 32, dirtColor[1]); // Dirt color - render16(40, 78, 336, 80, 0); // Dirt Dots - render(44, 82, 40,152,0); // Seeds - - render16(24,78,48,112,0); // Player (Right) - renderc(36,78,40,160,8,16,0); // Slash (Right) - render(38,82,32,144,0); // Gem Shovel - - render(82,78,48,152,0); // Wheat - render(90,78,48,152,0); // Wheat - render(82,86,48,152,0); // Wheat - render(90,86,48,152,0); // Wheat - drawText(">",203,164); - render16(108,76,96,128,0); // Oven - drawText(">",246,164); - render(132,82,72,152,0); // Bread - break; - case 6: //Mining - render16(23,32,464,48,0); // iron ore - render16(23,52,480,48,0); // gold ore - render16(23,72,496,48,0); // gem ore - renderb(41,38,88,152,0,ironColor); // Iron ore item - renderb(41,58,88,152,0,goldColor); // Gold ore item - render(41,78,112,152,0); // Gem item - drawText(">",104,74); - drawText(">",104,114); - drawText(">",104,154); - render16(60,32,112,128,0); // Furnace - render16(60,52,112,128,0); // Furnace - render16(60,72,240,128,0); // Enchanter - drawText(">",160,74); - drawText(">",160,114); - drawText(">",160,154); - renderb(88,36,96,152,0,ironColor); // Iron ingot item - renderb(88,56,96,152,0,goldColor); // Gold ingot item - renderb(88,76,152,144,0,goldColor); // Gem Pickaxe - drawText(">",200,74); - drawText(">",200,114); - render16(106,32,64,128,0); // Anvil - render16(106,52,64,128,0); // Anvil - drawText(">",244,74); - drawText(">",244,114); - render(130,36,136,144,0); // Iron Pickaxe - render(130,56,144,144,0); // Gold Pickaxe - break; + render16(12+8,20+4,256,48,0);//Tree + renderc(12+9,20+14,16,160,16,8,0);//Slash + render(12+9+4,20+14,192,144,0);//Axe + render16(12+9,20+18,16,112,0);//Player-up + + menuRenderTilePit(122,62,320,0);// sand pit + render16(130,70,256,16,0);// hole + render16(116,70,48,112,0);//Player-right + renderb(136,76,16,152,0,sandColor);// Sand item + renderc(128,70,40,160,8,16,0);//Slash + render(130,74,0,144,0);//Shovel + break; + case 2: // Inventory + renderFrame(4,4,17,11,0xFFFF1010); + renderItemStuffWithText(ITEM_APPLE,5,false,80,78); + renderItemStuffWithText(ITEM_SLIME,11,false,80,94); + renderItemStuffWithText(TOOL_SWORD,4,true,80,110); + renderItemStuffWithText(ITEM_IRONORE,3,false,80,126); + renderItemStuffWithText(ITEM_IRONINGOT,11,false,80,142); + sf2d_draw_rectangle(64, 110, 12, 12, 0xFF); + drawText(">", 64, 110); + renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 44, 92, 1); + renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 44, 108, 1); + renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 44, 125, 1); + break; + case 3: // Furniture + sf2d_draw_rectangle(64, 48, 192, 32, grassColor); + renderc(32,24,64,128,96,16,0);//Furniture entities + + renderFurniture(ITEM_WORKBENCH, 50,60); + render16(50,46,0,112,0);//Player-down + renderc(50,58,16,160,16,8,2);//Slash + render(54,58,56,152,0);//Power glove + + render16(92,56,0,128,0);//Player(Carrying) + render16(92,44,128,128,0);//Workbench + break; + case 4: // Crafting + renderFrame(11,3,19,6,0xFFFF1010); + renderFrame(11,7,19,12,0xFFFF1010); + renderFrame(1,3,10,12,0xFFFF1010); + renderItemStuffWithText(TOOL_AXE,0,true,28,64); + renderItemIcon(TOOL_AXE, 0, 94, 32); + drawText("0", 206, 66); + renderItemIcon(ITEM_WOOD, 0, 94, 64); + drawText("16/5", 206, 130); + break; + case 5: // Farming (Bottom screen) + renderc(24,16,352,48,112,16,0); // Wheat Stages + + render16(20,40,352,48,0); // Farm Tile + render16(36,40,448,48,0); // Wheat Tile + render16(52,40,448,48,0); // Wheat Tile + render16(20,54,16,112,0); // Player (Up) + renderc(20,50,16,160,16,8,0); // Slash (Up) + render(19,45,40,152,0); // Seeds + render(26,39,48,152,0); // Wheat1 + render(29,44,48,152,0); // Wheat2 + + renderc(72,40,352,48,32,16,0); // Farm Tile + Seeded Wheat Tile + render16(72,54,16,112,0); // Player (Up) + renderc(72,50,16,160,16,8,0); // Slash (Up) + render(76,48,40,152,0); // Seeds + + sf2d_draw_rectangle(216, 80, 32, 32, dirtColor[1]); // Dirt color for grass + render16(108, 40, 256, 0, 0); // Grass + render16(124, 40,352,48,0); // Farm Tile + render16(108,54,16,112,0); // Player (Up) + renderc(108,50,16,160,16,8,0); // Slash (Up) + render(112,48,72,144,0); // Gem Hoe + + sf2d_draw_rectangle(112, 156, 32, 32, dirtColor[1]); // Dirt color for grass + render16(56, 78, 256, 0, 0); // Grass + sf2d_draw_rectangle(80, 156, 32, 32, dirtColor[1]); // Dirt color + render16(40, 78, 336, 80, 0); // Dirt Dots + render(44, 82, 40,152,0); // Seeds + + render16(24,78,48,112,0); // Player (Right) + renderc(36,78,40,160,8,16,0); // Slash (Right) + render(38,82,32,144,0); // Gem Shovel + + render(82,78,48,152,0); // Wheat + render(90,78,48,152,0); // Wheat + render(82,86,48,152,0); // Wheat + render(90,86,48,152,0); // Wheat + drawText(">",203,164); + render16(108,76,96,128,0); // Oven + drawText(">",246,164); + render(132,82,72,152,0); // Bread + break; + case 6: //Mining + render16(23,32,464,48,0); // iron ore + render16(23,52,480,48,0); // gold ore + render16(23,72,496,48,0); // gem ore + renderb(41,38,88,152,0,ironColor); // Iron ore item + renderb(41,58,88,152,0,goldColor); // Gold ore item + render(41,78,112,152,0); // Gem item + drawText(">",104,74); + drawText(">",104,114); + drawText(">",104,154); + render16(60,32,112,128,0); // Furnace + render16(60,52,112,128,0); // Furnace + render16(60,72,240,128,0); // Enchanter + drawText(">",160,74); + drawText(">",160,114); + drawText(">",160,154); + renderb(88,36,96,152,0,ironColor); // Iron ingot item + renderb(88,56,96,152,0,goldColor); // Gold ingot item + renderb(88,76,152,144,0,goldColor); // Gem Pickaxe + drawText(">",200,74); + drawText(">",200,114); + render16(106,32,64,128,0); // Anvil + render16(106,52,64,128,0); // Anvil + drawText(">",244,74); + drawText(">",244,114); + render(130,36,136,144,0); // Iron Pickaxe + render(130,56,144,144,0); // Gold Pickaxe + break; case 7: // Brewing - render16(65, 56, 240, 96, 0); - break; - } - - drawText(pageText,(320-(strlen(pageText))*12)/2,12); - if(pageNum > 0){ - drawText("<",2,16); - renderButtonIcon(localInputs.k_menuPrev.input & -localInputs.k_menuPrev.input, 8, 2, 2); - } - if(pageNum < maxPageNum){ - drawText(">",306,16); - renderButtonIcon(localInputs.k_menuNext.input & -localInputs.k_menuNext.input, 136, 2, 2); - } - drawText("Press to exit",(320-(15*12))/2,218); - renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 140, 216, 1); - } + render16(65, 56, 240, 96, 0); + break; + } + + drawText(pageText,(320-(strlen(pageText))*12)/2,12); + if(pageNum > 0){ + drawText("<",2,16); + renderButtonIcon(localInputs.k_menuPrev.input & -localInputs.k_menuPrev.input, 8, 2, 2); + } + if(pageNum < maxPageNum){ + drawText(">",306,16); + renderButtonIcon(localInputs.k_menuNext.input & -localInputs.k_menuNext.input, 136, 2, 2); + } + drawText("Press to exit",(320-(15*12))/2,218); + renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 140, 216, 1); + } } diff --git a/source/MenuTutorial.h b/source/MenuTutorial.h index 682d7c7..5ce7f4e 100755 --- a/source/MenuTutorial.h +++ b/source/MenuTutorial.h @@ -1,7 +1,7 @@ #pragma once #include <3ds.h> -#include +#include #include #include #include diff --git a/source/Network.c b/source/Network.c index 9e6bbce..1489bbe 100755 --- a/source/Network.c +++ b/source/Network.c @@ -46,211 +46,211 @@ void clearSendAckedBuffer(); bool sendAck(u16 target, u16 ack); void networkThreadMain(void *arg) { - while(networkRunThread) { - if(udsRunning && isConnected) { - networkUpdateStatus(); - networkHandleRecieve(); - networkHandleSend(); - } - - //TODO: Set meaningfull value, WARNING: Setting this near 1ms (1000*1000) will make everything super laggy, higher values actually work better! - svcSleepThread(10000 * 1000); - } + while(networkRunThread) { + if(udsRunning && isConnected) { + networkUpdateStatus(); + networkHandleRecieve(); + networkHandleSend(); + } + + //TODO: Set meaningfull value, WARNING: Setting this near 1ms (1000*1000) will make everything super laggy, higher values actually work better! + svcSleepThread(10000 * 1000); + } } void networkUpdateStatus() { - /*for(int i=0; i<10; i++) { - Result ret = udsGetConnectionStatus(&networkStatus); - if(!R_FAILED(ret)) { - return; - } - }*/ - if(udsWaitConnectionStatusEvent(false, false)) { - udsGetConnectionStatus(&networkStatus); - } + /*for(int i=0; i<10; i++) { + Result ret = udsGetConnectionStatus(&networkStatus); + if(!R_FAILED(ret)) { + return; + } + }*/ + if(udsWaitConnectionStatusEvent(false, false)) { + udsGetConnectionStatus(&networkStatus); + } } void networkHandleRecieve() { - bool recieved = false; - do { - recieved = false; - - size_t actualSize = 0; + bool recieved = false; + do { + recieved = false; + + size_t actualSize = 0; u16 sourceNetworkNodeID; - u32 ackToSend = 0; - + u32 ackToSend = 0; + memset(networkBuffer, 0, networkBufferSize); - + Result ret = udsPullPacket(&networkBindCtx, networkBuffer, networkBufferSize, &actualSize, &sourceNetworkNodeID); if(R_FAILED(ret)) { //TODO: what do? - + //actualSize will be 0 if no packet is available } else if(actualSize) { - void *readPointer = networkBuffer; - - //ack frame - if(actualSize==sizeof(u16)) { - networkSeqSendConf[sourceNetworkNodeID] = *((u16*) readPointer); - clearSendAckedBuffer(); - //normal frame - } else { - while(actualSize>0) { - //read seqID and size - u16 seqID = *((u16*) readPointer); - readPointer += sizeof(u16); - actualSize -= sizeof(u16); - - u16 size = *((u16*) readPointer); - readPointer += sizeof(u16); - actualSize -= sizeof(u16); - - //if the seq id was expected handle the packet - u16 nextID = networkGetExpectedSeqFrom(sourceNetworkNodeID); - if(seqID==nextID) { - networkSeqRecvLast[sourceNetworkNodeID] = seqID; - ackToSend = seqID; - - //handle data - TODO: WARNING: Do not send sizeof(u16) packets or else they will get confused with this one - if(size==sizeof(u16)) { - networkConnectedMask = *((u16*) readPointer); - } else { - processPacket(readPointer, size); - } - } else if(networkSeqIsLowerThan(seqID, nextID)) { - ackToSend = seqID; - } - readPointer += size; - actualSize -= size; - } - - if(ackToSend!=0) { - if(sendAck(sourceNetworkNodeID, ackToSend)) { - } - } - } - - recieved = true; - } - } while(recieved); + void *readPointer = networkBuffer; + + //ack frame + if(actualSize==sizeof(u16)) { + networkSeqSendConf[sourceNetworkNodeID] = *((u16*) readPointer); + clearSendAckedBuffer(); + //normal frame + } else { + while(actualSize>0) { + //read seqID and size + u16 seqID = *((u16*) readPointer); + readPointer += sizeof(u16); + actualSize -= sizeof(u16); + + u16 size = *((u16*) readPointer); + readPointer += sizeof(u16); + actualSize -= sizeof(u16); + + //if the seq id was expected handle the packet + u16 nextID = networkGetExpectedSeqFrom(sourceNetworkNodeID); + if(seqID==nextID) { + networkSeqRecvLast[sourceNetworkNodeID] = seqID; + ackToSend = seqID; + + //handle data - TODO: WARNING: Do not send sizeof(u16) packets or else they will get confused with this one + if(size==sizeof(u16)) { + networkConnectedMask = *((u16*) readPointer); + } else { + processPacket(readPointer, size); + } + } else if(networkSeqIsLowerThan(seqID, nextID)) { + ackToSend = seqID; + } + readPointer += size; + actualSize -= size; + } + + if(ackToSend!=0) { + if(sendAck(sourceNetworkNodeID, ackToSend)) { + } + } + } + + recieved = true; + } + } while(recieved); } void networkHandleSend() { - if(networkSendBufferStartPos!=networkSendBufferEndPos) { - LightLock_Lock(&sendBufferLock); - - //determine send size - size_t currentSize = 0; - while(networkSendBufferStartPos+currentSize0) { - //TODO: Once we have our own custom mask, no longer broadcast, but send directly because bcast doesn't always reach everyone? - if(networkConnectedMask==0) { - //send frame - Result ret = udsSendTo(UDS_BROADCAST_NETWORKNODEID, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize); - if(UDS_CHECK_SENDTO_FATALERROR(ret)) { - //TODO: what do? - } else if(R_FAILED(ret)) { - //TODO: what do? - } - } else { - for(int i=1; i<=UDS_MAXNODES; i++) { - if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) { - //send frame - Result ret = udsSendTo(i, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize); - if(UDS_CHECK_SENDTO_FATALERROR(ret)) { - //TODO: what do? - } else if(R_FAILED(ret)) { - //TODO: what do? - } - } - } - } - } - - LightLock_Unlock(&sendBufferLock); - } + if(networkSendBufferStartPos!=networkSendBufferEndPos) { + LightLock_Lock(&sendBufferLock); + + //determine send size + size_t currentSize = 0; + while(networkSendBufferStartPos+currentSize0) { + //TODO: Once we have our own custom mask, no longer broadcast, but send directly because bcast doesn't always reach everyone? + if(networkConnectedMask==0) { + //send frame + Result ret = udsSendTo(UDS_BROADCAST_NETWORKNODEID, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize); + if(UDS_CHECK_SENDTO_FATALERROR(ret)) { + //TODO: what do? + } else if(R_FAILED(ret)) { + //TODO: what do? + } + } else { + for(int i=1; i<=UDS_MAXNODES; i++) { + if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) { + //send frame + Result ret = udsSendTo(i, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize); + if(UDS_CHECK_SENDTO_FATALERROR(ret)) { + //TODO: what do? + } else if(R_FAILED(ret)) { + //TODO: what do? + } + } + } + } + } + + LightLock_Unlock(&sendBufferLock); + } } void clearSendAckedBuffer() { - //find last ack recieved from all com partners - u16 ackID = 0; - for(int i=1; i<=UDS_MAXNODES; i++) { - if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) { - if(networkSeqSendConf[i]==0) { - ackID = 0; - return; - } - - if(ackID==0) { - ackID = networkSeqSendConf[i]; - } else if(networkSeqSendConf[i]<100) { - if(ackID > networkSeqSendConf[i] && ackID<65535-100) ackID = networkSeqSendConf[i]; - } else if(networkSeqSendConf[i]>65535-100) { - if(ackID > networkSeqSendConf[i] || ackID<100) ackID = networkSeqSendConf[i]; - } else { - if(ackID > networkSeqSendConf[i]) ackID = networkSeqSendConf[i]; - } - } - } - if(ackID==0) return; - - LightLock_Lock(&sendBufferLock); - - //clear buffer of acknowledgt packets - while(networkSendBufferStartPos!=networkSendBufferEndPos) { - //find current seqid and size - u16 seqID = *((u16*) (networkSendBuffer+networkSendBufferStartPos)); - u16 size = *((u16*) (networkSendBuffer+networkSendBufferStartPos+sizeof(u16))); - - if(seqID<=ackID || (ackID<100 && seqID>65535-100)) { - - size_t currentSize = sizeof(u16)*2 + size; - - //adjust buffer "pointers" - networkSendBufferStartPos += currentSize; - if(networkSendBufferStartPos==networkSendBufferEndPos) { - networkSendBufferStartPos = 0; - networkSendBufferEndPos = 0; - networkSendBufferWrapPos = 0; - } - - //wrap - if(networkSendBufferStartPos==networkSendBufferWrapPos) { - networkSendBufferStartPos = 0; - networkSendBufferWrapPos = networkSendBufferEndPos; - } - } else { - break; - } - } - LightLock_Unlock(&sendBufferLock); + //find last ack recieved from all com partners + u16 ackID = 0; + for(int i=1; i<=UDS_MAXNODES; i++) { + if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) { + if(networkSeqSendConf[i]==0) { + ackID = 0; + return; + } + + if(ackID==0) { + ackID = networkSeqSendConf[i]; + } else if(networkSeqSendConf[i]<100) { + if(ackID > networkSeqSendConf[i] && ackID<65535-100) ackID = networkSeqSendConf[i]; + } else if(networkSeqSendConf[i]>65535-100) { + if(ackID > networkSeqSendConf[i] || ackID<100) ackID = networkSeqSendConf[i]; + } else { + if(ackID > networkSeqSendConf[i]) ackID = networkSeqSendConf[i]; + } + } + } + if(ackID==0) return; + + LightLock_Lock(&sendBufferLock); + + //clear buffer of acknowledgt packets + while(networkSendBufferStartPos!=networkSendBufferEndPos) { + //find current seqid and size + u16 seqID = *((u16*) (networkSendBuffer+networkSendBufferStartPos)); + u16 size = *((u16*) (networkSendBuffer+networkSendBufferStartPos+sizeof(u16))); + + if(seqID<=ackID || (ackID<100 && seqID>65535-100)) { + + size_t currentSize = sizeof(u16)*2 + size; + + //adjust buffer "pointers" + networkSendBufferStartPos += currentSize; + if(networkSendBufferStartPos==networkSendBufferEndPos) { + networkSendBufferStartPos = 0; + networkSendBufferEndPos = 0; + networkSendBufferWrapPos = 0; + } + + //wrap + if(networkSendBufferStartPos==networkSendBufferWrapPos) { + networkSendBufferStartPos = 0; + networkSendBufferWrapPos = networkSendBufferEndPos; + } + } else { + break; + } + } + LightLock_Unlock(&sendBufferLock); } bool sendAck(u16 target, u16 ack) { - Result ret = udsSendTo(target, NETWORK_CHANNEL, UDS_SENDFLAG_Default, &ack, sizeof(u16)); - if(UDS_CHECK_SENDTO_FATALERROR(ret)) { - //TODO: what do? - return false; - } else if(R_FAILED(ret)) { - //TODO: what do? - return false; - } else { - return true; - } + Result ret = udsSendTo(target, NETWORK_CHANNEL, UDS_SENDFLAG_Default, &ack, sizeof(u16)); + if(UDS_CHECK_SENDTO_FATALERROR(ret)) { + //TODO: what do? + return false; + } else if(R_FAILED(ret)) { + //TODO: what do? + return false; + } else { + return true; + } } void networkInit() { @@ -259,87 +259,87 @@ void networkInit() { udsRunning = false; } else { udsRunning = true; - + scannedNetworksCount = 0; scannedNetworks = NULL; isConnected = false; isServer = false; - networkConnectedMask = 0; + networkConnectedMask = 0; - networkWriteBuffer = malloc(NETWORK_MAXDATASIZE); - if(networkWriteBuffer==NULL) { - networkExit(); - return; - } - - networkBufferSize = 0x4000; + networkWriteBuffer = malloc(NETWORK_MAXDATASIZE); + if(networkWriteBuffer==NULL) { + networkExit(); + return; + } + + networkBufferSize = 0x4000; networkBuffer = malloc(networkBufferSize); - if(networkBuffer==NULL) { - networkExit(); - return; - } - - networkSendBufferStartPos = 0; - networkSendBufferEndPos = 0; - networkSendBufferWrapPos = 0; - networkSendBuffer = malloc(NETWORK_SENDBUFFERSIZE); - if(networkSendBuffer==NULL) { - networkExit(); - return; - } - - networkSeqSendNext = 1; - for(int i=0; i=scannedNetworksCount) return false; - + Result ret = udsGetNodeInfoUsername(&(scannedNetworks[pos].nodes[0]), name); if(R_FAILED(ret)) { //TODO: what do? @@ -418,16 +418,16 @@ bool networkGetScanName(char *name, int pos) { bool networkConnect(int pos) { if(udsRunning && !isConnected) { if(pos<0 || pos>=scannedNetworksCount) return false; - + Result ret = udsConnectNetwork(&scannedNetworks[pos].network, NETWORK_PASSPHRASE, strlen(NETWORK_PASSPHRASE)+1, &networkBindCtx, UDS_BROADCAST_NETWORKNODEID, UDSCONTYPE_Client, NETWORK_CHANNEL, NETWORK_RECVBUFSIZE); if(R_FAILED(ret)) { return false; } else { - if(udsWaitConnectionStatusEvent(false, false)) {} - udsGetConnectionStatus(&networkStatus); + if(udsWaitConnectionStatusEvent(false, false)) {} + udsGetConnectionStatus(&networkStatus); isConnected = true; isServer = false; - networkConnectedMask = 0; + networkConnectedMask = 0; return true; } } @@ -438,25 +438,25 @@ void networkDisconnect() { //For clients this just means disconnect, for the server it means destroy the network if(udsRunning && isConnected) { isConnected = false; - - LightLock_Lock(&sendBufferLock); - //reset send buffer - networkSendBufferStartPos = 0; - networkSendBufferEndPos = 0; - networkSendBufferWrapPos = 0; - - //reset ack status - networkSeqSendNext = 1; - for(int i=0; i20*networkthreadsleep) (wait unti no more stuff gets send) - - //TODO + + LightLock_Lock(&sendBufferLock); + //reset send buffer + networkSendBufferStartPos = 0; + networkSendBufferEndPos = 0; + networkSendBufferWrapPos = 0; + + //reset ack status + networkSeqSendNext = 1; + for(int i=0; i20*networkthreadsleep) (wait unti no more stuff gets send) + + //TODO if(isServer) { //TODO: Clients need to cleanup too, how can I tell they got disconnected udsDestroyNetwork(); @@ -464,59 +464,59 @@ void networkDisconnect() { udsDisconnectNetwork(); } udsUnbind(&networkBindCtx); - + isServer = false; } } void networkStart() { - //TODO: This sends the node_bitmask from server to everyone else, because it is uncorrect on some clients? - if(udsRunning && isConnected && isServer) { - void *buffer = networkWriteBuffer; - - *((u16*) buffer) = networkStatus.node_bitmask; - networkConnectedMask = networkStatus.node_bitmask; - - networkSend(networkWriteBuffer, sizeof(u16)); - networkSendWaitFlush(); - } + //TODO: This sends the node_bitmask from server to everyone else, because it is uncorrect on some clients? + if(udsRunning && isConnected && isServer) { + void *buffer = networkWriteBuffer; + + *((u16*) buffer) = networkStatus.node_bitmask; + networkConnectedMask = networkStatus.node_bitmask; + + networkSend(networkWriteBuffer, sizeof(u16)); + networkSendWaitFlush(); + } } bool networkConnected() { return isConnected; -} +} int networkGetNodeCount() { - if(udsRunning && isConnected) { - return networkStatus.total_nodes; - } else { - return 0; - } + if(udsRunning && isConnected) { + return networkStatus.total_nodes; + } else { + return 0; + } } u16 networkGetLocalNodeID() { - if(udsRunning && isConnected) { - return networkStatus.cur_NetworkNodeID; - } else { - return 0; - } + if(udsRunning && isConnected) { + return networkStatus.cur_NetworkNodeID; + } else { + return 0; + } } bool networkIsNodeConnected(u16 id) { - if(udsRunning && isConnected) { - return networkStatus.node_bitmask & (1 << (id-1)); - } else { - return false; - } + if(udsRunning && isConnected) { + return networkStatus.node_bitmask & (1 << (id-1)); + } else { + return false; + } } bool networkGetNodeName(u16 id, char *name) { - if(udsRunning && isConnected && networkIsNodeConnected(id)) { - udsNodeInfo nodeInfo; - udsGetNodeInformation(id, &nodeInfo); - + if(udsRunning && isConnected && networkIsNodeConnected(id)) { + udsNodeInfo nodeInfo; + udsGetNodeInformation(id, &nodeInfo); + Result ret = udsGetNodeInfoUsername(&nodeInfo, name); if(R_FAILED(ret)) { //TODO: what do? @@ -547,74 +547,74 @@ bool networkSeqIsLowerThan(u16 firstID, u16 secondID) { } int fitInSendBuffer(size_t size) { - //add "header" length - size += sizeof(u16)*2; - - //we have no wrap currently - if(networkSendBufferStartPos<=networkSendBufferEndPos) { - //and can fit without wrap - if(networkSendBufferEndPos+sizesize) { - networkSendBufferEndPos += size; - - return networkSendBufferEndPos-size; - } - } - - return -1; + //add "header" length + size += sizeof(u16)*2; + + //we have no wrap currently + if(networkSendBufferStartPos<=networkSendBufferEndPos) { + //and can fit without wrap + if(networkSendBufferEndPos+sizesize) { + networkSendBufferEndPos += size; + + return networkSendBufferEndPos-size; + } + } + + return -1; } void networkSend(void *packet, size_t size) { - //search for fit in buffer (and BLOCK until free space is found) + //search for fit in buffer (and BLOCK until free space is found) LightLock_Lock(&sendBufferLock); - int pos = fitInSendBuffer(size); - while(pos==-1) { - LightLock_Unlock(&sendBufferLock); - svcSleepThread(4500 * 1000); //TODO: Set meaningfull value - LightLock_Lock(&sendBufferLock); - - pos = fitInSendBuffer(size); - } - - //fit found -> space is allready "reserved" -> write packet to buffer - void *writePointer = networkSendBuffer + pos; - - //write seq number - *((u16*) writePointer) = networkSeqSendNext; - networkSeqSendNext++; - if(networkSeqSendNext==0) { - networkSeqSendNext = 1; - } - writePointer += sizeof(u16); - - //write size - *((u16*) writePointer) = (u16) size; - writePointer += sizeof(u16); - - //write data - memcpy(writePointer, packet, size); - writePointer += size; - - LightLock_Unlock(&sendBufferLock); + int pos = fitInSendBuffer(size); + while(pos==-1) { + LightLock_Unlock(&sendBufferLock); + svcSleepThread(4500 * 1000); //TODO: Set meaningfull value + LightLock_Lock(&sendBufferLock); + + pos = fitInSendBuffer(size); + } + + //fit found -> space is allready "reserved" -> write packet to buffer + void *writePointer = networkSendBuffer + pos; + + //write seq number + *((u16*) writePointer) = networkSeqSendNext; + networkSeqSendNext++; + if(networkSeqSendNext==0) { + networkSeqSendNext = 1; + } + writePointer += sizeof(u16); + + //write size + *((u16*) writePointer) = (u16) size; + writePointer += sizeof(u16); + + //write data + memcpy(writePointer, packet, size); + writePointer += size; + + LightLock_Unlock(&sendBufferLock); } void networkSendWaitFlush() { - while(networkSendBufferStartPos!=networkSendBufferEndPos) { - svcSleepThread(4500 * 1000); - } + while(networkSendBufferStartPos!=networkSendBufferEndPos) { + svcSleepThread(4500 * 1000); + } } diff --git a/source/PacketHandler.c b/source/PacketHandler.c index 2d92c19..7369b44 100755 --- a/source/PacketHandler.c +++ b/source/PacketHandler.c @@ -5,359 +5,347 @@ FILE *recvFile; size_t recvFileSize; - - - void * writeBool(void *buffer, size_t *size, bool value) { - *((bool*) buffer) = value; - *(size) += sizeof(bool); - return buffer + sizeof(bool); + *((bool*) buffer) = value; + *(size) += sizeof(bool); + return buffer + sizeof(bool); } void * writeU8(void *buffer, size_t *size, u8 value) { - *((u8*) buffer) = value; - *(size) += sizeof(u8); - return buffer + sizeof(u8); + *((u8*) buffer) = value; + *(size) += sizeof(u8); + return buffer + sizeof(u8); } void * writeU16(void *buffer, size_t *size, u16 value) { - *((u16*) buffer) = value; - *(size) += sizeof(u16); - return buffer + sizeof(u16); + *((u16*) buffer) = value; + *(size) += sizeof(u16); + return buffer + sizeof(u16); } void * writeU32(void *buffer, size_t *size, u32 value) { - *((u32*) buffer) = value; - *(size) += sizeof(u32); - return buffer + sizeof(u32); + *((u32*) buffer) = value; + *(size) += sizeof(u32); + return buffer + sizeof(u32); } void * writeSizeT(void *buffer, size_t *size, size_t value) { - *((size_t*) buffer) = value; - *(size) += sizeof(size_t); - return buffer + sizeof(size_t); + *((size_t*) buffer) = value; + *(size) += sizeof(size_t); + return buffer + sizeof(size_t); } - - - void * readBool(void *buffer, size_t *size, bool *value) { - *value = *((bool*) buffer); - *(size) -= sizeof(bool); - return buffer + sizeof(bool); + *value = *((bool*) buffer); + *(size) -= sizeof(bool); + return buffer + sizeof(bool); } void * readU8(void *buffer, size_t *size, u8 *value) { - *value = *((u8*) buffer); - *(size) -= sizeof(u8); - return buffer + sizeof(u8); + *value = *((u8*) buffer); + *(size) -= sizeof(u8); + return buffer + sizeof(u8); } void * readU16(void *buffer, size_t *size, u16 *value) { - *value = *((u16*) buffer); - *(size) -= sizeof(u16); - return buffer + sizeof(u16); + *value = *((u16*) buffer); + *(size) -= sizeof(u16); + return buffer + sizeof(u16); } void * readU32(void *buffer, size_t *size, u32 *value) { - *value = *((u32*) buffer); - *(size) -= sizeof(u32); - return buffer + sizeof(u32); + *value = *((u32*) buffer); + *(size) -= sizeof(u32); + return buffer + sizeof(u32); } void * readSizeT(void *buffer, size_t *size, size_t *value) { - *value = *((size_t*) buffer); - *(size) -= sizeof(size_t); - return buffer + sizeof(size_t); + *value = *((size_t*) buffer); + *(size) -= sizeof(size_t); + return buffer + sizeof(size_t); } - - - void processPacket(void *packet, size_t size) { - //Differenciate the packets and process them - switch(packetGetID(packet)) { - case PACKET_START: { - void *buffer = packetGetDataStart(packet); - size = packetGetDataSize(size); - - //find player index based on network node id - //and set player uuid in synchronizer - u32 seed; - u32 playerCount = 1; - int playerIndex = 0; - - buffer = readU32(buffer, &size, &seed); - buffer = readU32(buffer, &size, &playerCount); - for(int i=0; ik_touch.px); - buffer = writeU16(buffer, &size, inputs->k_touch.py); - - buffer = writeBool(buffer, &size, inputs->k_up.down); buffer = writeBool(buffer, &size, inputs->k_up.clicked); - buffer = writeBool(buffer, &size, inputs->k_down.down); buffer = writeBool(buffer, &size, inputs->k_down.clicked); - buffer = writeBool(buffer, &size, inputs->k_left.down); buffer = writeBool(buffer, &size, inputs->k_left.clicked); - buffer = writeBool(buffer, &size, inputs->k_right.down); buffer = writeBool(buffer, &size, inputs->k_right.clicked); - buffer = writeBool(buffer, &size, inputs->k_attack.down); buffer = writeBool(buffer, &size, inputs->k_attack.clicked); - buffer = writeBool(buffer, &size, inputs->k_menu.down); buffer = writeBool(buffer, &size, inputs->k_menu.clicked); - buffer = writeBool(buffer, &size, inputs->k_pause.down); buffer = writeBool(buffer, &size, inputs->k_pause.clicked); - buffer = writeBool(buffer, &size, inputs->k_accept.down); buffer = writeBool(buffer, &size, inputs->k_accept.clicked); - buffer = writeBool(buffer, &size, inputs->k_decline.down); buffer = writeBool(buffer, &size, inputs->k_decline.clicked); - buffer = writeBool(buffer, &size, inputs->k_delete.down); buffer = writeBool(buffer, &size, inputs->k_delete.clicked); - buffer = writeBool(buffer, &size, inputs->k_menuNext.down); buffer = writeBool(buffer, &size, inputs->k_menuNext.clicked); - buffer = writeBool(buffer, &size, inputs->k_menuPrev.down); buffer = writeBool(buffer, &size, inputs->k_menuPrev.clicked); - - return size; + size_t size = 0; + buffer = writeU8(buffer, &size, PACKET_TURN_INPUT); + buffer = writeU8(buffer, &size, playerID); + buffer = writeU32(buffer, &size, turnNumber); + + buffer = writeU16(buffer, &size, inputs->k_touch.px); + buffer = writeU16(buffer, &size, inputs->k_touch.py); + + buffer = writeBool(buffer, &size, inputs->k_up.down); buffer = writeBool(buffer, &size, inputs->k_up.clicked); + buffer = writeBool(buffer, &size, inputs->k_down.down); buffer = writeBool(buffer, &size, inputs->k_down.clicked); + buffer = writeBool(buffer, &size, inputs->k_left.down); buffer = writeBool(buffer, &size, inputs->k_left.clicked); + buffer = writeBool(buffer, &size, inputs->k_right.down); buffer = writeBool(buffer, &size, inputs->k_right.clicked); + buffer = writeBool(buffer, &size, inputs->k_attack.down); buffer = writeBool(buffer, &size, inputs->k_attack.clicked); + buffer = writeBool(buffer, &size, inputs->k_menu.down); buffer = writeBool(buffer, &size, inputs->k_menu.clicked); + buffer = writeBool(buffer, &size, inputs->k_pause.down); buffer = writeBool(buffer, &size, inputs->k_pause.clicked); + buffer = writeBool(buffer, &size, inputs->k_accept.down); buffer = writeBool(buffer, &size, inputs->k_accept.clicked); + buffer = writeBool(buffer, &size, inputs->k_decline.down); buffer = writeBool(buffer, &size, inputs->k_decline.clicked); + buffer = writeBool(buffer, &size, inputs->k_delete.down); buffer = writeBool(buffer, &size, inputs->k_delete.clicked); + buffer = writeBool(buffer, &size, inputs->k_menuNext.down); buffer = writeBool(buffer, &size, inputs->k_menuNext.clicked); + buffer = writeBool(buffer, &size, inputs->k_menuPrev.down); buffer = writeBool(buffer, &size, inputs->k_menuPrev.clicked); + + return size; } bool readInputPacketData(void *buffer, size_t size, Inputs *inputs) { - buffer = readU16(buffer, &size, &(inputs->k_touch.px)); - if(size<=0) return false; - buffer = readU16(buffer, &size, &(inputs->k_touch.py)); - if(size<=0) return false; - - buffer = readBool(buffer, &size, &(inputs->k_up.down)); buffer = readBool(buffer, &size, &(inputs->k_up.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_down.down)); buffer = readBool(buffer, &size, &(inputs->k_down.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_left.down)); buffer = readBool(buffer, &size, &(inputs->k_left.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_right.down)); buffer = readBool(buffer, &size, &(inputs->k_right.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_attack.down)); buffer = readBool(buffer, &size, &(inputs->k_attack.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_menu.down)); buffer = readBool(buffer, &size, &(inputs->k_menu.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_pause.down)); buffer = readBool(buffer, &size, &(inputs->k_pause.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_accept.down)); buffer = readBool(buffer, &size, &(inputs->k_accept.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_decline.down)); buffer = readBool(buffer, &size, &(inputs->k_decline.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_delete.down)); buffer = readBool(buffer, &size, &(inputs->k_delete.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_menuNext.down)); buffer = readBool(buffer, &size, &(inputs->k_menuNext.clicked)); - if(size<=0) return false; - buffer = readBool(buffer, &size, &(inputs->k_menuPrev.down)); buffer = readBool(buffer, &size, &(inputs->k_menuPrev.clicked)); + buffer = readU16(buffer, &size, &(inputs->k_touch.px)); + if(size<=0) return false; + buffer = readU16(buffer, &size, &(inputs->k_touch.py)); + if(size<=0) return false; - return size==0; + buffer = readBool(buffer, &size, &(inputs->k_up.down)); buffer = readBool(buffer, &size, &(inputs->k_up.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_down.down)); buffer = readBool(buffer, &size, &(inputs->k_down.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_left.down)); buffer = readBool(buffer, &size, &(inputs->k_left.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_right.down)); buffer = readBool(buffer, &size, &(inputs->k_right.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_attack.down)); buffer = readBool(buffer, &size, &(inputs->k_attack.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_menu.down)); buffer = readBool(buffer, &size, &(inputs->k_menu.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_pause.down)); buffer = readBool(buffer, &size, &(inputs->k_pause.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_accept.down)); buffer = readBool(buffer, &size, &(inputs->k_accept.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_decline.down)); buffer = readBool(buffer, &size, &(inputs->k_decline.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_delete.down)); buffer = readBool(buffer, &size, &(inputs->k_delete.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_menuNext.down)); buffer = readBool(buffer, &size, &(inputs->k_menuNext.clicked)); + if(size<=0) return false; + buffer = readBool(buffer, &size, &(inputs->k_menuPrev.down)); buffer = readBool(buffer, &size, &(inputs->k_menuPrev.clicked)); + + return size==0; } void sendFile(FILE *file, u8 fileType, u8 id) { - fseek(file, 0, SEEK_END); // seek to end of file - size_t fsize = ftell(file); // get current file pointer - fseek(file, 0, SEEK_SET); // seek back to beginning of file - - //send file header - void *buffer = networkWriteBuffer; - size_t size = 0; - buffer = writeU8(buffer, &size, PACKET_START_FILEHEADER); - buffer = writeU8(buffer, &size, 0); - buffer = writeU32(buffer, &size, 0); - buffer = writeU8(buffer, &size, fileType); - buffer = writeU8(buffer, &size, id); - buffer = writeSizeT(buffer, &size, fsize); - networkSend(networkWriteBuffer, size); - - //send file data - while(fsize>0) { - buffer = networkWriteBuffer; - size = 0; - buffer = writeU8(buffer, &size, PACKET_START_FILEDATA); - buffer = writeU8(buffer, &size, 0); - buffer = writeU32(buffer, &size, 0); - - //read file data - size_t towrite = NETWORK_MAXDATASIZE - size; - if(towrite>fsize) towrite = fsize; - - fread(buffer, 1, towrite, file); - - size += towrite; - fsize -= towrite; - - //send file data - networkSend(networkWriteBuffer, size); - } + fseek(file, 0, SEEK_END); // seek to end of file + size_t fsize = ftell(file); // get current file pointer + fseek(file, 0, SEEK_SET); // seek back to beginning of file + + //send file header + void *buffer = networkWriteBuffer; + size_t size = 0; + buffer = writeU8(buffer, &size, PACKET_START_FILEHEADER); + buffer = writeU8(buffer, &size, 0); + buffer = writeU32(buffer, &size, 0); + buffer = writeU8(buffer, &size, fileType); + buffer = writeU8(buffer, &size, id); + buffer = writeSizeT(buffer, &size, fsize); + networkSend(networkWriteBuffer, size); + + //send file data + while(fsize>0) { + buffer = networkWriteBuffer; + size = 0; + buffer = writeU8(buffer, &size, PACKET_START_FILEDATA); + buffer = writeU8(buffer, &size, 0); + buffer = writeU32(buffer, &size, 0); + + //read file data + size_t towrite = NETWORK_MAXDATASIZE - size; + if(towrite>fsize) towrite = fsize; + + fread(buffer, 1, towrite, file); + + size += towrite; + fsize -= towrite; + + //send file data + networkSend(networkWriteBuffer, size); + } } void sendIDPacket(u8 playerID, u32 uid) { - void *buffer = networkWriteBuffer; - size_t size = 0; - - buffer = writeU8(buffer, &size, PACKET_START_ID); - buffer = writeU8(buffer, &size, playerID); - buffer = writeU32(buffer, &size, 0); - - buffer = writeU32(buffer, &size, uid); - - networkSend(networkWriteBuffer, size); + void *buffer = networkWriteBuffer; + size_t size = 0; + + buffer = writeU8(buffer, &size, PACKET_START_ID); + buffer = writeU8(buffer, &size, playerID); + buffer = writeU32(buffer, &size, 0); + + buffer = writeU32(buffer, &size, uid); + + networkSend(networkWriteBuffer, size); } void sendStartReadyPacket(u8 playerID) { - void *buffer = networkWriteBuffer; - size_t size = 0; - - buffer = writeU8(buffer, &size, PACKET_START_READY); - buffer = writeU8(buffer, &size, playerID); - buffer = writeU32(buffer, &size, 0); - - networkSend(networkWriteBuffer, size); + void *buffer = networkWriteBuffer; + size_t size = 0; + + buffer = writeU8(buffer, &size, PACKET_START_READY); + buffer = writeU8(buffer, &size, playerID); + buffer = writeU32(buffer, &size, 0); + + networkSend(networkWriteBuffer, size); } void sendStartSyncPacket() { - void *buffer = networkWriteBuffer; - size_t size = 0; - - buffer = writeU8(buffer, &size, PACKET_TURN_START); - buffer = writeU8(buffer, &size, 0); - buffer = writeU32(buffer, &size, 0); - - networkSend(networkWriteBuffer, size); + void *buffer = networkWriteBuffer; + size_t size = 0; + + buffer = writeU8(buffer, &size, PACKET_TURN_START); + buffer = writeU8(buffer, &size, 0); + buffer = writeU32(buffer, &size, 0); + + networkSend(networkWriteBuffer, size); } diff --git a/source/Player.c b/source/Player.c index 20cb454..8d3ec55 100644 --- a/source/Player.c +++ b/source/Player.c @@ -19,15 +19,15 @@ void potionEffect(int type) { } void initPlayers() { - for(int i=0; ientity.type = ENTITY_PLAYER; - pd->entity.level = 1; - pd->entity.xr = 4; - pd->entity.yr = 3; - pd->entity.canSwim = true; - pd->entity.p.ax = 0; - pd->entity.p.ay = 0; - pd->entity.p.health = 10; - pd->entity.p.stamina = 10; - pd->entity.p.walkDist = 0; - pd->entity.p.attackTimer = 0; - pd->entity.p.dir = 0; - pd->entity.p.isDead = false; - pd->entity.p.hasWon = false; - - pd->entity.p.data = pd; + pd->entity.type = ENTITY_PLAYER; + pd->entity.level = 1; + pd->entity.xr = 4; + pd->entity.yr = 3; + pd->entity.canSwim = true; + pd->entity.p.ax = 0; + pd->entity.p.ay = 0; + pd->entity.p.health = 10; + pd->entity.p.stamina = 10; + pd->entity.p.walkDist = 0; + pd->entity.p.attackTimer = 0; + pd->entity.p.dir = 0; + pd->entity.p.isDead = false; + pd->entity.p.hasWon = false; + + pd->entity.p.data = pd; } void playerInitInventory(PlayerData *pd) { - //reset inventory - pd->inventory.lastSlot = 0; - pd->activeItem = &noItem; - - addItemToInventory(newItem(ITEM_WORKBENCH,0), &(pd->inventory)); - addItemToInventory(newItem(ITEM_POWGLOVE,0), &(pd->inventory)); - - if(shouldRenderDebug && playerCount < 2) { + //reset inventory + pd->inventory.lastSlot = 0; + pd->activeItem = &noItem; + + addItemToInventory(newItem(ITEM_WORKBENCH,0), &(pd->inventory)); + addItemToInventory(newItem(ITEM_POWGLOVE,0), &(pd->inventory)); + + if(shouldRenderDebug && playerCount < 2) { addItemToInventory(newItem(ITEM_GOLD_APPLE,1), &(pd->inventory)); addItemToInventory(newItem(ITEM_STRENGTH_POTION,1), &(pd->inventory)); addItemToInventory(newItem(ITEM_REGEN_POTION,1), &(pd->inventory)); addItemToInventory(newItem(ITEM_SWIM_BREATH_POTION,1), &(pd->inventory)); addItemToInventory(newItem(ITEM_SPEED_POTION,1), &(pd->inventory)); addItemToInventory(newItem(ITEM_POTION_MAKER,0), &(pd->inventory)); - addItemToInventory(newItem(TOOL_SHOVEL,1), &(pd->inventory)); - addItemToInventory(newItem(TOOL_HOE,4), &(pd->inventory)); - addItemToInventory(newItem(TOOL_SWORD,4), &(pd->inventory)); - addItemToInventory(newItem(TOOL_PICKAXE,4), &(pd->inventory)); - addItemToInventory(newItem(TOOL_AXE,4), &(pd->inventory)); - - addItemToInventory(newItem(ITEM_ANVIL,0), &(pd->inventory)); - addItemToInventory(newItem(ITEM_CHEST,0), &(pd->inventory)); - addItemToInventory(newItem(ITEM_OVEN,0), &(pd->inventory)); - addItemToInventory(newItem(ITEM_FURNACE,0), &(pd->inventory)); - addItemToInventory(newItem(ITEM_LANTERN,0), &(pd->inventory)); - - addItemToInventory(newItem(TOOL_MAGIC_COMPASS,1), &(pd->inventory)); - - int i; - for (i = 7;i < 28;++i) addItemToInventory(newItem(i,50), &(pd->inventory)); - } + addItemToInventory(newItem(TOOL_SHOVEL,1), &(pd->inventory)); + addItemToInventory(newItem(TOOL_HOE,4), &(pd->inventory)); + addItemToInventory(newItem(TOOL_SWORD,4), &(pd->inventory)); + addItemToInventory(newItem(TOOL_PICKAXE,4), &(pd->inventory)); + addItemToInventory(newItem(TOOL_AXE,4), &(pd->inventory)); + + addItemToInventory(newItem(ITEM_ANVIL,0), &(pd->inventory)); + addItemToInventory(newItem(ITEM_CHEST,0), &(pd->inventory)); + addItemToInventory(newItem(ITEM_OVEN,0), &(pd->inventory)); + addItemToInventory(newItem(ITEM_FURNACE,0), &(pd->inventory)); + addItemToInventory(newItem(ITEM_LANTERN,0), &(pd->inventory)); + + addItemToInventory(newItem(TOOL_MAGIC_COMPASS,1), &(pd->inventory)); + + int i; + for (i = 7;i < 28;++i) addItemToInventory(newItem(i,50), &(pd->inventory)); + } } void playerInitSprite(PlayerData *pd) { - pd->sprite.choosen = false; - - pd->sprite.legs = 0; - pd->sprite.body = 0; - pd->sprite.arms = 0; - pd->sprite.head = 0; - pd->sprite.eyes = 0; + pd->sprite.choosen = false; + + pd->sprite.legs = 0; + pd->sprite.body = 0; + pd->sprite.arms = 0; + pd->sprite.head = 0; + pd->sprite.eyes = 0; } void playerInitMenus(PlayerData *pd) { - pd->ingameMenu = MENU_NONE; - pd->ingameMenuSelection = 0; - pd->ingameMenuInvSel = 0; - pd->ingameMenuInvSelOther = 0; - pd->ingameMenuAreYouSure = false; - pd->ingameMenuAreYouSureSave = false; - pd->ingameMenuTimer = 0; - - resetNPCMenuData(&(pd->npcMenuData)); - - pd->mapShouldRender = false; + pd->ingameMenu = MENU_NONE; + pd->ingameMenuSelection = 0; + pd->ingameMenuInvSel = 0; + pd->ingameMenuInvSelOther = 0; + pd->ingameMenuAreYouSure = false; + pd->ingameMenuAreYouSureSave = false; + pd->ingameMenuTimer = 0; + + resetNPCMenuData(&(pd->npcMenuData)); + + pd->mapShouldRender = false; pd->mapScrollX = 0; pd->mapScrollY = 0; pd->mapZoomLevel = 2; - sprintf(pd->mapText,"x%d", pd->mapZoomLevel); - - pd->touchLastX = -1; - pd->touchLastY = -1; - pd->touchIsDraggingMap = false; - pd->touchIsChangingSize = false; + sprintf(pd->mapText,"x%d", pd->mapZoomLevel); + + pd->touchLastX = -1; + pd->touchLastY = -1; + pd->touchIsDraggingMap = false; + pd->touchIsChangingSize = false; } void initPlayer(PlayerData *pd) { - pd->isSpawned = false; - - playerInitMiniMapData(pd->minimapData); - playerInitEntity(pd); - playerInitInventory(pd); - - playerInitSprite(pd); - - initQuests(&(pd->questManager)); - resetQuests(&(pd->questManager)); - - playerInitMenus(pd); - - pd->score = 0; + pd->isSpawned = false; + + playerInitMiniMapData(pd->minimapData); + playerInitEntity(pd); + playerInitInventory(pd); + + playerInitSprite(pd); + + initQuests(&(pd->questManager)); + resetQuests(&(pd->questManager)); + + playerInitMenus(pd); + + pd->score = 0; } void freePlayer(PlayerData *pd) { - freeQuests(&(pd->questManager)); + freeQuests(&(pd->questManager)); } PlayerData* getNearestPlayer(s8 level, s16 x, s16 y) { - int nearest = -1; - unsigned int nearestDist = UINT_MAX; - - for(int i=0; iactiveItem->id){ - //shooting arrows - case TOOL_BOW: - item = getItemFromInventory(ITEM_ARROW_WOOD, &(pd->inventory)); - if(item!=NULL) { - aitemID = ITEM_ARROW_WOOD; - aitem = item; - } - item = getItemFromInventory(ITEM_ARROW_STONE, &(pd->inventory)); - if(item!=NULL) { - aitemID = ITEM_ARROW_STONE; - aitem = item; - } - item = getItemFromInventory(ITEM_ARROW_IRON, &(pd->inventory)); - if(item!=NULL) { - aitemID = ITEM_ARROW_IRON; - aitem = item; - } - item = getItemFromInventory(ITEM_ARROW_GOLD, &(pd->inventory)); - if(item!=NULL) { - aitemID = ITEM_ARROW_GOLD; - aitem = item; - } - item = getItemFromInventory(ITEM_ARROW_GEM, &(pd->inventory)); - if(item!=NULL) { - aitemID = ITEM_ARROW_GEM; - aitem = item; - } - - if(aitemID!=0) { - --aitem->countLevel; - if (isItemEmpty(aitem)) { - removeItemFromInventory(aitem->slotNum, &(pd->inventory)); - } - - switch(pd->entity.p.dir) { - case 0: - addEntityToList(newArrowEntity(&(pd->entity), aitemID, 0, 2, pd->entity.level), &eManager); - break; - case 1: - addEntityToList(newArrowEntity(&(pd->entity), aitemID, 0, -2, pd->entity.level), &eManager); - break; - case 2: - addEntityToList(newArrowEntity(&(pd->entity), aitemID, -2, 0, pd->entity.level), &eManager); - break; - case 3: - addEntityToList(newArrowEntity(&(pd->entity), aitemID, 2, 0, pd->entity.level), &eManager); - break; - } - return true; - } - break; - - // Health items - case ITEM_APPLE: - if(pd->entity.p.health < 10 && playerUseEnergy(pd, 2)){ - playerHeal(pd, 1); - --(pd->activeItem->countLevel); - } - break; + int aitemID = 0; + Item * aitem; + Item * item ; + + switch(pd->activeItem->id){ + //shooting arrows + case TOOL_BOW: + item = getItemFromInventory(ITEM_ARROW_WOOD, &(pd->inventory)); + if(item!=NULL) { + aitemID = ITEM_ARROW_WOOD; + aitem = item; + } + item = getItemFromInventory(ITEM_ARROW_STONE, &(pd->inventory)); + if(item!=NULL) { + aitemID = ITEM_ARROW_STONE; + aitem = item; + } + item = getItemFromInventory(ITEM_ARROW_IRON, &(pd->inventory)); + if(item!=NULL) { + aitemID = ITEM_ARROW_IRON; + aitem = item; + } + item = getItemFromInventory(ITEM_ARROW_GOLD, &(pd->inventory)); + if(item!=NULL) { + aitemID = ITEM_ARROW_GOLD; + aitem = item; + } + item = getItemFromInventory(ITEM_ARROW_GEM, &(pd->inventory)); + if(item!=NULL) { + aitemID = ITEM_ARROW_GEM; + aitem = item; + } + + if(aitemID!=0) { + --aitem->countLevel; + if (isItemEmpty(aitem)) { + removeItemFromInventory(aitem->slotNum, &(pd->inventory)); + } + + switch(pd->entity.p.dir) { + case 0: + addEntityToList(newArrowEntity(&(pd->entity), aitemID, 0, 2, pd->entity.level), &eManager); + break; + case 1: + addEntityToList(newArrowEntity(&(pd->entity), aitemID, 0, -2, pd->entity.level), &eManager); + break; + case 2: + addEntityToList(newArrowEntity(&(pd->entity), aitemID, -2, 0, pd->entity.level), &eManager); + break; + case 3: + addEntityToList(newArrowEntity(&(pd->entity), aitemID, 2, 0, pd->entity.level), &eManager); + break; + } + return true; + } + break; + + // Health items + case ITEM_APPLE: + if(pd->entity.p.health < 10 && playerUseEnergy(pd, 2)){ + playerHeal(pd, 1); + --(pd->activeItem->countLevel); + } + break; case ITEM_STRENGTH_POTION: if(pd->entity.p.health < 20 && pd->entity.p.strengthTimer == 0){ potionEffect(1); --(pd->activeItem->countLevel); } - return 0; + return 0; case ITEM_SPEED_POTION: if(pd->entity.p.health < 20 && pd->entity.p.speedTimer == 0){ potionEffect(2); --(pd->activeItem->countLevel); } - return 0; + return 0; case ITEM_REGEN_POTION: if(pd->entity.p.health < 20 && pd->entity.p.regenTimer == 0){ potionEffect(3); --(pd->activeItem->countLevel); } - return 0; + return 0; case ITEM_SWIM_BREATH_POTION: if(pd->entity.p.health < 20 && pd->entity.p.swimBreathTimer == 0){ potionEffect(4); --(pd->activeItem->countLevel); } - return 0; + return 0; case ITEM_GOLD_APPLE: - if(pd->entity.p.health < 10 && playerUseEnergy(pd, 1)){ - playerHeal(pd, 8); + if(pd->entity.p.health < 10 && playerUseEnergy(pd, 1)){ + playerHeal(pd, 8); playerUseEnergy(pd, -10); - --(pd->activeItem->countLevel); - } - return 0; - case ITEM_FLESH: - if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){ - playerHeal(pd, 1); - --(pd->activeItem->countLevel); - } - break; - case ITEM_BREAD: - if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){ - playerHeal(pd, 2); - --(pd->activeItem->countLevel); - } - break; + --(pd->activeItem->countLevel); + } + return 0; + case ITEM_FLESH: + if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){ + playerHeal(pd, 1); + --(pd->activeItem->countLevel); + } + break; + case ITEM_BREAD: + if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){ + playerHeal(pd, 2); + --(pd->activeItem->countLevel); + } + break; case ITEM_PORK_RAW: - if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){ - playerHeal(pd, 1); - --(pd->activeItem->countLevel); - } - break; + if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){ + playerHeal(pd, 1); + --(pd->activeItem->countLevel); + } + break; case ITEM_PORK_COOKED: - if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){ - playerHeal(pd, 3); - --(pd->activeItem->countLevel); - } - break; + if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){ + playerHeal(pd, 3); + --(pd->activeItem->countLevel); + } + break; case ITEM_BEEF_RAW: - if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){ - playerHeal(pd, 1); - --(pd->activeItem->countLevel); - } - break; + if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){ + playerHeal(pd, 1); + --(pd->activeItem->countLevel); + } + break; case ITEM_BEEF_COOKED: - if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){ - playerHeal(pd, 4); - --(pd->activeItem->countLevel); - } - break; + if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){ + playerHeal(pd, 4); + --(pd->activeItem->countLevel); + } + break; //special item case ITEM_WIZARD_SUMMON: if(pd->entity.level==0) { - --(pd->activeItem->countLevel); - + --(pd->activeItem->countLevel); + airWizardHealthDisplay = 2000; addEntityToList(newAirWizardEntity(630, 820, 0), &eManager); } - break; - } - - if (isItemEmpty(pd->activeItem)) { - removeItemFromInventory(pd->activeItem->slotNum, &(pd->inventory)); - pd->activeItem = &noItem; - } - + break; + } + + if (isItemEmpty(pd->activeItem)) { + removeItemFromInventory(pd->activeItem->slotNum, &(pd->inventory)); + pd->activeItem = &noItem; + } + return false; } @@ -329,28 +329,28 @@ bool playerInteract(PlayerData *pd, int x0, int y0, int x1, int y1) { for (i = 0; i < eSize; ++i) { Entity * ent = es[i]; if (ent != &(pd->entity)){ - if (ItemVsEntity(pd, pd->activeItem, ent, pd->entity.p.dir)) return true; - } + if (ItemVsEntity(pd, pd->activeItem, ent, pd->entity.p.dir)) return true; + } } return false; } void playerAttack(PlayerData *pd) { - bool done = false; + bool done = false; pd->entity.p.attackTimer = 5; int yo = -2; - int range = 12; - - //directly using an item + int range = 12; + + //directly using an item if(playerUseItem(pd)) return; - - //interacting with entities - switch(pd->entity.p.dir){ - case 0: if(playerInteract(pd, pd->entity.x - 8, pd->entity.y + 4 + yo, pd->entity.x + 8, pd->entity.y + range + yo)) return; break; - case 1: if(playerInteract(pd, pd->entity.x - 8, pd->entity.y - range + yo, pd->entity.x + 8, pd->entity.y - 4 + yo)) return; break; - case 2: if(playerInteract(pd, pd->entity.x - range, pd->entity.y - 8 + yo, pd->entity.x - 4, pd->entity.y + 8 + yo)) return; break; - case 3: if(playerInteract(pd, pd->entity.x + 4, pd->entity.y - 8 + yo, pd->entity.x + range, pd->entity.y + 8 + yo)) return; break; - } + + //interacting with entities + switch(pd->entity.p.dir){ + case 0: if(playerInteract(pd, pd->entity.x - 8, pd->entity.y + 4 + yo, pd->entity.x + 8, pd->entity.y + range + yo)) return; break; + case 1: if(playerInteract(pd, pd->entity.x - 8, pd->entity.y - range + yo, pd->entity.x + 8, pd->entity.y - 4 + yo)) return; break; + case 2: if(playerInteract(pd, pd->entity.x - range, pd->entity.y - 8 + yo, pd->entity.x - 4, pd->entity.y + 8 + yo)) return; break; + case 3: if(playerInteract(pd, pd->entity.x + 4, pd->entity.y - 8 + yo, pd->entity.x + range, pd->entity.y + 8 + yo)) return; break; + } int xt = pd->entity.x >> 4; int yt = (pd->entity.y + yo) >> 4; @@ -360,37 +360,37 @@ void playerAttack(PlayerData *pd) { if (pd->entity.p.dir == 2) xt = (pd->entity.x - r) >> 4; if (pd->entity.p.dir == 3) xt = (pd->entity.x + r) >> 4; - //interacting with tiles + //interacting with tiles if (xt >= 0 && yt >= 0 && xt < 128 && yt < 128) { - s8 itract = itemTileInteract(getTile(pd->entity.level, xt, yt), pd, pd->activeItem, pd->entity.level, xt, yt, pd->entity.x, pd->entity.y, pd->entity.p.dir); - if(itract > 0){ - if(itract==2) pd->entity.p.isCarrying = false; - done = true; - } - + s8 itract = itemTileInteract(getTile(pd->entity.level, xt, yt), pd, pd->activeItem, pd->entity.level, xt, yt, pd->entity.x, pd->entity.y, pd->entity.p.dir); + if(itract > 0){ + if(itract==2) pd->entity.p.isCarrying = false; + done = true; + } + if (pd->activeItem != &noItem && isItemEmpty(pd->activeItem)) { removeItemFromInventory(pd->activeItem->slotNum, &(pd->inventory)); pd->activeItem = &noItem; } } - + if(done) return; - - //breaking tiles - if (pd->activeItem == &noItem || pd->activeItem->id == TOOL_SWORD || pd->activeItem->id == TOOL_AXE) { - if (xt >= 0 && yt >= 0 && xt < 128 && 128) { - playerHurtTile(pd, getTile(pd->entity.level, xt, yt), pd->entity.level, xt, yt, (rand()%3) + 1, pd->entity.p.dir); - } - } + + //breaking tiles + if (pd->activeItem == &noItem || pd->activeItem->id == TOOL_SWORD || pd->activeItem->id == TOOL_AXE) { + if (xt >= 0 && yt >= 0 && xt < 128 && 128) { + playerHurtTile(pd, getTile(pd->entity.level, xt, yt), pd->entity.level, xt, yt, (rand()%3) + 1, pd->entity.p.dir); + } + } } bool playerUseArea(PlayerData *pd, int x0, int y0, int x1, int y1) { Entity * entities[eManager.lastSlot[pd->entity.level]]; int i; - int ae = getEntities(entities, pd->entity.level, x0, y0, x1, y1); - for(i = 0; i < ae; ++i){ - if(useEntity(pd, entities[i])) return true; - } + int ae = getEntities(entities, pd->entity.level, x0, y0, x1, y1); + for(i = 0; i < ae; ++i){ + if(useEntity(pd, entities[i])) return true; + } return false; } @@ -404,14 +404,14 @@ bool playerUse(PlayerData *pd) { } void tickPlayer(PlayerData *pd, bool inmenu) { - if (pd->entity.p.isDead) return; - - //invincibility time - if (pd->entity.hurtTime > 0) pd->entity.hurtTime--; - - //stamina recharging - bool swimming = isWater(pd->entity.level, pd->entity.x>>4, pd->entity.y>>4); - if (pd->entity.p.stamina <= 0 && pd->entity.p.staminaRechargeDelay == 0 && pd->entity.p.staminaRecharge == 0) { + if (pd->entity.p.isDead) return; + + //invincibility time + if (pd->entity.hurtTime > 0) pd->entity.hurtTime--; + + //stamina recharging + bool swimming = isWater(pd->entity.level, pd->entity.x>>4, pd->entity.y>>4); + if (pd->entity.p.stamina <= 0 && pd->entity.p.staminaRechargeDelay == 0 && pd->entity.p.staminaRecharge == 0) { pd->entity.p.staminaRechargeDelay = 40; } @@ -422,25 +422,25 @@ void tickPlayer(PlayerData *pd, bool inmenu) { if (pd->entity.p.staminaRechargeDelay == 0) { ++pd->entity.p.staminaRecharge; if (swimming) pd->entity.p.staminaRecharge = 0; - + while (pd->entity.p.staminaRecharge > 10) { pd->entity.p.staminaRecharge -= 10; if (pd->entity.p.stamina < 10) ++pd->entity.p.stamina; } } - - if(!inmenu) { - if(!pd->sprite.choosen) { - pd->ingameMenu = MENU_CHARACTER_CUSTOMIZE; - pd->ingameMenuSelection = 0; - return; - } - - //movement - pd->entity.p.ax = 0; - pd->entity.p.ay = 0; - - if (pd->inputs.k_left.down){ + + if(!inmenu) { + if(!pd->sprite.choosen) { + pd->ingameMenu = MENU_CHARACTER_CUSTOMIZE; + pd->ingameMenuSelection = 0; + return; + } + + //movement + pd->entity.p.ax = 0; + pd->entity.p.ay = 0; + + if (pd->inputs.k_left.down){ if(UnderSpeedEffect) { pd->entity.p.ax -= 2; pd->entity.p.dir = 2; @@ -451,9 +451,9 @@ void tickPlayer(PlayerData *pd, bool inmenu) { pd->entity.p.dir = 2; ++pd->entity.p.walkDist; } - } - if (pd->inputs.k_right.down){ - if(UnderSpeedEffect) { + } + if (pd->inputs.k_right.down){ + if(UnderSpeedEffect) { pd->entity.p.ax += 2; pd->entity.p.dir = 3; ++pd->entity.p.walkDist; @@ -463,9 +463,9 @@ void tickPlayer(PlayerData *pd, bool inmenu) { pd->entity.p.dir = 3; ++pd->entity.p.walkDist; } - } - if (pd->inputs.k_up.down){ - if(UnderSpeedEffect) { + } + if (pd->inputs.k_up.down){ + if(UnderSpeedEffect) { pd->entity.p.ay -= 2; pd->entity.p.dir = 1; ++pd->entity.p.walkDist; @@ -475,9 +475,9 @@ void tickPlayer(PlayerData *pd, bool inmenu) { pd->entity.p.dir = 1; ++pd->entity.p.walkDist; } - } - if (pd->inputs.k_down.down){ - if(UnderSpeedEffect) { + } + if (pd->inputs.k_down.down){ + if(UnderSpeedEffect) { pd->entity.p.ay += 2; pd->entity.p.dir = 0; ++pd->entity.p.walkDist; @@ -487,52 +487,52 @@ void tickPlayer(PlayerData *pd, bool inmenu) { pd->entity.p.dir = 0; ++pd->entity.p.walkDist; } - } - if (pd->entity.p.staminaRechargeDelay % 2 == 0) moveMob(&(pd->entity), pd->entity.p.ax, pd->entity.p.ay); - - //"pausing", TODO: since multiplayer this will no longer pause - if (pd->inputs.k_pause.clicked){ - pd->ingameMenuSelection = 0; - pd->ingameMenu = MENU_PAUSED; - } - - //attacking - if(pd->inputs.k_attack.clicked){ - if (pd->entity.p.stamina != 0) { - if(!shouldRenderDebug) pd->entity.p.stamina--; - pd->entity.p.staminaRecharge = 0; - - playerAttack(pd); - } - } - - if (pd->inputs.k_menu.clicked){ - pd->ingameMenuInvSel = 0; - if(!playerUse(pd)) pd->ingameMenu = MENU_INVENTORY; - } - } - - //swimming stamina and drowning + } + if (pd->entity.p.staminaRechargeDelay % 2 == 0) moveMob(&(pd->entity), pd->entity.p.ax, pd->entity.p.ay); + + //"pausing", TODO: since multiplayer this will no longer pause + if (pd->inputs.k_pause.clicked){ + pd->ingameMenuSelection = 0; + pd->ingameMenu = MENU_PAUSED; + } + + //attacking + if(pd->inputs.k_attack.clicked){ + if (pd->entity.p.stamina != 0) { + if(!shouldRenderDebug) pd->entity.p.stamina--; + pd->entity.p.staminaRecharge = 0; + + playerAttack(pd); + } + } + + if (pd->inputs.k_menu.clicked){ + pd->ingameMenuInvSel = 0; + if(!playerUse(pd)) pd->ingameMenu = MENU_INVENTORY; + } + } + + //swimming stamina and drowning if (swimming && pd->entity.p.swimTimer % 60 == 0 && UnderSwimBreathEffect != true) { if (pd->entity.p.stamina > 0) { if(!shouldRenderDebug) --pd->entity.p.stamina; } else { - hurtEntity(&(pd->entity), 1, -1, 0xFFAF00FF, NULL); + hurtEntity(&(pd->entity), 1, -1, 0xFFAF00FF, NULL); } } - + //Regen healing if (regening && pd->entity.p.regenTimer % 75 == 0) { playerHeal(pd, 1); } - - if(isWater(pd->entity.level, pd->entity.x>>4, pd->entity.y>>4)) ++pd->entity.p.swimTimer; + + if(isWater(pd->entity.level, pd->entity.x>>4, pd->entity.y>>4)) ++pd->entity.p.swimTimer; if(regening) ++pd->entity.p.regenTimer; if(UnderSpeedEffect) ++pd->entity.p.speedTimer; if(UnderStrengthEffect) ++pd->entity.p.strengthTimer; if(UnderSwimBreathEffect) ++pd->entity.p.swimBreathTimer; - if(pd->entity.p.attackTimer > 0) --pd->entity.p.attackTimer; - + if(pd->entity.p.attackTimer > 0) --pd->entity.p.attackTimer; + //TODO - maybe move to own function //Update Minimap int xp; @@ -549,35 +549,35 @@ void tickPlayer(PlayerData *pd, bool inmenu) { } void playerSetActiveItem(PlayerData *pd, Item *item) { - pd->activeItem = item; - if(pd->activeItem->id > 27 && pd->activeItem->id < 51) pd->entity.p.isCarrying = true; - else pd->entity.p.isCarrying = false; + pd->activeItem = item; + if(pd->activeItem->id > 27 && pd->activeItem->id < 51) pd->entity.p.isCarrying = true; + else pd->entity.p.isCarrying = false; } bool playerUseEnergy(PlayerData *pd, int amount) { - if(shouldRenderDebug) return true; - if(amount > pd->entity.p.stamina) return false; - pd->entity.p.stamina -= amount; - return true; + if(shouldRenderDebug) return true; + if(amount > pd->entity.p.stamina) return false; + pd->entity.p.stamina -= amount; + return true; } void playerHeal(PlayerData *pd, int amount) { - pd->entity.p.health += amount; - if(pd->entity.p.health > 10) pd->entity.p.health = 10; - char healText[11]; - sprintf(healText, "%d", amount); - addEntityToList(newTextParticleEntity(healText,0xFF00FF00, pd->entity.x, pd->entity.y, pd->entity.level), &eManager); + pd->entity.p.health += amount; + if(pd->entity.p.health > 10) pd->entity.p.health = 10; + char healText[11]; + sprintf(healText, "%d", amount); + addEntityToList(newTextParticleEntity(healText,0xFF00FF00, pd->entity.x, pd->entity.y, pd->entity.level), &eManager); } void playerSpawn(PlayerData *pd) { - while(true){ - int rx = rand()%128; - int ry = rand()%128; - if(getTile(pd->entity.level, rx, ry) == TILE_GRASS){ - pd->entity.x = (rx << 4) + 8; - pd->entity.y = (ry << 4) + 8; - pd->isSpawned = true; - break; - } - } + while(true){ + int rx = rand()%128; + int ry = rand()%128; + if(getTile(pd->entity.level, rx, ry) == TILE_GRASS){ + pd->entity.x = (rx << 4) + 8; + pd->entity.y = (ry << 4) + 8; + pd->isSpawned = true; + break; + } + } } diff --git a/source/Player.h b/source/Player.h index 33efda1..b3d28bc 100644 --- a/source/Player.h +++ b/source/Player.h @@ -16,64 +16,64 @@ typedef struct _plrsp { - bool choosen; - - u8 legs; - u8 body; - u8 arms; - u8 head; - u8 eyes; + bool choosen; + + u8 legs; + u8 body; + u8 arms; + u8 head; + u8 eyes; } PlayerSprite; typedef struct _plrd { - //for identification in save data and sync game start - u32 id; - bool idSet; - bool ready; - - //input/multiplayer/synchronization - Inputs inputs; - Inputs nextInputs[MAX_INPUT_BUFFER]; - bool nextTurnReady[MAX_INPUT_BUFFER]; - - // - bool isSpawned; - u8 minimapData[128*128]; - + //for identification in save data and sync game start + u32 id; + bool idSet; + bool ready; + + //input/multiplayer/synchronization + Inputs inputs; + Inputs nextInputs[MAX_INPUT_BUFFER]; + bool nextTurnReady[MAX_INPUT_BUFFER]; + + // + bool isSpawned; + u8 minimapData[128*128]; + int score; - QuestlineManager questManager; - - Entity entity; - Inventory inventory; - Item *activeItem; - - PlayerSprite sprite; - - //menu data - u8 ingameMenu; - s8 ingameMenuSelection; - s16 ingameMenuInvSel; - s16 ingameMenuInvSelOther; - bool ingameMenuAreYouSure; - bool ingameMenuAreYouSureSave; - s16 ingameMenuTimer; - NPC_MenuData npcMenuData; - - RecipeManager currentRecipes; - char *currentCraftTitle; - Entity *curChestEntity; - s8 curChestEntityR; - - bool mapShouldRender; - u8 mapZoomLevel; - s16 mapScrollX; - s16 mapScrollY; - char mapText[32]; - - s16 touchLastX; - s16 touchLastY; - bool touchIsDraggingMap; - bool touchIsChangingSize; + QuestlineManager questManager; + + Entity entity; + Inventory inventory; + Item *activeItem; + + PlayerSprite sprite; + + //menu data + u8 ingameMenu; + s8 ingameMenuSelection; + s16 ingameMenuInvSel; + s16 ingameMenuInvSelOther; + bool ingameMenuAreYouSure; + bool ingameMenuAreYouSureSave; + s16 ingameMenuTimer; + NPC_MenuData npcMenuData; + + RecipeManager currentRecipes; + char *currentCraftTitle; + Entity *curChestEntity; + s8 curChestEntityR; + + bool mapShouldRender; + u8 mapZoomLevel; + s16 mapScrollX; + s16 mapScrollY; + char mapText[32]; + + s16 touchLastX; + s16 touchLastY; + bool touchIsDraggingMap; + bool touchIsChangingSize; } PlayerData; PlayerData players[MAX_PLAYERS]; diff --git a/source/Quests.c b/source/Quests.c index 993ae6b..9f10b43 100755 --- a/source/Quests.c +++ b/source/Quests.c @@ -4,434 +4,434 @@ #include "Render.h" void initTrades() { - 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.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 + 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 freeTrades() { - free(priestTrades.recipes); - free(farmerTrades.recipes); - free(dwarfTrades.recipes); + free(priestTrades.recipes); + free(farmerTrades.recipes); + free(dwarfTrades.recipes); } void initQuests(QuestlineManager *questManager) { - if(questManager->questlines!=NULL) { - freeQuests(questManager); - } - - questManager->size = 2; - questManager->questlines = (Questline*)malloc(sizeof(Questline) * (questManager->size)); + if(questManager->questlines!=NULL) { + freeQuests(questManager); + } + + questManager->size = 2; + questManager->questlines = (Questline*)malloc(sizeof(Questline) * (questManager->size)); } void resetQuests(QuestlineManager *questManager) { - int i; - for(i=0; isize; ++i) { - questManager->questlines[i].currentQuest = 0; - questManager->questlines[i].currentQuestDone = false; - } + int i; + for(i=0; isize; ++i) { + questManager->questlines[i].currentQuest = 0; + questManager->questlines[i].currentQuestDone = false; + } } void freeQuests(QuestlineManager *questManager) { - free(questManager->questlines); - questManager->questlines = NULL; + free(questManager->questlines); + questManager->questlines = NULL; } void resetNPCMenuData(NPC_MenuData *data) { - data->currentNPC = 0; - data->currentNPCMenu = 0; - data->currentNPCVal = 0; - - data->currentTalkSel = 0; - data->currentTalkDone = false; - data->currentTalkOptions = 0; - - data->currentTalkOption0 = ""; - data->currentTalkOption1 = ""; - data->currentTalkOption2 = ""; - data->currentTalk0 = ""; - data->currentTalk1 = ""; - data->currentTalk2 = ""; - data->currentTalk3 = ""; - data->currentTalk4 = ""; - data->currentTalk5 = ""; + data->currentNPC = 0; + data->currentNPCMenu = 0; + data->currentNPCVal = 0; + + data->currentTalkSel = 0; + data->currentTalkDone = false; + data->currentTalkOptions = 0; + + data->currentTalkOption0 = ""; + data->currentTalkOption1 = ""; + data->currentTalkOption2 = ""; + data->currentTalk0 = ""; + data->currentTalk1 = ""; + data->currentTalk2 = ""; + data->currentTalk3 = ""; + data->currentTalk4 = ""; + data->currentTalk5 = ""; } void openNPCMenu(PlayerData *pd, int npc) { - pd->ingameMenu = MENU_NPC; - - NPC_MenuData *data = &(pd->npcMenuData); - QuestlineManager *questManager = &(pd->questManager); - - data->currentNPC = npc; - data->currentNPCVal = 0; - data->currentNPCMenu = NPC_MENU_TALK; - - data->currentTalkSel = 0; - data->currentTalkDone = false; - data->currentTalkOptions = 1; - data->currentTalkOption0 = "Bye"; - data->currentTalkOption1 = ""; - data->currentTalkOption2 = ""; - data->currentTalk0 = ""; - data->currentTalk1 = ""; - data->currentTalk2 = ""; - data->currentTalk3 = ""; - data->currentTalk4 = ""; - data->currentTalk5 = ""; - - //TODO: Handle upon currentNPC as well as the fitting quest progress - switch(data->currentNPC) { - case NPC_GIRL: - data->currentTalkOptions = 1; - data->currentTalkOption0 = "..."; - - data->currentTalk0 = "Hello?"; - data->currentTalk1 = "I have a feeling of having"; - data->currentTalk2 = "forgotten something very"; - data->currentTalk3 = "important."; - data->currentTalk4 = "Hopefully I will remember"; - data->currentTalk5 = "it soon..."; - break; - case NPC_PRIEST: - data->currentTalkOptions = 3; - data->currentTalkOption1 = "Trade"; - data->currentTalkOption2 = "Why are you so few?"; - - data->currentTalk0 = "Welcome to our small village"; - data->currentTalk1 = "I am the leader of our group."; - data->currentTalk2 = "If you have anything usefull"; - data->currentTalk3 = "for us I might be able to"; - data->currentTalk4 = "provide something nice in"; - data->currentTalk5 = "exchange."; - break; - case NPC_FARMER: - data->currentTalkOptions = 2; - data->currentTalkOption0 = "Maybe some other time"; - data->currentTalkOption1 = "Trade"; - - data->currentTalk0 = "Hello friend!"; - data->currentTalk1 = "Nice seeing somebody else"; - data->currentTalk2 = "visit my little farm."; - data->currentTalk3 = "Interested in buying some"; - data->currentTalk4 = "fresh farm goods?"; - data->currentTalk5 = ""; - break; - case NPC_LIBRARIAN: - data->currentTalkOptions = 2; - data->currentTalkOption0 = "Nothing"; - data->currentTalkOption1 = "What are you doing here?"; - if(questManager->questlines[1].currentQuest==1) { - data->currentTalkOptions = 3; - data->currentTalkOption2 = "Dwarvish language"; - } - - data->currentTalk0 = "Oh hello?"; - data->currentTalk1 = "You must be quite brave"; - data->currentTalk2 = "or stupid to be walking"; - data->currentTalk3 = "around in this dungeon."; - data->currentTalk4 = ""; - data->currentTalk5 = "How can I help you?"; - break; - case NPC_DWARF: - if(questManager->questlines[1].currentQuest<=1) { - questManager->questlines[1].currentQuest = 1; - - data->currentTalkOptions = 1; - data->currentTalkOption0 = "?"; - - data->currentTalk0 = "Dwo neal bet reck da lo"; - data->currentTalk1 = "dhum don lir lugn at el"; - data->currentTalk2 = "nur tor erno ur yo trad"; - data->currentTalk3 = "thra so tir kho ukk tin"; - data->currentTalk4 = "hel dro ic"; - data->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) { - data->currentTalkOptions = 2; - data->currentTalkOption0 = "Not really"; - data->currentTalkOption1 = "Trade"; - - data->currentTalk0 = "How are ya?"; - data->currentTalk1 = "Pretty unusal meeting a"; - data->currentTalk2 = "human down here."; - data->currentTalk3 = ""; - data->currentTalk4 = "have something valuable"; - data->currentTalk5 = "to trade?"; - } - break; - } + pd->ingameMenu = MENU_NPC; + + NPC_MenuData *data = &(pd->npcMenuData); + QuestlineManager *questManager = &(pd->questManager); + + data->currentNPC = npc; + data->currentNPCVal = 0; + data->currentNPCMenu = NPC_MENU_TALK; + + data->currentTalkSel = 0; + data->currentTalkDone = false; + data->currentTalkOptions = 1; + data->currentTalkOption0 = "Bye"; + data->currentTalkOption1 = ""; + data->currentTalkOption2 = ""; + data->currentTalk0 = ""; + data->currentTalk1 = ""; + data->currentTalk2 = ""; + data->currentTalk3 = ""; + data->currentTalk4 = ""; + data->currentTalk5 = ""; + + //TODO: Handle upon currentNPC as well as the fitting quest progress + switch(data->currentNPC) { + case NPC_GIRL: + data->currentTalkOptions = 1; + data->currentTalkOption0 = "..."; + + data->currentTalk0 = "Hello?"; + data->currentTalk1 = "I have a feeling of having"; + data->currentTalk2 = "forgotten something very"; + data->currentTalk3 = "important."; + data->currentTalk4 = "Hopefully I will remember"; + data->currentTalk5 = "it soon..."; + break; + case NPC_PRIEST: + data->currentTalkOptions = 3; + data->currentTalkOption1 = "Trade"; + data->currentTalkOption2 = "Why are you so few?"; + + data->currentTalk0 = "Welcome to our small village"; + data->currentTalk1 = "I am the leader of our group."; + data->currentTalk2 = "If you have anything usefull"; + data->currentTalk3 = "for us I might be able to"; + data->currentTalk4 = "provide something nice in"; + data->currentTalk5 = "exchange."; + break; + case NPC_FARMER: + data->currentTalkOptions = 2; + data->currentTalkOption0 = "Maybe some other time"; + data->currentTalkOption1 = "Trade"; + + data->currentTalk0 = "Hello friend!"; + data->currentTalk1 = "Nice seeing somebody else"; + data->currentTalk2 = "visit my little farm."; + data->currentTalk3 = "Interested in buying some"; + data->currentTalk4 = "fresh farm goods?"; + data->currentTalk5 = ""; + break; + case NPC_LIBRARIAN: + data->currentTalkOptions = 2; + data->currentTalkOption0 = "Nothing"; + data->currentTalkOption1 = "What are you doing here?"; + if(questManager->questlines[1].currentQuest==1) { + data->currentTalkOptions = 3; + data->currentTalkOption2 = "Dwarvish language"; + } + + data->currentTalk0 = "Oh hello?"; + data->currentTalk1 = "You must be quite brave"; + data->currentTalk2 = "or stupid to be walking"; + data->currentTalk3 = "around in this dungeon."; + data->currentTalk4 = ""; + data->currentTalk5 = "How can I help you?"; + break; + case NPC_DWARF: + if(questManager->questlines[1].currentQuest<=1) { + questManager->questlines[1].currentQuest = 1; + + data->currentTalkOptions = 1; + data->currentTalkOption0 = "?"; + + data->currentTalk0 = "Dwo neal bet reck da lo"; + data->currentTalk1 = "dhum don lir lugn at el"; + data->currentTalk2 = "nur tor erno ur yo trad"; + data->currentTalk3 = "thra so tir kho ukk tin"; + data->currentTalk4 = "hel dro ic"; + data->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) { + data->currentTalkOptions = 2; + data->currentTalkOption0 = "Not really"; + data->currentTalkOption1 = "Trade"; + + data->currentTalk0 = "How are ya?"; + data->currentTalk1 = "Pretty unusal meeting a"; + data->currentTalk2 = "human down here."; + data->currentTalk3 = ""; + data->currentTalk4 = "have something valuable"; + data->currentTalk5 = "to trade?"; + } + break; + } } void tickTalkMenu(PlayerData *pd, NPC_MenuData *data) { - if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE; - - if (pd->inputs.k_up.clicked){ ++data->currentTalkSel; if(data->currentTalkSel >= data->currentTalkOptions) data->currentTalkSel=0;} - if (pd->inputs.k_down.clicked){ --data->currentTalkSel; if(data->currentTalkSel < 0) data->currentTalkSel=data->currentTalkOptions-1;} - - if(pd->inputs.k_accept.clicked){ - data->currentTalkDone = true; - } + if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE; + + if (pd->inputs.k_up.clicked){ ++data->currentTalkSel; if(data->currentTalkSel >= data->currentTalkOptions) data->currentTalkSel=0;} + if (pd->inputs.k_down.clicked){ --data->currentTalkSel; if(data->currentTalkSel < 0) data->currentTalkSel=data->currentTalkOptions-1;} + + if(pd->inputs.k_accept.clicked){ + data->currentTalkDone = true; + } } void tickNPCMenu(PlayerData *pd) { - NPC_MenuData *data = &(pd->npcMenuData); - QuestlineManager *questManager = &(pd->questManager); - - //TODO: Handle upon currentNPC as well as the fitting quest progress - if(data->currentNPCMenu==NPC_MENU_TALK) tickTalkMenu(pd, data); + NPC_MenuData *data = &(pd->npcMenuData); + QuestlineManager *questManager = &(pd->questManager); - - switch(data->currentNPC) { - case NPC_GIRL: - if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { - if(data->currentNPCVal==0) pd->ingameMenu = MENU_NONE; - } - break; - case NPC_PRIEST: - if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { - if(data->currentNPCVal==0) { - if(data->currentTalkSel==0) { - pd->ingameMenu = MENU_NONE; - } else if(data->currentTalkSel==1) { - openCraftingMenu(pd, &priestTrades, "Trading"); - } else if(data->currentTalkSel==2) { - data->currentNPCVal = 1; - - data->currentTalkSel = 0; - data->currentTalkDone = false; - data->currentTalkOptions = 1; - data->currentTalkOption0 = "..."; - - data->currentTalk0 = "For quite some time now this"; - data->currentTalk1 = "village has been tyrannized"; - data->currentTalk2 = "by a powerfull Air Wizard."; - data->currentTalk3 = "We are the only ones who"; - data->currentTalk4 = "still have not given up"; - data->currentTalk5 = "our old homes."; - } - } else if(data->currentNPCVal==1) { - if(data->currentTalkSel==0) { - data->currentNPCVal = 2; - - data->currentTalkSel = 0; - data->currentTalkDone = false; - data->currentTalkOptions = 1; - data->currentTalkOption0 = "..."; - - data->currentTalk0 = "Most of the time the wizard"; - data->currentTalk1 = "hides somewhere in the"; - data->currentTalk2 = "cloudes. They can only be"; - data->currentTalk3 = "reached by a stairwell"; - data->currentTalk4 = "protected by an almost"; - data->currentTalk5 = "undestroyable stone barrier."; - } - } else if(data->currentNPCVal==2) { - if(data->currentTalkSel==0) { - data->currentNPCVal = 3; - - data->currentTalkSel = 0; - data->currentTalkDone = false; - data->currentTalkOptions = 1; - data->currentTalkOption0 = "..."; - - data->currentTalk0 = "I am guessing you would "; - data->currentTalk1 = "need tools atleast as"; - data->currentTalk2 = "strong as diamonds to be"; - data->currentTalk3 = "able to destroy it."; - data->currentTalk4 = ""; - data->currentTalk5 = ""; - } - } else if(data->currentNPCVal==3) { - if(data->currentTalkSel==0) { - data->currentNPCVal = 4; - - data->currentTalkSel = 0; - data->currentTalkDone = false; - data->currentTalkOptions = 2; - data->currentTalkOption0 = "Let me do it!"; - data->currentTalkOption1 = "I am not sure"; - - data->currentTalk0 = "I am willing to give an"; - data->currentTalk1 = "ancient artifact passed"; - data->currentTalk2 = "down over generations to"; - data->currentTalk3 = "anybody who manages to"; - data->currentTalk4 = "chase the wizard away and"; - data->currentTalk5 = "come back with proof."; - } - } else if(data->currentNPCVal==4) { - pd->ingameMenu = MENU_NONE; - } - } - break; - case NPC_FARMER: - if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { - if(data->currentNPCVal==0) { - if(data->currentTalkSel==0) { - pd->ingameMenu = MENU_NONE; - } else if(data->currentTalkSel==1) { - openCraftingMenu(pd, &farmerTrades, "Trading"); - } - } - } - break; - case NPC_LIBRARIAN: - if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { - if(data->currentNPCVal==0) { - if(data->currentTalkSel==0) { - pd->ingameMenu = MENU_NONE; - } else if(data->currentTalkSel==1) { - data->currentNPCVal = 2; - - data->currentTalkSel = 0; - data->currentTalkDone = false; - data->currentTalkOptions = 1; - data->currentTalkOption0 = "Ok"; - - data->currentTalk0 = "The books in this dungeon"; - data->currentTalk1 = "house secrets that cannot be"; - data->currentTalk2 = "found anywhere else in the"; - data->currentTalk3 = "world. So I came to study"; - data->currentTalk4 = "them. Most are written in"; - data->currentTalk5 = "an ancient language."; - } else if(data->currentTalkSel==2) { - data->currentNPCVal = 1; - - data->currentTalkSel = 0; - data->currentTalkDone = false; - data->currentTalkOptions = 2; - data->currentTalkOption0 = "I need to think about it"; - data->currentTalkOption1 = "Here they are"; - - data->currentTalk0 = "So you have met a dwarf but"; - data->currentTalk1 = "had a little communication"; - data->currentTalk2 = "problem? I do have a dwarvish"; - data->currentTalk3 = "translation book but I havent"; - data->currentTalk4 = "read it yet. For 10 Gold bars"; - data->currentTalk5 = "I will give it to you anyway."; - } - } else if(data->currentNPCVal==1) { - if(data->currentTalkSel==0) { - pd->ingameMenu = MENU_NONE; - } else if(data->currentTalkSel==1) { - data->currentNPCVal = 2; - - data->currentTalkSel = 0; - data->currentTalkDone = false; - data->currentTalkOptions = 1; - data->currentTalkOption0 = ""; - - if(countItemInv(ITEM_GOLDINGOT, 0, &(pd->inventory))>=10) { - //remove gold from player inventory - //TODO: Maybe I should make a generic substract items method sometime - Item* item = getItemFromInventory(ITEM_GOLDINGOT, &(pd->inventory)); - item->countLevel -= 10; - if(item->countLevel < 1) removeItemFromInventory(item->slotNum, &(pd->inventory)); - - questManager->questlines[1].currentQuest = 2; - - data->currentTalk0 = "Thank you these will be"; - data->currentTalk1 = "really helpfull."; - data->currentTalk2 = "Here take this book with"; - data->currentTalk3 = "it you should be able to"; - data->currentTalk4 = "easily understand anything"; - data->currentTalk5 = "a dwarf can say."; - - data->currentTalkOption0 = "Thanks"; - } else { - data->currentTalk0 = "You do not seem to have"; - data->currentTalk1 = "enough Gold Bars with you."; - data->currentTalk2 = ""; - data->currentTalk3 = "Ask again when you have"; - data->currentTalk4 = "collected the 10 Bars."; - data->currentTalk5 = ""; - - data->currentTalkOption0 = "Ok"; - } - } - } else if(data->currentNPCVal==2) { - if(data->currentTalkSel==0) { - pd->ingameMenu = MENU_NONE; - } - } - } - break; - case NPC_DWARF: - if(questManager->questlines[1].currentQuest<=1) { - if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { - if(data->currentNPCVal==0) pd->ingameMenu = MENU_NONE; - } - } else if(questManager->questlines[1].currentQuest==2) { - if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { - if(data->currentTalkSel==0) { - pd->ingameMenu = MENU_NONE; - } else if(data->currentTalkSel==1) { - openCraftingMenu(pd, &dwarfTrades, "Trading"); - } - } - } - break; - } + //TODO: Handle upon currentNPC as well as the fitting quest progress + if(data->currentNPCMenu==NPC_MENU_TALK) tickTalkMenu(pd, data); + + + switch(data->currentNPC) { + case NPC_GIRL: + if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { + if(data->currentNPCVal==0) pd->ingameMenu = MENU_NONE; + } + break; + case NPC_PRIEST: + if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { + if(data->currentNPCVal==0) { + if(data->currentTalkSel==0) { + pd->ingameMenu = MENU_NONE; + } else if(data->currentTalkSel==1) { + openCraftingMenu(pd, &priestTrades, "Trading"); + } else if(data->currentTalkSel==2) { + data->currentNPCVal = 1; + + data->currentTalkSel = 0; + data->currentTalkDone = false; + data->currentTalkOptions = 1; + data->currentTalkOption0 = "..."; + + data->currentTalk0 = "For quite some time now this"; + data->currentTalk1 = "village has been tyrannized"; + data->currentTalk2 = "by a powerfull Air Wizard."; + data->currentTalk3 = "We are the only ones who"; + data->currentTalk4 = "still have not given up"; + data->currentTalk5 = "our old homes."; + } + } else if(data->currentNPCVal==1) { + if(data->currentTalkSel==0) { + data->currentNPCVal = 2; + + data->currentTalkSel = 0; + data->currentTalkDone = false; + data->currentTalkOptions = 1; + data->currentTalkOption0 = "..."; + + data->currentTalk0 = "Most of the time the wizard"; + data->currentTalk1 = "hides somewhere in the"; + data->currentTalk2 = "cloudes. They can only be"; + data->currentTalk3 = "reached by a stairwell"; + data->currentTalk4 = "protected by an almost"; + data->currentTalk5 = "undestroyable stone barrier."; + } + } else if(data->currentNPCVal==2) { + if(data->currentTalkSel==0) { + data->currentNPCVal = 3; + + data->currentTalkSel = 0; + data->currentTalkDone = false; + data->currentTalkOptions = 1; + data->currentTalkOption0 = "..."; + + data->currentTalk0 = "I am guessing you would "; + data->currentTalk1 = "need tools atleast as"; + data->currentTalk2 = "strong as diamonds to be"; + data->currentTalk3 = "able to destroy it."; + data->currentTalk4 = ""; + data->currentTalk5 = ""; + } + } else if(data->currentNPCVal==3) { + if(data->currentTalkSel==0) { + data->currentNPCVal = 4; + + data->currentTalkSel = 0; + data->currentTalkDone = false; + data->currentTalkOptions = 2; + data->currentTalkOption0 = "Let me do it!"; + data->currentTalkOption1 = "I am not sure"; + + data->currentTalk0 = "I am willing to give an"; + data->currentTalk1 = "ancient artifact passed"; + data->currentTalk2 = "down over generations to"; + data->currentTalk3 = "anybody who manages to"; + data->currentTalk4 = "chase the wizard away and"; + data->currentTalk5 = "come back with proof."; + } + } else if(data->currentNPCVal==4) { + pd->ingameMenu = MENU_NONE; + } + } + break; + case NPC_FARMER: + if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { + if(data->currentNPCVal==0) { + if(data->currentTalkSel==0) { + pd->ingameMenu = MENU_NONE; + } else if(data->currentTalkSel==1) { + openCraftingMenu(pd, &farmerTrades, "Trading"); + } + } + } + break; + case NPC_LIBRARIAN: + if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { + if(data->currentNPCVal==0) { + if(data->currentTalkSel==0) { + pd->ingameMenu = MENU_NONE; + } else if(data->currentTalkSel==1) { + data->currentNPCVal = 2; + + data->currentTalkSel = 0; + data->currentTalkDone = false; + data->currentTalkOptions = 1; + data->currentTalkOption0 = "Ok"; + + data->currentTalk0 = "The books in this dungeon"; + data->currentTalk1 = "house secrets that cannot be"; + data->currentTalk2 = "found anywhere else in the"; + data->currentTalk3 = "world. So I came to study"; + data->currentTalk4 = "them. Most are written in"; + data->currentTalk5 = "an ancient language."; + } else if(data->currentTalkSel==2) { + data->currentNPCVal = 1; + + data->currentTalkSel = 0; + data->currentTalkDone = false; + data->currentTalkOptions = 2; + data->currentTalkOption0 = "I need to think about it"; + data->currentTalkOption1 = "Here they are"; + + data->currentTalk0 = "So you have met a dwarf but"; + data->currentTalk1 = "had a little communication"; + data->currentTalk2 = "problem? I do have a dwarvish"; + data->currentTalk3 = "translation book but I havent"; + data->currentTalk4 = "read it yet. For 10 Gold bars"; + data->currentTalk5 = "I will give it to you anyway."; + } + } else if(data->currentNPCVal==1) { + if(data->currentTalkSel==0) { + pd->ingameMenu = MENU_NONE; + } else if(data->currentTalkSel==1) { + data->currentNPCVal = 2; + + data->currentTalkSel = 0; + data->currentTalkDone = false; + data->currentTalkOptions = 1; + data->currentTalkOption0 = ""; + + if(countItemInv(ITEM_GOLDINGOT, 0, &(pd->inventory))>=10) { + //remove gold from player inventory + //TODO: Maybe I should make a generic substract items method sometime + Item* item = getItemFromInventory(ITEM_GOLDINGOT, &(pd->inventory)); + item->countLevel -= 10; + if(item->countLevel < 1) removeItemFromInventory(item->slotNum, &(pd->inventory)); + + questManager->questlines[1].currentQuest = 2; + + data->currentTalk0 = "Thank you these will be"; + data->currentTalk1 = "really helpfull."; + data->currentTalk2 = "Here take this book with"; + data->currentTalk3 = "it you should be able to"; + data->currentTalk4 = "easily understand anything"; + data->currentTalk5 = "a dwarf can say."; + + data->currentTalkOption0 = "Thanks"; + } else { + data->currentTalk0 = "You do not seem to have"; + data->currentTalk1 = "enough Gold Bars with you."; + data->currentTalk2 = ""; + data->currentTalk3 = "Ask again when you have"; + data->currentTalk4 = "collected the 10 Bars."; + data->currentTalk5 = ""; + + data->currentTalkOption0 = "Ok"; + } + } + } else if(data->currentNPCVal==2) { + if(data->currentTalkSel==0) { + pd->ingameMenu = MENU_NONE; + } + } + } + break; + case NPC_DWARF: + if(questManager->questlines[1].currentQuest<=1) { + if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { + if(data->currentNPCVal==0) pd->ingameMenu = MENU_NONE; + } + } else if(questManager->questlines[1].currentQuest==2) { + if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) { + if(data->currentTalkSel==0) { + pd->ingameMenu = MENU_NONE; + } else if(data->currentTalkSel==1) { + openCraftingMenu(pd, &dwarfTrades, "Trading"); + } + } + } + break; + } } void renderTalkMenu(NPC_MenuData *data, char * name) { - renderFrame(1,1,24,14,0xFFFF1010); - drawTextColor(name,24+1,14+1,0xFF000000); + renderFrame(1,1,24,14,0xFFFF1010); + drawTextColor(name,24+1,14+1,0xFF000000); drawTextColor(name,24,14,0xFF6FE2E2); - - drawText(data->currentTalk0, 32, 32); - drawText(data->currentTalk1, 32, 48); - drawText(data->currentTalk2, 32, 64); - drawText(data->currentTalk3, 32, 80); - drawText(data->currentTalk4, 32, 96); - drawText(data->currentTalk5, 32, 112); - - if(data->currentTalkOptions>=3) drawText(data->currentTalkOption2, 64, 147); - if(data->currentTalkOptions>=2) drawText(data->currentTalkOption1, 64, 171); - if(data->currentTalkOptions>=1) drawText(data->currentTalkOption0, 64, 195); - - if(data->currentTalkOptions>=3 && data->currentTalkSel==2) drawText(">", 48, 147); - if(data->currentTalkOptions>=2 && data->currentTalkSel==1) drawText(">", 48, 171); - if(data->currentTalkOptions>=1 && data->currentTalkSel==0) drawText(">", 48, 195); + + drawText(data->currentTalk0, 32, 32); + drawText(data->currentTalk1, 32, 48); + drawText(data->currentTalk2, 32, 64); + drawText(data->currentTalk3, 32, 80); + drawText(data->currentTalk4, 32, 96); + drawText(data->currentTalk5, 32, 112); + + if(data->currentTalkOptions>=3) drawText(data->currentTalkOption2, 64, 147); + if(data->currentTalkOptions>=2) drawText(data->currentTalkOption1, 64, 171); + if(data->currentTalkOptions>=1) drawText(data->currentTalkOption0, 64, 195); + + if(data->currentTalkOptions>=3 && data->currentTalkSel==2) drawText(">", 48, 147); + if(data->currentTalkOptions>=2 && data->currentTalkSel==1) drawText(">", 48, 171); + if(data->currentTalkOptions>=1 && data->currentTalkSel==0) drawText(">", 48, 195); } void renderNPCMenu(NPC_MenuData *data) { - //TODO: Handle upon currentNPC as well as the fitting quest progress - switch(data->currentNPC) { - case NPC_GIRL: - if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Maria"); - break; - case NPC_PRIEST: - if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Priest Brom"); - break; - case NPC_FARMER: - if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Farmer Garrow"); - break; - case NPC_LIBRARIAN: - if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Librarian Ajihad"); - break; - case NPC_DWARF: - if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Dwarf Orik"); - break; - } + //TODO: Handle upon currentNPC as well as the fitting quest progress + switch(data->currentNPC) { + case NPC_GIRL: + if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Maria"); + break; + case NPC_PRIEST: + if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Priest Brom"); + break; + case NPC_FARMER: + if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Farmer Garrow"); + break; + case NPC_LIBRARIAN: + if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Librarian Ajihad"); + break; + case NPC_DWARF: + if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Dwarf Orik"); + break; + } } diff --git a/source/QuestsData.h b/source/QuestsData.h index 6972aed..91a770e 100644 --- a/source/QuestsData.h +++ b/source/QuestsData.h @@ -3,33 +3,33 @@ #include <3ds.h> typedef struct _questline { - int currentQuest; - bool currentQuestDone; + int currentQuest; + bool currentQuestDone; } Questline; typedef struct _questlineManager { - int size; - Questline * questlines; + int size; + Questline * questlines; } QuestlineManager; typedef struct _npcMenuData { - u8 currentNPC; + u8 currentNPC; - int currentNPCMenu; - int currentNPCVal; + 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; + int currentTalkSel; + bool currentTalkDone; + int currentTalkOptions; + char * currentTalkOption0; + char * currentTalkOption1; + char * currentTalkOption2; + char * currentTalk0; + char * currentTalk1; + char * currentTalk2; + char * currentTalk3; + char * currentTalk4; + char * currentTalk5; } NPC_MenuData; //TODO: Actually move the data here diff --git a/source/Render.c b/source/Render.c index 9d2b520..5ae4d06 100755 --- a/source/Render.c +++ b/source/Render.c @@ -165,8 +165,8 @@ void renderp(s32 xp, s32 yp, u32 xTile, u32 yTile) { xp -= offsetX; yp -= offsetY; int scaleX = playerScale, scaleY = playerScale; - sf2d_draw_texture_part_scale(playerSprites, xp << 1, yp << 1, xTile, yTile, 16, 16, - scaleX, scaleY); + sf2d_draw_texture_part_scale(playerSprites, xp << 1, yp << 1, xTile, yTile, 16, 16, + scaleX, scaleY); } void renderTitle(int x, int y) { @@ -285,13 +285,13 @@ void renderFrame(int x1, int y1, int x2, int y2, u32 bgColor) { void bakeLights() { playerLightBake = sf2d_create_texture(64, 64, TEXFMT_RGBA8, SF2D_PLACE_RAM); lanternLightBake = sf2d_create_texture(128, 128, TEXFMT_RGBA8, SF2D_PLACE_RAM); - + glowwormLightBake = sf2d_create_texture(32, 32, TEXFMT_RGBA8, SF2D_PLACE_RAM); glowwormBigLightBake = sf2d_create_texture(64, 64, TEXFMT_RGBA8, SF2D_PLACE_RAM); bakeLight(playerLightBake, 32, 32, 32); bakeLight(lanternLightBake, 64, 64, 64); - + bakeLight(glowwormLightBake, 8, 8, 8); bakeLight(glowwormBigLightBake, 12, 12, 12); } @@ -299,7 +299,7 @@ void bakeLights() { void freeLightBakes() { sf2d_free_texture(playerLightBake); sf2d_free_texture(lanternLightBake); - + sf2d_free_texture(glowwormLightBake); sf2d_free_texture(glowwormBigLightBake); } @@ -311,9 +311,9 @@ void renderLightsToStencil(PlayerData *pd, bool force, bool invert, bool rplayer C3D_StencilOp(GPU_STENCIL_REPLACE, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP); C3D_AlphaTest(true, GPU_GREATER, 0); - if(pd->activeItem->id == ITEM_LANTERN) renderLight(pd->entity.x, pd->entity.y, lanternLightBake); - else if(rplayer) renderLight(pd->entity.x, pd->entity.y, playerLightBake); - + if(pd->activeItem->id == ITEM_LANTERN) renderLight(pd->entity.x, pd->entity.y, lanternLightBake); + else if(rplayer) renderLight(pd->entity.x, pd->entity.y, playerLightBake); + int i; for (i = 0; i < eManager.lastSlot[pd->entity.level]; ++i) { Entity e = eManager.entities[pd->entity.level][i]; @@ -326,7 +326,7 @@ void renderLightsToStencil(PlayerData *pd, bool force, bool invert, bool rplayer else renderLight(e.x+8, e.y-8, glowwormLightBake); } } - + int xo = offsetX >> 4; int yo = offsetY >> 4; int x, y; @@ -334,7 +334,7 @@ void renderLightsToStencil(PlayerData *pd, bool force, bool invert, bool rplayer //TODO: Even this is not performant enough for old 3DS, when there is a lot of lava on screen for (x = xo-2; x <= 13 + xo+2; ++x) { for (y = yo-2; y <= 8 + yo+2; ++y) { - if(getTile(pd->entity.level, x, y) == TILE_LAVA) { + if(getTile(pd->entity.level, x, y) == TILE_LAVA) { //experimental "speedhack" if(getTile(pd->entity.level, x+1,y)==TILE_LAVA && getTile(pd->entity.level, x-1,y)==TILE_LAVA && getTile(pd->entity.level, x,y+1)==TILE_LAVA && getTile(pd->entity.level, x,y-1)==TILE_LAVA) { if((x+y)%2 == 0) continue; @@ -343,7 +343,7 @@ void renderLightsToStencil(PlayerData *pd, bool force, bool invert, bool rplayer } } } - + C3D_DepthTest(true, GPU_GEQUAL, GPU_WRITE_ALL); if(invert) { @@ -421,7 +421,7 @@ void renderDots(int x, int y, u8 bits1, u8 bits2, u8 bits3, u8 bits4, u32 xTile, 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); @@ -478,40 +478,40 @@ void renderTile(int i, int d, u8 level, int x, int y) { checkSurrTiles4(level, x >> 4, y >> 4, TILE_TREE); checkSurrTiles4(level, x >> 4, y >> 4, TILE_FLOWER); checkSurrTiles4(level, x >> 4, y >> 4, TILE_SAPLING_TREE); - - if(level==1 && worldData.season==3) renderConnectedTile4(x, y, 256, 112); - else if(level==1 && worldData.season==2) renderConnectedTile4(x, y, 256, 128); + + if(level==1 && worldData.season==3) renderConnectedTile4(x, y, 256, 112); + else if(level==1 && worldData.season==2) renderConnectedTile4(x, y, 256, 128); else renderConnectedTile4(x, y, 256, 0); break; case TILE_TREE: renderTile(TILE_GRASS, 0, level, x, y); - + checkSurrTiles8(level, x >> 4, y >> 4, TILE_TREE); - - if(worldData.season==2) { - render(x, y, 352+((tu && tl && tul) ? 16 : 0), 96, 0); - render(x+8, y, 360+((tu && tr && tur) ? 16 : 0), 96, 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(worldData.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); - } - + + if(worldData.season==2) { + render(x, y, 352+((tu && tl && tul) ? 16 : 0), 96, 0); + render(x+8, y, 360+((tu && tr && tur) ? 16 : 0), 96, 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(worldData.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; case TILE_ROCK: checkSurrTiles8(level, x >> 4, y >> 4, TILE_ROCK); - if(level>1) - renderConnectedTile8(x, y, 256, 96); - else - renderConnectedTile8(x, y, 336, 64); + if(level>1) + renderConnectedTile8(x, y, 256, 96); + else + renderConnectedTile8(x, y, 336, 64); break; case TILE_HARDROCK: checkSurrTiles8(level, x >> 4, y >> 4, TILE_HARDROCK); @@ -527,33 +527,33 @@ void renderTile(int i, int d, u8 level, int x, int y) { checkSurrTiles4(level, x >> 4, y >> 4, TILE_SAND); checkSurrTiles4(level, x >> 4, y >> 4, TILE_CACTUS); checkSurrTiles4(level, x >> 4, y >> 4, TILE_SAPLING_CACTUS); - + if(level==1 && worldData.season==3) { - renderConnectedTile4(x, y, 256, 112); + renderConnectedTile4(x, y, 256, 112); } else { - renderConnectedTile4(x, y, 320, 0); - - if (d > 0) { - render16(x, y, 336, 48, 0); - } - } + renderConnectedTile4(x, y, 320, 0); + + if (d > 0) { + render16(x, y, 336, 48, 0); + } + } break; case TILE_WATER: checkSurrTiles4(level, x >> 4, y >> 4, TILE_WATER); checkSurrTiles4(level, x >> 4, y >> 4, TILE_HOLE); checkSurrTiles4(level, x >> 4, y >> 4, TILE_ICE); - + renderConnectedTile4(x, y, 384, 0); - + srand((syncTickCount + (x / 2 - y) * 4311) / 10); renderDots(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, 288, 64); break; case TILE_LAVA: checkSurrTiles4(level, x >> 4, y >> 4, TILE_LAVA); checkSurrTiles4(level, x >> 4, y >> 4, TILE_HOLE); - + renderConnectedTile4(x, y, 448, 0); - + srand((syncTickCount + (x / 2 - y) * 4311) / 10); renderDots(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, 304, 64); break; @@ -561,7 +561,7 @@ void renderTile(int i, int d, u8 level, int x, int y) { checkSurrTiles4(level, x >> 4, y >> 4, TILE_HOLE); checkSurrTiles4(level, x >> 4, y >> 4, TILE_WATER); checkSurrTiles4(level, x >> 4, y >> 4, TILE_LAVA); - + renderConnectedTile4(x, y, 256, 16); break; case TILE_CACTUS: @@ -571,7 +571,7 @@ void renderTile(int i, int d, u8 level, int x, int y) { case TILE_FLOWER: renderTile(TILE_GRASS, 0, level, x, y); if(level==1 && worldData.season==3) render16(x, y, 320, 112, d); - else render16(x, y, 320, 48, d); + else render16(x, y, 320, 48, d); break; case TILE_STAIRS_DOWN: if (level == 0) @@ -594,7 +594,7 @@ void renderTile(int i, int d, u8 level, int x, int y) { checkSurrTiles4(level, x >> 4, y >> 4, TILE_CLOUD); checkSurrTiles4(level, x >> 4, y >> 4, TILE_STAIRS_DOWN); checkSurrTiles4(level, x >> 4, y >> 4, TILE_CLOUDCACTUS); - + renderConnectedTile4(x, y, 320, 16); break; case TILE_CLOUDCACTUS: @@ -620,32 +620,32 @@ void renderTile(int i, int d, u8 level, int x, int y) { break; case TILE_WOOD_WALL: checkSurrTiles4(level, x >> 4, y >> 4, TILE_WOOD_WALL); - + renderConnectedTile4(x, y, 384, 16); break; case TILE_STONE_WALL: checkSurrTiles4(level, x >> 4, y >> 4, TILE_STONE_WALL); - + renderConnectedTile4(x, y, 256, 80); break; case TILE_IRON_WALL: checkSurrTiles4(level, x >> 4, y >> 4, TILE_IRON_WALL); - + renderConnectedTile4(x, y, 448, 16); break; case TILE_GOLD_WALL: checkSurrTiles4(level, x >> 4, y >> 4, TILE_GOLD_WALL); - + renderConnectedTile4(x, y, 256, 32); break; case TILE_GEM_WALL: checkSurrTiles4(level, x >> 4, y >> 4, TILE_GEM_WALL); - + renderConnectedTile4(x, y, 320, 32); break; case TILE_DUNGEON_WALL: checkSurrTiles8(level, x >> 4, y >> 4, TILE_DUNGEON_WALL); - + renderConnectedTile8(x, y, 384, 32); break; case TILE_DUNGEON_FLOOR: @@ -657,61 +657,61 @@ void renderTile(int i, int d, u8 level, int x, int y) { case TILE_MAGIC_BARRIER: renderTile(TILE_DUNGEON_FLOOR, 0, level, x, y); render16(x, y, 320, 64, d); - + //draw remaining pillar count - PlayerData *lp = getLocalPlayer(); + PlayerData *lp = getLocalPlayer(); if((lp->entity.x - (x+8))*(lp->entity.x - (x+8)) + (lp->entity.y - (y+8))*(lp->entity.y - (y+8)) <= 24*24) { x -= offsetX; y -= offsetY; - + int data = 0; int i = 0; for (i = 0; i < eManager.lastSlot[level]; ++i) { Entity * e = &eManager.entities[level][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; - case TILE_BOOKSHELVES: + case TILE_BOOKSHELVES: checkSurrTiles4(level, 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: + case TILE_WOOD_FLOOR: + render16(x, y, 336, 96, 0); + break; + case TILE_MYCELIUM: checkSurrTiles4(level, x >> 4, y >> 4, TILE_MYCELIUM); checkSurrTiles4(level, x >> 4, y >> 4, TILE_MUSHROOM_BROWN); checkSurrTiles4(level, x >> 4, y >> 4, TILE_MUSHROOM_RED); - + if(level==1 && worldData.season==3) renderConnectedTile4(x, y, 256, 112); else renderConnectedTile4(x, y, 448, 80); break; - case TILE_MUSHROOM_BROWN: - renderTile(TILE_MYCELIUM, 0, level, x, y); + case TILE_MUSHROOM_BROWN: + renderTile(TILE_MYCELIUM, 0, level, x, y); render16(x, y, 448 + (d&0x1)*16, 96, 0); - break; - case TILE_MUSHROOM_RED: - renderTile(TILE_MYCELIUM, 0, level, x, y); + break; + case TILE_MUSHROOM_RED: + renderTile(TILE_MYCELIUM, 0, level, x, y); render16(x, y, 480 + (d&0x1)*16, 96, 0); - break; - case TILE_ICE: + break; + case TILE_ICE: renderTile(TILE_WATER, 0, level, x, y); //checkSurrTiles4(x >> 4, y >> 4, TILE_WATER); //checkSurrTiles4(x >> 4, y >> 4, TILE_HOLE); checkSurrTiles4(level, x >> 4, y >> 4, TILE_ICE); - + renderConnectedTile4(x, y, 448, 112); break; } @@ -725,12 +725,12 @@ void renderConnectedTile4(int x, int y, u32 xTile, u32 yTile) { render16(x, y, xTile+48, yTile, 0); return; } - + int l = (tl ? 16 : 0); int r = (tr ? 16 : 0); int u = (tu ? 32 : 0); int d = (td ? 32 : 0); - + 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); @@ -743,12 +743,12 @@ void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile) { render16(x, y, xTile+64, yTile, 0); return; } - + int l = (tl ? 16 : 0); int r = (tr ? 16 : 0); int u = (tu ? 32 : 0); int d = (td ? 32 : 0); - + 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); @@ -757,45 +757,45 @@ void renderConnectedTile8(int x, int y, u32 xTile, u32 yTile) { void renderZoomedMap(PlayerData *pd) { 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 = pd->mapScrollX; - int my = pd->mapScrollY; - if(pd->mapZoomLevel == 2) mx = 32; + + int mx = pd->mapScrollX; + int my = pd->mapScrollY; + if(pd->mapZoomLevel == 2) mx = 32; sf2d_draw_texture_scale(minimap[pd->entity.level], mx, my, pd->mapZoomLevel, pd->mapZoomLevel); // zoomed map - + // Airwizard on zoomed map if(pd->entity.level == 0){ if(awX != 0 && awY != 0){ render16c( - (mx+((awX/16)*pd->mapZoomLevel)-16)/2, - (my+((awY/16)*pd->mapZoomLevel)-16)/2, - 160, 112, - ((pd->entity.p.walkDist >> 6) & 1) == 0 ? 0 : 1, + (mx+((awX/16)*pd->mapZoomLevel)-16)/2, + (my+((awY/16)*pd->mapZoomLevel)-16)/2, + 160, 112, + ((pd->entity.p.walkDist >> 6) & 1) == 0 ? 0 : 1, 2, 2 ); } - } + } // Player on zoomed map - //TODO: Maybe also render other players? - render16c( - (mx+((pd->entity.x/16)*pd->mapZoomLevel)-16)/2, - (my+((pd->entity.y/16)*pd->mapZoomLevel)-16)/2, - 0, 112, - ((pd->entity.p.walkDist >> 6) & 1) == 0 ? 0 : 1, - 2, 2 - ); - - drawText(pd->mapText,224, 214); // "x2"/"x4"/"x6" - render16(142, 2, 72, 208, 0); // Exit button - renderc(126, 102, 40, 208, 32, 16, 0); // Plus/Minus zoom buttons - if(pd->mapZoomLevel < 3) sf2d_draw_rectangle(258, 210, 26, 20, 0x7F4F4F4F); // gray out minus button - else if(pd->mapZoomLevel > 5) sf2d_draw_rectangle(284, 210, 26, 20, 0x7F4F4F4F); // gray out minus button + //TODO: Maybe also render other players? + render16c( + (mx+((pd->entity.x/16)*pd->mapZoomLevel)-16)/2, + (my+((pd->entity.y/16)*pd->mapZoomLevel)-16)/2, + 0, 112, + ((pd->entity.p.walkDist >> 6) & 1) == 0 ? 0 : 1, + 2, 2 + ); + + drawText(pd->mapText,224, 214); // "x2"/"x4"/"x6" + render16(142, 2, 72, 208, 0); // Exit button + renderc(126, 102, 40, 208, 32, 16, 0); // Plus/Minus zoom buttons + if(pd->mapZoomLevel < 3) sf2d_draw_rectangle(258, 210, 26, 20, 0x7F4F4F4F); // gray out minus button + else if(pd->mapZoomLevel > 5) sf2d_draw_rectangle(284, 210, 26, 20, 0x7F4F4F4F); // gray out minus button } char scoreT[32]; void renderGui(PlayerData *pd) { int i; - //health and stamina + //health and stamina for (i = 0; i < 10; ++i) { if (i < pd->entity.p.health) render(i * 8 + 6, 5, 168, 152, 0); @@ -806,11 +806,11 @@ void renderGui(PlayerData *pd) { else render(i * 8 + 6, 14, 191, 152, 0); } - - //minimap + + //minimap sf2d_draw_texture(minimap[pd->entity.level], 10, 102); - - //active item + + //active item renderItemWithTextCentered(pd->activeItem, 320, 66); itoa(pd->score, scoreT, 10); // integer to base10 string drawText("Score:",214,12); @@ -819,10 +819,10 @@ void renderGui(PlayerData *pd) { if(awX != 0 && awY != 0){ renderc(1 + (awX/32), 47 + (awY/32), 88, 216, 8, 8, 0); // Mini-AWizard head. } - } - //TODO: Maybe also render other players? + } + //TODO: Maybe also render other players? renderc(1 + (pd->entity.x/32), 47 + (pd->entity.y/32), 88, 208, 8, 8, 0); // Mini-Player head. - + //quick select drawText("Quickselect:",164,118); @@ -832,7 +832,7 @@ void renderGui(PlayerData *pd) { if((inv->lastSlot) > i) { int xip = i % 4; int yip = i / 4; - + item = &inv->items[i]; renderItemIcon(item->id, item->countLevel, 81+xip*21, 77+yip*21); } @@ -840,86 +840,86 @@ void renderGui(PlayerData *pd) { } void renderPlayer(PlayerData *pd) { - if (pd->entity.level!=getLocalPlayer()->entity.level) { - return; - } + if (pd->entity.level!=getLocalPlayer()->entity.level) { + return; + } if (pd->entity.p.isDead) { return; - } + } int xo = pd->entity.x - 8; int yo = pd->entity.y - 8; - //attack animation upwards + //attack animation upwards if (pd->entity.p.attackTimer > 0 && pd->entity.p.dir == 1) { renderc(xo, yo - 4, 16, 160, 16, 8, 0); renderItemIcon(pd->activeItem->id, pd->activeItem->countLevel, xo + 4, yo - 4); } - - //find basic indices - int aIndexBig = 0; - int aIndexSmall = 0; - switch(pd->entity.p.dir) { - case 0: //down - aIndexBig = 0; - aIndexSmall = 0; - break; - case 1: //up - aIndexBig = 2; - aIndexSmall = 1; - break; - case 2: //left - aIndexBig = 7; - aIndexSmall = 3; - break; - case 3: //right - aIndexBig = 4; - aIndexSmall = 2; - break; - } - - //find index offset based on walk state - u8 walkingOffset = (pd->entity.p.walkDist >> 4) % 2; - if(pd->entity.p.dir==2 || pd->entity.p.dir==3) { - walkingOffset = (pd->entity.p.walkDist >> 4) % 4; - if(walkingOffset==2) walkingOffset = 0; - if(walkingOffset==3) walkingOffset = 2; - } - - bool swimming = isWater(pd->entity.level, pd->entity.x>>4, pd->entity.y>>4); - - //render water anim when swimming - if (swimming) { - renderc(xo, yo + 5, 48, 160 + (((pd->entity.p.swimTimer >> 4) & 1) << 3), 16, 8, 0); - } - - - //render the different parts - //legs - if(!swimming) { - renderp(xo, yo, (0+aIndexBig+walkingOffset)*16, pd->sprite.legs*16); - } - //body - renderp(xo, yo, (10+aIndexBig+walkingOffset)*16, pd->sprite.body*16); - //arms (normal) - if(!(pd->entity.p.isCarrying)) { - renderp(xo, yo, (20+aIndexBig+walkingOffset)*16, pd->sprite.arms*16); - } - //head - renderp(xo, yo, (30+aIndexSmall)*16, pd->sprite.head*16); - //eyes - renderp(xo, yo, (34+aIndexSmall)*16, pd->sprite.eyes*16); - //arms (carrying) - if(pd->entity.p.isCarrying) { - renderp(xo, yo, (38+aIndexSmall)*16, pd->sprite.arms*16); - } - - - //furniture + + //find basic indices + int aIndexBig = 0; + int aIndexSmall = 0; + switch(pd->entity.p.dir) { + case 0: //down + aIndexBig = 0; + aIndexSmall = 0; + break; + case 1: //up + aIndexBig = 2; + aIndexSmall = 1; + break; + case 2: //left + aIndexBig = 7; + aIndexSmall = 3; + break; + case 3: //right + aIndexBig = 4; + aIndexSmall = 2; + break; + } + + //find index offset based on walk state + u8 walkingOffset = (pd->entity.p.walkDist >> 4) % 2; + if(pd->entity.p.dir==2 || pd->entity.p.dir==3) { + walkingOffset = (pd->entity.p.walkDist >> 4) % 4; + if(walkingOffset==2) walkingOffset = 0; + if(walkingOffset==3) walkingOffset = 2; + } + + bool swimming = isWater(pd->entity.level, pd->entity.x>>4, pd->entity.y>>4); + + //render water anim when swimming + if (swimming) { + renderc(xo, yo + 5, 48, 160 + (((pd->entity.p.swimTimer >> 4) & 1) << 3), 16, 8, 0); + } + + + //render the different parts + //legs + if(!swimming) { + renderp(xo, yo, (0+aIndexBig+walkingOffset)*16, pd->sprite.legs*16); + } + //body + renderp(xo, yo, (10+aIndexBig+walkingOffset)*16, pd->sprite.body*16); + //arms (normal) + if(!(pd->entity.p.isCarrying)) { + renderp(xo, yo, (20+aIndexBig+walkingOffset)*16, pd->sprite.arms*16); + } + //head + renderp(xo, yo, (30+aIndexSmall)*16, pd->sprite.head*16); + //eyes + renderp(xo, yo, (34+aIndexSmall)*16, pd->sprite.eyes*16); + //arms (carrying) + if(pd->entity.p.isCarrying) { + renderp(xo, yo, (38+aIndexSmall)*16, pd->sprite.arms*16); + } + + + //furniture if (pd->entity.p.isCarrying) { renderFurniture(pd->activeItem->id, xo, yo - 12); } - //attack animation (other directios) + //attack animation (other directios) if (pd->entity.p.attackTimer > 0) { switch (pd->entity.p.dir) { case 0: @@ -939,37 +939,37 @@ void renderPlayer(PlayerData *pd) { } void renderWeather(u8 level, int xScroll, int yScroll) { - if(level==1) { - if(worldData.season==3) { - int xp = -128 + ((syncTickCount>>2) - xScroll*2)%128; - int yp = -128 + ((syncTickCount>>1) - yScroll*2)%128; - int xp2 = 0 - ((syncTickCount>>2) + xScroll*2)%128; - int yp2 = -128 + ((syncTickCount>>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(worldData.rain) { - int xp = -((xScroll*2)%128); - int yp = -128 + ((syncTickCount<<2) - yScroll*2)%128; - int xp2 = -((xScroll*2+8)%128); - int yp2 = -128 + ((syncTickCount<<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); - } - } - } - } + if(level==1) { + if(worldData.season==3) { + int xp = -128 + ((syncTickCount>>2) - xScroll*2)%128; + int yp = -128 + ((syncTickCount>>1) - yScroll*2)%128; + int xp2 = 0 - ((syncTickCount>>2) + xScroll*2)%128; + int yp2 = -128 + ((syncTickCount>>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(worldData.rain) { + int xp = -((xScroll*2)%128); + int yp = -128 + ((syncTickCount<<2) - yScroll*2)%128; + int xp2 = -((xScroll*2+8)%128); + int yp2 = -128 + ((syncTickCount<<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(PlayerData *pd) { @@ -978,7 +978,7 @@ void renderDayNight(PlayerData *pd) { int color2 = 0x00100C0C; int alpha1 = 0x88; int alpha2 = 0xDD; - + if(worldData.daytime>5000 && worldData.daytime<6000) { alpha2 = (alpha2 * (1000-(worldData.daytime-5000)))/1000; alpha1 = (alpha1 * (1000-(worldData.daytime-5000)))/1000; @@ -986,10 +986,10 @@ void renderDayNight(PlayerData *pd) { alpha1 = (alpha1 * (worldData.daytime-18000))/1000; alpha2 = (alpha2 * (worldData.daytime-18000))/1000; } - + color1 = color1 | (alpha1 << 24); color2 = color2 | (alpha2 << 24); - + sf2d_draw_rectangle(0, 0, 400, 240, color1); //You might think "real" black would be better, but it actually looks better that way renderLightsToStencil(pd, true, true, false); sf2d_draw_rectangle(0, 0, 400, 240, color2); //You might think "real" black would be better, but it actually looks better that way @@ -998,7 +998,7 @@ void renderDayNight(PlayerData *pd) { } void renderBackground(s8 level, int xScroll, int yScroll) { - if(level == 0) { + if(level == 0) { sf2d_draw_texture_part_scale(minimap[1], (-xScroll / 3) - 256, (-yScroll / 3) - 32, 0, 0, 128, 128, 12.5, 7.5); sf2d_draw_rectangle(0, 0, 400, 240, 0xAFDFDFDF); } else if(level == 5) { @@ -1118,7 +1118,7 @@ void renderFurniture(int itemID, int x, int y) { render16(x, y, 240, 128, 0); break; case ITEM_POTION_MAKER: - render16(x, y, 240, 96, 0); + render16(x, y, 192, 168, 0); break; } } @@ -1265,7 +1265,7 @@ void renderEntity(Entity* e, int x, int y) { break; } break; - case ENTITY_DRAGONPROJECTILE: + case ENTITY_DRAGONPROJECTILE: if(e->dragonFire.type==0) { renderr(x, y, 0, 320, 0, e->dragonFire.age * 0.349); } else { @@ -1279,7 +1279,7 @@ void renderEntity(Entity* e, int x, int y) { if (e->arrow.age >= 200) if (e->arrow.age / 6 % 2 == 0) return; - + int abits = 0; int ayp = 168; if(e->arrow.xa<0) { @@ -1292,7 +1292,7 @@ void renderEntity(Entity* e, int x, int y) { ayp += 8; abits += 2; } - + switch (e->arrow.itemID) { case ITEM_ARROW_WOOD: render(x-2, y-2, 72, ayp, abits); @@ -1314,7 +1314,7 @@ void renderEntity(Entity* e, int x, int y) { case ENTITY_GLOWWORM: render(x-4, y-4, 224, 112, 0); break; - case ENTITY_NPC: + case ENTITY_NPC: render16(x - 8, y - 8, (e->npc.type*16) + 0, 64, 0); } } @@ -1432,10 +1432,10 @@ void renderRecipes(RecipeManager * r, int xo, int yo, int x1, int y1, int select else col = 0xFF7F7F7F; if(r->recipes[i + io].itemAmountLevel==1) { - drawTextColor(getBasicItemName(r->recipes[i + io].itemResult, r->recipes[i + io].itemAmountLevel), x + 18, y + 2, col); - } else { - drawTextColor(getItemName(r->recipes[i + io].itemResult, r->recipes[i + io].itemAmountLevel), x + 18, y + 2, col); - } + drawTextColor(getBasicItemName(r->recipes[i + io].itemResult, r->recipes[i + io].itemAmountLevel), x + 18, y + 2, col); + } else { + drawTextColor(getItemName(r->recipes[i + io].itemResult, r->recipes[i + io].itemAmountLevel), x + 18, y + 2, col); + } } int yy = selected + 1 - io + yo; @@ -1463,13 +1463,13 @@ void renderItemStuffWithText(int itemID, int itemCL, bool onlyOne, int x, int y) y + 2, 0xFFD2D2D2, 0xFFFFFFFF); } -/* For bottom screen */ +/* For bottom screen */ void renderItemWithTextCentered(Item* item, int width, int y) { char * tn = getItemName(item->id, item->countLevel); - int x = (width - ((strlen(tn) + 2) * 12))/2; - + int x = (width - ((strlen(tn) + 2) * 12))/2; + renderItemIcon(item->id, item->countLevel, x >> 1, y >> 1); - + if (item->onlyOne) drawText(getItemName(item->id, item->countLevel), x + 18, y + 2); else @@ -1478,8 +1478,8 @@ void renderItemWithTextCentered(Item* item, int width, int y) { } void renderItemIcon(int itemID, int countLevel, int x, int y) { - int xd; - int yd; + int xd; + int yd; switch (itemID) { case ITEM_NULL: return; @@ -1523,7 +1523,7 @@ void renderItemIcon(int itemID, int countLevel, int x, int y) { render(x, y, 0, 152, 0); break; case ITEM_WOOD: - render(x, y, 8, 152, 0); + render(x, y, 160, 168, 0); break; case ITEM_STONE: renderb(x, y, 16, 152, 0, rockColor[1]); @@ -1559,19 +1559,19 @@ void renderItemIcon(int itemID, int countLevel, int x, int y) { render(x, y, 80, 152, 0); break; case ITEM_GOLD_APPLE: - render(x, y, 177, 160, 0); + render(x, y, 144, 168, 0); break; case ITEM_STRENGTH_POTION: - render(x, y, 184, 160, 0); + render(x, y, 176, 160, 0); break; case ITEM_SPEED_POTION: - render(x, y, 191, 160, 0); + render(x, y, 184, 160, 0); break; case ITEM_REGEN_POTION: - render(x, y, 198, 160, 0); + render(x, y, 192, 160, 0); break; case ITEM_SWIM_BREATH_POTION: - render(x, y, 219, 160, 0); + render(x, y, 200, 160, 0); break; case ITEM_SLIME: renderb(x, y, 88, 152, 0, 0xFF4DC04D); @@ -1604,7 +1604,7 @@ void renderItemIcon(int itemID, int countLevel, int x, int y) { render(x, y, 144, 160, 0); break; case ITEM_POTION_MAKER: - render(x, y, 216, 152, 0); + render(x, y, 192, 168, 0); break; case ITEM_WALL_WOOD: renderb(x, y, 224, 144, 0, woodColor); @@ -1672,14 +1672,14 @@ void renderItemIcon(int itemID, int countLevel, int x, int y) { case ITEM_DRAGON_SCALE: render(x, y, 168, 160, 0); break; - case ITEM_BOOKSHELVES: + case ITEM_BOOKSHELVES: render(x, y, 232, 144, 0); break; - case ITEM_MAGIC_DUST: - render(x, y, 200, 152, 0); + case ITEM_MAGIC_DUST: + render(x, y, 200, 152, 0); break; - case ITEM_COIN: - render(x, y, 208, 152, 0); + case ITEM_COIN: + render(x, y, 208, 152, 0); break; case TOOL_BUCKET: render(x, y, 200 + countLevel * 8, 144, 0); @@ -1687,16 +1687,16 @@ void renderItemIcon(int itemID, int countLevel, int x, int y) { case TOOL_BOW: render(x, y, 64, 168, 0); break; - case TOOL_MAGIC_COMPASS: - xd = worldData.compassData[getLocalPlayer()->entity.level][0] - (getLocalPlayer()->entity.x>>4); - yd = worldData.compassData[getLocalPlayer()->entity.level][1] - (getLocalPlayer()->entity.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); - } + case TOOL_MAGIC_COMPASS: + xd = worldData.compassData[getLocalPlayer()->entity.level][0] - (getLocalPlayer()->entity.x>>4); + yd = worldData.compassData[getLocalPlayer()->entity.level][1] - (getLocalPlayer()->entity.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; } } diff --git a/source/Render.h b/source/Render.h index 98e39a7..e967538 100755 --- a/source/Render.h +++ b/source/Render.h @@ -1,7 +1,7 @@ #pragma once #include <3ds.h> #include -#include +#include #include #include #include "Globals.h" diff --git a/source/SaveLoad.c b/source/SaveLoad.c index 19b1e4d..ecd1067 100755 --- a/source/SaveLoad.c +++ b/source/SaveLoad.c @@ -3,33 +3,33 @@ #include "ZipHelper.h" bool entityIsImportant(Entity * e){ - switch(e->type){ - case ENTITY_AIRWIZARD: - case ENTITY_SLIME: - case ENTITY_ZOMBIE: + switch(e->type){ + case ENTITY_AIRWIZARD: + case ENTITY_SLIME: + case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: - case ENTITY_ITEM: - case ENTITY_FURNITURE: + case ENTITY_ITEM: + case ENTITY_FURNITURE: case ENTITY_PASSIVE: case ENTITY_GLOWWORM: case ENTITY_DRAGON: - case ENTITY_NPC: - return true; - default: - return false; - } + case ENTITY_NPC: + return true; + default: + 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; + int i; + s16 count = 0; + for(i = 0; i < eManager->lastSlot[level]; ++i){ + if(entityIsImportant(&eManager->entities[level][i])){ + count++; + } + } + return count; } //helper methods @@ -37,574 +37,574 @@ char **files; int fileCount; void saveTrackFileReset() { - if(files!=NULL) { - for(int i=0; i0) { - fwrite(buffer, 1, size, out); - } - } while(size>0); - - fclose(in); - fclose(out); - - return true; + char buffer[SAVE_COPYBUFFER_SIZE]; + + FILE *in = fopen(source, "rb"); + if(in==NULL) { + return false; + } + FILE *out = fopen(target, "wb"); + if(out==NULL) { + fclose(out); + return false; + } + + size_t size; + do { + size = fread(buffer, 1, SAVE_COPYBUFFER_SIZE, in); + + if(size>0) { + fwrite(buffer, 1, size, out); + } + } while(size>0); + + fclose(in); + fclose(out); + + return true; } //internal save methods void saveInventory(Inventory *inv, EntityManager *eManager, FILE *file) { - fwrite(&inv->lastSlot, sizeof(s16), 1, file); // write amount of items in inventory; - for(int j = 0; j < inv->lastSlot; ++j) { - fwrite(&(inv->items[j].id), sizeof(s16), 1, file); // write ID of item - fwrite(&(inv->items[j].countLevel), sizeof(s16), 1, file); // write count/level of item - fwrite(&(inv->items[j].onlyOne), sizeof(bool), 1, file); - if(inv->items[j].id == ITEM_CHEST){ - int invIndex = inv->items[j].chestPtr - eManager->invs; - fwrite(&invIndex, sizeof(int), 1, file); - } - } + fwrite(&inv->lastSlot, sizeof(s16), 1, file); // write amount of items in inventory; + for(int j = 0; j < inv->lastSlot; ++j) { + fwrite(&(inv->items[j].id), sizeof(s16), 1, file); // write ID of item + fwrite(&(inv->items[j].countLevel), sizeof(s16), 1, file); // write count/level of item + fwrite(&(inv->items[j].onlyOne), sizeof(bool), 1, file); + if(inv->items[j].id == ITEM_CHEST){ + int invIndex = inv->items[j].chestPtr - eManager->invs; + fwrite(&invIndex, sizeof(int), 1, file); + } + } } void saveWorldInternal(char *filename, EntityManager *eManager, WorldData *worldData) { - FILE * file = fopen(filename, "wb"); //TODO: should be checked - - int i, j; - - //write savefile version - int version = SAVE_VERSION; - fwrite(&version, sizeof(int), 1, file); - - // Inventory Data - fwrite(&eManager->nextInv, sizeof(s16), 1, file); // write amount of inventories. - for(i = 0; i < eManager->nextInv; ++i) { - saveInventory(&(eManager->invs[i]), eManager, file); - } - - // Entity Data - for(i = 0; i < 5; ++i) { //for every level (except dungeon of course) - int amount = calculateImportantEntites(eManager,i); - fwrite(&amount, sizeof(s16), 1, file); // read amount of entities in level. - for(j = 0; j < eManager->lastSlot[i]; ++j){ - if(!entityIsImportant(&eManager->entities[i][j])) continue; - - fwrite(&eManager->entities[i][j].type, sizeof(s16), 1, file); // write entity's type ID - fwrite(&eManager->entities[i][j].x, sizeof(s16), 1, file); // write entity's x coordinate - fwrite(&eManager->entities[i][j].y, sizeof(s16), 1, file); // write entity's y coordinate - switch(eManager->entities[i][j].type){ - case ENTITY_AIRWIZARD: - fwrite(&eManager->entities[i][j].wizard.health, sizeof(s16), 1, file); - break; - case ENTITY_SLIME: - fwrite(&eManager->entities[i][j].slime.health, sizeof(s16), 1, file); - fwrite(&eManager->entities[i][j].slime.lvl, sizeof(s8), 1, file); - break; - case ENTITY_ZOMBIE: + FILE * file = fopen(filename, "wb"); //TODO: should be checked + + int i, j; + + //write savefile version + int version = SAVE_VERSION; + fwrite(&version, sizeof(int), 1, file); + + // Inventory Data + fwrite(&eManager->nextInv, sizeof(s16), 1, file); // write amount of inventories. + for(i = 0; i < eManager->nextInv; ++i) { + saveInventory(&(eManager->invs[i]), eManager, file); + } + + // Entity Data + for(i = 0; i < 5; ++i) { //for every level (except dungeon of course) + int amount = calculateImportantEntites(eManager,i); + fwrite(&amount, sizeof(s16), 1, file); // read amount of entities in level. + for(j = 0; j < eManager->lastSlot[i]; ++j){ + if(!entityIsImportant(&eManager->entities[i][j])) continue; + + fwrite(&eManager->entities[i][j].type, sizeof(s16), 1, file); // write entity's type ID + fwrite(&eManager->entities[i][j].x, sizeof(s16), 1, file); // write entity's x coordinate + fwrite(&eManager->entities[i][j].y, sizeof(s16), 1, file); // write entity's y coordinate + switch(eManager->entities[i][j].type){ + case ENTITY_AIRWIZARD: + fwrite(&eManager->entities[i][j].wizard.health, sizeof(s16), 1, file); + break; + case ENTITY_SLIME: + fwrite(&eManager->entities[i][j].slime.health, sizeof(s16), 1, file); + fwrite(&eManager->entities[i][j].slime.lvl, sizeof(s8), 1, file); + break; + case ENTITY_ZOMBIE: case ENTITY_SKELETON: case ENTITY_KNIGHT: - fwrite(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file); - fwrite(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file); - break; - case ENTITY_ITEM: - fwrite(&eManager->entities[i][j].entityItem.item.id, sizeof(s16), 1, file); - fwrite(&eManager->entities[i][j].entityItem.item.countLevel, sizeof(s16), 1, file); - fwrite(&eManager->entities[i][j].entityItem.age, sizeof(s16), 1, file); - break; - case ENTITY_FURNITURE: - fwrite(&eManager->entities[i][j].entityFurniture.itemID, sizeof(s16), 1, file); - int invIndex = eManager->entities[i][j].entityFurniture.inv - eManager->invs; - fwrite(&invIndex, sizeof(int), 1, file); - break; + fwrite(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file); + fwrite(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file); + break; + case ENTITY_ITEM: + fwrite(&eManager->entities[i][j].entityItem.item.id, sizeof(s16), 1, file); + fwrite(&eManager->entities[i][j].entityItem.item.countLevel, sizeof(s16), 1, file); + fwrite(&eManager->entities[i][j].entityItem.age, sizeof(s16), 1, file); + break; + case ENTITY_FURNITURE: + fwrite(&eManager->entities[i][j].entityFurniture.itemID, sizeof(s16), 1, file); + int invIndex = eManager->entities[i][j].entityFurniture.inv - eManager->invs; + fwrite(&invIndex, sizeof(int), 1, file); + break; case ENTITY_PASSIVE: fwrite(&eManager->entities[i][j].passive.health, sizeof(s16), 1, file); - fwrite(&eManager->entities[i][j].passive.mtype, sizeof(u8), 1, file); - break; + 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; - case ENTITY_NPC: - fwrite(&eManager->entities[i][j].npc.type, sizeof(u8), 1, file); - break; - } - } - } - - // Day/season Data - fwrite(&worldData->daytime, sizeof(u16), 1, file); + fwrite(&eManager->entities[i][j].dragon.health, sizeof(s16), 1, file); + break; + case ENTITY_NPC: + fwrite(&eManager->entities[i][j].npc.type, sizeof(u8), 1, file); + break; + } + } + } + + // Day/season Data + fwrite(&worldData->daytime, sizeof(u16), 1, file); fwrite(&worldData->day, sizeof(int), 1, file); fwrite(&worldData->season, sizeof(u8), 1, file); - fwrite(&worldData->rain, sizeof(bool), 1, file); - - // Compass Data - fwrite(worldData->compassData, sizeof(u8), 6*3, file); //x,y of choosen stair and count per level - - // Map Data + fwrite(&worldData->rain, sizeof(bool), 1, file); + + // Compass Data + fwrite(worldData->compassData, sizeof(u8), 6*3, file); //x,y of choosen stair and count per level + + // Map Data //Don't write or load dungeon, so only first 5 levels not 6 - fwrite(worldData->map, sizeof(u8), 128*128*5, file); // Map Tile IDs, 128*128*5 bytes = 80KB - fwrite(worldData->data, sizeof(u8), 128*128*5, file); // Map Tile Data (Damage done to trees/rocks, age of wheat & saplings, etc). 80KB - - fclose(file); + fwrite(worldData->map, sizeof(u8), 128*128*5, file); // Map Tile IDs, 128*128*5 bytes = 80KB + fwrite(worldData->data, sizeof(u8), 128*128*5, file); // Map Tile Data (Damage done to trees/rocks, age of wheat & saplings, etc). 80KB + + fclose(file); } void savePlayerInternal(char *filename, PlayerData *player, EntityManager *eManager) { - FILE * file = fopen(filename, "wb"); //TODO: should be checked - - int i; - - //write savefile version - int version = SAVE_VERSION; - fwrite(&version, sizeof(int), 1, file); - - // basic player info - fwrite(&player->score, sizeof(int), 1, file); - fwrite(&player->isSpawned, sizeof(bool), 1, file); - fwrite(&player->entity.p.hasWonSaved, sizeof(bool), 1, file); - fwrite(&player->entity.p.health, sizeof(s16), 1, file); - fwrite(&player->entity.x, sizeof(s16), 1, file); - fwrite(&player->entity.y, sizeof(s16), 1, file); - fwrite(&player->entity.level, sizeof(s8), 1, file); - - saveInventory(&(player->inventory), eManager, file); - - // Sprite info - fwrite(&(player->sprite.choosen), sizeof(bool), 1, file); - fwrite(&(player->sprite.legs), sizeof(u8), 1, file); - fwrite(&(player->sprite.body), sizeof(u8), 1, file); - fwrite(&(player->sprite.arms), sizeof(u8), 1, file); - fwrite(&(player->sprite.head), sizeof(u8), 1, file); - fwrite(&(player->sprite.eyes), sizeof(u8), 1, file); - - // Minimap Data - fwrite(player->minimapData, sizeof(u8), 128*128, file); // Minimap, visibility data 16KB - - // Quest Data - fwrite(&(player->questManager.size), sizeof(int), 1, file); - for(i = 0; i < player->questManager.size; ++i) { - fwrite(&(player->questManager.questlines[i].currentQuest), sizeof(int), 1, file); - fwrite(&(player->questManager.questlines[i].currentQuestDone), sizeof(bool), 1, file); - } - - //Potion Data - fwrite(&UnderStrengthEffect, sizeof(bool), 1, file); - fwrite(&UnderSpeedEffect, sizeof(bool), 1, file); - fwrite(®ening, sizeof(bool), 1, file); - fwrite(&UnderSwimBreathEffect, sizeof(bool), 1, file); - fwrite(&player->entity.p.strengthTimer, sizeof(int), 1, file); - fwrite(&player->entity.p.speedTimer, sizeof(int), 1, file); - fwrite(&player->entity.p.swimBreathTimer, sizeof(int), 1, file); - fwrite(&player->entity.p.regenTimer, sizeof(int), 1, file); + FILE * file = fopen(filename, "wb"); //TODO: should be checked - fclose(file); + int i; + + //write savefile version + int version = SAVE_VERSION; + fwrite(&version, sizeof(int), 1, file); + + // basic player info + fwrite(&player->score, sizeof(int), 1, file); + fwrite(&player->isSpawned, sizeof(bool), 1, file); + fwrite(&player->entity.p.hasWonSaved, sizeof(bool), 1, file); + fwrite(&player->entity.p.health, sizeof(s16), 1, file); + fwrite(&player->entity.x, sizeof(s16), 1, file); + fwrite(&player->entity.y, sizeof(s16), 1, file); + fwrite(&player->entity.level, sizeof(s8), 1, file); + + saveInventory(&(player->inventory), eManager, file); + + // Sprite info + fwrite(&(player->sprite.choosen), sizeof(bool), 1, file); + fwrite(&(player->sprite.legs), sizeof(u8), 1, file); + fwrite(&(player->sprite.body), sizeof(u8), 1, file); + fwrite(&(player->sprite.arms), sizeof(u8), 1, file); + fwrite(&(player->sprite.head), sizeof(u8), 1, file); + fwrite(&(player->sprite.eyes), sizeof(u8), 1, file); + + // Minimap Data + fwrite(player->minimapData, sizeof(u8), 128*128, file); // Minimap, visibility data 16KB + + // Quest Data + fwrite(&(player->questManager.size), sizeof(int), 1, file); + for(i = 0; i < player->questManager.size; ++i) { + fwrite(&(player->questManager.questlines[i].currentQuest), sizeof(int), 1, file); + fwrite(&(player->questManager.questlines[i].currentQuestDone), sizeof(bool), 1, file); + } + + //Potion Data + fwrite(&UnderStrengthEffect, sizeof(bool), 1, file); + fwrite(&UnderSpeedEffect, sizeof(bool), 1, file); + fwrite(®ening, sizeof(bool), 1, file); + fwrite(&UnderSwimBreathEffect, sizeof(bool), 1, file); + fwrite(&player->entity.p.strengthTimer, sizeof(int), 1, file); + fwrite(&player->entity.p.speedTimer, sizeof(int), 1, file); + fwrite(&player->entity.p.swimBreathTimer, sizeof(int), 1, file); + fwrite(&player->entity.p.regenTimer, sizeof(int), 1, file); + + fclose(file); } //internal load methods void loadInventory(Inventory *inv, EntityManager *eManager, FILE *file) { - fread(&(inv->lastSlot), sizeof(s16), 1, file); // read amount of items in inventory; - for(int j = 0; j < inv->lastSlot; ++j) { - fread(&(inv->items[j].id), sizeof(s16), 1, file); // write ID of item - fread(&(inv->items[j].countLevel), sizeof(s16), 1, file); // write count/level of item - fread(&(inv->items[j].onlyOne), sizeof(bool), 1, file); - inv->items[j].invPtr = (int*)inv; // setup Inventory pointer - inv->items[j].slotNum = j; // setup slot number - if(inv->items[j].id == ITEM_CHEST){ // for chest item specifically. - int invIndex; - fread(&invIndex, sizeof(int), 1, file); - inv->items[j].chestPtr = (Inventory*)&eManager->invs[invIndex]; // setup chest inventory pointer. - } - } + fread(&(inv->lastSlot), sizeof(s16), 1, file); // read amount of items in inventory; + for(int j = 0; j < inv->lastSlot; ++j) { + fread(&(inv->items[j].id), sizeof(s16), 1, file); // write ID of item + fread(&(inv->items[j].countLevel), sizeof(s16), 1, file); // write count/level of item + fread(&(inv->items[j].onlyOne), sizeof(bool), 1, file); + inv->items[j].invPtr = (int*)inv; // setup Inventory pointer + inv->items[j].slotNum = j; // setup slot number + if(inv->items[j].id == ITEM_CHEST){ // for chest item specifically. + int invIndex; + fread(&invIndex, sizeof(int), 1, file); + inv->items[j].chestPtr = (Inventory*)&eManager->invs[invIndex]; // setup chest inventory pointer. + } + } } void loadWorldInternal(char *filename, EntityManager *eManager, WorldData *worldData) { - FILE * file = fopen(filename, "rb"); //TODO: should be checked - - int i, j; - - //read savefile version - int version; - fread(&version, sizeof(int), 1, file); - - // Inventory Data - fread(&eManager->nextInv, sizeof(s16), 1, file); - for(i = 0; i < eManager->nextInv; ++i) { - loadInventory(&(eManager->invs[i]), eManager, file); - } - - // Entity Data - for(i = 0; i < 5; ++i){ - fread(&eManager->lastSlot[i], sizeof(s16), 1, file); // read amount of entities in level. - for(j = 0; j < eManager->lastSlot[i]; ++j){ - fread(&eManager->entities[i][j].type, sizeof(s16), 1, file); // read entity's type ID - fread(&eManager->entities[i][j].x, sizeof(s16), 1, file); // read entity's x coordinate - fread(&eManager->entities[i][j].y, sizeof(s16), 1, file); // read entity's y coordinate - eManager->entities[i][j].slotNum = j; - switch(eManager->entities[i][j].type){ - case ENTITY_SMASHPARTICLE: - eManager->entities[i][j].level = i; - eManager->entities[i][j].smashParticle.age = 300; - eManager->entities[i][j].canPass = true; - break; - case ENTITY_TEXTPARTICLE: - eManager->entities[i][j].level = i; - eManager->entities[i][j].canPass = true; - eManager->entities[i][j].textParticle.age = 59; - eManager->entities[i][j].textParticle.text = NULL; - eManager->entities[i][j].textParticle.xx = eManager->entities[i][j].x; - eManager->entities[i][j].textParticle.yy = eManager->entities[i][j].y; - eManager->entities[i][j].textParticle.zz = 2; - eManager->entities[i][j].textParticle.xa = 0; - eManager->entities[i][j].textParticle.ya = 0; - eManager->entities[i][j].textParticle.za = 0; - break; - case ENTITY_SPARK: - eManager->entities[i][j].level = i; - eManager->entities[i][j].spark.age = 300; - break; - case ENTITY_AIRWIZARD: - fread(&eManager->entities[i][j].wizard.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].wizard.dir = 0; - eManager->entities[i][j].wizard.attackDelay = 0; - eManager->entities[i][j].wizard.attackTime = 0; - eManager->entities[i][j].wizard.attackType = 0; - eManager->entities[i][j].wizard.xa = 0; - eManager->entities[i][j].wizard.ya = 0; - eManager->entities[i][j].xr = 4; - eManager->entities[i][j].yr = 3; - eManager->entities[i][j].canPass = true; - break; - case ENTITY_SLIME: - fread(&eManager->entities[i][j].slime.health, sizeof(s16), 1, file); - fread(&eManager->entities[i][j].slime.lvl, sizeof(s8), 1, file); - eManager->entities[i][j].level = i; - eManager->entities[i][j].hurtTime = 0; - eManager->entities[i][j].xKnockback = 0; - eManager->entities[i][j].yKnockback = 0; - eManager->entities[i][j].slime.xa = 0; - eManager->entities[i][j].slime.ya = 0; - eManager->entities[i][j].slime.dir = 0; - eManager->entities[i][j].xr = 4; - eManager->entities[i][j].yr = 3; - eManager->entities[i][j].canPass = false; - switch(eManager->entities[i][j].slime.lvl){ - case 2: eManager->entities[i][j].slime.color = 0xFF8282CC; break; - case 3: eManager->entities[i][j].slime.color = 0xFFEFEFEF; break; - case 4: eManager->entities[i][j].slime.color = 0xFFAA6262; break; - default: eManager->entities[i][j].slime.color = 0xFF95DB95; break; - } - break; - case ENTITY_ZOMBIE: - fread(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file); - fread(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file); - eManager->entities[i][j].level = i; - eManager->entities[i][j].hurtTime = 0; - eManager->entities[i][j].xKnockback = 0; - eManager->entities[i][j].yKnockback = 0; - eManager->entities[i][j].hostile.dir = 0; - eManager->entities[i][j].xr = 4; - eManager->entities[i][j].yr = 3; - eManager->entities[i][j].canPass = false; - switch(eManager->entities[i][j].hostile.lvl){ - case 2: eManager->entities[i][j].hostile.color = 0xFF8282CC; break; - case 3: eManager->entities[i][j].hostile.color = 0xFFEFEFEF; break; - case 4: eManager->entities[i][j].hostile.color = 0xFFAA6262; break; - default: eManager->entities[i][j].hostile.color = 0xFF95DB95; break; - } - break; - case ENTITY_SKELETON: - fread(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file); - fread(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file); - eManager->entities[i][j].level = i; - eManager->entities[i][j].hurtTime = 0; - eManager->entities[i][j].xKnockback = 0; - eManager->entities[i][j].yKnockback = 0; - eManager->entities[i][j].hostile.dir = 0; - eManager->entities[i][j].hostile.randAttackTime = 0; - eManager->entities[i][j].xr = 4; - eManager->entities[i][j].yr = 3; - eManager->entities[i][j].canPass = false; - switch(eManager->entities[i][j].hostile.lvl){ - case 2: eManager->entities[i][j].hostile.color = 0xFFC4C4C4; break; - case 3: eManager->entities[i][j].hostile.color = 0xFFA0A0A0; break; - case 4: eManager->entities[i][j].hostile.color = 0xFF7A7A7A; break; - default: eManager->entities[i][j].hostile.color = 0xFFFFFFFF; break; - } - break; - case ENTITY_KNIGHT: - fread(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file); - fread(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file); - eManager->entities[i][j].level = i; - eManager->entities[i][j].hurtTime = 0; - eManager->entities[i][j].xKnockback = 0; - eManager->entities[i][j].yKnockback = 0; - eManager->entities[i][j].hostile.dir = 0; - eManager->entities[i][j].xr = 4; - eManager->entities[i][j].yr = 3; - eManager->entities[i][j].canPass = false; - switch(eManager->entities[i][j].hostile.lvl){ - case 2: eManager->entities[i][j].hostile.color = 0xFF0000C6; break; - case 3: eManager->entities[i][j].hostile.color = 0xFF00A3C6; break; - case 4: eManager->entities[i][j].hostile.color = 0xFF707070; break; - default: eManager->entities[i][j].hostile.color = 0xFFFFFFFF; break; - } - break; - case ENTITY_ITEM: - //eManager->entities[i][j].entityItem.item = newItem(0,0); - fread(&eManager->entities[i][j].entityItem.item.id, sizeof(s16), 1, file); - fread(&eManager->entities[i][j].entityItem.item.countLevel, sizeof(s16), 1, file); - fread(&eManager->entities[i][j].entityItem.age, sizeof(s16), 1, file); - eManager->entities[i][j].level = i; - eManager->entities[i][j].entityItem.age = 0; - eManager->entities[i][j].xr = 3; - eManager->entities[i][j].yr = 3; - eManager->entities[i][j].canPass = false; - eManager->entities[i][j].entityItem.xx = eManager->entities[i][j].x; - eManager->entities[i][j].entityItem.yy = eManager->entities[i][j].y; - eManager->entities[i][j].entityItem.zz = 2; - eManager->entities[i][j].entityItem.xa = 0; - eManager->entities[i][j].entityItem.ya = 0; - eManager->entities[i][j].entityItem.za = 0; - break; - case ENTITY_FURNITURE: - fread(&eManager->entities[i][j].entityFurniture.itemID, sizeof(s16), 1, file); - int invIndex; - fread(&invIndex, sizeof(int), 1, file); - eManager->entities[i][j].entityFurniture.inv = &eManager->invs[invIndex]; - eManager->entities[i][j].xr = 3; - eManager->entities[i][j].yr = 3; - eManager->entities[i][j].canPass = false; - if(eManager->entities[i][j].entityFurniture.itemID == ITEM_LANTERN) eManager->entities[i][j].entityFurniture.r = 8; - break; - case ENTITY_PASSIVE: - fread(&eManager->entities[i][j].passive.health, sizeof(s16), 1, file); - fread(&eManager->entities[i][j].passive.mtype, sizeof(u8), 1, file); - eManager->entities[i][j].level = i; - eManager->entities[i][j].hurtTime = 0; - eManager->entities[i][j].xKnockback = 0; - eManager->entities[i][j].yKnockback = 0; - eManager->entities[i][j].passive.dir = 0; - eManager->entities[i][j].xr = 4; - eManager->entities[i][j].yr = 3; - eManager->entities[i][j].canPass = false; - break; - case ENTITY_GLOWWORM: - eManager->entities[i][j].glowworm.xa = 0; - eManager->entities[i][j].glowworm.ya = 0; - eManager->entities[i][j].glowworm.randWalkTime = 0; - eManager->entities[i][j].glowworm.waitTime = 0; - break; - 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; - 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; - } - } - } - - // Day/season Data - fread(&worldData->daytime, sizeof(u16), 1, file); + FILE * file = fopen(filename, "rb"); //TODO: should be checked + + int i, j; + + //read savefile version + int version; + fread(&version, sizeof(int), 1, file); + + // Inventory Data + fread(&eManager->nextInv, sizeof(s16), 1, file); + for(i = 0; i < eManager->nextInv; ++i) { + loadInventory(&(eManager->invs[i]), eManager, file); + } + + // Entity Data + for(i = 0; i < 5; ++i){ + fread(&eManager->lastSlot[i], sizeof(s16), 1, file); // read amount of entities in level. + for(j = 0; j < eManager->lastSlot[i]; ++j){ + fread(&eManager->entities[i][j].type, sizeof(s16), 1, file); // read entity's type ID + fread(&eManager->entities[i][j].x, sizeof(s16), 1, file); // read entity's x coordinate + fread(&eManager->entities[i][j].y, sizeof(s16), 1, file); // read entity's y coordinate + eManager->entities[i][j].slotNum = j; + switch(eManager->entities[i][j].type){ + case ENTITY_SMASHPARTICLE: + eManager->entities[i][j].level = i; + eManager->entities[i][j].smashParticle.age = 300; + eManager->entities[i][j].canPass = true; + break; + case ENTITY_TEXTPARTICLE: + eManager->entities[i][j].level = i; + eManager->entities[i][j].canPass = true; + eManager->entities[i][j].textParticle.age = 59; + eManager->entities[i][j].textParticle.text = NULL; + eManager->entities[i][j].textParticle.xx = eManager->entities[i][j].x; + eManager->entities[i][j].textParticle.yy = eManager->entities[i][j].y; + eManager->entities[i][j].textParticle.zz = 2; + eManager->entities[i][j].textParticle.xa = 0; + eManager->entities[i][j].textParticle.ya = 0; + eManager->entities[i][j].textParticle.za = 0; + break; + case ENTITY_SPARK: + eManager->entities[i][j].level = i; + eManager->entities[i][j].spark.age = 300; + break; + case ENTITY_AIRWIZARD: + fread(&eManager->entities[i][j].wizard.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].wizard.dir = 0; + eManager->entities[i][j].wizard.attackDelay = 0; + eManager->entities[i][j].wizard.attackTime = 0; + eManager->entities[i][j].wizard.attackType = 0; + eManager->entities[i][j].wizard.xa = 0; + eManager->entities[i][j].wizard.ya = 0; + eManager->entities[i][j].xr = 4; + eManager->entities[i][j].yr = 3; + eManager->entities[i][j].canPass = true; + break; + case ENTITY_SLIME: + fread(&eManager->entities[i][j].slime.health, sizeof(s16), 1, file); + fread(&eManager->entities[i][j].slime.lvl, sizeof(s8), 1, file); + eManager->entities[i][j].level = i; + eManager->entities[i][j].hurtTime = 0; + eManager->entities[i][j].xKnockback = 0; + eManager->entities[i][j].yKnockback = 0; + eManager->entities[i][j].slime.xa = 0; + eManager->entities[i][j].slime.ya = 0; + eManager->entities[i][j].slime.dir = 0; + eManager->entities[i][j].xr = 4; + eManager->entities[i][j].yr = 3; + eManager->entities[i][j].canPass = false; + switch(eManager->entities[i][j].slime.lvl){ + case 2: eManager->entities[i][j].slime.color = 0xFF8282CC; break; + case 3: eManager->entities[i][j].slime.color = 0xFFEFEFEF; break; + case 4: eManager->entities[i][j].slime.color = 0xFFAA6262; break; + default: eManager->entities[i][j].slime.color = 0xFF95DB95; break; + } + break; + case ENTITY_ZOMBIE: + fread(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file); + fread(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file); + eManager->entities[i][j].level = i; + eManager->entities[i][j].hurtTime = 0; + eManager->entities[i][j].xKnockback = 0; + eManager->entities[i][j].yKnockback = 0; + eManager->entities[i][j].hostile.dir = 0; + eManager->entities[i][j].xr = 4; + eManager->entities[i][j].yr = 3; + eManager->entities[i][j].canPass = false; + switch(eManager->entities[i][j].hostile.lvl){ + case 2: eManager->entities[i][j].hostile.color = 0xFF8282CC; break; + case 3: eManager->entities[i][j].hostile.color = 0xFFEFEFEF; break; + case 4: eManager->entities[i][j].hostile.color = 0xFFAA6262; break; + default: eManager->entities[i][j].hostile.color = 0xFF95DB95; break; + } + break; + case ENTITY_SKELETON: + fread(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file); + fread(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file); + eManager->entities[i][j].level = i; + eManager->entities[i][j].hurtTime = 0; + eManager->entities[i][j].xKnockback = 0; + eManager->entities[i][j].yKnockback = 0; + eManager->entities[i][j].hostile.dir = 0; + eManager->entities[i][j].hostile.randAttackTime = 0; + eManager->entities[i][j].xr = 4; + eManager->entities[i][j].yr = 3; + eManager->entities[i][j].canPass = false; + switch(eManager->entities[i][j].hostile.lvl){ + case 2: eManager->entities[i][j].hostile.color = 0xFFC4C4C4; break; + case 3: eManager->entities[i][j].hostile.color = 0xFFA0A0A0; break; + case 4: eManager->entities[i][j].hostile.color = 0xFF7A7A7A; break; + default: eManager->entities[i][j].hostile.color = 0xFFFFFFFF; break; + } + break; + case ENTITY_KNIGHT: + fread(&eManager->entities[i][j].hostile.health, sizeof(s16), 1, file); + fread(&eManager->entities[i][j].hostile.lvl, sizeof(s8), 1, file); + eManager->entities[i][j].level = i; + eManager->entities[i][j].hurtTime = 0; + eManager->entities[i][j].xKnockback = 0; + eManager->entities[i][j].yKnockback = 0; + eManager->entities[i][j].hostile.dir = 0; + eManager->entities[i][j].xr = 4; + eManager->entities[i][j].yr = 3; + eManager->entities[i][j].canPass = false; + switch(eManager->entities[i][j].hostile.lvl){ + case 2: eManager->entities[i][j].hostile.color = 0xFF0000C6; break; + case 3: eManager->entities[i][j].hostile.color = 0xFF00A3C6; break; + case 4: eManager->entities[i][j].hostile.color = 0xFF707070; break; + default: eManager->entities[i][j].hostile.color = 0xFFFFFFFF; break; + } + break; + case ENTITY_ITEM: + //eManager->entities[i][j].entityItem.item = newItem(0,0); + fread(&eManager->entities[i][j].entityItem.item.id, sizeof(s16), 1, file); + fread(&eManager->entities[i][j].entityItem.item.countLevel, sizeof(s16), 1, file); + fread(&eManager->entities[i][j].entityItem.age, sizeof(s16), 1, file); + eManager->entities[i][j].level = i; + eManager->entities[i][j].entityItem.age = 0; + eManager->entities[i][j].xr = 3; + eManager->entities[i][j].yr = 3; + eManager->entities[i][j].canPass = false; + eManager->entities[i][j].entityItem.xx = eManager->entities[i][j].x; + eManager->entities[i][j].entityItem.yy = eManager->entities[i][j].y; + eManager->entities[i][j].entityItem.zz = 2; + eManager->entities[i][j].entityItem.xa = 0; + eManager->entities[i][j].entityItem.ya = 0; + eManager->entities[i][j].entityItem.za = 0; + break; + case ENTITY_FURNITURE: + fread(&eManager->entities[i][j].entityFurniture.itemID, sizeof(s16), 1, file); + int invIndex; + fread(&invIndex, sizeof(int), 1, file); + eManager->entities[i][j].entityFurniture.inv = &eManager->invs[invIndex]; + eManager->entities[i][j].xr = 3; + eManager->entities[i][j].yr = 3; + eManager->entities[i][j].canPass = false; + if(eManager->entities[i][j].entityFurniture.itemID == ITEM_LANTERN) eManager->entities[i][j].entityFurniture.r = 8; + break; + case ENTITY_PASSIVE: + fread(&eManager->entities[i][j].passive.health, sizeof(s16), 1, file); + fread(&eManager->entities[i][j].passive.mtype, sizeof(u8), 1, file); + eManager->entities[i][j].level = i; + eManager->entities[i][j].hurtTime = 0; + eManager->entities[i][j].xKnockback = 0; + eManager->entities[i][j].yKnockback = 0; + eManager->entities[i][j].passive.dir = 0; + eManager->entities[i][j].xr = 4; + eManager->entities[i][j].yr = 3; + eManager->entities[i][j].canPass = false; + break; + case ENTITY_GLOWWORM: + eManager->entities[i][j].glowworm.xa = 0; + eManager->entities[i][j].glowworm.ya = 0; + eManager->entities[i][j].glowworm.randWalkTime = 0; + eManager->entities[i][j].glowworm.waitTime = 0; + break; + 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; + 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; + } + } + } + + // Day/season Data + fread(&worldData->daytime, sizeof(u16), 1, file); fread(&worldData->day, sizeof(int), 1, file); fread(&worldData->season, sizeof(u8), 1, file); - fread(&worldData->rain, sizeof(bool), 1, file); - - // Compass Data - fread(worldData->compassData, sizeof(u8), 6*3, file); //x,y of choosen stair and count per level - - // Map Data + fread(&worldData->rain, sizeof(bool), 1, file); + + // Compass Data + fread(worldData->compassData, sizeof(u8), 6*3, file); //x,y of choosen stair and count per level + + // Map Data //Don't write or load dungeon, so only first 5 levels not 6 - fread(worldData->map, sizeof(u8), 128*128*5, file); // Map Tile IDs, 128*128*5 bytes = 80KB - fread(worldData->data, sizeof(u8), 128*128*5, file); // Map Tile Data (Damage done to trees/rocks, age of wheat & saplings, etc). 80KB - - fclose(file); + fread(worldData->map, sizeof(u8), 128*128*5, file); // Map Tile IDs, 128*128*5 bytes = 80KB + fread(worldData->data, sizeof(u8), 128*128*5, file); // Map Tile Data (Damage done to trees/rocks, age of wheat & saplings, etc). 80KB + + fclose(file); } void loadPlayerInternal(char *filename, PlayerData *player, EntityManager *eManager) { - FILE * file = fopen(filename, "rb"); //TODO: should be checked - - int i; - - //read savefile version - int version; - fread(&version, sizeof(int), 1, file); - - // basic player info - fread(&player->score, sizeof(int), 1, file); - fread(&player->isSpawned, sizeof(bool), 1, file); - fread(&player->entity.p.hasWonSaved, sizeof(bool), 1, file); - fread(&player->entity.p.health, sizeof(s16), 1, file); - fread(&player->entity.x, sizeof(s16), 1, file); - fread(&player->entity.y, sizeof(s16), 1, file); - fread(&player->entity.level, sizeof(s8), 1, file); - - loadInventory(&(player->inventory), eManager, file); - - // Sprite info - fread(&(player->sprite.choosen), sizeof(bool), 1, file); - fread(&(player->sprite.legs), sizeof(u8), 1, file); - fread(&(player->sprite.body), sizeof(u8), 1, file); - fread(&(player->sprite.arms), sizeof(u8), 1, file); - fread(&(player->sprite.head), sizeof(u8), 1, file); - fread(&(player->sprite.eyes), sizeof(u8), 1, file); - - // Minimap Data - fread(player->minimapData, sizeof(u8), 128*128, file); // Minimap, visibility data 16KB - - // Quest Data - fread(&(player->questManager.size), sizeof(int), 1, file); - for(i = 0; i < player->questManager.size; ++i) { - fread(&(player->questManager.questlines[i].currentQuest), sizeof(int), 1, file); - fread(&(player->questManager.questlines[i].currentQuestDone), sizeof(bool), 1, file); - } - - //Potion Data - fread(&UnderStrengthEffect, sizeof(bool), 1, file); - fread(&UnderSpeedEffect, sizeof(bool), 1, file); - fread(®ening, sizeof(bool), 1, file); - fread(&UnderSwimBreathEffect, sizeof(bool), 1, file); - fread(&player->entity.p.strengthTimer, sizeof(int), 1, file); - fread(&player->entity.p.speedTimer, sizeof(int), 1, file); - fread(&player->entity.p.swimBreathTimer, sizeof(int), 1, file); - fread(&player->entity.p.regenTimer, sizeof(int), 1, file); - - fclose(file); + FILE * file = fopen(filename, "rb"); //TODO: should be checked + + int i; + + //read savefile version + int version; + fread(&version, sizeof(int), 1, file); + + // basic player info + fread(&player->score, sizeof(int), 1, file); + fread(&player->isSpawned, sizeof(bool), 1, file); + fread(&player->entity.p.hasWonSaved, sizeof(bool), 1, file); + fread(&player->entity.p.health, sizeof(s16), 1, file); + fread(&player->entity.x, sizeof(s16), 1, file); + fread(&player->entity.y, sizeof(s16), 1, file); + fread(&player->entity.level, sizeof(s8), 1, file); + + loadInventory(&(player->inventory), eManager, file); + + // Sprite info + fread(&(player->sprite.choosen), sizeof(bool), 1, file); + fread(&(player->sprite.legs), sizeof(u8), 1, file); + fread(&(player->sprite.body), sizeof(u8), 1, file); + fread(&(player->sprite.arms), sizeof(u8), 1, file); + fread(&(player->sprite.head), sizeof(u8), 1, file); + fread(&(player->sprite.eyes), sizeof(u8), 1, file); + + // Minimap Data + fread(player->minimapData, sizeof(u8), 128*128, file); // Minimap, visibility data 16KB + + // Quest Data + fread(&(player->questManager.size), sizeof(int), 1, file); + for(i = 0; i < player->questManager.size; ++i) { + fread(&(player->questManager.questlines[i].currentQuest), sizeof(int), 1, file); + fread(&(player->questManager.questlines[i].currentQuestDone), sizeof(bool), 1, file); + } + + //Potion Data + fread(&UnderStrengthEffect, sizeof(bool), 1, file); + fread(&UnderSpeedEffect, sizeof(bool), 1, file); + fread(®ening, sizeof(bool), 1, file); + fread(&UnderSwimBreathEffect, sizeof(bool), 1, file); + fread(&player->entity.p.strengthTimer, sizeof(int), 1, file); + fread(&player->entity.p.speedTimer, sizeof(int), 1, file); + fread(&player->entity.p.swimBreathTimer, sizeof(int), 1, file); + fread(&player->entity.p.regenTimer, sizeof(int), 1, file); + + fclose(file); } bool saveWorld(char *filename, EntityManager *eManager, WorldData *worldData, PlayerData *players, int playerCount) { - //check if old save file exists - bool exists = false; - FILE *testFile = fopen(filename, "rb"); - if(testFile) { - fclose(testFile); - exists = true; - } - - saveTrackFileReset(); - - if(exists) { - //create backup copy - char *filenameBackup = malloc(sizeof(filename)+4+1); - if(filenameBackup==NULL) { - return false; - } - strcpy(filenameBackup, filename); - strcat(filenameBackup, ".bak"); - if(!saveFileCopy(filenameBackup, filename)) { - return false; - } - - //extract files and keep track of references - if(unzipAndLoad(filename, &saveTrackFile, SAVE_COMMENT, ZIPHELPER_KEEP_FILES)!=0) { - saveDeleteTrackedFiles(); - return false; - } - - remove(filename); - } - - //save world data - saveWorldInternal("main.wld", eManager, worldData); - saveTrackFile("main.wld"); - - //save player data of active players - for(int i=0; isize = ftell(file)/2; - fseek(file, 0, SEEK_SET); - snd->buffer = linearAlloc(snd->size*sizeof(u16)); - fread(snd->buffer, 1, snd->size, file); - } - fclose(file); + FILE *file = fopen(filename, "rb"); + if(file != NULL){ + fseek(file, 0, SEEK_END); + snd->size = ftell(file)/2; + fseek(file, 0, SEEK_SET); + snd->buffer = linearAlloc(snd->size*sizeof(u16)); + fread(snd->buffer, 1, snd->size, file); + } + fclose(file); } void playSound(Sound snd){ - csndPlaySound(8, SOUND_FORMAT_16BIT | SOUND_ONE_SHOT, 44100, 1, 0, snd.buffer, snd.buffer, snd.size); + csndPlaySound(8, SOUND_FORMAT_16BIT | SOUND_ONE_SHOT, 44100, 1, 0, snd.buffer, snd.buffer, snd.size); } void playSoundPositioned(Sound snd, s8 level, int x, int y) { - if(level != soundListenerLevel) return; - int xd = soundListenerX - x; - int yd = soundListenerY - y; - if (xd * xd + yd * yd > 80 * 80) return; - - csndPlaySound(8, SOUND_FORMAT_16BIT | SOUND_ONE_SHOT, 44100, 1, 0, snd.buffer, snd.buffer, snd.size); + if(level != soundListenerLevel) return; + int xd = soundListenerX - x; + int yd = soundListenerY - y; + if (xd * xd + yd * yd > 80 * 80) return; + + csndPlaySound(8, SOUND_FORMAT_16BIT | SOUND_ONE_SHOT, 44100, 1, 0, snd.buffer, snd.buffer, snd.size); } void setListenerPosition(s8 level, int x, int y) { - soundListenerLevel = level; - soundListenerX = x; - soundListenerY = y; + soundListenerLevel = level; + soundListenerX = x; + soundListenerY = y; } void playMusic(Sound *snd){ - static Sound *lastSnd; - if(lastSnd==snd) return; - lastSnd = snd; - - csndPlaySound(10, SOUND_FORMAT_16BIT | SOUND_REPEAT, 44100, 1, 0, snd->buffer, snd->buffer, snd->size); + static Sound *lastSnd; + if(lastSnd==snd) return; + lastSnd = snd; + + csndPlaySound(10, SOUND_FORMAT_16BIT | SOUND_REPEAT, 44100, 1, 0, snd->buffer, snd->buffer, snd->size); } void stopMusic() { CSND_SetPlayState(8, 0); CSND_SetPlayState(10, 0); - csndExecCmds(true); + csndExecCmds(true); } void updateMusic(int lvl, int time) { @@ -77,7 +77,7 @@ void loadSounds() { loadSound(&snd_pickup, "romfs:/resources/pickup.raw"); loadSound(&snd_bossdeath, "romfs:/resources/bossdeath.raw"); loadSound(&snd_craft, "romfs:/resources/craft.raw"); - + loadSound(&music_menu, "romfs:/resources/music/menu.raw"); loadSound(&music_floor0, "romfs:/resources/music/floor0.raw"); loadSound(&music_floor1, "romfs:/resources/music/floor1.raw"); @@ -87,18 +87,18 @@ void loadSounds() { } void freeSounds(){ - linearFree(snd_playerHurt.buffer); - linearFree(snd_playerDeath.buffer); - linearFree(snd_monsterHurt.buffer); - linearFree(snd_test.buffer); - linearFree(snd_pickup.buffer); - linearFree(snd_bossdeath.buffer); - linearFree(snd_craft.buffer); - + linearFree(snd_playerHurt.buffer); + linearFree(snd_playerDeath.buffer); + linearFree(snd_monsterHurt.buffer); + linearFree(snd_test.buffer); + linearFree(snd_pickup.buffer); + linearFree(snd_bossdeath.buffer); + linearFree(snd_craft.buffer); + linearFree(music_menu.buffer); linearFree(music_floor0.buffer); linearFree(music_floor1.buffer); linearFree(music_floor1_night.buffer); linearFree(music_floor23.buffer); linearFree(music_floor4.buffer); -} \ No newline at end of file +} diff --git a/source/Sound.h b/source/Sound.h index 3e9b7a2..b85193b 100755 --- a/source/Sound.h +++ b/source/Sound.h @@ -6,8 +6,8 @@ typedef struct { - u32 size; - u8 * buffer; + u32 size; + u8 * buffer; } Sound; void loadSound(Sound * snd, char * filename); @@ -36,4 +36,4 @@ Sound music_floor0; Sound music_floor1; Sound music_floor1_night; Sound music_floor23; -Sound music_floor4; \ No newline at end of file +Sound music_floor4; diff --git a/source/Synchronizer.c b/source/Synchronizer.c index 74d3fbb..546a4d2 100644 --- a/source/Synchronizer.c +++ b/source/Synchronizer.c @@ -21,204 +21,204 @@ void synchronizerSendLocalInputs(); int synchronizerGetTurnIndex(u32 turn); void synchronizerInit(int seed, int initPlayerCount, int initPlayerLocalID) { - synchronizerLocalTurn = 0; - synchronizerNextSeed = seed; - playerCount = initPlayerCount; - playerLocalID = initPlayerLocalID; - syncTickCount = 0; - - //reset player turn states (e.g. is turn data recieved), first turn needs to happen with no inputs - for(int i=0; i send to server - sendStartReadyPacket(playerLocalID); + //we are ready when we recieved all uids + for(int i=0; i send to server + sendStartReadyPacket(playerLocalID); } void synchronizerSetPlayerReady(int playerID) { - players[playerID].ready = true; + players[playerID].ready = true; } bool synchronizerAllReady() { - for(int i=0; i1) { - size_t size = writeInputPacket(networkWriteBuffer, &localInputs, playerLocalID, synchronizerLocalTurn); - networkSend(networkWriteBuffer, size); - } + //scan local inputs + hidScanInput(); + tickKeys(&localInputs, hidKeysHeld(), hidKeysDown()); + + //store local input in nextInput + players[playerLocalID].nextInputs[synchronizerGetTurnIndex(synchronizerLocalTurn)] = localInputs; + players[playerLocalID].nextTurnReady[synchronizerGetTurnIndex(synchronizerLocalTurn)] = true; + + //send local input + if(playerCount>1) { + size_t size = writeInputPacket(networkWriteBuffer, &localInputs, playerLocalID, synchronizerLocalTurn); + networkSend(networkWriteBuffer, size); + } } void synchronizerOnInputPacket(u8 playerID, u32 turnNumber, void *data, size_t dataSize) { - if(turnNumber>=synchronizerLocalTurn && turnNumber=synchronizerLocalTurn && turnNumber 0) { - fwrite(read_buffer, error, 1, out); // You should check return of fwrite... - } - } while (error > 0); + free(buffer); + } - fclose(out); - - //run callback - if((*fileCallback)(filename) != 0) { - free(read_buffer); - unzClose(zipfile); - remove(filename); - return 10; // Error: Callback error - } - - if(keepFiles==ZIPHELPER_CLEANUP_FILES) { - remove(filename); - } - } + // Buffer to hold data read from the zip file. + void *read_buffer = malloc(READ_SIZE); + if(read_buffer==NULL) { + // Error: Could not allocate read buffer + return 5; + } - unzCloseCurrentFile(zipfile); + // Loop to extract all files + uLong i; + for (i = 0; i < global_info.number_entry; ++i) { + // Get info about current file. + unz_file_info file_info; + char filename[MAX_FILENAME]; + if (unzGetCurrentFileInfo(zipfile, &file_info, filename, MAX_FILENAME, NULL, 0, NULL, 0 ) != UNZ_OK) { + free(read_buffer); + unzClose(zipfile); + return 6; // Error: Could not read file info + } - // Go the the next entry listed in the zip file. - if (( i+1 ) < global_info.number_entry) { - if (unzGoToNextFile( zipfile ) != UNZ_OK) { - free(read_buffer); - unzClose(zipfile); - return 11; - } - } - } - - free(read_buffer); - unzClose(zipfile); - - return 0; + // Check if this entry is NOT a directory or file. + const size_t filename_length = strlen(filename); + if (filename[ filename_length-1 ] != dir_delimter){ + if (unzOpenCurrentFile( zipfile ) != UNZ_OK) { + free(read_buffer); + unzClose(zipfile); + return 7; + } + + // Open a file to write out the data. + FILE * out = fopen(filename, "wb"); + if (out == NULL) { + free(read_buffer); + unzCloseCurrentFile(zipfile); + unzClose(zipfile); + return 8; + } + + int error = UNZ_OK; + do { + error = unzReadCurrentFile(zipfile, read_buffer, READ_SIZE); + if ( error < 0 ) { + //printf("error %d\n", error); + free(read_buffer); + unzCloseCurrentFile(zipfile); + unzClose(zipfile); + fclose(out); + remove(filename); + return 9; + } + + // Write data to file. + if (error > 0) { + fwrite(read_buffer, error, 1, out); // You should check return of fwrite... + } + } while (error > 0); + + fclose(out); + + //run callback + if((*fileCallback)(filename) != 0) { + free(read_buffer); + unzClose(zipfile); + remove(filename); + return 10; // Error: Callback error + } + + if(keepFiles==ZIPHELPER_CLEANUP_FILES) { + remove(filename); + } + } + + unzCloseCurrentFile(zipfile); + + // Go the the next entry listed in the zip file. + if (( i+1 ) < global_info.number_entry) { + if (unzGoToNextFile( zipfile ) != UNZ_OK) { + free(read_buffer); + unzClose(zipfile); + return 11; + } + } + } + + free(read_buffer); + unzClose(zipfile); + + return 0; } int zipFiles(char *filename, char **files, int fileCount, int mode, char *comment) { - // Set mode - int zipMode = mode==ZIPHELPER_ADD ? APPEND_STATUS_ADDINZIP : APPEND_STATUS_CREATE; - FILE *testFile = fopen(filename, "r"); - if(testFile!=NULL) { - fclose(testFile); - } else { - zipMode = APPEND_STATUS_CREATE; - } - - // Open the zip file - zipFile *zipfile = zipOpen(filename, zipMode); - if (zipfile == NULL) return 1; // Error: ZipFile could not be opened. - - // Buffer to hold data read from the files. - void *read_buffer = malloc(READ_SIZE); - if(read_buffer==NULL) { - // Error: Could not allocate read buffer - return 2; - } - - // Loop all files to add - for(int i = 0; i < fileCount; i++) { - // Open a zipfile to write out the data. - if (zipOpenNewFileInZip(zipfile, files[i], NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) { - free(read_buffer); - zipClose(zipfile, ""); - return 3; - } - - // Open a file to read the data. - FILE *in = fopen(files[i], "rb"); - if (in == NULL) { - free(read_buffer); - zipCloseFileInZip(zipfile); - zipClose(zipfile, ""); - return 4; - } + // Set mode + int zipMode = mode==ZIPHELPER_ADD ? APPEND_STATUS_ADDINZIP : APPEND_STATUS_CREATE; + FILE *testFile = fopen(filename, "r"); + if(testFile!=NULL) { + fclose(testFile); + } else { + zipMode = APPEND_STATUS_CREATE; + } - size_t size; - do - { - size = fread(read_buffer, 1, READ_SIZE, in); - - - if(size0) { - //write data to zip - if (zipWriteInFileInZip(zipfile, read_buffer, size) != ZIP_OK) { - //printf("error %d\n", error); - free(read_buffer); - zipCloseFileInZip(zipfile); - zipClose(zipfile, ""); - fclose(in); - return 6; - } - } - } while (size > 0); + // Open the zip file + zipFile *zipfile = zipOpen(filename, zipMode); + if (zipfile == NULL) return 1; // Error: ZipFile could not be opened. - fclose(in); + // Buffer to hold data read from the files. + void *read_buffer = malloc(READ_SIZE); + if(read_buffer==NULL) { + // Error: Could not allocate read buffer + return 2; + } - zipCloseFileInZip(zipfile); - } - - free(read_buffer); - zipClose(zipfile, comment); - - return 0; + // Loop all files to add + for(int i = 0; i < fileCount; i++) { + // Open a zipfile to write out the data. + if (zipOpenNewFileInZip(zipfile, files[i], NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) { + free(read_buffer); + zipClose(zipfile, ""); + return 3; + } + + // Open a file to read the data. + FILE *in = fopen(files[i], "rb"); + if (in == NULL) { + free(read_buffer); + zipCloseFileInZip(zipfile); + zipClose(zipfile, ""); + return 4; + } + + size_t size; + do + { + size = fread(read_buffer, 1, READ_SIZE, in); + + + if(size0) { + //write data to zip + if (zipWriteInFileInZip(zipfile, read_buffer, size) != ZIP_OK) { + //printf("error %d\n", error); + free(read_buffer); + zipCloseFileInZip(zipfile); + zipClose(zipfile, ""); + fclose(in); + return 6; + } + } + } while (size > 0); + + fclose(in); + + zipCloseFileInZip(zipfile); + } + + free(read_buffer); + zipClose(zipfile, comment); + + return 0; } diff --git a/source/main.c b/source/main.c index 4c0afb1..345ee41 100755 --- a/source/main.c +++ b/source/main.c @@ -1,7 +1,7 @@ #include <3ds.h> #include #include -#include +#include #include #include #include @@ -31,23 +31,23 @@ void setupGame() { synchronizerInit(rand(), 1, 0); synchronizerSetPlayerUID(0, localUID); synchronizerStart(); - + initGame = 0; } void setupGameServer() { size_t size; - + networkHostStopConnections(); - + networkStart(); - + //send start info (seed) size = writeStartPacket(networkWriteBuffer, rand()); networkSend(networkWriteBuffer, size); processPacket(networkWriteBuffer, size); networkSendWaitFlush(); - + //send save file if loading FILE *file = fopen(currentFileName, "rb"); if(file!=NULL) { @@ -55,12 +55,12 @@ void setupGameServer() { networkSendWaitFlush(); fclose(file); } - + //send start command size = writeStartRequestPacket(networkWriteBuffer); networkSend(networkWriteBuffer, size); processPacket(networkWriteBuffer, size); - + initMPGame = 0; } @@ -68,15 +68,15 @@ void setupBGMap() { // Reset entity manager. memset(&eManager, 0, sizeof(eManager)); sf2d_set_clear_color(0xFF6C6D82); - + srand(time(NULL)); createAndValidateTopMap(128, 128, 1, worldData.map[1], worldData.data[1]); - + // Reset entity manager. memset(&eManager, 0, sizeof(eManager)); sf2d_set_clear_color(0xFF6C6D82); - + initBGMap = 0; } static void task_apt_hook(APT_HookType hook, void* param) { @@ -111,49 +111,49 @@ int main() { sf2d_init(); csndInit(); networkInit(); - + srand(time(NULL)); - + //load or create localUID if ((file = fopen("m3ds_uid.bin", "rb"))) { fread(&localUID, sizeof(u32), 1, file); fclose(file); } else { localUID = (((u32) (rand()%256))<<24) | (((u32) (rand()%256))<<16) | (((u32) (rand()%256))<<8) | (((u32) (rand()%256))); - + if ((file = fopen("m3ds_uid.bin", "wb"))) { fwrite(&localUID, sizeof(u32), 1, file); fclose(file); } } - + noItem = newItem(ITEM_NULL, 0); - + initMenus(); currentMenu = MENU_TITLE; currentSelection = 0; quitGame = false; initBGMap = 1; - icons = sfil_load_PNG_buffer(icons2_png, SF2D_PLACE_RAM); + icons = sfil_load_PNG_buffer(icons_png, SF2D_PLACE_RAM); playerSprites = sfil_load_PNG_buffer(player_png, SF2D_PLACE_RAM); font = sfil_load_PNG_buffer(Font_png, SF2D_PLACE_RAM); bottombg = sfil_load_PNG_buffer(bottombg_png, SF2D_PLACE_RAM); loadSounds(); playMusic(&music_menu); - + bakeLights(); - + int i; for (i = 0; i < 6; ++i) { minimap[i] = sf2d_create_texture(128, 128, TEXFMT_RGBA8, SF2D_PLACE_RAM); sf2d_texture_tile32(minimap[i]); } - + reloadColors(); - + sf2d_set_vblank_wait(true); sf2d_set_clear_color(0xFF); @@ -163,18 +163,18 @@ int main() { localInputs.k_down.input = KEY_DDOWN | KEY_CPAD_DOWN | KEY_CSTICK_DOWN; localInputs.k_left.input = KEY_DLEFT | KEY_CPAD_LEFT | KEY_CSTICK_LEFT; localInputs.k_right.input = KEY_DRIGHT | KEY_CPAD_RIGHT | KEY_CSTICK_RIGHT; - localInputs.k_attack.input = KEY_A | KEY_B | KEY_L | KEY_ZR; - localInputs.k_menu.input = KEY_X | KEY_Y | KEY_R | KEY_ZL; + localInputs.k_attack.input = KEY_A | KEY_B; + localInputs.k_menu.input = KEY_X | KEY_Y; localInputs.k_pause.input = KEY_START; localInputs.k_accept.input = KEY_A; localInputs.k_decline.input = KEY_B; localInputs.k_delete.input = KEY_X; - localInputs.k_menuNext.input = KEY_R; - localInputs.k_menuPrev.input = KEY_L; + localInputs.k_menuNext.input = KEY_R | KEY_ZR; + localInputs.k_menuPrev.input = KEY_L | KEY_ZL; /* If btnSave exists, then use that. */ if ((file = fopen("btnSave.bin", "rb"))) { - fread(&(localInputs.k_up.input), sizeof(int), 1, file); + fread(&(localInputs.k_up.input), sizeof(int), 1, file); fread(&(localInputs.k_down.input), sizeof(int), 1, file); fread(&(localInputs.k_left.input), sizeof(int), 1, file); fread(&(localInputs.k_right.input), sizeof(int), 1, file); @@ -188,15 +188,15 @@ int main() { fread(&(localInputs.k_menuPrev.input), sizeof(int), 1, file); fclose(file); } - + /* If lastTP exists, then use that. */ if ((file = fopen("lastTP.bin", "r"))) { char fnbuf[256]; fgets(fnbuf, 256, file); // get directory to texturepack - loadTexturePack(fnbuf); + loadTexturePack(fnbuf); fclose(file); } - + initPlayers(); initRecipes(); initTrades(); @@ -208,7 +208,7 @@ int main() { if (initGame > 0 && --initGame==0) setupGame(); if (initMPGame > 0 && --initMPGame==0) setupGameServer(); if (initBGMap > 0 && --initBGMap==0) setupBGMap(); - + if (currentMenu == MENU_NONE) { tickGame(); renderGame(); @@ -216,14 +216,14 @@ int main() { //input scanning ingame is handled by the synchronizer hidScanInput(); tickKeys(&localInputs, hidKeysHeld(), hidKeysDown()); - + tickMenu(currentMenu); renderMenu(currentMenu, xscr, yscr); } sf2d_swapbuffers(); } - + stopMusic(); freeTrades(); diff --git a/source/texturepack.c b/source/texturepack.c index e2a18ff..9398c10 100755 --- a/source/texturepack.c +++ b/source/texturepack.c @@ -10,91 +10,91 @@ bool texturepackUseDefaultFont = true; bool texturepackUseDefaultBottom = true; void toLowerString(char * str){ - int i; - for (i = 0; str[i] != '\0'; i++)str[i] = (char)tolower((unsigned char)str[i]); + int i; + for (i = 0; str[i] != '\0'; i++)str[i] = (char)tolower((unsigned char)str[i]); } int getTexturePackComment(char * filename, char * cmmtBuf){ - // Open the zip file - unzFile *zipfile = unzOpen(filename); - if ( zipfile == NULL ) return 1; // Error: ZipFile could not be opened. - - // Get info about the zip file - unz_global_info global_info; - if (unzGetGlobalInfo(zipfile, &global_info ) != UNZ_OK ) - { - unzClose( zipfile ); - return 2; // Error: Could not read global info - } - - unzGetGlobalComment(zipfile, cmmtBuf, 58); + // Open the zip file + unzFile *zipfile = unzOpen(filename); + if ( zipfile == NULL ) return 1; // Error: ZipFile could not be opened. - unzClose( zipfile ); + // Get info about the zip file + unz_global_info global_info; + if (unzGetGlobalInfo(zipfile, &global_info ) != UNZ_OK ) + { + unzClose( zipfile ); + return 2; // Error: Could not read global info + } - return 0; + unzGetGlobalComment(zipfile, cmmtBuf, 58); + + unzClose( zipfile ); + + return 0; } int loadTexture(char * filename) { - char lowerFilename[MAX_FILENAME]; - strcpy(lowerFilename,filename); - toLowerString(lowerFilename); - - if(strcmp(lowerFilename, "icons.png") == 0){ - if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){ - return 0; - } - - icons = sfil_load_PNG_file(filename, SF2D_PLACE_RAM); - reloadColors(); - - texturepackUseDefaultIcons = false; - } else if(strcmp(lowerFilename, "player.png") == 0){ - if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){ - return 0; - } - - playerSprites = sfil_load_PNG_file(filename, SF2D_PLACE_RAM); - - texturepackUseDefaultPlayer = false; - } else if(strcmp(lowerFilename, "font.png") == 0){ - if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){ - return 0; - } - - font = sfil_load_PNG_file(filename, SF2D_PLACE_RAM); - - texturepackUseDefaultFont = false; - } else if(strcmp(lowerFilename, "bottombg.png") == 0){ - if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){ - return 0; - } - - bottombg = sfil_load_PNG_file(filename, SF2D_PLACE_RAM); - - texturepackUseDefaultBottom = false; - } - - return 0; + char lowerFilename[MAX_FILENAME]; + strcpy(lowerFilename,filename); + toLowerString(lowerFilename); + + if(strcmp(lowerFilename, "icons.png") == 0){ + if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){ + return 0; + } + + icons = sfil_load_PNG_file(filename, SF2D_PLACE_RAM); + reloadColors(); + + texturepackUseDefaultIcons = false; + } else if(strcmp(lowerFilename, "player.png") == 0){ + if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){ + return 0; + } + + playerSprites = sfil_load_PNG_file(filename, SF2D_PLACE_RAM); + + texturepackUseDefaultPlayer = false; + } else if(strcmp(lowerFilename, "font.png") == 0){ + if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){ + return 0; + } + + font = sfil_load_PNG_file(filename, SF2D_PLACE_RAM); + + texturepackUseDefaultFont = false; + } else if(strcmp(lowerFilename, "bottombg.png") == 0){ + if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){ + return 0; + } + + bottombg = sfil_load_PNG_file(filename, SF2D_PLACE_RAM); + + texturepackUseDefaultBottom = false; + } + + return 0; } int loadTexturePack(char * filename) { - texturepackUseDefaultIcons = true; - texturepackUseDefaultPlayer = true; - texturepackUseDefaultFont = true; - texturepackUseDefaultBottom = true; + texturepackUseDefaultIcons = true; + texturepackUseDefaultPlayer = true; + texturepackUseDefaultFont = true; + texturepackUseDefaultBottom = true; - if(unzipAndLoad(filename, &loadTexture, NULL, ZIPHELPER_CLEANUP_FILES)!=0) { - return 1; - } - - if(texturepackUseDefaultIcons){ - icons = sfil_load_PNG_buffer(icons2_png, SF2D_PLACE_RAM); - reloadColors(); - } - if(texturepackUseDefaultPlayer) playerSprites = sfil_load_PNG_buffer(player_png, SF2D_PLACE_RAM); - if(texturepackUseDefaultFont) font = sfil_load_PNG_buffer(Font_png, SF2D_PLACE_RAM); - if(texturepackUseDefaultBottom) bottombg = sfil_load_PNG_buffer(bottombg_png, SF2D_PLACE_RAM); + if(unzipAndLoad(filename, &loadTexture, NULL, ZIPHELPER_CLEANUP_FILES)!=0) { + return 1; + } - return 0; + if(texturepackUseDefaultIcons){ + icons = sfil_load_PNG_buffer(icons_png, SF2D_PLACE_RAM); + reloadColors(); + } + if(texturepackUseDefaultPlayer) playerSprites = sfil_load_PNG_buffer(player_png, SF2D_PLACE_RAM); + if(texturepackUseDefaultFont) font = sfil_load_PNG_buffer(Font_png, SF2D_PLACE_RAM); + if(texturepackUseDefaultBottom) bottombg = sfil_load_PNG_buffer(bottombg_png, SF2D_PLACE_RAM); + + return 0; }