I have some trouble with save and load game and weapons using viewmodelforclient.
This is how it is when it's working: When I change a weapon, the old one goes down and when it's down and out of view, it is removed and then the new weapon is spawned to the view and it comes up from the bottom.
When it's not working, the weapon I had ready when I saved the game will be there twice when I load the game. This error doesn't happen with the original quake weapons, as they they don't use the weapon spawn and remove code. They use that self.weaponmodel ="v_some.mdl" stuff.
Every save will increase the amount of weapons been spawned errorneously.
This error doesn't only make two weapons appear to the screen, but it also makes their thinking happen too often. So they either have too fast fire rate or start the firing sequence again before the weapon actually fired anything...
Here's my code stuff:
This is in w_main.qc (formerly known as weapons.qc):
Code: Select all
//==============================================================================
// W_RemoveWeapon
// removes the weapon
//==============================================================================
void() W_RemoveWeapon =
{
self.weaponmodel = "";
if(self.hand_w)
remove(self.hand_w);
if(self.weapon_w)
remove(self.weapon_w);
self.weaponspawned = FALSE;
dprint("weapons removed...\n");
};
//==============================================================================
// W_TakeWeapon
// sets the take weapon up time when changing weapons
//==============================================================================
void() W_TakeWeapon =
{
dprint("weapon take up...\n");
// remove old weapons
W_RemoveWeapon();
if(self.newweapon == IT_HANDS)
self.take_finished = time + 0.6;
else if(self.newweapon == IT_EMPNP)
self.take_finished = time + 1.2;
// and same for every other weapon, which are still old quake weapons
self.weaponstate = WS_TAKE;
self.wpnaniframe = 0;
self.weapon = self.newweapon;
W_SetCurrentAmmo();
};
//==============================================================================
// W_AwayWeapon
// sets the away weapon down time when changing weapons
//==============================================================================
void() W_AwayWeapon =
{
dprint("weapon going away...\n");
if(self.weapon == IT_HANDS)
self.away_finished = time + 0.6;
else if(self.weapon == IT_EMPNP)
self.away_finished = time + 1.2;
// and same for every other weapon, which are still old quake weapons
self.weaponstate = WS_AWAY;
self.wpnaniframe = 0;
};
//==============================================================================
// W_WeaponAnimation
// animates the weapons
//==============================================================================
void() W_WeaponAnimation =
{
if(self.weapon == IT_HANDS)
W_Hands_Animation();
else if(self.weapon == IT_EMPNP)
W_EMPNP_Animation();
else
return;
};
//==============================================================================
// W_WeaponFrame
// called every frame
//==============================================================================
void() W_WeaponFrame =
{
// Weapon animations should be done always
W_WeaponAnimation();
// Impulse commands can be done, weapon won't change, if the player is firing..
I_ImpulseCommands();
// Doing an attack
if(time < self.attack_finished)
return;
// Start putting the weapon down
if(self.weapon != self.newweapon && (self.weaponstate == WS_READY_A || self.weaponstate == WS_READY_B))
W_AwayWeapon();
if(time < self.away_finished)
return;
// Start taking the weapon up
if(self.weapon != self.newweapon && self.weaponstate == WS_AWAY)
W_TakeWeapon();
if(time < self.take_finished)
return;
// Attack
if(self.button0)
{
self.weaponstate = WS_ATTACK_A;
W_SuperDamageSound();
W_Attack();
return;
}
// Alternate Attack
if(self.button3)
{
self.weaponstate = WS_ATTACK_B;
W_SuperDamageSound();
W_AttackAlternate();
return;
}
self.weaponstate = WS_READY_A;
};
Code: Select all
void() W_HandThink =
{
if(!self.owner.frametics)
self.owner.frametics = 0.1;
self.nextthink = time + self.owner.frametics; // how often to change frames, some actions change the frametics
self.owner.wpnaniframe = self.owner.wpnaniframe + 1; // same kind of stuff as walkframe in player.qc
self.frame = self.owner.weaponframe;
};
void() W_WeaponThink =
{
// pretty much the same as W_HandThink, but has some stuff for changing the skin
};
void(entity hud_weapon) W_SpawnEMPNPHands =
{
self.hand_w = spawn();
self.hand_w.owner = hud_weapon;
self.hand_w.movetype = MOVETYPE_NONE;
self.hand_w.solid = SOLID_NOT;
self.hand_w.classname = "cl_empnp_h";
setmodel(self.hand_w, "model/cloaked_h/cl_empnp_h.dpm");
self.hand_w.viewmodelforclient = hud_weapon;
self.hand_w.skin = 0;
self.hand_w.think = W_HandThink;
self.hand_w.nextthink = time;
dprint("empnp hands spawned...\n");
};
void(entity hud_weapon) W_SpawnEMPNP =
{
// about the same as W_SpawnEMPNPHands, but spawns a self.weapon_w and use different model
};
void() W_EMPNP_Animation =
{
// Spawn the weapons if they're not spawned
if(self.weaponspawned == FALSE)
{
W_SpawnEMPNP(self);
W_SpawnEMPNPHands(self);
self.weaponspawned = TRUE;
}
// Taking the weapon
if(time < self.take_finished)
{
empnp_take();
return;
}
// Putting it away
if(time < self.away_finished)
{
empnp_away();
return;
}
// Attacking
if(time < self.attack_finished)
{
if(self.weaponstate == WS_ATTACK_A)
empnp_attack_a();
else if(self.weaponstate == WS_ATTACK_B)
empnp_attack_b();
return;
}
// Ready to do anything
if(self.weaponstate == WS_READY_A)
{
empnp_idle();
return;
}
};
After eating some ice cream and doing something else for a moment, I found how to get rid of the error:
Code: Select all
void() W_HandThink =
{
// This prevents weapons being spawned again when loading a game
// weaponspawned needs to set FALSE, otherwise player won't have any weapon
// visible and can't do anything but change weapon...
if(self.owner.hand_w != self)
{
self.owner.weaponspawned = FALSE;
remove(self);
return;
}
if(!self.owner.frametics)
self.owner.frametics = 0.1;
self.nextthink = time + self.owner.frametics;
self.owner.wpnaniframe = self.owner.wpnaniframe + 1;
self.frame = self.owner.weaponframe;
};