示例#1
0
        public void TestInit()
        {
            world = new World(null, 0, new History());
            combatant = new CombatantModel(0, "Combatant", "bar", new Vector3D(), Quaternion.Identity, 10, 10, EnumMobileState.Running, 2, 20, 20, 20, 20, 20);
            entity = new EntityModel(1, "Entity", "bar", new Vector3D(10, 10, 10), Quaternion.Identity, 10, 10, EnumMobileState.Standing, 2);

        }
示例#2
0
        public Party(string name, CombatantModel leader)
        {
            Contract.Requires<ArgumentNullException>(leader != null);
            Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(name));

            Name = name;
            Leader = leader;
        }
 public static void DoKick(CombatantModel source, EntityModel target)
 {
     //source.Kick(target);
 }
 public static double GetCompetancy(CombatantModel combatant, Schema.EnumSkillRow skill)
 {
     Schema.MobileHasSkillRow mhs = Global.Schema.MobileHasSkill.FindByTemplateObjectIDEnumSkillID(
         // TODO: do we even want templates?
         //TemplateObjectId,
         combatant.Id,
         skill.EnumSkillID);
     if (mhs != null)
         return mhs.Rating;
     return 0;
 }
        public static EntityModel DamagedBy(this EntityModel target, CombatantModel source, Schema.EnumSkillRow skill)
        {
            // TODO: use actual damage and hitroll
            float damage = skill.EnergyCost * 2;
            int hitroll = 80;

            // hit armor, or bypass armor
            // TODO: use armor rating
            if (Global.Rand.Next(hitroll) < 50)
                damage -= 8; // opponent.ArmorRating
            if (damage < 0)
                damage = 0;

            var opponent = target as CombatantModel;
            if (opponent != null)
                damage *= source.Strength / opponent.Constitution;

            target = target.WithHealthChange(-damage);

            if (target.MobileState != EnumMobileState.Dead
                && target.MobileState != EnumMobileState.Incapacitated
                && target.MobileState != EnumMobileState.Fighting)
            {
                target = target.WithState(EnumMobileState.Fighting);
                if (opponent != null && opponent.Target == null)
                    target = opponent.WithTarget(source);
            }

            return target;
        }
        public static EntityModel MagicallyDamagedBy(this EntityModel target, CombatantModel source, Schema.EnumSkillRow skill)
        {
            float damage = skill.EnergyCost * 2;
            damage += Math.Max(skill.AirAffinity * source.Affinity.Air / target.Affinity.Air, 0);
            damage += Math.Max(skill.EarthAffinity * source.Affinity.Earth / target.Affinity.Earth, 0);
            damage += Math.Max(skill.FireAffinity * source.Affinity.Fire / target.Affinity.Fire, 0);
            damage += Math.Max(skill.LifeAffinity * source.Affinity.Life / target.Affinity.Life, 0);
            damage += Math.Max(skill.WaterAffinity * source.Affinity.Water / target.Affinity.Water, 0);

            var opponent = target as CombatantModel;
            if (opponent != null)
                damage *= source.Cognition / opponent.Willpower;

            return target.WithHealthChange(-damage);
        }
 public static bool Avoids(this EntityModel target, CombatantModel source, Schema.EnumSkillRow skill)
 {
     var opponent = target as CombatantModel;
     if (opponent == null || opponent != source)
         return false;
     else if ((EnumActivationType)skill.EnumActivationTypeID == EnumActivationType.Skill)
         // physical attack: ratio of Dexterity
         // 20% chance for equal dexterity player to avoid
         return (source.Dexterity == 0 || Global.Rand.Next(100) <= opponent.Dexterity / source.Dexterity * 20);
     else
         // magical attack: Dexterity
         return (Global.Rand.Next(100) <= opponent.Dexterity);
 }
        public static void UseSkillNow(this World world, CombatantModel source, Schema.EnumSkillRow skill, EntityModel target)
        {
            if (source.MobileState == EnumMobileState.Dead || source.MobileState == EnumMobileState.Incapacitated)
            {
                world.LogMessage(source, "Unable to use " + skill.EnumSkillName + " while " + source.MobileState);
                return;
            }

            /* TODO: skill specific states
            if ( skill.EnumMobileState > caster.MobileState ) {
                caster.SendLog( "Not while " + caster.MobileState.Name );
            }
             */

            if ((source.Position - target.Position).Length > skill.Range)
            {
                world.LogMessage(source, target.Name + " is out of range");
                return;
            }

            if (skill.EnergyCost > source.Energy)
            {
                world.LogMessage(source, "Not enough energy to use " + skill.EnumSkillName + ", requires " + skill.EnergyCost);
                return;
            }
            
            // deduct energy regardless
            // TODO: can remove the explicit cast here by using generics
            source = (CombatantModel)source.WithEnergyChange(-skill.EnergyCost);

            bool succeeds = source.Succeeds(skill);

            bool hits = source.Hits(target, skill);

            bool avoids = target.Avoids(source, skill);

            // successful casting affects affinity with the elements
            if (succeeds && hits && !avoids)
            {
                // TODO: can remove the explicit cast here by using generics
                source = (CombatantModel)source.WithAffinityChange(
                    skill.AirAffinity / 1000f,
                    skill.EarthAffinity / 1000f,
                    skill.FireAffinity / 1000f,
                    skill.LifeAffinity / 1000f,
                    skill.WaterAffinity / 1000f);

                // TODO: just get the damage number instead??

                switch ((EnumActivationType)skill.EnumActivationTypeID)
                {
                    case EnumActivationType.AttackSpell:
                        target = target.MagicallyDamagedBy(source, skill);
                        break;
                    case EnumActivationType.Enchantment:
                        target = target.EnchantedBy(source, skill);
                        break;
                    case EnumActivationType.Glamour:
                        source.Activates(skill, target);
                        break;
                    case EnumActivationType.HealingSpell:
                        target = target.HealedBy(source, skill);
                        break;
                    case EnumActivationType.Skill:
                        target = target.DamagedBy(source, skill);
                        target = target.AffectedBy(source, skill);
                        source.Activates(skill, target);
                        break;
                    case EnumActivationType.Sorcery:
                        break;
                    default:
                        world.LogMessage(source, "That skill does not work yet, contact admin.");
                        Log.Error("Unhandled activation type " + (EnumActivationType)skill.EnumActivationTypeID + " for skill " + skill.EnumSkillName);
                        break;
                }
            }

            source = source.FinishSkill();
            string description = avoids ? "Avoided" : !hits ? "Missed" : !succeeds ? "Failed" : "Success";
            world.Apply(new SkillEvent(source, (EnumSkill)skill.EnumSkillID, target, succeeds, hits, avoids, description));
        }
示例#9
0
 public void Add(CombatantModel member)
 {
     _members.Add(member.Id, member);
 }
        void ProcessMessage(ClientConnection client, PossessMobile message)
        {
            var avatar = World.History.Head.Entities.ValueOrDefault(message.InstanceId);
            if (avatar != null)
            {
                // reconnected, replace existing connection with the new
                ClientConnection possessedBy;
                if (World.Possession.TryGetValue(avatar.Id, out possessedBy))
                {
                    if (possessedBy == client)
                    {
                        client.LogMessage("You already possess " + avatar);
                        return;
                    }
                    else
                    {
                        _log.Info("Mobile " + avatar + " has been taken over by " + client);
                        possessedBy.LogMessage("You lost control of " + avatar);
                        possessedBy.Avatar = null;
                    }
                }
                if (client.Avatar != null && client.Avatar.Id != avatar.Id)
                {
                    // TODO: omg releasing this sends a combatant which crashes
                    // release control of previous avatar
                    //World.Possession.Remove(client.Avatar.Id);
                }
                World.Possession[avatar.Id] = client;
                client.Avatar = avatar;
                client.LogMessage("You are now controlling " + avatar);
            }
            else
            {
                // try to load the character
                avatar = World.LoadMobile(message.InstanceId);
                if (avatar == null)
                {
                    _log.Warn("Character " + message.InstanceId + " not found.");
                    //TODO: rely on world loading
                    //client.Close();
                    //return;
                    avatar = new CombatantModel(
                        Global.Rand.Next(), client.AuthenticatedUsername, "RTSRobot",
                        new Vector3D(), Quaternion.Identity, 100, 100, Common.EnumMobileState.Standing, 1.7f,
                        20, 20, 20, 20, 20);
                }

                World.Possession[avatar.Id] = client;
                client.Avatar = avatar;

                // try to add the character to the world
                World.Apply(new EntityUpdateEvent(avatar, "Loaded for possession"));
            }
            World.SendInitialWorldView(client);
        }
示例#11
0
 public CombatantModel WithTarget(CombatantModel target)
 {
     var r = (CombatantModel)MemberwiseClone();
     r.Target = target;
     return r;
 }