Thanks
#20 posted by Mike Woodham on 2007/08/12 13:26:48
I'll play a little more with this to see if I can figure out a workaround.
No, I Can't Figure It Out And I'm Going Round In Circles
#21 posted by Mike Woodham on 2007/08/12 18:43:01
I thought I could set up a flag to say whether or not the music was playing at the time of the savegame (state = TRUE/FALSE). I know the piece of music playing by tracking it with a variable (cnt = 1/3/5/7, for 4 set pieces of music). I know both of these are saved in the savegame file (actually FALSE appears not to be saved), so presumably are loaded with loadgame.
But world.qc baulks at everything I try, usually with a 'types function and field not allowed'. So I cannot figure out how to either read the entitie's 'state' and 'cnt' and make use of them; or how to call the 'music_play_tune' function from world.qc.
Do you think I am trying to do the impossible or is it just that the logic is beyond me?
This Might Not
#22 posted by aguirRe on 2007/08/12 19:10:17
be a very good idea, but just to make the music_play_tune "callable" from StartFrame, you could assign a global entity var music_entity the value of self in play_music.
In StartFrame, you'd then just set music_entity.nextthink = time to make it execute as soon as possible. You should probably add a check for music_entity being not-world, i.e.:
if (music_entity)
music_entity.nextthink = time;
Maybe someone else can suggest a better way to actually achieve whatever you're trying to do.
Btw
#23 posted by aguirRe on 2007/08/12 19:13:50
savegame files don't contain vars that are 0 (= FALSE), so that might be why it's "not saved".
I Don't Think It's Impossible
#24 posted by necros on 2007/08/12 19:20:54
are you waiting long enough for all the entities to be spawned before you go searching for the music entity?
it should just be a matter of using a while loop to .chain through your entities until you find your music ent, checking the entity fields and then giving it a .nextthink and .think to call it's function.
music_play_tune likely has stuff with self in it, so that's why you'd need to do musicent.think = music_play_tune; instead of directly calling music_play_tune();.
or am i misunderstanding the problem?
?
#25 posted by necros on 2007/08/12 19:26:34
savegame files don't contain vars that are 0 (= FALSE), so that might be why it's "not saved".
false = 0, and i'm pretty sure variables in quake are automatically initialized to 0 if they have no value, so technically, they are 'saved' whether it's actually in the save file or not.
OK
#26 posted by Mike Woodham on 2007/08/12 20:19:16
I didn't have a problem not seeing 'state = 0' in the savegame because I would have been looking for 'state = 1' to tell me if the music was playing at the time of the savegame.
No, my "problem" is that I cannot get a compile with any statement that uses something like 'musicent.think = music_play_tune;' in world.qc as I get an error of "Types function and field not allowed". I don't know how to copy one entity into another so that the world.qc can use it.
The reason I am having difficulty is that I am only an occaisional user of QC and don't really have enough depth of knowledge about the language or protocols in use. I get by, by reading other people's code and adapting it to my use or by plain old trial and error. But I don't think we have had music in Quake in the way in which I have implemented it, so nobody has yet written the code for me to adapt, and all my trials (Lord, soon be over) have ended in failure. Well, at least I'm consistent ;-)
If someone wants to take this on, I would have no problem passing my play-music code on. It's not a work of art but it does work.
And, "at the end of the day" I am only trying to tidy up something I have already finished.
Didn't
#27 posted by aguirRe on 2007/08/12 20:46:30
my suggestion work? To copy self in play_music, you just have a new global var
entity music_entity;
and assign self to it:
music_entity = self;
Then you set
music_entity.nextthink = time;
in e.g. StartFrame. You shouldn't set the think function, that's AFAIK already set in play_music.
You only make sure music_entity's think function will be run as soon as possible (you can't control exactly when, though).
AguirRe
#28 posted by Mike Woodham on 2007/08/12 22:54:23
No, it didn't work.
If I place the 'entity music_entity;' outside of world.qc I get a compile error "world.qc(359):error: unknown value 'music_entity'".
Line 359 is where 'music_entity.nextthink = time;' sits.
So I place it in world.qc immediately following the line, 'nosave float loadflag;'
I've added 'music_entity = self;' inside play_music, thinking that it needs to be there otherwise the new entity doesn't know who 'self' is.
Finally, 'music_entity.nextthink = time;' is in LoadGame, which is called from StartFrame.
Ah, but... I have just re-read everything and added '+ 3' to 'music_entity.nextthink = time;' and now it works. I had written a note in play_music that the sound will not play for one second - I read that somewhere but don't know why it is so.
Cool! Lookin' good!
Thanks.
Now I can get to work on checking which piece should play (or not). Watch this space!
Thanks again.
Long Standing Bug?
#29 posted by Preach on 2007/08/12 23:10:12
Is this, in the eyes of those present here, a bug? (and if so, one worth fixing?)
self.th_pain (attacker, take);
// nightmare mode monsters don't go into pain frames often
if (skill == 3)
self.pain_finished = time + 5;
You might expect that this piece of code makes sure that there is a minimum 5 seconds between each pain animation on nightmare, in the same way that self.pain_finished = time + 2; in the pain function puts a minimum of two seconds gap. But this isn't quite right.
You see, most pain functions only set pain_finished times once they've already concluded that pain_finished < time. Otherwise they'd constantly set pain_finished further into the future as long as the monster kept taking damage within the pain_finished period. Nightmare mode is, in effect, doing exactly that. You have to go 5 seconds without damaging the monster at all, rather than 5 seconds since you last caused it to go into pain.
So you end up with very odd behavior. If you pour nail after nail into an ogre, it'll only go into pain on the first one, but if you spread each nail 5 seconds apart, it will go into pain from every single one. Of course, the bug doesn't manifest itself that noticably, as 5 seconds is about enough time to kill any monster if you're focusing exclusively on it. Still, it might becomes more important with new high hp enemies, like in Quoth or the like. So, thoughts?
Mike
#30 posted by aguirRe on 2007/08/12 23:32:25
The reason you get a compile error is because of the order in progs.src file. Since world.qc is before play_music.qc, the compiler needs to know what it is before you can use it.
You can get around this kind of problem by declaring the global var in defs.qc or another file that's early in progs.src.
Or just declare the var in all files that you use it in. It'll just be one var anyway, as you can't have two global vars with the same name.
Good that it works now.
Well
#31 posted by ijed on 2007/08/12 23:51:39
In Quake2 the enemies never went into a pain animation in NM - they just ignored the shots, feeling no pain.
And it felt right, they are cyborgs. In Quake it is a bit strange that I can always count on a Vore (for example) yowling on the first hit, and have enough time in the animation to throw four grenades (1 to cause it to go into pain, three more to kill it) without reprisal.
Is it possible to add a randfloat value to the factor for pain - with the skill number deducting from this? (Yeah, just exhausted my coding knowledge).
What I'm suggesting is recoding the monster pain sequence, which can most likely cause alot of headaches, but I can see:
Create random Variable 1-10, deduct (skill level).
Is Variable higher than 5? If yes, play pain animation.
Which should give the engine less to think about for each particular monster currently in combat, since they're not all accumulating delays. This could be useful if, for example, the player is spraying nails into a horde of Vorelings.
It could also gives an organic feel to the enemies, making them less predictable and robotic.
Sorta
#32 posted by Preach on 2007/08/13 00:13:26
Some of the quake monsters already do that, for instance the pain decision code for the fiend is:
if (self.touch == Demon_JumpTouch)
return;
if (self.pain_finished > time)
return;
self.pain_finished = time + 1;
sound (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM);
if (random()*200 > damage)
return; // didn't flinch
demon1_pain1 ();
So any hit of less that 200 damage has a chance of being ignored(apart from the sound). This tends to only be done for the tougher monsters though. I imagine that the vore always goes into pain because it's a more frail thing - although it does get a 3 second gap between attacks to compensate. The wizard gets a flinch value of 70 hp because if it does stop in pain, it's probably gonna die because the player can get a bead on it. Setting it that high gives it a good chance of ignoring nails. I don't think it's something that should be applied across the board though.
#33 posted by necros on 2007/08/13 02:56:33
could make it take into account it's current health when determining whether to go into pain or not. then add a random time to it, and wait until that time expires to add more delay.
Preach:
#34 posted by metlslime on 2007/08/13 10:08:18
do you know if that "nosave" keyword is reliable? If i sit there and spam the save and load buttons, every once in a while the sound won't be playing after I load. If i then keep loading that one save file, it will be missing the sound 100% of the time. This suggests that something is wrong with that save file (like the loadflag variable is occasionally getting saved)
Aghhhh!
#35 posted by metlslime on 2007/08/13 10:37:15
now i'm finding that certain quakec changes are causing the level to not load, giving errors like
"couldn't spawn server maps/info_player_start.bsp"
"couldn't spawn server maps/samelevel.bsp"
almost as if strings in the progs are getting all jumbled up. Is frikgui27 a bad version to be using? Maybe it's got some bugs or something?
Okay....
#36 posted by metlslime on 2007/08/13 10:48:04
Anyway, i think i solved the issue; I guess i just needed to delay a bit before trying to play a sound. I guess sometimes if you try to play a sound too soon after starting a level or loading a save, the game just swallows it and you don't hear anything. I've noticed the same is true with printing messages to players in spawn functions.
As for the crazy errors in post 35, no idea what happened there but it's gone after making more changes.
Yeah...
#37 posted by Preach on 2007/08/13 11:53:07
I've had that string bug happen to me before, usually it goes away if you restart frikgui. Must be some kind of bug - if it keeps recurring you might want to use fteqcc instead, or mention it to frikac. I'm pretty sure that nosave is a reliable feature, although it sounds like you've fixed it anyway.
Just To Close The Loop
#38 posted by Mike Woodham on 2007/08/13 21:49:10
I put a flag in play_music set to true when music is playing and then read it in LoadGame. It works a treat.
Thanks.
Loading DPM Model Files In Darkplaces
#39 posted by Zylyx on 2007/12/10 13:35:48
Hi!
I posted thsi thread last week on the Inside3d forums, but I didn't get any replies, so I wnated to try my luck here, with you nice folks ;).
I'm having some trouble loading a DPM model for Darkplaces.
This is the code I have, minus the comments (added to weapons.qc)
//model precache (added at the beginning of the //file
precache_model("models/weapons/ak/v_ak47.dpm");
//Set the weapon up in players viewport
if ((self.weapon == IT_SHOTGUN))
{
self.currentammo = self.ammo_shells;
self.weaponmodel = "models/weapons/ak/v_ak47.dpm";
self.weaponframe = FALSE;
self.items = (self.items | IT_SHELLS);
}
When I try this out, the model doesnt show up, and the console reports "cant find <tex name> for mesh <tex name>, using default grey_checkerboard" (or something along those lines)
I'm using the the test v_ak47.dpm model that came with the dpm model viewer utility.
The model directory is as follows:
mygame/models/weapons/ak/v_ak47.pm
Inside the ak directory I have the following files (including the textures that the engine reports it cant find, in TGA file format):
-v_ak47.pdm
-10 of the TGA textures corresponding to the model
I would really appreciate if someone could tell me how to load and display DPM models in darkplaces.
Thanx again in advance!
-Zylyx
Hmm
#40 posted by Preach on 2007/12/10 20:09:46
I don't really know much about dpm models, but I guess the first thing to check would be that the filenames are correct. Can you give a specific example of one of the paths? If they came ready named with the example file then it's unlikely to be the problem. Also, see if a shorter path helps, like putting the model in mygame/progs. Again it sounds unlikely but it's worth a shot.
Otherwise I'm gonna have to pass you on to another forum again. The best place to ask/check out would be the nexuis forums. Nexuis uses dpm for all it's models IIRC, so checking out their source code/mod to see how to do it might help. If even that fails you might post on their forums and hopefully a coder there can help.
#41 posted by Zylyx on 2007/12/10 22:59:25
thnx!
My model directory code is as follows (in the "mygame" directory in the Quake directory, coz that where my progs.dat file get's called from for my mod):
precache_model("models/weapons/ak/v_ak47.dpm");
and for the viewport setup:
self.weaponmodel = "models/weapons/ak/v_ak47.dpm";
I'll have a go at the Nexuiz forums, and I'll hopefully be able to get some info there.
C++ Coding Help
#42 posted by necros on 2008/03/30 08:14:01
i was wondering if someone could give me a hand with this...
basically, i wanted to create some kind of time system in a c++ game i'm working on. well, actually, i'm working on someone else's code, and currently, there's no sense of time at all, all timing is done by frames, which, to me anyway, seems like a Bad Thing.
ideally, i'd like to have a simple counter that starts at 0 and goes up in seconds like quake's 'time' float so that i can do things similar to self.nextthink = time + 5.2; (obviously, wouldn't be identical)
btw, i'm a c++ noob. ;)
Necros:
#43 posted by metlslime on 2008/03/30 11:04:43
you basically have a global time variable, and have the code update the value at the beginning of each frame. Probably, you'd do it in the main loop that runs your game. And the time you can get by using the appropriate system call, for example windows has one, SDL has its own, etc. See Sys_FloatTime() in the quake source for an example of how it's done.
Once you have a time variable that is available to any piece of code, you can do simple tests like: if (this.nextthink <= time) this.think();
Or
#44 posted by megaman on 2008/03/30 15:22:46
you hand the last frame time delta into all your updates
|