Ticket #2357: idle_worker_blink_v5.patch
File idle_worker_blink_v5.patch, 19.1 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/gui/common/colorFades.js
1 1 /* 2 DESCRIPTION : Some functions to make colo ur fades on GUI elements (f.e. used for hero and group icons)2 DESCRIPTION : Some functions to make color fades on GUI elements (f.e. used for hero and group icons) 3 3 NOTES : 4 4 */ 5 5 6 // Used for storing object names of running color fades in order to stop them, if the fade is restarted before the old ended 7 var g_colorFade = {}; 8 g_colorFade["id"] = {}; 9 g_colorFade["tick"] = {}; 6 // Used for storing information about color fades 7 var g_colorFade = {}; 10 8 11 9 /** 12 * starts fading a colour of a GUI object using the sprite argument 13 * name: name of the object which colour should be faded 14 * changeInterval: interval in ms when the next colour change should be made 15 * duration: maximal duration of the complete fade 16 * colour: RGB + opacity object with keys r,g,b and o 10 * returns the init RGB color setting 11 */ 12 function getInitColorFadeRGB() 13 { 14 var rgb = {}; 15 rgb.r = 0; 16 rgb.g = 0; 17 rgb.b = 0; 18 rgb.o = 100; 19 return rgb; 20 } 21 22 /** 23 * starts fading a color of a GUI object using the sprite argument 24 * name: name of the object which color should be faded 25 * tickInterval: interval in ms when the next color change should be made 26 * duration: maximal duration of the complete fade (if 0 it runs until it is stopped) 17 27 * fun_colorTransform: function which transform the colors; 18 * arguments: [colour object, tickCounter] 28 * arguments: [var data] 29 * restartAble [optional: if false, the fade can not be restarted; default: true 19 30 * fun_smoothRestart [optional]: a function, which returns a smooth tick counter, if the fade should be started; 20 * arguments: [tickCounter of current fade; not smaller than 1 or it restarts at 0] returns: smooth tick counter value 21 * tickCounter [optional]: should not be set by hand! - how often the function was called recursively 31 * arguments: [var data]; must return false, if smooth restart was not possible and true, if it was ok 22 32 */ 23 function fadeColour(name, changeInterval, duration, colour, fun_colorTransform, fun_smoothRestart, tickCounter)33 function startColorFade(name, tickInterval, duration, fun_colorTransform, restartAble, fun_smoothRestart) // TODO: replace restartAble = true, fun_smoothRestart = null when it is supported (spiderMonkey upgrade #1886) 24 34 { 25 35 // get the overlay 26 36 var overlay = Engine.GetGUIObjectByName(name); … … 28 38 return; 29 39 30 40 // check, if fade overlay was started just now 31 if (! tickCounter)41 if (!isColorFadeRunning(name)) 32 42 { 33 tickCounter = 1;34 43 overlay.hidden = false; 35 36 // check, if another animation is running and restart it, if it's the case 37 if (isColourFadeRunning(name)) 38 { 39 restartColourFade(name, changeInterval, duration, colour, fun_colorTransform, fun_smoothRestart, g_colorFade.tick[name]); 40 return; 41 } 44 45 // store the values into a var to make it more flexible (can be changed from every function) 46 var data = {}; 47 data.timerId = -1; 48 data.tickInterval = tickInterval; 49 data.duration = duration; 50 data.fun_colorTransform = fun_colorTransform; 51 data.restartAble = restartAble !== false; // TODO: ' !== false' and add default parameter 52 data.fun_smoothRestart = fun_smoothRestart; 53 data.tickCounter = 0; 54 data.runsUntilStop = duration == 0; 55 data.stopFade = false; 56 data.rgb = getInitColorFadeRGB(); 57 58 // store it! 59 g_colorFade[name] = data; 60 61 // start with fading 62 fadeColorTick(name); 42 63 } 64 else if (restartAble) 65 { 66 restartColorFade(name, tickInterval, duration, fun_colorTransform, restartAble, fun_smoothRestart); 67 return; 68 } 69 } 70 71 /** 72 * makes the color changes in a tick 73 * name: name of the object which color should be faded 74 */ 75 function fadeColorTick(name) 76 { 77 // make some checks 78 if (!isColorFadeRunning(name)) 79 return; 80 81 var overlay = Engine.GetGUIObjectByName(name); 82 if (!overlay) 83 return; 84 var data = g_colorFade[name]; 85 86 // change the color 87 data.fun_colorTransform(data); 43 88 44 // get colors 45 fun_colorTransform(colour, tickCounter); 46 47 // set new colour 48 overlay.sprite="colour: "+colour.r+" "+colour.g+" "+colour.b+" "+colour.o; 89 // set new color 90 var rgb = data.rgb; 91 overlay.sprite="colour: "+rgb.r+" "+rgb.g+" "+rgb.b+" "+rgb.o; 49 92 50 93 // recusive call, if duration is positive 51 duration-= changeInterval; 52 if (duration > 0 && colour.o > 0) 94 if (!data.stopFade && (data.runsUntilStop || data.duration - (data.tickInterval * data.tickCounter) > 0)) 53 95 { 54 var id = setTimeout(function() { fadeColo ur(name, changeInterval, duration, colour, fun_colorTransform, fun_smoothRestart, ++tickCounter); }, changeInterval);55 g_colorFade.id[name]= id;56 g_colorFade.tick[name] = tickCounter;96 var id = setTimeout(function() { fadeColorTick(name); }, data.tickInterval); 97 data.timerId = id; 98 data.tickCounter++; 57 99 } 58 100 else 59 101 { 60 102 overlay.hidden = true; 61 stopColo urFade(name);103 stopColorFade(name); 62 104 } 63 105 } 64 106 65 66 107 /** 67 * checks, if a colo ur fade on that object is running68 * name: name of the object which colo ur fade should be checked108 * checks, if a color fade on that object is running 109 * name: name of the object which color fade should be checked 69 110 * return: true a running fade was found 70 111 */ 71 function isColo urFadeRunning(name)112 function isColorFadeRunning(name) 72 113 { 73 return name in g_colorFade .id;114 return name in g_colorFade; 74 115 } 75 116 76 117 /** 77 * stops fading a colo ur78 * name: name of the object which colo ur fade should be stopped79 * hideOverlay : hides the overlay, if true118 * stops fading a color 119 * name: name of the object which color fade should be stopped 120 * hideOverlay [optional]: hides the overlay, if true [default: true] 80 121 * return: true a running fade was stopped 81 122 */ 82 function stopColo urFade(name, hideOverlay)123 function stopColorFade(name, hideOverlay) //TODO: add 'hideOverlay = true' when its supported (spiderMonkey upgrade #1886) 83 124 { 84 // check, if a colo ur fade is running85 if (!isColo urFadeRunning(name))125 // check, if a color fade is running 126 if (!isColorFadeRunning(name)) 86 127 return false; 87 128 88 129 // delete the timer 89 clearTimeout(g_colorFade .id[name]);90 delete g_colorFade .id[name];91 delete g_colorFade.tick[name]; 92 130 clearTimeout(g_colorFade[name].timerId); 131 delete g_colorFade[name]; 132 133 hideOverlay = hideOverlay !== false; // TODO: remove this line and add default value for hideOverlay 93 134 // get the overlay and hide it 94 135 if (hideOverlay) 95 136 { 96 137 var overlay = Engine.GetGUIObjectByName(name); 97 if (overlay)138 if (overlay) 98 139 overlay.hidden = true; 99 140 } 100 141 return true; … … 101 142 } 102 143 103 144 /** 104 * restarts a colo ur fade105 * see paramter in fadeColourfunction145 * restarts a color fade 146 * see paramter in startColorFade function 106 147 */ 107 function restartColo urFade(name, changeInterval, duration, colour, fun_colorTransform, fun_smoothRestart, tickCounter)148 function restartColorFade(name) 108 149 { 109 // check, if a colo ur fade is running110 if (!isColo urFadeRunning(name))150 // check, if a color fade is running 151 if (!isColorFadeRunning(name)) 111 152 return false; 112 153 154 var data = g_colorFade[name]; 113 155 // check, if fade can be restarted smoothly 114 if ( fun_smoothRestart)156 if (data.fun_smoothRestart) 115 157 { 116 tickCounter = fun_smoothRestart(colour, tickCounter); 117 // set new function to existing timer 118 var fun = function() { fadeColour(name, changeInterval, duration, colour, fun_colorTransform, fun_smoothRestart, tickCounter); }; 119 setNewTimerFunction(g_colorFade.id[name], fun); 158 // if call was too late 159 if (!data.fun_smoothRestart(data)) 160 { 161 data.rgb = getInitColorFadeRGB(); // set RGB start values 162 data.tickCounter = 0; 163 } 120 164 } 121 165 // stop it and restart it 122 166 else 123 167 { 124 stopColo urFade(name, true);125 fadeColour(name, changeInterval, duration, colour, fun_colorTransform);168 stopColorFade(name, false); 169 startColorFade(name, data.changeInterval, data.duration, data.fun_colorTransform, data.restartAble, data.fun_smoothRestart); 126 170 } 127 171 return true; 128 172 } … … 133 177 134 178 var g_fadeAttackUnit = {}; 135 179 g_fadeAttackUnit.blinkingTicks = 50; // how many ticks should first blinking phase be 136 g_fadeAttackUnit.blinkingChangeInterval = 5; // how often should the colo ur be changed during the blinking phase137 g_fadeAttackUnit.gb ColourChangeRate = 3; // how fast should blue and green part of the colour change180 g_fadeAttackUnit.blinkingChangeInterval = 5; // how often should the color be changed during the blinking phase 181 g_fadeAttackUnit.gbcolorChangeRate = 3; // how fast should blue and green part of the color change 138 182 g_fadeAttackUnit.fadeOutStart = 100; // when should the fade out start using the opacity 139 183 g_fadeAttackUnit.opacityChangeRate = 3; // how fast should opacity change 140 184 141 /** 142 * rgb: colour object with keys r,g,b and o 143 * tickCounter: how often the fade was executed 144 */ 145 function colourFade_attackUnit(rgb, tickCounter) 185 function colorFade_attackUnit(data) 146 186 { 187 var rgb = data.rgb; 188 189 // init color 190 if (data.tickCounter == 0) 191 rgb.r = 175; 147 192 // blinking 148 if ( tickCounter < g_fadeAttackUnit.blinkingTicks)193 if (data.tickCounter < g_fadeAttackUnit.blinkingTicks) 149 194 { 150 195 // slow that process down 151 if ( tickCounter % g_fadeAttackUnit.blinkingChangeInterval != 0)196 if (data.tickCounter % g_fadeAttackUnit.blinkingChangeInterval != 0) 152 197 return; 153 198 154 rgb.g = rgb.g == 0 ? 255 : rgb.g = 0; 155 rgb.b = rgb.b == 0 ? 255 : rgb.b = 0; 199 rgb.g = rgb.g == 0 ? 255 : 0; 156 200 } 157 // wait a short time and then colo ur fade from red to grey to nothing158 else if ( tickCounter >= g_fadeAttackUnit.blinkingTicks + g_fadeAttackUnit.blinkingChangeInterval)201 // wait a short time and then color fade from red to grey to nothing 202 else if ( data.tickCounter >= g_fadeAttackUnit.blinkingTicks + g_fadeAttackUnit.blinkingChangeInterval) 159 203 { 160 rgb.g = rgb.g < 255 ? rgb.g += g_fadeAttackUnit.gbColourChangeRate * Math.sqrt(tickCounter - g_fadeAttackUnit.blinkingTicks) : 255; 161 rgb.b = rgb.g; 204 rgb.g = rgb.g < 255 ? rgb.g += g_fadeAttackUnit.gbcolorChangeRate * Math.sqrt(data.tickCounter - g_fadeAttackUnit.blinkingTicks) : 255; 162 205 163 206 // start with fading it out 164 207 if (rgb.g > g_fadeAttackUnit.fadeOutStart) 165 208 rgb.o = rgb.o > g_fadeAttackUnit.opacityChangeRate ? rgb.o -= g_fadeAttackUnit.opacityChangeRate : 0; 209 // check for end 210 if (rgb.o == 0) 211 data.stopFade = true; 166 212 } 213 rgb.b = rgb.g; 167 214 } 168 215 169 /** 170 * makes a smooth fade, if the attack on the unit has not stopped yet 171 * rgb: colour object with keys r,g,b and o 172 * tickCounter: how often the fade was executed 173 */ 174 function smoothColourFadeRestart_attackUnit(rgb, tickCounter) 216 function smoothColorFadeRestart_attackUnit(data) 175 217 { 176 218 // check, if in blinking phase 177 if ( tickCounter < g_fadeAttackUnit.blinkingTicks)219 if (data.tickCounter < g_fadeAttackUnit.blinkingTicks) 178 220 { 179 // get rgb to current state 180 for (var i = 1; i <= tickCounter; i++) 181 colourFade_attackUnit(rgb, i); 182 // set the tick counter back to start 183 return (tickCounter % (g_fadeAttackUnit.blinkingChangeInterval * 2)) + 1; 221 data.tickCounter = data.tickCounter % (g_fadeAttackUnit.blinkingChangeInterval * 2); 222 data.rgb.o = getInitColorFadeRGB().o; 223 return true; 184 224 } 185 return 1;225 return false; 186 226 } 187 227 188 //[END] of hero fade functions 189 No newline at end of file 228 //[END] of hero fade functions 229 //[START] idle workers icon 230 231 function colorFade_IdleWorker(data) 232 { 233 var rgb = data.rgb; 234 // init color 235 if (data.tickCounter == 0) 236 { 237 rgb.r = 255; 238 rgb.g = 255; 239 rgb.b = 255; 240 } 241 // hide it every tick 242 if (data.tickCounter % 2 == 0) 243 rgb.o = 0; 244 else 245 rgb.o = 100; 246 } 247 248 //[END] of idle workers icon functions 249 No newline at end of file -
binaries/data/mods/public/gui/session/session.js
486 486 487 487 updateHero(); 488 488 updateGroups(); 489 updateIdleWorkerButton(); 489 490 updateDebug(); 490 491 updatePlayerDisplay(); 491 492 updateSelectionDetails(); … … 499 500 if (battleState) 500 501 global.music.setState(global.music.states[battleState]); 501 502 503 }; 504 505 /** 506 * updates the idle worker button 507 */ 508 function updateIdleWorkerButton() 509 { 510 var simState = GetSimState(); 511 var idleUnitsCounter = simState.players[Engine.GetPlayerID()].idleWorkerButtonCount; 512 // set color fade and label 513 if (idleUnitsCounter > 0) 514 { 515 startColorFade("idleWorkerOverlay", 750, 0, colorFade_IdleWorker, false); 516 var label = Engine.GetGUIObjectByName("idleWorkerLabel") 517 label.caption = idleUnitsCounter; 518 label.hidden = false; 519 } 520 else 521 { 522 stopColorFade("idleWorkerOverlay"); 523 var label = Engine.GetGUIObjectByName("idleWorkerLabel"); 524 label.hidden = true; 525 } 502 526 } 503 527 528 504 529 /** 505 530 * updates a status bar on the GUI 506 531 * nameOfBar: name of the bar … … 595 620 { 596 621 g_previousHeroHitPoints = heroState.hitpoints; 597 622 // trigger the animation 598 fadeColour("heroHitOverlay", 100, 10000, {"r": 175,"g": 0,"b": 0,"o": 100}, colourFade_attackUnit, smoothColourFadeRestart_attackUnit);623 startColorFade("heroHitOverlay", 100, 0, colorFade_attackUnit, true, smoothColorFadeRestart_attackUnit); 599 624 return; 600 625 } 601 626 } -
binaries/data/mods/public/gui/session/session.xml
956 956 tooltip="Find idle worker" 957 957 hotkey="selection.idleworker" 958 958 > 959 <!-- TODO: should highlight the button if there's non-zero idle workers -->960 959 <object size="0 0 100% 100%" type="image" sprite="idleWorker" ghost="true" /> 961 <action on="Press">findIdleUnit(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action> 960 <object name="idleWorkerOverlay" hidden="true" type="image" ghost="true" size="2 2 100%-2 100%-2"/> 961 <object name="idleWorkerLabel" type="text" style="groupIconsText" size="0 0 100% 100%" ghost="true"/> 962 <action on="Press">findIdleUnit(["Worker", "Trade", "FishingBoat", "Healer"]);</action> 962 963 </object> 963 964 </object> 964 965 </object> -
binaries/data/mods/public/simulation/components/GuiInterface.js
89 89 "team": cmpPlayer.GetTeam(), 90 90 "teamsLocked": cmpPlayer.GetLockTeams(), 91 91 "cheatsEnabled": cmpPlayer.GetCheatsEnabled(), 92 "idleWorkerButtonCount": cmpPlayer.GetIdleWorkerButtonCount(), 92 93 "phase": phase, 93 94 "isAlly": allies, 94 95 "isMutualAlly": mutualAllies, … … 1973 1974 "SetWallPlacementPreview": 1, 1974 1975 "GetFoundationSnapData": 1, 1975 1976 "PlaySound": 1, 1977 "GetIdleWorkerButtonCount": 1, 1976 1978 "FindIdleUnits": 1, 1977 1979 "GetTradingRouteGain": 1, 1978 1980 "GetTradingDetails": 1, -
binaries/data/mods/public/simulation/components/Player.js
36 36 this.gatherRateMultiplier = 1; 37 37 this.cheatsEnabled = false; 38 38 this.cheatTimeMultiplier = 1; 39 this.idleWorkerButtonCount = 0; 39 40 this.heroes = []; 40 41 Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager).CheckConquestCriticalEntities(); 41 42 }; … … 560 561 if (index >= 0) 561 562 this.heroes.splice(index, 1); 562 563 } 564 565 // check, if new idle worker is gone 566 var cmpUnitAI = Engine.QueryInterface(msg.entity, IID_UnitAI); 567 if (cmpUnitAI) 568 if (cmpUnitAI.IsIdle() && cmpUnitAI.IsUsedForIdleWorkerButton()) 569 this.DecreaseWorkerButtonCount(); 563 570 } 564 571 if (msg.to == this.playerID) 565 572 { … … 571 578 572 579 if (cmpIdentity && cmpIdentity.HasClass("Hero")) 573 580 this.heroes.push(msg.entity); 581 582 // check, if new idle worker is there 583 var cmpUnitAI = Engine.QueryInterface(msg.entity, IID_UnitAI); 584 if (cmpUnitAI) 585 if (cmpUnitAI.IsIdle() && cmpUnitAI.IsUsedForIdleWorkerButton()) 586 this.IncreaseWorkerButtonCount(); 574 587 } 575 588 }; 576 589 … … 664 677 cmpGUIInterface.PushNotification(notification); 665 678 }; 666 679 680 Player.prototype.GetIdleWorkerButtonCount = function() 681 { 682 return this.idleWorkerButtonCount; 683 }; 684 685 Player.prototype.IncreaseWorkerButtonCount = function() 686 { 687 this.idleWorkerButtonCount++; 688 }; 689 690 Player.prototype.DecreaseWorkerButtonCount = function() 691 { 692 this.idleWorkerButtonCount--; 693 if (this.idleWorkerButtonCount < 0) 694 error("Negative worker idle count for player '" + this.playerID + "'"); 695 }; 696 667 697 Engine.RegisterComponentType(IID_Player, "Player", Player); -
binaries/data/mods/public/simulation/components/UnitAI.js
123 123 }, 124 124 }; 125 125 126 // classes used for the work idle button 127 var g_idleClassNames = ["Worker", "Trade", "FishingBoat", "Healer"]; 128 126 129 // See ../helpers/FSM.js for some documentation of this FSM specification syntax 127 130 var UnitFsmSpec = { 128 131 … … 169 172 "GuardedAttacked": function(msg) { 170 173 // ignore 171 174 }, 175 176 "UnitIdleChanged": function(msg) { 177 // check if this are units which can be selected by the workes idle button 178 if(this.IsUsedForIdleWorkerButton()) 179 { 180 if(msg.idle) 181 this.IncreaseIdleWorkerButtonCount(); 182 else 183 this.DecreaseIdleWorkerButtonCount(); 184 } 185 }, 172 186 173 187 // Formation handlers: 174 188 … … 3130 3144 return Engine.QueryInterface(this.entity, IID_Heal); 3131 3145 }; 3132 3146 3147 UnitAI.prototype.IsUsedForIdleWorkerButton = function() 3148 { 3149 var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); 3150 if (!cmpIdentity) 3151 return false; 3152 // check idle class names 3153 for each(var className in g_idleClassNames) 3154 if (cmpIdentity.HasClass(className)) { 3155 return true; 3156 } 3157 // return false because all checks where negative 3158 return false; 3159 }; 3160 3133 3161 UnitAI.prototype.IsIdle = function() 3134 3162 { 3135 3163 return this.isIdle; … … 3772 3800 UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed}); 3773 3801 }; 3774 3802 3803 UnitAI.prototype.OnUnitIdleChanged = function(msg) 3804 { 3805 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 3806 if (!cmpOwnership) 3807 return; 3808 UnitFsm.ProcessMessage(this, {"type": "UnitIdleChanged", "idle": msg.idle, "player": cmpOwnership.GetOwner()}); 3809 } 3810 3775 3811 //// Helper functions to be called by the FSM //// 3776 3812 3777 3813 UnitAI.prototype.GetWalkSpeed = function() … … 5606 5642 return true; 5607 5643 }; 5608 5644 5645 UnitAI.prototype.IncreaseIdleWorkerButtonCount = function() 5646 { 5647 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); 5648 if (cmpPlayer) 5649 cmpPlayer.IncreaseWorkerButtonCount(); 5650 } 5651 5652 UnitAI.prototype.DecreaseIdleWorkerButtonCount = function() 5653 { 5654 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); 5655 if (cmpPlayer) 5656 cmpPlayer.DecreaseWorkerButtonCount(); 5657 } 5658 5609 5659 Engine.RegisterComponentType(IID_UnitAI, "UnitAI", UnitAI);