From 52d4e1274c9465b6e67ef4325c72d4799918e363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Mon, 22 May 2017 18:29:04 +0200 Subject: [PATCH] Improved cooldown representation --- README.md | 4 +- TODO | 7 +- graphics/ui/battle.svg | 140 +++++++++++++++---- out/assets/images/battle/action-cooldown.png | Bin 708 -> 2907 bytes src/core/Cooldown.spec.ts | 9 +- src/core/Cooldown.ts | 21 ++- src/core/Ship.spec.ts | 2 +- src/core/actions/BaseAction.spec.ts | 13 +- src/core/actions/BaseAction.ts | 22 +++ src/core/actions/EndTurnAction.ts | 4 + src/core/ai/TacticalAIHelpers.spec.ts | 8 +- src/core/ai/TacticalAIHelpers.ts | 2 +- src/core/equipments/GatlingGun.ts | 2 +- src/core/equipments/PowerDepleter.ts | 2 +- src/core/equipments/RepairDrone.ts | 2 +- src/core/equipments/RocketEngine.ts | 2 +- src/core/equipments/SubMunitionMissile.ts | 2 +- src/ui/battle/ActionIcon.ts | 62 ++++---- src/ui/battle/ActionTooltip.spec.ts | 3 +- src/ui/battle/ActionTooltip.ts | 24 +--- 20 files changed, 230 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index af59efa..a32a4a4 100644 --- a/README.md +++ b/README.md @@ -109,8 +109,8 @@ item is then temporarily disabled (no more effects and cannot be used), until th Equipments may overheat, and need to cooldown for some time, during which it cannot be used. If an equipment has "overheat 2 / cooldown 3", using it twice in the same turn will cause it to -overheat. It then cannot be used for the next three turns. Using this equipment only once per turn -is safe, and will never overheat it. +overheat. It then needs three "end of turns" to cool down and be available again. Using this equipment +only once per turn is safe, and will never overheat it. If an equipment has multiple actions associated, any of these actions will increase the shared heat. diff --git a/TODO b/TODO index 067cd36..20312b9 100644 --- a/TODO +++ b/TODO @@ -20,11 +20,12 @@ * Arena: display effects description instead of attribute changes * Arena: add auto-move to attack * Arena: fix effects originating from real ship location instead of current sprite (when AI fires then moves) -* Actions: separate overheat and cooldown display * Actions: show power usage/recovery in power bar, on action hover * Actions: fix targetting not resetting when using keyboard shortcuts * Suspend AI operation when the game is paused (window not focused) * Add permanent effects to ship models to ease balancing +* Add actions with cost dependent of distance (like current move actions) +* Keep move actions out of arena borders * Find incentives to move from starting position * Outcome: add battle statistics and/or honors * Outcome: disable the loot button if there is no loot @@ -54,8 +55,10 @@ * Campaign: Missions/quests system * Campaign: Main story arc -Weapon ideas: +Equipment ideas: * Shield with toggle effect that absorbs damage in an area +* Shield stealing ability +* Drive with minimal distance * Cooldown drone or ability Later, if possible: diff --git a/graphics/ui/battle.svg b/graphics/ui/battle.svg index 73883d3..37badfd 100644 --- a/graphics/ui/battle.svg +++ b/graphics/ui/battle.svg @@ -1069,6 +1069,84 @@ y="121.98493" transform="rotate(45)" /> + + + + + + + + + + + + + + + + + inkscape:label="Action icon cooldown" + style="display:inline"> + id="g5353" + inkscape:export-filename="/home/michael/workspace/perso/spacetac/out/assets/images/battle/action-cooldown.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> - - + r="28.59375" + cy="-50.982056" + cx="252.2561" + id="path4218" + style="fill:#545252;fill-opacity:0.72765958;fill-rule:evenodd;stroke:none;stroke-width:0.9375px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + + 2 ze|Sr;?1cp{4K0eIDceN~RE0O~Tckz7LjIw`axEoQvEaG)9q5s_pf(agjERLvB6TFuN1 z000pY01$|f5D5VY5gCXAe=~;=!W<#axDbBL%%6zJ)o!=jIeYeO4I8xhMg(K4)#A@S z`)p@fmWNdJ*&O3v)+v2kQX&=UDnK$3QB@_P6@3rx7!gzziHMMh3DL9n4aW@Z{cl1D z|3*abS5!bgSnVE=4R*|TxDyq9x;+|6vM~L9AF^L`2P^nU$t`ln{3j z^BwQ~!jU6Kx)(2AeBclMK*6n6%c<%Z5&byF`15X6J)2@&$|+T5CL3|vje>{(W~w4d zdfs#d5XVCZ3uRd@zVgZ|RlD8(+8_UG1)n%^!tL0xW4EgQe?_e8U(|Iyky2Vvkqt-5 zM}&b{R@J1c;|4I{oSW}R=g*Oz97qobpPBJymk>%Xb%`cO=1 z(Nq&6ZVIsge*lPRl5@%_Eyfu4*LD3GGavi>^UsIiJ^}fj7QS)gMiT)3OjUnY_vY+^ zh-@0mewqH-tpJe0Y(FtKnfcn&Pd|O@(xppjZTqhXZnavj+wC4y)t9TPdMU@alyj~( zlV#Vk63h%h5n#eGFAwb4aqZ;ElM8Eu*jksSPN%a|e?)$m>iVZS#<-tbiX{nzzZ57PSl!%7=uKn8=UU;E1 zJw3gu;ma1LMx!wT0LNmCKa`Y~RAgOg+h#yTvgEv!Vmzj*$INU5zNB;Y!|Btfy{hg@ zDg8upf3|+QxanPaEr@72=a_Q_5&21sasTPlr~S&`R|I2KRl|t*{hZRbH0SDZr;Cpn z)tsxG^LL2odsS7f&Se4sXti2QM7t%W7jw=iBI$8$1pXBCw^~VZ#+1^F&beK!R*M1p zf;*i~6A{NnWI{!{s=Ac|)jd&F(VT0|`3Mp1e_dW)E&+Oi5da3w?3pYwl2h7L+0;fs zL=)90sw0xpcT-A(0DwF>Imsb}an1R!>$=`0Iaja=GpdbXW`IPVoih>nU}9q8*2+=p zu$t`!)o5m0Iau8VBC7Vz*7h;;@YvXxBW5lEU_?ZQ%uI-ATUfV`fmt@QmE+=)VvG#{ zf7q$2r2*&`4$fb}%)kItLFv#nKexC=x?W-fdPf81y^{we4D(VK6+xdiaXb7?Efa$Z$G@y`8*oGalz zrPM6~5p(H7xC8(f%d(t@{!Vb!b*HDN?fK`QS48xx`Xf;V70Fv|T{bgh?;Ab@7ee?) z@BR5RXU;4_U+|Z$sEF7xvk!_8K5)(r5VLzS!`?W=?3{B0A%yo4@k2!He?V`q4*+Yb zhtt#3`rLERMI;haJ!)p9Zqh>deIW1sKq!i(5W?R%=RQ1h=FHMv4c0thd-v|0SJewe zQT(g(-m~|Ot*~uG#1&T#&inTO;D0{;_~QjwW2~<%Kkar~$H&L3q2b{!0z74^-!`+P zBDz_1n;EimAr!?>D2o4Ve>57unwy)ueD2)2xVG&**V{{%F6HCLkKZwX3W>(eY~0L} zs%|>bW`^XP_aO|05H5xg{-G#}kKTRv-8=Vcf4`;2_UzfSU}o<(8jZgXA$;b%A7tnJ zX3E0)mi6BIK_9~Z`4D~y03Qqw53fe$wcIzOYPZ`qI5=33jg8F{f6)Q}8~}hl(0g0v ziJxC1BC>PAhcHwW#qUB0f17juugjM&&z(Jc_P$Be*QStHu3XWVUw*k-T3Wj0y}yY> zPXoYyQB~`eRG(DzCicDzMKRPUii^H4c4lVg_w9E3YhTlNV9wlbxApMh!^__LTh6)9 z*|~rKhXKHunVRaKf9zz)%#fJ9^M0UF6h))a_z!Y!3K9Q%et!PuxpU_pm<~VGCgI}6 zi+1G5kuDM4EX(pbA}%AqVI&$x09Eb1IsCYUn;8-j_m`c)P!vl=2>#Z)VV`{B?8+iWw`TXjuuP%J?#TT>8{M(`^t`hSAB90Mri2wwM z&_D2p^_&Z0?>R(7CT8!QD_sZ!p(waf6qkJnQ_TD?&bbfw?AbH>#v5;}I}7|qmpo3N zJ{`<#B*wU(e~7-9QhHHyK9WU7Bo@ zf3s!fpCb{088b67^BrPdK%#4i_z^Q-f=zUd=PP}ke>ic1CnhFJA{t`mK~)`g&h5-O zKZS_nsyb?BB>*(~&vc1snE>V#;JS0}79!pjk$FU1h%qkC%*<5nc6;+&)Vg24D_8OA zx^6h<%DS$LqA0wXv4|i*?<$^|Y0f!1=VH#eDvF}px8$lPJWBom_o-jJNA~iX00000 MNkvXX1g=70f+tCg1^@s6 delta 645 zcmV;00($-17Q_W1iBL{Q4GJ0x0000DNk~Le0000I0000I2nGNE09MY9SCJu1e*!^C zL_t(IjjhvPXi`xe2k_s$JJ)~dRg`s&{eiSAE0(yuG#G;n=U7qrP*B7kD(EeUXc1!% zzVu{o>wOeGwTE7!P|`8__qGX5)*m&THkD21Rns%?y`CPzTZ6S}^nLun`JCVR{Wt*s zDb!v?LWohSO2a$#idSxkJ+dehf22YijLs0$5X}l@ri6VVzn{?eZ~yS%vT(N;UvqD* zMNui01R2+X(Hp^J8<4EdkwugJSm5E@p|IaiHCt!VpUBJ|e65g7Jcz$q;MU)Up_2U$ z&}{y`iKda^NZ&YrZtCQ%tG-zPGT*|Kj&P~!EhfJ{`S|n^mwvwl62^a>e+SZNfWL4f zH*oR#6zAYx0|3yinP8zb9e?@kKm-6l!Wa@S9$Pm)yqP8i!YU9h;o*ENdV2j`D3F93y+SIvd$4Upu2-R)FZL;r zEJ{Si^^OpLUz-xe22r3ce-+9goxWp;R_j2k)uk1P(HKK)zeDO2Qn8$9=syusAiY(; za@aMxsI_qIcS9rS9`r;kHa@CA6h#SU{&>JPemO@YRa+2iKb7klI~%a@R9S%l0Osb+ zVcX=T*`uB-Ii%9<+lh%E&GC~rXPmyFNUOf<(-K0c!k7G+cqn);TebAuUCw-FoJD#cq$e00000NkvXXu0mjfQVKET diff --git a/src/core/Cooldown.spec.ts b/src/core/Cooldown.spec.ts index 2bb01eb..c0a5258 100644 --- a/src/core/Cooldown.spec.ts +++ b/src/core/Cooldown.spec.ts @@ -7,7 +7,7 @@ module TS.SpaceTac.Specs { cooldown.use(); expect(cooldown.canUse()).toBe(true); - cooldown.configure(2, 2); + cooldown.configure(2, 3); expect(cooldown.canUse()).toBe(true); cooldown.use(); @@ -25,11 +25,14 @@ module TS.SpaceTac.Specs { cooldown.cool(); expect(cooldown.canUse()).toBe(true); - /*cooldown.configure(1, 0); + cooldown.configure(1, 0); expect(cooldown.canUse()).toBe(true); cooldown.use(); - expect(cooldown.canUse()).toBe(false);*/ + expect(cooldown.canUse()).toBe(false); + + cooldown.cool(); + expect(cooldown.canUse()).toBe(true); }); }); } \ No newline at end of file diff --git a/src/core/Cooldown.ts b/src/core/Cooldown.ts index 5985199..67e4525 100644 --- a/src/core/Cooldown.ts +++ b/src/core/Cooldown.ts @@ -12,10 +12,10 @@ module TS.SpaceTac { // Maximum number of uses allowed per turn before overheating (0 for unlimited) overheat = 0 - // Number of turns needed to cooldown when overheated - cooling = 0 + // Number of "end turn" needed to cooldown when overheated + cooling = 1 - constructor(overheat = 0, cooling = 0) { + constructor(overheat = 0, cooling = 1) { this.configure(overheat, cooling); } @@ -41,7 +41,11 @@ module TS.SpaceTac { * Check the number of uses before overheating */ getRemainingUses(): number { - return (this.heat > 0) ? 0 : (this.overheat - this.uses); + if (this.overheat) { + return (this.heat > 0) ? 0 : (this.overheat - this.uses); + } else { + return Infinity; + } } /** @@ -49,7 +53,7 @@ module TS.SpaceTac { */ configure(overheat: number, cooling: number) { this.overheat = overheat; - this.cooling = cooling; + this.cooling = Math.max(1, cooling); this.reset(); } @@ -60,7 +64,7 @@ module TS.SpaceTac { if (this.overheat) { this.uses += 1; if (this.uses >= this.overheat) { - this.heat = this.cooling + 1; + this.heat = this.cooling; } } } @@ -69,10 +73,13 @@ module TS.SpaceTac { * Apply one cooling-down step if necessary */ cool(): void { - this.uses = 0; if (this.heat > 0) { this.heat -= 1; } + + if (this.heat == 0) { + this.uses = 0; + } } /** diff --git a/src/core/Ship.spec.ts b/src/core/Ship.spec.ts index 34d0987..9b0d091 100644 --- a/src/core/Ship.spec.ts +++ b/src/core/Ship.spec.ts @@ -38,7 +38,7 @@ module TS.SpaceTac.Specs { it("applies equipment cooldown", function () { let ship = new Ship(); let equipment = new Equipment(SlotType.Weapon); - equipment.cooldown.configure(1, 1); + equipment.cooldown.configure(1, 2); ship.addSlot(SlotType.Weapon).attach(equipment); expect(equipment.cooldown.canUse()).toBe(true, 1); diff --git a/src/core/actions/BaseAction.spec.ts b/src/core/actions/BaseAction.spec.ts index 024ba33..753e2bc 100644 --- a/src/core/actions/BaseAction.spec.ts +++ b/src/core/actions/BaseAction.spec.ts @@ -32,27 +32,38 @@ module TS.SpaceTac { let ship = new Ship(); expect(action.checkCannotBeApplied(ship)).toBe(null); + expect(action.getUsesBeforeOverheat()).toBe(Infinity); equipment.cooldown.use(); expect(action.checkCannotBeApplied(ship)).toBe(null); + expect(action.getUsesBeforeOverheat()).toBe(Infinity); - equipment.cooldown.configure(2, 2); + equipment.cooldown.configure(2, 3); expect(action.checkCannotBeApplied(ship)).toBe(null); + expect(action.getUsesBeforeOverheat()).toBe(2); equipment.cooldown.use(); expect(action.checkCannotBeApplied(ship)).toBe(null); + expect(action.getUsesBeforeOverheat()).toBe(1); + expect(action.getCooldownDuration()).toBe(0); equipment.cooldown.use(); expect(action.checkCannotBeApplied(ship)).toBe("overheated"); + expect(action.getUsesBeforeOverheat()).toBe(0); + expect(action.getCooldownDuration()).toBe(3); equipment.cooldown.cool(); expect(action.checkCannotBeApplied(ship)).toBe("overheated"); + expect(action.getCooldownDuration()).toBe(2); equipment.cooldown.cool(); expect(action.checkCannotBeApplied(ship)).toBe("overheated"); + expect(action.getCooldownDuration()).toBe(1); equipment.cooldown.cool(); expect(action.checkCannotBeApplied(ship)).toBe(null); + expect(action.getCooldownDuration()).toBe(0); + expect(action.getCooldownDuration(true)).toBe(3); }); it("wears down equipment and power generators", function () { diff --git a/src/core/actions/BaseAction.ts b/src/core/actions/BaseAction.ts index d09d9f1..edf5573 100644 --- a/src/core/actions/BaseAction.ts +++ b/src/core/actions/BaseAction.ts @@ -21,6 +21,28 @@ module TS.SpaceTac { this.equipment = equipment; } + /** + * Get the number of turns this action is unavailable, because of overheating + */ + getCooldownDuration(estimated = false): number { + if (this.equipment) { + return estimated ? this.equipment.cooldown.cooling : this.equipment.cooldown.heat; + } else { + return 0; + } + } + + /** + * Get the number of remaining uses before overheat, infinity if there is no overheat + */ + getUsesBeforeOverheat(): number { + if (this.equipment) { + return this.equipment.cooldown.getRemainingUses(); + } else { + return Infinity; + } + } + /** * Check basic conditions to know if the ship can use this action at all * diff --git a/src/core/actions/EndTurnAction.ts b/src/core/actions/EndTurnAction.ts index 0ce2f46..edf4ab3 100644 --- a/src/core/actions/EndTurnAction.ts +++ b/src/core/actions/EndTurnAction.ts @@ -13,5 +13,9 @@ module TS.SpaceTac { battle.advanceToNextShip(); } } + + getEffectsDescription(): string { + return "End the current ship's turn.\nWill also generate power and cool down equipments."; + } } } diff --git a/src/core/ai/TacticalAIHelpers.spec.ts b/src/core/ai/TacticalAIHelpers.spec.ts index e22c1ba..8e0abd7 100644 --- a/src/core/ai/TacticalAIHelpers.spec.ts +++ b/src/core/ai/TacticalAIHelpers.spec.ts @@ -205,16 +205,16 @@ module TS.SpaceTac.Specs { let maneuver = new Maneuver(ship, weapon.action, new Target(0, 0)); expect(TacticalAIHelpers.evaluateOverheat(ship, battle, maneuver)).toEqual(0); - weapon.cooldown.configure(1, 0); + weapon.cooldown.configure(1, 1); expect(TacticalAIHelpers.evaluateOverheat(ship, battle, maneuver)).toEqual(-0.4); - weapon.cooldown.configure(1, 1); + weapon.cooldown.configure(1, 2); expect(TacticalAIHelpers.evaluateOverheat(ship, battle, maneuver)).toEqual(-0.8); - weapon.cooldown.configure(1, 2); + weapon.cooldown.configure(1, 3); expect(TacticalAIHelpers.evaluateOverheat(ship, battle, maneuver)).toEqual(-1); - weapon.cooldown.configure(2, 0); + weapon.cooldown.configure(2, 1); expect(TacticalAIHelpers.evaluateOverheat(ship, battle, maneuver)).toEqual(0); }); }); diff --git a/src/core/ai/TacticalAIHelpers.ts b/src/core/ai/TacticalAIHelpers.ts index a0fc08f..55e913a 100644 --- a/src/core/ai/TacticalAIHelpers.ts +++ b/src/core/ai/TacticalAIHelpers.ts @@ -218,7 +218,7 @@ module TS.SpaceTac { */ static evaluateOverheat(ship: Ship, battle: Battle, maneuver: Maneuver): number { if (maneuver.action.equipment && maneuver.action.equipment.cooldown.willOverheat()) { - return -Math.min(1, 0.4 * (maneuver.action.equipment.cooldown.cooling + 1)); + return -Math.min(1, 0.4 * maneuver.action.equipment.cooldown.cooling); } else { return 0; } diff --git a/src/core/equipments/GatlingGun.ts b/src/core/equipments/GatlingGun.ts index b018789..c85b57f 100644 --- a/src/core/equipments/GatlingGun.ts +++ b/src/core/equipments/GatlingGun.ts @@ -6,7 +6,7 @@ module TS.SpaceTac.Equipments { super(SlotType.Weapon, "Gatling Gun", "Mechanical weapon using loads of metal bullets propelled by guided explosions"); this.setSkillsRequirements({ "skill_material": 1 }); - this.setCooldown(irepeat(2), irepeat(1)); + this.setCooldown(irepeat(2), irepeat(2)); this.addFireAction(irepeat(3), irepeat(600), 0, [ new EffectTemplate(new DamageEffect(), { base: istep(30, irepeat(5)), span: istep(20, irepeat(5)) }) ]); diff --git a/src/core/equipments/PowerDepleter.ts b/src/core/equipments/PowerDepleter.ts index edd0353..0fa339f 100644 --- a/src/core/equipments/PowerDepleter.ts +++ b/src/core/equipments/PowerDepleter.ts @@ -6,7 +6,7 @@ module TS.SpaceTac.Equipments { super(SlotType.Weapon, "Power Depleter", "Direct-hit weapon that creates an energy well near the target, sucking its power surplus"); this.setSkillsRequirements({ "skill_energy": 1 }); - this.setCooldown(irepeat(2), irepeat(2)); + this.setCooldown(irepeat(2), irepeat(3)); this.addFireAction(irepeat(4), istep(500, irepeat(20)), 0, [ new StickyEffectTemplate(new AttributeLimitEffect("power_capacity"), { "value": irepeat(3) }, irepeat(2)) ]); diff --git a/src/core/equipments/RepairDrone.ts b/src/core/equipments/RepairDrone.ts index c6aef7e..5c4b92a 100644 --- a/src/core/equipments/RepairDrone.ts +++ b/src/core/equipments/RepairDrone.ts @@ -9,7 +9,7 @@ module TS.SpaceTac.Equipments { super(SlotType.Weapon, "Repair Drone", "Drone able to repair small hull breaches, remotely controlled by human pilots"); this.setSkillsRequirements({ "skill_human": 1 }); - this.setCooldown(irepeat(1), istep(2, irepeat(0.2))); + this.setCooldown(irepeat(1), istep(3, irepeat(0.2))); this.addDroneAction(irepeat(4), istep(300, irepeat(10)), istep(1, irepeat(0.2)), istep(100, irepeat(10)), [ new EffectTemplate(new ValueEffect("hull"), { "value": istep(30, irepeat(3)) }) ]); diff --git a/src/core/equipments/RocketEngine.ts b/src/core/equipments/RocketEngine.ts index 39fa751..50a9cb0 100644 --- a/src/core/equipments/RocketEngine.ts +++ b/src/core/equipments/RocketEngine.ts @@ -6,7 +6,7 @@ module TS.SpaceTac.Equipments { super(SlotType.Engine, "Rocket Engine", "First-era conventional deep-space engine, based on gas exhausts pushed through a nozzle"); this.setSkillsRequirements({ "skill_energy": 1 }); - this.setCooldown(irepeat(3), 0); + this.setCooldown(irepeat(2), 0); this.addAttributeEffect("initiative", 1); this.addMoveAction(istep(200, irepeat(20))); } diff --git a/src/core/equipments/SubMunitionMissile.ts b/src/core/equipments/SubMunitionMissile.ts index d434f1f..f733b7d 100644 --- a/src/core/equipments/SubMunitionMissile.ts +++ b/src/core/equipments/SubMunitionMissile.ts @@ -6,7 +6,7 @@ module TS.SpaceTac.Equipments { super(SlotType.Weapon, "SubMunition Missile", "Explosive missile releasing small shelled payloads, that will in turn explode on impact"); this.setSkillsRequirements({ "skill_material": 1 }); - this.setCooldown(irepeat(1), irepeat(0)); + this.setCooldown(irepeat(1), 0); this.addFireAction(irepeat(4), istep(500, irepeat(20)), istep(150, irepeat(5)), [ new EffectTemplate(new DamageEffect(), { base: istep(30, irepeat(2)), span: istep(2, irepeat(1)) }) ]); diff --git a/src/ui/battle/ActionIcon.ts b/src/ui/battle/ActionIcon.ts index c851511..7f79999 100644 --- a/src/ui/battle/ActionIcon.ts +++ b/src/ui/battle/ActionIcon.ts @@ -2,40 +2,41 @@ module TS.SpaceTac.UI { // Icon to activate a ship capability (move, fire...) export class ActionIcon extends Phaser.Button { // Link to the parent bar - bar: ActionBar; + bar: ActionBar // Link to the parent battle view - battleview: BattleView; + battleview: BattleView // Related ship - ship: Ship; + ship: Ship // Related game action - action: BaseAction; + action: BaseAction // True if the action can be used - active: boolean; + active: boolean // True if the action is selected for use - selected: boolean; + selected: boolean // True if an action is currently selected, and this one won't be available after its use - fading: boolean; + fading: boolean // Current targetting - private targetting: Targetting | null; + private targetting: Targetting | null // Action icon - image representing the action - private layer_icon: Phaser.Image; + private layer_icon: Phaser.Image // Layer applied when the action is active - private layer_active: Phaser.Image; + private layer_active: Phaser.Image // Layer applied when the action is selected - private layer_selected: Phaser.Image; + private layer_selected: Phaser.Image // Cooldown indicators - private layer_cooldown: Phaser.Group + private cooldown: Phaser.Image + private cooldown_count: Phaser.Text // Create an icon for a single ship action constructor(bar: ActionBar, x: number, y: number, ship: Ship, action: BaseAction, position: number) { @@ -69,8 +70,12 @@ module TS.SpaceTac.UI { this.addChild(this.layer_icon); // Cooldown layer - this.layer_cooldown = new Phaser.Group(this.game); - this.addChild(this.layer_cooldown); + this.cooldown = new Phaser.Image(this.game, this.width / 2, this.height / 2, "battle-action-cooldown"); + this.cooldown.anchor.set(0.5, 0.5); + this.cooldown_count = new Phaser.Text(this.game, 0, 0, "", { align: "center", font: "36pt Arial", fill: "#aaaaaa" }); + this.cooldown_count.anchor.set(0.5, 0.5); + this.cooldown.addChild(this.cooldown_count); + this.addChild(this.cooldown); // Events this.battleview.tooltip.bind(this, filler => { @@ -169,23 +174,26 @@ module TS.SpaceTac.UI { setSelected(selected: boolean) { this.selected = selected; this.battleview.animations.setVisible(this.layer_selected, this.selected, 300); + this.updateCooldownStatus(); } // Update the cooldown status updateCooldownStatus(): void { - this.layer_cooldown.removeAll(); - if (this.action.equipment) { - let cooldown = this.action.equipment.cooldown; - let count = cooldown.heat ? cooldown.heat : (cooldown.willOverheat() ? cooldown.cooling + 1 : 0); - if (count) { - let positions = UITools.evenlySpace(68, 18, count); - range(count).forEach(i => { - let dot = new Phaser.Image(this.game, 10 + positions[i], 10, "battle-action-cooldown"); - dot.anchor.set(0.5, 0.5); - dot.alpha = cooldown.heat ? 1 : 0.5; - this.layer_cooldown.add(dot); - }); - } + let remaining = this.action.getUsesBeforeOverheat(); + if (this.selected && remaining == 1) { + // will overheat, hint at the cooldown time + let cooldown = this.action.getCooldownDuration(true); + this.cooldown.scale.set(0.7); + this.cooldown_count.text = `${cooldown}`; + this.battleview.animations.setVisible(this.cooldown, true, 300); + } else if (remaining == 0) { + // overheated, show cooldown time + let cooldown = this.action.getCooldownDuration(false); + this.cooldown.scale.set(1); + this.cooldown_count.text = `${cooldown}`; + this.battleview.animations.setVisible(this.cooldown, true, 300); + } else { + this.battleview.animations.setVisible(this.cooldown, false, 300); } } diff --git a/src/ui/battle/ActionTooltip.spec.ts b/src/ui/battle/ActionTooltip.spec.ts index 4dd9466..e366d55 100644 --- a/src/ui/battle/ActionTooltip.spec.ts +++ b/src/ui/battle/ActionTooltip.spec.ts @@ -34,7 +34,8 @@ module TS.SpaceTac.UI.Specs { tooltip.hide(); ActionTooltip.fill(tooltip.getFiller(), ship, action3, 2); checkText((tooltip).container.content.children[1], "End turn"); - checkText((tooltip).container.content.children[2], "[ space ]"); + checkText((tooltip).container.content.children[2], "End the current ship's turn.\nWill also generate power and cool down equipments."); + checkText((tooltip).container.content.children[3], "[ space ]"); }); }); } diff --git a/src/ui/battle/ActionTooltip.ts b/src/ui/battle/ActionTooltip.ts index e3dd28a..e437be5 100644 --- a/src/ui/battle/ActionTooltip.ts +++ b/src/ui/battle/ActionTooltip.ts @@ -34,25 +34,15 @@ module TS.SpaceTac.UI { if (action.equipment && action.equipment.cooldown.overheat) { let cooldown = action.equipment.cooldown; - let uses = cooldown.getRemainingUses(); - let uses_message = ""; - if (uses == 0) { - uses_message = "Overheated !"; - if (cooldown.heat == 1) { - uses_message += " Available next turn"; - } else if (cooldown.heat == 2) { - uses_message += " Unavailable next turn"; + if (cooldown.heat > 0) { + filler.addText(150, 90, "Cooling down ...", "#c9604c", 20); + } else if (cooldown.willOverheat() && cost != "Not enough power") { + if (cooldown.cooling > 1) { + let turns = cooldown.cooling; + filler.addText(150, 90, `Unavailable for ${turns} turn${turns > 1 ? "s" : ""} if used`, "#c9604c", 20); } else { - uses_message += ` Unavailable next ${cooldown.heat - 1} turns`; + filler.addText(150, 90, "Unavailable until next turn if used", "#c9604c", 20); } - } else { - uses_message = uses == 1 ? "Overheats if used" : `${uses} uses before overheat`; - if (cooldown.cooling) { - uses_message += ` (for ${cooldown.cooling} turn${cooldown.cooling ? "s" : ""})`; - } - } - if (uses_message) { - filler.addText(150, 90, uses_message, "#c9604c", 20); } }