+ }
+ _setmodel(this.weaponchild, W_Model(strcat("v_", name, ".md3")));
+ setattachment(this.weaponchild, this, t);
+ }
+ else
+ {
+ if (this.weaponchild) remove(this.weaponchild);
+ this.weaponchild = NULL;
+ }
+
+ setorigin(this, '0 0 0');
+ this.angles = '0 0 0';
+ this.frame = 0;
+#ifdef SVQC
+ this.viewmodelforclient = NULL;
+#else
+ this.renderflags &= ~RF_VIEWMODEL;
+#endif
+ if (v_shot_idx) // v_ model attached to invisible h_ model
+ {
+ this.movedir = gettaginfo(this.weaponchild, v_shot_idx);
+ }
+ else
+ {
+ int idx;
+ if ((idx = gettagindex(this, "shot")) || (idx = gettagindex(this, "tag_shot")))
+ {
+ this.movedir = gettaginfo(this, idx);
+ }
+ else
+ {
+ LOG_WARNINGF("weapon model %s does not support the 'shot' tag, will display shots TOTALLY wrong\n",
+ this.model);
+ this.movedir = '0 0 0';
+ }
+ }
+ {
+ int idx = 0;
+ // v_ model attached to invisible h_ model
+ if (this.weaponchild
+ && ((idx = gettagindex(this.weaponchild, "shell")) || (idx = gettagindex(this.weaponchild, "tag_shell"))))
+ {
+ this.spawnorigin = gettaginfo(this.weaponchild, idx);
+ }
+ else if ((idx = gettagindex(this, "shell")) || (idx = gettagindex(this, "tag_shell")))
+ {
+ this.spawnorigin = gettaginfo(this, idx);
+ }
+ else
+ {
+ LOG_WARNINGF("weapon model %s does not support the 'shell' tag, will display casings wrong\n",
+ this.model);
+ this.spawnorigin = this.movedir;
+ }
+ }
+ if (v_shot_idx)
+ {
+ this.oldorigin = '0 0 0'; // use regular attachment
+ }
+ else
+ {
+ int idx;
+ if (this.weaponchild)
+ (idx = gettagindex(this, "weapon")) || (idx = gettagindex(this, "tag_weapon"));
+ else
+ (idx = gettagindex(this, "handle")) || (idx = gettagindex(this, "tag_handle"));
+ if (idx)
+ {
+ this.oldorigin = this.movedir - gettaginfo(this, idx);
+ }
+ else
+ {
+ LOG_WARNINGF(
+ "weapon model %s does not support the 'handle' tag "
+ "and neither does the v_ model support the 'shot' tag, "
+ "will display muzzle flashes TOTALLY wrong\n",
+ this.model);
+ this.oldorigin = '0 0 0'; // there is no way to recover from this
+ }
+ }
+
+#ifdef SVQC
+ this.viewmodelforclient = this.owner;
+#else
+ this.renderflags |= RF_VIEWMODEL;
+#endif
+ }
+
+ this.view_ofs = '0 0 0';
+
+ if (this.movedir.x >= 0)
+ {
+#ifdef SVQC
+ int algn = this.owner.cvar_cl_gunalign;
+#else
+ int algn = autocvar_cl_gunalign;
+#endif
+ vector v = this.movedir;
+ this.movedir = shotorg_adjust(v, false, false, algn);
+ this.view_ofs = shotorg_adjust(v, false, true, algn) - v;
+ }
+ int compressed_shotorg = compressShotOrigin(this.movedir);
+ // make them match perfectly
+#ifdef SVQC
+ this.movedir = decompressShotOrigin(this.owner.stat_shotorg = compressed_shotorg);
+#else
+ this.movedir = decompressShotOrigin(compressed_shotorg);
+#endif
+
+ this.spawnorigin += this.view_ofs; // offset the casings origin by the same amount
+
+ // check if an instant weapon switch occurred
+ setorigin(this, this.view_ofs);
+ // reset animstate now
+ this.wframe = WFRAME_IDLE;
+ setanim(this, this.anim_idle, true, false, true);
+}
+#endif
+
+#ifndef MENUQC
+
+REGISTER_NET_TEMP(wframe, bool isNew)
+#ifdef CSQC
+{
+ vector a;
+ a.x = ReadCoord();
+ a.y = ReadCoord();
+ a.z = ReadCoord();
+ bool restartanim = ReadByte();
+ setanim(viewmodel, a, restartanim == false, restartanim, restartanim);
+}
+#endif
+
+#ifdef SVQC
+void wframe_send(entity actor, vector a, bool restartanim)
+{
+ if (!IS_REAL_CLIENT(actor)) return;
+ int channel = MSG_ONE;
+ msg_entity = actor;
+ WriteHeader(channel, wframe);
+ WriteCoord(channel, a.x);
+ WriteCoord(channel, a.y);
+ WriteCoord(channel, a.z);
+ WriteByte(channel, restartanim);
+}
+#endif
+
+#endif
+