API Docs for:
Show:

File: src/valid-targets.js

(function(root) {
    'use strict';

    /**
     * Manages a list of valid targets and which is currently selected.
     * @class ValidTargets
     * @constructor
     * @param {Game} game - Game instance this obj is attached to.
     * @param {Array} [targets=Array] An Array of valid target objects to select from (intended to be in the format `validTargetsFinder.getValidTargets()` returns).
     * @param {Object} settings
     * @param {Array} [settings.typeSortPriority=this.typeSortPriority] - Array of types in order of their sort priority.
     * @param {Bool} [settings.mapWidth=game.map.width] - Width of `this.map`.
     * @param {Bool} [settings.mapHeight=game.map.height] - Height of `this.map`.
     * @param {Bool} [settings.skipSort=false] - If true initial sort is skipped.
     */
    var ValidTargets = function(game, targets, settings){
        this.game = game;

        settings = settings || {};
        this.typeSortPriority = settings.typeSortPriority || [].concat(this.typeSortPriority);

        var width = settings.mapWidth || this.game.map.width;
        var height = settings.mapWidth || this.game.map.width;

        this.map = new RL.MultiObjectManager(this.game, null, width, height);
        this.setTargets(targets);
        if(!settings.skipSort){
            this.sort();
        }
    };

    ValidTargets.prototype = {
        constructor: ValidTargets,

        /**
        * Game instance this obj is attached to.
        * @property game
        * @type {Game}
        */
        game: null,

        /**
         * Array of target objects.
         * @type {Array}
         * @property targets
         * @readOnly
         */
        targets: null,

        /**
         * Map of target positions.
         * @type {MultiObjectManager}
         * @property map
         *
         */
        map: null,

        /**
         * Currently Selected Object.
         * @property current
         * @type {Object}
         * @readOnly
         */
        current: null,

        /**
         * Array of types in order of their sort priority.
         * @type {Array}
         * @property typeSortPriority
         */
        typeSortPriority: [],

        /**
         * Sets the targets, replacing currently set ones.
         * @method setTargets
         * @param {Array} targets
         */
        setTargets: function(targets){
            targets = targets || [];
            this.targets = targets;
            this.map.reset();
            for(var i = targets.length - 1; i >= 0; i--){
                var target = targets[i];
                this.map.add(target.x, target.y, target);
            }
        },

        /**
         * Sets the currently selected target object.
         * @method setCurrent
         * @param {Object} target
         * @return {Bool} If target was found in `this.targets`. (only set if found).
         */
        setCurrent: function(target){
            var index = this.targets.indexOf(target);
            if(index !== -1){
                this.current = target;
                return true;
            }
            return false;
        },

        /**
         * Gets the currently selected target object.
         * @method getCurrent
         * @param {Bool} [autoset=true] - If no target is set to current autoset the first.
         * @return {Object}
         */
        getCurrent: function(autoset){
            autoset =  autoset !== void 0 ? autoset : true;
            if(autoset && !this.current && this.targets.length){
                this.sort();
                this.setCurrent(this.targets[0]);
            }

            return this.current;
        },

        /**
         * Sets the object after the currently selected object to be the selected object.
         * @method next
         * @return {Object} The new currently selected object.
         */
        next: function(){
            if(!this.current){
                return this.getCurrent();
            }

            var index = this.targets.indexOf(this.current);
            if(index === this.targets.length - 1){
                index = 0;
            } else {
                index++;
            }
            this.setCurrent(this.targets[index]);
            return this.current;
        },

        /**
         * Sets the object before the currently selected object to be the selected object.
         * @method prev
         * @return {Object} The new currently selected object.
         */
        prev: function(){
            if(!this.current){
                return this.getCurrent();
            }

            var index = this.targets.indexOf(this.current);
            if(index === 0){
                index = this.targets.length - 1;
            } else {
                index--;
            }
            this.setCurrent(this.targets[index]);

            return this.current;
        },

        /**
         * Gets the sort priority of an object based on its type using 'this.typeSortPriority'.
         * @method getTypeSortPriority
         * @param {Object} obj
         * @return {Number}
         */
        getTypeSortPriority: function(obj){
            for(var i = this.typeSortPriority.length - 1; i >= 0; i--){
                var type = this.typeSortPriority[i];
                if(obj instanceof type){
                    return i;
                }
            }
        },
        /**
         * Sorts `this.targets` by `this.typeSortPriority` then by range.
         * @method sort
         * @return {Number}
         */
        sort: function(){
            var _this = this;
            this.targets.sort(function(a, b){

                var aTypeSortPriority = _this.getTypeSortPriority(a.value);
                var bTypeSortPriority = _this.getTypeSortPriority(b.value);

                if(aTypeSortPriority === bTypeSortPriority){
                    return a.range - b.range;
                }
                if(aTypeSortPriority > bTypeSortPriority){
                    return 1;
                }
                if(aTypeSortPriority < bTypeSortPriority){
                    return -1;
                }
            });
        },

        /**
         * Finds a target object by its value.
         * @method getTargetByValue
         * @param {Object} value
         * @return {Object}
         */
        getTargetByValue: function(value){
            for(var i = this.targets.length - 1; i >= 0; i--){
                var target = this.targets[i];
                if(target.value === value){
                    return target;
                }
            }
        }
    };

    root.RL.ValidTargets = ValidTargets;

}(this));