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
Ya I Been Thinking 
of monsters being able to drown and be burnt

hvent gotten round to figuing it out

somthing with limiting there aair like the player and wutnot 
Monsters In Liquid 
Re: ijed

Number 1 is fixed by Gyrofying them. Liquids have movement resistance. You can even give them buoyancy.

Number two, I agree, they should drown or burn. This shouldn't be so hard to do. Monsters should just remove self when inh2o= lava.

// Gollum :-P 
Party Hard2 
http://shub-hub.com/files/images/ogreb.gif

Maybe in the crowd for Madfox' band ;) 
Ijed 
I'd love to see such an ogre in Quake :D 
Remake Quake 
 
 
z-aware monsters, monsters taking liquid damage etc can be found in the DarkPlacesMod. Monsters also do a bit more damage, do some leading... but not perfectly. However LordHavoc also made one-hit kills from monsters deadly. They can only bring you down to 1 in a single hit, after that, its your priority to get the hell out of Dodge (for which he provided health regen and offhand grapple). I enjoy DPmod, its a good way to replay any map due to the presence of the grapple with the more aggressive monsters. 
Fiends 
Here's a bug that needs to be fixed:
fiends getting stuck. I know it's part of the "gamePLAY" to use stairs or little doorways as a way of defusing fiends so you can plug away at them safely, but it just seems like an exploit.

I wonder if the lookspring code could be adapted to alter fiend jump velocity to get them up stairs? Or maybe just lift them 16 units off the ground when they jump so that they clear whatever stair they're butting against - wonder how obvious that would look. 
Better Yet 
Just make them hull1. Doesn't sort out the stairs thing, but it solves nearly everything else... 
Fiend Jumping Trick 
I'd be wary of doing something like bumping them up 16 units, in places with low ceilings you'd run the risk of them getting stuck in the ceiling, and then they're a worse sitting duck.

What might work better is giving a little extra horizontal velocity to the fiend at the apex of its jump. This would be a bit like the air control the player has, just nudge them forwards by 10-20 units/second. That should be low enough that you wouldn't notice the extra speed if they're making a full leap. Ordinarily the fiend gets stuck because all the horizontal velocity is zeroed when he hits the step at the start of the jump. If you give it him when he's already high enough to clear the step, then it should work.

Of course, that little velocity won't get him up more than one step per jump. Perhaps if you started him off a little slower in the horizontal direction and gave him multiple small boosts during the jump you'd get better results. I'd recommend storing the initial jump direction for all of these calculations, you shouldn't be letting the fiend correct its course mid-flight. 
Also Fiend Bug 
To get rid of the fiend instakill leap bug, add some code just after the damage code in the touch function. Check to see if the "other" entity is still alive after the touch. If so, then prevent the fiend from doing any more damage in this leap by setting a flag, for example setting self.worldtype to 1. Then you need to check for this flag before the damage is inflicted. Also be sure to reset this flag each time the fiend launches a new jump. 
Wouldn't That Save Me From Multiple Fiend Impacts At Once? 
The demon_jumptouch function is supposed to reset its self's touch func when it's called so it only does damage once, and that doesn't seem to happen (so if you're running at a fiend as it's leaping it's like being under a crush door). why is that? 
Jonesing For A Fix 
Because the flag would be recorded per fiend, you'd still take damage from multiple fiends hitting you. The reason it doesn't cancel after one hit can be found in the if(!checkbottom(self) block. This checks if the fiend is properly onground, basically if it's on flat navigable ground. If this is not the case then it's still in the air, or stuck on a steep slope. The inner if statement checks for FL_ONGROUND, which would mean it's on a steep slope. In that case it resets the touch function and goes for another jump.

However, most commonly if checkbottom is false, the fiend is off the ground with no FL_ONGROUND, so it just goes to the return at the bottom of the block without changing the touch function.

Normally when two entities collide side to side and stay in contact they don't get repeat touches called, so even if you run at the fiend which is leaping, you only take one ping of damage. In theory if you could hit it, back off and hit it again you could take damage twice but it's not easy to do that.

When a fiend lands on your head it's a bit different. For some reason quake registers a touch every frame for vertical collisions like this, possibly the gravity code, I couldn't say. But isn't the fiend at rest as soon as it comes to rest on your head? Sadly, standing on an entity doesn't count for checkbottom, and even worse, the sliding bbox effect is caused because you don't get FL_ONGROUND on top of such an entity. So the fiend decides it's in the air the whole time, and you keep getting hit. 
Now That Bug... 
...I would totally agree with fixing. Because it's a game-breaking insta-death bug. Unlike, say, Ogres who can't aim right, the Fiend bug really fucks your gameplay experience up on the occasions when it happens. That is probably the best reason for fixing anything... 
Couldn't You 
just let the finds run a bit more than they do now and make them climb up stairs while running? 
P.S. 
Fiends:

1. Don't have eyes.

2. Are an awesomely cool monster. 
More Running, Less Jumping 
Yeah megaman, this would be another good way to prevent stairs from blocking fiends. You could add an self.attack_finished time to the jump which is a bit longer than the length of a full jump, all frames included. Then make sure that DemonCheckAttack checks for it before making a jump(although it should be ignored for melee attacks as usual).

Alternatively you could just extend the jump sequence by adding

void() demon1_jump12 =[ $leap12, demon1_jump13 ] {};
void() demon1_jump13 =[ $run1, demon1_jump14 ] {};
void() demon1_jump14 =[ $run2, demon1_run3 ] {};

You'd also want to actual put some ai_face(); movetogoal(n) stuff to make it move during those last two frames without calling ai_run. I don't think this would be the best way to do it though.

This would make the fiend slightly slower to rejump in all situations though. You could make it a bit smarter about this by calculating at the start of the jump the rough endpoint of the jump under the assumption the fiend isn't obstructed, and store that in self.pos1. Also store the current position, or somewhere a little behind the fiend in self.pos2.

Then in demom1_jump11 (the first landing frame) decide if the fiend's origin is nearer pos1 or pos2. If the former, then the jump went well and continue as normal. If you're still nearer pos2 then put an attack_finished time on of half a second or so, making sure you won't jump for a while. The reason you might want to put pos2 some way behind the fiend is so that the jump doesn't have to get more than half way to count as a "good jump". Just make sure that if the fiend goes nowhere/essentially nowhere, pos2 is going to be nearer.

The attack_finished trick is already used for the pyro in quoth, to make sure that after each shot he tries to close the distance with you. It's pretty neat, but you do have to be careful when thinking about nightmare skill. If you use SUB_AttackFinished to set your attack_finished value then you won't get the behaviour in nightmare mode. So you should only use that subroutine if the attack_finished time is intended to make the monster less dangerous. 
That Won't Work 
unless luns_mom_jumptouch is triggered previously and in sequence.

sorry dunno what's got into me :E 
Advanced Lessons In Fiend Tweaking 
So I had a go at implementing the first fiend stair fix, and ran into a snag pretty quick. Almost instantly after the fiend jumps into a set of stairs the touch function decides the fiend is on ground and jumps to demon1_jump11, thereby bypassing the velocity boost added to demon1_jump5.

(to avoid confusion, in the rest of the post "frame" means a server frame, animation frame functions should just be called by name)

As far as I can tell, in the first frame after the jump starts, the function checkbottom returns true even though the fiend is off the ground, and has just banged into a wall. I suppose that this might be a consequence of the order things run in the physics engine, that touch functions occur before the information that checkbottom relies on is updated.

In any case, if you set
self.t_length = framecount;
in demon1_jump4, and then add

if(framecount == self.t_length + 1)
return;

in DemonJumpTouch just before

self.touch = SUB_Null;
self.think = demon1_jump11;
self.nextthink = time + 0.1;

Then the jump actually reaches demon1_jump5 so the physics trick can go ahead. And then it does in fact work. It's good enough that the fiends in e1m3 only get stuck once or twice before leaping up to you, even if you try and glitch them in place.

Stay tuned for part II where I see what the other fix does for the fiend. 
Advanceder Lessons In Fiend Tweaking 
So, armed with this knowledge, I decided to try the other way. The basic method is to add

if (self.attack_finished > time)
return FALSE;

to CheckDemonJump.

The trick is knowing when to apply the waiting time. In the last post we had to work around the problem of the jump cancelling at the first available opportunity, but here we can use this to our advantage. It turns out that if that happens, it's very likely that the fiend is stuck on some stairs. So we put the same line into demon1_jump4:
self.t_length = framecount;

Then in the same place in DemonJumpTouch we add

if(framecount == self.t_length + 1)
self.attack_finished = time + 1;


And just like that fiends will walk a way up stairs if they jump into them, it actually looks quite natural. I went for a 1 second gap, because it takes about half a second for the fiend to actually land again and begin to run. If you wanted to get more sophisticated you might vary the time based on how much higher the player way, but you would have to ask if the sophisticated way would actually perform better.

The source I came up for each of these methods can be found at
http://www.btinternet.com/~chapterhonour/demon_variantsl.zip
[warning: the insta-kill fix has not been applied to these files, and in the case of the first one it's really worth doing, as the extra velocity boosts could make it inflict multiple hits]

If you notice a strange alteration to one of the jump functions, you may want to read the next post, which gets really nitpicky about it.

Some food for thought to finish with. The second method only alters the way in which a fiend chooses to use it's abilities, rather than adding a new dimension to it. So it might sound like a fairly faithful and "safe" alteration. However, remember that all that differentiates the majority of nightmare monsters from their regular skill counterparts is when they decide to use their attack and pain sequences...so the decision process matters too. 
Another Fiend Bug Caught 
Take a look at this shot:
http://www.btinternet.com/~chapterhonour/fiendbug.jpg
How did the fiend end up through the wall, so high up in Gloom Keep?

The eagle-eyed might have spotted the alteration I alluded to above, it was a setorigin call in demon1_jump4. Nobody saw that? Fair enough...

You might be thinking that I was trying to sneak Lunaran's 16 unit lifting fix into the mix as well. Actually, the code that lifts the fiend 1 unit off the ground is in the original ID source, but they do it as:
self.origin_z = self.origin_z + 1;
This is bad practice, as you aren't meant to set the origin of an object without calling setorigin(but you can get away with it if the object isn't solid yet). So I thought I was fixing a bug.

It turns out I was fixing a bug after a fashion, but only in the sense that the original line is a bug, and the fixed line is a bug with the proper function call. Because there's no checking for low ceilings when the line is called, the fiend can be bumped up into a stuck position.

It's not easy to do this, as quake monsters won't walk into a place where there's no clearance between the top of their bbox and the ceiling above them. Due to grid snapping, you need to use sloping surfaces to make the gap smaller than 1 unit. The small doorway below the fiend in the screenshot offers one such place, as the doorway has 45 degree bevels at the top. If you jam the fiend into the doorway and make it leap into the door frame enough times, eventually it'll do it close enough to get stuck. The 1 unit bump just moves its bounding box into the sloped roof of the doorway.

Then once the fiend is stuck, it tries to jump its way free. Each jump it tries to make begins with the 1 unit bump, so it gets stuck further. If you go away and do the crossword for a bit, the end result is what you see in the screenshot.

Now, I believe I'm right in saying that the line should just be commented out, because lifting the fiend off the ground like that is unnecessary. From trial runs, the fiend certainly jumps just like before. Unless someone can suggest a more unusual case when the height bump is needed, I think the line only causes the occasional bug. 
Jump! 
Do the other monsters that use leaping attacks (dog, spawn, that's it, isn't it?) have these issues as well? 
Bump! 
Both of them have the same line that increases their height by 1 unit each time they jump, so if you're fixing that for one, fix it for all of them. I've not checked if they have the same problem jumping into stairs, so it could go either way. The best way to verify that would be experimentally. The same kind of approaches to fixing them should work, if they are problems. 
Dogs And Spawn 
(gee, I just love this thread)

Spawn don't have the same problem with stairs because they become MOVETYPE_BOUNCE when they start jumping. This means when they collide with a stair, they bounce back off it, and so they launch their next jump with enough of a run up to clear the obstacle.

If you look in the dog.qc file, there's a comment
// if close enough for slashing, go for it
which suggests the whole thing is a big copy-paste from the fiend file. Technically you can get dogs stuck jumping in the same way, but it's harder to do, as dogs will only leap at you under very specific circumstances. You have to be between 80 and 150 units away, which isn't easy to judge.

Still, if it bothers you enough you can fix it by copy-pasting the lines of code from demon.qc. Hell, it's what iD did... 
Heheh 
can make them jump too you if u r using some cranked stuff 
Hey Preach 
why is:
self.origin_z = self.origin_z + 1; // raise off floor a bit
in walkmonster_start_go?

i'm guessing it has to do with either droptofloor or the somewhat hacky use of walkmove to print out the debug message?

and what exactly is the difference between setting origin directly anyway? what does that mean 'messes up entity links' or whatever. i've always used setorigin but never really understood why. 
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.