1[
EntityEditorProps(
category:
"GameScripted/Components", description:
"Allows player to spawn entities configured in EntityCatalogs, usually found on factions. Requires SCR_EntitySpawnerSlotComponent in vicinity.", color:
"0 0 255 255")]
4 [
Attribute(defvalue:
"{56EBF5038622AC95}Assets/Conflict/CanBuild.emat",
params:
"emat",
desc:
"Material used on entity previews, visible to local players only",
category:
"Entity Spawner")]
7 [
Attribute(defvalue:
"{14A9DCEA57D1C381}Assets/Conflict/CannotBuild.emat",
params:
"emat",
desc:
"Material used on unavailable entity previews, visible to local players only",
category:
"Entity Spawner")]
10 [
Attribute(defvalue :
"{000CD338713F2B5A}Prefabs/AI/Groups/Group_Base.et",
UIWidgets.ResourceNamePicker,
"Default group to be initially assigned to created units",
"et",
category:
"Entity Spawner")]
13 [
Attribute(defvalue:
"{FFF9518F73279473}PrefabsEditable/Auto/AI/Waypoints/E_AIWaypoint_Move.et",
UIWidgets.ResourceNamePicker,
"Defend waypoint prefab",
"et",
category:
"Entity Spawner")]
22 [
Attribute(defvalue:
"10",
params:
"0 inf",
desc:
"How long should be vehicle locked after spawn",
category:
"Vehicle lock protection")]
63class SCR_CatalogEntitySpawnerComponent : SCR_SlotServiceComponent
66 static const ref array<SCR_CatalogEntitySpawnerComponent>
INSTANCES = {};
88 [
Attribute(defvalue:
"1",
desc:
"If true, Spawner will require from entities that they have all allowed labels.",
category:
"Catalog Parameters")]
106 [
Attribute(
params:
"0 inf",
desc:
"Multiplier used to affect the resource usage of the refund actions after the grace period has expired.",
category:
"Supplies")]
119 static const int SLOT_CHECK_INTERVAL = 60;
157 if (entityId.IsValid())
168 if (entityId.IsValid())
180 if (!entityId.IsValid() || !userId.IsValid())
199 if (!entityId.IsValid() || !userId.IsValid())
216 if (!entityId.IsValid())
236 if (!entityId.IsValid())
261 if (!entityId.IsValid())
264 if (!userId.IsValid())
267 if (startingTime == FLT_INF)
268 startingTime =
GetGame().GetWorld().GetWorldTime() / 1000.0;
286 if (startingTime == FLT_INF)
287 startingTime =
GetGame().GetWorld().GetWorldTime() / 1000.0;
311 if (campaign.CanRequestVehicleWithoutRank())
314 int playerId =
GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(user);
318 IEntity playerController =
GetGame().GetPlayerManager().GetPlayerController(playerId);
319 if (!playerController)
362 array<SCR_EntityCatalogEntry> newAssets = {};
363 array<typename> includedDataClasses = {};
395 array<BaseUserAction> userActions = {};
399 Print(
"There is not enough of SCR_CatalogSpawnerUserAction attached to actionManager. Some assets won't appear.",
LogLevel.WARNING);
406 if (!spawnerUserAction)
426 [
Obsolete(
"SCR_CatalogEntitySpawnerComponent.AssignSupplyComponent() should be used instead.")]
429 m_SupplyComponent = supplyComp;
468 if (currentTime.DiffMilliseconds(timestamp) > (SLOT_CHECK_INTERVAL * 100))
471 occupiedSlots.Insert(slot);
486 if (currentTime.DiffMilliseconds(timestamp) > (SLOT_CHECK_INTERVAL * 100))
488 else if (spawnerData.CanSpawnInSlot(slot.GetSlotType()))
502 foreach (SCR_EntitySpawnerSlotComponent slot : slots)
504 if (!spawnerData.CanSpawnInSlot(slot.GetSlotType()) || occupiedSlots.Contains(slot))
507 if (!slot.IsOccupied())
535 array<SCR_EntitySpawnerSlotComponent> occupiedSlots = {};
553 IEntity user =
GetGame().GetPlayerManager().GetPlayerControlledEntity(userId);
566 PerformSpawn(entityEntry, user, slot);
588 if (consumer && entitySpawnerData && (entitySpawnerData.
GetSupplyCost() > consumer.GetAggregatedResourceValue()))
613 BaseGameMode gameMode =
GetGame().GetGameMode();
617 SCR_SpawnerAIGroupManagerComponent groupSpawningManager = SCR_SpawnerAIGroupManagerComponent.Cast(gameMode.FindComponent(SCR_SpawnerAIGroupManagerComponent));
618 if (!groupSpawningManager || groupSpawningManager.IsAtAILimit())
626 SCR_PlayerControllerGroupComponent groupController = SCR_PlayerControllerGroupComponent.Cast(controller.FindComponent(SCR_PlayerControllerGroupComponent));
627 if (!groupController || !groupController.IsPlayerLeaderOwnGroup())
654 if (!commandingManager)
658 if (!playerController)
661 SCR_PlayerControllerGroupComponent groupController = SCR_PlayerControllerGroupComponent.Cast(playerController.FindComponent(SCR_PlayerControllerGroupComponent));
662 if (!groupController)
665 SCR_AIGroup group = groupController.GetPlayersGroup();
673 SCR_SpawnerRequestComponent reqComponent = SCR_SpawnerRequestComponent.Cast(playerController.FindComponent(SCR_SpawnerRequestComponent));
677 int queuedAICount = reqComponent.GetQueuedAIs();
679 return commandingManager.GetMaxAIPerGroup() >= (slaveGroup.
GetAIMembers().
Count() + queuedAICount + aiCount);
697 if (groups.param1 == group)
699 playerGroup = groups.param2;
709 if (!playerController)
712 SCR_PlayerControllerGroupComponent groupController = SCR_PlayerControllerGroupComponent.Cast(playerController.FindComponent(SCR_PlayerControllerGroupComponent));
713 if (!groupController)
716 array<AIAgent> agents = {};
717 group.GetAgents(agents);
720 SCR_ChimeraCharacter aiCharacter;
721 foreach (AIAgent agent : agents)
723 aiCharacter = SCR_ChimeraCharacter.Cast(agent.GetControlledEntity());
727 groupController.AddAIToSlaveGroup(agent.GetControlledEntity(), playerGroup);
730 SCR_SpawnerRequestComponent spawnerReqComponent = SCR_SpawnerRequestComponent.Cast(playerController.FindComponent(SCR_SpawnerRequestComponent));
731 if (spawnerReqComponent)
732 spawnerReqComponent.AddQueuedAI(-1);
750 SCR_PlayerControllerGroupComponent groupController = SCR_PlayerControllerGroupComponent.Cast(controller.FindComponent(SCR_PlayerControllerGroupComponent));
751 if (!groupController)
754 groupController.RequestAddAIAgent(ai, controller.GetPlayerId());
762 SCR_ChimeraCharacter player = SCR_ChimeraCharacter.Cast(user);
766 return player.GetFaction();
799 int playerId = playerManager.GetPlayerIdFromControlledEntity(userEntity);
811 if (!playerController)
814 return SCR_SpawnerRequestComponent.Cast(playerController.FindComponent(SCR_SpawnerRequestComponent));
825 reqComponent.SendPlayerFeedback(msgId, assetId, catalogType);
851 if (!resource || !resource.IsValid())
855 params.TransformMode = ETransformMode.WORLD;
857 slot.GetOwner().GetTransform(
params.Transform);
861 material = prefabData.m_sPreviewEntityMaterial;
863 material = prefabData.m_sPreviewEntityMaterialUnavailable;
905 SCR_EntitySpawnerSlotComponent slot;
906 if (preferredSlot && spawnerData.
CanSpawnInSlot(preferredSlot.GetSlotType()) && !preferredSlot.IsOccupied())
908 slot = preferredSlot;
947 array<SCR_EntityCatalogEntry> entityList = {};
948 parentCatalog.GetEntityList(entityList);
949 int assetIndex = entityList.Find(entityEntry);
960 carController.SetPersistentHandBrake(
true);
963 if (physicsComponent)
964 physicsComponent.SetVelocity(
"0 -0.1 0");
970 if (!actionsManagerComponent)
974 array<BaseUserAction> outActions = {};
976 actionsManagerComponent.GetActionsList(outActions);
991 if (!requestComponent)
999 slot.MoveCharactersFromSlot();
1011 if (!entityResource || !entityResource.IsValid())
1013 Print(
"CatalogEntitySpawnerComponent - SpawnEntity cannot spawn new entity without valid resource. Used SCR_EntityCatalogEntry is probably set incorrectly",
LogLevel.ERROR);
1018 params.TransformMode = ETransformMode.WORLD;
1019 slotOwner.GetTransform(
params.Transform);
1030 SCR_VehicleSpawnProtectionComponent protectionComp = SCR_VehicleSpawnProtectionComponent.Cast(
m_SpawnedEntity.FindComponent(SCR_VehicleSpawnProtectionComponent));
1031 if (!protectionComp)
1038 protectionComp.SetVehicleOwner(
GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(owningUser));
1053 [
Obsolete(
"SCR_CatalogEntitySpawnerComponent.GetSpawnerResourceComponent() should be used instead.")]
1056 return m_SupplyComponent;
1072 return consumer.GetAggregatedResourceValue();
1078 [
Obsolete(
"SCR_CatalogEntitySpawnerComponent.GetSpawnerResourceValue() should be used instead.")]
1081 if (!m_SupplyComponent)
1084 return m_SupplyComponent.GetSupplies();
1094 SCR_ResourceInteractor interactor;
1103 interactor = generator;
1114 interactor = consumer;
1116 consumer.RequestConsumtion(-supplies);
1135 int userId =
GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(user);
1140 if (!playerController)
1144 if (!networkComponent)
1147 SCR_CampaignFactionManager factionManager = SCR_CampaignFactionManager.Cast(
GetGame().GetFactionManager());
1148 if (!factionManager)
1153 WorldTimestamp timeout = lastTimestamp.PlusMilliseconds(factionManager.GetRankRequestCooldown(rank, playerController.GetPlayerId()));
1155 return (lastTimestamp == 0 || timeout.Less(world.GetServerTimestamp()));
1169 if (!requestComponent)
1172 BaseGameMode gameMode =
GetGame().GetGameMode();
1176 SCR_SpawnerAIGroupManagerComponent groupSpawningManager = SCR_SpawnerAIGroupManagerComponent.Cast(gameMode.FindComponent(SCR_SpawnerAIGroupManagerComponent));
1177 if (!groupSpawningManager)
1180 foreach (
int i,
ResourceName resName : group.m_aUnitPrefabSlots)
1182 groupSpawningManager.QueueSpawn(
this, resName, user, slotEntity, rallyPoint);
1185 requestComponent.AddQueuedAI(group.m_aUnitPrefabSlots.Count());
1197 SCR_ChimeraCharacter ai = SCR_ChimeraCharacter.Cast(
SpawnEntity(resName, slotEntity));
1211 if (groups.param1 != group)
1214 playerGroup = groups.param2;
1218 if (!playerController)
1221 SCR_SpawnerRequestComponent spawnerReqComponent = SCR_SpawnerRequestComponent.Cast(playerController.FindComponent(SCR_SpawnerRequestComponent));
1222 if (spawnerReqComponent)
1223 spawnerReqComponent.AddQueuedAI(-1);
1230 AIControlComponent control = AIControlComponent.Cast(ai.FindComponent(AIControlComponent));
1234 control.ActivateAI();
1250 AIAgent agent = control.GetAIAgent();
1263 group.AddAgent(agent);
1264 group.AddWaypoint(wp);
1278 if (!playerController)
1285 m_aGroupsToAssign.Insert(
new Tuple2<SCR_AIGroup, SCR_AIGroup>(group, groupManager.GetPlayerGroup(playerController.GetPlayerId())));
1297 wpParams.TransformMode = ETransformMode.WORLD;
1298 rallyPoint.GetOwner().GetTransform(wpParams.Transform);
1301 if (!wpRes.IsValid())
1313 SCR_ResourceComponent resourceComponent = SCR_ResourceComponent.FindResourceComponent(ent);
1315 if (resourceComponent)
1336 float worldTime =
GetGame().GetWorld().GetWorldTime() / 1000.0;
1353 count =
Math.Max(0, count - 1);
1358 entity.
GetBounds(entityMins, entityMaxs);
1366 count =
Math.Max(0, count - 1);
1376 super.EOnInit(owner);
1381 Print(
"SCR_CatalogEntitySpawnerComponent requires RplComponent for its functionality!",
LogLevel.WARNING);
1387 Print(
"No Action Manager detected on owner of Spawner Component!",
LogLevel.WARNING);
1398 SCR_CatalogEntitySpawnerComponent.INSTANCES.Insert(
this);
1404 super.OnDelete(owner);
1406 SCR_CatalogEntitySpawnerComponent.INSTANCES.RemoveItem(
this);
1415 super.OnPostInit(owner);
ArmaReforgerScripted GetGame()
SCR_CacheNoteComponentClass ScriptComponentClass RplProp()] protected ref array< string > m_aLines
RplComponent m_RplComponent
SCR_CampaignFaction GetFaction()
void SCR_CampaignSuppliesComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
void SendNotification(int msgId, notnull IEntity user, int assetId=-1, int catalogType=-1)
ref array< SCR_EntityCatalogEntry > m_aAssetList
void OnAIAgentRemoved(SCR_AIGroup group, AIAgent ai)
SCR_EEntityRequestStatus GetRequestState(notnull SCR_EntityCatalogEntry entityEntry, IEntity user=null)
void ~SCR_CatalogEntitySpawnerComponent()
void DeletePreviewEntity()
Delete existing Preview entity at spawner.
SCR_CampaignSuppliesComponent GetSpawnerSupplyComponent()
ref array< float > m_aGracePeriodStartingTimes
ref array< RplId > m_aGracePeriodRequesters
SCR_CatalogEntitySpawnerComponentClass INSTANCES
static variable used to store all the instances created of this component.
ref array< EEditableEntityLabel > m_aAllowedLabels
float m_fLastUpdateElapsedTime
bool RankCheck(notnull SCR_EntityCatalogEntry entityEntry, notnull IEntity user)
void SpawnAIGroupMember(ResourceName resName, notnull IEntity user, IEntity slotEntity, SCR_EntityLabelPointComponent rallyPoint=null)
bool IsSuppliesConsumptionEnabled()
bool m_bSuppliesConsumptionEnabled
ref array< RplId > m_aGracePeriodEntries
ScriptInvoker GetOnSpawnerSuppliesChanged()
void OnGroupWaypointFinished(notnull AIWaypoint wp)
void OnChimeraCharacterSpawned(notnull SCR_ChimeraCharacter ai, notnull IEntity user, SCR_EntityLabelPointComponent rallyPoint=null)
Called from PerformSpawn, if spawned entity is ChimeraCharacter.
SCR_EntitySpawnerSlotComponent GetLastKnownSuitableSlot(notnull SCR_EntityCatalogSpawnerData spawnerData)
Returns last known suitable free slot. Used to reduce amount of redundant slot checks and save perfor...
void AddKnownOccupiedSlot(notnull SCR_EntitySpawnerSlotComponent slot)
void OnAIGroupSpawned(notnull SCR_AIGroup group, notnull IEntity user, notnull IEntity slotEntity, SCR_EntityLabelPointComponent rallyPoint=null)
Called from PerformSpawn, if spawned entity is AIGroup.
ref array< EEditableEntityLabel > m_aIgnoredLabels
void UnregisterGracePeriod(notnull IEntity entity)
ActionsManagerComponent m_ActionManager
ref ScriptInvoker m_OnSpawnerSuppliesChanged
ScriptInvoker GetOnEntitySpawned()
float m_fGracePeriodAreaRange
ref array< ref Tuple2< SCR_AIGroup, SCR_AIGroup > > m_aGroupsToAssign
SCR_PlayerController GetPlayerControllerFromEntity(notnull IEntity userEntity)
bool CanRefund(RplId entityId, RplId userId)
void AddAISoldierToPlayerGroup(notnull SCR_ChimeraCharacter ai, notnull IEntity user)
void InitiateSpawn(notnull SCR_EntityCatalogEntry entityEntry, int userId, SCR_EntitySpawnerSlotComponent slot)
float GetSpawnerSupplies()
SCR_EntityCatalogEntry GetEntryAtIndex(int index)
Obtain Faction entity from AssetList on specific index.
ref array< EEntityCatalogType > m_aCatalogTypes
bool CanRequestAI(notnull IEntity user, int aiCount=1)
ref map< SCR_EntitySpawnerSlotComponent, WorldTimestamp > m_mKnownFreeSlots
SCR_EntitySpawnerSlotComponent GetFreeSlot(notnull SCR_EntityCatalogSpawnerData spawnerData)
SCR_EntitySpawnerSlotComponent GetFreeSlotFromArray(notnull array< SCR_EntitySpawnerSlotComponent > slots, notnull SCR_EntityCatalogSpawnerData spawnerData, notnull array< SCR_EntitySpawnerSlotComponent > occupiedSlots)
void ClearKnownSlots()
Manually clears known slots, thus forcing Spawner to do otherwise ignored checks.
bool CooldownCheck(notnull IEntity user)
void UpdateOccupiedSlots(out array< SCR_EntitySpawnerSlotComponent > occupiedSlots)
void AddSpawnerSupplies(float supplies)
float m_fPostGracePeriodRefundMultiplier
float GetPostGracePeriodRefundMultiplier()
bool SupplyComponentSearchCallback(IEntity ent)
Callback for Search query in EOnInit. Search will be stopped, if Base with Supply component is found.
ref map< AIWaypoint, SCR_AIGroup > m_mGroupWaypoints
SCR_ResourceComponent GetSpawnerResourceComponent()
void SetCurrentFactionCatalog()
Set Asset Catalog from currently owning faction. If null, asset list will be cleared.
float GetSpawnerResourceValue()
void AssignSupplyComponent(notnull SCR_CampaignSuppliesComponent supplyComp)
ref map< SCR_EntitySpawnerSlotComponent, WorldTimestamp > m_mKnownOccupiedSlots
bool IsInGracePeriod(IEntity entity)
void LockSpawnedVehicle(notnull IEntity owningUser)
@ REQUESTER_NOT_GROUPLEADER
void RegisterGracePeriod(notnull IEntity entity, notnull IEntity user, float startingTime=FLT_INF)
SCR_AIWaypoint CreateRallyPointWaypoint(notnull SCR_EntityLabelPointComponent rallyPoint)
Returns waypoint created as rally point for spawned unit.
void AssignResourceComponent(notnull SCR_ResourceComponent component)
Assign resource component to handle resources of spawner.
const float UPDATE_PERIOD
void AddAssetsFromCatalog(notnull SCR_EntityCatalog entityCatalog, bool overwriteOld=false)
Faction GetRequesterFaction(notnull IEntity user)
IEntity SpawnEntity(ResourceName entityResourceName, notnull IEntity slotOwner)
SCR_SpawnerRequestComponent GetRequestComponentFromPlayerEntity(notnull IEntity playerEntity)
bool m_bEnableGracePeriod
ref ScriptInvoker m_OnEntitySpawned
SCR_PrefabPreviewEntity GetPreviewEntity()
void CreatePreviewEntity(notnull SCR_EntityCatalogEntry spawnData, notnull SCR_EntitySpawnerSlotComponent slot, SCR_EEntityRequestStatus reqStatus=SCR_EEntityRequestStatus.CAN_SPAWN)
void SCR_CharacterRankComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
SCR_CharacterSoundComponentClass GetComponentData()
void SCR_CommandingManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
void SCR_GameModeCampaign(IEntitySource src, IEntity parent)
void SCR_GroupsManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
override void EOnFrame(IEntity owner, float timeSlice)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
ref array< SCR_EntitySpawnerSlotComponent > m_aNearSlots
ref array< SCR_EntitySpawnerSlotComponent > m_aChildSlots
SCR_ResourceComponent m_ResourceComponent
proto external Managed FindComponent(typename typeName)
proto external void GetBounds(out vector mins, out vector maxs)
proto external void GetWorldTransform(out vector mat[])
See IEntity::GetTransform.
proto external BaseWorld GetWorld()
Object holding reference to resource. In destructor release the resource.
Replication item identifier.
array< SCR_ChimeraCharacter > GetAIMembers()
ScriptInvoker GetOnAgentRemoved()
ScriptInvoker GetOnWaypointCompleted()
static void IgnoreSpawning(bool ignore)
Takes care of Campaign-specific server <> client communication and requests.
WorldTimestamp GetLastRequestTimestamp()
float GetSupplySearchRadius()
int GetVehicleLockedDuration()
float GetMoveWaypointCompletionRadius()
ResourceName GetDefaultWaypointPrefab()
float m_fSupplyComponentSearchRadius
float m_fMoveWaypointCompletionRadius
ResourceName GetDefaultGroupPrefab()
int m_iVehicleLockedDuration
ResourceName m_sDefaultGroupPrefab
ResourceName m_sDefaultWaypointPrefab
void SetSpawnerData(SCR_EntityCatalogEntry entityData)
Get Data type return Returns Catalog type of holder *EEntityCatalogType GetCatalogType()
Get random variant or default prefab return Random variant or default prefab *ResourceName GetRandomDefaultOrVariantPrefab()
Check if entity can be spawned in slot of given size param slotSize Slot size to check return Returns true if entity can spawn in given slot size *bool CanSpawnInSlot(SCR_EEntitySpawnerSlotType slotSize)
Get supply cost of spawning Entity return Supply cost *int GetSupplyCost()
Check if entity can be spawned by player with specific rank Will check if given rank is equal or greater then minimum required rank param rank Rank of player that request the spawn return Returns true if player has the required rank *bool HasRequiredRank(SCR_ECharacterRank rank)
SCR_EntityCatalog GetFactionEntityCatalogOfType(EEntityCatalogType catalogType, bool printNotFound=true)
SCR_ResourceGenerationResponse RequestGeneration(float resourceAmount, SCR_ResourceGenerator generator=null)
enum EPhysicsLayerPresets Vehicle
IEntity GetOwner()
Owner entity of the fuel tank.
override void EOnInit(IEntity owner)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
SCR_FieldOfViewSettings Attribute
EEditorTransformVertical
Vertical transformation mode.
EntityEvent
Various entity events.
proto external PlayerController GetPlayerController()