Ticket #2154: patch_townbell.2.diff
File patch_townbell.2.diff, 19.7 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/audio/interface/alarm/alarm_alert.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>alarmalert.ogg</Replacement> 22 <Path>audio/interface/alarm/</Path> 23 <Sound>alarmalert.ogg</Sound> 24 </SoundGroup> -
binaries/data/mods/public/audio/interface/alarm/alarm_alert_end.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>alarmalertend.ogg</Replacement> 22 <Path>audio/interface/alarm/</Path> 23 <Sound>alarmalertend.ogg</Sound> 24 </SoundGroup> -
binaries/data/mods/public/audio/interface/alarm/alarm_alert_red.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>alarmalertred.ogg</Replacement> 22 <Path>audio/interface/alarm/</Path> 23 <Sound>alarmalertred.ogg</Sound> 24 </SoundGroup> -
binaries/data/mods/public/gui/session/input.js
1844 1844 case "back-to-work": 1845 1845 backToWork(); 1846 1846 break; 1847 case "raise-alert-yellow": 1848 raiseYellowAlert(); 1849 break; 1850 case "raise-alert-red": 1851 raiseRedAlert(); 1852 break; 1853 case "alert-end": 1854 endOfAlert(); 1855 break; 1847 1856 default: 1848 1857 break; 1849 1858 } … … 2118 2127 2119 2128 } 2120 2129 2130 function raiseYellowAlert() 2131 { 2132 var raisers = g_Selection.toList().filter(function(e) { 2133 var state = GetEntityState(e); 2134 if (state && state.alertRaiser && state.alertRaiser.level == "End") 2135 return true; 2136 return false; 2137 }); 2138 2139 Engine.PostNetworkCommand({"type": "raise-alert-yellow", "entities": raisers}); 2140 } 2141 2142 function raiseRedAlert() 2143 { 2144 var raisers = g_Selection.toList().filter(function(e) { 2145 var state = GetEntityState(e); 2146 if (state && state.alertRaiser && state.alertRaiser.level == "Yellow") 2147 return true; 2148 return false; 2149 }); 2150 2151 Engine.PostNetworkCommand({"type": "raise-alert-red", "entities": raisers}); 2152 } 2153 2154 function endOfAlert() 2155 { 2156 var raisers = g_Selection.toList().filter(function(e) { 2157 var state = GetEntityState(e); 2158 if (state && state.alertRaiser && (state.alertRaiser.level == "Yellow" || state.alertRaiser.level == "Red")) 2159 return true; 2160 return false; 2161 }); 2162 2163 Engine.PostNetworkCommand({"type": "alert-end", "entities": raisers}); 2164 } 2165 2121 2166 function clearSelection() 2122 2167 { 2123 2168 if(inputState==INPUT_BUILDING_PLACEMENT || inputState==INPUT_BUILDING_WALL_PATHING) -
binaries/data/mods/public/gui/session/utility_functions.js
302 302 "icon": "production.png" 303 303 }); 304 304 } 305 306 if(entState.alertRaiser) 307 { 308 switch(entState.alertRaiser.level) 309 { 310 case "End": 311 commands.push({ 312 "name": "raise-alert-yellow", 313 "tooltip": "Alert : Garrison all female citizens in the first nearby building", 314 "icon": "bell_level1.png" 315 }); 316 break; 317 case "Yellow": 318 commands.push({ 319 "name": "raise-alert-red", 320 "tooltip": "Red Alert : Garrison also the citizen-soldiers", 321 "icon": "bell_level2.png" 322 }); 323 commands.push({ 324 "name": "alert-end", 325 "tooltip": "End of Alert", 326 "icon": "bell_level0.png" 327 }); 328 break; 329 case "Red": 330 commands.push({ 331 "name": "alert-end", 332 "tooltip": "End of Alert", 333 "icon": "bell_level0.png" 334 }); 335 break; 336 default: 337 break; 338 } 339 } 305 340 306 341 return commands; 307 342 } -
binaries/data/mods/public/simulation/components/AlertRaiser.js
1 function AlertRaiser() {} 2 3 AlertRaiser.prototype.Schema = "<element name='Range'><data type='nonNegativeInteger'/></element>"; 4 5 AlertRaiser.prototype.Init = function() 6 { 7 this.level = "End"; 8 9 // Remember the units ordered to garrison 10 this.garrisonedUnits = []; 11 this.walkingUnits = []; 12 }; 13 14 AlertRaiser.prototype.GetLevel = function() 15 { 16 return this.level; 17 }; 18 19 AlertRaiser.prototype.RaiseYellowAlert = function() 20 { 21 // Find units owned by this unit's player 22 var players = []; 23 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 24 if (cmpOwnership) 25 players.push(cmpOwnership.GetOwner()); 26 27 var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 28 var units = rangeMan.ExecuteQuery(this.entity, 0, this.template.Range, players, IID_UnitAI).filter( function(e){ 29 var cmpIdentity = Engine.QueryInterface(e, IID_Identity); 30 return (cmpIdentity && cmpIdentity.HasClass("Female")); 31 }); 32 33 this.level = "Yellow"; 34 PlaySound("alert", this.entity); 35 36 for each(unit in units) 37 { 38 var cmpUnitAI = Engine.QueryInterface(unit, IID_UnitAI); 39 cmpUnitAI.ReplaceOrder("Alert", {"raiser": this.entity, "force": true}); 40 this.walkingUnits.push(unit); 41 } 42 43 return true; 44 }; 45 46 AlertRaiser.prototype.RaiseRedAlert = function() 47 { 48 // Find units owned by this unit's player 49 var players = []; 50 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 51 if (cmpOwnership) 52 players.push(cmpOwnership.GetOwner()); 53 54 // If a yellow alert has already been raised, only give orders to the units who don't already have orders. 55 var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 56 var units = rangeMan.ExecuteQuery(this.entity, 0, this.template.Range, players, IID_UnitAI).filter( function(e){ 57 var cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI); 58 return (!cmpUnitAI.IsUnderAlert() && !cmpUnitAI.IsAnimal()); 59 }); 60 61 this.level = "Red"; 62 PlaySound("alertred", this.entity); 63 64 for each(unit in units) 65 { 66 var cmpUnitAI = Engine.QueryInterface(unit, IID_UnitAI); 67 cmpUnitAI.ReplaceOrder("Alert", {"raiser": this.entity, "force": true}); 68 this.walkingUnits.push(unit); 69 } 70 71 return true; 72 }; 73 74 AlertRaiser.prototype.OnUnitGarrisonedAfterAlert = function(msg) 75 { 76 this.garrisonedUnits.push({"holder": msg.holder, "unit": msg.unit}); 77 78 var index = this.walkingUnits.indexOf(msg.unit); 79 if (index != -1) 80 this.walkingUnits.splice(index, 1); 81 82 } 83 84 AlertRaiser.prototype.EndOfAlert = function() 85 { 86 // First, handle units not yet garrisoned 87 for each(unit in this.walkingUnits) 88 { 89 var cmpUnitAI = Engine.QueryInterface(unit, IID_UnitAI); 90 if (cmpUnitAI) 91 { 92 cmpUnitAI.ResetAlert(); 93 94 if (cmpUnitAI.HasWorkOrders()) 95 cmpUnitAI.BackToWork(); 96 else 97 cmpUnitAI.ReplaceOrder("Stop", undefined); 98 } 99 } 100 this.walkingUnits = []; 101 102 // Then, eject garrisoned units 103 for each(slot in this.garrisonedUnits) 104 { 105 var cmpGarrisonHolder = Engine.QueryInterface(slot.holder, IID_GarrisonHolder); 106 var cmpUnitAI = Engine.QueryInterface(slot.unit, IID_UnitAI); 107 108 if(cmpGarrisonHolder) 109 { 110 var success = cmpGarrisonHolder.PerformEject([slot.unit], true); 111 if (success && cmpUnitAI) 112 { 113 cmpUnitAI.ResetAlert(); 114 if (cmpUnitAI.HasWorkOrders()) 115 cmpUnitAI.BackToWork(); 116 } 117 } 118 } 119 this.garrisonedUnits = []; 120 121 this.level = "End"; 122 PlaySound("alertend", this.entity); 123 return true; 124 }; 125 126 Engine.RegisterComponentType(IID_AlertRaiser, "AlertRaiser", AlertRaiser); -
binaries/data/mods/public/simulation/components/GarrisonHolder.js
239 239 cmpAura.ApplyGarrisonBonus(this.entity); 240 240 241 241 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {}); 242 243 var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); 244 if (cmpUnitAI && cmpUnitAI.GetAlertRaiser()) 245 Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity}); 246 242 247 return true; 243 248 }; 244 249 -
binaries/data/mods/public/simulation/components/GuiInterface.js
350 350 "state": cmpUnitAI.GetCurrentState(), 351 351 "orders": cmpUnitAI.GetOrders(), 352 352 "hasWorkOrders": cmpUnitAI.HasWorkOrders(), 353 "isUnderAlert": cmpUnitAI.IsUnderAlert(), 353 354 }; 354 355 // Add some information needed for ungarrisoning 355 356 if (cmpUnitAI.isGarrisoned && ret.player !== undefined) … … 378 379 "healableClasses": cmpHeal.GetHealableClasses(), 379 380 }; 380 381 } 382 383 var cmpAlertRaiser = Engine.QueryInterface(ent, IID_AlertRaiser); 384 if(cmpAlertRaiser) 385 { 386 ret.alertRaiser = { 387 "level": cmpAlertRaiser.GetLevel(), 388 }; 389 } 381 390 382 391 ret.visibility = cmpRangeManager.GetLosVisibility(ent, player, false); 383 392 -
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
663 663 } 664 664 }, 665 665 666 "Order.Alert": function(msg) { 667 this.alertRaiser = this.order.data.raiser; 668 669 // Find a target to garrison into, if we don't already have one 670 if(!this.garrisoningTarget) 671 { 672 var nearby = this.FindNearbyGarrisonHolder(); 673 if (nearby) 674 this.garrisoningTarget = nearby; 675 else 676 this.FinishOrder(); 677 } 678 679 this.ReplaceOrder("Garrison", {"target": this.garrisoningTarget}); 680 }, 681 666 682 "Order.Cheering": function(msg) { 667 683 this.SetNextState("INDIVIDUAL.CHEERING"); 668 684 }, … … 2382 2398 }, 2383 2399 2384 2400 "MoveCompleted": function() { 2385 this.SetNextState("GARRISONED"); 2401 if(this.garrisoningTarget) // We're under Alert 2402 { 2403 // check that we can garrison in the building we're supposed to garrison in 2404 var cmpGarrisonHolder = Engine.QueryInterface(this.garrisoningTarget, IID_GarrisonHolder); 2405 if (!cmpGarrisonHolder || cmpGarrisonHolder.GetCapacity() <= cmpGarrisonHolder.GetEntities().length) 2406 { 2407 // Try to find another nearby building 2408 var nearby = this.FindNearbyGarrisonHolder(); 2409 if (nearby) 2410 { 2411 this.garrisoningTarget = nearby; 2412 if (this.MoveToTarget(this.garrisoningTarget)) 2413 this.SetNextState("APPROACHING"); 2414 } 2415 else 2416 this.FinishOrder(); 2417 } 2418 else 2419 this.SetNextState("GARRISONED"); 2420 } 2421 else 2422 this.SetNextState("GARRISONED"); 2386 2423 }, 2387 2424 }, 2388 2425 2389 2426 "GARRISONED": { 2390 2427 "enter": function() { 2391 var target = this.order.data.target; 2428 // Target is not handled the same way with Alert and direct garrisoning 2429 if(this.order.data.target) 2430 var target = this.order.data.target; 2431 else 2432 { 2433 if(!this.garrisoningTarget) 2434 { 2435 // We've been unable to find a target nearby, so give up 2436 this.FinishOrder(); 2437 return true; 2438 } 2439 var target = this.garrisoningTarget; 2440 } 2441 2392 2442 var cmpGarrisonHolder = Engine.QueryInterface(target, IID_GarrisonHolder); 2393 2443 2394 2444 // Check that we can garrison here … … 2695 2745 // Queue of remembered works 2696 2746 this.workOrders = []; 2697 2747 2748 // "Town Bell" behaviour 2749 this.alertRaiser = undefined; 2750 this.garrisoningTarget = undefined; 2751 2698 2752 // For preventing increased action rate due to Stop orders or target death. 2699 2753 this.lastAttacked = undefined; 2700 2754 this.lastHealed = undefined; … … 2702 2756 this.SetStance(this.template.DefaultStance); 2703 2757 }; 2704 2758 2759 UnitAI.prototype.IsUnderAlert = function() 2760 { 2761 return (this.garrisoningTarget != undefined); 2762 }; 2763 2764 UnitAI.prototype.ResetAlert = function() 2765 { 2766 this.garrisoningTarget = undefined; 2767 }; 2768 2705 2769 UnitAI.prototype.IsFormationController = function() 2706 2770 { 2707 2771 return (this.template.FormationController == "true"); … … 3301 3365 this.workOrders = orders; 3302 3366 }; 3303 3367 3368 UnitAI.prototype.GetAlertRaiser = function() 3369 { 3370 return this.alertRaiser; 3371 }; 3372 3304 3373 UnitAI.prototype.TimerHandler = function(data, lateness) 3305 3374 { 3306 3375 // Reset the timer … … 3545 3614 }; 3546 3615 3547 3616 /** 3617 * Returns the entity ID of the nearest building in which the unit can garrison, 3618 * or undefined if none can be found close enough. 3619 */ 3620 UnitAI.prototype.FindNearbyGarrisonHolder = function() 3621 { 3622 var range = 128; // TODO: what's a sensible number? 3623 3624 // Find buildings owned by this unit's player 3625 var players = []; 3626 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 3627 if (cmpOwnership) 3628 players.push(cmpOwnership.GetOwner()); 3629 3630 var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 3631 var nearby = rangeMan.ExecuteQuery(this.entity, 0, range, players, IID_GarrisonHolder); 3632 for each (var ent in nearby) 3633 { 3634 var cmpGarrisonHolder = Engine.QueryInterface(ent, IID_GarrisonHolder); 3635 // We only want to garrison in buildings, not in moving units like ships,... 3636 var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); 3637 if (!cmpUnitAI && cmpGarrisonHolder.AllowedToGarrison(this.entity) && cmpGarrisonHolder.GetCapacity() > cmpGarrisonHolder.GetEntities().length) 3638 return ent; 3639 } 3640 3641 return undefined; 3642 }; 3643 3644 /** 3548 3645 * Play a sound appropriate to the current entity. 3549 3646 */ 3550 3647 UnitAI.prototype.PlaySound = function(name) -
binaries/data/mods/public/simulation/helpers/Commands.js
399 399 notifyUnloadFailure(player, garrisonHolder) 400 400 } 401 401 break; 402 403 case "raise-alert-yellow": 404 for each (var raiser in entities) 405 { 406 var cmpAlertRaiser = Engine.QueryInterface(raiser, IID_AlertRaiser); 407 if (!cmpAlertRaiser || !cmpAlertRaiser.RaiseYellowAlert()) 408 notifyAlertFailure(player); 409 } 410 break; 411 412 case "raise-alert-red": 413 for each (var raiser in entities) 414 { 415 var cmpAlertRaiser = Engine.QueryInterface(raiser, IID_AlertRaiser); 416 if (!cmpAlertRaiser || !cmpAlertRaiser.RaiseRedAlert()) 417 notifyAlertFailure(player); 418 } 419 break; 420 421 case "alert-end": 422 for each (var raiser in entities) 423 { 424 var cmpAlertRaiser = Engine.QueryInterface(raiser, IID_AlertRaiser); 425 if (!cmpAlertRaiser || !cmpAlertRaiser.EndOfAlert()) 426 notifyAlertFailure(player); 427 } 428 break; 402 429 403 430 case "formation": 404 431 GetFormationUnitAIs(entities, player, cmd.name).forEach(function(cmpUnitAI) { … … 538 565 } 539 566 540 567 /** 568 * Sends a GUI notification about Alerts that failed to be raised 569 */ 570 function notifyAlertFailure(player) 571 { 572 var cmpPlayer = QueryPlayerIDInterface(player, IID_Player); 573 var notification = {"player": cmpPlayer.GetPlayerID(), "message": "Unable to sound the horns" }; 574 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 575 cmpGUIInterface.PushNotification(notification); 576 } 577 578 /** 541 579 * Get some information about the formations used by entities. 542 580 * The entities must have a UnitAI component. 543 581 */ -
binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
91 91 <constructed>interface/complete/building/complete_civ_center.xml</constructed> 92 92 <attack>attack/weapon/arrowfly.xml</attack> 93 93 <death>attack/destruction/building_collapse_large.xml</death> 94 <alert>interface/alarm/alarm_alert.xml</alert> 95 <alertred>interface/alarm/alarm_alert_red.xml</alertred> 96 <alertend>interface/alarm/alarm_alert_end.xml</alertend> 94 97 </SoundGroups> 95 98 </Sound> 96 99 <TerritoryInfluence> … … 98 101 <Radius>140</Radius> 99 102 <Weight>65536</Weight> 100 103 </TerritoryInfluence> 104 <AlertRaiser> 105 <Range>140</Range> 106 </AlertRaiser> 101 107 <Vision> 102 108 <Range>90</Range> 103 109 </Vision>