/// <inheritdoc /> protected override void HandleEvent(PlayerJoinedGroupEventArgs args) { //TODO: We need to check if we have one available //Claim a unitframe. GroupUnitframeManager.TryClaimUnitFrame(args.PlayerGuid); //Even if we don't know them, we should register an event for it. GroupUnitframeManager.RegisterCallback <int>(args.PlayerGuid, (int)EntityObjectField.UNIT_FIELD_HEALTH, OnCurrentHealthChangedValue); GroupUnitframeManager.RegisterCallback <int>(args.PlayerGuid, (int)BaseObjectField.UNIT_FIELD_LEVEL, OnCurrentLevelChanged); //TODO: If we come to know them after group join, we'll need to register. if (!EntityDataMappable.ContainsKey(args.PlayerGuid)) { if (Logger.IsDebugEnabled) { Logger.Debug($"Encountered GroupJoin from far-away Entity: {args.PlayerGuid.RawGuidValue}"); } GroupUnitframeManager[args.PlayerGuid].SetElementActive(true); return; } else { //Very possible we don't know them //But if we do we should calculate their initial unitframe resources RecalulateHealthUI(args.PlayerGuid, EntityDataMappable.RetrieveEntity(args.PlayerGuid).GetFieldValue <int>((int)EntityObjectField.UNIT_FIELD_HEALTH)); RecaculateLevelUI(args.PlayerGuid, EntityDataMappable.RetrieveEntity(args.PlayerGuid).GetFieldValue <int>((int)BaseObjectField.UNIT_FIELD_LEVEL)); GroupUnitframeManager[args.PlayerGuid].SetElementActive(true); } }
public BaseEntityBehaviourComponent Create([NotNull] NetworkEntityGuid context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } IEntityDataFieldContainer dataFieldContainer = EntityDataMappable.RetrieveEntity(context); GameObject worldObject = WorldObjectMappable.RetrieveEntity(context); Type behaviourType = ComputeExpectedBehaviourType(dataFieldContainer.GetEnumFieldValue <GameObjectType>(GameObjectField.GAMEOBJECT_TYPE_ID)); using (var scope = ReflectionContainer.BeginLifetimeScope(cb => { cb.RegisterInstance(context) .AsSelf(); cb.RegisterInstance(worldObject) .As <GameObject>(); cb.RegisterInstance(dataFieldContainer) .As <IEntityDataFieldContainer>() .As <IReadonlyEntityDataFieldContainer>() .SingleInstance(); cb.RegisterType(behaviourType); })) { return((BaseEntityBehaviourComponent)scope.Resolve(behaviourType)); } }
protected override void OnEntityCreationFinished(EntityCreationFinishedEventArgs args) { IEntityDataFieldContainer entityData = EntityDataMappable.RetrieveEntity(args.EntityGuid); GameObjectTemplateModel objectTemplateModel = GameObjectTemplateMappable.RetrieveEntity(args.EntityGuid); //We should generally consider this field static. I cannot even IMAGINE how we'd handle a change to this field on either //client or server. entityData.SetFieldValue(GameObjectField.GAMEOBJECT_TYPE_ID, (int)objectTemplateModel.ObjectType); }
private void OnTargetEntityHealthChanged(NetworkEntityGuid entity, EntityDataChangedArgs <int> args) { IEntityDataFieldContainer entityData = EntityDataMappable.RetrieveEntity(entity); //Ignore the changed value. int health = entityData.GetFieldValue <int>(EntityObjectField.UNIT_FIELD_HEALTH); int maxHealth = entityData.GetFieldValue <int>(EntityObjectField.UNIT_FIELD_MAXHEALTH); TargetUnitFrame.HealthBar.BarText.Text = $"{health} / {maxHealth}"; TargetUnitFrame.HealthBar.BarFillable.FillAmount = (float)health / maxHealth; }
protected override void OnLocalPlayerTargetChanged(LocalPlayerTargetChangedEventArgs args) { IEntityDataFieldContainer entityData = EntityDataMappable.RetrieveEntity(args.TargetedEntity); EntityDataChangeCallbackService.RegisterCallback <int>(args.TargetedEntity, (int)BaseObjectField.UNIT_FIELD_LEVEL, OnTargetEntityLevelChanged); //Only initialize if we have their values if (entityData.DataSetIndicationArray.Get((int)BaseObjectField.UNIT_FIELD_LEVEL)) { OnTargetEntityLevelChanged(args.TargetedEntity, new EntityDataChangedArgs <int>(0, entityData.GetFieldValue <int>(BaseObjectField.UNIT_FIELD_LEVEL))); } }
protected override void OnEventFired(object source, EntityCreationStartingEventArgs args) { //Only do creatures. if (args.EntityGuid.EntityType != EntityType.Creature) { return; } IEntityDataFieldContainer dataContainer = EntityDataMappable.RetrieveEntity(args.EntityGuid); CreatureTemplateModel template = CreatureTemplateMappable.RetrieveEntity(args.EntityGuid); //Initialize the creature display model ID. dataContainer.SetFieldValue(BaseObjectField.UNIT_FIELD_DISPLAYID, template.ModelId); }
protected override void OnLocalPlayerTargetChanged(LocalPlayerTargetChangedEventArgs args) { IEntityDataFieldContainer entityData = EntityDataMappable.RetrieveEntity(args.TargetedEntity); foreach (var unreg in Unregisterables) { unreg.Unregister(); } Unregisterables.Clear(); //Listen for both max and current health. Unregisterables.Add(EntityDataChangeCallbackService.RegisterCallback <int>(args.TargetedEntity, (int)EntityObjectField.UNIT_FIELD_HEALTH, OnTargetEntityHealthChanged)); Unregisterables.Add(EntityDataChangeCallbackService.RegisterCallback <int>(args.TargetedEntity, (int)EntityObjectField.UNIT_FIELD_MAXHEALTH, OnTargetEntityHealthChanged)); //Only initialize if we have their values if (entityData.DataSetIndicationArray.Get((int)EntityObjectField.UNIT_FIELD_HEALTH)) { OnTargetEntityHealthChanged(args.TargetedEntity, new EntityDataChangedArgs <int>(0, 0)); } }
/// <inheritdoc /> public async Task SaveAsync(NetworkEntityGuid guid) { //We can only handle players at the moment, not sure how NPC data would be saved. if (guid.EntityType != EntityType.Player) { return; } //Player ALWAYS has this existing. EntitySaveableConfiguration saveConfig = PersistenceConfiguration.RetrieveEntity(guid); EntityFieldDataCollection entityData = EntityDataMappable.RetrieveEntity(guid); await ZonePersistenceQueueable.SaveFullCharacterDataAsync(guid.EntityId, new FullCharacterDataSaveRequest(true, saveConfig.isCurrentPositionSaveable, CreatedLocationSaveData(guid), entityData)); //We cleanup player data on the zoneserver in a different place //here, because we needed it until this very last moment. foreach (var ed in DataCollections) { ed.RemoveEntityEntry(guid); } }
private void CreateActor(WorldActorState state, CreateCreatureEntityActorMessage message) { //Create the actor and tell it to initialize. IActorRef actorRef = state.WorldActorFactory.ActorOf(Resolver.Create <DefaultCreatureEntityActor>(), message.EntityGuid.RawGuidValue.ToString()); //TODO: Move to factory. CreatureInstanceModel instanceModel = CreatureInstanceMappable.RetrieveEntity(message.EntityGuid); CreatureTemplateModel templateModel = CreatureTemplateMappable.RetrieveEntity(message.EntityGuid); DefaultCreatureEntityActor.InitializeActor(actorRef, new DefaultCreatureActorState(EntityDataMappable.RetrieveEntity(message.EntityGuid), message.EntityGuid, instanceModel, templateModel, InterestMappable.RetrieveEntity(message.EntityGuid))); ActorRefMappable.AddObject(message.EntityGuid, actorRef); if (Logger.IsInfoEnabled) { Logger.Info($"Created Creature Actor: {typeof(DefaultCreatureEntityActor)} for Entity: {message.EntityGuid}"); } }
private void RecalulateHealthUI(NetworkEntityGuid player, int currentHealth) { float healthPercentage = (float)currentHealth / EntityDataMappable[player].GetFieldValue <int>((int)EntityObjectField.UNIT_FIELD_MAXHEALTH); GroupUnitframeManager[player].HealthBar.BarFillable.FillAmount = healthPercentage; //Also we want to see the percentage text GroupUnitframeManager[player].HealthBar.BarText.Text = $"{currentHealth} / {EntityDataMappable.RetrieveEntity(player).GetFieldValue<int>((int)EntityObjectField.UNIT_FIELD_MAXHEALTH)}"; }
private EntityActorStateInitializeMessage <BehaviourGameObjectState <TBehaviourType> > CreateState <TBehaviourType>(NetworkEntityGuid entityGuid) where TBehaviourType : class, IGameObjectLinkable { GameObjectTemplateModel templateModel = GameObjectDataContainer.GameObjectTemplateMappable.RetrieveEntity(entityGuid); GameObjectInstanceModel instanceModel = GameObjectDataContainer.GameObjectInstanceMappable.RetrieveEntity(entityGuid); return(new EntityActorStateInitializeMessage <BehaviourGameObjectState <TBehaviourType> >(new BehaviourGameObjectState <TBehaviourType>(EntityDataMappable.RetrieveEntity(entityGuid), entityGuid, instanceModel, templateModel, GameObjectDataContainer.GetBehaviourInstanceData <TBehaviourType>(entityGuid), InterestMappable.RetrieveEntity(entityGuid)))); }
private IEntityActorStateInitializeMessage <DefaultGameObjectActorState> CreateDefaultInitializationState(NetworkEntityGuid entityGuid) { GameObjectTemplateModel templateModel = GameObjectDataContainer.GameObjectTemplateMappable.RetrieveEntity(entityGuid); GameObjectInstanceModel instanceModel = GameObjectDataContainer.GameObjectInstanceMappable.RetrieveEntity(entityGuid); return(new EntityActorStateInitializeMessage <DefaultGameObjectActorState>(new DefaultGameObjectActorState(EntityDataMappable.RetrieveEntity(entityGuid), entityGuid, instanceModel, templateModel, InterestMappable.RetrieveEntity(entityGuid)))); }
private IActorRef CreateActor(WorldActorState state, CreatePlayerEntityActorMessage message) { //Create the actor and tell it to initialize. IActorRef actorRef = state.WorldActorFactory.ActorOf(Resolver.Create <DefaultPlayerEntityActor>(), message.EntityGuid.RawGuidValue.ToString()); DefaultPlayerEntityActor.InitializeActor(actorRef, new DefaultPlayerEntityActorState(EntityDataMappable.RetrieveEntity(message.EntityGuid), message.EntityGuid, InterestMappable.RetrieveEntity(message.EntityGuid), SendServiceMappable.RetrieveEntity(message.EntityGuid))); //Actors aren't removed from this //they are just replaced with nobody. if (ActorRefMappable.ContainsKey(message.EntityGuid)) { //If nobody, all good. Otherwise THIS SHOULD NEVER HAPPEN if (ActorRefMappable[message.EntityGuid].IsNobody()) { ActorRefMappable.ReplaceObject(message.EntityGuid, actorRef); } else { throw new InvalidOperationException($"World attempted to spawn multiple of the same player actor/"); //this will literally kill the world actor. } } else { ActorRefMappable.AddObject(message.EntityGuid, actorRef); } if (Logger.IsInfoEnabled) { Logger.Info($"Created Player Actor: {typeof(DefaultPlayerEntityActor)} for Entity: {message.EntityGuid}"); } return(actorRef); }