Cleaning up stuff
This commit is contained in:
parent
5423be67ca
commit
a5ea06a928
44 changed files with 7329 additions and 7432 deletions
BIN
3dslink.exe
BIN
3dslink.exe
Binary file not shown.
BIN
3dstool.exe
BIN
3dstool.exe
Binary file not shown.
BIN
bannertool.exe
BIN
bannertool.exe
Binary file not shown.
|
@ -2,9 +2,9 @@
|
||||||
echo Building 3DSX/ELF/SMDH...
|
echo Building 3DSX/ELF/SMDH...
|
||||||
make
|
make
|
||||||
echo Creating banner...
|
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...
|
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...
|
echo Creating ROMFS...
|
||||||
3dstool -cvtf romfs icons-banners/romfs.bin --romfs-dir romfs/
|
3dstool -cvtf romfs icons-banners/romfs.bin --romfs-dir romfs/
|
||||||
echo Creating CIA...
|
echo Creating CIA...
|
||||||
|
@ -14,4 +14,4 @@ makerom -f cci -o result/Minicraft3DS.3ds -DAPP_ENCRYPTED=true -rsf icons-banner
|
||||||
echo Cleaning Up...
|
echo Cleaning Up...
|
||||||
del /s result\Minicraft3DS.elf
|
del /s result\Minicraft3DS.elf
|
||||||
del /s result\Minicraft3DS.smdh
|
del /s result\Minicraft3DS.smdh
|
||||||
pause
|
pause
|
||||||
|
|
BIN
ctrtool.exe
BIN
ctrtool.exe
Binary file not shown.
BIN
data/icons.png
Executable file
BIN
data/icons.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
data/icons2.png
BIN
data/icons2.png
Binary file not shown.
Before Width: | Height: | Size: 37 KiB |
|
@ -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/
|
|
|
@ -1,4 +0,0 @@
|
||||||
theme: jekyll-theme-cayman
|
|
||||||
title: Minicraft3DS
|
|
||||||
description: A 2D Homebrew for 3DS
|
|
||||||
show_downloads: true
|
|
BIN
makerom.exe
BIN
makerom.exe
Binary file not shown.
|
@ -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
|
|
|
@ -1,132 +1,132 @@
|
||||||
#include "Crafting.h"
|
#include "Crafting.h"
|
||||||
|
|
||||||
void cloneRecipeManager(RecipeManager *from, RecipeManager *to) {
|
void cloneRecipeManager(RecipeManager *from, RecipeManager *to) {
|
||||||
//free old manager recipes
|
//free old manager recipes
|
||||||
free(to->recipes);
|
free(to->recipes);
|
||||||
|
|
||||||
//copy over recipes
|
//copy over recipes
|
||||||
to->size = from->size;
|
to->size = from->size;
|
||||||
to->recipes = (Recipe*)malloc(sizeof(Recipe) * to->size);
|
to->recipes = (Recipe*)malloc(sizeof(Recipe) * to->size);
|
||||||
memcpy(to->recipes, from->recipes, sizeof(Recipe) * to->size);
|
memcpy(to->recipes, from->recipes, sizeof(Recipe) * to->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkCanCraftRecipes(RecipeManager * rm, Inventory * inv){
|
void checkCanCraftRecipes(RecipeManager * rm, Inventory * inv){
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < rm->size; i++){
|
for(i = 0; i < rm->size; i++){
|
||||||
rm->recipes[i].canCraft = true;
|
rm->recipes[i].canCraft = true;
|
||||||
for(j = 0; j < rm->recipes[i].numOfCosts; j++){
|
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){
|
if(countItemInv(rm->recipes[i].costs[j].costItem,0,inv) < rm->recipes[i].costs[j].costAmount){
|
||||||
rm->recipes[i].canCraft = false;
|
rm->recipes[i].canCraft = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int compareCanCraft(const void * ra, const void * rb) {
|
int compareCanCraft(const void * ra, const void * rb) {
|
||||||
Recipe* r1 = (Recipe*)ra;
|
Recipe* r1 = (Recipe*)ra;
|
||||||
Recipe* r2 = (Recipe*)rb;
|
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;
|
if (!r1->canCraft && r2->canCraft) return 1;
|
||||||
return r1->order - r2->order; // Needed for stable sorting.
|
return r1->order - r2->order; // Needed for stable sorting.
|
||||||
}
|
}
|
||||||
|
|
||||||
void sortRecipes(RecipeManager * rm){
|
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){
|
void deductCost(Cost c, Inventory * inv){
|
||||||
Item* item = getItemFromInventory(c.costItem, inv);
|
Item* item = getItemFromInventory(c.costItem, inv);
|
||||||
if(!item->onlyOne){
|
if(!item->onlyOne){
|
||||||
item->countLevel -= c.costAmount;
|
item->countLevel -= c.costAmount;
|
||||||
if(item->countLevel < 1) removeItemFromInventory(item->slotNum, inv);
|
if(item->countLevel < 1) removeItemFromInventory(item->slotNum, inv);
|
||||||
} else {
|
} else {
|
||||||
removeItemFromInventory(item->slotNum, inv);
|
removeItemFromInventory(item->slotNum, inv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool craftItem(RecipeManager * rm, Recipe* r, Inventory* inv){
|
bool craftItem(RecipeManager * rm, Recipe* r, Inventory* inv){
|
||||||
if(r->canCraft){
|
if(r->canCraft){
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<r->numOfCosts;++i) deductCost(r->costs[i], inv);
|
for(i=0;i<r->numOfCosts;++i) deductCost(r->costs[i], inv);
|
||||||
Item item = newItem(r->itemResult,r->itemAmountLevel);
|
Item item = newItem(r->itemResult,r->itemAmountLevel);
|
||||||
|
|
||||||
if(!item.onlyOne && countItemInv(item.id,item.countLevel,inv) > 0){
|
if(!item.onlyOne && countItemInv(item.id,item.countLevel,inv) > 0){
|
||||||
getItemFromInventory(item.id, inv)->countLevel += r->itemAmountLevel;
|
getItemFromInventory(item.id, inv)->countLevel += r->itemAmountLevel;
|
||||||
} else{
|
} else{
|
||||||
pushItemToInventoryFront(item, inv);
|
pushItemToInventoryFront(item, inv);
|
||||||
}
|
}
|
||||||
checkCanCraftRecipes(rm, inv);
|
checkCanCraftRecipes(rm, inv);
|
||||||
sortRecipes(rm);
|
sortRecipes(rm);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cost newCost(int i, int c){
|
Cost newCost(int i, int c){
|
||||||
Cost nc;
|
Cost nc;
|
||||||
nc.costItem = i;
|
nc.costItem = i;
|
||||||
nc.costAmount = c;
|
nc.costAmount = c;
|
||||||
return nc;
|
return nc;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 curPlace = 0;
|
u8 curPlace = 0;
|
||||||
Recipe defineRecipe(int item, int amountOrLevel, int numArgs, ...){
|
Recipe defineRecipe(int item, int amountOrLevel, int numArgs, ...){
|
||||||
Recipe r;
|
Recipe r;
|
||||||
r.itemResult = item;
|
r.itemResult = item;
|
||||||
r.itemAmountLevel = amountOrLevel;
|
r.itemAmountLevel = amountOrLevel;
|
||||||
r.numOfCosts = numArgs;
|
r.numOfCosts = numArgs;
|
||||||
int i;
|
int i;
|
||||||
va_list al;
|
va_list al;
|
||||||
numArgs <<= 1; // Did this to get rid of a warning.
|
numArgs <<= 1; // Did this to get rid of a warning.
|
||||||
va_start(al,numArgs);
|
va_start(al,numArgs);
|
||||||
for(i=0;i<r.numOfCosts;++i) r.costs[i] = newCost(va_arg(al,int), va_arg(al,int));
|
for(i=0;i<r.numOfCosts;++i) r.costs[i] = newCost(va_arg(al,int), va_arg(al,int));
|
||||||
va_end(al);
|
va_end(al);
|
||||||
r.order = curPlace;
|
r.order = curPlace;
|
||||||
curPlace++;
|
curPlace++;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initRecipes(){
|
void initRecipes(){
|
||||||
|
|
||||||
curPlace = 0;
|
curPlace = 0;
|
||||||
workbenchRecipes.size = 22;
|
workbenchRecipes.size = 22;
|
||||||
workbenchRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (workbenchRecipes.size));
|
workbenchRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (workbenchRecipes.size));
|
||||||
workbenchRecipes.recipes[0] = defineRecipe(ITEM_WORKBENCH,1,1,ITEM_WOOD,20);
|
workbenchRecipes.recipes[0] = defineRecipe(ITEM_WORKBENCH,1,1,ITEM_WOOD,20);
|
||||||
workbenchRecipes.recipes[1] = defineRecipe(ITEM_FURNACE,1,1,ITEM_STONE,20);
|
workbenchRecipes.recipes[1] = defineRecipe(ITEM_FURNACE,1,1,ITEM_STONE,20);
|
||||||
workbenchRecipes.recipes[2] = defineRecipe(ITEM_OVEN,1,1,ITEM_STONE,20);
|
workbenchRecipes.recipes[2] = defineRecipe(ITEM_OVEN,1,1,ITEM_STONE,20);
|
||||||
workbenchRecipes.recipes[3] = defineRecipe(ITEM_CHEST,1,1,ITEM_WOOD,20);
|
workbenchRecipes.recipes[3] = defineRecipe(ITEM_CHEST,1,1,ITEM_WOOD,20);
|
||||||
workbenchRecipes.recipes[4] = defineRecipe(ITEM_ANVIL,1,1,ITEM_IRONINGOT,5);
|
workbenchRecipes.recipes[4] = defineRecipe(ITEM_ANVIL,1,1,ITEM_IRONINGOT,5);
|
||||||
workbenchRecipes.recipes[5] = defineRecipe(ITEM_LANTERN,1,3,ITEM_WOOD,5,ITEM_SLIME,10,ITEM_GLASS,4);
|
workbenchRecipes.recipes[5] = defineRecipe(ITEM_LANTERN,1,3,ITEM_WOOD,5,ITEM_SLIME,10,ITEM_GLASS,4);
|
||||||
workbenchRecipes.recipes[6] = defineRecipe(ITEM_LOOM,1,2,ITEM_WOOD,10,ITEM_WOOL,5);
|
workbenchRecipes.recipes[6] = defineRecipe(ITEM_LOOM,1,2,ITEM_WOOD,10,ITEM_WOOL,5);
|
||||||
workbenchRecipes.recipes[7] = defineRecipe(TOOL_SWORD,0,1,ITEM_WOOD,5);
|
workbenchRecipes.recipes[7] = defineRecipe(TOOL_SWORD,0,1,ITEM_WOOD,5);
|
||||||
workbenchRecipes.recipes[8] = defineRecipe(TOOL_AXE,0,1,ITEM_WOOD,5);
|
workbenchRecipes.recipes[8] = defineRecipe(TOOL_AXE,0,1,ITEM_WOOD,5);
|
||||||
workbenchRecipes.recipes[9] = defineRecipe(TOOL_HOE,0,1,ITEM_WOOD,5);
|
workbenchRecipes.recipes[9] = defineRecipe(TOOL_HOE,0,1,ITEM_WOOD,5);
|
||||||
workbenchRecipes.recipes[10] = defineRecipe(TOOL_PICKAXE,0,1,ITEM_WOOD,5);
|
workbenchRecipes.recipes[10] = defineRecipe(TOOL_PICKAXE,0,1,ITEM_WOOD,5);
|
||||||
workbenchRecipes.recipes[11] = defineRecipe(TOOL_SHOVEL,0,1,ITEM_WOOD,5);
|
workbenchRecipes.recipes[11] = defineRecipe(TOOL_SHOVEL,0,1,ITEM_WOOD,5);
|
||||||
workbenchRecipes.recipes[12] = defineRecipe(TOOL_BOW,0,2,ITEM_WOOD,10,ITEM_STRING,1);
|
workbenchRecipes.recipes[12] = defineRecipe(TOOL_BOW,0,2,ITEM_WOOD,10,ITEM_STRING,1);
|
||||||
workbenchRecipes.recipes[13] = defineRecipe(ITEM_ARROW_WOOD,1,2,ITEM_WOOD,2,ITEM_STRING,1);
|
workbenchRecipes.recipes[13] = defineRecipe(ITEM_ARROW_WOOD,1,2,ITEM_WOOD,2,ITEM_STRING,1);
|
||||||
workbenchRecipes.recipes[14] = defineRecipe(TOOL_SWORD,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
workbenchRecipes.recipes[14] = defineRecipe(TOOL_SWORD,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||||
workbenchRecipes.recipes[15] = defineRecipe(TOOL_AXE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
workbenchRecipes.recipes[15] = defineRecipe(TOOL_AXE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||||
workbenchRecipes.recipes[16] = defineRecipe(TOOL_HOE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
workbenchRecipes.recipes[16] = defineRecipe(TOOL_HOE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||||
workbenchRecipes.recipes[17] = defineRecipe(TOOL_PICKAXE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
workbenchRecipes.recipes[17] = defineRecipe(TOOL_PICKAXE,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||||
workbenchRecipes.recipes[18] = defineRecipe(TOOL_SHOVEL,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
workbenchRecipes.recipes[18] = defineRecipe(TOOL_SHOVEL,1,2,ITEM_WOOD,5,ITEM_STONE,5);
|
||||||
workbenchRecipes.recipes[19] = defineRecipe(ITEM_ARROW_STONE,1,3,ITEM_WOOD,1,ITEM_STONE,1,ITEM_STRING,1);
|
workbenchRecipes.recipes[19] = defineRecipe(ITEM_ARROW_STONE,1,3,ITEM_WOOD,1,ITEM_STONE,1,ITEM_STRING,1);
|
||||||
workbenchRecipes.recipes[20] = defineRecipe(ITEM_WALL_WOOD,1,1,ITEM_WOOD,4);
|
workbenchRecipes.recipes[20] = defineRecipe(ITEM_WALL_WOOD,1,1,ITEM_WOOD,4);
|
||||||
workbenchRecipes.recipes[21] = defineRecipe(ITEM_WALL_STONE,1,1,ITEM_STONE,4);
|
workbenchRecipes.recipes[21] = defineRecipe(ITEM_WALL_STONE,1,1,ITEM_STONE,4);
|
||||||
|
|
||||||
anvilRecipes.size = 18;
|
anvilRecipes.size = 18;
|
||||||
anvilRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (anvilRecipes.size));
|
anvilRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (anvilRecipes.size));
|
||||||
anvilRecipes.recipes[0] = defineRecipe(TOOL_SWORD,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
anvilRecipes.recipes[0] = defineRecipe(TOOL_SWORD,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||||
anvilRecipes.recipes[1] = defineRecipe(TOOL_AXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
anvilRecipes.recipes[1] = defineRecipe(TOOL_AXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||||
anvilRecipes.recipes[2] = defineRecipe(TOOL_HOE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
anvilRecipes.recipes[2] = defineRecipe(TOOL_HOE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||||
anvilRecipes.recipes[3] = defineRecipe(TOOL_PICKAXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
anvilRecipes.recipes[3] = defineRecipe(TOOL_PICKAXE,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||||
anvilRecipes.recipes[4] = defineRecipe(TOOL_SHOVEL,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
anvilRecipes.recipes[4] = defineRecipe(TOOL_SHOVEL,2,2,ITEM_WOOD,5,ITEM_IRONINGOT,5);
|
||||||
anvilRecipes.recipes[5] = defineRecipe(ITEM_ARROW_IRON,1,3,ITEM_WOOD,1,ITEM_IRONINGOT,1,ITEM_STRING,1);
|
anvilRecipes.recipes[5] = defineRecipe(ITEM_ARROW_IRON,1,3,ITEM_WOOD,1,ITEM_IRONINGOT,1,ITEM_STRING,1);
|
||||||
anvilRecipes.recipes[6] = defineRecipe(TOOL_SWORD,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
anvilRecipes.recipes[6] = defineRecipe(TOOL_SWORD,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||||
anvilRecipes.recipes[7] = defineRecipe(TOOL_AXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
anvilRecipes.recipes[7] = defineRecipe(TOOL_AXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||||
anvilRecipes.recipes[8] = defineRecipe(TOOL_HOE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
anvilRecipes.recipes[8] = defineRecipe(TOOL_HOE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||||
anvilRecipes.recipes[9] = defineRecipe(TOOL_PICKAXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
anvilRecipes.recipes[9] = defineRecipe(TOOL_PICKAXE,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||||
anvilRecipes.recipes[10] = defineRecipe(TOOL_SHOVEL,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
anvilRecipes.recipes[10] = defineRecipe(TOOL_SHOVEL,3,2,ITEM_WOOD,5,ITEM_GOLDINGOT,5);
|
||||||
anvilRecipes.recipes[11] = defineRecipe(ITEM_ARROW_GOLD,1,3,ITEM_WOOD,1,ITEM_GOLDINGOT,1,ITEM_STRING,1);
|
anvilRecipes.recipes[11] = defineRecipe(ITEM_ARROW_GOLD,1,3,ITEM_WOOD,1,ITEM_GOLDINGOT,1,ITEM_STRING,1);
|
||||||
anvilRecipes.recipes[12] = defineRecipe(TOOL_BUCKET,0,1,ITEM_IRONINGOT,10);
|
anvilRecipes.recipes[12] = defineRecipe(TOOL_BUCKET,0,1,ITEM_IRONINGOT,10);
|
||||||
anvilRecipes.recipes[13] = defineRecipe(ITEM_ENCHANTER,1,3,ITEM_WOOD,10,ITEM_GOLDINGOT,10,ITEM_GEM,20);
|
anvilRecipes.recipes[13] = defineRecipe(ITEM_ENCHANTER,1,3,ITEM_WOOD,10,ITEM_GOLDINGOT,10,ITEM_GEM,20);
|
||||||
|
@ -134,36 +134,36 @@ void initRecipes(){
|
||||||
anvilRecipes.recipes[15] = defineRecipe(ITEM_WALL_GOLD,1,1,ITEM_GOLDINGOT,2);
|
anvilRecipes.recipes[15] = defineRecipe(ITEM_WALL_GOLD,1,1,ITEM_GOLDINGOT,2);
|
||||||
anvilRecipes.recipes[16] = defineRecipe(ITEM_COIN,3,1,ITEM_IRONINGOT,1);
|
anvilRecipes.recipes[16] = defineRecipe(ITEM_COIN,3,1,ITEM_IRONINGOT,1);
|
||||||
anvilRecipes.recipes[17] = defineRecipe(ITEM_POTION_MAKER,1,3,ITEM_IRONINGOT,5,ITEM_GOLDINGOT,25,ITEM_GEM,5);
|
anvilRecipes.recipes[17] = defineRecipe(ITEM_POTION_MAKER,1,3,ITEM_IRONINGOT,5,ITEM_GOLDINGOT,25,ITEM_GEM,5);
|
||||||
|
|
||||||
furnaceRecipes.size = 3;
|
furnaceRecipes.size = 3;
|
||||||
furnaceRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (furnaceRecipes.size));
|
furnaceRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (furnaceRecipes.size));
|
||||||
furnaceRecipes.recipes[0] = defineRecipe(ITEM_IRONINGOT,1,2,ITEM_IRONORE,4,ITEM_COAL,1);
|
furnaceRecipes.recipes[0] = defineRecipe(ITEM_IRONINGOT,1,2,ITEM_IRONORE,4,ITEM_COAL,1);
|
||||||
furnaceRecipes.recipes[1] = defineRecipe(ITEM_GOLDINGOT,1,2,ITEM_GOLDORE,4,ITEM_COAL,1);
|
furnaceRecipes.recipes[1] = defineRecipe(ITEM_GOLDINGOT,1,2,ITEM_GOLDORE,4,ITEM_COAL,1);
|
||||||
furnaceRecipes.recipes[2] = defineRecipe(ITEM_GLASS,1,2,ITEM_SAND,4,ITEM_COAL,1);
|
furnaceRecipes.recipes[2] = defineRecipe(ITEM_GLASS,1,2,ITEM_SAND,4,ITEM_COAL,1);
|
||||||
|
|
||||||
ovenRecipes.size = 3;
|
ovenRecipes.size = 3;
|
||||||
ovenRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (ovenRecipes.size));
|
ovenRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (ovenRecipes.size));
|
||||||
ovenRecipes.recipes[0] = defineRecipe(ITEM_BREAD,1,1,ITEM_WHEAT,4);
|
ovenRecipes.recipes[0] = defineRecipe(ITEM_BREAD,1,1,ITEM_WHEAT,4);
|
||||||
ovenRecipes.recipes[1] = defineRecipe(ITEM_PORK_COOKED,1,2,ITEM_PORK_RAW,1,ITEM_COAL,1);
|
ovenRecipes.recipes[1] = defineRecipe(ITEM_PORK_COOKED,1,2,ITEM_PORK_RAW,1,ITEM_COAL,1);
|
||||||
ovenRecipes.recipes[2] = defineRecipe(ITEM_BEEF_COOKED,1,2,ITEM_BEEF_RAW,1,ITEM_COAL,1);
|
ovenRecipes.recipes[2] = defineRecipe(ITEM_BEEF_COOKED,1,2,ITEM_BEEF_RAW,1,ITEM_COAL,1);
|
||||||
|
|
||||||
loomRecipes.size = 1;
|
loomRecipes.size = 1;
|
||||||
loomRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (loomRecipes.size));
|
loomRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (loomRecipes.size));
|
||||||
loomRecipes.recipes[0] = defineRecipe(ITEM_STRING,1,1,ITEM_WOOL,1);
|
loomRecipes.recipes[0] = defineRecipe(ITEM_STRING,1,1,ITEM_WOOL,1);
|
||||||
|
|
||||||
enchanterRecipes.size = 8;
|
enchanterRecipes.size = 8;
|
||||||
enchanterRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (enchanterRecipes.size));
|
enchanterRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (enchanterRecipes.size));
|
||||||
enchanterRecipes.recipes[0] = defineRecipe(TOOL_SWORD,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
enchanterRecipes.recipes[0] = defineRecipe(TOOL_SWORD,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||||
enchanterRecipes.recipes[1] = defineRecipe(TOOL_AXE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
enchanterRecipes.recipes[1] = defineRecipe(TOOL_AXE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||||
enchanterRecipes.recipes[2] = defineRecipe(TOOL_HOE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
enchanterRecipes.recipes[2] = defineRecipe(TOOL_HOE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||||
enchanterRecipes.recipes[3] = defineRecipe(TOOL_PICKAXE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
enchanterRecipes.recipes[3] = defineRecipe(TOOL_PICKAXE,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||||
enchanterRecipes.recipes[4] = defineRecipe(TOOL_SHOVEL,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
enchanterRecipes.recipes[4] = defineRecipe(TOOL_SHOVEL,4,2,ITEM_WOOD,5,ITEM_GEM,50);
|
||||||
enchanterRecipes.recipes[5] = defineRecipe(ITEM_ARROW_GEM,1,3,ITEM_WOOD,1,ITEM_GEM,3,ITEM_STRING,1);
|
enchanterRecipes.recipes[5] = defineRecipe(ITEM_ARROW_GEM,1,3,ITEM_WOOD,1,ITEM_GEM,3,ITEM_STRING,1);
|
||||||
enchanterRecipes.recipes[6] = defineRecipe(ITEM_WALL_GEM,1,1,ITEM_GEM,10);
|
enchanterRecipes.recipes[6] = defineRecipe(ITEM_WALL_GEM,1,1,ITEM_GEM,10);
|
||||||
enchanterRecipes.recipes[7] = defineRecipe(ITEM_GOLD_APPLE,1,2,ITEM_APPLE,1,ITEM_GOLDINGOT,15);
|
enchanterRecipes.recipes[7] = defineRecipe(ITEM_GOLD_APPLE,1,2,ITEM_APPLE,1,ITEM_GOLDINGOT,15);
|
||||||
|
|
||||||
potionMakerRecipes.size = 4;
|
potionMakerRecipes.size = 4;
|
||||||
potionMakerRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (potionMakerRecipes.size));
|
potionMakerRecipes.recipes = (Recipe*)malloc(sizeof(Recipe) * (potionMakerRecipes.size));
|
||||||
potionMakerRecipes.recipes[0] = defineRecipe(ITEM_STRENGTH_POTION,1,3,ITEM_GOLD_APPLE,1,ITEM_GLASS,10,ITEM_IRONINGOT,10);
|
potionMakerRecipes.recipes[0] = defineRecipe(ITEM_STRENGTH_POTION,1,3,ITEM_GOLD_APPLE,1,ITEM_GLASS,10,ITEM_IRONINGOT,10);
|
||||||
potionMakerRecipes.recipes[1] = defineRecipe(ITEM_SPEED_POTION,1,4,ITEM_GEM,2,ITEM_GLASS,10,ITEM_IRONINGOT,10, ITEM_GOLDINGOT,15);
|
potionMakerRecipes.recipes[1] = defineRecipe(ITEM_SPEED_POTION,1,4,ITEM_GEM,2,ITEM_GLASS,10,ITEM_IRONINGOT,10, ITEM_GOLDINGOT,15);
|
||||||
potionMakerRecipes.recipes[2] = defineRecipe(ITEM_REGEN_POTION,1,3,ITEM_GOLD_APPLE,2,ITEM_GLASS,10,ITEM_GEM,10);
|
potionMakerRecipes.recipes[2] = defineRecipe(ITEM_REGEN_POTION,1,3,ITEM_GOLD_APPLE,2,ITEM_GLASS,10,ITEM_GEM,10);
|
||||||
|
@ -172,10 +172,10 @@ void initRecipes(){
|
||||||
|
|
||||||
/* Free up allocated memory */
|
/* Free up allocated memory */
|
||||||
void freeRecipes(){
|
void freeRecipes(){
|
||||||
free(workbenchRecipes.recipes);
|
free(workbenchRecipes.recipes);
|
||||||
free(ovenRecipes.recipes);
|
free(ovenRecipes.recipes);
|
||||||
free(furnaceRecipes.recipes);
|
free(furnaceRecipes.recipes);
|
||||||
free(anvilRecipes.recipes);
|
free(anvilRecipes.recipes);
|
||||||
free(loomRecipes.recipes);
|
free(loomRecipes.recipes);
|
||||||
free(enchanterRecipes.recipes);
|
free(enchanterRecipes.recipes);
|
||||||
free(potionMakerRecipes.recipes);
|
free(potionMakerRecipes.recipes);
|
||||||
|
|
|
@ -3,22 +3,22 @@
|
||||||
#include "Item.h"
|
#include "Item.h"
|
||||||
|
|
||||||
typedef struct _recipecost {
|
typedef struct _recipecost {
|
||||||
int costItem;
|
int costItem;
|
||||||
int costAmount;
|
int costAmount;
|
||||||
} Cost;
|
} Cost;
|
||||||
|
|
||||||
typedef struct _recipe {
|
typedef struct _recipe {
|
||||||
bool canCraft;
|
bool canCraft;
|
||||||
int itemResult;
|
int itemResult;
|
||||||
int itemAmountLevel;
|
int itemAmountLevel;
|
||||||
s8 numOfCosts;
|
s8 numOfCosts;
|
||||||
Cost costs[6]; // Up to 6 items for costs
|
Cost costs[6]; // Up to 6 items for costs
|
||||||
u8 order; // Used for stable sorting.
|
u8 order; // Used for stable sorting.
|
||||||
} Recipe;
|
} Recipe;
|
||||||
|
|
||||||
typedef struct _recipeManager {
|
typedef struct _recipeManager {
|
||||||
int size;
|
int size;
|
||||||
Recipe * recipes;
|
Recipe * recipes;
|
||||||
} RecipeManager;
|
} RecipeManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
496
source/Entity.c
496
source/Entity.c
|
@ -3,361 +3,361 @@
|
||||||
#include "Synchronizer.h"
|
#include "Synchronizer.h"
|
||||||
|
|
||||||
Entity newItemEntity(Item item, int x, int y, int level){
|
Entity newItemEntity(Item item, int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_ITEM;
|
e.type = ENTITY_ITEM;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.entityItem.age = 0;
|
e.entityItem.age = 0;
|
||||||
e.entityItem.item = item;
|
e.entityItem.item = item;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.xr = 3;
|
e.xr = 3;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
|
|
||||||
e.entityItem.xx = x;
|
e.entityItem.xx = x;
|
||||||
e.entityItem.yy = y;
|
e.entityItem.yy = y;
|
||||||
e.entityItem.zz = 2;
|
e.entityItem.zz = 2;
|
||||||
e.entityItem.xa = gaussrand(false) * 0.1;
|
e.entityItem.xa = gaussrand(false) * 0.1;
|
||||||
e.entityItem.ya = gaussrand(false) * 0.1;
|
e.entityItem.ya = gaussrand(false) * 0.1;
|
||||||
e.entityItem.za = ((float)rand() / RAND_MAX) * 0.45 + 1;
|
e.entityItem.za = ((float)rand() / RAND_MAX) * 0.45 + 1;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void assignInventory(Entity* e){
|
void assignInventory(Entity* e){
|
||||||
if(eManager.nextInv > 300) return;
|
if(eManager.nextInv > 300) return;
|
||||||
e->entityFurniture.inv = &eManager.invs[eManager.nextInv];
|
e->entityFurniture.inv = &eManager.invs[eManager.nextInv];
|
||||||
eManager.nextInv++;
|
eManager.nextInv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newFurnitureEntity(int itemID,Inventory * invPtr, int x, int y, int level){
|
Entity newFurnitureEntity(int itemID,Inventory * invPtr, int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_FURNITURE;
|
e.type = ENTITY_FURNITURE;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.xr = 3;
|
e.xr = 3;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.entityFurniture.itemID = itemID;
|
e.entityFurniture.itemID = itemID;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
if(itemID == ITEM_LANTERN) e.entityFurniture.r = 8;
|
if(itemID == ITEM_LANTERN) e.entityFurniture.r = 8;
|
||||||
else if(itemID == ITEM_CHEST){
|
else if(itemID == ITEM_CHEST){
|
||||||
if(invPtr == NULL)assignInventory(&e);
|
if(invPtr == NULL)assignInventory(&e);
|
||||||
else e.entityFurniture.inv = invPtr;
|
else e.entityFurniture.inv = invPtr;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newPassiveEntity(int type, int x, int y, int level){
|
Entity newPassiveEntity(int type, int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_PASSIVE;
|
e.type = ENTITY_PASSIVE;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.hurtTime = 0;
|
e.hurtTime = 0;
|
||||||
e.xKnockback = 0;
|
e.xKnockback = 0;
|
||||||
e.yKnockback = 0;
|
e.yKnockback = 0;
|
||||||
e.passive.mtype = type;
|
e.passive.mtype = type;
|
||||||
e.passive.health = 20;
|
e.passive.health = 20;
|
||||||
e.passive.dir = 0;
|
e.passive.dir = 0;
|
||||||
e.passive.xa = 0;
|
e.passive.xa = 0;
|
||||||
e.passive.ya = 0;
|
e.passive.ya = 0;
|
||||||
e.xr = 4;
|
e.xr = 4;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newZombieEntity(int lvl, int x, int y, int level){
|
Entity newZombieEntity(int lvl, int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_ZOMBIE;
|
e.type = ENTITY_ZOMBIE;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.hurtTime = 0;
|
e.hurtTime = 0;
|
||||||
e.xKnockback = 0;
|
e.xKnockback = 0;
|
||||||
e.yKnockback = 0;
|
e.yKnockback = 0;
|
||||||
e.hostile.lvl = lvl;
|
e.hostile.lvl = lvl;
|
||||||
e.hostile.xa = 0;
|
e.hostile.xa = 0;
|
||||||
e.hostile.ya = 0;
|
e.hostile.ya = 0;
|
||||||
e.hostile.health = lvl * lvl * 10;
|
e.hostile.health = lvl * lvl * 10;
|
||||||
e.hostile.dir = 0;
|
e.hostile.dir = 0;
|
||||||
e.xr = 4;
|
e.xr = 4;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
switch(lvl){
|
switch(lvl){
|
||||||
case 2: e.hostile.color = 0xFF8282CC; break;
|
case 2: e.hostile.color = 0xFF8282CC; break;
|
||||||
case 3: e.hostile.color = 0xFFEFEFEF; break;
|
case 3: e.hostile.color = 0xFFEFEFEF; break;
|
||||||
case 4: e.hostile.color = 0xFFAA6262; break;
|
case 4: e.hostile.color = 0xFFAA6262; break;
|
||||||
default: e.hostile.color = 0xFF95DB95; break;
|
default: e.hostile.color = 0xFF95DB95; break;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newSkeletonEntity(int lvl, int x, int y, int level){
|
Entity newSkeletonEntity(int lvl, int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_SKELETON;
|
e.type = ENTITY_SKELETON;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.hurtTime = 0;
|
e.hurtTime = 0;
|
||||||
e.xKnockback = 0;
|
e.xKnockback = 0;
|
||||||
e.yKnockback = 0;
|
e.yKnockback = 0;
|
||||||
e.hostile.lvl = lvl;
|
e.hostile.lvl = lvl;
|
||||||
e.hostile.xa = 0;
|
e.hostile.xa = 0;
|
||||||
e.hostile.ya = 0;
|
e.hostile.ya = 0;
|
||||||
e.hostile.health = lvl * lvl * 10;
|
e.hostile.health = lvl * lvl * 10;
|
||||||
e.hostile.dir = 0;
|
e.hostile.dir = 0;
|
||||||
e.hostile.randAttackTime = 0;
|
e.hostile.randAttackTime = 0;
|
||||||
e.xr = 4;
|
e.xr = 4;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
switch(lvl){
|
switch(lvl){
|
||||||
case 2: e.hostile.color = 0xFFC4C4C4; break;
|
case 2: e.hostile.color = 0xFFC4C4C4; break;
|
||||||
case 3: e.hostile.color = 0xFFA0A0A0; break;
|
case 3: e.hostile.color = 0xFFA0A0A0; break;
|
||||||
case 4: e.hostile.color = 0xFF7A7A7A; break;
|
case 4: e.hostile.color = 0xFF7A7A7A; break;
|
||||||
default: e.hostile.color = 0xFFFFFFFF; break;
|
default: e.hostile.color = 0xFFFFFFFF; break;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newKnightEntity(int lvl, int x, int y, int level){
|
Entity newKnightEntity(int lvl, int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_KNIGHT;
|
e.type = ENTITY_KNIGHT;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.hurtTime = 0;
|
e.hurtTime = 0;
|
||||||
e.xKnockback = 0;
|
e.xKnockback = 0;
|
||||||
e.yKnockback = 0;
|
e.yKnockback = 0;
|
||||||
e.hostile.lvl = lvl;
|
e.hostile.lvl = lvl;
|
||||||
e.hostile.xa = 0;
|
e.hostile.xa = 0;
|
||||||
e.hostile.ya = 0;
|
e.hostile.ya = 0;
|
||||||
e.hostile.health = lvl * lvl * 20;
|
e.hostile.health = lvl * lvl * 20;
|
||||||
e.hostile.dir = 0;
|
e.hostile.dir = 0;
|
||||||
e.xr = 4;
|
e.xr = 4;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
switch(lvl){
|
switch(lvl){
|
||||||
case 2: e.hostile.color = 0xFF0000C6; break;
|
case 2: e.hostile.color = 0xFF0000C6; break;
|
||||||
case 3: e.hostile.color = 0xFF00A3C6; break;
|
case 3: e.hostile.color = 0xFF00A3C6; break;
|
||||||
case 4: e.hostile.color = 0xFF707070; break;
|
case 4: e.hostile.color = 0xFF707070; break;
|
||||||
default: e.hostile.color = 0xFFFFFFFF; break;
|
default: e.hostile.color = 0xFFFFFFFF; break;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newSlimeEntity(int lvl, int x, int y, int level){
|
Entity newSlimeEntity(int lvl, int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_SLIME;
|
e.type = ENTITY_SLIME;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.hurtTime = 0;
|
e.hurtTime = 0;
|
||||||
e.xKnockback = 0;
|
e.xKnockback = 0;
|
||||||
e.yKnockback = 0;
|
e.yKnockback = 0;
|
||||||
e.slime.lvl = lvl;
|
e.slime.lvl = lvl;
|
||||||
e.slime.xa = 0;
|
e.slime.xa = 0;
|
||||||
e.slime.ya = 0;
|
e.slime.ya = 0;
|
||||||
e.slime.dir = 0;
|
e.slime.dir = 0;
|
||||||
e.slime.health = lvl * lvl * 5;
|
e.slime.health = lvl * lvl * 5;
|
||||||
e.xr = 4;
|
e.xr = 4;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
switch(lvl){
|
switch(lvl){
|
||||||
case 2: e.slime.color = 0xFF8282CC; break;
|
case 2: e.slime.color = 0xFF8282CC; break;
|
||||||
case 3: e.slime.color = 0xFFEFEFEF; break;
|
case 3: e.slime.color = 0xFFEFEFEF; break;
|
||||||
case 4: e.slime.color = 0xFFAA6262; break;
|
case 4: e.slime.color = 0xFFAA6262; break;
|
||||||
default: e.slime.color = 0xFF95DB95; break;
|
default: e.slime.color = 0xFF95DB95; break;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newAirWizardEntity(int x, int y, int level){
|
Entity newAirWizardEntity(int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_AIRWIZARD;
|
e.type = ENTITY_AIRWIZARD;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.hurtTime = 0;
|
e.hurtTime = 0;
|
||||||
e.xKnockback = 0;
|
e.xKnockback = 0;
|
||||||
e.yKnockback = 0;
|
e.yKnockback = 0;
|
||||||
e.wizard.dir = 0;
|
e.wizard.dir = 0;
|
||||||
e.wizard.health = 2000;
|
e.wizard.health = 2000;
|
||||||
e.wizard.attackDelay = 0;
|
e.wizard.attackDelay = 0;
|
||||||
e.wizard.attackTime = 0;
|
e.wizard.attackTime = 0;
|
||||||
e.wizard.attackType = 0;
|
e.wizard.attackType = 0;
|
||||||
e.wizard.xa = 0;
|
e.wizard.xa = 0;
|
||||||
e.wizard.ya = 0;
|
e.wizard.ya = 0;
|
||||||
e.xr = 4;
|
e.xr = 4;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = true;
|
e.canPass = true;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newSparkEntity(Entity* parent, float xa, float ya){
|
Entity newSparkEntity(Entity* parent, float xa, float ya){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_SPARK;
|
e.type = ENTITY_SPARK;
|
||||||
e.level = parent->level;
|
e.level = parent->level;
|
||||||
e.spark.age = 0;
|
e.spark.age = 0;
|
||||||
e.spark.parent = parent;
|
e.spark.parent = parent;
|
||||||
e.spark.xa = xa;
|
e.spark.xa = xa;
|
||||||
e.spark.ya = ya;
|
e.spark.ya = ya;
|
||||||
e.spark.xx = parent->x;
|
e.spark.xx = parent->x;
|
||||||
e.spark.yy = parent->y;
|
e.spark.yy = parent->y;
|
||||||
e.xr = 3;
|
e.xr = 3;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = true;
|
e.canPass = true;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newDragonEntity(int x, int y, int level) {
|
Entity newDragonEntity(int x, int y, int level) {
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_DRAGON;
|
e.type = ENTITY_DRAGON;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.hurtTime = 0;
|
e.hurtTime = 0;
|
||||||
e.xKnockback = 0;
|
e.xKnockback = 0;
|
||||||
e.yKnockback = 0;
|
e.yKnockback = 0;
|
||||||
e.dragon.dir = 0;
|
e.dragon.dir = 0;
|
||||||
e.dragon.health = 2000;
|
e.dragon.health = 2000;
|
||||||
e.dragon.attackDelay = 0;
|
e.dragon.attackDelay = 0;
|
||||||
e.dragon.attackTime = 0;
|
e.dragon.attackTime = 0;
|
||||||
e.dragon.attackType = 0;
|
e.dragon.attackType = 0;
|
||||||
e.dragon.animTimer = 0;
|
e.dragon.animTimer = 0;
|
||||||
e.dragon.xa = 0;
|
e.dragon.xa = 0;
|
||||||
e.dragon.ya = 0;
|
e.dragon.ya = 0;
|
||||||
e.xr = 8;
|
e.xr = 8;
|
||||||
e.yr = 8;
|
e.yr = 8;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newDragonFireEntity(Entity* parent, u8 type, int x, int y, float xa, float ya) {
|
Entity newDragonFireEntity(Entity* parent, u8 type, int x, int y, float xa, float ya) {
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_DRAGONPROJECTILE;
|
e.type = ENTITY_DRAGONPROJECTILE;
|
||||||
e.level = parent->level;
|
e.level = parent->level;
|
||||||
e.dragonFire.age = 0;
|
e.dragonFire.age = 0;
|
||||||
e.dragonFire.type = type;
|
e.dragonFire.type = type;
|
||||||
e.dragonFire.parent = parent;
|
e.dragonFire.parent = parent;
|
||||||
e.dragonFire.xa = xa;
|
e.dragonFire.xa = xa;
|
||||||
e.dragonFire.ya = ya;
|
e.dragonFire.ya = ya;
|
||||||
e.dragonFire.xx = x;
|
e.dragonFire.xx = x;
|
||||||
e.dragonFire.yy = y;
|
e.dragonFire.yy = y;
|
||||||
e.x = (int) x;
|
e.x = (int) x;
|
||||||
e.y = (int) y;
|
e.y = (int) y;
|
||||||
e.xr = 3;
|
e.xr = 3;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = true;
|
e.canPass = true;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newMagicPillarEntity(int x, int y, int level){
|
Entity newMagicPillarEntity(int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_MAGIC_PILLAR;
|
e.type = ENTITY_MAGIC_PILLAR;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.xr = 3;
|
e.xr = 3;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newTextParticleEntity(char * str, u32 color, int x, int y, int level){
|
Entity newTextParticleEntity(char * str, u32 color, int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_TEXTPARTICLE;
|
e.type = ENTITY_TEXTPARTICLE;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.textParticle.color = color;
|
e.textParticle.color = color;
|
||||||
e.textParticle.age = 0;
|
e.textParticle.age = 0;
|
||||||
e.textParticle.text = (char*)calloc(strlen(str),sizeof(char));
|
e.textParticle.text = (char*)calloc(strlen(str),sizeof(char));
|
||||||
strncpy(e.textParticle.text,str,strlen(str));
|
strncpy(e.textParticle.text,str,strlen(str));
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.canPass = true;
|
e.canPass = true;
|
||||||
e.textParticle.xx = x;
|
e.textParticle.xx = x;
|
||||||
e.textParticle.yy = y;
|
e.textParticle.yy = y;
|
||||||
e.textParticle.zz = 2;
|
e.textParticle.zz = 2;
|
||||||
e.textParticle.xa = gaussrand(false) * 0.3;
|
e.textParticle.xa = gaussrand(false) * 0.3;
|
||||||
e.textParticle.ya = gaussrand(false) * 0.2;
|
e.textParticle.ya = gaussrand(false) * 0.2;
|
||||||
e.textParticle.za = ((float)rand() / RAND_MAX) * 0.7 + 2;
|
e.textParticle.za = ((float)rand() / RAND_MAX) * 0.7 + 2;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
Entity newSmashParticleEntity(int x, int y, int level){
|
Entity newSmashParticleEntity(int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_SMASHPARTICLE;
|
e.type = ENTITY_SMASHPARTICLE;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.smashParticle.age = 0;
|
e.smashParticle.age = 0;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.canPass = true;
|
e.canPass = true;
|
||||||
playSoundPositioned(snd_monsterHurt, e.level, e.x, e.y); //TODO: This is a wierd location for the effect
|
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 newArrowEntity(Entity* parent, int itemID, s8 xa, s8 ya, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_ARROW;
|
e.type = ENTITY_ARROW;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.arrow.age = 0;
|
e.arrow.age = 0;
|
||||||
e.arrow.parent = parent;
|
e.arrow.parent = parent;
|
||||||
e.arrow.itemID = itemID;
|
e.arrow.itemID = itemID;
|
||||||
e.arrow.xa = xa;
|
e.arrow.xa = xa;
|
||||||
e.arrow.ya = ya;
|
e.arrow.ya = ya;
|
||||||
e.x = parent->x;
|
e.x = parent->x;
|
||||||
e.y = parent->y;
|
e.y = parent->y;
|
||||||
e.xr = 2;
|
e.xr = 2;
|
||||||
e.yr = 2;
|
e.yr = 2;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
e.canSwim = true;
|
e.canSwim = true;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newGlowwormEntity(int x, int y, int level){
|
Entity newGlowwormEntity(int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_GLOWWORM;
|
e.type = ENTITY_GLOWWORM;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.glowworm.xa = 0;
|
e.glowworm.xa = 0;
|
||||||
e.glowworm.ya = 0;
|
e.glowworm.ya = 0;
|
||||||
e.glowworm.randWalkTime = 0;
|
e.glowworm.randWalkTime = 0;
|
||||||
e.glowworm.waitTime = 0;
|
e.glowworm.waitTime = 0;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.canPass = true;
|
e.canPass = true;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity newNPCEntity(int type, int x, int y, int level){
|
Entity newNPCEntity(int type, int x, int y, int level){
|
||||||
Entity e;
|
Entity e;
|
||||||
e.type = ENTITY_NPC;
|
e.type = ENTITY_NPC;
|
||||||
e.level = level;
|
e.level = level;
|
||||||
e.x = x;
|
e.x = x;
|
||||||
e.y = y;
|
e.y = y;
|
||||||
e.hurtTime = 0;
|
e.hurtTime = 0;
|
||||||
e.xKnockback = 0;
|
e.xKnockback = 0;
|
||||||
e.yKnockback = 0;
|
e.yKnockback = 0;
|
||||||
e.npc.type = type;
|
e.npc.type = type;
|
||||||
e.xr = 4;
|
e.xr = 4;
|
||||||
e.yr = 3;
|
e.yr = 3;
|
||||||
e.canPass = false;
|
e.canPass = false;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addEntityToList(Entity e, EntityManager* em){
|
void addEntityToList(Entity e, EntityManager* em){
|
||||||
e.slotNum = em->lastSlot[e.level];
|
e.slotNum = em->lastSlot[e.level];
|
||||||
em->entities[e.level][em->lastSlot[e.level]] = e;
|
em->entities[e.level][em->lastSlot[e.level]] = e;
|
||||||
++em->lastSlot[e.level];
|
++em->lastSlot[e.level];
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeEntityFromList(Entity * e,int level,EntityManager* em){
|
void removeEntityFromList(Entity * e,int level,EntityManager* em){
|
||||||
int i;
|
int i;
|
||||||
if(em->entities[level][e->slotNum].type == ENTITY_TEXTPARTICLE) free(em->entities[level][e->slotNum].textParticle.text);
|
if(em->entities[level][e->slotNum].type == ENTITY_TEXTPARTICLE) free(em->entities[level][e->slotNum].textParticle.text);
|
||||||
for(i = e->slotNum; i < em->lastSlot[level];++i){
|
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] = em->entities[level][i + 1]; // Move the items down.
|
||||||
em->entities[level][i].slotNum = i;
|
em->entities[level][i].slotNum = i;
|
||||||
}
|
}
|
||||||
em->lastSlot[level]--;
|
em->lastSlot[level]--;
|
||||||
em->entities[level][em->lastSlot[level]] = nullEntity; // Make the last slot null.
|
em->entities[level][em->lastSlot[level]] = nullEntity; // Make the last slot null.
|
||||||
}
|
}
|
||||||
|
|
227
source/Entity.h
227
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 _plrd PlayerData; //in order to not include Player.h and cause all sorts of problems
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s8 ax;
|
s8 ax;
|
||||||
s8 ay;
|
s8 ay;
|
||||||
u8 dir;
|
u8 dir;
|
||||||
s8 health;
|
s8 health;
|
||||||
s8 stamina;
|
s8 stamina;
|
||||||
s8 staminaRecharge;
|
s8 staminaRecharge;
|
||||||
s8 staminaRechargeDelay;
|
s8 staminaRechargeDelay;
|
||||||
s8 attackTimer;
|
s8 attackTimer;
|
||||||
u8 spawnTrigger;
|
u8 spawnTrigger;
|
||||||
bool isDead;
|
bool isDead;
|
||||||
bool hasWon;
|
bool hasWon;
|
||||||
bool hasWonSaved;
|
bool hasWonSaved;
|
||||||
s8 endTimer;
|
s8 endTimer;
|
||||||
s16 walkDist;
|
s16 walkDist;
|
||||||
bool isCarrying;
|
bool isCarrying;
|
||||||
bool isSwimming;
|
bool isSwimming;
|
||||||
int swimTimer;
|
int swimTimer;
|
||||||
int regenTimer;
|
int regenTimer;
|
||||||
int strengthTimer;
|
int strengthTimer;
|
||||||
int swimBreathTimer;
|
int swimBreathTimer;
|
||||||
int speedTimer;
|
int speedTimer;
|
||||||
int score;
|
int score;
|
||||||
PlayerData *data;
|
PlayerData *data;
|
||||||
} Player;
|
} Player;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float xa;
|
float xa;
|
||||||
float ya;
|
float ya;
|
||||||
float za;
|
float za;
|
||||||
float xx;
|
float xx;
|
||||||
float yy;
|
float yy;
|
||||||
float zz;
|
float zz;
|
||||||
s16 age;
|
s16 age;
|
||||||
Item item;
|
Item item;
|
||||||
} EntityItem;
|
} EntityItem;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s16 itemID;
|
s16 itemID;
|
||||||
bool active;
|
bool active;
|
||||||
s8 r; // light radius for lantern.
|
s8 r; // light radius for lantern.
|
||||||
Inventory* inv; // Points to chest inventory.
|
Inventory* inv; // Points to chest inventory.
|
||||||
} EntityFurniture;
|
} EntityFurniture;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 mtype;
|
u8 mtype;
|
||||||
s8 xa;
|
s8 xa;
|
||||||
s8 ya;
|
s8 ya;
|
||||||
s16 health;
|
s16 health;
|
||||||
s8 dir;
|
s8 dir;
|
||||||
s8 randWalkTime;
|
s8 randWalkTime;
|
||||||
s8 walkDist;
|
s8 walkDist;
|
||||||
} PassiveMob;
|
} PassiveMob;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s8 xa;
|
s8 xa;
|
||||||
s8 ya;
|
s8 ya;
|
||||||
s16 health;
|
s16 health;
|
||||||
s8 dir;
|
s8 dir;
|
||||||
s8 lvl;
|
s8 lvl;
|
||||||
s8 randWalkTime;
|
s8 randWalkTime;
|
||||||
s8 walkDist;
|
s8 walkDist;
|
||||||
s8 randAttackTime;
|
s8 randAttackTime;
|
||||||
u32 color;
|
u32 color;
|
||||||
} HostileMob;
|
} HostileMob;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s8 xa;
|
s8 xa;
|
||||||
s8 ya;
|
s8 ya;
|
||||||
s16 health;
|
s16 health;
|
||||||
s8 lvl;
|
s8 lvl;
|
||||||
s8 dir;
|
s8 dir;
|
||||||
s8 jumpTime;
|
s8 jumpTime;
|
||||||
u32 color;
|
u32 color;
|
||||||
} Slime;
|
} Slime;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s8 xa;
|
s8 xa;
|
||||||
s8 ya;
|
s8 ya;
|
||||||
s16 health;
|
s16 health;
|
||||||
s8 randWalkTime;
|
s8 randWalkTime;
|
||||||
s8 walkDist;
|
s8 walkDist;
|
||||||
s8 dir;
|
s8 dir;
|
||||||
int attackDelay;
|
int attackDelay;
|
||||||
int attackTime;
|
int attackTime;
|
||||||
int attackType;
|
int attackType;
|
||||||
|
@ -120,12 +120,12 @@ typedef struct {
|
||||||
} AirWizard;
|
} AirWizard;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Entity* parent;
|
Entity* parent;
|
||||||
s16 age;
|
s16 age;
|
||||||
float xa;
|
float xa;
|
||||||
float ya;
|
float ya;
|
||||||
float xx;
|
float xx;
|
||||||
float yy;
|
float yy;
|
||||||
} Spark;
|
} Spark;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -137,12 +137,12 @@ typedef struct {
|
||||||
} Arrow;
|
} Arrow;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s8 xa;
|
s8 xa;
|
||||||
s8 ya;
|
s8 ya;
|
||||||
s16 health;
|
s16 health;
|
||||||
s8 randWalkTime;
|
s8 randWalkTime;
|
||||||
s8 walkDist;
|
s8 walkDist;
|
||||||
s8 dir;
|
s8 dir;
|
||||||
int attackDelay;
|
int attackDelay;
|
||||||
int attackTime;
|
int attackTime;
|
||||||
int attackType;
|
int attackType;
|
||||||
|
@ -150,19 +150,19 @@ typedef struct {
|
||||||
} Dragon;
|
} Dragon;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Entity* parent;
|
Entity* parent;
|
||||||
u8 type;
|
u8 type;
|
||||||
s16 age;
|
s16 age;
|
||||||
float xa;
|
float xa;
|
||||||
float ya;
|
float ya;
|
||||||
float xx;
|
float xx;
|
||||||
float yy;
|
float yy;
|
||||||
} DragonFire;
|
} DragonFire;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s8 xa;
|
s8 xa;
|
||||||
s8 ya;
|
s8 ya;
|
||||||
s8 randWalkTime;
|
s8 randWalkTime;
|
||||||
s8 waitTime;
|
s8 waitTime;
|
||||||
} Glowworm;
|
} Glowworm;
|
||||||
|
|
||||||
|
@ -171,56 +171,56 @@ typedef struct {
|
||||||
} NPC;
|
} NPC;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float xa;
|
float xa;
|
||||||
float ya;
|
float ya;
|
||||||
float za;
|
float za;
|
||||||
float xx;
|
float xx;
|
||||||
float yy;
|
float yy;
|
||||||
float zz;
|
float zz;
|
||||||
s16 age;
|
s16 age;
|
||||||
char* text;
|
char* text;
|
||||||
int color;
|
int color;
|
||||||
} TextParticleEntity;
|
} TextParticleEntity;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s16 age;
|
s16 age;
|
||||||
} SmashParticleEntity;
|
} SmashParticleEntity;
|
||||||
|
|
||||||
struct Entity {
|
struct Entity {
|
||||||
s16 x;
|
s16 x;
|
||||||
s16 y;
|
s16 y;
|
||||||
s8 xKnockback,yKnockback;
|
s8 xKnockback,yKnockback;
|
||||||
u8 xr,yr;
|
u8 xr,yr;
|
||||||
u8 type;
|
u8 type;
|
||||||
u8 level;
|
u8 level;
|
||||||
s8 hurtTime;
|
s8 hurtTime;
|
||||||
s16 slotNum; // Read-only. Do not mess with this.
|
s16 slotNum; // Read-only. Do not mess with this.
|
||||||
bool canPass;
|
bool canPass;
|
||||||
bool canSwim;
|
bool canSwim;
|
||||||
union {
|
union {
|
||||||
Player p;
|
Player p;
|
||||||
EntityItem entityItem;
|
EntityItem entityItem;
|
||||||
EntityFurniture entityFurniture;
|
EntityFurniture entityFurniture;
|
||||||
PassiveMob passive;
|
PassiveMob passive;
|
||||||
HostileMob hostile;
|
HostileMob hostile;
|
||||||
Slime slime;
|
Slime slime;
|
||||||
AirWizard wizard;
|
AirWizard wizard;
|
||||||
Spark spark;
|
Spark spark;
|
||||||
Arrow arrow;
|
Arrow arrow;
|
||||||
Glowworm glowworm;
|
Glowworm glowworm;
|
||||||
Dragon dragon;
|
Dragon dragon;
|
||||||
DragonFire dragonFire;
|
DragonFire dragonFire;
|
||||||
NPC npc;
|
NPC npc;
|
||||||
TextParticleEntity textParticle;
|
TextParticleEntity textParticle;
|
||||||
SmashParticleEntity smashParticle;
|
SmashParticleEntity smashParticle;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Entity entities[6][1000];
|
Entity entities[6][1000];
|
||||||
s16 lastSlot[6];
|
s16 lastSlot[6];
|
||||||
Inventory invs[300];
|
Inventory invs[300];
|
||||||
s16 nextInv;
|
s16 nextInv;
|
||||||
} EntityManager;
|
} EntityManager;
|
||||||
|
|
||||||
EntityManager eManager;
|
EntityManager eManager;
|
||||||
|
@ -246,6 +246,3 @@ Entity newGlowwormEntity(int x, int y, int level);
|
||||||
Entity newNPCEntity(int type, int x, int y, int level);
|
Entity newNPCEntity(int type, int x, int y, int level);
|
||||||
void addEntityToList(Entity e, EntityManager* em);
|
void addEntityToList(Entity e, EntityManager* em);
|
||||||
void removeEntityFromList(Entity * e,int level,EntityManager* em);
|
void removeEntityFromList(Entity * e,int level,EntityManager* em);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
2496
source/Globals.c
2496
source/Globals.c
File diff suppressed because it is too large
Load diff
|
@ -7,7 +7,7 @@
|
||||||
#include "MapGen.h"
|
#include "MapGen.h"
|
||||||
#include "Quests.h"
|
#include "Quests.h"
|
||||||
|
|
||||||
#include "icons2_png.h"
|
#include "icons_png.h"
|
||||||
#include "player_png.h"
|
#include "player_png.h"
|
||||||
#include "Font_png.h"
|
#include "Font_png.h"
|
||||||
#include "bottombg_png.h"
|
#include "bottombg_png.h"
|
||||||
|
@ -142,15 +142,15 @@ bool quitGame;
|
||||||
s8 currentSelection;
|
s8 currentSelection;
|
||||||
|
|
||||||
typedef struct _worldData {
|
typedef struct _worldData {
|
||||||
u8 map[6][128*128];
|
u8 map[6][128*128];
|
||||||
u8 data[6][128*128];
|
u8 data[6][128*128];
|
||||||
|
|
||||||
u16 daytime;
|
u16 daytime;
|
||||||
int day;
|
int day;
|
||||||
u8 season;
|
u8 season;
|
||||||
bool rain;
|
bool rain;
|
||||||
|
|
||||||
u8 compassData[6][3];
|
u8 compassData[6][3];
|
||||||
} WorldData;
|
} WorldData;
|
||||||
|
|
||||||
WorldData worldData;
|
WorldData worldData;
|
||||||
|
@ -201,4 +201,4 @@ u32 getMinimapColor(PlayerData *pd, int level, int x, int y);
|
||||||
void initMinimapLevel(PlayerData *pd, int level);
|
void initMinimapLevel(PlayerData *pd, int level);
|
||||||
void updateLevel1Map();
|
void updateLevel1Map();
|
||||||
|
|
||||||
void reloadColors();
|
void reloadColors();
|
||||||
|
|
626
source/Ingame.c
626
source/Ingame.c
|
@ -17,53 +17,53 @@ bool stallAreYouSure;
|
||||||
|
|
||||||
//generates stairs up and creates compass data
|
//generates stairs up and creates compass data
|
||||||
void generatePass2() {
|
void generatePass2() {
|
||||||
int level, x, y;
|
int level, x, 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
|
for (level = 0; level < 5; ++level) {
|
||||||
switch (worldData.map[level][x + y * 128]) {
|
for (x = 0; x < 128; ++x) {
|
||||||
case TILE_STAIRS_DOWN:
|
for (y = 0; y < 128; ++y) {
|
||||||
if(level < 4) {
|
|
||||||
worldData.map[level + 1][x + y * 128] = TILE_STAIRS_UP;
|
//generate stairs up matching stairs down
|
||||||
if (level == 0) {
|
switch (worldData.map[level][x + y * 128]) {
|
||||||
worldData.map[level + 1][(x + 1) + y * 128] = TILE_HARDROCK;
|
case TILE_STAIRS_DOWN:
|
||||||
worldData.map[level + 1][x + (y + 1) * 128] = TILE_HARDROCK;
|
if(level < 4) {
|
||||||
worldData.map[level + 1][(x - 1) + y * 128] = TILE_HARDROCK;
|
worldData.map[level + 1][x + y * 128] = TILE_STAIRS_UP;
|
||||||
worldData.map[level + 1][x + (y - 1) * 128] = TILE_HARDROCK;
|
if (level == 0) {
|
||||||
worldData.map[level + 1][(x + 1) + (y + 1) * 128] = TILE_HARDROCK;
|
worldData.map[level + 1][(x + 1) + y * 128] = TILE_HARDROCK;
|
||||||
worldData.map[level + 1][(x - 1) + (y - 1) * 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 * 128] = TILE_HARDROCK;
|
||||||
worldData.map[level + 1][(x + 1) + (y - 1) * 128] = TILE_HARDROCK;
|
worldData.map[level + 1][x + (y - 1) * 128] = TILE_HARDROCK;
|
||||||
} else {
|
worldData.map[level + 1][(x + 1) + (y + 1) * 128] = TILE_HARDROCK;
|
||||||
worldData.map[level + 1][(x + 1) + y * 128] = TILE_DIRT;
|
worldData.map[level + 1][(x - 1) + (y - 1) * 128] = TILE_HARDROCK;
|
||||||
worldData.map[level + 1][x + (y + 1) * 128] = TILE_DIRT;
|
worldData.map[level + 1][(x - 1) + (y + 1) * 128] = TILE_HARDROCK;
|
||||||
worldData.map[level + 1][(x - 1) + y * 128] = TILE_DIRT;
|
worldData.map[level + 1][(x + 1) + (y - 1) * 128] = TILE_HARDROCK;
|
||||||
worldData.map[level + 1][x + (y - 1) * 128] = TILE_DIRT;
|
} else {
|
||||||
worldData.map[level + 1][(x + 1) + (y + 1) * 128] = TILE_DIRT;
|
worldData.map[level + 1][(x + 1) + y * 128] = TILE_DIRT;
|
||||||
worldData.map[level + 1][(x - 1) + (y - 1) * 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 * 128] = TILE_DIRT;
|
||||||
worldData.map[level + 1][(x + 1) + (y - 1) * 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:
|
//calculate compass data
|
||||||
worldData.compassData[level][2] = worldData.compassData[level][2] + 1;
|
//choose one stair down and store for magic compass
|
||||||
if((worldData.compassData[level][2]==1) || (rand()%(worldData.compassData[level][2])==0)) {
|
switch (worldData.map[level][x + y * 128]) {
|
||||||
worldData.compassData[level][0] = x;
|
case TILE_STAIRS_DOWN:
|
||||||
worldData.compassData[level][1] = y;
|
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() {
|
void initNewMap() {
|
||||||
|
@ -72,7 +72,7 @@ void initNewMap() {
|
||||||
createAndValidateUndergroundMap(128, 128, 1, 2, worldData.map[2], worldData.data[2]);
|
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, 2, 3, worldData.map[3], worldData.data[3]);
|
||||||
createAndValidateUndergroundMap(128, 128, 3, 4, worldData.map[4], worldData.data[4]);
|
createAndValidateUndergroundMap(128, 128, 3, 4, worldData.map[4], worldData.data[4]);
|
||||||
generatePass2();
|
generatePass2();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initMiniMap(PlayerData *pd) {
|
void initMiniMap(PlayerData *pd) {
|
||||||
|
@ -83,297 +83,297 @@ void initMiniMap(PlayerData *pd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void startGame(bool load, char *filename) {
|
void startGame(bool load, char *filename) {
|
||||||
// Reset entity manager.
|
// Reset entity manager.
|
||||||
memset(&eManager, 0, sizeof(eManager));
|
memset(&eManager, 0, sizeof(eManager));
|
||||||
|
|
||||||
// Reset players
|
// Reset players
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
initPlayer(players+i);
|
initPlayer(players+i);
|
||||||
}
|
}
|
||||||
if (playerCount > 1) {
|
if (playerCount > 1) {
|
||||||
shouldRenderDebug = false;
|
shouldRenderDebug = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!load) {
|
if (!load) {
|
||||||
initNewMap();
|
initNewMap();
|
||||||
airWizardHealthDisplay = 2000;
|
airWizardHealthDisplay = 2000;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 5; ++i) {
|
for (i = 0; i < 5; ++i) {
|
||||||
trySpawn(500, i);
|
trySpawn(500, i);
|
||||||
}
|
}
|
||||||
addEntityToList(newAirWizardEntity(630, 820, 0), &eManager);
|
addEntityToList(newAirWizardEntity(630, 820, 0), &eManager);
|
||||||
worldData.daytime = 6000;
|
worldData.daytime = 6000;
|
||||||
worldData.day = 0;
|
worldData.day = 0;
|
||||||
worldData.season = 0;
|
worldData.season = 0;
|
||||||
worldData.rain = false;
|
worldData.rain = false;
|
||||||
} else {
|
} else {
|
||||||
if(!loadWorld(filename, &eManager, &worldData, players, playerCount)) {
|
if(!loadWorld(filename, &eManager, &worldData, players, playerCount)) {
|
||||||
//TODO: What do?
|
//TODO: What do?
|
||||||
networkDisconnect();
|
networkDisconnect();
|
||||||
|
|
||||||
sf2d_set_clear_color(0xFF);
|
sf2d_set_clear_color(0xFF);
|
||||||
currentSelection = 0;
|
currentSelection = 0;
|
||||||
currentMenu = MENU_TITLE;
|
currentMenu = MENU_TITLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spawn players
|
// Spawn players
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
if(!players[i].isSpawned) {
|
if(!players[i].isSpawned) {
|
||||||
playerSpawn(players+i);
|
playerSpawn(players+i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init player maps
|
// Init player maps
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
initMiniMap(players+i);
|
initMiniMap(players+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
stallCounter = 0;
|
stallCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncedTick() {
|
void syncedTick() {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
setListenerPosition(getLocalPlayer()->entity.level, getLocalPlayer()->entity.x, getLocalPlayer()->entity.y);
|
|
||||||
|
|
||||||
//win/death menus
|
setListenerPosition(getLocalPlayer()->entity.level, getLocalPlayer()->entity.x, getLocalPlayer()->entity.y);
|
||||||
for(i=0; i<playerCount; i++) {
|
|
||||||
if (players[i].entity.p.isDead) {
|
|
||||||
if (players[i].entity.p.endTimer < 1) {
|
|
||||||
players[i].ingameMenu = MENU_LOSE;
|
|
||||||
}
|
|
||||||
--players[i].entity.p.endTimer;
|
|
||||||
} else if (players[i].entity.p.hasWon) {
|
|
||||||
if (players[i].entity.p.endTimer < 1) {
|
|
||||||
players[i].ingameMenu = MENU_WIN;
|
|
||||||
}
|
|
||||||
--players[i].entity.p.endTimer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//update worldData (daytime,season and weather)
|
//win/death menus
|
||||||
++worldData.daytime;
|
for(i=0; i<playerCount; i++) {
|
||||||
if(worldData.daytime>=24000) {
|
if (players[i].entity.p.isDead) {
|
||||||
worldData.daytime -= 24000;
|
if (players[i].entity.p.endTimer < 1) {
|
||||||
++worldData.day;
|
players[i].ingameMenu = MENU_LOSE;
|
||||||
//TODO: maybe make season length not as hardcoded + make the transition better (fade to black and back maybe?)
|
}
|
||||||
if(worldData.day%7==0) {
|
--players[i].entity.p.endTimer;
|
||||||
++worldData.season;
|
} else if (players[i].entity.p.hasWon) {
|
||||||
if(worldData.season==4) worldData.season = 0;
|
if (players[i].entity.p.endTimer < 1) {
|
||||||
}
|
players[i].ingameMenu = MENU_WIN;
|
||||||
worldData.rain = false;
|
}
|
||||||
if(worldData.season!=3 && rand()%5==0) worldData.rain = true;
|
--players[i].entity.p.endTimer;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//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<playerCount; i++) {
|
|
||||||
if(players[i].entity.level==level) {
|
|
||||||
hasPlayer = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!hasPlayer) continue;
|
|
||||||
|
|
||||||
//tick tiles
|
//update worldData (daytime,season and weather)
|
||||||
for (i = 0; i < 324; ++i) {
|
++worldData.daytime;
|
||||||
int xx = rand() & 127;
|
if(worldData.daytime>=24000) {
|
||||||
int yy = rand() & 127;
|
worldData.daytime -= 24000;
|
||||||
tickTile(level, xx, yy);
|
++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;
|
||||||
for(i=0; i<playerCount; i++) {
|
}
|
||||||
ingameMenuTickTouch(players+i);
|
worldData.rain = false;
|
||||||
|
if(worldData.season!=3 && rand()%5==0) worldData.rain = true;
|
||||||
bool inmenu = false;
|
}
|
||||||
if(players[i].ingameMenu != MENU_NONE) {
|
|
||||||
ingameMenuTick(players+i, players[i].ingameMenu);
|
|
||||||
inmenu = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
tickPlayer(players+i, inmenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//update music
|
||||||
//for every active level
|
updateMusic(getLocalPlayer()->entity.level, worldData.daytime);
|
||||||
for(level = 0; level < 6; level++) {
|
|
||||||
if(level==5 && !dungeonActive()) continue;
|
//for every active level
|
||||||
|
s8 level;
|
||||||
bool hasPlayer = false;
|
for(level = 0; level < 6; level++) {
|
||||||
for(i=0; i<playerCount; i++) {
|
bool hasPlayer = false;
|
||||||
if(players[i].entity.level==level) {
|
for(i=0; i<playerCount; i++) {
|
||||||
hasPlayer = true;
|
if(players[i].entity.level==level) {
|
||||||
}
|
hasPlayer = true;
|
||||||
}
|
}
|
||||||
if(!hasPlayer) continue;
|
}
|
||||||
|
if(!hasPlayer) continue;
|
||||||
//spawn entities
|
|
||||||
if(eManager.lastSlot[level]<80 && level != 5) {
|
//tick tiles
|
||||||
trySpawn(1, level);
|
for (i = 0; i < 324; ++i) {
|
||||||
}
|
int xx = rand() & 127;
|
||||||
|
int yy = rand() & 127;
|
||||||
//update entities
|
tickTile(level, xx, yy);
|
||||||
for (i = 0; i < eManager.lastSlot[level]; ++i) {
|
}
|
||||||
Entity * e = &eManager.entities[level][i];
|
}
|
||||||
PlayerData * p = getNearestPlayer(level, e->x, e->y);
|
|
||||||
|
|
||||||
//should never happen, but just for safety to prevent hard crashes
|
for(i=0; i<playerCount; i++) {
|
||||||
if(p==NULL) continue;
|
ingameMenuTickTouch(players+i);
|
||||||
|
|
||||||
if ((e->type != ENTITY_ZOMBIE && e->type != ENTITY_SKELETON && e->type != ENTITY_KNIGHT && e->type != ENTITY_SLIME && e->type != ENTITY_PASSIVE && e->type != ENTITY_GLOWWORM)
|
bool inmenu = false;
|
||||||
|| (e->type == ENTITY_GLOWWORM && (worldData.daytime>6000 || worldData.daytime<18000))
|
if(players[i].ingameMenu != MENU_NONE) {
|
||||||
|| (e->x > p->entity.x - 160 && e->y > p->entity.y - 125 && e->x < p->entity.x + 160 && e->y < p->entity.y + 125)) {
|
ingameMenuTick(players+i, players[i].ingameMenu);
|
||||||
tickEntity(e);
|
inmenu = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
tickPlayer(players+i, inmenu);
|
||||||
|
}
|
||||||
stallCounter = 0;
|
|
||||||
|
|
||||||
|
//for every active level
|
||||||
|
for(level = 0; level < 6; level++) {
|
||||||
|
if(level==5 && !dungeonActive()) continue;
|
||||||
|
|
||||||
|
bool hasPlayer = false;
|
||||||
|
for(i=0; i<playerCount; i++) {
|
||||||
|
if(players[i].entity.level==level) {
|
||||||
|
hasPlayer = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!hasPlayer) continue;
|
||||||
|
|
||||||
|
//spawn entities
|
||||||
|
if(eManager.lastSlot[level]<80 && level != 5) {
|
||||||
|
trySpawn(1, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
//update entities
|
||||||
|
for (i = 0; i < eManager.lastSlot[level]; ++i) {
|
||||||
|
Entity * e = &eManager.entities[level][i];
|
||||||
|
PlayerData * p = getNearestPlayer(level, e->x, 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() {
|
void tickGame() {
|
||||||
synchronizerTick(&syncedTick);
|
synchronizerTick(&syncedTick);
|
||||||
|
|
||||||
|
|
||||||
if(synchronizerIsRunning()) {
|
if(synchronizerIsRunning()) {
|
||||||
stallCounter++;
|
stallCounter++;
|
||||||
//game stalled -> most likely a player disconnected -> present option to exit game
|
//game stalled -> most likely a player disconnected -> present option to exit game
|
||||||
if(stallCounter>=STALL_TIME) {
|
if(stallCounter>=STALL_TIME) {
|
||||||
if(stallCounter==STALL_TIME) stallAreYouSure = false;
|
if(stallCounter==STALL_TIME) stallAreYouSure = false;
|
||||||
|
|
||||||
//scan local inputs, because synchronizer only updates them when not stalled
|
//scan local inputs, because synchronizer only updates them when not stalled
|
||||||
hidScanInput();
|
hidScanInput();
|
||||||
tickKeys(&localInputs, hidKeysHeld(), hidKeysDown());
|
tickKeys(&localInputs, hidKeysHeld(), hidKeysDown());
|
||||||
|
|
||||||
if (localInputs.k_accept.clicked) {
|
if (localInputs.k_accept.clicked) {
|
||||||
if(stallAreYouSure) {
|
if(stallAreYouSure) {
|
||||||
//create backup save
|
//create backup save
|
||||||
if(playerLocalID==0) {
|
if(playerLocalID==0) {
|
||||||
char backupSaveFileName[256+32];
|
char backupSaveFileName[256+32];
|
||||||
backupSaveFileName[0] = '\0';
|
backupSaveFileName[0] = '\0';
|
||||||
|
|
||||||
strncat(backupSaveFileName, currentFileName, strlen(currentFileName)-4);
|
strncat(backupSaveFileName, currentFileName, strlen(currentFileName)-4);
|
||||||
strcat(backupSaveFileName, ".exit.msv");
|
strcat(backupSaveFileName, ".exit.msv");
|
||||||
|
|
||||||
saveWorld(backupSaveFileName, &eManager, &worldData, players, playerCount);
|
saveWorld(backupSaveFileName, &eManager, &worldData, players, playerCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
exitGame();
|
exitGame();
|
||||||
} else {
|
} else {
|
||||||
stallAreYouSure = true;
|
stallAreYouSure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (localInputs.k_decline.clicked) {
|
if (localInputs.k_decline.clicked) {
|
||||||
stallAreYouSure = false;
|
stallAreYouSure = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//for rendering -> move to a better place
|
//for rendering -> move to a better place
|
||||||
int xscr = 0, yscr = 0;
|
int xscr = 0, yscr = 0;
|
||||||
|
|
||||||
void renderGame() {
|
void renderGame() {
|
||||||
//Important: all code called from this function should never affect game state!
|
//Important: all code called from this function should never affect game state!
|
||||||
sf2d_start_frame(GFX_TOP, GFX_LEFT);
|
sf2d_start_frame(GFX_TOP, GFX_LEFT);
|
||||||
|
|
||||||
int xscr = getLocalPlayer()->entity.x - 100;
|
int xscr = getLocalPlayer()->entity.x - 100;
|
||||||
int yscr = getLocalPlayer()->entity.y - 56;
|
int yscr = getLocalPlayer()->entity.y - 56;
|
||||||
if (xscr < 16)
|
if (xscr < 16)
|
||||||
xscr = 16;
|
xscr = 16;
|
||||||
else if (xscr > 1832)
|
else if (xscr > 1832)
|
||||||
xscr = 1832;
|
xscr = 1832;
|
||||||
if (yscr < 16)
|
if (yscr < 16)
|
||||||
yscr = 16;
|
yscr = 16;
|
||||||
else if (yscr > 1912)
|
else if (yscr > 1912)
|
||||||
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);
|
|
||||||
|
|
||||||
renderBackground(getLocalPlayer()->entity.level, xscr, yscr);
|
|
||||||
renderEntities(getLocalPlayer()->entity.level, getLocalPlayer()->entity.x, getLocalPlayer()->entity.y, &eManager);
|
|
||||||
for(int i=0; i<playerCount; i++) {
|
|
||||||
renderPlayer(players+i);
|
|
||||||
}
|
|
||||||
renderWeather(getLocalPlayer()->entity.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) {
|
offsetX = xscr;
|
||||||
drawText("Press to leave the game", (400 - (25 * 12))/2, 160);
|
offsetY = yscr;
|
||||||
renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 120, 157, 1);
|
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
|
||||||
|
|
||||||
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);
|
renderLightsToStencil(getLocalPlayer(), false, false, true);
|
||||||
if(!players[playerLocalID].mapShouldRender){
|
|
||||||
sf2d_draw_texture(bottombg, 0, 0);
|
renderBackground(getLocalPlayer()->entity.level, xscr, yscr);
|
||||||
renderGui(getLocalPlayer());
|
renderEntities(getLocalPlayer()->entity.level, getLocalPlayer()->entity.x, getLocalPlayer()->entity.y, &eManager);
|
||||||
} else {
|
for(int i=0; i<playerCount; i++) {
|
||||||
renderZoomedMap(getLocalPlayer());
|
renderPlayer(players+i);
|
||||||
}
|
}
|
||||||
sf2d_end_frame();
|
renderWeather(getLocalPlayer()->entity.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() {
|
void exitGame() {
|
||||||
networkDisconnect();
|
networkDisconnect();
|
||||||
synchronizerReset();
|
synchronizerReset();
|
||||||
|
|
||||||
sf2d_set_clear_color(0xFF);
|
sf2d_set_clear_color(0xFF);
|
||||||
currentSelection = 0;
|
currentSelection = 0;
|
||||||
currentMenu = MENU_TITLE;
|
currentMenu = MENU_TITLE;
|
||||||
|
|
||||||
playMusic(&music_menu);
|
playMusic(&music_menu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,104 +10,104 @@
|
||||||
char pOptions[][24] = {"Return to game", "Save Progress", "Exit to title"};
|
char pOptions[][24] = {"Return to game", "Save Progress", "Exit to title"};
|
||||||
|
|
||||||
void ingameMenuTick(PlayerData *pd, int menu) {
|
void ingameMenuTick(PlayerData *pd, int menu) {
|
||||||
switch(menu) {
|
switch(menu) {
|
||||||
case MENU_PAUSED:
|
case MENU_PAUSED:
|
||||||
if(!pd->ingameMenuAreYouSure && !pd->ingameMenuAreYouSureSave){
|
if(!pd->ingameMenuAreYouSure && !pd->ingameMenuAreYouSureSave){
|
||||||
if (pd->ingameMenuTimer > 0) --pd->ingameMenuTimer;
|
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_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_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_down.clicked) { ++pd->ingameMenuSelection; if(pd->ingameMenuSelection > 2) pd->ingameMenuSelection=0; }
|
||||||
if (pd->inputs.k_accept.clicked){
|
if (pd->inputs.k_accept.clicked){
|
||||||
switch(pd->ingameMenuSelection){
|
switch(pd->ingameMenuSelection){
|
||||||
case 0:
|
case 0:
|
||||||
pd->ingameMenu = MENU_NONE;
|
pd->ingameMenu = MENU_NONE;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if(!dungeonActive()) pd->ingameMenuAreYouSureSave = true;
|
if(!dungeonActive()) pd->ingameMenuAreYouSureSave = true;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
pd->ingameMenuAreYouSure = true;
|
pd->ingameMenuAreYouSure = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(pd->ingameMenuAreYouSureSave) {
|
} else if(pd->ingameMenuAreYouSureSave) {
|
||||||
if (pd->inputs.k_accept.clicked){
|
if (pd->inputs.k_accept.clicked){
|
||||||
pd->ingameMenuTimer = 60;
|
pd->ingameMenuTimer = 60;
|
||||||
|
|
||||||
if(playerLocalID==0) {
|
if(playerLocalID==0) {
|
||||||
saveWorld(currentFileName, &eManager, &worldData, players, playerCount);
|
saveWorld(currentFileName, &eManager, &worldData, players, playerCount);
|
||||||
}
|
}
|
||||||
pd->ingameMenuAreYouSureSave = false;
|
pd->ingameMenuAreYouSureSave = false;
|
||||||
pd->ingameMenuAreYouSure = false;
|
pd->ingameMenuAreYouSure = false;
|
||||||
} else if (pd->inputs.k_decline.clicked){
|
} else if (pd->inputs.k_decline.clicked){
|
||||||
pd->ingameMenuAreYouSureSave = false;
|
pd->ingameMenuAreYouSureSave = false;
|
||||||
pd->ingameMenuAreYouSure = false;
|
pd->ingameMenuAreYouSure = false;
|
||||||
}
|
}
|
||||||
} else if(pd->ingameMenuAreYouSure) {
|
} else if(pd->ingameMenuAreYouSure) {
|
||||||
if (pd->inputs.k_accept.clicked){
|
if (pd->inputs.k_accept.clicked){
|
||||||
pd->ingameMenuAreYouSure = false;
|
pd->ingameMenuAreYouSure = false;
|
||||||
pd->ingameMenuAreYouSureSave = false;
|
pd->ingameMenuAreYouSureSave = false;
|
||||||
|
|
||||||
exitGame();
|
exitGame();
|
||||||
} else if (pd->inputs.k_decline.clicked){
|
} else if (pd->inputs.k_decline.clicked){
|
||||||
pd->ingameMenuAreYouSure = false;
|
pd->ingameMenuAreYouSure = false;
|
||||||
pd->ingameMenuAreYouSureSave = false;
|
pd->ingameMenuAreYouSureSave = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MENU_INVENTORY:
|
case MENU_INVENTORY:
|
||||||
if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked){
|
if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked){
|
||||||
pd->ingameMenu = MENU_NONE;
|
pd->ingameMenu = MENU_NONE;
|
||||||
pd->activeItem = &noItem;
|
pd->activeItem = &noItem;
|
||||||
pd->entity.p.isCarrying = false;
|
pd->entity.p.isCarrying = false;
|
||||||
}
|
}
|
||||||
if (pd->inputs.k_accept.clicked){ // Select item from inventory
|
if (pd->inputs.k_accept.clicked){ // Select item from inventory
|
||||||
if(pd->inventory.lastSlot!=0){
|
if(pd->inventory.lastSlot!=0){
|
||||||
Item median = pd->inventory.items[pd->ingameMenuInvSel]; // create copy of item.
|
Item median = pd->inventory.items[pd->ingameMenuInvSel]; // create copy of item.
|
||||||
removeItemFromInventory(pd->ingameMenuInvSel, &(pd->inventory)); // remove original
|
removeItemFromInventory(pd->ingameMenuInvSel, &(pd->inventory)); // remove original
|
||||||
pushItemToInventoryFront(median, &(pd->inventory)); // add copy to front
|
pushItemToInventoryFront(median, &(pd->inventory)); // add copy to front
|
||||||
playerSetActiveItem(pd, &(pd->inventory.items[0])); // active item = copy.
|
playerSetActiveItem(pd, &(pd->inventory.items[0])); // active item = copy.
|
||||||
}
|
}
|
||||||
pd->ingameMenu = MENU_NONE;
|
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_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; }
|
if (pd->inputs.k_down.clicked) { ++pd->ingameMenuInvSel; if(pd->ingameMenuInvSel > pd->inventory.lastSlot-1)pd->ingameMenuInvSel=0; }
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_CRAFTING:
|
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_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) {
|
if (pd->inputs.k_left.clicked) {
|
||||||
pd->curChestEntityR = 0;
|
pd->curChestEntityR = 0;
|
||||||
int tmp = pd->ingameMenuInvSel;
|
int tmp = pd->ingameMenuInvSel;
|
||||||
|
@ -120,7 +120,7 @@ void ingameMenuTick(PlayerData *pd, int menu) {
|
||||||
pd->ingameMenuInvSel = pd->ingameMenuInvSelOther;
|
pd->ingameMenuInvSel = pd->ingameMenuInvSelOther;
|
||||||
pd->ingameMenuInvSelOther = tmp;
|
pd->ingameMenuInvSelOther = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Inventory* i1 = pd->curChestEntityR == 1 ? &(pd->inventory) : pd->curChestEntity->entityFurniture.inv;
|
Inventory* i1 = pd->curChestEntityR == 1 ? &(pd->inventory) : pd->curChestEntity->entityFurniture.inv;
|
||||||
Inventory* i2 = pd->curChestEntityR == 0 ? &(pd->inventory) : pd->curChestEntity->entityFurniture.inv;
|
Inventory* i2 = pd->curChestEntityR == 0 ? &(pd->inventory) : pd->curChestEntity->entityFurniture.inv;
|
||||||
int len = i1->lastSlot;
|
int len = i1->lastSlot;
|
||||||
|
@ -131,7 +131,7 @@ void ingameMenuTick(PlayerData *pd, int menu) {
|
||||||
if (len == 0) pd->ingameMenuInvSel = 0;
|
if (len == 0) pd->ingameMenuInvSel = 0;
|
||||||
if (pd->ingameMenuInvSel < 0) pd->ingameMenuInvSel += len;
|
if (pd->ingameMenuInvSel < 0) pd->ingameMenuInvSel += len;
|
||||||
if (pd->ingameMenuInvSel >= len) pd->ingameMenuInvSel -= len;
|
if (pd->ingameMenuInvSel >= len) pd->ingameMenuInvSel -= len;
|
||||||
|
|
||||||
if(pd->inputs.k_accept.clicked && len > 0){
|
if(pd->inputs.k_accept.clicked && len > 0){
|
||||||
Item* pullItem = &i1->items[pd->ingameMenuInvSel];
|
Item* pullItem = &i1->items[pd->ingameMenuInvSel];
|
||||||
Item pushItem = newItem(pullItem->id, pullItem->countLevel);
|
Item pushItem = newItem(pullItem->id, pullItem->countLevel);
|
||||||
|
@ -146,11 +146,11 @@ void ingameMenuTick(PlayerData *pd, int menu) {
|
||||||
removeItemFromCurrentInv(pullItem);
|
removeItemFromCurrentInv(pullItem);
|
||||||
if (pd->ingameMenuInvSel >= i1->lastSlot) pd->ingameMenuInvSel = i1->lastSlot - 1;
|
if (pd->ingameMenuInvSel >= i1->lastSlot) pd->ingameMenuInvSel = i1->lastSlot - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_DUNGEON:
|
case MENU_DUNGEON:
|
||||||
if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE;
|
if (pd->inputs.k_menu.clicked || pd->inputs.k_decline.clicked) pd->ingameMenu = MENU_NONE;
|
||||||
|
|
||||||
if(pd->inputs.k_accept.clicked) {
|
if(pd->inputs.k_accept.clicked) {
|
||||||
if(pd->entity.level!=5) {
|
if(pd->entity.level!=5) {
|
||||||
Item * item = getItemFromInventory(ITEM_DUNGEON_KEY, &(pd->inventory));
|
Item * item = getItemFromInventory(ITEM_DUNGEON_KEY, &(pd->inventory));
|
||||||
|
@ -159,68 +159,68 @@ void ingameMenuTick(PlayerData *pd, int menu) {
|
||||||
if(item->countLevel==0) {
|
if(item->countLevel==0) {
|
||||||
removeItemFromCurrentInv(item);
|
removeItemFromCurrentInv(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
enterDungeon(pd);
|
enterDungeon(pd);
|
||||||
} else if(shouldRenderDebug) {
|
} else if(shouldRenderDebug) {
|
||||||
enterDungeon(pd);
|
enterDungeon(pd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
leaveDungeon(pd);
|
leaveDungeon(pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
pd->ingameMenu = MENU_NONE;
|
pd->ingameMenu = MENU_NONE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_NPC:
|
case MENU_NPC:
|
||||||
tickNPCMenu(pd);
|
tickNPCMenu(pd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_CHARACTER_CUSTOMIZE:
|
case MENU_CHARACTER_CUSTOMIZE:
|
||||||
if (pd->inputs.k_up.clicked) { --pd->ingameMenuSelection; if(pd->ingameMenuSelection < 0) pd->ingameMenuSelection=6; }
|
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; }
|
if (pd->inputs.k_down.clicked) { ++pd->ingameMenuSelection; if(pd->ingameMenuSelection > 6) pd->ingameMenuSelection=0; }
|
||||||
|
|
||||||
u8 wrap = 0;
|
u8 wrap = 0;
|
||||||
wrap = wrap - 1;
|
wrap = wrap - 1;
|
||||||
|
|
||||||
pd->entity.p.health = 10;
|
pd->entity.p.health = 10;
|
||||||
pd->entity.hurtTime = 10;
|
pd->entity.hurtTime = 10;
|
||||||
|
|
||||||
//head
|
//head
|
||||||
if(pd->ingameMenuSelection==0) {
|
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_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; }
|
if (pd->inputs.k_right.clicked) { ++pd->sprite.head; if(pd->sprite.head > PLAYER_SPRITE_HEAD_COUNT-1) pd->sprite.head=0; }
|
||||||
//eyes
|
//eyes
|
||||||
} else if(pd->ingameMenuSelection==1) {
|
} 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_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; }
|
if (pd->inputs.k_right.clicked) { ++pd->sprite.eyes; if(pd->sprite.eyes > PLAYER_SPRITE_EYES_COUNT-1) pd->sprite.eyes=0; }
|
||||||
//body
|
//body
|
||||||
} else if(pd->ingameMenuSelection==2) {
|
} 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_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; }
|
if (pd->inputs.k_right.clicked) { ++pd->sprite.body; if(pd->sprite.body > PLAYER_SPRITE_BODY_COUNT-1) pd->sprite.body=0; }
|
||||||
//arms
|
//arms
|
||||||
} else if(pd->ingameMenuSelection==3) {
|
} 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_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; }
|
if (pd->inputs.k_right.clicked) { ++pd->sprite.arms; if(pd->sprite.arms > PLAYER_SPRITE_ARMS_COUNT-1) pd->sprite.arms=0; }
|
||||||
//legs
|
//legs
|
||||||
} else if(pd->ingameMenuSelection==4) {
|
} 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_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; }
|
if (pd->inputs.k_right.clicked) { ++pd->sprite.legs; if(pd->sprite.legs > PLAYER_SPRITE_LEGS_COUNT-1) pd->sprite.legs=0; }
|
||||||
//rotation
|
//rotation
|
||||||
} else if(pd->ingameMenuSelection==5) {
|
} 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_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; }
|
if (pd->inputs.k_right.clicked) { ++pd->entity.p.dir; if(pd->entity.p.dir > 3) pd->entity.p.dir=0; }
|
||||||
//done
|
//done
|
||||||
} else if(pd->ingameMenuSelection==6) {
|
} else if(pd->ingameMenuSelection==6) {
|
||||||
if(pd->inputs.k_accept.clicked) {
|
if(pd->inputs.k_accept.clicked) {
|
||||||
//TODO: are you sure dialog?
|
//TODO: are you sure dialog?
|
||||||
pd->ingameMenu = 0;
|
pd->ingameMenu = 0;
|
||||||
pd->ingameMenuSelection = 0;
|
pd->ingameMenuSelection = 0;
|
||||||
pd->sprite.choosen = true;
|
pd->sprite.choosen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,291 +229,291 @@ bool rev = true;
|
||||||
char scoreText[15];
|
char scoreText[15];
|
||||||
|
|
||||||
void ingameMenuRender(PlayerData *pd, int menu) {
|
void ingameMenuRender(PlayerData *pd, int menu) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch(menu) {
|
switch(menu) {
|
||||||
case MENU_PAUSED:
|
case MENU_PAUSED:
|
||||||
renderFrame(1,1,24,14,0xFF1010AF);
|
renderFrame(1,1,24,14,0xFF1010AF);
|
||||||
drawText("Paused",164,32);
|
drawText("Paused",164,32);
|
||||||
for(i = 3; i >= 0; --i){
|
for(i = 3; i >= 0; --i){
|
||||||
char* msg = pOptions[i];
|
char* msg = pOptions[i];
|
||||||
u32 color = 0xFF7F7F7F;
|
u32 color = 0xFF7F7F7F;
|
||||||
if(i == pd->ingameMenuSelection) color = 0xFFFFFFFF;
|
if(i == pd->ingameMenuSelection) color = 0xFFFFFFFF;
|
||||||
if((i == 1 && dungeonActive())) {
|
if((i == 1 && dungeonActive())) {
|
||||||
color = 0xFF7F7FFF;
|
color = 0xFF7F7FFF;
|
||||||
if(i == pd->ingameMenuSelection) color = 0xFFAFAFFF;
|
if(i == pd->ingameMenuSelection) color = 0xFFAFAFFF;
|
||||||
}
|
}
|
||||||
drawTextColor(msg,(400 - (strlen(msg) * 12))/2, (i * 24) + 88, color);
|
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->ingameMenuTimer > 0) drawTextColor("Game Saved!", (400-(11*12))/2, 64,0xFF20FF20);
|
||||||
|
|
||||||
if(pd->ingameMenuAreYouSure || pd->ingameMenuAreYouSureSave){
|
if(pd->ingameMenuAreYouSure || pd->ingameMenuAreYouSureSave){
|
||||||
if(pd->ingameMenuAreYouSure)renderFrame(6,5,19,10,0xFF10108F);
|
if(pd->ingameMenuAreYouSure)renderFrame(6,5,19,10,0xFF10108F);
|
||||||
else renderFrame(6,5,19,10,0xFF108F10);
|
else renderFrame(6,5,19,10,0xFF108F10);
|
||||||
|
|
||||||
drawText("Are you sure?",122,96);
|
drawText("Are you sure?",122,96);
|
||||||
drawText(" Yes", 164, 117);
|
drawText(" Yes", 164, 117);
|
||||||
renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 166, 114, 1);
|
renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 166, 114, 1);
|
||||||
drawText(" No", 170, 133);
|
drawText(" No", 170, 133);
|
||||||
renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 166, 130, 1);
|
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(amnt<ttlCst) col = 0xFF7F7F7F;
|
|
||||||
renderItemIcon(rec->costs[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;
|
break;
|
||||||
|
case MENU_WIN:
|
||||||
case MENU_NPC:
|
renderFrame(5,3,21,12,0xFFFF1010);
|
||||||
renderNPCMenu(&(pd->npcMenuData));
|
if(!rev){ opacity+=5; if(opacity == 255) rev = true; }
|
||||||
break;
|
else { opacity-=5; if(opacity == 100) rev = false; }
|
||||||
|
sprintf(scoreText,"Score: %d", pd->score);
|
||||||
case MENU_CHARACTER_CUSTOMIZE:
|
drawTextColor("You Win!",158,76,0x0000AFAF + (opacity << 24));
|
||||||
renderFrame(1,1,24,14,0xFFFF1010);
|
drawText(scoreText, 200-((strlen(scoreText)-1)*6), 100);
|
||||||
drawTextColor("Character",24+1,14+1,0xFF000000);
|
drawText("Press to continue", 96, 150);
|
||||||
drawTextColor("Character",24,14,0xFF6FE2E2);
|
renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 166, 148, 1);
|
||||||
|
|
||||||
drawText("Head: ", 32, 56);
|
//printf("0x%08X",localInputs.k_attack.input & -localInputs.k_attack.input);
|
||||||
drawText("Eyes: ", 32, 72);
|
break;
|
||||||
drawText("Body: ", 32, 88);
|
case MENU_LOSE:
|
||||||
drawText("Arms: ", 32, 104);
|
renderFrame(5,3,21,12,0xFFFF1010);
|
||||||
drawText("Legs: ", 32, 120);
|
if(!rev){ opacity+=5; if(opacity == 255) rev = true; }
|
||||||
drawText("Rot.: ", 32, 144);
|
else { opacity-=5; if(opacity == 100) rev = false; }
|
||||||
|
sprintf(scoreText,"Score: %d", pd->score);
|
||||||
//for the dynamic part
|
drawTextColor("You DIED!",158,76,0x000000AF + (opacity << 24));
|
||||||
char display[30];
|
drawText(scoreText, 200-((strlen(scoreText)-1)*6), 100);
|
||||||
|
drawText("Press to continue", 96, 150);
|
||||||
sprintf(display, pd->ingameMenuSelection==0 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.head+1, PLAYER_SPRITE_HEAD_COUNT);
|
renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 166, 148, 1);
|
||||||
drawText(display, 96, 56);
|
//printf("0x%08X",localInputs.k_attack.input & -localInputs.k_attack.input);
|
||||||
sprintf(display, pd->ingameMenuSelection==1 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.eyes+1, PLAYER_SPRITE_EYES_COUNT);
|
break;
|
||||||
drawText(display, 96, 72);
|
case MENU_INVENTORY:
|
||||||
sprintf(display, pd->ingameMenuSelection==2 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.body+1, PLAYER_SPRITE_BODY_COUNT);
|
renderFrame(1,1,24,14,0xFFFF1010);
|
||||||
drawText(display, 96, 88);
|
drawTextColor("Inventory",24+1,14+1,0xFF000000);
|
||||||
sprintf(display, pd->ingameMenuSelection==3 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.arms+1, PLAYER_SPRITE_ARMS_COUNT);
|
drawTextColor("Inventory",24,14,0xFF6FE2E2);
|
||||||
drawText(display, 96, 104);
|
renderItemList(&(pd->inventory), 1,1,24,14, pd->ingameMenuInvSel);
|
||||||
sprintf(display, pd->ingameMenuSelection==4 ? "< %02i/%02i >" : " %02i/%02i ", pd->sprite.legs+1, PLAYER_SPRITE_LEGS_COUNT);
|
break;
|
||||||
drawText(display, 96, 120);
|
case MENU_CRAFTING:
|
||||||
sprintf(display, pd->ingameMenuSelection==5 ? "< %02i/%02i >" : " %02i/%02i ", pd->entity.p.dir+1, 4);
|
renderFrame(15,1,24,4,0xFFFF1010);
|
||||||
drawText(display, 96, 144);
|
drawTextColor("Have",248+1,14+1,0xFF000000);
|
||||||
sprintf(display, pd->ingameMenuSelection==6 ? "< Done >" : " Done ");
|
drawTextColor("Have",248,14,0xFF6FE2E2);
|
||||||
drawText(display, 96, 172);
|
renderFrame(15,5,24,14,0xFFFF1010);
|
||||||
|
drawTextColor("Cost",248+1,78+1,0xFF000000);
|
||||||
int oox = offsetX;
|
drawTextColor("Cost",248,78,0xFF6FE2E2);
|
||||||
int ooy = offsetY;
|
renderFrame(1,1,14,14,0xFFFF1010);
|
||||||
int osx = playerScale;
|
drawTextColor(pd->currentCraftTitle,24+1,14+1,0xFF000000);
|
||||||
|
drawTextColor(pd->currentCraftTitle,24,14,0xFF6FE2E2);
|
||||||
renderFrame(13,3,22,12,0xFF909090);
|
renderRecipes(&(pd->currentRecipes), 1, 1, 14, 14, pd->ingameMenuInvSel);
|
||||||
//move player sprite to 0/0
|
|
||||||
offsetX = pd->entity.x - 8;
|
Recipe* rec = &(pd->currentRecipes.recipes[pd->ingameMenuInvSel]);
|
||||||
offsetY = pd->entity.y - 8;
|
renderItemIcon(rec->itemResult,rec->itemAmountLevel,128,16);
|
||||||
//move to where I want it
|
char craftText[12];
|
||||||
offsetX -= 108;
|
sprintf(craftText, "%d", countItemInv(rec->itemResult, rec->itemAmountLevel, &(pd->inventory)));
|
||||||
offsetY -= 28;
|
drawText(craftText,274,34);
|
||||||
playerScale = 8;
|
|
||||||
renderPlayer(pd);
|
if(rec->numOfCosts > 0){
|
||||||
|
int i;
|
||||||
offsetX = oox;
|
for(i = 0; i < rec->numOfCosts; i++){
|
||||||
offsetY = ooy;
|
int amnt = countItemInv(rec->costs[i].costItem,0, &(pd->inventory));
|
||||||
playerScale = osx;
|
int ttlCst = rec->costs[i].costAmount;
|
||||||
break;
|
int col = 0xFFFFFFFF; if(amnt<ttlCst) col = 0xFF7F7F7F;
|
||||||
}
|
renderItemIcon(rec->costs[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
|
//touch menu
|
||||||
void tickTouchMap(PlayerData *pd){
|
void tickTouchMap(PlayerData *pd){
|
||||||
if(pd->mapShouldRender){
|
if(pd->mapShouldRender){
|
||||||
if(pd->inputs.k_touch.px > 0 || pd->inputs.k_touch.py > 0){
|
if(pd->inputs.k_touch.px > 0 || pd->inputs.k_touch.py > 0){
|
||||||
// Plus/Minus zoom button
|
// Plus/Minus zoom button
|
||||||
if(pd->inputs.k_touch.py > 204 && pd->inputs.k_touch.py < 232){
|
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->inputs.k_touch.px > 284 && pd->inputs.k_touch.px < 312){
|
||||||
if(pd->mapZoomLevel > 4) return;
|
if(pd->mapZoomLevel > 4) return;
|
||||||
if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){
|
if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){
|
||||||
pd->mapZoomLevel += 2;
|
pd->mapZoomLevel += 2;
|
||||||
pd->mapScrollX -= (50 * (pd->mapZoomLevel/2));
|
pd->mapScrollX -= (50 * (pd->mapZoomLevel/2));
|
||||||
pd->mapScrollY -= (40 * (pd->mapZoomLevel/2));
|
pd->mapScrollY -= (40 * (pd->mapZoomLevel/2));
|
||||||
pd->touchIsChangingSize = true;
|
pd->touchIsChangingSize = true;
|
||||||
sprintf(pd->mapText, "x%d", pd->mapZoomLevel);
|
sprintf(pd->mapText, "x%d", pd->mapZoomLevel);
|
||||||
}
|
}
|
||||||
if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel);
|
if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel);
|
||||||
else if(pd->mapScrollX > 0) pd->mapScrollX = 0;
|
else if(pd->mapScrollX > 0) pd->mapScrollX = 0;
|
||||||
if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel);
|
if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel);
|
||||||
else if(pd->mapScrollY > 0) pd->mapScrollY = 0;
|
else if(pd->mapScrollY > 0) pd->mapScrollY = 0;
|
||||||
return;
|
return;
|
||||||
} else if(pd->inputs.k_touch.px > 256 && pd->inputs.k_touch.px < 284){
|
} else if(pd->inputs.k_touch.px > 256 && pd->inputs.k_touch.px < 284){
|
||||||
if(pd->mapZoomLevel < 4) return;
|
if(pd->mapZoomLevel < 4) return;
|
||||||
if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){
|
if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){
|
||||||
pd->mapScrollX += (50 * (pd->mapZoomLevel/2));
|
pd->mapScrollX += (50 * (pd->mapZoomLevel/2));
|
||||||
pd->mapScrollY += (40 * (pd->mapZoomLevel/2));
|
pd->mapScrollY += (40 * (pd->mapZoomLevel/2));
|
||||||
pd->mapZoomLevel -= 2;
|
pd->mapZoomLevel -= 2;
|
||||||
pd->touchIsChangingSize = true;
|
pd->touchIsChangingSize = true;
|
||||||
sprintf(pd->mapText, "x%d", pd->mapZoomLevel);
|
sprintf(pd->mapText, "x%d", pd->mapZoomLevel);
|
||||||
}
|
}
|
||||||
if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel);
|
if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel);
|
||||||
else if(pd->mapScrollX > 0) pd->mapScrollX = 0;
|
else if(pd->mapScrollX > 0) pd->mapScrollX = 0;
|
||||||
if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel);
|
if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel);
|
||||||
else if(pd->mapScrollY > 0) pd->mapScrollY = 0;
|
else if(pd->mapScrollY > 0) pd->mapScrollY = 0;
|
||||||
return;
|
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){
|
} 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
|
// Exit Button
|
||||||
if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){
|
if(!pd->touchIsChangingSize && !pd->touchIsDraggingMap){
|
||||||
pd->mapShouldRender = false;
|
pd->mapShouldRender = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!pd->touchIsDraggingMap){
|
if(!pd->touchIsDraggingMap){
|
||||||
pd->touchLastX = pd->inputs.k_touch.px;
|
pd->touchLastX = pd->inputs.k_touch.px;
|
||||||
pd->touchLastY = pd->inputs.k_touch.py;
|
pd->touchLastY = pd->inputs.k_touch.py;
|
||||||
}
|
}
|
||||||
if(pd->mapZoomLevel > 2){
|
if(pd->mapZoomLevel > 2){
|
||||||
int dx = pd->touchLastX - pd->inputs.k_touch.px;
|
int dx = pd->touchLastX - pd->inputs.k_touch.px;
|
||||||
if(dx > 1 || dx < -1){
|
if(dx > 1 || dx < -1){
|
||||||
pd->mapScrollX -= dx;
|
pd->mapScrollX -= dx;
|
||||||
if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel);
|
if(pd->mapScrollX < 320-(128*pd->mapZoomLevel)) pd->mapScrollX = 320-(128*pd->mapZoomLevel);
|
||||||
else if(pd->mapScrollX > 0) pd->mapScrollX = 0;
|
else if(pd->mapScrollX > 0) pd->mapScrollX = 0;
|
||||||
}
|
}
|
||||||
pd->touchLastX = pd->inputs.k_touch.px;
|
pd->touchLastX = pd->inputs.k_touch.px;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dy = pd->touchLastY - pd->inputs.k_touch.py;
|
int dy = pd->touchLastY - pd->inputs.k_touch.py;
|
||||||
if(dy > 1 || dy < -1){
|
if(dy > 1 || dy < -1){
|
||||||
pd->mapScrollY -= dy;
|
pd->mapScrollY -= dy;
|
||||||
if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel);
|
if(pd->mapScrollY < 240-(128*pd->mapZoomLevel)) pd->mapScrollY = 240-(128*pd->mapZoomLevel);
|
||||||
else if(pd->mapScrollY > 0) pd->mapScrollY = 0;
|
else if(pd->mapScrollY > 0) pd->mapScrollY = 0;
|
||||||
}
|
}
|
||||||
pd->touchLastY = pd->inputs.k_touch.py;
|
pd->touchLastY = pd->inputs.k_touch.py;
|
||||||
pd->touchIsDraggingMap = true;
|
pd->touchIsDraggingMap = true;
|
||||||
} else {
|
} else {
|
||||||
pd->touchIsDraggingMap = false;
|
pd->touchIsDraggingMap = false;
|
||||||
pd->touchIsChangingSize = false;
|
pd->touchIsChangingSize = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// touch minimap to bring up zoomed map.
|
// 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){
|
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;
|
pd->mapShouldRender = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tickTouchQuickSelect(PlayerData *pd) {
|
void tickTouchQuickSelect(PlayerData *pd) {
|
||||||
if (pd->ingameMenu == MENU_NONE && !pd->mapShouldRender) {
|
if (pd->ingameMenu == MENU_NONE && !pd->mapShouldRender) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Inventory * inv = &(pd->inventory);
|
Inventory * inv = &(pd->inventory);
|
||||||
|
|
||||||
for (i = 0; i < 8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
if((inv->lastSlot) > i) {
|
if((inv->lastSlot) > i) {
|
||||||
int xip = i % 4;
|
int xip = i % 4;
|
||||||
int yip = 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) {
|
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]);
|
playerSetActiveItem(pd, &inv->items[i]);
|
||||||
}
|
}
|
||||||
|
@ -523,6 +523,6 @@ void tickTouchQuickSelect(PlayerData *pd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ingameMenuTickTouch(PlayerData *pd) {
|
void ingameMenuTickTouch(PlayerData *pd) {
|
||||||
tickTouchMap(pd);
|
tickTouchMap(pd);
|
||||||
tickTouchQuickSelect(pd);
|
tickTouchQuickSelect(pd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,55 @@
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
|
|
||||||
void toggleKey(Key* key, bool held, bool down){
|
void toggleKey(Key* key, bool held, bool down){
|
||||||
key->down = held;
|
key->down = held;
|
||||||
key->clicked = down;
|
key->clicked = down;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tickKeys(Inputs *inputs, u32 held, u32 down){
|
void tickKeys(Inputs *inputs, u32 held, u32 down){
|
||||||
hidTouchRead(&(inputs->k_touch)); // Update touch position
|
hidTouchRead(&(inputs->k_touch)); // Update touch position
|
||||||
toggleKey(&(inputs->k_up), held & localInputs.k_up.input, down & localInputs.k_up.input);
|
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_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_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_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_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_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_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_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_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_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_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);
|
toggleKey(&(inputs->k_menuPrev), held & localInputs.k_menuPrev.input, down & localInputs.k_menuPrev.input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetKeys(Inputs *inputs) {
|
void resetKeys(Inputs *inputs) {
|
||||||
(inputs->k_touch).px = -1;
|
(inputs->k_touch).px = -1;
|
||||||
(inputs->k_touch).py = -1;
|
(inputs->k_touch).py = -1;
|
||||||
|
|
||||||
toggleKey(&(inputs->k_up), false, false);
|
toggleKey(&(inputs->k_up), false, false);
|
||||||
toggleKey(&(inputs->k_down), false, false);
|
toggleKey(&(inputs->k_down), false, false);
|
||||||
toggleKey(&(inputs->k_left), false, false);
|
toggleKey(&(inputs->k_left), false, false);
|
||||||
toggleKey(&(inputs->k_right), false, false);
|
toggleKey(&(inputs->k_right), false, false);
|
||||||
toggleKey(&(inputs->k_pause), false, false);
|
toggleKey(&(inputs->k_pause), false, false);
|
||||||
toggleKey(&(inputs->k_attack), false, false);
|
toggleKey(&(inputs->k_attack), false, false);
|
||||||
toggleKey(&(inputs->k_menu), false, false);
|
toggleKey(&(inputs->k_menu), false, false);
|
||||||
toggleKey(&(inputs->k_accept), false, false);
|
toggleKey(&(inputs->k_accept), false, false);
|
||||||
toggleKey(&(inputs->k_decline), false, false);
|
toggleKey(&(inputs->k_decline), false, false);
|
||||||
toggleKey(&(inputs->k_delete), false, false);
|
toggleKey(&(inputs->k_delete), false, false);
|
||||||
toggleKey(&(inputs->k_menuNext), false, false);
|
toggleKey(&(inputs->k_menuNext), false, false);
|
||||||
toggleKey(&(inputs->k_menuPrev), false, false);
|
toggleKey(&(inputs->k_menuPrev), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetClicked(Inputs *inputs) {
|
void resetClicked(Inputs *inputs) {
|
||||||
inputs->k_up.clicked = false;
|
inputs->k_up.clicked = false;
|
||||||
inputs->k_down.clicked = false;
|
inputs->k_down.clicked = false;
|
||||||
inputs->k_left.clicked = false;
|
inputs->k_left.clicked = false;
|
||||||
inputs->k_right.clicked = false;
|
inputs->k_right.clicked = false;
|
||||||
inputs->k_pause.clicked = false;
|
inputs->k_pause.clicked = false;
|
||||||
inputs->k_attack.clicked = false;
|
inputs->k_attack.clicked = false;
|
||||||
inputs->k_menu.clicked = false;
|
inputs->k_menu.clicked = false;
|
||||||
inputs->k_accept.clicked = false;
|
inputs->k_accept.clicked = false;
|
||||||
inputs->k_decline.clicked = false;
|
inputs->k_decline.clicked = false;
|
||||||
inputs->k_delete.clicked = false;
|
inputs->k_delete.clicked = false;
|
||||||
inputs->k_menuNext.clicked = false;
|
inputs->k_menuNext.clicked = false;
|
||||||
inputs->k_menuPrev.clicked = false;
|
inputs->k_menuPrev.clicked = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,20 +9,20 @@ typedef struct {
|
||||||
} Key;
|
} Key;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Key k_null;
|
Key k_null;
|
||||||
Key k_up;
|
Key k_up;
|
||||||
Key k_down;
|
Key k_down;
|
||||||
Key k_left;
|
Key k_left;
|
||||||
Key k_right;
|
Key k_right;
|
||||||
Key k_attack;
|
Key k_attack;
|
||||||
Key k_menu;
|
Key k_menu;
|
||||||
Key k_pause;
|
Key k_pause;
|
||||||
Key k_accept;
|
Key k_accept;
|
||||||
Key k_decline;
|
Key k_decline;
|
||||||
Key k_delete;
|
Key k_delete;
|
||||||
Key k_menuNext;
|
Key k_menuNext;
|
||||||
Key k_menuPrev;
|
Key k_menuPrev;
|
||||||
touchPosition k_touch;
|
touchPosition k_touch;
|
||||||
} Inputs;
|
} Inputs;
|
||||||
|
|
||||||
Inputs localInputs;
|
Inputs localInputs;
|
||||||
|
|
446
source/Item.c
446
source/Item.c
|
@ -3,168 +3,168 @@
|
||||||
char currentName[16];
|
char currentName[16];
|
||||||
|
|
||||||
bool isItemEmpty(Item* item) {
|
bool isItemEmpty(Item* item) {
|
||||||
if(item->id < 6 || item->id > 100 || item->onlyOne == true) return false;
|
if(item->id < 6 || item->id > 100 || item->onlyOne == true) return false;
|
||||||
if(item->countLevel < 1) return true;
|
if(item->countLevel < 1) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushItemToInventoryFront(Item item, Inventory * inv) {
|
void pushItemToInventoryFront(Item item, Inventory * inv) {
|
||||||
if(inv->lastSlot < 300) ++inv->lastSlot;
|
if(inv->lastSlot < 300) ++inv->lastSlot;
|
||||||
int i;
|
int i;
|
||||||
for(i = inv->lastSlot;i > 0;--i){
|
for(i = inv->lastSlot;i > 0;--i){
|
||||||
inv->items[i] = inv->items[i-1]; // Move the items up the list.
|
inv->items[i] = inv->items[i-1]; // Move the items up the list.
|
||||||
inv->items[i].slotNum = i;
|
inv->items[i].slotNum = i;
|
||||||
}
|
}
|
||||||
item.invPtr = (int*)inv;
|
item.invPtr = (int*)inv;
|
||||||
inv->items[0] = item;
|
inv->items[0] = item;
|
||||||
inv->items[0].slotNum = 0;
|
inv->items[0].slotNum = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addItemToInventory(Item item, Inventory * inv) {
|
void addItemToInventory(Item item, Inventory * inv) {
|
||||||
if(!item.onlyOne){
|
if(!item.onlyOne){
|
||||||
int i;
|
int i;
|
||||||
for(i = 0;i < inv->lastSlot;++i){ //Search inventory if item already exists.
|
for(i = 0;i < inv->lastSlot;++i){ //Search inventory if item already exists.
|
||||||
if(inv->items[i].id == item.id){
|
if(inv->items[i].id == item.id){
|
||||||
inv->items[i].countLevel+=item.countLevel;
|
inv->items[i].countLevel+=item.countLevel;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item.slotNum = inv->lastSlot;
|
item.slotNum = inv->lastSlot;
|
||||||
item.invPtr = (int*)inv;
|
item.invPtr = (int*)inv;
|
||||||
inv->items[inv->lastSlot] = item;
|
inv->items[inv->lastSlot] = item;
|
||||||
++inv->lastSlot;
|
++inv->lastSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeItemFromCurrentInv(Item* item) {
|
void removeItemFromCurrentInv(Item* item) {
|
||||||
removeItemFromInventory(item->slotNum, (Inventory*)item->invPtr);
|
removeItemFromInventory(item->slotNum, (Inventory*)item->invPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Item nullItem;
|
Item nullItem;
|
||||||
void removeItemFromInventory(int slot, Inventory * inv) {
|
void removeItemFromInventory(int slot, Inventory * inv) {
|
||||||
int i;
|
int i;
|
||||||
for(i = slot;i < inv->lastSlot - 1;++i){
|
for(i = slot;i < inv->lastSlot - 1;++i){
|
||||||
inv->items[i] = inv->items[i + 1]; // Move the items down.
|
inv->items[i] = inv->items[i + 1]; // Move the items down.
|
||||||
inv->items[i].slotNum--;
|
inv->items[i].slotNum--;
|
||||||
}
|
}
|
||||||
--inv->lastSlot;
|
--inv->lastSlot;
|
||||||
inv->items[inv->lastSlot] = nullItem; // Make the last slot null.
|
inv->items[inv->lastSlot] = nullItem; // Make the last slot null.
|
||||||
}
|
}
|
||||||
|
|
||||||
Item newItem(int id, int cLevel) {
|
Item newItem(int id, int cLevel) {
|
||||||
Item item;
|
Item item;
|
||||||
item.id = id;
|
item.id = id;
|
||||||
if(id != ITEM_NULL){
|
if(id != ITEM_NULL){
|
||||||
if(cLevel > 999) cLevel = 999;
|
if(cLevel > 999) cLevel = 999;
|
||||||
item.countLevel = cLevel;
|
item.countLevel = cLevel;
|
||||||
if(id < 7 || (id > 27 && id < 51) || id > 100) item.onlyOne = true; // Tools + Furniture.
|
if(id < 7 || (id > 27 && id < 51) || id > 100) item.onlyOne = true; // Tools + Furniture.
|
||||||
else item.onlyOne = false;
|
else item.onlyOne = false;
|
||||||
}
|
}
|
||||||
item.chestPtr = NULL;
|
item.chestPtr = NULL;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
Item* getItemFromInventory(int itemID, Inventory * inv) {
|
Item* getItemFromInventory(int itemID, Inventory * inv) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0;i < inv->lastSlot;++i){
|
for(i = 0;i < inv->lastSlot;++i){
|
||||||
if(inv->items[i].id == itemID){
|
if(inv->items[i].id == itemID){
|
||||||
return &inv->items[i];
|
return &inv->items[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (Item*)NULL;
|
return (Item*)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int countItemInv(int itemID, int level, Inventory* inv) {
|
int countItemInv(int itemID, int level, Inventory* inv) {
|
||||||
int i, count = 0;
|
int i, count = 0;
|
||||||
for(i = 0;i < inv->lastSlot;++i){
|
for(i = 0;i < inv->lastSlot;++i){
|
||||||
if(inv->items[i].id == itemID){
|
if(inv->items[i].id == itemID){
|
||||||
if(inv->items[i].onlyOne){
|
if(inv->items[i].onlyOne){
|
||||||
if(level == inv->items[i].countLevel) count++;
|
if(level == inv->items[i].countLevel) count++;
|
||||||
} else count += inv->items[i].countLevel;
|
} else count += inv->items[i].countLevel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* getItemName(int itemID, int countLevel) {
|
char* getItemName(int itemID, int countLevel) {
|
||||||
switch(itemID){
|
switch(itemID){
|
||||||
case TOOL_SHOVEL:
|
case TOOL_SHOVEL:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Shovel";
|
case 1: return "Rock Shovel";
|
||||||
case 2: return "Iron Shovel";
|
case 2: return "Iron Shovel";
|
||||||
case 3: return "Gold Shovel";
|
case 3: return "Gold Shovel";
|
||||||
case 4: return "Gem Shovel";
|
case 4: return "Gem Shovel";
|
||||||
default: return "Wood Shovel";
|
default: return "Wood Shovel";
|
||||||
}
|
}
|
||||||
case TOOL_HOE:
|
case TOOL_HOE:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Hoe";
|
case 1: return "Rock Hoe";
|
||||||
case 2: return "Iron Hoe";
|
case 2: return "Iron Hoe";
|
||||||
case 3: return "Gold Hoe";
|
case 3: return "Gold Hoe";
|
||||||
case 4: return "Gem Hoe";
|
case 4: return "Gem Hoe";
|
||||||
default: return "Wood Hoe";
|
default: return "Wood Hoe";
|
||||||
}
|
}
|
||||||
case TOOL_SWORD:
|
case TOOL_SWORD:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Sword";
|
case 1: return "Rock Sword";
|
||||||
case 2: return "Iron Sword";
|
case 2: return "Iron Sword";
|
||||||
case 3: return "Gold Sword";
|
case 3: return "Gold Sword";
|
||||||
case 4: return "Gem Sword";
|
case 4: return "Gem Sword";
|
||||||
default: return "Wood Sword";
|
default: return "Wood Sword";
|
||||||
}
|
}
|
||||||
case TOOL_PICKAXE:
|
case TOOL_PICKAXE:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Pickaxe";
|
case 1: return "Rock Pickaxe";
|
||||||
case 2: return "Iron Pickaxe";
|
case 2: return "Iron Pickaxe";
|
||||||
case 3: return "Gold Pickaxe";
|
case 3: return "Gold Pickaxe";
|
||||||
case 4: return "Gem Pickaxe";
|
case 4: return "Gem Pickaxe";
|
||||||
default: return "Wood Pickaxe";
|
default: return "Wood Pickaxe";
|
||||||
}
|
}
|
||||||
case TOOL_AXE:
|
case TOOL_AXE:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Axe";
|
case 1: return "Rock Axe";
|
||||||
case 2: return "Iron Axe";
|
case 2: return "Iron Axe";
|
||||||
case 3: return "Gold Axe";
|
case 3: return "Gold Axe";
|
||||||
case 4: return "Gem Axe";
|
case 4: return "Gem Axe";
|
||||||
default: return "Wood Axe";
|
default: return "Wood Axe";
|
||||||
}
|
}
|
||||||
case ITEM_ANVIL: return "Anvil";
|
case ITEM_ANVIL: return "Anvil";
|
||||||
case ITEM_CHEST: return "Chest";
|
case ITEM_CHEST: return "Chest";
|
||||||
case ITEM_OVEN: return "Oven";
|
case ITEM_OVEN: return "Oven";
|
||||||
case ITEM_FURNACE: return "Furnace";
|
case ITEM_FURNACE: return "Furnace";
|
||||||
case ITEM_WORKBENCH: return "Workbench";
|
case ITEM_WORKBENCH: return "Workbench";
|
||||||
case ITEM_POTION_MAKER: return "Potion Maker";
|
case ITEM_POTION_MAKER: return "Potion Maker";
|
||||||
case ITEM_LANTERN: return "Lantern";
|
case ITEM_LANTERN: return "Lantern";
|
||||||
case ITEM_POWGLOVE: return "Power Glove";
|
case ITEM_POWGLOVE: return "Power Glove";
|
||||||
case ITEM_FLOWER: sprintf(currentName,"%d Flower", countLevel); return currentName;
|
case ITEM_FLOWER: sprintf(currentName,"%d Flower", countLevel); return currentName;
|
||||||
case ITEM_WOOD: sprintf(currentName,"%d Wood", 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_STONE: sprintf(currentName,"%d Stone", countLevel); return currentName;
|
||||||
case ITEM_SAND: sprintf(currentName,"%d Sand", 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_DIRT: sprintf(currentName,"%d Dirt", countLevel); return currentName;
|
||||||
case ITEM_CLOUD: sprintf(currentName,"%d Cloud", 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_ACORN: sprintf(currentName,"%d Acorn", countLevel); return currentName;
|
||||||
case ITEM_CACTUS: sprintf(currentName,"%d Cactus", 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_SEEDS: sprintf(currentName,"%d Seeds", countLevel); return currentName;
|
||||||
case ITEM_WHEAT: sprintf(currentName,"%d Wheat", 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_FLESH: sprintf(currentName,"%d Flesh", countLevel); return currentName;
|
||||||
case ITEM_BREAD: sprintf(currentName,"%d Bread", 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_APPLE: sprintf(currentName,"%d Apple", countLevel); return currentName;
|
||||||
case ITEM_GOLD_APPLE: sprintf(currentName,"%d Golden 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_STRENGTH_POTION: sprintf(currentName,"%d Strength Potion", countLevel); return currentName;
|
||||||
case ITEM_SPEED_POTION: sprintf(currentName,"%d Speed 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_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_SWIM_BREATH_POTION: sprintf(currentName,"%d Swim Potion", countLevel); return currentName;
|
||||||
case ITEM_COAL: sprintf(currentName,"%d Coal", 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_IRONORE: sprintf(currentName,"%d Iron ore", countLevel); return currentName;
|
||||||
case ITEM_GOLDORE: sprintf(currentName,"%d Gold 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_IRONINGOT: sprintf(currentName,"%d Iron ingot", countLevel); return currentName;
|
||||||
case ITEM_GOLDINGOT: sprintf(currentName,"%d Gold 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_GLASS: sprintf(currentName,"%d Glass", countLevel); return currentName;
|
||||||
case ITEM_GEM: sprintf(currentName,"%d Gem", countLevel); return currentName;
|
case ITEM_GEM: sprintf(currentName,"%d Gem", countLevel); return currentName;
|
||||||
case ITEM_SLIME: sprintf(currentName,"%d Slime", countLevel); return currentName;
|
case ITEM_SLIME: sprintf(currentName,"%d Slime", countLevel); return currentName;
|
||||||
|
|
||||||
case ITEM_LOOM: return "Loom";
|
case ITEM_LOOM: return "Loom";
|
||||||
case ITEM_ENCHANTER: return "Enchanter";
|
case ITEM_ENCHANTER: return "Enchanter";
|
||||||
case ITEM_WALL_WOOD: sprintf(currentName,"%d Wood Wall", countLevel); return currentName;
|
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_EGG: sprintf(currentName,"%d Dragon Egg", countLevel); return currentName;
|
||||||
case ITEM_DRAGON_SCALE: sprintf(currentName,"%d Dragon Scale", countLevel); return currentName;
|
case ITEM_DRAGON_SCALE: sprintf(currentName,"%d Dragon Scale", countLevel); return currentName;
|
||||||
case ITEM_BOOKSHELVES: sprintf(currentName,"%d Bookshelves", countLevel); return currentName;
|
case ITEM_BOOKSHELVES: sprintf(currentName,"%d Bookshelves", countLevel); return currentName;
|
||||||
case ITEM_MAGIC_DUST: sprintf(currentName,"%d Magic Dust", 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_COIN: sprintf(currentName,"%d Coins", countLevel); return currentName;
|
||||||
case TOOL_BUCKET:
|
case TOOL_BUCKET:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Water Bucket";
|
case 1: return "Water Bucket";
|
||||||
case 2: return "Lava Bucket";
|
case 2: return "Lava Bucket";
|
||||||
default: return "Empty Bucket";
|
default: return "Empty Bucket";
|
||||||
}
|
}
|
||||||
case TOOL_BOW: return "Bow";
|
case TOOL_BOW: return "Bow";
|
||||||
case TOOL_MAGIC_COMPASS: return "Magic Compass";
|
case TOOL_MAGIC_COMPASS: return "Magic Compass";
|
||||||
default: return ""; // null
|
default: return ""; // null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* getBasicItemName(int itemID, int countLevel) {
|
char* getBasicItemName(int itemID, int countLevel) {
|
||||||
switch(itemID){
|
switch(itemID){
|
||||||
case TOOL_SHOVEL:
|
case TOOL_SHOVEL:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Shovel";
|
case 1: return "Rock Shovel";
|
||||||
case 2: return "Iron Shovel";
|
case 2: return "Iron Shovel";
|
||||||
case 3: return "Gold Shovel";
|
case 3: return "Gold Shovel";
|
||||||
case 4: return "Gem Shovel";
|
case 4: return "Gem Shovel";
|
||||||
default: return "Wood Shovel";
|
default: return "Wood Shovel";
|
||||||
}
|
}
|
||||||
case TOOL_HOE:
|
case TOOL_HOE:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Hoe";
|
case 1: return "Rock Hoe";
|
||||||
case 2: return "Iron Hoe";
|
case 2: return "Iron Hoe";
|
||||||
case 3: return "Gold Hoe";
|
case 3: return "Gold Hoe";
|
||||||
case 4: return "Gem Hoe";
|
case 4: return "Gem Hoe";
|
||||||
default: return "Wood Hoe";
|
default: return "Wood Hoe";
|
||||||
}
|
}
|
||||||
case TOOL_SWORD:
|
case TOOL_SWORD:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Sword";
|
case 1: return "Rock Sword";
|
||||||
case 2: return "Iron Sword";
|
case 2: return "Iron Sword";
|
||||||
case 3: return "Gold Sword";
|
case 3: return "Gold Sword";
|
||||||
case 4: return "Gem Sword";
|
case 4: return "Gem Sword";
|
||||||
default: return "Wood Sword";
|
default: return "Wood Sword";
|
||||||
}
|
}
|
||||||
case TOOL_PICKAXE:
|
case TOOL_PICKAXE:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Pickaxe";
|
case 1: return "Rock Pickaxe";
|
||||||
case 2: return "Iron Pickaxe";
|
case 2: return "Iron Pickaxe";
|
||||||
case 3: return "Gold Pickaxe";
|
case 3: return "Gold Pickaxe";
|
||||||
case 4: return "Gem Pickaxe";
|
case 4: return "Gem Pickaxe";
|
||||||
default: return "Wood Pickaxe";
|
default: return "Wood Pickaxe";
|
||||||
}
|
}
|
||||||
case TOOL_AXE:
|
case TOOL_AXE:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Rock Axe";
|
case 1: return "Rock Axe";
|
||||||
case 2: return "Iron Axe";
|
case 2: return "Iron Axe";
|
||||||
case 3: return "Gold Axe";
|
case 3: return "Gold Axe";
|
||||||
case 4: return "Gem Axe";
|
case 4: return "Gem Axe";
|
||||||
default: return "Wood Axe";
|
default: return "Wood Axe";
|
||||||
}
|
}
|
||||||
case ITEM_ANVIL: return "Anvil";
|
case ITEM_ANVIL: return "Anvil";
|
||||||
case ITEM_CHEST: return "Chest";
|
case ITEM_CHEST: return "Chest";
|
||||||
case ITEM_OVEN: return "Oven";
|
case ITEM_OVEN: return "Oven";
|
||||||
case ITEM_FURNACE: return "Furnace";
|
case ITEM_FURNACE: return "Furnace";
|
||||||
case ITEM_WORKBENCH: return "Workbench";
|
case ITEM_WORKBENCH: return "Workbench";
|
||||||
case ITEM_POTION_MAKER: return "Potion Maker";
|
case ITEM_POTION_MAKER: return "Potion Maker";
|
||||||
case ITEM_LANTERN: return "Lantern";
|
case ITEM_LANTERN: return "Lantern";
|
||||||
case ITEM_POWGLOVE: return "Power Glove";
|
case ITEM_POWGLOVE: return "Power Glove";
|
||||||
case ITEM_FLOWER: return "Flower";
|
case ITEM_FLOWER: return "Flower";
|
||||||
case ITEM_WOOD: return "Wood";
|
case ITEM_WOOD: return "Wood";
|
||||||
case ITEM_STONE: return "Stone";
|
case ITEM_STONE: return "Stone";
|
||||||
case ITEM_SAND: return "Sand";
|
case ITEM_SAND: return "Sand";
|
||||||
case ITEM_DIRT: return "Dirt";
|
case ITEM_DIRT: return "Dirt";
|
||||||
case ITEM_CLOUD: return "Cloud";
|
case ITEM_CLOUD: return "Cloud";
|
||||||
case ITEM_ACORN: return "Acorn";
|
case ITEM_ACORN: return "Acorn";
|
||||||
case ITEM_CACTUS: return "Cactus";
|
case ITEM_CACTUS: return "Cactus";
|
||||||
case ITEM_SEEDS: return "Seeds";
|
case ITEM_SEEDS: return "Seeds";
|
||||||
case ITEM_WHEAT: return "Wheat";
|
case ITEM_WHEAT: return "Wheat";
|
||||||
case ITEM_FLESH: return "Flesh";
|
case ITEM_FLESH: return "Flesh";
|
||||||
case ITEM_BREAD: return "Bread";
|
case ITEM_BREAD: return "Bread";
|
||||||
case ITEM_APPLE: return "Apple";
|
case ITEM_APPLE: return "Apple";
|
||||||
case ITEM_GOLD_APPLE: return "Gold Apple";
|
case ITEM_GOLD_APPLE: return "Gold Apple";
|
||||||
case ITEM_COAL: return "Coal";
|
case ITEM_COAL: return "Coal";
|
||||||
case ITEM_IRONORE: return "Iron ore";
|
case ITEM_IRONORE: return "Iron ore";
|
||||||
case ITEM_GOLDORE: return "Gold ore";
|
case ITEM_GOLDORE: return "Gold ore";
|
||||||
case ITEM_IRONINGOT: return "Iron ingot";
|
case ITEM_IRONINGOT: return "Iron ingot";
|
||||||
case ITEM_GOLDINGOT: return "Gold ingot";
|
case ITEM_GOLDINGOT: return "Gold ingot";
|
||||||
case ITEM_GLASS: return "Glass";
|
case ITEM_GLASS: return "Glass";
|
||||||
case ITEM_GEM: return "Gem";
|
case ITEM_GEM: return "Gem";
|
||||||
case ITEM_SLIME: return "Slime";
|
case ITEM_SLIME: return "Slime";
|
||||||
|
|
||||||
case ITEM_LOOM: return "Loom";
|
case ITEM_LOOM: return "Loom";
|
||||||
case ITEM_ENCHANTER: return "Enchanter";
|
case ITEM_ENCHANTER: return "Enchanter";
|
||||||
case ITEM_WALL_WOOD: return "Wood Wall";
|
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_EGG: return "Dragon Egg";
|
||||||
case ITEM_DRAGON_SCALE: return "Dragon Scale";
|
case ITEM_DRAGON_SCALE: return "Dragon Scale";
|
||||||
case ITEM_BOOKSHELVES: return "Bookshelves";
|
case ITEM_BOOKSHELVES: return "Bookshelves";
|
||||||
case ITEM_MAGIC_DUST: return "Magic Dust";
|
case ITEM_MAGIC_DUST: return "Magic Dust";
|
||||||
case ITEM_COIN: return "Coin";
|
case ITEM_COIN: return "Coin";
|
||||||
case ITEM_STRENGTH_POTION: return "Strength Potion";
|
case ITEM_STRENGTH_POTION: return "Strength Potion";
|
||||||
case ITEM_SPEED_POTION: return "Speed Potion";
|
case ITEM_SPEED_POTION: return "Speed Potion";
|
||||||
case ITEM_REGEN_POTION: return "Regen Potion";
|
case ITEM_REGEN_POTION: return "Regen Potion";
|
||||||
case ITEM_SWIM_BREATH_POTION: return "Water Potion";
|
case ITEM_SWIM_BREATH_POTION: return "Water Potion";
|
||||||
case TOOL_BUCKET:
|
case TOOL_BUCKET:
|
||||||
switch(countLevel){
|
switch(countLevel){
|
||||||
case 1: return "Water Bucket";
|
case 1: return "Water Bucket";
|
||||||
case 2: return "Lava Bucket";
|
case 2: return "Lava Bucket";
|
||||||
default: return "Empty Bucket";
|
default: return "Empty Bucket";
|
||||||
}
|
}
|
||||||
case TOOL_BOW: return "Bow";
|
case TOOL_BOW: return "Bow";
|
||||||
case TOOL_MAGIC_COMPASS: return "Magic Compass";
|
case TOOL_MAGIC_COMPASS: return "Magic Compass";
|
||||||
default: return ""; // null
|
default: return ""; // null
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,17 +87,17 @@
|
||||||
typedef struct Inventory Inventory;
|
typedef struct Inventory Inventory;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s16 id;
|
s16 id;
|
||||||
s16 countLevel; // Count for items, Level for tools.
|
s16 countLevel; // Count for items, Level for tools.
|
||||||
s16 slotNum; // Read-only. Do not mess with this.
|
s16 slotNum; // Read-only. Do not mess with this.
|
||||||
bool onlyOne;
|
bool onlyOne;
|
||||||
int* invPtr; // pointer to current inventory.
|
int* invPtr; // pointer to current inventory.
|
||||||
Inventory * chestPtr; // pointer to chest inventory for chest item.
|
Inventory * chestPtr; // pointer to chest inventory for chest item.
|
||||||
} Item;
|
} Item;
|
||||||
|
|
||||||
struct Inventory {
|
struct Inventory {
|
||||||
Item items[300]; // Maximum of 300 slots in every 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.
|
s16 lastSlot; // lastSlot can also be used to read the size of the inventory.
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isItemEmpty(Item* item);
|
bool isItemEmpty(Item* item);
|
||||||
|
|
817
source/MapGen.c
817
source/MapGen.c
File diff suppressed because it is too large
Load diff
|
@ -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);
|
void createDwarfHouse(int w, int h, int level, u8 * map, u8 * data);
|
||||||
|
|
||||||
bool hasNPC;
|
bool hasNPC;
|
||||||
void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data);
|
void createDungeonRoom(int w, int h, bool dragon, int level, u8 * map, u8 * data);
|
||||||
|
|
2228
source/Menu.c
2228
source/Menu.c
File diff suppressed because it is too large
Load diff
|
@ -4,257 +4,257 @@ u8 pageNum = 0;
|
||||||
u8 maxPageNum = 7;
|
u8 maxPageNum = 7;
|
||||||
|
|
||||||
u32 biasedCirclePad(u32 in){
|
u32 biasedCirclePad(u32 in){
|
||||||
if(in & KEY_CPAD_UP) return KEY_CPAD_UP;
|
if(in & KEY_CPAD_UP) return KEY_CPAD_UP;
|
||||||
else if(in & KEY_CPAD_DOWN) return KEY_CPAD_DOWN;
|
else if(in & KEY_CPAD_DOWN) return KEY_CPAD_DOWN;
|
||||||
else if(in & KEY_CPAD_LEFT) return KEY_CPAD_LEFT;
|
else if(in & KEY_CPAD_LEFT) return KEY_CPAD_LEFT;
|
||||||
else if(in & KEY_CPAD_RIGHT) return KEY_CPAD_RIGHT;
|
else if(in & KEY_CPAD_RIGHT) return KEY_CPAD_RIGHT;
|
||||||
else return (in & -in);
|
else return (in & -in);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 biasedMenuXY(u32 in){
|
u32 biasedMenuXY(u32 in){
|
||||||
if(in & KEY_X) return KEY_X;
|
if(in & KEY_X) return KEY_X;
|
||||||
else if(in & KEY_Y) return KEY_Y;
|
else if(in & KEY_Y) return KEY_Y;
|
||||||
else return (in & -in);
|
else return (in & -in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Oh my god, this was so damn tedious to make. */
|
/** Oh my god, this was so damn tedious to make. */
|
||||||
void renderTutorialPage(bool topScreen){
|
void renderTutorialPage(bool topScreen){
|
||||||
if(topScreen){
|
if(topScreen){
|
||||||
drawTextColor("How to Play",(400-11*12)/2,12,0xFF00AFAF);
|
drawTextColor("How to Play",(400-11*12)/2,12,0xFF00AFAF);
|
||||||
switch(pageNum){
|
switch(pageNum){
|
||||||
case 0: // Moving the character
|
case 0: // Moving the character
|
||||||
drawTextColor("Movement",(400-8*12)/2,40,0xFF007FBF);
|
drawTextColor("Movement",(400-8*12)/2,40,0xFF007FBF);
|
||||||
drawText("Press to move up",92,90);
|
drawText("Press to move up",92,90);
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 164, 88, 1);
|
renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 164, 88, 1);
|
||||||
drawText("Press to move down",80,120);
|
drawText("Press to move down",80,120);
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 152, 118, 1);
|
renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 152, 118, 1);
|
||||||
drawText("Press to move left",80,150);
|
drawText("Press to move left",80,150);
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_left.input), 152, 148, 1);
|
renderButtonIcon(biasedCirclePad(localInputs.k_left.input), 152, 148, 1);
|
||||||
drawText("Press to move right",74,180);
|
drawText("Press to move right",74,180);
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_right.input), 146, 178, 1);
|
renderButtonIcon(biasedCirclePad(localInputs.k_right.input), 146, 178, 1);
|
||||||
break;
|
break;
|
||||||
case 1: // Attacking
|
case 1: // Attacking
|
||||||
drawTextColor("Attacking",(400-9*12)/2,40,0xFF007FBF);
|
drawTextColor("Attacking",(400-9*12)/2,40,0xFF007FBF);
|
||||||
drawText("Press to Attack",98,80);
|
drawText("Press to Attack",98,80);
|
||||||
renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 168, 78, 1);
|
renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 168, 78, 1);
|
||||||
drawText("Attack with an item to use it",26,120);
|
drawText("Attack with an item to use it",26,120);
|
||||||
drawText("Use the axe to cut down trees",26,140);
|
drawText("Use the axe to cut down trees",26,140);
|
||||||
drawText("Use the sword to attack enemies",14,160);
|
drawText("Use the sword to attack enemies",14,160);
|
||||||
drawText("Use the shovel to dig ground",32,180);
|
drawText("Use the shovel to dig ground",32,180);
|
||||||
drawText("Use the pickaxe to mine rock/ore",8,200);
|
drawText("Use the pickaxe to mine rock/ore",8,200);
|
||||||
break;
|
break;
|
||||||
case 2: // Inventory
|
case 2: // Inventory
|
||||||
drawTextColor("Inventory",(400-9*12)/2,40,0xFF007FBF);
|
drawTextColor("Inventory",(400-9*12)/2,40,0xFF007FBF);
|
||||||
drawText("Press to open the menu",56,80);
|
drawText("Press to open the menu",56,80);
|
||||||
renderButtonIcon(biasedMenuXY(localInputs.k_menu.input), 126, 78, 1);
|
renderButtonIcon(biasedMenuXY(localInputs.k_menu.input), 126, 78, 1);
|
||||||
drawText("Press to scroll up",80,110);
|
drawText("Press to scroll up",80,110);
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 152, 108, 1);
|
renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 152, 108, 1);
|
||||||
drawText("Press to scroll down",68,140);
|
drawText("Press to scroll down",68,140);
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 140, 138, 1);
|
renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 140, 138, 1);
|
||||||
drawText("Press to select an item",50,170);
|
drawText("Press to select an item",50,170);
|
||||||
renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 120, 168, 1);
|
renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 120, 168, 1);
|
||||||
drawText("Press to close the menu",50,200);
|
drawText("Press to close the menu",50,200);
|
||||||
renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 120, 198, 1);
|
renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 120, 198, 1);
|
||||||
break;
|
break;
|
||||||
case 3: // Furniture
|
case 3: // Furniture
|
||||||
drawTextColor("Furniture",(400-9*12)/2,40,0xFF007FBF);
|
drawTextColor("Furniture",(400-9*12)/2,40,0xFF007FBF);
|
||||||
drawText("Use furniture for item crafting",(400-31*12)/2,74);
|
drawText("Use furniture for item crafting",(400-31*12)/2,74);
|
||||||
drawText("Press to open the menu",56,100);
|
drawText("Press to open the menu",56,100);
|
||||||
renderButtonIcon(biasedMenuXY(localInputs.k_menu.input), 126, 98, 1);
|
renderButtonIcon(biasedMenuXY(localInputs.k_menu.input), 126, 98, 1);
|
||||||
drawText("while infront of the furniture",(400-30*12)/2,116);
|
drawText("while infront of the furniture",(400-30*12)/2,116);
|
||||||
drawText("Use the lantern item to light",(400-29*12)/2,144);
|
drawText("Use the lantern item to light",(400-29*12)/2,144);
|
||||||
drawText("up underground areas",(400-20*12)/2,160);
|
drawText("up underground areas",(400-20*12)/2,160);
|
||||||
drawText("Use the power glove item to",(400-27*12)/2,184);
|
drawText("Use the power glove item to",(400-27*12)/2,184);
|
||||||
drawText("pick up furniture",(400-17*12)/2,200);
|
drawText("pick up furniture",(400-17*12)/2,200);
|
||||||
break;
|
break;
|
||||||
case 4: // Crafting
|
case 4: // Crafting
|
||||||
drawTextColor("Crafting",(400-8*12)/2,40,0xFF007FBF);
|
drawTextColor("Crafting",(400-8*12)/2,40,0xFF007FBF);
|
||||||
drawText("Create new items and tools",(400-26*12)/2,74);
|
drawText("Create new items and tools",(400-26*12)/2,74);
|
||||||
drawText("Go up to a furniture item and",(400-29*12)/2,104);
|
drawText("Go up to a furniture item and",(400-29*12)/2,104);
|
||||||
drawText("Press to open the menu",56,120);
|
drawText("Press to open the menu",56,120);
|
||||||
renderButtonIcon(biasedMenuXY(localInputs.k_menu.input), 126, 118, 1);
|
renderButtonIcon(biasedMenuXY(localInputs.k_menu.input), 126, 118, 1);
|
||||||
drawText("Gather up the required materials",(400-32*12)/2,150);
|
drawText("Gather up the required materials",(400-32*12)/2,150);
|
||||||
drawText("and then press to craft it",(400-28*12)/2,166);
|
drawText("and then press to craft it",(400-28*12)/2,166);
|
||||||
renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 210, 164, 1);
|
renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 210, 164, 1);
|
||||||
break;
|
break;
|
||||||
case 5: // Farming
|
case 5: // Farming
|
||||||
drawTextColor("Farming",(400-7*12)/2,40,0xFF007FBF);
|
drawTextColor("Farming",(400-7*12)/2,40,0xFF007FBF);
|
||||||
drawText("Grow wheat to make bread",(400-24*12)/2,74);
|
drawText("Grow wheat to make bread",(400-24*12)/2,74);
|
||||||
drawText("Dig up grass to gather seeds",(400-28*12)/2,94);
|
drawText("Dig up grass to gather seeds",(400-28*12)/2,94);
|
||||||
drawText("Use the hoe to till ground",(400-26*12)/2,114);
|
drawText("Use the hoe to till ground",(400-26*12)/2,114);
|
||||||
drawText("Harvest wheat when it is yellow",(400-31*12)/2,134);
|
drawText("Harvest wheat when it is yellow",(400-31*12)/2,134);
|
||||||
drawText("Use the oven to bake bread",(400-26*12)/2,154);
|
drawText("Use the oven to bake bread",(400-26*12)/2,154);
|
||||||
drawText("It takes 4 wheat to craft bread",(400-31*12)/2,174);
|
drawText("It takes 4 wheat to craft bread",(400-31*12)/2,174);
|
||||||
break;
|
break;
|
||||||
case 6: // Mining
|
case 6: // Mining
|
||||||
drawTextColor("Mining",(400-6*12)/2,40,0xFF007FBF);
|
drawTextColor("Mining",(400-6*12)/2,40,0xFF007FBF);
|
||||||
drawText("Use a pickaxe tool for mining",(400-29*12)/2,74);
|
drawText("Use a pickaxe tool for mining",(400-29*12)/2,74);
|
||||||
drawText("Mine rocks for stone",(400-20*12)/2,94);
|
drawText("Mine rocks for stone",(400-20*12)/2,94);
|
||||||
drawText("Mine iron ore for iron",(400-22*12)/2,114);
|
drawText("Mine iron ore for iron",(400-22*12)/2,114);
|
||||||
drawText("Mine gold ore for gold",(400-22*12)/2,134);
|
drawText("Mine gold ore for gold",(400-22*12)/2,134);
|
||||||
drawText("Mine gem ore to get gems",(400-24*12)/2,154);
|
drawText("Mine gem ore to get gems",(400-24*12)/2,154);
|
||||||
drawText("It takes 4 ore and 1 coal to",(400-28*12)/2,190);
|
drawText("It takes 4 ore and 1 coal to",(400-28*12)/2,190);
|
||||||
drawText("make an ingot inside a furnace",(400-30*12)/2,210);
|
drawText("make an ingot inside a furnace",(400-30*12)/2,210);
|
||||||
break;
|
break;
|
||||||
case 7: // Potion Brewing
|
case 7: // Potion Brewing
|
||||||
drawTextColor("Brewing",(400-6*12)/2,40,0xFF007FBF);
|
drawTextColor("Brewing",(400-6*12)/2,40,0xFF007FBF);
|
||||||
drawText("Create potions.",(400-13*12)/2,74);
|
drawText("Create potions.",(400-13*12)/2,74);
|
||||||
drawText("The potions give you abilities",(400-29*12)/2,94);
|
drawText("The potions give you abilities",(400-29*12)/2,94);
|
||||||
drawText("Like speed and strength",(400-22*12)/2,114);
|
drawText("Like speed and strength",(400-22*12)/2,114);
|
||||||
drawText("They are hard to obtain",(400-22*12)/2,134);
|
drawText("They are hard to obtain",(400-22*12)/2,134);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(pageNum){
|
switch(pageNum){
|
||||||
case 0: // Moving the character
|
case 0: // Moving the character
|
||||||
render16(30,56,16,112,0);//Player up
|
render16(30,56,16,112,0);//Player up
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 30,40, 2);
|
renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 30,40, 2);
|
||||||
render16(60,56,0,112,0);//Player down
|
render16(60,56,0,112,0);//Player down
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 60,40, 2);
|
renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 60,40, 2);
|
||||||
render16(90,56,48,112,1);//Player left
|
render16(90,56,48,112,1);//Player left
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_left.input), 90,40, 2);
|
renderButtonIcon(biasedCirclePad(localInputs.k_left.input), 90,40, 2);
|
||||||
render16(120,56,48,112,0);//Player right
|
render16(120,56,48,112,0);//Player right
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_right.input), 120,40, 2);
|
renderButtonIcon(biasedCirclePad(localInputs.k_right.input), 120,40, 2);
|
||||||
break;
|
break;
|
||||||
case 1: // Attacking
|
case 1: // Attacking
|
||||||
render16(60,56,0,112,0);//Player-down
|
render16(60,56,0,112,0);//Player-down
|
||||||
renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 80, 56, 2);
|
renderButtonIcon(localInputs.k_attack.input & -localInputs.k_attack.input, 80, 56, 2);
|
||||||
renderc(60,68,16,160,16,8,2);//Slash
|
renderc(60,68,16,160,16,8,2);//Slash
|
||||||
|
|
||||||
menuRenderTilePit(12,20,256,0);// grass pit
|
menuRenderTilePit(12,20,256,0);// grass pit
|
||||||
render16(12+8,20+4,256,48,0);//Tree
|
render16(12+8,20+4,256,48,0);//Tree
|
||||||
renderc(12+9,20+14,16,160,16,8,0);//Slash
|
renderc(12+9,20+14,16,160,16,8,0);//Slash
|
||||||
render(12+9+4,20+14,192,144,0);//Axe
|
render(12+9+4,20+14,192,144,0);//Axe
|
||||||
render16(12+9,20+18,16,112,0);//Player-up
|
render16(12+9,20+18,16,112,0);//Player-up
|
||||||
|
|
||||||
menuRenderTilePit(122,62,320,0);// sand pit
|
menuRenderTilePit(122,62,320,0);// sand pit
|
||||||
render16(130,70,256,16,0);// hole
|
render16(130,70,256,16,0);// hole
|
||||||
render16(116,70,48,112,0);//Player-right
|
render16(116,70,48,112,0);//Player-right
|
||||||
renderb(136,76,16,152,0,sandColor);// Sand item
|
renderb(136,76,16,152,0,sandColor);// Sand item
|
||||||
renderc(128,70,40,160,8,16,0);//Slash
|
renderc(128,70,40,160,8,16,0);//Slash
|
||||||
render(130,74,0,144,0);//Shovel
|
render(130,74,0,144,0);//Shovel
|
||||||
break;
|
break;
|
||||||
case 2: // Inventory
|
case 2: // Inventory
|
||||||
renderFrame(4,4,17,11,0xFFFF1010);
|
renderFrame(4,4,17,11,0xFFFF1010);
|
||||||
renderItemStuffWithText(ITEM_APPLE,5,false,80,78);
|
renderItemStuffWithText(ITEM_APPLE,5,false,80,78);
|
||||||
renderItemStuffWithText(ITEM_SLIME,11,false,80,94);
|
renderItemStuffWithText(ITEM_SLIME,11,false,80,94);
|
||||||
renderItemStuffWithText(TOOL_SWORD,4,true,80,110);
|
renderItemStuffWithText(TOOL_SWORD,4,true,80,110);
|
||||||
renderItemStuffWithText(ITEM_IRONORE,3,false,80,126);
|
renderItemStuffWithText(ITEM_IRONORE,3,false,80,126);
|
||||||
renderItemStuffWithText(ITEM_IRONINGOT,11,false,80,142);
|
renderItemStuffWithText(ITEM_IRONINGOT,11,false,80,142);
|
||||||
sf2d_draw_rectangle(64, 110, 12, 12, 0xFF);
|
sf2d_draw_rectangle(64, 110, 12, 12, 0xFF);
|
||||||
drawText(">", 64, 110);
|
drawText(">", 64, 110);
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 44, 92, 1);
|
renderButtonIcon(biasedCirclePad(localInputs.k_up.input), 44, 92, 1);
|
||||||
renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 44, 108, 1);
|
renderButtonIcon(localInputs.k_accept.input & -localInputs.k_accept.input, 44, 108, 1);
|
||||||
renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 44, 125, 1);
|
renderButtonIcon(biasedCirclePad(localInputs.k_down.input), 44, 125, 1);
|
||||||
break;
|
break;
|
||||||
case 3: // Furniture
|
case 3: // Furniture
|
||||||
sf2d_draw_rectangle(64, 48, 192, 32, grassColor);
|
sf2d_draw_rectangle(64, 48, 192, 32, grassColor);
|
||||||
renderc(32,24,64,128,96,16,0);//Furniture entities
|
renderc(32,24,64,128,96,16,0);//Furniture entities
|
||||||
|
|
||||||
renderFurniture(ITEM_WORKBENCH, 50,60);
|
renderFurniture(ITEM_WORKBENCH, 50,60);
|
||||||
render16(50,46,0,112,0);//Player-down
|
render16(50,46,0,112,0);//Player-down
|
||||||
renderc(50,58,16,160,16,8,2);//Slash
|
renderc(50,58,16,160,16,8,2);//Slash
|
||||||
render(54,58,56,152,0);//Power glove
|
render(54,58,56,152,0);//Power glove
|
||||||
|
|
||||||
render16(92,56,0,128,0);//Player(Carrying)
|
render16(92,56,0,128,0);//Player(Carrying)
|
||||||
render16(92,44,128,128,0);//Workbench
|
render16(92,44,128,128,0);//Workbench
|
||||||
break;
|
break;
|
||||||
case 4: // Crafting
|
case 4: // Crafting
|
||||||
renderFrame(11,3,19,6,0xFFFF1010);
|
renderFrame(11,3,19,6,0xFFFF1010);
|
||||||
renderFrame(11,7,19,12,0xFFFF1010);
|
renderFrame(11,7,19,12,0xFFFF1010);
|
||||||
renderFrame(1,3,10,12,0xFFFF1010);
|
renderFrame(1,3,10,12,0xFFFF1010);
|
||||||
renderItemStuffWithText(TOOL_AXE,0,true,28,64);
|
renderItemStuffWithText(TOOL_AXE,0,true,28,64);
|
||||||
renderItemIcon(TOOL_AXE, 0, 94, 32);
|
renderItemIcon(TOOL_AXE, 0, 94, 32);
|
||||||
drawText("0", 206, 66);
|
drawText("0", 206, 66);
|
||||||
renderItemIcon(ITEM_WOOD, 0, 94, 64);
|
renderItemIcon(ITEM_WOOD, 0, 94, 64);
|
||||||
drawText("16/5", 206, 130);
|
drawText("16/5", 206, 130);
|
||||||
break;
|
break;
|
||||||
case 5: // Farming (Bottom screen)
|
case 5: // Farming (Bottom screen)
|
||||||
renderc(24,16,352,48,112,16,0); // Wheat Stages
|
renderc(24,16,352,48,112,16,0); // Wheat Stages
|
||||||
|
|
||||||
render16(20,40,352,48,0); // Farm Tile
|
render16(20,40,352,48,0); // Farm Tile
|
||||||
render16(36,40,448,48,0); // Wheat Tile
|
render16(36,40,448,48,0); // Wheat Tile
|
||||||
render16(52,40,448,48,0); // Wheat Tile
|
render16(52,40,448,48,0); // Wheat Tile
|
||||||
render16(20,54,16,112,0); // Player (Up)
|
render16(20,54,16,112,0); // Player (Up)
|
||||||
renderc(20,50,16,160,16,8,0); // Slash (Up)
|
renderc(20,50,16,160,16,8,0); // Slash (Up)
|
||||||
render(19,45,40,152,0); // Seeds
|
render(19,45,40,152,0); // Seeds
|
||||||
render(26,39,48,152,0); // Wheat1
|
render(26,39,48,152,0); // Wheat1
|
||||||
render(29,44,48,152,0); // Wheat2
|
render(29,44,48,152,0); // Wheat2
|
||||||
|
|
||||||
renderc(72,40,352,48,32,16,0); // Farm Tile + Seeded Wheat Tile
|
renderc(72,40,352,48,32,16,0); // Farm Tile + Seeded Wheat Tile
|
||||||
render16(72,54,16,112,0); // Player (Up)
|
render16(72,54,16,112,0); // Player (Up)
|
||||||
renderc(72,50,16,160,16,8,0); // Slash (Up)
|
renderc(72,50,16,160,16,8,0); // Slash (Up)
|
||||||
render(76,48,40,152,0); // Seeds
|
render(76,48,40,152,0); // Seeds
|
||||||
|
|
||||||
sf2d_draw_rectangle(216, 80, 32, 32, dirtColor[1]); // Dirt color for grass
|
sf2d_draw_rectangle(216, 80, 32, 32, dirtColor[1]); // Dirt color for grass
|
||||||
render16(108, 40, 256, 0, 0); // Grass
|
render16(108, 40, 256, 0, 0); // Grass
|
||||||
render16(124, 40,352,48,0); // Farm Tile
|
render16(124, 40,352,48,0); // Farm Tile
|
||||||
render16(108,54,16,112,0); // Player (Up)
|
render16(108,54,16,112,0); // Player (Up)
|
||||||
renderc(108,50,16,160,16,8,0); // Slash (Up)
|
renderc(108,50,16,160,16,8,0); // Slash (Up)
|
||||||
render(112,48,72,144,0); // Gem Hoe
|
render(112,48,72,144,0); // Gem Hoe
|
||||||
|
|
||||||
sf2d_draw_rectangle(112, 156, 32, 32, dirtColor[1]); // Dirt color for grass
|
sf2d_draw_rectangle(112, 156, 32, 32, dirtColor[1]); // Dirt color for grass
|
||||||
render16(56, 78, 256, 0, 0); // Grass
|
render16(56, 78, 256, 0, 0); // Grass
|
||||||
sf2d_draw_rectangle(80, 156, 32, 32, dirtColor[1]); // Dirt color
|
sf2d_draw_rectangle(80, 156, 32, 32, dirtColor[1]); // Dirt color
|
||||||
render16(40, 78, 336, 80, 0); // Dirt Dots
|
render16(40, 78, 336, 80, 0); // Dirt Dots
|
||||||
render(44, 82, 40,152,0); // Seeds
|
render(44, 82, 40,152,0); // Seeds
|
||||||
|
|
||||||
render16(24,78,48,112,0); // Player (Right)
|
render16(24,78,48,112,0); // Player (Right)
|
||||||
renderc(36,78,40,160,8,16,0); // Slash (Right)
|
renderc(36,78,40,160,8,16,0); // Slash (Right)
|
||||||
render(38,82,32,144,0); // Gem Shovel
|
render(38,82,32,144,0); // Gem Shovel
|
||||||
|
|
||||||
render(82,78,48,152,0); // Wheat
|
render(82,78,48,152,0); // Wheat
|
||||||
render(90,78,48,152,0); // Wheat
|
render(90,78,48,152,0); // Wheat
|
||||||
render(82,86,48,152,0); // Wheat
|
render(82,86,48,152,0); // Wheat
|
||||||
render(90,86,48,152,0); // Wheat
|
render(90,86,48,152,0); // Wheat
|
||||||
drawText(">",203,164);
|
drawText(">",203,164);
|
||||||
render16(108,76,96,128,0); // Oven
|
render16(108,76,96,128,0); // Oven
|
||||||
drawText(">",246,164);
|
drawText(">",246,164);
|
||||||
render(132,82,72,152,0); // Bread
|
render(132,82,72,152,0); // Bread
|
||||||
break;
|
break;
|
||||||
case 6: //Mining
|
case 6: //Mining
|
||||||
render16(23,32,464,48,0); // iron ore
|
render16(23,32,464,48,0); // iron ore
|
||||||
render16(23,52,480,48,0); // gold ore
|
render16(23,52,480,48,0); // gold ore
|
||||||
render16(23,72,496,48,0); // gem ore
|
render16(23,72,496,48,0); // gem ore
|
||||||
renderb(41,38,88,152,0,ironColor); // Iron ore item
|
renderb(41,38,88,152,0,ironColor); // Iron ore item
|
||||||
renderb(41,58,88,152,0,goldColor); // Gold ore item
|
renderb(41,58,88,152,0,goldColor); // Gold ore item
|
||||||
render(41,78,112,152,0); // Gem item
|
render(41,78,112,152,0); // Gem item
|
||||||
drawText(">",104,74);
|
drawText(">",104,74);
|
||||||
drawText(">",104,114);
|
drawText(">",104,114);
|
||||||
drawText(">",104,154);
|
drawText(">",104,154);
|
||||||
render16(60,32,112,128,0); // Furnace
|
render16(60,32,112,128,0); // Furnace
|
||||||
render16(60,52,112,128,0); // Furnace
|
render16(60,52,112,128,0); // Furnace
|
||||||
render16(60,72,240,128,0); // Enchanter
|
render16(60,72,240,128,0); // Enchanter
|
||||||
drawText(">",160,74);
|
drawText(">",160,74);
|
||||||
drawText(">",160,114);
|
drawText(">",160,114);
|
||||||
drawText(">",160,154);
|
drawText(">",160,154);
|
||||||
renderb(88,36,96,152,0,ironColor); // Iron ingot item
|
renderb(88,36,96,152,0,ironColor); // Iron ingot item
|
||||||
renderb(88,56,96,152,0,goldColor); // Gold ingot item
|
renderb(88,56,96,152,0,goldColor); // Gold ingot item
|
||||||
renderb(88,76,152,144,0,goldColor); // Gem Pickaxe
|
renderb(88,76,152,144,0,goldColor); // Gem Pickaxe
|
||||||
drawText(">",200,74);
|
drawText(">",200,74);
|
||||||
drawText(">",200,114);
|
drawText(">",200,114);
|
||||||
render16(106,32,64,128,0); // Anvil
|
render16(106,32,64,128,0); // Anvil
|
||||||
render16(106,52,64,128,0); // Anvil
|
render16(106,52,64,128,0); // Anvil
|
||||||
drawText(">",244,74);
|
drawText(">",244,74);
|
||||||
drawText(">",244,114);
|
drawText(">",244,114);
|
||||||
render(130,36,136,144,0); // Iron Pickaxe
|
render(130,36,136,144,0); // Iron Pickaxe
|
||||||
render(130,56,144,144,0); // Gold Pickaxe
|
render(130,56,144,144,0); // Gold Pickaxe
|
||||||
break;
|
break;
|
||||||
case 7: // Brewing
|
case 7: // Brewing
|
||||||
render16(65, 56, 240, 96, 0);
|
render16(65, 56, 240, 96, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawText(pageText,(320-(strlen(pageText))*12)/2,12);
|
drawText(pageText,(320-(strlen(pageText))*12)/2,12);
|
||||||
if(pageNum > 0){
|
if(pageNum > 0){
|
||||||
drawText("<",2,16);
|
drawText("<",2,16);
|
||||||
renderButtonIcon(localInputs.k_menuPrev.input & -localInputs.k_menuPrev.input, 8, 2, 2);
|
renderButtonIcon(localInputs.k_menuPrev.input & -localInputs.k_menuPrev.input, 8, 2, 2);
|
||||||
}
|
}
|
||||||
if(pageNum < maxPageNum){
|
if(pageNum < maxPageNum){
|
||||||
drawText(">",306,16);
|
drawText(">",306,16);
|
||||||
renderButtonIcon(localInputs.k_menuNext.input & -localInputs.k_menuNext.input, 136, 2, 2);
|
renderButtonIcon(localInputs.k_menuNext.input & -localInputs.k_menuNext.input, 136, 2, 2);
|
||||||
}
|
}
|
||||||
drawText("Press to exit",(320-(15*12))/2,218);
|
drawText("Press to exit",(320-(15*12))/2,218);
|
||||||
renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 140, 216, 1);
|
renderButtonIcon(localInputs.k_decline.input & -localInputs.k_decline.input, 140, 216, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sf2d.h>
|
#include <sf2d.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
744
source/Network.c
744
source/Network.c
|
@ -46,211 +46,211 @@ void clearSendAckedBuffer();
|
||||||
bool sendAck(u16 target, u16 ack);
|
bool sendAck(u16 target, u16 ack);
|
||||||
|
|
||||||
void networkThreadMain(void *arg) {
|
void networkThreadMain(void *arg) {
|
||||||
while(networkRunThread) {
|
while(networkRunThread) {
|
||||||
if(udsRunning && isConnected) {
|
if(udsRunning && isConnected) {
|
||||||
networkUpdateStatus();
|
networkUpdateStatus();
|
||||||
networkHandleRecieve();
|
networkHandleRecieve();
|
||||||
networkHandleSend();
|
networkHandleSend();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Set meaningfull value, WARNING: Setting this near 1ms (1000*1000) will make everything super laggy, higher values actually work better!
|
//TODO: Set meaningfull value, WARNING: Setting this near 1ms (1000*1000) will make everything super laggy, higher values actually work better!
|
||||||
svcSleepThread(10000 * 1000);
|
svcSleepThread(10000 * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkUpdateStatus() {
|
void networkUpdateStatus() {
|
||||||
/*for(int i=0; i<10; i++) {
|
/*for(int i=0; i<10; i++) {
|
||||||
Result ret = udsGetConnectionStatus(&networkStatus);
|
Result ret = udsGetConnectionStatus(&networkStatus);
|
||||||
if(!R_FAILED(ret)) {
|
if(!R_FAILED(ret)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
if(udsWaitConnectionStatusEvent(false, false)) {
|
if(udsWaitConnectionStatusEvent(false, false)) {
|
||||||
udsGetConnectionStatus(&networkStatus);
|
udsGetConnectionStatus(&networkStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkHandleRecieve() {
|
void networkHandleRecieve() {
|
||||||
bool recieved = false;
|
bool recieved = false;
|
||||||
do {
|
do {
|
||||||
recieved = false;
|
recieved = false;
|
||||||
|
|
||||||
size_t actualSize = 0;
|
size_t actualSize = 0;
|
||||||
u16 sourceNetworkNodeID;
|
u16 sourceNetworkNodeID;
|
||||||
u32 ackToSend = 0;
|
u32 ackToSend = 0;
|
||||||
|
|
||||||
memset(networkBuffer, 0, networkBufferSize);
|
memset(networkBuffer, 0, networkBufferSize);
|
||||||
|
|
||||||
Result ret = udsPullPacket(&networkBindCtx, networkBuffer, networkBufferSize, &actualSize, &sourceNetworkNodeID);
|
Result ret = udsPullPacket(&networkBindCtx, networkBuffer, networkBufferSize, &actualSize, &sourceNetworkNodeID);
|
||||||
if(R_FAILED(ret)) {
|
if(R_FAILED(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
|
|
||||||
//actualSize will be 0 if no packet is available
|
//actualSize will be 0 if no packet is available
|
||||||
} else if(actualSize) {
|
} else if(actualSize) {
|
||||||
void *readPointer = networkBuffer;
|
void *readPointer = networkBuffer;
|
||||||
|
|
||||||
//ack frame
|
//ack frame
|
||||||
if(actualSize==sizeof(u16)) {
|
if(actualSize==sizeof(u16)) {
|
||||||
networkSeqSendConf[sourceNetworkNodeID] = *((u16*) readPointer);
|
networkSeqSendConf[sourceNetworkNodeID] = *((u16*) readPointer);
|
||||||
clearSendAckedBuffer();
|
clearSendAckedBuffer();
|
||||||
//normal frame
|
//normal frame
|
||||||
} else {
|
} else {
|
||||||
while(actualSize>0) {
|
while(actualSize>0) {
|
||||||
//read seqID and size
|
//read seqID and size
|
||||||
u16 seqID = *((u16*) readPointer);
|
u16 seqID = *((u16*) readPointer);
|
||||||
readPointer += sizeof(u16);
|
readPointer += sizeof(u16);
|
||||||
actualSize -= sizeof(u16);
|
actualSize -= sizeof(u16);
|
||||||
|
|
||||||
u16 size = *((u16*) readPointer);
|
u16 size = *((u16*) readPointer);
|
||||||
readPointer += sizeof(u16);
|
readPointer += sizeof(u16);
|
||||||
actualSize -= sizeof(u16);
|
actualSize -= sizeof(u16);
|
||||||
|
|
||||||
//if the seq id was expected handle the packet
|
//if the seq id was expected handle the packet
|
||||||
u16 nextID = networkGetExpectedSeqFrom(sourceNetworkNodeID);
|
u16 nextID = networkGetExpectedSeqFrom(sourceNetworkNodeID);
|
||||||
if(seqID==nextID) {
|
if(seqID==nextID) {
|
||||||
networkSeqRecvLast[sourceNetworkNodeID] = seqID;
|
networkSeqRecvLast[sourceNetworkNodeID] = seqID;
|
||||||
ackToSend = seqID;
|
ackToSend = seqID;
|
||||||
|
|
||||||
//handle data - TODO: WARNING: Do not send sizeof(u16) packets or else they will get confused with this one
|
//handle data - TODO: WARNING: Do not send sizeof(u16) packets or else they will get confused with this one
|
||||||
if(size==sizeof(u16)) {
|
if(size==sizeof(u16)) {
|
||||||
networkConnectedMask = *((u16*) readPointer);
|
networkConnectedMask = *((u16*) readPointer);
|
||||||
} else {
|
} else {
|
||||||
processPacket(readPointer, size);
|
processPacket(readPointer, size);
|
||||||
}
|
}
|
||||||
} else if(networkSeqIsLowerThan(seqID, nextID)) {
|
} else if(networkSeqIsLowerThan(seqID, nextID)) {
|
||||||
ackToSend = seqID;
|
ackToSend = seqID;
|
||||||
}
|
}
|
||||||
readPointer += size;
|
readPointer += size;
|
||||||
actualSize -= size;
|
actualSize -= size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ackToSend!=0) {
|
if(ackToSend!=0) {
|
||||||
if(sendAck(sourceNetworkNodeID, ackToSend)) {
|
if(sendAck(sourceNetworkNodeID, ackToSend)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recieved = true;
|
recieved = true;
|
||||||
}
|
}
|
||||||
} while(recieved);
|
} while(recieved);
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkHandleSend() {
|
void networkHandleSend() {
|
||||||
if(networkSendBufferStartPos!=networkSendBufferEndPos) {
|
if(networkSendBufferStartPos!=networkSendBufferEndPos) {
|
||||||
LightLock_Lock(&sendBufferLock);
|
LightLock_Lock(&sendBufferLock);
|
||||||
|
|
||||||
//determine send size
|
//determine send size
|
||||||
size_t currentSize = 0;
|
size_t currentSize = 0;
|
||||||
while(networkSendBufferStartPos+currentSize<networkSendBufferWrapPos && networkSendBufferStartPos+currentSize!=networkSendBufferEndPos) {
|
while(networkSendBufferStartPos+currentSize<networkSendBufferWrapPos && networkSendBufferStartPos+currentSize!=networkSendBufferEndPos) {
|
||||||
//size of "header info" (seqid,size)
|
//size of "header info" (seqid,size)
|
||||||
size_t extraSize = sizeof(u16) + sizeof(u16);
|
size_t extraSize = sizeof(u16) + sizeof(u16);
|
||||||
//data size
|
//data size
|
||||||
extraSize += *((u16*) ((networkSendBuffer+networkSendBufferStartPos+currentSize) + sizeof(u16)));
|
extraSize += *((u16*) ((networkSendBuffer+networkSendBufferStartPos+currentSize) + sizeof(u16)));
|
||||||
|
|
||||||
//if next packet can fit in frame include it
|
//if next packet can fit in frame include it
|
||||||
if(currentSize+extraSize < UDS_DATAFRAME_MAXSIZE) {
|
if(currentSize+extraSize < UDS_DATAFRAME_MAXSIZE) {
|
||||||
currentSize += extraSize;
|
currentSize += extraSize;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//send frame
|
//send frame
|
||||||
if(currentSize>0) {
|
if(currentSize>0) {
|
||||||
//TODO: Once we have our own custom mask, no longer broadcast, but send directly because bcast doesn't always reach everyone?
|
//TODO: Once we have our own custom mask, no longer broadcast, but send directly because bcast doesn't always reach everyone?
|
||||||
if(networkConnectedMask==0) {
|
if(networkConnectedMask==0) {
|
||||||
//send frame
|
//send frame
|
||||||
Result ret = udsSendTo(UDS_BROADCAST_NETWORKNODEID, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize);
|
Result ret = udsSendTo(UDS_BROADCAST_NETWORKNODEID, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize);
|
||||||
if(UDS_CHECK_SENDTO_FATALERROR(ret)) {
|
if(UDS_CHECK_SENDTO_FATALERROR(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
} else if(R_FAILED(ret)) {
|
} else if(R_FAILED(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for(int i=1; i<=UDS_MAXNODES; i++) {
|
for(int i=1; i<=UDS_MAXNODES; i++) {
|
||||||
if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) {
|
if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) {
|
||||||
//send frame
|
//send frame
|
||||||
Result ret = udsSendTo(i, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize);
|
Result ret = udsSendTo(i, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize);
|
||||||
if(UDS_CHECK_SENDTO_FATALERROR(ret)) {
|
if(UDS_CHECK_SENDTO_FATALERROR(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
} else if(R_FAILED(ret)) {
|
} else if(R_FAILED(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LightLock_Unlock(&sendBufferLock);
|
LightLock_Unlock(&sendBufferLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearSendAckedBuffer() {
|
void clearSendAckedBuffer() {
|
||||||
//find last ack recieved from all com partners
|
//find last ack recieved from all com partners
|
||||||
u16 ackID = 0;
|
u16 ackID = 0;
|
||||||
for(int i=1; i<=UDS_MAXNODES; i++) {
|
for(int i=1; i<=UDS_MAXNODES; i++) {
|
||||||
if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) {
|
if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) {
|
||||||
if(networkSeqSendConf[i]==0) {
|
if(networkSeqSendConf[i]==0) {
|
||||||
ackID = 0;
|
ackID = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ackID==0) {
|
if(ackID==0) {
|
||||||
ackID = networkSeqSendConf[i];
|
ackID = networkSeqSendConf[i];
|
||||||
} else if(networkSeqSendConf[i]<100) {
|
} else if(networkSeqSendConf[i]<100) {
|
||||||
if(ackID > networkSeqSendConf[i] && ackID<65535-100) ackID = networkSeqSendConf[i];
|
if(ackID > networkSeqSendConf[i] && ackID<65535-100) ackID = networkSeqSendConf[i];
|
||||||
} else if(networkSeqSendConf[i]>65535-100) {
|
} else if(networkSeqSendConf[i]>65535-100) {
|
||||||
if(ackID > networkSeqSendConf[i] || ackID<100) ackID = networkSeqSendConf[i];
|
if(ackID > networkSeqSendConf[i] || ackID<100) ackID = networkSeqSendConf[i];
|
||||||
} else {
|
} else {
|
||||||
if(ackID > networkSeqSendConf[i]) ackID = networkSeqSendConf[i];
|
if(ackID > networkSeqSendConf[i]) ackID = networkSeqSendConf[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ackID==0) return;
|
if(ackID==0) return;
|
||||||
|
|
||||||
LightLock_Lock(&sendBufferLock);
|
LightLock_Lock(&sendBufferLock);
|
||||||
|
|
||||||
//clear buffer of acknowledgt packets
|
//clear buffer of acknowledgt packets
|
||||||
while(networkSendBufferStartPos!=networkSendBufferEndPos) {
|
while(networkSendBufferStartPos!=networkSendBufferEndPos) {
|
||||||
//find current seqid and size
|
//find current seqid and size
|
||||||
u16 seqID = *((u16*) (networkSendBuffer+networkSendBufferStartPos));
|
u16 seqID = *((u16*) (networkSendBuffer+networkSendBufferStartPos));
|
||||||
u16 size = *((u16*) (networkSendBuffer+networkSendBufferStartPos+sizeof(u16)));
|
u16 size = *((u16*) (networkSendBuffer+networkSendBufferStartPos+sizeof(u16)));
|
||||||
|
|
||||||
if(seqID<=ackID || (ackID<100 && seqID>65535-100)) {
|
if(seqID<=ackID || (ackID<100 && seqID>65535-100)) {
|
||||||
|
|
||||||
size_t currentSize = sizeof(u16)*2 + size;
|
size_t currentSize = sizeof(u16)*2 + size;
|
||||||
|
|
||||||
//adjust buffer "pointers"
|
//adjust buffer "pointers"
|
||||||
networkSendBufferStartPos += currentSize;
|
networkSendBufferStartPos += currentSize;
|
||||||
if(networkSendBufferStartPos==networkSendBufferEndPos) {
|
if(networkSendBufferStartPos==networkSendBufferEndPos) {
|
||||||
networkSendBufferStartPos = 0;
|
networkSendBufferStartPos = 0;
|
||||||
networkSendBufferEndPos = 0;
|
networkSendBufferEndPos = 0;
|
||||||
networkSendBufferWrapPos = 0;
|
networkSendBufferWrapPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//wrap
|
//wrap
|
||||||
if(networkSendBufferStartPos==networkSendBufferWrapPos) {
|
if(networkSendBufferStartPos==networkSendBufferWrapPos) {
|
||||||
networkSendBufferStartPos = 0;
|
networkSendBufferStartPos = 0;
|
||||||
networkSendBufferWrapPos = networkSendBufferEndPos;
|
networkSendBufferWrapPos = networkSendBufferEndPos;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LightLock_Unlock(&sendBufferLock);
|
LightLock_Unlock(&sendBufferLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sendAck(u16 target, u16 ack) {
|
bool sendAck(u16 target, u16 ack) {
|
||||||
Result ret = udsSendTo(target, NETWORK_CHANNEL, UDS_SENDFLAG_Default, &ack, sizeof(u16));
|
Result ret = udsSendTo(target, NETWORK_CHANNEL, UDS_SENDFLAG_Default, &ack, sizeof(u16));
|
||||||
if(UDS_CHECK_SENDTO_FATALERROR(ret)) {
|
if(UDS_CHECK_SENDTO_FATALERROR(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
return false;
|
return false;
|
||||||
} else if(R_FAILED(ret)) {
|
} else if(R_FAILED(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkInit() {
|
void networkInit() {
|
||||||
|
@ -259,87 +259,87 @@ void networkInit() {
|
||||||
udsRunning = false;
|
udsRunning = false;
|
||||||
} else {
|
} else {
|
||||||
udsRunning = true;
|
udsRunning = true;
|
||||||
|
|
||||||
scannedNetworksCount = 0;
|
scannedNetworksCount = 0;
|
||||||
scannedNetworks = NULL;
|
scannedNetworks = NULL;
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
isServer = false;
|
isServer = false;
|
||||||
networkConnectedMask = 0;
|
networkConnectedMask = 0;
|
||||||
|
|
||||||
networkWriteBuffer = malloc(NETWORK_MAXDATASIZE);
|
networkWriteBuffer = malloc(NETWORK_MAXDATASIZE);
|
||||||
if(networkWriteBuffer==NULL) {
|
if(networkWriteBuffer==NULL) {
|
||||||
networkExit();
|
networkExit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
networkBufferSize = 0x4000;
|
networkBufferSize = 0x4000;
|
||||||
networkBuffer = malloc(networkBufferSize);
|
networkBuffer = malloc(networkBufferSize);
|
||||||
if(networkBuffer==NULL) {
|
if(networkBuffer==NULL) {
|
||||||
networkExit();
|
networkExit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
networkSendBufferStartPos = 0;
|
networkSendBufferStartPos = 0;
|
||||||
networkSendBufferEndPos = 0;
|
networkSendBufferEndPos = 0;
|
||||||
networkSendBufferWrapPos = 0;
|
networkSendBufferWrapPos = 0;
|
||||||
networkSendBuffer = malloc(NETWORK_SENDBUFFERSIZE);
|
networkSendBuffer = malloc(NETWORK_SENDBUFFERSIZE);
|
||||||
if(networkSendBuffer==NULL) {
|
if(networkSendBuffer==NULL) {
|
||||||
networkExit();
|
networkExit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
networkSeqSendNext = 1;
|
networkSeqSendNext = 1;
|
||||||
for(int i=0; i<UDS_MAXNODES+1; i++) {
|
for(int i=0; i<UDS_MAXNODES+1; i++) {
|
||||||
networkSeqSendConf[i] = 0;
|
networkSeqSendConf[i] = 0;
|
||||||
networkSeqRecvLast[i] = 0;
|
networkSeqRecvLast[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
networkAckBuffer = malloc(sizeof(u16)+sizeof(u16)+sizeof(u16));
|
networkAckBuffer = malloc(sizeof(u16)+sizeof(u16)+sizeof(u16));
|
||||||
if(networkAckBuffer==NULL) {
|
if(networkAckBuffer==NULL) {
|
||||||
networkExit();
|
networkExit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LightLock_Init(&sendBufferLock);
|
LightLock_Init(&sendBufferLock);
|
||||||
|
|
||||||
s32 prio = 0;
|
s32 prio = 0;
|
||||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||||
|
|
||||||
//NOTE: It is important the networkThread is prioritized over the main thread (so substract 1) or else nothing will work
|
//NOTE: It is important the networkThread is prioritized over the main thread (so substract 1) or else nothing will work
|
||||||
networkRunThread = true;
|
networkRunThread = true;
|
||||||
networkThread = threadCreate(networkThreadMain, NULL, NETWORK_STACKSIZE, prio-1, -2, false);
|
networkThread = threadCreate(networkThreadMain, NULL, NETWORK_STACKSIZE, prio-1, -2, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkExit() {
|
void networkExit() {
|
||||||
//Additionally to shutting down the service, clear any left over memory!
|
//Additionally to shutting down the service, clear any left over memory!
|
||||||
if(udsRunning) {
|
if(udsRunning) {
|
||||||
udsRunning = false;
|
udsRunning = false;
|
||||||
|
|
||||||
if(networkRunThread) {
|
if(networkRunThread) {
|
||||||
networkRunThread = false;
|
networkRunThread = false;
|
||||||
threadJoin(networkThread, U64_MAX);
|
threadJoin(networkThread, U64_MAX);
|
||||||
threadFree(networkThread);
|
threadFree(networkThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
//cleanup any dynamically reserved memory
|
//cleanup any dynamically reserved memory
|
||||||
if(scannedNetworks!=NULL) free(scannedNetworks);
|
if(scannedNetworks!=NULL) free(scannedNetworks);
|
||||||
scannedNetworks = NULL;
|
scannedNetworks = NULL;
|
||||||
|
|
||||||
if(networkWriteBuffer!=NULL) free(networkWriteBuffer);
|
if(networkWriteBuffer!=NULL) free(networkWriteBuffer);
|
||||||
networkWriteBuffer = NULL;
|
networkWriteBuffer = NULL;
|
||||||
|
|
||||||
if(networkBuffer!=NULL) free(networkBuffer);
|
if(networkBuffer!=NULL) free(networkBuffer);
|
||||||
networkBuffer = NULL;
|
networkBuffer = NULL;
|
||||||
|
|
||||||
if(networkSendBuffer!=NULL) free(networkSendBuffer);
|
if(networkSendBuffer!=NULL) free(networkSendBuffer);
|
||||||
networkSendBuffer = NULL;
|
networkSendBuffer = NULL;
|
||||||
|
|
||||||
if(networkAckBuffer!=NULL) free(networkAckBuffer);
|
if(networkAckBuffer!=NULL) free(networkAckBuffer);
|
||||||
networkAckBuffer = NULL;
|
networkAckBuffer = NULL;
|
||||||
|
|
||||||
networkDisconnect();
|
networkDisconnect();
|
||||||
|
|
||||||
udsExit();
|
udsExit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,17 +355,17 @@ bool networkAvailable() {
|
||||||
bool networkHost() {
|
bool networkHost() {
|
||||||
if(udsRunning && !isConnected) {
|
if(udsRunning && !isConnected) {
|
||||||
udsGenerateDefaultNetworkStruct(&networkStruct, NETWORK_WLANCOMMID, 0, NETWORK_MAXPLAYERS);
|
udsGenerateDefaultNetworkStruct(&networkStruct, NETWORK_WLANCOMMID, 0, NETWORK_MAXPLAYERS);
|
||||||
|
|
||||||
Result ret = udsCreateNetwork(&networkStruct, NETWORK_PASSPHRASE, strlen(NETWORK_PASSPHRASE)+1, &networkBindCtx, NETWORK_CHANNEL, NETWORK_RECVBUFSIZE);
|
Result ret = udsCreateNetwork(&networkStruct, NETWORK_PASSPHRASE, strlen(NETWORK_PASSPHRASE)+1, &networkBindCtx, NETWORK_CHANNEL, NETWORK_RECVBUFSIZE);
|
||||||
if(R_FAILED(ret)) {
|
if(R_FAILED(ret)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if(udsWaitConnectionStatusEvent(false, false)) {}
|
if(udsWaitConnectionStatusEvent(false, false)) {}
|
||||||
udsGetConnectionStatus(&networkStatus);
|
udsGetConnectionStatus(&networkStatus);
|
||||||
udsSetNewConnectionsBlocked(false, true, false);
|
udsSetNewConnectionsBlocked(false, true, false);
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
isServer = true;
|
isServer = true;
|
||||||
networkConnectedMask = 0;
|
networkConnectedMask = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ bool networkHost() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkHostStopConnections() {
|
void networkHostStopConnections() {
|
||||||
udsSetNewConnectionsBlocked(true, true, false);
|
udsSetNewConnectionsBlocked(true, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkScan() {
|
void networkScan() {
|
||||||
|
@ -382,7 +382,7 @@ void networkScan() {
|
||||||
if(scannedNetworks!=NULL) free(scannedNetworks);
|
if(scannedNetworks!=NULL) free(scannedNetworks);
|
||||||
scannedNetworks = NULL;
|
scannedNetworks = NULL;
|
||||||
scannedNetworksCount = 0;
|
scannedNetworksCount = 0;
|
||||||
|
|
||||||
//scan
|
//scan
|
||||||
memset(networkBuffer, 0, networkBufferSize);
|
memset(networkBuffer, 0, networkBufferSize);
|
||||||
Result ret = udsScanBeacons(networkBuffer, networkBufferSize, &scannedNetworks, &scannedNetworksCount, NETWORK_WLANCOMMID, 0, NULL, isConnected);
|
Result ret = udsScanBeacons(networkBuffer, networkBufferSize, &scannedNetworks, &scannedNetworksCount, NETWORK_WLANCOMMID, 0, NULL, isConnected);
|
||||||
|
@ -404,7 +404,7 @@ int networkGetScanCount() {
|
||||||
bool networkGetScanName(char *name, int pos) {
|
bool networkGetScanName(char *name, int pos) {
|
||||||
if(udsRunning) {
|
if(udsRunning) {
|
||||||
if(pos<0 || pos>=scannedNetworksCount) return false;
|
if(pos<0 || pos>=scannedNetworksCount) return false;
|
||||||
|
|
||||||
Result ret = udsGetNodeInfoUsername(&(scannedNetworks[pos].nodes[0]), name);
|
Result ret = udsGetNodeInfoUsername(&(scannedNetworks[pos].nodes[0]), name);
|
||||||
if(R_FAILED(ret)) {
|
if(R_FAILED(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
|
@ -418,16 +418,16 @@ bool networkGetScanName(char *name, int pos) {
|
||||||
bool networkConnect(int pos) {
|
bool networkConnect(int pos) {
|
||||||
if(udsRunning && !isConnected) {
|
if(udsRunning && !isConnected) {
|
||||||
if(pos<0 || pos>=scannedNetworksCount) return false;
|
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);
|
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)) {
|
if(R_FAILED(ret)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if(udsWaitConnectionStatusEvent(false, false)) {}
|
if(udsWaitConnectionStatusEvent(false, false)) {}
|
||||||
udsGetConnectionStatus(&networkStatus);
|
udsGetConnectionStatus(&networkStatus);
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
isServer = false;
|
isServer = false;
|
||||||
networkConnectedMask = 0;
|
networkConnectedMask = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,25 +438,25 @@ void networkDisconnect() {
|
||||||
//For clients this just means disconnect, for the server it means destroy the network
|
//For clients this just means disconnect, for the server it means destroy the network
|
||||||
if(udsRunning && isConnected) {
|
if(udsRunning && isConnected) {
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
|
|
||||||
LightLock_Lock(&sendBufferLock);
|
LightLock_Lock(&sendBufferLock);
|
||||||
//reset send buffer
|
//reset send buffer
|
||||||
networkSendBufferStartPos = 0;
|
networkSendBufferStartPos = 0;
|
||||||
networkSendBufferEndPos = 0;
|
networkSendBufferEndPos = 0;
|
||||||
networkSendBufferWrapPos = 0;
|
networkSendBufferWrapPos = 0;
|
||||||
|
|
||||||
//reset ack status
|
//reset ack status
|
||||||
networkSeqSendNext = 1;
|
networkSeqSendNext = 1;
|
||||||
for(int i=0; i<UDS_MAXNODES+1; i++) {
|
for(int i=0; i<UDS_MAXNODES+1; i++) {
|
||||||
networkSeqSendConf[i] = 0;
|
networkSeqSendConf[i] = 0;
|
||||||
networkSeqRecvLast[i] = 0;
|
networkSeqRecvLast[i] = 0;
|
||||||
}
|
}
|
||||||
LightLock_Unlock(&sendBufferLock);
|
LightLock_Unlock(&sendBufferLock);
|
||||||
|
|
||||||
//With new changes citra now crashes HOST with "cannot be a router if we are not a host" when exiting game with more than 2 people
|
//With new changes citra now crashes HOST with "cannot be a router if we are not a host" when exiting game with more than 2 people
|
||||||
svcSleepThread(220000 * 1000); //HACK: prevent citra crash (>20*networkthreadsleep) (wait unti no more stuff gets send)
|
svcSleepThread(220000 * 1000); //HACK: prevent citra crash (>20*networkthreadsleep) (wait unti no more stuff gets send)
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
if(isServer) {
|
if(isServer) {
|
||||||
//TODO: Clients need to cleanup too, how can I tell they got disconnected
|
//TODO: Clients need to cleanup too, how can I tell they got disconnected
|
||||||
udsDestroyNetwork();
|
udsDestroyNetwork();
|
||||||
|
@ -464,59 +464,59 @@ void networkDisconnect() {
|
||||||
udsDisconnectNetwork();
|
udsDisconnectNetwork();
|
||||||
}
|
}
|
||||||
udsUnbind(&networkBindCtx);
|
udsUnbind(&networkBindCtx);
|
||||||
|
|
||||||
isServer = false;
|
isServer = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void networkStart() {
|
void networkStart() {
|
||||||
//TODO: This sends the node_bitmask from server to everyone else, because it is uncorrect on some clients?
|
//TODO: This sends the node_bitmask from server to everyone else, because it is uncorrect on some clients?
|
||||||
if(udsRunning && isConnected && isServer) {
|
if(udsRunning && isConnected && isServer) {
|
||||||
void *buffer = networkWriteBuffer;
|
void *buffer = networkWriteBuffer;
|
||||||
|
|
||||||
*((u16*) buffer) = networkStatus.node_bitmask;
|
*((u16*) buffer) = networkStatus.node_bitmask;
|
||||||
networkConnectedMask = networkStatus.node_bitmask;
|
networkConnectedMask = networkStatus.node_bitmask;
|
||||||
|
|
||||||
networkSend(networkWriteBuffer, sizeof(u16));
|
networkSend(networkWriteBuffer, sizeof(u16));
|
||||||
networkSendWaitFlush();
|
networkSendWaitFlush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool networkConnected() {
|
bool networkConnected() {
|
||||||
return isConnected;
|
return isConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
int networkGetNodeCount() {
|
int networkGetNodeCount() {
|
||||||
if(udsRunning && isConnected) {
|
if(udsRunning && isConnected) {
|
||||||
return networkStatus.total_nodes;
|
return networkStatus.total_nodes;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 networkGetLocalNodeID() {
|
u16 networkGetLocalNodeID() {
|
||||||
if(udsRunning && isConnected) {
|
if(udsRunning && isConnected) {
|
||||||
return networkStatus.cur_NetworkNodeID;
|
return networkStatus.cur_NetworkNodeID;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool networkIsNodeConnected(u16 id) {
|
bool networkIsNodeConnected(u16 id) {
|
||||||
if(udsRunning && isConnected) {
|
if(udsRunning && isConnected) {
|
||||||
return networkStatus.node_bitmask & (1 << (id-1));
|
return networkStatus.node_bitmask & (1 << (id-1));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool networkGetNodeName(u16 id, char *name) {
|
bool networkGetNodeName(u16 id, char *name) {
|
||||||
if(udsRunning && isConnected && networkIsNodeConnected(id)) {
|
if(udsRunning && isConnected && networkIsNodeConnected(id)) {
|
||||||
udsNodeInfo nodeInfo;
|
udsNodeInfo nodeInfo;
|
||||||
udsGetNodeInformation(id, &nodeInfo);
|
udsGetNodeInformation(id, &nodeInfo);
|
||||||
|
|
||||||
Result ret = udsGetNodeInfoUsername(&nodeInfo, name);
|
Result ret = udsGetNodeInfoUsername(&nodeInfo, name);
|
||||||
if(R_FAILED(ret)) {
|
if(R_FAILED(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
|
@ -547,74 +547,74 @@ bool networkSeqIsLowerThan(u16 firstID, u16 secondID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int fitInSendBuffer(size_t size) {
|
int fitInSendBuffer(size_t size) {
|
||||||
//add "header" length
|
//add "header" length
|
||||||
size += sizeof(u16)*2;
|
size += sizeof(u16)*2;
|
||||||
|
|
||||||
//we have no wrap currently
|
//we have no wrap currently
|
||||||
if(networkSendBufferStartPos<=networkSendBufferEndPos) {
|
if(networkSendBufferStartPos<=networkSendBufferEndPos) {
|
||||||
//and can fit without wrap
|
//and can fit without wrap
|
||||||
if(networkSendBufferEndPos+size<NETWORK_SENDBUFFERSIZE) {
|
if(networkSendBufferEndPos+size<NETWORK_SENDBUFFERSIZE) {
|
||||||
networkSendBufferEndPos += size;
|
networkSendBufferEndPos += size;
|
||||||
networkSendBufferWrapPos = networkSendBufferEndPos;
|
networkSendBufferWrapPos = networkSendBufferEndPos;
|
||||||
|
|
||||||
return networkSendBufferEndPos-size;
|
return networkSendBufferEndPos-size;
|
||||||
//we need to wrap
|
//we need to wrap
|
||||||
} else {
|
} else {
|
||||||
if(size<networkSendBufferStartPos) {
|
if(size<networkSendBufferStartPos) {
|
||||||
networkSendBufferEndPos = size;
|
networkSendBufferEndPos = size;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//we have wrap currently
|
//we have wrap currently
|
||||||
} else {
|
} else {
|
||||||
int available = networkSendBufferStartPos - networkSendBufferEndPos - 1;
|
int available = networkSendBufferStartPos - networkSendBufferEndPos - 1;
|
||||||
if(available>size) {
|
if(available>size) {
|
||||||
networkSendBufferEndPos += size;
|
networkSendBufferEndPos += size;
|
||||||
|
|
||||||
return networkSendBufferEndPos-size;
|
return networkSendBufferEndPos-size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkSend(void *packet, size_t size) {
|
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);
|
LightLock_Lock(&sendBufferLock);
|
||||||
int pos = fitInSendBuffer(size);
|
int pos = fitInSendBuffer(size);
|
||||||
while(pos==-1) {
|
while(pos==-1) {
|
||||||
LightLock_Unlock(&sendBufferLock);
|
LightLock_Unlock(&sendBufferLock);
|
||||||
svcSleepThread(4500 * 1000); //TODO: Set meaningfull value
|
svcSleepThread(4500 * 1000); //TODO: Set meaningfull value
|
||||||
LightLock_Lock(&sendBufferLock);
|
LightLock_Lock(&sendBufferLock);
|
||||||
|
|
||||||
pos = fitInSendBuffer(size);
|
pos = fitInSendBuffer(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//fit found -> space is allready "reserved" -> write packet to buffer
|
//fit found -> space is allready "reserved" -> write packet to buffer
|
||||||
void *writePointer = networkSendBuffer + pos;
|
void *writePointer = networkSendBuffer + pos;
|
||||||
|
|
||||||
//write seq number
|
//write seq number
|
||||||
*((u16*) writePointer) = networkSeqSendNext;
|
*((u16*) writePointer) = networkSeqSendNext;
|
||||||
networkSeqSendNext++;
|
networkSeqSendNext++;
|
||||||
if(networkSeqSendNext==0) {
|
if(networkSeqSendNext==0) {
|
||||||
networkSeqSendNext = 1;
|
networkSeqSendNext = 1;
|
||||||
}
|
}
|
||||||
writePointer += sizeof(u16);
|
writePointer += sizeof(u16);
|
||||||
|
|
||||||
//write size
|
//write size
|
||||||
*((u16*) writePointer) = (u16) size;
|
*((u16*) writePointer) = (u16) size;
|
||||||
writePointer += sizeof(u16);
|
writePointer += sizeof(u16);
|
||||||
|
|
||||||
//write data
|
//write data
|
||||||
memcpy(writePointer, packet, size);
|
memcpy(writePointer, packet, size);
|
||||||
writePointer += size;
|
writePointer += size;
|
||||||
|
|
||||||
LightLock_Unlock(&sendBufferLock);
|
LightLock_Unlock(&sendBufferLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkSendWaitFlush() {
|
void networkSendWaitFlush() {
|
||||||
while(networkSendBufferStartPos!=networkSendBufferEndPos) {
|
while(networkSendBufferStartPos!=networkSendBufferEndPos) {
|
||||||
svcSleepThread(4500 * 1000);
|
svcSleepThread(4500 * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,359 +5,347 @@
|
||||||
FILE *recvFile;
|
FILE *recvFile;
|
||||||
size_t recvFileSize;
|
size_t recvFileSize;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void * writeBool(void *buffer, size_t *size, bool value) {
|
void * writeBool(void *buffer, size_t *size, bool value) {
|
||||||
*((bool*) buffer) = value;
|
*((bool*) buffer) = value;
|
||||||
*(size) += sizeof(bool);
|
*(size) += sizeof(bool);
|
||||||
return buffer + sizeof(bool);
|
return buffer + sizeof(bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * writeU8(void *buffer, size_t *size, u8 value) {
|
void * writeU8(void *buffer, size_t *size, u8 value) {
|
||||||
*((u8*) buffer) = value;
|
*((u8*) buffer) = value;
|
||||||
*(size) += sizeof(u8);
|
*(size) += sizeof(u8);
|
||||||
return buffer + sizeof(u8);
|
return buffer + sizeof(u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * writeU16(void *buffer, size_t *size, u16 value) {
|
void * writeU16(void *buffer, size_t *size, u16 value) {
|
||||||
*((u16*) buffer) = value;
|
*((u16*) buffer) = value;
|
||||||
*(size) += sizeof(u16);
|
*(size) += sizeof(u16);
|
||||||
return buffer + sizeof(u16);
|
return buffer + sizeof(u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * writeU32(void *buffer, size_t *size, u32 value) {
|
void * writeU32(void *buffer, size_t *size, u32 value) {
|
||||||
*((u32*) buffer) = value;
|
*((u32*) buffer) = value;
|
||||||
*(size) += sizeof(u32);
|
*(size) += sizeof(u32);
|
||||||
return buffer + sizeof(u32);
|
return buffer + sizeof(u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * writeSizeT(void *buffer, size_t *size, size_t value) {
|
void * writeSizeT(void *buffer, size_t *size, size_t value) {
|
||||||
*((size_t*) buffer) = value;
|
*((size_t*) buffer) = value;
|
||||||
*(size) += sizeof(size_t);
|
*(size) += sizeof(size_t);
|
||||||
return buffer + sizeof(size_t);
|
return buffer + sizeof(size_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void * readBool(void *buffer, size_t *size, bool *value) {
|
void * readBool(void *buffer, size_t *size, bool *value) {
|
||||||
*value = *((bool*) buffer);
|
*value = *((bool*) buffer);
|
||||||
*(size) -= sizeof(bool);
|
*(size) -= sizeof(bool);
|
||||||
return buffer + sizeof(bool);
|
return buffer + sizeof(bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * readU8(void *buffer, size_t *size, u8 *value) {
|
void * readU8(void *buffer, size_t *size, u8 *value) {
|
||||||
*value = *((u8*) buffer);
|
*value = *((u8*) buffer);
|
||||||
*(size) -= sizeof(u8);
|
*(size) -= sizeof(u8);
|
||||||
return buffer + sizeof(u8);
|
return buffer + sizeof(u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * readU16(void *buffer, size_t *size, u16 *value) {
|
void * readU16(void *buffer, size_t *size, u16 *value) {
|
||||||
*value = *((u16*) buffer);
|
*value = *((u16*) buffer);
|
||||||
*(size) -= sizeof(u16);
|
*(size) -= sizeof(u16);
|
||||||
return buffer + sizeof(u16);
|
return buffer + sizeof(u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * readU32(void *buffer, size_t *size, u32 *value) {
|
void * readU32(void *buffer, size_t *size, u32 *value) {
|
||||||
*value = *((u32*) buffer);
|
*value = *((u32*) buffer);
|
||||||
*(size) -= sizeof(u32);
|
*(size) -= sizeof(u32);
|
||||||
return buffer + sizeof(u32);
|
return buffer + sizeof(u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void * readSizeT(void *buffer, size_t *size, size_t *value) {
|
void * readSizeT(void *buffer, size_t *size, size_t *value) {
|
||||||
*value = *((size_t*) buffer);
|
*value = *((size_t*) buffer);
|
||||||
*(size) -= sizeof(size_t);
|
*(size) -= sizeof(size_t);
|
||||||
return buffer + sizeof(size_t);
|
return buffer + sizeof(size_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void processPacket(void *packet, size_t size) {
|
void processPacket(void *packet, size_t size) {
|
||||||
//Differenciate the packets and process them
|
//Differenciate the packets and process them
|
||||||
switch(packetGetID(packet)) {
|
switch(packetGetID(packet)) {
|
||||||
case PACKET_START: {
|
case PACKET_START: {
|
||||||
void *buffer = packetGetDataStart(packet);
|
void *buffer = packetGetDataStart(packet);
|
||||||
size = packetGetDataSize(size);
|
size = packetGetDataSize(size);
|
||||||
|
|
||||||
//find player index based on network node id
|
//find player index based on network node id
|
||||||
//and set player uuid in synchronizer
|
//and set player uuid in synchronizer
|
||||||
u32 seed;
|
u32 seed;
|
||||||
u32 playerCount = 1;
|
u32 playerCount = 1;
|
||||||
int playerIndex = 0;
|
int playerIndex = 0;
|
||||||
|
|
||||||
buffer = readU32(buffer, &size, &seed);
|
buffer = readU32(buffer, &size, &seed);
|
||||||
buffer = readU32(buffer, &size, &playerCount);
|
buffer = readU32(buffer, &size, &playerCount);
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
u16 nodeID;
|
u16 nodeID;
|
||||||
|
|
||||||
buffer = readU16(buffer, &size, &nodeID);
|
buffer = readU16(buffer, &size, &nodeID);
|
||||||
|
|
||||||
if(nodeID==networkGetLocalNodeID()) {
|
if(nodeID==networkGetLocalNodeID()) {
|
||||||
playerIndex = i;
|
playerIndex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//cleanup transfer tmp file
|
//cleanup transfer tmp file
|
||||||
FILE *file = fopen("tmpTransfer.bin", "wb");
|
FILE *file = fopen("tmpTransfer.bin", "wb");
|
||||||
if(file!=NULL) {
|
if(file!=NULL) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
remove("tmpTransfer.bin");
|
remove("tmpTransfer.bin");
|
||||||
}
|
}
|
||||||
|
|
||||||
//init synchronizer
|
//init synchronizer
|
||||||
synchronizerInit(seed, playerCount, playerIndex);
|
synchronizerInit(seed, playerCount, playerIndex);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_START_FILEHEADER: {
|
case PACKET_START_FILEHEADER: {
|
||||||
void *data = packetGetDataStart(packet);
|
void *data = packetGetDataStart(packet);
|
||||||
|
|
||||||
u8 type;
|
u8 type;
|
||||||
u8 id;
|
u8 id;
|
||||||
size_t fsize;
|
size_t fsize;
|
||||||
|
|
||||||
data = readU8(data, &size, &type);
|
data = readU8(data, &size, &type);
|
||||||
data = readU8(data, &size, &id);
|
data = readU8(data, &size, &id);
|
||||||
data = readSizeT(data, &size, &fsize);
|
data = readSizeT(data, &size, &fsize);
|
||||||
|
|
||||||
recvFile = fopen("tmpTransfer.bin", "wb");
|
recvFile = fopen("tmpTransfer.bin", "wb");
|
||||||
recvFileSize = fsize;
|
recvFileSize = fsize;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_START_FILEDATA: {
|
case PACKET_START_FILEDATA: {
|
||||||
void *data = packetGetDataStart(packet);
|
void *data = packetGetDataStart(packet);
|
||||||
size_t dsize = packetGetDataSize(size);
|
size_t dsize = packetGetDataSize(size);
|
||||||
|
|
||||||
size_t toread = dsize;
|
size_t toread = dsize;
|
||||||
|
|
||||||
fwrite(data, 1, toread, recvFile);
|
fwrite(data, 1, toread, recvFile);
|
||||||
|
|
||||||
recvFileSize -= toread;
|
recvFileSize -= toread;
|
||||||
if(recvFileSize<=0) {
|
if(recvFileSize<=0) {
|
||||||
fclose(recvFile);
|
fclose(recvFile);
|
||||||
recvFile = NULL;
|
recvFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_START_REQUEST_IDS: {
|
case PACKET_START_REQUEST_IDS: {
|
||||||
synchronizerSendUID();
|
synchronizerSendUID();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_START_ID: {
|
case PACKET_START_ID: {
|
||||||
u8 playerID = packetGetSender(packet);
|
u8 playerID = packetGetSender(packet);
|
||||||
u32 uid;
|
u32 uid;
|
||||||
|
|
||||||
void *data = packetGetDataStart(packet);
|
void *data = packetGetDataStart(packet);
|
||||||
size_t dsize = packetGetDataSize(size);
|
size_t dsize = packetGetDataSize(size);
|
||||||
|
|
||||||
data = readU32(data, &dsize, &uid);
|
data = readU32(data, &dsize, &uid);
|
||||||
|
|
||||||
synchronizerSetPlayerUID(playerID, uid);
|
synchronizerSetPlayerUID(playerID, uid);
|
||||||
synchronizerSendIfReady();
|
synchronizerSendIfReady();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_START_READY: {
|
case PACKET_START_READY: {
|
||||||
synchronizerSetPlayerReady(packetGetSender(packet));
|
synchronizerSetPlayerReady(packetGetSender(packet));
|
||||||
if(playerLocalID==0) {
|
if(playerLocalID==0) {
|
||||||
if(synchronizerAllReady()) {
|
if(synchronizerAllReady()) {
|
||||||
sendStartSyncPacket();
|
sendStartSyncPacket();
|
||||||
synchronizerStart(); //server needs to call this here, all others do when they recieve the packet
|
synchronizerStart(); //server needs to call this here, all others do when they recieve the packet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PACKET_TURN_START: {
|
case PACKET_TURN_START: {
|
||||||
synchronizerStart();
|
synchronizerStart();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_TURN_INPUT: {
|
case PACKET_TURN_INPUT: {
|
||||||
synchronizerOnInputPacket(packetGetSender(packet), packetGetTurn(packet), packetGetDataStart(packet), packetGetDataSize(size));
|
synchronizerOnInputPacket(packetGetSender(packet), packetGetTurn(packet), packetGetDataStart(packet), packetGetDataSize(size));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 packetGetID(void *packet) {
|
u8 packetGetID(void *packet) {
|
||||||
return *((u8*) packet);
|
return *((u8*) packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 packetGetSender(void *packet) {
|
u8 packetGetSender(void *packet) {
|
||||||
return *((u8*) packet+sizeof(u8));
|
return *((u8*) packet+sizeof(u8));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 packetGetTurn(void *packet) {
|
u32 packetGetTurn(void *packet) {
|
||||||
return *((u32*) (packet+sizeof(u8)+sizeof(u8)));
|
return *((u32*) (packet+sizeof(u8)+sizeof(u8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void * packetGetDataStart(void *packet) {
|
void * packetGetDataStart(void *packet) {
|
||||||
return packet+sizeof(u8)+sizeof(u8)+sizeof(u32);
|
return packet+sizeof(u8)+sizeof(u8)+sizeof(u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t packetGetDataSize(size_t size) {
|
size_t packetGetDataSize(size_t size) {
|
||||||
return size-sizeof(u8)-sizeof(u8)-sizeof(u32);
|
return size-sizeof(u8)-sizeof(u8)-sizeof(u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
size_t writeStartPacket(void *buffer, u32 seed) {
|
size_t writeStartPacket(void *buffer, u32 seed) {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
buffer = writeU8(buffer, &size, PACKET_START);
|
buffer = writeU8(buffer, &size, PACKET_START);
|
||||||
buffer = writeU8(buffer, &size, 0);
|
buffer = writeU8(buffer, &size, 0);
|
||||||
buffer = writeU32(buffer, &size, 0);
|
buffer = writeU32(buffer, &size, 0);
|
||||||
|
|
||||||
buffer = writeU32(buffer, &size, seed);
|
buffer = writeU32(buffer, &size, seed);
|
||||||
buffer = writeU32(buffer, &size, (u32)networkGetNodeCount());
|
buffer = writeU32(buffer, &size, (u32)networkGetNodeCount());
|
||||||
for(int i=1; i<=UDS_MAXNODES; i++) {
|
for(int i=1; i<=UDS_MAXNODES; i++) {
|
||||||
if(networkIsNodeConnected(i)) {
|
if(networkIsNodeConnected(i)) {
|
||||||
buffer = writeU16(buffer, &size, (u16)i);
|
buffer = writeU16(buffer, &size, (u16)i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t writeStartRequestPacket(void *buffer) {
|
size_t writeStartRequestPacket(void *buffer) {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
buffer = writeU8(buffer, &size, PACKET_START_REQUEST_IDS);
|
buffer = writeU8(buffer, &size, PACKET_START_REQUEST_IDS);
|
||||||
buffer = writeU8(buffer, &size, 0);
|
buffer = writeU8(buffer, &size, 0);
|
||||||
buffer = writeU32(buffer, &size, 0);
|
buffer = writeU32(buffer, &size, 0);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t writeInputPacket(void *buffer, Inputs *inputs, u8 playerID, u32 turnNumber) {
|
size_t writeInputPacket(void *buffer, Inputs *inputs, u8 playerID, u32 turnNumber) {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
buffer = writeU8(buffer, &size, PACKET_TURN_INPUT);
|
buffer = writeU8(buffer, &size, PACKET_TURN_INPUT);
|
||||||
buffer = writeU8(buffer, &size, playerID);
|
buffer = writeU8(buffer, &size, playerID);
|
||||||
buffer = writeU32(buffer, &size, turnNumber);
|
buffer = writeU32(buffer, &size, turnNumber);
|
||||||
|
|
||||||
buffer = writeU16(buffer, &size, inputs->k_touch.px);
|
buffer = writeU16(buffer, &size, inputs->k_touch.px);
|
||||||
buffer = writeU16(buffer, &size, inputs->k_touch.py);
|
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_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_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_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_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_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_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_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_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_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_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_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);
|
buffer = writeBool(buffer, &size, inputs->k_menuPrev.down); buffer = writeBool(buffer, &size, inputs->k_menuPrev.clicked);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool readInputPacketData(void *buffer, size_t size, Inputs *inputs) {
|
bool readInputPacketData(void *buffer, size_t size, Inputs *inputs) {
|
||||||
buffer = readU16(buffer, &size, &(inputs->k_touch.px));
|
buffer = readU16(buffer, &size, &(inputs->k_touch.px));
|
||||||
if(size<=0) return false;
|
if(size<=0) return false;
|
||||||
buffer = readU16(buffer, &size, &(inputs->k_touch.py));
|
buffer = readU16(buffer, &size, &(inputs->k_touch.py));
|
||||||
if(size<=0) return false;
|
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));
|
|
||||||
|
|
||||||
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) {
|
void sendFile(FILE *file, u8 fileType, u8 id) {
|
||||||
fseek(file, 0, SEEK_END); // seek to end of file
|
fseek(file, 0, SEEK_END); // seek to end of file
|
||||||
size_t fsize = ftell(file); // get current file pointer
|
size_t fsize = ftell(file); // get current file pointer
|
||||||
fseek(file, 0, SEEK_SET); // seek back to beginning of file
|
fseek(file, 0, SEEK_SET); // seek back to beginning of file
|
||||||
|
|
||||||
//send file header
|
//send file header
|
||||||
void *buffer = networkWriteBuffer;
|
void *buffer = networkWriteBuffer;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
buffer = writeU8(buffer, &size, PACKET_START_FILEHEADER);
|
buffer = writeU8(buffer, &size, PACKET_START_FILEHEADER);
|
||||||
buffer = writeU8(buffer, &size, 0);
|
buffer = writeU8(buffer, &size, 0);
|
||||||
buffer = writeU32(buffer, &size, 0);
|
buffer = writeU32(buffer, &size, 0);
|
||||||
buffer = writeU8(buffer, &size, fileType);
|
buffer = writeU8(buffer, &size, fileType);
|
||||||
buffer = writeU8(buffer, &size, id);
|
buffer = writeU8(buffer, &size, id);
|
||||||
buffer = writeSizeT(buffer, &size, fsize);
|
buffer = writeSizeT(buffer, &size, fsize);
|
||||||
networkSend(networkWriteBuffer, size);
|
networkSend(networkWriteBuffer, size);
|
||||||
|
|
||||||
//send file data
|
//send file data
|
||||||
while(fsize>0) {
|
while(fsize>0) {
|
||||||
buffer = networkWriteBuffer;
|
buffer = networkWriteBuffer;
|
||||||
size = 0;
|
size = 0;
|
||||||
buffer = writeU8(buffer, &size, PACKET_START_FILEDATA);
|
buffer = writeU8(buffer, &size, PACKET_START_FILEDATA);
|
||||||
buffer = writeU8(buffer, &size, 0);
|
buffer = writeU8(buffer, &size, 0);
|
||||||
buffer = writeU32(buffer, &size, 0);
|
buffer = writeU32(buffer, &size, 0);
|
||||||
|
|
||||||
//read file data
|
//read file data
|
||||||
size_t towrite = NETWORK_MAXDATASIZE - size;
|
size_t towrite = NETWORK_MAXDATASIZE - size;
|
||||||
if(towrite>fsize) towrite = fsize;
|
if(towrite>fsize) towrite = fsize;
|
||||||
|
|
||||||
fread(buffer, 1, towrite, file);
|
fread(buffer, 1, towrite, file);
|
||||||
|
|
||||||
size += towrite;
|
size += towrite;
|
||||||
fsize -= towrite;
|
fsize -= towrite;
|
||||||
|
|
||||||
//send file data
|
//send file data
|
||||||
networkSend(networkWriteBuffer, size);
|
networkSend(networkWriteBuffer, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendIDPacket(u8 playerID, u32 uid) {
|
void sendIDPacket(u8 playerID, u32 uid) {
|
||||||
void *buffer = networkWriteBuffer;
|
void *buffer = networkWriteBuffer;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
|
||||||
buffer = writeU8(buffer, &size, PACKET_START_ID);
|
buffer = writeU8(buffer, &size, PACKET_START_ID);
|
||||||
buffer = writeU8(buffer, &size, playerID);
|
buffer = writeU8(buffer, &size, playerID);
|
||||||
buffer = writeU32(buffer, &size, 0);
|
buffer = writeU32(buffer, &size, 0);
|
||||||
|
|
||||||
buffer = writeU32(buffer, &size, uid);
|
buffer = writeU32(buffer, &size, uid);
|
||||||
|
|
||||||
networkSend(networkWriteBuffer, size);
|
networkSend(networkWriteBuffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendStartReadyPacket(u8 playerID) {
|
void sendStartReadyPacket(u8 playerID) {
|
||||||
void *buffer = networkWriteBuffer;
|
void *buffer = networkWriteBuffer;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
|
||||||
buffer = writeU8(buffer, &size, PACKET_START_READY);
|
buffer = writeU8(buffer, &size, PACKET_START_READY);
|
||||||
buffer = writeU8(buffer, &size, playerID);
|
buffer = writeU8(buffer, &size, playerID);
|
||||||
buffer = writeU32(buffer, &size, 0);
|
buffer = writeU32(buffer, &size, 0);
|
||||||
|
|
||||||
networkSend(networkWriteBuffer, size);
|
networkSend(networkWriteBuffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendStartSyncPacket() {
|
void sendStartSyncPacket() {
|
||||||
void *buffer = networkWriteBuffer;
|
void *buffer = networkWriteBuffer;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
|
||||||
buffer = writeU8(buffer, &size, PACKET_TURN_START);
|
buffer = writeU8(buffer, &size, PACKET_TURN_START);
|
||||||
buffer = writeU8(buffer, &size, 0);
|
buffer = writeU8(buffer, &size, 0);
|
||||||
buffer = writeU32(buffer, &size, 0);
|
buffer = writeU32(buffer, &size, 0);
|
||||||
|
|
||||||
networkSend(networkWriteBuffer, size);
|
networkSend(networkWriteBuffer, size);
|
||||||
}
|
}
|
||||||
|
|
678
source/Player.c
678
source/Player.c
|
@ -19,15 +19,15 @@ void potionEffect(int type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void initPlayers() {
|
void initPlayers() {
|
||||||
for(int i=0; i<MAX_PLAYERS; i++) {
|
for(int i=0; i<MAX_PLAYERS; i++) {
|
||||||
initPlayer(players+i);
|
initPlayer(players+i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void freePlayers() {
|
void freePlayers() {
|
||||||
for(int i=0; i<MAX_PLAYERS; i++) {
|
for(int i=0; i<MAX_PLAYERS; i++) {
|
||||||
freePlayer(players+i);
|
freePlayer(players+i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerInitMiniMapData(u8 *minimapData) {
|
void playerInitMiniMapData(u8 *minimapData) {
|
||||||
|
@ -38,287 +38,287 @@ void playerInitMiniMapData(u8 *minimapData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerInitEntity(PlayerData *pd) {
|
void playerInitEntity(PlayerData *pd) {
|
||||||
pd->entity.type = ENTITY_PLAYER;
|
pd->entity.type = ENTITY_PLAYER;
|
||||||
pd->entity.level = 1;
|
pd->entity.level = 1;
|
||||||
pd->entity.xr = 4;
|
pd->entity.xr = 4;
|
||||||
pd->entity.yr = 3;
|
pd->entity.yr = 3;
|
||||||
pd->entity.canSwim = true;
|
pd->entity.canSwim = true;
|
||||||
pd->entity.p.ax = 0;
|
pd->entity.p.ax = 0;
|
||||||
pd->entity.p.ay = 0;
|
pd->entity.p.ay = 0;
|
||||||
pd->entity.p.health = 10;
|
pd->entity.p.health = 10;
|
||||||
pd->entity.p.stamina = 10;
|
pd->entity.p.stamina = 10;
|
||||||
pd->entity.p.walkDist = 0;
|
pd->entity.p.walkDist = 0;
|
||||||
pd->entity.p.attackTimer = 0;
|
pd->entity.p.attackTimer = 0;
|
||||||
pd->entity.p.dir = 0;
|
pd->entity.p.dir = 0;
|
||||||
pd->entity.p.isDead = false;
|
pd->entity.p.isDead = false;
|
||||||
pd->entity.p.hasWon = false;
|
pd->entity.p.hasWon = false;
|
||||||
|
|
||||||
pd->entity.p.data = pd;
|
pd->entity.p.data = pd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerInitInventory(PlayerData *pd) {
|
void playerInitInventory(PlayerData *pd) {
|
||||||
//reset inventory
|
//reset inventory
|
||||||
pd->inventory.lastSlot = 0;
|
pd->inventory.lastSlot = 0;
|
||||||
pd->activeItem = &noItem;
|
pd->activeItem = &noItem;
|
||||||
|
|
||||||
addItemToInventory(newItem(ITEM_WORKBENCH,0), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_WORKBENCH,0), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_POWGLOVE,0), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_POWGLOVE,0), &(pd->inventory));
|
||||||
|
|
||||||
if(shouldRenderDebug && playerCount < 2) {
|
if(shouldRenderDebug && playerCount < 2) {
|
||||||
addItemToInventory(newItem(ITEM_GOLD_APPLE,1), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_GOLD_APPLE,1), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_STRENGTH_POTION,1), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_STRENGTH_POTION,1), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_REGEN_POTION,1), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_REGEN_POTION,1), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_SWIM_BREATH_POTION,1), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_SWIM_BREATH_POTION,1), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_SPEED_POTION,1), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_SPEED_POTION,1), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_POTION_MAKER,0), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_POTION_MAKER,0), &(pd->inventory));
|
||||||
addItemToInventory(newItem(TOOL_SHOVEL,1), &(pd->inventory));
|
addItemToInventory(newItem(TOOL_SHOVEL,1), &(pd->inventory));
|
||||||
addItemToInventory(newItem(TOOL_HOE,4), &(pd->inventory));
|
addItemToInventory(newItem(TOOL_HOE,4), &(pd->inventory));
|
||||||
addItemToInventory(newItem(TOOL_SWORD,4), &(pd->inventory));
|
addItemToInventory(newItem(TOOL_SWORD,4), &(pd->inventory));
|
||||||
addItemToInventory(newItem(TOOL_PICKAXE,4), &(pd->inventory));
|
addItemToInventory(newItem(TOOL_PICKAXE,4), &(pd->inventory));
|
||||||
addItemToInventory(newItem(TOOL_AXE,4), &(pd->inventory));
|
addItemToInventory(newItem(TOOL_AXE,4), &(pd->inventory));
|
||||||
|
|
||||||
addItemToInventory(newItem(ITEM_ANVIL,0), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_ANVIL,0), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_CHEST,0), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_CHEST,0), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_OVEN,0), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_OVEN,0), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_FURNACE,0), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_FURNACE,0), &(pd->inventory));
|
||||||
addItemToInventory(newItem(ITEM_LANTERN,0), &(pd->inventory));
|
addItemToInventory(newItem(ITEM_LANTERN,0), &(pd->inventory));
|
||||||
|
|
||||||
addItemToInventory(newItem(TOOL_MAGIC_COMPASS,1), &(pd->inventory));
|
addItemToInventory(newItem(TOOL_MAGIC_COMPASS,1), &(pd->inventory));
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 7;i < 28;++i) addItemToInventory(newItem(i,50), &(pd->inventory));
|
for (i = 7;i < 28;++i) addItemToInventory(newItem(i,50), &(pd->inventory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerInitSprite(PlayerData *pd) {
|
void playerInitSprite(PlayerData *pd) {
|
||||||
pd->sprite.choosen = false;
|
pd->sprite.choosen = false;
|
||||||
|
|
||||||
pd->sprite.legs = 0;
|
pd->sprite.legs = 0;
|
||||||
pd->sprite.body = 0;
|
pd->sprite.body = 0;
|
||||||
pd->sprite.arms = 0;
|
pd->sprite.arms = 0;
|
||||||
pd->sprite.head = 0;
|
pd->sprite.head = 0;
|
||||||
pd->sprite.eyes = 0;
|
pd->sprite.eyes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerInitMenus(PlayerData *pd) {
|
void playerInitMenus(PlayerData *pd) {
|
||||||
pd->ingameMenu = MENU_NONE;
|
pd->ingameMenu = MENU_NONE;
|
||||||
pd->ingameMenuSelection = 0;
|
pd->ingameMenuSelection = 0;
|
||||||
pd->ingameMenuInvSel = 0;
|
pd->ingameMenuInvSel = 0;
|
||||||
pd->ingameMenuInvSelOther = 0;
|
pd->ingameMenuInvSelOther = 0;
|
||||||
pd->ingameMenuAreYouSure = false;
|
pd->ingameMenuAreYouSure = false;
|
||||||
pd->ingameMenuAreYouSureSave = false;
|
pd->ingameMenuAreYouSureSave = false;
|
||||||
pd->ingameMenuTimer = 0;
|
pd->ingameMenuTimer = 0;
|
||||||
|
|
||||||
resetNPCMenuData(&(pd->npcMenuData));
|
resetNPCMenuData(&(pd->npcMenuData));
|
||||||
|
|
||||||
pd->mapShouldRender = false;
|
pd->mapShouldRender = false;
|
||||||
pd->mapScrollX = 0;
|
pd->mapScrollX = 0;
|
||||||
pd->mapScrollY = 0;
|
pd->mapScrollY = 0;
|
||||||
pd->mapZoomLevel = 2;
|
pd->mapZoomLevel = 2;
|
||||||
sprintf(pd->mapText,"x%d", pd->mapZoomLevel);
|
sprintf(pd->mapText,"x%d", pd->mapZoomLevel);
|
||||||
|
|
||||||
pd->touchLastX = -1;
|
pd->touchLastX = -1;
|
||||||
pd->touchLastY = -1;
|
pd->touchLastY = -1;
|
||||||
pd->touchIsDraggingMap = false;
|
pd->touchIsDraggingMap = false;
|
||||||
pd->touchIsChangingSize = false;
|
pd->touchIsChangingSize = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initPlayer(PlayerData *pd) {
|
void initPlayer(PlayerData *pd) {
|
||||||
pd->isSpawned = false;
|
pd->isSpawned = false;
|
||||||
|
|
||||||
playerInitMiniMapData(pd->minimapData);
|
playerInitMiniMapData(pd->minimapData);
|
||||||
playerInitEntity(pd);
|
playerInitEntity(pd);
|
||||||
playerInitInventory(pd);
|
playerInitInventory(pd);
|
||||||
|
|
||||||
playerInitSprite(pd);
|
playerInitSprite(pd);
|
||||||
|
|
||||||
initQuests(&(pd->questManager));
|
initQuests(&(pd->questManager));
|
||||||
resetQuests(&(pd->questManager));
|
resetQuests(&(pd->questManager));
|
||||||
|
|
||||||
playerInitMenus(pd);
|
playerInitMenus(pd);
|
||||||
|
|
||||||
pd->score = 0;
|
pd->score = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void freePlayer(PlayerData *pd) {
|
void freePlayer(PlayerData *pd) {
|
||||||
freeQuests(&(pd->questManager));
|
freeQuests(&(pd->questManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerData* getNearestPlayer(s8 level, s16 x, s16 y) {
|
PlayerData* getNearestPlayer(s8 level, s16 x, s16 y) {
|
||||||
int nearest = -1;
|
int nearest = -1;
|
||||||
unsigned int nearestDist = UINT_MAX;
|
unsigned int nearestDist = UINT_MAX;
|
||||||
|
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
if(players[i].entity.level!=level) continue;
|
if(players[i].entity.level!=level) continue;
|
||||||
|
|
||||||
int xdif = players[i].entity.x - x;
|
int xdif = players[i].entity.x - x;
|
||||||
int ydif = players[i].entity.y - y;
|
int ydif = players[i].entity.y - y;
|
||||||
|
|
||||||
unsigned int dist = xdif*xdif + ydif*ydif;
|
unsigned int dist = xdif*xdif + ydif*ydif;
|
||||||
if(dist<nearestDist) {
|
if(dist<nearestDist) {
|
||||||
nearest = i;
|
nearest = i;
|
||||||
nearestDist = dist;
|
nearestDist = dist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nearest==-1) return NULL;
|
if(nearest==-1) return NULL;
|
||||||
|
|
||||||
return players+nearest;
|
return players+nearest;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerData* getLocalPlayer() {
|
PlayerData* getLocalPlayer() {
|
||||||
return players+playerLocalID;
|
return players+playerLocalID;
|
||||||
}
|
}
|
||||||
|
|
||||||
//player update functions
|
//player update functions
|
||||||
bool playerUseItem(PlayerData *pd) {
|
bool playerUseItem(PlayerData *pd) {
|
||||||
int aitemID = 0;
|
int aitemID = 0;
|
||||||
Item * aitem;
|
Item * aitem;
|
||||||
Item * item ;
|
Item * item ;
|
||||||
|
|
||||||
switch(pd->activeItem->id){
|
switch(pd->activeItem->id){
|
||||||
//shooting arrows
|
//shooting arrows
|
||||||
case TOOL_BOW:
|
case TOOL_BOW:
|
||||||
item = getItemFromInventory(ITEM_ARROW_WOOD, &(pd->inventory));
|
item = getItemFromInventory(ITEM_ARROW_WOOD, &(pd->inventory));
|
||||||
if(item!=NULL) {
|
if(item!=NULL) {
|
||||||
aitemID = ITEM_ARROW_WOOD;
|
aitemID = ITEM_ARROW_WOOD;
|
||||||
aitem = item;
|
aitem = item;
|
||||||
}
|
}
|
||||||
item = getItemFromInventory(ITEM_ARROW_STONE, &(pd->inventory));
|
item = getItemFromInventory(ITEM_ARROW_STONE, &(pd->inventory));
|
||||||
if(item!=NULL) {
|
if(item!=NULL) {
|
||||||
aitemID = ITEM_ARROW_STONE;
|
aitemID = ITEM_ARROW_STONE;
|
||||||
aitem = item;
|
aitem = item;
|
||||||
}
|
}
|
||||||
item = getItemFromInventory(ITEM_ARROW_IRON, &(pd->inventory));
|
item = getItemFromInventory(ITEM_ARROW_IRON, &(pd->inventory));
|
||||||
if(item!=NULL) {
|
if(item!=NULL) {
|
||||||
aitemID = ITEM_ARROW_IRON;
|
aitemID = ITEM_ARROW_IRON;
|
||||||
aitem = item;
|
aitem = item;
|
||||||
}
|
}
|
||||||
item = getItemFromInventory(ITEM_ARROW_GOLD, &(pd->inventory));
|
item = getItemFromInventory(ITEM_ARROW_GOLD, &(pd->inventory));
|
||||||
if(item!=NULL) {
|
if(item!=NULL) {
|
||||||
aitemID = ITEM_ARROW_GOLD;
|
aitemID = ITEM_ARROW_GOLD;
|
||||||
aitem = item;
|
aitem = item;
|
||||||
}
|
}
|
||||||
item = getItemFromInventory(ITEM_ARROW_GEM, &(pd->inventory));
|
item = getItemFromInventory(ITEM_ARROW_GEM, &(pd->inventory));
|
||||||
if(item!=NULL) {
|
if(item!=NULL) {
|
||||||
aitemID = ITEM_ARROW_GEM;
|
aitemID = ITEM_ARROW_GEM;
|
||||||
aitem = item;
|
aitem = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(aitemID!=0) {
|
if(aitemID!=0) {
|
||||||
--aitem->countLevel;
|
--aitem->countLevel;
|
||||||
if (isItemEmpty(aitem)) {
|
if (isItemEmpty(aitem)) {
|
||||||
removeItemFromInventory(aitem->slotNum, &(pd->inventory));
|
removeItemFromInventory(aitem->slotNum, &(pd->inventory));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(pd->entity.p.dir) {
|
switch(pd->entity.p.dir) {
|
||||||
case 0:
|
case 0:
|
||||||
addEntityToList(newArrowEntity(&(pd->entity), aitemID, 0, 2, pd->entity.level), &eManager);
|
addEntityToList(newArrowEntity(&(pd->entity), aitemID, 0, 2, pd->entity.level), &eManager);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
addEntityToList(newArrowEntity(&(pd->entity), aitemID, 0, -2, pd->entity.level), &eManager);
|
addEntityToList(newArrowEntity(&(pd->entity), aitemID, 0, -2, pd->entity.level), &eManager);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
addEntityToList(newArrowEntity(&(pd->entity), aitemID, -2, 0, pd->entity.level), &eManager);
|
addEntityToList(newArrowEntity(&(pd->entity), aitemID, -2, 0, pd->entity.level), &eManager);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
addEntityToList(newArrowEntity(&(pd->entity), aitemID, 2, 0, pd->entity.level), &eManager);
|
addEntityToList(newArrowEntity(&(pd->entity), aitemID, 2, 0, pd->entity.level), &eManager);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Health items
|
// Health items
|
||||||
case ITEM_APPLE:
|
case ITEM_APPLE:
|
||||||
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 2)){
|
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 2)){
|
||||||
playerHeal(pd, 1);
|
playerHeal(pd, 1);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ITEM_STRENGTH_POTION:
|
case ITEM_STRENGTH_POTION:
|
||||||
if(pd->entity.p.health < 20 && pd->entity.p.strengthTimer == 0){
|
if(pd->entity.p.health < 20 && pd->entity.p.strengthTimer == 0){
|
||||||
potionEffect(1);
|
potionEffect(1);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case ITEM_SPEED_POTION:
|
case ITEM_SPEED_POTION:
|
||||||
if(pd->entity.p.health < 20 && pd->entity.p.speedTimer == 0){
|
if(pd->entity.p.health < 20 && pd->entity.p.speedTimer == 0){
|
||||||
potionEffect(2);
|
potionEffect(2);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case ITEM_REGEN_POTION:
|
case ITEM_REGEN_POTION:
|
||||||
if(pd->entity.p.health < 20 && pd->entity.p.regenTimer == 0){
|
if(pd->entity.p.health < 20 && pd->entity.p.regenTimer == 0){
|
||||||
potionEffect(3);
|
potionEffect(3);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case ITEM_SWIM_BREATH_POTION:
|
case ITEM_SWIM_BREATH_POTION:
|
||||||
if(pd->entity.p.health < 20 && pd->entity.p.swimBreathTimer == 0){
|
if(pd->entity.p.health < 20 && pd->entity.p.swimBreathTimer == 0){
|
||||||
potionEffect(4);
|
potionEffect(4);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case ITEM_GOLD_APPLE:
|
case ITEM_GOLD_APPLE:
|
||||||
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 1)){
|
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 1)){
|
||||||
playerHeal(pd, 8);
|
playerHeal(pd, 8);
|
||||||
playerUseEnergy(pd, -10);
|
playerUseEnergy(pd, -10);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case ITEM_FLESH:
|
case ITEM_FLESH:
|
||||||
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){
|
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){
|
||||||
playerHeal(pd, 1);
|
playerHeal(pd, 1);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ITEM_BREAD:
|
case ITEM_BREAD:
|
||||||
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){
|
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){
|
||||||
playerHeal(pd, 2);
|
playerHeal(pd, 2);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ITEM_PORK_RAW:
|
case ITEM_PORK_RAW:
|
||||||
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){
|
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){
|
||||||
playerHeal(pd, 1);
|
playerHeal(pd, 1);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ITEM_PORK_COOKED:
|
case ITEM_PORK_COOKED:
|
||||||
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){
|
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){
|
||||||
playerHeal(pd, 3);
|
playerHeal(pd, 3);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ITEM_BEEF_RAW:
|
case ITEM_BEEF_RAW:
|
||||||
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){
|
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 4+(rand()%4))){
|
||||||
playerHeal(pd, 1);
|
playerHeal(pd, 1);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ITEM_BEEF_COOKED:
|
case ITEM_BEEF_COOKED:
|
||||||
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){
|
if(pd->entity.p.health < 10 && playerUseEnergy(pd, 3)){
|
||||||
playerHeal(pd, 4);
|
playerHeal(pd, 4);
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
//special item
|
//special item
|
||||||
case ITEM_WIZARD_SUMMON:
|
case ITEM_WIZARD_SUMMON:
|
||||||
if(pd->entity.level==0) {
|
if(pd->entity.level==0) {
|
||||||
--(pd->activeItem->countLevel);
|
--(pd->activeItem->countLevel);
|
||||||
|
|
||||||
airWizardHealthDisplay = 2000;
|
airWizardHealthDisplay = 2000;
|
||||||
addEntityToList(newAirWizardEntity(630, 820, 0), &eManager);
|
addEntityToList(newAirWizardEntity(630, 820, 0), &eManager);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isItemEmpty(pd->activeItem)) {
|
if (isItemEmpty(pd->activeItem)) {
|
||||||
removeItemFromInventory(pd->activeItem->slotNum, &(pd->inventory));
|
removeItemFromInventory(pd->activeItem->slotNum, &(pd->inventory));
|
||||||
pd->activeItem = &noItem;
|
pd->activeItem = &noItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,28 +329,28 @@ bool playerInteract(PlayerData *pd, int x0, int y0, int x1, int y1) {
|
||||||
for (i = 0; i < eSize; ++i) {
|
for (i = 0; i < eSize; ++i) {
|
||||||
Entity * ent = es[i];
|
Entity * ent = es[i];
|
||||||
if (ent != &(pd->entity)){
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerAttack(PlayerData *pd) {
|
void playerAttack(PlayerData *pd) {
|
||||||
bool done = false;
|
bool done = false;
|
||||||
pd->entity.p.attackTimer = 5;
|
pd->entity.p.attackTimer = 5;
|
||||||
int yo = -2;
|
int yo = -2;
|
||||||
int range = 12;
|
int range = 12;
|
||||||
|
|
||||||
//directly using an item
|
//directly using an item
|
||||||
if(playerUseItem(pd)) return;
|
if(playerUseItem(pd)) return;
|
||||||
|
|
||||||
//interacting with entities
|
//interacting with entities
|
||||||
switch(pd->entity.p.dir){
|
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 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 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 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;
|
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 xt = pd->entity.x >> 4;
|
||||||
int yt = (pd->entity.y + yo) >> 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 == 2) xt = (pd->entity.x - r) >> 4;
|
||||||
if (pd->entity.p.dir == 3) 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) {
|
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);
|
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 > 0){
|
||||||
if(itract==2) pd->entity.p.isCarrying = false;
|
if(itract==2) pd->entity.p.isCarrying = false;
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pd->activeItem != &noItem && isItemEmpty(pd->activeItem)) {
|
if (pd->activeItem != &noItem && isItemEmpty(pd->activeItem)) {
|
||||||
removeItemFromInventory(pd->activeItem->slotNum, &(pd->inventory));
|
removeItemFromInventory(pd->activeItem->slotNum, &(pd->inventory));
|
||||||
pd->activeItem = &noItem;
|
pd->activeItem = &noItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(done) return;
|
if(done) return;
|
||||||
|
|
||||||
//breaking tiles
|
//breaking tiles
|
||||||
if (pd->activeItem == &noItem || pd->activeItem->id == TOOL_SWORD || pd->activeItem->id == TOOL_AXE) {
|
if (pd->activeItem == &noItem || pd->activeItem->id == TOOL_SWORD || pd->activeItem->id == TOOL_AXE) {
|
||||||
if (xt >= 0 && yt >= 0 && xt < 128 && 128) {
|
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);
|
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) {
|
bool playerUseArea(PlayerData *pd, int x0, int y0, int x1, int y1) {
|
||||||
Entity * entities[eManager.lastSlot[pd->entity.level]];
|
Entity * entities[eManager.lastSlot[pd->entity.level]];
|
||||||
int i;
|
int i;
|
||||||
int ae = getEntities(entities, pd->entity.level, x0, y0, x1, y1);
|
int ae = getEntities(entities, pd->entity.level, x0, y0, x1, y1);
|
||||||
for(i = 0; i < ae; ++i){
|
for(i = 0; i < ae; ++i){
|
||||||
if(useEntity(pd, entities[i])) return true;
|
if(useEntity(pd, entities[i])) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,14 +404,14 @@ bool playerUse(PlayerData *pd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void tickPlayer(PlayerData *pd, bool inmenu) {
|
void tickPlayer(PlayerData *pd, bool inmenu) {
|
||||||
if (pd->entity.p.isDead) return;
|
if (pd->entity.p.isDead) return;
|
||||||
|
|
||||||
//invincibility time
|
//invincibility time
|
||||||
if (pd->entity.hurtTime > 0) pd->entity.hurtTime--;
|
if (pd->entity.hurtTime > 0) pd->entity.hurtTime--;
|
||||||
|
|
||||||
//stamina recharging
|
//stamina recharging
|
||||||
bool swimming = isWater(pd->entity.level, pd->entity.x>>4, pd->entity.y>>4);
|
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.stamina <= 0 && pd->entity.p.staminaRechargeDelay == 0 && pd->entity.p.staminaRecharge == 0) {
|
||||||
pd->entity.p.staminaRechargeDelay = 40;
|
pd->entity.p.staminaRechargeDelay = 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,25 +422,25 @@ void tickPlayer(PlayerData *pd, bool inmenu) {
|
||||||
if (pd->entity.p.staminaRechargeDelay == 0) {
|
if (pd->entity.p.staminaRechargeDelay == 0) {
|
||||||
++pd->entity.p.staminaRecharge;
|
++pd->entity.p.staminaRecharge;
|
||||||
if (swimming) pd->entity.p.staminaRecharge = 0;
|
if (swimming) pd->entity.p.staminaRecharge = 0;
|
||||||
|
|
||||||
while (pd->entity.p.staminaRecharge > 10) {
|
while (pd->entity.p.staminaRecharge > 10) {
|
||||||
pd->entity.p.staminaRecharge -= 10;
|
pd->entity.p.staminaRecharge -= 10;
|
||||||
if (pd->entity.p.stamina < 10) ++pd->entity.p.stamina;
|
if (pd->entity.p.stamina < 10) ++pd->entity.p.stamina;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!inmenu) {
|
if(!inmenu) {
|
||||||
if(!pd->sprite.choosen) {
|
if(!pd->sprite.choosen) {
|
||||||
pd->ingameMenu = MENU_CHARACTER_CUSTOMIZE;
|
pd->ingameMenu = MENU_CHARACTER_CUSTOMIZE;
|
||||||
pd->ingameMenuSelection = 0;
|
pd->ingameMenuSelection = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//movement
|
//movement
|
||||||
pd->entity.p.ax = 0;
|
pd->entity.p.ax = 0;
|
||||||
pd->entity.p.ay = 0;
|
pd->entity.p.ay = 0;
|
||||||
|
|
||||||
if (pd->inputs.k_left.down){
|
if (pd->inputs.k_left.down){
|
||||||
if(UnderSpeedEffect) {
|
if(UnderSpeedEffect) {
|
||||||
pd->entity.p.ax -= 2;
|
pd->entity.p.ax -= 2;
|
||||||
pd->entity.p.dir = 2;
|
pd->entity.p.dir = 2;
|
||||||
|
@ -451,9 +451,9 @@ void tickPlayer(PlayerData *pd, bool inmenu) {
|
||||||
pd->entity.p.dir = 2;
|
pd->entity.p.dir = 2;
|
||||||
++pd->entity.p.walkDist;
|
++pd->entity.p.walkDist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pd->inputs.k_right.down){
|
if (pd->inputs.k_right.down){
|
||||||
if(UnderSpeedEffect) {
|
if(UnderSpeedEffect) {
|
||||||
pd->entity.p.ax += 2;
|
pd->entity.p.ax += 2;
|
||||||
pd->entity.p.dir = 3;
|
pd->entity.p.dir = 3;
|
||||||
++pd->entity.p.walkDist;
|
++pd->entity.p.walkDist;
|
||||||
|
@ -463,9 +463,9 @@ void tickPlayer(PlayerData *pd, bool inmenu) {
|
||||||
pd->entity.p.dir = 3;
|
pd->entity.p.dir = 3;
|
||||||
++pd->entity.p.walkDist;
|
++pd->entity.p.walkDist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pd->inputs.k_up.down){
|
if (pd->inputs.k_up.down){
|
||||||
if(UnderSpeedEffect) {
|
if(UnderSpeedEffect) {
|
||||||
pd->entity.p.ay -= 2;
|
pd->entity.p.ay -= 2;
|
||||||
pd->entity.p.dir = 1;
|
pd->entity.p.dir = 1;
|
||||||
++pd->entity.p.walkDist;
|
++pd->entity.p.walkDist;
|
||||||
|
@ -475,9 +475,9 @@ void tickPlayer(PlayerData *pd, bool inmenu) {
|
||||||
pd->entity.p.dir = 1;
|
pd->entity.p.dir = 1;
|
||||||
++pd->entity.p.walkDist;
|
++pd->entity.p.walkDist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pd->inputs.k_down.down){
|
if (pd->inputs.k_down.down){
|
||||||
if(UnderSpeedEffect) {
|
if(UnderSpeedEffect) {
|
||||||
pd->entity.p.ay += 2;
|
pd->entity.p.ay += 2;
|
||||||
pd->entity.p.dir = 0;
|
pd->entity.p.dir = 0;
|
||||||
++pd->entity.p.walkDist;
|
++pd->entity.p.walkDist;
|
||||||
|
@ -487,52 +487,52 @@ void tickPlayer(PlayerData *pd, bool inmenu) {
|
||||||
pd->entity.p.dir = 0;
|
pd->entity.p.dir = 0;
|
||||||
++pd->entity.p.walkDist;
|
++pd->entity.p.walkDist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pd->entity.p.staminaRechargeDelay % 2 == 0) moveMob(&(pd->entity), pd->entity.p.ax, pd->entity.p.ay);
|
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
|
//"pausing", TODO: since multiplayer this will no longer pause
|
||||||
if (pd->inputs.k_pause.clicked){
|
if (pd->inputs.k_pause.clicked){
|
||||||
pd->ingameMenuSelection = 0;
|
pd->ingameMenuSelection = 0;
|
||||||
pd->ingameMenu = MENU_PAUSED;
|
pd->ingameMenu = MENU_PAUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
//attacking
|
//attacking
|
||||||
if(pd->inputs.k_attack.clicked){
|
if(pd->inputs.k_attack.clicked){
|
||||||
if (pd->entity.p.stamina != 0) {
|
if (pd->entity.p.stamina != 0) {
|
||||||
if(!shouldRenderDebug) pd->entity.p.stamina--;
|
if(!shouldRenderDebug) pd->entity.p.stamina--;
|
||||||
pd->entity.p.staminaRecharge = 0;
|
pd->entity.p.staminaRecharge = 0;
|
||||||
|
|
||||||
playerAttack(pd);
|
playerAttack(pd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pd->inputs.k_menu.clicked){
|
if (pd->inputs.k_menu.clicked){
|
||||||
pd->ingameMenuInvSel = 0;
|
pd->ingameMenuInvSel = 0;
|
||||||
if(!playerUse(pd)) pd->ingameMenu = MENU_INVENTORY;
|
if(!playerUse(pd)) pd->ingameMenu = MENU_INVENTORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//swimming stamina and drowning
|
//swimming stamina and drowning
|
||||||
if (swimming && pd->entity.p.swimTimer % 60 == 0 && UnderSwimBreathEffect != true) {
|
if (swimming && pd->entity.p.swimTimer % 60 == 0 && UnderSwimBreathEffect != true) {
|
||||||
if (pd->entity.p.stamina > 0) {
|
if (pd->entity.p.stamina > 0) {
|
||||||
if(!shouldRenderDebug) --pd->entity.p.stamina;
|
if(!shouldRenderDebug) --pd->entity.p.stamina;
|
||||||
} else {
|
} else {
|
||||||
hurtEntity(&(pd->entity), 1, -1, 0xFFAF00FF, NULL);
|
hurtEntity(&(pd->entity), 1, -1, 0xFFAF00FF, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Regen healing
|
//Regen healing
|
||||||
if (regening && pd->entity.p.regenTimer % 75 == 0) {
|
if (regening && pd->entity.p.regenTimer % 75 == 0) {
|
||||||
playerHeal(pd, 1);
|
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(regening) ++pd->entity.p.regenTimer;
|
||||||
if(UnderSpeedEffect) ++pd->entity.p.speedTimer;
|
if(UnderSpeedEffect) ++pd->entity.p.speedTimer;
|
||||||
if(UnderStrengthEffect) ++pd->entity.p.strengthTimer;
|
if(UnderStrengthEffect) ++pd->entity.p.strengthTimer;
|
||||||
if(UnderSwimBreathEffect) ++pd->entity.p.swimBreathTimer;
|
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
|
//TODO - maybe move to own function
|
||||||
//Update Minimap
|
//Update Minimap
|
||||||
int xp;
|
int xp;
|
||||||
|
@ -549,35 +549,35 @@ void tickPlayer(PlayerData *pd, bool inmenu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerSetActiveItem(PlayerData *pd, Item *item) {
|
void playerSetActiveItem(PlayerData *pd, Item *item) {
|
||||||
pd->activeItem = item;
|
pd->activeItem = item;
|
||||||
if(pd->activeItem->id > 27 && pd->activeItem->id < 51) pd->entity.p.isCarrying = true;
|
if(pd->activeItem->id > 27 && pd->activeItem->id < 51) pd->entity.p.isCarrying = true;
|
||||||
else pd->entity.p.isCarrying = false;
|
else pd->entity.p.isCarrying = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool playerUseEnergy(PlayerData *pd, int amount) {
|
bool playerUseEnergy(PlayerData *pd, int amount) {
|
||||||
if(shouldRenderDebug) return true;
|
if(shouldRenderDebug) return true;
|
||||||
if(amount > pd->entity.p.stamina) return false;
|
if(amount > pd->entity.p.stamina) return false;
|
||||||
pd->entity.p.stamina -= amount;
|
pd->entity.p.stamina -= amount;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerHeal(PlayerData *pd, int amount) {
|
void playerHeal(PlayerData *pd, int amount) {
|
||||||
pd->entity.p.health += amount;
|
pd->entity.p.health += amount;
|
||||||
if(pd->entity.p.health > 10) pd->entity.p.health = 10;
|
if(pd->entity.p.health > 10) pd->entity.p.health = 10;
|
||||||
char healText[11];
|
char healText[11];
|
||||||
sprintf(healText, "%d", amount);
|
sprintf(healText, "%d", amount);
|
||||||
addEntityToList(newTextParticleEntity(healText,0xFF00FF00, pd->entity.x, pd->entity.y, pd->entity.level), &eManager);
|
addEntityToList(newTextParticleEntity(healText,0xFF00FF00, pd->entity.x, pd->entity.y, pd->entity.level), &eManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerSpawn(PlayerData *pd) {
|
void playerSpawn(PlayerData *pd) {
|
||||||
while(true){
|
while(true){
|
||||||
int rx = rand()%128;
|
int rx = rand()%128;
|
||||||
int ry = rand()%128;
|
int ry = rand()%128;
|
||||||
if(getTile(pd->entity.level, rx, ry) == TILE_GRASS){
|
if(getTile(pd->entity.level, rx, ry) == TILE_GRASS){
|
||||||
pd->entity.x = (rx << 4) + 8;
|
pd->entity.x = (rx << 4) + 8;
|
||||||
pd->entity.y = (ry << 4) + 8;
|
pd->entity.y = (ry << 4) + 8;
|
||||||
pd->isSpawned = true;
|
pd->isSpawned = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
108
source/Player.h
108
source/Player.h
|
@ -16,64 +16,64 @@
|
||||||
|
|
||||||
|
|
||||||
typedef struct _plrsp {
|
typedef struct _plrsp {
|
||||||
bool choosen;
|
bool choosen;
|
||||||
|
|
||||||
u8 legs;
|
u8 legs;
|
||||||
u8 body;
|
u8 body;
|
||||||
u8 arms;
|
u8 arms;
|
||||||
u8 head;
|
u8 head;
|
||||||
u8 eyes;
|
u8 eyes;
|
||||||
} PlayerSprite;
|
} PlayerSprite;
|
||||||
|
|
||||||
typedef struct _plrd {
|
typedef struct _plrd {
|
||||||
//for identification in save data and sync game start
|
//for identification in save data and sync game start
|
||||||
u32 id;
|
u32 id;
|
||||||
bool idSet;
|
bool idSet;
|
||||||
bool ready;
|
bool ready;
|
||||||
|
|
||||||
//input/multiplayer/synchronization
|
//input/multiplayer/synchronization
|
||||||
Inputs inputs;
|
Inputs inputs;
|
||||||
Inputs nextInputs[MAX_INPUT_BUFFER];
|
Inputs nextInputs[MAX_INPUT_BUFFER];
|
||||||
bool nextTurnReady[MAX_INPUT_BUFFER];
|
bool nextTurnReady[MAX_INPUT_BUFFER];
|
||||||
|
|
||||||
//
|
//
|
||||||
bool isSpawned;
|
bool isSpawned;
|
||||||
u8 minimapData[128*128];
|
u8 minimapData[128*128];
|
||||||
|
|
||||||
int score;
|
int score;
|
||||||
QuestlineManager questManager;
|
QuestlineManager questManager;
|
||||||
|
|
||||||
Entity entity;
|
Entity entity;
|
||||||
Inventory inventory;
|
Inventory inventory;
|
||||||
Item *activeItem;
|
Item *activeItem;
|
||||||
|
|
||||||
PlayerSprite sprite;
|
PlayerSprite sprite;
|
||||||
|
|
||||||
//menu data
|
//menu data
|
||||||
u8 ingameMenu;
|
u8 ingameMenu;
|
||||||
s8 ingameMenuSelection;
|
s8 ingameMenuSelection;
|
||||||
s16 ingameMenuInvSel;
|
s16 ingameMenuInvSel;
|
||||||
s16 ingameMenuInvSelOther;
|
s16 ingameMenuInvSelOther;
|
||||||
bool ingameMenuAreYouSure;
|
bool ingameMenuAreYouSure;
|
||||||
bool ingameMenuAreYouSureSave;
|
bool ingameMenuAreYouSureSave;
|
||||||
s16 ingameMenuTimer;
|
s16 ingameMenuTimer;
|
||||||
NPC_MenuData npcMenuData;
|
NPC_MenuData npcMenuData;
|
||||||
|
|
||||||
RecipeManager currentRecipes;
|
RecipeManager currentRecipes;
|
||||||
char *currentCraftTitle;
|
char *currentCraftTitle;
|
||||||
Entity *curChestEntity;
|
Entity *curChestEntity;
|
||||||
s8 curChestEntityR;
|
s8 curChestEntityR;
|
||||||
|
|
||||||
bool mapShouldRender;
|
bool mapShouldRender;
|
||||||
u8 mapZoomLevel;
|
u8 mapZoomLevel;
|
||||||
s16 mapScrollX;
|
s16 mapScrollX;
|
||||||
s16 mapScrollY;
|
s16 mapScrollY;
|
||||||
char mapText[32];
|
char mapText[32];
|
||||||
|
|
||||||
s16 touchLastX;
|
s16 touchLastX;
|
||||||
s16 touchLastY;
|
s16 touchLastY;
|
||||||
bool touchIsDraggingMap;
|
bool touchIsDraggingMap;
|
||||||
bool touchIsChangingSize;
|
bool touchIsChangingSize;
|
||||||
} PlayerData;
|
} PlayerData;
|
||||||
|
|
||||||
PlayerData players[MAX_PLAYERS];
|
PlayerData players[MAX_PLAYERS];
|
||||||
|
|
794
source/Quests.c
794
source/Quests.c
|
@ -4,434 +4,434 @@
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
|
|
||||||
void initTrades() {
|
void initTrades() {
|
||||||
priestTrades.size = 5;
|
priestTrades.size = 5;
|
||||||
priestTrades.recipes = (Recipe*)malloc(sizeof(Recipe) * (priestTrades.size));
|
priestTrades.recipes = (Recipe*)malloc(sizeof(Recipe) * (priestTrades.size));
|
||||||
priestTrades.recipes[0] = defineRecipe(ITEM_DUNGEON_KEY,1,1,ITEM_MAGIC_DUST,2);
|
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[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[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[3] = defineRecipe(ITEM_COIN,1,1,ITEM_SLIME,5);
|
||||||
priestTrades.recipes[4] = defineRecipe(ITEM_COIN,1,1,ITEM_FLESH,5);
|
priestTrades.recipes[4] = defineRecipe(ITEM_COIN,1,1,ITEM_FLESH,5);
|
||||||
|
|
||||||
farmerTrades.size = 7;
|
farmerTrades.size = 7;
|
||||||
farmerTrades.recipes = (Recipe*)malloc(sizeof(Recipe) * (farmerTrades.size));
|
farmerTrades.recipes = (Recipe*)malloc(sizeof(Recipe) * (farmerTrades.size));
|
||||||
farmerTrades.recipes[0] = defineRecipe(ITEM_WHEAT,5,1,ITEM_COIN,3);
|
farmerTrades.recipes[0] = defineRecipe(ITEM_WHEAT,5,1,ITEM_COIN,3);
|
||||||
farmerTrades.recipes[1] = defineRecipe(ITEM_BREAD,1,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[2] = defineRecipe(ITEM_APPLE,2,1,ITEM_COIN,4);
|
||||||
farmerTrades.recipes[3] = defineRecipe(ITEM_ACORN,3,1,ITEM_COIN,1);
|
farmerTrades.recipes[3] = defineRecipe(ITEM_ACORN,3,1,ITEM_COIN,1);
|
||||||
farmerTrades.recipes[4] = defineRecipe(ITEM_SEEDS,4,1,ITEM_COIN,2);
|
farmerTrades.recipes[4] = defineRecipe(ITEM_SEEDS,4,1,ITEM_COIN,2);
|
||||||
farmerTrades.recipes[5] = defineRecipe(ITEM_COIN,2,1,ITEM_SEEDS,5);
|
farmerTrades.recipes[5] = defineRecipe(ITEM_COIN,2,1,ITEM_SEEDS,5);
|
||||||
farmerTrades.recipes[6] = defineRecipe(ITEM_COIN,1,1,ITEM_ACORN,5);
|
farmerTrades.recipes[6] = defineRecipe(ITEM_COIN,1,1,ITEM_ACORN,5);
|
||||||
|
|
||||||
dwarfTrades.size = 2;
|
dwarfTrades.size = 2;
|
||||||
dwarfTrades.recipes = (Recipe*)malloc(sizeof(Recipe) * (dwarfTrades.size));
|
dwarfTrades.recipes = (Recipe*)malloc(sizeof(Recipe) * (dwarfTrades.size));
|
||||||
dwarfTrades.recipes[0] = defineRecipe(ITEM_IRONINGOT,4,1,ITEM_GOLDINGOT,1);
|
dwarfTrades.recipes[0] = defineRecipe(ITEM_IRONINGOT,4,1,ITEM_GOLDINGOT,1);
|
||||||
dwarfTrades.recipes[1] = defineRecipe(ITEM_GOLDINGOT,2,1,ITEM_GEM,1);
|
dwarfTrades.recipes[1] = defineRecipe(ITEM_GOLDINGOT,2,1,ITEM_GEM,1);
|
||||||
//TODO: Trade Dragon Scales for something really nice
|
//TODO: Trade Dragon Scales for something really nice
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeTrades() {
|
void freeTrades() {
|
||||||
free(priestTrades.recipes);
|
free(priestTrades.recipes);
|
||||||
free(farmerTrades.recipes);
|
free(farmerTrades.recipes);
|
||||||
free(dwarfTrades.recipes);
|
free(dwarfTrades.recipes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initQuests(QuestlineManager *questManager) {
|
void initQuests(QuestlineManager *questManager) {
|
||||||
if(questManager->questlines!=NULL) {
|
if(questManager->questlines!=NULL) {
|
||||||
freeQuests(questManager);
|
freeQuests(questManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
questManager->size = 2;
|
questManager->size = 2;
|
||||||
questManager->questlines = (Questline*)malloc(sizeof(Questline) * (questManager->size));
|
questManager->questlines = (Questline*)malloc(sizeof(Questline) * (questManager->size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetQuests(QuestlineManager *questManager) {
|
void resetQuests(QuestlineManager *questManager) {
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<questManager->size; ++i) {
|
for(i=0; i<questManager->size; ++i) {
|
||||||
questManager->questlines[i].currentQuest = 0;
|
questManager->questlines[i].currentQuest = 0;
|
||||||
questManager->questlines[i].currentQuestDone = false;
|
questManager->questlines[i].currentQuestDone = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeQuests(QuestlineManager *questManager) {
|
void freeQuests(QuestlineManager *questManager) {
|
||||||
free(questManager->questlines);
|
free(questManager->questlines);
|
||||||
questManager->questlines = NULL;
|
questManager->questlines = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetNPCMenuData(NPC_MenuData *data) {
|
void resetNPCMenuData(NPC_MenuData *data) {
|
||||||
data->currentNPC = 0;
|
data->currentNPC = 0;
|
||||||
data->currentNPCMenu = 0;
|
data->currentNPCMenu = 0;
|
||||||
data->currentNPCVal = 0;
|
data->currentNPCVal = 0;
|
||||||
|
|
||||||
data->currentTalkSel = 0;
|
data->currentTalkSel = 0;
|
||||||
data->currentTalkDone = false;
|
data->currentTalkDone = false;
|
||||||
data->currentTalkOptions = 0;
|
data->currentTalkOptions = 0;
|
||||||
|
|
||||||
data->currentTalkOption0 = "";
|
data->currentTalkOption0 = "";
|
||||||
data->currentTalkOption1 = "";
|
data->currentTalkOption1 = "";
|
||||||
data->currentTalkOption2 = "";
|
data->currentTalkOption2 = "";
|
||||||
data->currentTalk0 = "";
|
data->currentTalk0 = "";
|
||||||
data->currentTalk1 = "";
|
data->currentTalk1 = "";
|
||||||
data->currentTalk2 = "";
|
data->currentTalk2 = "";
|
||||||
data->currentTalk3 = "";
|
data->currentTalk3 = "";
|
||||||
data->currentTalk4 = "";
|
data->currentTalk4 = "";
|
||||||
data->currentTalk5 = "";
|
data->currentTalk5 = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void openNPCMenu(PlayerData *pd, int npc) {
|
void openNPCMenu(PlayerData *pd, int npc) {
|
||||||
pd->ingameMenu = MENU_NPC;
|
pd->ingameMenu = MENU_NPC;
|
||||||
|
|
||||||
NPC_MenuData *data = &(pd->npcMenuData);
|
NPC_MenuData *data = &(pd->npcMenuData);
|
||||||
QuestlineManager *questManager = &(pd->questManager);
|
QuestlineManager *questManager = &(pd->questManager);
|
||||||
|
|
||||||
data->currentNPC = npc;
|
data->currentNPC = npc;
|
||||||
data->currentNPCVal = 0;
|
data->currentNPCVal = 0;
|
||||||
data->currentNPCMenu = NPC_MENU_TALK;
|
data->currentNPCMenu = NPC_MENU_TALK;
|
||||||
|
|
||||||
data->currentTalkSel = 0;
|
data->currentTalkSel = 0;
|
||||||
data->currentTalkDone = false;
|
data->currentTalkDone = false;
|
||||||
data->currentTalkOptions = 1;
|
data->currentTalkOptions = 1;
|
||||||
data->currentTalkOption0 = "Bye";
|
data->currentTalkOption0 = "Bye";
|
||||||
data->currentTalkOption1 = "";
|
data->currentTalkOption1 = "";
|
||||||
data->currentTalkOption2 = "";
|
data->currentTalkOption2 = "";
|
||||||
data->currentTalk0 = "";
|
data->currentTalk0 = "";
|
||||||
data->currentTalk1 = "";
|
data->currentTalk1 = "";
|
||||||
data->currentTalk2 = "";
|
data->currentTalk2 = "";
|
||||||
data->currentTalk3 = "";
|
data->currentTalk3 = "";
|
||||||
data->currentTalk4 = "";
|
data->currentTalk4 = "";
|
||||||
data->currentTalk5 = "";
|
data->currentTalk5 = "";
|
||||||
|
|
||||||
//TODO: Handle upon currentNPC as well as the fitting quest progress
|
//TODO: Handle upon currentNPC as well as the fitting quest progress
|
||||||
switch(data->currentNPC) {
|
switch(data->currentNPC) {
|
||||||
case NPC_GIRL:
|
case NPC_GIRL:
|
||||||
data->currentTalkOptions = 1;
|
data->currentTalkOptions = 1;
|
||||||
data->currentTalkOption0 = "...";
|
data->currentTalkOption0 = "...";
|
||||||
|
|
||||||
data->currentTalk0 = "Hello?";
|
data->currentTalk0 = "Hello?";
|
||||||
data->currentTalk1 = "I have a feeling of having";
|
data->currentTalk1 = "I have a feeling of having";
|
||||||
data->currentTalk2 = "forgotten something very";
|
data->currentTalk2 = "forgotten something very";
|
||||||
data->currentTalk3 = "important.";
|
data->currentTalk3 = "important.";
|
||||||
data->currentTalk4 = "Hopefully I will remember";
|
data->currentTalk4 = "Hopefully I will remember";
|
||||||
data->currentTalk5 = "it soon...";
|
data->currentTalk5 = "it soon...";
|
||||||
break;
|
break;
|
||||||
case NPC_PRIEST:
|
case NPC_PRIEST:
|
||||||
data->currentTalkOptions = 3;
|
data->currentTalkOptions = 3;
|
||||||
data->currentTalkOption1 = "Trade";
|
data->currentTalkOption1 = "Trade";
|
||||||
data->currentTalkOption2 = "Why are you so few?";
|
data->currentTalkOption2 = "Why are you so few?";
|
||||||
|
|
||||||
data->currentTalk0 = "Welcome to our small village";
|
data->currentTalk0 = "Welcome to our small village";
|
||||||
data->currentTalk1 = "I am the leader of our group.";
|
data->currentTalk1 = "I am the leader of our group.";
|
||||||
data->currentTalk2 = "If you have anything usefull";
|
data->currentTalk2 = "If you have anything usefull";
|
||||||
data->currentTalk3 = "for us I might be able to";
|
data->currentTalk3 = "for us I might be able to";
|
||||||
data->currentTalk4 = "provide something nice in";
|
data->currentTalk4 = "provide something nice in";
|
||||||
data->currentTalk5 = "exchange.";
|
data->currentTalk5 = "exchange.";
|
||||||
break;
|
break;
|
||||||
case NPC_FARMER:
|
case NPC_FARMER:
|
||||||
data->currentTalkOptions = 2;
|
data->currentTalkOptions = 2;
|
||||||
data->currentTalkOption0 = "Maybe some other time";
|
data->currentTalkOption0 = "Maybe some other time";
|
||||||
data->currentTalkOption1 = "Trade";
|
data->currentTalkOption1 = "Trade";
|
||||||
|
|
||||||
data->currentTalk0 = "Hello friend!";
|
data->currentTalk0 = "Hello friend!";
|
||||||
data->currentTalk1 = "Nice seeing somebody else";
|
data->currentTalk1 = "Nice seeing somebody else";
|
||||||
data->currentTalk2 = "visit my little farm.";
|
data->currentTalk2 = "visit my little farm.";
|
||||||
data->currentTalk3 = "Interested in buying some";
|
data->currentTalk3 = "Interested in buying some";
|
||||||
data->currentTalk4 = "fresh farm goods?";
|
data->currentTalk4 = "fresh farm goods?";
|
||||||
data->currentTalk5 = "";
|
data->currentTalk5 = "";
|
||||||
break;
|
break;
|
||||||
case NPC_LIBRARIAN:
|
case NPC_LIBRARIAN:
|
||||||
data->currentTalkOptions = 2;
|
data->currentTalkOptions = 2;
|
||||||
data->currentTalkOption0 = "Nothing";
|
data->currentTalkOption0 = "Nothing";
|
||||||
data->currentTalkOption1 = "What are you doing here?";
|
data->currentTalkOption1 = "What are you doing here?";
|
||||||
if(questManager->questlines[1].currentQuest==1) {
|
if(questManager->questlines[1].currentQuest==1) {
|
||||||
data->currentTalkOptions = 3;
|
data->currentTalkOptions = 3;
|
||||||
data->currentTalkOption2 = "Dwarvish language";
|
data->currentTalkOption2 = "Dwarvish language";
|
||||||
}
|
}
|
||||||
|
|
||||||
data->currentTalk0 = "Oh hello?";
|
data->currentTalk0 = "Oh hello?";
|
||||||
data->currentTalk1 = "You must be quite brave";
|
data->currentTalk1 = "You must be quite brave";
|
||||||
data->currentTalk2 = "or stupid to be walking";
|
data->currentTalk2 = "or stupid to be walking";
|
||||||
data->currentTalk3 = "around in this dungeon.";
|
data->currentTalk3 = "around in this dungeon.";
|
||||||
data->currentTalk4 = "";
|
data->currentTalk4 = "";
|
||||||
data->currentTalk5 = "How can I help you?";
|
data->currentTalk5 = "How can I help you?";
|
||||||
break;
|
break;
|
||||||
case NPC_DWARF:
|
case NPC_DWARF:
|
||||||
if(questManager->questlines[1].currentQuest<=1) {
|
if(questManager->questlines[1].currentQuest<=1) {
|
||||||
questManager->questlines[1].currentQuest = 1;
|
questManager->questlines[1].currentQuest = 1;
|
||||||
|
|
||||||
data->currentTalkOptions = 1;
|
data->currentTalkOptions = 1;
|
||||||
data->currentTalkOption0 = "?";
|
data->currentTalkOption0 = "?";
|
||||||
|
|
||||||
data->currentTalk0 = "Dwo neal bet reck da lo";
|
data->currentTalk0 = "Dwo neal bet reck da lo";
|
||||||
data->currentTalk1 = "dhum don lir lugn at el";
|
data->currentTalk1 = "dhum don lir lugn at el";
|
||||||
data->currentTalk2 = "nur tor erno ur yo trad";
|
data->currentTalk2 = "nur tor erno ur yo trad";
|
||||||
data->currentTalk3 = "thra so tir kho ukk tin";
|
data->currentTalk3 = "thra so tir kho ukk tin";
|
||||||
data->currentTalk4 = "hel dro ic";
|
data->currentTalk4 = "hel dro ic";
|
||||||
data->currentTalk5 = "";
|
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)
|
//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) {
|
} else if(questManager->questlines[1].currentQuest==2) {
|
||||||
data->currentTalkOptions = 2;
|
data->currentTalkOptions = 2;
|
||||||
data->currentTalkOption0 = "Not really";
|
data->currentTalkOption0 = "Not really";
|
||||||
data->currentTalkOption1 = "Trade";
|
data->currentTalkOption1 = "Trade";
|
||||||
|
|
||||||
data->currentTalk0 = "How are ya?";
|
data->currentTalk0 = "How are ya?";
|
||||||
data->currentTalk1 = "Pretty unusal meeting a";
|
data->currentTalk1 = "Pretty unusal meeting a";
|
||||||
data->currentTalk2 = "human down here.";
|
data->currentTalk2 = "human down here.";
|
||||||
data->currentTalk3 = "";
|
data->currentTalk3 = "";
|
||||||
data->currentTalk4 = "have something valuable";
|
data->currentTalk4 = "have something valuable";
|
||||||
data->currentTalk5 = "to trade?";
|
data->currentTalk5 = "to trade?";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tickTalkMenu(PlayerData *pd, NPC_MenuData *data) {
|
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_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_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_down.clicked){ --data->currentTalkSel; if(data->currentTalkSel < 0) data->currentTalkSel=data->currentTalkOptions-1;}
|
||||||
|
|
||||||
if(pd->inputs.k_accept.clicked){
|
if(pd->inputs.k_accept.clicked){
|
||||||
data->currentTalkDone = true;
|
data->currentTalkDone = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tickNPCMenu(PlayerData *pd) {
|
void tickNPCMenu(PlayerData *pd) {
|
||||||
NPC_MenuData *data = &(pd->npcMenuData);
|
NPC_MenuData *data = &(pd->npcMenuData);
|
||||||
QuestlineManager *questManager = &(pd->questManager);
|
QuestlineManager *questManager = &(pd->questManager);
|
||||||
|
|
||||||
//TODO: Handle upon currentNPC as well as the fitting quest progress
|
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK) tickTalkMenu(pd, data);
|
|
||||||
|
|
||||||
|
//TODO: Handle upon currentNPC as well as the fitting quest progress
|
||||||
switch(data->currentNPC) {
|
if(data->currentNPCMenu==NPC_MENU_TALK) tickTalkMenu(pd, data);
|
||||||
case NPC_GIRL:
|
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
|
||||||
if(data->currentNPCVal==0) pd->ingameMenu = MENU_NONE;
|
switch(data->currentNPC) {
|
||||||
}
|
case NPC_GIRL:
|
||||||
break;
|
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
||||||
case NPC_PRIEST:
|
if(data->currentNPCVal==0) pd->ingameMenu = MENU_NONE;
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
}
|
||||||
if(data->currentNPCVal==0) {
|
break;
|
||||||
if(data->currentTalkSel==0) {
|
case NPC_PRIEST:
|
||||||
pd->ingameMenu = MENU_NONE;
|
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
||||||
} else if(data->currentTalkSel==1) {
|
if(data->currentNPCVal==0) {
|
||||||
openCraftingMenu(pd, &priestTrades, "Trading");
|
if(data->currentTalkSel==0) {
|
||||||
} else if(data->currentTalkSel==2) {
|
pd->ingameMenu = MENU_NONE;
|
||||||
data->currentNPCVal = 1;
|
} else if(data->currentTalkSel==1) {
|
||||||
|
openCraftingMenu(pd, &priestTrades, "Trading");
|
||||||
data->currentTalkSel = 0;
|
} else if(data->currentTalkSel==2) {
|
||||||
data->currentTalkDone = false;
|
data->currentNPCVal = 1;
|
||||||
data->currentTalkOptions = 1;
|
|
||||||
data->currentTalkOption0 = "...";
|
data->currentTalkSel = 0;
|
||||||
|
data->currentTalkDone = false;
|
||||||
data->currentTalk0 = "For quite some time now this";
|
data->currentTalkOptions = 1;
|
||||||
data->currentTalk1 = "village has been tyrannized";
|
data->currentTalkOption0 = "...";
|
||||||
data->currentTalk2 = "by a powerfull Air Wizard.";
|
|
||||||
data->currentTalk3 = "We are the only ones who";
|
data->currentTalk0 = "For quite some time now this";
|
||||||
data->currentTalk4 = "still have not given up";
|
data->currentTalk1 = "village has been tyrannized";
|
||||||
data->currentTalk5 = "our old homes.";
|
data->currentTalk2 = "by a powerfull Air Wizard.";
|
||||||
}
|
data->currentTalk3 = "We are the only ones who";
|
||||||
} else if(data->currentNPCVal==1) {
|
data->currentTalk4 = "still have not given up";
|
||||||
if(data->currentTalkSel==0) {
|
data->currentTalk5 = "our old homes.";
|
||||||
data->currentNPCVal = 2;
|
}
|
||||||
|
} else if(data->currentNPCVal==1) {
|
||||||
data->currentTalkSel = 0;
|
if(data->currentTalkSel==0) {
|
||||||
data->currentTalkDone = false;
|
data->currentNPCVal = 2;
|
||||||
data->currentTalkOptions = 1;
|
|
||||||
data->currentTalkOption0 = "...";
|
data->currentTalkSel = 0;
|
||||||
|
data->currentTalkDone = false;
|
||||||
data->currentTalk0 = "Most of the time the wizard";
|
data->currentTalkOptions = 1;
|
||||||
data->currentTalk1 = "hides somewhere in the";
|
data->currentTalkOption0 = "...";
|
||||||
data->currentTalk2 = "cloudes. They can only be";
|
|
||||||
data->currentTalk3 = "reached by a stairwell";
|
data->currentTalk0 = "Most of the time the wizard";
|
||||||
data->currentTalk4 = "protected by an almost";
|
data->currentTalk1 = "hides somewhere in the";
|
||||||
data->currentTalk5 = "undestroyable stone barrier.";
|
data->currentTalk2 = "cloudes. They can only be";
|
||||||
}
|
data->currentTalk3 = "reached by a stairwell";
|
||||||
} else if(data->currentNPCVal==2) {
|
data->currentTalk4 = "protected by an almost";
|
||||||
if(data->currentTalkSel==0) {
|
data->currentTalk5 = "undestroyable stone barrier.";
|
||||||
data->currentNPCVal = 3;
|
}
|
||||||
|
} else if(data->currentNPCVal==2) {
|
||||||
data->currentTalkSel = 0;
|
if(data->currentTalkSel==0) {
|
||||||
data->currentTalkDone = false;
|
data->currentNPCVal = 3;
|
||||||
data->currentTalkOptions = 1;
|
|
||||||
data->currentTalkOption0 = "...";
|
data->currentTalkSel = 0;
|
||||||
|
data->currentTalkDone = false;
|
||||||
data->currentTalk0 = "I am guessing you would ";
|
data->currentTalkOptions = 1;
|
||||||
data->currentTalk1 = "need tools atleast as";
|
data->currentTalkOption0 = "...";
|
||||||
data->currentTalk2 = "strong as diamonds to be";
|
|
||||||
data->currentTalk3 = "able to destroy it.";
|
data->currentTalk0 = "I am guessing you would ";
|
||||||
data->currentTalk4 = "";
|
data->currentTalk1 = "need tools atleast as";
|
||||||
data->currentTalk5 = "";
|
data->currentTalk2 = "strong as diamonds to be";
|
||||||
}
|
data->currentTalk3 = "able to destroy it.";
|
||||||
} else if(data->currentNPCVal==3) {
|
data->currentTalk4 = "";
|
||||||
if(data->currentTalkSel==0) {
|
data->currentTalk5 = "";
|
||||||
data->currentNPCVal = 4;
|
}
|
||||||
|
} else if(data->currentNPCVal==3) {
|
||||||
data->currentTalkSel = 0;
|
if(data->currentTalkSel==0) {
|
||||||
data->currentTalkDone = false;
|
data->currentNPCVal = 4;
|
||||||
data->currentTalkOptions = 2;
|
|
||||||
data->currentTalkOption0 = "Let me do it!";
|
data->currentTalkSel = 0;
|
||||||
data->currentTalkOption1 = "I am not sure";
|
data->currentTalkDone = false;
|
||||||
|
data->currentTalkOptions = 2;
|
||||||
data->currentTalk0 = "I am willing to give an";
|
data->currentTalkOption0 = "Let me do it!";
|
||||||
data->currentTalk1 = "ancient artifact passed";
|
data->currentTalkOption1 = "I am not sure";
|
||||||
data->currentTalk2 = "down over generations to";
|
|
||||||
data->currentTalk3 = "anybody who manages to";
|
data->currentTalk0 = "I am willing to give an";
|
||||||
data->currentTalk4 = "chase the wizard away and";
|
data->currentTalk1 = "ancient artifact passed";
|
||||||
data->currentTalk5 = "come back with proof.";
|
data->currentTalk2 = "down over generations to";
|
||||||
}
|
data->currentTalk3 = "anybody who manages to";
|
||||||
} else if(data->currentNPCVal==4) {
|
data->currentTalk4 = "chase the wizard away and";
|
||||||
pd->ingameMenu = MENU_NONE;
|
data->currentTalk5 = "come back with proof.";
|
||||||
}
|
}
|
||||||
}
|
} else if(data->currentNPCVal==4) {
|
||||||
break;
|
pd->ingameMenu = MENU_NONE;
|
||||||
case NPC_FARMER:
|
}
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
}
|
||||||
if(data->currentNPCVal==0) {
|
break;
|
||||||
if(data->currentTalkSel==0) {
|
case NPC_FARMER:
|
||||||
pd->ingameMenu = MENU_NONE;
|
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
||||||
} else if(data->currentTalkSel==1) {
|
if(data->currentNPCVal==0) {
|
||||||
openCraftingMenu(pd, &farmerTrades, "Trading");
|
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) {
|
break;
|
||||||
if(data->currentTalkSel==0) {
|
case NPC_LIBRARIAN:
|
||||||
pd->ingameMenu = MENU_NONE;
|
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
||||||
} else if(data->currentTalkSel==1) {
|
if(data->currentNPCVal==0) {
|
||||||
data->currentNPCVal = 2;
|
if(data->currentTalkSel==0) {
|
||||||
|
pd->ingameMenu = MENU_NONE;
|
||||||
data->currentTalkSel = 0;
|
} else if(data->currentTalkSel==1) {
|
||||||
data->currentTalkDone = false;
|
data->currentNPCVal = 2;
|
||||||
data->currentTalkOptions = 1;
|
|
||||||
data->currentTalkOption0 = "Ok";
|
data->currentTalkSel = 0;
|
||||||
|
data->currentTalkDone = false;
|
||||||
data->currentTalk0 = "The books in this dungeon";
|
data->currentTalkOptions = 1;
|
||||||
data->currentTalk1 = "house secrets that cannot be";
|
data->currentTalkOption0 = "Ok";
|
||||||
data->currentTalk2 = "found anywhere else in the";
|
|
||||||
data->currentTalk3 = "world. So I came to study";
|
data->currentTalk0 = "The books in this dungeon";
|
||||||
data->currentTalk4 = "them. Most are written in";
|
data->currentTalk1 = "house secrets that cannot be";
|
||||||
data->currentTalk5 = "an ancient language.";
|
data->currentTalk2 = "found anywhere else in the";
|
||||||
} else if(data->currentTalkSel==2) {
|
data->currentTalk3 = "world. So I came to study";
|
||||||
data->currentNPCVal = 1;
|
data->currentTalk4 = "them. Most are written in";
|
||||||
|
data->currentTalk5 = "an ancient language.";
|
||||||
data->currentTalkSel = 0;
|
} else if(data->currentTalkSel==2) {
|
||||||
data->currentTalkDone = false;
|
data->currentNPCVal = 1;
|
||||||
data->currentTalkOptions = 2;
|
|
||||||
data->currentTalkOption0 = "I need to think about it";
|
data->currentTalkSel = 0;
|
||||||
data->currentTalkOption1 = "Here they are";
|
data->currentTalkDone = false;
|
||||||
|
data->currentTalkOptions = 2;
|
||||||
data->currentTalk0 = "So you have met a dwarf but";
|
data->currentTalkOption0 = "I need to think about it";
|
||||||
data->currentTalk1 = "had a little communication";
|
data->currentTalkOption1 = "Here they are";
|
||||||
data->currentTalk2 = "problem? I do have a dwarvish";
|
|
||||||
data->currentTalk3 = "translation book but I havent";
|
data->currentTalk0 = "So you have met a dwarf but";
|
||||||
data->currentTalk4 = "read it yet. For 10 Gold bars";
|
data->currentTalk1 = "had a little communication";
|
||||||
data->currentTalk5 = "I will give it to you anyway.";
|
data->currentTalk2 = "problem? I do have a dwarvish";
|
||||||
}
|
data->currentTalk3 = "translation book but I havent";
|
||||||
} else if(data->currentNPCVal==1) {
|
data->currentTalk4 = "read it yet. For 10 Gold bars";
|
||||||
if(data->currentTalkSel==0) {
|
data->currentTalk5 = "I will give it to you anyway.";
|
||||||
pd->ingameMenu = MENU_NONE;
|
}
|
||||||
} else if(data->currentTalkSel==1) {
|
} else if(data->currentNPCVal==1) {
|
||||||
data->currentNPCVal = 2;
|
if(data->currentTalkSel==0) {
|
||||||
|
pd->ingameMenu = MENU_NONE;
|
||||||
data->currentTalkSel = 0;
|
} else if(data->currentTalkSel==1) {
|
||||||
data->currentTalkDone = false;
|
data->currentNPCVal = 2;
|
||||||
data->currentTalkOptions = 1;
|
|
||||||
data->currentTalkOption0 = "";
|
data->currentTalkSel = 0;
|
||||||
|
data->currentTalkDone = false;
|
||||||
if(countItemInv(ITEM_GOLDINGOT, 0, &(pd->inventory))>=10) {
|
data->currentTalkOptions = 1;
|
||||||
//remove gold from player inventory
|
data->currentTalkOption0 = "";
|
||||||
//TODO: Maybe I should make a generic substract items method sometime
|
|
||||||
Item* item = getItemFromInventory(ITEM_GOLDINGOT, &(pd->inventory));
|
if(countItemInv(ITEM_GOLDINGOT, 0, &(pd->inventory))>=10) {
|
||||||
item->countLevel -= 10;
|
//remove gold from player inventory
|
||||||
if(item->countLevel < 1) removeItemFromInventory(item->slotNum, &(pd->inventory));
|
//TODO: Maybe I should make a generic substract items method sometime
|
||||||
|
Item* item = getItemFromInventory(ITEM_GOLDINGOT, &(pd->inventory));
|
||||||
questManager->questlines[1].currentQuest = 2;
|
item->countLevel -= 10;
|
||||||
|
if(item->countLevel < 1) removeItemFromInventory(item->slotNum, &(pd->inventory));
|
||||||
data->currentTalk0 = "Thank you these will be";
|
|
||||||
data->currentTalk1 = "really helpfull.";
|
questManager->questlines[1].currentQuest = 2;
|
||||||
data->currentTalk2 = "Here take this book with";
|
|
||||||
data->currentTalk3 = "it you should be able to";
|
data->currentTalk0 = "Thank you these will be";
|
||||||
data->currentTalk4 = "easily understand anything";
|
data->currentTalk1 = "really helpfull.";
|
||||||
data->currentTalk5 = "a dwarf can say.";
|
data->currentTalk2 = "Here take this book with";
|
||||||
|
data->currentTalk3 = "it you should be able to";
|
||||||
data->currentTalkOption0 = "Thanks";
|
data->currentTalk4 = "easily understand anything";
|
||||||
} else {
|
data->currentTalk5 = "a dwarf can say.";
|
||||||
data->currentTalk0 = "You do not seem to have";
|
|
||||||
data->currentTalk1 = "enough Gold Bars with you.";
|
data->currentTalkOption0 = "Thanks";
|
||||||
data->currentTalk2 = "";
|
} else {
|
||||||
data->currentTalk3 = "Ask again when you have";
|
data->currentTalk0 = "You do not seem to have";
|
||||||
data->currentTalk4 = "collected the 10 Bars.";
|
data->currentTalk1 = "enough Gold Bars with you.";
|
||||||
data->currentTalk5 = "";
|
data->currentTalk2 = "";
|
||||||
|
data->currentTalk3 = "Ask again when you have";
|
||||||
data->currentTalkOption0 = "Ok";
|
data->currentTalk4 = "collected the 10 Bars.";
|
||||||
}
|
data->currentTalk5 = "";
|
||||||
}
|
|
||||||
} else if(data->currentNPCVal==2) {
|
data->currentTalkOption0 = "Ok";
|
||||||
if(data->currentTalkSel==0) {
|
}
|
||||||
pd->ingameMenu = MENU_NONE;
|
}
|
||||||
}
|
} 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) {
|
break;
|
||||||
if(data->currentNPCVal==0) pd->ingameMenu = MENU_NONE;
|
case NPC_DWARF:
|
||||||
}
|
if(questManager->questlines[1].currentQuest<=1) {
|
||||||
} else if(questManager->questlines[1].currentQuest==2) {
|
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
if(data->currentNPCVal==0) pd->ingameMenu = MENU_NONE;
|
||||||
if(data->currentTalkSel==0) {
|
}
|
||||||
pd->ingameMenu = MENU_NONE;
|
} else if(questManager->questlines[1].currentQuest==2) {
|
||||||
} else if(data->currentTalkSel==1) {
|
if(data->currentNPCMenu==NPC_MENU_TALK && data->currentTalkDone) {
|
||||||
openCraftingMenu(pd, &dwarfTrades, "Trading");
|
if(data->currentTalkSel==0) {
|
||||||
}
|
pd->ingameMenu = MENU_NONE;
|
||||||
}
|
} else if(data->currentTalkSel==1) {
|
||||||
}
|
openCraftingMenu(pd, &dwarfTrades, "Trading");
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderTalkMenu(NPC_MenuData *data, char * name) {
|
void renderTalkMenu(NPC_MenuData *data, char * name) {
|
||||||
renderFrame(1,1,24,14,0xFFFF1010);
|
renderFrame(1,1,24,14,0xFFFF1010);
|
||||||
drawTextColor(name,24+1,14+1,0xFF000000);
|
drawTextColor(name,24+1,14+1,0xFF000000);
|
||||||
drawTextColor(name,24,14,0xFF6FE2E2);
|
drawTextColor(name,24,14,0xFF6FE2E2);
|
||||||
|
|
||||||
drawText(data->currentTalk0, 32, 32);
|
drawText(data->currentTalk0, 32, 32);
|
||||||
drawText(data->currentTalk1, 32, 48);
|
drawText(data->currentTalk1, 32, 48);
|
||||||
drawText(data->currentTalk2, 32, 64);
|
drawText(data->currentTalk2, 32, 64);
|
||||||
drawText(data->currentTalk3, 32, 80);
|
drawText(data->currentTalk3, 32, 80);
|
||||||
drawText(data->currentTalk4, 32, 96);
|
drawText(data->currentTalk4, 32, 96);
|
||||||
drawText(data->currentTalk5, 32, 112);
|
drawText(data->currentTalk5, 32, 112);
|
||||||
|
|
||||||
if(data->currentTalkOptions>=3) drawText(data->currentTalkOption2, 64, 147);
|
if(data->currentTalkOptions>=3) drawText(data->currentTalkOption2, 64, 147);
|
||||||
if(data->currentTalkOptions>=2) drawText(data->currentTalkOption1, 64, 171);
|
if(data->currentTalkOptions>=2) drawText(data->currentTalkOption1, 64, 171);
|
||||||
if(data->currentTalkOptions>=1) drawText(data->currentTalkOption0, 64, 195);
|
if(data->currentTalkOptions>=1) drawText(data->currentTalkOption0, 64, 195);
|
||||||
|
|
||||||
if(data->currentTalkOptions>=3 && data->currentTalkSel==2) drawText(">", 48, 147);
|
if(data->currentTalkOptions>=3 && data->currentTalkSel==2) drawText(">", 48, 147);
|
||||||
if(data->currentTalkOptions>=2 && data->currentTalkSel==1) drawText(">", 48, 171);
|
if(data->currentTalkOptions>=2 && data->currentTalkSel==1) drawText(">", 48, 171);
|
||||||
if(data->currentTalkOptions>=1 && data->currentTalkSel==0) drawText(">", 48, 195);
|
if(data->currentTalkOptions>=1 && data->currentTalkSel==0) drawText(">", 48, 195);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderNPCMenu(NPC_MenuData *data) {
|
void renderNPCMenu(NPC_MenuData *data) {
|
||||||
//TODO: Handle upon currentNPC as well as the fitting quest progress
|
//TODO: Handle upon currentNPC as well as the fitting quest progress
|
||||||
switch(data->currentNPC) {
|
switch(data->currentNPC) {
|
||||||
case NPC_GIRL:
|
case NPC_GIRL:
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Maria");
|
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Maria");
|
||||||
break;
|
break;
|
||||||
case NPC_PRIEST:
|
case NPC_PRIEST:
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Priest Brom");
|
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Priest Brom");
|
||||||
break;
|
break;
|
||||||
case NPC_FARMER:
|
case NPC_FARMER:
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Farmer Garrow");
|
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Farmer Garrow");
|
||||||
break;
|
break;
|
||||||
case NPC_LIBRARIAN:
|
case NPC_LIBRARIAN:
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Librarian Ajihad");
|
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Librarian Ajihad");
|
||||||
break;
|
break;
|
||||||
case NPC_DWARF:
|
case NPC_DWARF:
|
||||||
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Dwarf Orik");
|
if(data->currentNPCMenu==NPC_MENU_TALK) renderTalkMenu(data, "Dwarf Orik");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,33 +3,33 @@
|
||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
|
|
||||||
typedef struct _questline {
|
typedef struct _questline {
|
||||||
int currentQuest;
|
int currentQuest;
|
||||||
bool currentQuestDone;
|
bool currentQuestDone;
|
||||||
} Questline;
|
} Questline;
|
||||||
|
|
||||||
typedef struct _questlineManager {
|
typedef struct _questlineManager {
|
||||||
int size;
|
int size;
|
||||||
Questline * questlines;
|
Questline * questlines;
|
||||||
} QuestlineManager;
|
} QuestlineManager;
|
||||||
|
|
||||||
typedef struct _npcMenuData {
|
typedef struct _npcMenuData {
|
||||||
u8 currentNPC;
|
u8 currentNPC;
|
||||||
|
|
||||||
int currentNPCMenu;
|
int currentNPCMenu;
|
||||||
int currentNPCVal;
|
int currentNPCVal;
|
||||||
|
|
||||||
int currentTalkSel;
|
int currentTalkSel;
|
||||||
bool currentTalkDone;
|
bool currentTalkDone;
|
||||||
int currentTalkOptions;
|
int currentTalkOptions;
|
||||||
char * currentTalkOption0;
|
char * currentTalkOption0;
|
||||||
char * currentTalkOption1;
|
char * currentTalkOption1;
|
||||||
char * currentTalkOption2;
|
char * currentTalkOption2;
|
||||||
char * currentTalk0;
|
char * currentTalk0;
|
||||||
char * currentTalk1;
|
char * currentTalk1;
|
||||||
char * currentTalk2;
|
char * currentTalk2;
|
||||||
char * currentTalk3;
|
char * currentTalk3;
|
||||||
char * currentTalk4;
|
char * currentTalk4;
|
||||||
char * currentTalk5;
|
char * currentTalk5;
|
||||||
} NPC_MenuData;
|
} NPC_MenuData;
|
||||||
|
|
||||||
//TODO: Actually move the data here
|
//TODO: Actually move the data here
|
||||||
|
|
514
source/Render.c
514
source/Render.c
|
@ -165,8 +165,8 @@ void renderp(s32 xp, s32 yp, u32 xTile, u32 yTile) {
|
||||||
xp -= offsetX;
|
xp -= offsetX;
|
||||||
yp -= offsetY;
|
yp -= offsetY;
|
||||||
int scaleX = playerScale, scaleY = playerScale;
|
int scaleX = playerScale, scaleY = playerScale;
|
||||||
sf2d_draw_texture_part_scale(playerSprites, xp << 1, yp << 1, xTile, yTile, 16, 16,
|
sf2d_draw_texture_part_scale(playerSprites, xp << 1, yp << 1, xTile, yTile, 16, 16,
|
||||||
scaleX, scaleY);
|
scaleX, scaleY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderTitle(int x, int y) {
|
void renderTitle(int x, int y) {
|
||||||
|
@ -285,13 +285,13 @@ void renderFrame(int x1, int y1, int x2, int y2, u32 bgColor) {
|
||||||
void bakeLights() {
|
void bakeLights() {
|
||||||
playerLightBake = sf2d_create_texture(64, 64, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
playerLightBake = sf2d_create_texture(64, 64, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
||||||
lanternLightBake = sf2d_create_texture(128, 128, TEXFMT_RGBA8, 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);
|
glowwormLightBake = sf2d_create_texture(32, 32, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
||||||
glowwormBigLightBake = sf2d_create_texture(64, 64, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
glowwormBigLightBake = sf2d_create_texture(64, 64, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
||||||
|
|
||||||
bakeLight(playerLightBake, 32, 32, 32);
|
bakeLight(playerLightBake, 32, 32, 32);
|
||||||
bakeLight(lanternLightBake, 64, 64, 64);
|
bakeLight(lanternLightBake, 64, 64, 64);
|
||||||
|
|
||||||
bakeLight(glowwormLightBake, 8, 8, 8);
|
bakeLight(glowwormLightBake, 8, 8, 8);
|
||||||
bakeLight(glowwormBigLightBake, 12, 12, 12);
|
bakeLight(glowwormBigLightBake, 12, 12, 12);
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,7 @@ void bakeLights() {
|
||||||
void freeLightBakes() {
|
void freeLightBakes() {
|
||||||
sf2d_free_texture(playerLightBake);
|
sf2d_free_texture(playerLightBake);
|
||||||
sf2d_free_texture(lanternLightBake);
|
sf2d_free_texture(lanternLightBake);
|
||||||
|
|
||||||
sf2d_free_texture(glowwormLightBake);
|
sf2d_free_texture(glowwormLightBake);
|
||||||
sf2d_free_texture(glowwormBigLightBake);
|
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_StencilOp(GPU_STENCIL_REPLACE, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP);
|
||||||
C3D_AlphaTest(true, GPU_GREATER, 0);
|
C3D_AlphaTest(true, GPU_GREATER, 0);
|
||||||
|
|
||||||
if(pd->activeItem->id == ITEM_LANTERN) renderLight(pd->entity.x, pd->entity.y, lanternLightBake);
|
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);
|
else if(rplayer) renderLight(pd->entity.x, pd->entity.y, playerLightBake);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < eManager.lastSlot[pd->entity.level]; ++i) {
|
for (i = 0; i < eManager.lastSlot[pd->entity.level]; ++i) {
|
||||||
Entity e = eManager.entities[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);
|
else renderLight(e.x+8, e.y-8, glowwormLightBake);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int xo = offsetX >> 4;
|
int xo = offsetX >> 4;
|
||||||
int yo = offsetY >> 4;
|
int yo = offsetY >> 4;
|
||||||
int x, y;
|
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
|
//TODO: Even this is not performant enough for old 3DS, when there is a lot of lava on screen
|
||||||
for (x = xo-2; x <= 13 + xo+2; ++x) {
|
for (x = xo-2; x <= 13 + xo+2; ++x) {
|
||||||
for (y = yo-2; y <= 8 + yo+2; ++y) {
|
for (y = yo-2; y <= 8 + yo+2; ++y) {
|
||||||
if(getTile(pd->entity.level, x, y) == TILE_LAVA) {
|
if(getTile(pd->entity.level, x, y) == TILE_LAVA) {
|
||||||
//experimental "speedhack"
|
//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(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;
|
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);
|
C3D_DepthTest(true, GPU_GEQUAL, GPU_WRITE_ALL);
|
||||||
if(invert) {
|
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);
|
render16(x, y, xTile, yTile, bits1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tu && tl) render(x, y, xTile, yTile, bits1);
|
if(tu && tl) render(x, y, xTile, yTile, bits1);
|
||||||
if(tu && tr) render(x + 8, y, xTile+8, yTile, bits2);
|
if(tu && tr) render(x + 8, y, xTile+8, yTile, bits2);
|
||||||
if(td && tl) render(x, y + 8, xTile, yTile+8, bits3);
|
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_TREE);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_FLOWER);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_FLOWER);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_SAPLING_TREE);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_SAPLING_TREE);
|
||||||
|
|
||||||
if(level==1 && worldData.season==3) renderConnectedTile4(x, y, 256, 112);
|
if(level==1 && worldData.season==3) renderConnectedTile4(x, y, 256, 112);
|
||||||
else if(level==1 && worldData.season==2) renderConnectedTile4(x, y, 256, 128);
|
else if(level==1 && worldData.season==2) renderConnectedTile4(x, y, 256, 128);
|
||||||
else renderConnectedTile4(x, y, 256, 0);
|
else renderConnectedTile4(x, y, 256, 0);
|
||||||
break;
|
break;
|
||||||
case TILE_TREE:
|
case TILE_TREE:
|
||||||
renderTile(TILE_GRASS, 0, level, x, y);
|
renderTile(TILE_GRASS, 0, level, x, y);
|
||||||
|
|
||||||
checkSurrTiles8(level, x >> 4, y >> 4, TILE_TREE);
|
checkSurrTiles8(level, x >> 4, y >> 4, TILE_TREE);
|
||||||
|
|
||||||
if(worldData.season==2) {
|
if(worldData.season==2) {
|
||||||
render(x, y, 352+((tu && tl && tul) ? 16 : 0), 96, 0);
|
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+8, y, 360+((tu && tr && tur) ? 16 : 0), 96, 0);
|
||||||
render(x, y+8, 352+((td && tl && tdl) ? 16 : 0), 104, 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);
|
render(x+8, y+8, 360+((td && tr && tdr) ? 16 : 0), 104, 0);
|
||||||
} else if(worldData.season==3) {
|
} else if(worldData.season==3) {
|
||||||
render(x, y, 352+((tu && tl && tul) ? 16 : 0), 112, 0);
|
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+8, y, 360+((tu && tr && tur) ? 16 : 0), 112, 0);
|
||||||
render(x, y+8, 352+((td && tl && tdl) ? 16 : 0), 120, 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);
|
render(x+8, y+8, 360+((td && tr && tdr) ? 16 : 0), 120, 0);
|
||||||
} else {
|
} else {
|
||||||
render(x, y, 256+((tu && tl && tul) ? 16 : 0), 48, 0);
|
render(x, y, 256+((tu && tl && tul) ? 16 : 0), 48, 0);
|
||||||
render(x+8, y, 264+((tu && tr && tur) ? 16 : 0), 48, 0);
|
render(x+8, y, 264+((tu && tr && tur) ? 16 : 0), 48, 0);
|
||||||
render(x, y+8, 256+((td && tl && tdl) ? 16 : 0), 56, 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);
|
render(x+8, y+8, 264+((td && tr && tdr) ? 16 : 0), 56, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TILE_ROCK:
|
case TILE_ROCK:
|
||||||
checkSurrTiles8(level, x >> 4, y >> 4, TILE_ROCK);
|
checkSurrTiles8(level, x >> 4, y >> 4, TILE_ROCK);
|
||||||
if(level>1)
|
if(level>1)
|
||||||
renderConnectedTile8(x, y, 256, 96);
|
renderConnectedTile8(x, y, 256, 96);
|
||||||
else
|
else
|
||||||
renderConnectedTile8(x, y, 336, 64);
|
renderConnectedTile8(x, y, 336, 64);
|
||||||
break;
|
break;
|
||||||
case TILE_HARDROCK:
|
case TILE_HARDROCK:
|
||||||
checkSurrTiles8(level, x >> 4, y >> 4, 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_SAND);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_CACTUS);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_CACTUS);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_SAPLING_CACTUS);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_SAPLING_CACTUS);
|
||||||
|
|
||||||
if(level==1 && worldData.season==3) {
|
if(level==1 && worldData.season==3) {
|
||||||
renderConnectedTile4(x, y, 256, 112);
|
renderConnectedTile4(x, y, 256, 112);
|
||||||
} else {
|
} else {
|
||||||
renderConnectedTile4(x, y, 320, 0);
|
renderConnectedTile4(x, y, 320, 0);
|
||||||
|
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
render16(x, y, 336, 48, 0);
|
render16(x, y, 336, 48, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TILE_WATER:
|
case TILE_WATER:
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, 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_HOLE);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_ICE);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_ICE);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 384, 0);
|
renderConnectedTile4(x, y, 384, 0);
|
||||||
|
|
||||||
srand((syncTickCount + (x / 2 - y) * 4311) / 10);
|
srand((syncTickCount + (x / 2 - y) * 4311) / 10);
|
||||||
renderDots(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, 288, 64);
|
renderDots(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, 288, 64);
|
||||||
break;
|
break;
|
||||||
case TILE_LAVA:
|
case TILE_LAVA:
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_LAVA);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_LAVA);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_HOLE);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_HOLE);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 448, 0);
|
renderConnectedTile4(x, y, 448, 0);
|
||||||
|
|
||||||
srand((syncTickCount + (x / 2 - y) * 4311) / 10);
|
srand((syncTickCount + (x / 2 - y) * 4311) / 10);
|
||||||
renderDots(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, 304, 64);
|
renderDots(x, y, rand() & 3, rand() & 3, rand() & 3, rand() & 3, 304, 64);
|
||||||
break;
|
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_HOLE);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_WATER);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_WATER);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_LAVA);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_LAVA);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 256, 16);
|
renderConnectedTile4(x, y, 256, 16);
|
||||||
break;
|
break;
|
||||||
case TILE_CACTUS:
|
case TILE_CACTUS:
|
||||||
|
@ -571,7 +571,7 @@ void renderTile(int i, int d, u8 level, int x, int y) {
|
||||||
case TILE_FLOWER:
|
case TILE_FLOWER:
|
||||||
renderTile(TILE_GRASS, 0, level, x, y);
|
renderTile(TILE_GRASS, 0, level, x, y);
|
||||||
if(level==1 && worldData.season==3) render16(x, y, 320, 112, d);
|
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;
|
break;
|
||||||
case TILE_STAIRS_DOWN:
|
case TILE_STAIRS_DOWN:
|
||||||
if (level == 0)
|
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_CLOUD);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_STAIRS_DOWN);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_STAIRS_DOWN);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_CLOUDCACTUS);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_CLOUDCACTUS);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 320, 16);
|
renderConnectedTile4(x, y, 320, 16);
|
||||||
break;
|
break;
|
||||||
case TILE_CLOUDCACTUS:
|
case TILE_CLOUDCACTUS:
|
||||||
|
@ -620,32 +620,32 @@ void renderTile(int i, int d, u8 level, int x, int y) {
|
||||||
break;
|
break;
|
||||||
case TILE_WOOD_WALL:
|
case TILE_WOOD_WALL:
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_WOOD_WALL);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_WOOD_WALL);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 384, 16);
|
renderConnectedTile4(x, y, 384, 16);
|
||||||
break;
|
break;
|
||||||
case TILE_STONE_WALL:
|
case TILE_STONE_WALL:
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_STONE_WALL);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_STONE_WALL);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 256, 80);
|
renderConnectedTile4(x, y, 256, 80);
|
||||||
break;
|
break;
|
||||||
case TILE_IRON_WALL:
|
case TILE_IRON_WALL:
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_IRON_WALL);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_IRON_WALL);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 448, 16);
|
renderConnectedTile4(x, y, 448, 16);
|
||||||
break;
|
break;
|
||||||
case TILE_GOLD_WALL:
|
case TILE_GOLD_WALL:
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_GOLD_WALL);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_GOLD_WALL);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 256, 32);
|
renderConnectedTile4(x, y, 256, 32);
|
||||||
break;
|
break;
|
||||||
case TILE_GEM_WALL:
|
case TILE_GEM_WALL:
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_GEM_WALL);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_GEM_WALL);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 320, 32);
|
renderConnectedTile4(x, y, 320, 32);
|
||||||
break;
|
break;
|
||||||
case TILE_DUNGEON_WALL:
|
case TILE_DUNGEON_WALL:
|
||||||
checkSurrTiles8(level, x >> 4, y >> 4, TILE_DUNGEON_WALL);
|
checkSurrTiles8(level, x >> 4, y >> 4, TILE_DUNGEON_WALL);
|
||||||
|
|
||||||
renderConnectedTile8(x, y, 384, 32);
|
renderConnectedTile8(x, y, 384, 32);
|
||||||
break;
|
break;
|
||||||
case TILE_DUNGEON_FLOOR:
|
case TILE_DUNGEON_FLOOR:
|
||||||
|
@ -657,61 +657,61 @@ void renderTile(int i, int d, u8 level, int x, int y) {
|
||||||
case TILE_MAGIC_BARRIER:
|
case TILE_MAGIC_BARRIER:
|
||||||
renderTile(TILE_DUNGEON_FLOOR, 0, level, x, y);
|
renderTile(TILE_DUNGEON_FLOOR, 0, level, x, y);
|
||||||
render16(x, y, 320, 64, d);
|
render16(x, y, 320, 64, d);
|
||||||
|
|
||||||
//draw remaining pillar count
|
//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) {
|
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;
|
x -= offsetX;
|
||||||
y -= offsetY;
|
y -= offsetY;
|
||||||
|
|
||||||
int data = 0;
|
int data = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (i = 0; i < eManager.lastSlot[level]; ++i) {
|
for (i = 0; i < eManager.lastSlot[level]; ++i) {
|
||||||
Entity * e = &eManager.entities[level][i];
|
Entity * e = &eManager.entities[level][i];
|
||||||
|
|
||||||
if(e->type == ENTITY_MAGIC_PILLAR) {
|
if(e->type == ENTITY_MAGIC_PILLAR) {
|
||||||
++data;
|
++data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char currentCount[3];
|
char currentCount[3];
|
||||||
sprintf(currentCount, "%d", data);
|
sprintf(currentCount, "%d", data);
|
||||||
|
|
||||||
drawSizedTextColor(currentCount, x+4 + 1, y+4 + 1, 2, dungeonColor[1]);
|
drawSizedTextColor(currentCount, x+4 + 1, y+4 + 1, 2, dungeonColor[1]);
|
||||||
drawSizedTextColor(currentCount, x+4, y+4, 2, dungeonColor[0]);
|
drawSizedTextColor(currentCount, x+4, y+4, 2, dungeonColor[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TILE_BOOKSHELVES:
|
case TILE_BOOKSHELVES:
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_BOOKSHELVES);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_BOOKSHELVES);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 384, 80 + d*16);
|
renderConnectedTile4(x, y, 384, 80 + d*16);
|
||||||
break;
|
break;
|
||||||
case TILE_WOOD_FLOOR:
|
case TILE_WOOD_FLOOR:
|
||||||
render16(x, y, 336, 96, 0);
|
render16(x, y, 336, 96, 0);
|
||||||
break;
|
break;
|
||||||
case TILE_MYCELIUM:
|
case TILE_MYCELIUM:
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, 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_BROWN);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_MUSHROOM_RED);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_MUSHROOM_RED);
|
||||||
|
|
||||||
if(level==1 && worldData.season==3) renderConnectedTile4(x, y, 256, 112);
|
if(level==1 && worldData.season==3) renderConnectedTile4(x, y, 256, 112);
|
||||||
else renderConnectedTile4(x, y, 448, 80);
|
else renderConnectedTile4(x, y, 448, 80);
|
||||||
break;
|
break;
|
||||||
case TILE_MUSHROOM_BROWN:
|
case TILE_MUSHROOM_BROWN:
|
||||||
renderTile(TILE_MYCELIUM, 0, level, x, y);
|
renderTile(TILE_MYCELIUM, 0, level, x, y);
|
||||||
render16(x, y, 448 + (d&0x1)*16, 96, 0);
|
render16(x, y, 448 + (d&0x1)*16, 96, 0);
|
||||||
break;
|
break;
|
||||||
case TILE_MUSHROOM_RED:
|
case TILE_MUSHROOM_RED:
|
||||||
renderTile(TILE_MYCELIUM, 0, level, x, y);
|
renderTile(TILE_MYCELIUM, 0, level, x, y);
|
||||||
render16(x, y, 480 + (d&0x1)*16, 96, 0);
|
render16(x, y, 480 + (d&0x1)*16, 96, 0);
|
||||||
break;
|
break;
|
||||||
case TILE_ICE:
|
case TILE_ICE:
|
||||||
renderTile(TILE_WATER, 0, level, x, y);
|
renderTile(TILE_WATER, 0, level, x, y);
|
||||||
//checkSurrTiles4(x >> 4, y >> 4, TILE_WATER);
|
//checkSurrTiles4(x >> 4, y >> 4, TILE_WATER);
|
||||||
//checkSurrTiles4(x >> 4, y >> 4, TILE_HOLE);
|
//checkSurrTiles4(x >> 4, y >> 4, TILE_HOLE);
|
||||||
checkSurrTiles4(level, x >> 4, y >> 4, TILE_ICE);
|
checkSurrTiles4(level, x >> 4, y >> 4, TILE_ICE);
|
||||||
|
|
||||||
renderConnectedTile4(x, y, 448, 112);
|
renderConnectedTile4(x, y, 448, 112);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -725,12 +725,12 @@ void renderConnectedTile4(int x, int y, u32 xTile, u32 yTile) {
|
||||||
render16(x, y, xTile+48, yTile, 0);
|
render16(x, y, xTile+48, yTile, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int l = (tl ? 16 : 0);
|
int l = (tl ? 16 : 0);
|
||||||
int r = (tr ? 16 : 0);
|
int r = (tr ? 16 : 0);
|
||||||
int u = (tu ? 32 : 0);
|
int u = (tu ? 32 : 0);
|
||||||
int d = (td ? 32 : 0);
|
int d = (td ? 32 : 0);
|
||||||
|
|
||||||
render(x, y, xTile +l+u, yTile, 0);
|
render(x, y, xTile +l+u, yTile, 0);
|
||||||
render(x+8, y, xTile+8+r+u, yTile, 0);
|
render(x+8, y, xTile+8+r+u, yTile, 0);
|
||||||
render(x, y+8, xTile +l+d, yTile+8, 0);
|
render(x, 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);
|
render16(x, y, xTile+64, yTile, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int l = (tl ? 16 : 0);
|
int l = (tl ? 16 : 0);
|
||||||
int r = (tr ? 16 : 0);
|
int r = (tr ? 16 : 0);
|
||||||
int u = (tu ? 32 : 0);
|
int u = (tu ? 32 : 0);
|
||||||
int d = (td ? 32 : 0);
|
int d = (td ? 32 : 0);
|
||||||
|
|
||||||
render(x, y, xTile +l+u+((tl && tu && tul) ? 16 : 0), yTile, 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+8, y, xTile+8+r+u+((tr && tu && tur) ? 16 : 0), yTile, 0);
|
||||||
render(x, y+8, xTile +l+d+((tl && td && tdl) ? 16 : 0), yTile+8, 0);
|
render(x, 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) {
|
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
|
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 mx = pd->mapScrollX;
|
||||||
int my = pd->mapScrollY;
|
int my = pd->mapScrollY;
|
||||||
if(pd->mapZoomLevel == 2) mx = 32;
|
if(pd->mapZoomLevel == 2) mx = 32;
|
||||||
sf2d_draw_texture_scale(minimap[pd->entity.level], mx, my, pd->mapZoomLevel, pd->mapZoomLevel); // zoomed map
|
sf2d_draw_texture_scale(minimap[pd->entity.level], mx, my, pd->mapZoomLevel, pd->mapZoomLevel); // zoomed map
|
||||||
|
|
||||||
// Airwizard on zoomed map
|
// Airwizard on zoomed map
|
||||||
if(pd->entity.level == 0){
|
if(pd->entity.level == 0){
|
||||||
if(awX != 0 && awY != 0){
|
if(awX != 0 && awY != 0){
|
||||||
render16c(
|
render16c(
|
||||||
(mx+((awX/16)*pd->mapZoomLevel)-16)/2,
|
(mx+((awX/16)*pd->mapZoomLevel)-16)/2,
|
||||||
(my+((awY/16)*pd->mapZoomLevel)-16)/2,
|
(my+((awY/16)*pd->mapZoomLevel)-16)/2,
|
||||||
160, 112,
|
160, 112,
|
||||||
((pd->entity.p.walkDist >> 6) & 1) == 0 ? 0 : 1,
|
((pd->entity.p.walkDist >> 6) & 1) == 0 ? 0 : 1,
|
||||||
2, 2
|
2, 2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Player on zoomed map
|
// Player on zoomed map
|
||||||
//TODO: Maybe also render other players?
|
//TODO: Maybe also render other players?
|
||||||
render16c(
|
render16c(
|
||||||
(mx+((pd->entity.x/16)*pd->mapZoomLevel)-16)/2,
|
(mx+((pd->entity.x/16)*pd->mapZoomLevel)-16)/2,
|
||||||
(my+((pd->entity.y/16)*pd->mapZoomLevel)-16)/2,
|
(my+((pd->entity.y/16)*pd->mapZoomLevel)-16)/2,
|
||||||
0, 112,
|
0, 112,
|
||||||
((pd->entity.p.walkDist >> 6) & 1) == 0 ? 0 : 1,
|
((pd->entity.p.walkDist >> 6) & 1) == 0 ? 0 : 1,
|
||||||
2, 2
|
2, 2
|
||||||
);
|
);
|
||||||
|
|
||||||
drawText(pd->mapText,224, 214); // "x2"/"x4"/"x6"
|
drawText(pd->mapText,224, 214); // "x2"/"x4"/"x6"
|
||||||
render16(142, 2, 72, 208, 0); // Exit button
|
render16(142, 2, 72, 208, 0); // Exit button
|
||||||
renderc(126, 102, 40, 208, 32, 16, 0); // Plus/Minus zoom buttons
|
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
|
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
|
else if(pd->mapZoomLevel > 5) sf2d_draw_rectangle(284, 210, 26, 20, 0x7F4F4F4F); // gray out minus button
|
||||||
}
|
}
|
||||||
|
|
||||||
char scoreT[32];
|
char scoreT[32];
|
||||||
void renderGui(PlayerData *pd) {
|
void renderGui(PlayerData *pd) {
|
||||||
int i;
|
int i;
|
||||||
//health and stamina
|
//health and stamina
|
||||||
for (i = 0; i < 10; ++i) {
|
for (i = 0; i < 10; ++i) {
|
||||||
if (i < pd->entity.p.health)
|
if (i < pd->entity.p.health)
|
||||||
render(i * 8 + 6, 5, 168, 152, 0);
|
render(i * 8 + 6, 5, 168, 152, 0);
|
||||||
|
@ -806,11 +806,11 @@ void renderGui(PlayerData *pd) {
|
||||||
else
|
else
|
||||||
render(i * 8 + 6, 14, 191, 152, 0);
|
render(i * 8 + 6, 14, 191, 152, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//minimap
|
//minimap
|
||||||
sf2d_draw_texture(minimap[pd->entity.level], 10, 102);
|
sf2d_draw_texture(minimap[pd->entity.level], 10, 102);
|
||||||
|
|
||||||
//active item
|
//active item
|
||||||
renderItemWithTextCentered(pd->activeItem, 320, 66);
|
renderItemWithTextCentered(pd->activeItem, 320, 66);
|
||||||
itoa(pd->score, scoreT, 10); // integer to base10 string
|
itoa(pd->score, scoreT, 10); // integer to base10 string
|
||||||
drawText("Score:",214,12);
|
drawText("Score:",214,12);
|
||||||
|
@ -819,10 +819,10 @@ void renderGui(PlayerData *pd) {
|
||||||
if(awX != 0 && awY != 0){
|
if(awX != 0 && awY != 0){
|
||||||
renderc(1 + (awX/32), 47 + (awY/32), 88, 216, 8, 8, 0); // Mini-AWizard head.
|
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.
|
renderc(1 + (pd->entity.x/32), 47 + (pd->entity.y/32), 88, 208, 8, 8, 0); // Mini-Player head.
|
||||||
|
|
||||||
//quick select
|
//quick select
|
||||||
drawText("Quickselect:",164,118);
|
drawText("Quickselect:",164,118);
|
||||||
|
|
||||||
|
@ -832,7 +832,7 @@ void renderGui(PlayerData *pd) {
|
||||||
if((inv->lastSlot) > i) {
|
if((inv->lastSlot) > i) {
|
||||||
int xip = i % 4;
|
int xip = i % 4;
|
||||||
int yip = i / 4;
|
int yip = i / 4;
|
||||||
|
|
||||||
item = &inv->items[i];
|
item = &inv->items[i];
|
||||||
renderItemIcon(item->id, item->countLevel, 81+xip*21, 77+yip*21);
|
renderItemIcon(item->id, item->countLevel, 81+xip*21, 77+yip*21);
|
||||||
}
|
}
|
||||||
|
@ -840,86 +840,86 @@ void renderGui(PlayerData *pd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderPlayer(PlayerData *pd) {
|
void renderPlayer(PlayerData *pd) {
|
||||||
if (pd->entity.level!=getLocalPlayer()->entity.level) {
|
if (pd->entity.level!=getLocalPlayer()->entity.level) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pd->entity.p.isDead) {
|
if (pd->entity.p.isDead) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int xo = pd->entity.x - 8;
|
int xo = pd->entity.x - 8;
|
||||||
int yo = pd->entity.y - 8;
|
int yo = pd->entity.y - 8;
|
||||||
|
|
||||||
//attack animation upwards
|
//attack animation upwards
|
||||||
if (pd->entity.p.attackTimer > 0 && pd->entity.p.dir == 1) {
|
if (pd->entity.p.attackTimer > 0 && pd->entity.p.dir == 1) {
|
||||||
renderc(xo, yo - 4, 16, 160, 16, 8, 0);
|
renderc(xo, yo - 4, 16, 160, 16, 8, 0);
|
||||||
renderItemIcon(pd->activeItem->id, pd->activeItem->countLevel, xo + 4, yo - 4);
|
renderItemIcon(pd->activeItem->id, pd->activeItem->countLevel, xo + 4, yo - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
//find basic indices
|
//find basic indices
|
||||||
int aIndexBig = 0;
|
int aIndexBig = 0;
|
||||||
int aIndexSmall = 0;
|
int aIndexSmall = 0;
|
||||||
switch(pd->entity.p.dir) {
|
switch(pd->entity.p.dir) {
|
||||||
case 0: //down
|
case 0: //down
|
||||||
aIndexBig = 0;
|
aIndexBig = 0;
|
||||||
aIndexSmall = 0;
|
aIndexSmall = 0;
|
||||||
break;
|
break;
|
||||||
case 1: //up
|
case 1: //up
|
||||||
aIndexBig = 2;
|
aIndexBig = 2;
|
||||||
aIndexSmall = 1;
|
aIndexSmall = 1;
|
||||||
break;
|
break;
|
||||||
case 2: //left
|
case 2: //left
|
||||||
aIndexBig = 7;
|
aIndexBig = 7;
|
||||||
aIndexSmall = 3;
|
aIndexSmall = 3;
|
||||||
break;
|
break;
|
||||||
case 3: //right
|
case 3: //right
|
||||||
aIndexBig = 4;
|
aIndexBig = 4;
|
||||||
aIndexSmall = 2;
|
aIndexSmall = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//find index offset based on walk state
|
//find index offset based on walk state
|
||||||
u8 walkingOffset = (pd->entity.p.walkDist >> 4) % 2;
|
u8 walkingOffset = (pd->entity.p.walkDist >> 4) % 2;
|
||||||
if(pd->entity.p.dir==2 || pd->entity.p.dir==3) {
|
if(pd->entity.p.dir==2 || pd->entity.p.dir==3) {
|
||||||
walkingOffset = (pd->entity.p.walkDist >> 4) % 4;
|
walkingOffset = (pd->entity.p.walkDist >> 4) % 4;
|
||||||
if(walkingOffset==2) walkingOffset = 0;
|
if(walkingOffset==2) walkingOffset = 0;
|
||||||
if(walkingOffset==3) walkingOffset = 2;
|
if(walkingOffset==3) walkingOffset = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool swimming = isWater(pd->entity.level, pd->entity.x>>4, pd->entity.y>>4);
|
bool swimming = isWater(pd->entity.level, pd->entity.x>>4, pd->entity.y>>4);
|
||||||
|
|
||||||
//render water anim when swimming
|
//render water anim when swimming
|
||||||
if (swimming) {
|
if (swimming) {
|
||||||
renderc(xo, yo + 5, 48, 160 + (((pd->entity.p.swimTimer >> 4) & 1) << 3), 16, 8, 0);
|
renderc(xo, yo + 5, 48, 160 + (((pd->entity.p.swimTimer >> 4) & 1) << 3), 16, 8, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//render the different parts
|
//render the different parts
|
||||||
//legs
|
//legs
|
||||||
if(!swimming) {
|
if(!swimming) {
|
||||||
renderp(xo, yo, (0+aIndexBig+walkingOffset)*16, pd->sprite.legs*16);
|
renderp(xo, yo, (0+aIndexBig+walkingOffset)*16, pd->sprite.legs*16);
|
||||||
}
|
}
|
||||||
//body
|
//body
|
||||||
renderp(xo, yo, (10+aIndexBig+walkingOffset)*16, pd->sprite.body*16);
|
renderp(xo, yo, (10+aIndexBig+walkingOffset)*16, pd->sprite.body*16);
|
||||||
//arms (normal)
|
//arms (normal)
|
||||||
if(!(pd->entity.p.isCarrying)) {
|
if(!(pd->entity.p.isCarrying)) {
|
||||||
renderp(xo, yo, (20+aIndexBig+walkingOffset)*16, pd->sprite.arms*16);
|
renderp(xo, yo, (20+aIndexBig+walkingOffset)*16, pd->sprite.arms*16);
|
||||||
}
|
}
|
||||||
//head
|
//head
|
||||||
renderp(xo, yo, (30+aIndexSmall)*16, pd->sprite.head*16);
|
renderp(xo, yo, (30+aIndexSmall)*16, pd->sprite.head*16);
|
||||||
//eyes
|
//eyes
|
||||||
renderp(xo, yo, (34+aIndexSmall)*16, pd->sprite.eyes*16);
|
renderp(xo, yo, (34+aIndexSmall)*16, pd->sprite.eyes*16);
|
||||||
//arms (carrying)
|
//arms (carrying)
|
||||||
if(pd->entity.p.isCarrying) {
|
if(pd->entity.p.isCarrying) {
|
||||||
renderp(xo, yo, (38+aIndexSmall)*16, pd->sprite.arms*16);
|
renderp(xo, yo, (38+aIndexSmall)*16, pd->sprite.arms*16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//furniture
|
//furniture
|
||||||
if (pd->entity.p.isCarrying) {
|
if (pd->entity.p.isCarrying) {
|
||||||
renderFurniture(pd->activeItem->id, xo, yo - 12);
|
renderFurniture(pd->activeItem->id, xo, yo - 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
//attack animation (other directios)
|
//attack animation (other directios)
|
||||||
if (pd->entity.p.attackTimer > 0) {
|
if (pd->entity.p.attackTimer > 0) {
|
||||||
switch (pd->entity.p.dir) {
|
switch (pd->entity.p.dir) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -939,37 +939,37 @@ void renderPlayer(PlayerData *pd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderWeather(u8 level, int xScroll, int yScroll) {
|
void renderWeather(u8 level, int xScroll, int yScroll) {
|
||||||
if(level==1) {
|
if(level==1) {
|
||||||
if(worldData.season==3) {
|
if(worldData.season==3) {
|
||||||
int xp = -128 + ((syncTickCount>>2) - xScroll*2)%128;
|
int xp = -128 + ((syncTickCount>>2) - xScroll*2)%128;
|
||||||
int yp = -128 + ((syncTickCount>>1) - yScroll*2)%128;
|
int yp = -128 + ((syncTickCount>>1) - yScroll*2)%128;
|
||||||
int xp2 = 0 - ((syncTickCount>>2) + xScroll*2)%128;
|
int xp2 = 0 - ((syncTickCount>>2) + xScroll*2)%128;
|
||||||
int yp2 = -128 + ((syncTickCount>>1)+64 - yScroll*2)%128;
|
int yp2 = -128 + ((syncTickCount>>1)+64 - yScroll*2)%128;
|
||||||
int xt;
|
int xt;
|
||||||
int yt;
|
int yt;
|
||||||
for(xt=0; xt<4; ++xt) {
|
for(xt=0; xt<4; ++xt) {
|
||||||
for(yt=0; yt<3; ++yt) {
|
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, 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);
|
sf2d_draw_texture_part_scale(icons, xp2 + xt*128, yp2 + yt*128, 192, 0, 64, 64, 2, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(worldData.rain) {
|
if(worldData.rain) {
|
||||||
int xp = -((xScroll*2)%128);
|
int xp = -((xScroll*2)%128);
|
||||||
int yp = -128 + ((syncTickCount<<2) - yScroll*2)%128;
|
int yp = -128 + ((syncTickCount<<2) - yScroll*2)%128;
|
||||||
int xp2 = -((xScroll*2+8)%128);
|
int xp2 = -((xScroll*2+8)%128);
|
||||||
int yp2 = -128 + ((syncTickCount<<1)+64 - yScroll*2)%128;
|
int yp2 = -128 + ((syncTickCount<<1)+64 - yScroll*2)%128;
|
||||||
int xt;
|
int xt;
|
||||||
int yt;
|
int yt;
|
||||||
for(xt=0; xt<4; ++xt) {
|
for(xt=0; xt<4; ++xt) {
|
||||||
for(yt=0; yt<3; ++yt) {
|
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, 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);
|
sf2d_draw_texture_part_scale(icons, xp2 + xt*128, yp2 + yt*128, 128, 0, 64, 64, 2, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderDayNight(PlayerData *pd) {
|
void renderDayNight(PlayerData *pd) {
|
||||||
|
@ -978,7 +978,7 @@ void renderDayNight(PlayerData *pd) {
|
||||||
int color2 = 0x00100C0C;
|
int color2 = 0x00100C0C;
|
||||||
int alpha1 = 0x88;
|
int alpha1 = 0x88;
|
||||||
int alpha2 = 0xDD;
|
int alpha2 = 0xDD;
|
||||||
|
|
||||||
if(worldData.daytime>5000 && worldData.daytime<6000) {
|
if(worldData.daytime>5000 && worldData.daytime<6000) {
|
||||||
alpha2 = (alpha2 * (1000-(worldData.daytime-5000)))/1000;
|
alpha2 = (alpha2 * (1000-(worldData.daytime-5000)))/1000;
|
||||||
alpha1 = (alpha1 * (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;
|
alpha1 = (alpha1 * (worldData.daytime-18000))/1000;
|
||||||
alpha2 = (alpha2 * (worldData.daytime-18000))/1000;
|
alpha2 = (alpha2 * (worldData.daytime-18000))/1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
color1 = color1 | (alpha1 << 24);
|
color1 = color1 | (alpha1 << 24);
|
||||||
color2 = color2 | (alpha2 << 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
|
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);
|
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
|
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) {
|
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_texture_part_scale(minimap[1], (-xScroll / 3) - 256, (-yScroll / 3) - 32, 0, 0, 128, 128, 12.5, 7.5);
|
||||||
sf2d_draw_rectangle(0, 0, 400, 240, 0xAFDFDFDF);
|
sf2d_draw_rectangle(0, 0, 400, 240, 0xAFDFDFDF);
|
||||||
} else if(level == 5) {
|
} else if(level == 5) {
|
||||||
|
@ -1118,7 +1118,7 @@ void renderFurniture(int itemID, int x, int y) {
|
||||||
render16(x, y, 240, 128, 0);
|
render16(x, y, 240, 128, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_POTION_MAKER:
|
case ITEM_POTION_MAKER:
|
||||||
render16(x, y, 240, 96, 0);
|
render16(x, y, 192, 168, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1265,7 +1265,7 @@ void renderEntity(Entity* e, int x, int y) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENTITY_DRAGONPROJECTILE:
|
case ENTITY_DRAGONPROJECTILE:
|
||||||
if(e->dragonFire.type==0) {
|
if(e->dragonFire.type==0) {
|
||||||
renderr(x, y, 0, 320, 0, e->dragonFire.age * 0.349);
|
renderr(x, y, 0, 320, 0, e->dragonFire.age * 0.349);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1279,7 +1279,7 @@ void renderEntity(Entity* e, int x, int y) {
|
||||||
if (e->arrow.age >= 200)
|
if (e->arrow.age >= 200)
|
||||||
if (e->arrow.age / 6 % 2 == 0)
|
if (e->arrow.age / 6 % 2 == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int abits = 0;
|
int abits = 0;
|
||||||
int ayp = 168;
|
int ayp = 168;
|
||||||
if(e->arrow.xa<0) {
|
if(e->arrow.xa<0) {
|
||||||
|
@ -1292,7 +1292,7 @@ void renderEntity(Entity* e, int x, int y) {
|
||||||
ayp += 8;
|
ayp += 8;
|
||||||
abits += 2;
|
abits += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (e->arrow.itemID) {
|
switch (e->arrow.itemID) {
|
||||||
case ITEM_ARROW_WOOD:
|
case ITEM_ARROW_WOOD:
|
||||||
render(x-2, y-2, 72, ayp, abits);
|
render(x-2, y-2, 72, ayp, abits);
|
||||||
|
@ -1314,7 +1314,7 @@ void renderEntity(Entity* e, int x, int y) {
|
||||||
case ENTITY_GLOWWORM:
|
case ENTITY_GLOWWORM:
|
||||||
render(x-4, y-4, 224, 112, 0);
|
render(x-4, y-4, 224, 112, 0);
|
||||||
break;
|
break;
|
||||||
case ENTITY_NPC:
|
case ENTITY_NPC:
|
||||||
render16(x - 8, y - 8, (e->npc.type*16) + 0, 64, 0);
|
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
|
else
|
||||||
col = 0xFF7F7F7F;
|
col = 0xFF7F7F7F;
|
||||||
if(r->recipes[i + io].itemAmountLevel==1) {
|
if(r->recipes[i + io].itemAmountLevel==1) {
|
||||||
drawTextColor(getBasicItemName(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 {
|
} else {
|
||||||
drawTextColor(getItemName(r->recipes[i + io].itemResult, r->recipes[i + io].itemAmountLevel), x + 18, y + 2, col);
|
drawTextColor(getItemName(r->recipes[i + io].itemResult, r->recipes[i + io].itemAmountLevel), x + 18, y + 2, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int yy = selected + 1 - io + yo;
|
int yy = selected + 1 - io + yo;
|
||||||
|
@ -1463,13 +1463,13 @@ void renderItemStuffWithText(int itemID, int itemCL, bool onlyOne, int x, int y)
|
||||||
y + 2, 0xFFD2D2D2, 0xFFFFFFFF);
|
y + 2, 0xFFD2D2D2, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For bottom screen */
|
/* For bottom screen */
|
||||||
void renderItemWithTextCentered(Item* item, int width, int y) {
|
void renderItemWithTextCentered(Item* item, int width, int y) {
|
||||||
char * tn = getItemName(item->id, item->countLevel);
|
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);
|
renderItemIcon(item->id, item->countLevel, x >> 1, y >> 1);
|
||||||
|
|
||||||
if (item->onlyOne)
|
if (item->onlyOne)
|
||||||
drawText(getItemName(item->id, item->countLevel), x + 18, y + 2);
|
drawText(getItemName(item->id, item->countLevel), x + 18, y + 2);
|
||||||
else
|
else
|
||||||
|
@ -1478,8 +1478,8 @@ void renderItemWithTextCentered(Item* item, int width, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderItemIcon(int itemID, int countLevel, int x, int y) {
|
void renderItemIcon(int itemID, int countLevel, int x, int y) {
|
||||||
int xd;
|
int xd;
|
||||||
int yd;
|
int yd;
|
||||||
switch (itemID) {
|
switch (itemID) {
|
||||||
case ITEM_NULL:
|
case ITEM_NULL:
|
||||||
return;
|
return;
|
||||||
|
@ -1523,7 +1523,7 @@ void renderItemIcon(int itemID, int countLevel, int x, int y) {
|
||||||
render(x, y, 0, 152, 0);
|
render(x, y, 0, 152, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_WOOD:
|
case ITEM_WOOD:
|
||||||
render(x, y, 8, 152, 0);
|
render(x, y, 160, 168, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_STONE:
|
case ITEM_STONE:
|
||||||
renderb(x, y, 16, 152, 0, rockColor[1]);
|
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);
|
render(x, y, 80, 152, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_GOLD_APPLE:
|
case ITEM_GOLD_APPLE:
|
||||||
render(x, y, 177, 160, 0);
|
render(x, y, 144, 168, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_STRENGTH_POTION:
|
case ITEM_STRENGTH_POTION:
|
||||||
render(x, y, 184, 160, 0);
|
render(x, y, 176, 160, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_SPEED_POTION:
|
case ITEM_SPEED_POTION:
|
||||||
render(x, y, 191, 160, 0);
|
render(x, y, 184, 160, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_REGEN_POTION:
|
case ITEM_REGEN_POTION:
|
||||||
render(x, y, 198, 160, 0);
|
render(x, y, 192, 160, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_SWIM_BREATH_POTION:
|
case ITEM_SWIM_BREATH_POTION:
|
||||||
render(x, y, 219, 160, 0);
|
render(x, y, 200, 160, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_SLIME:
|
case ITEM_SLIME:
|
||||||
renderb(x, y, 88, 152, 0, 0xFF4DC04D);
|
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);
|
render(x, y, 144, 160, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_POTION_MAKER:
|
case ITEM_POTION_MAKER:
|
||||||
render(x, y, 216, 152, 0);
|
render(x, y, 192, 168, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_WALL_WOOD:
|
case ITEM_WALL_WOOD:
|
||||||
renderb(x, y, 224, 144, 0, woodColor);
|
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:
|
case ITEM_DRAGON_SCALE:
|
||||||
render(x, y, 168, 160, 0);
|
render(x, y, 168, 160, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_BOOKSHELVES:
|
case ITEM_BOOKSHELVES:
|
||||||
render(x, y, 232, 144, 0);
|
render(x, y, 232, 144, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_MAGIC_DUST:
|
case ITEM_MAGIC_DUST:
|
||||||
render(x, y, 200, 152, 0);
|
render(x, y, 200, 152, 0);
|
||||||
break;
|
break;
|
||||||
case ITEM_COIN:
|
case ITEM_COIN:
|
||||||
render(x, y, 208, 152, 0);
|
render(x, y, 208, 152, 0);
|
||||||
break;
|
break;
|
||||||
case TOOL_BUCKET:
|
case TOOL_BUCKET:
|
||||||
render(x, y, 200 + countLevel * 8, 144, 0);
|
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:
|
case TOOL_BOW:
|
||||||
render(x, y, 64, 168, 0);
|
render(x, y, 64, 168, 0);
|
||||||
break;
|
break;
|
||||||
case TOOL_MAGIC_COMPASS:
|
case TOOL_MAGIC_COMPASS:
|
||||||
xd = worldData.compassData[getLocalPlayer()->entity.level][0] - (getLocalPlayer()->entity.x>>4);
|
xd = worldData.compassData[getLocalPlayer()->entity.level][0] - (getLocalPlayer()->entity.x>>4);
|
||||||
yd = worldData.compassData[getLocalPlayer()->entity.level][1] - (getLocalPlayer()->entity.y>>4);
|
yd = worldData.compassData[getLocalPlayer()->entity.level][1] - (getLocalPlayer()->entity.y>>4);
|
||||||
if(abs(yd)>abs(xd)) {
|
if(abs(yd)>abs(xd)) {
|
||||||
if(yd<0) render(x, y, 112, 168, 0);
|
if(yd<0) render(x, y, 112, 168, 0);
|
||||||
else render(x, y, 120, 168, 0);
|
else render(x, y, 120, 168, 0);
|
||||||
} else {
|
} else {
|
||||||
if(xd<0) render(x, y, 128, 168, 0);
|
if(xd<0) render(x, y, 128, 168, 0);
|
||||||
else render(x, y, 136, 168, 0);
|
else render(x, y, 136, 168, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
#include <sf2d.h>
|
#include <sf2d.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
1170
source/SaveLoad.c
1170
source/SaveLoad.c
File diff suppressed because it is too large
Load diff
|
@ -5,48 +5,48 @@ int soundListenerX;
|
||||||
int soundListenerY;
|
int soundListenerY;
|
||||||
|
|
||||||
void loadSound(Sound * snd, char * filename){
|
void loadSound(Sound * snd, char * filename){
|
||||||
FILE *file = fopen(filename, "rb");
|
FILE *file = fopen(filename, "rb");
|
||||||
if(file != NULL){
|
if(file != NULL){
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
snd->size = ftell(file)/2;
|
snd->size = ftell(file)/2;
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_SET);
|
||||||
snd->buffer = linearAlloc(snd->size*sizeof(u16));
|
snd->buffer = linearAlloc(snd->size*sizeof(u16));
|
||||||
fread(snd->buffer, 1, snd->size, file);
|
fread(snd->buffer, 1, snd->size, file);
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void playSound(Sound snd){
|
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) {
|
void playSoundPositioned(Sound snd, s8 level, int x, int y) {
|
||||||
if(level != soundListenerLevel) return;
|
if(level != soundListenerLevel) return;
|
||||||
int xd = soundListenerX - x;
|
int xd = soundListenerX - x;
|
||||||
int yd = soundListenerY - y;
|
int yd = soundListenerY - y;
|
||||||
if (xd * xd + yd * yd > 80 * 80) return;
|
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);
|
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) {
|
void setListenerPosition(s8 level, int x, int y) {
|
||||||
soundListenerLevel = level;
|
soundListenerLevel = level;
|
||||||
soundListenerX = x;
|
soundListenerX = x;
|
||||||
soundListenerY = y;
|
soundListenerY = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void playMusic(Sound *snd){
|
void playMusic(Sound *snd){
|
||||||
static Sound *lastSnd;
|
static Sound *lastSnd;
|
||||||
if(lastSnd==snd) return;
|
if(lastSnd==snd) return;
|
||||||
lastSnd = snd;
|
lastSnd = snd;
|
||||||
|
|
||||||
csndPlaySound(10, SOUND_FORMAT_16BIT | SOUND_REPEAT, 44100, 1, 0, snd->buffer, snd->buffer, snd->size);
|
csndPlaySound(10, SOUND_FORMAT_16BIT | SOUND_REPEAT, 44100, 1, 0, snd->buffer, snd->buffer, snd->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopMusic() {
|
void stopMusic() {
|
||||||
CSND_SetPlayState(8, 0);
|
CSND_SetPlayState(8, 0);
|
||||||
CSND_SetPlayState(10, 0);
|
CSND_SetPlayState(10, 0);
|
||||||
csndExecCmds(true);
|
csndExecCmds(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateMusic(int lvl, int time) {
|
void updateMusic(int lvl, int time) {
|
||||||
|
@ -77,7 +77,7 @@ void loadSounds() {
|
||||||
loadSound(&snd_pickup, "romfs:/resources/pickup.raw");
|
loadSound(&snd_pickup, "romfs:/resources/pickup.raw");
|
||||||
loadSound(&snd_bossdeath, "romfs:/resources/bossdeath.raw");
|
loadSound(&snd_bossdeath, "romfs:/resources/bossdeath.raw");
|
||||||
loadSound(&snd_craft, "romfs:/resources/craft.raw");
|
loadSound(&snd_craft, "romfs:/resources/craft.raw");
|
||||||
|
|
||||||
loadSound(&music_menu, "romfs:/resources/music/menu.raw");
|
loadSound(&music_menu, "romfs:/resources/music/menu.raw");
|
||||||
loadSound(&music_floor0, "romfs:/resources/music/floor0.raw");
|
loadSound(&music_floor0, "romfs:/resources/music/floor0.raw");
|
||||||
loadSound(&music_floor1, "romfs:/resources/music/floor1.raw");
|
loadSound(&music_floor1, "romfs:/resources/music/floor1.raw");
|
||||||
|
@ -87,18 +87,18 @@ void loadSounds() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeSounds(){
|
void freeSounds(){
|
||||||
linearFree(snd_playerHurt.buffer);
|
linearFree(snd_playerHurt.buffer);
|
||||||
linearFree(snd_playerDeath.buffer);
|
linearFree(snd_playerDeath.buffer);
|
||||||
linearFree(snd_monsterHurt.buffer);
|
linearFree(snd_monsterHurt.buffer);
|
||||||
linearFree(snd_test.buffer);
|
linearFree(snd_test.buffer);
|
||||||
linearFree(snd_pickup.buffer);
|
linearFree(snd_pickup.buffer);
|
||||||
linearFree(snd_bossdeath.buffer);
|
linearFree(snd_bossdeath.buffer);
|
||||||
linearFree(snd_craft.buffer);
|
linearFree(snd_craft.buffer);
|
||||||
|
|
||||||
linearFree(music_menu.buffer);
|
linearFree(music_menu.buffer);
|
||||||
linearFree(music_floor0.buffer);
|
linearFree(music_floor0.buffer);
|
||||||
linearFree(music_floor1.buffer);
|
linearFree(music_floor1.buffer);
|
||||||
linearFree(music_floor1_night.buffer);
|
linearFree(music_floor1_night.buffer);
|
||||||
linearFree(music_floor23.buffer);
|
linearFree(music_floor23.buffer);
|
||||||
linearFree(music_floor4.buffer);
|
linearFree(music_floor4.buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 size;
|
u32 size;
|
||||||
u8 * buffer;
|
u8 * buffer;
|
||||||
} Sound;
|
} Sound;
|
||||||
|
|
||||||
void loadSound(Sound * snd, char * filename);
|
void loadSound(Sound * snd, char * filename);
|
||||||
|
@ -36,4 +36,4 @@ Sound music_floor0;
|
||||||
Sound music_floor1;
|
Sound music_floor1;
|
||||||
Sound music_floor1_night;
|
Sound music_floor1_night;
|
||||||
Sound music_floor23;
|
Sound music_floor23;
|
||||||
Sound music_floor4;
|
Sound music_floor4;
|
||||||
|
|
|
@ -21,204 +21,204 @@ void synchronizerSendLocalInputs();
|
||||||
int synchronizerGetTurnIndex(u32 turn);
|
int synchronizerGetTurnIndex(u32 turn);
|
||||||
|
|
||||||
void synchronizerInit(int seed, int initPlayerCount, int initPlayerLocalID) {
|
void synchronizerInit(int seed, int initPlayerCount, int initPlayerLocalID) {
|
||||||
synchronizerLocalTurn = 0;
|
synchronizerLocalTurn = 0;
|
||||||
synchronizerNextSeed = seed;
|
synchronizerNextSeed = seed;
|
||||||
playerCount = initPlayerCount;
|
playerCount = initPlayerCount;
|
||||||
playerLocalID = initPlayerLocalID;
|
playerLocalID = initPlayerLocalID;
|
||||||
syncTickCount = 0;
|
syncTickCount = 0;
|
||||||
|
|
||||||
//reset player turn states (e.g. is turn data recieved), first turn needs to happen with no inputs
|
//reset player turn states (e.g. is turn data recieved), first turn needs to happen with no inputs
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
resetKeys(&(players[i].inputs));
|
resetKeys(&(players[i].inputs));
|
||||||
for(int j=0; j<MAX_INPUT_BUFFER; j++) {
|
for(int j=0; j<MAX_INPUT_BUFFER; j++) {
|
||||||
resetKeys(&(players[i].nextInputs[j]));
|
resetKeys(&(players[i].nextInputs[j]));
|
||||||
}
|
}
|
||||||
players[i].nextTurnReady[0] = true;
|
players[i].nextTurnReady[0] = true;
|
||||||
players[i].idSet = false;
|
players[i].idSet = false;
|
||||||
players[i].ready = false;
|
players[i].ready = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
players[playerLocalID].id = localUID;
|
players[playerLocalID].id = localUID;
|
||||||
players[playerLocalID].idSet = true;
|
players[playerLocalID].idSet = true;
|
||||||
players[playerLocalID].ready = true;
|
players[playerLocalID].ready = true;
|
||||||
|
|
||||||
|
|
||||||
//switch menu
|
//switch menu
|
||||||
currentMenu = MENU_LOADING;
|
currentMenu = MENU_LOADING;
|
||||||
|
|
||||||
synchronizerRunning = false;
|
synchronizerRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerSendUID() {
|
void synchronizerSendUID() {
|
||||||
sendIDPacket(playerLocalID, localUID);
|
sendIDPacket(playerLocalID, localUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerSetPlayerUID(int playerID, u32 uid) {
|
void synchronizerSetPlayerUID(int playerID, u32 uid) {
|
||||||
players[playerID].id = uid;
|
players[playerID].id = uid;
|
||||||
players[playerID].idSet = true;
|
players[playerID].idSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerSendIfReady() {
|
void synchronizerSendIfReady() {
|
||||||
//we are ready when we recieved all uids
|
//we are ready when we recieved all uids
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
if(!players[i].idSet) {
|
if(!players[i].idSet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//ready -> send to server
|
//ready -> send to server
|
||||||
sendStartReadyPacket(playerLocalID);
|
sendStartReadyPacket(playerLocalID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerSetPlayerReady(int playerID) {
|
void synchronizerSetPlayerReady(int playerID) {
|
||||||
players[playerID].ready = true;
|
players[playerID].ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool synchronizerAllReady() {
|
bool synchronizerAllReady() {
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
if(!players[i].ready) {
|
if(!players[i].ready) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerStart() {
|
void synchronizerStart() {
|
||||||
//check if save file is present
|
//check if save file is present
|
||||||
bool doLoad = false;
|
bool doLoad = false;
|
||||||
char *loadName = NULL;
|
char *loadName = NULL;
|
||||||
|
|
||||||
//host and single player need to load the actual file
|
//host and single player need to load the actual file
|
||||||
if(playerLocalID==0) {
|
if(playerLocalID==0) {
|
||||||
FILE *file = fopen(currentFileName, "rb");
|
FILE *file = fopen(currentFileName, "rb");
|
||||||
if(file!=NULL) {
|
if(file!=NULL) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
doLoad = true;
|
doLoad = true;
|
||||||
loadName = currentFileName;
|
loadName = currentFileName;
|
||||||
}
|
}
|
||||||
//all others the transfered one
|
//all others the transfered one
|
||||||
} else {
|
} else {
|
||||||
FILE *file = fopen("tmpTransfer.bin", "rb");
|
FILE *file = fopen("tmpTransfer.bin", "rb");
|
||||||
if(file!=NULL) {
|
if(file!=NULL) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
doLoad = true;
|
doLoad = true;
|
||||||
loadName = "tmpTransfer.bin";
|
loadName = "tmpTransfer.bin";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset random generators
|
// reset random generators
|
||||||
srand(synchronizerNextSeed);
|
srand(synchronizerNextSeed);
|
||||||
gaussrand(true);
|
gaussrand(true);
|
||||||
|
|
||||||
//start the game
|
//start the game
|
||||||
startGame(doLoad, loadName);
|
startGame(doLoad, loadName);
|
||||||
|
|
||||||
//remove transfered save file from clients
|
//remove transfered save file from clients
|
||||||
if(playerLocalID!=0) {
|
if(playerLocalID!=0) {
|
||||||
FILE *file = fopen("tmpTransfer.bin", "rb");
|
FILE *file = fopen("tmpTransfer.bin", "rb");
|
||||||
if(file!=NULL) {
|
if(file!=NULL) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
remove("tmpTransfer.bin");
|
remove("tmpTransfer.bin");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear menu
|
//clear menu
|
||||||
currentMenu = MENU_NONE;
|
currentMenu = MENU_NONE;
|
||||||
|
|
||||||
synchronizerRunning = true;
|
synchronizerRunning = true;
|
||||||
synchronizerCurrentTicks = SYNCHRONIZER_TICKS_PER_TURN;
|
synchronizerCurrentTicks = SYNCHRONIZER_TICKS_PER_TURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerTick(void (*gtick)(void)) {
|
void synchronizerTick(void (*gtick)(void)) {
|
||||||
if(synchronizerRunning && synchronizerTurnReady()) {
|
if(synchronizerRunning && synchronizerTurnReady()) {
|
||||||
synchronizerNextTurn();
|
synchronizerNextTurn();
|
||||||
|
|
||||||
// reset random generators
|
// reset random generators
|
||||||
srand(synchronizerNextSeed);
|
srand(synchronizerNextSeed);
|
||||||
gaussrand(true);
|
gaussrand(true);
|
||||||
|
|
||||||
|
|
||||||
syncTickCount++;
|
syncTickCount++;
|
||||||
|
|
||||||
//call game tick
|
//call game tick
|
||||||
(*gtick)();
|
(*gtick)();
|
||||||
|
|
||||||
synchronizerNextSeed = rand();
|
synchronizerNextSeed = rand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test if all players (including single player) input is recieved
|
//Test if all players (including single player) input is recieved
|
||||||
bool synchronizerTurnReady() {
|
bool synchronizerTurnReady() {
|
||||||
if(synchronizerCurrentTicks<SYNCHRONIZER_TICKS_PER_TURN) return true;
|
if(synchronizerCurrentTicks<SYNCHRONIZER_TICKS_PER_TURN) return true;
|
||||||
|
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
if(!players[i].nextTurnReady[synchronizerGetTurnIndex(synchronizerLocalTurn)]) {
|
if(!players[i].nextTurnReady[synchronizerGetTurnIndex(synchronizerLocalTurn)]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerNextTurn() {
|
void synchronizerNextTurn() {
|
||||||
if(synchronizerCurrentTicks<SYNCHRONIZER_TICKS_PER_TURN) {
|
if(synchronizerCurrentTicks<SYNCHRONIZER_TICKS_PER_TURN) {
|
||||||
synchronizerCurrentTicks++;
|
synchronizerCurrentTicks++;
|
||||||
|
|
||||||
//clicked events are only fired for the first tick per turn
|
//clicked events are only fired for the first tick per turn
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
resetClicked(&(players[i].inputs));
|
resetClicked(&(players[i].inputs));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//move nextInput of every player to currentInput
|
//move nextInput of every player to currentInput
|
||||||
for(int i=0; i<playerCount; i++) {
|
for(int i=0; i<playerCount; i++) {
|
||||||
players[i].inputs = players[i].nextInputs[synchronizerGetTurnIndex(synchronizerLocalTurn)];
|
players[i].inputs = players[i].nextInputs[synchronizerGetTurnIndex(synchronizerLocalTurn)];
|
||||||
players[i].nextTurnReady[synchronizerGetTurnIndex(synchronizerLocalTurn)] = false;
|
players[i].nextTurnReady[synchronizerGetTurnIndex(synchronizerLocalTurn)] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Increase turn number
|
//Increase turn number
|
||||||
synchronizerLocalTurn++;
|
synchronizerLocalTurn++;
|
||||||
synchronizerCurrentTicks = 1;
|
synchronizerCurrentTicks = 1;
|
||||||
|
|
||||||
//send local input
|
//send local input
|
||||||
synchronizerSendLocalInputs();
|
synchronizerSendLocalInputs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerSendLocalInputs() {
|
void synchronizerSendLocalInputs() {
|
||||||
//scan local inputs
|
//scan local inputs
|
||||||
hidScanInput();
|
hidScanInput();
|
||||||
tickKeys(&localInputs, hidKeysHeld(), hidKeysDown());
|
tickKeys(&localInputs, hidKeysHeld(), hidKeysDown());
|
||||||
|
|
||||||
//store local input in nextInput
|
//store local input in nextInput
|
||||||
players[playerLocalID].nextInputs[synchronizerGetTurnIndex(synchronizerLocalTurn)] = localInputs;
|
players[playerLocalID].nextInputs[synchronizerGetTurnIndex(synchronizerLocalTurn)] = localInputs;
|
||||||
players[playerLocalID].nextTurnReady[synchronizerGetTurnIndex(synchronizerLocalTurn)] = true;
|
players[playerLocalID].nextTurnReady[synchronizerGetTurnIndex(synchronizerLocalTurn)] = true;
|
||||||
|
|
||||||
//send local input
|
//send local input
|
||||||
if(playerCount>1) {
|
if(playerCount>1) {
|
||||||
size_t size = writeInputPacket(networkWriteBuffer, &localInputs, playerLocalID, synchronizerLocalTurn);
|
size_t size = writeInputPacket(networkWriteBuffer, &localInputs, playerLocalID, synchronizerLocalTurn);
|
||||||
networkSend(networkWriteBuffer, size);
|
networkSend(networkWriteBuffer, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerOnInputPacket(u8 playerID, u32 turnNumber, void *data, size_t dataSize) {
|
void synchronizerOnInputPacket(u8 playerID, u32 turnNumber, void *data, size_t dataSize) {
|
||||||
if(turnNumber>=synchronizerLocalTurn && turnNumber<synchronizerLocalTurn+MAX_INPUT_BUFFER && playerID<playerCount) {
|
if(turnNumber>=synchronizerLocalTurn && turnNumber<synchronizerLocalTurn+MAX_INPUT_BUFFER && playerID<playerCount) {
|
||||||
if(readInputPacketData(data, dataSize, &(players[playerID].nextInputs[synchronizerGetTurnIndex(turnNumber)]))) {
|
if(readInputPacketData(data, dataSize, &(players[playerID].nextInputs[synchronizerGetTurnIndex(turnNumber)]))) {
|
||||||
players[playerID].nextTurnReady[synchronizerGetTurnIndex(turnNumber)] = true;
|
players[playerID].nextTurnReady[synchronizerGetTurnIndex(turnNumber)] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int synchronizerGetTurnIndex(u32 turn) {
|
int synchronizerGetTurnIndex(u32 turn) {
|
||||||
return turn%MAX_INPUT_BUFFER;
|
return turn%MAX_INPUT_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizerReset() {
|
void synchronizerReset() {
|
||||||
synchronizerRunning = false;
|
synchronizerRunning = false;
|
||||||
synchronizerCurrentTicks = 0;
|
synchronizerCurrentTicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool synchronizerIsRunning() {
|
bool synchronizerIsRunning() {
|
||||||
return synchronizerRunning;
|
return synchronizerRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
// helpers for random numbers
|
// helpers for random numbers
|
||||||
|
@ -228,13 +228,13 @@ double gaussrand(bool reset)
|
||||||
static double U, V;
|
static double U, V;
|
||||||
static int phase = 0;
|
static int phase = 0;
|
||||||
double Z;
|
double Z;
|
||||||
|
|
||||||
if(reset) {
|
if(reset) {
|
||||||
U = 0;
|
U = 0;
|
||||||
V = 0;
|
V = 0;
|
||||||
phase = 0;
|
phase = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(phase == 0) {
|
if(phase == 0) {
|
||||||
U = (rand() + 1.) / (RAND_MAX + 2.);
|
U = (rand() + 1.) / (RAND_MAX + 2.);
|
||||||
|
@ -242,8 +242,8 @@ double gaussrand(bool reset)
|
||||||
Z = sqrt(-2 * log(U)) * sin(2 * PI * V);
|
Z = sqrt(-2 * log(U)) * sin(2 * PI * V);
|
||||||
} else {
|
} else {
|
||||||
Z = sqrt(-2 * log(U)) * cos(2 * PI * V);
|
Z = sqrt(-2 * log(U)) * cos(2 * PI * V);
|
||||||
}
|
}
|
||||||
|
|
||||||
phase = 1 - phase;
|
phase = 1 - phase;
|
||||||
|
|
||||||
return Z;
|
return Z;
|
||||||
|
|
|
@ -11,203 +11,203 @@
|
||||||
#define READ_SIZE 9216
|
#define READ_SIZE 9216
|
||||||
|
|
||||||
int unzipAndLoad(char *filename, int (*fileCallback)(char *filename), char *expectedComment, int keepFiles) {
|
int unzipAndLoad(char *filename, int (*fileCallback)(char *filename), char *expectedComment, int keepFiles) {
|
||||||
// Open the zip file
|
// Open the zip file
|
||||||
unzFile *zipfile = unzOpen(filename);
|
unzFile *zipfile = unzOpen(filename);
|
||||||
if (zipfile == NULL) {
|
if (zipfile == NULL) {
|
||||||
return 1; // Error: ZipFile could not be opened.
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
if(expectedComment!=NULL) {
|
|
||||||
char *buffer = malloc(global_info.size_comment+1);
|
|
||||||
if(buffer==NULL) {
|
|
||||||
unzClose(zipfile);
|
|
||||||
return 3; // Error: Could not read global comment
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unzGetGlobalComment(zipfile, buffer, global_info.size_comment+1) < 0) {
|
|
||||||
unzClose(zipfile);
|
|
||||||
return 3; // Error: Could not read global comment
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(expectedComment, buffer)!=0) {
|
|
||||||
unzClose(zipfile);
|
|
||||||
return 4; // Error: Global comment did not have expected value
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop to extract all files
|
// Get info about the zip file
|
||||||
uLong i;
|
unz_global_info global_info;
|
||||||
for (i = 0; i < global_info.number_entry; ++i) {
|
if (unzGetGlobalInfo(zipfile, &global_info ) != UNZ_OK) {
|
||||||
// Get info about current file.
|
unzClose(zipfile);
|
||||||
unz_file_info file_info;
|
return 2; // Error: Could not read global 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this entry is NOT a directory or file.
|
if(expectedComment!=NULL) {
|
||||||
const size_t filename_length = strlen(filename);
|
char *buffer = malloc(global_info.size_comment+1);
|
||||||
if (filename[ filename_length-1 ] != dir_delimter){
|
if(buffer==NULL) {
|
||||||
if (unzOpenCurrentFile( zipfile ) != UNZ_OK) {
|
unzClose(zipfile);
|
||||||
free(read_buffer);
|
return 3; // Error: Could not read global comment
|
||||||
unzClose(zipfile);
|
}
|
||||||
return 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open a file to write out the data.
|
if (unzGetGlobalComment(zipfile, buffer, global_info.size_comment+1) < 0) {
|
||||||
FILE * out = fopen(filename, "wb");
|
unzClose(zipfile);
|
||||||
if (out == NULL) {
|
return 3; // Error: Could not read global comment
|
||||||
free(read_buffer);
|
}
|
||||||
unzCloseCurrentFile(zipfile);
|
|
||||||
unzClose(zipfile);
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
int error = UNZ_OK;
|
if (strcmp(expectedComment, buffer)!=0) {
|
||||||
do {
|
unzClose(zipfile);
|
||||||
error = unzReadCurrentFile(zipfile, read_buffer, READ_SIZE);
|
return 4; // Error: Global comment did not have expected value
|
||||||
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.
|
free(buffer);
|
||||||
if (error > 0) {
|
}
|
||||||
fwrite(read_buffer, error, 1, out); // You should check return of fwrite...
|
|
||||||
}
|
|
||||||
} while (error > 0);
|
|
||||||
|
|
||||||
fclose(out);
|
// Buffer to hold data read from the zip file.
|
||||||
|
void *read_buffer = malloc(READ_SIZE);
|
||||||
//run callback
|
if(read_buffer==NULL) {
|
||||||
if((*fileCallback)(filename) != 0) {
|
// Error: Could not allocate read buffer
|
||||||
free(read_buffer);
|
return 5;
|
||||||
unzClose(zipfile);
|
}
|
||||||
remove(filename);
|
|
||||||
return 10; // Error: Callback error
|
|
||||||
}
|
|
||||||
|
|
||||||
if(keepFiles==ZIPHELPER_CLEANUP_FILES) {
|
|
||||||
remove(filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
// Check if this entry is NOT a directory or file.
|
||||||
if (( i+1 ) < global_info.number_entry) {
|
const size_t filename_length = strlen(filename);
|
||||||
if (unzGoToNextFile( zipfile ) != UNZ_OK) {
|
if (filename[ filename_length-1 ] != dir_delimter){
|
||||||
free(read_buffer);
|
if (unzOpenCurrentFile( zipfile ) != UNZ_OK) {
|
||||||
unzClose(zipfile);
|
free(read_buffer);
|
||||||
return 11;
|
unzClose(zipfile);
|
||||||
}
|
return 7;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Open a file to write out the data.
|
||||||
free(read_buffer);
|
FILE * out = fopen(filename, "wb");
|
||||||
unzClose(zipfile);
|
if (out == NULL) {
|
||||||
|
free(read_buffer);
|
||||||
return 0;
|
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) {
|
int zipFiles(char *filename, char **files, int fileCount, int mode, char *comment) {
|
||||||
// Set mode
|
// Set mode
|
||||||
int zipMode = mode==ZIPHELPER_ADD ? APPEND_STATUS_ADDINZIP : APPEND_STATUS_CREATE;
|
int zipMode = mode==ZIPHELPER_ADD ? APPEND_STATUS_ADDINZIP : APPEND_STATUS_CREATE;
|
||||||
FILE *testFile = fopen(filename, "r");
|
FILE *testFile = fopen(filename, "r");
|
||||||
if(testFile!=NULL) {
|
if(testFile!=NULL) {
|
||||||
fclose(testFile);
|
fclose(testFile);
|
||||||
} else {
|
} else {
|
||||||
zipMode = APPEND_STATUS_CREATE;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size;
|
// Open the zip file
|
||||||
do
|
zipFile *zipfile = zipOpen(filename, zipMode);
|
||||||
{
|
if (zipfile == NULL) return 1; // Error: ZipFile could not be opened.
|
||||||
size = fread(read_buffer, 1, READ_SIZE, in);
|
|
||||||
|
|
||||||
|
|
||||||
if(size<READ_SIZE) {
|
|
||||||
if(!feof(in)) {
|
|
||||||
free(read_buffer);
|
|
||||||
zipCloseFileInZip(zipfile);
|
|
||||||
zipClose(zipfile, "");
|
|
||||||
fclose(in);
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(size>0) {
|
|
||||||
//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);
|
// 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);
|
// Loop all files to add
|
||||||
}
|
for(int i = 0; i < fileCount; i++) {
|
||||||
|
// Open a zipfile to write out the data.
|
||||||
free(read_buffer);
|
if (zipOpenNewFileInZip(zipfile, files[i], NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION) != ZIP_OK) {
|
||||||
zipClose(zipfile, comment);
|
free(read_buffer);
|
||||||
|
zipClose(zipfile, "");
|
||||||
return 0;
|
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(size<READ_SIZE) {
|
||||||
|
if(!feof(in)) {
|
||||||
|
free(read_buffer);
|
||||||
|
zipCloseFileInZip(zipfile);
|
||||||
|
zipClose(zipfile, "");
|
||||||
|
fclose(in);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(size>0) {
|
||||||
|
//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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
#include <sf2d.h>
|
#include <sf2d.h>
|
||||||
#include <sfil.h>
|
#include <sfil.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -31,23 +31,23 @@ void setupGame() {
|
||||||
synchronizerInit(rand(), 1, 0);
|
synchronizerInit(rand(), 1, 0);
|
||||||
synchronizerSetPlayerUID(0, localUID);
|
synchronizerSetPlayerUID(0, localUID);
|
||||||
synchronizerStart();
|
synchronizerStart();
|
||||||
|
|
||||||
initGame = 0;
|
initGame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupGameServer() {
|
void setupGameServer() {
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
networkHostStopConnections();
|
networkHostStopConnections();
|
||||||
|
|
||||||
networkStart();
|
networkStart();
|
||||||
|
|
||||||
//send start info (seed)
|
//send start info (seed)
|
||||||
size = writeStartPacket(networkWriteBuffer, rand());
|
size = writeStartPacket(networkWriteBuffer, rand());
|
||||||
networkSend(networkWriteBuffer, size);
|
networkSend(networkWriteBuffer, size);
|
||||||
processPacket(networkWriteBuffer, size);
|
processPacket(networkWriteBuffer, size);
|
||||||
networkSendWaitFlush();
|
networkSendWaitFlush();
|
||||||
|
|
||||||
//send save file if loading
|
//send save file if loading
|
||||||
FILE *file = fopen(currentFileName, "rb");
|
FILE *file = fopen(currentFileName, "rb");
|
||||||
if(file!=NULL) {
|
if(file!=NULL) {
|
||||||
|
@ -55,12 +55,12 @@ void setupGameServer() {
|
||||||
networkSendWaitFlush();
|
networkSendWaitFlush();
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
//send start command
|
//send start command
|
||||||
size = writeStartRequestPacket(networkWriteBuffer);
|
size = writeStartRequestPacket(networkWriteBuffer);
|
||||||
networkSend(networkWriteBuffer, size);
|
networkSend(networkWriteBuffer, size);
|
||||||
processPacket(networkWriteBuffer, size);
|
processPacket(networkWriteBuffer, size);
|
||||||
|
|
||||||
initMPGame = 0;
|
initMPGame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,15 +68,15 @@ void setupBGMap() {
|
||||||
// Reset entity manager.
|
// Reset entity manager.
|
||||||
memset(&eManager, 0, sizeof(eManager));
|
memset(&eManager, 0, sizeof(eManager));
|
||||||
sf2d_set_clear_color(0xFF6C6D82);
|
sf2d_set_clear_color(0xFF6C6D82);
|
||||||
|
|
||||||
|
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
createAndValidateTopMap(128, 128, 1, worldData.map[1], worldData.data[1]);
|
createAndValidateTopMap(128, 128, 1, worldData.map[1], worldData.data[1]);
|
||||||
|
|
||||||
// Reset entity manager.
|
// Reset entity manager.
|
||||||
memset(&eManager, 0, sizeof(eManager));
|
memset(&eManager, 0, sizeof(eManager));
|
||||||
sf2d_set_clear_color(0xFF6C6D82);
|
sf2d_set_clear_color(0xFF6C6D82);
|
||||||
|
|
||||||
initBGMap = 0;
|
initBGMap = 0;
|
||||||
}
|
}
|
||||||
static void task_apt_hook(APT_HookType hook, void* param) {
|
static void task_apt_hook(APT_HookType hook, void* param) {
|
||||||
|
@ -111,49 +111,49 @@ int main() {
|
||||||
sf2d_init();
|
sf2d_init();
|
||||||
csndInit();
|
csndInit();
|
||||||
networkInit();
|
networkInit();
|
||||||
|
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
//load or create localUID
|
//load or create localUID
|
||||||
if ((file = fopen("m3ds_uid.bin", "rb"))) {
|
if ((file = fopen("m3ds_uid.bin", "rb"))) {
|
||||||
fread(&localUID, sizeof(u32), 1, file);
|
fread(&localUID, sizeof(u32), 1, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
} else {
|
} else {
|
||||||
localUID = (((u32) (rand()%256))<<24) | (((u32) (rand()%256))<<16) | (((u32) (rand()%256))<<8) | (((u32) (rand()%256)));
|
localUID = (((u32) (rand()%256))<<24) | (((u32) (rand()%256))<<16) | (((u32) (rand()%256))<<8) | (((u32) (rand()%256)));
|
||||||
|
|
||||||
if ((file = fopen("m3ds_uid.bin", "wb"))) {
|
if ((file = fopen("m3ds_uid.bin", "wb"))) {
|
||||||
fwrite(&localUID, sizeof(u32), 1, file);
|
fwrite(&localUID, sizeof(u32), 1, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
noItem = newItem(ITEM_NULL, 0);
|
noItem = newItem(ITEM_NULL, 0);
|
||||||
|
|
||||||
initMenus();
|
initMenus();
|
||||||
currentMenu = MENU_TITLE;
|
currentMenu = MENU_TITLE;
|
||||||
currentSelection = 0;
|
currentSelection = 0;
|
||||||
quitGame = false;
|
quitGame = false;
|
||||||
initBGMap = 1;
|
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);
|
playerSprites = sfil_load_PNG_buffer(player_png, SF2D_PLACE_RAM);
|
||||||
font = sfil_load_PNG_buffer(Font_png, SF2D_PLACE_RAM);
|
font = sfil_load_PNG_buffer(Font_png, SF2D_PLACE_RAM);
|
||||||
bottombg = sfil_load_PNG_buffer(bottombg_png, SF2D_PLACE_RAM);
|
bottombg = sfil_load_PNG_buffer(bottombg_png, SF2D_PLACE_RAM);
|
||||||
|
|
||||||
loadSounds();
|
loadSounds();
|
||||||
playMusic(&music_menu);
|
playMusic(&music_menu);
|
||||||
|
|
||||||
bakeLights();
|
bakeLights();
|
||||||
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 6; ++i) {
|
for (i = 0; i < 6; ++i) {
|
||||||
minimap[i] = sf2d_create_texture(128, 128, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
minimap[i] = sf2d_create_texture(128, 128, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
||||||
sf2d_texture_tile32(minimap[i]);
|
sf2d_texture_tile32(minimap[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadColors();
|
reloadColors();
|
||||||
|
|
||||||
sf2d_set_vblank_wait(true);
|
sf2d_set_vblank_wait(true);
|
||||||
|
|
||||||
sf2d_set_clear_color(0xFF);
|
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_down.input = KEY_DDOWN | KEY_CPAD_DOWN | KEY_CSTICK_DOWN;
|
||||||
localInputs.k_left.input = KEY_DLEFT | KEY_CPAD_LEFT | KEY_CSTICK_LEFT;
|
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_right.input = KEY_DRIGHT | KEY_CPAD_RIGHT | KEY_CSTICK_RIGHT;
|
||||||
localInputs.k_attack.input = KEY_A | KEY_B | KEY_L | KEY_ZR;
|
localInputs.k_attack.input = KEY_A | KEY_B;
|
||||||
localInputs.k_menu.input = KEY_X | KEY_Y | KEY_R | KEY_ZL;
|
localInputs.k_menu.input = KEY_X | KEY_Y;
|
||||||
localInputs.k_pause.input = KEY_START;
|
localInputs.k_pause.input = KEY_START;
|
||||||
localInputs.k_accept.input = KEY_A;
|
localInputs.k_accept.input = KEY_A;
|
||||||
localInputs.k_decline.input = KEY_B;
|
localInputs.k_decline.input = KEY_B;
|
||||||
localInputs.k_delete.input = KEY_X;
|
localInputs.k_delete.input = KEY_X;
|
||||||
localInputs.k_menuNext.input = KEY_R;
|
localInputs.k_menuNext.input = KEY_R | KEY_ZR;
|
||||||
localInputs.k_menuPrev.input = KEY_L;
|
localInputs.k_menuPrev.input = KEY_L | KEY_ZL;
|
||||||
|
|
||||||
/* If btnSave exists, then use that. */
|
/* If btnSave exists, then use that. */
|
||||||
if ((file = fopen("btnSave.bin", "rb"))) {
|
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_down.input), sizeof(int), 1, file);
|
||||||
fread(&(localInputs.k_left.input), sizeof(int), 1, file);
|
fread(&(localInputs.k_left.input), sizeof(int), 1, file);
|
||||||
fread(&(localInputs.k_right.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);
|
fread(&(localInputs.k_menuPrev.input), sizeof(int), 1, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If lastTP exists, then use that. */
|
/* If lastTP exists, then use that. */
|
||||||
if ((file = fopen("lastTP.bin", "r"))) {
|
if ((file = fopen("lastTP.bin", "r"))) {
|
||||||
char fnbuf[256];
|
char fnbuf[256];
|
||||||
fgets(fnbuf, 256, file); // get directory to texturepack
|
fgets(fnbuf, 256, file); // get directory to texturepack
|
||||||
loadTexturePack(fnbuf);
|
loadTexturePack(fnbuf);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
initPlayers();
|
initPlayers();
|
||||||
initRecipes();
|
initRecipes();
|
||||||
initTrades();
|
initTrades();
|
||||||
|
@ -208,7 +208,7 @@ int main() {
|
||||||
if (initGame > 0 && --initGame==0) setupGame();
|
if (initGame > 0 && --initGame==0) setupGame();
|
||||||
if (initMPGame > 0 && --initMPGame==0) setupGameServer();
|
if (initMPGame > 0 && --initMPGame==0) setupGameServer();
|
||||||
if (initBGMap > 0 && --initBGMap==0) setupBGMap();
|
if (initBGMap > 0 && --initBGMap==0) setupBGMap();
|
||||||
|
|
||||||
if (currentMenu == MENU_NONE) {
|
if (currentMenu == MENU_NONE) {
|
||||||
tickGame();
|
tickGame();
|
||||||
renderGame();
|
renderGame();
|
||||||
|
@ -216,14 +216,14 @@ int main() {
|
||||||
//input scanning ingame is handled by the synchronizer
|
//input scanning ingame is handled by the synchronizer
|
||||||
hidScanInput();
|
hidScanInput();
|
||||||
tickKeys(&localInputs, hidKeysHeld(), hidKeysDown());
|
tickKeys(&localInputs, hidKeysHeld(), hidKeysDown());
|
||||||
|
|
||||||
tickMenu(currentMenu);
|
tickMenu(currentMenu);
|
||||||
renderMenu(currentMenu, xscr, yscr);
|
renderMenu(currentMenu, xscr, yscr);
|
||||||
}
|
}
|
||||||
|
|
||||||
sf2d_swapbuffers();
|
sf2d_swapbuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
stopMusic();
|
stopMusic();
|
||||||
|
|
||||||
freeTrades();
|
freeTrades();
|
||||||
|
|
|
@ -10,91 +10,91 @@ bool texturepackUseDefaultFont = true;
|
||||||
bool texturepackUseDefaultBottom = true;
|
bool texturepackUseDefaultBottom = true;
|
||||||
|
|
||||||
void toLowerString(char * str){
|
void toLowerString(char * str){
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; str[i] != '\0'; i++)str[i] = (char)tolower((unsigned char)str[i]);
|
for (i = 0; str[i] != '\0'; i++)str[i] = (char)tolower((unsigned char)str[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getTexturePackComment(char * filename, char * cmmtBuf){
|
int getTexturePackComment(char * filename, char * cmmtBuf){
|
||||||
|
|
||||||
// Open the zip file
|
// Open the zip file
|
||||||
unzFile *zipfile = unzOpen(filename);
|
unzFile *zipfile = unzOpen(filename);
|
||||||
if ( zipfile == NULL ) return 1; // Error: ZipFile could not be opened.
|
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);
|
|
||||||
|
|
||||||
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) {
|
int loadTexture(char * filename) {
|
||||||
char lowerFilename[MAX_FILENAME];
|
char lowerFilename[MAX_FILENAME];
|
||||||
strcpy(lowerFilename,filename);
|
strcpy(lowerFilename,filename);
|
||||||
toLowerString(lowerFilename);
|
toLowerString(lowerFilename);
|
||||||
|
|
||||||
if(strcmp(lowerFilename, "icons.png") == 0){
|
if(strcmp(lowerFilename, "icons.png") == 0){
|
||||||
if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){
|
if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
icons = sfil_load_PNG_file(filename, SF2D_PLACE_RAM);
|
icons = sfil_load_PNG_file(filename, SF2D_PLACE_RAM);
|
||||||
reloadColors();
|
reloadColors();
|
||||||
|
|
||||||
texturepackUseDefaultIcons = false;
|
texturepackUseDefaultIcons = false;
|
||||||
} else if(strcmp(lowerFilename, "player.png") == 0){
|
} else if(strcmp(lowerFilename, "player.png") == 0){
|
||||||
if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){
|
if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
playerSprites = sfil_load_PNG_file(filename, SF2D_PLACE_RAM);
|
playerSprites = sfil_load_PNG_file(filename, SF2D_PLACE_RAM);
|
||||||
|
|
||||||
texturepackUseDefaultPlayer = false;
|
texturepackUseDefaultPlayer = false;
|
||||||
} else if(strcmp(lowerFilename, "font.png") == 0){
|
} else if(strcmp(lowerFilename, "font.png") == 0){
|
||||||
if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){
|
if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
font = sfil_load_PNG_file(filename, SF2D_PLACE_RAM);
|
font = sfil_load_PNG_file(filename, SF2D_PLACE_RAM);
|
||||||
|
|
||||||
texturepackUseDefaultFont = false;
|
texturepackUseDefaultFont = false;
|
||||||
} else if(strcmp(lowerFilename, "bottombg.png") == 0){
|
} else if(strcmp(lowerFilename, "bottombg.png") == 0){
|
||||||
if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){
|
if(sfil_load_PNG_file(filename, SF2D_PLACE_RAM) == NULL){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bottombg = sfil_load_PNG_file(filename, SF2D_PLACE_RAM);
|
bottombg = sfil_load_PNG_file(filename, SF2D_PLACE_RAM);
|
||||||
|
|
||||||
texturepackUseDefaultBottom = false;
|
texturepackUseDefaultBottom = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int loadTexturePack(char * filename) {
|
int loadTexturePack(char * filename) {
|
||||||
texturepackUseDefaultIcons = true;
|
texturepackUseDefaultIcons = true;
|
||||||
texturepackUseDefaultPlayer = true;
|
texturepackUseDefaultPlayer = true;
|
||||||
texturepackUseDefaultFont = true;
|
texturepackUseDefaultFont = true;
|
||||||
texturepackUseDefaultBottom = true;
|
texturepackUseDefaultBottom = true;
|
||||||
|
|
||||||
if(unzipAndLoad(filename, &loadTexture, NULL, ZIPHELPER_CLEANUP_FILES)!=0) {
|
if(unzipAndLoad(filename, &loadTexture, NULL, ZIPHELPER_CLEANUP_FILES)!=0) {
|
||||||
return 1;
|
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);
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue