Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
noshutdown

is map design of this kind encouraged?

Recommended Posts

Well in many cases, archviles aren't quite as efficient at putting monsters on a map as a dummy sector that funnels monsters through to some teleport destinations. Its much faster and you can use more monsters that way.

Archviles can only resurrect monsters if nothing is standing on their corpse. So if you released 10 archviles into a field full of fallen mancubi and arachnatrons, they may only resurrect like 5 or 6 of them, as the herd moves together with the direction of the player. The larger space-consuming monsters will block some of the dead space-consuming monsters making the archviles neglect them.

This would be less of a problem with smaller tough monsters like revenants, hell knights, hell barons and chaingunners. Though hell knights and hell barons are pretty far from fun (which you should be cognizant of as a mapper, btw) and the archviles will usually always be the players priority in such a circumstance. It has more to do with the way they can target you from behind a horde of monsters, while any other monster species in a pack is only as dangerous as the ones on the front line.

Share this post


Link to post
40oz said:

Archviles can only resurrect monsters if nothing is standing on their corpse.

I didn't know that tid bit, thanks for the info. The only sceanario Where I'v thought of this kind of situation and thought it might be fun is a special arena where archviles would resurect Cacos off of pillars to decend upon you from above. Don't know why but this idea sounds cool in my head. XD.

Share this post


Link to post

I'm kinda leaning on AV deployment into visited areas quite a bit (alot) in a 100lines map I'm mucking about with atm :X

It has allowed for more "map" instead of using lines for extra closets though.

Share this post


Link to post

The map has a number of closets for traps but I also use just about every 2s linedef that is accessible for walkover to teleport monsters (walkover once) to other parts of the map once they are alerted. If you rush into one stairwell you see the final frames of telefog from 4 monsters getting moved to other parts of the map.

Share this post


Link to post
Job said:

A mapper should remember that no monster can drastically upset difficulty and item balance like an archvile. They should be used sparingly and strategically. If you go to the trouble to balance gameplay, don't mess it up with haphazard archvile use.


NUTS.WAD had like 1000 archviles and it was not difficult at all to finish[/obvious trolling]

40oz said:

Archviles can only resurrect monsters if nothing is standing on their corpse.


It all depends on what definition of "standing on their corpse" is used. Must their entire hitbox not overlap, or just their dead-centers are taken into account?

Even by using the "hitbox must not overlap" definition, don't most monster corpses have a significantly smaller hitbox (if they have one) than their living form? So a dead Mancubus might not necessarily overlap as much as a live one would.

Archviles are known to resurrect monsters and causing them to get stuck together, probably due to this asymmetry.

Edit: here's the relevant code snippet from PIT_VileCheck:

    maxdist = thing->info->radius + mobjinfo[MT_VILE].radius;
	
    if ( abs(thing->x - viletryx) > maxdist
	 || abs(thing->y - viletryy) > maxdist )
	return true;		// not actually touching
		
    corpsehit = thing;
    corpsehit->momx = corpsehit->momy = 0;
    corpsehit->height <<= 2;
    check = P_CheckPosition (corpsehit, corpsehit->x, corpsehit->y);
    corpsehit->height >>= 2;
There are actually two hitbox-related checks here: one uses the archvile's own radius to ensure that the archvile is not too far (interestingly, that means that a monster with a large enough hitbox wouldn't be able to be resurrected by the archvile). For that particual check, the radius stored in the thing->info->radius field is used, which cannot be modified.

However, in the subsequent check in P_CheckPosition, the thing->radius field is used instead, and that one can be modified through various mechanisms (crushing being the most common). Thus monsters raised from a crushed state may get stuck together or even in walls.

What's interesting is that during the "resurrectability" check, a corpse's height is forcefully divided by 2, and then remultiplied by two. This will eventually turn all all odd corpse heights to even numbers, or to 0 (for heights of 1). Also, the Archvile's check instantly stops sliding corpses by zeroeing their momentums. O_o

Share this post


Link to post

The only time where I don't mind an arch-vile reviving a bunch of dead enemies is the zombie types. At least they will continue to drop ammo. Sometimes I let an arch-vile revive the same couple of zombies a few times just so I can stock up on shells or bullets, or I can leave the ammo on the ground and come back to that spot later on if I need more. And to top it all off, there's also the infighting.

Share this post


Link to post
Maes said:

    corpsehit->height <<= 2;
    check = P_CheckPosition (corpsehit, corpsehit->x, corpsehit->y);
    corpsehit->height >>= 2;
What's interesting is that during the "resurrectability" check, a corpse's height is forcefully divided by 2, and then remultiplied by two.

"<<= 2" is multiplication by 4, and ">>= 2" is division by 4. So, actually, the corpse's height is reset to the monster's normal height by being multiplied by 4, checked for collision, and then reset back to the corpse's height by being divided by 4.

Share this post


Link to post
scifista42 said:

"<<= 2" is multiplication by 4, and ">>= 2" is division by 4. So, actually, the corpse's height is multiplied by 4, checked, and then divided by 4.


Whoops. OK, by examining the rest of the code, the "4x stretching" is done to counter the "4x crumbling" that happens to monsters upon death.

Share this post


Link to post

Why do programmers always use these unintuitive looking mathematical operations, are they faster or something? Even Maes got confused.

Share this post


Link to post

Yes, a bit shift is usually going to be faster than a straight multiplication between two arbitrary integer numbers, even though many compilers would optimize a multiplication (or division) with a power-of-two number to a corresponding bit-shift anyway.

Share this post


Link to post

I'm not 100% sure about the truth of the following claim, but it'd be true according to a stackoverflow post I once read, and makes sense to me as well: If the variable was of a signed type (and I think this is the case here), the compiler would not optimize division into a bit shift (because signed division doesn't work the same way as a logical bit shift if the value is negative, and while the programmer knows the value will always be positive, the compiler can't know that), and therefore the programmer actually improves the program's speed by using the >>= (bit shift) operator instead of / (division), at the cost that it would give a wrong result if the value was negative.

Share this post


Link to post

Um actually, many (well, not all) programming languages differentiate between a signed and an unsigned bit shift for this very reason: in C/C++, the >> shift is a signed right shift (division by power of two), and in the case of a signed number, it's the CPU's ALU itself which keeps track of the value of the MSB (Most Significant Bit) and actually fills in 1s or 0s to the left. So a negative value will remain negative, and viceversa.

No need for the software to check or know the sign, it's the job of the hardware, and happily implemented in all CPUs made after 1974 or so ;-)

However, C/C++ don't have an unsigned shift operator: to achieve that you'll have to use compiler-specific extensions or inline assembly, or rely on the compiler being super-smart and understand what you were trying to achieve. Same goes for bit rotation operations.

Java does have an unsigned left shift operator (>>>), even though it didn't formally have unsigned types before Java 8 (well, there were unsigned shorts, kinda).

Share this post


Link to post
Maes said:

C/C++ don't have an unsigned shift operator

But if I use >> operator onto an unsigned type variable, it will act as an unsigned shift operator, right? If the unsigned type variable contained a value "100...000", the result would NOT be "110...000", right?

Share this post


Link to post
scifista42 said:

But if I use >> operator onto an unsigned type variable, it will act as an unsigned shift operator, right? If the unsigned type variable contained a value "100...000", the result would NOT be "110...000", right?


Hopefully. At that point, the compiler can only trust your declaration of the variable as unsigned and thus take it as a hint to generate an unsigned shift instruction (or logic shift, as opposed to arithmetic shift, in different terminology). YMMV between compilers and CPU architectures here.

http://stackoverflow.com/questions/6487918/signed-right-shift-which-compiler-use-logical-shift

With C, you're pretty much only guaranteed that >> means an arithmetic (sign-preserving) shift when dealing with signed variables. All other cases are pretty much undefined, and you should really use inline assembly or (if your compiler has them) its own extensions. Don't trust >> to work as a purely logical bit shift when dealing with unsigned variables. Besides, you might not want it to.

Share this post


Link to post
Maes said:

Don't trust >> to work as a purely logical bit shift when dealing with unsigned variables.

This sounds pretty crazy to me, but OK.

Back to Memfis's question: Yes, the reason why programmers tend to use unintuitive looking mathematical operations is nearly always because they're faster and/or save memory. For example, object flags: Storing them as an array of bool variables and saving them or checking their values via an [] operator would be much slower than saving them into a single variable using |= operator and checking their values using & operator. Alternatively, in programming languages like C++ where programmers can define the meaning of operators for their own classes of objects, they may use these operators simply because they're shorter to type than named functions/methods would be.

Share this post


Link to post

I just had a thought. What if, after the player left a room, a crusher ceiling came down and crushed all the corpses and then new demons spawned in in their place? It would almost look like the corpses were reformed into those new demons.

Share this post


Link to post
MetroidJunkie said:

I just had a thought. What if, after the player left a room, a crusher ceiling came down and crushed all the corpses and then new demons spawned in in their place? It would almost look like the corpses were reformed into those new demons.

That reminds me...if you really want to troll the players, bring in a few arch-vile after those monsters get crushed. For instance, have fun trying to kill a horde of revenant ghosts, which are already annoying enough while they were alive and solid.

Share this post


Link to post
Ichor said:

That reminds me...if you really want to troll the players, bring in a few arch-vile after those monsters get crushed. For instance, have fun trying to kill a horde of revenant ghosts, which are already annoying enough while they were alive and solid.


Well...that can be made somewhat fairer by giving the player a BFG (it can still track ghosts, right?), or a RL and something solid to explode rockets against. Or spawn some barrels between the monsters. After all, they can't block the projectiles anymore, so this could be a challenging quick reaction puzzle. Super-easy if you act fact and correctly, or get pretty much fucked if you don't ;-)

Share this post


Link to post
Maes said:

BFG (it can still track ghosts, right?)

No, it can't.

Maes said:

spawn some barrels between the monsters. After all, they can't block the projectiles anymore,

Barrels do block projectiles fired by the ghost monsters.

Share this post


Link to post
scifista42 said:

No, it can't.


Hmm weird...I was under the impression that ghost monsters are not 100% invulnerable to hitscan and melee attacks at least: melee attacks from other monsters are automatically directed at the ghosts' center, so they are still effective, while they player's hitscan attacks have a change of connecting if they are dead-center and at the right height.

Since the BFG essentially auto-aims for you (or scatters randomly), there must be a non-zero chance of hitting a ghost with it. However, with a zero radius, any hitscan attack must not only be 100% accurate, but it must also not be "betrayed" by rounding errors.

scifista42 said:

Barrels do block projectiles fired by the ghost monsters.


Why shouldn't they? I was thinking more about the player shooting at the barrels behind the monsters, through the monsters. But the monsters can set them off too, why now?

Share this post


Link to post
Maes said:

melee attacks from other monsters

are not hitscans in most versions of Doom, they're just distance chance that ( iirc ) don't even have a line of sight check to them.

Share this post


Link to post

^ Line of sight check is part of P_CheckMeleeRange, which is called immediately before the melee attack deals damage, so the last part of your statement isn't quite right. But otherwise, you are right - monster's melee attacks target ghost monsters without a problem, while hitscan attacks (including player's fist and chainsaw) do not.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×