diff --git a/TODO.md b/TODO.md
index 8aa5789..2256daf 100644
--- a/TODO.md
+++ b/TODO.md
@@ -64,9 +64,10 @@ Ships models and equipments
* Add "cone" targetting
* Add disc targetting (for some jump move actions)
* Add "chain" effects
+* Add mines equivalent (drones that apply only at the end)
* RepelEffect should apply on ships in a good order (distance decreasing)
* Add hull points to drones and make them take area damage
-* "Shield Transfer" has no quality offsets
+* Quality modifiers should be based on an "quality diff" to reach
Artificial Intelligence
-----------------------
diff --git a/out/loot.html b/out/loot.html
index 81648a8..8f51e22 100644
--- a/out/loot.html
+++ b/out/loot.html
@@ -59,6 +59,7 @@
---
+ Refresh
@@ -106,6 +107,9 @@
current_name = this.value;
update();
}
+ document.getElementById("refresh").onclick = function () {
+ update();
+ }
update();
};
diff --git a/src/core/LootQualityModifiers.ts b/src/core/LootQualityModifiers.ts
new file mode 100644
index 0000000..f73c596
--- /dev/null
+++ b/src/core/LootQualityModifiers.ts
@@ -0,0 +1,103 @@
+module TS.SpaceTac {
+ /**
+ * Modifiers of basic loot, to obtain different quality levels
+ */
+ export class LootQualityModifiers {
+ /**
+ * Generic quality modifier
+ */
+ static applyStandard(equipment: Equipment, quality: EquipmentQuality, random: RandomGenerator): boolean {
+ // Collect available modifiers
+ let modifiers: Function[] = [];
+
+ let factor = 1;
+ if (quality == EquipmentQuality.WEAK) {
+ factor = 0.8;
+ } else if (quality == EquipmentQuality.FINE) {
+ factor = 1.1;
+ } else if (quality == EquipmentQuality.PREMIUM) {
+ factor = 1.3;
+ } else if (quality == EquipmentQuality.LEGENDARY) {
+ factor = 1.6;
+ }
+
+ if (quality == EquipmentQuality.WEAK && any(values(equipment.requirements), value => value > 0)) {
+ modifiers.push(() => {
+ iteritems(copy(equipment.requirements), (skill, value) => {
+ equipment.requirements[skill] = Math.max(equipment.requirements[skill] + 1, Math.floor(equipment.requirements[skill] / factor));
+ });
+ });
+ }
+
+ function simpleFactor(obj: T, attr: keyof T, inverse = false) {
+ let val = obj[attr];
+ if (val && val != 0) {
+ let nval = Math.round((inverse ? (1 / factor) : factor) * val);
+ if (nval != val) {
+ modifiers.push(() => (obj)[attr] = nval);
+ }
+ }
+ }
+
+ function effectFactor(effect: BaseEffect) {
+ if (effect instanceof ValueEffect || effect instanceof AttributeEffect) {
+ simpleFactor(effect, 'value');
+ } else if (effect instanceof AttributeLimitEffect) {
+ simpleFactor(effect, 'value', true);
+ } else if (effect instanceof StickyEffect) {
+ simpleFactor(effect, 'duration');
+ effectFactor(effect.base);
+ } else if (effect instanceof DamageEffect) {
+ simpleFactor(effect, 'base');
+ simpleFactor(effect, 'span');
+ } else if (effect instanceof RepelEffect) {
+ simpleFactor(effect, 'value');
+ } else if (effect instanceof DamageModifierEffect) {
+ simpleFactor(effect, 'factor');
+ } else if (effect instanceof ValueTransferEffect) {
+ simpleFactor(effect, 'amount');
+ }
+ }
+
+ equipment.effects.forEach(effectFactor);
+
+ if (equipment.action instanceof FireWeaponAction) {
+ simpleFactor(equipment.action, 'power', true);
+ simpleFactor(equipment.action, 'blast');
+ simpleFactor(equipment.action, 'range');
+ equipment.action.effects.forEach(effectFactor);
+ }
+
+ if (equipment.action instanceof ToggleAction) {
+ simpleFactor(equipment.action, 'power', true);
+ simpleFactor(equipment.action, 'radius');
+ equipment.action.effects.forEach(effectFactor);
+ }
+
+ if (equipment.action instanceof DeployDroneAction) {
+ simpleFactor(equipment.action, 'deploy_distance');
+ simpleFactor(equipment.action, 'effect_radius');
+ equipment.action.effects.forEach(effectFactor);
+ }
+
+ if (equipment.action instanceof MoveAction) {
+ simpleFactor(equipment.action, 'distance_per_power');
+ }
+
+ if (equipment.cooldown.overheat) {
+ simpleFactor(equipment.cooldown, 'overheat', true);
+ simpleFactor(equipment.cooldown, 'cooling', true);
+ }
+
+ // Choose a random one
+ if (modifiers.length > 0) {
+ let chosen = random.choice(modifiers);
+ chosen();
+ equipment.price = Math.ceil(equipment.price * factor * factor);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/core/LootTemplate.ts b/src/core/LootTemplate.ts
index 6d19bad..c95dc1b 100644
--- a/src/core/LootTemplate.ts
+++ b/src/core/LootTemplate.ts
@@ -81,90 +81,6 @@ module TS.SpaceTac {
}
}
- /**
- * Generic quality modifier
- */
- function standardQualityModifier(equipment: Equipment, quality: EquipmentQuality, random: RandomGenerator): boolean {
- // Collect available modifiers
- let modifiers: Function[] = [];
-
- let factor = 1;
- if (quality == EquipmentQuality.WEAK) {
- factor = 0.8;
- } else if (quality == EquipmentQuality.FINE) {
- factor = 1.1;
- } else if (quality == EquipmentQuality.PREMIUM) {
- factor = 1.3;
- } else if (quality == EquipmentQuality.LEGENDARY) {
- factor = 1.6;
- }
-
- if (quality == EquipmentQuality.WEAK && any(values(equipment.requirements), value => value > 0)) {
- modifiers.push(() => {
- iteritems(copy(equipment.requirements), (skill, value) => {
- equipment.requirements[skill] = Math.max(equipment.requirements[skill] + 1, Math.floor(equipment.requirements[skill] / factor));
- });
- });
- }
-
- function simpleFactor(obj: T, attr: keyof T, inverse = false) {
- let val = obj[attr];
- if (val && val > 0) {
- let nval = Math.round((inverse ? (1 / factor) : factor) * val);
- if (nval != val) {
- modifiers.push(() => (obj)[attr] = nval);
- }
- }
- }
-
- function effectFactor(effect: BaseEffect) {
- if (effect instanceof ValueEffect || effect instanceof AttributeEffect) {
- simpleFactor(effect, 'value');
- } else if (effect instanceof AttributeLimitEffect) {
- simpleFactor(effect, 'value', true);
- } else if (effect instanceof StickyEffect) {
- simpleFactor(effect, 'duration');
- effectFactor(effect.base);
- } else if (effect instanceof DamageEffect) {
- simpleFactor(effect, 'base');
- simpleFactor(effect, 'span');
- }
- }
-
- equipment.effects.forEach(effectFactor);
-
- if (equipment.action instanceof FireWeaponAction) {
- simpleFactor(equipment.action, 'blast');
- simpleFactor(equipment.action, 'range');
- equipment.action.effects.forEach(effectFactor);
- }
-
- if (equipment.action instanceof DeployDroneAction) {
- simpleFactor(equipment.action, 'deploy_distance');
- simpleFactor(equipment.action, 'effect_radius');
- equipment.action.effects.forEach(effectFactor);
- }
-
- if (equipment.action instanceof MoveAction) {
- simpleFactor(equipment.action, 'distance_per_power');
- }
-
- if (equipment.cooldown.overheat) {
- simpleFactor(equipment.cooldown, 'overheat', true);
- simpleFactor(equipment.cooldown, 'cooling', true);
- }
-
- // Choose a random one
- if (modifiers.length > 0) {
- let chosen = random.choice(modifiers);
- chosen();
- equipment.price = Math.ceil(equipment.price * factor * factor);
- return true;
- } else {
- return false;
- }
- }
-
/**
* Template used to generate a loot equipment
*/
@@ -193,7 +109,7 @@ module TS.SpaceTac {
this.description = description;
this.price = istep(price_base, istep(price_inflation, irepeat(price_inflation)));
this.base_modifiers = [];
- this.quality_modifiers = [standardQualityModifier];
+ this.quality_modifiers = [LootQualityModifiers.applyStandard];
}
/**