예제 #1
0
 public InventoryGrid(Actor owner, int rows, int columns, int slot = 0)
 {
     this._backpack = new uint[rows, columns];
     this._owner = owner;
     this.Items = new Dictionary<uint, Item>();
     this.EquipmentSlot = slot;
 }
예제 #2
0
        public bool RunPower(Actor user, PowerScript power, Actor target = null,
                             Vector3D targetPosition = null, TargetMessage targetMessage = null)
        {
            // replace power with existing channel instance if one exists
            if (power is ChanneledSkill)
            {
                var existingChannel = _FindChannelingSkill(user, power.PowerSNO);
                if (existingChannel != null)
                {
                    power = existingChannel;
                }
                else  // new channeled skill, add it to the list
                {
                    _channeledSkills.Add((ChanneledSkill)power);
                }
            }

            // copy in context params
            power.User = user;
            power.Target = target;
            power.World = user.World;
            power.TargetPosition = targetPosition;
            power.TargetMessage = targetMessage;

            _StartScript(power);
            return true;
        }
예제 #3
0
        // generates a random item from given type category.
        // we can also set a difficulty mode parameter here, but it seems current db doesnt have nightmare or hell-mode items with valid snoId's /raist.
        public static Item GenerateRandom(Actor player, ItemType type)
        {
            var validDefinitions = ItemDefinitions[type].Where(definition => definition.SNOId != 0).ToList(); // only find item definitions with snoId!=0 for given itemtype.
            var itemDefinition = GetRandom(validDefinitions);

            return CreateItem(player, itemDefinition);
        }
예제 #4
0
파일: CombatSystem.cs 프로젝트: K42/mooege
 // get nearest target of targetType
 public static Actor GetNearestTarget(World world, Actor attacker, Vector3D centerPosition, float range, ActorType targetType = ActorType.Monster)
 {
     Actor result = null;
     List<Actor> actors = world.QuadTree.Query<Actor>(new Circle(centerPosition.X, centerPosition.Y, range));
     if (actors.Count > 1)
     {
         float distanceNearest = range; // max. range
         float distance = 0f;
         foreach (var target in actors.Where(target => ((target.ActorType == targetType) && (target != attacker) && !target.Attributes[GameAttribute.Is_NPC])))
         {
             if ((target.World == null) || (world.GetActorByDynamicId(target.DynamicID) == null))
             {
                 // leaving world
                 continue;
             }
             distance = ActorUtils.GetDistance(centerPosition, target.Position);
             if ((result == null) || (distance < distanceNearest))
             {
                 result = target;
                 distanceNearest = distance;
             }
         }
     }
     return result;
 }
예제 #5
0
파일: PowerEffect.cs 프로젝트: Sasho/mooege
        public void PlayAnimation(Actor actor, int animationId)
        {
            if (actor == null) return;

            foreach (Mooege.Core.GS.Player.Player player in actor.World.GetPlayersInRange(actor.Position, 150f))
            {
                //Stop actor current animation
                player.InGameClient.SendMessage(new ANNDataMessage(Opcodes.ANNDataMessage13)
                {
                    ActorID = actor.DynamicID
                });

                player.InGameClient.SendMessage(new PlayAnimationMessage()
                {
                    ActorID = actor.DynamicID,
                    Field1 = 0xb,
                    Field2 = 0,
                    tAnim = new PlayAnimationMessageSpec[1]
                    {
                        new PlayAnimationMessageSpec()
                        {
                            Field0 = 0x2,
                            Field1 = animationId,
                            Field2 = 0x0,
                            Field3 = 0.6f
                        }
                    }
                });
            } 
        }
예제 #6
0
파일: Pathfinder.cs 프로젝트: vrobel/mooege
 //This submits a request for a path to the pathfinder thread. This is the main point of entry for usage. - DarkLotus
 public PathRequestTask GetPath(Actor owner, Vector3D vector3D, Vector3D heading)
 {
     if (aipather == null)
         aipather = new Pathfinder();
     var pathRequestTask = new PathRequestTask(aipather, owner, owner.Position, heading);
     _queuedPathTasks.TryAdd(owner.DynamicID, pathRequestTask);
     return pathRequestTask;
 }
예제 #7
0
파일: HitPayload.cs 프로젝트: loonbg/mooege
        public HitPayload(AttackPayload attackPayload, bool criticalHit, Actor target)
            : base(attackPayload.Context, target)
        {
            this.IsCriticalHit = criticalHit;
            
            // TODO: select these values based on element type?
            float weaponMinDamage = this.Context.User.Attributes[GameAttribute.Damage_Weapon_Min_Total, 0];
            float weaponDamageDelta = this.Context.User.Attributes[GameAttribute.Damage_Weapon_Delta_Total, 0];

            // calculate and add up damage amount for each element type
            this.ElementDamages = new Dictionary<DamageType, float>();

            foreach (var entry in attackPayload.DamageEntries)
            {
                if (!this.ElementDamages.ContainsKey(entry.DamageType))
                    this.ElementDamages[entry.DamageType] = 0f;

                if (entry.IsWeaponBasedDamage)
                    this.ElementDamages[entry.DamageType] += entry.WeaponDamageMultiplier *
                        (weaponMinDamage + (float)PowerContext.Rand.NextDouble() * weaponDamageDelta);
                else
                    this.ElementDamages[entry.DamageType] += entry.MinDamage + (float)PowerContext.Rand.NextDouble() * entry.DamageDelta;

                this.ElementDamages[entry.DamageType] *= 1.0f + this.Target.Attributes[GameAttribute.Amplify_Damage_Percent];
            }

            // apply critical damage boost
            if (criticalHit)
            {
                // TODO: probably will calculate this off of GameAttribute.Crit_Damage_Percent, but right now that attribute is never set
                var damTypes = this.ElementDamages.Keys.ToArray();
                foreach (var type in damTypes)
                    this.ElementDamages[type] *= 1.5f + this.Target.Attributes[GameAttribute.Crit_Percent_Bonus_Capped];
            }



            // TODO: reduce element damage amounts according to target's resistances

            // TODO: reduce total damage by target's armor
            // ~weltmeyer Using WOW Calculation till we find the correct formula :)


            this.TotalDamage = this.ElementDamages.Sum(kv => kv.Value) ;
            var targetArmor = target.Attributes[GameAttribute.Armor_Total];
            var attackerLevel = attackPayload.Context.User.Attributes[GameAttribute.Level];
            var reduction = TotalDamage * (0.1f * targetArmor) /
                               ((8.5f * attackerLevel) + 40);

            reduction /= 1+reduction;
            reduction = Math.Min(0.75f, reduction);
            this.TotalDamage = TotalDamage*(1 - reduction);

            this.DominantDamageType = this.ElementDamages.OrderByDescending(kv => kv.Value).FirstOrDefault().Key;
            if (this.DominantDamageType == null)
                this.DominantDamageType = DamageType.Physical; // default to physical if no other damage type calced
        }
예제 #8
0
파일: World.cs 프로젝트: Rianon/mooege
 public bool ActorExists(Actor actor)
 {
     return Actors.Any(
         t =>
             t.SnoId == actor.SnoId && 
             t.Position.X == actor.Position.X && 
             t.Position.Y == actor.Position.Y &&
             t.Position.Z == actor.Position.Z);
 }
예제 #9
0
파일: Brain.cs 프로젝트: ncoop23/mooege
        public void Chase(Actor actor)
        {
            if (this.Heading == actor.Position)
                return;

            this.Target = actor;
            this.Heading = this.Target.Position;

            this.Move(this.Target);
        }
예제 #10
0
파일: Minion.cs 프로젝트: God601/mooege
 public Minion(World world, int snoId, Actor master, TagMap tags)
     : base(world, snoId, tags)
 {
     // The following two seems to be shared with monsters. One wonders why there isn't a specific actortype for minions.
     this.Master = master;
     this.Field2 = 0x8; 
     this.GBHandle.Type = (int)GBHandleType.Monster; this.GBHandle.GBID = 1;
     this.Attributes[GameAttribute.Summoned_By_ACDID] = (int)master.DynamicID;
     this.Attributes[GameAttribute.TeamID] = master.Attributes[GameAttribute.TeamID];
 }
예제 #11
0
파일: World.cs 프로젝트: bryan77/mooege
 public void BroadcastIfRevealed(GameMessage message, Actor actor)
 {
     foreach (var player in this.Players.Values)
     {
         if (player.RevealedObjects.ContainsKey(actor.DynamicID))
         {
             player.InGameClient.SendMessageNow(message);
         }
     }
 }
예제 #12
0
파일: CombatSystem.cs 프로젝트: K42/mooege
 // shhots projectile at 2D angle
 public static void ShootAtAngle(World world, Actor projectile, float angle, float speed)
 {
     float[] delta = ActorUtils.GetDistanceDelta(speed, angle);
     world.BroadcastInclusive(new ACDTranslateFixedMessage()
     {
         Id = 113, // needed
         ActorId = unchecked((int)projectile.DynamicID),
         Velocity = new Vector3D { X = delta[0], Y = delta[1], Z = 0 },
         Field2 = 1,
         AnimationTag = 1,//walkAnimationSNO
         Field4 = 1,
     }, projectile);
 }
예제 #13
0
        public MonsterBrain(Actor body)
            : base(body)
        {
            this.PresetPowers = new List<int>();

            // build list of powers defined in monster mpq data
            if (body.ActorData.MonsterSNO > 0)
            {
                var monsterData = (Mooege.Common.MPQ.FileFormats.Monster)MPQStorage.Data.Assets[SNOGroup.Monster][body.ActorData.MonsterSNO].Data;
                foreach (var monsterSkill in monsterData.SkillDeclarations)
                {
                    if (monsterSkill.SNOPower > 0)
                        this.PresetPowers.Add(monsterSkill.SNOPower);
                }
            }
        }
예제 #14
0
        public bool UsePower(Actor user, PowerScript power, Actor target = null,
                             Vector3D targetPosition = null, TargetMessage targetMessage = null)
        {
            // replace power with existing channel instance if one exists
            if (power is ChanneledPower)
            {
                var chanpow = _FindChannelingPower(user, power.PowerSNO);
                if (chanpow != null)
                    power = chanpow;
            }

            // copy in context params
            power.User = user;
            power.Target = target;
            power.World = user.World;
            power.TargetPosition = targetPosition;
            power.TargetMessage = targetMessage;

            // process channeled power events
            var channeledPower = power as ChanneledPower;
            if (channeledPower != null)
            {
                if (channeledPower.ChannelOpen)
                {
                    channeledPower.OnChannelUpdated();
                }
                else
                {
                    channeledPower.OnChannelOpen();
                    channeledPower.ChannelOpen = true;
                    _channeledPowers.Add(channeledPower);
                }
            }

            var powerEnum = power.Run().GetEnumerator();
            // actual power will first run here, if it yielded a timer process it in the waiting list
            if (powerEnum.MoveNext() && powerEnum.Current != PowerScript.StopExecution)
            {
                _waitingPowers.Add(new WaitingPower
                {
                    PowerEnumerator = powerEnum,
                    Implementation = power
                });
            }

            return true;
        }
예제 #15
0
파일: PowerEffect.cs 프로젝트: Sasho/mooege
        public void PlayEffectGroupActorToActor(int effectId, Actor from, Actor target)
        {
            if (target == null) return;

            foreach (Mooege.Core.GS.Player.Player player in from.World.GetPlayersInRange(from.Position, 150f))
            {
                player.InGameClient.SendMessage(new EffectGroupACDToACDMessage()
                {
                    Id = 0xaa,
                    effectSNO = effectId,
                    fromActorID = from.DynamicID,
                    toActorID = target.DynamicID
                });

                SendDWordTick(player.InGameClient);
            }
        }
예제 #16
0
파일: PowerEffect.cs 프로젝트: Sasho/mooege
        public void PlayHitEffect(HitEffect id, Actor target, Actor from)
        {
            if (target == null) return;

            foreach (Mooege.Core.GS.Player.Player player in target.World.GetPlayersInRange(target.Position, 150f))
            {
                player.InGameClient.SendMessage(new PlayHitEffectMessage()
                {
                    Id = 0x7b,
                    ActorID = target.DynamicID,
                    HitDealer = from.DynamicID,
                    Field2 = (int)id,
                    Field3 = false
                });

                SendDWordTick(player.InGameClient);
            }
        }
예제 #17
0
        public MonsterBrain(Actor body)
            : base(body)
        {
            this.PresetPowers = new List<int>();

            // build list of powers defined in monster mpq data
            if (body.ActorData.MonsterSNO > 0)
            {
                var monsterData = (Mooege.Common.MPQ.FileFormats.Monster)MPQStorage.Data.Assets[SNOGroup.Monster][body.ActorData.MonsterSNO].Data;
                _mpqPowerCount = monsterData.SkillDeclarations.Count(e => e.SNOPower != -1);
                foreach (var monsterSkill in monsterData.SkillDeclarations)
                {
                    if (Powers.PowerLoader.HasImplementationForPowerSNO(monsterSkill.SNOPower))
                    {
                        this.PresetPowers.Add(monsterSkill.SNOPower);
                    }
                }
            }
        }
예제 #18
0
파일: HitPayload.cs 프로젝트: n3rus/mooege
        public HitPayload(AttackPayload attackPayload, bool criticalHit, Actor target)
        {
            this.Context = attackPayload.Context;
            this.Target = target;
            this.IsCriticalHit = criticalHit;
            
            // TODO: select these values based on element type?
            float weaponMinDamage = this.Context.User.Attributes[GameAttribute.Damage_Weapon_Min_Total, 0];
            float weaponDamageDelta = this.Context.User.Attributes[GameAttribute.Damage_Weapon_Delta_Total, 0];

            // calculate and add up damage amount for each element type
            this.ElementDamages = new Dictionary<DamageType, float>();

            foreach (var entry in attackPayload.DamageEntries)
            {
                if (!this.ElementDamages.ContainsKey(entry.DamageType))
                    this.ElementDamages[entry.DamageType] = 0f;

                if (entry.IsWeaponBasedDamage)
                    this.ElementDamages[entry.DamageType] += entry.WeaponDamageMultiplier *
                        (weaponMinDamage + (float)PowerContext.Rand.NextDouble() * weaponDamageDelta);
                else
                    this.ElementDamages[entry.DamageType] += entry.MinDamage + (float)PowerContext.Rand.NextDouble() * entry.DamageDelta;
            }

            // apply critical damage boost
            if (criticalHit)
            {
                // TODO: probably will calculate this off of GameAttribute.Crit_Damage_Percent, but right now that attribute is never set
                var damTypes = this.ElementDamages.Keys.ToArray();
                foreach (var type in damTypes)
                    this.ElementDamages[type] *= 1.0f + 0.25f;
            }

            // TODO: reduce element damage amounts according to target's resistances

            // TODO: reduce total damage by target's armor

            this.TotalDamage = this.ElementDamages.Sum(kv => kv.Value);
            this.DominantDamageType = this.ElementDamages.OrderByDescending(kv => kv.Value).FirstOrDefault().Key;
        }
예제 #19
0
 protected HirelingBrain(Actor body) : base(body)
 { }
예제 #20
0
 public DeathPayload(PowerContext context, DamageType deathDamageType, Actor target)
 {
     this.Context = context;
     this.DeathDamageType = deathDamageType;
     this.Target = target;
 }
예제 #21
0
 private void DrawActor(Actor actor, Graphics graphics, Brush brush, int radius)
 {
     var rect = new Rectangle((int)actor.Bounds.X, (int)actor.Bounds.Y, (int)actor.Bounds.Width + radius, (int)actor.Bounds.Height + radius);
     graphics.FillEllipse(brush, rect);
 }
예제 #22
0
 private void _SetHiddenAttribute(Actor actor, bool active)
 {
     actor.Attributes[GameAttribute.Hidden] = active;
     actor.Attributes.BroadcastChangedIfRevealed();
 }
예제 #23
0
 protected FollowerBrain(Actor body) : base(body)
 { }
예제 #24
0
파일: Actor.cs 프로젝트: elitepilot/mooege
 // TODO: add an actor mover helper function! /raist.
 public void OnActorMove(Actor actor, Vector3D prevPosition)
 {
     // TODO: Unreveal from players that are now outside the actor's range. /komiga
 }
예제 #25
0
파일: ActorMover.cs 프로젝트: God601/mooege
 public ActorMover(Actor target)
 {
     this.Target = target;
 }
예제 #26
0
파일: Brain.cs 프로젝트: fasbat/mooege
 protected Brain(Actor body)
 {
     this.Body = body;
     this.State = BrainState.Idle;
     this.Actions = new Queue<ActorAction>();
 }
예제 #27
0
파일: Pathfinder.cs 프로젝트: vrobel/mooege
        public List<Vector3D> FindPath(Actor actor, Vector3D Start, Vector3D Destination)
        {
            _baseX = 0; _baseY = 0; // reset to 0

            // Should only be null first time a path is requested.
            if (_curScene == null)
            { 
                _curScene = actor.CurrentScene;
                if(!listOfPathFinderInstances.TryGetValue(_curScene.SceneSNO.Id,out mPathFinder)) // Attempts to pull the pathfinder which matches the scenes SNO from the patherlist
                {
                    mPathFinder = new PathFinderFast(_curScene.NavMesh.WalkGrid); // Create a new pather, using the current scenes grid.
                    listOfPathFinderInstances.TryAdd(_curScene.SceneSNO.Id, mPathFinder); // add it to our patherlist, with the SNO as key.
                }
                
                InitPathFinder();
            }
            
            // Checks if our path start location is inside current scene, if it isnt, we reset curScene and set mPathfinder to the corrent grid.
            if (!_curScene.Bounds.IntersectsWith(new System.Windows.Rect(Start.X, Start.Y, 1, 1)))
            { 
                _curScene = actor.CurrentScene;// TODO- THIS CAN RETURN PARENT RATHER THAN SUBSCENE - DarkLotus
                if (!listOfPathFinderInstances.TryGetValue(_curScene.SceneSNO.Id, out mPathFinder))
                {
                    mPathFinder = new PathFinderFast(_curScene.NavMesh.WalkGrid);
                    listOfPathFinderInstances.TryAdd(_curScene.SceneSNO.Id, mPathFinder);
                }

                InitPathFinder();
            }

            _baseX = _curScene.Position.X; //Our base location for working out world > SceneLocal coordinates.
            _baseY = _curScene.Position.Y;

            // Path's start and destination are both in same scene.
            if (_curScene.Bounds.IntersectsWith(new System.Windows.Rect(Destination.X, Destination.Y, 1, 1)))
            {
                _destScene = _curScene; 
            }
            else
            {
                //Builds a new grid on the fly containing both the start and destination scenes. This is not really optimal, but its a trade off.
                // Keeping grids Scene based means they can be used cross game even when laid out different in a seperate world. This keeps memory usage down substantially.
                // Also limited to a max distance of scene > scene. Again this keeps memory usage low.
                _destScene = _curScene.World.QuadTree.Query<Scene>(new System.Windows.Rect(Destination.X, Destination.Y, 1, 1)).FirstOrDefault();
                mPathFinder = new PathFinderFast(BuildOutOfSceneGrid(_curScene, _destScene, ref _baseX, ref _baseY));
                InitPathFinder();
            }
            //2.5f is because Scene navmesh's are based on 96x96 for a 240x240 scene - Darklotus
            _startSceneLocal.X = (int)((Start.X - _baseX) / 2.5f);
            _startSceneLocal.Y = (int)((Start.Y - _baseY) / 2.5f);
            _destinationSceneLocal.X = (int)((Destination.X - _baseX) / 2.5f);
            _destinationSceneLocal.Y = (int)((Destination.Y - _baseY) / 2.5f);
            //Possibily add a check to ensure start/dest local coords are valid. Unneeded so far.
            
            nodePathList = mPathFinder.FindPath(_startSceneLocal, _destinationSceneLocal); // The actual pathfind request, the path is found here.
            
            vectorPathList.Clear(); // Clear the previous path.

            if (nodePathList == null) {
                //TODO: Sometimes Mobs are require to spawn outside current walkable boundaries, with the current implementation
                //Pathfinder is unable to return a valid path if the mob is outside this boundaries.
                //This is just a hackish way to force a path over the mob.
                Logger.Debug("Pathfinding forced hack activated due Mob outside walkable area");
                vectorPathList.Insert(0, new Vector3D(Destination.X,Destination.Y,Destination.Z));
                return vectorPathList; 
                
            }// No Path Found.
            if (nodePathList.Count < 1) { return vectorPathList; } // Safety net Incase start/dest are the same.
           
            for (int i = 0; i < nodePathList.Count; i++)
            {
                // Convert the path into world coordinates for use in Movement.
                // TODO Objectpool maybe?
                vectorPathList.Insert(0, new Vector3D(nodePathList[i].X * 2.5f + _baseX, nodePathList[i].Y * 2.5f + _baseY, 0));
            }
            //new System.Threading.Thread(c => System.Windows.Forms.Application.Run(new PatherDebug.PatherDebug(actor, vectorPathList))).Start();
            
           
            return vectorPathList;
        }
예제 #28
0
파일: Wizard.cs 프로젝트: n4v/mooege
        public override void OnChannelOpen()
        {
            EffectsPerSecond = ScriptFormula(18);

            _calcTargetPosition();
            _target = SpawnEffect(RuneSelect(52687, 52687, 93544, -1, 52687, 215723), TargetPosition, 0, WaitInfinite());
            User.AddComplexEffect(RuneSelect(18792, 18792, 93529, -1, 93593, 216368), _target);
        }
예제 #29
0
파일: Pathfinder.cs 프로젝트: vrobel/mooege
 public PathRequestTask(Pathfinder pathing, Actor actor, Vector3D Start, Vector3D Destination)
 {
     this._pathfinder = pathing;
     this._actor = actor;
     this._start = Start;
     this._destination = Destination;
     this.Path = new List<Vector3D>();
 }
예제 #30
0
파일: Wizard.cs 프로젝트: n4v/mooege
        public override void OnChannelOpen()
        {
            EffectsPerSecond = 0.2f;

            _targetProxy = SpawnEffect(RuneSelect(134595, 170443, 170285, 170830, 170590, 134595), TargetPosition, 0, WaitInfinite());
            _userProxy = SpawnProxy(User.Position, WaitInfinite());
            _userProxy.PlayEffectGroup(RuneSelect(134442, 170263, 170264, 170569, 170572, 164077), _targetProxy);
        }