Skip to content

Commit

Permalink
Render damage in world and on HUD
Browse files Browse the repository at this point in the history
  • Loading branch information
theonlypwner committed Jun 9, 2019
1 parent d2d4ad2 commit 1a667cc
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 16 deletions.
4 changes: 3 additions & 1 deletion source/src/clientgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,12 +864,14 @@ void dodamage(int damage, playerent *pl, playerent *actor, int gun, int style, c
if (pl != actor || gun == GUN_GRENADE || gun == GUN_RPG || pl->o.dist(src) > 4)
{
// damage indicator
pl->damagestack.add(damageinfo(src, totalmillis, damage));
if (pl == focus) pl->damagelist_hud.add(damageinfo(src, totalmillis, damage));
// push
vec dir = pl->o;
dir.sub(src).normalize();
pl->hitpush(damage, dir, actor, gun);
}
// damage particles
pl->adddamage_world(totalmillis, damage, pl == focus || actor == focus);

// critical damage
if(style & FRAG_CRIT)
Expand Down
1 change: 1 addition & 0 deletions source/src/clients2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false)
const int cn = getint(p), health = getint(p);
playerent *d = getclient(cn);
if (!d) break;
d->adddamage_world(totalmillis, d->health - health, d == focus);
d->health = health;
d->lastregen = lastmillis;
if (!healer) break;
Expand Down
4 changes: 4 additions & 0 deletions source/src/entities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,11 @@ void pickupeffects(int n, playerent *d, int spawntime)
e.spawned = false;
e.spawntime = lastmillis + spawntime;
if(!d) return;

const int oldhealth = d->health;
d->pickup(e.type);
if (d->health != oldhealth) d->adddamage_world(totalmillis, oldhealth - d->health, d == focus);

const itemstat *is = d->itemstats(e.type);
if(is)
{
Expand Down
34 changes: 31 additions & 3 deletions source/src/entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,19 @@ struct damageinfo
damageinfo(vec src, int time, int damage) : o(src), millis(time), damage(damage) { }
};

struct damageparticleinfo
{
vec o;
int millis, damage;
float xoff, yoff;
char color;
bool ours;
damageparticleinfo(vec o, int time, int damage, bool ours) : o(o), millis(time), damage(abs(damage)),
xoff((rnd(100) - 50) / 50.f), yoff(-rnd(101) / 100.f),
color(damage > 0 ? '3' : damage < 0 ? '0' : '2'), ours(ours)
{ }
};

struct kd
{
int kills;
Expand Down Expand Up @@ -633,7 +646,8 @@ class playerent : public dynent, public playerstate
int eardamagemillis;
int respawnoffset;
vector<eventicon> icons;
vector<damageinfo> damagestack;
vector<damageinfo> damagelist_hud;
vector<damageparticleinfo> damagelist_world;
kd weapstats[NUMGUNS];
bool allowmove() { return state!=CS_DEAD || spectatemode==SM_FLY; }

Expand Down Expand Up @@ -699,13 +713,27 @@ class playerent : public dynent, public playerstate
icons.add(icon);
}

void adddamage_world(int millis, int damage, bool ours)
{
int damagemillis = millis;
if (!damagelist_world.empty())
{
damageparticleinfo &l = damagelist_world.last();
damagemillis = max(damagemillis, l.millis + 150);
}
vec od = o;
od.z += aboveeye;
damagelist_world.add(damageparticleinfo(od, damagemillis, damage, ours));
}

void removeai();

virtual ~playerent()
{
removeai();
icons.shrink(0);
//damagestack.setsize(0);
// damagelist_hud.setsize(0);
// damagelist_world.setsize(0);
extern void removebounceents(playerent *owner);
extern void removedynlights(physent *owner);
extern void zapplayerflags(playerent *owner);
Expand Down Expand Up @@ -757,7 +785,7 @@ class playerent : public dynent, public playerstate
eardamagemillis = 0;
eyeheight = maxeyeheight;
curskin = nextskin[team_base(team)];
damagestack.setsize(0);
damagelist_hud.setsize(0);
}

void spawnstate(int team, int gamemode, int mutators)
Expand Down
39 changes: 34 additions & 5 deletions source/src/rendergl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,10 @@ VARP(aboveheadiconfadetime, 1, 2000, 10000);

void renderaboveheadicon(playerent *p)
{
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);

static Texture **texs = geteventicons();
loopi(p->icons.length() + 1)
{
Expand Down Expand Up @@ -429,20 +433,45 @@ void renderaboveheadicon(playerent *p)
default: scalef = aspect = 1; break;
}
glPushMatrix();
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTranslatef(p->o.x, p->o.y, p->o.z + p->aboveeye);
glRotatef(camera1->yaw - 180, 0, 0, 1);
glColor4f(1.0f, 1.0f, 1.0f, (aboveheadiconfadetime - t) / float(aboveheadiconfadetime));
float s = aboveheadiconsize / 75.0f*scalef, offset = t * 2.f / aboveheadiconfadetime, anim = totalmillis / 100 % (h * 2);
if (anim >= h) anim = h * 2 - anim + 1;
anim /= h;
quad(tex->id, vec(s, 0, s * 2 / aspect + offset), vec(-s, 0, 0.0f + offset), 0.0f, anim, 1.0f, 1.f / h);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glPopMatrix();
}

loopv(p->damagelist_world)
{
const damageparticleinfo &d = p->damagelist_world[i];
const int t = totalmillis - d.millis;
if (t > aboveheadiconfadetime)
{
p->damagelist_world.remove(i--);
continue;
}

div_t dmg = div(d.damage, HEALTHSCALE);
defformatstring(damagetext)(dmg.rem ? "\f%c%d.%*d" : "\f%c%d", d.color, dmg.quot, HEALTHPRECISION, dmg.rem);
const int xoff = d.xoff - text_width(damagetext) / 2;
const float yoff = d.yoff + t * 8.f / aboveheadiconfadetime;
const float scalef = sqrt(camera1->o.dist(d.o)) * 0.005;

if (d.ours) glDisable(GL_DEPTH_TEST);
glPushMatrix();
glTranslatef(d.o.x, d.o.y, d.o.z + yoff);
glRotatef(camera1->yaw, 0, 0, 1);
glRotatef(camera1->pitch + 90, -1, 0, 0);
glScalef(scalef, scalef, 1);
draw_text(damagetext, xoff, 0, 255, 255, 255, 255 * min(aboveheadiconfadetime - t, aboveheadiconfadetime) / (float)aboveheadiconfadetime);
glPopMatrix();
if (d.ours) glEnable(GL_DEPTH_TEST);
}

glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}

void rendercursor(int x, int y, int w)
Expand Down
35 changes: 28 additions & 7 deletions source/src/renderhud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,17 +470,18 @@ void draweventicons()
{
static Texture **texs = geteventicons();

const int eventicontime = 3000;
loopv(focus->icons)
{
eventicon &icon = focus->icons[i];
if (icon.type < 0 || icon.type >= eventicon::TOTAL || icon.millis + 3000 < totalmillis)
if (icon.type < 0 || icon.type >= eventicon::TOTAL || icon.millis + eventicontime < totalmillis)
{
focus->icons.remove(i--);
continue;
}
Texture *tex = texs[icon.type];
int h = 1;
float aspect = 1, scalef = 1, offset = (totalmillis - icon.millis) / 3000.f * 160.f;
float aspect = 1, scalef = 1, offset = (totalmillis - icon.millis) / (float)eventicontime * 160.f;
switch (icon.type)
{
case eventicon::CHAT:
Expand All @@ -506,7 +507,7 @@ void draweventicons()
glBindTexture(GL_TEXTURE_2D, tex->id);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glColor4f(1.f, 1.f, 1.f, (3000 + icon.millis - totalmillis) / 3000.f);
glColor4f(1.f, 1.f, 1.f, (eventicontime + icon.millis - totalmillis) / (float)eventicontime);
glBegin(GL_TRIANGLE_STRIP);
float anim = (totalmillis / 100) % (h * 2);
if (anim >= h) anim = h * 2 - anim + 1;
Expand All @@ -519,6 +520,26 @@ void draweventicons()
glTexCoord2f(1, anim); glVertex2f(VIRTW / 2 + xx, VIRTH / 2 + yy + yoffset);
glEnd();
}

const int damagetime = 3000;
loopv(focus->damagelist_world)
{
const damageparticleinfo &d = focus->damagelist_world[i];
const int t = totalmillis - d.millis;
if (t > damagetime)
{
focus->damagelist_world.remove(i--);
continue;
}

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
div_t dmg = div(d.damage, HEALTHSCALE);
defformatstring(damagetext)(dmg.rem ? "\f%c%d.%*d" : "\f%c%d", d.color, dmg.quot, HEALTHPRECISION, dmg.rem);
const int xoff = d.xoff * 50 - text_width(damagetext) / 2;
const float yoff = d.yoff * 50 - t * (float)(VIRTH / 3) / damagetime;
draw_text(damagetext, VIRTW / 2 + xoff, VIRTH / 2 + yoff, 255, 255, 255, 255 * min(damagetime - t, damagetime) / (float)damagetime);
}
}

VARP(hidedamageindicator, 0, 0, 1);
Expand All @@ -529,21 +550,21 @@ VARP(damageindicatoralpha, 1, 50, 100);

void drawdmgindicator()
{
if (!damageindicatorsize || !focus->damagestack.length()) return;
if (!damageindicatorsize || !focus->damagelist_hud.length()) return;

static Texture *damagedirtex = NULL;
if (!damagedirtex) damagedirtex = textureload("packages/misc/damagedir.png", 3);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, damagedirtex->id);

loopv(focus->damagestack)
loopv(focus->damagelist_hud)
{
const damageinfo &pain = focus->damagestack[i];
const damageinfo &pain = focus->damagelist_hud[i];
const float damagefade = damageindicatortime + pain.damage * 200 / HEALTHSCALE;
if (pain.millis + damagefade <= totalmillis)
{
focus->damagestack.remove(i--);
focus->damagelist_hud.remove(i--);
continue;
}
vec dir = pain.o;
Expand Down

0 comments on commit 1a667cc

Please sign in to comment.