View previous topic :: View next topic |
Author |
Message |
jim

Joined: 05 Aug 2005 Posts: 400 Location: In The Sun
|
Posted: Sun Sep 30, 2007 10:43 pm Post subject: Save/Load Game and Weapons |
|
|
I solved my error, but you may take a look...
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: |
//==============================================================================
// 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;
};
|
And this is in my w_empnp.qc, which handles one of the weapons.. the IT_EMPNP, w_hands.qc is for IT_HANDS and currently it's almost a copy of this:
Code: |
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;
}
};
|
So why aren't the self.hand_w and self.weapon_w removed after save and load? They aren't saved? How to save them then?
After eating some ice cream and doing something else for a moment, I found how to get rid of the error:
Code: |
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;
};
|
_________________ zbang! |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Mon Oct 01, 2007 7:44 am Post subject: |
|
|
I haven't looked through all of your code, but I still have one major thing to point out in your code design: Don't remove and spawn new entities for held weapons. If you don't do this, you'll completely eliminate the entire possibility of the double weapons issue, since there's no weapon spawning happening, you can't accidentally spawn a weapon on top of another. What you want to do is this:
Have a field for the weapon in your hand, similar to how quake does it, but instead of a string, you make it an entity:
Code: | .entity heldweapon; |
Then you have a linked list of all the weapons in the entire game:
Code: | entity weapon_list;
.entity w_next;
e = spawn();
e.mdl = "progs/v_plasmaweapon.mdl";
e.shootfunction = PlasmaShot;
etc...
e.w_next = weapon_list;
weapon_list = e; |
Then all you need to do is scroll through the weapons list and check against the players inventory wether he owns this weapon or not, and then simply do the awesome trick of copying all the relevant info from the list to self.heldweapon, and play the raise animation. You just eliminated your problem, and made a really solid and smooth weapons handling system  _________________ Look out for Twigboy |
|
Back to top |
|
 |
jim

Joined: 05 Aug 2005 Posts: 400 Location: In The Sun
|
Posted: Mon Oct 01, 2007 2:22 pm Post subject: |
|
|
This definitely sounds better than that spawning stuff, though now it seems to be working. But who knows if there's some more situations when it wants to spawn too much...
My weapons handling system is a bit not so solid and smooth. Using faster slowmo rate breaks it completely. The firing sequence is playing at somewhat random rate, though it's synchronized with both the hand and weapon entities.. I have a feeling it's not working well in netgames (I hope I'm wrong about that). _________________ zbang! |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2004 phpBB Group
|