Example #1
0
export function optimalLoadout(applicableItems: DimItem[], bestItemFn: (item: DimItem) => number, name: string): Loadout {
  const itemsByType = _.groupBy(applicableItems, 'type');

  // Pick the best item
  let items = _.mapObject(itemsByType, (items) => _.max(items, bestItemFn));

  // Solve for the case where our optimizer decided to equip two exotics
  const getLabel = (i) => i.equippingLabel;
  // All items that share an equipping label, grouped by label
  const overlaps: _.Dictionary<DimItem[]> = _.groupBy(Object.values(items).filter(getLabel), getLabel);
  _.each(overlaps, (overlappingItems) => {
    if (overlappingItems.length <= 1) {
      return;
    }

    const options: _.Dictionary<DimItem>[] = [];
    // For each item, replace all the others overlapping it with the next best thing
    for (const item of overlappingItems) {
      const option = copy(items);
      const otherItems = overlappingItems.filter((i) => i !== item);
      let optionValid = true;

      for (const otherItem of otherItems) {
        // Note: we could look for items that just don't have the *same* equippingLabel but
        // that may fail if there are ever mutual-exclusion items beyond exotics.
        const nonExotics = itemsByType[otherItem.type].filter((i) => !i.equippingLabel);
        if (nonExotics.length) {
          option[otherItem.type] = _.max(nonExotics, bestItemFn);
        } else {
          // this option isn't usable because we couldn't swap this exotic for any non-exotic
          optionValid = false;
        }
      }

      if (optionValid) {
        options.push(option);
      }
    }

    // Pick the option where the optimizer function adds up to the biggest number, again favoring equipped stuff
    if (options.length > 0) {
      const bestOption = _.max(options, (opt) => sum(Object.values(opt), bestItemFn));
      items = bestOption;
    }
  });

  // Copy the items and mark them equipped and put them in arrays, so they look like a loadout
  const finalItems: { [type: string]: DimItem[] } = {};
  _.each(items, (item, type) => {
    const itemCopy = copy(item);
    itemCopy.equipped = true;
    finalItems[type.toLowerCase()] = [itemCopy];
  });

  return {
    classType: -1,
    name,
    items: finalItems
  };
}
Example #2
0
File: utils.ts Project: bhollis/DIM
export function getSetTiers(armorSets: ArmorSet[]): string[] {
  const tiersSet = new Set<string>();
  armorSets.forEach((set: ArmorSet) => {
    set.tiers.forEach((tier: string) => {
      tiersSet.add(tier);
    });
  });

  const tiers = _.each(
    _.groupBy(Array.from(tiersSet.keys()), (tierString: string) => {
      return sum(tierString.split('/'), (num) => parseInt(num, 10));
    }),
    (tier) => {
      tier.sort().reverse();
    }
  );

  const tierKeys = Object.keys(tiers);
  const setTiers: string[] = [];
  for (let tier = tierKeys.length; tier > tierKeys.length - 3; tier--) {
    if (tierKeys[tier]) {
      setTiers.push(t('LoadoutBuilder.SelectTierHeader', { tier: tierKeys[tier] }));
      tiers[tierKeys[tier]].forEach((set) => {
        setTiers.push(set);
      });
    }
  }

  return setTiers;
}
Example #3
0
    cloudThis: function (objectList, idProp, keyProp, textProp, options) {
        let exclude = options.exclude || [];
        let topN = options.topN || 50;
        let minCount = options.minCount || 1;
        let descFinder = options.descriptions || function () { return null; };

        var plaqueLists = _.groupBy(objectList, (o) => {
            return o[keyProp];
        });

        let toplist = _.map(Object.keys(plaqueLists), function (key) {
            var tags = analyseArray(plaqueLists[key]);
            let words = _(Object.keys(tags))
                .filter((w) => exclude.indexOf(w) === -1)
                .map((w) => {
                    return {
                        word: w,
                        plaques: _.uniq(tags[w], (t) => t.id)
                    };
                })
                .filter((w) => w.plaques.length > minCount);

            let sorted = _.sortBy(words, (w) => w.plaques.length * -1);
            let top10 = _.first(sorted, topN);

            return {
                key: key,
                words: top10,
                description: descFinder(key)
            };
        });

        return toplist;
    }
Example #4
0
export function gatherTokensLoadout(storeService: StoreServiceType): Loadout {
  let tokens = storeService.getAllItems().filter((i) => {
    return REP_TOKENS.has(i.hash) && !i.notransfer;
  });

  if (tokens.length === 0) {
    throw new Error(t('Loadouts.NoTokens'));
  }

  tokens = addUpStackables(tokens);

  const itemsByType = _.groupBy(tokens, 'type');

  // Copy the items and put them in arrays, so they look like a loadout
  const finalItems = {};
  _.each(itemsByType, (items, type) => {
    if (items) {
      finalItems[type.toLowerCase()] = items;
    }
  });

  return {
    classType: -1,
    name: t('Loadouts.GatherTokens'),
    items: finalItems
  };
}
Example #5
0
export function searchLoadout(storeService: StoreServiceType, store: DimStore): Loadout {
  let items = storeService.getAllItems().filter((i) => {
    return i.visible &&
      !i.location.inPostmaster &&
      !i.notransfer;
  });

  items = addUpStackables(items);

  const itemsByType = _.mapObject(_.groupBy(items, 'type'), (items) => limitToBucketSize(items, store.isVault));

  // Copy the items and mark them equipped and put them in arrays, so they look like a loadout
  const finalItems = {};
  _.each(itemsByType, (items, type) => {
    if (items) {
      finalItems[type.toLowerCase()] = items.map((i) => {
        const copiedItem = copy(i);
        copiedItem.equipped = false;
        return copiedItem;
      });
    }
  });

  return {
    classType: -1,
    name: t('Loadouts.FilteredItems'),
    items: finalItems
  };
}
Example #6
0
    ).then((items) => {
      store.items = items;

      // by type-bucket
      store.buckets = _.groupBy(items, (i) => i.location.id);

      store.vaultCounts = {};

      // Fill in any missing buckets
      Object.values(buckets.byType).forEach((bucket) => {
        if (!store.buckets[bucket.id]) {
          store.buckets[bucket.id] = [];
        }

        if (bucket.vaultBucket) {
          const vaultBucketId = bucket.vaultBucket.id;
          store.vaultCounts[vaultBucketId] = store.vaultCounts[vaultBucketId] || {
            count: 0,
            bucket: bucket.accountWide ? bucket : bucket.vaultBucket
          };
          store.vaultCounts[vaultBucketId].count += store.buckets[bucket.id].length;
        }
      });

      return store;
    });
Example #7
0
	constructor(private navCtrl: NavController) {
		this.titles = [];
		const g = groupBy(TITLE_DEFAULT, (t) => t.classify);
		for (const c in g) {
			if (c in g) {
				this.titles.push([c, g[c]]);
			}
		}
	}
Example #8
0
// Add up stackable items so we don't have duplicates. This helps us actually move them, see
// https://github.com/DestinyItemManager/DIM/issues/2691#issuecomment-373970255
function addUpStackables(items: DimItem[]) {
  return flatMap(Object.values(_.groupBy(items, (t) => t.hash)), (items) => {
    if (items[0].maxStackSize > 1) {
      const item = copy(items[0]);
      item.amount = sum(items, (i) => i.amount);
      return [item];
    } else {
      return items;
    }
  });
}
Example #9
0
    ).then((items) => {
      store.items = items;

      // by type-bucket
      store.buckets = _.groupBy(items, (i) => i.location.id);

      // Fill in any missing buckets
      Object.values(buckets.byType).forEach((bucket) => {
        if (!store.buckets[bucket.id]) {
          store.buckets[bucket.id] = [];
        }
      });

      return store;
    });
Example #10
0
    return processItems(store, items, itemComponents, previousItems, newItems, itemInfoService).then((items) => {
      store.items = items;

      // by type-bucket
      store.buckets = _.groupBy(items, (i) => {
        return i.location.id;
      });

      // Fill in any missing buckets
      Object.values(buckets.byType).forEach((bucket) => {
        if (!store.buckets[bucket.id]) {
          store.buckets[bucket.id] = [];
        }
      });

      return store;
    });