Exemple #1
0
        public virtual bool AcceptEscorter(Mobile mobile)
        {
            EDI dest = GetDestination();

            if (dest == null || mobile == null)
            {
                return(false);
            }

            if (!mobile.Alive)
            {
                return(false);
            }

            BaseBoat m_Boat = BaseBoat.FindBoatAt(mobile.Location, mobile.Map);

            if (m_Boat != null)
            {
                if (m_Boat.Deleted || m_Boat.m_SinkTimer != null)
                {
                    mobile.SendMessage("Your boat is in no condition right now to be taking on passengers!");

                    return(false);
                }

                if (!(m_Boat.IsOwner(mobile) || m_Boat.IsCoOwner(mobile)))
                {
                    mobile.SendMessage("Only owners and co-owners of this ship have permission to take on passengers.");

                    return(false);
                }

                Say("Thank you! Let us return to " + dest.Name);

                if (Body.IsHuman && !Mounted)
                {
                    Animate(32, 3, 1, true, false, 0);
                }

                if (m_DeleteTimer != null)
                {
                    m_DeleteTimer.Stop();
                }

                m_DeleteTime = DateTime.UtcNow + TimeSpan.FromMinutes(120);

                m_DeleteTimer = new DeleteTimer(this, m_DeleteTime - DateTime.UtcNow);
                m_DeleteTimer.Start();

                Location = m_Boat.GetRandomEmbarkLocation(true);
                m_Boat.AddEmbarkedMobile(this);
            }

            return(true);
        }
Exemple #2
0
        public static void StartThrowShipBomb(BaseCreature creature, BaseBoat targetBoat)
        {
            Timer.DelayCall(TimeSpan.FromSeconds(.3), delegate { Effects.PlaySound(creature.Location, creature.Map, 0x666); });

            Point3D randomShipLocation = targetBoat.GetRandomEmbarkLocation(true);

            IEntity startLocation = new Entity(Serial.Zero, new Point3D(creature.Location.X, creature.Location.Y, creature.Location.Z + 10), creature.Map);
            IEntity endLocation   = new Entity(Serial.Zero, new Point3D(randomShipLocation.X, randomShipLocation.Y, randomShipLocation.Z + 5), targetBoat.Map);

            Effects.SendMovingEffect(startLocation, endLocation, 0x1C19, 10, 0, false, false, 0, 0);

            int distance = targetBoat.GetBoatToLocationDistance(targetBoat, creature.Location);

            double destinationDelay = (double)distance * .06;
            double explosionDelay   = (double)distance * .16;

            Timer.DelayCall(TimeSpan.FromSeconds(destinationDelay), delegate { Effects.SendLocationEffect(endLocation.Location, targetBoat.Map, 0x1C19, 20); });
            Timer.DelayCall(TimeSpan.FromSeconds(explosionDelay), delegate { DetonateShipBomb(creature, targetBoat, randomShipLocation); });
        }
Exemple #3
0
        public void OnTarget(Mobile from, Point3D point, bool IsNPCShip, bool canHitCenter, bool canHitHold, bool canHitTillerman)
        {
            if (m_Boat == null)
            {
                return;
            }

            Map      map        = from.Map;
            BaseBoat targetBoat = BaseBoat.FindBoatAt(point, map);

            //For Player Ships
            if (m_Boat.MobileControlType == MobileControlType.Player)
            {
                if (!from.Player)
                {
                    return;
                }

                else if (!from.Alive)
                {
                    from.SendMessage("You must be alive to use this.");
                    return;
                }

                else if (!m_Boat.Contains(from))
                {
                    from.SendMessage("You are no longer on the boat.");
                    return;
                }

                else if (targetBoat == m_Boat)
                {
                    from.SendMessage("You may not fire onto your own ship!");
                    return;
                }

                else if (Ammunition == 0)
                {
                    from.SendMessage("At least one of your cannons must be loaded to fire a volley.");
                    return;
                }

                else if (DateTime.UtcNow < m_Boat.CannonCooldown)
                {
                    from.SendMessage("You must wait before firing another cannon volley.");
                    return;
                }
            }

            bool volleyValid = false;
            bool tooClose    = false;

            double cannonDelayTotal = 0;
            int    cannonsFiring    = 0;

            //Need At Least One Cannon With LOS to Target and In Range of Target For Volley To Be Valid
            foreach (ShipCannon shipCannon in m_Boat.m_Cannons)
            {
                //Cannon Has Ammunition and is on Correct Ship Side for Volley
                if (shipCannon.Ammunition > 0 && shipCannon.Facing == Facing)
                {
                    cannonDelayTotal += BaseBoat.CannonCooldownTime;
                    cannonsFiring++;

                    double modifiedRange = (double)BaseBoat.CannonMaxRange * m_Boat.CannonRangeScalar;

                    //Already Deterined to Be Valid Shot: NPC AI Ship
                    if (IsNPCShip)
                    {
                        volleyValid = true;
                        break;
                    }

                    //Cannon is in LOS and Within Range
                    if (shipCannon.InAngle(point) && Utility.GetDistanceToSqrt(shipCannon.Location, point) <= modifiedRange)
                    {
                        volleyValid = true;
                    }

                    //Cannon is too close
                    if (Utility.GetDistanceToSqrt(shipCannon.Location, point) < 2)
                    {
                        tooClose = true;
                    }
                }
            }

            //At Least One Cannon Was Too Close to Fire
            if (tooClose)
            {
                volleyValid = false;
            }

            //Can Fire Cannon Volley
            if (volleyValid)
            {
                if (m_Boat.TillerMan != null)
                {
                    m_Boat.TillerMan.Say("Firing cannons!");
                }

                m_Boat.LastCombatTime = DateTime.UtcNow;

                //Ship Cooldown Time (Average of Delay for Each Cannon Type that is Firing)
                double cooldown = cannonDelayTotal / cannonsFiring;

                m_Boat.CannonCooldown = DateTime.UtcNow + TimeSpan.FromSeconds(cooldown);
                m_Boat.StartCannonCooldown();

                List <ShipCannon> cannonsToFire = new List <ShipCannon>();

                foreach (ShipCannon shipCannon in m_Boat.m_Cannons)
                {
                    if (shipCannon.Ammunition > 0 && shipCannon.Facing == Facing)
                    {
                        cannonsToFire.Add(shipCannon);
                    }
                }

                int firingLoops = BaseBoat.CannonFiringLoops;

                int cannonCount = cannonsToFire.Count;

                for (int a = 0; a < firingLoops; a++)
                {
                    for (int b = 0; b < cannonCount; b++)
                    {
                        bool showSmoke  = false;
                        bool lastCannon = false;

                        int        cannonIndex = Utility.RandomMinMax(0, cannonsToFire.Count - 1);
                        ShipCannon shipCannon  = cannonsToFire[cannonIndex];

                        if (a == 0)
                        {
                            showSmoke = true;
                        }

                        if (a == (firingLoops - 1))
                        {
                            shipCannon.Ammunition--;
                            cannonsToFire.RemoveAt(cannonIndex);

                            if (b == cannonCount - 1)
                            {
                                lastCannon = true;
                            }
                        }

                        //Check Accuracy
                        double cannonAccuracy = BaseBoat.CannonAccuracy * m_Boat.CannonAccuracyModifer;

                        double opponentMovementPenalty = 0;
                        double movementAccuracyPenalty = 0;

                        //Own Ship Movement Penalty
                        TimeSpan timeStationary    = DateTime.UtcNow - m_Boat.TimeLastMoved;
                        double   secondsStationary = (double)timeStationary.TotalSeconds;

                        if (secondsStationary > BaseBoat.CannonMovementAccuracyCooldown)
                        {
                            secondsStationary = BaseBoat.CannonMovementAccuracyCooldown;
                        }

                        if (targetBoat != null)
                        {
                            TimeSpan timeTargetStationary      = DateTime.UtcNow - targetBoat.TimeLastMoved;
                            double   secondsOpponentStationary = (double)timeStationary.TotalSeconds;

                            if (secondsOpponentStationary > BaseBoat.CannonMovementAccuracyCooldown)
                            {
                                secondsOpponentStationary = BaseBoat.CannonMovementAccuracyCooldown;
                            }

                            opponentMovementPenalty = 1 - (BaseBoat.CannonTargetMovementMaxAccuracyPenalty * (1 - (secondsOpponentStationary / BaseBoat.CannonMovementAccuracyCooldown)));

                            //No Movement Penalty to Shoot a Ship That is in Reduced Speed Mode
                            if (targetBoat.ReducedSpeedMode)
                            {
                                opponentMovementPenalty = 1;
                            }
                        }

                        movementAccuracyPenalty = 1 - (BaseBoat.CannonMovementMaxAccuracyPenalty * (1 - (secondsStationary / BaseBoat.CannonMovementAccuracyCooldown)));

                        double finalAccuracy = cannonAccuracy * movementAccuracyPenalty * opponentMovementPenalty;

                        double chance = Utility.RandomDouble();

                        bool hit = false;

                        //Hit Target
                        if (chance <= finalAccuracy)
                        {
                            hit = true;
                        }

                        Point3D cannonEndLocation = point;

                        if (IsNPCShip && targetBoat != null)
                        {
                            if (canHitCenter)
                            {
                                cannonEndLocation = targetBoat.GetRandomEmbarkLocation(true);
                            }

                            else if (canHitHold && canHitTillerman)
                            {
                                if (Utility.RandomDouble() < .5)
                                {
                                    cannonEndLocation = targetBoat.Hold.Location;
                                }

                                else
                                {
                                    cannonEndLocation = targetBoat.TillerMan.Location;
                                }
                            }

                            else if (canHitHold && !canHitTillerman)
                            {
                                cannonEndLocation = targetBoat.Hold.Location;
                            }

                            else if (!canHitHold && canHitTillerman)
                            {
                                cannonEndLocation = targetBoat.TillerMan.Location;
                            }
                        }

                        double delay = (BaseBoat.CannonLoopDelay * (a + 1) / (double)firingLoops) * b;

                        Timer.DelayCall(TimeSpan.FromSeconds(delay), delegate
                        {
                            FireCannon(shipCannon, from, cannonEndLocation, map, hit, showSmoke);
                        });
                    }
                }
            }

            else
            {
                if (tooClose)
                {
                    from.SendMessage("Your target is too close to the ship to be fired upon.");
                }

                else
                {
                    from.SendMessage("At least one of your cannons must be within range of and in line of sight of your target in order to fire a cannon volley.");
                }
            }
        }
Exemple #4
0
        public static void GenerateShipCrew(BaseBoat boat)
        {
            if (boat == null) return;
            if (boat.Deleted) return;

            int shipLevel = 1;

            if (boat is MediumBoat || boat is MediumDragonBoat) shipLevel = 2;
            if (boat is LargeBoat || boat is LargeDragonBoat) shipLevel = 3;
            if (boat is CarrackBoat) shipLevel = 4;
            if (boat is GalleonBoat) shipLevel = 5;

            BaseCreature bc_Creature;
            Point3D creatureLocation;

            int crewNumber = 0;
            int ratChances = 0;

            Dictionary<Type, int> DictCrewOptions = new Dictionary<Type, int>();

            switch (boat.MobileFactionType)
            {
                case MobileFactionType.Fishing:
                    #region Fishing
                    crewNumber = 3 + shipLevel;

                    for (int a = 0; a < crewNumber; a++)
                    {
                        creatureLocation = boat.GetRandomEmbarkLocation(true);

                        bc_Creature = new Custom.Pirates.OceanFisherman();
                        bc_Creature.BardImmune = true;
                        bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                        boat.Crew.Add(bc_Creature);
                        boat.AddEmbarkedMobile(bc_Creature);
                    }
                    #endregion
                break;

                case MobileFactionType.Pirate:
                    #region Pirate
                    crewNumber = 3 + shipLevel;
                    
                    for (int a = 0; a < crewNumber; a++)
                    {
                        creatureLocation = boat.GetRandomEmbarkLocation(true);

                        bc_Creature = new Custom.Pirates.OceanPirate();
                        bc_Creature.BardImmune = true;
                        bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                        boat.Crew.Add(bc_Creature);
                        boat.AddEmbarkedMobile(bc_Creature);
                    }

                    if (Utility.RandomDouble() <= (.2 * shipLevel) )
                    {
                        creatureLocation = boat.GetRandomEmbarkLocation(true);

                        bc_Creature = new Custom.Pirates.PirateShipCarpenter();
                        bc_Creature.BardImmune = true;
                        bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                        boat.Crew.Add(bc_Creature);
                        boat.AddEmbarkedMobile(bc_Creature);
                    }

                    if (Utility.RandomDouble() <= (.2 * shipLevel))
                    {
                        creatureLocation = boat.GetRandomEmbarkLocation(true);

                        bc_Creature = new Custom.Pirates.PirateSawbones();
                        bc_Creature.BardImmune = true;
                        bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                        boat.Crew.Add(bc_Creature);
                        boat.AddEmbarkedMobile(bc_Creature);
                    }

                    creatureLocation = boat.GetRandomEmbarkLocation(true);

                    bc_Creature = new Custom.Pirates.OceanPirateCaptain(boat);
                    bc_Creature.BardImmune = true;
                    bc_Creature.MoveToWorld(creatureLocation, boat.Map);  

                    boat.Crew.Add(bc_Creature);
                    boat.Owner = bc_Creature;
                    boat.AddEmbarkedMobile(bc_Creature);
                    
                    #endregion
                break;

                case MobileFactionType.Britain:
                    #region Britain
                    DictCrewOptions = new Dictionary<Type, int>();

                    DictCrewOptions.Add(typeof(Custom.Pirates.BritainSailor), 2);
                    DictCrewOptions.Add(typeof(Custom.Pirates.BritainMarine), 1);

                    crewNumber = 3 + shipLevel;

                    for (int a = 0; a < crewNumber; a++)
                    {
                        int TotalValues = 0;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            TotalValues += pair.Value;
                        }

                        double ActionCheck = Utility.RandomDouble();
                        double CumulativeAmount = 0.0;
                        double AdditionalAmount = 0.0;

                        bool foundDirection = true;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            AdditionalAmount = (double)pair.Value / (double)TotalValues;

                            if (ActionCheck >= CumulativeAmount && ActionCheck < (CumulativeAmount + AdditionalAmount))
                            {
                                bc_Creature = (BaseCreature)Activator.CreateInstance(pair.Key);

                                if (bc_Creature == null)
                                    continue;

                                creatureLocation = boat.GetRandomEmbarkLocation(true);

                                bc_Creature.BardImmune = true;
                                bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                                boat.Crew.Add(bc_Creature);
                                boat.AddEmbarkedMobile(bc_Creature);

                                break;
                            }

                            CumulativeAmount += AdditionalAmount;
                        }
                    }      
             
                    if (Utility.RandomDouble() <= (.2 * shipLevel ) )
                    {
                        creatureLocation = boat.GetRandomEmbarkLocation(true);

                        bc_Creature = new Custom.Pirates.BritainShipCarpenter();                        
                        bc_Creature.BardImmune = true;
                        bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                        boat.Crew.Add(bc_Creature);
                        boat.AddEmbarkedMobile(bc_Creature);

                    }

                    if (Utility.RandomDouble() <= (.2 * shipLevel))
                    {
                        creatureLocation = boat.GetRandomEmbarkLocation(true);

                        bc_Creature = new Custom.Pirates.BritainShipSurgeon();
                        bc_Creature.BardImmune = true;
                        bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                        boat.Crew.Add(bc_Creature);
                        boat.AddEmbarkedMobile(bc_Creature);

                    }

                    creatureLocation = boat.GetRandomEmbarkLocation(true);

                    bc_Creature = new Custom.Pirates.BritainShipCaptain(boat);
                    bc_Creature.BardImmune = true;
                    bc_Creature.MoveToWorld(creatureLocation, boat.Map); 

                    boat.Crew.Add(bc_Creature);
                    boat.Owner = bc_Creature;
                    boat.AddEmbarkedMobile(bc_Creature);
                    #endregion
                break;                

                case MobileFactionType.Orc:
                    #region Orc
                    
                    crewNumber = 3 + shipLevel;

                    DictCrewOptions = new Dictionary<Type, int>();

                    DictCrewOptions.Add(typeof(OrcishGrunt), 1);
                    DictCrewOptions.Add(typeof(OrcishScout), 1);
                    DictCrewOptions.Add(typeof(OrcMojoka), 1);

                    for (int a = 0; a < crewNumber; a++)
                    {
                        int TotalValues = 0;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            TotalValues += pair.Value;
                        }

                        double ActionCheck = Utility.RandomDouble();
                        double CumulativeAmount = 0.0;
                        double AdditionalAmount = 0.0;

                        bool foundDirection = true;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            AdditionalAmount = (double)pair.Value / (double)TotalValues;

                            if (ActionCheck >= CumulativeAmount && ActionCheck < (CumulativeAmount + AdditionalAmount))
                            {
                                bc_Creature = (BaseCreature)Activator.CreateInstance(pair.Key);

                                if (bc_Creature == null)
                                    continue;

                                if (bc_Creature is OrcishGrunt)                                                                    
                                    bc_Creature.PackItem(new Bow() { Movable = false, Hue = 0 });

                                creatureLocation = boat.GetRandomEmbarkLocation(true);

                                bc_Creature.BardImmune = true;
                                bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                                boat.Crew.Add(bc_Creature);
                                boat.AddEmbarkedMobile(bc_Creature);


                                break;
                            }

                            CumulativeAmount += AdditionalAmount;
                        }
                    }

                    crewNumber = (int)(Math.Ceiling((double)shipLevel / 2));

                    DictCrewOptions = new Dictionary<Type, int>();

                    DictCrewOptions.Add(typeof(OrcishExecutioner), 1);
                    DictCrewOptions.Add(typeof(OrcishSurjin), 1);
                    DictCrewOptions.Add(typeof(OrcishMaurk), 1);
                    DictCrewOptions.Add(typeof(ElderMojoka), 1);  

                    for (int a = 0; a < crewNumber; a++)
                    {
                        int TotalValues = 0;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            TotalValues += pair.Value;
                        }

                        double ActionCheck = Utility.RandomDouble();
                        double CumulativeAmount = 0.0;
                        double AdditionalAmount = 0.0;

                        bool foundDirection = true;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            AdditionalAmount = (double)pair.Value / (double)TotalValues;

                            if (ActionCheck >= CumulativeAmount && ActionCheck < (CumulativeAmount + AdditionalAmount))
                            {
                                bc_Creature = (BaseCreature)Activator.CreateInstance(pair.Key);

                                if (bc_Creature == null)
                                    continue;

                                if (bc_Creature is OrcishExecutioner || bc_Creature is OrcishSurjin)
                                    bc_Creature.PackItem(new Bow() { Movable = false, Hue = 0 });                                

                                creatureLocation = boat.GetRandomEmbarkLocation(true);

                                bc_Creature.BardImmune = true;
                                bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                                boat.Crew.Add(bc_Creature);
                                boat.AddEmbarkedMobile(bc_Creature);

                                break;
                            }

                            CumulativeAmount += AdditionalAmount;
                        }
                    }

                    #endregion
                break;

                case MobileFactionType.Orghereim:
                    #region Orghereim
                    crewNumber = 3 + shipLevel;

                    DictCrewOptions = new Dictionary<Type, int>();

                    DictCrewOptions.Add(typeof(OrghereimBowMaiden), 1);
                    DictCrewOptions.Add(typeof(OrghereimTracker), 1);
                    DictCrewOptions.Add(typeof(OrghereimSwordThane), 1);
                    DictCrewOptions.Add(typeof(OrghereimIceCarl), 1); 
                    DictCrewOptions.Add(typeof(OrghereimShieldMaiden), 1);

                    for (int a = 0; a < crewNumber; a++)
                    {
                        int TotalValues = 0;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            TotalValues += pair.Value;
                        }

                        double ActionCheck = Utility.RandomDouble();
                        double CumulativeAmount = 0.0;
                        double AdditionalAmount = 0.0;

                        bool foundDirection = true;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            AdditionalAmount = (double)pair.Value / (double)TotalValues;

                            if (ActionCheck >= CumulativeAmount && ActionCheck < (CumulativeAmount + AdditionalAmount))
                            {
                                bc_Creature = (BaseCreature)Activator.CreateInstance(pair.Key);

                                if (bc_Creature == null)
                                    continue;

                                if (bc_Creature is OrghereimSwordThane || bc_Creature is OrghereimShieldMaiden)
                                    bc_Creature.PackItem(new Bow() { Movable = false, Hue = 0 });                                

                                creatureLocation = boat.GetRandomEmbarkLocation(true);

                                bc_Creature.BardImmune = true;
                                bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                                boat.Crew.Add(bc_Creature);
                                boat.AddEmbarkedMobile(bc_Creature);

                                break;
                            }

                            CumulativeAmount += AdditionalAmount;
                        }
                    }

                    crewNumber = (int)(Math.Ceiling((double)shipLevel / 2));

                    DictCrewOptions = new Dictionary<Type, int>();

                    DictCrewOptions.Add(typeof(OrghereimBoneMender), 1);
                    DictCrewOptions.Add(typeof(OrghereimCrone), 1);
                    DictCrewOptions.Add(typeof(OrghereimSage), 1);
                    DictCrewOptions.Add(typeof(OrghereimShieldMother), 1); 

                    for (int a = 0; a < crewNumber; a++)
                    {
                        int TotalValues = 0;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            TotalValues += pair.Value;
                        }

                        double ActionCheck = Utility.RandomDouble();
                        double CumulativeAmount = 0.0;
                        double AdditionalAmount = 0.0;

                        bool foundDirection = true;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            AdditionalAmount = (double)pair.Value / (double)TotalValues;

                            if (ActionCheck >= CumulativeAmount && ActionCheck < (CumulativeAmount + AdditionalAmount))
                            {
                                bc_Creature = (BaseCreature)Activator.CreateInstance(pair.Key);

                                if (bc_Creature == null)
                                    continue;

                                if (bc_Creature is OrghereimShieldMother)
                                    bc_Creature.PackItem(new Bow() { Movable = false, Hue = 0 });                                

                                creatureLocation = boat.GetRandomEmbarkLocation(true);

                                bc_Creature.BardImmune = true;
                                bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                                boat.Crew.Add(bc_Creature);
                                boat.AddEmbarkedMobile(bc_Creature);

                                break;
                            }

                            CumulativeAmount += AdditionalAmount;
                        }
                    }
                    #endregion
                break;

                case MobileFactionType.Undead:
                    #region Undead
                    crewNumber = 3 + shipLevel;
                    
                    for (int a = 0; a < crewNumber; a++)
                    {
                        creatureLocation = boat.GetRandomEmbarkLocation(true);

                        bc_Creature = new Custom.Pirates.SkeletalCrewman();
                        bc_Creature.BardImmune = true;
                        bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                        boat.Crew.Add(bc_Creature);
                        boat.AddEmbarkedMobile(bc_Creature);
                    }

                    crewNumber = 3 + shipLevel;

                    DictCrewOptions = new Dictionary<Type, int>();

                    DictCrewOptions.Add(typeof(Skeleton), 15);
                    DictCrewOptions.Add(typeof(ZombieMagi), 5);
                    DictCrewOptions.Add(typeof(SkeletalMage), 5);
                    DictCrewOptions.Add(typeof(Lich), 3);                 
                    DictCrewOptions.Add(typeof(SkeletalDrake), 2);
                    DictCrewOptions.Add(typeof(LichLord), 1);

                    for (int a = 0; a < crewNumber; a++)
                    {
                        int TotalValues = 0;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            TotalValues += pair.Value;
                        }

                        double ActionCheck = Utility.RandomDouble();
                        double CumulativeAmount = 0.0;
                        double AdditionalAmount = 0.0;

                        bool foundDirection = true;

                        foreach (KeyValuePair<Type, int> pair in DictCrewOptions)
                        {
                            AdditionalAmount = (double)pair.Value / (double)TotalValues;

                            if (ActionCheck >= CumulativeAmount && ActionCheck < (CumulativeAmount + AdditionalAmount))
                            {
                                bc_Creature = (BaseCreature)Activator.CreateInstance(pair.Key);

                                if (bc_Creature == null)
                                    continue;

                                creatureLocation = boat.GetRandomEmbarkLocation(true);

                                bc_Creature.BardImmune = true;
                                bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                                boat.Crew.Add(bc_Creature);
                                boat.AddEmbarkedMobile(bc_Creature);

                                break;
                            }

                            CumulativeAmount += AdditionalAmount;
                        }
                    }

                    int necromancers = (int)(Math.Ceiling((double)shipLevel / 2));
                    for (int a = 0; a < necromancers; a++)
                    {
                        creatureLocation = boat.GetRandomEmbarkLocation(true);

                        bc_Creature = new Custom.Pirates.GhostShipNecromancer();
                        bc_Creature.BardImmune = true;
                        bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                        boat.Crew.Add(bc_Creature);
                        boat.AddEmbarkedMobile(bc_Creature);
                    }

                    creatureLocation = boat.GetRandomEmbarkLocation(true);

                    bc_Creature = new Custom.Pirates.SkeletalCaptain(boat);
                    bc_Creature.BardImmune = true;
                    bc_Creature.MoveToWorld(creatureLocation, boat.Map);

                    boat.Crew.Add(bc_Creature);
                    boat.Owner = bc_Creature;
                    boat.AddEmbarkedMobile(bc_Creature);

                    #endregion
                break;
            }
        }