News | Forum | People | FAQ | Links | Search | Register | Log in
Coding Help
This is a counterpart to the "Mapping Help" thread. If you need help with QuakeC coding, or questions about how to do some engine modification, this is the place for you! We've got a few coders here on the forum and hopefully someone knows the answer.
First | Previous | Next | Last
A Gun That Winds Up, Shoots, Wind Downs 
So I've been trying to code my weapon today, and it's a Gatling Gun composed of 3 states: a wind up, a shooting loop, and a wind down.

The programming's supposed to be like this: weapon.qc holds the code to play sounds, and player.qc holds the animation (the W_Attack part in weapons.qc calls the starting animation in player.qc, "player_gatlup1"), and both of them are supposed to sync.
weapons.qc: http://pastebin.com/kJ1mMtqC
player.qc: http://pastebin.com/Bnf4ThZ1

Problem is, in weapons.qc, I want the Gatling Wind Up part to go on for 0.9 second no matter what, and then switch to Gatling Shoot. And it seems like self.attack_finished isn't the way to go, but after the help I got I got more confused because I haven't been told of a workaround.
Would somebody be kind enough to help me on this? 
Spin Up 
The traditional way would be to have a series of animation functions leading to the firing sequence:

player_gatlup1
player_gatlup2
...
player_gatlup9


and only player_gatlup9 sends you to player_gatlshot1. For this approach, I'd probably ditch W_GatlingSpinUp and import the sound cue into player_gatlup1. As an important side note, you don't need these lines:

self.nextthink = time + 0.1;
self.attack_finished = time + 0.9;

in your player_gatlup1 function. nextthink is set automatically to time + 0.1 when you start a function with the prologue [$light1, player_gatlup2], and as the later code sets the attack_finished time that portion is redundant.

Hopefully from there things should start to work, it is something that there's no natural example of in the Quake code so the approach isn't obvious. I called this the traditional way - once you've got that bit working, there is a way to reduce the number of functions back down, but perhaps for another day... 
Preach 
Thanks, that made the weapon functionnal, but when I hold the shoot button, it indeed does the windup animation, but if I continue holding, it shoots a bullet, then does the wind down animation while still playing the gatling gun wind up sound on a loop. The windup, shoot a bullet, winddown routine goes on a loop until I let go of the button, when it'll imediately snaps back to its starting position while playing the gatling gun wind down sound once (the self.attacked_finished = time+0.9 is still in effect here).

Here's my reworked code from what you've said: http://pastebin.com/QbC7R7nT 
OK, My Apologies 
I have a theory on what's happening. If the theory is true then I was wrong, the self.attacked_finished = time + 0.9 is doing important work I hadn't recognised, and I shouldn't have told you to remove it.

My theory is that you're not getting the wind-down animation, just jumping to the top of the wind-up animation, because your attack_finished time you set in player_gatlup1 just runs out when you make it to player_gatlshot1, and then the rest of the code decides that it's time to launch a new attack from player_gatlup1. So I think you should try putting some more self.attacked_finished = time + 0.9 in all the attack sequences, plus perhaps the last of the spinup functions.

As a side note, watch out for the function W_CheckNoAmmo. Although it looks like it's just returning some information to your function, it actually has a side effect of changing your weapon instantly! This will mean it skips your wind-down animation if you run out of ammo. Put a simpler check like self.currentammo > 0 in its place, and perform the weapon switching on the last frame of the wind-down instead. 
Some More Problems... 
I added the self.attack_finished = time + 0.9 lines to the last 3 frames of the gatling spin up part, deleted "return" as a condition result for self.currentammo > 0 and instead put it in the gatling down's function once frame 34 is played (the last one, for when the weapon winds down).
Now if I just press the fire key once or hold it, the weapon spins up, and after it finishes its animation it shoots once (the fire animation's not playing like before), then goes back to its first frame, and the gatling firing loop sound plays once. I have to wait 0.9 second -it seems- to be able to fire again.
Geez, how did Team Fortress Software able to code the Assault Canon properly for QWTF? 
Patience Young Grasshopper 
They wrote the code for the assault cannon exactly like this, except they did all the cursing in private and didn't show anyone until they'd got it to work.

One of the things that I've spotted:

void() player_gatldown1 =[$nailatt1, player_run ]

The bit that says player_run there means that 1 frame after you've started the spindown animation, you skip straight to "everything is normal" mode, besides waiting for the attack_finished counter to run down. You should change that bit to player_gatldown1 so that it keeps looping back to the same function. Of course, it will never return to "everything is normal" mode unless you add a line which runs player_run(); once the animation has completed, so add that too.

Are you getting a chain of shots in-between spinning up and spinning down, so long as you hold fire? I hope that's all working now... 
 
I can only get one shot either by just hitting the button once or holding it.
After I did what you suggested, it can only fire once like I said (it did it before) and then the winddown function loops at one frame at a time, and I can't do anything weapon-wise until I pick up an item.

code: http://pastebin.com/wFj7j1cJ 
For Your Consideration 
Please ponder the following two lines

self.weaponframe = 15;
self.weaponframe = self.weaponframe + 1;

When you see what is wrong you will see why you can't exit the spindown (besides collecting an item).

This still does not fix the 1 shot at a time issue. If you have added the attack_finished code to the player_gatlshot1 etc functions then I am stumped. It might relate to how the code interacts with the parts in other files you haven't posted.... 
 
I now have put self.attack_finished = 0.9 on each firing frames, and did as follows:

firing frames: hhttp://pastebin.com/ucD70L9N
gatling down: http://pastebin.com/x8nfUsRc

It still fires one shot no matter if I push once, or hold the trigger, or not push anything during the sequence. But the spindown animation now plays properly, as well as the sound.
Making it fire is now the last problem programming-wise. 
Also, 
Because Gatling wind down is called every time a frame passes, the self.attack_finished I intended to be set on 0.9 is now too high, I have to wait for the whole animation to end before doing anything, while the idea is to wait for an animation cue to do things again weapon-wise. 
 
They wrote the code for the assault cannon exactly like this, except they did all the cursing in private.

Nice. 
 
is the qwtf source available? 
 
It is, but last time I checked I couldn't understand how the Assault Canon actually worked, the code kinda looked messy. 
Removal 
I think you are safe in getting rid of self.attack_finished = time + 0.9; from the wind-down part now, so long as it's set in each of the attacking frame you should get a decent wind-down which can't be interrupted, without a huge pause afterwards. If it's too short, change the values in the attack frames.

You have the ammo check the wrong way round in your attack frames btw, and I worry you may need more brackets. Can you try changing

if ((!self.button0) || self.currentammo > 0)

to look like

if ((!self.button0) || (self.currentammo <= 0))

That should stop you exiting after 1 shot. You may want to make those code blocks end with a return once more if that starts working, so that you don't fire an extra shot on the frame you released fire on/ran out of ammo on. 
 
Thanks, I'll try to take it from here for now on, since there are fixes to be done.
Before that I should mention that adding "return;" to the end of each firing blocks doesn't fix the problem of firing an extra bullet before exiting/skipping the firing pattern.
Also, the firing loop sound still plays if it's still on the set timer after switching to the spindown part. I assumed the winddown sound would play over it, since they're on the same channel. This obviously has something to do with self.t_width, but I don't know what condition it takes to say "if mingn2 is playing, play mingn3, else play mingn3" in the spindown block. 
Fix 
Before that I should mention that adding "return;" to the end of each firing blocks doesn't fix the problem of firing an extra bullet before exiting/skipping the firing pattern.

Add it to the if block that decides if the sequence is ending, not the whole function. 
 
OK, so the Gatling Gun i've been coding this past few days now works flawlessly, it's great. I can't thank Preach enough for his help.
I've been testing it in Darkplaces (like I did with the InfantryGun), but once I switched to Quakespasm the weapon doesn't appear at all. In fact he gives this error in the console:

http://image.noelshack.com/fichiers/2015/42/1444865216-spasm0005.png

So what gives? I don't think that's linked to the bit field I gave to it (it being "8388608" so it doesn't conflict with other items). 
 
is it case sensitive and you have inconsist case between the map file and the quakec? 
 
I checked if it was a case of hitboxes changing between clients, like how powerups need to be lifted up to 16 units from the ground to appear properly. I tried that, but the error's still there. 
Looks Like Your Progs.day Isnt Loaded 
 
That Error 
Means the qc being called doesn't exist.

So yeah, check that you haven't got an upper/lower case problem somewhere that Dark places was automatically correcting. 
 
the error literally means the classname in the map file doesn't match any spawn functions found in the progs.dat, which is why i suggested the upper/lower case issue. It could also be a spelling issue (though can't explain why it would work in darkplaces then) or maybe the progs.dat isn't even being loaded (perhaps darkplaces has different rules about folder searchpaths or valid filenames for it?) 
 
That was it, when I transferred the files from darkplaces to quakespasm I forgot to transfer the progs.dat file.
Thanks again for your support! 
Mdl Winding Sanity Check 
Can anyone tell me what the correct winding order is for quake .mdl triangles? (CW or CCW?). It's not a big issue because I can reorder my vertices to switch the winding, but the fact that my tris are coming out flipped is baffling me a little bit. 
Pretty Sure It's CW 
 
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.