diff --git a/source/src/bot/ac_bot.cpp b/source/src/bot/ac_bot.cpp index 04d309dd..faa54a83 100644 --- a/source/src/bot/ac_bot.cpp +++ b/source/src/bot/ac_bot.cpp @@ -32,7 +32,7 @@ void CACBot::Spawn() spawnplayer(m_pMyEnt); m_pMyEnt->targetyaw = m_pMyEnt->yaw = m_pMyEnt->targetpitch = m_pMyEnt->pitch = 0.0f; - m_pMyEnt->primary = m_pMyEnt->nextprimary = GUN_ASSULT; + m_pMyEnt->primary = m_pMyEnt->nextprimary = GUN_ASSAULT; radd(this->m_pMyEnt); m_pMyEnt->move = 0; m_pMyEnt->enemy = NULL; @@ -166,6 +166,7 @@ void CACBot::BotPain(int damage, dynent *d) } addmsg(1, 2, SV_FRAGS, player1->frags += frags); addmsg(1, 4, SV_BOTDIED, BotManager.GetBotIndex(m_pMyEnt), -1, false); + if(player1->gunselect==GUN_KNIFE) addgib(m_pMyEnt); } else if (d->monsterstate) conoutf("%s got killed by %s", (int)m_pMyEnt->name, (int)d->name); @@ -201,6 +202,7 @@ void CACBot::BotPain(int damage, dynent *d) } addmsg(1, 4, SV_BOTDIED, BotManager.GetBotIndex(m_pMyEnt), KillerIndex, d->bIsBot); + if(d->gunselect==GUN_KNIFE) addgib(m_pMyEnt); } m_pMyEnt->lifesequence++; @@ -291,10 +293,10 @@ void CACBot::AddItem(int i, int &v, int spawnsec) return; //fixmebot - if(v>=itemstats[ents[i].type-1].max) // don't pick up if not needed + if(v>=itemstats[ents[i].type].max) // don't pick up if not needed return; - itemstat &is = itemstats[ents[i].type-1]; + itemstat &is = itemstats[ents[i].type]; ents[i].spawned = false; v += is.add; if(v>is.max) v = is.max; diff --git a/source/src/bot/ac_bot_ai.cpp b/source/src/bot/ac_bot_ai.cpp index b4bdd4fa..db67c1b9 100644 --- a/source/src/bot/ac_bot_ai.cpp +++ b/source/src/bot/ac_bot_ai.cpp @@ -152,17 +152,17 @@ entity *CACBot::SearchForEnts(bool bUseWPs, float flRange, float flMaxHeight) switch(e.type) { case I_CLIPS: - sMaxAmmo = itemstats[GUN_PISTOL-1].max; + sMaxAmmo = itemstats[GUN_PISTOL].max; bInteresting = (m_pMyEnt->ammo[GUN_PISTOL]ammo[GUN_PISTOL]; break; case I_AMMO: - sMaxAmmo = itemstats[m_pMyEnt->primary-1].max; + sMaxAmmo = itemstats[m_pMyEnt->primary].max; bInteresting = (m_pMyEnt->ammo[m_pMyEnt->primary]ammo[m_pMyEnt->primary]; break; case I_GRENADE: - sMaxAmmo = itemstats[GUN_GRENADE-1].max; + sMaxAmmo = itemstats[GUN_GRENADE].max; bInteresting = (m_pMyEnt->ammo[GUN_GRENADE]ammo[GUN_GRENADE]; break; diff --git a/source/src/clientextras.cpp b/source/src/clientextras.cpp index db5360bc..a9a9ce1e 100644 --- a/source/src/clientextras.cpp +++ b/source/src/clientextras.cpp @@ -24,6 +24,7 @@ void renderclient(dynent *d, bool team, char *mdlname, float scale) int basetime = -((int)d&0xFFF); if(d->state==CS_DEAD) { + loopv(physents) if(physents[i]->state==GIB && physents[i]->owner==d) return; d->pitch = 0.1f; int r; n = (d->lastaction%3)+18; diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 562d138d..74da09f5 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -104,7 +104,7 @@ dynent *newdynent() // create a new blank player or monster d->state = CS_ALIVE; d->shots = 0; d->reloading = false; - d->primary = d->nextprimary = GUN_ASSULT; + d->primary = d->nextprimary = GUN_ASSAULT; d->hasarmour = false; d->gunselect = GUN_PISTOL; d->onladder = false; @@ -255,24 +255,6 @@ void otherplayers() // End add }; -extern void explode_nade(physent *i); - -void mphysents() -{ - loopv(physents) if(physents[i]) - { - physent *p = physents[i]; - if(p->state == NADE_THROWED) moveplayer(p, 2, false); - - if(lastmillis - p->millis >= p->timetolife) - { - if(p->state==NADE_ACTIVATED || p->state==NADE_THROWED) explode_nade(physents[i]); - physents.remove(i); - i--; - }; - }; -}; - int sleepwait = 0; string sleepcmd; void scriptsleep(char *msec, char *cmd) { sleepwait = atoi(msec)+lastmillis; strcpy_s(sleepcmd, cmd); }; @@ -443,7 +425,7 @@ void mousemove(int dx, int dy) // damage arriving from the network, monsters, yourself, all ends up here. -void selfdamage(int damage, int actor, dynent *act) +void selfdamage(int damage, int actor, dynent *act, bool gib) { if(player1->state!=CS_ALIVE || editmode || intermission) return; damageblend(damage); @@ -492,7 +474,7 @@ void selfdamage(int damage, int actor, dynent *act) showscores(true); if(scoped) togglescope(); if(act->bIsBot) addmsg(1, 2, SV_DIEDBYBOT, actor); - else addmsg(1, 2, SV_DIED, actor); + else addmsg(1, 2, gib ? SV_GIBDIED : SV_DIED, actor); player1->lifesequence++; player1->attacking = false; player1->state = CS_DEAD; @@ -500,6 +482,7 @@ void selfdamage(int damage, int actor, dynent *act) player1->pitch = 0; player1->roll = 60; playsound(S_DIE1+rnd(2)); + if(gib) addgib(player1); spawnstate(player1); //player1->lastaction = lastmillis; //fixme diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 9bea2e8b..f50ba38b 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -84,6 +84,7 @@ void localservertoclient(uchar *buf, int len) // processes any updates from th dynent *d = NULL; bool mapchanged = false; bool c2si = false, killedbybot=false; + bool gib=false; while(plifesequence) selfdamage(damage, cn, d); else printf("wrong lifesequence\n"); } + if(target==clientnum) { if(ls==player1->lifesequence) selfdamage(damage, cn, d, gib); else printf("wrong lifesequence\n"); } else playsound(S_PAIN1+rnd(5), &getclient(target)->o); - break; - }; + gib = false; + break; + } case SV_BOT2CLIENTDMG: { @@ -252,11 +256,15 @@ void localservertoclient(uchar *buf, int len) // processes any updates from th break; } + case SV_DIEDBYBOT: killedbybot = true; + case SV_GIBDIED: + gib = true; // fixme case SV_DIED: { int actor = getint(p); + if(actor==cn && !killedbybot) { conoutf("%s suicided", (int)d->name); @@ -275,10 +283,11 @@ void localservertoclient(uchar *buf, int len) // processes any updates from th conoutf("you fragged %s", (int)d->name); }; addmsg(1, 2, SV_FRAGS, player1->frags += frags); + if(gib) addgib(d); } else { - dynent *a = killedbybot ? getbot(actor) : getclient(actor); + dynent *a = killedbybot ? getbot(actor) : getclient(actor); if(a) { if(isteam(a->team, d->name)) @@ -289,11 +298,12 @@ void localservertoclient(uchar *buf, int len) // processes any updates from th { conoutf("%s fragged %s", (int)a->name, (int)d->name); }; + if(gib) addgib(d); }; }; playsound(S_DIE1+rnd(2), &d->o); if(!c2si) d->lifesequence++; - killedbybot = false; + killedbybot = gib = false; break; }; @@ -592,6 +602,8 @@ void localservertoclient(uchar *buf, int len) // processes any updates from th conoutf("you fragged %s", (int)bot->name); }; addmsg(1, 2, SV_FRAGS, player1->frags += frags); + if(player1->gunselect==GUN_KNIFE) + addgib(bot); } else { @@ -614,9 +626,9 @@ void localservertoclient(uchar *buf, int len) // processes any updates from th { conoutf("%s fragged %s", (int)bot->name, (int)k->name); } + if(k->gunselect==GUN_KNIFE) addgib(bot); } } - playsound(S_DIE1+rnd(2), &bot->o); bot->lifesequence++; break; diff --git a/source/src/cube.h b/source/src/cube.h index 1a60dc0a..f9f11e77 100644 --- a/source/src/cube.h +++ b/source/src/cube.h @@ -91,7 +91,7 @@ struct vec { float x, y, z; }; struct block { int x, y, xs, ys; }; struct mapmodelinfo { int rad, h, zoff, snap; char *name; }; -enum { GUN_KNIFE = 0, GUN_PISTOL, GUN_SHOTGUN, GUN_SUBGUN, GUN_SNIPER, GUN_ASSULT, GUN_GRENADE, NUMGUNS }; +enum { GUN_KNIFE = 0, GUN_PISTOL, GUN_SHOTGUN, GUN_SUBGUN, GUN_SNIPER, GUN_ASSAULT, GUN_GRENADE, NUMGUNS }; enum { G_PRIMARY=0, G_SECONDARY, G_MELEE, G_GRENADE, G_NUM }; @@ -240,6 +240,7 @@ struct dynent // players & monsters struct physent *inhandnade; int akimbo; int akimbolastaction[2]; + float rotspeed; // Added by Rick CBot *pBot; // Only used if this is a bot, points to the bot class if we are the host, @@ -269,7 +270,7 @@ struct flaginfo flaginfo() : flag(0), thief(0), state(CTFF_INBASE), pick_ack(false) {}; }; -enum { PHYSENT_NONE = 0, NADE_ACTIVATED, NADE_THROWED }; +enum { PHYSENT_NONE = 0, NADE_ACTIVATED, NADE_THROWED, GIB}; struct physent : dynent // nades, gibs { @@ -280,6 +281,8 @@ struct physent : dynent // nades, gibs #define NADE_IN_HAND (player1->gunselect==GUN_GRENADE && player1->inhandnade) #define NADE_THROWING (player1->gunselect==GUN_GRENADE && player1->thrownademillis && !player1->inhandnade) +#define has_akimbo(d) ((d)->gunselect==GUN_PISTOL && (d)->akimbo) + #define SAVEGAMEVERSION 6 // bump if dynent/netprotocol changes or any other savegame/demo data bumped from 5 //enum { A_BLUE, A_GREEN, A_YELLOW }; // armour types... take 20/40/60 % off @@ -297,7 +300,7 @@ enum { M_NONE = 0, M_SEARCH, M_HOME, M_ATTACKING, M_PAIN, M_SLEEP, M_AIMING, M_N enum { SV_INITS2C = 0, SV_INITC2S, SV_POS, SV_TEXT, SV_SOUND, SV_CDIS, - SV_DIED, SV_DAMAGE, SV_SHOT, SV_FRAGS, + SV_GIBDIED, SV_DIED, SV_GIBDAMAGE, SV_DAMAGE, SV_SHOT, SV_FRAGS, SV_TIMEUP, SV_EDITENT, SV_MAPRELOAD, SV_ITEMACC, SV_MAPCHANGE, SV_ITEMSPAWN, SV_ITEMPICKUP, SV_DENIED, SV_PING, SV_PONG, SV_CLIENTPING, SV_GAMEMODE, @@ -328,14 +331,14 @@ enum S_ITEMAMMO, S_ITEMHEALTH, S_ITEMARMOUR, S_ITEMPUP, S_NOAMMO, S_PUPOUT, - S_PAIN1, S_PAIN2, S_PAIN3, S_PAIN4, S_PAIN5, S_PAIN6, + S_PAIN1, S_PAIN2, S_PAIN3, S_PAIN4, S_PAIN5, S_PAIN6, //24 S_DIE1, S_DIE2, S_FEXPLODE, S_SPLASH1, S_SPLASH2, S_GRUNT1, S_GRUNT2, S_RUMBLE, S_FLAGDROP, S_FLAGPICKUP, S_FLAGRETURN, S_FLAGSCORE, S_GRENADEPULL, S_GRENADETHROW, - S_RAKIMBO, S_GUNCHANGE, + S_RAKIMBO, S_GUNCHANGE, S_GIB, S_NULL }; diff --git a/source/src/entities.cpp b/source/src/entities.cpp index d99c3b0f..5385ae77 100644 --- a/source/src/entities.cpp +++ b/source/src/entities.cpp @@ -80,39 +80,29 @@ void renderentities() itemstat itemstats[] = { - 16, 32, 72, S_ITEMAMMO, //pistol - 14, 28, 21, S_ITEMAMMO, //shotgun - 60, 30, 90, S_ITEMAMMO, //subgun - 10, 20, 15, S_ITEMAMMO, //sniper - 40, 60, 60, S_ITEMAMMO, //assault - 2, 0, 2, S_ITEMAMMO, //grenade - 33, 100, 100, S_ITEMHEALTH, //health - 50, 100, 100, S_ITEMARMOUR, //armour - 16, 0, 72, S_ITEMPUP, //powerup + 1, 1, 1, S_ITEMAMMO, //knife dummy + 16, 32, 72, S_ITEMAMMO, //pistol + 14, 28, 21, S_ITEMAMMO, //shotgun + 60, 90, 90, S_ITEMAMMO, //subgun + 10, 20, 15, S_ITEMAMMO, //sniper + 40, 60, 60, S_ITEMAMMO, //assault + 2, 0, 2, S_ITEMAMMO, //grenade + 33, 100,100,S_ITEMHEALTH, //health + 50, 100,100,S_ITEMARMOUR, //armour + 16, 0, 72, S_ITEMPUP, //powerup }; -void baseammo(int gun) { player1->ammo[gun] = itemstats[gun-1].add*2; }; +void baseammo(int gun) { player1->ammo[gun] = itemstats[gun].add*2; }; // Added by Rick: baseammo for bots -void botbaseammo(int gun, dynent *d) { d->ammo[gun] = itemstats[gun-1].add*2; }; +void botbaseammo(int gun, dynent *d) { d->ammo[gun] = itemstats[gun].add*2; }; // End add // these two functions are called when the server acknowledges that you really // picked up the item (in multiplayer someone may grab it before you). -/* -void radditem(int i, int &v) -{ - itemstat &is = itemstats[ents[i].type-I_CLIPS]; - ents[i].spawned = false; - v += is.add; - if(v>is.max) v = is.max; - playsoundc(is.sound); -}; -*/ - void radditem(int i, int &v, int t) { - itemstat &is = itemstats[t-1]; + itemstat &is = itemstats[t]; ents[i].spawned = false; v += is.add; if(v>is.max) v = is.max; @@ -154,18 +144,6 @@ void realpickup(int n, dynent *d) // these functions are called when the client touches the item -/* -void additem(int i, int &v, int spawnsec) -{ - if(vammo[GUN_PISTOL] = itemstats[GUN_PISTOL].start-magsize(GUN_PISTOL); d->mag[GUN_PISTOL] = magsize(GUN_PISTOL); - d->ammo[d->primary] = itemstats[d->primary-1].start-magsize(d->primary); + d->ammo[d->primary] = itemstats[d->primary].start-magsize(d->primary); d->mag[d->primary] = magsize(d->primary); }; @@ -362,4 +340,3 @@ bool intersect(entity *e, vec &from, vec &to, vec *end) // if lineseg hits entit return false; }; // End add by Ricks - diff --git a/source/src/main.cpp b/source/src/main.cpp index 307a44e0..cbd09829 100644 --- a/source/src/main.cpp +++ b/source/src/main.cpp @@ -148,7 +148,7 @@ int main(int argc, char **argv) if(SDL_SetVideoMode(scr_w, scr_h, 0, SDL_OPENGL|fs)==NULL) fatal("Unable to create OpenGL screen"); log("video: misc"); - SDL_WM_SetCaption("Action Cube", NULL); + SDL_WM_SetCaption("ActionCube", NULL); SDL_WM_GrabInput(SDL_GRAB_ON); keyrepeat(false); SDL_ShowCursor(0); diff --git a/source/src/menus.cpp b/source/src/menus.cpp index 822890c1..249580f9 100644 --- a/source/src/menus.cpp +++ b/source/src/menus.cpp @@ -106,8 +106,9 @@ void rendermenumdl() glRotatef(player1->pitch, 0, 0, 1); float z=0.0f; + bool isplayermodel = !strncmp(m.mdl, "playermodels", strlen("playermodels")); - if(!strncmp(m.mdl, "playermodels", strlen("playermodels"))) + if(isplayermodel) { glTranslatef(2.0f, 1.0f, 1.5f); z = -1.0f; @@ -115,11 +116,19 @@ void rendermenumdl() else { glTranslatef(2.0f, 1.7f, 0.0f); - } + }; if(m.rotspeed) glRotatef(lastmillis/5.0f/100.0f*m.rotspeed, 0, 1, 0); - rendermodel(m.mdl, m.frame, m.range, 0.0f, 0.0f, 0.0f, z, 0, 0, 0, false, (float)(m.scale ? m.scale/25.0f : 1), 100, 0, 0, false); + + if(isplayermodel) + { + string vwep; + strcpy_s(vwep, "weapons/subgun/world"); + path(vwep); + rendermodel(vwep, m.frame, m.range, 0.0f, 0.0f, 0.0f, z, 0, 0, 0, false, (float)(m.scale ? m.scale/25.0f : 1), 100, 0, 0, false); + }; + glPopMatrix(); } diff --git a/source/src/physics.cpp b/source/src/physics.cpp index dd6b52fc..c073b9ae 100644 --- a/source/src/physics.cpp +++ b/source/src/physics.cpp @@ -262,9 +262,9 @@ void moveplayer(dynent *pl, int moveres, bool local, int curtime) if(pl->isphysent) { - pl->pitch += ((float) sqrt(dotprod(pl->vel, pl->vel)))*speed*5.0f; + pl->pitch += ((float) sqrt(dotprod(pl->vel, pl->vel)))*speed*pl->rotspeed*5.0f; if(pl->pitch>360.0f) pl->pitch = 0.0f; - pl->yaw += ((float) sqrt(dotprod(pl->vel, pl->vel)))*speed*5.0f; + pl->yaw += ((float) sqrt(dotprod(pl->vel, pl->vel)))*speed*pl->rotspeed*5.0f; if(pl->yaw>360.0f) pl->yaw = 0.0f; } @@ -414,3 +414,66 @@ void moveplayer(dynent *pl, int moveres, bool local) { loopi(physicsrepeat) moveplayer(pl, moveres, local, i ? curtime/physicsrepeat : curtime-curtime/physicsrepeat*(physicsrepeat-1)); }; + +physent *new_physent() +{ + physent *p = (physent *)gp()->alloc(sizeof(physent)); + + p->yaw = 270; + p->pitch = 0; + p->roll = 0; + p->isphysent = true; + p->rotspeed = 1.0f; + + p->maxspeed = 40; + p->outsidemap = false; + p->inwater = false; + p->radius = 0.2f; + p->eyeheight = 0.3f; + p->aboveeye = 0.0f; + p->frags = 0; + p->plag = 0; + p->ping = 0; + p->lastupdate = lastmillis; + p->enemy = NULL; + p->monsterstate = 0; + p->name[0] = p->team[0] = 0; + p->blocked = false; + p->lifesequence = 0; + p->dynent::state = CS_ALIVE; + p->state = PHYSENT_NONE; + p->shots = 0; + p->reloading = false; + p->nextprimary = 1; + p->hasarmour = false; + + p->k_left = false; + p->k_right = false; + p->k_up = false; + p->k_down = false; + p->jumpnext = false; + p->onladder = false; + p->strafe = 0; + p->move = 0; + + physents.add(p); + return p; +} + +extern void explode_nade(physent *i); + +void mphysents() +{ + loopv(physents) if(physents[i]) + { + physent *p = physents[i]; + if(p->state == NADE_THROWED || p->state == GIB) moveplayer(p, 2, false); + + if(lastmillis - p->millis >= p->timetolife) + { + if(p->state==NADE_ACTIVATED || p->state==NADE_THROWED) explode_nade(physents[i]); + physents.remove(i); + i--; + }; + }; +}; diff --git a/source/src/protos.h b/source/src/protos.h index 159a6ddd..4e65a7f7 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -83,7 +83,7 @@ extern void startmap(char *name); extern void changemap(char *name); extern void initclient(); extern void spawnplayer(dynent *d, bool secure=false); -extern void selfdamage(int damage, int actor, dynent *act); +extern void selfdamage(int damage, int actor, dynent *act, bool gib=false); extern dynent *newdynent(); extern char *getclientmap(); extern const char *modestr(int n); @@ -173,6 +173,7 @@ extern void shotlinereset(); extern void renderphysents(); extern bool scoped; extern void togglescope(bool deactivate = false); +extern void addgib(dynent *d); // renderparticles extern void setorient(vec &r, vec &u); @@ -201,6 +202,8 @@ extern void entinmap(dynent *d); extern void setentphysics(int mml, int mmr); extern void physicsframe(); extern void movephysent(physent *pl); +extern physent *new_physent(); +extern void mphysents(); // sound extern void playsound(int n, vec *loc = 0); @@ -239,7 +242,7 @@ extern ENetPacket *recvmap(int n); // weapon //extern void selectgun(int a = -1, int b = -1, int c =-1); extern void shoot(dynent *d, vec &to); -extern void shootv(int gun, vec &from, vec &to, dynent *d = 0, bool local = false, int nadepercent=0); +extern void shootv(int gun, vec &from, vec &to, dynent *d = 0, bool local = false, int nademillis=0); extern void createrays(vec &from, vec &to); extern void moveprojectiles(float time); extern void projreset(); diff --git a/source/src/renderextras.cpp b/source/src/renderextras.cpp index 45525591..919044ea 100644 --- a/source/src/renderextras.cpp +++ b/source/src/renderextras.cpp @@ -51,11 +51,13 @@ void blendbox(int x1, int y1, int x2, int y2, bool border, int tex) glBindTexture(GL_TEXTURE_2D, tex); glEnable(GL_TEXTURE_2D); glDisable(GL_BLEND); + glColor3d(1.0, 1.0, 1.0); float texw = 512.0f; float texh = texw; int cols = (x2-x1)/texw+1; int rows = (y2-y1)/texh+1; + xtraverts += cols*rows*4; loopj(rows) { @@ -97,6 +99,7 @@ void blendbox(int x1, int y1, int x2, int y2, bool border, int tex) glTexCoord2f(1, 1); glVertex2i(x2, y2); glTexCoord2f(0, 1); glVertex2i(x1, y2); glEnd(); + xtraverts += 4; }; glDisable(GL_BLEND); @@ -110,7 +113,6 @@ void blendbox(int x1, int y1, int x2, int y2, bool border, int tex) glVertex2i(x1, y2); glEnd(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - xtraverts += 8; glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); glDepthMask(GL_TRUE); @@ -400,7 +402,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat else if(player1->health<=25) glColor3ub(255,0,0); else if(player1->health<=50) glColor3ub(255,128,0); }; - float chsize = (float)crosshairsize; + float chsize = (float)crosshairsize * (player1->gunselect==GUN_ASSAULT && player1->shots > 3 ? 1.4f : 1.0f); glTexCoord2d(0.0, 0.0); glVertex2f(VIRTW/2 - chsize, VIRTH/2 - chsize); glTexCoord2d(1.0, 0.0); glVertex2f(VIRTW/2 + chsize, VIRTH/2 - chsize); glTexCoord2d(1.0, 1.0); glVertex2f(VIRTW/2 + chsize, VIRTH/2 + chsize); @@ -596,8 +598,53 @@ void renderphysents() { loopv(physents) { - physent *d = physents[i]; - if(d && d->state==NADE_THROWED) rendermodel("weapons/grenade/static", 0, 1, 0, 0, d->o.x, d->o.z, d->o.y, d->yaw, d->pitch, false, 2.0f, 100.0f, 0, 0); + physent *p = physents[i]; + if(!p) continue; + string model; + + switch(p->state) + { + case NADE_THROWED: + strcpy_s(model, "weapons/grenade/static"); + break; + case GIB: + default: + sprintf_s(model)("misc/gib0%i", (((int)p)%2)+1); + printf("%i\n", (((int)p)%3)+1); + break; + } + path(model); + rendermodel(model, 0, 1, 0, 0, p->o.x, p->o.z, p->o.y, p->yaw, p->pitch, false, 2.0f, 100.0f, 0, 0); }; }; +VAR(numgibs, 0, 10, 100); + +void addgib(dynent *d) +{ + if(!d) return; + playsound(S_GIB, &d->o); + loopi(numgibs) + { + physent *p = new_physent(); + p->owner = d; + p->millis = lastmillis; + p->timetolife = 4000; + p->state = GIB; + + p->isphysent = true; + p->gravity = 20; + p->timeinair = 0; + p->onfloor = false; + + p->o = d->o; + p->o.z -= d->aboveeye; + p->vel.z = 0.3f + rnd(30)/100.0f; + p->vel.x = -0.2f + rnd(50)/100.0f; + p->vel.y = -0.2f + rnd(50)/100.0f; + p->yaw = (float)rnd(360); + p->pitch = (float)rnd(360); + p->rotspeed = 3.0f; + } +}; + diff --git a/source/src/rendermd2.cpp b/source/src/rendermd2.cpp index 84a4daf0..a7f23941 100644 --- a/source/src/rendermd2.cpp +++ b/source/src/rendermd2.cpp @@ -218,10 +218,9 @@ void md2::render(vec &light, int frame, int range, float x, float y, float z, fl verts2p = mverts[prev.fr2]; aifrac1 = (lastmillis-d->lastanimswitchtime)/(float)animationinterpolationtime; aifrac2 = 1-aifrac1; + if(!verts1p || !verts2p) return; //fixme }; - if(doai) printf("(%i %f %i) %f (%i %f %i)\n", prev.fr1, prev.frac1, prev.fr2, aifrac1, current.fr1, current.frac1, current.fr2); - for(int *command = glCommands; (*command)!=0;) { int numVertex = *command++; @@ -352,3 +351,18 @@ void rendermodel(char *mdl, int frame, int range, int tex, float rad, float x, f m->render(light, frame, range, x, y, z, yaw, pitch, scale, speed, snap, basetime, d); }; + + +void preload_mapmodels() +{ + int xs, ys; + loopv(ents) + { + entity &e = ents[i]; + mapmodelinfo &mmi = getmminfo(e.attr2); + if(!&mmi) continue; + md2 *m = loadmodel(mmi.name); + delayedload(m); + lookuptexture(e.attr4 ? lookuptexture(e.attr4, xs, ys) : FIRSTMDL+m->mdlnum, xs, ys); + } +} \ No newline at end of file diff --git a/source/src/rendermd3.cpp b/source/src/rendermd3.cpp index 3348d302..a69bec14 100644 --- a/source/src/rendermd3.cpp +++ b/source/src/rendermd3.cpp @@ -231,8 +231,6 @@ void md3model::render() a->frm = 0; nextfrm = a->frm + 1; } - - /*printf("frame %i\n", a->frm);*/ #define interpolate(p1,p2) ((p1) + t * ((p2) - (p1))) @@ -291,7 +289,7 @@ void md3model::draw(float x, float y, float z, float yaw, float pitch, float rad glRotatef(-90, 0, 1, 0); glRotatef(-90, 1, 0, 0); - glScalef( scale.x, scale.y, scale.z); + glScalef(scale.x, scale.y, scale.z); if(mirrored) glCullFace(GL_BACK); render(); diff --git a/source/src/serverutil.cpp b/source/src/serverutil.cpp index 6a836df9..89aec460 100644 --- a/source/src/serverutil.cpp +++ b/source/src/serverutil.cpp @@ -53,7 +53,7 @@ char msgsizesl[] = // size inclusive message token, 0 for variable char msgsizesl[] = // size inclusive message token, 0 for variable or not-checked sizes { SV_INITS2C, 4, SV_INITC2S, 0, SV_POS, 12, SV_TEXT, 0, SV_SOUND, 2, SV_CDIS, 2, - SV_DIED, 2, SV_DAMAGE, 4, SV_SHOT, 9, SV_FRAGS, 2, + SV_GIBDIED, 2, SV_DIED, 2, SV_GIBDAMAGE, 4, SV_DAMAGE, 4, SV_SHOT, 9, SV_FRAGS, 2, SV_TIMEUP, 2, SV_EDITENT, 10, SV_MAPRELOAD, 2, SV_ITEMACC, 2, SV_MAPCHANGE, 0, SV_ITEMSPAWN, 2, SV_ITEMPICKUP, 3, SV_DENIED, 2, SV_PING, 2, SV_PONG, 2, SV_CLIENTPING, 2, SV_GAMEMODE, 2, diff --git a/source/src/sound.cpp b/source/src/sound.cpp index 11decd96..2cd513d9 100644 --- a/source/src/sound.cpp +++ b/source/src/sound.cpp @@ -199,10 +199,11 @@ void playsound(int n, vec *loc) { if(nosound) return; if(!soundvol) return; + if(n==S_NULL) return; if(lastmillis==lastsoundmillis) soundsatonce++; else soundsatonce = 1; lastsoundmillis = lastmillis; if(soundsatonce>5) return; // avoid bursts of sounds with heavy packetloss and in sp - if(n<0 || n>=samples.length()) { conoutf("unregistered sound: %d", n); return; }; + if(n<0 || n>=samples.length()) { conoutf("unregistered sound: %d", n); return; }; if(!samples[n]) { diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index cc7d486c..11bd65dd 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -44,12 +44,12 @@ void weaponswitch(int gun) player1->lastaction = player1->akimbolastaction[0] = player1->akimbolastaction[1] = lastmillis; player1->nextweapon = gun; playsound(S_GUNCHANGE); -} +}; void weapon(int gun) { if(scoped) togglescope(); - if(player1->gunselect==GUN_GRENADE && player1->inhandnade) return; + if(NADE_IN_HAND) return; gun %= G_NUM; if(gun<0) gun = G_NUM+gun; @@ -225,9 +225,9 @@ void newprojectile(vec &from, vec &to, float speed, bool local, dynent *owner, i }; }; -void hit(int target, int damage, dynent *d, dynent *at) +void hit(int target, int damage, dynent *d, dynent *at, bool gib=false) { - if(d==player1) selfdamage(damage, at==player1 ? -1 : -2, at); + if(d==player1) selfdamage(damage, at==player1 ? -1 : -2, at, gib); //else if(d->monsterstate) monsterpain(d, damage, at); // Added by Rick: Let bots take damage else if(d->pBot) d->pBot->BotPain(damage, at); @@ -276,9 +276,9 @@ void hit(int target, int damage, dynent *d, dynent *at) } } if(at->bIsBot) addmsg(1, 5, SV_BOT2CLIENTDMG, target, damage, d->lifesequence, PlayerIndex); - else addmsg(1, 4, SV_DAMAGE, target, damage, d->lifesequence); + else addmsg(1, 4, gib ? SV_GIBDAMAGE : SV_DAMAGE, target, damage, d->lifesequence); playsound(S_PAIN1+rnd(5), &d->o); - }; + }; particle_splash(3, damage, 1000, d->o); demodamage(damage, d->o); @@ -296,7 +296,7 @@ void radialeffect(dynent *o, vec &v, int cn, int qdam, dynent *at) { if(dist<0) dist = 0; int damage = (int)(qdam*(1-(dist/RL_DAMRAD))); - hit(cn, damage, o, at); + hit(cn, damage, o, at, true); vmul(temp, (RL_DAMRAD-dist)*damage/800); vadd(o->vel, temp); }; @@ -349,7 +349,7 @@ inline void projdamage(dynent *o, projectile *p, vec &v, int i, int im, int ib, { // splash(p, v, p->o, i, im, qdam); Modified by Rick splash(p, v, p->o, i, im, ib, qdam); - hit(i, qdam, o, p->owner); + hit(i, qdam, o, p->owner, true); //fixme }; }; @@ -443,68 +443,23 @@ void throw_nade(dynent *d, vec &to, physent *p) if(d==player1) { player1->lastaction = lastmillis; - int percent_done = (lastmillis-p->millis)*100/nadetimer; - if(percent_done < 0 || percent_done > 100) percent_done = 100; - addmsg(1, 9, SV_SHOT, d->gunselect, (int)(from.x*DMF), (int)(from.y*DMF), (int)(from.z*DMF), (int)(to.x*DMF), (int)(to.y*DMF), (int)(to.z*DMF), percent_done); + conoutf("throw %i\n", lastmillis-p->millis); + addmsg(1, 9, SV_SHOT, d->gunselect, (int)(from.x*DMF), (int)(from.y*DMF), (int)(from.z*DMF), (int)(to.x*DMF), (int)(to.y*DMF), (int)(to.z*DMF), lastmillis-p->millis); }; }; -physent *new_physent() -{ - physent *p = (physent *)gp()->alloc(sizeof(physent)); - - p->yaw = 270; - p->pitch = 0; - p->roll = 0; - p->isphysent = true; - - p->maxspeed = 40; - p->outsidemap = false; - p->inwater = false; - p->radius = 0.2f; - p->eyeheight = 0.3f; - p->aboveeye = 0.0f; - p->frags = 0; - p->plag = 0; - p->ping = 0; - p->lastupdate = lastmillis; - p->enemy = NULL; - p->monsterstate = 0; - p->name[0] = p->team[0] = 0; - p->blocked = false; - p->lifesequence = 0; - p->dynent::state = CS_ALIVE; - p->state = PHYSENT_NONE; - p->shots = 0; - p->reloading = false; - p->nextprimary = 1; - p->hasarmour = false; - - p->k_left = false; - p->k_right = false; - p->k_up = false; - p->k_down = false; - p->jumpnext = false; - p->onladder = false; - p->strafe = 0; - p->move = 0; - - physents.add(p); - return p; -} - physent *new_nade(dynent *d, int millis = 0) { - printf("newnade\n"); physent *p = new_physent(); p->owner = d; p->millis = lastmillis; p->timetolife = 2000-millis; + conoutf("newnade %i", p->timetolife); p->state = NADE_ACTIVATED; d->inhandnade = p; d->thrownademillis = 0; - playsound(S_GRENADEPULL); + playsound(S_GRENADEPULL, &d->o); return p; }; @@ -524,7 +479,7 @@ void explode_nade(physent *i) newprojectile(i->o, i->o, 1, i->owner==player1, i->owner, GUN_GRENADE); }; -void shootv(int gun, vec &from, vec &to, dynent *d, bool local, int nadepercent) // create visual effect from a shot +void shootv(int gun, vec &from, vec &to, dynent *d, bool local, int nademillis) // create visual effect from a shot { playsound(guns[gun].sound, d==player1 ? NULL : &d->o); int pspeed = 25; @@ -541,22 +496,22 @@ void shootv(int gun, vec &from, vec &to, dynent *d, bool local, int nadepercent) case GUN_PISTOL: case GUN_SUBGUN: - case GUN_ASSULT: + case GUN_ASSAULT: addshotline(d, from, to); particle_splash(0, 5, 250, to); //particle_trail(1, 10, from, to); break; case GUN_GRENADE: + { + if(d!=player1) { - if(d!=player1) - { - int nademillis = nadetimer/100*nadepercent; - if(nademillis<0 || nademillis>100) nademillis = 100; - physent *p = new_nade(d, nademillis); - throw_nade(d, to, p); - } - }; + /*int nademillis = nadetimer/100*nadepercent; + if(nademillis<0 || nademillis>100) nademillis = 100;*/ + physent *p = new_nade(d, nademillis); + throw_nade(d, to, p); + } + }; break; case GUN_SNIPER: @@ -569,7 +524,7 @@ void shootv(int gun, vec &from, vec &to, dynent *d, bool local, int nadepercent) void hitpush(int target, int damage, dynent *d, dynent *at, vec &from, vec &to) { - hit(target, damage, d, at); + hit(target, damage, d, at, at->gunselect==GUN_KNIFE ? true : false); vdist(dist, v, from, to); vmul(v, damage/dist/50); vadd(d->vel, v); @@ -602,7 +557,7 @@ void spreadandrecoil(vec &from, vec &to, dynent *d) //recoil int rcl = guns[d->gunselect].recoil*-0.01f; - if(d->gunselect==GUN_ASSULT) + if(d->gunselect==GUN_ASSAULT) { if(d->shots > 3) spd = 70; @@ -639,9 +594,8 @@ bool hasammo(dynent *d) // bot mod else playsoundc(S_NOAMMO); d->gunwait = 250; d->lastattackgun = -1; - printf("noammo\n"); return false; - } else { printf("ammo\n"); return true; } + } else return true; } const int grenadepulltime = 650; @@ -650,8 +604,9 @@ bool akimboside = false; void shoot(dynent *d, vec &targ) { int attacktime = lastmillis-d->lastaction; - if(d->weaponchanging || attacktimegunwait) return; - d->gunwait = 0; + + vec from = d->o; + vec to = targ; if(d->gunselect==GUN_GRENADE) { @@ -661,36 +616,41 @@ void shoot(dynent *d, vec &targ) { d->weaponchanging = true; d->nextweapon = d->mag[GUN_GRENADE] ? GUN_GRENADE : d->primary; - d->thrownademillis = 0;// + d->thrownademillis = 0; d->lastaction = lastmillis-1-WEAPONCHANGE_TIME/2; }; + if(d->weaponchanging || attacktimegunwait) return; + d->gunwait = 0; + if(d->attacking && !d->inhandnade) // activate { if(!hasammo(d)) return; d->mag[d->gunselect]--; new_nade(d); - d->gunwait = guns[d->gunselect].attackdelay; + d->gunwait = grenadepulltime; d->lastaction = lastmillis; + d->lastattackgun = d->gunselect; d->reloading = false; - return; } - else if(d->inhandnade) // throw nade + else if(!d->attacking && d->inhandnade && attacktime>grenadepulltime) // throw { - if(attacktime>grenadepulltime) throw_nade(d, targ, d->inhandnade); - return; + throw_nade(d, targ, d->inhandnade); } + return; } else { - if(!d->attacking) return; + if(d->weaponchanging || attacktimegunwait) return; + d->gunwait = 0; + + if(!d->attacking) { d->shots = 0; return; }; d->lastaction = lastmillis; d->lastattackgun = d->gunselect; if(!hasammo(d)) { d->shots = 0; return; }; d->reloading = false; - - + if(guns[d->gunselect].isauto) d->shots++; else d->attacking = false; @@ -702,51 +662,44 @@ void shoot(dynent *d, vec &targ) } if(d->gunselect) d->mag[d->gunselect]--; - - } - - vec from = d->o; - vec to = targ; from.z -= 0.2f; // below eye - - spreadandrecoil(from,to,d); - vdist(dist, unitv, from, to); - vdiv(unitv, dist); - - if(d->gunselect==GUN_KNIFE) - { - vmul(unitv, 3); // punch range - to = from; - vadd(to, unitv); - }; - if(d->gunselect==GUN_SHOTGUN) createrays(from, to); - - if(d->gunselect==GUN_PISTOL && d->akimbo) d->gunwait = guns[d->gunselect].attackdelay / 2; //make akimbo pistols shoot twice as fast as normal pistol - else d->gunwait = guns[d->gunselect].attackdelay; - - - //fixmebot - shootv(d->gunselect, from, to, d, 0); - addmsg(1, 9, SV_SHOT, d->gunselect, (int)(from.x*DMF), (int)(from.y*DMF), (int)(from.z*DMF), (int)(to.x*DMF), (int)(to.y*DMF), (int)(to.z*DMF), 0 ); - - if(guns[d->gunselect].projspeed) return; - - loopv(players) - { - dynent *o = players[i]; - if(!o) continue; - raydamage(o, from, to, d, i); - }; - - // Added by Rick: raydamage on bots too - loopv(bots) - { - dynent *o = bots[i]; - if(!o || (o == d)) continue; - raydamage(o, from, to, d, i); - }; - // End add by Rick - - if(d->bIsBot) raydamage(player1, from, to, d, -1); + }; + spreadandrecoil(from,to,d); + vdist(dist, unitv, from, to); + vdiv(unitv, dist); + + if(d->gunselect==GUN_KNIFE) + { + vmul(unitv, 3); // punch range + to = from; + vadd(to, unitv); + }; + if(d->gunselect==GUN_SHOTGUN) createrays(from, to); + + if(has_akimbo(d)) d->gunwait = guns[d->gunselect].attackdelay / 2; //make akimbo pistols shoot twice as fast as normal pistol + else d->gunwait = guns[d->gunselect].attackdelay; + + //fixmebot + shootv(d->gunselect, from, to, d, 0); + addmsg(1, 9, SV_SHOT, d->gunselect, (int)(from.x*DMF), (int)(from.y*DMF), (int)(from.z*DMF), (int)(to.x*DMF), (int)(to.y*DMF), (int)(to.z*DMF), 0 ); + if(guns[d->gunselect].projspeed || d->gunselect==GUN_GRENADE) return; + + loopv(players) + { + dynent *o = players[i]; + if(!o) continue; + raydamage(o, from, to, d, i); + }; + + // Added by Rick: raydamage on bots too + loopv(bots) + { + dynent *o = bots[i]; + if(!o || (o == d)) continue; + raydamage(o, from, to, d, i); + }; + // End add by Rick + + if(d->bIsBot) raydamage(player1, from, to, d, -1); }; diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index 3a5b8d6d..6120abdf 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -207,6 +207,7 @@ void save_world(char *mname) }; extern void preparectf(bool cleanonly = false); +extern void preload_mapmodels(); void load_world(char *mname) // still supports all map formats that have existed since the earliest cube betas! { @@ -349,8 +350,6 @@ void load_world(char *mname) // still supports all map formats that have gzclose(f); calclight(); settagareas(); - int xs, ys; - loopi(256) if(texuse) lookuptexture(i, xs, ys); conoutf("read map %s (%d milliseconds)", (int)cgzname, SDL_GetTicks()-lastmillis); conoutf("%s", (int)hdr.maptitle); startmap(mname); @@ -362,6 +361,9 @@ void load_world(char *mname) // still supports all map formats that have execfile("config/default_map_settings.cfg"); execfile(pcfname); execfile(mcfname); + int xs, ys; + loopi(256) if(texuse) lookuptexture(i, xs, ys); + preload_mapmodels(); }; COMMANDN(savemap, save_world, ARG_1STR);