Ticket #2162: group_health_patch_v2.2.patch
File group_health_patch_v2.2.patch, 30.0 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 228 //[END] of hero fade functions 229 No newline at end of file -
binaries/data/mods/public/gui/session/selection.js
106 106 return this.groups[templateName]; 107 107 }; 108 108 109 EntityGroups.prototype.hasMembers = function() 110 { 111 return Object.keys(this.groups).length != 0; 112 }; 113 109 114 EntityGroups.prototype.getTotalCount = function() 110 115 { 111 116 var totalCount = 0; … … 442 447 function EntityGroupsContainer() 443 448 { 444 449 this.groups = []; 450 this.info = []; 451 // init groups 0 to 9 445 452 for (var i = 0; i < 10; ++i) 446 453 { 447 454 this.groups[i] = new EntityGroups(); 455 var data = {}; // hitpoints, maxGroupHitPoints, numberOfUnits, initialNumberOfUnits, deathCycle, dirty, attack 456 this.info[i] = data; 448 457 } 449 458 } 450 459 451 EntityGroupsContainer.prototype.addEntities = function(groupName, ents) 460 /** 461 * adds entities to the group 462 * groupID: id of the group 463 * ents: array of entity IDs 464 */ 465 EntityGroupsContainer.prototype.addEntities = function(groupID, ents) 452 466 { 453 467 for each (var ent in ents) 454 468 { 455 for each (var group in this.groups) 469 // remove the entity out of all other groups 470 for (var gID in this.groups) 456 471 { 472 var group = this.groups[gID]; 457 473 if (ent in group.ents) 458 474 { 459 475 group.removeEnt(ent); 476 this.removeEnt(gID, ent); // is used because fade and icon should not be triggered if a unit comes to another group 477 break; 460 478 } 461 479 } 462 480 } 463 this.groups[groupName].add(ents); 481 // add entities to group 482 this.groups[groupID].add(ents); 483 this.updateAdditionalData(groupID, ents, true); 464 484 } 465 485 486 /** 487 * removes a entity from the info data 488 * groupID: id of the group 489 * ent: entity ID 490 */ 491 EntityGroupsContainer.prototype.removeEnt = function(groupID, ent) 492 { 493 if (!this.hasMembers(groupID)) 494 return; 495 var entState = GetEntityState(+ent); 496 if (!entState) 497 return; 498 499 // update the data like this unit would never be in this group 500 var data = this.info[groupID]; 501 data.hitpoints -= entState.hitpoints; 502 data.maxGroupHitPoints -= entState.maxHitpoints; 503 data.numberOfUnits--; 504 data.initialNumberOfUnits--; 505 data.dirty = true; 506 warn(JSON.stringify(data)); 507 } 508 509 /** 510 * updates the additional info of a group; can be called for init or update but should only be called, if needed 511 * groupID: id of the group 512 * ents: array of entity IDs 513 * init: true, if init 514 */ 515 EntityGroupsContainer.prototype.updateAdditionalData = function(groupID, ents, init) 516 { 517 if (!this.hasMembers(groupID)) 518 return; 519 520 if (init) 521 { 522 var data = {}; 523 data.dirty = true; // true, if GUI should be updated 524 data.attack = false; // true, if GUI should start color attack animation 525 data.hitpoints = 0; 526 data.maxGroupHitPoints = 0; 527 data.numberOfUnits = ents.length; 528 data.initialNumberOfUnits = data.numberOfUnits; 529 data.deathCycle = 0; // used for death icon 530 531 // update the additional info 532 if (data.numberOfUnits > 0) 533 this.info[groupID] = data; 534 else 535 this.info[groupID] = {}; 536 } 537 538 // update the values needed for the GUI 539 this.updateHealth(groupID); 540 this.updateMaxHealth(groupID); 541 this.updateMembers(groupID); 542 } 543 544 /** 545 * updates the current health points of a group 546 * groupID: id of the group 547 */ 548 EntityGroupsContainer.prototype.updateHealth = function(groupID) 549 { 550 if (!this.hasMembers(groupID)) 551 return; 552 553 var data = this.info[groupID]; 554 var hitpoints = 0; 555 // calculate health 556 for (var ent in this.groups[groupID].ents) 557 { 558 var entState = GetEntityState(+ent); 559 hitpoints += entState.hitpoints; 560 } 561 562 // check, if attack is running. 563 if (hitpoints < data.hitpoints) 564 data.attack = true; 565 // update prev points 566 if (hitpoints != data.hitpoints) 567 { 568 data.hitpoints = hitpoints; 569 data.dirty = true; 570 } 571 } 572 573 /** 574 * updates the member count of the group 575 * groupID: id of the group 576 */ 577 EntityGroupsContainer.prototype.updateMembers = function(groupID) 578 { 579 if (!this.hasMembers(groupID)) 580 return; 581 582 var data = this.info[groupID]; 583 var numberOfUnits = this.groups[groupID].getTotalCount(); 584 if (numberOfUnits < data.numberOfUnits) 585 { 586 // update unit count 587 data.numberOfUnits = numberOfUnits; 588 data.deathCycle = 1; // show death symbol 589 // update max health of the group 590 this.updateMaxHealth(groupID); 591 data.dirty = true; 592 } 593 } 594 595 /** 596 * updates the max health a group can have 597 * groupID: id of the group 598 */ 599 EntityGroupsContainer.prototype.updateMaxHealth = function(groupID) 600 { 601 if (!this.hasMembers(groupID)) 602 return; 603 604 var data = this.info[groupID]; 605 data.maxGroupHitPoints = 0; 606 for (var ent in this.groups[groupID].ents) 607 { 608 var entState = GetEntityState(+ent); 609 data.maxGroupHitPoints += entState.maxHitpoints; 610 } 611 } 612 613 /** 614 * updates the death cycle icon 615 * groupID: id of the group 616 */ 617 EntityGroupsContainer.prototype.updateDeathCycle = function(groupID) 618 { 619 if (!this.hasMembers(groupID)) 620 return; 621 622 var data = this.info[groupID]; 623 if (data.deathCycle > 0) 624 data.deathCycle++; 625 if (data.deathCycle >= g_groupDeathShowIconTicks) 626 data.dirty = true; 627 } 628 629 /** 630 * checks, if some entities where removed or renamed 631 */ 466 632 EntityGroupsContainer.prototype.update = function() 467 633 { 468 634 this.checkRenamedEntities(); 469 for each (var groupin this.groups)635 for (var groupID in this.groups) 470 636 { 637 // nothing to do, if no members are there 638 if (!this.hasMembers(groupID)) 639 continue; 640 641 var group = this.groups[groupID]; 471 642 for (var ent in group.ents) 472 643 { 473 644 var entState = GetEntityState(+ent); … … 474 645 475 646 // Remove deleted units 476 647 if (!entState) 477 {478 648 group.removeEnt(ent); 479 }480 649 } 650 // update the values needed for the GUI 651 this.updateHealth(groupID); 652 this.updateMembers(groupID); 653 this.updateDeathCycle(groupID); 481 654 } 482 655 } 483 656 … … 494 667 for each (var renamedEntity in renamedEntities) 495 668 renamedLookup[renamedEntity.entity] = renamedEntity.newentity; 496 669 497 for each (var groupin this.groups)670 for (var groupID in this.groups) 498 671 { 672 var group = this.groups[groupID]; 499 673 for each (var renamedEntity in renamedEntities) 500 674 { 501 675 // Reconstruct the group if at least one entity has been renamed. … … 502 676 if (renamedEntity.entity in group.ents) 503 677 { 504 678 group.rebuildGroup(renamedLookup); 679 this.updateAdditionalData(groupID, Object.keys(group.ents), false); 505 680 break; 506 681 } 507 682 } … … 509 684 } 510 685 } 511 686 687 /** 688 * resets the initialNumberOfUnits 689 * groupID: id of the group 690 */ 691 EntityGroupsContainer.prototype.resetMemberStatus = function(groupID) 692 { 693 if (!this.hasMembers(groupID)) 694 return; 695 696 var data = this.info[groupID]; 697 data.initialNumberOfUnits = data.numberOfUnits; 698 data.dirty = true; 699 } 700 701 /** 702 * checks, if a group with that ID has members 703 * groupID: id of the group 704 */ 705 EntityGroupsContainer.prototype.hasMembers = function(groupID) 706 { 707 return this.groups[groupID].hasMembers(); 708 } 709 710 /** 711 * gets the dirty state for the GUI 712 * groupID: id of the group 713 */ 714 EntityGroupsContainer.prototype.isDirty = function(groupID) 715 { 716 return this.hasMembers(groupID) && this.info[groupID].dirty; 717 } 718 719 /** 720 * sets the dirty state to false after the GUI redrawed the stuff 721 * groupID: id of the group 722 */ 723 EntityGroupsContainer.prototype.resetDirty = function(groupID) 724 { 725 if (!this.hasMembers(groupID)) 726 return; 727 728 this.info[groupID].dirty = false; 729 } 730 731 /** 732 * gets the attack state for the GUI 733 * groupID: id of the group 734 */ 735 EntityGroupsContainer.prototype.isAttacked = function(groupID) 736 { 737 return this.hasMembers(groupID) && this.info[groupID].attack; 738 } 739 740 /** 741 * sets the attack state to false after the color fade was started 742 * groupID: id of the group 743 */ 744 EntityGroupsContainer.prototype.resetAttack = function(groupID) 745 { 746 if (!this.hasMembers(groupID)) 747 return; 748 749 this.info[groupID].attack = false; 750 } 751 752 /** 753 * sets the death cycle back to zero (off) 754 * groupID: id of the group 755 */ 756 EntityGroupsContainer.prototype.resetDeathCycle = function(groupID) 757 { 758 if (!this.hasMembers(groupID)) 759 return; 760 761 this.info[groupID].deathCycle = 0; 762 } 763 512 764 var g_Groups = new EntityGroupsContainer(); -
binaries/data/mods/public/gui/session/session.js
56 56 // always through the list of all ongoing attacks... 57 57 var g_previousHeroHitPoints = undefined; 58 58 59 // simulation ticks until the deathIcon of a group is removed. 60 var g_groupDeathShowIconTicks = 60; 61 59 62 function GetSimState() 60 63 { 61 64 if (!g_SimState) … … 165 168 Engine.GetGUIObjectByName("civIcon").sprite = "stretched:" + g_CivData[g_Players[Engine.GetPlayerID()].civ].Emblem; 166 169 Engine.GetGUIObjectByName("civIcon").tooltip = g_CivData[g_Players[Engine.GetPlayerID()].civ].Name; 167 170 initMenuPosition(); // set initial position 171 initLayoutGroupButtons(); // init group buttons 168 172 169 173 // Populate player selection dropdown 170 174 var playerNames = []; … … 211 215 setTimeout(function() { reportPerformance(60); }, 60000); 212 216 } 213 217 218 // inits the layout of the group buttons (adds spacers, labels and events to buttons) 219 function initLayoutGroupButtons() 220 { 221 var guiName = "Group"; 222 for (var i = 0; i < 10; i++) 223 { 224 // add spacers 225 var buttonSideLength = Engine.GetGUIObjectByName("unit"+guiName+"Button["+i+"]").size.bottom; 226 var buttonSpacer = buttonSideLength+12; 227 layoutButtonRow(i, guiName, buttonSideLength, buttonSpacer, i, i+1); 228 229 // add label 230 var label = Engine.GetGUIObjectByName("unit"+guiName+"Label["+i+"]").caption = i; 231 232 // add button events and hide it 233 var button = Engine.GetGUIObjectByName("unit"+guiName+"Button["+i+"]"); 234 button.onpress = (function(i) { return function() { performGroup((Engine.HotkeyIsPressed("selection.add") ? "add" : "select"), i); } })(i); 235 button.ondoublepress = (function(i) { return function() { performGroup("snap", i); } })(i); 236 button.onpressright = (function(i) { return function() { performGroup("breakUp", i); } })(i); 237 button.hidden = true; 238 239 // get the members status bar and add a event 240 var memberButton = Engine.GetGUIObjectByName("unit"+guiName+"MembersButton["+i+"]"); 241 memberButton.onpress = (function(i) { return function() { g_Groups.resetMemberStatus(i); } })(i); 242 } 243 } 244 214 245 function selectViewPlayer(playerID) 215 246 { 216 247 Engine.SetPlayerID(playerID); … … 311 342 var data = {}; 312 343 data.playerAssignments = g_PlayerAssignments; 313 344 data.groups = g_Groups.groups; 345 data.additionalGroupInfo = g_Groups.info; 314 346 // TODO: any other gui state? 315 347 return data; 316 348 } … … 325 357 { 326 358 g_Groups.groups[groupNumber].groups = data.groups[groupNumber].groups; 327 359 g_Groups.groups[groupNumber].ents = data.groups[groupNumber].ents; 360 g_Groups.info[groupNumber] = data.additionalGroupInfo[groupNumber]; 361 g_Groups.info[groupNumber].dirty = true; 328 362 } 329 363 updateGroups(); 330 364 } … … 498 532 var battleState = Engine.GuiInterfaceCall("GetBattleState", Engine.GetPlayerID()); 499 533 if (battleState) 500 534 global.music.setState(global.music.states[battleState]); 501 502 535 } 503 536 504 537 /** … … 510 543 */ 511 544 function updateGUIStatusBar(nameOfBar, points, maxPoints, direction) 512 545 { 546 // check, if values are valid 547 if (!(points && maxPoints)) 548 return; 513 549 // check, if optional direction parameter is valid. 514 550 if (!direction || !(direction >= 0 && direction < 4)) 515 551 direction = 0; … … 523 559 var value = 100*Math.max(0, Math.min(1, points / maxPoints)); 524 560 525 561 // inverse bar 526 if (direction == 2 || direction == 3)562 if (direction == 2 || direction == 3) 527 563 value = 100 - value; 528 564 529 if (direction == 0)565 if (direction == 0) 530 566 healthSize.rright = value; 531 else if (direction == 1)567 else if (direction == 1) 532 568 healthSize.rbottom = value; 533 else if (direction == 2)569 else if (direction == 2) 534 570 healthSize.rleft = value; 535 else if (direction == 3)571 else if (direction == 3) 536 572 healthSize.rtop = value; 537 573 538 574 // update bar … … 539 575 statusBar.size = healthSize; 540 576 } 541 577 578 /** 579 * changes the visibility of a status bar 580 * nameOfBar: name of the bar 581 * hide: true, if bar should be hidden 582 */ 583 function changeVisibilityStatusBar(nameOfBar, hide) 584 { 585 // get the bar and update it 586 var statusBar = Engine.GetGUIObjectByName(nameOfBar); 587 if (!statusBar) 588 return; 589 590 statusBar.hidden = hide; 591 } 542 592 593 594 543 595 function updateHero() 544 596 { 545 597 var simState = GetSimState(); … … 595 647 { 596 648 g_previousHeroHitPoints = heroState.hitpoints; 597 649 // trigger the animation 598 fadeColour("heroHitOverlay", 100, 10000, {"r": 175,"g": 0,"b": 0,"o": 100}, colourFade_attackUnit, smoothColourFadeRestart_attackUnit);650 startColorFade("heroHitOverlay", 100, 0, colorFade_attackUnit, true, smoothColorFadeRestart_attackUnit); 599 651 return; 600 652 } 601 653 } 602 654 603 655 656 // updates the groups on the GUI 604 657 function updateGroups() 605 658 { 606 659 var guiName = "Group"; 607 660 g_Groups.update(); 608 for (var i = 0; i < 10; i++) 609 { 610 var button = Engine.GetGUIObjectByName("unit"+guiName+"Button["+i+"]"); 611 var label = Engine.GetGUIObjectByName("unit"+guiName+"Label["+i+"]").caption = i; 612 if (g_Groups.groups[i].getTotalCount() == 0) 613 button.hidden = true; 661 for (var i = 0; i < 10; i++) 662 { 663 var button = Engine.GetGUIObjectByName("unit"+guiName+"Button["+i+"]"); 664 // check, if group has members 665 if (!g_Groups.hasMembers(i)) 666 { 667 button.hidden = true; 668 stopColorFade("unitGroupHitOverlay["+i+"]"); 669 var deathIcon = Engine.GetGUIObjectByName("unitGroupIconDeath["+ i +"]"); 670 deathIcon.hidden = true; 671 continue; // nothing to do, if group has no members 672 } 673 else 674 button.hidden = false; // make button visible 675 676 // check, if status bars must be redrawn 677 if (!g_Groups.isDirty(i)) 678 continue; 679 680 // update the status bars 681 var data = g_Groups.info[i]; 682 updateGUIStatusBar("unitGroupHealthBar["+ i +"]", data.hitpoints, data.maxGroupHitPoints); 683 684 if(data.initialNumberOfUnits == 1) 685 changeVisibilityStatusBar("unitGroupMembersButton["+ i +"]", true); 614 686 else 615 button.hidden = false; 616 button.onpress = (function(i) { return function() { performGroup((Engine.HotkeyIsPressed("selection.add") ? "add" : "select"), i); } })(i); 617 button.ondoublepress = (function(i) { return function() { performGroup("snap", i); } })(i); 618 button.onpressright = (function(i) { return function() { performGroup("breakUp", i); } })(i); 619 } 620 var numButtons = i; 621 var rowLength = 1; 622 var numRows = Math.ceil(numButtons / rowLength); 623 var buttonSideLength = Engine.GetGUIObjectByName("unit"+guiName+"Button[0]").size.bottom; 624 var buttonSpacer = buttonSideLength+1; 625 for (var i = 0; i < numRows; i++) 626 layoutButtonRow(i, guiName, buttonSideLength, buttonSpacer, rowLength*i, rowLength*(i+1) ); 687 { 688 changeVisibilityStatusBar("unitGroupMembersButton["+ i +"]", false); 689 updateGUIStatusBar("unitGroupMembersBar["+ i +"]", data.numberOfUnits, data.initialNumberOfUnits, 3); 690 } 691 692 // check, if the attack should be started 693 if (g_Groups.isAttacked(i)) 694 { 695 startColorFade("unitGroupHitOverlay["+i+"]", 100, 10000, colorFade_attackUnit, true, smoothColorFadeRestart_attackUnit); 696 g_Groups.resetAttack(i); 697 } 698 699 // check, if the death symbol should be triggered 700 if (data.deathCycle > 0) 701 { 702 var deathIcon = Engine.GetGUIObjectByName("unitGroupIconDeath["+ i +"]"); 703 // show the symbol 704 if (data.deathCycle >= g_groupDeathShowIconTicks) 705 { 706 deathIcon.hidden = true; 707 g_Groups.resetDeathCycle(i); 708 } 709 else if (data.deathCycle >= 1) 710 deathIcon.hidden = false; 711 } 712 713 // reset the dirty state after the updates are complete 714 g_Groups.resetDirty(i); 715 } 627 716 } 628 717 629 718 function updateDebug() -
binaries/data/mods/public/gui/session/session.xml
904 904 > 905 905 <repeat count="10"> 906 906 <object name="unitGroupButton[n]" size="0 0 36 36" type="button" hidden="false" style="iconButton" tooltip_style="sessionToolTipBottomBold" 907 tooltip="Click to select grouped units, double-click to focus the grouped units and right-click to disband the group." 908 > 907 tooltip="Click to select grouped units, double-click to focus the grouped units and right-click to disband the group."> 909 908 <object name="unitGroupIcon[n]" size="3 3 33 33" type="image" sprite="groupsIcon" ghost="true"/> 909 <object name="unitGroupHitOverlay[n]" hidden="true" type="image" ghost="true" size="3 3 33 33"/> 910 910 <object name="unitGroupLabel[n]" type="text" style="largeCenteredOutlinedText" ghost="true"/> 911 <object name="unitGroupIconDeath[n]" size="21 3 35 17" type="image" sprite="killIcon" hidden="true" ghost="true"/> 912 <!-- Group Health bar --> 913 <object size="2 37 34 40" name="unitGroupHealthSection[n]"> 914 <object size="0 0 100% 4" name="unitGroupHealth[n]" ghost="true" type="image"> 915 <object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/> 916 <object type="image" sprite="healthBackground" ghost="true"/> 917 <object type="image" sprite="healthForeground" ghost="true" name="unitGroupHealthBar[n]"/> 918 <object type="image" sprite="statsBarShaderHorizontal" ghost="true"/> 919 </object> 920 </object> 921 <!-- Group Health bar --> 922 <object size="37 2 40 34" name="unitGroupMembersButton[n]" type="button" tooltip_style="sessionToolTipBottomBold" 923 tooltip="Click to reset unit counter bar."> 924 <object size="0 0 4 100%" name="unitGroupMembers[n]" ghost="true" type="image"> 925 <object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/> 926 <object type="image" sprite="groupSizeBackground" ghost="true"/> 927 <object type="image" sprite="groupSizeForeground" ghost="true" name="unitGroupMembersBar[n]"/> 928 <object type="image" sprite="statsBarShaderVertical" ghost="true"/> 929 </object> 930 </object> 911 931 </object> 912 932 </repeat> 913 933 </object> -
binaries/data/mods/public/gui/session/sprites.xml
8 8 size="0 0 100% 100%" 9 9 /> 10 10 </sprite> 11 11 12 <sprite name="killIcon"> 13 <image 14 texture="session/icons/kill.png" 15 size="0 0 100% 100%" 16 /> 17 </sprite> 18 12 19 <sprite name="idleWorker"> 13 20 <image 14 21 texture="session/icons/repair.png" … … 16 23 size="0 0 100% 100%" 17 24 /> 18 25 </sprite> 26 27 <sprite name="groupSizeForeground"> 28 <image backcolor="255 184 0 255"/> 29 </sprite> 30 31 <sprite name="groupSizeBackground"> 32 <image backcolor="184 184 184 255"/> 33 </sprite> 19 34 20 35 <!-- ================================ ================================ --> 21 36 <!-- Menu -->