aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog38
-rw-r--r--Goals.txt4
-rw-r--r--Makefile3
-rw-r--r--assets/items/ITEM_PAGE.pngbin0 -> 349 bytes
-rw-r--r--include/common.h17
-rw-r--r--include/entities.h39
-rw-r--r--include/inventory.h17
-rw-r--r--include/ui.h2
-rw-r--r--include/world.h16
-rw-r--r--main.cpp16
-rw-r--r--src/common.cpp17
-rw-r--r--src/entities.cpp136
-rw-r--r--src/gameplay.cpp94
-rw-r--r--src/ui.cpp37
-rw-r--r--src/world.cpp86
-rw-r--r--xcf/page.xcfbin0 -> 1059 bytes
16 files changed, 435 insertions, 87 deletions
diff --git a/Changelog b/Changelog
index 6d5fa3b..68edc5e 100644
--- a/Changelog
+++ b/Changelog
@@ -444,3 +444,41 @@
- fixed NPC spawning world location stuff
- messed with threads/forks
- re-fixed/added indoor environment; fixed indoor background
+
+12/18/2015:
+===========
+
+ - upgraded development utilities
+ - began working on pages, made sprite and handler
+ - GLSL shaders are better
+ - redid theme_jazz
+
+12/21/2015:
+===========
+
+ - fixed dialog options issues, finished basic pages
+ - added World::getAvailableNPC() for easy quest assigner assigning
+ - added the Condition class, so that events and actions can be remembered by NPCs
+ - added functionality for multiple lights (GLSL)
+
+12/22/2015:
+===========
+
+ - 3 month Changelog anniversary!
+ - fixed dialog quitting bug
+ - worked on village spawning
+ - worked on wrapping text for dialog boxes
+ - did more work on GLSL shaders
+
+1/3/2015:
+=========
+
+ - finished wrapping text for dialog boxes
+ - began working on world saving/loading again
+ - got some mad GLSL shaders running
+
+1/4/2015:
+=========
+
+ - fixed basic world save/load, working on entity saving
+ - GLSL shaders worked?
diff --git a/Goals.txt b/Goals.txt
index 140cdd3..4848bac 100644
--- a/Goals.txt
+++ b/Goals.txt
@@ -35,7 +35,7 @@ End of December:
- create first 'chapters' of story
- create very first areas in the game (code it) to get an
idea of what's gonna go down
-
+
January - March:
===============
@@ -45,7 +45,7 @@ January - March:
February - End of March:
========================
- - design sound effects / background music?
+ - design or focus on sound effects / background music?
March-ish:
======
diff --git a/Makefile b/Makefile
index e48afa6..81862c0 100644
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,7 @@ WIN_LIBS = -lopengl32 -lglew32 -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_m
FLAGS = -std=c++11 -Iinclude -Iinclude/freetype2 -Wall -Wextra -Werror
MFLAGS64 = 64
+
all:
@echo "Building for 32-bit target"
@rm -f out/*.o
@@ -21,7 +22,7 @@ all:
win32:
@g++ $(FLAGS) -o main main.cpp src/*.cpp $(WIN_LIBS)
-
+
clean:
@echo " RM main"
@-rm -f main
diff --git a/assets/items/ITEM_PAGE.png b/assets/items/ITEM_PAGE.png
new file mode 100644
index 0000000..4602afe
--- /dev/null
+++ b/assets/items/ITEM_PAGE.png
Binary files differ
diff --git a/include/common.h b/include/common.h
index 207b95f..0c4d700 100644
--- a/include/common.h
+++ b/include/common.h
@@ -151,6 +151,23 @@ extern unsigned int loops;
extern GLuint shaderProgram;
/**
+ * This class contains a string for identification and a value. It can be used to
+ * save certain events for and decisions so that they can be recalled later.
+ */
+
+class Condition {
+private:
+ char *id;
+ void *value;
+public:
+ Condition(const char *_id,void *val);
+ ~Condition();
+
+ bool sameID(const char *s);
+ void *getValue(void);
+};
+
+/**
* Prints a formatted debug message to the console, along with the callee's file and line
* number.
*/
diff --git a/include/entities.h b/include/entities.h
index a4bc282..90af0f2 100644
--- a/include/entities.h
+++ b/include/entities.h
@@ -32,7 +32,8 @@ enum MOB_SUB {
MS_RABBIT = 1,
MS_BIRD,
MS_TRIGGER,
- MS_DOOR
+ MS_DOOR,
+ MS_PAGE
};
enum BUILD_SUB{
@@ -44,6 +45,31 @@ enum BUILD_SUB{
FOUNTAIN
};
+typedef struct {
+ InventorySavePacket isp;
+ vec2 loc;
+ vec2 vel;
+ float width;
+ float height;
+ float speed;
+ float health;
+ float maxHealth;
+ int subtype;
+ int ticksToUse;
+ unsigned int randDialog;
+ unsigned char ground;
+ bool near;
+ bool canMove;
+ bool right,left;
+ bool alive;
+ bool hit;
+ _TYPE type;
+ GENDER gender;
+ size_t nameSize;
+ //char *name;
+ //Texturec *tex;
+} __attribute__ ((packed)) EntitySavePacket;
+
class World;
class Particles{
@@ -139,6 +165,9 @@ public:
virtual void interact(){}
virtual ~Entity(){}
+
+ char *baseSave(void);
+ void baseLoad(char *);
};
class Player : public Entity{
@@ -150,6 +179,11 @@ public:
~Player();
void interact();
};
+
+typedef struct {
+ EntitySavePacket esp;
+} __attribute__ ((packed)) NPCSavePacket;
+
class NPC : public Entity{
public:
std::vector<int (*)(NPC *)>aiFunc;
@@ -160,6 +194,9 @@ public:
void addAIFunc(int (*func)(NPC *),bool preload);
void interact();
void wander(int);
+
+ char *save(unsigned int *size);
+ void load(char *b);
};
class Structures : public Entity{
diff --git a/include/inventory.h b/include/inventory.h
index 31b7d88..b035f91 100644
--- a/include/inventory.h
+++ b/include/inventory.h
@@ -60,6 +60,11 @@ struct item_t{
ITEM_ID id;
} __attribute__((packed));
+typedef struct {
+ unsigned int size;
+ int os;
+ unsigned int sel;
+} __attribute__ ((packed)) InventorySavePacket;
class Inventory {
private:
@@ -87,6 +92,18 @@ public:
void draw(void); // Draws a text list of items in this inventory (should only be called for the player for now)
+ char *save(void){
+ static InventorySavePacket *isp = new InventorySavePacket();
+ isp->size = size;
+ isp->os = os;
+ isp->sel = sel;
+ return (char *)isp;
+ }
+ void load(InventorySavePacket *isp){
+ size = isp->size;
+ os = isp->os;
+ sel = isp->sel;
+ }
};
void itemUse(void *p);
diff --git a/include/ui.h b/include/ui.h
index 6a81dab..b769bbf 100644
--- a/include/ui.h
+++ b/include/ui.h
@@ -33,6 +33,8 @@ namespace ui {
extern unsigned char dialogOptChosen;
extern bool dialogImportant;
+ extern unsigned int textWrapLimit;
+
/*
* Initializes the FreeType system.
*/
diff --git a/include/world.h b/include/world.h
index e10d0dc..5021fbb 100644
--- a/include/world.h
+++ b/include/world.h
@@ -8,6 +8,9 @@
#ifndef WORLD_H
#define WORLD_H
+#include <ostream>
+#include <istream>
+
#include <common.h>
#include <entities.h>
@@ -133,6 +136,7 @@ protected:
*/
Texturec *bgTex;
+ WORLD_BG_TYPE bgType;
/**
* The Mix_Music object that holds the background soundtrack for the world.
@@ -173,13 +177,19 @@ public:
std::vector<Light > light;
void addStructure(_TYPE t,BUILD_SUB sub,float x,float y,World *inside);
- void addVillage(int bCount, int npcMin, int npcMax,_TYPE t,float x,float y,World *outside);
+ void addVillage(int bCount, int npcMin, int npcMax,_TYPE t,World *inside);
void addMob(int t,float x,float y);
void addMob(int t,float x,float y,void (*hey)(Mob *));
void addNPC(float x,float y);
void addObject(ITEM_ID, bool, const char *, float, float);
void addParticle(float, float, float, float, float, float, Color color, int);
void addLight(vec2, Color);
+
+ NPC *getAvailableNPC(void);
+
+ /*
+ * Update coordinates of all entities.
+ */
void update(Player *p,unsigned int delta);
@@ -263,8 +273,8 @@ public:
int getTheWidth(void);
- void save(FILE *);
- void load(FILE *);
+ void save(std::ofstream *);
+ void load(std::ifstream *);
};
/*
diff --git a/main.cpp b/main.cpp
index c174f11..1725ccf 100644
--- a/main.cpp
+++ b/main.cpp
@@ -3,7 +3,8 @@
The main game loop contains all of the global variables the game uses, and it runs the main game loop, the render loop, and the logic loop that control all of the entities.
*/
-#include <cstdio> // fopen
+#include <fstream>
+#include <istream>
#include <thread>
#include <common.h>
@@ -123,7 +124,7 @@ Mix_Chunk *crickets;
* referenced in src/entities.cpp for getting random names.
*/
-FILE *names;
+std::istream *names;
/*
* loops is used for texture animation. It is believed to be passed to entity
@@ -201,7 +202,7 @@ extern int fadeIntensity;
int main(/*int argc, char *argv[]*/){
//*argv = (char *)argc;
gameRunning=false;
-
+
/*!
* (Attempt to) Initialize SDL libraries so that we can use SDL facilities and eventually
* make openGL calls. Exit if there was an error.
@@ -386,7 +387,10 @@ int main(/*int argc, char *argv[]*/){
*
*/
- names = fopen("assets/names_en-us", "r+");
+ static std::filebuf fb;
+ fb.open("assets/names_en-us",std::ios::in);
+ names = new std::istream(&fb);
+
crickets=Mix_LoadWAV("assets/sounds/crickets.wav");
//Mix_Volume(2,25);
@@ -426,7 +430,7 @@ int main(/*int argc, char *argv[]*/){
Mix_HaltMusic();
- fclose(names);
+ fb.close();
SDL_GL_DeleteContext(mainGLContext);
SDL_DestroyWindow(window);
@@ -475,6 +479,7 @@ void mainLoop(void){
if(prev != currentWorld){
currentWorld->bgmPlay(prev);
+ ui::dialogBoxExists = false;
}
if(prevPrevTime + MSEC_PER_TICK <= currentTime){
@@ -894,6 +899,7 @@ void logic(){
m->wander((rand()%240 + 15)); // Make the mob wander :)
break;
case MS_TRIGGER:
+ case MS_PAGE:
m->wander(0);
break;
case MS_DOOR:
diff --git a/src/common.cpp b/src/common.cpp
index 7449a35..dbcef0b 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -1,4 +1,5 @@
#include <common.h>
+#include <cstring>
#include <cstdio>
#include <chrono>
@@ -11,6 +12,22 @@ unsigned int millis(void){
#endif // __WIN32__
+Condition::Condition(const char *_id,void *val){
+ id = new char[strlen(_id)+1];
+ strcpy(id,_id);
+ value = val;
+}
+Condition::~Condition(){
+ delete[] id;
+}
+
+bool Condition::sameID(const char *s){
+ return !strcmp(id,s);
+}
+void *Condition::getValue(void){
+ return value;
+}
+
void DEBUG_prints(const char* file, int line, const char *s,...){
va_list args;
printf("%s:%d: ",file,line);
diff --git a/src/entities.cpp b/src/entities.cpp
index d12a1ca..7e8d55a 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -1,9 +1,10 @@
#include <entities.h>
#include <ui.h>
-#include <unistd.h>
+#include <istream>
+//#include <unistd.h>
-extern FILE* names;
+extern std::istream *names;
extern unsigned int loops;
extern World *currentWorld;
@@ -12,39 +13,30 @@ extern Player *player;
extern const char *itemName;
-extern
-
void getRandomName(Entity *e){
- int tempNum,max=0;
+ unsigned int tempNum,max=0;
char *bufs;
- rewind(names);
+ names->seekg(0,names->beg);
- bufs = new char[16]; //(char *)malloc(16);
+ bufs = new char[32];
- for(;!feof(names);max++){
- fgets(bufs,16,(FILE*)names);
- }
+ for(;!names->eof();max++)
+ names->getline(bufs,32);
tempNum = rand() % max;
- rewind(names);
+ names->seekg(0,names->beg);
- for(int i=0;i<tempNum;i++){
- fgets(bufs,16,(FILE*)names);
- }
+ for(unsigned int i=0;i<tempNum;i++)
+ names->getline(bufs,32);
- switch(fgetc(names)){
+ switch(bufs[0]){
+ default :
case 'm': e->gender = MALE; break;
case 'f': e->gender = FEMALE;break;
- default : break;
}
- if((fgets(bufs,16,(FILE*)names)) != NULL){
- bufs[strlen(bufs)] = '\0';
- strcpy(e->name,bufs);
- if(e->name[strlen(e->name)-1] == '\n')
- e->name[strlen(e->name)-1] = '\0';
- }
+ strcpy(e->name,bufs+1);
delete[] bufs;
}
@@ -73,7 +65,7 @@ void Entity::spawn(float x, float y){ //spawns the entity you pass to it based o
}
}
- name = new char[16];
+ name = new char[32];
getRandomName(this);
}
@@ -109,7 +101,7 @@ NPC::NPC(){ //sets all of the NPC specific traits on object creation
tex = new Texturec(1,"assets/NPC.png");
inv = new Inventory(NPC_INV_SIZE);
- randDialog = rand() % 12 - 1;
+ randDialog = 6;//rand() % 12 - 1;
}
NPC::~NPC(){
while(!aiFunc.empty()){
@@ -154,15 +146,22 @@ Mob::Mob(int sub){
width = HLINE * 8;
height = HLINE * 8;
tex = new Texturec(1, "assets/robin.png");
+ break;
case MS_TRIGGER:
width = HLINE * 20;
height = 2000;
tex = new Texturec(0);
+ break;
case MS_DOOR:
width = HLINE * 12;
height = HLINE * 20;
tex = new Texturec(1,"assets/door.png");
break;
+ case MS_PAGE:
+ width = HLINE * 6;
+ height = HLINE * 4;
+ tex = new Texturec(1,"assets/items/ITEM_PAGE.png");
+ break;
}
inv = new Inventory(NPC_INV_SIZE);
@@ -256,6 +255,7 @@ void Entity::draw(void){ //draws the entities
break;
case MS_BIRD:
case MS_DOOR:
+ case MS_PAGE:
default:
glActiveTexture(GL_TEXTURE0 + 0);
tex->bind(0);
@@ -363,7 +363,7 @@ const char *randomDialog[] = {
"How much wood could a woodchuck chuck if a woodchuck could chuck wood?",
"I don\'t think anyone has ever been able to climb up that hill.",
"If you ever see a hole in the ground, watch out; it could mean the end for you.",
- "Did you know this game has over 4000 lines of code? I didn\'t. I didn't even know I was in a game until now...",
+ "Did you know this game has over 5000 lines of code? I didn\'t. I didn't even know I was in a game until now...",
"HELP MY CAPS LOCK IS STUCK",
"You know, if anyone ever asked me who I wanted to be when I grow up, I would say Abby Ross.",
"I want to have the wallpaper in our house changed. It doesn\'t really fit the environment.",
@@ -493,8 +493,92 @@ void Mob::wander(int timeRun){
}
break;
- case MS_DOOR:
+ case MS_PAGE:
+ if(player->loc.x > loc.x - 100 &&
+ player->loc.x < loc.x + 100 &&
+ ui::mouse.x > loc.x &&
+ ui::mouse.x < loc.x + width &&
+ ui::mouse.y > loc.y - width / 2 &&
+ ui::mouse.y < loc.y + width * 1.5 &&
+ SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)){
+ if(speed != 666){
+ speed = 666;
+ hey(this);
+ speed = 0;
+ }
+ }
+ break;
default:
break;
}
}
+
+char *Entity::baseSave(void){
+ static EntitySavePacket *esp = new EntitySavePacket();
+ memcpy(&esp->isp,inv->save(),sizeof(InventorySavePacket));
+ esp->loc = loc;
+ esp->vel = vel;
+ esp->width = width;
+ esp->height = height;
+ esp->speed = speed;
+ esp->health = health;
+ esp->maxHealth = maxHealth;
+ esp->subtype = subtype;
+ esp->ticksToUse = ticksToUse;
+ esp->randDialog = randDialog;
+ esp->ground = ground;
+ esp->near = near;
+ esp->canMove = canMove;
+ esp->right = right;
+ esp->left = left;
+ esp->alive = alive;
+ esp->hit = hit;
+ esp->type = type;
+ esp->gender = gender;
+ esp->nameSize = strlen(name) + 1;
+ return (char *)esp;
+}
+
+void Entity::baseLoad(char *e){
+ const char *tmpname = "GG\0";
+ EntitySavePacket *esp = (EntitySavePacket *)e;
+ inv->load(&esp->isp);
+ loc = esp->loc;
+ vel = esp->vel;
+ width = esp->width;
+ height = esp->height;
+ speed = esp->speed;
+ health = esp->health;
+ maxHealth = esp->maxHealth;
+ subtype = esp->subtype;
+ ticksToUse = esp->ticksToUse;
+ randDialog = esp->randDialog;
+ ground = esp->ground;
+ near = esp->near;
+ canMove = esp->canMove;
+ right = esp->right;
+ left = esp->left;
+ alive = esp->alive;
+ hit = esp->hit;
+ type = esp->type;
+ gender = esp->gender;
+ name = new char[esp->nameSize+1];
+ strcpy(name,tmpname);
+}
+
+char *NPC::save(unsigned int *size){
+ static char *buf = new char[(*size = sizeof(EntitySavePacket) + aiFunc.size() * sizeof(int(*)(NPC *)))],*esp;
+ memcpy(buf,(esp = baseSave()),sizeof(EntitySavePacket));
+ delete[] esp;
+ memcpy(buf+sizeof(EntitySavePacket),aiFunc.data(),aiFunc.size() * sizeof(int(*)(NPC *)));
+ return buf;
+}
+
+void NPC::load(char *b){
+ unsigned int size = *(unsigned int *)b,size2,i;
+ baseLoad(b + sizeof(unsigned int));
+ size2 = (size - sizeof(unsigned int) - sizeof(EntitySavePacket)) / sizeof(int(*)(NPC *));
+ for(i=0;i<size2;i++){
+ //aiFunc.push_back
+ }
+}
diff --git a/src/gameplay.cpp b/src/gameplay.cpp
index 1c83bd8..431d2cf 100644
--- a/src/gameplay.cpp
+++ b/src/gameplay.cpp
@@ -28,6 +28,10 @@ void story(Mob *callee){
callee->alive = false;
}
+/*
+ * Gens
+ */
+
float gen_worldSpawnHill1(float x){
return (float)(pow(2,(-x+200)/5) + GEN_MIN);
}
@@ -42,7 +46,6 @@ float gen_worldSpawnHill3(float x){
*/
void worldSpawnHill1_hillBlock(Mob *callee){
- std::cout<<"oi";
player->vel.x = 0;
player->loc.x = callee->loc.x + callee->width;
ui::dialogBox(player->name,NULL,false,"This hill seems to steep to climb up...");
@@ -51,30 +54,46 @@ void worldSpawnHill1_hillBlock(Mob *callee){
static Arena *a;
void worldSpawnHill2_infoSprint(Mob *callee){
- callee->alive = false;
- a = new Arena(currentWorld,player);
- a->setBackground(BG_FOREST);
- a->setBGM("assets/music/embark.wav");
- ui::toggleWhiteFast();
- ui::waitForCover();
- currentWorld = a;
- ui::toggleWhiteFast();
+
+ ui::dialogBox(player->name,":Sure:Nah",false,"This page would like to take you somewhere.");
+ ui::waitForDialog();
+ switch(ui::dialogOptChosen){
+ case 1:
+ ui::dialogBox(player->name,NULL,true,"Cool.");
+ callee->alive = false;
+ a = new Arena(currentWorld,player);
+ a->setBackground(BG_FOREST);
+ a->setBGM("assets/music/embark.wav");
+ ui::toggleWhiteFast();
+ ui::waitForCover();
+ currentWorld = a;
+ ui::toggleWhiteFast();
+ break;
+ case 2:
+ default:
+ ui::dialogBox(player->name,NULL,false,"Okay then.");
+ break;
+ }
+
//ui::dialogBox("B-) ",NULL,true,"Press \'Shift\' to run!");
}
-void worldSpawnHill3_itemGet(Mob *callee){
- ui::dialogBox("B-) ",NULL,true,"Right click to pick up items!");
- callee->alive = false;
-}
-
-void worldSpawnHill3_itemSee(Mob *callee){
- ui::dialogBox("B-) ",NULL,true,"Press \'e\' to open your inventory!");
- callee->alive = false;
+int worldSpawnHill2_Quest2(NPC *callee){
+ ui::dialogBox(callee->name,NULL,false,"Yo.");
+ ui::waitForDialog();
+ return 0;
}
-void worldSpawnHill3_leave(Mob *callee){
- ui::dialogBox("B-) ",NULL,true,"Now jump in this hole, and let your journey begin :)");
- callee->alive = false;
+int worldSpawnHill2_Quest1(NPC *callee){
+ ui::dialogBox(callee->name,":Cool.",false,"Did you know that I\'m the coolest NPC in the world?");
+ ui::waitForDialog();
+ if(ui::dialogOptChosen == 1){
+ ui::dialogBox(callee->name,NULL,false,"Yeah, it is.");
+ currentWorld->getAvailableNPC()->addAIFunc(worldSpawnHill2_Quest2,true);
+ ui::waitForDialog();
+ return 0;
+ }
+ return 1;
}
/*
@@ -96,39 +115,48 @@ static World *worldSpawnHill3;
static IndoorWorld *worldSpawnHill2_Building1;
+static World *worldFirstVillage;
/*
* initEverything() start
*/
void destroyEverything(void);
void initEverything(void){
-
+ static std::ifstream i ("world.dat",std::ifstream::in | std::ifstream::binary);
+
worldSpawnHill1 = new World();
- worldSpawnHill1->generateFunc(400,gen_worldSpawnHill1);
worldSpawnHill1->setBackground(BG_FOREST);
- worldSpawnHill1->setBGM("assets/music/embark.wav");
+ // if(!i.fail()){
+ // worldSpawnHill1->load(&i);
+ // i.close();
+ // }else{
+ worldSpawnHill1->generateFunc(400,gen_worldSpawnHill1);
+ worldSpawnHill1->setBGM("assets/music/embark.wav");
+ // }
worldSpawnHill1->addMob(MS_TRIGGER,0,0,worldSpawnHill1_hillBlock);
worldSpawnHill2 = new World();
worldSpawnHill2->generate(700);
worldSpawnHill2->setBackground(BG_FOREST);
worldSpawnHill2->setBGM("assets/music/ozone.wav");
- worldSpawnHill2->addMob(MS_TRIGGER,-400,0,worldSpawnHill2_infoSprint);
+ worldSpawnHill2->addMob(MS_PAGE,-400,0,worldSpawnHill2_infoSprint);
worldSpawnHill3 = new World();
worldSpawnHill3->generateFunc(1000,gen_worldSpawnHill3);
worldSpawnHill3->setBackground(BG_FOREST);
worldSpawnHill3->setBGM("assets/music/ozone.wav");
- worldSpawnHill3->addMob(MS_TRIGGER,-500,0,worldSpawnHill3_itemGet);
- worldSpawnHill3->addMob(MS_TRIGGER,0,0,worldSpawnHill3_itemSee);
- worldSpawnHill3->addObject(FLASHLIGHT,false,"",-200,300);
- worldSpawnHill3->addMob(MS_TRIGGER,650,0,worldSpawnHill3_leave);
- worldSpawnHill3->addHole(800,1000);
+
+ worldFirstVillage = new World();
+ worldFirstVillage->generate(1000);
+ worldFirstVillage->setBackground(BG_FOREST);
+ worldFirstVillage->setBGM("assets/music/embark.wav");
worldSpawnHill1->toRight = worldSpawnHill2;
worldSpawnHill2->toLeft = worldSpawnHill1;
worldSpawnHill2->toRight = worldSpawnHill3;
worldSpawnHill3->toLeft = worldSpawnHill2;
+ worldSpawnHill3->toRight = worldFirstVillage;
+ worldFirstVillage->toLeft = worldSpawnHill3;
/*
* Spawn some entities.
@@ -150,6 +178,9 @@ void initEverything(void){
worldSpawnHill2->addStructure(STRUCTURET,HOUSE,(rand()%120*HLINE),100,worldSpawnHill2_Building1);
worldSpawnHill2->addLight({300,100},{1.0f,1.0f,1.0f});
+ worldSpawnHill2->getAvailableNPC()->addAIFunc(worldSpawnHill2_Quest1,false);
+
+ worldFirstVillage->addVillage(5,0,0,STRUCTURET,worldSpawnHill2_Building1);
//worldSpawnHill2->addStructure(STRUCTURET,HOUSE,(rand()%120*HLINE),100,worldSpawnHill1,worldSpawnHill2);
player = new Player();
@@ -164,6 +195,11 @@ extern std::vector<int (*)(NPC *)> AIpreload;
extern std::vector<NPC *> AIpreaddr;
void destroyEverything(void){
+ static std::ofstream o;
+ o.open("world.dat",std::ifstream::binary);
+ worldSpawnHill1->save(&o);
+ o.close();
+
while(!AIpreload.empty())
AIpreload.pop_back();
while(!AIpreaddr.empty())
diff --git a/src/ui.cpp b/src/ui.cpp
index b9a44aa..7979138 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -95,6 +95,8 @@ namespace ui {
bool dialogImportant = false;
unsigned char dialogOptChosen = 0;
+ unsigned int textWrapLimit = 110;
+
/*
* Current font size. Changing this WILL NOT change the font size, see setFontSize() for
* actual font size changing.
@@ -266,7 +268,13 @@ namespace ui {
*/
do{
- if(s[i]=='\n'){ // Handle newlines
+ if(i && ((i / 110.0) == (i / 110))){
+ yo-=fontSize*1.05;
+ xo=x;
+ if(s[i] == ' ')
+ i++;
+ }
+ if(s[i] == '\n'){
yo-=fontSize*1.05;
xo=x;
}else if(s[i]==' '){ // Handle spaces
@@ -300,19 +308,21 @@ namespace ui {
}
}while(s[++i]);
- return putString(x-width/2,y,s);
+ putString(x-width/2,y,s);
+ return width;
}
/*
* Draw a string in a typewriter-esque fashion. Each letter is rendered as calls are made
* to this function. Passing a different string to the function will reset the counters.
*/
-
+
+ static char *ret = NULL;
char *typeOut(char *str){
static unsigned int sinc, // Acts as a delayer for the space between each character.
linc=0, // Contains the number of letters that should be drawn.
size=0; // Contains the full size of the current string.
- static char *ret = NULL;
+ //static char *ret = NULL;
/*
* Create a well-sized buffer if we haven't yet.
@@ -452,6 +462,8 @@ namespace ui {
dialogBoxExists = true;
dialogImportant = false;
+ if(ret)
+ ret[0] = '\0';
}
void waitForDialog(void){
do{
@@ -487,7 +499,7 @@ namespace ui {
}
void draw(void){
unsigned char i;
- float x,y;
+ float x,y,tmp;
char *rtext;
if(dialogBoxExists){
@@ -524,12 +536,12 @@ namespace ui {
for(i=0;i<dialogOptCount;i++){
setFontColor(255,255,255);
- dialogOptLoc[i][1]=y-SCREEN_HEIGHT/4+(fontSize+HLINE)*(i+1);
- dialogOptLoc[i][2]=
- putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i]);
- dialogOptLoc[i][0]=offset.x-dialogOptLoc[i][2]/2;
+ tmp = putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i]);
+ dialogOptLoc[i][2] = offset.x + tmp;
+ dialogOptLoc[i][0] = offset.x - tmp;
+ dialogOptLoc[i][1] = y - SCREEN_HEIGHT / 4 + (fontSize + HLINE) * (i + 1);
if(mouse.x > dialogOptLoc[i][0] &&
- mouse.x < dialogOptLoc[i][0] + dialogOptLoc[i][2] &&
+ mouse.x < dialogOptLoc[i][2] &&
mouse.y > dialogOptLoc[i][1] &&
mouse.y < dialogOptLoc[i][1] + 16 ){ // fontSize
setFontColor(255,255,0);
@@ -666,7 +678,6 @@ DONE:
memcpy(&player->loc,&tmppos,sizeof(vec2));
currentWorld = tmp;
toggleBlackFast();
- dialogBoxExists = false;
}
}
break;
@@ -688,7 +699,6 @@ DONE:
memcpy(&player->loc,&tmppos,sizeof(vec2));
currentWorld = tmp;
toggleBlackFast();
- dialogBoxExists = false;
}
}
break;
@@ -804,6 +814,9 @@ DONE:
case SDLK_RIGHT:
player->inv->sel++;
break;
+ case SDLK_f:
+
+ break;
default:
break;
}
diff --git a/src/world.cpp b/src/world.cpp
index b539a87..c6ab6e1 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -52,6 +52,7 @@ float worldGetYBase(World *w){
}
void World::setBackground(WORLD_BG_TYPE bgt){
+ bgType = bgt;
switch(bgt){
case BG_FOREST:
bgTex = new Texturec(7,bgPaths[0]);
@@ -62,12 +63,69 @@ void World::setBackground(WORLD_BG_TYPE bgt){
}
}
-void World::save(FILE *s){
- fclose(s);
+void World::save(std::ofstream *o){
+ static unsigned int size2;
+ unsigned int size,i;
+ size_t bgms = strlen(bgm) + 1;
+ char *bufptr;
+
+ o->write((char *)&lineCount, sizeof(unsigned int));
+ o->write((char *)line ,lineCount * sizeof(struct line_t));
+ o->write("GG" ,2 * sizeof(char));
+ o->write((char *)star ,100 * sizeof(vec2));
+ o->write((char *)&bgType , sizeof(WORLD_BG_TYPE));
+ o->write((char *)&bgms , sizeof(size_t));
+ o->write(bgm ,strlen(bgm)+1);
+ o->write("NO" ,2 * sizeof(char));
+
+ /*std::vector<NPC *> npc;
+ std::vector<Structures *> build;
+ std::vector<Mob *> mob;
+ std::vector<Entity *> entity;
+ std::vector<Object *> object;*/
+
+ size = npc.size();
+ for(i=0;i<size;i++){
+ bufptr = npc[i]->save(&size2);
+ o->write((char *)&size2,sizeof(unsigned int));
+ o->write(bufptr,size2);
+ }
}
-void World::load(FILE *s){
- fclose(s);
+void World::load(std::ifstream *i){
+ //unsigned int size;
+ size_t bgms;
+ char sig[2];
+
+ i->read((char *)&lineCount,sizeof(unsigned int));
+
+ line = new struct line_t[lineCount];
+ i->read((char *)line,lineCount * sizeof(struct line_t));
+
+ i->read(sig,2 * sizeof(char));
+ if(strncmp(sig,"GG",2)){
+ std::cout<<"world.dat corrupt"<<std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ x_start = 0 - getWidth(this) / 2;
+
+ i->read((char *)star,100 * sizeof(vec2));
+ i->read((char *)&bgType,sizeof(WORLD_BG_TYPE));
+
+ i->read((char *)&bgms,sizeof(size_t));
+ bgm = new char[bgms];
+ i->read(bgm,bgms);
+ setBGM(bgm);
+
+
+ i->read(sig,2 * sizeof(char));
+ if(strncmp(sig,"NO",2)){
+ std::cout<<"world.dat corrupt"<<std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+
}
World::World(void){
@@ -942,16 +1000,20 @@ void World::addStructure(_TYPE t,BUILD_SUB sub, float x,float y,World *inside){
entity.push_back(build.back());
}
-void World::addVillage(int bCount, int npcMin, int npcMax,_TYPE t,float x,float y,World *outside){
+void World::addVillage(int bCount, int npcMin, int npcMax,_TYPE t,World *inside){
std::cout << npcMin << ", " << npcMax << std::endl;
- int xwasd;
+ //int xwasd;
for(int i = 0; i < bCount; i++){
- xwasd = (rand()%(int)x+1000*HLINE);
+ addStructure(t,HOUSE,x_start + (i * 300),100,inside);
+ /*std::cout<<"1\n";
HERE:
+ xwasd = (rand()%(int)x+1000*HLINE);
for(auto &bu : build){
if(xwasd > bu->loc.x && xwasd < bu->loc.x+bu->width)goto HERE;
}
- addStructure(t,HOUSE,xwasd,y,outside);
+ std::cout<<"2\n";
+ addStructure(t,HOUSE,xwasd,y,inside);
+ std::cout<<"3\n";*/
}
}
void World::addMob(int t,float x,float y){
@@ -1015,6 +1077,14 @@ void World::addLayer(unsigned int width){
behind->bgTex=bgTex;
}
+NPC *World::getAvailableNPC(void){
+ for(auto &n : npc){
+ if(n->aiFunc.empty())
+ return n;
+ }
+ return (NPC *)NULL;
+}
+
World *World::goWorldLeft(Player *p){
if(toLeft&&p->loc.x<x_start+HLINE*15){
p->loc.x=toLeft->x_start+getWidth(toLeft)-HLINE*10;
diff --git a/xcf/page.xcf b/xcf/page.xcf
new file mode 100644
index 0000000..72a34cf
--- /dev/null
+++ b/xcf/page.xcf
Binary files differ