{"size": 5394, "ext": "js", "max_stars_repo_path": "src/crowcraft/src/models/item/item.js", "max_stars_repo_name": "Piskieee/guillaume-docquier.github.io", "max_stars_repo_stars_event_min_datetime": "2021-06-20T13:17:54.000Z", "max_stars_repo_stars_event_max_datetime": "2021-09-08T17:16:49.000Z", "max_issues_repo_path": "src/crowcraft/src/models/item/item.js", "max_issues_repo_name": "Piskieee/guillaume-docquier.github.io", "max_issues_repo_issues_event_min_datetime": "2021-06-10T18:19:26.000Z", "max_issues_repo_issues_event_max_datetime": "2021-12-23T20:53:06.000Z", "max_forks_repo_path": "src/crowcraft/src/models/item/item.js", "max_forks_repo_name": "Piskieee/guillaume-docquier.github.io", "max_forks_repo_forks_event_min_datetime": "2021-06-14T08:16:42.000Z", "max_forks_repo_forks_event_max_datetime": "2021-11-28T01:43:06.000Z"}
{"max_stars_count": 6, "max_issues_count": 57, "max_forks_count": 7, "avg_line_length": 36.2013422819, "max_line_length": 162, "alphanum_fraction": 0.6358917316}
import { String, Sorting } from "utils";
import { Craft } from "../craft";
import { CraftingMaterial } from "../crafting-material";

export class Item {
    constructor(name, professions, rarities, craftingMaterials, craftingQuantity, craftingRecipeName) {
        this._name = name;
        this.professions = professions;
        this.rarities = rarities.sort(Sorting.ascending(rar => rar.rank));
        this._craftingMaterials = craftingMaterials;
        this.craftingQuantity = craftingQuantity;
        this.craftingRecipeName = craftingRecipeName ? craftingRecipeName : name

        this._assetId = String.decapitalize(this.constructor.name);
        this.craftingRank = this.getCraftingRank();
        this.rarity = this.rarities[0];
    }

    get id() {
        return [this.name, this.rarity.name, ...this.craftingMaterials.map(craftingMaterial => craftingMaterial.item.name)].join(".");
    }

    get baseName() {
        return this._name;
    }

    get name() {
        return this._name;
    }

    get craftingMaterials() {
        return this._craftingMaterials;
    }

    get isCraftable() {
        return this.craftingMaterials.length > 0;
    }

    adjustCraftingRanks() {
        for(const craftingMaterial of this.craftingMaterials) {
            craftingMaterial.item.adjustCraftingRanks();
        }

        this.craftingRank = this.getCraftingRank();
    }

    createNew() {
        return new this.constructor();
    }

    get assetId() {
        return this._assetId;
    }

    setRarity(rarity) {
        if (this.rarities.includes(rarity)) {
            this.rarity = rarity;
        }
        else {
            this.rarity = this.rarities[0]
        }

        for (const craftingMaterial of this.craftingMaterials) {
            craftingMaterial.item.setRarity(this.rarity);
        }
    }

    isCustomizable() {
        return this.getCustomizableComponents().length > 0;
    }

    getCustomizableComponents() {
        let customizableComponents = [];
        for (const craftingMaterial of this.craftingMaterials) {
            customizableComponents = customizableComponents.concat(craftingMaterial.item.getCustomizableComponents());
        }

        return customizableComponents;
    }

    getCraftingRank() {
        if (this.craftingMaterials.length === 0) {
            return 0;
        }

        return Math.max(...this.craftingMaterials.map(mat => mat.item.craftingRank)) + 1;
    }

    // This is wierd, but we must pass in 'applyDiscsAndBeltsDiscounts' because we can't import it here or else we get a circular dependency
    getCraftingRundown(applyDiscsAndBeltsDiscounts) {
        this.adjustCraftingRanks();
        const initialCraftingMaterial = new CraftingMaterial(this.craftingQuantity, this);
        applyDiscsAndBeltsDiscounts(initialCraftingMaterial);

        const crafts = [new Craft(initialCraftingMaterial.item.craftingMaterials, initialCraftingMaterial)];
        let craftingMaterials = [...this.craftingMaterials];
        for (const craftingMaterial of craftingMaterials) {
            applyDiscsAndBeltsDiscounts(craftingMaterial);
        }

        let rank = this.craftingRank;
        while (rank > 1) {
            rank -= 1;
            craftingMaterials.sort(Sorting.descending(rawMaterial => rawMaterial.item.craftingRank));

            const craftingSet = {};
            let i = 0;
            for (i; i < craftingMaterials.length && craftingMaterials[i].item.craftingRank === rank; i++) {
                const materialToCraft = craftingMaterials[i];
                if (craftingSet[materialToCraft.item.id] === undefined) {
                    craftingSet[materialToCraft.item.id] = new CraftingMaterial(materialToCraft.quantity, materialToCraft.item);
                }
                else {
                    craftingSet[materialToCraft.item.id].quantity += materialToCraft.quantity;
                }
            }

            craftingMaterials = craftingMaterials.slice(i, craftingMaterials.length);

            for (const materialToCraft of Object.values(craftingSet)) {
                const numberOfCrafts = Math.ceil(materialToCraft.quantity / materialToCraft.item.craftingQuantity);
                const materialsForThisCraft = materialToCraft.item.craftingMaterials.map(mat => new CraftingMaterial(mat.quantity * numberOfCrafts, mat.item));
                for (const materialForThisCraft of materialsForThisCraft) {
                    applyDiscsAndBeltsDiscounts(materialForThisCraft);
                }

                crafts.push(new Craft(materialsForThisCraft, new CraftingMaterial(numberOfCrafts * materialToCraft.item.craftingQuantity, materialToCraft.item)));
                craftingMaterials = craftingMaterials.concat(materialsForThisCraft);
            }
        }

        crafts.reverse();

        const rawMaterialsSet = {};
        for (const craftingMaterial of craftingMaterials) {
            if (rawMaterialsSet[craftingMaterial.item.id] === undefined) {
                rawMaterialsSet[craftingMaterial.item.id] = new CraftingMaterial(craftingMaterial.quantity, craftingMaterial.item);
            }
            else {
                rawMaterialsSet[craftingMaterial.item.id].quantity += craftingMaterial.quantity;
            }
        }

        return {
            crafts,
            rawMaterials: Object.values(rawMaterialsSet)
        }
    }
};