Ticket #2154: patch_townbell.8.diff
File patch_townbell.8.diff, 21.0 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/audio/interface/alarm/alarm_alert_0.xml
1 <?xml version="1.0" encoding="utf-8" standalone="no" ?> 2 <SoundGroup> 3 <Omnipresent>1</Omnipresent> 4 <HeardBy>owner</HeardBy> 5 <Gain>0.25</Gain> 6 <Pitch>1</Pitch> 7 <Priority>100</Priority> 8 <ConeGain>1</ConeGain> 9 <ConeInner>360</ConeInner> 10 <ConeOuter>360</ConeOuter> 11 <Looping>0</Looping> 12 <RandOrder>1</RandOrder> 13 <RandGain>1</RandGain> 14 <GainUpper>0.25</GainUpper> 15 <GainLower>0.2</GainLower> 16 <RandPitch>1</RandPitch> 17 <PitchUpper>1.1</PitchUpper> 18 <PitchLower>0.9</PitchLower> 19 <Threshold>1</Threshold> 20 <Decay>3</Decay> 21 <Replacement>alarmalert0.ogg</Replacement> 22 <Path>audio/interface/alarm/</Path> 23 <Sound>alarmalert0.ogg</Sound> 24 </SoundGroup> -
binaries/data/mods/public/audio/interface/alarm/alarm_alert_1.xml
1 <?xml version="1.0" encoding="utf-8" standalone="no" ?> 2 <SoundGroup> 3 <Omnipresent>1</Omnipresent> 4 <HeardBy>owner</HeardBy> 5 <Gain>0.25</Gain> 6 <Pitch>1</Pitch> 7 <Priority>100</Priority> 8 <ConeGain>1</ConeGain> 9 <ConeInner>360</ConeInner> 10 <ConeOuter>360</ConeOuter> 11 <Looping>0</Looping> 12 <RandOrder>1</RandOrder> 13 <RandGain>1</RandGain> 14 <GainUpper>0.25</GainUpper> 15 <GainLower>0.2</GainLower> 16 <RandPitch>1</RandPitch> 17 <PitchUpper>1.1</PitchUpper> 18 <PitchLower>0.9</PitchLower> 19 <Threshold>1</Threshold> 20 <Decay>3</Decay> 21 <Replacement>alarmalert1.ogg</Replacement> 22 <Path>audio/interface/alarm/</Path> 23 <Sound>alarmalert1.ogg</Sound> 24 </SoundGroup> -
binaries/data/mods/public/audio/interface/alarm/alarm_alert_2.xml
1 <?xml version="1.0" encoding="utf-8" standalone="no" ?> 2 <SoundGroup> 3 <Omnipresent>1</Omnipresent> 4 <HeardBy>owner</HeardBy> 5 <Gain>0.25</Gain> 6 <Pitch>1</Pitch> 7 <Priority>100</Priority> 8 <ConeGain>1</ConeGain> 9 <ConeInner>360</ConeInner> 10 <ConeOuter>360</ConeOuter> 11 <Looping>0</Looping> 12 <RandOrder>1</RandOrder> 13 <RandGain>1</RandGain> 14 <GainUpper>0.25</GainUpper> 15 <GainLower>0.2</GainLower> 16 <RandPitch>1</RandPitch> 17 <PitchUpper>1.1</PitchUpper> 18 <PitchLower>0.9</PitchLower> 19 <Threshold>1</Threshold> 20 <Decay>3</Decay> 21 <Replacement>alarmalert2.ogg</Replacement> 22 <Path>audio/interface/alarm/</Path> 23 <Sound>alarmalert2.ogg</Sound> 24 </SoundGroup> -
binaries/data/mods/public/gui/session/input.js
1906 1906 case "back-to-work": 1907 1907 backToWork(); 1908 1908 break; 1909 case "increase-alert-level": 1910 increaseAlertLevel(); 1911 break; 1912 case "alert-end": 1913 endOfAlert(); 1914 break; 1909 1915 default: 1910 1916 break; 1911 1917 } … … 2179 2185 Engine.PostNetworkCommand({"type": "remove-guard", "entities": entities}); 2180 2186 } 2181 2187 2188 function increaseAlertLevel() 2189 { 2190 var raisers = g_Selection.toList().filter(function(e) { 2191 var state = GetEntityState(e); 2192 return (state && state.alertRaiser && state.alertRaiser.canIncreaseLevel); 2193 }); 2194 2195 Engine.PostNetworkCommand({"type": "increase-alert-level", "entities": raisers}); 2196 } 2197 2198 function endOfAlert() 2199 { 2200 var raisers = g_Selection.toList().filter(function(e) { 2201 var state = GetEntityState(e); 2202 return (state && state.alertRaiser && state.alertRaiser.hasRaisedAlert); 2203 }); 2204 2205 Engine.PostNetworkCommand({"type": "alert-end", "entities": raisers}); 2206 } 2207 2182 2208 function clearSelection() 2183 2209 { 2184 2210 if(inputState==INPUT_BUILDING_PLACEMENT || inputState==INPUT_BUILDING_WALL_PATHING) -
binaries/data/mods/public/gui/session/utility_functions.js
320 320 "icon": "remove-guard.png" 321 321 }); 322 322 } 323 324 if(entState.alertRaiser) 325 { 326 if(entState.alertRaiser.canIncreaseLevel) 327 commands.push({ 328 "name": "increase-alert-level", 329 "tooltip": "Raise the alert ! Or raise it again to protect more units.", 330 "icon": "bell_level1.png" 331 }); 332 333 if(entState.alertRaiser.hasRaisedAlert) 334 commands.push({ 335 "name": "alert-end", 336 "tooltip": "End of alert.", 337 "icon": "bell_level0.png" 338 }); 339 } 323 340 324 341 return commands; 325 342 } -
binaries/data/mods/public/simulation/components/AlertRaiser.js
1 function AlertRaiser() {} 2 3 AlertRaiser.prototype.Schema = 4 "<element name='MaximumLevel'><data type='nonNegativeInteger'/></element>" + 5 "<element name='Range'><data type='nonNegativeInteger'/></element>"; 6 7 AlertRaiser.prototype.Init = function() 8 { 9 this.level = 0; 10 11 // Remember the units ordered to garrison 12 this.garrisonedUnits = []; 13 this.walkingUnits = []; 14 }; 15 16 AlertRaiser.prototype.GetLevel = function() 17 { 18 return this.level; 19 }; 20 21 AlertRaiser.prototype.HasRaisedAlert = function() 22 { 23 return this.level > 0; 24 }; 25 26 AlertRaiser.prototype.CanIncreaseLevel = function() 27 { 28 return this.template.MaximumLevel > this.level; 29 }; 30 31 AlertRaiser.prototype.SoundAlert = function() 32 { 33 var alertString = "alert" + this.level; 34 PlaySound(alertString, this.entity); 35 }; 36 37 AlertRaiser.prototype.IncreaseAlertLevel = function() 38 { 39 if(!this.CanIncreaseLevel()) 40 return false; 41 42 // Find units owned by this unit's player 43 var players = []; 44 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 45 if (cmpOwnership) 46 players = [cmpOwnership.GetOwner()]; 47 48 this.level++; 49 this.SoundAlert(); 50 51 // Select units to put under alert, ignoring domestic animals (NB : war dogs are not domestic) 52 var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 53 var level = this.GetLevel(); 54 var units = rangeMan.ExecuteQuery(this.entity, 0, this.template.Range, players, IID_UnitAI).filter( function(e){ 55 var cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI); 56 return (cmpUnitAI.ReactsToAlert(level) && !cmpUnitAI.IsDomestic()); 57 }); 58 59 for each(var unit in units) 60 { 61 var cmpUnitAI = Engine.QueryInterface(unit, IID_UnitAI); 62 cmpUnitAI.ReplaceOrder("Alert", {"raiser": this.entity, "force": true}); 63 this.walkingUnits.push(unit); 64 } 65 66 return true; 67 }; 68 69 AlertRaiser.prototype.OnUnitGarrisonedAfterAlert = function(msg) 70 { 71 this.garrisonedUnits.push({"holder": msg.holder, "unit": msg.unit}); 72 73 var index = this.walkingUnits.indexOf(msg.unit); 74 if (index != -1) 75 this.walkingUnits.splice(index, 1); 76 77 } 78 79 AlertRaiser.prototype.EndOfAlert = function() 80 { 81 this.level = 0; 82 this.SoundAlert(); 83 84 // First, handle units not yet garrisoned 85 for each(var unit in this.walkingUnits) 86 { 87 var cmpUnitAI = Engine.QueryInterface(unit, IID_UnitAI); 88 89 cmpUnitAI.ResetAlert(); 90 91 if (cmpUnitAI.HasWorkOrders()) 92 cmpUnitAI.BackToWork(); 93 else 94 cmpUnitAI.ReplaceOrder("Stop", undefined); 95 } 96 this.walkingUnits = []; 97 98 // Then, eject garrisoned units 99 for each(var slot in this.garrisonedUnits) 100 { 101 var cmpGarrisonHolder = Engine.QueryInterface(slot.holder, IID_GarrisonHolder); 102 var cmpUnitAI = Engine.QueryInterface(slot.unit, IID_UnitAI); 103 104 if(cmpGarrisonHolder && cmpGarrisonHolder.PerformEject([slot.unit], true)) 105 { 106 cmpUnitAI.ResetAlert(); 107 if (cmpUnitAI.HasWorkOrders()) 108 cmpUnitAI.BackToWork(); 109 } 110 } 111 this.garrisonedUnits = []; 112 113 return true; 114 }; 115 116 Engine.RegisterComponentType(IID_AlertRaiser, "AlertRaiser", AlertRaiser); -
binaries/data/mods/public/simulation/components/GarrisonHolder.js
247 247 cmpAura.ApplyGarrisonBonus(this.entity); 248 248 249 249 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {}); 250 251 var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); 252 if (cmpUnitAI && cmpUnitAI.GetAlertRaiser()) 253 Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity}); 254 250 255 return true; 251 256 }; 252 257 -
binaries/data/mods/public/simulation/components/GuiInterface.js
375 375 ret.resourceGatherRates = cmpResourceGatherer.GetGatherRates(); 376 376 ret.resourceCarrying = cmpResourceGatherer.GetCarryingStatus(); 377 377 } 378 379 var cmpAlertRaiser = Engine.QueryInterface(ent, IID_AlertRaiser); 380 if(cmpAlertRaiser) 381 { 382 ret.alertRaiser = { 383 "level": cmpAlertRaiser.GetLevel(), 384 "canIncreaseLevel": cmpAlertRaiser.CanIncreaseLevel(), 385 "hasRaisedAlert": cmpAlertRaiser.HasRaisedAlert(), 386 }; 387 } 378 388 379 389 var cmpResourceDropsite = Engine.QueryInterface(ent, IID_ResourceDropsite); 380 390 if (cmpResourceDropsite) -
binaries/data/mods/public/simulation/components/interfaces/AlertRaiser.js
1 Engine.RegisterInterface("AlertRaiser"); 2 No newline at end of file -
binaries/data/mods/public/simulation/components/interfaces/GarrisonHolder.js
4 4 // sent to the current entity whenever the garrisoned units change. 5 5 Engine.RegisterMessageType("GarrisonedUnitsChanged"); 6 6 7 // Message of the form { "holder": this.entity, "unit" : unit } sent to the AlertRaiser 8 // which ordered the unit "unit" to garrison. 9 Engine.RegisterMessageType("UnitGarrisonedAfterAlert"); -
binaries/data/mods/public/simulation/components/UnitAI.js
3 3 UnitAI.prototype.Schema = 4 4 "<a:help>Controls the unit's movement, attacks, etc, in response to commands from the player.</a:help>" + 5 5 "<a:example/>" + 6 "<element name='AlertReactiveLevel'>" + 7 "<data type='nonNegativeInteger'/>" + 8 "</element>" + 6 9 "<element name='DefaultStance'>" + 7 10 "<choice>" + 8 11 "<value>violent</value>" + … … 684 687 this.SetNextState("INDIVIDUAL.AUTOGARRISON"); 685 688 }, 686 689 690 "Order.Alert": function(msg) { 691 this.alertRaiser = this.order.data.raiser; 692 693 // Find a target to garrison into, if we don't already have one 694 if(!this.alertGarrisoningTarget) 695 this.alertGarrisoningTarget = this.FindNearbyGarrisonHolder(); 696 697 if(this.alertGarrisoningTarget) 698 this.ReplaceOrder("Garrison", {"target": this.alertGarrisoningTarget}); 699 else 700 this.FinishOrder(); 701 }, 702 687 703 "Order.Cheering": function(msg) { 688 704 this.SetNextState("INDIVIDUAL.CHEERING"); 689 705 }, … … 2546 2562 }, 2547 2563 2548 2564 "MoveCompleted": function() { 2549 this.SetNextState("GARRISONED"); 2565 if(this.IsUnderAlert()) 2566 { 2567 // check that we can garrison in the building we're supposed to garrison in 2568 var cmpGarrisonHolder = Engine.QueryInterface(this.alertGarrisoningTarget, IID_GarrisonHolder); 2569 if (!cmpGarrisonHolder || cmpGarrisonHolder.IsFull()) 2570 { 2571 // Try to find another nearby building 2572 var nearby = this.FindNearbyGarrisonHolder(); 2573 if (nearby) 2574 { 2575 this.alertGarrisoningTarget = nearby; 2576 if (this.MoveToTarget(this.alertGarrisoningTarget)) 2577 this.SetNextState("APPROACHING"); 2578 } 2579 else 2580 this.FinishOrder(); 2581 } 2582 else 2583 this.SetNextState("GARRISONED"); 2584 } 2585 else 2586 this.SetNextState("GARRISONED"); 2550 2587 }, 2551 2588 }, 2552 2589 2553 2590 "GARRISONED": { 2554 2591 "enter": function() { 2555 var target = this.order.data.target; 2592 // Target is not handled the same way with Alert and direct garrisoning 2593 if(this.order.data.target) 2594 var target = this.order.data.target; 2595 else 2596 { 2597 if(!this.alertGarrisoningTarget) 2598 { 2599 // We've been unable to find a target nearby, so give up 2600 this.FinishOrder(); 2601 return true; 2602 } 2603 var target = this.alertGarrisoningTarget; 2604 } 2605 2556 2606 var cmpGarrisonHolder = Engine.QueryInterface(target, IID_GarrisonHolder); 2557 2607 2558 2608 // Check that we can garrison here … … 2877 2927 2878 2928 this.isGuardOf = undefined; 2879 2929 2930 // "Town Bell" behaviour 2931 this.alertRaiser = undefined; 2932 this.alertGarrisoningTarget = undefined; 2933 2880 2934 // For preventing increased action rate due to Stop orders or target death. 2881 2935 this.lastAttacked = undefined; 2882 2936 this.lastHealed = undefined; … … 2884 2938 this.SetStance(this.template.DefaultStance); 2885 2939 }; 2886 2940 2941 UnitAI.prototype.ReactsToAlert = function(level) 2942 { 2943 return this.template.AlertReactiveLevel <= level; 2944 }; 2945 2946 UnitAI.prototype.IsUnderAlert = function() 2947 { 2948 return this.alertGarrisoningTarget != undefined; 2949 }; 2950 2951 UnitAI.prototype.ResetAlert = function() 2952 { 2953 this.alertGarrisoningTarget = undefined; 2954 }; 2955 2887 2956 UnitAI.prototype.IsFormationController = function() 2888 2957 { 2889 2958 return (this.template.FormationController == "true"); … … 3482 3551 this.workOrders = orders; 3483 3552 }; 3484 3553 3554 UnitAI.prototype.GetAlertRaiser = function() 3555 { 3556 return this.alertRaiser; 3557 }; 3558 3485 3559 UnitAI.prototype.TimerHandler = function(data, lateness) 3486 3560 { 3487 3561 // Reset the timer … … 3678 3752 var players = []; 3679 3753 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 3680 3754 if (cmpOwnership) 3681 players .push(cmpOwnership.GetOwner());3755 players = [cmpOwnership.GetOwner()]; 3682 3756 3683 3757 // Ships are unable to reach land dropsites and shouldn't attempt to do so. 3684 3758 var excludeLand = Engine.QueryInterface(this.entity, IID_Identity).HasClass("Ship"); … … 3716 3790 var players = []; 3717 3791 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 3718 3792 if (cmpOwnership) 3719 players .push(cmpOwnership.GetOwner());3793 players = [cmpOwnership.GetOwner()]; 3720 3794 3721 3795 var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 3722 3796 var nearby = rangeMan.ExecuteQuery(this.entity, 0, range, players, IID_Foundation); … … 3736 3810 }; 3737 3811 3738 3812 /** 3813 * Returns the entity ID of the nearest building in which the unit can garrison, 3814 * or undefined if none can be found close enough. 3815 */ 3816 UnitAI.prototype.FindNearbyGarrisonHolder = function() 3817 { 3818 var range = 128; // TODO: what's a sensible number? 3819 3820 // Find buildings owned by this unit's player 3821 var players = []; 3822 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 3823 if (cmpOwnership) 3824 players = [cmpOwnership.GetOwner()]; 3825 3826 var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 3827 var nearby = rangeMan.ExecuteQuery(this.entity, 0, range, players, IID_GarrisonHolder); 3828 for each (var ent in nearby) 3829 { 3830 var cmpGarrisonHolder = Engine.QueryInterface(ent, IID_GarrisonHolder); 3831 // We only want to garrison in buildings, not in moving units like ships,... 3832 var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); 3833 if (!cmpUnitAI && cmpGarrisonHolder.AllowedToGarrison(this.entity) && !cmpGarrisonHolder.IsFull()) 3834 return ent; 3835 } 3836 3837 return undefined; 3838 }; 3839 3840 /** 3739 3841 * Play a sound appropriate to the current entity. 3740 3842 */ 3741 3843 UnitAI.prototype.PlaySound = function(name) -
binaries/data/mods/public/simulation/helpers/Commands.js
422 422 notifyUnloadFailure(player, garrisonHolder) 423 423 } 424 424 break; 425 426 case "increase-alert-level": 427 for each (var raiser in entities) 428 { 429 var cmpAlertRaiser = Engine.QueryInterface(raiser, IID_AlertRaiser); 430 if (!cmpAlertRaiser || !cmpAlertRaiser.IncreaseAlertLevel()) 431 notifyAlertFailure(player); 432 } 433 break; 434 435 case "alert-end": 436 for each (var raiser in entities) 437 { 438 var cmpAlertRaiser = Engine.QueryInterface(raiser, IID_AlertRaiser); 439 if (cmpAlertRaiser) 440 cmpAlertRaiser.EndOfAlert(); 441 } 442 break; 425 443 426 444 case "formation": 427 445 GetFormationUnitAIs(entities, player, cmd.name).forEach(function(cmpUnitAI) { … … 561 579 } 562 580 563 581 /** 582 * Sends a GUI notification about Alerts that failed to be raised 583 */ 584 function notifyAlertFailure(player) 585 { 586 var cmpPlayer = QueryPlayerIDInterface(player, IID_Player); 587 var notification = {"player": cmpPlayer.GetPlayerID(), "message": "You can't raise the alert to a higher level !" }; 588 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 589 cmpGUIInterface.PushNotification(notification); 590 } 591 592 /** 564 593 * Get some information about the formations used by entities. 565 594 * The entities must have a UnitAI component. 566 595 */ -
binaries/data/mods/public/simulation/templates/special/formation.xml
14 14 <TurnRate>3.0</TurnRate> 15 15 </Position> 16 16 <UnitAI> 17 <AlertReactiveLevel>2</AlertReactiveLevel> 17 18 <DefaultStance>aggressive</DefaultStance> 18 19 <FleeDistance>12.0</FleeDistance> 19 20 <FormationController>true</FormationController> -
binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
98 98 <constructed>interface/complete/building/complete_civ_center.xml</constructed> 99 99 <attack>attack/weapon/arrowfly.xml</attack> 100 100 <death>attack/destruction/building_collapse_large.xml</death> 101 <alert0>interface/alarm/alarm_alert_0.xml</alert0> 102 <alert1>interface/alarm/alarm_alert_1.xml</alert1> 103 <alert2>interface/alarm/alarm_alert_2.xml</alert2> 101 104 </SoundGroups> 102 105 </Sound> 103 106 <TerritoryInfluence> … … 105 108 <Radius>140</Radius> 106 109 <Weight>65536</Weight> 107 110 </TerritoryInfluence> 111 <AlertRaiser> 112 <MaximumLevel>2</MaximumLevel> 113 <Range>140</Range> 114 </AlertRaiser> 108 115 <Vision> 109 116 <Range>90</Range> 110 117 </Vision> -
binaries/data/mods/public/simulation/templates/template_unit.xml
99 99 <HeightOffset>5.0</HeightOffset> 100 100 </StatusBars> 101 101 <UnitAI> 102 <AlertReactiveLevel>2</AlertReactiveLevel> 102 103 <DefaultStance>aggressive</DefaultStance> 103 104 <FleeDistance>12.0</FleeDistance> 104 105 <FormationController>false</FormationController> -
binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
95 95 <Stamina> 96 96 <Max>500</Max> 97 97 </Stamina> 98 <UnitAI> 99 <AlertReactiveLevel>1</AlertReactiveLevel> 100 </UnitAI> 98 101 <UnitMotion> 99 102 <WalkSpeed>8.0</WalkSpeed> 100 103 <Run>