Example #1
0
        public void DeathTestReviveLater()
        {
            BaseEntity player = new MockEntity(Engine)
            {
                Name = "MOCK_PLAYER", Key = "MOCK_KEY"
            };
            long reviveDuration = 10;

            player.ReviveDuration = new MeNode(reviveDuration);
            player.RefreshProperties();
            player.Kill();
            MockTimer timer = (MockTimer)Engine.GetTimer();

            for (int i = 0; i < reviveDuration; ++i)
            {
                player.Update();
                timer.ForceTick();
                Assert.AreEqual(true, player.IsDead);
            }
            player.Update();
            Assert.AreEqual(false, player.IsDead);
            ResourceInstance hp = player.GetResource(Entity.HP_KEY);

            Assert.AreEqual(hp.MaxAmount * hp.Modifier, hp.Value);
        }
Example #2
0
        public void LogEntity(Entity target)
        {
            ResourceInstance hp    = target.GetResource(Entity.HP_KEY);
            string           hpBar = Utils.Utility.getBar(hp.Value, hp.MaxAmount);
            string           msg   = $"{target.Name} {hpBar}";

            Log(msg);
        }
Example #3
0
        public virtual void LogHeal(Entity target, Entity source, double amount)
        {
            ResourceInstance hp    = target.GetResource(Entity.HP_KEY);
            string           hpBar = Utils.Utility.getBar(hp.Value, hp.MaxAmount);
            string           msg   = $"{target.Name} {hpBar} [{(amount>0?"+":"")}{amount}:0. {hp.Resource.Name}]";

            Log(msg);
        }
Example #4
0
        public void LogDamage(Entity target, Entity source, DamageTypeTemplate typeTemplate, double amount, double resisted)
        {
            ResourceInstance hp    = target.GetResource(Entity.HP_KEY);
            string           hpBar = Utils.Utility.getBar(hp.Value, hp.MaxAmount);
            //string resist = Utils.Utility.DoubleEq(resisted,0.0)?"": $"({resisted} resisted)";
            string msg = $"{target.Name} {hpBar} {(amount < 0 ? "" : "-")}{amount} {typeTemplate.Name} damage";

            Log(msg);
        }
Example #5
0
        public void AddResource(ResourceTemplate resource)
        {
            if (ResourceMap.ContainsKey(resource.Key))
            {
                return;
            }
            ResourceInstance resIn = new ResourceInstance(resource, this);

            ResourceMap.Add(resource.Key, resIn);
            RefreshProperties();
        }
Example #6
0
        public void AddToResource(string key, double amount)
        {
            if (!ResourceMap.ContainsKey(key))
            {
                return;
            }
            ResourceInstance res = ResourceMap[key];

            Engine.Log().Log($"[{Name}]Generated {amount:0.} {res.Resource.Name}.");
            res.Add(amount);
        }
Example #7
0
        public void LevelTestStatIncreaseAffectsResource()
        {
            string           stat        = "VIT";
            MockEntity       ent         = new MockEntity(Engine);
            double           expected    = ent.GetProperty(stat).Value + 1;
            ResourceInstance hp          = ((ResourceInstance)ent.GetProperty(Entity.HP_KEY));
            double           expectedRes = hp.MaxAmount + 20;

            ent.AddExp(StartExp);
            ent.AssignAttributePoint(stat);
            Assert.AreEqual(expected, ent.GetProperty(stat).Value);
            Assert.AreEqual(expectedRes, hp.MaxAmount);
        }
Example #8
0
        public void DeathTestRevive()
        {
            BaseEntity player = new MockEntity(Engine)
            {
                Name = "MOCK_PLAYER", Key = "MOCK_KEY"
            };

            player.Kill();
            player.Update();
            Assert.AreEqual(true, player.IsDead);
            player.Update();
            Assert.AreEqual(false, player.IsDead);
            ResourceInstance hp = player.GetResource(Entity.HP_KEY);

            Assert.AreEqual(hp.MaxAmount * hp.Modifier, hp.Value);
        }
Example #9
0
 void LoadedUI(GameUI ui, ResourceInstance res, params object[] args)
 {
     if (ui.state == UIState.Loading)
     {
         ui.Load();
         ui.Open(args);
     }
     else
     {
         if (ui.state == UIState.Unloaded)
         {
         }
         else if (ui.state == UIState.Close)
         {
             ui.Load();
         }
     }
 }
Example #10
0
    public ResourceInstance LoadPrefabAsync(string path, Action <ResourceInstance> loaded = null)
    {
        var resIns = prefabList.Find(item => item.path == path);

        if (resIns == null)
        {
            resIns = new ResourceInstance(path);
            if (loaded != null)
            {
                resIns.OnLoaded += loaded;
            }
            prefabList.Add(resIns);
            StartCoroutine(resIns.StartLoad());
            return(resIns);
        }
        else
        {
            return(resIns);
        }
    }
        /// <summary>
        /// Method is done as a cleanup, when a resource is deleted, this method will remove the deleted object from an entityInstance reference property
        /// </summary>
        /// <param name="targetResource">Resource to look for in the currentEntityInstance</param>
        /// <param name="property">Reference property to look in on the currentEntityInstance</param>
        /// <param name="currentEntityInstance">currentEntityInstance that may contain the targetResource</param>
        private void SetEntityReferenceToNullOnTargetResourceMatch(ResourceInstance targetResource, ResourceProperty property, ResourceInstance currentEntityInstance)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(property, "property");
            ExceptionUtilities.CheckArgumentNotNull(currentEntityInstance, "currentEntityInstance");
            ExceptionUtilities.Assert(property.Kind == ResourcePropertyKind.ResourceReference, "Should only be called with reference properties");

            string propertyName = property.Name;
            object propertyValue;
            if (currentEntityInstance.TryGetValue(propertyName, out propertyValue) && propertyValue == targetResource)
            {
                this.pendingChanges.Add(() => currentEntityInstance[propertyName] = null);
            }
        }
        /// <summary>
        /// The IUpdatable was leaving around left over references after it a resource was being deleted. This will ensure the reference is removed from collections
        /// and reference properties
        /// </summary>
        /// <param name="targetResource">TargetResource To remove</param>
        private void DeleteAllReferences(ResourceInstance targetResource)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");

            ResourceSet targetResourceSet = this.GetResourceSet(targetResource.ResourceSetName);
            ExceptionUtilities.CheckObjectNotNull(targetResourceSet, "Resource set could not be found");
            List<ResourceSet> resourceSetsToCheck = this.metadataHelper.ResourceAssociationSets.Where(ras => ras.End1.ResourceSet == targetResourceSet).Select(ras2 => ras2.End2.ResourceSet).ToList();
            resourceSetsToCheck.AddRange(this.metadataHelper.ResourceAssociationSets.Where(ras => ras.End2.ResourceSet == targetResourceSet).Select(ras2 => ras2.End1.ResourceSet).ToList());
            resourceSetsToCheck = resourceSetsToCheck.Distinct().ToList();

            foreach (var resourceSet in resourceSetsToCheck)
            {
                IList<ResourceInstance> entitySetList = this.ResourceSetsStorage[resourceSet.Name];

                foreach (var currentEntityInstance in entitySetList)
                {
                    ResourceType currentEntityInstanceType = this.GetResourceTypeInternal(currentEntityInstance);

                    foreach (var referenceProperty in currentEntityInstanceType.GetAllPropertiesLazily().Where(p => p.Kind == ResourcePropertyKind.ResourceReference))
                    {
                        if (this.metadataHelper.IsKindOf(currentEntityInstanceType, currentEntityInstanceType))
                        {
                            this.SetEntityReferenceToNullOnTargetResourceMatch(targetResource, referenceProperty, currentEntityInstance);
                        }
                    }

                    foreach (var collectionProperty in currentEntityInstanceType.GetAllPropertiesLazily().Where(p => p.Kind == ResourcePropertyKind.ResourceSetReference))
                    {
                        this.RemoveResourceFromCollectionOnTargetResourceMatch(targetResource, collectionProperty, currentEntityInstance);
                    }
                }
            }
        }
        /// <summary>
        /// Method is done as a cleanup, when a resource is deleted, this method will remove the deleted object from an entityInstance collection property
        /// </summary>
        /// <param name="targetResource">Resource to look for in the currentEntityInstance</param>
        /// <param name="property">The collection property to remove from</param>
        /// <param name="currentEntityInstance">currentEntityInstance that may contain the targetResource</param>
        private void RemoveResourceFromCollectionOnTargetResourceMatch(ResourceInstance targetResource, ResourceProperty property, ResourceInstance currentEntityInstance)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(property, "property");
            ExceptionUtilities.CheckArgumentNotNull(currentEntityInstance, "currentEntityInstance");
            ExceptionUtilities.Assert(property.Kind == ResourcePropertyKind.ResourceSetReference, "Should only be called with reference properties");

            string propertyName = property.Name;
            object propertyValue;
            if (!currentEntityInstance.TryGetValue(propertyName, out propertyValue))
            {
                return;
            }

            IEnumerable childCollectionObject = propertyValue as IEnumerable;
            ExceptionUtilities.CheckObjectNotNull(childCollectionObject, "Value of '{0}.{1}' was null or not a collection", currentEntityInstance.ResourceTypeName, propertyName);

            var removeMethod = childCollectionObject.GetType().GetMethod("Remove");
            ExceptionUtilities.CheckObjectNotNull(removeMethod, "Could not find remove method for collection property '{0}.{1}'", currentEntityInstance.ResourceTypeName, propertyName);

            if (childCollectionObject.Cast<object>().Any(o => o == targetResource))
            {
                this.pendingChanges.Add(() => removeMethod.Invoke(childCollectionObject, new object[] { targetResource }));
            }
        }
        /// <summary>
        /// For the given association from source to target, perform the appropriate reversed action
        /// </summary>
        /// <param name="source">the source of the association to reverse</param>
        /// <param name="target">the target of the association to reverse</param>
        /// <param name="forwardPropertyName">the name of the property from source to target</param>
        /// <param name="remove">whether or not to remove the reversed association</param>
        private void SetReverseNavigation(ResourceInstance source, ResourceInstance target, string forwardPropertyName, bool remove)
        {
            ResourceType targetType;
            ResourceType sourceType = this.GetResourceTypeInternal(source);

            if (target == null)
            {
                targetType = sourceType.GetAllPropertiesLazily().Single(p => p.Name == forwardPropertyName).ResourceType;
            }
            else
            {
                targetType = this.GetResourceTypeInternal(target);
            }

            ResourceProperty forwardProperty = sourceType.GetAllPropertiesLazily().SingleOrDefault(p => p.Name == forwardPropertyName);

            if (forwardProperty != null && forwardProperty.CustomState != null)
            {
                // because sourceType could match targetType, we need to make sure we filter out the target property
                ResourceProperty reverseProperty = targetType.GetAllPropertiesLazily()
                    .SingleOrDefault(
                    p =>
                    p != forwardProperty && p.CustomState != null &&
                    (string)p.CustomState == (string)forwardProperty.CustomState);

                if (reverseProperty != null)
                {
                    bool reference = (reverseProperty.Kind & ResourcePropertyKind.ResourceReference) != 0;
                    if (remove)
                    {
                        if (reference)
                        {
                            this.SetReference_Internal(target, reverseProperty.Name, null, false);
                        }
                        else
                        {
                            this.RemoveReferenceFromCollection_Internal(target, reverseProperty.Name, source, false);
                        }
                    }
                    else
                    {
                        if (reference)
                        {
                            this.SetReference_Internal(target, reverseProperty.Name, source, false);
                        }
                        else
                        {
                            this.AddReferenceToCollection_Internal(target, reverseProperty.Name, source, false);
                        }
                    }
                }
            }
        }
        private void RemoveReferenceFromCollection_Internal(ResourceInstance targetResource, string propertyName, ResourceInstance resourceToBeRemoved, bool removeBackReference)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
            ExceptionUtilities.CheckArgumentNotNull(resourceToBeRemoved, "resourceToBeRemoved");

            var resourceType = this.metadataHelper.ResourceTypes.Single(t => t.FullName == targetResource.ResourceTypeName);
            var property = resourceType.GetAllPropertiesLazily().SingleOrDefault(p => p.Name == propertyName);
            ExceptionUtilities.CheckObjectNotNull(property, "Could not find resource property '{0}' on resource type '{1}'", propertyName, resourceType.FullName);
            ExceptionUtilities.Assert(property.Kind == ResourcePropertyKind.ResourceSetReference, "RemoveReferenceFromCollection called on property '{0}' with kind '{1}'", propertyName, property.Kind);

            var collection = (IEnumerable)targetResource[propertyName];
            var removeMethod = collection.GetType().GetMethod("Remove");
            ExceptionUtilities.CheckObjectNotNull(removeMethod, "Could not find 'Remove' method on collection of type: " + collection.GetType());

            removeMethod.Invoke(collection, new object[] { resourceToBeRemoved });

            if (removeBackReference)
            {
                this.SetReverseNavigation(targetResource, resourceToBeRemoved, propertyName, true);
            }
        }
Example #16
0
 public ResourceLoadCoroutine(ResourceInstance res)
 {
     this.res = res;
 }
        private void SetValue(ResourceInstance instance, string propertyName, object propertyValue)
        {
            var resourceType = this.metadataHelper.ResourceTypes.Single(t => t.FullName == instance.ResourceTypeName);

            ResourceProperty property = resourceType.GetAllPropertiesLazily().SingleOrDefault(p => p.Name == propertyName);

            bool isMultiValue = false;
            if (property != null)
            {
                ExceptionUtilities.Assert(!property.Kind.HasFlag(ResourcePropertyKind.Stream), "SetValue called on stream property '{0}'", propertyName);
                isMultiValue = property.Kind.HasFlag(ResourcePropertyKind.Collection);
            }

            if (isMultiValue)
            {
                var enumerable = propertyValue as IEnumerable;
                ExceptionUtilities.CheckObjectNotNull(enumerable, "Collection property value was not an enumerable");

                this.pendingChanges.Add(() => this.SetCollectionPropertyValue(instance, propertyName, enumerable));
            }
            else
            {
                this.pendingChanges.Add(() => instance[propertyName] = UpdatableToken.ResolveIfToken(propertyValue));
            }
        }
        /// <summary>
        /// Creates a resource in the given set with the given type
        /// </summary>
        /// <param name="containerName">The given set name</param>
        /// <param name="fullTypeName">The given type name</param>
        /// <returns>The resource created</returns>
        public virtual object CreateResource(string containerName, string fullTypeName)
        {
            ExceptionUtilities.CheckArgumentNotNull(fullTypeName, "fullTypeName");

            ResourceType type = this.metadataHelper.ResourceTypes.SingleOrDefault(t => t.FullName == fullTypeName);
            ExceptionUtilities.CheckObjectNotNull(type, "Could not find type with name '{0}'", fullTypeName);
            ExceptionUtilities.ThrowDataServiceExceptionIfFalse(!type.IsAbstract, 400, "Cannot create resource because type '{0}' is abstract.", type.FullName);

            ResourceInstance instance;
            if (type.ResourceTypeKind == ResourceTypeKind.ComplexType)
            {
                ExceptionUtilities.Assert(containerName == null, "Container name must be null for complex types. Value was '{0}'", containerName);

                if (type.InstanceType == typeof(ResourceInstance))
                {
                    instance = new ResourceInstance(type);
                }
                else
                {
                    ConstructorInfo constructor = type.InstanceType.GetConstructor(new[] { typeof(ResourceType) });
                    ExceptionUtilities.CheckObjectNotNull(constructor, "Could not find constructor for complex type '{0}'", type.InstanceType);
                    instance = (ResourceInstance)constructor.Invoke(new object[] { type });
                }
            }
            else
            {
                ExceptionUtilities.CheckArgumentNotNull(containerName, "containerName");
                ResourceSet set = this.GetResourceSet(containerName);
                ExceptionUtilities.CheckObjectNotNull(set, "Could not find resource set with name '{0}'", containerName);

                ExceptionUtilities.Assert(set.ResourceType == type || this.GetDerivedTypesInternal(set.ResourceType).Contains(type), "An entity of type '{0}' cannot be added to set '{1}'", fullTypeName, containerName);

                if (type.InstanceType == typeof(ResourceInstance))
                {
                    instance = new ResourceInstance(type, set);
                }
                else
                {
                    ConstructorInfo constructor = type.InstanceType.GetConstructor(new[] { typeof(ResourceType), typeof(ResourceSet) });
                    ExceptionUtilities.CheckObjectNotNull(constructor, "Could not find constructor for entity type '{0}'", type.InstanceType);
                    instance = (ResourceInstance)constructor.Invoke(new object[] { type, set });
                }

                // TODO: better message
                ExceptionUtilities.ThrowDataServiceExceptionIfFalse(!this.ResourceSetsStorage[set.Name].Any(e => this.AreKeysEqual(e, instance)), 500, "Duplicate key");

                this.pendingChanges.Add(() => this.ResourceSetsStorage[set.Name].Add(instance));
            }

            var token = new UpdatableToken(instance);

            // foreach property marked as being server generated
            foreach (ResourceProperty property in type.GetAllPropertiesLazily())
            {
                string propertyName = property.Name;
                object generatedValue;
                if (this.TryGetStoreGeneratedValue(containerName, fullTypeName, propertyName, out generatedValue))
                {
                    token.PendingPropertyUpdates[propertyName] = generatedValue;
                    this.pendingChanges.Add(() => instance[propertyName] = generatedValue);
                }
            }

            this.InitializeCollectionProperties(type, instance, token, p => p.Kind == ResourcePropertyKind.ResourceSetReference || p.Kind == ResourcePropertyKind.Collection);

            return token;
        }
 private void InitializeCollectionProperties(ResourceType type, ResourceInstance instance, UpdatableToken token, Func<ResourceProperty, bool> filter)
 {
     foreach (ResourceProperty property in type.GetAllPropertiesLazily().Where(filter))
     {
         string propertyName = property.Name;
         Type collectionType = this.GetCollectionPropertyType(type.FullName, propertyName);
         if (collectionType != null)
         {
             var newCollection = Activator.CreateInstance(collectionType);
             token.PendingPropertyUpdates[propertyName] = newCollection;
             this.pendingChanges.Add(() => instance[propertyName] = newCollection);
         }
     }
 }
        /// <summary>
        /// Returns whether two instances have equivalent keys
        /// </summary>
        /// <param name="instance1">The first instance to compare</param>
        /// <param name="instance2">The second instance to compare</param>
        /// <returns>True if the keys are equal, otherwise false</returns>
        private bool AreKeysEqual(ResourceInstance instance1, ResourceInstance instance2)
        {
            ExceptionUtilities.CheckArgumentNotNull(instance1, "instance1");
            ExceptionUtilities.CheckArgumentNotNull(instance2, "instance2");
            ExceptionUtilities.Assert(instance1.IsEntityType, "Key equality check only supported on entities");
            ExceptionUtilities.Assert(instance2.IsEntityType, "Key equality check only supported on entities");

            if (instance1.ResourceSetName != instance2.ResourceSetName)
            {
                return false;
            }

            var type1 = this.metadataHelper.ResourceTypes.Single(t => t.FullName == instance1.ResourceTypeName);
            var type2 = this.metadataHelper.ResourceTypes.Single(t => t.FullName == instance2.ResourceTypeName);

            if (!type1.KeyProperties.SequenceEqual(type2.KeyProperties))
            {
                return false;
            }

            foreach (var keyProperty in type1.KeyProperties)
            {
                var value1 = instance1.Where(pair => pair.Key == keyProperty.Name).Select(pair => pair.Value).SingleOrDefault();
                var value2 = instance2.Where(pair => pair.Key == keyProperty.Name).Select(pair => pair.Value).SingleOrDefault();
                if (!ResourceInstance.ArePropertyValuesEqual(value1, value2))
                {
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// Sets the value of a collection property
        /// </summary>
        /// <param name="targetResource">The resource to set the value on</param>
        /// <param name="propertyName">The property to set</param>
        /// <param name="propertyValue">The collection value</param>
        protected virtual void SetCollectionPropertyValue(ResourceInstance targetResource, string propertyName, IEnumerable propertyValue)
        {
            Type collectionType = this.GetCollectionPropertyType(targetResource.ResourceTypeName, propertyName);
            if (collectionType == null)
            {
                targetResource[propertyName] = propertyValue;
                return;
            }

            // need to go through the enumerable and resolve any tokens
            propertyValue = propertyValue.Cast<object>().Select(o => UpdatableToken.ResolveIfToken(o));

            object collection;
            var enumerableConstructor = collectionType.GetConstructor(new Type[] { typeof(IEnumerable) });
            if (enumerableConstructor != null)
            {
                collection = enumerableConstructor.Invoke(new object[] { propertyValue });
            }
            else if (collectionType.IsGenericType && collectionType.GetGenericArguments().Count() == 1)
            {
                var typeArgument = collectionType.GetGenericArguments().Single();
                var typedEnumerableConstructor = collectionType.GetConstructor(new Type[] { typeof(IEnumerable<>).MakeGenericType(typeArgument) });

                if (typedEnumerableConstructor != null)
                {
                    var typedEnumerable = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(typeArgument).Invoke(null, new object[] { propertyValue });
                    collection = typedEnumerableConstructor.Invoke(new object[] { typedEnumerable });
                }
                else
                {
                    var typedAddMethod = collectionType.GetMethod("Add", new Type[] { typeArgument });
                    ExceptionUtilities.CheckObjectNotNull(typedAddMethod, "Could not find constructor or add method for type: " + collectionType.FullName);
                    
                    collection = Activator.CreateInstance(collectionType);
                    foreach (var element in propertyValue)
                    {
                        typedAddMethod.Invoke(collection, new object[] { element });
                    }
                }
            }
            else
            {
                var addMethod = collectionType.GetMethod("Add");
                ExceptionUtilities.CheckObjectNotNull(addMethod, "Could not find constructor or add method for type: " + collectionType.FullName);
               
                collection = Activator.CreateInstance(collectionType);
                foreach (var element in propertyValue)
                {
                    addMethod.Invoke(collection, new object[] { element });
                }
            }

            targetResource[propertyName] = collection;
        }
        private void SetReference_Internal(ResourceInstance targetResource, string propertyName, ResourceInstance propertyValue, bool setBackReference)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");

            var resourceType = this.metadataHelper.ResourceTypes.Single(t => t.FullName == targetResource.ResourceTypeName);
            var property = resourceType.GetAllPropertiesLazily().SingleOrDefault(p => p.Name == propertyName);
            ExceptionUtilities.CheckObjectNotNull(property, "Could not find resource property '{0}' on resource type '{1}'", propertyName, resourceType.FullName);
            ExceptionUtilities.Assert(property.Kind == ResourcePropertyKind.ResourceReference, "SetReference called on property '{0}' with kind '{1}'", propertyName, property.Kind);

            object oldValue;
            if (!targetResource.TryGetValue(propertyName, out oldValue))
            {
                oldValue = null;
            }

            targetResource[propertyName] = propertyValue;
            
            if (setBackReference)
            {
                if (propertyValue == null)
                {
                    propertyValue = (ResourceInstance)oldValue;
                }

                if (propertyValue != null)
                {
                    this.SetReverseNavigation(targetResource, propertyValue, propertyName, (propertyValue == null));
                }
            }
        }
        private void AddReferenceToCollection_Internal(ResourceInstance targetResource, string propertyName, ResourceInstance resourceToBeAdded, bool addBackReference)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
            ExceptionUtilities.CheckArgumentNotNull(resourceToBeAdded, "resourceToBeAdded");

            var resourceType = this.metadataHelper.ResourceTypes.Single(t => t.FullName == targetResource.ResourceTypeName);
            var property = resourceType.GetAllPropertiesLazily().SingleOrDefault(p => p.Name == propertyName);
            ExceptionUtilities.CheckObjectNotNull(property, "Could not find resource property '{0}' on resource type '{1}'", propertyName, resourceType.FullName);
            ExceptionUtilities.Assert(property.Kind == ResourcePropertyKind.ResourceSetReference, "AddReferenceToCollection called on property '{0}' with kind '{1}'", propertyName, property.Kind);

            object propertyValue;
            if (!targetResource.TryGetValue(propertyName, out propertyValue))
            {
                Type collectionType = this.GetCollectionPropertyType(targetResource.ResourceTypeName, propertyName);
                ExceptionUtilities.CheckObjectNotNull(collectionType, "Could not get collection type for '{0}.{1}'", targetResource.ResourceTypeName, propertyName);
                targetResource[propertyName] = propertyValue = Activator.CreateInstance(collectionType);
            }

            // Check to see if item already exists
            var collection = (IEnumerable)propertyValue;
            foreach (var existingEntity in collection)
            {
                if (this.AreKeysEqual(resourceToBeAdded, (ResourceInstance)existingEntity))
                {
                    // TODO: throw?
                    return;
                }
            }

            var addMethod = collection.GetType().GetMethod("Add");
            ExceptionUtilities.CheckObjectNotNull(addMethod, "Could not find 'Add' method on collection of type: " + collection.GetType());

            addMethod.Invoke(collection, new object[] { resourceToBeAdded });

            if (addBackReference)
            {
                this.SetReverseNavigation(targetResource, resourceToBeAdded, propertyName, false);
            }
        }
Example #24
0
        public override bool Cast(Entity target, string skillKey, bool autocast = false)
        {
            string tryAlias = Engine.GetSkillManager().GetKeyFromAlias(skillKey);

            if (tryAlias == null)
            {
                tryAlias = skillKey;
            }

            SkillInstance skill = Skills.ContainsKey(tryAlias) ? Skills[tryAlias] : null;

            if (skill == null)
            {
                Engine.Log().Log($"[{Name}] You don't have that skill({tryAlias}).");
                //log that you don't have that skill
                return(false);
            }
            if (skill.CooldownFinishTime != 0)
            {
                long seconds = (skill.CooldownFinishTime - Engine.GetTimer().GetNow()) / GameConstants.TickTime;
                Engine.Log().Log($"[{Name}] {skill.Skill.Name} is on cooldown for {seconds} s.");
                return(false);
            }

            if (!Free)
            {
                Engine.Log().Log($"[{Name}] You are busy.");
                return(false);
            }

            if (!ResourceMap.ContainsKey(skill.Values().Cost.Resource.Key))
            {
                Engine.Log().Log($"[{Name}] You don't have \"{skill.Values().Cost.Resource.Name}\".");
                return(false);
            }
            ResourceInstance res    = ResourceMap[skill.Values().Cost.Resource.Key];
            double           amount = Sanitizer.ReplacePropeties(skill.Values().Cost.Amount, this).Resolve().Value.ToDouble();

            if (!res.CanCast(amount))
            {
                Engine.Log().Log($"[{Name}] Not enough {skill.Values().Cost.Resource.Name} for {skill.Skill.Name}.");
                return(false);
            }

            res.Cast(amount);

            Free = false;

            CurrentlyCasting = new SkillCastData(skill, target, this, Engine.GetTimer().GetNow());
            long time = CurrentlyCasting.CastFinishTime - Engine.GetTimer().GetNow();

            if (time >= GameConstants.TickTime * 3)
            {
                string type         = skill.Skill.Type == SkillType.Cast ? "casting" : "channeling";
                string castedFinish = Key.Equals(CurrentlyCasting.Target.Key)
                    ? ""
                    : $" on  {CurrentlyCasting.Target.Name}";
                Engine.Log()
                .Log(
                    $"[{Name}] Started {type} {CurrentlyCasting.Skill.Skill.Name}{castedFinish}.");
            }
            return(true);
        }