AI coding continued: in the MP SDK

  • Thread starter Thread starter Dr_Fripp
  • Start date Start date
D

Dr_Fripp

Guest
The question I have here is pretty much related to the topic of AI coding on this board:
AI Code

I want to do something like this, but I want to do it in MP-style: I need an AI team to fight human players of another team. Let's say a co-operative gamestyle is okay, but I really need to do it in MP because I want to evolve it into something different later on.

I have read about the necessity to add relationships to the relationship table in hl2_gamerules.cpp, and alter the Classify() function.

However, in the MP SDK I'm dealing with the sdk_gamerules.cpp, which only happens to have a function for deciding the relationship among players.

So I tried to simply add the InitDefaultAIRelationships function to the sdk_gamerules, and import the headcrab.cpp for a temporary simple AI entity (commenting everything out that generates problems with compiling). However, both the Classify() in headcrab.cpp and the SetDefaultRelationship() in the gamerules need definitions for the CLASS_HEADCRAB. These classes are defined in baseentity.cpp, but this file is not readily accessible in the MP SDK. Even after managing to #include "../../dlls/baseentity.h" (!!), an awful lot of problems result at compiling.

(Furthermore, half of the header files are in the "game_shared" dir, and the other half in the "dlls" dir, and this causes the compiler to not find included files sometimes. This is another hurdle in trying to include files from the SP SDK to the MP SDK.)

I feel I need those relationships in MP, but I just can't get them imported in an easy way. Am I doing something wrong, or is my approach totally off? Any help would be appreciated.

Thanks in advance.
 
It's a difficult task - it got me so riled, I eventually just redid the way HL2 deals with relationships by having each creature have a 'team' variable, and compare them to see whether they should attack.

-Angry Lawyer
 
Ok, then I'll try to do it myself as well. Just have to see where the AI decides to attack someone instead of just setting the relationship...
 
Well, I guess I'm stuck again.

I tried to trace down the bit where the AI decides that somebody is their enemy and updates the enemy list. Finally I arrived at ai_basenpc.h, the "OnLooked" function. Here, newly seen enemies get added to the enemylist (that's what I've gathered, at least).

I commented out the lines that excluded neutral entities from the enemy list:

Code:
//if ( relation != D_NU )	
//{	
//}

then I proceeded to just add the following two lines after the switch(relation){} statement, to be sure that any entity would be seen as something to hate:

Code:
SetCondition(COND_SEE_HATE);	
UpdateEnemyMemory(pSightEnt,pSightEnt->GetAbsOrigin());

But upon running a level and spawning a headcrab, it just sits still...
 
You've gone about it in the wrong way, I think. You need something that forces the relationship to D_HT, rather than comment out the block.

Look for where the "Classify" parts, and the relationship table should be called, and simply put relation = D_HT

Of course, you'll need to add checks for teams, but that can come later. If I get a chance, I'll have a quick look at how I fixed it.

-Angry Lawyer
 
Ok, I'll just post here about my own findings so far. I now tried to follow your advice, and traced down the changeworthy code to CAI_BaseNPC::AddRelationship.

Here - it seems - the relationship table is set, with as base an entity relationship string. It calls "Add(Entity/Class)Relationship(entity, disposition, priority )" multiple times, and I just force "disposition" to be "D_HT" everytime.

For completeness: the Classify() function of my headcrab always returns CLASS_ULTIMATE_FIEND, which is a class I defined myself in addition to the NONE/PLAYER/ALLY classes in baseentity.h. Should work.

But it doesn't; the headcrab still doesn't attack me. :P
 
The Classify is used for more things than relationships - avoid changing it.

Look for something like "Disposition_t CAI_BaseNPC::IRelationType(CBaseEntity *pTarget)", or if you can't find it, inherit/override it in AI_BaseNPC.

Just because I can't be bothered to explain it, here's the code I used:

Code:
//-----------------------------------------------------------------------------
// LAWYER:  Force combat relationships based on team.
//-----------------------------------------------------------------------------
Disposition_t CAI_BaseNPC::IRelationType(CBaseEntity *pTarget)
{

	int iTheirTeam = 0; //LAWYER:  Variable to store their team
	iTheirTeam = ((CBaseCombatCharacter*)pTarget)->GetConqTeam(); //LAWYER:  Store it.
	
	if ( !(pTarget->IsSolidFlagSet( FSOLID_NOT_SOLID )) )
	{ //Check if the target is non-solid
		//LAWYER:  Now for the proper stuff
		if (iTheirTeam == 0)
		{
			return D_NU; //Team 0 is passive to everyone
		}
		else if (iTheirTeam != this->GetConqTeam())
		{
			return D_HT; //Xenophobia is in the air - hate all who aren't like us!
			//LAWYER:  Remember to add the ability to find allies.
		}
		else if (iTheirTeam == this->GetConqTeam())
		{
			return D_LI; //We love our team-mates!
		}
	}
	return D_NU; //In case of emergency, return neutrality.
}

-Angry Lawyer
 
Thanks for the help, at least the headcrab finally attacks me (without damage).
 
You now need to define the damage. All you have to do is look for where skill.cfg gets called, and comment out the bits that only enable it in single-player. Should sort the problem out.

-Angry Lawyer
 
Oh, I did it another way, via the "sk_headcrab_melee_dmg" skill setting in my headcrab.cpp.

I think that's just one setting out of all in skill.cfg then.

Update: Your change worked, but I noticed that the skill.cfg is in some place that doesn't directly belong to my mod. Doesn't this interfere with my ability to create custom entities with custom damage? (I mean, then I would have to provide a new cfg(gcf) file as well).

Now it looks like I'm better off putting the damage in the code itself...
 
Well, having a CFG just has the advantage of not having to recompile every time you change a damage variable. It's only one file you need to add to your mod, which can be extracted quite easily.

-Angry Lawyer
 
Ok then, thanks for all the help. It's awesome how you manage to help everyone around here; personally I would find it difficult to be helping people every day with their trivial questions. I mean, the stuff I don't know really isn't that difficult, but somehow I find it very hard to get by.
 
Well, hopefully you have a general idea about this problem as well: I have now imported the combine soldier class, to see if I can have placeholder npc's for my project in an easy way (by just copying the npc_combines.cpp/h). I can now spawn them with a shotgun. However, they don't shoot and don't walk (the console complains about a missing sequence for "ACT_WALK"). ACT_WALK is defined in my project of course, so how can there be no sequence for it? I thought the relationship was schedule->task->activity...The code pertaining to this problem is pretty mystifying (I can't really track it down to something). Does the inability to shoot have anything to do with all of this, or do I have to look somewhere else for that?
 
Yeah, I know I'm a hero, but thats what Angry Lawyers do.

We're going into grey area here, though, it's stuff I've not actually reached in my mod (I'm focusing on getting the RTS perspective camera working, first).
The inability to shoot is due to a difference in the .cpp of HL2's singleplayer shotgun, and HL2's multiplayer shotgun, as far as I know. The singleplayer shotgun has a large block of code defining how NPCs actually use it. As far as I know, you just need that block of code, and implement it in the multiplayer shotgun.

The non-walking Combine is due to the way that the animations are dealt with in HL2MP. As I'm not using the HL2MP source (rather, the blank slate to do my mod), I don't actually have this problem. But, it's something to do with the mod renaming animations. Just find out where it's doing it, and turn it off. I'll get back to you on this one if I figure out any more - I'm sure they've sorted it on VERC.

-Angry Lawyer
 
Ok I'll look a bit longer on VERC then.

Coincidentally, I need an RTS-style camera as well...it was the next thing I planned on doing.
 
I've almost got the camera working. I've just got to work out why the one most important function doesn't work - that of reading mouse coordinates on a panel.

So, what kind of mod are you aiming to do?

-Angry Lawyer
 
I'm going to try and combine RTS elements with FPS elements in a team vs commander-type of setting.

It is still doubtful how much of an RTS can be replicated in HL2, but I guess that's what you're at as well?

By the way: the activities work now, but for the activities to be declared I need to put my shotgun in the server dir instead of the shared dir. This is because include-files from the server dir are illegal when the shotgun is in the shared dir, but not the other way around. Is there a special reason for this, and could it cause me trouble in the future?

Update: I think I found the answer, because putting it in the server dll dir leads to not using baseentity_shared for my CBaseEntity definition, which makes dealing damage impossible. This brings me into a difficult position, because I can't include the files from the server dll dir.
 
As I said, you've entered the grey zone of my knowledge. I've not done anything with holdable weapons yet, as I've focused on melee creatures, and things with innate attacks (like the Stalker, which I've fixed, by the way).

Anyways, doesn't look like you're competeting too much with my mod, as you're aiming for something akin to Natural Selection, and I'm going for an actual RTS, as fully as possible. And if server load from NPCs becomes over the top, I'll just scale it down so players kit out a small squad instead of an army.

-Angry Lawyer
 
True, it's more in the sense of NS than a full-fledged RTS.

Long way to go tho... :P
 
Definately. I've been coding mine since the SDK was released. Still, not far before an early, testable build for me!

-Angry Lawyer
 
Well, the best of luck then. I'd definitely like to see it in action.
 
Thanks. Best of luck to you, too, and I hope to see your mod in the near future.

-Angry Lawyer
 
Back
Top