Ticket #2357: idle_worker_blink_v2.patch
File idle_worker_blink_v2.patch, 18.6 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: [var data] 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 * 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 18 * arguments: [var data] 22 19 */ 23 function fadeColour(name, changeInterval, duration, colour, fun_colorTransform, fun_smoothRestart, tickCounter)20 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 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; // TODO: ' !== false' and add default parameter 39 data.fun_smoothRestart = fun_smoothRestart; 40 data.tickCounter = 0; 41 data.runsUntilStop = duration == 0; 42 data.stopFade = false; 43 var rgb = {"r": 0,"g": 0,"b": 0,"o": 100}; 44 data.rgb = rgb; 45 // store it! 46 g_colorFade[name] = data; 47 48 // start with fading 49 fadeColorTick(name); 42 50 } 51 else if (restartAble) 52 { 53 restartColorFade(name, tickInterval, duration, fun_colorTransform, restartAble, fun_smoothRestart); 54 return; 55 } 56 } 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 var data = g_colorFade[name]; 72 73 // change the color 74 data.fun_colorTransform(data); 43 75 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; 76 // set new color 77 var rgb = data.rgb; 78 overlay.sprite="colour: "+rgb.r+" "+rgb.g+" "+rgb.b+" "+rgb.o; 49 79 50 80 // recusive call, if duration is positive 51 duration-= changeInterval; 52 if (duration > 0 && colour.o > 0) 81 if (!data.stopFade && (data.runsUntilStop || data.duration - (data.tickInterval * data.tickCounter) > 0)) 53 82 { 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;83 var id = setTimeout(function() { fadeColorTick(name); }, data.tickInterval); 84 data.timerId = id; 85 data.tickCounter++; 57 86 } 58 87 else 59 88 { 60 89 overlay.hidden = true; 61 stopColo urFade(name);90 stopColorFade(name); 62 91 } 63 92 } 64 93 65 66 94 /** 67 * checks, if a colo ur fade on that object is running68 * name: name of the object which colo ur fade should be checked95 * checks, if a color fade on that object is running 96 * name: name of the object which color fade should be checked 69 97 * return: true a running fade was found 70 98 */ 71 function isColo urFadeRunning(name)99 function isColorFadeRunning(name) 72 100 { 73 return name in g_colorFade .id;101 return name in g_colorFade; 74 102 } 75 103 76 104 /** 77 * stops fading a colo ur78 * name: name of the object which colo ur fade should be stopped79 * hideOverlay : hides the overlay, if true105 * stops fading a color 106 * name: name of the object which color fade should be stopped 107 * hideOverlay [optional]: hides the overlay, if true [default: true] 80 108 * return: true a running fade was stopped 81 109 */ 82 function stopColo urFade(name, hideOverlay)110 function stopColorFade(name, hideOverlay) //TODO: add 'hideOverlay = true' when its supported (spiderMonkey upgrade #1886) 83 111 { 84 // check, if a colo ur fade is running85 if (!isColo urFadeRunning(name))112 // check, if a color fade is running 113 if (!isColorFadeRunning(name)) 86 114 return false; 87 115 88 116 // delete the timer 89 clearTimeout(g_colorFade .id[name]);90 delete g_colorFade .id[name];91 delete g_colorFade.tick[name]; 92 117 clearTimeout(g_colorFade[name].timerId); 118 delete g_colorFade[name]; 119 120 hideOverlay = hideOverlay !== false; // TODO: remove this line and add default value for hideOverlay 93 121 // get the overlay and hide it 94 122 if (hideOverlay) 95 123 { 96 124 var overlay = Engine.GetGUIObjectByName(name); 97 if (overlay)125 if (overlay) 98 126 overlay.hidden = true; 99 127 } 100 128 return true; … … 101 129 } 102 130 103 131 /** 104 * restarts a colo ur fade105 * see paramter in fadeColourfunction132 * restarts a color fade 133 * see paramter in startColorFade function 106 134 */ 107 function restartColo urFade(name, changeInterval, duration, colour, fun_colorTransform, fun_smoothRestart, tickCounter)135 function restartColorFade(name) 108 136 { 109 // check, if a colo ur fade is running110 if (!isColo urFadeRunning(name))137 // check, if a color fade is running 138 if (!isColorFadeRunning(name)) 111 139 return false; 112 140 141 var data = g_colorFade[name]; 113 142 // check, if fade can be restarted smoothly 114 if ( fun_smoothRestart)143 if (data.fun_smoothRestart) 115 144 { 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); 145 data.fun_smoothRestart(data); 120 146 } 121 147 // stop it and restart it 122 148 else 123 149 { 124 stopColo urFade(name, true);125 fadeColour(name, changeInterval, duration, colour, fun_colorTransform);150 stopColorFade(name, false); 151 startColorFade(name, data.changeInterval, data.duration, data.fun_colorTransform, data.restartAble, data.fun_smoothRestart); 126 152 } 127 153 return true; 128 154 } … … 133 159 134 160 var g_fadeAttackUnit = {}; 135 161 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 change162 g_fadeAttackUnit.blinkingChangeInterval = 5; // how often should the color be changed during the blinking phase 163 g_fadeAttackUnit.gbcolorChangeRate = 3; // how fast should blue and green part of the color change 138 164 g_fadeAttackUnit.fadeOutStart = 100; // when should the fade out start using the opacity 139 165 g_fadeAttackUnit.opacityChangeRate = 3; // how fast should opacity change 140 166 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) 167 function colorFade_attackUnit(data) 146 168 { 169 var rgb = data.rgb; 170 // init color 171 if (data.tickCounter == 0) 172 rgb.r = 175; 147 173 // blinking 148 if ( tickCounter < g_fadeAttackUnit.blinkingTicks)174 if (data.tickCounter < g_fadeAttackUnit.blinkingTicks) 149 175 { 150 176 // slow that process down 151 if ( tickCounter % g_fadeAttackUnit.blinkingChangeInterval != 0)177 if (data.tickCounter % g_fadeAttackUnit.blinkingChangeInterval != 0) 152 178 return; 153 179 154 rgb.g = rgb.g == 0 ? 255 : rgb.g = 0; 155 rgb.b = rgb.b == 0 ? 255 : rgb.b = 0; 180 rgb.g = rgb.g == 0 ? 255 : 0; 156 181 } 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)182 // wait a short time and then color fade from red to grey to nothing 183 else if ( data.tickCounter >= g_fadeAttackUnit.blinkingTicks + g_fadeAttackUnit.blinkingChangeInterval) 159 184 { 160 rgb.g = rgb.g < 255 ? rgb.g += g_fadeAttackUnit.gbColourChangeRate * Math.sqrt(tickCounter - g_fadeAttackUnit.blinkingTicks) : 255; 161 rgb.b = rgb.g; 185 rgb.g = rgb.g < 255 ? rgb.g += g_fadeAttackUnit.gbcolorChangeRate * Math.sqrt(data.tickCounter - g_fadeAttackUnit.blinkingTicks) : 255; 162 186 163 187 // start with fading it out 164 188 if (rgb.g > g_fadeAttackUnit.fadeOutStart) 165 189 rgb.o = rgb.o > g_fadeAttackUnit.opacityChangeRate ? rgb.o -= g_fadeAttackUnit.opacityChangeRate : 0; 190 // check for end 191 if (rgb.o == 0) 192 data.stopFade = true; 166 193 } 194 rgb.b = rgb.g; 167 195 } 168 196 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) 197 function smoothColorFadeRestart_attackUnit(data) 175 198 { 176 199 // check, if in blinking phase 177 if ( tickCounter < g_fadeAttackUnit.blinkingTicks)200 if (data.tickCounter < g_fadeAttackUnit.blinkingTicks) 178 201 { 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; 202 data.tickCounter = data.tickCounter % (g_fadeAttackUnit.blinkingChangeInterval * 2); 184 203 } 185 return 1; 204 else 205 data.tickCounter = 1; 186 206 } 187 207 188 //[END] of hero fade functions 189 No newline at end of file 208 //[END] of hero fade functions 209 //[START] idle workers icon 210 211 //var g_fadeIdleWorker = {}; 212 213 function colorFade_IdleWorker(data) 214 { 215 var rgb = data.rgb; 216 // init color 217 if (data.tickCounter == 0) 218 { 219 rgb.r = 255; 220 rgb.g = 255; 221 rgb.b = 255; 222 } 223 // hide it every tick 224 if (data.tickCounter % 2 == 0) 225 rgb.o = 0; 226 else 227 rgb.o = 100; 228 } 229 230 //[END] of idle workers icon functions 231 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 /** 498 * updates the idle worker button 499 */ 500 function updateIdleWorkerButton() 501 { 502 var idleUnitsCounter = Engine.GuiInterfaceCall("GetIdleWorkerButtonCount", Engine.GetPlayerID()); 503 if (idleUnitsCounter == -1) 504 return; 505 if (idleUnitsCounter != 0) 506 startColorFade("idleWorkerOverlay", 750, 0, colorFade_IdleWorker, false); 507 else 508 stopColorFade("idleWorkerOverlay"); 494 509 } 495 510 511 496 512 /** 497 513 * updates a status bar on the GUI 498 514 * nameOfBar: name of the bar … … 587 603 { 588 604 g_previousHeroHitPoints = heroState.hitpoints; 589 605 // trigger the animation 590 fadeColour("heroHitOverlay", 100, 10000, {"r": 175,"g": 0,"b": 0,"o": 100}, colourFade_attackUnit, smoothColourFadeRestart_attackUnit);606 startColorFade("heroHitOverlay", 100, 0, colorFade_attackUnit, true, smoothColorFadeRestart_attackUnit); 591 607 return; 592 608 } 593 609 } -
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 <action on="Press">findIdleUnit(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action> 954 <object name="idleWorkerOverlay" hidden="true" type="image" ghost="true" size="2 2 100%-2 100%-2"/> 955 <action on="Press">findIdleUnit(["Worker", "Trade", "FishingBoat", "Healer"]);</action> 955 956 </object> 956 957 </object> 957 958 </object> -
binaries/data/mods/public/simulation/components/GuiInterface.js
1709 1709 PlaySound(data.name, data.entity); 1710 1710 }; 1711 1711 1712 GuiInterface.prototype.GetIdleWorkerButtonCount = function(player) 1713 { 1714 var cmpPlayer = QueryPlayerIDInterface(player, IID_Player); 1715 if (!cmpPlayer) 1716 return -1; 1717 return cmpPlayer.GetIdleWorkerButtonCount(); 1718 } 1719 1712 1720 function isIdleUnit(ent, idleClass) 1713 1721 { 1714 1722 var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); … … 1946 1954 "SetWallPlacementPreview": 1, 1947 1955 "GetFoundationSnapData": 1, 1948 1956 "PlaySound": 1, 1957 "GetIdleWorkerButtonCount": 1, 1949 1958 "FindIdleUnits": 1, 1950 1959 "GetTradingRouteGain": 1, 1951 1960 "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 }; … … 665 666 cmpGUIInterface.PushNotification(notification); 666 667 }; 667 668 669 Player.prototype.GetIdleWorkerButtonCount = function() 670 { 671 return this.idleWorkerButtonCount; 672 }; 673 674 Player.prototype.IncreaseWorkerButtonCount = function() 675 { 676 this.idleWorkerButtonCount++; 677 }; 678 679 Player.prototype.DecreaseWorkerButtonCount = function() 680 { 681 this.idleWorkerButtonCount--; 682 if (this.idleWorkerButtonCount < 0) 683 error("Negative worker idle count for player '" + this.playerID + "'"); 684 }; 685 668 686 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 IncreaseIdleWorkerButtonCount(msg.player); 182 else 183 DecreaseIdleWorkerButtonCount(msg.player); 184 } 185 }, 172 186 173 187 // Formation handlers: 174 188 … … 3036 3050 return Engine.QueryInterface(this.entity, IID_Heal); 3037 3051 }; 3038 3052 3053 UnitAI.prototype.IsUsedForIdleWorkerButton = function() 3054 { 3055 var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); 3056 if (!cmpIdentity) 3057 return false; 3058 // check idle class names 3059 for each(var className in g_idleClassNames) 3060 if (cmpIdentity.HasClass(className)) { 3061 return true; 3062 } 3063 // return false because all checks where negative 3064 return false; 3065 }; 3066 3039 3067 UnitAI.prototype.IsIdle = function() 3040 3068 { 3041 3069 return this.isIdle; … … 3100 3128 if(!this.isGarrisoned) 3101 3129 this.Stop(false); 3102 3130 } 3131 // check for idleWorks 3132 else if (this.isIdle) 3133 { 3134 // idle worker gone 3135 if (msg.to == -1) 3136 { 3137 DecreaseIdleWorkerButtonCount(msg.from); 3138 IncreaseIdleWorkerButtonCount(msg.to); 3139 } 3140 // new idle worker 3141 else 3142 { 3143 DecreaseIdleWorkerButtonCount(msg.to); 3144 IncreaseIdleWorkerButtonCount(msg.from); 3145 } 3146 } 3103 3147 }; 3104 3148 3105 3149 UnitAI.prototype.OnDestroy = function() … … 3682 3726 UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed}); 3683 3727 }; 3684 3728 3729 UnitAI.prototype.OnUnitIdleChanged = function(msg) 3730 { 3731 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 3732 if (!cmpOwnership) 3733 return; 3734 UnitFsm.ProcessMessage(this, {"type": "UnitIdleChanged", "idle": msg.idle, "player": cmpOwnership.GetOwner()}); 3735 } 3736 3685 3737 //// Helper functions to be called by the FSM //// 3686 3738 3687 3739 UnitAI.prototype.GetWalkSpeed = function() … … 5481 5533 ); 5482 5534 }; 5483 5535 5536 UnitAI.prototype.getNumberOfIdleUnits = function() 5537 { 5538 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 5539 if (!cmpOwnership) 5540 return -1; 5541 if (!isIdleCountDefined(cmpOwnership.GetOwner())) 5542 return -1; 5543 return getIdleCount(cmpOwnership.GetOwner()); 5544 } 5545 5546 function getCmpPlayer(player) 5547 { 5548 var playerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 5549 return Engine.QueryInterface(playerMan.GetPlayerByID(player), IID_Player); 5550 } 5551 5552 function IncreaseIdleWorkerButtonCount(player) 5553 { 5554 if (player == -1) 5555 return; 5556 var cmpPlayer = getCmpPlayer(player); 5557 if (cmpPlayer) 5558 cmpPlayer.IncreaseWorkerButtonCount(); 5559 } 5560 5561 function DecreaseIdleWorkerButtonCount(player) 5562 { 5563 if (player == -1) 5564 return; 5565 var cmpPlayer = getCmpPlayer(player); 5566 if (cmpPlayer) 5567 cmpPlayer.DecreaseWorkerButtonCount(); 5568 } 5569 5484 5570 Engine.RegisterComponentType(IID_UnitAI, "UnitAI", UnitAI);