|
Rotating Brushes
#6150 posted by inertia on 2007/07/13 06:35:12
is there a way to do it that isn't weird and complex (like the original rotating stuff in the first expansion pack)?
Inertia
#6151 posted by than on 2007/07/13 07:02:42
I explained it in the basepack thread (or perhaps this one) already, but basically it involves using a liquid brush as the visible glass with an invisible (by using skip) func_wall for the collision detection. Using skip you can remove surfaces of any water brushes near the glass and create the impression that the water is butting up against the water.
The main problem is that it only works on gl engines and requires the user to set wateralpha, but using Quoth you can set it automatically when the map loads so it isn't a problem for my basepack map.
Another problem is that the water and glass will share the same level of transparency, but using lighting and fog intelligently around windows can hide this problem well.
Alternatively you can require Nehahara or whatever, but I'd rather try and support all GL engines and software if possible. The map actually loads fine in software, but you can't see through the glass. The only software engine that supports transparent water that I know of is tochrisquake. I am not sure if Bengt has added it to his SW engine or not.
Than
#6152 posted by inertia on 2007/07/13 08:32:08
ok thanks :D
Wrappers And Rotation
#6153 posted by Preach on 2007/07/13 12:18:52
So, the cunning application of the external bsp files is this: rotating entities. Once you have the two wrappers described in the last post set up, add the following entity to misc.qc
void() func_illusionary_rotate =
{
setmodel(self, self.model);
self.movetype = MOVETYPE_NOCLIP;
}
Now you can easily set up a rotating entity in your map. First thing is to make your rotating model. Start a new map, and make the object you want to rotate. The important thing to do is to make the origin of this new map the axis about which your object will rotate. Set up some lights around it, to match the area of map - you don't need to be too precise about this, since it's rotating you can't sensibly have one half shadowed and one half light. Just give it about the right levels. Then compile it and leave it in the maps directory.
Then you just add a point entity to your actual map, with classname func_illusionary_rotate, avelocity set to how you want it to rotate and model to the path to the bsp model you just made. Position it so the point entity is on the axis you want to rotate about. Nice and simple, and it avoids the difficulty aligning the textures and setting up those origin brushes or whatever hipnotic had you do.
Obviously this is a simple example, but you can use it as a base for the more complex rotating things. For instance it's not a solid entity, but quake can't do solids rotating without an engine fix, so anything you'd do would be some kind of hack. I'm sure it's possible to adapt the hipnotic hacks to this method. Hopefully soon I'll have one of my own hacks worked out, and I'll post that too.
Monster Count Issue On Reload....
#6154 posted by JPL on 2007/07/15 09:44:58
Copied from Base Pack thread: On my current project (I used Quoth) I have a weird effect when (quick)saving, and reloading the map. The monster count (at the end of the level) doesn't correspond to any of the skillset.. Any idea about this issue ??
Is it something that is Quoth related, or simply a Quake bug ? Or could it come from my map ?
Very Strange
#6155 posted by Preach on 2007/07/15 13:47:19
The total monster count is saved directly in the savegame file, you can see it by opening it as a text file. It might be that somehow the server and client parts of the game are becoming desynchronized, you have to do a bit of work to update the client if the total number of monsters has changed. It's possible that somewhere the client is getting a (correct) update to the number of monsters, but the server isn't. Then when you save the game, you're going by the server's record of things, so you run into problems.
Anyway, I'd have to see the map and the save file first, it's not a issue known to me before now.
This Is
#6156 posted by aguirRe on 2007/07/15 15:04:20
actually one of the most common bugs in many mods; monsters are being spawned, resurrected or killed without being accounted properly (via killed_monsters and total_monsters vars plus updating the client).
It can be pretty tricky to track down these issues, but in all progs that I've fixed, the killcount should (hopefully) be correct.
#6157 posted by necros on 2007/07/15 15:29:10
does DecodeLevelParms() get called when you load a save game? it might be messing up with left over data in parm11 and parm12...
Monster Count
#6158 posted by JPL on 2007/07/15 21:54:53
DecodeLevelParms(): Err, how can check its use ?
As far as I understood, it comes from the Quoth mod, so how is it possible nobody saw it before ?
#6159 posted by necros on 2007/07/16 01:00:03
nm, i checked and it can't be because of decodelevelparms.
Qc Help
#6160 posted by madfox on 2007/07/16 04:38:53
As I'm developping a new Quake1 monster I want to give it some crossed over functions. So I altered the demon fiend in a kind of tribolitus creature, gave it a new skin and now I'm working on a qc for it.
As far things went right (had 15 vertice meshes in 81 frames) and now I see the creature everywhere...but nevermind.
I wrote a qc, which is a mix of the demon fiend and the lightning bold of the shambler. I'm almost done, but the last vexing problem is that by imitating the shambler's blast the qc compiler keeps bumping on
shambler.qc:194:Castlightning redeclared
The creature.qc compiles right now but shammy not.
Is there a way to relay this message or is the Castlightning an unique statement in the qc. I mean can it only be used once?
Defining Functions
#6161 posted by lurker on 2007/07/16 07:48:20
If you copied and pasted the Castlightning code from shambler.qc with no modifications, try adding
void CastLightning();
to the very beginning of your new monster's .qc file. Then, delete the copied CastLightning code from newmonster.qc .
If you copied Castlightning but modified it, give it a new name like Castnewlightning in your new monster's .qc .
Thanks!
#6162 posted by madfox on 2007/07/16 17:54:09
I knew modding with the Q1.qc can lead to a story without end. After changing the one line, others seem to jump up.
I had to change the fight.qc also and of course now other unknown punctuations appear.
I didn't change CastLightning in the monster.qc and changing it to CastNewLightning seems to help. Now it comes to a broad stroke, only the behaviour of the
function Monster_JumpTouch was not defined
breaks up again.
So I'm plotting further again.
Thanks for your advice, lurker!
Function Declaration
#6163 posted by Preach on 2007/07/16 19:05:07
What the problem is:
The compiler will only let you call functions that it already knows about, functions that you've already written earlier on in the code. If you want to call a function which you haven't defined yet, then you must do something called prototyping. A prototype is where you just tell the compiler the name of the function, warning it in advance that you are going to define it.
What to do:
The error you're getting tells you that you need to create a prototype of the function Monster_JumpTouch. The prototype looks like this:
void() Monster_JumpTouch;
Add that line at the top of your qc file(or anywhere above where you first use the function) and the error should go away.
Well...
#6164 posted by madfox on 2007/07/17 01:40:48
thanks for your attention, preach.
to keep it simple, the monster.qc is identic to the demon.qc , except the lightning beam addition.
This means, as in the demon.qc it starts with the
void()Monster_JumpTouch;
statement, and further on in the jump function
ai_face();
self.touch = Monster_JumpTouch;
makevectors (self.angles);
self.origin_z = self.origin_z + 1;
self.velocity = v_forward * 600 + '0 0 250';
if (self.flags & FL_ONGROUND)
self.flags = self.flags - FL_ONGROUND;
so I can't find the reason why the compiler bumps.
Hmm
#6165 posted by Preach on 2007/07/17 02:00:09
That bit looks in order, so the problem might be elsewhere. Check that Monster_JumpTouch isn't defined in both monster.qc and demon.qc, even though the error message doesn't sound quite right. Also, what are you using for compiling? If you use something recent like FTEQCC(http://www.fteqw.com/) then you get more informative error messages, as well as warnings that can help you pinpoint errors.
Hey...
#6166 posted by madfox on 2007/07/17 04:31:19
thanks for the link, preach! Suddenly I've got a progs.dat Only the messages run so fast I have to turn back to dos to watch them. I'm testing now how far things run.
I have two different prototyping for them, so I used Demon_JumpTouch and Monster_JumpTouch.
But as I copied them, their statements are the same.
I use the old proqcc and fastqcc as compilers.
They give a clear overvieuw of what's going on, but tend grimm for giving a progs.dat when errors appear.
GUI
#6167 posted by Preach on 2007/07/17 12:30:35
There is a GUI version which allows you to read the output of the compiler in a window, and gives you a full windows interface for selecting optimisations etc. You can nab it from http://downloads.sourceforge.net/fteqw/fteqccgui2770-win32.zip?modtime=1153182266&big_mirror=0
Yes!
#6168 posted by madfox on 2007/07/17 16:57:00
That's better. Although now I get 81 warnings from all kind of errors I suppose I don't have to take need of.
Now I'm so far I have two monsters, the demon and the gnerk seperated in one level. I had a rude job to model the head of the thing, because one can't just cut them off from the base part in Qmle.
The strange error occurs that the gnerk stands alright, but at leap moment it freezes for 3 seconds and then starts jumping again. Also the ligtning beam doesn't appear, although it doesn't give a message error.
For your convienent I have the two altered qc files from the fresh Q1.qc downloadable.
Maybe you could be so kind to take a look at them. I can't think of a line that's wrong.
The Gnerk_JumpTouch keeps bumping.
http://members.home.nl/gimli/gnerk.qc
http://members.home.nl/gimli/FIGHT.QC
Names
#6169 posted by Preach on 2007/07/17 20:47:47
Don't worry too much about the warnings, they are in fact mostly from the original ID code, only two from your own code, and 1 of them is harmless. The other one tells us what the problem is:
gnerk.qc:52: warning: function Gnerk_JumpTouch was not defined
You may be thinking that you did define such a function, a copy of the Demon_JumpTouch function. However, you renamed it Demon_GnerkTouch rather than Gnerk_JumpTouch. Fix that and your monster should work, somewhat. It won't freeze up when jumping in any case.
The problem you'll next encounter is that your monster isn't ever going to use lightning. This is a much knottier problem, discussed in the next post.
#6170 posted by Trinca on 2007/07/17 21:14:55
Preach the lurker map of vertical event crash in the 2 new progs.dat in old quoth works nicely
New Precaches For Quoth2?
#6171 posted by lurker on 2007/07/17 21:49:21
Trinca/Preach: My map was pushing precache limits in id progs and Quoth progs due to func_illusionary (and func_wall?) abuse. It originally crashed Quoth but worked in id progs due to a couple of extra Quoth precaches. If more were added since the official Quoth release, that would do it.
I'm not sure it's a big deal, however, since the map uses no Quoth features and works with id progs.dat .
#6172 posted by madfox on 2007/07/17 21:53:20
I'm still looking to much to the outcome of fastqcc. If i see errors I want to devoid them.
I had overcome the freezing of the gnerk by changing line 110:
void() gnerk_jump10 =[ $leap10, gnerk_jump1] {
self.nextthink = time + 3;
// if three seconds pass, assume gnerk is stuck and jump again
};
into
void() gnerk_jump10 =[ $leap10, gnerk_jump11] {
//self.nextthink = time + 3;
// if three seconds pass, assume gnerk is stuck and jump again
};
so by changing the gnerk_jump1 to gnerk_jump11 and adding two slashes for the self.think the error faded.
I now tried your way by changing Gnerk_JumpTouch into Demon_GnerkTouch, which also works. But it still gives that nasty error in fastqcc. I don't mind, but as I worked on the NewBoss earlier I found myself only content by getting a clean outcome.
And yes, why doesn't it struck its beam?
Seems that Shambler doesn't give pass to his magic laserbeam so easily!
Arrgh
#6173 posted by Preach on 2007/07/18 00:48:00
I lost a really long, nicely formatted post about the various systems that govern ai decisions, then the computer crashed. Here we go again:
It's quite hard to follow how the various functions that govern the decisions the monsters make. The functions involved for any given monster are spread out over 3 qc files, so here's a summary of how a monster goes from running to attacking. It starts in the running animation frame functions, which call ai_run().
ai_run(float dist) (ai.qc)
The first thing this function does is check if the current enemy is dead, and find another target if so. Once satisfied with the enemy, the function checks self.attack_state. If it is set to AS_MISSILE the function runs ai_run_missile, and if it is AI_MELEE it runs ai_run_melee. Otherwise the function runs CheckAnyAttack to see if the monster should attack yet, and if that returns false the monster runs forward the distance specified by dist.
CheckAnyAttack() (ai.qc)
This function asks the question "is this a good moment for the monster to start attacking the player?". If it is not then the function returns FALSE. If it is, then the function returns TRUE, but also starts off the attack sequence, in a way that varies from monster to monster. If you look at the function you will find lots of lines like:
if (self.classname == "monster_shambler")
return ShamCheckAttack ();
So it's actually another function that determines whether an attack occurs. If a monster is not on this list then it uses CheckAttack to decide.
CheckAttack (fight.qc)
This generic function checks if the player is in line of sight, and then if they are in melee range executes self.th_melee. If the monster does not melee attack, then there is a chance it will enact a missile attack from self.th_missile. The exact probability of an attack depends on the range. Otherwise the function returns FALSE, so the monster will go all the way back to ai_run and run forwards.
ShamCheckAttack() (fight.qc)
It's interesting to note that ShamCheckAttack has a slightly different approach to CheckAttack. Although the decision process of whether to attack or not is similar, if it decides to missile attack, it just sets self.attack_state = AS_MISSILE. Then the next time the monster runs ai_run(probably the time of it's nextthink), it will run ai_run_missile.
ai_run_missile() (ai.qc)
This calls self.th_missile only if the monster is facing the player, making it slightly different to the CheckAttack method.
So at the moment the Gnerk is using CheckAttack, and so leaps at the player before it is facing the right way(DemonCheckAttack uses the AS_MISSILE method). The first thing to change would be to add a line
if (self.classname == "monster_gnerk")
return GnerkCheckAttack ();
to the function CheckAnyAttack. That way you use the GnerkCheckAttack function you added. You have to prototype it before CheckAnyAttack.
There are a number of ways you could add the lightning attack. One would be to add lines like
chance = random();
if(chance < 0.1)
{
gnerk_magic1();
return TRUE;
}
just after the lines
if (enemy_range == RANGE_FAR)
return FALSE;
of GnerkCheckAttack. This directly calls the attack. The problem is that it misses out on the AS_MISSILE bit, so the gnerk will attack before it's facing the player. Another way to do it would be to set
self.th_missile = Gnerk_ChooseAttack;
in the monsters spawn function. Then write a function Gnerk_ChooseAttack which randomly selects either gnerk_jump1() or gnerk_magic1(). You could even make it select the attack based on effectiveness, but that would be contrary to the tradition and style of Quake...
Oh... My Odds And Maths
#6174 posted by madfox on 2007/07/18 05:36:00
My god, Preach, if I had the knowledge you had I probably made my own Quake mod of Hellboy. I'm only joking of course, although the idea won't leave me alone. But this little creature took already 825 verticemeshes of my time, so.. let's get on with it.
First let me thank you for your thouroughly explination of the source code. I'm beginning to understand it has more to do with comparisions than with logical copying. And me maths are a wreckage, but right.
I'm glad someone took the time to make an odd fool like me to understand how things work and I'm really gratefull for that. This qc can't stand a wrong aphostrophe and that hurts.
I hope it wasn't my code that crashed your computer.
As far I can understand I tried your first attempt on the GnerkCheck Attack, and I hope it was in the fight.qc and not in the ia.qc(?)
Changing the line gave me a few errors as the compiler doesn't want the gnerk_magic1. I have reposted the fight.qc so you can see.
It has gone deep in the night as I rearranged new gnerk sounds from the hellboy dvd, and my nerves started rumbling the same.
But the change from Gnerk_jumpTouch to Demon_GnerkTouch was a good hint! So far things run great, even in fastqcc. Hope my language also...
|
|
You must be logged in to post in this thread.
|
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.
|
|