Killable (with conventional weapons) Chthon Tutorial

Discuss the construction of maps and the tools to create maps for 3D games.
Post Reply
FrikaC
Site Admin
Posts: 1026
Joined: Fri Oct 08, 2004 11:19 pm

Killable (with conventional weapons) Chthon Tutorial

Post by FrikaC »

Ever wanted to blast that lava beasty without resorting to some obscure cdrom.com era patch, without touching a compiler or QuakeC code? No? Well tough, I'm going to tell you how to do this with pure map entities anyway.

It's kind of gimmicky and the 'mapping establishment' may frown down on this sort of thing, but if executed well, it can be nice. Some of you may remember a speedmap I did during one of the expos that had this in there. That was probably a good example of how NOT to do it.

I guess the first thing I should answer and get out of the way is the simple question "How is this possible?". Well, the interesting thing about Quake is that all the fields that exist on an entity are completely exposed to the mapper, although you may not realize it. There's a certain set of accepted fields you're "supposed" to fill in, but things like "think", "nextthink" and so forth are open to you, and you can make them point to any function you want. There's even a handy "info_notnull" entity that can be a blank template for whatever you want to make.

You obviously can't make entirely new code, but you can manipulate the existing code in various ways to produce things like player-model enemies, super monsters of all kinds and so on. Doing these may require "a programmer" to find the events you need to chain together, but once the store is given up (as in this tutorial), the floodgates are opened.

To get a killable Chthon we'll basically be creating 'a new monster' with map entities. So let's get to it.

In Quake, monsters and every other map entity have "a spawn function", this is the function called by Quake when loading the map and specified in the map as the "classname" field. Familiar spawn functions to you may be "info_player_start" and "monster_soldier". The former has really no code attached to it, the player just finds this blank entity and spawns there in single player.

The latter on the other hand has a bunch of code that defines the parameters of a grunt monster. Things like health, the weapon, the animation functions it will use and so forth. The key point here is that all that function, monster_soldier really 'does' is setup fields on an entity. You may have remembered me just saying that all fields in QuakeC are exposed to the mapper. You may now sense where this is going.

We can basically write our own 'spawn functions' from within the map. As all it does is configure the fields of an entity. A word of warning though, if you get too carried away with this you can break your map with a ton of mods, as most mods latch into these spawn functions to set up new fields that never existed before in Quake. For our little SP map however, this is not a concern.

How we create this new spawn function is by abusing an "info_notnull" entity. This entity, like the info_player_start entity previously mentioned, has no setup function at all. It's blank except for the fields you define.

So let's create an info_notnull on our map. This will be the spawn location of our chthon, so it'd probably be wise to locate in some lava somewhere. You should probably also activate the "Not In Deathmatch" spawnflag in case you want to support deathmatch mode in your map (otherwise "our" Chthon would appear in DM and would likely crash the server because "his counterpart" won't (I'll get to this later)).

Next we need to fill in the other fields of info_notnull Chthon. So add these fields as I present them. Adding fields is different in each map editor. I primarily use Worldcraft. To add fields in this editor, turn off "Smart Edit" and use the add button. I'll be presenting the fields as quoted name and value pairs, as would be seen inside a .map file. Under WorldCraft, don't include the quotes.

Code: Select all

"nextthink" "0.01"
"think" "boss_awake"
First off we need to set the model and size of our monster. Since these fields can't really be set with much accuracy from the map (You can actually do it, it's just not very pretty) we'll need to latch into the real Chthon code. boss_awake is a boss.qc function that does the actual setup of Chthon. The function also (unfortunately) sets Chthon to either 1 or 3 health depending on skill level. He loses 1 health each time the electrodes are actviated in his e1m7 lair, but for our purposes, with a Chthon that takes normal damage, this kinda blows. We'll fix this in a bit.

The think field of an entity tells Quake which function to run when the game time passes the nextthink field on an entity. By setting nextthink to 0.01 and think to boss_awake we're basically calling boss_awake 10 milliseconds after the map load. Calling this function is a needed step to get our Chthon set up and looking like Chthon.

Code: Select all

"targetname" "my_boss"
This is the probably the already familiar "targetname" field. This field is used by code in the QuakeC to find entities when they are 'used' by some other entity.

For example when you walk through an invisible trigger on a map, you will cause the game to search for all entities that have a field "targetname" that matches the "target" of the trigger. For each of the entities it finds, it will run the function .use() function for that entity. That differs from entity to entity, monsters awake when used, trigger_teleports and trigger_hurts toggle on and off, lights toggle on and off and so on.

Unfortunately for us, our blank info_notnull has no use function. But fear not, that's where the next field comes in

Code: Select all

"use" "walkmonster_start_go"
This is our use function, when triggered, our info_notnull Chthon will call the function "walkmonster_start_go", which you probably never heard of. This function is called by most of the monsters in Quake and is a "second stage" set up for monsters. It will set Chthon to be killable, set his solid and damage types. Basically it does half the work we need to do and sets things up that would otherwise be many more fields on our notnull. It also starts the monster into the standard think/animation loops of the ai, which is also handy.

Code: Select all

"armorvalue" "2997"
"armortype" "1"
Alright I'm about to reveal here a super magic mega awesome cool secret trick in Quake mapping. You can make any enemies have more "hitpoints" quite simply by giving them armor. This is the answer to the above mentioned "problem" of Chthon only having 1 or 3 health.

The "armortype" field indicates how good the armor is, the percentage of damage it actually blocks. The best armor the player can get, red armor, has an armortype of "0.8", it blocks 80% of the damage dealt to the player. You'll notice I put a 1 in this field, this means 100% of all damage is blocked, that means before you can do damage to the health of the creature, you must completely wear away all his armor. Et viola, we can give our Chthon 2997 armor, so that his final "health" is 2998 to 3000 hitpoints.


This trick works for all monsters, try it out, and when you're done making super duper shamblers, we'll continue..

Code: Select all

"th_run" "boss_missile1"
"th_walk" "boss_missile1"
"th_stand" "boss_missile1"
"th_missile" "boss_missile1"
Chthon is a pretty boring guy and not very animated, in fact he really only does one thing, throw lava balls. We really don't want to give him an idle state for reasons I don't want to get into (suffice to say, he doesn't have much in the way of AI), so we'll just fill all his animations with his attack, boss_missile1. An unfortunate side effect of this is he'll always be attacking, but that's basically the effect you'd get with a normal Chthon.

Code: Select all

"th_pain" "plat_hit_bottom"
"noise1" "boss1/pain.wav"
Now Chthon has his own normal pain function where he screams and wiggles (shocked by the electrodes) , but in practice, it makes him as a killable monster a little too easy, as he is damagable all throughout this and as long as you apply steady damage, eg from a nailgun, he'll basically never leave this pain animation.

So we kinda need a different pain reaction. The easy solution is to use another obscure function, plat_hit_bottom as our pain. Plat Hit Bottom does little but play a sound file, in this case, specified by the noise1 field on the entity.

So hidden here is our next super secret mega awesome map trick: You can make triggered sounds in Quake maps simply by targeting a notnull who's "use" field is plat_hit_bottom and who's "noise1" field is the sound you want to play. Unforunately, the sound needs to be precached first, so you're rather resticted in what sounds you can play with this method - only player or door, monster or item sounds of things that already exist on the level.

Anyway, getting back to our Chthon, we're nearly done, bear with me just a bit longer.

Code: Select all

"th_die" "boss_death1"
This is the final animation for our notnull. This defines the function to call when we finally kill Chthon, and we use the standard falling into the lava. You can trigger an event when this happens just like the "Real Chthon", by using a target field. This is optional however, he can just be a 'standard' monster.

Alright We're done with the info_notnull, however we're not completely done. We'll need to set up a trigger to force Quake to call our Chthon's use. You can use a button or an invisible trigger_once or whatever. Take note, Chthon will work before it is activated, but he won't be killable until it's pressed, so you may want to make it a bit challenging before the player activates it, or you may want to trigger it right away. Just don't trigger it immediately, before that 10 ms delay we talking about for "think".

Next we'll need actual monster_chthon on the level so Quake will precache all of chthon's sounds and models. You can just stick it in the level somewhere, you don't need to activate it, or even make it accessible to the player in any way, it's just so the precaches in the monster_chthon function get called.

Well, that's it. I hope you learned something about mapping and QuakeC and I hope you found this in some ways valuable.
Last edited by FrikaC on Thu Nov 19, 2009 7:31 pm, edited 4 times in total.
Tei
Posts: 193
Joined: Mon Oct 25, 2004 12:22 pm

Re: Killable (with conventional weapons) Chthon Tutorial

Post by Tei »

So the map entity is that?:

{
"nextthink" "0.01"
"think" "boss_awake"
"targetname" "my_boss"
"use" "walkmonster_start_go"
"armorvalue" "2997"
"armortype" "1"
"th_run" "boss_missile1"
"th_walk" "boss_missile1"
"th_stand" "boss_missile1"
"th_missile" "boss_missile1"
"th_pain" "plat_hit_bottom"
"noise1" "boss1/pain.wav"
"th_die" "boss_death1"
}
FrikaC
Site Admin
Posts: 1026
Joined: Fri Oct 08, 2004 11:19 pm

Post by FrikaC »

Yes, and "classname" "info_notnull", but simplifying it that much kinda takes the 'tutorial' of it :)
ajay
Posts: 559
Joined: Fri Oct 29, 2004 6:44 am
Location: Swindon, UK

Post by ajay »

This is very interesting, not quite so much for Chthon specifically, but just in teaching me how much can be done through mapping.

Another interesting point was about monsters being weak and getting "stuck" in pain animations; I had a real problem with one enemy in Lunkin's Journey that did this, so I did a similar thing in qc and took away all of it's pain responses. I always thought it was quite a clumsy thing to do, and if I'd had more enthusiasm at the time, I might have tried something else: radomising the chance of a pain response, so it didn't always go into it's pain animation, or making it invulnerable during pain (like the player can be in some games, often when flickering/transparent) which I wasn't much keen on either.
Obviously it would be nice if the monsters had a "attack_while_pain", or "run_while_in_pain" or suchlike animations, but they don't, so I'll shut up....
neg!ke

Post by neg!ke »

nice find, thanks.

you might want to check out this thread for more hacks (a few in 'mapping help' too).
i wonder what else could be done with this... what about a shootable shub niggurath for example...? ;)
FrikaC
Site Admin
Posts: 1026
Joined: Fri Oct 08, 2004 11:19 pm

Post by FrikaC »

Just trying to get a little traffic here on the mapping boards :)

That and Asaki asked me about this after I did this in my speedmap for SM84
Dr. Shadowborg
InsideQC Staff
Posts: 1120
Joined: Sat Oct 16, 2004 3:34 pm

Post by Dr. Shadowborg »

ajay wrote: Another interesting point was about monsters being weak and getting "stuck" in pain animations
Pain Tolerance is on my list of things to do for the monster complation mod I'm working on.
Tei
Posts: 193
Joined: Mon Oct 25, 2004 12:22 pm

Post by Tei »

Dr. Shadowborg wrote:
ajay wrote: Another interesting point was about monsters being weak and getting "stuck" in pain animations
Pain Tolerance is on my list of things to do for the monster complation mod I'm working on.
I think a way can be to have 2 or 3 pain animations. Avoid restarting animations, and use a random one if still is damaged.

Another way can be to have "pain" sound, but not animations. Or "the monster can't use his weapons" cooldown, but not animation.

And tiny animations (2 o 3 frames). And everything mixed :D

I once tried to have realistic fiends, and failed. I am such a bad QC coders :(
Entar
Posts: 439
Joined: Fri Nov 05, 2004 7:27 pm
Location: At my computer
Contact:

Post by Entar »

ajay wrote:This is very interesting, not quite so much for Chthon specifically, but just in teaching me how much can be done through mapping.
I'm surprised the mapping and modding communities aren't together just through that - there's so much the mapper can do with the QC from the map editor, and you'd think they'd work together to exploit that and make some very interesting map/mod combos.
Tei
Posts: 193
Joined: Mon Oct 25, 2004 12:22 pm

Post by Tei »

Entar wrote: I'm surprised the mapping and modding communities aren't together just through that - there's so much the mapper can do with the QC from the map editor, and you'd think they'd work together to exploit that and make some very interesting map/mod combos.
This is not posible, and theres references here and there to explain why.

The conclusion is: The mapping community map for the original Quake, and not for mods. We are not creating something the mappers want to use. Not even engines (except maybe faithfull ones like Fritzquake).
So.. How we can be helpfull to this community?, I think we can share our knogement about how to add new weapons, new mods and maybe sonf func_* entitys. Because is that what a mapper may need: some weapon, some monster or a func_wall_explode.

What FrikaC has do here, is exactly what can help the mappers. And more candy will atract more flies.
Dr. Shadowborg
InsideQC Staff
Posts: 1120
Joined: Sat Oct 16, 2004 3:34 pm

Post by Dr. Shadowborg »

Tei wrote: I think a way can be to have 2 or 3 pain animations. Avoid restarting animations, and use a random one if still is damaged.

Another way can be to have "pain" sound, but not animations. Or "the monster can't use his weapons" cooldown, but not animation.

And tiny animations (2 o 3 frames). And everything mixed :D

I once tried to have realistic fiends, and failed. I am such a bad QC coders :(
Nah. Monsters already play their pain sounds when they take damage. Under nightmare skill monsters don't use their pain frames at all either.

I was thinking something more along the line of what can be found in shambler.qc's pain function, only more adjustable, with skill settings also coming into play.

As far as making something mappers want to use, that's kind of the whole idea behind my Faerie Journal mod. A one stop shop where they can find most any monster they may want / need, all in a easy to snatch format, with lots 'n lots of flexibilitiy features that they can set from a mapping program. i.e. the Custents of Monsters.
Lardarse
Posts: 266
Joined: Sat Nov 05, 2005 1:58 pm
Location: Bristol, UK

Post by Lardarse »

[00:58:18] RocketGuy7: he thinks chthon is in e1m6.. very nice
[01:01:30] RocketGuy7: even better.. he thinks red armor blocks 90% of damage
I'm kinda ashamed that I didn't notice that...

But apart from that. it's a very cool tutorial, and exactly in the spirit on the func_ thread that neg!ke linked to...

More, please!
FrikaC
Site Admin
Posts: 1026
Joined: Fri Oct 08, 2004 11:19 pm

Post by FrikaC »

Lardarse wrote:
[00:58:18] RocketGuy7: he thinks chthon is in e1m6.. very nice
[01:01:30] RocketGuy7: even better.. he thinks red armor blocks 90% of damage
I'm kinda ashamed that I didn't notice that...

But apart from that. it's a very cool tutorial, and exactly in the spirit on the func_ thread that neg!ke linked to...

More, please!
Oh poopy. The e1m6 thing was a brainfart. I keep thinking the Door to Chthon is his "lair".

The 90% thing, I honestly looked it up to be sure, but I looked it up on a modified source base :oops: I have an excuse, I wrote this in the middle of the night when I was sleepy. Still, only two mistakes in all that jabbering, that's not bad.
Spirit
Posts: 1065
Joined: Sat Nov 20, 2004 9:00 pm
Contact:

Post by Spirit »

I just tried this and got an invulnerable Chthon (fired many quad rockets in it and it did not die) for some reason. Has someone verified that there are no bugs in this tutorial?


Also I just tried replacing the "think" "boss_awake" with "think" "monster_army" (and put a monster_army in the map "above" the info_notnull for precaching). The game stops with a precache error. I guess because the monster_army function wants to precache this cannot work no matter how hard I try, correct? Would be a shame as only Chthon has the spawn function detached from the precaching. Or is there another way?

Thanks!

edit: Damn, I thought this was posted last QExpo. Time flies by so fast...
Improve Quaddicted, send me a pull request: https://github.com/SpiritQuaddicted/Quaddicted-reviews
FrikaC
Site Admin
Posts: 1026
Joined: Fri Oct 08, 2004 11:19 pm

Post by FrikaC »

It works, but you need to trigger it for him to be killable.
Post Reply