return true;
}
-/*
- * supported formats:
- *
- * 1. simple animated model, muzzle flash handling on h_ model:
- * h_tuba.dpm, h_tuba.dpm.framegroups - invisible model controlling the animation
- * tags:
- * shot = muzzle end (shot origin, also used for muzzle flashes)
- * shell = casings ejection point (must be on the right hand side of the gun)
- * weapon = attachment for v_tuba.md3
- * v_tuba.md3 - first and third person model
- * g_tuba.md3 - pickup model
- *
- * 2. simple animated model, muzzle flash handling on v_ model:
- * h_tuba.dpm, h_tuba.dpm.framegroups - invisible model controlling the animation
- * tags:
- * weapon = attachment for v_tuba.md3
- * v_tuba.md3 - first and third person model
- * tags:
- * shot = muzzle end (shot origin, also used for muzzle flashes)
- * shell = casings ejection point (must be on the right hand side of the gun)
- * g_tuba.md3 - pickup model
- *
- * 3. fully animated model, muzzle flash handling on h_ model:
- * h_tuba.dpm, h_tuba.dpm.framegroups - animated first person model
- * tags:
- * shot = muzzle end (shot origin, also used for muzzle flashes)
- * shell = casings ejection point (must be on the right hand side of the gun)
- * handle = corresponding to the origin of v_tuba.md3 (used for muzzle flashes)
- * v_tuba.md3 - third person model
- * g_tuba.md3 - pickup model
- *
- * 4. fully animated model, muzzle flash handling on v_ model:
- * h_tuba.dpm, h_tuba.dpm.framegroups - animated first person model
- * tags:
- * shot = muzzle end (shot origin)
- * shell = casings ejection point (must be on the right hand side of the gun)
- * v_tuba.md3 - third person model
- * tags:
- * shot = muzzle end (for muzzle flashes)
- * g_tuba.md3 - pickup model
- */
-
-// writes:
-// this.origin, this.angles
-// this.weaponentity
-// this.movedir, this.view_ofs
-// attachment stuff
-// anim stuff
-// to free:
-// call again with ""
-// remove the ent
-void CL_WeaponEntity_SetModel(entity this, .entity weaponentity, string name)
-{
- if (name != "")
- {
- // if there is a child entity, hide it until we're sure we use it
- if (this.(weaponentity)) this.(weaponentity).model = "";
- _setmodel(this, W_Model(strcat("v_", name, ".md3")));
- int v_shot_idx = gettagindex(this, "shot"); // used later
- if (!v_shot_idx) v_shot_idx = gettagindex(this, "tag_shot");
-
- _setmodel(this, W_Model(strcat("h_", name, ".iqm")));
- // preset some defaults that work great for renamed zym files (which don't need an animinfo)
- this.anim_fire1 = animfixfps(this, '0 1 0.01', '0 0 0');
- this.anim_fire2 = animfixfps(this, '1 1 0.01', '0 0 0');
- this.anim_idle = animfixfps(this, '2 1 0.01', '0 0 0');
- this.anim_reload = animfixfps(this, '3 1 0.01', '0 0 0');
-
- // if we have a "weapon" tag, let's attach the v_ model to it ("invisible hand" style model)
- // if we don't, this is a "real" animated model
- if (gettagindex(this, "weapon"))
- {
- if (!this.(weaponentity)) this.(weaponentity) = new(weaponentity);
- _setmodel(this.(weaponentity), W_Model(strcat("v_", name, ".md3")));
- setattachment(this.(weaponentity), this, "weapon");
- }
- else if (gettagindex(this, "tag_weapon"))
- {
- if (!this.(weaponentity)) this.(weaponentity) = new(weaponentity);
- _setmodel(this.(weaponentity), W_Model(strcat("v_", name, ".md3")));
- setattachment(this.(weaponentity), this, "tag_weapon");
- }
- else
- {
- if (this.(weaponentity)) remove(this.(weaponentity));
- this.(weaponentity) = NULL;
- }
-
- setorigin(this, '0 0 0');
- this.angles = '0 0 0';
- this.frame = 0;
- this.viewmodelforclient = NULL;
-
- float idx;
-
- if (v_shot_idx) // v_ model attached to invisible h_ model
- {
- this.movedir = gettaginfo(this.(weaponentity), v_shot_idx);
- }
- else
- {
- idx = gettagindex(this, "shot");
- if (!idx) idx = gettagindex(this, "tag_shot");
- if (idx)
- {
- this.movedir = gettaginfo(this, idx);
- }
- else
- {
- LOG_INFO("WARNING: weapon model ", this.model,
- " does not support the 'shot' tag, will display shots TOTALLY wrong\n");
- this.movedir = '0 0 0';
- }
- }
-
- if (this.(weaponentity)) // v_ model attached to invisible h_ model
- {
- idx = gettagindex(this.(weaponentity), "shell");
- if (!idx) idx = gettagindex(this.(weaponentity), "tag_shell");
- if (idx) this.spawnorigin = gettaginfo(this.(weaponentity), idx);
- }
- else
- {
- idx = 0;
- }
- if (!idx)
- {
- idx = gettagindex(this, "shell");
- if (!idx) idx = gettagindex(this, "tag_shell");
- if (idx)
- {
- this.spawnorigin = gettaginfo(this, idx);
- }
- else
- {
- LOG_INFO("WARNING: weapon model ", this.model,
- " does not support the 'shell' tag, will display casings wrong\n");
- this.spawnorigin = this.movedir;
- }
- }
-
- if (v_shot_idx)
- {
- this.oldorigin = '0 0 0'; // use regular attachment
- }
- else
- {
- if (this.(weaponentity))
- {
- idx = gettagindex(this, "weapon");
- if (!idx) idx = gettagindex(this, "tag_weapon");
- }
- else
- {
- idx = gettagindex(this, "handle");
- if (!idx) idx = gettagindex(this, "tag_handle");
- }
- if (idx)
- {
- this.oldorigin = this.movedir - gettaginfo(this, idx);
- }
- else
- {
- LOG_INFO("WARNING: weapon model ", this.model,
- " does not support the 'handle' tag and neither does the v_ model support the 'shot' tag, will display muzzle flashes TOTALLY wrong\n");
- this.oldorigin = '0 0 0'; // there is no way to recover from this
- }
- }
-
- this.viewmodelforclient = this.owner;
- }
- else
- {
- this.model = "";
- if (this.(weaponentity)) remove(this.(weaponentity));
- this.(weaponentity) = NULL;
- this.movedir = '0 0 0';
- this.spawnorigin = '0 0 0';
- this.oldorigin = '0 0 0';
- this.anim_fire1 = '0 1 0.01';
- this.anim_fire2 = '0 1 0.01';
- this.anim_idle = '0 1 0.01';
- this.anim_reload = '0 1 0.01';
- }
-
- this.view_ofs = '0 0 0';
-
- if (this.movedir.x >= 0)
- {
- vector v0 = this.movedir;
- this.movedir = shotorg_adjust(v0, false, false, this.owner.cvar_cl_gunalign);
- this.view_ofs = shotorg_adjust(v0, false, true, this.owner.cvar_cl_gunalign) - v0;
- }
- this.owner.stat_shotorg = compressShotOrigin(this.movedir);
- this.movedir = decompressShotOrigin(this.owner.stat_shotorg); // make them match perfectly
-
- 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);
-}
-
-vector CL_Weapon_GetShotOrg(float wpn)
+vector CL_Weapon_GetShotOrg(int wpn)
{
- entity wi = get_weaponinfo(wpn);
+ entity wi = Weapons_from(wpn);
entity e = spawn();
- .entity weaponentity = weaponentities[0];
- CL_WeaponEntity_SetModel(e, weaponentity, wi.mdl);
+ CL_WeaponEntity_SetModel(e, wi.mdl);
vector ret = e.movedir;
- CL_WeaponEntity_SetModel(e, weaponentity, "");
+ CL_WeaponEntity_SetModel(e, "");
remove(e);
return ret;
}
SELFPARAM();
this.nextthink = time;
if (intermission_running) this.frame = this.anim_idle.x;
- int slot = 0; // TODO: unhardcode
- if (this.owner.weaponentity[slot] != this)
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+ if (this.owner.(weaponentity) != this)
{
- if (this.(weaponentity)) remove(this.(weaponentity));
+ // owner has new gun; remove self
+ if (this.weaponchild) remove(this.weaponchild);
remove(this);
return;
}
this.angles = '0 0 0';
- float f = (this.owner.weapon_nextthink - time);
+ float f = this.owner.weapon_nextthink - time;
if (this.state == WS_RAISE && !intermission_running)
{
- entity newwep = get_weaponinfo(this.owner.switchweapon);
+ entity newwep = Weapons_from(this.owner.switchweapon);
f = f * g_weaponratefactor / max(f, newwep.switchdelay_raise);
this.angles_x = -90 * f * f;
}
}
// spawning weaponentity for client
- void CL_SpawnWeaponentity(entity actor, int slot)
-void CL_SpawnWeaponentity(entity e, .entity weaponentity)
++void CL_SpawnWeaponentity(entity actor, .entity weaponentity)
{
- entity view = actor.weaponentity[slot] = new(weaponentity);
- entity view = e.(weaponentity) = new(weaponentity);
++ entity view = actor.(weaponentity) = new(weaponentity);
view.solid = SOLID_NOT;
- view.owner = e;
+ view.owner = actor;
setmodel(view, MDL_Null); // precision set when changed
setorigin(view, '0 0 0');
- view.angles = '0 0 0';
- view.viewmodelforclient = e;
- view.flags = 0;
view.think = CL_Weaponentity_Think;
- view.customizeentityforclient = CL_Weaponentity_CustomizeEntityForClient;
view.nextthink = time;
+ view.viewmodelforclient = actor;
+ view.customizeentityforclient = CL_Weaponentity_CustomizeEntityForClient;
- if (slot == 0)
+ if (weaponentity == weaponentities[0])
{
- entity exterior = e.exteriorweaponentity = spawn();
- exterior.classname = "exteriorweaponentity";
+ entity exterior = actor.exteriorweaponentity = new(exteriorweaponentity);
exterior.solid = SOLID_NOT;
- exterior.exteriorweaponentity = exterior;
- exterior.owner = e;
+ exterior.owner = actor;
setorigin(exterior, '0 0 0');
- exterior.angles = '0 0 0';
exterior.think = CL_ExteriorWeaponentity_Think;
exterior.nextthink = time;
return false;
}
- void weapon_thinkf(entity actor, int slot, float fr, float t,
- void(Weapon thiswep, entity actor, int slot, int fire) func)
+void wframe_send(entity actor, vector a, bool restartanim);
+
+ void weapon_thinkf(entity actor, .entity weaponentity, float fr, float t, void(Weapon thiswep, entity actor,
+ .entity weaponentity, int fire) func)
{
bool restartanim;
if (fr == WFRAME_DONTCHANGE)
vector or = v_right;
vector ou = v_up;
- if (actor.weaponentity[slot])
+ if (actor.(weaponentity))
{
- actor.weaponentity[slot].wframe = fr;
+ actor.(weaponentity).wframe = fr;
vector a = '0 0 0';
- if (fr == WFRAME_IDLE) a = actor.weaponentity[slot].anim_idle;
- else if (fr == WFRAME_FIRE1) a = actor.weaponentity[slot].anim_fire1;
- else if (fr == WFRAME_FIRE2) a = actor.weaponentity[slot].anim_fire2;
+ if (fr == WFRAME_IDLE) a = actor.(weaponentity).anim_idle;
+ else if (fr == WFRAME_FIRE1) a = actor.(weaponentity).anim_fire1;
+ else if (fr == WFRAME_FIRE2) a = actor.(weaponentity).anim_fire2;
else // if (fr == WFRAME_RELOAD)
- a = actor.weaponentity[slot].anim_reload;
+ a = actor.(weaponentity).anim_reload;
a.z *= g_weaponratefactor;
- setanim(actor.(weaponentity), a, restartanim == false, restartanim, restartanim);
+ wframe_send(actor, a, restartanim);
}
v_forward = of;
flash.owner = actor;
flash.angles_z = random() * 360;
- entity view = actor.weaponentity[slot];
- if (gettagindex(actor.(weaponentity), "shot")) setattachment(flash, actor.(weaponentity), "shot");
- else setattachment(flash, actor.(weaponentity), "tag_shot");
++ entity view = actor.(weaponentity);
+ entity exterior = actor.exteriorweaponentity;
+
+ if (gettagindex(view, "shot")) setattachment(flash, view, "shot");
+ else setattachment(flash, view, "tag_shot");
setorigin(flash, offset);
entity xflash = spawn();