|
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. |
|
|
Show Of Hands
#502 posted by Preach on 2011/03/30 01:31:00
Quick straw poll here:
If I was going to invest some time in a qc project, which would be most useful to mappers?
1) A medium-range navigation system for the AI. Where monsters now walk straight at the player over gaps they can't cross, this system would direct them around to the bridge. Basically navigation on the scale of rooms, not levels.
2) A system to create alternative shapes for triggers. For example, cylindrical, spherical, rotated rectangles, composition of multiple triggers into a single unit.
3) create an event-based system for with inputs and outputs on doors and other funcs. For instance, allowing you fire triggers on the events of a door beginning to open, reaching closed position, being blocked, etc.
On the input side rather than having just a trigger, you might be able to command a door to open (does nothing if it's already open), or shut (vice versa ), or toggle (the old behaviour). Having a system of 'filters' would allow conditional triggers like "pass this input on if door X is still moving".
In Order (favorite Idea First):
#503 posted by RickyT33 on 2011/03/30 01:54:58
AI first
I/O Triggers second
trigger b-box control third.
I guess all would have their uses, but better nav AI for monsters is the coolest idea IMO :)
Ai
#504 posted by jt_ on 2011/03/30 02:57:25
Would be neat to give monsters specific commands, ie attack this, run over there etc. :E
Being able to give things specific triggers would be great, for example, forcing a door to close only on a specific trigger, or making func_trains that can be made to reverse and go backwards through their track. :)
3
#506 posted by Drew on 2011/03/30 03:29:29
I would vote 3, but I don't really *release* maps, so...
AI
#507 posted by Lardarse on 2011/03/30 04:39:39
3!
#508 posted by Spirit on 2011/03/30 08:51:06
Quake is a simple pattern based arcade shooter that lives from its simplistic ai. 3 would allow people to create more atmosphere rich maps.
1!
#509 posted by negke on 2011/03/30 10:54:31
Actually, all three.
1
AI
#511 posted by ijed on 2011/03/30 12:52:42
1...3...2
#512 posted by generic on 2011/03/30 13:43:54
I can't count :)
Thoughts
#513 posted by Kinn on 2011/03/30 21:15:35
1) sounds like it would have the most tangible impact on the gameplay, although purists might argue that it would feel wrong to have Quake monsters capable of relentlessly chasing the player from room to room.
That said, I did feel the need to mackle up a very basic system in my maps to allow the monsters to chase the player up and down some of the spiral staircases, that otherwise they would have had real problems with.
2) sounds like its use would be too limited. 90% of the time, axis-aligned boxes will do the job, although I might as well admit that in Marcher I hacked in a sort of line-segment trigger (that functioned like an arbitrarily oriented invisible tripwire) which I used in a couple of places.
3) Sounds very useful all round and is a philosophy I wish Quake's trigger system had adopted from the beginning.
Clarification
#514 posted by Preach on 2011/03/30 23:38:39
Without wanting to influence anyone's votes
to allow the monsters to chase the player up and down some of the spiral staircases
This is almost exactly the use case I had in mind - a system that would be capable of allowing this, or for creatures to know how to move from a balcony, down the stairs into the atrium where the player was. The trick is making a single system flexible enough to do that without being a nightmare to set up.
It wouldn't let monsters chase you from room to room, you'd have one trigger brush creating a region, and if the monster and the player were both touching the trigger then the monster would be told the direction which moves them topologically closer* to the player. Hopefully that doesn't compromise the fundamental behaviour of any monster, just allows them to deal with complex rooms as well as open spaces.
* As opposed to the direction bringing them physically closer - the current navigation method. In open spaces, the two are the same. So by reduction the gameplay is unchanged, and in a single bound I am free!
#515 posted by rj on 2011/03/31 00:00:43
i seem to remember nehahra had some improved navigation systems for monsters, but you could always specify which one to use when placing the entity. i'd favour this approach
AI 'smell' Trail
#516 posted by ijed on 2011/03/31 02:23:22
Was something we were pondering. It got denounced when we mentioned it here of course.
Nehahra had various layers of AI and additional flags like INTREPID (ignore hazards when leaping off stuff) and the ability to teleport at will.
#517 posted by necros on 2011/03/31 03:28:11
ai sounds like the most useful.
i've experimented with different methods but never really been satisfied.
currently, i'm using a sort of waypoint system that monsters will follow after they loose sight of your.
it has the benefit of making monsters look realistic when searching for you, but in some ways, it makes them less effective.
an interim system i have is to have the ability to flag path_corners to make monsters both not search for the player, not react to damage, and to use their run animation instead of walk when moving to them.
this is only useful for initial pathing, as once the monster is awake and not following path_corners, there's no benefit.
but yeah, a unified pathing system would be totally awesome, but i just can't see how to get it to work for all cases. :(
good luck though. i'd be really interested to see what you come up with!
A simple but useful bit of AI gameplay wise would be that melee monsters that are below the player or otherwise can't find a direct path to the player will instead seek to hide from the player's LoS (whether they could hide from grenades I dunno :P ).
This could help prevent a lot of cheesing combat, if the monster hides when the player is trying to pick it off from a safe position. It's often this which easily disarms the challenge in a lot of maps, and is why the only way to really create a challenging fight is just to suddenly drop the enemies directly on top of the player in a trap.
#519 posted by necros on 2011/04/01 21:55:23
This could help prevent a lot of cheesing combat, if the monster hides when the player is trying to pick it off from a safe position. It's often this which easily disarms the challenge in a lot of maps, and is why the only way to really create a challenging fight is just to suddenly drop the enemies directly on top of the player in a trap.
i feel this is more a mapper's failing. you shouldn't really be letting melee monsters get into a position like that unless it's something you can't plan for (ie: fiend jumps off a ledge and can't reach you anymore).
but like, for example, you shouldn't really be able to 'pull' melee monsters from far away or don't provide an easy way to exploit them.
Speaking As Primarily Not A Mapper...
#520 posted by Lardarse on 2011/04/02 02:50:52
(...and no, this isn't an excuse to tell me to fuck off)
I'd contemplated re-writing the trigger system before, but I wasn't sure how best to do it. The way that makes most sense to me right now, is some sort of "message" system, that goes something like this:
"targetname" is what is being sent the message. The additional targetname entries (if present in the code) give it additional frequencies to be listening to.
"target" is what to send the message to. Again, the additional targets work like additional frequences to be broadcasting on.
And them there's an (as yet) unnamed 3rd field, which is the message to be sent. This could be something like a traditional use/activate signal, a kill signal, a change texture signal (so you can have brush entities that are doing something more useful than just being func_walls change their appearance), or maybe even something else.
This is made more interesting, of course, by being able to send a different signal to each target. Yes, this is still similar to how we have .target and .killtarget now (and yes, this would allow both to be done at the same time, as is the case in Quoth, RMQ, and other mods), but it would be more flexible than that.
The only part I'm not sure on, is if this signal should be a float or a string. And then, of course, you have to define what all of the signals mean for each object. Obviously, there would be a few common ones, but some would need additional things specified.
#521 posted by necros on 2011/04/02 07:18:29
yeah, that's an ok system. it's good because it's unified and probably easy to understand from a programming point of view.
i imagine the 'message' could be a simple bit mask where you can select what you want to change to the triggered object. so a single trigger could change, for example, both the func_door texture AND open it or whatever.
but it's just easier to code up helper or script entities instead and more intuitive in an editor (not to mention there's no support for an 'entity message' in any editors).
#522 posted by necros on 2011/04/02 07:21:07
mm, my mind apparently skipped a beat and i didn't actually explain myself on that third paragraph. o.0
i say it's easier, but it's also more flexible.
i have script entities that can change an entity's owner, change specific 'target' strings, toggle flags/spawnflags on entities.
toggling a func_walls texture is simple, but how would you put 'change targetname2 on this entity to xxxxx' in a simple one string/integer message. you'd end up with other helpers anyway.
Collecting Sigils
#523 posted by Mike Woodham on 2011/04/02 19:15:52
What is the code that lights the sigil's place marker on the player's GUI as each sigil is collected?
Are the lights just made in order or do the shapes relate to the actual sigil?
I do not get any lights when I use them (and collect them)in my levels - what gives?
Sigils/rune
#524 posted by necros on 2011/04/02 19:46:30
an engine coder could tell you for certain, but in the qc, picking up runes sets a global variable 'serverflags' with bits 1, 2, 4 and 8, corresponding to the appropriate episode.
the runes only work if the UI is set to the default one. hipnotic and rogue game modes turn on their respective UIs which don't check the runes. so if your mod uses one of those UIs or you're using quoth which uses hipnotic UI, then the runes don't show up.
Mmmmm...
#525 posted by Mike Woodham on 2011/04/02 20:57:11
Yes, if I use standard progs.dat (1.06) then the UI lights up. I am not using a mod but I am using an 'enhanced' progs.dat.
However, I have checked the sigil_touch section in items.qc and it exactly the same as the 1.06 version. I cannot find any other differences related to 'serverflags'.
Strange. Must be something, but I don't know what.
WARNING: BAD CODE AHEAD
#526 posted by Preach on 2011/04/02 23:44:24
THIS CODE IS PURE EVIL.
YOU MIGHT FIND IT USEFUL.
BUT DON'T GET FUNNY IDEAS.
So...I was working on the winner of the straw poll, which is the navigation entity stuff. Idea 3 did attract some attention so I might put up an article about naming in QC which would contain the "clever ideas" part of the event system I had in mind, so someone else with time on their hands would be free to do the footwork implementing it. Most of the effort would be in creating useful input and output on the various func_ entities, but at least it's a chance to exercise some creativity.
Anyway, I was trying to create some beautiful code involving callback functions (been reading too much ajax stuff recently) and managed to confuse the compiler enough for it to mistake a string field for a float. As you may or may not know string fields in QC are integer offsets into a big block of strings. So I came up with the following:
float INT_1 = 0.0000000000000000000000000000000000000000000014013;
.string tempstring;
void(.float stringfield) increment_string =
{
��float increment, stringvalue;
��increment = INT_1;
��if(self.stringfield < 0)
����increment = increment * -1;
��stringvalue = self.stringfield;
��do
��{
����stringvalue = stringvalue + increment;
����increment = increment * 2;
��}
��while(stringvalue == self.stringfield);
��
��self.stringfield = stringvalue;
}
void(void(.string floatfield) dispatch, .string fieldtype) strip_fieldtype =
{
��dispatch(fieldtype);
}
//then put the following code somewhere
{
��self.tempstring = self.model;
��while(self.tempstring != "")
��{
����strip_fieldtype (increment_string, tempstring);
����dprint(self.tempstring);
����dprint("\n");
����if(self.tempstring == ".bsp")
����{
������dprint("It's a bsp file!\n");
������break;
����}
��}
}
It's so hacky I don't even want to talk about why it works.
|
|
You must be logged in to post in this thread.
|
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.
|
|