|
Posted by metlslime on 2007/08/08 04:57:56 |
This is a counterpart to the "Mapping Help" thread. If you need help with QuakeC coding, or questions about how to do some engine modification, this is the place for you! We've got a few coders here on the forum and hopefully someone knows the answer. |
|
|
Geometric Distribution
#431 posted by Preach on 2010/10/05 21:53:02
The code you posted means he has an 80% chance to attack each frame. One of the best ways to understand what this means is to look at the probability that the monster will start attacking before the 2nd, 3rd, 4th frames etc.
The easiest way to do the calculation is to flip the question on it's head. What is the probability that we are still not attacking on the 2nd, 3rd, 4th frame? For that to be the case, we must have failed to attack in all the previous frames, and the chance of that is 0.2 each time. Since each trial is independent, we can multiply them together, as follows:
Frame 2: 0.2 * 0.2 = 0.04. 4% chance of not attacking after the second frame
Frame 3: 0.2 * 0.04 = 0.008. A 0.8% chance of not attacking on the third frame or earlier.
Frame 4: 0.2 * 0.008 = 0.0016. Scarcely a 0.1% chance that we are not attacking 4 frames of considering it.
So it's pretty certain we'll attack within the first 3 frames, our code is largely creating variety in behaviour over a range of just 0.3 seconds. Even if we changed the probability to 0.5 we'd still expect the monster to attack quite quickly: 1 / (2^10) is the probability that we wouldn't have attacked after 1 second - which works out at > 0.1%.
Using attack_finished as a cooldown is probably the best way to to long pauses out of your monsters, if you want them to choose between attacking with a missile or closing the distance with the player.
Yeah
#432 posted by necros on 2010/10/05 23:25:20
that makes a whole lot more sense. i confused myself over why the chance to attack would go down over time, which is just stupid because every time we check, we are giving a new chance to attack.
Quick Question
#433 posted by than on 2010/10/07 16:21:16
I have a feeling I could find this if I dug through the Quake source, but are the lengths of key/value pairs for map entities limited to 16 and 32 chars respectively? If not is there some other limit? Does anyone know.
On top of that, if anyone happens to know the max number of:
entities in a map
faces per brush (guess this is compiler limited)
key/value pairs per entity
I'd love to know them :)
^^
#434 posted by necros on 2010/10/07 19:04:03
Thanks
#435 posted by than on 2010/10/08 00:20:21
1024 seems quite a lot. I'll just get rid of the limits I put on my map loader.
Texture names do appear to be limited to 16 chars though.
#436 posted by metlslime on 2010/10/08 00:39:27
Texture names do appear to be limited to 16 chars though.
15 chars unfortunately, since you need a null terminator.
#437 posted by Spirit on 2010/10/08 16:25:55
This is not QuakeC related. The answer is hopefully simple algebra but I am too stupid to figure it out for myself and Google is not helping.
Let's say I have these 2D coordinates:
1) 10;10
2) 54321;12345
and want to fit them into a smaller (let's say 800x800) window. How would I code that? Do I really need to make an affine transformation? If yes, no need to explain the how, I should know that.
";" Is Not A Name
#438 posted by jt_ on 2010/10/08 22:57:46
frikqcc keeps complaining about ";" not being a name in the following function, but I can't any ;'s being used as names, or any stray ones that might being messing with things. This is just the BackpackTouch func from progs106
<code>
/* PLAYER BACKPACKS */
void() BackpackTouch =
{
local string s;
local float best, old, new;
local entity stemp;
local float acount;
if(other.classname != "player")
return;
if(other.health <= 0)
return;
acount = 0;
sprint(other, "You get ");
if(self.items)
if((other.items & self.items) == 0) {
acount = 1;
sprint(other, "the ");
sprint(other, self.netname);
}
// if the player was using his best weapon, change up to the new one if better
stemp = self;
self = other;
best = W_BestWeapon();
self = stemp;
// change weapons
other.ammo_shells = other.ammo_shells + self.ammo_shells;
other.ammo_nails = other.ammo_nails + self.ammo_nails;
other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
other.ammo_cells = other.ammo_cells + self.ammo_cells;
new = self.items;
if(!new)
new = other.weapon;
old = other.items;
other.items = other.items | new;
bound_other_ammo();
if(self.ammo_shells) {
if(acount)
sprint(other, ", ");
acount = 1;
s = ftos(self.ammo_shells);
sprint(other, s);
sprint(other, " shells");
}
if(self.ammo_nails) {
if(acount)
sprint(other, ", ");
acount = 1;
s = ftos(self.ammo_nails);
sprint(other, s);
sprint(other, " nails");
}
if(self.ammo_rockets) {
if(acount)
sprint(other, ", ");
acount = 1;
s = ftos(self.ammo_rockets);
sprint(other, s);
sprint(other, " rockets");
}
if(self.ammo_cells) {
if(acount)
sprint(other, ", ");
acount = 1;
s = ftos(self.ammo_cells);
sprint(other, s);
sprint(other, " cells");
sprint(other, "\n");
// backpack touch sound
sound(other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
stuffcmd(other, "bf\n");
// remove the backpack, change self to the player
remove(self);
self = other;
// change to the weapon
if(!deathmatch)
self.weapon = new;
else
Deathmatch_Weapon(old, new);
W_SetCurrentAmmo();
};</code>
Deception
#439 posted by Preach on 2010/10/09 00:14:24
The error message is true but unhelpful. It's trying to use a ; as a name, but what that means is that it's reading a line in a way you didn't intend. Often you get unexpected parsing errors when you leave a function earlier or later than expected. In this case you're missing the closing braces for the self.ammo_cells block, and so it's reading some further code incorrectly.
I know that func_ eats indentation(unless you're really patient with inserting nbsp character entities) so I can't say if missing indentation might have made this harder to spot. But I can recommend editing code in something that can highlight matching braces in some way - I pasted the code into notepad++ to check the matching. I will concede that knowing it could be a mismatched brace based on the error was really key, so it's not all software solutions.
Hat Tip
#440 posted by jt_ on 2010/10/09 00:32:49
That was it, thanks Preach. In my editor (acme) everything is indented fine, but as you said func_ at them. Wish func_ has support for <code></code> tags.
Don't Forget To Spellcheck...
#441 posted by jt_ on 2010/10/09 00:33:58
s/at/&e
#442 posted by necros on 2010/10/09 02:23:15
a preformatted tag would be nice, but that would likely break the forum width?
mind you, the forum could probably get twice as wide without bothering anyone.
#443 posted by Spirit on 2010/10/09 08:23:06
No, absolutely not. Apart from the colours and no-clutter, the 72-80 character line length ensures the great readability of func. Forums that spread to full-width (or anything remotely like that) are an abomination.
Use http://www.inside3d.com/pastebin.php , that even gives you syntax highlighting. Also be aware that func has a preview button. ;)
Yeah
#444 posted by RickyT33 on 2010/10/09 14:59:28
No offence to Quakeone.com for example, but having like more than 12 words on a line is a bit of a no-no. Just hurts my eyes :)
Good Point
#445 posted by ijed on 2010/10/09 17:45:18
Ok...
#446 posted by necros on 2010/10/09 19:37:21
Ropes...
#447 posted by necros on 2010/12/07 02:45:52
so i was wondering... how hard would it be to create some kind of dynamic rope thing in QC?
i'm thinking, you would put down a func_rope and then specify the length of the rope. then target at an info_notnull.
for the code, i first thought it would be pretty easy, all you'd have to do is first spawn an entity chain and then set each of the nodes in the chain to obey quake gravity.
then, all you'd need to do is check every frame to make sure the next link hasn't moved out of range and if it has, move it back along a straight vector.
but then i started thinking that you can't just iterate forward through the chain because you would have two anchored positions with only the center moving freely and then my head exploded. :(
Oh
#448 posted by necros on 2010/12/07 02:48:37
and this is the best part: i started trying to code it because i was too lazy to make brushwork wires in my map. �_�
#449 posted by metlslime on 2010/12/07 03:50:25
ropes are easy enough, just set up a havok-like physics system and include inverse kinematics, then set up the constraints between your rope links, and mark the two ends as unmoveable. :)
You Have To Burn The Rope From Both Ends At Once
#450 posted by Lardarse on 2010/12/07 03:52:34
With two anchor points, you have the trail of gravity come from both at once. The only tricky situation is in the middle.
Actually....
#451 posted by metlslime on 2010/12/07 03:55:34
if all you want is a rope that doesn't collide with anything, including itself... it's doable.
To solve the rope position for a static rope, you just set it up at spawn: guess and then iteratively refine the locations of all entities until it's within a certain tolerance.
If you want it to be dynamic, you don't need iteration, but you give the rope some elasticity and then have it accelerate to the correct position every frame. With the right values, it will look pretty good. Otherwise it will be bouncy and rubbery and go crazy.
Of Course...
#452 posted by metlslime on 2010/12/07 03:58:08
You also need to render the rope. I guess you would use a model that represented a segment of rope X units long. Whenever the distance between segments is not X, you will see gaps or overlap. Or have a bunch of frames in the .mdl to represent a range of distances, and quakec can select the frame based on the actual distance between joints on that frame.
Sounds Cool
#453 posted by ericw on 2010/12/07 04:00:43
Here's one tutorial I found, not sure how easy it would be to implement in quakec though: http://freespace.virgin.net/hugo.elias/models/m_string.htm
#454 posted by mwh on 2010/12/07 05:12:42
If it's static, a rope hangs in a cosh curve ( http://en.wikipedia.org/wiki/Catenary ). You can just calculate it with a scientific calculator I guess :-)
Ropey Mechanism
#455 posted by Preach on 2010/12/07 21:10:04
The thing I'd want the most from creating a good rope system is just frustratingly out of reach of the QC - to be able to control endpoints of a polygon independently of each other. The use would be to attach some end of a polygon to one "entity" and the other end to another, so you could create a continuous mesh that you could deform individual segments of.
Without that, I'd say you're better off just creating a static mdl prop to represent a rope. One trick that I think could work well in a map is creating a reaction to "wind", and ropes would be a great prop for displaying it. The idea is to have a global wind variable which stores a value between say 0 and 40 representing the wind force in that frame.
You'd want a slow random walk which would move the wind through these values, it's possible that adding crandom()(sic) to it every 0.1 seconds and capping the value within the range would suffice. Scaling the adjustments by frametime(and then back up with a larger constant) would allow you to recalculate the wind strength every frame which might improve the animation. It might also benefit the model to make it more likely to move the wind towards the middle values than the extremes.
You then need props through your level like ropes, "ye olde inne" signs, torches, lanterns and flags which are specially designed to react to the wind. They might be give specially designed models which have frames from 0 to 40 corresponding to the strength of the wind. Then they would only need to have think functions which regularly update the entity's frame to match the wind in that frame, maybe with some jitter.
In some cases, like the sign at the inn, you might only be going for simple rotation back and forth. Then you would be better served using .angles rotation since some engines transmit it with higher precision, and you would avoid the floating vertices rotating a sign two degrees each frame is bound to produce. You would also not need to use granular values between 0 and 40, but just use the floating point wind value directly to calculate the angle.
Then just add some howling wind and creaking timber sounds and your windswept landscape is complete!
|
|
You must be logged in to post in this thread.
|
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.
|
|