This commit is contained in:
2023-04-13 17:30:38 +02:00
commit 013c6f3b4d
921 changed files with 337975 additions and 0 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,250 @@
function autoexec main()
{
/#
level.__ai_debugInterface = GetDvarInt( "ai_debugInterface" );
#/
}
function private _CheckValue( archetype, attributeName, value )
{
/#
attribute = level.__ai_interface[ archetype ][ attributeName ];
switch ( attribute[ "type" ] )
{
case "_interface_match":
possibleValues = attribute[ "values" ];
assert( !IsArray( possibleValues ) || IsInArray( possibleValues, value ),
"AI: \"" + value + "\" is not one of the allowed values for attribute \"" +
attributeName + "\"." );
break;
case "_interface_numeric":
maxValue = attribute[ "max_value" ];
minValue = attribute[ "min_value" ];
assert( IsInt( value ) || IsFloat( value ), "AI: Attribute \"" + attributeName +
"\" requires a numeric value and \"" + value + "\" does not qualify." );
assert( ( !IsDefined( maxValue ) && !IsDefined( minValue ) ) ||
( value <= maxValue && value >= minValue ),
"AI: \"" + value + "\" is outside the allowed range of (" + minValue + "," +
maxValue + ")." );
break;
case "_interface_vector":
if ( IsDefined( value ) )
assert( IsVec( value ), "AI: Attribute \"" + attributeName +
"\" requires a vector value and \"" + value + "\" does not qualify." );
break;
default:
assert( "AI: Unknown attribute type of \"" + attribute[ "type" ] +
"\" for attribute \"" + attributeName + "\"." );
break;
}
#/
}
function private _CheckPrerequisites( entity, attribute )
{
/#
assert( IsEntity( entity ), "AI: Must pass an entity to access an attribute." );
assert( IsActor( entity ) || IsVehicle( entity ), "AI: Must pass an actor or vehicle to access an attribute." );
assert( IsString( attribute ), "AI: Must pass in a valid attribute name." );
// In depth debugging, only necessary to debug if an AI or the AI Interface system has been setup properly.
if ( IsDefined( level.__ai_debugInterface ) && level.__ai_debugInterface > 0 )
{
assert( IsArray( entity.__interface ),
"AI: Entity(" + entity.archetype + ") must create an interface before accessing an " +
"attribute, see \"ai::CreateInterfaceForEntity\"." );
assert( IsArray( level.__ai_interface ),
"AI: No attributes have been registered with the AI interface system yet." );
assert( IsArray( level.__ai_interface[ entity.archetype ] ),
"AI: No attributes for archetype \"" + entity.archetype + "\" have been registered." );
assert( IsArray( level.__ai_interface[ entity.archetype ][ attribute ] ),
"AI: Attribute \"" + attribute + "\" has not been registered for archetype \"" +
entity.archetype + "\" yet." );
assert( IsString( level.__ai_interface[ entity.archetype ][ attribute ][ "type" ] ),
"AI: Attribute type is undefined for \"" + attribute + "\"." );
}
#/
}
function private _CheckRegistrationPrerequisites( archetype, attribute, callbackFunction )
{
/#
assert( IsString( archetype ), "AI: \"archetype\" value is mandatory for registration." );
assert( IsString( attribute ), "AI: \"attribute\" value is mandatory for registration." );
assert( !IsDefined( callbackFunction ) || IsFunctionPtr( callbackFunction ),
"AI: \"callbackFunction\" is optional but must be a function pointer if specified." );
#/
}
function private _InitializeLevelInterface( archetype )
{
if ( !IsDefined( level.__ai_interface ) )
{
level.__ai_interface = [];
}
if ( !IsDefined( level.__ai_interface[ archetype ] ) )
{
level.__ai_interface[ archetype ] = [];
}
}
#namespace ai;
function CreateInterfaceForEntity( entity )
{
if ( !IsDefined( entity.__interface ) )
{
entity.__interface = [];
}
}
function GetAiAttribute( entity, attribute )
{
/#
ai_interface::_CheckPrerequisites( entity, attribute );
#/
if ( !IsDefined( entity.__interface[ attribute ] ) )
{
return level.__ai_interface[ entity.archetype ][ attribute ][ "default_value" ];
}
return entity.__interface[ attribute ];
}
function HasAiAttribute( entity, attribute )
{
return
IsDefined( entity ) &&
IsDefined( attribute ) &&
IsDefined( entity.archetype ) &&
IsDefined( level.__ai_interface ) &&
IsDefined( level.__ai_interface[ entity.archetype ] ) &&
IsDefined( level.__ai_interface[ entity.archetype ][ attribute ] );
}
function RegisterMatchedInterface( archetype, attribute, defaultValue, possibleValues, callbackFunction )
{
/#
ai_interface::_CheckRegistrationPrerequisites( archetype, attribute, callbackFunction );
assert( !IsDefined( possibleValues ) || IsArray( possibleValues ),
"AI: \"possibleValues\" is optional but must be an array if specified." );
#/
ai_interface::_InitializeLevelInterface( archetype );
/#
assert( !IsDefined( level.__ai_interface[ archetype ][ attribute ] ),
"AI: \"" + attribute + "\" is already registered for archetype \"" + archetype + "\"" );
#/
level.__ai_interface[ archetype ][ attribute ] = [];
level.__ai_interface[ archetype ][ attribute ][ "callback" ] = callbackFunction;
level.__ai_interface[ archetype ][ attribute ][ "default_value" ] = defaultValue;
level.__ai_interface[ archetype ][ attribute ][ "type" ] = "_interface_match";
level.__ai_interface[ archetype ][ attribute ][ "values" ] = possibleValues;
/#
ai_interface::_CheckValue( archetype, attribute, defaultValue );
#/
}
function RegisterNumericInterface( archetype, attribute, defaultValue, minimum, maximum, callbackFunction )
{
/#
ai_interface::_CheckRegistrationPrerequisites( archetype, attribute, callbackFunction );
assert( !IsDefined( minimum ) || IsInt( minimum ) || IsFloat( minimum ),
"AI: \"minimum\" is optional but must be a numeric if specified." );
assert( !IsDefined( maximum ) || IsInt( maximum ) || IsFloat( maximum ),
"AI: \"maximum\" is optional but must be a numeric if specified." );
assert( ( !IsDefined( minimum ) && !IsDefined( maximum ) ) ||
( IsDefined( minimum ) && IsDefined( maximum ) ),
"AI: Either both a minimum and maximum must be defined or both undefined, not mixed.");
assert( ( !IsDefined( minimum ) && !IsDefined( maximum ) ) ||
( minimum <= maximum ),
"AI: Attribute \"" + attribute + "\" cannot specify a minimum greater than " +
"the attribute's maximum");
#/
ai_interface::_InitializeLevelInterface( archetype );
/#
assert( !IsDefined( level.__ai_interface[ archetype ][ attribute ] ),
"AI: \"" + attribute + "\" is already registered for archetype \"" + archetype + "\"" );
#/
level.__ai_interface[ archetype ][ attribute ] = [];
level.__ai_interface[ archetype ][ attribute ][ "callback" ] = callbackFunction;
level.__ai_interface[ archetype ][ attribute ][ "default_value" ] = defaultValue;
level.__ai_interface[ archetype ][ attribute ][ "max_value" ] = maximum;
level.__ai_interface[ archetype ][ attribute ][ "min_value" ] = minimum;
level.__ai_interface[ archetype ][ attribute ][ "type" ] = "_interface_numeric";
/#
ai_interface::_CheckValue( archetype, attribute, defaultValue );
#/
}
function RegisterVectorInterface( archetype, attribute, defaultValue, callbackFunction )
{
/#
ai_interface::_CheckRegistrationPrerequisites( archetype, attribute, callbackFunction );
#/
ai_interface::_InitializeLevelInterface( archetype );
/#
assert( !IsDefined( level.__ai_interface[ archetype ][ attribute ] ),
"AI: \"" + attribute + "\" is already registered for archetype \"" + archetype + "\"" );
#/
level.__ai_interface[ archetype ][ attribute ] = [];
level.__ai_interface[ archetype ][ attribute ][ "callback" ] = callbackFunction;
level.__ai_interface[ archetype ][ attribute ][ "default_value" ] = defaultValue;
level.__ai_interface[ archetype ][ attribute ][ "type" ] = "_interface_vector";
/#
ai_interface::_CheckValue( archetype, attribute, defaultValue );
#/
}
function SetAiAttribute( entity, attribute, value )
{
/#
ai_interface::_CheckPrerequisites( entity, attribute );
ai_interface::_CheckValue( entity.archetype, attribute, value );
#/
oldValue = entity.__interface[ attribute ];
if ( !IsDefined( oldValue ) )
{
oldValue = level.__ai_interface[ entity.archetype ][ attribute ][ "default_value" ];
}
entity.__interface[ attribute ] = value;
callback = level.__ai_interface[ entity.archetype ][ attribute ][ "callback" ];
if ( IsFunctionPtr( callback ) )
{
[[callback]]( entity, attribute, oldValue, value );
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,16 @@
#namespace AnimationSelectorTable;
function RegisterAnimationSelectorTableEvaluator( functionName, functionPtr )
{
if ( !IsDefined( level._astevaluatorscriptfunctions ) )
{
level._astevaluatorscriptfunctions = [];
}
functionName = ToLower( functionName );
Assert( IsDefined( functionName ) && IsDefined( functionPtr ) );
Assert( !IsDefined( level._astevaluatorscriptfunctions[functionName] ) );
level._astevaluatorscriptfunctions[functionName] = functionPtr;
}

View File

@ -0,0 +1,90 @@
// ASM RUNNING STATUS FLAGS ------------------------------------------------------//
// TODO - Find a better way to not need to have this hardcoded state name.
// ASM NOTETRACK HANDLER DEFINES -----------------------------------------------//
// ASM AIM/SHOOT NODE DEFINES -------------------------------------------------//
// ASM MOCOMP ATTRIBUTES -----------------------------------------------------//
// NOTERACKS HANDLED BY ASM ---------------------------------------------------//
// AI_ANIM_MODE, DEFINED SAME AS CODE -----------------------------------------//

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,15 @@
// EMPTY ANIMSCRIPT AS WE DO NOT NEED AI TO RUN ANYTHING HERE
function main()
{
}
function end_script()
{
// This callback will be called when AI will change states from AIS_BEHAVE to AIS_SCRIPTED
// i.e when it will go from behavior state to animscripted state
if( IsDefined( self.___ArchetypeOnAnimscriptedCallback ) )
[[self.___ArchetypeOnAnimscriptedCallback]]( self );
}

View File

@ -0,0 +1,98 @@
// at 96 units distance, AI will prefer to walk instead of running to it.
// standing offset at covernodes based on the AI pose
// yaws used to check if the AI can see the enemy
// offsets used to check if the AI can see the enemy
// in sec, if AI has not seen enemy for 4 sec, then he will be considered hidden
// maximum time for idle action at cover, ir-respective of the animation length
// grenade throw ranges
// grenade throw modifiers
// Lower bound of time before a person of the same team can throw another grenade
// Upper bound of time before a person of the same team can throw another grenade
// Lower bound of time before a person that finished a scripted animation can throw a grenade
// Upper bound of time before a person that finished a scripted animation can throw a grenade
// Lower bound of time before being able to throw another grenade
// Upper bound of time before being able to throw another grenade
// New grenade throws must land atleast this far from any previous throw, within the GRENADE_THROW_TIME window.
// Don't throw a grenade if you are on team allies and it will land this close to a player (may want to change to any ally)
// Don't throw a grenade if there is a player in laststand this close to the target.
// Melee ranges and timers
// allowed 10 units to account for charge blend
// charge distance is the minimum distance required to even attempt melee
// Arrival
// Distance at which enmey is considered to be nearby
// Cover modes
//Sprint values
//delay between two sprints
//upto one more second delay between sprint
//additional compensation factor
//value between 0 and 100, probability of sprinting
// Cover shoot times
// *********** SUMEET TODO - Merge seeking and exposed reacquiring behavior together. ***********
// Reacquire/ Cover/Locomotion Seek

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,19 @@
// These enums must match with StateMachineStatus in behavior_state_machine_db.h
// HACK - just to match status codes with the behavior tree, ease of use!
// HACK - just to match status codes with the behavior tree, ease of use!

View File

@ -0,0 +1,17 @@
// return status for BehaviorTreeNodes tick functions - BHTN_STATUS, order is important, BHTN_RUNNING needs to be highest

View File

@ -0,0 +1,71 @@
#namespace BehaviorTreeNetwork;
// ------------- BehaviorTreeScript ----------- //
function RegisterBehaviorTreeScriptAPIInternal( functionName, functionPtr )
{
if ( !IsDefined( level._BehaviorTreeScriptFunctions ) )
{
level._BehaviorTreeScriptFunctions = [];
}
// SUMEET TODO - remove the need of ToLower and have the functionNames defined in .gsh
functionName = ToLower( functionName );
Assert( IsDefined( functionName ) && IsDefined( functionPtr ), "BT - (RegisterBehaviorTreeScriptAPI) No functionPtr defined or no functionName defined for BehaviorTreeScript." );
Assert( !IsDefined( level._BehaviorTreeScriptFunctions[functionName] ), "BT - (RegisterBehaviorTreeScriptAPI) functionName is already defined for BehaviorTreeScript." );
level._BehaviorTreeScriptFunctions[functionName] = functionPtr;
}
// ------------- BehaviorTreeAction ----------- //
function RegisterBehaviorTreeActionInternal( actionName, startFuncPtr, updateFuncPtr, terminateFuncPtr )
{
if ( !IsDefined( level._BehaviorTreeActions ) )
{
level._BehaviorTreeActions = [];
}
actionName = ToLower( actionName );
Assert( IsString( actionName ), "BT - actionName for RegisterBehaviorTreeActionInternal is not a string." );
Assert( !IsDefined(level._BehaviorTreeActions[actionName]), "BT - (RegisterBehaviorTreeActionInternal) actionName " + actionName + " is already registered." );
level._BehaviorTreeActions[actionName] = array();
// BHTN_ACTION_START
if( IsDefined( startFuncPtr ) )
{
Assert( IsFunctionPtr( startFuncPtr ), "BT - BehaviorTreeAction startFuncPtr must be of type functionPtr." );
level._BehaviorTreeActions[actionName]["bhtn_action_start"] = startFuncPtr;
}
// BHTN_ACTION_UPDATE
if( IsDefined( updateFuncPtr ) )
{
Assert( IsFunctionPtr( updateFuncPtr ), "BT - BehaviorTreeAction updateFuncPtr must be of type functionPtr." );
level._BehaviorTreeActions[actionName]["bhtn_action_update"] = updateFuncPtr;
}
// BHTN_ACTION_TERMINATE
if( IsDefined( terminateFuncPtr ) )
{
Assert( IsFunctionPtr( terminateFuncPtr ), "BT - BehaviorTreeAction terminateFuncPtr must be of type functionPtr." );
level._BehaviorTreeActions[actionName]["bhtn_action_terminate"] = terminateFuncPtr;
}
}
// ------------- utility----------- //
#namespace BehaviorTreeNetworkUtility;
function RegisterBehaviorTreeScriptAPI( functionName, functionPtr )
{
BehaviorTreeNetwork::RegisterBehaviorTreeScriptAPIInternal( functionName, functionPtr );
}
function RegisterBehaviorTreeAction( actionName, startFuncPtr, updateFuncPtr, terminateFuncPtr )
{
BehaviorTreeNetwork::RegisterBehaviorTreeActionInternal( actionName, startFuncPtr, updateFuncPtr, terminateFuncPtr );
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,424 @@
// -------------------------------------------- BLACKBOARD ATTRIBUTES --------------------------//
// Attribute names, keep it lowercase. "_" before the attribute name indicates that its being used by both AST and BT.
// Desired values should have DESIRED and "_desired_" in their definition. There should be a associated BB attribute existing already
// Eg. ATTRIBUTE and DESIRED_ATTRIBUTE and "_attribute" and "_desired_attribute". Try to keep them together please. :)
// Robots
//Zombies
//contains all the possible knockdown animations
//only has the quick to the ground knockdown animations
// will be set to YES if AI will look good if he reacts with flanking
// -------------------------------------------- BLACKBOARD DEFINES --------------------//
// -------------------------------------------- AIM RELATED --------------------------//
// -------------------------------------------- STANCES -------------------------------//
// -------------------------------------------- WEAPONS -------------------------------//
// -------------------------------------------- DAMAGE -------------------------------//
// -------------------------------------------- TACTICAL WALK -------------------------//
// -------------------------------------------- CORNER PREDICTION ----------------------//
// -------------------------------------------- ARRIVAL -------------------------------//
// -------------------------------------------- LOCMOTION PAIN ------------------------//
// -------------------------------------------- DAMAGE DIRECTION ------------------------//
// -------------------------------------------- SPECIAL DEATH ------------------------//
// -------------------------------------------- AWARENESS ------------------------//
// -------------------------------- STAIRS ------------------------//
// skip4 Not implemented yet
// -------------------------------------------- HITLOCS ------------------------//
// same as hitLocation_t enum in q_shared.h

414
shared/ai/systems/debug.gsc Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,24 @@
// 20 possible states and 1 toggle bit to determine if spawning gib models should happen on the client.
// The toggle bit is used to predamage characters when they are spawned in, without creating gib models.
// (20 + 1) states
// Pieces numbers start at 1, and stop at DESTRUCT_MAX_PIECES

421
shared/ai/systems/face.gsc Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@

792
shared/ai/systems/gib.csc Normal file

File diff suppressed because one or more lines are too long

663
shared/ai/systems/gib.gsc Normal file

File diff suppressed because one or more lines are too long

57
shared/ai/systems/gib.gsh Normal file
View File

@ -0,0 +1,57 @@
// Server side only
// Server side only
// Server side only
// 7 Damage states and 1 toggle bit to determine if gib models should be spawned on the client.
// Less than GIB_TORSO_RIGHT_ARM_FLAG
// Client/Server scriptbundle

414
shared/ai/systems/init.gsc Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File