News | Forum | People | FAQ | Links | Search | Register | Log in
Mapping Help
This is the place to ask about mapping problems, techniques, and bug fixing, and pretty much anything else you want to do in the level editor.

For questions about coding, check out the Coding Help thread: https://www.celephais.net/board/view_thread.php?id=60097
First | Previous | Next | Last
Jpl: 
no point having 22khz, since quake only supports 11khz, it'll downsample it itself and you're just wasting memory.

i noticed that quake uses different markers for looping sounds. usually music programs use 'sustain' loop markers for looping, but quake seems to use region markers. 
Nah, That's Easy 
Because the thing there is, you are allowed to control the constant velocity to be anything that you like. Picture(in fact, draw a copy, it'll help the explanation) a trapeseum for the graph of velocity against time, with constant slope upwards for the accelerating portion, constant slope downwards for the decelerating portion, and a horizontal line joining the two. You now need a simple result from calculus to tell you that the distance travelled is the area beneath the velocity curve and the line
v = 0.

So, we calculate the area of this trapeseum. Divide it into two right-angled triangles and a square. The triangles have base acceltime and deceltime, so the area enclosed is 1/2*(acceltime + deceltime)*v, where v is a constant speed that we will calculate later.

The square has base movetime - (acceltime + deceltime) so the area is [movetime - (acceltime + deceltime)]*v. Sum all these areas and we get:
[movetime - ((acceltime + deceltime)/2)]*v = delta_x
So, solve this for v by dividing through.
v = delta_x / [movetime - ((acceltime + deceltime)/2)]

It's not worth doing this calculation every time the door moves, do it once when the door spawns and store it in the door's .speed field.

This gives us the constant velocity for the middle section of the motion, but we still need a simple formula for the velocity at each end. It's what you'd expect:
x'(t) = v * t / acceltime for the accelerating phase and
x'(t) = v * (movetime - t) / deceltime for the decelerating phase.

And that's it, very short and sweet.

So how does it relate to the other problem? Well, imagine that we didn't have the freedom to choose the velocity for the constant speed, but we can join the origin and the first part of the horizontal line by any curve that we like(or any strictly increasing curve if you prefer). Ignore the decelerating phase at this point.

We have to choose the shape of this curve so that the area underneath it plus the area below the constant velocity section adds up to the right distance. We can see that we're limited already as the curve isn't allowed to go above the horizontal line for v, and it can't have negative area. So we've got v*acceltime area to play with, and in theory we can come up with a curve for any area between 0 and v*acceltime, ie distances between 0 and v*acceltime have theoretical solutions.

Now, I think that in theory the area under a function of the form
((a*(acceltime-t))^p + (b*x')^p)^(1/p) = v will take any area from 0 to v*acceltime, for the correct value of p between 0 and infinity. For instance with p = 2 and the correct scaling you'd have the equation of an ellipse through the origin and (acceltime,v), and p = 1 is the straight line solution we've already seen. I'd hazard a = v/acceltime and b = 1 as the right scaling but don't hold me to it.

Anyway, that's all academic really as you'd have to solve for p, which isn't easy under the best of circumstances. QC just isn't going to cut it at all. But it's nice to see it can be done in theory
: - ) 
Necros 
It seems that you need to be able to divide the total time that the door operates into segments. In the secret door code functions you already have an example of this available (first second cues sound, second second the door is pulled backwards . . . etc).

The first part of the problem would be to add a factor that allows you to
predetermine the length of time it takes to arrive at the destination.
If it takes 1 second to reach 64 units then plug in an equation that divides the total number of unit segments that need to be moved and then divides that result by the movetime.

So a door that moves 128 units whose move time is 8 is traveling at a constant of .25 seconds. Once you have a constant, you can plug in variables that will give you the acceleration and deceleration you are looking to add.

The movement code in the secret door function is in this bit of code.

SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);

you'll need to get it to use movetime as a countdown (The loop controling the function would look something like this) a = 0, if a > movetime then stop!, a = a + 1) so you can force it to plug in a change for the self.speed for each segment of the movetime countdown. 
yeah, none of that was the problem. it was just solving the change in acceleration such that it would arrive on time. 
Hmm 
keeping things simple, you would gauge deceltime with acceltime so we can easily balance this factor out of the equation and all we have to deal with is the time of constant velocity.

dt/at

Then you will need to find the difference between the constant .25 with the 2 seconds
of constant velocity divided by the number decel seconds, and add to the dec modifier which you use to decriment the speed in the last four seconds.

so if the basic aceltime unit is self.speed = self.speed + .2 than 4/2, .2/2, the the first variable for the decrement in deceltime will be a convenient self.speed = self.speed - .1.

Now for the second variabl in the decrement equation.

Constant velocity reached self.speed + .4, times this by the number of seconds of constant velocity and you get .8, then divide by number of seconds of decelaeration (4) = .2.

So we add this to the first total and adjust the deceleration speed to self.speed = self.speed - .3 and that will get us there in 8 seconds. 
Sounds In Quake 
no point having 22khz, since quake only supports 11khz, it'll downsample it itself and you're just wasting memory.

OK, not a big deal to downsample the file... with any sound editor...

i noticed that quake uses different markers for looping sounds. usually music programs use 'sustain' loop markers for looping, but quake seems to use region markers.

So, how to manage it properly when saving the .wav file ? I saw aloop enable option in Cool Edit, but it is avalaible without any "extra" options about the way it is marked in the file... ?
OTOH, is there a good tutorial for sound creatio for Quake (like there are some texture creation tutorials)? 
JPL 
in cool edit, just flag the loop field in the wave properties and the sound loops in quake. 
Neg!ke 
I did it, but it doesn't loop in Quake... note I even save the .wav file after that :P

furthermore, I tested the sound with play_sound_triggered item, and the sound has been played properly, so the .wav file is not the cause.... maybe the loop info..

So where's the issue ? Any idea ? 
Oh 
in an older version of cooledit it worked like that (at least iirc).
then you'll have to set
(loop) markers at start/end. 
Neg!ke 
Thanks, I'll take a look. 
YEEeeessss !!! 
Neg!ke, even if the loop properties was set correctly, it was missing the loop marker. I added it and it is working fine now...
I'm now able to add new sounds to my map... Thanks a lot ! You rock ! 
Cool 
jpl 
 
can anyone explain me why doesn�t the fucking door dont work after i pass? :\

http://trinca.no.sapo.pt/l.zip

thks in advance! 
Trinca 
I'm getting a 'not a valid file' error from Winzip. 
 
Trinca 
standard triggers can only have one single function: target or killtarget or message.
put the message in a trigger_relay with the same targetname as the door and it works. 
QuakeC Query 
I want to have a func_button (for a deliberate player action) and a trigger_once (for a non-deliberate/unintentional action) pointing to the same target.

Can I tell from within the target's function, which of the two activated the target? This would enable me to give a different response e.g. if activated by a button, do this, else do that (to the targeted entity) 
Not Easily... 
As far as I can see, there isn't a nice self contained way to do it - meaning a way to write it that doesn't involve changing the code for the buttons and the trigger_once in some way. There is a global entity variable called "activator" that stores who is performing the triggering when something uses its targets. Unfortunately this stores the player entity that pressed the button, not the button entity itself. This inspires us to create such a global to store the entity that is doing the actual using, which I will refer to as the "mechanism"(although effector might be a better term).

Ok, first open up defs.qc and add to the bottom:

entity mechanism;


We will use this global to store the entity that is enacting the trigger, for example the button or trigger.

Next up is subs.qc, find the function
SUB_UseTargets
Right at the top of it add a temporary entity called "mech" to the existing list, followed immediately by this code:

if(self.classname == "DelayedUse")
mech = self.owner;
else
mech = self;

Next add

t.owner = self;

right after the line

t.target = self.target;

This relates to the DelayedUse line above, so that if the trigger has a delay, we still count the mechanism as the real trigger, not this temporary entity.

Now go down to the big loop at the bottom and add

mechanism = mech;

right above the line
t = find (t, targetname, self.target);
in the loop marked //fire targets(not the killtarget loop). We keep resetting this each time we run the loop, as each time we trigger something it might call SUB_UseTargets itself, which may change mechanism.

Now it's very simple to test which one of your entities set off the thing. In your new entity's use function, perform a check like

if(mechanism.classname == "func_button")
do stuff
else
do other stuff

I think this is a fairly robust system, but I've not tested it so just say if there are problems. 
Preach 
Thanks, this looks good.

I will test it later this evening and report back. 
Illusionary + Efrags 
i have a lot func_illusionaries consisting of several brushes which are seperated from each other. this gives 'too many efrags' warnings. changing them to func_walls solves the problem, but i'd rather have them be nonsolid. creating a seperate func_illusionary for every single brush is out of question because (i think) there are more than 128.
so what's the principle underlying this, how far can the brushes be apart from each other, what's the difference between static and dynamic entites concerning this distance? 
Preach 
Said in English with a very French accent and much overuse of the hands...

...soooperrrb!!

Thanks. 
Negike: 
I don't fully understand efrags, but from what I do understand, any large entity is divided into multiple efrags based on how many nodes of the BSP it occupies. This is why a large func_* with many seperate small parts is problematic.

I also don't know if/why it's different for func_wall vs. func_illusionary. But the one obvious difference is func_illusionary is a static object, and func_wall is an edict. So maybe that is partly why. 
 
why in gl i dont have any HOM�s and in software i got a lot of then? is there any way to solve this? 
Light Attenuation 
how can i attenuate a spotlight (light with a target) in quake - pretty sure ive read something on this somewhere but can't remember where. if i remember rightly its just a single key with float value . . .

neg!ke - why not just split the big 128 brush illusionary into 2x64 brush versions? if that doesn't work split into 4x32 and so on until you get rid of the error. don't know if that'll work because i haven't come across the problem before. 
Trinca: 
The thing you're describing is called "greyflash" -- solution: increase r_maxsurfs and r_maxedges in the console. 
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.