示例#1
0
        public PyDataType DestroyFitting(PyInteger itemID, CallInformation call)
        {
            ItemEntity item = this.mInventory.Items[itemID];

            if (item.IsInRigSlot() == false)
            {
                throw new CannotDestroyFittedItem();
            }

            if (item is ShipModule module)
            {
                // disable passive effects
                module.StopApplyingPassiveEffects(Client);
            }

            int   oldLocationID = item.LocationID;
            Flags oldFlag       = item.Flag;

            // destroy the rig
            this.ItemFactory.DestroyItem(item);

            // notify the client about the change
            call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(item, oldFlag, oldLocationID));

            return(null);
        }
示例#2
0
 private void InvokeChanged(OptionsItemChangedEventArgs <TKey, TOptionsItem> args)
 {
     if (OnItemChange != null)
     {
         OnItemChange?.Invoke(args);
     }
 }
示例#3
0
        /// <summary>
        /// Removes an expired sell order from the database and returns the leftover items back to the player's hangar
        /// </summary>
        /// <param name="connection">The database connection that acquired the lock</param>
        /// <param name="order">The order to mark as expired</param>
        private void SellOrderExpired(MySqlConnection connection, MarketOrder order)
        {
            // remove order
            this.DB.RemoveOrder(connection, order.OrderID);
            // create the item back into the player's hanger

            // create the new item that will be used by the player
            ItemEntity item = this.ItemFactory.CreateSimpleItem(
                this.TypeManager[order.TypeID], order.CharacterID, order.LocationID, Flags.Hangar, order.UnitsLeft
                );

            // immediately unload it, if it has to be loaded the OnItemUpdate notification will take care of that
            this.ItemFactory.UnloadItem(item);

            long stationNode = this.SystemManager.GetNodeStationBelongsTo(order.LocationID);

            if (stationNode == 0 || this.SystemManager.StationBelongsToUs(order.LocationID) == true)
            {
                this.NotificationManager.NotifyCharacter(order.CharacterID, Notifications.Client.Inventory.OnItemChange.BuildLocationChange(item, this.ItemFactory.LocationMarket.ID));
            }
            else
            {
                this.NotificationManager.NotifyNode(stationNode, OnItemChange.BuildLocationChange(item.ID, this.ItemFactory.LocationMarket.ID, order.LocationID));
            }

            // finally notify the character about the order change
            this.NotificationManager.NotifyCharacter(order.CharacterID, new OnOwnOrderChanged(order.TypeID, "Expiry"));
            // TODO: SEND AN EVEMAIL TO THE PLAYER?
        }
示例#4
0
    public void AddItem(Item item)
    {
        if (item.Stackable())
        {
            bool isInInv = false;
            // Increment the item's quantity if its already in the inventory
            foreach (Item inventoryItem in itemList)
            {
                if (inventoryItem.itemType == item.itemType)
                {
                    inventoryItem.quantity += item.quantity;
                    isInInv = true;
                }
            }
            // If the item is not in the inventory, then add it
            if (!isInInv)
            {
                itemList.Add(item);
            }
        }
        else
        {
            itemList.Add(item);
        }

        // When the player picks up an item, it will trigger the EventHandler
        // which invokes its method in the InvUI.cs to force a re-draw of the inventory with the update
        OnItemChange?.Invoke(this, EventArgs.Empty);
    }
示例#5
0
        private void Reprocess(Character character, ItemEntity item, Client client)
        {
            if (item.Quantity < item.Type.PortionSize)
            {
                throw new QuantityLessThanMinimumPortion(item.Type);
            }

            int leftovers         = item.Quantity % item.Type.PortionSize;
            int quantityToProcess = item.Quantity - leftovers;

            List <ReprocessingDB.Recoverables> recoverablesList = this.ReprocessingDB.GetRecoverables(item.Type.ID);

            foreach (ReprocessingDB.Recoverables recoverable in recoverablesList)
            {
                int ratio = recoverable.AmountPerBatch * quantityToProcess / item.Type.PortionSize;

                double efficiency = this.CalculateEfficiency(character, recoverable.TypeID);

                int quantityForClient = (int)(efficiency * (1.0 - this.mCorporation.TaxRate) * ratio);

                // create the new item
                ItemEntity newItem = this.ItemFactory.CreateSimpleItem(this.TypeManager[recoverable.TypeID], character, this.mStation,
                                                                       Flags.Hangar, quantityForClient);
                // notify the client about the new item
                client.NotifyMultiEvent(OnItemChange.BuildNewItemChange(newItem));
            }
        }
示例#6
0
文件: ship.cs 项目: lanicon/EVESharp
        public PyInteger LeaveShip(CallInformation call)
        {
            int callerCharacterID = call.Client.EnsureCharacterIsSelected();

            Character character = this.ItemFactory.GetItem <Character>(callerCharacterID);
            // get the item type
            Type capsuleType = this.TypeManager[Types.Capsule];
            // create a pod for this character
            ItemInventory capsule = this.ItemFactory.CreateShip(capsuleType, this.Location, character);

            // update capsule's name
            capsule.Name = character.Name + "'s Capsule";
            // change character's location to the pod
            character.LocationID = capsule.ID;
            // notify the client about the item changes
            call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(capsule, Flags.Capsule, capsule.LocationID));
            call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(character, Flags.Pilot, call.Client.ShipID));
            // update session
            call.Client.ShipID = capsule.ID;

            // persist changes!
            capsule.Persist();
            character.Persist();

            // TODO: CHECKS FOR IN-SPACE LEAVING!

            return(capsule.ID);
        }
示例#7
0
        public PyDataType CharAddImplant(PyInteger itemID, CallInformation call)
        {
            if (this.Character.SkillQueue.Count > 0)
            {
                throw new FailedPlugInImplant();
            }

            // get the item and plug it into our brain now!
            ItemEntity item = this.ItemFactory.LoadItem(itemID);

            // ensure the item is somewhere we can interact with it
            if (item.LocationID != call.Client.ShipID && item.LocationID != call.Client.StationID)
            {
                throw new CustomError("You do not have direct access to this implant");
            }

            // check if the slot is free or not
            this.Character.EnsureFreeImplantSlot(item);

            // check ownership and skills required to plug in the implant
            item.EnsureOwnership(this.Character);
            item.CheckPrerequisites(this.Character);

            // separate the item if there's more than one
            if (item.Quantity > 1)
            {
                item.Quantity--;

                // notify the client of the stack change
                call.Client.NotifyMultiEvent(OnItemChange.BuildQuantityChange(item, item.Quantity + 1));

                // save the item to the database
                item.Persist();

                // create the new item with a default location and flag
                // this way the item location change notification is only needed once
                item = this.ItemFactory.CreateSimpleItem(item.Type, item.OwnerID, 0,
                                                         Flags.None, 1, item.Contraband, item.Singleton);
            }

            int   oldLocationID = item.LocationID;
            Flags oldFlag       = item.Flag;

            item.LocationID = this.Character.ID;
            item.Flag       = Flags.Implant;

            call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(item, oldFlag, oldLocationID));

            // add the item to the inventory it belongs
            this.Character.AddItem(item);

            // persist item changes to database
            item.Persist();

            return(null);
        }
示例#8
0
    /// <summary>
    /// 设置代理
    /// </summary>
    /// <param name="_onItemChange"></param>
    /// <param name="_onClickItem"></param>
    public void SetDelegate(OnItemChange _onItemChange,
                            OnClickItem _onClickItem)
    {
        m_pItemChangeCallBack = _onItemChange;

        if (_onClickItem != null)
        {
            m_pOnClickItemCallBack = _onClickItem;
        }
    }
示例#9
0
        public PyDataType MultiMerge(PyList merges, CallInformation call)
        {
            foreach (PyTuple merge in merges.GetEnumerable <PyTuple>())
            {
                if (merge[0] is PyInteger == false || merge[1] is PyInteger == false || merge[2] is PyInteger == false)
                {
                    continue;
                }

                PyInteger fromItemID = merge[0] as PyInteger;
                PyInteger toItemID   = merge[1] as PyInteger;
                PyInteger quantity   = merge[2] as PyInteger;

                if (this.mInventory.Items.TryGetValue(toItemID, out ItemEntity toItem) == false)
                {
                    continue;
                }

                ItemEntity fromItem = this.ItemFactory.GetItem(fromItemID);

                // ignore singleton items
                if (fromItem.Singleton == true || toItem.Singleton == true)
                {
                    continue;
                }
                // ignore items that are not the same type
                if (fromItem.Type.ID != toItem.Type.ID)
                {
                    continue;
                }
                // if we're fully merging two stacks, just remove one item
                if (quantity == fromItem.Quantity)
                {
                    int oldLocationID = fromItem.LocationID;
                    // remove the item
                    this.ItemFactory.DestroyItem(fromItem);
                    // notify the client about the item too
                    call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(fromItem, oldLocationID));
                }
                else
                {
                    // change the item's quantity
                    fromItem.Quantity -= quantity;
                    // notify the client about the change
                    call.Client.NotifyMultiEvent(OnItemChange.BuildQuantityChange(fromItem, fromItem.Quantity + quantity));
                    fromItem.Persist();
                }

                toItem.Quantity += quantity;
                call.Client.NotifyMultiEvent(OnItemChange.BuildQuantityChange(toItem, toItem.Quantity - quantity));
                toItem.Persist();
            }

            return(null);
        }
示例#10
0
文件: ship.cs 项目: lanicon/EVESharp
        public PyDataType AssembleShip(PyInteger itemID, CallInformation call)
        {
            int callerCharacterID = call.Client.EnsureCharacterIsSelected();
            int stationID         = call.Client.EnsureCharacterIsInStation();

            // ensure the item is loaded somewhere in this node
            // this will usually be taken care by the EVE Client
            if (this.ItemFactory.TryGetItem(itemID, out Ship ship) == false)
            {
                throw new CustomError("Ships not loaded for player and hangar!");
            }

            Character character = this.ItemFactory.GetItem <Character>(callerCharacterID);

            if (ship.OwnerID != callerCharacterID)
            {
                throw new AssembleOwnShipsOnly(ship.OwnerID);
            }

            // do not do anything if item is already assembled
            if (ship.Singleton == true)
            {
                return(new ShipAlreadyAssembled(ship.Type));
            }

            // first split the stack
            if (ship.Quantity > 1)
            {
                // subtract one off the stack
                ship.Quantity -= 1;
                ship.Persist();
                // notify the quantity change
                call.Client.NotifyMultiEvent(OnItemChange.BuildQuantityChange(ship, ship.Quantity + 1));

                // create the new item in the database
                Station station = this.ItemFactory.GetStaticStation(stationID);
                ship = this.ItemFactory.CreateShip(ship.Type, station, character);
                // notify the new item
                call.Client.NotifyMultiEvent(OnItemChange.BuildNewItemChange(ship));
            }
            else
            {
                // stack of one, simple as changing the singleton flag
                ship.Singleton = true;
                call.Client.NotifyMultiEvent(OnItemChange.BuildSingletonChange(ship, false));
            }

            // save the ship
            ship.Persist();

            return(null);
        }
示例#11
0
        private void PrepareItemsForCourierOrAuctionContract(MySqlConnection connection, ulong contractID,
                                                             ClusterConnection clusterConnection, PyList <PyList> itemList, Station station, int ownerID, int shipID)
        {
            // create the container in the system to ensure it's not visible to the player
            Container container = this.ItemFactory.CreateSimpleItem(this.TypeManager[Types.PlasticWrap],
                                                                    this.ItemFactory.LocationSystem.ID, station.ID, Flags.None) as Container;

            Dictionary <int, ContractDB.ItemQuantityEntry> items =
                this.DB.PrepareItemsForContract(connection, contractID, itemList, station, ownerID, container.ID, shipID);

            double volume = 0;

            // build notification for item changes
            OnItemChange changes            = new OnItemChange();
            long         stationNode        = this.SystemManager.GetNodeStationBelongsTo(station.ID);
            bool         stationBelongsToUs = this.SystemManager.StationBelongsToUs(station.ID);

            // notify the changes in the items to the nodes
            foreach ((int _, ContractDB.ItemQuantityEntry item) in items)
            {
                if (stationNode == 0 || stationBelongsToUs == true)
                {
                    ItemEntity entity = this.ItemFactory.LoadItem(item.ItemID);

                    entity.LocationID = container.ID;
                    entity.Persist();

                    // notify the character
                    this.NotificationManager.NotifyCharacter(ownerID, Notifications.Client.Inventory.OnItemChange.BuildLocationChange(entity, station.ID));
                }
                else
                {
                    // queue the notification
                    changes.AddChange(item.ItemID, "locationID", station.ID, container.ID);
                }

                // ensure the volume is taken into account
                volume += item.Volume;
            }

            // notify the proper node if needed
            if (changes.Updates.Count > 0)
            {
                this.NotificationManager.NotifyNode(stationNode, changes);
            }

            // update the contract with the crate and the new volume
            this.DB.UpdateContractCrateAndVolume(ref connection, contractID, container.ID, volume);
        }
示例#12
0
        public PyDataType RemoveImplantFromCharacter(PyInteger itemID, CallInformation call)
        {
            if (this.Character.Items.TryGetValue(itemID, out ItemEntity item) == false)
            {
                throw new CustomError("This implant is not in your brain!");
            }

            // now destroy the item
            this.ItemFactory.DestroyItem(item);

            // notify the change
            call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(item, this.Character.ID));

            return(null);
        }
示例#13
0
文件: ship.cs 项目: lanicon/EVESharp
        public PyDataType Board(PyInteger itemID, CallInformation call)
        {
            int callerCharacterID = call.Client.EnsureCharacterIsSelected();

            // ensure the item is loaded somewhere in this node
            // this will usually be taken care by the EVE Client
            if (this.ItemFactory.TryGetItem(itemID, out Ship newShip) == false)
            {
                throw new CustomError("Ships not loaded for player and hangar!");
            }

            Character character   = this.ItemFactory.GetItem <Character>(callerCharacterID);
            Ship      currentShip = this.ItemFactory.GetItem <Ship>((int)call.Client.ShipID);

            if (newShip.Singleton == false)
            {
                throw new CustomError("TooFewSubSystemsToUndock");
            }

            // TODO: CHECKS FOR IN-SPACE BOARDING!

            // check skills required to board the given ship
            newShip.EnsureOwnership(character);
            newShip.CheckPrerequisites(character);

            // move the character into this new ship
            character.LocationID = newShip.ID;
            // finally update the session
            call.Client.ShipID = newShip.ID;
            // notify the client about the change in location
            call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(character, Flags.Pilot, currentShip.ID));

            character.Persist();

            // ensure the character is not removed when the capsule is removed
            currentShip.RemoveItem(character);

            if (currentShip.Type.ID == (int)Types.Capsule)
            {
                // destroy the pod from the database
                this.ItemFactory.DestroyItem(currentShip);
                // notify the player of the item change
                call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(currentShip, this.Location.ID));
            }

            return(null);
        }
示例#14
0
        private void OnSkillTrainingCompleted(int itemID)
        {
            Skill skill = this.Character.Items[itemID] as Skill;

            // set the skill to the proper flag and set the correct attributes
            skill.Flag       = Flags.Skill;
            skill.Level      = skill.Level + 1;
            skill.ExpiryTime = 0;

            // make sure the client is aware of the new item's status
            this.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(skill, Flags.SkillInTraining));
            // also notify attribute changes
            this.Client.NotifyAttributeChange(new Attributes[] { Attributes.skillPoints, Attributes.skillLevel }, skill);
            this.Client.NotifyMultiEvent(new OnSkillTrained(skill));
            this.Client.SendPendingNotifications();

            skill.Persist();

            // create history entry
            this.DB.CreateSkillHistoryRecord(skill.Type, this.Character, SkillHistoryReason.SkillTrainingComplete, skill.Points);

            // finally remove it off the skill queue
            this.Character.SkillQueue.RemoveAll(x => x.Skill.ID == skill.ID && x.TargetLevel == skill.Level);

            this.Character.CalculateSkillPoints();

            // get the next skill from the queue (if any) and send the client proper notifications
            if (this.Character.SkillQueue.Count == 0)
            {
                this.Character.Persist();
                return;
            }

            skill = this.Character.SkillQueue[0].Skill;

            // setup the process for training next skill in the queue
            this.SetupTimerForNextSkillInQueue();
            this.Client.SendPendingNotifications();

            // create history entry
            this.DB.CreateSkillHistoryRecord(skill.Type, this.Character, SkillHistoryReason.SkillTrainingStarted, skill.Points);

            // persist the character changes
            this.Character.Persist();
        }
示例#15
0
        void MouseDown(UIMouseEvent evt, UIElement listeningElement)
        {
            Player player = Main.LocalPlayer;


            if (player.itemAnimation == 0 && player.itemTime == 0 && !IsLocked() && CanPutIntoSlot(Main.mouseItem))
            {
                Item tempItem = Main.mouseItem.Clone();
                Main.mouseItem = item.Clone();
                if (!Main.mouseItem.IsAir)
                {
                    Main.playerInventory = true;
                }
                item = tempItem;
                Main.PlaySound(SoundID.Grab, Main.LocalPlayer.position);
                OnItemChange?.Invoke(Main.mouseItem, item);
            }
        }
示例#16
0
        private void InitializeCharacter()
        {
            // perform basic checks on the skill queue

            // iterate the skill queue and generate a timer for the first skill that must be trained
            // this also prepares the correct notification for multiple skill training done
            PyList <PyInteger> skillTypeIDs           = new PyList <PyInteger>();
            List <Character.SkillQueueEntry> toRemove = new List <Character.SkillQueueEntry>();

            foreach (Character.SkillQueueEntry entry in this.Character.SkillQueue)
            {
                if (entry.Skill.ExpiryTime < DateTime.Now.ToFileTimeUtc())
                {
                    // ensure the skill is marked as trained and that they have the correct values stored
                    entry.Skill.Level      = entry.TargetLevel;
                    entry.Skill.Flag       = Flags.Skill;
                    entry.Skill.ExpiryTime = 0;

                    // add the skill to the list of trained skills for the big notification
                    skillTypeIDs.Add(entry.Skill.Type.ID);
                    toRemove.Add(entry);

                    // update it's location in the client if needed
                    this.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(entry.Skill, Flags.SkillInTraining));
                    // also notify attribute changes
                    this.Client.NotifyAttributeChange(new Attributes[] { Attributes.skillPoints, Attributes.skillLevel }, entry.Skill);
                }
            }

            // remove skills that already expired
            this.Character.SkillQueue.RemoveAll(x => toRemove.Contains(x));

            // send notification of multiple skills being finished training (if any)
            if (skillTypeIDs.Count > 0)
            {
                this.Client.NotifyMultiEvent(new OnGodmaMultipleSkillsTrained(skillTypeIDs));
            }

            // persists the skill queue
            this.Character.Persist();

            // setup the process for training next skill in the queue
            this.SetupTimerForNextSkillInQueue();
        }
示例#17
0
        private void StackAll(Flags locationFlag, CallInformation call)
        {
            // TODO: ADD CONSTRAINTS CHECKS FOR THE LOCATIONFLAG
            foreach ((int firstItemID, ItemEntity firstItem) in this.mInventory.Items)
            {
                // singleton items are not even checked
                if (firstItem.Singleton == true || firstItem.Flag != locationFlag)
                {
                    continue;
                }

                foreach ((int secondItemID, ItemEntity secondItem) in this.mInventory.Items)
                {
                    // ignore the same itemID as they cannot really be merged
                    if (firstItemID == secondItemID)
                    {
                        continue;
                    }
                    // ignore the item if it's singleton
                    if (secondItem.Singleton == true || secondItem.Flag != locationFlag)
                    {
                        continue;
                    }
                    // ignore the item check if they're not the same type ID
                    if (firstItem.Type.ID != secondItem.Type.ID)
                    {
                        continue;
                    }
                    int oldQuantity = secondItem.Quantity;
                    // add the quantity of the first item to the second
                    secondItem.Quantity += firstItem.Quantity;
                    // also create the notification for the user
                    call.Client.NotifyMultiEvent(OnItemChange.BuildQuantityChange(secondItem, oldQuantity));
                    this.ItemFactory.DestroyItem(firstItem);
                    // notify the client about the item too
                    call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(firstItem, firstItem.Flag, secondItem.LocationID));
                    // ensure the second item is saved to database too
                    secondItem.Persist();
                    // finally break this loop as the merge was already done
                    break;
                }
            }
        }
示例#18
0
        public PyDataType Reprocess(PyList itemIDs, PyInteger ownerID, PyInteger flag, PyBool unknown, PyList skipChecks, CallInformation call)
        {
            Character character = this.ItemFactory.GetItem <Character>(call.Client.EnsureCharacterIsSelected());

            // TODO: TAKE INTO ACCOUNT OWNERID AND FLAG, THESE MOST LIKELY WILL BE USED BY CORP STUFF
            foreach (PyInteger itemID in itemIDs.GetEnumerable <PyInteger>())
            {
                if (this.mInventory.Items.TryGetValue(itemID, out ItemEntity item) == false)
                {
                    throw new MktNotOwner();
                }

                // reprocess the item
                this.Reprocess(character, item, call.Client);
                int oldLocationID = item.LocationID;
                // finally remove the item from the inventories
                this.ItemFactory.DestroyItem(item);
                // notify the client about the item being destroyed
                call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(item, oldLocationID));
            }

            return(null);
        }
示例#19
0
        private void CreateCmd(string[] argv, CallInformation call)
        {
            if (argv.Length < 2)
            {
                throw new SlashError("create takes at least one argument");
            }

            int typeID   = int.Parse(argv[1]);
            int quantity = 1;

            if (argv.Length > 2)
            {
                quantity = int.Parse(argv[2]);
            }

            if (call.Client.StationID == null)
            {
                throw new SlashError("Creating items can only be done at station");
            }
            // ensure the typeID exists
            if (this.TypeManager.ContainsKey(typeID) == false)
            {
                throw new SlashError("The specified typeID doesn't exist");
            }

            // create a new item with the correct locationID
            Station   location  = this.ItemFactory.GetStaticStation((int)call.Client.StationID);
            Character character = this.ItemFactory.GetItem <Character>(call.Client.EnsureCharacterIsSelected());

            Type       itemType = this.TypeManager[typeID];
            ItemEntity item     = this.ItemFactory.CreateSimpleItem(itemType, character, location, Flags.Hangar, quantity);

            item.Persist();

            // send client a notification so they can display the item in the hangar
            call.Client.NotifyMultiEvent(OnItemChange.BuildNewItemChange(item));
        }
示例#20
0
        public PyDataType TrashItems(PyList itemIDs, PyInteger stationID, CallInformation call)
        {
            foreach (PyInteger itemID in itemIDs.GetEnumerable <PyInteger>())
            {
                // do not trash the active ship
                if (itemID == call.Client.ShipID)
                {
                    throw new CantMoveActiveShip();
                }

                ItemEntity item = this.ItemFactory.GetItem(itemID);
                // store it's location id
                int   oldLocation = item.LocationID;
                Flags oldFlag     = item.Flag;
                // remove the item off the ItemManager
                this.ItemFactory.DestroyItem(item);
                // notify the client of the change
                call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(item, oldFlag, oldLocation));
                // TODO: CHECK IF THE ITEM HAS ANY META INVENTORY AND/OR BOUND SERVICE
                // TODO: AND FREE THOSE TOO SO THE ITEMS CAN BE REMOVED OFF THE DATABASE
            }

            return(null);
        }
示例#21
0
        public PyDataType AssembleCargoContainer(PyInteger containerID, PyDataType ignored, PyDecimal ignored2,
                                                 CallInformation call)
        {
            ItemEntity item = this.ItemFactory.GetItem(containerID);

            if (item.OwnerID != call.Client.EnsureCharacterIsSelected())
            {
                throw new TheItemIsNotYoursToTake(containerID);
            }

            // ensure the item is a cargo container
            switch (item.Type.Group.ID)
            {
            case (int)Groups.CargoContainer:
            case (int)Groups.SecureCargoContainer:
            case (int)Groups.AuditLogSecureContainer:
            case (int)Groups.FreightContainer:
            case (int)Groups.Tool:
            case (int)Groups.MobileWarpDisruptor:
                break;

            default:
                throw new ItemNotContainer(containerID);
            }

            bool oldSingleton = item.Singleton;

            // update singleton
            item.Singleton = true;
            item.Persist();

            // notify the client
            call.Client.NotifyMultiEvent(OnItemChange.BuildSingletonChange(item, oldSingleton));

            return(null);
        }
示例#22
0
        public PyDataType CancelCharOrder(PyInteger orderID, PyInteger regionID, CallInformation call)
        {
            int callerCharacterID = call.Client.EnsureCharacterIsSelected();

            Character character = this.ItemFactory.GetItem <Character>(callerCharacterID);

            using MySqlConnection connection = this.DB.AcquireMarketLock();
            try
            {
                MarketOrder order = this.DB.GetOrderById(connection, orderID);

                if (order.CharacterID != callerCharacterID)
                {
                    throw new MktOrderDidNotMatch();
                }

                long currentTime = DateTime.UtcNow.ToFileTimeUtc();
                // check for timers, no changes in less than 5 minutes
                if (currentTime < order.Issued + TimeSpan.TicksPerSecond * this.NodeContainer.Constants[Constants.mktModificationDelay])
                {
                    throw new MktOrderDelay((order.Issued + TimeSpan.TicksPerSecond * this.NodeContainer.Constants[Constants.mktModificationDelay]) - currentTime);
                }

                // check for escrow
                if (order.Escrow > 0.0 && order.Bid == TransactionType.Buy)
                {
                    using Wallet wallet = this.WalletManager.AcquireWallet(character.ID, 1000);
                    {
                        wallet.CreateJournalRecord(MarketReference.MarketEscrow, null, null, order.Escrow);
                    }
                }

                if (order.Bid == TransactionType.Sell)
                {
                    // create the new item that will be used by the player
                    ItemEntity item = this.ItemFactory.CreateSimpleItem(
                        this.TypeManager[order.TypeID], character.ID, order.LocationID, Flags.Hangar, order.UnitsLeft
                        );
                    // immediately unload it, if it has to be loaded the OnItemUpdate notification will take care of that
                    this.ItemFactory.UnloadItem(item);

                    // check what node this item should be loaded at
                    long stationNode = this.SystemManager.GetNodeStationBelongsTo(order.LocationID);

                    if (stationNode == 0 || this.SystemManager.StationBelongsToUs(order.LocationID) == true)
                    {
                        this.NotificationManager.NotifyCharacter(character.ID, Notifications.Client.Inventory.OnItemChange.BuildLocationChange(item, this.ItemFactory.LocationMarket.ID));
                    }
                    else
                    {
                        this.NotificationManager.NotifyNode(stationNode, OnItemChange.BuildLocationChange(item.ID, this.ItemFactory.LocationMarket.ID, order.LocationID));
                    }
                }

                // finally remove the order
                this.DB.RemoveOrder(connection, order.OrderID);
                // send a OnOwnOrderChange notification
                call.Client.NotifyMultiEvent(new OnOwnOrderChanged(order.TypeID, "Removed"));
            }
            finally
            {
                this.DB.ReleaseMarketLock(connection);
            }

            return(null);
        }
示例#23
0
        private void MoveItemHere(ItemEntity item, Flags newFlag)
        {
            // get the old location stored as it'll be used in the notifications
            int   oldLocation = item.LocationID;
            Flags oldFlag     = item.Flag;

            // rig slots cannot be moved
            if (item.IsInRigSlot() == true)
            {
                throw new CannotRemoveUpgradeManually();
            }

            // special situation, if the old location is a module slot ensure the item is first offlined
            if (item.IsInModuleSlot() == true)
            {
                if (item is ShipModule module)
                {
                    if (module.Attributes[Attributes.isOnline] == 1)
                    {
                        module.StopApplyingEffect("online", Client);
                    }

                    // disable passive effects too
                    module.StopApplyingPassiveEffects(Client);
                }
            }

            // extra special situation, is the new flag an autofit one?
            if (newFlag == Flags.AutoFit)
            {
                // capsules cannot fit anything
                if (this.mInventory.Type.ID == (int)Types.Capsule)
                {
                    throw new CantFitToCapsule();
                }

                if (this.mInventory is Ship ship)
                {
                    // determine where to put the item
                    if (item is ShipModule module)
                    {
                        if (module.IsHighSlot() == true)
                        {
                            newFlag = this.GetFreeHighSlot(ship);
                        }
                        else if (module.IsMediumSlot() == true)
                        {
                            newFlag = this.GetFreeMediumSlot(ship);
                        }
                        else if (module.IsLowSlot() == true)
                        {
                            newFlag = this.GetFreeLowSlot(ship);
                        }
                        else if (module.IsRigSlot() == true)
                        {
                            newFlag = this.GetFreeRigSlot(ship);
                        }
                        else
                        {
                            // this item cannot be fitted, move it to cargo, maybe throw a exception about not being able to fit it?
                            newFlag = Flags.Cargo;
                        }
                    }
                    // TODO: HANDLE CHARGES!
                    else
                    {
                        newFlag = Flags.Cargo;
                    }
                }
                else
                {
                    newFlag = Flags.Hangar;
                }
            }

            // special situation, if the new location is a module slot ensure the item is a singleton (TODO: HANDLE CHARGES TOO)
            if (newFlag.IsModule() == true)
            {
                ShipModule module = null;

                if (item is ShipModule shipModule)
                {
                    module = shipModule;
                }

                if (item.Quantity == 1)
                {
                    // remove item off the old inventory if required
                    if (this.ItemFactory.TryGetItem(item.LocationID, out ItemInventory inventory) == true)
                    {
                        inventory.RemoveItem(item);
                    }

                    OnItemChange changes = new OnItemChange(item);

                    if (item.Singleton == false)
                    {
                        changes.AddChange(ItemChange.Singleton, item.Singleton);
                    }

                    item.LocationID = this.mInventory.ID;
                    item.Flag       = newFlag;
                    item.Singleton  = true;

                    changes
                    .AddChange(ItemChange.LocationID, oldLocation)
                    .AddChange(ItemChange.Flag, (int)oldFlag);

                    // notify the character about the change
                    Client.NotifyMultiEvent(changes);
                    // update meta inventories too
                    this.ItemFactory.MetaInventoryManager.OnItemMoved(item, oldLocation, this.mInventory.ID);

                    // finally persist the item changes
                    item.Persist();
                }
                else
                {
                    // item is not a singleton, create a new item, decrease quantity and send notifications
                    ItemEntity newItem = this.ItemFactory.CreateSimpleItem(item.Type, item.OwnerID, this.mInventory.ID, newFlag, 1, false,
                                                                           true);

                    item.Quantity -= 1;

                    // notify the quantity change and the new item
                    Client.NotifyMultiEvent(OnItemChange.BuildQuantityChange(item, item.Quantity + 1));
                    Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(newItem, Flags.None, 0));

                    item.Persist();

                    // replace reference so the following code handle things properly
                    item = newItem;

                    if (item is ShipModule shipModule2)
                    {
                        module = shipModule2;
                    }
                }

                try
                {
                    // apply all the passive effects (this also blocks the item fitting if the initialization fails)
                    module?.ApplyPassiveEffects(Client);
                    // extra check, ensure that the character has the required skills
                }
                catch (UserError)
                {
                    // ensure that the passive effects that got applied already are removed from the item
                    module?.StopApplyingPassiveEffects(Client);

                    int   newOldLocation = item.LocationID;
                    Flags newOldFlag     = item.Flag;

                    // now undo the whole thing
                    item.LocationID = oldLocation;
                    item.Flag       = oldFlag;

                    Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(item, newOldFlag, newOldLocation));
                    throw;
                }

                // ensure the new inventory knows
                this.mInventory.AddItem(item);

                module?.Persist();

                // put the module online after fitting it as long as it's a normal module
                if (module?.IsRigSlot() == false)
                {
                    module?.ApplyEffect("online", Client);
                }
            }
            else
            {
                // remove item off the old inventory if required
                if (this.ItemFactory.TryGetItem(item.LocationID, out ItemInventory inventory) == true)
                {
                    inventory.RemoveItem(item);
                }

                // set the new location for the item
                item.LocationID = this.mInventory.ID;
                item.Flag       = newFlag;

                // notify the character about the change
                Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(item, oldFlag, oldLocation));
                // update meta inventories too
                this.ItemFactory.MetaInventoryManager.OnItemMoved(item, oldLocation, this.mInventory.ID);

                // ensure the new inventory knows
                this.mInventory.AddItem(item);

                // finally persist the item changes
                item.Persist();
            }
        }
示例#24
0
        private void PlaceSellOrderCharUpdateItems(MySqlConnection connection, Client client, int stationID, int typeID, int quantity)
        {
            Dictionary <int, MarketDB.ItemQuantityEntry> items = null;

            // depending on where the character that is placing the order, the way to detect the items should be different
            if (stationID == client.StationID)
            {
                items = this.DB.PrepareItemForOrder(connection, typeID, stationID, client.ShipID ?? -1, quantity, (int)client.CharacterID);
            }
            else
            {
                items = this.DB.PrepareItemForOrder(connection, typeID, stationID, -1, quantity, (int)client.CharacterID);
            }

            if (items is null)
            {
                throw new NotEnoughQuantity(this.TypeManager[typeID]);
            }

            long stationNode = this.SystemManager.GetNodeStationBelongsTo(stationID);

            if (this.SystemManager.StationBelongsToUs(stationID) == true || stationNode == 0)
            {
                // load the items here and send proper notifications
                foreach ((int _, MarketDB.ItemQuantityEntry entry) in items)
                {
                    ItemEntity item = this.ItemFactory.LoadItem(entry.ItemID);

                    if (entry.Quantity == 0)
                    {
                        // item has to be destroyed
                        this.ItemFactory.DestroyItem(item);
                        // notify item destroyal
                        client.NotifyMultiEvent(Notifications.Client.Inventory.OnItemChange.BuildLocationChange(item, stationID));
                    }
                    else
                    {
                        // just a quantity change
                        item.Quantity = entry.Quantity;
                        // notify the client
                        client.NotifyMultiEvent(Notifications.Client.Inventory.OnItemChange.BuildQuantityChange(item, entry.OriginalQuantity));
                        // unload the item if it's not needed
                        this.ItemFactory.UnloadItem(item);
                    }
                }
            }
            else
            {
                // the item changes should be handled by a different node
                OnItemChange changes = new OnItemChange();

                foreach ((int _, MarketDB.ItemQuantityEntry entry) in items)
                {
                    if (entry.Quantity == 0)
                    {
                        changes.AddChange(entry.ItemID, "locationID", stationID, this.ItemFactory.LocationMarket.ID);
                    }
                    else
                    {
                        changes.AddChange(entry.ItemID, "quantity", entry.OriginalQuantity, entry.Quantity);
                    }
                }
            }
        }
示例#25
0
        private void GiveSkillCmd(string[] argv, CallInformation call)
        {
            // TODO: NOT NODE-SAFE, MUST REIMPLEMENT TAKING THAT INTO ACCOUNT!
            if (argv.Length != 4)
            {
                throw new SlashError("GiveSkill must have 4 arguments");
            }

            string target    = argv[1].Trim(new [] { '"', ' ' });
            string skillType = argv[2];
            int    level     = int.Parse(argv[3]);

            if (target != "me")
            {
                throw new SlashError("giveskill only supports me for now");
            }

            Character character = this.ItemFactory.GetItem <Character>(call.Client.EnsureCharacterIsSelected());

            if (skillType == "all")
            {
                // player wants all the skills!
                IEnumerable <KeyValuePair <int, Type> > skillTypes =
                    this.TypeManager.Where(x => x.Value.Group.Category.ID == (int)Categories.Skill && x.Value.Published == true);

                Dictionary <int, Skill> injectedSkills = character.InjectedSkillsByTypeID;

                foreach (KeyValuePair <int, Type> pair in skillTypes)
                {
                    // skill already injected, train it to the desired level
                    if (injectedSkills.ContainsKey(pair.Key) == true)
                    {
                        Skill skill = injectedSkills[pair.Key];

                        skill.Level = level;
                        skill.Persist();
                        call.Client.NotifyMultiEvent(new OnSkillTrained(skill));
                    }
                    else
                    {
                        // skill not injected, create it, inject and done
                        Skill skill = this.ItemFactory.CreateSkill(pair.Value, character, level,
                                                                   SkillHistoryReason.GMGiveSkill);

                        call.Client.NotifyMultiEvent(OnItemChange.BuildNewItemChange(skill));
                        call.Client.NotifyMultiEvent(new OnSkillInjected());
                    }
                }
            }
            else
            {
                int skillTypeID = int.Parse(skillType);
                Dictionary <int, Skill> injectedSkills = character.InjectedSkillsByTypeID;

                if (injectedSkills.ContainsKey(skillTypeID) == true)
                {
                    Skill skill = injectedSkills[skillTypeID];

                    skill.Level = level;
                    skill.Persist();
                    call.Client.NotifyMultiEvent(new OnSkillTrained(skill));
                }
                else
                {
                    // skill not injected, create it, inject and done
                    Skill skill = this.ItemFactory.CreateSkill(this.TypeManager[skillTypeID], character, level,
                                                               SkillHistoryReason.GMGiveSkill);

                    call.Client.NotifyMultiEvent(OnItemChange.BuildNewItemChange(skill));
                    call.Client.NotifyMultiEvent(new OnSkillInjected());
                }
            }
        }
示例#26
0
        private void HandleOnItemUpdate(Notifications.Nodes.Inventory.OnItemChange change)
        {
            foreach ((PyInteger itemID, PyDictionary _changes) in change.Updates)
            {
                PyDictionary <PyString, PyTuple> changes = _changes.GetEnumerable <PyString, PyTuple>();

                ItemEntity item = this.ItemFactory.LoadItem(itemID, out bool loadRequired);

                // if the item was just loaded there's extra things to take into account
                // as the item might not even need a notification to the character it belongs to
                if (loadRequired == true)
                {
                    // trust that the notification got to the correct node
                    // load the item and check the owner, if it's logged in and the locationID is loaded by us
                    // that means the item should be kept here
                    if (this.ItemFactory.TryGetItem(item.LocationID, out ItemEntity location) == false || this.CharacterManager.IsCharacterConnected(item.OwnerID) == false)
                    {
                        // this item should not be loaded, so unload and return
                        this.ItemFactory.UnloadItem(item);
                        return;
                    }

                    bool locationBelongsToUs = true;

                    switch (location)
                    {
                    case Station _:
                        locationBelongsToUs = this.SystemManager.StationBelongsToUs(location.ID);
                        break;

                    case SolarSystem _:
                        locationBelongsToUs = this.SystemManager.SolarSystemBelongsToUs(location.ID);
                        break;
                    }

                    if (locationBelongsToUs == false)
                    {
                        this.ItemFactory.UnloadItem(item);
                        return;
                    }
                }

                OnItemChange itemChange = new OnItemChange(item);

                // update item and build change notification
                if (changes.TryGetValue("locationID", out PyTuple locationChange) == true)
                {
                    PyInteger oldValue = locationChange[0] as PyInteger;
                    PyInteger newValue = locationChange[1] as PyInteger;

                    itemChange.AddChange(ItemChange.LocationID, oldValue);
                    item.LocationID = newValue;
                }

                if (changes.TryGetValue("quantity", out PyTuple quantityChange) == true)
                {
                    PyInteger oldValue = quantityChange[0] as PyInteger;
                    PyInteger newValue = quantityChange[1] as PyInteger;

                    itemChange.AddChange(ItemChange.Quantity, oldValue);
                    item.Quantity = newValue;
                }

                if (changes.TryGetValue("ownerID", out PyTuple ownerChange) == true)
                {
                    PyInteger oldValue = ownerChange[0] as PyInteger;
                    PyInteger newValue = ownerChange[1] as PyInteger;

                    itemChange.AddChange(ItemChange.OwnerID, oldValue);
                    item.OwnerID = newValue;
                }

                if (changes.TryGetValue("singleton", out PyTuple singletonChange) == true)
                {
                    PyBool oldValue = singletonChange[0] as PyBool;
                    PyBool newValue = singletonChange[1] as PyBool;

                    itemChange.AddChange(ItemChange.Singleton, oldValue);
                    item.Singleton = newValue;
                }

                // TODO: IDEALLY THIS WOULD BE ENQUEUED SO ALL OF THEM ARE SENT AT THE SAME TIME
                // TODO: BUT FOR NOW THIS SHOULD SUFFICE
                // send the notification
                this.NotificationManager.NotifyCharacter(item.OwnerID, "OnMultiEvent",
                                                         new PyTuple(1)
                {
                    [0] = new PyList(1)
                    {
                        [0] = itemChange
                    }
                });

                if (item.LocationID == this.ItemFactory.LocationRecycler.ID)
                {
                    // the item is removed off the database if the new location is the recycler
                    item.Destroy();
                }
                else if (item.LocationID == this.ItemFactory.LocationMarket.ID)
                {
                    // items that are moved to the market can be unloaded
                    this.ItemFactory.UnloadItem(item);
                }
                else
                {
                    // save the item if the new location is not removal
                    item.Persist();
                }
            }
        }
示例#27
0
		//public void RenderPropertyList ()
		//{
		//	int i = 0;
				
//				if (inspecting_person != null) {
//						ylist = gameEngine.Instance.getScanner ().getPropertyListByOwner (inspecting_person);
//						foreach (Property pl in mylist) {
//								GameObject newitem = GameObject.Instantiate (preFabItemProperty) as GameObject; 
//								newitem.transform.parent = Grid.transform;
//								newitem.transform.localPosition = new Vector3 (itemBound.x * i, 0f, 0f);
//								foreach (Transform t in newitem.transform) {
//										if (t.gameObject.name.Equals ("UISprite")) {
//												setItemSprite (t.gameObject.GetComponent<UISprite> (), pl);
//												//Debug.Log ("girl is active");
//										}
//								}
//								i++;
//						}	
//				}
		//	}




		/// <summary>
		/// 设置代理
		/// </summary>
		/// <param name="_onItemChange"></param>
		/// <param name="_onClickItem"></param>
		public void SetDelegate (OnItemChange _onItemChange,
	                        OnClickItem _onClickItem)
		{
				m_pItemChangeCallBack = _onItemChange;
		
				if (_onClickItem != null) {
						m_pOnClickItemCallBack = _onClickItem;
				}
		}
示例#28
0
        private void AcceptItemExchangeContract(MySqlConnection connection, Client client, ContractDB.Contract contract, Station station, int ownerID, Flags flag = Flags.Hangar)
        {
            List <ContractDB.ItemQuantityEntry> offeredItems = this.DB.GetOfferedItems(connection, contract.ID);
            Dictionary <int, int> itemsToCheck = this.DB.GetRequiredItemTypeIDs(connection, contract.ID);
            List <ContractDB.ItemQuantityEntry> changedItems = this.DB.CheckRequiredItemsAtStation(connection, station, ownerID, contract.IssuerID, flag, itemsToCheck);

            // extract the crate
            this.DB.ExtractCrate(connection, contract.CrateID, station.ID, ownerID);

            long stationNode = this.SystemManager.GetNodeStationBelongsTo(station.ID);

            if (stationNode == 0 || this.SystemManager.StationBelongsToUs(station.ID) == true)
            {
                foreach (ContractDB.ItemQuantityEntry change in changedItems)
                {
                    ItemEntity item = this.ItemFactory.LoadItem(change.ItemID);

                    if (change.Quantity == 0)
                    {
                        // remove item from the meta inventories
                        this.ItemFactory.MetaInventoryManager.OnItemDestroyed(item);
                        // temporarily move the item to the recycler, let the current owner know
                        item.LocationID = this.ItemFactory.LocationRecycler.ID;
                        client.NotifyMultiEvent(Notifications.Client.Inventory.OnItemChange.BuildLocationChange(item, station.ID));
                        // now set the item to the correct owner and place and notify it's new owner
                        // TODO: TAKE forCorp INTO ACCOUNT
                        item.LocationID = station.ID;
                        item.OwnerID    = contract.IssuerID;
                        this.NotificationManager.NotifyCharacter(contract.IssuerID, Notifications.Client.Inventory.OnItemChange.BuildNewItemChange(item));
                        // add the item back to meta inventories if required
                        this.ItemFactory.MetaInventoryManager.OnItemLoaded(item);
                    }
                    else
                    {
                        int oldQuantity = item.Quantity;
                        item.Quantity = change.Quantity;
                        client.NotifyMultiEvent(Notifications.Client.Inventory.OnItemChange.BuildQuantityChange(item, oldQuantity));

                        item.Persist();

                        // unload the item if required
                        this.ItemFactory.UnloadItem(item);
                    }
                }

                // move the offered items
                foreach (ContractDB.ItemQuantityEntry entry in offeredItems)
                {
                    ItemEntity item = this.ItemFactory.LoadItem(entry.ItemID);

                    item.LocationID = station.ID;
                    item.OwnerID    = ownerID;

                    client.NotifyMultiEvent(Notifications.Client.Inventory.OnItemChange.BuildLocationChange(item, contract.CrateID));

                    item.Persist();

                    // unload the item if possible
                    this.ItemFactory.UnloadItem(item);
                }
            }
            else
            {
                OnItemChange changes = new OnItemChange();

                foreach (ContractDB.ItemQuantityEntry change in changedItems)
                {
                    if (change.Quantity == 0)
                    {
                        changes
                        .AddChange(change.ItemID, "locationID", contract.CrateID, station.ID)
                        .AddChange(change.ItemID, "ownerID", contract.IssuerID, ownerID);
                    }
                    else
                    {
                        // change the item quantity
                        changes.AddChange(change.ItemID, "quantity", change.OldQuantity, change.Quantity);
                        // create a new item and notify the new node about it
                        // TODO: HANDLE BLUEPRINTS TOO! RIGHT NOW NO DATA IS COPIED FOR THEM
                        ItemEntity item = this.ItemFactory.CreateSimpleItem(
                            this.TypeManager[change.TypeID], contract.IssuerID, station.ID, Flags.Hangar, change.OldQuantity - change.Quantity, false, false
                            );
                        // unload the created item
                        this.ItemFactory.UnloadItem(item);
                        changes.AddChange(item.ID, "location", 0, station.ID);
                    }
                }

                // move the offered items
                foreach (ContractDB.ItemQuantityEntry entry in offeredItems)
                {
                    // TODO: TAKE INTO ACCOUNT forCorp
                    changes
                    .AddChange(entry.ItemID, "locationID", contract.CrateID, station.ID)
                    .AddChange(entry.ItemID, "ownerID", contract.IssuerID, station.ID);
                }
            }

            // the contract was properly accepted, update it's status
            this.DB.UpdateContractStatus(ref connection, contract.ID, ContractStatus.Finished);
            this.DB.UpdateAcceptorID(ref connection, contract.ID, ownerID);
            this.DB.UpdateAcceptedDate(ref connection, contract.ID);
            this.DB.UpdateCompletedDate(ref connection, contract.ID);
            // notify the contract as being accepted
            if (contract.ForCorp == false)
            {
                this.NotificationManager.NotifyCharacter(contract.IssuerID, new OnContractAccepted(contract.ID));
            }
            else
            {
                this.NotificationManager.NotifyCorporation(contract.IssuerCorpID, new OnContractAccepted(contract.ID));
            }
        }
示例#29
0
        public PyDataType SaveSkillQueue(PyList queue, CallInformation call)
        {
            if (this.Character.SkillQueue.Count > 0)
            {
                // calculate current skill in training points
                Skill currentSkill = this.Character.SkillQueue[0].Skill;

                if (currentSkill.ExpiryTime > 0)
                {
                    // get the total amount of minutes the skill would have taken to train completely
                    long pointsLeft = (long)(currentSkill.GetSkillPointsForLevel(this.Character.SkillQueue[0].TargetLevel) - currentSkill.Points);

                    TimeSpan timeLeft   = TimeSpan.FromMinutes(pointsLeft / this.Character.GetSkillPointsPerMinute(currentSkill));
                    DateTime endTime    = DateTime.FromFileTimeUtc(currentSkill.ExpiryTime);
                    DateTime startTime  = endTime.Subtract(timeLeft);
                    TimeSpan timePassed = DateTime.UtcNow - startTime;

                    // calculate the skill points to add
                    double skillPointsToAdd = timePassed.TotalMinutes * this.Character.GetSkillPointsPerMinute(currentSkill);

                    currentSkill.Points += skillPointsToAdd;
                }

                // remove the timer associated with the queue
                this.FreeSkillQueueTimers();

                foreach (Character.SkillQueueEntry entry in this.Character.SkillQueue)
                {
                    entry.Skill.Flag = Flags.Skill;

                    call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(entry.Skill, Flags.SkillInTraining));

                    // send notification of skill training stopped
                    call.Client.NotifyMultiEvent(new OnSkillTrainingStopped(entry.Skill));

                    // create history entry
                    this.DB.CreateSkillHistoryRecord(entry.Skill.Type, this.Character, SkillHistoryReason.SkillTrainingCancelled,
                                                     entry.Skill.Points);

                    entry.Skill.ExpiryTime = 0;
                    entry.Skill.Persist();
                }

                this.Character.SkillQueue.Clear();
            }

            DateTime startDateTime = DateTime.UtcNow;
            bool     first         = true;

            foreach (PyTuple entry in queue.GetEnumerable <PyTuple>())
            {
                // ignore wrong entries
                if (entry.Count != 2)
                {
                    continue;
                }

                int typeID = entry[0] as PyInteger;
                int level  = entry[1] as PyInteger;

                // search for an item with the given typeID
                ItemEntity item = this.Character.Items.First(x => x.Value.Type.ID == typeID && (x.Value.Flag == Flags.Skill || x.Value.Flag == Flags.SkillInTraining)).Value;

                // ignore items that are not skills
                if (item is Skill == false)
                {
                    continue;
                }

                Skill skill = item as Skill;

                double skillPointsLeft = skill.GetSkillPointsForLevel(level) - skill.Points;

                TimeSpan duration = TimeSpan.FromMinutes(skillPointsLeft / this.Character.GetSkillPointsPerMinute(skill));

                DateTime expiryTime = startDateTime + duration;

                skill.ExpiryTime = expiryTime.ToFileTimeUtc();
                skill.Flag       = Flags.SkillInTraining;

                call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(skill, Flags.Skill));

                startDateTime = expiryTime;

                // skill added to the queue, persist the character to ensure all the changes are saved
                this.Character.SkillQueue.Add(new Character.SkillQueueEntry()
                {
                    Skill = skill, TargetLevel = level
                });

                if (first == true)
                {
                    // skill was trained, send the success message
                    call.Client.NotifyMultiEvent(new OnSkillStartTraining(skill));

                    // create history entry
                    this.DB.CreateSkillHistoryRecord(skill.Type, this.Character, SkillHistoryReason.SkillTrainingStarted, skill.Points);

                    first = false;
                }

                skill.Persist();
            }

            // ensure the timer is present for the first skill in the queue
            this.SetupTimerForNextSkillInQueue();

            // finally persist the data to the database
            this.Character.Persist();

            return(null);
        }
示例#30
0
        private void PlaceImmediateBuyOrderChar(MySqlConnection connection, Wallet wallet, int typeID, Character character, int stationID, int quantity, double price, int range, CallInformation call)
        {
            int solarSystemID = this.ItemFactory.GetStaticStation(stationID).SolarSystemID;

            // look for matching sell orders
            MarketOrder[] orders = this.DB.FindMatchingOrders(connection, price, typeID, character.ID, solarSystemID, TransactionType.Sell);

            // ensure there's at least some that match
            this.CheckMatchingSellOrders(orders, quantity, solarSystemID);

            foreach (MarketOrder order in orders)
            {
                int quantityToBuy = 0;

                if (order.Range == -1 && order.LocationID != stationID)
                {
                    continue;
                }
                if (order.Range != -1 && order.Range < order.Jumps)
                {
                    continue;
                }

                if (order.UnitsLeft <= quantity)
                {
                    // the order was completed, remove it from the database
                    this.DB.RemoveOrder(connection, order.OrderID);

                    // increase the amount of bought items
                    quantityToBuy = order.UnitsLeft;
                    quantity     -= order.UnitsLeft;
                }
                else
                {
                    // part of the sell order was satisfied
                    this.DB.UpdateOrderRemainingQuantity(connection, order.OrderID, order.UnitsLeft - quantity, 0);

                    quantityToBuy = quantity;
                    quantity      = 0;
                }

                if (quantityToBuy > 0)
                {
                    // acquire wallet journal for seller so we can update their balance to add the funds that he got
                    using Wallet sellerWallet = this.WalletManager.AcquireWallet(order.CharacterID, order.AccountID);
                    {
                        sellerWallet.CreateJournalRecord(MarketReference.MarketTransaction, character.ID, order.CharacterID, null, price * quantityToBuy);
                    }

                    // create the transaction records for both characters
                    this.WalletManager.CreateTransactionRecord(character.ID, TransactionType.Buy, order.CharacterID, typeID, quantityToBuy, price, stationID);
                    this.WalletManager.CreateTransactionRecord(order.CharacterID, TransactionType.Sell, character.ID, typeID, quantityToBuy, price, stationID);

                    long stationNode = this.SystemManager.GetNodeStationBelongsTo(stationID);

                    // create the new item that will be used by the player
                    ItemEntity item = this.ItemFactory.CreateSimpleItem(
                        this.TypeManager[typeID], character.ID, stationID, Flags.Hangar, quantityToBuy
                        );
                    // immediately unload it, if it has to be loaded the OnItemUpdate notification will take care of that
                    this.ItemFactory.UnloadItem(item);

                    if (stationNode == 0 || this.SystemManager.StationBelongsToUs(stationID) == true)
                    {
                        this.NotificationManager.NotifyCharacter(character.ID, Notifications.Client.Inventory.OnItemChange.BuildLocationChange(item, this.ItemFactory.LocationMarket.ID));
                    }
                    else
                    {
                        this.NotificationManager.NotifyNode(stationNode, OnItemChange.BuildLocationChange(item.ID, this.ItemFactory.LocationMarket.ID, stationID));
                    }
                }

                // ensure we do not buy more than we need
                if (quantity == 0)
                {
                    break;
                }
            }
        }
示例#31
0
        public PyDataType InjectSkillIntoBrain(PyList itemIDs, CallInformation call)
        {
            foreach (PyInteger item in itemIDs.GetEnumerable <PyInteger>())
            {
                try
                {
                    // get the item by it's ID and change the location of it
                    Skill skill = this.ItemFactory.GetItem <Skill>(item);

                    // check if the character already has this skill injected
                    if (this.Character.InjectedSkillsByTypeID.ContainsKey(skill.Type.ID) == true)
                    {
                        throw new CharacterAlreadyKnowsSkill(skill.Type);
                    }

                    // is this a stack of skills?
                    if (skill.Quantity > 1)
                    {
                        // add one of the skill into the character's brain
                        Skill newStack = this.ItemFactory.CreateSkill(skill.Type, this.Character, 0, SkillHistoryReason.None);

                        // subtract one from the quantity
                        skill.Quantity -= 1;

                        // save to database
                        skill.Persist();

                        // finally notify the client
                        call.Client.NotifyMultiEvent(OnItemChange.BuildQuantityChange(skill, skill.Quantity + 1));
                        call.Client.NotifyMultiEvent(OnItemChange.BuildNewItemChange(newStack));
                    }
                    else
                    {
                        // store old values for the notification
                        int   oldLocationID = skill.LocationID;
                        Flags oldFlag       = skill.Flag;

                        // now set the new values
                        skill.LocationID = this.Character.ID;
                        skill.Flag       = Flags.Skill;
                        skill.Level      = 0;
                        skill.Singleton  = true;

                        // ensure the character has the skill in his/her brain
                        this.Character.AddItem(skill);

                        // ensure the changes are saved
                        skill.Persist();

                        // notify the character of the change in the item
                        call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(skill, oldFlag, oldLocationID));
                        call.Client.NotifyMultiEvent(OnItemChange.BuildSingletonChange(skill, false));
                    }
                }
                catch (CharacterAlreadyKnowsSkill)
                {
                    throw;
                }
                catch (Exception)
                {
                    Log.Error($"Cannot inject itemID {item} into {this.Character.ID}'s brain...");
                    throw;
                }
            }

            // send the skill injected notification to refresh windows if needed
            call.Client.NotifyMultiEvent(new OnSkillInjected());

            return(null);
        }