aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2016-03-15 08:43:44 -0400
committerClyne Sullivan <tullivan99@gmail.com>2016-03-15 08:43:44 -0400
commit93d6035dad1eb60fb01648232809e55059dd1cfa (patch)
tree2384f3991593ce6b4a37e7e289cfdd634aeec380
parentc8c09860cb732006e161d26f25ff46e508770218 (diff)
hills
-rw-r--r--Changelog58
-rw-r--r--include/world.h11
-rw-r--r--main.cpp140
-rw-r--r--src/entities.cpp22
-rw-r--r--src/inventory.cpp10
-rw-r--r--src/ui.cpp2
-rw-r--r--src/world.cpp495
-rw-r--r--xml/playerSpawnHill1.xml29
-rw-r--r--xml/playerSpawnHill1_Building1.xml12
-rw-r--r--xml/playerSpawnHill2.xml4
10 files changed, 425 insertions, 358 deletions
diff --git a/Changelog b/Changelog
index 795aa0d..c40e851 100644
--- a/Changelog
+++ b/Changelog
@@ -44,7 +44,7 @@
- successfully ran game 200 entities
- improved debug screen
- added mouse interaction w/ NPCs
-
+
9/30/2015:
==========
@@ -54,10 +54,10 @@
- began work on giving names to NPCs
- began working on config file
- created a bug file
-
+
- added displaying of entity names on mouse hover
- found more fonts
-
+
10/1/2015:
==========
@@ -125,20 +125,20 @@
- fixed delaying quest assignments until dialog is closed
- checked and secured errors in malloc/calloc calls
-
+
10/19/2015:
===========
- fixed malloc/strlen bug that crashes the game on some linux systems
- broke andy's linux system on his laptop, allowing for test game build on Windows
- began extensive documentation in main.cpp
-
+
10/20/2015:
===========
- andy's laptop 'can' boot
- added 200+ lines of documentation to main.cpp
-
+
10/21/2015:
===========
@@ -156,14 +156,14 @@
- successfully build game on 32-bit Windows (game crashes on execution)
- removed npc array; NPCs are now created in the entity array
- created a basic texture handling library
-
+
10/23/2015:
===========
- fixed entity initialization
- added multiple mobs
- improved texture handling
-
+
10/26/2015:
===========
@@ -231,7 +231,7 @@
- added typewriter-esque text drawing
- documented ui.h
- continued work on GLSL shaders
-
+
11/4/2015:
==========
@@ -266,7 +266,7 @@
- added drawing/handling of entities on all layers at all times
- removed building entering/exiting
- andy broke SDL cuz he's bad
-
+
11/10/2015:
===========
@@ -296,7 +296,7 @@
- minor bug fixes
- began working on arenas
- began working on cutscene triggers
-
+
11/17/2015:
===========
@@ -317,7 +317,7 @@
- texture loaded tracks loaded textures to prevent re-loading (frees resources)
- continued work on things finished the following day (11/20) :)
-
+
11/20/2015:
===========
@@ -408,7 +408,7 @@
- imrpoved BGM handling
- continued work on particles, made a fountain
- added sanic
-
+
~ Broke 5000 lines of code/doc, now with some file Doxygen'd
12/14/2015:
@@ -488,21 +488,21 @@
- can save NPCs and Structures
- more shadering
-
+
1/6/2016:
=========
- flashlight!
- XML-scripted worlds!!!
- !!!!!!!!!!!!!!!!!!!!!!!!
-
+
1/7/2016:
=========
- xml'd npc and mob spawning
- xml'd npc dialogs
- drafted page xml
-
+
1/11/2016:
==========
@@ -518,7 +518,7 @@
- xml'ing indoors
- shaderssss
- more music
-
+
1/13/2016:
==========
@@ -533,7 +533,7 @@
- pondered on non-random generation
- fixed some drawing issues
- made spritesheet for easier solid-color-texture drawing
-
+
- began to incorporate XML into the world class for dynamic world loading...
1/16/2016:
@@ -587,7 +587,7 @@
- wrote paper regarding what we've learned, and where we're at
- ported game to Windows, left EXE and DLLs in repo
-
+
2/1/2016:
=========
@@ -632,7 +632,7 @@
- partially fixed text drawing
- XML'd quest checking, working on quest requirements
- worked on XML'ing villages
-
+
2/9/2016:
=========
@@ -673,7 +673,7 @@
- mob deaths are saved
- fixed building spawning
- volumes are better
-
+
~ 5 month Changelog anniversary!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2/23/2016:
@@ -741,7 +741,7 @@
- arenas work
- cleaned up world codes
- andy got here
-
+
~ Total of 7,379 lines of code!
3/8/2016:
@@ -756,3 +756,17 @@
- pages are XMLable and can be drawn
- dialogs are cool with threads
- better lighting
+
+3/14/2016:
+==========
+
+ - began implementing hills in worlds
+ - more inventory stuffs
+
+3/15/2016:
+==========
+
+ - finished hills, fixed hill collision physics
+ - fixed player repositioning when switching worlds
+ - XML'd tickCount setting
+ - even more inventory stuffs (side panes)
diff --git a/include/world.h b/include/world.h
index a60eab6..55c08f5 100644
--- a/include/world.h
+++ b/include/world.h
@@ -421,8 +421,15 @@ public:
void addHole(unsigned int start,unsigned int end);
- /*
- * Get's the world's width.
+ /**
+ * Adds a hill to the world, given the peak's coordinates and how wide the
+ * hill can be.
+ */
+
+ void addHill( ivec2 peak, unsigned int width );
+
+ /**
+ * Gets the world's width.
*/
int getTheWidth(void) const;
diff --git a/main.cpp b/main.cpp
index f9282c4..6e58e1c 100644
--- a/main.cpp
+++ b/main.cpp
@@ -104,7 +104,7 @@ GLuint fragShader;
/**
* TODO
*/
-
+
GLuint shaderProgram;
/**
@@ -202,9 +202,9 @@ void mainLoop(void);
int main(int argc, char *argv[]){
(void)argc;
(void)argv;
-
+
static SDL_GLContext mainGLContext = NULL;
-
+
gameRunning = false;
/**
@@ -307,13 +307,13 @@ int main(int argc, char *argv[]){
std::cout << "GLEW was not able to initialize! Error: " << glewGetErrorString(err) << std::endl;
return -1;
}
-
+
/*
* Initialize the random number generator. At the moment, initRand is a macro pointing to libc's
* srand, and its partner getRand points to rand. This is because having our own random number
* generator may be favorable in the future, but at the moment is not implemented.
*/
-
+
initRand(millis());
/*
@@ -321,24 +321,24 @@ int main(int argc, char *argv[]){
* setup the alpha channel for textures/transparency, and finally hide the system's mouse
* cursor so that we may draw our own.
*/
-
+
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
//SDL_GL_SetSwapInterval(0);
-
+
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-
+
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
+
SDL_ShowCursor(SDL_DISABLE);
Texture::initColorIndex();
initEntity();
-
+
/*
* Initializes our shaders so that the game has shadows.
*/
-
+
std::cout << "Initializing shaders!" << std::endl;
const GLchar *shaderSource = readFile("test.frag");
@@ -353,17 +353,17 @@ int main(int argc, char *argv[]){
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &bufferln);
glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength);
-
+
std::vector<char> fragShaderError ((logLength > 1) ? logLength : 1);
-
+
glGetShaderInfoLog(fragShader, logLength, NULL, &fragShaderError[0]);
std::cout << &fragShaderError[0] << std::endl;
-
+
if(bufferln == GL_FALSE){
std::cout << "Error compiling shader" << std::endl;
}
- shaderProgram = glCreateProgram();
+ shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, fragShader);
glLinkProgram(shaderProgram);
glValidateProgram(shaderProgram);
@@ -373,18 +373,18 @@ int main(int argc, char *argv[]){
std::vector<char> programError( (logLength > 1) ? logLength : 1 );
glGetProgramInfoLog(shaderProgram, logLength, NULL, &programError[0]);
std::cout << &programError[0] << std::endl;
-
+
delete[] shaderSource;
-
+
glEnable(GL_MULTISAMPLE);
-
+
/*
* Create all the worlds, entities, mobs, and the player. This function is defined in
* src/gameplay.cpp
*/
-
+
fadeIntensity = 250;
-
+
initEverything();
if(!currentWorld){
@@ -403,40 +403,40 @@ int main(int argc, char *argv[]){
invUI = Texture::loadTexture("assets/invUI.png" );
mouseTex = Texture::loadTexture("assets/mouse.png");
-
+
initInventorySprites();
-
+
/**************************
**** GAMELOOP ****
**************************/
-
+
std::cout << "Num threads: " << std::thread::hardware_concurrency() << std::endl;
//currentWorld->mob.back()->followee = player;
-
+
gameRunning = true;
while(gameRunning){
mainLoop();
}
-
+
/**************************
**** CLOSE PROGRAM ****
**************************/
-
+
/*
* Close the window and free resources
*/
-
+
Mix_HaltMusic();
Mix_CloseAudio();
-
+
destroyInventory();
ui::destroyFonts();
Texture::freeTextures();
-
+
SDL_GL_DeleteContext(mainGLContext);
SDL_DestroyWindow(window);
-
+
return 0; // Calls everything passed to atexit
}
@@ -451,20 +451,20 @@ static float debugY=0;
void mainLoop(void){
static unsigned int debugDiv=0; // A divisor used to update the debug menu if it's open
-
+
static unsigned int prevTime = 0, // Used for timing operations
currentTime = 0, //
prevPrevTime= 0; //
World *prev;
-
+
if(!currentTime) // Initialize currentTime if it hasn't been
currentTime=millis();
-
+
/*
* Update timing values. This is crucial to calling logic and updating the window (basically
* the entire game).
*/
-
+
prevTime = currentTime;
currentTime = millis();
deltaTime = currentTime - prevTime;
@@ -477,7 +477,7 @@ void mainLoop(void){
*/
prev = currentWorld;
-
+
//pool.Enqueue(ui::handleEvents);
ui::handleEvents();
@@ -496,23 +496,23 @@ void mainLoop(void){
/*
* Update player and entity coordinates.
*/
-
+
/*pool.Enqueue([](){
currentWorld->update(player,deltaTime);
});*/
-
+
currentWorld->update(player,deltaTime);
-
+
/*
* Update debug variables if necessary
*/
-
+
if ( ++debugDiv == 20 ) {
debugDiv=0;
-
+
if ( deltaTime )
fps = 1000 / deltaTime;
- else if(!(debugDiv%10))
+ if(!(debugDiv%10))
debugY = player->loc.y;
}
MENU:
@@ -520,12 +520,12 @@ MENU:
}
void render(){
-
+
/*
* This offset variable is what we use to move the camera and locked
* objects on the screen so they always appear to be in the same relative area
*/
-
+
offset.x = player->loc.x + player->width/2;
offset.y = SCREEN_HEIGHT/2;
@@ -533,7 +533,7 @@ void render(){
* If the camera will go off of the left or right of the screen we want to lock it so we can't
* see past the world render
*/
-
+
if(currentWorld->getTheWidth() < (int)SCREEN_WIDTH){
offset.x = 0;
}else{
@@ -542,7 +542,7 @@ void render(){
if(player->loc.x + player->width + SCREEN_WIDTH/2 > currentWorld->getTheWidth() * 0.5f)
offset.x = ((currentWorld->getTheWidth() * 0.5f) - SCREEN_WIDTH / 2) - player->width / 2;
}
-
+
if(player->loc.y > SCREEN_HEIGHT/2)
offset.y = player->loc.y + player->height;
@@ -558,7 +558,7 @@ void render(){
*
* glMatrixMode This changes our current stacks mode so the drawings below
* it can take on certain traits.
- *
+ *
* GL_PROJECTION This is the matrix mode that sets the cameras position,
* GL_PROJECTION is made up of a stack with two matrices which
* means we can make up to 2 seperate changes to the camera.
@@ -582,7 +582,7 @@ void render(){
* glLoadIdentity This scales the current matrix back to the origin so the
* translations are seen normally on a stack.
*/
-
+
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -591,7 +591,7 @@ void render(){
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
-
+
/*
* glPushAttrib This passes attributes to the renderer so it knows what it can
* render. In our case, GL_DEPTH_BUFFER_BIT allows the renderer to
@@ -602,14 +602,14 @@ void render(){
* glClear This clears the new matrices using the type passed. In our case:
* GL_COLOR_BUFFER_BIT allows the matrices to have color on them
*/
-
+
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT );
glClear(GL_COLOR_BUFFER_BIT);
/**************************
**** RENDER STUFF HERE ****
**************************/
-
+
/*
* Call the world's draw function, drawing the player, the world, the background, and entities. Also
* draw the player's inventory if it exists.
@@ -622,7 +622,7 @@ void render(){
/*
* Calculate the player's hand angle.
*/
-
+
handAngle = atan((ui::mouse.y - (player->loc.y + player->height/2)) / (ui::mouse.x - player->loc.x + player->width/2))*180/PI;
if(ui::mouse.x < player->loc.x){
if(handAngle <= 0)
@@ -631,21 +631,21 @@ void render(){
handAngle+=180;
}
}
-
+
if(ui::mouse.x > player->loc.x && ui::mouse.y < player->loc.y+player->height/2 && handAngle <= 0)
handAngle = 360 + handAngle;
-
+
/*
* Draw the player's inventory.
*/
-
+
player->inv->draw();
/*
* Here we draw a black overlay if it's been requested.
*/
-
+
if(fadeIntensity){
if(fadeWhite)
safeSetColorA(255,255,255,fadeIntensity);
@@ -662,7 +662,7 @@ void render(){
/*
* Draw UI elements. This includes the player's health bar and the dialog box.
*/
-
+
ui::draw();
/*
@@ -670,7 +670,7 @@ void render(){
*/
if(ui::debug){
-
+
ui::putText(offset.x-SCREEN_WIDTH/2,
(offset.y+SCREEN_HEIGHT/2)-ui::fontSize,
"FPS: %d\nG:%d\nRes: %ux%u\nE: %d\nPOS: (x)%+.2f\n (y)%+.2f\nTc: %u\nHA: %+.2f\nPl: %d\n Vol: %f",
@@ -686,7 +686,7 @@ void render(){
player->light,
VOLUME_MASTER
);
-
+
if(ui::posFlag){
glBegin(GL_LINES);
glColor3ub(255,0,0);
@@ -722,7 +722,7 @@ void render(){
glTexCoord2f(0,1);glVertex2i(ui::mouse.x ,ui::mouse.y-HLINE*5 );
glEnd();
glDisable(GL_TEXTURE_2D);
-
+
/**************************
**** END RENDERING ****
**************************/
@@ -757,7 +757,7 @@ void logic(){
* Run the world's detect function. This handles the physics of the player and any entities
* that exist in this world.
*/
-
+
currentWorld->detect(player);
if(player->loc.y<.02)gameRunning=false;
@@ -766,10 +766,10 @@ void logic(){
* basically runs their AI functions depending on what type of entity they are. For NPCs,
* click detection is done as well for NPC/player interaction.
*/
-
+
for(auto &n : currentWorld->npc){
if(n->alive){
-
+
/*
* Make the NPC 'wander' about the world if they're allowed to do so.
* Entity->canMove is modified when a player interacts with an NPC so
@@ -778,9 +778,9 @@ void logic(){
if(n->canMove)
n->wander((rand() % 120 + 30));
-
+
/*if(!player->inv->usingi) n->hit = false;
-
+
if(player->inv->usingi && !n->hit && player->inv->detectCollision((vec2){n->loc.x, n->loc.y},(vec2){n->loc.x+n->width,n->loc.y+n->height})){
n->health -= 25;
n->hit = true;
@@ -791,7 +791,7 @@ void logic(){
currentWorld->addParticle(rand()%HLINE*3 + n->loc.x - .05f,n->loc.y + n->height*.5, HLINE,HLINE, -(rand()%10)*.01,((rand()%10)*.01-.05), {(rand()%75)+10/100.0f,0,0}, 10000);
}
}*/
-
+
/*
* Don't bother handling the NPC if another has already been handled.
*/
@@ -848,7 +848,7 @@ void logic(){
}else n->near=false;
}
}
-
+
for(auto &m : currentWorld->mob){
if(m->alive){
@@ -873,7 +873,7 @@ void logic(){
}
}
}
-
+
if(!objectInteracting){
for(auto &o : currentWorld->object){
if(o->alive){
@@ -898,11 +898,11 @@ void logic(){
}
}
}
-
+
/*
* Switch between day and night (SUNNY and DARK) if necessary.
*/
-
+
if(!(tickCount%DAY_CYCLE)||!tickCount){
if ( weather == WorldWeather::Sunny )
weather = WorldWeather::Dark;
@@ -921,7 +921,7 @@ void logic(){
/*
* Transition to and from black if necessary.
*/
-
+
if(fadeEnable){
if(fadeIntensity < 150)fadeIntensity+=fadeFast?40:10;
else if(fadeIntensity < 255)fadeIntensity+=fadeFast?20:5;
diff --git a/src/entities.cpp b/src/entities.cpp
index 8a10428..7d906ea 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -562,17 +562,19 @@ void Mob::wander(int timeRun){
if(aggressive && !YAYA &&
player->loc.x + (width / 2) > loc.x && player->loc.x + (width / 2) < loc.x + width &&
player->loc.y + (height / 3) > loc.y && player->loc.y + (height / 3) < loc.y + height ){
- Arena *a = new Arena(currentWorld,player,this);
- a->setStyle("");
- a->setBackground( WorldBGType::Forest );
- a->setBGM("assets/music/embark.wav");
+ if ( !ui::dialogBoxExists ) {
+ Arena *a = new Arena(currentWorld,player,this);
+ a->setStyle("");
+ a->setBackground( WorldBGType::Forest );
+ a->setBGM("assets/music/embark.wav");
- ui::toggleWhiteFast();
- YAYA = true;
- ui::waitForCover();
- YAYA = false;
- currentWorld = a;
- ui::toggleWhiteFast();
+ ui::toggleWhiteFast();
+ YAYA = true;
+ ui::waitForCover();
+ YAYA = false;
+ currentWorld = a;
+ ui::toggleWhiteFast();
+ }
}
switch(subtype){
diff --git a/src/inventory.cpp b/src/inventory.cpp
index e82d99e..795fb55 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -142,12 +142,12 @@ const char *getItemTexturePath(std::string name){
}
GLuint getItemTexture(std::string name){
- for(auto &i : itemMap){
- if(i->name == name)
- return Texture::loadTexture(i->texloc);
+ for ( int i = itemMap.size(); i--; ) {
+ if ( itemMap[i]->name == name )
+ return itemtex[i];
}
-
- return Texture::loadTexture("assets/items/ITEM_TEST.png");
+ DEBUG_printf("Failed to find texture for item %s!", name.c_str() );
+ return 0;
}
float getItemWidth(std::string name){
diff --git a/src/ui.cpp b/src/ui.cpp
index 50ae9de..4148238 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -706,7 +706,7 @@ namespace ui {
glColor3ub(255,255,255);
glBegin(GL_LINE_STRIP);
- glVertex2f(x-1 ,y+1);
+ glVertex2f(x-1 ,y+1);
glVertex2f(x+1+(SCREEN_WIDTH/3),y+1);
glVertex2f(x+1+(SCREEN_WIDTH/3),y-1-SCREEN_HEIGHT*.6);
glVertex2f(x-1,y-1-SCREEN_HEIGHT*.6);
diff --git a/src/world.cpp b/src/world.cpp
index af28ac5..097847f 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -66,10 +66,10 @@ const std::string bgPaths[2][9]={
const std::string buildPaths[] = {
"townhall.png",
- "house1.png",
- "house2.png",
- "house1.png",
- "house1.png",
+ "house1.png",
+ "house2.png",
+ "house1.png",
+ "house1.png",
"fountain1.png",
"lampPost1.png",
"brazzier.png"
@@ -88,7 +88,7 @@ const float bgDraw[4][3]={
/**
* Sets the desired theme for the world's background.
- *
+ *
* The images chosen for the background layers are selected depending on the
* world's background type.
*/
@@ -101,7 +101,7 @@ setBackground( WorldBGType bgt )
case WorldBGType::Forest:
bgTex = new Texturec( bgFiles );
break;
-
+
case WorldBGType::WoodHouse:
bgTex = new Texturec( bgFilesIndoors );
break;
@@ -114,7 +114,7 @@ setBackground( WorldBGType bgt )
/**
* Sets the world's style.
- *
+ *
* The world's style will determine what sprites are used for things like\
* generic structures.
*/
@@ -123,25 +123,25 @@ void World::
setStyle( std::string pre )
{
unsigned int i;
-
+
// get folder prefix
std::string prefix = pre.empty() ? "assets/style/classic/" : pre;
-
+
for ( i = 0; i < arrAmt(buildPaths); i++ )
sTexLoc.push_back( prefix + buildPaths[i] );
-
+
prefix += "bg/";
-
+
for ( i = 0; i < arrAmt(bgPaths[0]); i++ )
bgFiles.push_back( prefix + bgPaths[0][i] );
-
+
for ( i = 0; i < arrAmt(bgPaths[1]); i++ )
bgFilesIndoors.push_back( prefix + bgPaths[1][i] );
}
/**
* Creates a world object.
- *
+ *
* Note that all this does is nullify pointers, to prevent as much disaster as
* possible. Functions like setBGM(), setStyle() and generate() should be called
* before the World is actually put into use.
@@ -151,14 +151,14 @@ World::
World( void )
{
bgmObj = NULL;
-
+
toLeft = NULL;
toRight = NULL;
}
/**
* The entity vector destroyer.
- *
+ *
* This function will free all memory used by all entities, and then empty the
* vectors they were stored in.
*/
@@ -177,25 +177,25 @@ deleteEntities( void )
delete npc.back();
npc.pop_back();
}
-
+
// free structures
while ( !build.empty() ) {
delete build.back();
build.pop_back();
}
-
+
// free objects
while ( !object.empty() ) {
delete object.back();
object.pop_back();
}
-
+
// clear entity array
entity.clear();
-
+
// free particles
particles.clear();
-
+
// clear light array
light.clear();
@@ -208,7 +208,7 @@ deleteEntities( void )
/**
* The world destructor.
- *
+ *
* This will free objects used by the world itself, then free the vectors of
* entity-related objects.
*/
@@ -219,9 +219,9 @@ World::
// sdl2_mixer's object
if(bgmObj)
Mix_FreeMusic(bgmObj);
-
+
delete bgTex;
-
+
delete[] toLeft;
delete[] toRight;
@@ -230,20 +230,20 @@ World::
/**
* Generates a world of the specified width.
- *
+ *
* This will mainly populate the WorldData array, mostly preparing the World
* object for usage.
*/
void World::
generate( unsigned int width )
-{
+{
// iterator for `for` loops
std::vector<WorldData>::iterator wditer;
-
+
// see below for description
float geninc = 0;
-
+
// check for valid width
if ( (int)width <= 0 )
UserError("Invalid world dimensions");
@@ -251,17 +251,17 @@ generate( unsigned int width )
// allocate space for world
worldData = std::vector<WorldData> (width + GROUND_HILLINESS, WorldData { false, {0,0}, 0, 0 });
lineCount = worldData.size();
-
+
// prepare for generation
worldData.front().groundHeight = GROUND_HEIGHT_INITIAL;
wditer = worldData.begin();
-
+
// give every GROUND_HILLINESSth entry a groundHeight value
for(unsigned int i = GROUND_HILLINESS; i < worldData.size(); i += GROUND_HILLINESS, wditer += GROUND_HILLINESS)
worldData[i].groundHeight = (*wditer).groundHeight + (randGet() % 8 - 4);
// create slopes from the points that were just defined, populate the rest of the WorldData structure
-
+
for(wditer = worldData.begin(); wditer != worldData.end(); wditer++){
if ((*wditer).groundHeight)
// wditer + GROUND_HILLINESS can go out of bounds (invalid read)
@@ -279,15 +279,15 @@ generate( unsigned int width )
(*wditer).groundHeight = GROUND_HEIGHT_MINIMUM;
else if ( (*wditer).groundHeight > GROUND_HEIGHT_MAXIMUM )
(*wditer).groundHeight = GROUND_HEIGHT_MAXIMUM;
-
+
if( (*wditer).groundHeight <= 0 )
(*wditer).groundHeight = GROUND_HEIGHT_MINIMUM;
}
-
+
// define x-coordinate of world's leftmost 'line'
worldStart = (width - GROUND_HILLINESS) * HLINE / 2 * -1;
-
+
// create empty star array, should be filled here as well...
star = std::vector<vec2> (100, vec2 { 0, 400 } );
for ( auto &s : star ) {
@@ -298,7 +298,7 @@ generate( unsigned int width )
/**
* Updates all entity and player coordinates with their velocities.
- *
+ *
* Also handles music fading, although that could probably be placed elsewhere.
*/
@@ -308,15 +308,20 @@ update( Player *p, unsigned int delta )
// update player coords
p->loc.y += p->vel.y * delta;
p->loc.x +=(p->vel.x * p->speed) * delta;
-
+
+ if ( p->loc.y > 5000 ) {
+ std::cout << "Too high for me m8." << std::endl;
+ abort();
+ }
+
// update entity coords
for ( auto &e : entity ) {
e->loc.y += e->vel.y * delta;
-
+
// dont let structures move?
if ( e->type != STRUCTURET && e->canMove ) {
e->loc.x += e->vel.x * delta;
-
+
// update boolean directions
if ( e->vel.x < 0 )
e->left = true;
@@ -342,7 +347,7 @@ update( Player *p, unsigned int delta )
}
}
}
-
+
// handle music fades
if ( ui::dialogImportant )
Mix_FadeOutMusic(2000);
@@ -352,7 +357,7 @@ update( Player *p, unsigned int delta )
/**
* Set the world's BGM.
- *
+ *
* This will load a sound file to be played while the player is in this world.
* If no file is found, no music should play.
*/
@@ -366,7 +371,7 @@ setBGM( std::string path )
/**
* Toggle play/stop of the background music.
- *
+ *
* If new music is to be played a crossfade will occur, otherwise... uhm.
*/
@@ -388,7 +393,7 @@ bgmPlay( World *prev ) const
/**
* The world draw function.
- *
+ *
* This function will draw the background layers, entities, and player to the
* screen.
*/
@@ -398,34 +403,34 @@ draw( Player *p )
{
// iterators
int i, iStart, iEnd;
-
+
// shade value for draws -- may be unnecessary
int shadeBackground = -worldShade;
-
+
// player's offset in worldData[]
int pOffset;
-
+
// world width in pixels
int width = worldData.size() * HLINE;
-
+
// shade value for GLSL
float shadeAmbient = -worldShade / 50.0f + 0.5f; // -0.5f to 1.5f
if ( shadeAmbient < 0 )
shadeAmbient = 0;
else if ( shadeAmbient > 0.9f )
shadeAmbient = 1;
-
+
/*
* Draw background images.
*/
-
+
glEnable( GL_TEXTURE_2D );
-
+
// the sunny wallpaper is faded with the night depending on tickCount
-
+
bgTex->bind( 0 );
safeSetColorA( 255, 255, 255, 255 - worldShade * 4 );
-
+
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 ); glVertex2i( worldStart, SCREEN_HEIGHT );
glTexCoord2i( 1, 0 ); glVertex2i( -worldStart, SCREEN_HEIGHT );
@@ -435,24 +440,24 @@ draw( Player *p )
bgTex->bindNext();
safeSetColorA( 255, 255, 255, worldShade * 4 );
-
+
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 ); glVertex2i( worldStart, SCREEN_HEIGHT );
glTexCoord2i( 1, 0 ); glVertex2i( -worldStart, SCREEN_HEIGHT );
glTexCoord2i( 1, 1 ); glVertex2i( -worldStart, 0 );
glTexCoord2i( 0, 1 ); glVertex2i( worldStart, 0 );
glEnd();
-
+
glDisable( GL_TEXTURE_2D );
-
+
// draw the stars if the time deems it appropriate
-
+
//if (((( weather == WorldWeather::Dark ) & ( tickCount % DAY_CYCLE )) < DAY_CYCLE / 2) ||
// ((( weather == WorldWeather::Sunny ) & ( tickCount % DAY_CYCLE )) > DAY_CYCLE * .75) ){
- if ( worldShade > 0 ) {
+ if ( worldShade > 0 ) {
safeSetColorA( 255, 255, 255, 255 - (getRand() % 30 - 15) );
-
+
for ( i = 0; i < 100; i++ ) {
glRectf(star[i].x + offset.x * .9,
star[i].y,
@@ -460,15 +465,15 @@ draw( Player *p )
star[i].y + HLINE
);
}
- }
-
+ }
+
// draw remaining background items
-
+
glEnable( GL_TEXTURE_2D );
-
+
bgTex->bindNext();
safeSetColorA( 150 + shadeBackground * 2, 150 + shadeBackground * 2, 150 + shadeBackground * 2, 255 );
-
+
glBegin( GL_QUADS );
for ( i = 0; i <= (int)(worldData.size() * HLINE / 1920); i++ ) {
glTexCoord2i( 0, 1 ); glVertex2i( width / 2 * -1 + (1920 * i ) + offset.x * .85, GROUND_HEIGHT_MINIMUM );
@@ -477,11 +482,11 @@ draw( Player *p )
glTexCoord2i( 0, 0 ); glVertex2i( width / 2 * -1 + (1920 * i ) + offset.x * .85, GROUND_HEIGHT_MINIMUM + 1080 );
}
glEnd();
-
+
for ( i = 0; i < 4; i++ ) {
bgTex->bindNext();
safeSetColorA( bgDraw[i][0] + shadeBackground * 2, bgDraw[i][0] + shadeBackground * 2, bgDraw[i][0] + shadeBackground * 2, bgDraw[i][1] );
-
+
glBegin( GL_QUADS );
for( int j = worldStart; j <= -worldStart; j += 600 ){
glTexCoord2i( 0, 1 ); glVertex2i( j + offset.x * bgDraw[i][2], GROUND_HEIGHT_MINIMUM );
@@ -491,22 +496,22 @@ draw( Player *p )
}
glEnd();
}
-
+
glDisable( GL_TEXTURE_2D );
-
+
// draw black under backgrounds
-
+
glColor3ub( 0, 0, 0 );
glRectf( worldStart, GROUND_HEIGHT_MINIMUM, -worldStart, 0 );
-
+
pOffset = (offset.x + p->width / 2 - worldStart) / HLINE;
-
+
/*
* Prepare for world ground drawing.
*/
-
+
// only draw world within player vision
-
+
if ((iStart = pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS) < 0)
iStart = 0;
@@ -518,51 +523,51 @@ draw( Player *p )
// draw particles and buildings
std::for_each( particles.begin(), particles.end(), [](Particles part) { if ( part.behind ) part.draw(); });
-
+
for ( auto &b : build )
b->draw();
// draw light elements?
-
+
glEnable( GL_TEXTURE_2D );
-
+
glActiveTexture( GL_TEXTURE0 );
bgTex->bindNext();
-
+
std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size() + p->light));
auto pointArray = pointArrayBuf.get();
-
+
for ( i = 0; i < (int)light.size(); i++ ) {
pointArray[2 * i ] = light[i].loc.x - offset.x;
pointArray[2 * i + 1] = light[i].loc.y;
}
-
+
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
-
+
glUseProgram( shaderProgram );
glUniform1i( glGetUniformLocation( shaderProgram, "sampler"), 0 );
glUniform1f( glGetUniformLocation( shaderProgram, "amb" ), shadeAmbient );
-
+
if ( p->light ) {
pointArray[2 * (light.size() + 1) ] = (float)( p->loc.x + SCREEN_WIDTH / 2 );
pointArray[2 * (light.size() + 1) + 1] = (float)( p->loc.y );
}
-
+
if ( light.size() + (int)p->light == 0)
glUniform1i( glGetUniformLocation( shaderProgram, "numLight"), 0);
else {
glUniform1i ( glGetUniformLocation( shaderProgram, "numLight" ), light.size() + (int)p->light );
- glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray );
+ glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray );
glUniform3f ( glGetUniformLocation( shaderProgram, "lightColor" ), 1.0f, 1.0f, 1.0f );
}
-
+
/*
* Draw the dirt.
*/
-
+
glBegin( GL_QUADS );
-
+
// faulty
/*glTexCoord2i(0 ,0);glVertex2i(pOffset - (SCREEN_WIDTH / 1.5),0);
glTexCoord2i(64,0);glVertex2i(pOffset + (SCREEN_WIDTH / 1.5),0);
@@ -578,50 +583,50 @@ draw( Player *p )
glTexCoord2i( 0, 0 ); glVertex2i(worldStart + i * HLINE , worldData[i].groundHeight - GRASS_HEIGHT );
glTexCoord2i( 1, 0 ); glVertex2i(worldStart + i * HLINE + HLINE , worldData[i].groundHeight - GRASS_HEIGHT );
-
+
glTexCoord2i( 1, (int)(worldData[i].groundHeight / 64) + worldData[i].groundColor ); glVertex2i(worldStart + i * HLINE + HLINE, 0 );
glTexCoord2i( 0, (int)(worldData[i].groundHeight / 64) + worldData[i].groundColor ); glVertex2i(worldStart + i * HLINE , 0 );
-
+
if ( worldData[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1 )
worldData[i].groundHeight = 0;
}
-
+
glEnd();
-
+
glUseProgram(0);
glDisable(GL_TEXTURE_2D);
-
+
/*
* Draw the grass/the top of the ground.
*/
glEnable( GL_TEXTURE_2D );
-
+
glActiveTexture( GL_TEXTURE0 );
bgTex->bindNext();
-
+
glUseProgram( shaderProgram );
glUniform1i( glGetUniformLocation( shaderProgram, "sampler"), 0);
float cgh[2];
for ( i = iStart; i < iEnd - GROUND_HILLINESS; i++ ) {
-
+
// load the current line's grass values
if ( worldData[i].groundHeight )
memcpy( cgh, worldData[i].grassHeight, 2 * sizeof( float ));
else
memset( cgh, 0 , 2 * sizeof( float ));
-
+
// flatten the grass if the player is standing on it.
if( !worldData[i].grassUnpressed ){
cgh[0] /= 4;
cgh[1] /= 4;
}
-
+
// actually draw the grass.
-
+
safeSetColorA( 255, 255, 255, 255 );
-
+
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 ); glVertex2i( worldStart + i * HLINE , worldData[i].groundHeight + cgh[0] );
glTexCoord2i( 1, 0 ); glVertex2i( worldStart + i * HLINE + HLINE / 2, worldData[i].groundHeight + cgh[0] );
@@ -640,9 +645,9 @@ draw( Player *p )
/*
* Draw remaining entities.
*/
-
+
std::for_each( particles.begin(), particles.end(), [](Particles part) { if ( !part.behind ) part.draw(); });
-
+
for ( auto &n : npc )
n->draw();
@@ -651,11 +656,11 @@ draw( Player *p )
for ( auto &o : object )
o->draw();
-
+
/*
* Handle grass-squishing.
*/
-
+
// calculate the line that the player is on
int ph = ( p->loc.x + p->width / 2 - worldStart ) / HLINE;
@@ -671,13 +676,13 @@ draw( Player *p )
/*
* Draw the player.
*/
-
+
p->draw();
}
/**
* Handles physics and such for a single entity.
- *
+ *
* This function is kept private, as World::detect() should be used instead to
* handle stuffs for all entities at once.
*/
@@ -688,11 +693,11 @@ singleDetect( Entity *e )
std::string killed;
unsigned int i,j;
int l;
-
+
/*
* Kill any dead entities.
*/
-
+
if ( !e->alive || e->health <= 0 ) {
for ( i = 0; i < entity.size(); i++) {
if ( entity[i] == e ){
@@ -748,71 +753,77 @@ singleDetect( Entity *e )
std::cout<<"RIP "<<e->name<<"."<<std::endl;
exit(0);
}
-
+
/*
* Handle only living entities.
*/
-
+
if(e->alive){
-
+
if ( e->type == MOBT && Mobp(e)->subtype == MS_TRIGGER )
return;
-
+
/*
* Calculate the line that this entity is currently standing on.
*/
-
+
l=(e->loc.x + e->width / 2 - worldStart) / HLINE;
if(l < 0) l=0;
i = l;
if(i > lineCount-1) i=lineCount-1;
-
+
/*
* If the entity is under the world/line, pop it back to the surface.
*/
-
+
if ( e->loc.y < worldData[i].groundHeight ) {
- e->loc.y= worldData[i].groundHeight - .001 * deltaTime;
- e->ground=true;
- e->vel.y=0;
-
+ if ( worldData[i].groundHeight - e->loc.y > 30 ) {
+ int dir = e->vel.x > 0 ? -1 : 1;
+ e->loc.x += HLINE * 8 * dir;
+ e->loc.y = worldData[i + 8 * dir].groundHeight;
+ } else {
+ e->loc.y = worldData[i].groundHeight - .001 * deltaTime;
+ e->ground = true;
+ e->vel.y = 0;
+ }
+
/*
* Handle gravity if the entity is above the line.
*/
-
+
}else{
-
+
if(e->type == STRUCTURET && e->loc.y > 2000){
e->loc.y = worldData[i].groundHeight;
e->vel.y = 0;
e->ground = true;
return;
}else if(e->vel.y > -2)e->vel.y-=.003 * deltaTime;
-
+
}
-
+
/*
* Insure that the entity doesn't fall off either edge of the world.
*/
if(e->loc.x < worldStart){ // Left bound
-
+
e->vel.x=0;
e->loc.x=(float)worldStart + HLINE / 2;
-
+
}else if(e->loc.x + e->width + HLINE > worldStart + worldStart * -2){ // Right bound
-
+
e->vel.x=0;
e->loc.x=worldStart + worldStart * -2 - e->width - HLINE;
-
+
}
}
}
/**
* Handle entity logic for the world.
- *
+ *
* This function runs World::singleDetect() for the player and every entity
* currently in a vector of this world. Particles and village entrance/exiting
* are also handled here.
@@ -822,20 +833,20 @@ void World::
detect( Player *p )
{
int l;
-
+
// handle the player
std::thread( &World::singleDetect, this, p).detach();
-
+
// handle other entities
for ( auto &e : entity )
std::thread(&World::singleDetect,this,e).detach();
-
+
// handle particles
for ( auto &part : particles ) {
-
+
// get particle's current world line
l = (part.loc.x + part.width / 2 - worldStart) / HLINE;
-
+
if ( l < 0 )
l = 0;
@@ -851,7 +862,7 @@ detect( Player *p )
} else if ( part.gravity && part.vely > -2 )
part.vely -= .003 * deltaTime;
}
-
+
// handle particle creation
for ( auto &b : build ) {
switch ( b->bsubtype ) {
@@ -870,7 +881,7 @@ detect( Player *p )
particles.back().fountain = true;
}
break;
-
+
case FIRE_PIT:
for(unsigned int r = (randGet() % 20) + 11; r--; ) {
addParticle(randGet() % (int)(b->width / 2) + b->loc.x + b->width / 4, // x
@@ -909,18 +920,18 @@ void World::addStructure(BUILD_SUB sub, float x,float y, std::string tex, std::s
build.push_back(new Structures());
build.back()->inWorld = this;
build.back()->textureLoc = tex;
-
+
build.back()->spawn(sub,x,y);
-
+
build.back()->inside = inside;
-
+
entity.push_back(build.back());
}
void World::addMob(int t,float x,float y){
mob.push_back(new Mob(t));
mob.back()->spawn(x,y);
-
+
entity.push_back(mob.back());
}
@@ -928,14 +939,14 @@ void World::addMob(int t,float x,float y,void (*hey)(Mob *)){
mob.push_back(new Mob(t));
mob.back()->spawn(x,y);
mob.back()->hey = hey;
-
+
entity.push_back(mob.back());
}
void World::addNPC(float x,float y){
npc.push_back(new NPC());
npc.back()->spawn(x,y);
-
+
entity.push_back(npc.back());
}
@@ -975,7 +986,7 @@ char *World::setToLeft(const char *file){
delete[] toLeft;
if(!file)
return (toLeft = NULL);
-
+
strcpy((toLeft = new char[strlen(file) + 1]),file);
return toLeft;
}
@@ -984,7 +995,7 @@ char *World::setToRight(const char *file){
delete[] toRight;
if(!file)
return (toRight = NULL);
-
+
strcpy((toRight = new char[strlen(file) + 1]),file);
return toRight;
}
@@ -993,33 +1004,37 @@ World *World::
goWorldLeft( Player *p )
{
World *tmp;
-
- // check if player is at world edge
- if(toLeft && p->loc.x < worldStart + HLINE * 15.0f){
-
- // load world (`toLeft` conditional confirms existance)
+
+ // check if player is at world edge
+ if( toLeft && p->loc.x < worldStart + HLINE * 15.0f ) {
+
+ // load world (`toLeft` conditional confirms existance)
tmp = loadWorldFromXML(toLeft);
-
- // adjust player location
- p->loc.x = tmp->worldStart - HLINE * -10.0f;
+
+ // adjust player location
+ p->loc.x = tmp->worldStart + HLINE * 20;
p->loc.y = tmp->worldData[tmp->lineCount - 1].groundHeight;
-
+
return tmp;
}
+
return this;
-}
+}
-World *World::goWorldRight(Player *p){
+World *World::
+goWorldRight( Player *p )
+{
World *tmp;
-
- if(toRight && p->loc.x + p->width > -worldStart - HLINE * 15){
+
+ if( toRight && p->loc.x + p->width > -worldStart - HLINE * 15 ) {
tmp = loadWorldFromXML(toRight);
-
- p->loc.x = tmp->worldStart + HLINE * 10;
+
+ p->loc.x = tmp->worldStart - HLINE * -15.0f;
p->loc.y = GROUND_HEIGHT_MINIMUM;
-
+
return tmp;
}
+
return this;
}
@@ -1033,13 +1048,13 @@ goInsideStructure( Player *p )
if(p->loc.x > b->loc.x &&
p->loc.x + p->width < b->loc.x + b->width ){
inside.push_back((std::string)(currentXML.c_str() + 4));
-
+
tmp = loadWorldFromXML(b->inside.c_str());
-
+
ui::toggleBlackFast();
ui::waitForCover();
ui::toggleBlackFast();
-
+
return tmp;
}
}
@@ -1052,11 +1067,11 @@ goInsideStructure( Player *p )
ui::toggleBlackFast();
ui::waitForCover();
-
+
p->loc.x = b->loc.x + (b->width / 2);
-
+
ui::toggleBlackFast();
-
+
return tmp;
}
}
@@ -1065,10 +1080,32 @@ goInsideStructure( Player *p )
return this;
}
-void World::addHole(unsigned int start,unsigned int end){
- unsigned int i;
- for(i=start;i<end;i++){
+void World::
+addHole( unsigned int start, unsigned int end )
+{
+ for ( unsigned int i = end; i-- > start; )
worldData[i].groundHeight = 0;
+}
+
+void World::
+addHill( const ivec2 peak, const unsigned int width )
+{
+ int start = peak.x - width / 2, end = start + width, offset;
+ const float thing = peak.y - worldData[start].groundHeight;
+ const float period = PI / width;
+
+ if ( start < 0 ) {
+ offset = -start;
+ start = 0;
+ }
+
+ if ( end > (signed)worldData.size() )
+ end = worldData.size();
+
+ for ( int i = start; i < end; i++ ) {
+ worldData[i].groundHeight += thing * sin((i - start + offset) * period);
+ if ( worldData[i].groundHeight > peak.y )
+ worldData[i].groundHeight = peak.y;
}
}
@@ -1080,10 +1117,10 @@ getTheWidth( void ) const
void World::save(void){
std::string data;
-
+
std::string save = (std::string)currentXML + ".dat";
std::ofstream out (save,std::ios::out | std::ios::binary);
-
+
std::cout<<"Saving to "<<save<<" ..."<<std::endl;
for(auto &n : npc){
@@ -1091,40 +1128,40 @@ void World::save(void){
data.append(std::to_string((int)n->loc.x) + "\n");
data.append(std::to_string((int)n->loc.y) + "\n");
}
-
+
for(auto &b : build){
data.append(std::to_string((int)b->loc.x) + "\n");
data.append(std::to_string((int)b->loc.y) + "\n");
}
-
+
for(auto &m : mob){
data.append(std::to_string((int)m->loc.x) + "\n");
data.append(std::to_string((int)m->loc.y) + "\n");
data.append(std::to_string((int)m->alive) + "\n");
}
-
+
data.append("dOnE\0");
out.write(data.c_str(),data.size());
-
+
out.close();
}
void World::load(void){
std::string save,data,line;
const char *filedata;
-
+
save = (std::string)currentXML + ".dat";
filedata = readFile(save.c_str());
data = filedata;
std::istringstream iss (data);
-
+
for(auto &n : npc){
std::getline(iss,line);
if(line == "dOnE")return;
if((n->dialogIndex = std::stoi(line)) != 9999)
n->addAIFunc(commonAIFunc,false);
else n->clearAIFunc();
-
+
std::getline(iss,line);
if(line == "dOnE")return;
n->loc.x = std::stoi(line);
@@ -1132,7 +1169,7 @@ void World::load(void){
if(line == "dOnE")return;
n->loc.y = std::stoi(line);
}
-
+
for(auto &b : build){
std::getline(iss,line);
if(line == "dOnE")return;
@@ -1141,7 +1178,7 @@ void World::load(void){
if(line == "dOnE")return;
b->loc.y = std::stoi(line);
}
-
+
for(auto &m : mob){
std::getline(iss,line);
if(line == "dOnE")return;
@@ -1153,12 +1190,12 @@ void World::load(void){
if(line == "dOnE")return;
m->alive = std::stoi(line);
}
-
+
while(std::getline(iss,line)){
if(line == "dOnE")
break;
}
-
+
delete[] filedata;
}
@@ -1167,16 +1204,16 @@ IndoorWorld::IndoorWorld(void){
IndoorWorld::~IndoorWorld(void){
delete bgTex;
-
+
deleteEntities();
}
void IndoorWorld::generate(unsigned int width){ // Generates a flat area of width 'width'
lineCount=width+GROUND_HILLINESS; // Sets line count to the desired width plus GEN_INC to remove incorrect line calculations.
if(lineCount<=0)abort();
-
+
worldData = std::vector<WorldData> (lineCount, WorldData { false, {0,0}, INDOOR_FLOOR_HEIGHT, 0 });
-
+
worldStart = (width - GROUND_HILLINESS) * HLINE / 2 * -1;
}
@@ -1184,71 +1221,71 @@ void IndoorWorld::draw(Player *p){
unsigned int i,ie;
//int j,x,v_offset;
int x;
-
+
/*
* Draw the background.
*/
-
+
glEnable(GL_TEXTURE_2D);
-
+
std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size() + p->light));
auto pointArray = pointArrayBuf.get();
-
+
for ( i = 0; i < light.size(); i++ ) {
pointArray[2 * i ] = light[i].loc.x - offset.x;
pointArray[2 * i + 1] = light[i].loc.y;
}
-
+
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
-
+
glUseProgram( shaderProgram );
glUniform1i( glGetUniformLocation( shaderProgram, "sampler"), 0 );
glUniform1f( glGetUniformLocation( shaderProgram, "amb" ), 0.3f );
-
+
if ( p->light ) {
pointArray[2 * (light.size() + 1) ] = (float)( p->loc.x + SCREEN_WIDTH / 2 );
pointArray[2 * (light.size() + 1) + 1] = (float)( p->loc.y );
}
-
+
if ( light.size() + (int)p->light == 0)
glUniform1i( glGetUniformLocation( shaderProgram, "numLight"), 0);
else {
glUniform1i ( glGetUniformLocation( shaderProgram, "numLight" ), light.size() + (int)p->light );
- glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray );
+ glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray );
glUniform3f ( glGetUniformLocation( shaderProgram, "lightColor" ), 1.0f, 1.0f, 1.0f );
}
-
+
bgTex->bind(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //for the s direction
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //for the t direction
glColor4ub(255,255,255,255);
-
+
glBegin(GL_QUADS);
glTexCoord2i(0,1); glVertex2i( worldStart - SCREEN_WIDTH / 2,0);
glTexCoord2i((-worldStart*2+SCREEN_WIDTH)/512,1);glVertex2i(-worldStart + SCREEN_WIDTH / 2,0);
glTexCoord2i((-worldStart*2+SCREEN_WIDTH)/512,0);glVertex2i(-worldStart + SCREEN_WIDTH / 2,SCREEN_HEIGHT);
glTexCoord2i(0,0); glVertex2i( worldStart - SCREEN_WIDTH / 2,SCREEN_HEIGHT);
glEnd();
-
+
glUseProgram(0);
glDisable(GL_TEXTURE_2D);
-
+
/*
* Calculate the starting and ending points to draw the ground from.
*/
-
+
/*v_offset = (p->loc.x - x_start) / HLINE;
j = v_offset - (SCREEN_WIDTH / 2 / HLINE) - GEN_INC;
if(j < 0)j = 0;
i = j;
-
+
ie = v_offset + (SCREEN_WIDTH / 2 / HLINE) - GEN_INC;
if(ie > lineCount)ie = lineCount;*/
-
+
i = 0;
ie = lineCount;
-
+
/*
* Draw the ground.
*/
@@ -1257,7 +1294,7 @@ void IndoorWorld::draw(Player *p){
glBegin(GL_QUADS);
for(;i < ie - GROUND_HILLINESS;i++){
safeSetColor(150,100,50);
-
+
x = worldStart + i * HLINE;
glVertex2i(x ,worldData[i].groundHeight);
glVertex2i(x + HLINE,worldData[i].groundHeight);
@@ -1266,11 +1303,11 @@ void IndoorWorld::draw(Player *p){
}
glEnd();
glUseProgram(0);
-
+
/*
* Draw all entities.
*/
-
+
for ( auto &part : particles )
part.draw();
@@ -1283,14 +1320,14 @@ void IndoorWorld::draw(Player *p){
Arena::Arena(World *leave,Player *p,Mob *m){
generate(800);
addMob(MS_DOOR,100,100);
-
+
inBattle = true;
mmob = m;
mmob->aggressive = false;
-
+
mob.push_back(m);
entity.push_back(m);
-
+
battleNest.push_back(leave);
battleNestLoc.push_back(p->loc);
}
@@ -1305,17 +1342,17 @@ World *Arena::exitArena(Player *p){
p->loc.x + p->width / 2 < mob[0]->loc.x + HLINE * 12 ){
tmp = battleNest.front();
battleNest.erase(battleNest.begin());
-
+
inBattle = !battleNest.empty();
ui::toggleBlackFast();
ui::waitForCover();
-
+
p->loc = battleNestLoc.back();
battleNestLoc.pop_back();
-
+
mob.clear();
mmob->alive = false;
-
+
return tmp;
}else{
return this;
@@ -1338,14 +1375,14 @@ loadWorldFromXMLNoSave( std::string path ) {
XMLDocument xml;
XMLElement *wxml;
XMLElement *vil;
-
+
World *tmp;
float spawnx, randx;
bool dialog,Indoor;
-
+
const char *ptr;
std::string name;
-
+
currentXML = (std::string)"xml/" + path;
xml.LoadFile(currentXML.c_str());
@@ -1362,10 +1399,10 @@ loadWorldFromXMLNoSave( std::string path ) {
Indoor = true;
tmp = new IndoorWorld();
}
-
+
while(wxml){
name = wxml->Name();
-
+
if ( name == "link" ) {
if((ptr = wxml->Attribute("left")))
tmp->setToLeft(ptr);
@@ -1382,7 +1419,7 @@ loadWorldFromXMLNoSave( std::string path ) {
if(Indoor)
((IndoorWorld *)tmp)->generate(wxml->UnsignedAttribute("width"));
else {
-
+
tmp->generate(wxml->UnsignedAttribute("width"));
}
}else if(Indoor)
@@ -1396,7 +1433,7 @@ loadWorldFromXMLNoSave( std::string path ) {
tmp->addMob(type,spawnx,wxml->FloatAttribute("y"));
if(wxml->QueryBoolAttribute("aggressive",&dialog) == XML_NO_ERROR)
tmp->mob.back()->aggressive = dialog;
-
+
} else if ( name == "npc" ) {
const char *npcname;
@@ -1404,23 +1441,23 @@ loadWorldFromXMLNoSave( std::string path ) {
tmp->addNPC(0,100);
else
tmp->addNPC(spawnx,wxml->FloatAttribute("y"));
-
-
+
+
if((npcname = wxml->Attribute("name"))){
delete[] tmp->npc.back()->name;
tmp->npc.back()->name = new char[strlen(npcname) + 1];
strcpy(tmp->npc.back()->name,npcname);
}
-
+
dialog = false;
if(wxml->QueryBoolAttribute("hasDialog",&dialog) == XML_NO_ERROR && dialog)
tmp->npc.back()->addAIFunc(commonAIFunc,false);
else tmp->npc.back()->dialogIndex = 9999;
-
+
} else if ( name == "structure" ) {
tmp->addStructure((BUILD_SUB)wxml->UnsignedAttribute("type"),
- wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR ?
- getRand() % tmp->getTheWidth() / 2.0f :
+ wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR ?
+ getRand() % tmp->getTheWidth() / 2.0f :
spawnx,
100,
wxml->StrAttribute("texture"),
@@ -1431,7 +1468,11 @@ loadWorldFromXMLNoSave( std::string path ) {
} else if ( name == "page" ) {
tmp->addMob( MS_PAGE, wxml->FloatAttribute("x"), 0, commonPageFunc );
tmp->mob.back()->heyid = wxml->Attribute("id");
- }
+ } else if ( name == "hill" ) {
+ tmp->addHill( ivec2 { wxml->IntAttribute("peakx"), wxml->IntAttribute("peaky") }, wxml->UnsignedAttribute("width") );
+ } else if ( name == "time") {
+ tickCount = std::stoi( wxml->GetText() );
+ }
wxml = wxml->NextSiblingElement();
}
@@ -1453,7 +1494,7 @@ loadWorldFromXMLNoSave( std::string path ) {
/**
* READS DATA ABOUT STRUCTURE CONTAINED IN VILLAGE
*/
-
+
if ( name == "structure" ) {
tmp->addStructure((BUILD_SUB)vil->UnsignedAttribute("type"),
vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx,
@@ -1464,7 +1505,7 @@ loadWorldFromXMLNoSave( std::string path ) {
if(!strcmp(vil->Attribute("type"),"market")){
std::cout << "Market" << std::endl;
tmp->addStructure((BUILD_SUB)70,
- vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
+ vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
randx : spawnx,
100,
vil->StrAttribute("texture"),
@@ -1488,20 +1529,20 @@ loadWorldFromXMLNoSave( std::string path ) {
}else if(!strcmp(vil->Attribute("type"),"trader")){
std::cout << "Trader" << std::endl;
tmp->addStructure((BUILD_SUB)71,
- vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
+ vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
randx : spawnx,
100,
vil->StrAttribute("texture"),
vil->StrAttribute("inside"));
}
}
-
+
vptr->build.push_back(tmp->build.back());
-
+
if(vptr->build.back()->loc.x < vptr->start.x){
vptr->start.x = vptr->build.back()->loc.x;
}
-
+
if(vptr->build.back()->loc.x + vptr->build.back()->width > vptr->end.x){
vptr->end.x = vptr->build.back()->loc.x + vptr->build.back()->width;
}
@@ -1509,7 +1550,7 @@ loadWorldFromXMLNoSave( std::string path ) {
//go to the next element in the village block
vil = vil->NextSiblingElement();
}
-
+
std::ifstream dat (((std::string)currentXML + ".dat").c_str());
if(dat.good()){
dat.close();
diff --git a/xml/playerSpawnHill1.xml b/xml/playerSpawnHill1.xml
index c79b93f..86ee397 100644
--- a/xml/playerSpawnHill1.xml
+++ b/xml/playerSpawnHill1.xml
@@ -2,17 +2,20 @@
<World>
<style background="0" bgm="assets/music/embark.wav" folder="assets/style/classic/" />
<generation type="Random" width="500" />
- <link left="playerSpawnHill2.xml" />
-
- <mob x="300" type="1" aggressive="true" />
-
- <trigger x="-300" id="Test" />
-
+ <link right="playerSpawnHill2.xml" />
+ <time>12000</time>
+
+ <hill peakx="0" peaky="1000" width="50" />
+
+ <mob x="300" type="1" aggressive="false" />
+
+ <!--<trigger x="-300" id="Test" />-->
+
<npc name="Ralph" hasDialog="true" />
<npc name="Johnny" hasDialog="false" />
-
+
<page x="-200" id="assets/pages/gootaGoFast.png" />
-
+
<village name="the Cranmore Tubing Park">
<structure type="0" x="-300" inside="playerSpawnHill1_Building1.xml"/>
<structure type="5" x="-500" inside="playerSpawnHill1_Building1.xml"/>
@@ -32,20 +35,20 @@ And it wasn't stormy.
...</Trigger>
<Dialog name="Ralph">
-
+
<text id="0" nextid="1" >
Hello there! My name is Ralph.
</text>
-
+
<text id="1" nextid="2" call="Johnny" callid="0" pause="true" >
You should go talk to my friend Johnny. He's a pretty chill dude.
</text>
-
+
<text id="2" >
Niice.
<quest check="Your First Quest" fail="3" />
</text>
-
+
<text id="3">
Go check out Johnny. He's cool.
</text>
@@ -59,7 +62,7 @@ And it wasn't stormy.
Wood Sword,1
</quest>
</text>
-
+
<text id="1" nextid="1" pause="true" >
Broooooooooooooo...
</text>
diff --git a/xml/playerSpawnHill1_Building1.xml b/xml/playerSpawnHill1_Building1.xml
index 67695c7..f0c8a21 100644
--- a/xml/playerSpawnHill1_Building1.xml
+++ b/xml/playerSpawnHill1_Building1.xml
@@ -2,7 +2,7 @@
<IndoorWorld>
<style background="1" bgm="assets/music/theme_jazz.wav" />
<generation type="Random" width="300" />
-
+
<npc name="Bob" hasDialog="true" />
</IndoorWorld>
@@ -12,23 +12,23 @@
Hey. Have a Dank MayMay :)
<give id="Dank MayMay" count="1" />
</text>
-
+
<text id="1" nextid="2">
What? You want another Dank MayMay?
</text>
-
+
<text id="2" nextid="3" pause="true">
K.
<give id="Dank MayMay" count="1" />
</text>
-
+
<text id="3" nextid="4">
Well... I'm out of Dank MayMays.
</text>
-
+
<text id="4">
Have a sword though.
<give id="Wood Sword" count="1" />
</text>
-
+
</Dialog>
diff --git a/xml/playerSpawnHill2.xml b/xml/playerSpawnHill2.xml
index c46dad3..8d3d328 100644
--- a/xml/playerSpawnHill2.xml
+++ b/xml/playerSpawnHill2.xml
@@ -3,7 +3,7 @@
<style background="0" bgm="assets/music/embark.wav" folder="assets/style/rustic/"/>
<generation type="Random" width="1000" />
<structure type="5" inside="playerSpawnHill1_Building1.xml"/>
-
- <link right="playerSpawnHill1.xml" />
+
+ <link left="playerSpawnHill1.xml" />
</World>