News | Forum | People | FAQ | Links | Search | Register | Log in
Monsters
Thought I'd start a thread on this, it could have gone in Gameplay Potential, but this is more specific.

What are the favoured special abilities for monsters to have?

Shield
Homing shots
poison
wall / ceiling climbing
leaping
explosive death
ressurection
cannabalism
spawning / cloning
Teleportation
Dodging

That's off the top of my head, anyone have any other cool ideas or concepts?

And what new abilties could the old monsters have - like Scrags that change to swimming if they enter water (thanks text_fish) or an Ogre that pisses on the player after killing them (thanks Romero).
First | Previous | Next | Last
Typo 
if(bearer.classname == "monster_ogre_melee")
return FALSE;


should read

if(bearer.classname != "monster_ogre_melee")
return FALSE;


But you all saw that, right? 
I Look 
At this from more of a design POV, and the most intersting bit of the posts for me is the idea of the Ogre getting angry and bored blocking all the time.

I love putting in lots of logic to monster functions, of which the player only registers a tiny percentage, where the above would fall neatly.

It makes me think of the Ogre getting pissed off enough to do a running charge with the sheild (still blocking) kind of like a L4D2 Charger.

I need to stop playing that game - its affecting my thinking too much. 
AI That's Worth Writing 
(I was kind of thinking charger too...)

For a while now I've had some idea about what is and is not, in my opinion, "good" AI, and this post is me trying to put that into words. I think there are three desirable properties for AI design, which I try to apply when designing and coding. Maybe "not worth writing" is too strong a term for things that don't meet them, but if you've got limited resources then they can guide you on what to focus on. They are:

� Useful
� Visible
� Effective

���Useful
This means that pretty much any player will see the behaviour after enough encounters. Either that means it has to arise in combat naturally, or it is something that a mapper can highlight by setting up combat in such a way that the behaviour is seen. Writing AI which 99% of people will never see is time that could have been spent better.

���Visible
The player has to be able to recognise what monster is doin. The example of AI that isn't visible which I always pick on is the ability of some half-life monsters to track you by scent. It's almost impossible for the player to see the difference between this and the ability of quake monsters to always know where you are. The latter is miles simpler to program, of course.

���Effective
The behaviour should change how combat between the player and monster unfolds. Effective doesn't have to mean that it makes the monster harder to kill. Making it so that the shield ogre won't interrupt melee attacks to block projectiles makes it vulnerable to attacks other than splash damage. This makes it much easier to fight, and also opens up a whole second kind of combat with them.

I know that they aren't entirely orthogonal concepts as written, but that's the closest I've come to describing them. They were things I was thinking about in the part of the post about the ogre choosing not to shield any more, and how the charge idea related to that.

Firstly, in order for unshielding to be useful, there needs to be some reason for the player to be spamming nails at the ogre in the first place. As a player, once I've worked out that it reflects everything I fire at it, I'm not going to waste nails doing that without some compelling reason. The ability to hold it at bay by firing isn't very helpful if I need it to be in melee range before I can hurt it. The charge attack was an idea for a threat it might pose which could make the player apply suppressive fire, and so make the behaviour useful.

The charge ability was also helpful because it could make the decision to unshield visible, if the ogre always launched into a charge as they drop the shield. You'd have to take care that reusing the charge idea didn't backfire - if the ogre will charge anyway, is suppressive fire going to remain a useful tactic? At least it's clear that this AI behaviour is effective, because once the decision is made, the ogre changes from invulnerable and static to vulnerable and moving, and the player will have to react to that.

By this point, it feels a lot like theorycraft, and even if you think you've satisfied all three in theory, you can find an ability doesn't work at all in practice*. But my feeling is that unshielding would probably fail as a useful behaviour. Once players figure out the deal with the shield, they won't ever find the need to fire at them for that amount of time, the benefit if any exists is too marginal to spend 10 nails on. So I would have to weight the effort of writing that code in order to experiment with it against the chance of it ever being seen outside my own testing.


* This happened 5-6 times with the Sentinel in Quoth, that thing was a nightmare... 
Hey That's Terrific! 
That's more assambly on my plate then I can hatch, but I asked for it.

Not sure if I can understand it at once, but there's a clue how to estimate the given question.
I'm not good with maths, and the only reason I'm still reading is that I feel there could be a logical scripting to make the monster do what it need.

Hadn't expect that reaktion, but when I remade the Zdoom monsters I already had this feeling quake monsters could be made better.
The animation frames for shielding are already there.

Now screwing that .scr to unknown puntuation.
grmrpf... 
Thanks Preach 
I tried your code of 408, much further I can't follow due to errors. If I place it just after void()spike_touch in WEAPONS.QC the compiler keeps asking for a definition of the spike_touch_reflected.


.float hit_z;
void() spike_touch =
{
local float rand;
if (other == self.owner)
return;

if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing

if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}

// hit something that bleeds
if (other.takedamage)
{
spawn_touchblood (9);
T_Damage (other, self, self.owner, 9);
}
if(other.classname == "monster_ogre_melee")
{
// all of our new reflection code goes here
local vector I,N;
I = self.velocity;
N = normalize(self.origin - other.origin);
self.velocity = 2*(N*I)*N - I;

self.owner = other;
self.touch = spike_touch_reflected;

return;
// all of our new reflection code end here

}
else
{


So I tried something like

void(vector org, vector dir) spike_touch_reflected =
{
if (other.takedamage)
{
spawn_touchblood (9);
T_Damage (other, self, self.owner, 5);
}
newmis = spawn ();
newmis.owner = other;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;

newmis.angles = vectoangles(dir);

newmis.touch = spike_touch_reflected;
newmis.classname = "spike";
newmis.think = SUB_Remove;
newmis.nextthink = time + 6;
setmodel (newmis, "progs/spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
setorigin (newmis, org);

newmis.velocity = dir * 1000;
};

And then the compiler gives no error, only me.
^v^ 
Spike_touch 
It was worth reading.

Really don't have a clue where to start now.
I keep trying to find a right scripture, but if I wonder where my reflected spike has gone. 
Preach's 
Posts are like classes in Qc.

Rinie, try adding �print's to everything - so when an attack deflects the console says "attack deflected" and then for every other stage "attack hit somethin" and so on.

Its the only way to know for sure what's going on. 
#12 
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.