- NPCs and mobs can gracefully walk between worlds, carry dialog
- began more work on combat stuffs
+
+5/16/2016:
+==========
+
+ - added jump page
+ - created quest lightbulb texture
+ - fixed overlay
+
+5/17/2016:
+==========
+
+ - added onHit and onDeath routines to mobs
+ - added mob drops on arena kills
+ - continued work on new renderings
2
-canSprint
-0
canJump
0
+canSprint
+1
#ifndef MOB_H_
#define MOB_H_
+#include <forward_list>
+#include <tuple>
+
#include <common.hpp>
#include <entities.hpp>
#include <gametime.hpp>
extern Player *player;
extern std::string currentXML;
+using Drop = std::tuple<std::string, unsigned int, float>;
+
class Mob : public Entity {
protected:
+ std::forward_list<Drop> drop;
+
unsigned int actCounter;
unsigned int actCounterInitial;
bool ridable;
void wander(void);
void ride(Entity *e);
virtual void act(void) =0;
+
+ virtual void onHit(unsigned int) =0;
+ virtual void onDeath(void);
+
virtual bool bindTex(void) =0;
virtual void createFromXML(const XMLElement *e) =0;
};
Page(void);
void act(void);
+ void onHit(unsigned int);
bool bindTex(void);
void createFromXML(const XMLElement *e);
};
Door(void);
void act(void);
+ void onHit(unsigned int);
bool bindTex(void);
void createFromXML(const XMLElement *e);
};
Cat(void);
void act(void);
+ void onHit(unsigned int);
bool bindTex(void);
void createFromXML(const XMLElement *e);
};
Rabbit(void);
void act(void);
+ void onHit(unsigned int);
bool bindTex(void);
void createFromXML(const XMLElement *e);
};
Bird(void);
void act(void);
+ void onHit(unsigned int);
bool bindTex(void);
void createFromXML(const XMLElement *e);
};
Trigger(void);
void act(void);
+ void onHit(unsigned int);
bool bindTex(void);
void createFromXML(const XMLElement *e);
};
float putText(const float x,const float y,const char *str,...);
+ /**
+ * This function is a facility for logic events to draw text; the text
+ * will be prepared then drawn in the render loop.
+ */
+ void putTextL(vec2 c,const char *str, ...);
+
/*
* Creates a dialogBox text string (format: `name`: `text`). This function simply sets up
* variables that are drawn in ui::draw(). When the dialog box exists player control is
// generate a name
name = new char[32];
if (type == MOBT)
- name[0] = '\0';
+ strncpy(name, "mob", 3);
else
randGetomName(this);
void Entity::takeHit(unsigned int _health, unsigned int cooldown)
{
if (hitCooldown <= 1) {
- std::cout << "Taking hit " << std::endl;
// modify variables
health = fmax(health - _health, 0);
forcedMove = true;
if (hitbox.end.x > e->loc.x && hitbox.end.x < e->loc.x + e->width) {
if (hitbox.end.y > e->loc.y && hitbox.end.y < e->loc.y + e->height) {
- e->takeHit(damage, 600);
+ if (e->type == MOBT)
+ Mobp(e)->onHit(damage);
+ else
+ e->takeHit(damage, 600);
- static GLuint sColor = Texture::genColor(Color(255,0,0));
-
- GLfloat t[] = {0.0, 0.0,
- 1.0, 1.0};
-
- GLfloat v[] = {hitbox.start.x, hitbox.start.y, 1.0,
- hitbox.end.x, hitbox.end.y, 1.0};
+ static GLuint sColor = Texture::genColor(Color(255,0,0));
+ GLfloat t[] = {0.0, 0.0,
+ 1.0, 1.0};
+ GLfloat v[] = {hitbox.start.x, hitbox.start.y, 1.0,
+ hitbox.end.x, hitbox.end.y, 1.0};
- glBindTexture(GL_TEXTURE_2D, sColor);
- glUseProgram(worldShader);
- glEnableVertexAttribArray(worldShader_attribute_coord);
- glEnableVertexAttribArray(worldShader_attribute_tex);
+ glBindTexture(GL_TEXTURE_2D, sColor);
+ glUseProgram(worldShader);
+ glEnableVertexAttribArray(worldShader_attribute_coord);
+ glEnableVertexAttribArray(worldShader_attribute_tex);
- glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, v);
- glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, t);
- glDrawArrays(GL_LINES, 0, 2);
+ glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, v);
+ glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, t);
+ glDrawArrays(GL_LINES, 0, 2);
- glDisableVertexAttribArray(worldShader_attribute_coord);
- glDisableVertexAttribArray(worldShader_attribute_tex);
- glUseProgram(0);
+ glDisableVertexAttribArray(worldShader_attribute_coord);
+ glDisableVertexAttribArray(worldShader_attribute_tex);
+ glUseProgram(0);
// add some blood
// for(int r = 0; r < (rand()%5);r++)
// currentWorld->addParticle(rand()%game::HLINE*3 + e->loc.x - .05f,e->loc.y + e->height*.5, game::HLINE,game::HLINE, -(rand()%10)*.01,((rand()%4)*.001-.002), {(rand()%75+10)/100.0f,0,0}, 10000);
}
}
+void Page::onHit(unsigned int _health)
+{
+ (void)_health;
+ act();
+}
+
bool Page::bindTex(void)
{
glActiveTexture(GL_TEXTURE0);
{
}
+void Door::onHit(unsigned int _health)
+{
+ (void)_health;
+}
+
bool Door::bindTex(void)
{
glActiveTexture(GL_TEXTURE0);
}
}
+void Cat::onHit(unsigned int _health)
+{
+ health += _health;
+}
+
bool Cat::bindTex(void)
{
glActiveTexture(GL_TEXTURE0);
tex = TextureIterator({"assets/rabbit.png", "assets/rabbit1.png"});
actCounterInitial = randGet() % 240 + 15;
actCounter = 1;
+
+ drop = {
+ std::make_tuple("Dank MayMay", 5, 1.00f)
+ };
}
void Rabbit::act(void)
}
}
+void Rabbit::onHit(unsigned int _health)
+{
+ takeHit(_health, 600);
+}
+
bool Rabbit::bindTex(void)
{
glActiveTexture(GL_TEXTURE0);
vel.x = direction ? -0.3f : 0.3f;
}
+void Bird::onHit(unsigned int _health)
+{
+ takeHit(_health, 1000);
+}
+
bool Bird::bindTex(void)
{
glActiveTexture(GL_TEXTURE0);
}
}
+void Trigger::onHit(unsigned int _health)
+{
+ (void)_health;
+}
+
bool Trigger::bindTex(void)
{
return false;
else
rider = e;
}
+
+void Mob::onDeath(void)
+{
+ vec2 q = vec2 {player->loc.x, game::SCREEN_HEIGHT - 100.0f};
+
+ ui::putTextL(q, "Player got: ");
+
+ for (const auto &d : drop) {
+ if ((randGet() % 100) < std::get<float>(d) * 100.0f) {
+ q.y -= 20;
+ ui::putTextL(q, "%d x %s", std::get<unsigned int>(d), std::get<std::string>(d).c_str());
+ player->inv->addItem(std::get<std::string>(d), std::get<unsigned int>(d));
+ }
+ }
+}
* Variables for dialog boxes / options.
*/
+static std::vector<std::pair<vec2, std::string>> textToDraw;
+
static std::vector<std::pair<std::string,vec3>> dialogOptText;
static std::string dialogBoxText;
static std::vector<vec3> merchArrowLoc (2, vec3 { 0, 0, 0 });
return putString(x, y, buf.get());
}
+ void putTextL(vec2 c, const char *str, ...) {
+ va_list args;
+ std::unique_ptr<char[]> buf (new char[512]);
+ memset(buf.get(), 0, 512 * sizeof(char));
+
+ va_start(args, str);
+ vsnprintf(buf.get(), 512, str, args);
+ va_end(args);
+
+ textToDraw.push_back(std::make_pair(c, buf.get()));
+ }
+
void dialogBox(std::string name, std::string opt, bool passive, std::string text, ...) {
va_list dialogArgs;
std::unique_ptr<char[]> printfbuf (new char[512]);
Mix_PlayChannel(1, dialogClick, 0);
}
+ } else {
+ for (const auto &s : textToDraw)
+ putString(s.first.x, s.first.y, s.second);
}
+
if (!fadeIntensity) {
vec2 hub = {
(SCREEN_WIDTH/2+offset.x)-fontSize*10,
if ((action::make = e.button.button & SDL_BUTTON_RIGHT))
/*player->inv->invHover =*/ edown = false;
- if (dialogBoxExists || pageTexReady) {
+ textToDraw.clear();
+
+ if (dialogBoxExists || pageTexReady) {
// right click advances dialog
if ((e.button.button & SDL_BUTTON_RIGHT))
dialogAdvance();
glUseProgram(textShader);
glBindTexture(GL_TEXTURE_2D, backTex);
- drawRect(vec2(offset.x - SCREEN_WIDTH / 2, offset.y - (SCREEN_HEIGHT / 2)), vec2(offset.x + SCREEN_WIDTH / 2, offset.y + (SCREEN_HEIGHT / 2)));
+ drawRect(vec2(offset.x - SCREEN_WIDTH / 2 - 1, offset.y - (SCREEN_HEIGHT / 2)),
+ vec2(offset.x + SCREEN_WIDTH / 2, offset.y + (SCREEN_HEIGHT / 2)));
glUseProgram(0);
} else if (e->health <= 0) {
// die
e->die();
+ if (inBattle && e->type == MOBT)
+ Mobp(e)->onDeath();
// delete the entity
for (i = 0; i < entity.size(); i++) {