Ticket #2357: idle_worker_blink.patch
File idle_worker_blink.patch, 16.9 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 * starts fading a color of a GUI object using the sprite argument 11 * name: name of the object which color should be faded 12 * tickInterval: interval in ms when the next color change should be made 13 * duration: maximal duration of the complete fade (if 0 it runs until it is stopped) 17 14 * fun_colorTransform: function which transform the colors; 18 * arguments: [colour object, tickCounter] 15 * arguments: [color object, tickCounter] 16 * restartAble [optional: if false, the fade can not be restarted; default: true 19 17 * fun_smoothRestart [optional]: a function, which returns a smooth tick counter, if the fade should be started; 20 18 * 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 recursively22 19 */ 23 function fadeColour(name, changeInterval, duration, colour, fun_colorTransform, fun_smoothRestart, tickCounter)20 function startColorFade(name, tickInterval, duration, fun_colorTransform, restartAble, fun_smoothRestart) 24 21 { 25 22 // get the overlay 26 23 var overlay = Engine.GetGUIObjectByName(name); … … 28 25 return; 29 26 30 27 // check, if fade overlay was started just now 31 if (! tickCounter)28 if (!isColorFadeRunning(name)) 32 29 { 33 tickCounter = 1;34 30 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 } 31 32 // store the values into a var to make it more flexible (can be changed from every function) 33 var data = {}; 34 data.timerId = -1; 35 data.tickInterval = tickInterval; 36 data.duration = duration; 37 data.fun_colorTransform = fun_colorTransform; 38 data.restartAble = restartAble !== false; 39 data.fun_smoothRestart = fun_smoothRestart; 40 data.tickCounter = 1; 41 data.runsUntilStop = duration == 0; 42 data.stopFade = false; 43 var rgb = {"r": 255,"g": 255,"b": 255,"o": 100}; 44 data.rgb = rgb; 45 // store it! 46 g_colorFade[name] = data; 47 48 // start with fading 49 fadeColorTick(name); 42 50 } 43 44 // get colors45 fun_colorTransform(colour, tickCounter);46 47 // set new colour48 overlay.sprite="colour: "+colour.r+" "+colour.g+" "+colour.b+" "+colour.o; 51 else if (restartAble) 52 { 53 restartColorFade(name, tickInterval, duration, fun_colorTransform, restartAble, fun_smoothRestart); 54 return; 55 } 56 } 49 57 58 /** 59 * makes the color changes in a tick 60 * name: name of the object which color should be faded 61 */ 62 function fadeColorTick(name) 63 { 64 // make some checks 65 if (!isColorFadeRunning(name)) 66 return; 67 68 var overlay = Engine.GetGUIObjectByName(name); 69 if (!overlay) 70 return; 71 72 var data = g_colorFade[name]; 73 74 // change the color 75 data.fun_colorTransform(data); 76 77 // set new color 78 var rgb = data.rgb; 79 overlay.sprite="colour: "+rgb.r+" "+rgb.g+" "+rgb.b+" "+rgb.o; 80 50 81 // recusive call, if duration is positive 51 duration-= changeInterval; 52 if (duration > 0 && colour.o > 0) 82 if (!data.stopFade && (data.runsUntilStop || data.duration - (data.tickInterval * data.tickCounter) > 0)) 53 83 { 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;84 var id = setTimeout(function() { fadeColorTick(name); }, data.tickInterval); 85 data.timerId = id; 86 data.tickCounter++; 57 87 } 58 88 else 59 89 { 60 90 overlay.hidden = true; 61 stopColo urFade(name);91 stopColorFade(name); 62 92 } 63 93 } 64 94 65 66 95 /** 67 * checks, if a colo ur fade on that object is running68 * name: name of the object which colo ur fade should be checked96 * checks, if a color fade on that object is running 97 * name: name of the object which color fade should be checked 69 98 * return: true a running fade was found 70 99 */ 71 function isColo urFadeRunning(name)100 function isColorFadeRunning(name) 72 101 { 73 return name in g_colorFade .id;102 return name in g_colorFade; 74 103 } 75 104 76 105 /** 77 * stops fading a colo ur78 * name: name of the object which colo ur fade should be stopped79 * hideOverlay : hides the overlay, if true106 * stops fading a color 107 * name: name of the object which color fade should be stopped 108 * hideOverlay [optional]: hides the overlay, if true [default: true] 80 109 * return: true a running fade was stopped 81 110 */ 82 function stopColo urFade(name, hideOverlay)111 function stopColorFade(name, hideOverlay) 83 112 { 84 // check, if a colo ur fade is running85 if (!isColo urFadeRunning(name))113 // check, if a color fade is running 114 if (!isColorFadeRunning(name)) 86 115 return false; 87 116 88 117 // delete the timer 89 clearTimeout(g_colorFade .id[name]);90 delete g_colorFade .id[name];91 delete g_colorFade.tick[name]; 92 118 clearTimeout(g_colorFade[name].timerId); 119 delete g_colorFade[name]; 120 121 hideOverlay = hideOverlay !== false; 93 122 // get the overlay and hide it 94 123 if (hideOverlay) 95 124 { 96 125 var overlay = Engine.GetGUIObjectByName(name); 97 if (overlay)126 if (overlay) 98 127 overlay.hidden = true; 99 128 } 100 129 return true; … … 101 130 } 102 131 103 132 /** 104 * restarts a colo ur fade105 * see paramter in fadeColourfunction133 * restarts a color fade 134 * see paramter in startColorFade function 106 135 */ 107 function restartColo urFade(name, changeInterval, duration, colour, fun_colorTransform, fun_smoothRestart, tickCounter)136 function restartColorFade(name) 108 137 { 109 // check, if a colo ur fade is running110 if (!isColo urFadeRunning(name))138 // check, if a color fade is running 139 if (!isColorFadeRunning(name)) 111 140 return false; 112 141 142 var data = g_colorFade[name]; 113 143 // check, if fade can be restarted smoothly 114 if ( fun_smoothRestart)144 if (data.fun_smoothRestart) 115 145 { 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); 146 data.fun_smoothRestart(data); 120 147 } 121 148 // stop it and restart it 122 149 else 123 150 { 124 stopColo urFade(name, true);125 fadeColour(name, changeInterval, duration, colour, fun_colorTransform);151 stopColorFade(name, false); 152 startColorFade(name, data.changeInterval, data.duration, data.fun_colorTransform, data.restartAble, data.fun_smoothRestart); 126 153 } 127 154 return true; 128 155 } … … 133 160 134 161 var g_fadeAttackUnit = {}; 135 162 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 change163 g_fadeAttackUnit.blinkingChangeInterval = 5; // how often should the color be changed during the blinking phase 164 g_fadeAttackUnit.gbcolorChangeRate = 3; // how fast should blue and green part of the color change 138 165 g_fadeAttackUnit.fadeOutStart = 100; // when should the fade out start using the opacity 139 166 g_fadeAttackUnit.opacityChangeRate = 3; // how fast should opacity change 140 167 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) 168 function colorFade_attackUnit(data) 146 169 { 170 var rgb = data.rgb; 171 // init color 172 if (data.tickCounter == 1) 173 rgb.r = 175; 147 174 // blinking 148 if ( tickCounter < g_fadeAttackUnit.blinkingTicks)175 if (data.tickCounter < g_fadeAttackUnit.blinkingTicks) 149 176 { 150 177 // slow that process down 151 if ( tickCounter % g_fadeAttackUnit.blinkingChangeInterval != 0)178 if (data.tickCounter % g_fadeAttackUnit.blinkingChangeInterval != 0) 152 179 return; 153 180 154 rgb.g = rgb.g == 0 ? 255 : rgb.g = 0; 155 rgb.b = rgb.b == 0 ? 255 : rgb.b = 0; 181 rgb.g = rgb.g == 0 ? 255 : 0; 156 182 } 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)183 // wait a short time and then color fade from red to grey to nothing 184 else if ( data.tickCounter >= g_fadeAttackUnit.blinkingTicks + g_fadeAttackUnit.blinkingChangeInterval) 159 185 { 160 rgb.g = rgb.g < 255 ? rgb.g += g_fadeAttackUnit.gbColourChangeRate * Math.sqrt(tickCounter - g_fadeAttackUnit.blinkingTicks) : 255; 161 rgb.b = rgb.g; 186 rgb.g = rgb.g < 255 ? rgb.g += g_fadeAttackUnit.gbcolorChangeRate * Math.sqrt(data.tickCounter - g_fadeAttackUnit.blinkingTicks) : 255; 162 187 163 188 // start with fading it out 164 189 if (rgb.g > g_fadeAttackUnit.fadeOutStart) 165 190 rgb.o = rgb.o > g_fadeAttackUnit.opacityChangeRate ? rgb.o -= g_fadeAttackUnit.opacityChangeRate : 0; 191 // check for end 192 if (rgb.o == 0) 193 data.stopFade = true; 166 194 } 195 rgb.b = rgb.g; 167 196 } 168 197 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) 198 function smoothColorFadeRestart_attackUnit(data) 175 199 { 176 200 // check, if in blinking phase 177 if ( tickCounter < g_fadeAttackUnit.blinkingTicks)201 if (data.tickCounter < g_fadeAttackUnit.blinkingTicks) 178 202 { 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; 203 // set the tick counter back to a smooth position 204 data.tickCounter = (data.tickCounter % (g_fadeAttackUnit.blinkingChangeInterval * 2)) + 1; 184 205 } 185 return1;206 data.tickCounter = 1; 186 207 } 187 208 188 //[END] of hero fade functions 189 No newline at end of file 209 //[END] of hero fade functions 210 //[START] idle workers icon 211 212 //var g_fadeIdleWorker = {}; 213 214 function colorFade_IdleWorker(data) 215 { 216 var rgb = data.rgb; 217 rgb.g = rgb.g == 0 ? 255 : 0; 218 rgb.b = rgb.g; 219 if (rgb.g == 0) 220 rgb.o = 0; 221 else 222 rgb.o = 100; 223 } 224 225 //[END] of idle workers icon functions 226 No newline at end of file -
binaries/data/mods/public/gui/session/session.js
478 478 479 479 updateHero(); 480 480 updateGroups(); 481 updateIdleWorkerButton(); 481 482 updateDebug(); 482 483 updatePlayerDisplay(); 483 484 updateSelectionDetails(); … … 491 492 if (battleState) 492 493 global.music.setState(global.music.states[battleState]); 493 494 495 }; 496 497 function updateIdleWorkerButton() 498 { 499 var idleUnitsCounter = Engine.GuiInterfaceCall("getNumberOfIdleUnits"); 500 501 if (idleUnitsCounter != 0) 502 startColorFade("idleWorkerOverlay", 500, 0, colorFade_IdleWorker, false); 503 else 504 stopColorFade("idleWorkerOverlay"); 505 494 506 } 495 507 508 496 509 /** 497 510 * updates a status bar on the GUI 498 511 * nameOfBar: name of the bar … … 587 600 { 588 601 g_previousHeroHitPoints = heroState.hitpoints; 589 602 // trigger the animation 590 fadeColour("heroHitOverlay", 100, 10000, {"r": 175,"g": 0,"b": 0,"o": 100}, colourFade_attackUnit, smoothColourFadeRestart_attackUnit);603 startColorFade("heroHitOverlay", 100, 0, colorFade_attackUnit, true, smoothColorFadeRestart_attackUnit); 591 604 return; 592 605 } 593 606 } -
binaries/data/mods/public/gui/session/session.xml
951 951 > 952 952 <!-- TODO: should highlight the button if there's non-zero idle workers --> 953 953 <object size="0 0 100% 100%" type="image" sprite="idleWorker" ghost="true" /> 954 <object name="idleWorkerOverlay" hidden="true" type="image" ghost="true" size="2 2 100%-2 100%-2"/> 954 955 <action on="Press">findIdleUnit(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action> 955 956 </object> 956 957 </object> -
binaries/data/mods/public/simulation/components/GuiInterface.js
1709 1709 PlaySound(data.name, data.entity); 1710 1710 }; 1711 1711 1712 GuiInterface.prototype.getNumberOfIdleUnits = function(player) 1713 { 1714 var entities = this.GetPlayerEntities(player); 1715 var cmpUnitAI = Engine.QueryInterface(entities[0], IID_UnitAI); 1716 if (!cmpUnitAI) 1717 return 0; 1718 return cmpUnitAI.getNumberOfIdleUnits(); 1719 } 1720 1712 1721 function isIdleUnit(ent, idleClass) 1713 1722 { 1714 1723 var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); … … 1946 1955 "SetWallPlacementPreview": 1, 1947 1956 "GetFoundationSnapData": 1, 1948 1957 "PlaySound": 1, 1958 "getNumberOfIdleUnits": 1, 1949 1959 "FindIdleUnits": 1, 1950 1960 "GetTradingRouteGain": 1, 1951 1961 "GetTradingDetails": 1, -
binaries/data/mods/public/simulation/components/UnitAI.js
169 169 "GuardedAttacked": function(msg) { 170 170 // ignore 171 171 }, 172 173 "UnitIdleChanged": function(msg) { 174 // check if this are units which can be selected by the workes idle button 175 if(this.IsUsedForIdleWorkerButton()) 176 { 177 if(msg.idle) 178 increaseIdleCount(msg.player); 179 else 180 decreaseIdleCount(msg.player); 181 } 182 }, 172 183 173 184 // Formation handlers: 174 185 … … 3036 3047 return Engine.QueryInterface(this.entity, IID_Heal); 3037 3048 }; 3038 3049 3050 UnitAI.prototype.IsUsedForIdleWorkerButton = function() 3051 { 3052 var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); 3053 if (!cmpIdentity) 3054 return false; 3055 // check idle class names 3056 for each(var className in g_idleClassNames) 3057 if (cmpIdentity.HasClass(className)) { 3058 return true; 3059 } 3060 // return false because all checks where negative 3061 return false; 3062 }; 3063 3039 3064 UnitAI.prototype.IsIdle = function() 3040 3065 { 3041 3066 return this.isIdle; … … 3100 3125 if(!this.isGarrisoned) 3101 3126 this.Stop(false); 3102 3127 } 3128 // check for idleWorks 3129 else if (this.isIdle) 3130 { 3131 // idle worker gone 3132 if (msg.to == -1) 3133 { 3134 decreaseIdleCount(msg.from); 3135 increaseIdleCount(msg.to); 3136 } 3137 // new idle worker 3138 else 3139 { 3140 decreaseIdleCount(msg.to); 3141 increaseIdleCount(msg.from); 3142 } 3143 } 3103 3144 }; 3104 3145 3105 3146 UnitAI.prototype.OnDestroy = function() … … 3682 3723 UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed}); 3683 3724 }; 3684 3725 3726 UnitAI.prototype.OnUnitIdleChanged = function(msg) 3727 { 3728 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 3729 if (!cmpOwnership) 3730 return; 3731 UnitFsm.ProcessMessage(this, {"type": "UnitIdleChanged", "idle": msg.idle, "player": cmpOwnership.GetOwner()}); 3732 } 3733 3685 3734 //// Helper functions to be called by the FSM //// 3686 3735 3687 3736 UnitAI.prototype.GetWalkSpeed = function() … … 5481 5530 ); 5482 5531 }; 5483 5532 5533 UnitAI.prototype.getNumberOfIdleUnits = function() 5534 { 5535 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 5536 if (!cmpOwnership) 5537 return 0; 5538 if (!isIdleCountDefined(cmpOwnership.GetOwner())) 5539 return 0; 5540 return getIdleCount(cmpOwnership.GetOwner()); 5541 } 5542 5543 var g_idleClassNames = ["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]; 5544 var g_idleUnitsCounter = {}; 5545 5546 function increaseIdleCount(player) 5547 { 5548 if (player == -1) 5549 return; 5550 if (!isIdleCountDefined(player)) 5551 g_idleUnitsCounter[player] = 1; 5552 else 5553 g_idleUnitsCounter[player]++; 5554 } 5555 5556 function decreaseIdleCount(player) 5557 { 5558 if (player == -1) 5559 return; 5560 // should not happen 5561 if (!isIdleCountDefined(player)) 5562 error("Negative idle worker count for player '" + player + "'"); 5563 else 5564 g_idleUnitsCounter[player]--; 5565 } 5566 5567 function isIdleCountDefined(player) 5568 { 5569 return (player in g_idleUnitsCounter); 5570 } 5571 5572 function getIdleCount(player) 5573 { 5574 if (!isIdleCountDefined(player)) 5575 return 0; 5576 else 5577 return g_idleUnitsCounter[player]; 5578 } 5579 5484 5580 Engine.RegisterComponentType(IID_UnitAI, "UnitAI", UnitAI);