- began work with threading pages/triggers
- added debug flag for settings.xml
- improved particle drawing
+
+4/6/2016:
+=========
+
+ - began considering vertex-based rendering
+ - discovered really weird thread handling issues
+ - broke world transitions
+
+4/7/2016:
+=========
+
+ - fixed world transitions
+ - implemented rain
+ - added custom health values in XML
+ - player can't leave arenas until mob death
+ - typeOut speed is consistent
+ - continued smart renderinging
+
+4/11/2016:
+==========
+
+ - heavily revised merchant code
+ - fixed bug that caused game to crash idly
+ - fixed bug with spawning NPCs at specific coordinates
+ - added functionality to ui to auto-complete the next typeOut
-#version 130\r
+#version 120\r
uniform sampler2D sampler;\r
\r
uniform int numLight;\r
#undef near
#endif
+/**
+ * Defines how many game ticks should occur in one second, affecting how often
+ * game logic is handled.
+ */
+
+#define TICKS_PER_SEC 20
+
+/**
+ * Defines how many milliseconds each game tick will take.
+ */
+
+#define MSEC_PER_TICK ( 1000 / TICKS_PER_SEC )
+
//#define SEGFAULT
/**
public:
std::string item[2];
int quantity[2];
- Trade(int qo, const char* o, int qt, const char* t){
- item[0] = o;
- item[1] = t;
-
- quantity[0] = qo;
- quantity[1] = qt;
-
- std::cout << "Trading: " << quantity[0] << " " << item[0] << " for " << quantity[1] << " " << item[1] << std::endl;
- }
+ Trade(int qo, std::string o, int qt, std::string t);
Trade(){}
};
vec2 loc;
float width;
float height;
- float velx;
- float vely;
+ vec2 vel;
Color color;
vec2 index;
float duration;
bool fountain;
bool gravity;
bool behind;
+ bool bounce;
Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d){
loc.x = x;
loc.y = y;
+ vel.x = vx;
+ vel.y = vy;
width = w;
height = h;
- velx = vx;
- vely = vy;
color = c;
duration = d;
fountain = false;
gravity = true;
behind = false;
+ bounce = false;
index = Texture::getIndex(c);
}
~Particles(){
-
}
void draw(){
- //glEnable(GL_TEXTURE_2D);
glColor3ub(255,255,255);
glBegin(GL_QUADS);
glTexCoord2f(.25*index.x, .125*index.y); glVertex2i(loc.x, loc.y);
glTexCoord2f(.25*index.x, .125*index.y); glVertex2i(loc.x + width, loc.y + height);
glTexCoord2f(.25*index.x, .125*index.y); glVertex2i(loc.x, loc.y + width);
glEnd();
- //glDisable(GL_TEXTURE_2D);
- //glUseProgram(0);
+ }
+ void update( float _gravity, float ground_y ) {
+ // handle ground collision
+ if ( loc.y < ground_y ) {
+ loc.y = ground_y;
+ if ( bounce ) {
+ vel.y *= -0.2f;
+ vel.x /= 4;
+ } else {
+ vel.x = vel.y = 0;
+ canMove = false;
+ }
+ } else if ( gravity && vel.y > -1 )
+ vel.y -= _gravity * deltaTime;
}
bool kill(float delta){
- duration -= delta;
- if(duration <= 0.0f){
- return true;
- }
- else return false;
+ return (duration -= delta) <= 0;
}
};
float speed; // A speed factor for X movement
+ unsigned int hitCooldown;
+
/*
* Movement flags
*/
virtual void wander(int);
};
-class Merchant : public NPC{
+class Merchant : public NPC {
public:
std::vector<Trade>trade;
uint currTrade;
void merchantBox();
void closeBox();
void waitForDialog(void);
- bool pageExists( void );
+ bool pageExists( void );
void drawPage( std::string path );
+
+ void dontTypeOut( void );
/*
* Draws a larger string in the center of the screen. Drawing is done inside this function.
*/
#define PLAYER_SPEED_CONSTANT 0.15f
+/**
+ * Gravity thing
+ */
+
+#define GRAVITY_CONSTANT 0.001f
+
/**
* Defines how many game ticks it takes for a day to elapse.
*/
#include <ui.hpp>
#include <entities.hpp>
-/**
- * Defines how many game ticks should occur in one second, affecting how often
- * game logic is handled.
- */
-
-#define TICKS_PER_SEC 20
-
-/**
- * Defines how many milliseconds each game tick will take.
- */
-
-#define MSEC_PER_TICK ( 1000 / TICKS_PER_SEC )
-
/**
* The window object returned by SDL when we create the main window.
*/
* textures for the entities and stuff.
*/
- if(!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) | !(IMG_Init(IMG_INIT_JPG) & IMG_INIT_JPG)){
+ if(!(IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG) & (IMG_INIT_PNG | IMG_INIT_JPG))){
std::cout << "Could not init image libraries! Error: " << IMG_GetError() << std::endl;
return -1;
}
GLint bufferln = GL_FALSE;
int logLength;
-
fragShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragShader, 1, &shaderSource, NULL);
glCompileShader(fragShader);
glGetShaderInfoLog(fragShader, logLength, NULL, &fragShaderError[0]);
std::cout << &fragShaderError[0] << std::endl;
- if(bufferln == GL_FALSE){
- std::cout << "Error compiling shader" << std::endl;
- }
+ if ( bufferln == GL_FALSE )
+ UserError("Error compiling shader");
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, fragShader);
fadeIntensity = 250;
- std::cout << "emem" << std::endl;
initEverything();
- std::cout << "meme" << std::endl;
if(!currentWorld){
std::cout<<"currentWorld == NULL!"<<std::endl;
ui::drawMenu(currentMenu);
}
- /*
- * Draw a white triangle as a replacement for the mouse's cursor.
- */
-
+ // draw the mouse cursor
glColor3ub(255,255,255);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mouseTex);
**** END RENDERING ****
**************************/
- /*
- * These next two function finish the rendering
- *
- * glPopMatrix This anchors all of the matrices and blends them to a single
- * matrix so the renderer can draw this to the screen, since screens
- * are only 2 dimensions, we have to combine the matrixes to be 2d.
- *
- * SDL_GL_SwapWindow Since SDL has control over our renderer, we need to now give our
- * new matrix to SDL so it can pass it to the window.
- */
-
glPopMatrix();
SDL_GL_SwapWindow(window);
}
e->health -= 25;
e->hit = true;
e->forcedMove = true;
+ e->hitCooldown = 10;
e->vel.x = 0.5f * (player->left ? -1 : 1);
e->vel.y = 0.2f;
break;
switch(m->subtype){
case MS_RABBIT:
case MS_BIRD:
- m->wander((rand()%240 + 15)); // Make the mob wander :)
+ m->wander((rand()%240 + 15)); // Make the mob wander
break;
case MS_TRIGGER:
case MS_PAGE:
{ 0, 0, 255 }, // RGB color
2500 // duration (ms)
);
+ currentWorld->particles.back().bounce = true;
}
} else if ( weather == WorldWeather::Snowy ) {
for ( unsigned int r = (randGet() % 25) + 11; r--; ) {
+++ /dev/null
-#version 120\r
-\r
-uniform vec2 lightLocation;\r
-uniform vec3 lightColor;\r
-uniform float lightStrength;\r
-uniform float screenHeight;\r
-\r
-void main(){\r
- float distance = length(lightLocation - gl_FragCoord.xy);\r
- float attenuation = lightStrength / distance;\r
- vec4 color = vec4(attenuation, attenuation, attenuation, (pow(attenuation, 3)) * vec4(lightColor, 2))+.5;\r
- \r
- gl_FragColor = color;\r
-}\r
switch(bufs[0]){
default :
- case 'm': e->gender = MALE; break;
- case 'f': e->gender = FEMALE;break;
+ case 'm':
+ e->gender = MALE;
+ break;
+ case 'f':
+ e->gender = FEMALE;
+ break;
}
- strcpy(e->name,bufs+1);
+ strcpy( e->name, bufs + 1 );
delete[] bufs;
}
+Trade::Trade(int qo, std::string o, int qt, std::string t){
+ item[0] = o;
+ item[1] = t;
+
+ quantity[0] = qo;
+ quantity[1] = qt;
+
+ std::cout << "Trading: " << quantity[0] << " " << item[0] << " for " << quantity[1] << " " << item[1] << std::endl;
+}
+
void Entity::spawn(float x, float y){ //spawns the entity you pass to it based off of coords and global entity settings
loc.x = x;
loc.y = y;
forcedMove = false;
ticksToUse = 0;
+ hitCooldown = 0;
if(!maxHealth)health = maxHealth = 1;
tex->bind(0);
break;
}
- glColor3ub(255,255,255);
+
+ if ( hitCooldown )
+ glColor3ub(255,255,0);
+ else
+ glColor3ub(255,255,255);
+
glUseProgram(shaderProgram);
glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
glBegin(GL_QUADS);
if ( forcedMove )
return;
+ if ( hitCooldown )
+ hitCooldown--;
+
if ( followee ) {
if ( loc.x < followee->loc.x - 40 )
direction = 1;
if( vel.x < 0)
currentWorld->goWorldLeft( this );
- if(inside != nullptr){
- if(loc.x <= inside->loc.x)loc.x = inside->loc.x;
- if(loc.x + width >= inside->loc.x + inside->width)loc.x = inside->loc.x + inside->width - width;
+ if ( inside != nullptr ) {
+ loc.y = inside->loc.y + HLINE * 2;
+ vel.y = GRAVITY_CONSTANT * 5;
+ if ( loc.x <= inside->loc.x + HLINE * 5 )
+ loc.x = inside->loc.x + HLINE * 5;
+ else if ( loc.x + width >= inside->loc.x + inside->width - HLINE * 5 )
+ loc.x = inside->loc.x + inside->width - width - HLINE * 5;
}
ticksToUse--;
}
std::thread([this]{
ui::merchantBox(name, trade[currTrade], ":Accept:Good-Bye", false, "Welcome to Smithy\'s. Buy your sausages here you freaking meme lording screw-face");
ui::waitForDialog();
- if(ui::dialogOptChosen == 1){
- if(!(player->inv->takeItem(trade[currTrade].item[1],trade[currTrade].quantity[1])))
+
+ // handle normal dialog options
+ switch ( ui::dialogOptChosen ) {
+ // Accept
+ case 1:
+ if ( !(player->inv->takeItem( trade[currTrade].item[1], trade[currTrade].quantity[1])) )
player->inv->addItem(trade[currTrade].item[0],trade[currTrade].quantity[0]);
- }else if(ui::dialogOptChosen == 2){
- }else if(ui::merchOptChosen == 1){
- if(currTrade != 0){
+ break;
+
+ // Good-bye
+ case 2:
+ break;
+
+ default:
+ break;
+ }
+
+ // handle merchant-specific dialog options
+ switch ( ui::merchOptChosen ) {
+ // left arrow
+ case 1:
+ if ( currTrade )
currTrade--;
- interact();
- }
- }else if(ui::merchOptChosen == 2){
- if(currTrade < trade.size()){
+ ui::dontTypeOut();
+ interact(); // TODO should we nest like this?
+ break;
+
+ // right arrow
+ case 2:
+ if ( currTrade < trade.size() - 1 )
currTrade++;
- interact();
- }
+ ui::dontTypeOut();
+ interact();
+ break;
+
+ default:
+ break;
}
}).detach();
}
//hey(this);
break;
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)){
- std::thread([this]{hey(this);}).detach();
- /*if(speed != 666){
- speed = 666;
- hey(this);
- speed = 0;
- }*/
- }
+ if(player->loc.x > loc.x - 100 && player->loc.x < loc.x + 100 && // within player ranger
+ ui::mouse.x > loc.x && ui::mouse.x < loc.x + width && // mouse x
+ ui::mouse.y > loc.y - width / 2 && ui::mouse.y < loc.y + width * 1.5 && // mouse y
+ SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)) // right click
+ hey(this);
break;
default:
break;
}
void commonPageFunc( Mob *callee ){
- //static bool lock = false;
-
- /*if ( !lock ) {
- lock = true;*/
- if ( !ui::dialogBoxExists ) {
- std::cout<<"begin\n";
- ui::drawPage( callee->heyid );
- while( ui::pageExists() );
- std::cout<<"done\n";
- //ui::waitForDialog();
-
- callee->health = 0;
- //lock = false;
- }
+ ui::drawPage( callee->heyid );
+ ui::waitForDialog();
+ callee->health = 0;
}
void commonTriggerFunc(Mob *callee){
static std::vector<std::pair<std::string,vec3>> dialogOptText;
static std::string dialogBoxText;
-static vec3 merchArrowLoc[2];
+static std::vector<vec3> merchArrowLoc ( 2, vec3 { 0, 0, 0 } );
static bool typeOutDone = true;
+static bool typeOutSustain = false;
/*
* Menu-related objects
Mix_Chunk *sanic;
static GLuint pageTex = 0;
+static bool pageTexReady = false;
void Menu::gotoParent(){
if(parent == NULL){
}
ftex = &ftex16;
ftdat = &ftdat16;
- } else if ( size == 24 ){
+ fontSize = 16;
+ } else if ( size == 24 ) {
if ( !ft24loaded ) {
loadFontSize( fontSize = size, ftex24, ftdat24 );
ft24loaded = true;
}
ftex = &ftex24;
ftdat = &ftdat24;
+ fontSize = 24;
}
}
return width;
}
+ /**
+ * Prevents typeOut from typing the next string it's given.
+ */
+
+ void dontTypeOut( void ) {
+ typeOutSustain = true;
+ }
+
/*
* 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.
std::string ret;
std::string typeOut( std::string str ) {
- static unsigned int sinc, // Acts as a delayer for the space between each character.
+ static unsigned int tadv = TICKS_PER_SEC / 12;
+ static unsigned int tickk,
linc=0, // Contains the number of letters that should be drawn.
size=0; // Contains the full size of the current string.
- /*
- * Reset values if a new string is being passed.
- */
-
- if(strncmp(ret.c_str(),str.c_str(),linc-1)){
- ret.clear(); // Zero the buffer
- size=str.size(); // Set the new target string size
- linc=0; // Reset the incrementers
- sinc=1;
- typeOutDone = false;
+ // reset values if a new string is being passed.
+ if ( !linc || ret.substr( 0, linc ) != str.substr( 0, linc ) ) {
+ tickk = tickCount + tadv;
+ ret = str.substr( 0, 1 );
+ size = str.size(); // Set the new target string size
+ linc = 1; // Reset the incrementers
+ if ( (typeOutDone = typeOutSustain) )
+ typeOutSustain = false;
}
- /*
- * Draw the next letter if necessary.
- */
-
- if(typeOutDone)
+ if ( typeOutDone )
return str;
- else if(++sinc==2){
- sinc=0;
- ret.append(str, linc, 1);
+ // Draw the next letter if necessary.
+ else if ( tickk <= tickCount ) {
+ tickk = tickCount + tadv;
+ ret += str[linc];
- if(linc<size)
+ if ( linc < size )
linc++;
else
typeOutDone = true;
ret.clear();
}
-
void merchantBox(const char *name,Trade trade,const char *opt,bool passive,const char *text,...){
va_list dialogArgs;
std::unique_ptr<char[]> printfbuf (new char[512]);
dialogPassive = passive;
-
- std::cout << "Market Trading: " << trade.quantity[0] << " " << trade.item[0] << " for " << trade.quantity[1] << " " << trade.item[1] << std::endl;
-
merchTrade = trade;
// clear the buffer
* Wait for a dialog box to be dismissed.
*/
- void waitForDialog(void){
- do{
- //std::thread(dialogAdvance);
- //mainLoop();
- }while(dialogBoxExists);
+ void waitForDialog ( void ) {
+ while ( dialogBoxExists );
}
- void waitForCover(void){
- do{
+
+ void waitForCover ( void ) {
+ while ( fadeIntensity < 255 )
mainLoop();
- }while(fadeIntensity < 255);
fadeIntensity = 255;
}
- void waitForNothing(unsigned int ms){
+
+ void waitForNothing ( unsigned int ms ) {
unsigned int target = millis() + ms;
- do{
- mainLoop();
- }while(millis() < target);
+ while ( millis() < target );
}
+
void importantText(const char *text,...){
va_list textArgs;
char *printfbuf;
void drawPage( std::string path ) {
pageTex = Texture::loadTexture( path );
- std::cout<<"page set\n";
- }
-
- bool pageExists( void ) {
- return pageTex;
+ pageTexReady = true;
}
void draw(void){
float x,y,tmp;
std::string rtext;
- if ( pageTex ) {
-
- std::cout<<"page draw\n";
-
- glEnable( GL_TEXTURE_2D);
+ if ( pageTexReady ) {
+ glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, pageTex );
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 ); glVertex2i( offset.x - 300, SCREEN_HEIGHT - 100 );
glTexCoord2i( 1, 1 ); glVertex2i( offset.x + 300, SCREEN_HEIGHT - 600 );
glTexCoord2i( 0, 1 ); glVertex2i( offset.x - 300, SCREEN_HEIGHT - 600 );
glEnd();
- glDisable( GL_TEXTURE_2D);
+ glDisable( GL_TEXTURE_2D );
- } else if (dialogBoxExists){
+ } else if (dialogBoxExists) {
rtext=typeOut(dialogBoxText);
putStringCentered(offset.x,offset.y,rtext.c_str());
setFontSize(16);
}
- }else if(dialogMerchant){
+ }else if ( dialogMerchant ) {
x=offset.x-SCREEN_WIDTH/6;
y=(offset.y+SCREEN_HEIGHT/2)-HLINE*8;
+ // draw the box border
glColor3ub(255,255,255);
glBegin(GL_LINE_STRIP);
glVertex2f(x-1 ,y+1);
glVertex2f(x - 1,y+1);
glEnd();
+ // draw the box
glColor3ub(0,0,0);
glRectf(x,y,x+SCREEN_WIDTH/3,y-SCREEN_HEIGHT*.6);
setFontColor(255, 255, 255);
// draw option
+ dialogOptText[i].second.y = y - SCREEN_HEIGHT / 2 - (fontSize + HLINE) * (i + 1);
tmp = putStringCentered(offset.x, dialogOptText[i].second.y, dialogOptText[i].first);
// get coordinate information on option
dialogOptText[i].second.z = offset.x + tmp;
dialogOptText[i].second.x = offset.x - tmp;
- dialogOptText[i].second.y = y - SCREEN_HEIGHT / 2 - (fontSize + HLINE) * (i + 1);
// make text yellow if the mouse hovers over the text
if(mouse.x > dialogOptText[i].second.x && mouse.x < dialogOptText[i].second.z &&
glColor3ub(0,0,0);
glRectf(x,y,x+SCREEN_WIDTH-HLINE*16,y-SCREEN_HEIGHT/4);
- rtext=typeOut(dialogBoxText);
+ rtext = typeOut(dialogBoxText);
putString(x+HLINE,y-fontSize-HLINE,rtext);
setFontColor(255,255,255);
}
- if ( rtext != dialogBoxText )
- Mix_PlayChannel(1,dialogClick,0);
+ static unsigned int rtext_oldsize = 0;
+ if ( rtext_oldsize != rtext.size() ) {
+ if ( !isspace( rtext[(rtext_oldsize = rtext.size()) - 1] ) )
+ Mix_PlayChannel( 1, dialogClick, 0 );
+ }
}if(!fadeIntensity){
vec2 hub = {
unsigned char i;
if ( pageTex ) {
- std::cout<<"rip page\n";
glDeleteTextures( 1, &pageTex );
pageTex = 0;
+ pageTexReady = false;
return;
}
- if(!typeOutDone){
+ /*if(!typeOutDone){
typeOutDone = true;
return;
- }
+ }*/
for(i=0;i<dialogOptText.size();i++){
if(mouse.x > dialogOptText[i].second.x &&
goto EXIT;
}
}
- if(dialogMerchant){
- for(i=0;i<2;i++){
+
+ if ( dialogMerchant ) {
+ for ( i = 0; i < merchArrowLoc.size(); i++ ) {
+
+ // TODO neaten this if statement
+
if(((merchArrowLoc[i].x < merchArrowLoc[i].z) ?
- (mouse.x > merchArrowLoc[i].x && mouse.x < merchArrowLoc[i].z) :
+ (mouse.x > merchArrowLoc[i].x && mouse.x < merchArrowLoc[i].z) :
(mouse.x < merchArrowLoc[i].x && mouse.x > merchArrowLoc[i].z) &&
mouse.y > merchArrowLoc[i].y - 8 && mouse.y < merchArrowLoc[i].y + 8)){
merchOptChosen = i + 1;
break;
case SDL_MOUSEBUTTONUP:
-
- // right click advances dialog
- if ( ( e.button.button & SDL_BUTTON_RIGHT ) && (dialogBoxExists | pageTex) )
- dialogAdvance();
-
if ( ig ) {
ig->vel.x = (fr.x - mouse.x) / 50.0f;
ig->vel.y = (fr.y - mouse.y) / 50.0f;
// mouse clicks
case SDL_MOUSEBUTTONDOWN:
+ // right click advances dialog
+ if ( ( e.button.button & SDL_BUTTON_RIGHT ) && (dialogBoxExists | pageTexReady) )
+ dialogAdvance();
+
// left click uses item
if ( ( e.button.button & SDL_BUTTON_LEFT ) && !dialogBoxExists )
player->inv->usingi = true;
currentWorld = ((Arena *)currentWorld)->exitArena( player );
if ( tmp != currentWorld )
toggleBlackFast();
- } else if( (tmp = currentWorld->goInsideStructure( player )) != currentWorld )
- currentWorld = tmp;
+ } else if ( (tmp = currentWorld->goInsideStructure( player )) != currentWorld )
+ currentWorld = tmp;
break;
case SDLK_LSHIFT:
if(debug){
debug ^= true;
break;
case SDLK_z:
- weather = WorldWeather::Snowy;
+ weather = WorldWeather::Rain;
break;
case SDLK_i:
if ( isCurrentWorldIndoors() && Indoorp(currentWorld)->isFloorAbove( player ) ) {
static GLubyte* pixels;
pixels = new GLubyte[ 3 * SCREEN_WIDTH * SCREEN_HEIGHT];
glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
- //static std::thread scr;
- //scr = std::thread(takeScreenshot,pixels);
- //scr.detach();
takeScreenshot(pixels);
std::cout << "Took screenshot" << std::endl;
}
}
- // Flush preloaded AI functions if necessary
+ // Flush preloaded AI functions if necessary
if ( !dialogBoxExists && AIpreaddr.size() ) {
while ( !AIpreaddr.empty() ) {
AIpreaddr.front()->addAIFunc( AIpreload.front(), false );
#define INDOOR_FLOOR_THICKNESS 50
#define INDOOR_FLOOR_HEIGHTT 400
-/**
- * Gravity thing
- */
-
-#define GRAVITY_CONSTANT 0.001f
-
extern Player *player; // main.cpp?
extern World *currentWorld; // main.cpp
extern World *currentWorldToLeft; // main.cpp
particles.erase( std::remove_if( particles.begin(), particles.end(), [&delta](Particles &part){return part.kill(delta);}), particles.end());
for ( auto part = particles.begin(); part != particles.end(); part++ ) {
if ( (*part).canMove ) {
- (*part).loc.y += (*part).vely * delta;
- (*part).loc.x += (*part).velx * delta;
+ (*part).loc.y += (*part).vel.y * delta;
+ (*part).loc.x += (*part).vel.x * delta;
for ( auto &b : build ) {
if ( b->bsubtype == FOUNTAIN ) {
// the sunny wallpaper is faded with the night depending on tickCount
bgTex->bind( 0 );
- safeSetColorA( 255, 255, 255, weather == WorldWeather::Snowy ? 150 : 255 - worldShade * 4);
+ int alpha;
+ switch( weather ) {
+ case WorldWeather::Snowy:
+ alpha = 150;
+ break;
+ case WorldWeather::Rain:
+ alpha = 0;
+ break;
+ default:
+ alpha = 255 - worldShade * 4;
+ break;
+ }
+ safeSetColorA( 255, 255, 255, alpha );
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 ); glVertex2i( offset.x - SCREEN_WIDTH/2-5, offset.y + SCREEN_HEIGHT/2 );
glEnd();
bgTex->bindNext();
- safeSetColorA( 255, 255, 255, worldShade * 4);
+ safeSetColorA( 255, 255, 255, !alpha ? 255 : worldShade * 4);
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 ); glVertex2i( offset.x - SCREEN_WIDTH/2-5, offset.y + SCREEN_HEIGHT/2 );
glUseProgram(0);
- for ( auto &b : build )
- b->draw();
+ for ( auto &b : build ) {
+ if ( b->bsubtype == STALL_MARKET ) {
+ for ( auto &n : npc ) {
+ if ( n->type == MERCHT && ((Merchant *)n)->inside == b ) {
+ n->draw();
+ break;
+ }
+ }
+ }
+ b->draw();
+ }
// draw light elements?
}
}
- for(uint i = 0; i < light.size(); i++){
+ for ( uint i = 0; i < light.size(); i++ )
flameArray[i] = light[i].fireFlicker;
- }
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glUseProgram(0);
- for ( auto &n : npc )
- n->draw();
+ for ( auto &n : npc ) {
+ if ( n->type != MERCHT )
+ n->draw();
+ }
for ( auto &m : mob )
m->draw();
// if the entity is under the world/line, pop it back to the surface
if ( e->loc.y < worldData[i].groundHeight ) {
int dir = e->vel.x < 0 ? -1 : 1;
- if ( worldData[i + (dir * 8)].groundHeight - 30 > worldData[i + dir].groundHeight ) {
+ if ( i + (dir * 2) < worldData.size() && worldData[i + (dir * 2)].groundHeight - 30 > worldData[i + dir].groundHeight ) {
e->loc.x -= ( PLAYER_SPEED_CONSTANT + 2.7 ) * e->speed * 2 * dir;
e->vel.x = 0;
} else {
int l;
// handle the player
- std::thread( &World::singleDetect, this, p).detach();
+ std::thread( &World::singleDetect, this, p ).detach();
// handle other entities
for ( auto &e : entity )
- std::thread(&World::singleDetect,this,e).detach();
+ std::thread( &World::singleDetect, this, e ).detach();
// handle particles
for ( auto &part : particles ) {
if ( l > (int)(lineCount - 1) )
l = lineCount - 1;
- // handle ground collision
- if ( part.loc.y < worldData[l].groundHeight ) {
- part.loc.y = worldData[l].groundHeight;
- part.vely = 0;
- part.velx = 0;
- part.canMove = false;
- } else if ( part.gravity && part.vely > -2 )
- part.vely -= GRAVITY_CONSTANT * deltaTime;
+ part.update( GRAVITY_CONSTANT, worldData[l].groundHeight );
}
// handle particle creation
World *Arena::exitArena(Player *p){
World *tmp;
- if(p->loc.x + p->width / 2 > mob[0]->loc.x &&
- p->loc.x + p->width / 2 < mob[0]->loc.x + HLINE * 12 ){
+ if ( !mmob->alive &&
+ p->loc.x + p->width / 2 > mob[0]->loc.x &&
+ p->loc.x + p->width / 2 < mob[0]->loc.x + HLINE * 12 ) {
tmp = battleNest.front();
battleNest.erase(battleNest.begin());
}
}
+ // tells what world is outside, if in a structure
+ else if ( Indoor && (ptr = wxml->Attribute("outside")) )
+ inside.push_back( ptr );
+
// error, invalid link tag
else
UserError("XML Error: Invalid <link> tag in " + currentXML + "!");
// indoor spawning floor selection
if ( Indoor && wxml->QueryUnsignedAttribute( "floor", &flooor ) == XML_NO_ERROR )
Indoorp(tmp)->moveToFloor( tmp->npc.back(), flooor );
+
+ // custom health value
+ if ( wxml->QueryFloatAttribute( "health", &spawnx) == XML_NO_ERROR )
+ tmp->mob.back()->health = tmp->mob.back()->maxHealth = spawnx;
}
// npc creation
// spawn at coordinates if desired
if ( wxml->QueryFloatAttribute( "x", &spawnx ) == XML_NO_ERROR)
- tmp->addNPC( spawnx, wxml->FloatAttribute("y") );
+ tmp->addNPC( spawnx, 100 );
else
tmp->addNPC( 0, 100 );
if ( Indoor && wxml->QueryUnsignedAttribute( "floor", &flooor ) == XML_NO_ERROR )
Indoorp(tmp)->moveToFloor( tmp->npc.back(), flooor );
+
+ // custom health value
+ if ( wxml->QueryFloatAttribute( "health", &spawnx) == XML_NO_ERROR )
+ tmp->mob.back()->health = tmp->mob.back()->maxHealth = spawnx;
}
// structure creation
wxml->StrAttribute("inside")
);
} else if ( name == "trigger" ) {
- tmp->addMob(MS_TRIGGER,wxml->FloatAttribute("x"),0,commonTriggerFunc);
+ tmp->addMob( MS_TRIGGER, wxml->FloatAttribute("x"), 0, commonTriggerFunc );
tmp->mob.back()->heyid = wxml->Attribute("id");
} else if ( name == "page" ) {
tmp->addMob( MS_PAGE, wxml->FloatAttribute("x"), 0, commonPageFunc );
Indoorp(tmp)->addFloor( wxml->UnsignedAttribute("width") );
}
+ spawnx = 0;
wxml = wxml->NextSiblingElement();
}
100,
vil->StrAttribute("texture"),
vil->StrAttribute("inside"));
- }else if ( name == "stall" ) {
- if(!strcmp(vil->Attribute("type"),"market")){
- tmp->addStructure((BUILD_SUB)70,
- vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
- randx : spawnx,
- 100,
- vil->StrAttribute("texture"),
- vil->StrAttribute("inside"));
- tmp->addMerchant(0,100);
+ } else if ( name == "stall" ) {
+ sptr = vil->StrAttribute("type");
+
+ // handle markets
+ if ( sptr == "market" ) {
+
+ // create a structure and a merchant, and pair them
+ tmp->addStructure( STALL_MARKET,
+ vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx,
+ 100,
+ vil->StrAttribute("texture"),
+ vil->StrAttribute("inside")
+ );
+ tmp->addMerchant( 0, 100 );
+
tmp->merchant.back()->inside = tmp->build.back();
- if(vil->FirstChildElement("buy")){
- }else if(vil->FirstChildElement("sell")){
- }else if(vil->FirstChildElement("trade")){
- tmp->merchant.back()->trade.push_back(Trade(vil->FirstChildElement("trade")->IntAttribute("quantity"),
- vil->FirstChildElement("trade")->Attribute("item"),
- vil->FirstChildElement("trade")->IntAttribute("quantity1"),
- vil->FirstChildElement("trade")->Attribute("item1")));
- tmp->merchant.back()->trade.push_back(Trade(1,"Wood Sword", 420, "Dank MayMay"));
+ }
+
+ // handle traders
+ else if ( sptr == "trader") {
+ tmp->addStructure( STALL_TRADER,
+ vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx,
+ 100,
+ vil->StrAttribute("texture"),
+ vil->StrAttribute("inside")
+ );
+ }
+
+ // loop through buy/sell/trade tags
+ XMLElement *sxml = vil->FirstChildElement();
+ std::string tag;
+ while ( sxml ) {
+ tag = sxml->Name();
+
+ if ( tag == "buy" ) {
+ // TODO
+ } else if ( tag == "sell" ) {
+ // TODO
+ } else if ( tag == "trade" ) {
+ tmp->merchant.back()->trade.push_back( Trade( sxml->IntAttribute("quantity"),
+ sxml->StrAttribute("item"),
+ sxml->IntAttribute("quantity1"),
+ sxml->StrAttribute("item1")
+ ));
}
- strcpy(tmp->merchant.back()->name,"meme");
- }else if(!strcmp(vil->Attribute("type"),"trader")){
- tmp->addStructure((BUILD_SUB)71,
- vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
- randx : spawnx,
- 100,
- vil->StrAttribute("texture"),
- vil->StrAttribute("inside"));
+ sxml = sxml->NextSiblingElement();
}
}
+++ /dev/null
--300
-72
-dOnE
\ No newline at end of file
+++ /dev/null
-#version 120\r
-uniform sampler2D sampler;\r
-\r
-uniform int numLight;\r
-uniform vec2 lightLocation[64];\r
-uniform vec3 lightColor;\r
-uniform float amb;\r
-\r
-float b = .0005;\r
-float minLight = .05;\r
-float radius = sqrt(1.0 / (b * minLight));\r
-\r
-//float radius = b*minlight;\r
-\r
-void main(){\r
- vec4 color = vec4(0.0,0.0,0.0,0.0);\r
- for(int i = 0; i < numLight; i++){\r
- vec2 loc = lightLocation[i];\r
- float dist = length(loc - gl_FragCoord.xy);\r
- //float attenuation=1.0/(1.0+0.01*dist+0.00000000001*dist*dist);\r
- float attenuation = clamp(1.0 - dist*dist/(radius*radius), 0.0, 1.0); attenuation *= attenuation;\r
-\r
- color += vec4(attenuation, attenuation, attenuation, 1.0) * vec4(lightColor, 1.0);\r
- }\r
- vec2 coords = gl_TexCoord[0].st;\r
- vec4 tex = texture2D(sampler, coords);\r
-\r
- color += vec4(amb,amb,amb,1.0+amb);\r
- gl_FragColor = tex * vec4(color)*tex.a;\r
-}\r
-\r
-/* b values\r
- .002 10\r
- .008 50\r
- .0005 200\r
- .00008 500\r
- .00002 1000\r
- .00005 2000\r
-*/
\ No newline at end of file
<hill peakx="0" peaky="1000" width="50" />
- <mob x="300" type="1" aggressive="false" />
+ <mob x="300" type="1" aggressive="false" health="1000" />
<!--<trigger x="-300" id="Test" />-->
- <npc name="Ralph" hasDialog="true" />
- <npc name="Johnny" hasDialog="false" />
- <npc name="Big Dave" hasDialog="true"/>
+ <npc name="Ralph" hasDialog="true" x="300" />
+ <npc name="Johnny" hasDialog="false" x="300" />
+ <npc name="Big Dave" hasDialog="true" x="300" />
- <page x="-200" id="assets/pages/gootaGoFast.png" />
+ <page x="-200" id="assets/door.png" />
<village name="Swaggggggggggggg">
<structure type="0" x="-300" inside="playerSpawnHill1_Building1.xml"/>