From ae82b6b22ec2c5a61581292b2726f656964471ad Mon Sep 17 00:00:00 2001 From: ac-stef Date: Thu, 7 May 2015 11:11:24 +0200 Subject: [PATCH] add attr5..7, add mapmodel pitch and roll Keys 5, 6 and 7 (in combination with the scrollwheel) can be used to alter the new entity attributes. Pressing editmeta (LCTRL by default) speeds up the scrolling. (Parts of the roll code are borrowed from Alejandro V. Garcia's commit "Model rotations, experimental" from January 2013) Note: coop edit is now broken between "next" and older clients, but I don't want to bump the protocol just yet. --- config/resetbinds.cfg | 13 ++++++++----- config/scripts.cfg | 13 ++++++++----- source/src/clients2c.cpp | 3 +++ source/src/editing.cpp | 2 +- source/src/entities.cpp | 12 ++++++------ source/src/entity.h | 12 +++++++----- source/src/md2.h | 7 +++++-- source/src/md3.h | 5 ++++- source/src/menus.cpp | 2 +- source/src/model.h | 2 +- source/src/protocol.cpp | 2 +- source/src/protos.h | 2 +- source/src/rendermodel.cpp | 19 ++++++++++--------- source/src/tools.cpp | 2 +- source/src/vertmodel.h | 7 ++++--- source/src/weapon.cpp | 4 ++-- source/src/world.cpp | 7 +++++-- source/src/worldio.cpp | 24 ++++++++++++++---------- 18 files changed, 82 insertions(+), 56 deletions(-) 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