diff --git a/config/resetbinds.cfg b/config/resetbinds.cfg index 7c17f60a..4eb75547 100644 --- a/config/resetbinds.cfg +++ b/config/resetbinds.cfg @@ -55,17 +55,20 @@ editbind PERIOD [ equalize 2 ] bind SLASH key_commandline bind 0 [] bind 1 primary -editbind 1 [ domodifier 5 ] +editbind 1 [ domodifier attr1 ] bind 2 secondary -editbind 2 [ domodifier 7 ] +editbind 2 [ domodifier attr2 ] bind 3 grenades -editbind 3 [ domodifier 8 ] +editbind 3 [ domodifier attr3 ] bind 4 melee -editbind 4 [ domodifier 9 ] +editbind 4 [ domodifier attr4 ] bind 5 [] +editbind 5 [ domodifier attr5 ] bind 6 [] +editbind 6 [ domodifier attr6 ] bind 7 [] -editbind 7 nextclosestent +editbind 7 [ domodifier attr7 ] +//editbind 7 nextclosestent bind 8 [] editbind 8 [ vdelta -1 ] bind 9 [] diff --git a/config/scripts.cfg b/config/scripts.cfg index b18b0461..144a3e3a 100644 --- a/config/scripts.cfg +++ b/config/scripts.cfg @@ -229,7 +229,7 @@ const universaldelta [ if $editing [ s = edit ] [ if (player1 alive) [ s = game ] [ s = spect ] ] - (concatword delta _ (pop s) _ $modifier) + (concatword delta _ (pop s) _ $modifier) (* $arg1 (at "1 3" $editmetakeydown)) (* $arg1 (at "1 10" $editmetakeydown)) ] // To utilize the below, you will need to bind "domodifier X" // (replace X with the number of the delta_edit) to a key. To @@ -241,13 +241,16 @@ delta_edit_1 = [ if $flrceil [ vdelta $arg1 ] [ vdelta (- 0 $arg1) ] ] // Change delta_edit_2 = [ edittex $flrceil $arg1 ] // Change floor/ceiling textures... delta_edit_3 = [ edittex (+ $flrceil 1) $arg1 ] // Change wall/upper-wall textures... delta_edit_4 = [ equalize $flrceil ] // Equalize floor/ceiling... -delta_edit_5 = [ entproperty 0 (* $arg1 (at "1 10" $editmetakeydown)) ] // Changes the first value on entities... delta_edit_6 = [ entproperty $editaxis $arg1 ] // Move map entity... -delta_edit_7 = [ entproperty 1 $arg1 ] // Changes the second value on entities... -delta_edit_8 = [ entproperty 2 $arg1 ] // Changes the third value on entities... -delta_edit_9 = [ entproperty 3 $arg1 ] // Changes the fourth value on entities... delta_edit_10 = [ if (checkrange (+f $flyspeed (divf $arg1 4)) 1 5) [ flyspeed (+f $flyspeed (divf $arg1 4)); echo $flyspeed ] ] // Tweak flyspeed delta_edit_11 = [ if (> $arg1 0) [ expandselection 1 ] [ shrinkselection 1 ] ] // Expand/shrink the current selection +delta_edit_attr1 = [ entproperty 0 $arg2 ] // Changes the first value on entities... +delta_edit_attr2 = [ entproperty 1 $arg2 ] // Changes the second value on entities... +delta_edit_attr3 = [ entproperty 2 $arg2 ] // Changes the third value on entities... +delta_edit_attr4 = [ entproperty 3 $arg2 ] // Changes the fourth value on entities... +delta_edit_attr5 = [ entproperty 4 $arg2 ] // Changes the fifth value on entities... +delta_edit_attr6 = [ entproperty 5 $arg2 ] // Changes the sixth value on entities... +delta_edit_attr7 = [ entproperty 6 $arg2 ] // Changes the seventh value on entities... // HUD toggles const toggleshowmap [ showmap 1; onrelease [ showmap 0 ] ] diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 6941c678..515e1764 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -965,6 +965,9 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) ents[i].attr2 = getint(p); ents[i].attr3 = getint(p); ents[i].attr4 = getint(p); + ents[i].attr5 = getint(p); + ents[i].attr6 = getint(p); + ents[i].attr7 = getint(p); ents[i].spawned = false; if(ents[i].type==LIGHT || to==LIGHT) calclight(); if(ents[i].type==SOUND) audiomgr.preloadmapsound(ents[i]); diff --git a/source/src/editing.cpp b/source/src/editing.cpp index 3bd5a2db..0fa95f8e 100644 --- a/source/src/editing.cpp +++ b/source/src/editing.cpp @@ -105,7 +105,7 @@ char *editinfo() if(e >= 0) { entity &c = ents[e]; - formatstring(info)("closest entity = %s (%d, %d, %d, %d), ", entnames[c.type], c.attr1, c.attr2, c.attr3, c.attr4); + formatstring(info)("closest entity = %s (%d, %d, %d, %d, %d, %d, %d), ", entnames[c.type], c.attr1, c.attr2, c.attr3, c.attr4, c.attr5, c.attr6, c.attr7); } if(selset()) concatformatstring(info, "selection = (%d, %d)", (sels.last()).xs, (sels.last()).ys); else concatformatstring(info, "no selection"); diff --git a/source/src/entities.cpp b/source/src/entities.cpp index 8c05c059..3d02e3c5 100644 --- a/source/src/entities.cpp +++ b/source/src/entities.cpp @@ -22,7 +22,7 @@ const char *entmdlnames[] = entmdlnames[e.type-I_CLIPS+(m_lss && e.type==I_GRENADE ? 5:0)]); float z = (float)(1+sinf(lastmillis/100.0f+e.x+e.y)/20), yaw = lastmillis/10.0f; - rendermodel(mdlname, ANIM_MAPMODEL|ANIM_LOOP|ANIM_DYNALLOC, 0, 0, vec(e.x, e.y, z+S(e.x, e.y)->floor+e.attr1), yaw, 0); + rendermodel(mdlname, ANIM_MAPMODEL|ANIM_LOOP|ANIM_DYNALLOC, 0, 0, vec(e.x, e.y, z+S(e.x, e.y)->floor+e.attr1), 0, yaw, 0); } void renderclip(entity &e) @@ -67,7 +67,7 @@ void rendermapmodels() { mapmodelinfo &mmi = getmminfo(e.attr2); if(!&mmi) continue; - rendermodel(mmi.name, ANIM_MAPMODEL|ANIM_LOOP, e.attr4, 0, vec(e.x, e.y, (float)S(e.x, e.y)->floor+mmi.zoff+e.attr3), e.attr1 / 4.0f, 0, 10.0f); + rendermodel(mmi.name, ANIM_MAPMODEL|ANIM_LOOP, e.attr4, 0, vec(e.x, e.y, (float)S(e.x, e.y)->floor+mmi.zoff+e.attr3), e.attr6, e.attr1 / 4.0f, e.attr5 / 4.0f, 10.0f); } } } @@ -218,7 +218,7 @@ void renderentities() if(e.type==CTF_FLAG) { defformatstring(path)("pickups/flags/%s", team_basestring(e.attr2)); - rendermodel(path, ANIM_FLAG|ANIM_LOOP, 0, 0, vec(e.x, e.y, (float)S(e.x, e.y)->floor), e.attr1 / 4.0f, 0, 120.0f); + rendermodel(path, ANIM_FLAG|ANIM_LOOP, 0, 0, vec(e.x, e.y, (float)S(e.x, e.y)->floor), 0, e.attr1 / 4.0f, 0, 120.0f); } else if((e.type == CLIP || e.type == PLCLIP) && showclips && !stenciling) renderclip(e); else if(e.type == MAPMODEL && showclips && showmodelclipping && !stenciling) @@ -261,7 +261,7 @@ void renderentities() { if(OUTBORD(f.actor->o.x, f.actor->o.y)) break; defformatstring(path)("pickups/flags/small_%s%s", m_ktf ? "" : team_basestring(i), m_htf ? "_htf" : m_ktf ? "ktf" : ""); - rendermodel(path, ANIM_FLAG|ANIM_START|ANIM_DYNALLOC, 0, 0, vec(f.actor->o).add(vec(0, 0, 0.3f+(sinf(lastmillis/100.0f)+1)/10)), lastmillis/2.5f, 0, 120.0f); + rendermodel(path, ANIM_FLAG|ANIM_START|ANIM_DYNALLOC, 0, 0, vec(f.actor->o).add(vec(0, 0, 0.3f+(sinf(lastmillis/100.0f)+1)/10)), 0, lastmillis/2.5f, 0, 120.0f); } break; case CTFF_INBASE: @@ -271,7 +271,7 @@ void renderentities() if(OUTBORD(f.pos.x, f.pos.y)) break; entity &e = *f.flagent; defformatstring(path)("pickups/flags/%s%s", m_ktf ? "" : team_basestring(i), m_htf ? "_htf" : m_ktf ? "ktf" : ""); - if(f.flagent->spawned) rendermodel(path, ANIM_FLAG|ANIM_LOOP, 0, 0, vec(f.pos.x, f.pos.y, f.state==CTFF_INBASE ? (float)S(int(f.pos.x), int(f.pos.y))->floor : f.pos.z), e.attr1 / 4.0f, 0, 120.0f); + if(f.flagent->spawned) rendermodel(path, ANIM_FLAG|ANIM_LOOP, 0, 0, vec(f.pos.x, f.pos.y, f.state==CTFF_INBASE ? (float)S(int(f.pos.x), int(f.pos.y))->floor : f.pos.z), 0, e.attr1 / 4.0f, 0, 120.0f); break; } case CTFF_IDLE: @@ -657,7 +657,7 @@ void syncentchanges(bool force) loopv(changedents) if(ents.inrange(changedents[i])) { entity &e = ents[changedents[i]]; - addmsg(SV_EDITENT, "ri9", changedents[i], e.type, e.x, e.y, e.z, e.attr1, e.attr2, e.attr3, e.attr4); + addmsg(SV_EDITENT, "ri9i3", changedents[i], e.type, e.x, e.y, e.z, e.attr1, e.attr2, e.attr3, e.attr4, e.attr5, e.attr6, e.attr7); } changedents.setsize(0); lastentsync = lastmillis; diff --git a/source/src/entity.h b/source/src/entity.h index a5ba5645..190aca85 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -1,12 +1,11 @@ enum // static entity types { NOTUSED = 0, // entity slot not in use in map (usually seen at deleted entities) - LIGHT, // lightsource, attr1 = radius, attr2 = intensity + LIGHT, // lightsource, attr1 = radius, attr2 = intensity (or attr2..4 = r-g-b) PLAYERSTART, // attr1 = angle, attr2 = team - I_CLIPS, I_AMMO, I_GRENADE, + I_CLIPS, I_AMMO, I_GRENADE, // attr1 = elevation I_HEALTH, I_HELMET, I_ARMOUR, I_AKIMBO, - // (helmet since mapversion 8) - MAPMODEL, // attr1 = angle, attr2 = idx, attr3 = elevation, attr4 = texture + MAPMODEL, // attr1 = angle, attr2 = idx, attr3 = elevation, attr4 = texture, attr5 = pitch, attr6 = roll CARROT, // attr1 = tag, attr2 = type LADDER, // attr1 = height CTF_FLAG, // attr1 = angle, attr2 = red/blue @@ -27,7 +26,10 @@ struct persistent_entity // map entity short attr1; uchar type; // type is one of the above uchar attr2, attr3, attr4; - persistent_entity(short x, short y, short z, uchar type, short attr1, uchar attr2, uchar attr3, uchar attr4) : x(x), y(y), z(z), attr1(attr1), type(type), attr2(attr2), attr3(attr3), attr4(attr4) {} + short attr5; + char attr6; + unsigned char attr7; + persistent_entity(short x, short y, short z, uchar type, short attr1, uchar attr2, uchar attr3, uchar attr4) : x(x), y(y), z(z), attr1(attr1), type(type), attr2(attr2), attr3(attr3), attr4(attr4), attr5(0), attr6(0), attr7(0) {} persistent_entity() {} }; diff --git a/source/src/md2.h b/source/src/md2.h index 0d6113bc..19367d34 100644 --- a/source/src/md2.h +++ b/source/src/md2.h @@ -177,7 +177,7 @@ struct md2 : vertmodel } }; - void render(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, float pitch, dynent *d, modelattach *a, float scale) + void render(int anim, int varseed, float speed, int basetime, const vec &o, float roll, float yaw, float pitch, dynent *d, modelattach *a, float scale) { if(!loaded) return; @@ -194,10 +194,12 @@ struct md2 : vertmodel shadowdir = vec(0, 1/SQRT2, -1/SQRT2); shadowdir.rotate_around_z((-shadowyaw-yaw-180.0f)*RAD); shadowdir.rotate_around_y(-pitch*RAD); + shadowdir.rotate_around_x(-roll*RAD); (shadowpos = shadowdir).mul(shadowdist); } modelpos = o; + modelroll = roll; modelyaw = yaw; modelpitch = pitch; @@ -206,6 +208,7 @@ struct md2 : vertmodel matrixstack[0].translate(o); matrixstack[0].rotate_around_z((yaw+180)*RAD); matrixstack[0].rotate_around_y(-pitch*RAD); + matrixstack[0].rotate_around_x(roll*RAD); if(anim&ANIM_MIRROR || scale!=1) matrixstack[0].scale(scale, anim&ANIM_MIRROR ? -scale : scale, scale); parts[0]->render(anim, varseed, speed, basetime, d); @@ -220,7 +223,7 @@ struct md2 : vertmodel if(!m) continue; m->parts[0]->index = parts.length()+i; m->setskin(); - m->render(anim, varseed, speed, basetime, o, yaw, pitch, d, NULL, scale); + m->render(anim, varseed, speed, basetime, o, roll, yaw, pitch, d, NULL, scale); } if(d) d->lastrendered = lastmillis; diff --git a/source/src/md3.h b/source/src/md3.h index 1a729f6d..b45ac039 100644 --- a/source/src/md3.h +++ b/source/src/md3.h @@ -153,7 +153,7 @@ struct md3 : vertmodel } }; - void render(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, float pitch, dynent *d, modelattach *a, float scale) + void render(int anim, int varseed, float speed, int basetime, const vec &o, float roll, float yaw, float pitch, dynent *d, modelattach *a, float scale) { if(!loaded) return; @@ -177,10 +177,12 @@ struct md3 : vertmodel shadowdir = vec(0, 1/SQRT2, -1/SQRT2); shadowdir.rotate_around_z((-shadowyaw-yaw-180.0f)*RAD); shadowdir.rotate_around_y(-pitch*RAD); + shadowdir.rotate_around_x(-roll*RAD); (shadowpos = shadowdir).mul(shadowdist); } modelpos = o; + modelroll = roll; modelyaw = yaw; modelpitch = pitch; @@ -189,6 +191,7 @@ struct md3 : vertmodel matrixstack[0].translate(o); matrixstack[0].rotate_around_z((yaw+180)*RAD); matrixstack[0].rotate_around_y(-pitch*RAD); + matrixstack[0].rotate_around_x(roll*RAD); if(anim&ANIM_MIRROR || scale!=1) matrixstack[0].scale(scale, anim&ANIM_MIRROR ? -scale : scale, scale); parts[0]->render(anim, varseed, speed, basetime, d); diff --git a/source/src/menus.cpp b/source/src/menus.cpp index 335e512c..08500203 100644 --- a/source/src/menus.cpp +++ b/source/src/menus.cpp @@ -1208,7 +1208,7 @@ void rendermenumdl() a[0].name = "weapons/subgun/world"; a[0].tag = "tag_weapon"; } - rendermodel(isplayermodel ? "playermodels" : m.mdl, m.anim|ANIM_DYNALLOC, tex, -1, pos, yaw, 0, 0, 0, NULL, a, m.scale ? m.scale/25.0f : 1.0f); + rendermodel(isplayermodel ? "playermodels" : m.mdl, m.anim|ANIM_DYNALLOC, tex, -1, pos, 0, yaw, 0, 0, 0, NULL, a, m.scale ? m.scale/25.0f : 1.0f); glPopMatrix(); } diff --git a/source/src/model.h b/source/src/model.h index 1db36b94..f0d9e91d 100644 --- a/source/src/model.h +++ b/source/src/model.h @@ -56,7 +56,7 @@ struct model virtual void cleanup() = 0; - virtual void render(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, float pitch, dynent *d, modelattach *a = NULL, float scale = 1.0f) = 0; + virtual void render(int anim, int varseed, float speed, int basetime, const vec &o, float roll, float yaw, float pitch, dynent *d, modelattach *a = NULL, float scale = 1.0f) = 0; virtual void setskin(int tex = 0) = 0; virtual void genshadows(float height, float rad) {} diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index 4e1d026d..9efef33e 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -329,7 +329,7 @@ static const int msgsizes[] = // size inclusive message token, 0 f SV_SHOOT, 0, SV_EXPLODE, 0, SV_SUICIDE, 1, SV_AKIMBO, 2, SV_RELOAD, 3, SV_AUTHT, 0, SV_AUTHREQ, 0, SV_AUTHTRY, 0, SV_AUTHANS, 0, SV_AUTHCHAL, 0, SV_GIBDIED, 5, SV_DIED, 5, SV_GIBDAMAGE, 7, SV_DAMAGE, 7, SV_HITPUSH, 6, SV_SHOTFX, 6, SV_THROWNADE, 8, SV_TRYSPAWN, 1, SV_SPAWNSTATE, 23, SV_SPAWN, 3, SV_SPAWNDENY, 2, SV_FORCEDEATH, 2, SV_RESUME, 0, - SV_DISCSCORES, 0, SV_TIMEUP, 3, SV_EDITENT, 10, SV_ITEMACC, 2, + SV_DISCSCORES, 0, SV_TIMEUP, 3, SV_EDITENT, 13, SV_ITEMACC, 2, SV_MAPCHANGE, 0, SV_ITEMSPAWN, 2, SV_ITEMPICKUP, 2, SV_PING, 2, SV_PONG, 2, SV_CLIENTPING, 2, SV_GAMEMODE, 2, SV_EDITMODE, 2, SV_EDITH, 7, SV_EDITT, 7, SV_EDITS, 6, SV_EDITD, 6, SV_EDITE, 6, SV_NEWMAP, 2, diff --git a/source/src/protos.h b/source/src/protos.h index ead6f6b3..97db2201 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -732,7 +732,7 @@ extern void writesoundconfig(stream *f); */ // rendermodel -extern void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, float yaw, float pitch, float speed = 0, int basetime = 0, playerent *d = NULL, modelattach *a = NULL, float scale = 1.0f); +extern void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, float roll, float yaw, float pitch, float speed = 0, int basetime = 0, playerent *d = NULL, modelattach *a = NULL, float scale = 1.0f); extern void startmodelbatches(); extern void endmodelbatches(bool flush = true); extern void clearmodelbatches(); diff --git a/source/src/rendermodel.cpp b/source/src/rendermodel.cpp index f943018d..99ee4d25 100644 --- a/source/src/rendermodel.cpp +++ b/source/src/rendermodel.cpp @@ -404,7 +404,7 @@ struct batchedmodel { vec o; int anim, varseed, tex; - float yaw, pitch, speed; + float roll, yaw, pitch, speed; int basetime; playerent *d; int attached; @@ -450,7 +450,7 @@ void renderbatchedmodel(model *m, batchedmodel &b) if(stenciling) { - m->render(b.anim|ANIM_NOSKIN, b.varseed, b.speed, b.basetime, b.o, b.yaw, b.pitch, b.d, a, b.scale); + m->render(b.anim|ANIM_NOSKIN, b.varseed, b.speed, b.basetime, b.o, b.roll, b.yaw, b.pitch, b.d, a, b.scale); return; } @@ -467,7 +467,7 @@ void renderbatchedmodel(model *m, batchedmodel &b) if(b.anim&ANIM_TRANSLUCENT) { glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - m->render(b.anim|ANIM_NOSKIN, b.varseed, b.speed, b.basetime, b.o, b.yaw, b.pitch, b.d, a, b.scale); + m->render(b.anim|ANIM_NOSKIN, b.varseed, b.speed, b.basetime, b.o, b.roll, b.yaw, b.pitch, b.d, a, b.scale); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthFunc(GL_LEQUAL); @@ -479,7 +479,7 @@ void renderbatchedmodel(model *m, batchedmodel &b) glColor4f(color[0], color[1], color[2], m->translucency); } - m->render(b.anim, b.varseed, b.speed, b.basetime, b.o, b.yaw, b.pitch, b.d, a, b.scale); + m->render(b.anim, b.varseed, b.speed, b.basetime, b.o, b.roll, b.yaw, b.pitch, b.d, a, b.scale); if(b.anim&ANIM_TRANSLUCENT) { @@ -593,7 +593,7 @@ const int dbgmbatch = 0; //VAR(dbgmbatch, 0, 0, 1); VARP(popdeadplayers, 0, 0, 1); -void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, float yaw, float pitch, float speed, int basetime, playerent *d, modelattach *a, float scale) +void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, float roll, float yaw, float pitch, float speed, int basetime, playerent *d, modelattach *a, float scale) { if(popdeadplayers && d && a) { @@ -637,6 +637,7 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl b.anim = anim; b.varseed = varseed; b.tex = tex; + b.roll = roll; b.yaw = yaw; b.pitch = pitch; b.speed = speed; @@ -651,7 +652,7 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl if(stenciling) { m->startrender(); - m->render(anim|ANIM_NOSKIN, varseed, speed, basetime, o, yaw, pitch, d, a, scale); + m->render(anim|ANIM_NOSKIN, varseed, speed, basetime, o, 0, yaw, pitch, d, a, scale); m->endrender(); return; } @@ -690,7 +691,7 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl if(anim&ANIM_TRANSLUCENT) { glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - m->render(anim|ANIM_NOSKIN, varseed, speed, basetime, o, yaw, pitch, d, a, scale); + m->render(anim|ANIM_NOSKIN, varseed, speed, basetime, o, 0, yaw, pitch, d, a, scale); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthFunc(GL_LEQUAL); @@ -702,7 +703,7 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl glColor4f(color[0], color[1], color[2], m->translucency); } - m->render(anim, varseed, speed, basetime, o, yaw, pitch, d, a, scale); + m->render(anim, varseed, speed, basetime, o, 0, yaw, pitch, d, a, scale); if(anim&ANIM_TRANSLUCENT) { @@ -911,7 +912,7 @@ void renderclient(playerent *d, const char *mdlname, const char *vwepname, int t anim |= ANIM_TRANSLUCENT; // see through followed player if(stenciling) return; } - rendermodel(mdlname, anim|ANIM_DYNALLOC, tex, 1.5f, o, d->yaw+90, d->pitch/4, speed, basetime, d, a); + rendermodel(mdlname, anim|ANIM_DYNALLOC, tex, 1.5f, o, 0, d->yaw+90, d->pitch/4, speed, basetime, d, a); if(!stenciling && !reflecting && !refracting) { if(isteam(player1->team, d->team)) renderaboveheadicon(d); diff --git a/source/src/tools.cpp b/source/src/tools.cpp index 7209b5f5..fd73bbc5 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -99,7 +99,7 @@ mapstats *loadmapstats(const char *filename, bool getlayout) entposs = new short[s.hdr.numents * 3]; loopi(s.hdr.numents) { - f->read(&e, sizeof(persistent_entity)); + f->read(&e, s.hdr.version < 10 ? 12 : sizeof(persistent_entity)); lilswap((short *)&e, 4); transformoldentities(s.hdr.version, e.type); if(e.type == PLAYERSTART && (e.attr2 == 0 || e.attr2 == 1 || e.attr2 == 100)) s.spawns[e.attr2 == 100 ? 2 : e.attr2]++; diff --git a/source/src/vertmodel.h b/source/src/vertmodel.h index b705c0ec..90d565a1 100644 --- a/source/src/vertmodel.h +++ b/source/src/vertmodel.h @@ -15,7 +15,7 @@ const int dbgvlight = 0; VARP(mdldlist, 0, 1, 1); vec modelpos; -float modelyaw, modelpitch; +float modelroll, modelyaw, modelpitch; struct vertmodel : model { @@ -116,7 +116,7 @@ struct vertmodel : model float t; int lastcalclight; vec pos; - float yaw, pitch; + float roll, yaw, pitch; lightvert *verts() { return (lightvert *)getdata(); } int numverts() { return int((size - sizeof(lightcacheentry)) / sizeof(lightvert)); } @@ -367,7 +367,7 @@ __attribute__((optimize(2))) int cachelen = 0; for(; d != lightcache.end(); d = d->next, cachelen++) { - if(d->lastcalclight != lastcalclight || d->pos != modelpos || d->yaw != modelyaw || d->pitch != modelpitch || d->cur != cur) continue; + if(d->lastcalclight != lastcalclight || d->pos != modelpos || d->roll != modelroll || d->yaw != modelyaw || d->pitch != modelpitch || d->cur != cur) continue; if(prev) { if(d->prev == *prev && d->t == ai_t) return d; @@ -387,6 +387,7 @@ __attribute__((optimize(2))) lightcache.addfirst(d); d->lastcalclight = lastcalclight; d->pos = modelpos; + d->roll = modelroll; d->yaw = modelyaw; d->pitch = modelpitch; d->cur = cur; diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index c3163858..5d5acabf 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -543,7 +543,7 @@ void renderbounceents() } } path(model); - rendermodel(model, anim|ANIM_LOOP|ANIM_DYNALLOC, 0, 1.1f, o, p->yaw+90, p->pitch, 0, basetime); + rendermodel(model, anim|ANIM_LOOP|ANIM_DYNALLOC, 0, 1.1f, o, 0, p->yaw+90, p->pitch, 0, basetime); } } @@ -907,7 +907,7 @@ void weapon::renderhudmodel(int lastaction, int index) defformatstring(path)("weapons/%s", identexists(widn)?getalias(widn):info.modelname); bool emit = (wm.anim&ANIM_INDEX)==ANIM_GUN_SHOOT && (lastmillis - lastaction) < flashtime(); // bool emit = (wm.anim&ANIM_INDEX)==ANIM_GUN_SHOOT && (lastmillis - p->lastaction) < flashtime(); - rendermodel(path, wm.anim|ANIM_DYNALLOC|(righthanded==index ? ANIM_MIRROR : 0)|(emit ? ANIM_PARTICLE : 0), 0, -1, wm.pos, p->yaw+90, p->pitch+wm.k_rot, 40.0f, wm.basetime, NULL, NULL, 1.28f); + rendermodel(path, wm.anim|ANIM_DYNALLOC|(righthanded==index ? ANIM_MIRROR : 0)|(emit ? ANIM_PARTICLE : 0), 0, -1, wm.pos, 0, p->yaw+90, p->pitch+wm.k_rot, 40.0f, wm.basetime, NULL, NULL, 1.28f); } void weapon::updatetimers(int millis) diff --git a/source/src/world.cpp b/source/src/world.cpp index cf26eded..98b6735c 100644 --- a/source/src/world.cpp +++ b/source/src/world.cpp @@ -178,6 +178,9 @@ void entproperty(int prop, int amount) case 1: e.attr2 += amount; break; case 2: e.attr3 += amount; break; case 3: e.attr4 += amount; break; + case 4: e.attr5 += amount; break; + case 5: e.attr6 += amount; break; + case 6: e.attr7 += amount; break; case 11: e.x += amount; break; case 12: e.y += amount; break; case 13: e.z += amount; break; @@ -246,7 +249,7 @@ void delent() } ents[n].type = NOTUSED; - addmsg(SV_EDITENT, "ri9", n, NOTUSED, 0, 0, 0, 0, 0, 0, 0); + addmsg(SV_EDITENT, "ri9i3", n, NOTUSED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); switch(t) { @@ -299,7 +302,7 @@ entity *newentity(int index, int x, int y, int z, char *what, int v1, int v2, in break; } syncentchanges(true); - addmsg(SV_EDITENT, "ri9", index<0 ? ents.length() : index, type, e.x, e.y, e.z, e.attr1, e.attr2, e.attr3, e.attr4); + addmsg(SV_EDITENT, "ri9i3", index<0 ? ents.length() : index, type, e.x, e.y, e.z, e.attr1, e.attr2, e.attr3, e.attr4, e.attr5, e.attr6, e.attr7); e.spawned = true; int oldtype = type; if(index<0) ents.add(e); diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index eb202b7c..05a7c676 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -552,7 +552,7 @@ void save_world(char *mname, bool skipoptimise, bool addcomfort) int writeextra = 0; if(hx.maxlen) tmp.headersize += writeextra = clamp(hx.maxlen, 0, MAXHEADEREXTRA); if(writeextra || skipoptimise) tmp.version = 10; // 9 and 10 are the same, but in 10 the headersize is reliable - if we don't need it, stick to 9 - bool oldmapmodelscaling = tmp.version < 10; + bool oldentityformat = tmp.version < 10; tmp.maprevision += advancemaprevision; DEBUG("version " << tmp.version << " headersize " << tmp.headersize << " entities " << tmp.numents << " factor " << tmp.sfactor << " revision " << tmp.maprevision); lilswap(&tmp.version, 4); // version, headersize, sfactor, numents @@ -568,9 +568,10 @@ void save_world(char *mname, bool skipoptimise, bool addcomfort) { if(!ne--) break; persistent_entity tmp = ents[i]; - if(oldmapmodelscaling && tmp.type == MAPMODEL) tmp.attr1 = tmp.attr1 / 4; + if(oldentityformat && tmp.type == MAPMODEL) tmp.attr1 = tmp.attr1 / 4; lilswap((short *)&tmp, 4); - f->write(&tmp, sizeof(persistent_entity)); + lilswap(&tmp.attr5, 1); + f->write(&tmp, oldentityformat ? 12 : sizeof(persistent_entity)); } } @@ -694,11 +695,14 @@ bool load_world(char *mname) // still supports all map formats that have ents.shrink(0); loopi(3) numspawn[i] = 0; loopi(2) numflagspawn[i] = 0; + bool oldentityformat = hdr.version < 10; loopi(hdr.numents) { entity &e = ents.add(); - f->read(&e, sizeof(persistent_entity)); + f->read(&e, oldentityformat ? 12 : sizeof(persistent_entity)); lilswap((short *)&e, 4); + if(oldentityformat) e.attr5 = e.attr6 = e.attr7 = 0; + else lilswap(&e.attr5, 1); e.spawned = false; if(e.type == LIGHT) { @@ -706,7 +710,7 @@ bool load_world(char *mname) // still supports all map formats that have if(e.attr1>32) e.attr1 = 32; // 12_03 and below } transformoldentities(hdr.version, e.type); - if(hdr.version < 10) + if(oldentityformat) { switch(e.type) { @@ -990,7 +994,7 @@ struct xmap loopv(ents) // entities are stored as plain text - you may edit them { persistent_entity &e = ents[i]; - f->printf("restorexmap ent %d %d %d %d %d %d %d %d // %s\n", e.type, e.x, e.y, e.z, e.attr1, e.attr2, e.attr3, e.attr4, e.type >= 0 && e.type < MAXENTTYPES ? entnames[e.type] : "unknown"); + f->printf("restorexmap ent %d %d %d %d %d %d %d %d %d %d %d // %s\n", e.type, e.x, e.y, e.z, e.attr1, e.attr2, e.attr3, e.attr4, e.attr5, e.attr6, e.attr7, e.type >= 0 && e.type < MAXENTTYPES ? entnames[e.type] : "unknown"); } if(mapconfig.length()) { @@ -1131,7 +1135,7 @@ COMMANDF(xmap_restore, "s", (const char *nick) // use xmap as current map void restorexmap(char **args, int numargs) // read an xmap from a cubescript file { const char *cmdnames[] = { "version", "names", "sizes", "header", "world", "headerextra", "ent", "config", "position", "" }; - const char cmdnumarg[] = { 3, 2, 3, 0, 0, 1, 8, 1, 5 }; + const char cmdnumarg[] = { 3, 2, 3, 0, 0, 1, 11, 1, 5 }; if(!xmjigsaw || numargs < 1) return; // { conoutf("restorexmap out of context"); return; } bool abort = false; @@ -1173,9 +1177,9 @@ void restorexmap(char **args, int numargs) // read an xmap from a cubescript f case 6: // ent { persistent_entity &e = xmjigsaw->ents.add(); - int a[8]; - loopi(8) a[i] = ATOI(args[i + 1]); - e.type = a[0]; e.x = a[1]; e.y = a[2]; e.z = a[3]; e.attr1 = a[4]; e.attr2 = a[5]; e.attr3 = a[6]; e.attr4 = a[7]; + int a[11]; + loopi(11) a[i] = ATOI(args[i + 1]); + e.type = a[0]; e.x = a[1]; e.y = a[2]; e.z = a[3]; e.attr1 = a[4]; e.attr2 = a[5]; e.attr3 = a[6]; e.attr4 = a[7]; e.attr5 = a[8]; e.attr6 = a[9]; e.attr7 = a[10]; break; } case 7: // config