@Daya
#1886 posted by Spike on 2015/12/21 05:30:26
'incompatible redeclaration' means you defined something twice, but with different types.
the error should include some kind of note that says where the previous definition/prototype can be found, while the error line itself says the new/later redeclaration of it.
just make sure they both have the same type (and only one initialisation, ideally).
like preach says, you probably already have some existing function/field/monkey with the same name elsewhere with a different purpose, in which case just rename one of them or something.
Alternatively you can prefix both defs with the 'static' keyword so that they won't conflict with other definitions from other .qc files.
With What Preach Said,
#1887 posted by aDaya on 2015/12/21 10:10:23
I remembered a solution I did before when something similar happened with animation declarations: I just had to rename them according to the monster's name.
@adib I'm not using it, I'm recreating it with my own code as far as I can, with a different skin and sound set.
Function Reuse
#1888 posted by Preach on 2015/12/21 18:25:08
But Daya, if both of the functions are identical apart from the name, wouldn't it make more sense to just use the same function in both places, and make sure that there's only one definition? I'm worried from your response that my explanation didn't make sense...
Oh No I Got It
#1889 posted by aDaya on 2015/12/21 19:18:40
Like, I could've deleted the chainsaw code inside butcher.qc, and the declarations would actually mention the one in ogre.qc, but I didn't do that simply for keeping things in their own sides, even if there's no changes.
Yes
#1890 posted by ijed on 2015/12/22 18:50:25
Duplicate entries are anathema for pro coder's - typically you want to keep only one function but make it more complex, so it would know which monster was calling it (butcher or ogre).
But the format of the QC doesn't help, since some attack functions are in weapons while many others are scattered across all the monsters.
One of the things we did in RMQ was to add an attack library qc, and then move everything to that one central location.
At Least
#1891 posted by ijed on 2015/12/22 21:16:59
That was the intention, to make everything modular. We got quite a way before the project collapsed.
The strength of a system like this is that your code is easier to debug and more open - if you decide to chop and change abilities or add new ones its pretty easy.
Especially since, in quake at least, almost all the projectile creations are the same apart from a few different variables like damage done, model used and so on.
Dir = Aim(self, 1000);
Is there any difference in the aim built in function than merely calling makevectors on your v_angle / angle and assigning :
dir = v_forward;
??
Or does the aim function do that but normalize the result? Also whats the float of 1000 or whatever you enter there actually do ?
#1893 posted by Spike on 2015/12/25 21:58:08
aim typically returns v_forward.
traditionally it also nudges the z value to point towards entities with .takedamage==DAMAGE_AIM
this gives the same sort of aiming found in doom with its complete lack of pitch angles.
of course, because this means peoples rockets always miss the enemy's feet, most engines default sv_aim to 2 or so in order to disable the autoaim/automiss effect.
#1894 posted by Lunaran on 2015/12/25 21:59:20
What does 2 do as opposed to 0?
Actually Looked
#1895 posted by Lunaran on 2015/12/25 22:13:03
It's just a dot product comparison, which means sv_aim is actually fully on instead of off.
I Want To Know As Well
#1896 posted by ijed on 2015/12/25 22:14:08
Esoteric but interesting.
#1897 posted by Spike on 2015/12/26 00:00:11
for fun, set sv_aim to -1 then try to do rocket jumps with a monster in the same room (including behind you) :)
Sprites!
#1898 posted by aDaya on 2015/12/26 21:45:55
So it seems I got the hang on sprite thingies, but I don't know how to properly integrate them.
From my observations on the explosion sprite, this is what I came up with: http://pastebin.com/DzipzBRq
Compiling And Logic
#1899 posted by Preach on 2015/12/26 22:38:24
I'm guessing that you want the plasma to animate while it flies, let me know if not.
The first problem is plasmashot1...etc are functions, but you have defined them in the middle of the LaunchPlasma function. Move those above the rest of the code and it should compile.
The second problem is that you aren't using them, you need something which says self.think = plasmashot1 to kick off the animation. Change the line for SUB_Remove to plasmashot1 instead and change self.nextthink = time + 0.05. Then you should get animations.
The third problem is that SUB_Remove never gets run, and so plasma might stick around forever. This is actually a bit harder to sort out, because we can only have one think function at a time, and we're already using it to run our animation. How can we schedule a think for 5 seconds in the future if we need to think 20 times a second in the meantime?
The nice thing is that your code will run without fixing this, so have a think about it first and I'll explain in a later post.
LaunchPlasma ()
Yea, Daya, I dont think you can compile voids within other voids...but, ok for some reason FTE compiler allows you to do that. I tested and even though it lets you compile a void in another function, if you try calling that void, the compiler catches it and does not really see it defined. So those frame macros for the plasma sprite need to come out of there and go somplace else, such as in player.qc where other frame macros are. Funny thing you found tho !
#1901 posted by Spike on 2015/12/27 10:09:21
nested functions are meant to be a thing, but I'm still getting the kinks out. thanks for finding one of them.
either way, writing lots of nested animation/state functions isn't really advisable, especially if you're likely to use incorrect indentation.
What Could They Be Used For?
#1902 posted by ijed on 2015/12/27 17:13:13
Only running nested ones from within the main, like an exclusivity thing?
#1903 posted by Spike on 2015/12/28 07:49:16
self.think = (void()){remove(self);};
is an example of an annonymous nested function.
they're good for simple callbacks and stuff.
reducing the number of top-level functions can make the code feel simpler and thus be more aproachable, plus it allows the callbacks to be nearer where they're used, which is a nice way to improve readability (when not abused).
unfortunately the qcvm allows no practical way to give callbacks access to the parent function's locals (unlike other languages may allow), but I can make an exception for static locals (which are really just glorified globals).
First Test With Sprites
#1904 posted by aDaya on 2015/12/28 15:01:22
So, this is what happens: the monster does his routine when he sees me, but after he fires his first shot (he 's an enforcer type of monster, so normally he fires 2 shots consecutively) he's stuck in his idle pose and his animation goes twice faster than usual for this animation only. Attacking him makes him go back to his routine after doing his hurt animation though. The sprite's animation is stuck on the first frame, but it disappears when it hits brushes or entities, so that's that.
Here's the code:
http://pastebin.com/mq8ivUPU
#1905 posted by Spike on 2015/12/28 15:49:49
self.think = plasmashot1;
you're mixing up your newmis and your self.
so that should be:
newmis.think = plasmashot1;
obviously this then conflicts with the following line that you have lower down:
newmis.think = SUB_Remove;
this is along the lines of what preach was talking about.
iirc sprites do also support framegroups, you might find those easier to tie in with remove timeouts, if you can find a tool to write those.
#1906 posted by aDaya on 2015/12/28 16:51:09
I'm using fimg, as suggested on the General Chat thread. How should I work this one out?
#1907 posted by Lunaran on 2015/12/28 17:57:01
leave the sprite the way it is and fix the self references. there's nothing wrong with the sprite.
Spike
#1908 posted by aDaya on 2015/12/28 18:37:39
Tried your thing, but the effects are the same as I've stated.
Code: http://pastebin.com/FwRPucgv
Daya
#1909 posted by Preach on 2015/12/28 19:22:10
He said to replace the line
self.think = plasmashot1
- you've left it in. You've also left in the line below
newmis.nextthink = time + 5;
newmis.think = SUB_Remove;
These will cancel out the newmis.think = plasmashot1 code. You need to have
newmis.nextthink = time + 0.05;
newmis.think = plasmashot1;
- plus have no other lines which change nextthink or think on either newmis or self.
Oh, My Mistake
#1910 posted by aDaya on 2015/12/28 19:34:27
Now it works. Thanks a lot!
|