How?
#56 posted by necros on 2008/04/05 00:10:17
how exactly do i make it static? or how do i declare the function outside a class definition? do i make a new cpp file or something or..?
Static
#57 posted by bambuz on 2008/04/05 01:02:27
is another modifier, kinda like private or public.
A static thing is something you can not make instances of, kinda.
So you have classes like Moose and you can make moose1, moose2 etc... But there can be a static method in the Moose class that is not particular to any moose1 or moose2 instance.
Like double Moose.mass_of_the_sun() which then returns a static constant that is always the same no matter what you do with the moose instances.
Kinda like that. Damn it's been too long since I've coded.
#58 posted by JneeraZ on 2008/04/05 12:23:49
necros
You're asking some pretty basic questions here in all honesty. Maybe reading a primer on C/C++ would be in order here.
Yeah
#59 posted by BlackDog on 2008/04/05 16:45:03
C++ is a painful and unforgiving language. If you dive right in, you're going to hit something hard and spiky.
I would go so far as suggesting a different language, if that's practical (pygame is pretty sweet). If it isn't, then you really need to read up on the basics.
#60 posted by JneeraZ on 2008/04/05 17:22:05
C++ is fine and gets far more flack than it deserves.
C# is far superior however. FAR superior.
I guess it would help to know what specifically you're trying to code and for what platform.
#61 posted by BlackDog on 2008/04/05 18:10:42
C++ does get treated unfairly - google Erik Naggum's usenet rants sometime for a hilarious example - but I wouldn't call it "fine".
I don't really want to get into a flamewar over C++'s fucked up design: I'm just going to note that there are plenty of better languages to choose from.
#62 posted by necros on 2008/04/05 23:14:37
at the same time, i always learnt best by doing. it's more frustrating, but it sticks better.
i've tried reading some lit on c++ but they annoy the hell out of me. i'd rather they just give me the syntax for it and give me a brief overview of how to put it in the code instead of going into all the long winded crap about stuff i never remember anyway.
otoh, the more i look at this code, the more i feel it needs to be rewritten almost from scratch. there are some things in here which i don't like at all.
ie: instead of treating ships and missiles as inheriting from the same class, they are completely different classes, and neither of them can 'see' the other.
ideally, i would have liked to override the basic 'update' function of a base entity class for specific ones (ie: for missiles and ships) and then be able to call it by just iterating down one big list of entities and calling the same function.
instead, i'm trying to hack my way around it by making a static function in a new class so that i can call it from inside one class that normally can't see the other class.
also, for, apparently no reason, missiles aren't instanciated objects, but are regular structs which is also causing other problems.
i'm going back to school next week, so i'll probably ask these questions to my instructors instead and see what they think...
Heh
#63 posted by necros on 2008/04/05 23:15:07
the title for the above post should have read "that may be true, but"
If This Is Your First C++ Program...
#64 posted by mwh on 2008/04/06 10:45:31
you should entirely expect to have to throw it away and start again.
(Or your 10th or 100th, to be fair: "build one to throw away" is a long standing slogan of software engineering).
#65 posted by JneeraZ on 2008/04/06 11:35:49
The problem is that hardly anyone ever does that. :) That's where horrible feature bloated abominations are born.
Unarmed Ogre
#66 posted by ijed on 2008/06/01 03:03:43
I've been stuggling to make an Ogre variant and I'm having troubles with ai/fight/ogreb.
Basically the fat cunt keeps trying to go to th_missile when he has no grenades (crash). I must be missing something obvious here but I don't know what.
The error returned is on his run sequence (has all his own functions) but if I replace his th_missile linking it to eg.melee then I'm ok, except it takes him ages to close the distance because he's swinging chainsaws about.
NULL function
Basically I don't want him to ever th_missile - but looking over ai and other monsters sheds no light - dogs / knights / fiends all use ai_run without problem.
I'm going in circles, it seems. If anyone can shed any light on this I'd appreciate it.
C++ For C Programmers
#67 posted by inertia on 2008/06/01 09:18:27
http://www.4p8.com/eric.brasseur/cppcen.html
I find that documents called "X For C Programmers" tend to hit the spot. This is mainly for necros.
Ijed
#68 posted by Supa on 2008/06/01 11:14:34
OgreCheckAttack sets their attack state to AS_MISSILE, which leads to ai_run calling ai_run_missile, which leads to self.th_missile.. which leads to the crash.
You'll need to comment out the monster_ogre/OgreCheckAttack lines in CheckAnyAttack (so they'll use CheckAttack instead) and make sure you don't give them a .th_missile, else CheckAttack will convienently call self.th_missile for you. :)
An Ogre By Another Name
#69 posted by Preach on 2008/06/01 11:39:17
Have you tried changing the classname from monster_ogre to, for example, monster_ogre_unarmed? I have a feeling that might make it work.
The reason why is hidden in fight.qc and ai.qc. fight.qc is the place to start, have a look at the two functions CheckAttack and OgreCheckAttack. The former is the generic function for any monster, and it's careful enough to check whether self.th_missile is set or not before deciding to make a missile attack. OgreCheckAttack is more presumptive, it knows that an ogre has a missile attack and so goes straight ahead with setting AS_MISSILE.
This is all quite deceptive, as OgreCheckAttack never explicitly uses th_missile - it just sets AS_MISSILE and lets ai.qc do the th_missile part. ai.qc is also the place to find out how the game chooses between CheckAttack and OgreCheckAttack. The function that decides is called CheckAnyAttack, and as you can see it decides based on the classname. So if you give your melee ogres a different classname then it should use CheckAttack only, which is safe to use without th_missile set.
The downside to this method is that, like with monster_ogre_marksman, your ogres will be able to infight with each other. So you could just make the check in CheckAnyAttack more stringent:
if (self.classname == "monster_ogre" && self.th_missile)
return OgreCheckAttack ();
For neatness of code, this way is probably better, as it means you can have a single spawnfunction for both grenadiers and berserkers. This is good code sharing, as any change you make to an ogre you probably want to make for both of them.
The third solution would be to modify OgreCheckAttack to properly check for th_missile, but I don't think that's the best way to go, it could end up complicated.
Infighting
#70 posted by rj on 2008/06/01 15:10:32
it's pretty easy to get around the infighting problem above when setting up a new classname. you just need to set up 'classes' (a la quoth) and modify the infighting code slightly
here's how i did it..
- add .string class; to the monster ai in defs.qc
- add self.class = "ogre"; to the different ogre classnames
- then in combat.qc under the '//react to damage' part, change this line:
if ( (self.flags & FL_MONSTER) && attacker != world)
to read this:
if ( (self.flags & FL_MONSTER) && (self.class != attacker.class) && attacker != world)
i think that was it. you can use it to group allied monster types or groups, either in the qc or simply by adding 'class' to any other monster entity (say if you had one particular battle where you wanted the monsters to focus on the player only)
Excellent
#71 posted by ijed on 2008/06/01 18:16:41
Thanks for all the answers, I should be able to close this issue sometime today.
I wanted to maintain the original ogres so made the new one a different classname - ogreb (berserk) already.
As to infighting, I'm thinking of modifying all Ogres to act the same as grunts. This might sound like a cheap dodge to not have to fix the issue, but I never did see the Ogres as particularly polite, and I'm a fan of chaos.
Thanks again.
Argh
#72 posted by ijed on 2008/06/01 18:24:37
Solved!
Turns out I was calling ogrecheckattack for the new ogres inside ai.
You live and learn.
Monster Won't Get Killed
#73 posted by madfox on 2008/09/09 00:06:00
While coding for a new Q1 monster I made up a little qc where I placed all args like stand walk run etc.
Having the monster standing in game all looks well, untill I try to kill the moster.
Having two monsters in game there's always one that don't die.(?!)
I hear the kill sound but the monster just goes on turning into stone to my bullits.
I have the regular death subroutine.
http://members.home.nl/gimli/Imp.qc
#74 posted by necros on 2008/09/09 00:27:45
lol...
if (random() < 0.5)
imp_die1 ();
these lines mean if random() (random number between 0 and 1) is smaller than 0.5, then it will play the animation sequence.
so half the time it will play the animation and half the time it won't.
Well
#75 posted by madfox on 2008/09/09 00:44:57
cll me a fool, but what should I number 0.5?
Right
#76 posted by madfox on 2008/09/09 00:52:05
if(me a fool)half the time < I ain't).
thanks for pointing me out.
Impulse Command Queuing.
#77 posted by necros on 2008/09/20 23:17:10
impulse command queuing.
is that handled by the engine?
in ImpulseCommands there's the if statement:
if (self.attack_finished > time)
{
self.impulse = 0;
return;
}
which seems to me to mean "if attack_finished is still ticking down, do not accept ANY impulses (set to 0) and then break out of the function altogether.
yet, when you attack with say the rocket launcher and then press 8, the impulse 8 command seems to get queued up and is executed after attack_finished is done.
is there something going on behind the scenes here? i'm actually trying to stop the queuing from happening, but can't really see even where it's happening.
Hmm
#78 posted by Preach on 2008/09/21 00:05:45
I don't see that line in the version posted at
http://www.inside3d.com/browse.php?show=weapons.qc
I'd probably say the place to look is in W_WeaponFrame, where any call to ImpulseCommands is skipped if self.attack_finished > time. If you really wanted to block impulses, then putting self.impulse = 0 just before that return should do the trick.
Hm...
#79 posted by necros on 2008/09/21 05:41:57
that's really odd. that means the if check in ImpulseCommands is completely redundant. it will never get to that point because an identical if check is done prior to even getting in that function. o.0
Random Coding Oddities In Quake?
#80 posted by mwh on 2008/09/21 09:40:41
Surely not!!
|