Skip to content

KAI_NPCGroup

inkoalawetrust edited this page Jun 24, 2024 · 3 revisions

Description

This class is a data container that contains and keeps track of info pertaining to NPC groups. Allowing KAI NPCs (And non-KAI NPCs, through KAI_DataToken) to access and modify group data, and inform them how to act when in group, like what to do when a member joins, or behave differently based on the class of the leader. All instances of KAI_NPCGroup are stored in an NPCGroups associative map in KAI_EventHandler. Make sure to read the functions section, as a lot of the variables in this class are not meant to be changed directly.

Creating a group

The best and only proper way to create a group is using the CreateGroup() function detailed below. As it handles tasks like setting variables, adding the group to the group map, etc. If you create an NPC group without using this function, you're on your own to handle it.

Making new group classes

Of course, you will possibly want to create your own custom group class that has its' own data besides built in functionality like giving your group different existing behavior flags. The CreateGroup() function should also handle that, just pass a different class name in the GroupClass parameter, for initializing custom data, such as giving your group different icons from the default ones, you can use the Pre and/or PostInitialize() virtuals, which CreateGroup() calls when making a new group instance.

Group events

When events concerning the group occur, such as generic events like an actor (That's a member) dying, or group-specific events like the leader changing. A event alert will be fired, to allow the group to decide what it should do about that event, such as for making a group class that removes dead members. In addition, if NPCGRP_NOMEMBERALERT is false, the group can also alert any KAI NPCs (ONLY KAI NPCs) in the group of the event through HandleNPCGroupEvent.

Group icons

Groups also have icons by default. The graphics used by these icons and their scale can be customized. The icons signify attributes like if the member is the leader or not, and if they're a player, and if they're dead or alive. Group icons will hover over the actual height of the current sprite the member they're attached to is using, NOT that members' physics height. Group icons can be disabled during group creation.

Variables

Handler

Type: Pointer to KAI_EventHandler

Has the same purpose and behavior as the KAIHandler variable does on KAI_Actor. Allowing the group to have easy access to the library's event handler for tasks like accessing the NPCGroups map quickly and calling functions like FindNPCGroupsByName().

GroupName

Type: String

The name of the NPC group, this is purely cosmetic and has no bearing on how NPC groups function unless you make it so in your usage of the NPC group feature. NPC groups can be found by name using FindGroupByName() too.

Members

Type: Dynamic array

An array of all the actors that are members of the group. This is an Actor array, it's not limited to only KAI NPCs, so non KAI NPCs and players can also be members of a group. Non-KAI members have local access to the groups they're in through KAI_DataToken. However using this info will require a hard dependency to the library.

Leader

Type: Pointer A pointer to the actor that is the leader of this group. Pretty much no group should just have no leader.

OldLeader

Type: Pointer A pointer to the actor that was the leader of this group before the current one.

Flags

Type: Integer The flags that determine the behavior of this group, this can only be read using GetNPCGroupFlags() and changed with ChangeNPCGroupFlags(). Possible flags are:

  • NPCGRP_EVERYONEDIED: Turned on when all members are dead, useful for quickly check if that is the case.
  • NPCGRP_NOMEMBERALERT: KAI NPCs in the group will not be individually alert of any events affecting the group.
  • NPCGRP_NOICONS: The group will not render and update icons over the members' heads. The icon visual thinkers will still spawn, but simply become dormant until this flag is disabled.

MemberIcon, DeadMemberIcon, LeaderIcon, DeadLeaderIcon, PlayerIcon, DeadPlayerIcon

Type: TextureIDs

The TextureID variables to the graphics to use for the group icons. The variable names should be self explanatory, MemberIcon is for standard members, LeaderIcon is for the groups' leader, and PlayerIcon is a special indicator for group members that are players. The Dead* variables are the graphics to use when the member with those icons is killed.

IconScale

Type: Vector2

The XY scale to use for the icons, can be used to resize icons, such as if they're too high resolution.

GroupIcons

Type: Dynamic array

An array storing references to all the KAI_GroupIcon visual thinkers that are attached to members of the group, used by UpdateGroupIcons() to know what icons to find.

Functions

ChangeNPCGroupFlags()

Parameters:
  • Set: The flags to set to the group.
  • Remove: The flags to remove from the group.
Function:

Sets the groups' flags. This is the only way to change the Flags variable.

GetNPCGroupFlags()

Return:

Returns the groups' Flags field/variable.

AddGroupIcon()

NOTE: This function has no reason to be used on its' own, as group icons are already created when an NPC is added to the group.

Parameters:
  • ToWho: The actor to attach the icon to.
Function:

Creates a KAI_GroupIcon, attaches it to ToWho, and passes the groups' icon TextureIDs to it.

Return:

Returns a pointer to the KAI_GroupIcon created, in addition to automatically adding it to the groups' GroupIcons array.

RemoveGroupIcon()

Note: There's no reason to use this function manually, group icons use it to remove themselves from GroupIcons when they're destroyed, such as if their assigned actor is erased from existence.

Parameters:
  • Icon: The KAI_GroupIcon to find and remove.
Function:

Searches for Icon in the GroupIcons array, and if found, removes its' entry from the array. This does not destroy the icon itself.

UpdateGroupIcons()

Function:

Iterates through the GroupIcons array and updates the graphic each icon uses based on if each actor is dead, or the group leader.

PrintGroupInfo()

Parameters:
  • DontPrint: Do not print the group info to the console.
  • ColorCode: The color code to color the debug text with. Default is "l" (No coloring)
Function:

Prints debug information about the groups' data, such as all of its members' pointers, class names, if they're dead, not a KAI NPCs, a player, etc.

Return:

Returns the debug group information as a text string.

CreateGroup()

Note: This is a static function, so it can be called from basically anywhere to form a group !

Parameters:
  • GroupName: The optional cosmetic name to give the NPC group.
  • Members: An array of all the actors that are supposed to be members of the group.
  • Leader: A pointer to the actor that'll be the groups' leader. If this is null, the group will try to set a leader on its' own with LeaderFallback(), if that also returns no actor, the group will not form, and return a warning in the console instead.
  • Flags: The flags to pass to the group, these are the groups' NPCGRP_ flags.
  • GroupClass: The class of the group to spawn, by default this is KAI_NPCGroup, but this allows to spawn your custom NPC group classes too.
Function:

Creates an NPC group from the specified parameters, handling actions like assigning members, initializing variables etc. It also runs the PreInitialize() virtual before any stock group variables are initialized, and PostInitialize() after all stock variables are set. Allowing you to override those virtuals for your custom group class to initialize your own custom code, and/or to change the group icons.

Return:

Returns a spawner to the group that was created and added to the NPCGroups map.

CreateGroupACS()

Note: This is a special static function, it should only really be called by ACS scripts using ScriptCall(), for creating groups with ZScript, just use CreateGroup().

Parameters:
  • Activator: A pointer to the activator of the ACS script this function is called from. The activator will be who is made into the group leader.
  • GroupName: The optional cosmetic name to give the NPC group.
  • MemberTID: Adds all valid actors with this TID to the NPC group.
  • Flags: The flags to pass to the group, these are the groups' NPCGRP_ flags.
  • GroupClass: The class of the group to spawn, by default this is KAI_NPCGroup, but this allows to spawn your custom NPC group classes too.
Function:

Used to create an NPC group through ACS with ScriptCall(), allowing for maps with the library to make scripted events that form groups, like forming a group that follows the player from the start.

Example

When the map starts, this ACS script will form a group around the NPC with a tag of 2, and add all NPCs with a tag of 7 as its' members. And give the group the NOMEMBERALERT and NOICONS flags.

#Import "KAILib.acs"
#Include "ZCommon.acs"

Script "StartMap" OPEN
{
	SetActivator (2);
	ScriptCall ("KAI_NPCGroup","CreateGroupAcs","KAI Example Group",7,NPCGRP_NOMEMBERALERT|NPCGRP_NOICONS);
}
Return:

Returns true if the group was successfully created.

AlertMembersOfEvent()

Parameters:
  • EventType: The GRPEVNT_ event that occured.
  • Affected: The actor that was affected by the event.
Function:

If the NPCGRP_NOMEMBERALERT flag is off. This function alerts individual group members of events that occur to the group, only works with KAI NPCs. This is used by the HandleGroupEvent() virtual, and if you make a custom group class, when you override that function, don't forget to include a call to this to allow the custom groups' members to individually pick up events.

GetStrongestMember()

Parameters:
  • NoPlayers: Make AssessThreatLevel() not consider players automatically more dangerous just because they're players. Passes the CheckPlayers parameter to AssessThreatLevel().
Function/Return:

Returns a pointer to the member with the highest threat level. Or at least one of them, if multiple members share the same highest threat level (i.e multiple THREAT_VERYDANGEROUS members).

AreWeAllDead()

Function/Return:

Returns true if every member of the group is dead, used by NPCGroupEventHandler to turn NPCGRP_EVERYONEDIED on or off whenever the life status of a member changes.

AddNPCToGroup()

Parameters:
  • Recruit: The actor to make a member of the NPC group.
Function:

Adds Recruit to the NPC group, unless they're already in it, or the Recruit is dead or an inanimate object. And also fires the GRPEVNT_JOIN event and assigns a group icon to the Recruit.

Return:

Returns true if the Recruit was added to the group, false if not.

RemoveNPCFromGroup()

Parameters:
  • Discharged: The actor to remove from the group.
  • NoLeftEvent: Do not trigger the GRPEVNT_LEFT event. Can be used if say, you want members to be removed when they die, so only GRPEVNT_DEATH is fired.
Function:

Removes Discharged from the group, if they were a member of it. Including removing the actors' assigned icon, firing the member leaving event, etc.

Return:

Returns true if Discharged was successfully found and removed, false if not.

ChangeLeader()

Parameters:
  • NewLeader: The actor to make the new leader.
Function:

Makes NewLeader the leader of the group, also firing the GRPEVNT_NEWLEADER event. If NewLeader is not already a member of the group, the function will call AddNPCToGroup() to try adding them, if that fails, the leader changing process also fails and returns false.

Return:

Returns true if the leader was successfully replaced, false otherwise.

FindGroupsImIn()

Note: This is a static function, it can be called from anywhere.

Parameters:
  • Who: Who to search for any groups they're in.
  • Groups: A KAI_NPCGroup array passed by reference, any groups Who is in will be passed here.
Function:

Searches the NPCGroups map in KAI_EventHandler to find all the groups that Who is in.

Return:

This function has no direct return, instead, all groups that Who is in are added to the Groups array you have to pass to the function.

Virtuals

PreInitialize()

Function:

Executes any code added into it before any of the stock variables in KAI_NPCGroup are initialized (i.e before the Members array is filled).

Default behavior:

Sets the group icon TextureIDs to the default icon graphics of the library, and sets their scale to (0.75,0.75).

PostInitialize()

Function:

Like PreInitialize(), but runs only AFTER all the stock variables have been set, i.e if for your custom group, you first need access to all members to initialize your class.

Default behavior:

Runs no code at all by default.

HandleGroupEvent()

Note: Don't forget when overriding this virtual, to still include a call to AlertMembersOfEvent(), passing down the virtuals' parameters to it. Also don't forget to call UpdateGroupIcons() when any valid event occurs.

Parameters:
  • EventType: What event occured to the group ? Possible event types are:
    • GRPEVNT_NONE: Nothing happened to the group ? This shouldn't be possible, so it's probably best to just abort virtual if that's the event that triggered it.
    • GRPEVNT_DEATH: A member was killed.
    • GRPEVNT_ERASED: A member was deleted from existence (i.e with the Thing_Remove map/script special).
    • GRPEVNT_REVIVAL: A member was brought back from the dead.
    • GRPEVNT_JOIN: A new member joined the group.
    • GRPEVNT_LEFT: An existing member left the group.
    • GRPEVNT_NEWLEADER: The group has changed leaders to someone else.
  • Affected: The member that was affected by the event, such as the new leader for GRPEVNT_NEWLEADER, or the actor that joined for GRPEVNT_JOIN. If this point is somehow null, the virtual should most likely be aborted.
Function:

Makes the group handle events that occur around it, and also react to them. Useful for making the group class itself do custom things when something happens. Such as remove members that died (Members erased from existence should be automatically removed from the member list already), reject members that join if they're hostile to the leader etc.

Default behavior:

By default, the virtual aborts if the event is NONE or affected is null. If that's not the case, then the virtual alerts any members of whatever event occured, and then does the following:

  • When the leader is killed or erased from existence, it uses ChangeLeader() to assign a new one, the leader to assign is determined by LeaderFallback().
  • When a member is revived and is not the group leader, it handles removing said member from the group if it is now hostile to the leader. Such as if the member was resurrected by an enemy archvile.
  • Calls UpdateGroupIcons() to update the icons over all members' heads. (i.e to now check what member died, and switch to their DeadMemberIcon TextureTID).

LeaderFallback()

Function:

Handles a stock fallback to a different leader, used by the default HandleGroupEvent() code, and when CreateGroup() is called, but the Leader parameter passed to it is null.

Return:

Returns a pointer to the leader to fall back to, has to be passed to ChangeLeader() to then actually set the leader.

Default behavior:

By default, all this virtual does is either destroy the group if it has no members left, or if there are still members, use GetStrongestMember() to set the leader to whoever is the most threatening member.

OnDestroy()

Note: Of course, this is a virtual built into GZDoom for all Objects. But it's listed here to warn you that if your custom group class overrides this function, don't forget to either call the original KAI_NPCGroup OnDestroy() using Super., or copy its' code. As KAI_NPCGroup also handles properly disposing of itself from the NPCGroups map when it is removed.

See also

Clone this wiki locally