From 5ddd6148e6fcffb1efb70ba7a6cd3290f9dad570 Mon Sep 17 00:00:00 2001 From: squeek Date: Tue, 9 Dec 2014 18:08:19 -0800 Subject: [PATCH 01/38] Fix unicode character support in VGUI/HUD elements * The "custom" "1" font flag breaks things and doesn't seem to be necessary, but I'm not totally sure what it's for (see https://developer.valvesoftware.com/wiki/Authoring_and_Using_TrueType_Fonts#The_.22Scheme.22) * Fixes fortressforever/fortressforever#19 --- resource/ClientScheme.res | 54 --------------------------------------- resource/SourceScheme.res | 14 ---------- 2 files changed, 68 deletions(-) diff --git a/resource/ClientScheme.res b/resource/ClientScheme.res index 0ef833a..5d41fa8 100644 --- a/resource/ClientScheme.res +++ b/resource/ClientScheme.res @@ -462,7 +462,6 @@ Scheme "1" { "name" "FortressForever - HUD Glyphs" - "custom" "1" "tall" "16" "weight" "0" "antialias" "1" @@ -471,7 +470,6 @@ Scheme "2" { "name" "FortressForever - HUD Glyphs" - "custom" "1" "tall" "18" "weight" "0" "antialias" "1" @@ -480,7 +478,6 @@ Scheme "3" { "name" "FortressForever - HUD Glyphs" - "custom" "1" "tall" "24" "weight" "0" "antialias" "1" @@ -489,7 +486,6 @@ Scheme "4" { "name" "FortressForever - HUD Glyphs" - "custom" "1" "tall" "32" "weight" "0" "antialias" "1" @@ -498,7 +494,6 @@ Scheme "5" { "name" "FortressForever - HUD Glyphs" - "custom" "1" "tall" "40" "weight" "0" "antialias" "1" @@ -510,7 +505,6 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "32" "weight" "0" "antialias" "1" @@ -519,7 +513,6 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "35" "weight" "0" "antialias" "1" @@ -528,7 +521,6 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "37" "weight" "0" "antialias" "1" @@ -537,7 +529,6 @@ Scheme "4" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "43" "weight" "0" "antialias" "1" @@ -546,7 +537,6 @@ Scheme "5" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "47" "weight" "0" "antialias" "1" @@ -802,7 +792,6 @@ Scheme "weight" "0" "antialias" "0" "additive" "1" - "custom" "1" "yres" "1 10000" } } @@ -815,7 +804,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } HudNumbers @@ -827,7 +815,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } HudNumbersGlow @@ -841,7 +828,6 @@ Scheme "scanlines" "2" "antialias" "1" "additive" "1" - "custom" "1" } } HudNumbersSmall @@ -853,7 +839,6 @@ Scheme "weight" "1000" "additive" "1" "antialias" "1" - "custom" "1" } } HudSelectionNumbers @@ -877,7 +862,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } @@ -892,7 +876,6 @@ Scheme "scanlines" "2" "antialias" "1" "additive" "1" - "custom" "1" } } @@ -1121,7 +1104,6 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "24" "weight" "0" "additive" "0" @@ -1132,7 +1114,6 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "40" "weight" "0" "additive" "0" @@ -1142,7 +1123,6 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "48" "weight" "0" "additive" "0" @@ -1152,7 +1132,6 @@ Scheme "4" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "80" "weight" "0" "yres" "1024 1199" @@ -1161,7 +1140,6 @@ Scheme "5" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "96" "weight" "0" "yres" "1200 6000" @@ -1177,7 +1155,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } CreditsText @@ -1200,7 +1177,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } CreditsOutroText @@ -1277,7 +1253,6 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "9" "weight" "500" "antialias" "1" @@ -1286,7 +1261,6 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "11" "weight" "500" "antialias" "1" @@ -1295,7 +1269,6 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "13" "weight" "600" "antialias" "1" @@ -1304,7 +1277,6 @@ Scheme "4" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "16" "weight" "900" "antialias" "1" @@ -1313,7 +1285,6 @@ Scheme "5" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "17" "weight" "1000" "antialias" "1" @@ -1326,7 +1297,6 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "18" "weight" "500" "antialias" "1" @@ -1335,7 +1305,6 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "18" "weight" "500" "antialias" "1" @@ -1344,7 +1313,6 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "24" "weight" "600" "antialias" "1" @@ -1353,7 +1321,6 @@ Scheme "4" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "36" "weight" "900" "antialias" "1" @@ -1362,7 +1329,6 @@ Scheme "5" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "48" "weight" "1000" "antialias" "1" @@ -1374,7 +1340,6 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "10" "weight" "300" "antialias" "1" @@ -1383,7 +1348,6 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "12" "weight" "500" "antialias" "1" @@ -1392,7 +1356,6 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "14" "weight" "500" "antialias" "1" @@ -1401,7 +1364,6 @@ Scheme "4" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "20" "weight" "1000" "antialias" "1" @@ -1410,7 +1372,6 @@ Scheme "5" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "24" "weight" "1000" "antialias" "1" @@ -1423,7 +1384,6 @@ Scheme { "name" "FortressForever - HUD Glyphs" "tall" "31" - "custom" "1" "antialias" "1" } } @@ -1433,7 +1393,6 @@ Scheme { "name" "FortressForever - HUD Glyphs" "tall" "31" - "custom" "1" "antialias" "1" } } @@ -1443,7 +1402,6 @@ Scheme { "name" "FortressForever - HUD Glyphs" "tall" "10" - "custom" "1" "antialias" "1" } @@ -1454,7 +1412,6 @@ Scheme { "name" "FortressForever - HUD Glyphs" "tall" "20" - "custom" "1" "antialias" "1" } @@ -1484,7 +1441,6 @@ Scheme { "name" "FortressForever - HUD Font" "tall" "12" - "custom" "1" "antialias" "1" "additive" "0" } @@ -1498,7 +1454,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } "WeaponIconsSelected" @@ -1512,7 +1467,6 @@ Scheme "blur" "5" "scanlines" "2" "additive" "1" - "custom" "1" } } "WeaponIconsClassSelect" @@ -1524,7 +1478,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } "WeaponIconsHUD" @@ -1536,7 +1489,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } "WeaponIconsSmall" @@ -1548,7 +1500,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } "AmmoIconsSmall" @@ -1560,7 +1511,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } "StatusGlyphs" @@ -1572,7 +1522,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } "StatusGlyphsSmall" @@ -1584,7 +1533,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } "GrenadeIcons" @@ -1607,7 +1555,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "1" - "custom" "1" } } "ClassGlyphs" // icons on hud when you disguise and such @@ -1619,7 +1566,6 @@ Scheme "weight" "0" "antialias" "1" "additive" "0" - "custom" "1" } } diff --git a/resource/SourceScheme.res b/resource/SourceScheme.res index 438a94b..f4def3c 100644 --- a/resource/SourceScheme.res +++ b/resource/SourceScheme.res @@ -254,7 +254,6 @@ Scheme "name" "FortressForever - HUD Font" "tall" "14" "antialias" "1" - "custom" "1" } } "DefaultBold" //doesn't appear to be used @@ -263,7 +262,6 @@ Scheme { "name" "Tahoma" - "custom" "1" "tall" "16" "weight" "500" } @@ -284,7 +282,6 @@ Scheme { "name" "Verdana" - "custom" "1" "tall" "12" "weight" "0" } @@ -295,7 +292,6 @@ Scheme { "name" "Verdana" - "custom" "1" "tall" "13" "weight" "0" "dropshadow" "1" @@ -307,7 +303,6 @@ Scheme { "name" "Tahoma" - "custom" "1" "tall" "14" "weight" "0" } @@ -319,7 +314,6 @@ Scheme { "name" "Verdana" - "custom" "1" "tall" "18" "weight" "0" } @@ -330,7 +324,6 @@ Scheme { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "16" "weight" "500" "antialias" "1" @@ -342,7 +335,6 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "16" "weight" "500" "antialias" "1" @@ -352,7 +344,6 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "18" "weight" "500" "antialias" "1" @@ -361,7 +352,6 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "22" "weight" "500" "antialias" "1" @@ -370,7 +360,6 @@ Scheme "4" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "24" "weight" "600" "antialias" "1" @@ -379,7 +368,6 @@ Scheme "5" { "name" "FortressForever - HUD Font" - "custom" "1" "tall" "32" "weight" "600" "antialias" "1" @@ -581,7 +569,6 @@ Scheme "tall" "72" "weight" "400" "antialias" "1" - "custom" "1" } } @@ -593,7 +580,6 @@ Scheme "tall" "120" "weight" "400" "antialias" "1" - "custom" "1" } } } From 3424d57a7a1e413fbddc92adf41fcc8b7ed8349a Mon Sep 17 00:00:00 2001 From: squeek Date: Tue, 9 Dec 2014 23:45:47 -0800 Subject: [PATCH 02/38] Add (incomplete) Russian localization by Gordon * Source: http://forums.fortress-forever.com/showpost.php?p=462871&postcount=101 --- resource/FortressForever_russian.txt | Bin 0 -> 12282 bytes resource/gameui_russian.txt | Bin 0 -> 200 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 resource/FortressForever_russian.txt create mode 100644 resource/gameui_russian.txt diff --git a/resource/FortressForever_russian.txt b/resource/FortressForever_russian.txt new file mode 100644 index 0000000000000000000000000000000000000000..bbfb56b4075a3b54b0e0f6445382fb8dc587798d GIT binary patch literal 12282 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 YEofNeW~a4q|8G6FfBJowJu^l92WTVeIRF3v literal 0 HcmV?d00001 diff --git a/resource/gameui_russian.txt b/resource/gameui_russian.txt new file mode 100644 index 0000000000000000000000000000000000000000..068a39af134560ca50359c789c707e18ce30a351 GIT binary patch literal 200 zcmYL@y$S+B5QD#B8UvAh)qhu|bR+l3niF~3#(a=c3Ojn9 d>g`g;Ks{qySZOn%U}AGy+Dbe%kH5YX{{T%q9UlMy literal 0 HcmV?d00001 From 09c0a1c7b5235540803e45cd39b7f4a9d45284c2 Mon Sep 17 00:00:00 2001 From: squeek Date: Tue, 9 Dec 2014 23:47:54 -0800 Subject: [PATCH 03/38] Add Spanish translation by VMX and Firefox11 * Source: http://forums.fortress-forever.com/showpost.php?p=447465&postcount=70 and http://forums.fortress-forever.com/showpost.php?p=447926&postcount=80 --- resource/FortressForever_spanish.txt | Bin 0 -> 92512 bytes resource/gameui_spanish.txt | Bin 0 -> 222 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 resource/FortressForever_spanish.txt create mode 100644 resource/gameui_spanish.txt diff --git a/resource/FortressForever_spanish.txt b/resource/FortressForever_spanish.txt new file mode 100644 index 0000000000000000000000000000000000000000..a239b0c361e9c7d95f01b4c6887a0e2e06b921c7 GIT binary patch literal 92512 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 A&;S4c literal 0 HcmV?d00001 diff --git a/resource/gameui_spanish.txt b/resource/gameui_spanish.txt new file mode 100644 index 0000000000000000000000000000000000000000..9b31729467f21c3c140e35e0380fe512373c7a09 GIT binary patch literal 222 zcmYL@%?iRm5QD$7;5#hyDxyVDSNd}<9;Ap`1=~~cp?v{ucG*SdFeH;?^7|S$PV{sb zjwK7Gw2fW5jM^RNs4&*Nc#8S(kT<)GTKFneuX|?yS%n;TT^qKvWVDa^QOri;l{;`z iPR?-Z;*{n&vXawt(EmzYP?!2yMqEh~y1!HRupKj0uOO=c literal 0 HcmV?d00001 From 767b5b2ab211ee517f4143e13c5fa04cf8d26570 Mon Sep 17 00:00:00 2001 From: squeek Date: Tue, 9 Dec 2014 23:50:14 -0800 Subject: [PATCH 04/38] Add Portuguese (BR) translation by Gemini Saga * Source: http://forums.fortress-forever.com/showpost.php?p=447839&postcount=74 and http://forums.fortress-forever.com/showpost.php?p=447930&postcount=82 --- resource/FortressForever_brazilian.txt | Bin 0 -> 83114 bytes resource/gameui_brazilian.txt | Bin 0 -> 240 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 resource/FortressForever_brazilian.txt create mode 100644 resource/gameui_brazilian.txt diff --git a/resource/FortressForever_brazilian.txt b/resource/FortressForever_brazilian.txt new file mode 100644 index 0000000000000000000000000000000000000000..e96dcf3a239f8a0051b663b8ed65d35418c9a290 GIT binary patch literal 83114 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 ACIA2c literal 0 HcmV?d00001 From 1b2b0d5b58dc073ad150b3d3be1081784a055d2f Mon Sep 17 00:00:00 2001 From: R00Ki3 Date: Tue, 10 Mar 2015 11:12:56 -0500 Subject: [PATCH 05/38] Update ff_weapon_sniperrifle.txt --- scripts/ff_weapon_sniperrifle.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ff_weapon_sniperrifle.txt b/scripts/ff_weapon_sniperrifle.txt index 979ce31..d9d7f06 100644 --- a/scripts/ff_weapon_sniperrifle.txt +++ b/scripts/ff_weapon_sniperrifle.txt @@ -27,7 +27,7 @@ WeaponData "default_clip" "60" "default_clip2" "-1" - "primary_ammo" "AMMO_SHELLS" + "primary_ammo" "AMMO_NAILS" "secondary_ammo" "None" "ffencrypted" "1" // required for the script to load From b0e05551db7162f0edc11a89646ece6279b7af91 Mon Sep 17 00:00:00 2001 From: R00Ki3 Date: Tue, 10 Mar 2015 11:21:20 -0500 Subject: [PATCH 06/38] Update ff_playerclass_sniper.txt --- scripts/ff_playerclass_sniper.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ff_playerclass_sniper.txt b/scripts/ff_playerclass_sniper.txt index 4fdcc55..d4990b6 100644 --- a/scripts/ff_playerclass_sniper.txt +++ b/scripts/ff_playerclass_sniper.txt @@ -43,7 +43,7 @@ PlayerClassData AmmoData { "AMMO_SHELLS" "60" - "AMMO_NAILS" "50" + "AMMO_NAILS" "60" "AMMO_CELLS" "0" "AMMO_ROCKETS" "0" "AMMO_DETPACK" "0" @@ -53,7 +53,7 @@ PlayerClassData MaxAmmoData { "AMMO_SHELLS" "75" - "AMMO_NAILS" "100" + "AMMO_NAILS" "75" "AMMO_CELLS" "30" "AMMO_ROCKETS" "25" "AMMO_DETPACK" "0" From ee2e31becef59743d84fea03ffd91019a0a249b6 Mon Sep 17 00:00:00 2001 From: alaswell Date: Mon, 16 Mar 2015 12:31:24 -0600 Subject: [PATCH 07/38] adds a timer on the HUD that reflects how long security is down for --- maps/includes/base_shutdown.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/maps/includes/base_shutdown.lua b/maps/includes/base_shutdown.lua index ff17040..0963c3a 100644 --- a/maps/includes/base_shutdown.lua +++ b/maps/includes/base_shutdown.lua @@ -53,6 +53,13 @@ function security_off( team ) clip:SetClipFlags({ClipFlags.kClipTeamBlue}) end end + + -- add a timer for the security on HUD + if team == "red" then + AddHudTimerToAll( "red_sec_timer", SECURITY_LENGTH + 1, -1, button_red.iconx, button_red.icony + 15, button_red.iconalign ) + else + AddHudTimerToAll( "blue_sec_timer", SECURITY_LENGTH + 1, -1, button_blue.iconx, button_blue.icony + 15, button_blue.iconalign ) + end end -- called when security gets turned on (team is a string prefix, like "red") @@ -75,6 +82,9 @@ function security_on( team ) clip:SetClipFlags(_G[clipname].clipflags) end end + + -- remove security timer + RemoveHudItemFromAll( team.."_sec_timer" ) end ----------------------------------------------------------------------------- From 31e2952cfc7dfcf3dd6711e0c94e4eb4fb3b8a7b Mon Sep 17 00:00:00 2001 From: squeek Date: Thu, 19 Mar 2015 21:50:23 -0700 Subject: [PATCH 08/38] Update gameinfo.txt SearchPaths to work with the new Hammer setup * See also fortressforever/fortressforever-maps#1 --- gameinfo.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gameinfo.txt b/gameinfo.txt index 000dddb..24df78b 100644 --- a/gameinfo.txt +++ b/gameinfo.txt @@ -42,8 +42,8 @@ SearchPaths { Game |gameinfo_path|. - Game hl2 - Game FortressForever + Game |gameinfo_path|..\hl2 + Game |gameinfo_path|..\platform } } } From 918c4afcf3181efb096752589d2ae4ca80b99981 Mon Sep 17 00:00:00 2001 From: squeek Date: Sat, 21 Mar 2015 19:27:16 -0700 Subject: [PATCH 09/38] Re-add ff_cornfield * See fortressforever/fortressforever#6 --- maps/ff_cornfield.lua | 83 +++++++++++++++++++++++++++++++++++++++++++ maps/ff_cornfield.txt | 21 +++++++++++ 2 files changed, 104 insertions(+) create mode 100644 maps/ff_cornfield.lua create mode 100644 maps/ff_cornfield.txt diff --git a/maps/ff_cornfield.lua b/maps/ff_cornfield.lua new file mode 100644 index 0000000..a159340 --- /dev/null +++ b/maps/ff_cornfield.lua @@ -0,0 +1,83 @@ +IncludeScript("base_id_new"); +IncludeScript("base_respawnturret"); +IncludeScript("base_location"); + +respawnturret_attackers = base_respawnturret:new({ team = attackers }) +respawnturret_defenders = base_respawnturret:new({ team = defenders }) + +cornhealthkit = genericbackpack:new({ + health = 50, + model = "models/items/healthkit.mdl", + materializesound = "Item.Materialize", + touchsound = "HealthKit.Touch" +}) +cornarmorkit = genericbackpack:new({ + armor = 200, + model = "models/items/armour/armour.mdl", + materializesound = "Item.Materialize", + touchsound = "ArmorKit.Touch" +}) +cornammopack = genericbackpack:new({ + health = 35, + armor = 50, + grenades = 20, + nails = 50, + shells = 100, + rockets = 15, + cells = 70, + model = "models/items/backpack/backpack.mdl", + materializesound = "Item.Materialize", + touchsound = "Backpack.Touch" +}) + +function cornammopack:dropatspawn() return false +end + +corngrenadepack = genericbackpack:new({ + health = 35, + armor = 50, + grenades = 20, + nails = 50, + shells = 100, + rockets = 15, + cells = 70, + mancannons = 1, + gren1 = 2, + gren2 = 1, + respawntime = 30, + model = "models/items/backpack/backpack.mdl", + materializesound = "Item.Materialize", + touchsound = "Backpack.Touch" +}) + +function corngrenadepack:dropatspawn() return false +end + +detpack_wall_open = nil + +function onroundreset() + -- close the door + if detpack_wall_open then + -- there's no "close".. wtf + OutputEvent("detpack_hole", "Toggle") + detpack_wall_open = nil + end + -- Reset The Turrets + respawnturret_attackers = base_respawnturret:new({ team = attackers }) + respawnturret_defenders = base_respawnturret:new({ team = defenders }) +end + +detpack_trigger = trigger_ff_script:new({}) +function detpack_trigger:onexplode( trigger_entity ) + if IsDetpack( trigger_entity ) then + ConsoleToAll("The door has been blown open!") + OutputEvent("detpack_hole", "Toggle") + detpack_wall_open = true + end + return EVENT_ALLOWED +end + +-- Don't want any body touching/triggering it except the detpack +function trigger_detpackable_door:allowed( trigger_entity ) return EVENT_DISALLOWED +end + diff --git a/maps/ff_cornfield.txt b/maps/ff_cornfield.txt new file mode 100644 index 0000000..a91a943 --- /dev/null +++ b/maps/ff_cornfield.txt @@ -0,0 +1,21 @@ +INVADE AND DEFEND + +Objective: + +Blue team starts as the attacker. Red team +starts as the defender. + +The attacking team must take control of the +town by pushing through and capping the four +Command Points sequentially. The defending +team simply tries to hold out as long as they +can. Once the attackers succeed, teams swap, +and play begins again. + +Command Points are captured by taking the flag +from the previous point and carrying it to the +next. When a Command Point is secured, the flag +required to capture the next Command Point +appears on top of it. For example, the flag +needed to capture Command Point 3 will always +spawn at Command Point 2. \ No newline at end of file From 231656c31d0bd0f17412bc6466dc0869f2e8e8bf Mon Sep 17 00:00:00 2001 From: squeek Date: Sat, 21 Mar 2015 19:26:13 -0700 Subject: [PATCH 10/38] Remove ff_push * See fortressforever/fortressforever#6 --- maps/ff_push.lua | 48 -------- maps/ff_push.txt | 4 - maps/ff_push_soundscapes.txt | 211 ----------------------------------- 3 files changed, 263 deletions(-) delete mode 100644 maps/ff_push.lua delete mode 100644 maps/ff_push.txt delete mode 100644 maps/ff_push_soundscapes.txt diff --git a/maps/ff_push.lua b/maps/ff_push.lua deleted file mode 100644 index eecaa51..0000000 --- a/maps/ff_push.lua +++ /dev/null @@ -1,48 +0,0 @@ --- ff_push.lua - ------------------------------------------------------------------------------ --- includes ------------------------------------------------------------------------------ -IncludeScript("base_push"); - ------------------------------------------------------------------------------ --- global overrides ------------------------------------------------------------------------------ - -local orig_startup = startup - -function startup() - -- set up team names. Localisation? - SetTeamName( Team.kBlue, "Ball Locks" ) - SetTeamName( Team.kRed, "Rocket Expediting" ) - - orig_startup() -end - ------------------------------------------------------------------------------ --- triggers for doors ------------------------------------------------------------------------------ -red_respawn_triggerA = respawndoor:new({ team = Team.kRed }) -red_respawn_triggerB = respawndoor:new({ team = Team.kRed }) - -blue_respawn_triggerA = respawndoor:new({ team = Team.kBlue }) -blue_respawn_triggerB = respawndoor:new({ team = Team.kBlue }) - - ------------------------------------------------------------------------------ --- unique push locations ------------------------------------------------------------------------------ -location_blue_corridor = location_info:new({ text = "Corridor", team = Team.kBlue }) -location_red_corridor = location_info:new({ text = "Corridor", team = Team.kRed }) - -location_blue_lasers = location_info:new({ text = "Lasers", team = Team.kBlue }) -location_red_lasers = location_info:new({ text = "Lasers", team = Team.kRed }) - -location_blue_side_warehouse = location_info:new({ text = "Side Warehouse", team = Team.kBlue }) -location_red_side_warehouse = location_info:new({ text = "Side Warehouse", team = Team.kRed }) - -location_blue_loading_bay = location_info:new({ text = "Loading Bay", team = Team.kBlue }) -location_red_loading_bay = location_info:new({ text = "Loading Bay", team = Team.kRed }) - -location_middle_warehouse = location_info:new({ text = "Middle Warehouse", team = Team.kUnassigned }) - diff --git a/maps/ff_push.txt b/maps/ff_push.txt deleted file mode 100644 index 54f6501..0000000 --- a/maps/ff_push.txt +++ /dev/null @@ -1,4 +0,0 @@ -PUSH SCORING - -Objective: Grab the ball from the centre warehouse and then run it to the enemy company's loading zone! Capture it on the raised platform. -The team with the most captures at the end of the game wins! \ No newline at end of file diff --git a/maps/ff_push_soundscapes.txt b/maps/ff_push_soundscapes.txt deleted file mode 100644 index cfa654d..0000000 --- a/maps/ff_push_soundscapes.txt +++ /dev/null @@ -1,211 +0,0 @@ -// Push soundscape file -// Author: Defrag -// Some sections based on existing valve soundscapes but modified - -// generic outside sound -"ff.outside" -{ - // constant wind base - "playlooping" - { - "volume" "0.2" - "pitch" "100" - "wave" "ambient/wind/ff_wasteland_wind.wav" - } - - // Wind gusts (based on cliffe's cs_assault settings) - "playrandom" - { - "time" "20,30" - "volume" "0.3,0.4" - "pitch" "90,110" - - "rndwave" - { - "wave" "ambient/wind/wind_snippet1.wav" - "wave" "ambient/wind/wind_snippet2.wav" - "wave" "ambient/wind/wind_snippet3.wav" - "wave" "ambient/wind/wind_snippet4.wav" - "wave" "ambient/wind/wind_snippet5.wav" - } - } -} - // Rats. Ach, gash! -"push.rats" -{ - "playrandom" - { - "time" "20,30" - "volume" "0.3,0.5" - "pitch" "90,100" - "position" "random" - "soundlevel" "SNDLVL_140db" - - "rndwave" - { - "wave" "ambient/creatures/rats1.wav" - "wave" "ambient/creatures/rats2.wav" - "wave" "ambient/creatures/rats3.wav" - "wave" "ambient/creatures/rats4.wav" - } - } -} - - // workshop noises -"push.workshop" -{ - "playrandom" - { - "time" "30,60" - "volume" "0.1,0.2" - "pitch" "90,110" - "position" "random" - "soundlevel" "SNDLVL_140db" - "rndwave" - { - "wave" "ambient/push/airhose.wav" - "wave" "ambient/push/airwrench1.wav" - "wave" "ambient/push/airwrench2.wav" - } - } -} -// outside area between the central warehouse and the base corridor -"push.outside" -{ - "dsp" "1" - "dsp_volume" "0.5" - - "playsoundscape" - { - "name" "ff.outside" - "volume" "1.0" - } -} - -// capture point area -"push.capturepoint" -{ - "dsp" "1" - "dsp_volume" "0.5" - - "playsoundscape" - { - "name" "ff.outside" - "volume" "1.0" - } - - // train going past - "playrandom" - { - "time" "120,180" - "volume" "0.3" - "pitch" "100" - - "rndwave" - { - "wave" "ambient/machines/train_rumble.wav" - } - } -} - - -// side warehouse with no roof -"push.sidewarehouse" -{ - "dsp" "1" - "dsp_volume" "0.5" - - "playsoundscape" - { - "name" "ff.outside" - "volume" "1.0" - } - - "playsoundscape" - { - "name" "push.rats" - "volume" "1.0" - } - - "playsoundscape" - { - "name" "push.workshop" - "volume" "1.0" - } -} - -// respawn -"push.respawn" -{ - "dsp" "1" - "dsp_volume" "0.5" - - // General ambient noise - "playlooping" - { - "volume" "0.3" - "pitch" "100" - "wave" "ambient/push/inside_amb1.wav" - } - - "playrandom" - { - "time" "30,60" - "volume" "0.3,0.5" - "pitch" "90,100" - "position" "random" - "soundlevel" "SNDLVL_140db" - "rndwave" - { - "wave" "ambient/materials/metal4.wav" - "wave" "ambient/materials/rustypipes1.wav" - "wave" "ambient/materials/rustypipes2.wav" - } - } -} - -// main warehouse in centre -"push.centralwarehouse" -{ - "dsp" "1" - "dsp_volume" "0.5" - - // General ambient noise - "playlooping" - { - "volume" "0.5" - "pitch" "100" - "wave" "ambient/push/inside_amb1.wav" - } - - "playsoundscape" - { - "name" "push.workshop" - "volume" "1.0" - } - - "playsoundscape" - { - "name" "ff.outside" - "volume" "0.6" - } -} - -// doughnut shaped hallway that connects the respawn, cap point, side warehouse etc. -"push.doughnut" -{ - "dsp" "1" - "dsp_volume" "0.5" - - "playsoundscape" - { - "name" "push.respawn" - "volume" "1.0" - } - - "playsoundscape" - { - "name" "ff.outside" - "volume" "0.6" - } -} \ No newline at end of file From ddb60b14433c8db705e249196032b1d66d98038c Mon Sep 17 00:00:00 2001 From: squeek Date: Sat, 21 Mar 2015 19:31:06 -0700 Subject: [PATCH 11/38] Make cornfield use base_id instead of base_id_new * See fortressforever/fortressforever#60 --- maps/ff_cornfield.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maps/ff_cornfield.lua b/maps/ff_cornfield.lua index a159340..278a75e 100644 --- a/maps/ff_cornfield.lua +++ b/maps/ff_cornfield.lua @@ -1,4 +1,4 @@ -IncludeScript("base_id_new"); +IncludeScript("base_id"); IncludeScript("base_respawnturret"); IncludeScript("base_location"); From 5e75dbba7e347e6c1d1ac83b6a0cdb51ae984649 Mon Sep 17 00:00:00 2001 From: squeek Date: Sun, 1 Feb 2015 02:20:18 -0800 Subject: [PATCH 12/38] Improve HUD font: add Latin-1 Supplement and other missing chars * Adds things like custom accented chars, #, &, $, ~, etc * Still missing some Latin-1 Supplement characters (copyright, paragraph, and whatnot) * Allows for non-broken Spanish/Portuguese translations (see #10, #8) Note: Due to the added accented chars, the Win Ascent was bumped up so that the accents do not cause the characters to be clipped. This alters the default line height of the font, which makes the text much smaller in-game. To compensate, the font sizes should probably be bumped up in the Scheme.res files. --- resource/HUDfont.ttf | Bin 11144 -> 21236 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/resource/HUDfont.ttf b/resource/HUDfont.ttf index f6693c07ac34b4f6b03021afc6cc51f423e4558f..ee42358c6582ad8e2c6f4f25b18f739ce5930ca2 100644 GIT binary patch delta 7957 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 Wm@MkWrDD2h5Q_!U5)wGMlm8FwjGPJp delta 1982 zcma)7X>3$g6#mZJW}oSlQo7O3&{BqJnQpXfr7Z;!%hC=EP@qtzokEdzXrK@TVK8yQ z1S0kZ;t!Qt5M0;-8lw^=gb-rj4=yo4@Q)EiSwyxJnDM+$_sh?9+dgSX@-UetIOXszAhPynkpJNT#2T13ahu3r^60C`WEj({t z-toe+c=fn;KsyEGgxcG}k*izkDtPWJqoSP!u6d@7Y)|2FUVCTv`on4dWjyX>Y+c#5 zIu^bA+PyJAei|!W?pW0t-aUEOCxH5p$EQ2P>${Y*c!`xc0C=L|&bE?7SAzBLb5M<4 ztJZWM{_NgJz~8_+MMg3l?r&3mi8i|`@4#l}Wx$D5gKz22lfPd*1jOxTleUeA7SIe` z%oi`xn&RpB)6ChU)oe0M8B>p`#gMe10X9P-AqhpO1r+;Z4H9+atLlYxxB=@QJXt$! zhR1^%c+jgYh-cuO)HWf7t_w`;=Fse21uf2@&N(L@2?yg9s;b z#8d_7;23vu0$(VL(W|CnzubpU8A44#gyrYO5jjPil|o{y)E<*s*gzZ+-4ESHL`|iT za)gaDvs(g~eEk&D=R)aXyO!n84CSEZxXbykJJH*a|U2;WG5LE)%CQE^FW z+350$C5xLDu{WWp=^{yWJOwk!g4C=hl9&R$=aY@hqSZWZIj0|+tg?J)m&;0nPXp>Z(H&$4VHD5 zU6!9MajW0@ytU7I+S+f+wl&(iZCh>oY^Q7&>{ffg9D7zqcyjjcRB6g!&U|cv4aQ|k`jNYpT0yPHC5{89nEu;OJ!33 z&iIYL_%v82w%EPm^GuI;&s-?p%=C+knLcsYw_No2hKd4TyJ&U$g~c5Z7n1_q&idxO zz&s2mpz^OHfM9$Rb141*rTo61Ig}WVG6WObQHkKg>&&4?9o!am@gC;-#5qi5`8DRy zqm`(GGk%3R$>5;|=NRlYxWM3m&P^yX1|HS|XKs=QwQ!0O$&g7Ql{7MuS@Z@|lPQG;Qz{MN=1Zpx z%A_o@S1lK9>gY8tSovq-#$?_F)m)S+)EEauGamBgC#Amu DQ~a~T From 25e0e0e42a1734c22ae4f58300e66f18c163a66f Mon Sep 17 00:00:00 2001 From: squeek Date: Sat, 21 Mar 2015 21:09:29 -0700 Subject: [PATCH 13/38] Fix sizes of various fonts due to the fixed height of the HUD font --- resource/ClientScheme.res | 30 +++++++++++++++--------------- resource/SourceScheme.res | 12 ++++++------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/resource/ClientScheme.res b/resource/ClientScheme.res index 5d41fa8..0c27b1a 100644 --- a/resource/ClientScheme.res +++ b/resource/ClientScheme.res @@ -897,7 +897,7 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "tall" "14" + "tall" "15" "weight" "0" "antialias" "1" "additive" "0" @@ -1104,7 +1104,7 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "tall" "24" + "tall" "32" "weight" "0" "additive" "0" "antialias" "1" @@ -1114,7 +1114,7 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "tall" "40" + "tall" "48" "weight" "0" "additive" "0" "antialias" "1" @@ -1123,7 +1123,7 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "tall" "48" + "tall" "64" "weight" "0" "additive" "0" "antialias" "1" @@ -1340,7 +1340,7 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "tall" "10" + "tall" "12" "weight" "300" "antialias" "1" "yres" "1 599" @@ -1348,7 +1348,7 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "tall" "12" + "tall" "14" "weight" "500" "antialias" "1" "yres" "600 767" @@ -1356,7 +1356,7 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "tall" "14" + "tall" "16" "weight" "500" "antialias" "1" "yres" "768 1023" @@ -1364,7 +1364,7 @@ Scheme "4" { "name" "FortressForever - HUD Font" - "tall" "20" + "tall" "24" "weight" "1000" "antialias" "1" "yres" "1024 1199" @@ -1372,7 +1372,7 @@ Scheme "5" { "name" "FortressForever - HUD Font" - "tall" "24" + "tall" "30" "weight" "1000" "antialias" "1" "yres" "1200 10000" @@ -1440,7 +1440,7 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "tall" "12" + "tall" "13" "antialias" "1" "additive" "0" } @@ -1648,7 +1648,7 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "tall" "10" + "tall" "12" "weight" "0" "dropshadow" "1" "antialias" "1" @@ -1658,7 +1658,7 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "tall" "12" + "tall" "14" "weight" "0" "antialias" "1" "dropshadow" "1" @@ -1667,7 +1667,7 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "tall" "14" + "tall" "16" "weight" "0" "antialias" "1" "dropshadow" "1" @@ -1676,7 +1676,7 @@ Scheme "4" { "name" "FortressForever - HUD Font" - "tall" "20" + "tall" "24" "weight" "0" "antialias" "1" "dropshadow" "1" @@ -1685,7 +1685,7 @@ Scheme "5" { "name" "FortressForever - HUD Font" - "tall" "24" + "tall" "30" "weight" "0" "antialias" "1" "dropshadow" "1" diff --git a/resource/SourceScheme.res b/resource/SourceScheme.res index f4def3c..cdf16d0 100644 --- a/resource/SourceScheme.res +++ b/resource/SourceScheme.res @@ -252,7 +252,7 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "tall" "14" + "tall" "16" "antialias" "1" } } @@ -324,7 +324,7 @@ Scheme { "name" "FortressForever - HUD Font" - "tall" "16" + "tall" "18" "weight" "500" "antialias" "1" } @@ -335,7 +335,7 @@ Scheme "1" { "name" "FortressForever - HUD Font" - "tall" "16" + "tall" "18" "weight" "500" "antialias" "1" @@ -344,7 +344,7 @@ Scheme "2" { "name" "FortressForever - HUD Font" - "tall" "18" + "tall" "20" "weight" "500" "antialias" "1" "yres" "600 767" @@ -352,7 +352,7 @@ Scheme "3" { "name" "FortressForever - HUD Font" - "tall" "22" + "tall" "24" "weight" "500" "antialias" "1" "yres" "768 1023" @@ -360,7 +360,7 @@ Scheme "4" { "name" "FortressForever - HUD Font" - "tall" "24" + "tall" "26" "weight" "600" "antialias" "1" "yres" "1024 1199" From 18e497f053123d0eab15cab93b6d5e9e03b22e52 Mon Sep 17 00:00:00 2001 From: squeek Date: Sat, 21 Mar 2015 21:39:39 -0700 Subject: [PATCH 14/38] Use SECURITY_LENGTH instead of SECURITY_LENGTH+1 --- maps/includes/base_shutdown.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maps/includes/base_shutdown.lua b/maps/includes/base_shutdown.lua index 0963c3a..c92e76e 100644 --- a/maps/includes/base_shutdown.lua +++ b/maps/includes/base_shutdown.lua @@ -56,9 +56,9 @@ function security_off( team ) -- add a timer for the security on HUD if team == "red" then - AddHudTimerToAll( "red_sec_timer", SECURITY_LENGTH + 1, -1, button_red.iconx, button_red.icony + 15, button_red.iconalign ) + AddHudTimerToAll( "red_sec_timer", SECURITY_LENGTH, -1, button_red.iconx, button_red.icony + 15, button_red.iconalign ) else - AddHudTimerToAll( "blue_sec_timer", SECURITY_LENGTH + 1, -1, button_blue.iconx, button_blue.icony + 15, button_blue.iconalign ) + AddHudTimerToAll( "blue_sec_timer", SECURITY_LENGTH, -1, button_blue.iconx, button_blue.icony + 15, button_blue.iconalign ) end end From bae25ad3b1159e26a1cb3a8aff86e18b6bc5ca28 Mon Sep 17 00:00:00 2001 From: squeek Date: Mon, 23 Mar 2015 04:10:08 -0700 Subject: [PATCH 15/38] Add standard Lua Class implementation --- maps/includes/base.lua | 2 +- maps/includes/util/class.lua | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 maps/includes/util/class.lua diff --git a/maps/includes/base.lua b/maps/includes/base.lua index d77275d..54dd4ab 100644 --- a/maps/includes/base.lua +++ b/maps/includes/base.lua @@ -6,8 +6,8 @@ -- This file is loaded automatically whenever a map is loaded. -- Do not change this file. ----------------------------------------------------------------------------- -local _G = getfenv(0) +Class = require "util.class" ----------------------------------------------------------------------------- -- defines diff --git a/maps/includes/util/class.lua b/maps/includes/util/class.lua new file mode 100644 index 0000000..9dd7c60 --- /dev/null +++ b/maps/includes/util/class.lua @@ -0,0 +1,46 @@ +-- from http://lua-users.org/wiki/SimpleLuaClasses + +function Class(base, _ctor) + local c = {} -- a new class instance + if not _ctor and type(base) == 'function' then + _ctor = base + base = nil + elseif type(base) == 'table' then + -- our new class is a shallow copy of the base class! + for i,v in pairs(base) do + c[i] = v + end + c._base = base + end + + -- the class will be the metatable for all its objects, + -- and they will look up their methods in it. + c.__index = c + + -- expose a constructor which can be called by () + local mt = {} + + mt.__call = function(class_tbl, ...) + local obj = {} + setmetatable(obj,c) + + if c._ctor then + c._ctor(obj,...) + end + return obj + end + + c._ctor = _ctor + c.is_a = function(self, klass) + local m = getmetatable(self) + while m do + if m == klass then return true end + m = m._base + end + return false + end + setmetatable(c, mt) + return c +end + +return Class \ No newline at end of file From e2f65b31bf60ece43ac903d3a6c4bd8879abd7b7 Mon Sep 17 00:00:00 2001 From: alaswell Date: Mon, 23 Mar 2015 23:49:11 -0600 Subject: [PATCH 16/38] Change team names to something more appropriate contributes to fortressforever/fortressforever#135 --- maps/ff_dm.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/maps/ff_dm.lua b/maps/ff_dm.lua index 5779cd7..f888307 100644 --- a/maps/ff_dm.lua +++ b/maps/ff_dm.lua @@ -14,7 +14,8 @@ function startup() SetPlayerLimit( Team.kYellow, -1 ) SetPlayerLimit( Team.kGreen, -1 ) - SetTeamName( Team.kRed, "Destroyers" ) + SetTeamName( Team.kBlue, "Blue Orcas" ) + SetTeamName( Team.kRed, "Red Gazelles" ) end function precache() From e5e5e1735b60e43aa4c0a5e861ea3f472a23304c Mon Sep 17 00:00:00 2001 From: squeek Date: Tue, 24 Mar 2015 12:34:20 -0700 Subject: [PATCH 17/38] Don't crash if class_info() is called on non-luabind objects * See https://github.com/luabind/luabind/commit/2c6c9054e3f9ae00498fc2b56331a17b590ab74e --- maps/includes/base.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/maps/includes/base.lua b/maps/includes/base.lua index d77275d..317e74a 100644 --- a/maps/includes/base.lua +++ b/maps/includes/base.lua @@ -48,6 +48,20 @@ function baseclass:new (o) end +----------------------------------------------------------------------------- +-- make luabind's class_info function safer +-- (don't crash if class_info() is called on non-luabind objects) +----------------------------------------------------------------------------- +local class_info_base = class_info +class_info = function(obj) + local obj_type = type(obj) + if obj_type == "userdata" and getmetatable(obj).__luabind_class then + return class_info_base(obj) + end + return {} +end + + ----------------------------------------------------------------------------- -- reset everything ----------------------------------------------------------------------------- From 1e2bd319291b7ce0954cd7793f2da836230a4e18 Mon Sep 17 00:00:00 2001 From: squeek Date: Tue, 24 Mar 2015 14:50:01 -0700 Subject: [PATCH 18/38] Fix weapon dropdown having the wrong name * Contributes towards fortressforever/fortressforever#142 --- resource/ui/FFOptionsSubCrosshairs.res | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resource/ui/FFOptionsSubCrosshairs.res b/resource/ui/FFOptionsSubCrosshairs.res index 25e043d..06acb97 100644 --- a/resource/ui/FFOptionsSubCrosshairs.res +++ b/resource/ui/FFOptionsSubCrosshairs.res @@ -500,10 +500,10 @@ "border" "DepressedBorder" "scaleImage" "1" } - "weapon" + "Crosshair" { "ControlName" "ComboBox" - "fieldName" "Weapon" + "fieldName" "Crosshair" "xpos" "292" "ypos" "23" "wide" "150" From 07fb48f0556237417c69107274aaca5ce6b5c15e Mon Sep 17 00:00:00 2001 From: squeek Date: Tue, 24 Mar 2015 14:56:33 -0700 Subject: [PATCH 19/38] Fix "use global crosshair for all" checkbox label getting cut off --- resource/ui/FFOptionsSubCrosshairs.res | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resource/ui/FFOptionsSubCrosshairs.res b/resource/ui/FFOptionsSubCrosshairs.res index 06acb97..98f035f 100644 --- a/resource/ui/FFOptionsSubCrosshairs.res +++ b/resource/ui/FFOptionsSubCrosshairs.res @@ -429,7 +429,7 @@ "xpos" "275" "ypos" "49" "wide" "185" - "tall" "24" + "tall" "32" "autoResize" "0" "pinCorner" "0" "visible" "1" @@ -439,7 +439,7 @@ "textAlignment" "west" "dulltext" "0" "brighttext" "0" - "wrap" "0" + "wrap" "1" "Default" "0" } "innerDisplay" From de3e235cfb8613da6705a683fcb6d178b75c3f5b Mon Sep 17 00:00:00 2001 From: Mike Parker Date: Fri, 27 Mar 2015 02:07:49 +0000 Subject: [PATCH 20/38] Add trail to flags --- maps/includes/base_teamplay.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/maps/includes/base_teamplay.lua b/maps/includes/base_teamplay.lua index e48f99d..bf36bd2 100644 --- a/maps/includes/base_teamplay.lua +++ b/maps/includes/base_teamplay.lua @@ -537,6 +537,7 @@ function baseflag:spawn() LogLuaEvent(0, 0, "flag_spawn","flag_name",flag:GetName()) self.status = 0 self:refreshStatusIcons(flag:GetName()) + flag:StartTrail(self.team) end function baseflag:addnotouch(player_id, duration) From 171376e24c5d3a04435748d9077fcf00b4172c48 Mon Sep 17 00:00:00 2001 From: squeek Date: Mon, 23 Mar 2015 04:13:56 -0700 Subject: [PATCH 21/38] Start of Lua-based collection implementation * Will eventually replace the entire Collection userdata with full backwards compatibility * See fortressforever/fortressforever#91 --- maps/includes/base.lua | 1 + maps/includes/util/collection.lua | 119 ++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 maps/includes/util/collection.lua diff --git a/maps/includes/base.lua b/maps/includes/base.lua index c73e3f9..59a3e36 100644 --- a/maps/includes/base.lua +++ b/maps/includes/base.lua @@ -8,6 +8,7 @@ ----------------------------------------------------------------------------- Class = require "util.class" +Collection = require "util.collection" ----------------------------------------------------------------------------- -- defines diff --git a/maps/includes/util/collection.lua b/maps/includes/util/collection.lua new file mode 100644 index 0000000..5a3cb31 --- /dev/null +++ b/maps/includes/util/collection.lua @@ -0,0 +1,119 @@ +-- backwards compatibility for the Collection class + +local Class = require "util.class" + +local function setup_items_key(self) + -- keep a usable reference to the base metatable + local real_obj = setmetatable({}, getmetatable(self)) + -- add special handling of the items key + setmetatable(self, { + -- the items key returns an iterator + __index = function(t, k) + if k == "items" then + local i = 0 + local n = self:Count() + return function() + i = i + 1 + if i <= n then return self.entities[i] end + end + end + return real_obj[k] + end, + -- protect the items key from being assigned + __newindex = function(t, k, v) + if k == "items" then + return + end + real_obj[k] = v + end + }) +end + +local Collection = Class(function(self) + setup_items_key(self) + self.entities = {} +end) + + +local function get_param_as_table(param) + if param == nil then return {} end + if type(param) == "table" then return param end + return {param} +end + +-- lua tables start at index 1 +local function to_lua_index(collection_index) + return collection_index+1 +end + +-- Collection started at index 0 +local function to_collection_index(lua_index) + return lua_index-1 +end + +function Collection:AddItem(entity_or_entities) + local entities_to_add = get_param_as_table(entity_or_entities) + + for i,entity_to_add in ipairs(entities_to_add) do + table.insert(self.entities, entity_to_add) + end +end + +function Collection:RemoveItem(entity_or_entities) + local entities_to_find = get_param_as_table(entity_or_entities) + + for i,entity_to_find in ipairs(entities_to_find) do + local i = self:FindItemIndex(entity_to_find) + if i then + table.remove(self.entities, to_lua_index(i)) + end + end +end + +function Collection:RemoveAllItems() + for k in ipairs(self.entities) do + self.entities[k] = nil + end +end + +function Collection:Count() + return #self.entities +end + +function Collection:HasItem(entity_or_entities) + local entities_to_find = get_param_as_table(entity_or_entities) + + for i,entity_to_find in ipairs(entities_to_find) do + if self:FindItemIndex(entity_to_find) then + return true + end + end + return false +end + +-- this is a strange function +function Collection:GetItem(entity_or_entities) + local entities_to_find = get_param_as_table(entity_or_entities) + + for i,entity_to_find in ipairs(entities_to_find) do + local i = self:FindItemIndex(entity_to_find) + if i then + return self:Element(i) + end + end +end + +function Collection:FindItemIndex(entity_to_find) + for i,entity in ipairs(self.entities) do + if entity:GetId() == entity_to_find:GetId() then + return to_collection_index(i) + end + end + return nil +end + +function Collection:Element(i) + return self.entities[to_lua_index(i)] +end + +return Collection \ No newline at end of file From e8c59ff5ec02e0267b827be69f199b0a08a77016 Mon Sep 17 00:00:00 2001 From: squeek Date: Mon, 23 Mar 2015 22:13:03 -0700 Subject: [PATCH 22/38] Allow GlobalEntityList to be iterated by pairs and ipairs * See https://github.com/fortressforever/fortressforever/commit/63095295902222c10d703410a20dded66beca561 Example usage: for ent_id, ent in pairs(GlobalEntityList) do print(ent_id, ent) end Note: The order of iteration is always arbitrary --- maps/includes/base.lua | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/maps/includes/base.lua b/maps/includes/base.lua index 59a3e36..5d96d75 100644 --- a/maps/includes/base.lua +++ b/maps/includes/base.lua @@ -49,6 +49,47 @@ function baseclass:new (o) end +----------------------------------------------------------------------------- +-- set up pairs and ipairs for iterating the global entity list +-- +-- Example usage: +-- +-- for ent_id, ent in pairs(GlobalEntityList) do +-- print(ent_id, ent) +-- end +-- +-- Note: The order of iteration is always arbitrary +----------------------------------------------------------------------------- +local GlobalEntityListIterator = function() + local entity = GlobalEntityList:FirstEntity() + return function() + local cur_ent = entity + entity = GlobalEntityList:NextEntity(cur_ent) + if cur_ent then + return cur_ent:GetId(), cur_ent + else + return nil + end + end +end + +local ipairs_base = ipairs +ipairs = function(t) + if t == GlobalEntityList then + return GlobalEntityListIterator() + end + return ipairs_base(t) +end + +local pairs_base = pairs +pairs = function(t) + if t == GlobalEntityList then + return GlobalEntityListIterator() + end + return pairs_base(t) +end + + ----------------------------------------------------------------------------- -- make luabind's class_info function safer -- (don't crash if class_info() is called on non-luabind objects) From 3a63082b071f261bfefa513062a16fac21979df2 Mon Sep 17 00:00:00 2001 From: squeek Date: Mon, 23 Mar 2015 22:15:20 -0700 Subject: [PATCH 23/38] Add some misc table util functions --- maps/includes/base.lua | 1 + maps/includes/util/utils.lua | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 maps/includes/util/utils.lua diff --git a/maps/includes/base.lua b/maps/includes/base.lua index 5d96d75..b33f1ad 100644 --- a/maps/includes/base.lua +++ b/maps/includes/base.lua @@ -7,6 +7,7 @@ -- Do not change this file. ----------------------------------------------------------------------------- +require "util.utils" Class = require "util.class" Collection = require "util.collection" diff --git a/maps/includes/util/utils.lua b/maps/includes/util/utils.lua new file mode 100644 index 0000000..d279d6c --- /dev/null +++ b/maps/includes/util/utils.lua @@ -0,0 +1,28 @@ + +function table.clear(tbl) + for k in pairs(tbl) do + tbl[k] = nil + end +end + +function table.contains(tbl, element) + if tbl == nil then return false end + for _, value in pairs(tbl) do + if value == element then + return true + end + end + return false +end + +function table.contains_any(tbl, elements) + if tbl == nil or elements == nil then return false end + for _, value in pairs(tbl) do + for _, element in pairs(elements) do + if value == element then + return true + end + end + end + return false +end \ No newline at end of file From fef39bebc749691ea161e3111d45ab6c59f61a71 Mon Sep 17 00:00:00 2001 From: squeek Date: Mon, 23 Mar 2015 22:16:41 -0700 Subject: [PATCH 24/38] Finish Collection implementation * Depends on https://github.com/fortressforever/fortressforever/pull/134 --- maps/includes/util/collection.lua | 127 +++++++++++++++++++++++++++--- 1 file changed, 118 insertions(+), 9 deletions(-) diff --git a/maps/includes/util/collection.lua b/maps/includes/util/collection.lua index 5a3cb31..ea39e02 100644 --- a/maps/includes/util/collection.lua +++ b/maps/includes/util/collection.lua @@ -1,6 +1,7 @@ -- backwards compatibility for the Collection class local Class = require "util.class" +require "util.utils" local function setup_items_key(self) -- keep a usable reference to the base metatable @@ -29,12 +30,6 @@ local function setup_items_key(self) }) end -local Collection = Class(function(self) - setup_items_key(self) - self.entities = {} -end) - - local function get_param_as_table(param) if param == nil then return {} end if type(param) == "table" then return param end @@ -51,6 +46,67 @@ local function to_collection_index(lua_index) return lua_index-1 end +local Collection = Class(function(self, entity_or_entities) + setup_items_key(self) + self.entities = get_param_as_table(entity_or_entities) +end) + +Collection.filters = { + [CF.kNone] = function(entity) return true end, + [CF.kPlayers] = function(entity) return IsPlayer(entity) end, + [CF.kHumanPlayers] = function(entity) return IsPlayer(entity) and not CastToPlayer(entity):IsBot() end, + [CF.kBotPlayers] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):IsBot() end, + [CF.kPlayerScout] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kScout end, + [CF.kPlayerSniper] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kSniper end, + [CF.kPlayerSoldier] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kSoldier end, + [CF.kPlayerDemoman] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kDemoman end, + [CF.kPlayerMedic] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kMedic end, + [CF.kPlayerHWGuy] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kHwguy end, + [CF.kPlayerPyro] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kPyro end, + [CF.kPlayerSpy] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kSpy end, + [CF.kPlayerEngineer] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kEngineer end, + [CF.kPlayerCivilian] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kCivilian end, + [CF.kPlayerScout] = function(entity) return IsPlayer(entity) and CastToPlayer(entity):GetClass() == Player.kScout end, + [CF.kTeams] = function(entity) return IsEntity(entity) and entity:GetTeamId() >= Team.kSpectator and entity:GetTeamId() <= Team.kGreen end, + [CF.kTeamSpec] = function(entity) return IsEntity(entity) and entity:GetTeamId() == Team.kSpectator end, + [CF.kTeamBlue] = function(entity) return IsEntity(entity) and entity:GetTeamId() == Team.kBlue end, + [CF.kTeamRed] = function(entity) return IsEntity(entity) and entity:GetTeamId() == Team.kRed end, + [CF.kTeamYellow] = function(entity) return IsEntity(entity) and entity:GetTeamId() == Team.kYellow end, + [CF.kTeamGreen] = function(entity) return IsEntity(entity) and entity:GetTeamId() == Team.kGreen end, + [CF.kProjectiles] = function(entity) return IsProjectile(entity) end, + [CF.kGrenades] = function(entity) return IsGrenade(entity) end, + [CF.kInfoScipts] = function(entity) return IsInfoScript(entity) end, + [CF.kInfoScript_Carried] = function(entity) return IsInfoScript(entity) and CastToInfoScript(entity):IsCarried() end, + [CF.kInfoScript_Dropped] = function(entity) return IsInfoScript(entity) and CastToInfoScript(entity):IsDropped() end, + [CF.kInfoScript_Returned] = function(entity) return IsInfoScript(entity) and CastToInfoScript(entity):IsReturned() end, + [CF.kInfoScript_Active] = function(entity) return IsInfoScript(entity) and CastToInfoScript(entity):IsActive() end, + [CF.kInfoScript_Inactive] = function(entity) return IsInfoScript(entity) and CastToInfoScript(entity):IsInactive() end, + [CF.kInfoScript_Removed] = function(entity) return IsInfoScript(entity) and CastToInfoScript(entity):IsRemoved() end, + [CF.kTraceBlockWalls] = function(entity) return true end, -- not applicable for this type of filtering + [CF.kBuildables] = function(entity) return IsBuildable(entity) end, + [CF.kDispenser] = function(entity) return IsDispenser(entity) end, + [CF.kSentrygun] = function(entity) return IsSentrygun(entity) end, + [CF.kDetpack] = function(entity) return IsDetpack(entity) end, + [CF.kJumpPad] = function(entity) return IsJumpPad(entity) end, +} + +function Collection.PassesFilter(entity, filter) + if not filter then filter = CF.kNone end + assert(Collection.filters[filter], "Unknown filter: "..tostring(filter)) + return Collection.filters[filter](entity) +end + +function Collection.PassesFilters(entity, filters) + if not filters then return true end + filters = get_param_as_table(filters) + for _,filter in ipairs(filters) do + if not Collection.PassesFilter(entity, filter) then + return false + end + end + return true +end + function Collection:AddItem(entity_or_entities) local entities_to_add = get_param_as_table(entity_or_entities) @@ -59,6 +115,16 @@ function Collection:AddItem(entity_or_entities) end end +function Collection:AddFiltered(entity_or_entities, filters) + local entities_to_add = get_param_as_table(entity_or_entities) + + for i,entity_to_add in ipairs(entities_to_add) do + if Collection.PassesFilters(entity_to_add, filters) then + table.insert(self.entities, entity_to_add) + end + end +end + function Collection:RemoveItem(entity_or_entities) local entities_to_find = get_param_as_table(entity_or_entities) @@ -71,15 +137,21 @@ function Collection:RemoveItem(entity_or_entities) end function Collection:RemoveAllItems() - for k in ipairs(self.entities) do - self.entities[k] = nil - end + table.clear(self.entities) end function Collection:Count() return #self.entities end +function Collection:NumItems() + return self:Count() +end + +function Collection:IsEmpty() + return self:Count() == 0 +end + function Collection:HasItem(entity_or_entities) local entities_to_find = get_param_as_table(entity_or_entities) @@ -116,4 +188,41 @@ function Collection:Element(i) return self.entities[to_lua_index(i)] end +function Collection:GetByFilter(filters) + filters = get_param_as_table(filters) + + -- optimization for players + local players_only = false + for _,filter in ipairs(filters) do + if filter >= CF.kPlayers and filter <= CF.kPlayerScout then + players_only = true + break + end + end + + if players_only then + self:AddFiltered(GetPlayers(), filters) + else + for ent_id, entity in ipairs(GlobalEntityList) do + self:AddFiltered(entity, filters) + end + end +end + +function Collection:GetByName(name_or_names, filters) + local names_to_find = get_param_as_table(name_or_names) + filters = get_param_as_table(filters) + + for i,name_to_find in ipairs(names_to_find) do + self:AddFiltered(GetEntitiesByName(name_to_find), filters) + end +end + +function Collection:GetInSphere(entity_or_origin, radius, filters) + filters = get_param_as_table(filters) + local origin = IsEntity(entity_or_origin) and entity_or_origin:GetOrigin() or entity_or_origin + local ignore_walls = not table.contains(filters, CF.kTraceBlockWalls) + self:AddFiltered(GetEntitiesInSphere(origin, radius, ignore_walls), filters) +end + return Collection \ No newline at end of file From 584e4bb9fd64d2584a3623795e67ea3db3ee30cb Mon Sep 17 00:00:00 2001 From: squeek Date: Thu, 26 Mar 2015 22:51:47 -0700 Subject: [PATCH 25/38] Bump version to 2.5.0 --- resource/ff_version_client.txt | 2 +- resource/ff_version_server.txt | 2 +- steam.inf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resource/ff_version_client.txt b/resource/ff_version_client.txt index 4e63c34..2488622 100644 --- a/resource/ff_version_client.txt +++ b/resource/ff_version_client.txt @@ -1,4 +1,4 @@ -2.46.1 +2.5.0 CLIENT version: - only the first line of this file matters diff --git a/resource/ff_version_server.txt b/resource/ff_version_server.txt index 47725c4..19e83f1 100644 --- a/resource/ff_version_server.txt +++ b/resource/ff_version_server.txt @@ -1,4 +1,4 @@ -2.46 +2.5.0 SERVER version: - only the first line of this file matters diff --git a/steam.inf b/steam.inf index 777d5d2..29ca18f 100644 --- a/steam.inf +++ b/steam.inf @@ -1,3 +1,3 @@ -PatchVersion=1.0.0.1 +PatchVersion=1.2.5.0 ProductName=FortressForever appID=253530 From c8de6cc716e15718aeb14b75a54cd077172d714c Mon Sep 17 00:00:00 2001 From: squeek Date: Thu, 26 Mar 2015 22:51:47 -0700 Subject: [PATCH 26/38] Bump version to 2.5.0 --- resource/ff_version_client.txt | 2 +- resource/ff_version_server.txt | 2 +- steam.inf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resource/ff_version_client.txt b/resource/ff_version_client.txt index 4e63c34..2488622 100644 --- a/resource/ff_version_client.txt +++ b/resource/ff_version_client.txt @@ -1,4 +1,4 @@ -2.46.1 +2.5.0 CLIENT version: - only the first line of this file matters diff --git a/resource/ff_version_server.txt b/resource/ff_version_server.txt index 47725c4..19e83f1 100644 --- a/resource/ff_version_server.txt +++ b/resource/ff_version_server.txt @@ -1,4 +1,4 @@ -2.46 +2.5.0 SERVER version: - only the first line of this file matters diff --git a/steam.inf b/steam.inf index 777d5d2..29ca18f 100644 --- a/steam.inf +++ b/steam.inf @@ -1,3 +1,3 @@ -PatchVersion=1.0.0.1 +PatchVersion=1.2.5.0 ProductName=FortressForever appID=253530 From 22f60ac1ece3fe8148d38537d489d8995ac36623 Mon Sep 17 00:00:00 2001 From: squeek Date: Fri, 27 Mar 2015 00:00:14 -0700 Subject: [PATCH 27/38] Revert accidental single shotgun removal from soldier --- scripts/ff_playerclass_soldier.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ff_playerclass_soldier.txt b/scripts/ff_playerclass_soldier.txt index 8530675..dc3c88c 100644 --- a/scripts/ff_playerclass_soldier.txt +++ b/scripts/ff_playerclass_soldier.txt @@ -27,6 +27,7 @@ PlayerClassData ArmamentsData { "weapon" "ff_weapon_crowbar" + "weapon" "ff_weapon_shotgun" "weapon" "ff_weapon_supershotgun" "weapon" "ff_weapon_rpg" } From 3dbf931bbeef8abab39dfa09064728ea6944d8ca Mon Sep 17 00:00:00 2001 From: squeek Date: Fri, 27 Mar 2015 11:14:21 -0700 Subject: [PATCH 28/38] Fix various HUD timers getting added with time + 1 --- maps/includes/base_adzone.lua | 4 ++-- maps/includes/base_id.lua | 8 ++++---- maps/includes/base_id_new.lua | 8 ++++---- maps/includes/base_teamplay.lua | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/maps/includes/base_adzone.lua b/maps/includes/base_adzone.lua index b7e5764..9e79e30 100644 --- a/maps/includes/base_adzone.lua +++ b/maps/includes/base_adzone.lua @@ -568,7 +568,7 @@ function update_zone_text( player ) if not zone_status then AddHudText( player, "defender_points_text", "#FF_Defenders", text_x, text_line1y, text_align ) AddHudText( player, "defender_points_text2", "#ADZ_ScoreNotice", text_x, text_line2y, text_align ) - AddHudTimer( player, "defender_points_timer", current_timer +1, -1, text_x, text_line3y, text_align ) + AddHudTimer( player, "defender_points_timer", current_timer, -1, text_x, text_line3y, text_align ) else AddHudText( player, "attackers_in_text", "#FF_Attackers", text_x, text_line1y, text_align ) AddHudText( player, "attackers_in_text2", "#ADZ_AreIn", text_x, text_line2y, text_align ) @@ -596,7 +596,7 @@ function update_zone_text( player ) if not zone_status then AddHudTextToAll( "defender_points_text", "#FF_Defenders", text_x, text_line1y, text_align ) AddHudTextToAll( "defender_points_text2", "#ADZ_ScoreNotice", text_x, text_line2y, text_align ) - AddHudTimerToAll( "defender_points_timer", current_timer +1, -1, text_x, text_line3y, text_align ) + AddHudTimerToAll( "defender_points_timer", current_timer, -1, text_x, text_line3y, text_align ) else AddHudTextToAll( "attackers_in_text", "#FF_Attackers", text_x, text_line1y, text_align ) AddHudTextToAll( "attackers_in_text2", "#ADZ_AreIn", text_x, text_line2y, text_align ) diff --git a/maps/includes/base_id.lua b/maps/includes/base_id.lua index 5d8e9a8..2e93001 100644 --- a/maps/includes/base_id.lua +++ b/maps/includes/base_id.lua @@ -785,7 +785,7 @@ function flaginfo( player_entity ) else AddHudTextToAll("flag_return_text", "#AD_FlagReturnBase", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0) end - AddHudTimer(player, "flag_return_timer", current_timer + 1, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign) + AddHudTimer(player, "flag_return_timer", current_timer, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign) AddHudIcon(player, hudstatusicondropped, ( "cp_flag_d" ), flag_hudstatusiconx, flag_hudstatusicony, flag_hudstatusiconw, flag_hudstatusiconh, flag_hudstatusiconalign ) elseif _G[flagname].status == 0 then AddHudText(player, "flag_athome", "#AD_FlagIsAt", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0) @@ -802,7 +802,7 @@ function flaginfo( player_entity ) else AddHudText(player, "flag_tobase_text", "#AD_FlagReturnBase", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0) end - AddHudTimer(player, "flag_tobase_timer", current_timer + 1, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign) + AddHudTimer(player, "flag_tobase_timer", current_timer, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign) AddHudIcon(player, hudstatusicontobase, ( "cp_flag_h" ), flag_hudstatusiconx, flag_hudstatusicony, flag_hudstatusiconw, flag_hudstatusiconh, flag_hudstatusiconalign ) end @@ -891,7 +891,7 @@ function update_hud() else AddHudTextToAll("flag_return_text", "#AD_FlagReturnBase", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0) end - AddHudTimerToAll("flag_return_timer", current_timer + 1, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign) + AddHudTimerToAll("flag_return_timer", current_timer, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign) AddHudIconToAll( hudstatusicondropped, ( "cp_flag_d" ), flag_hudstatusiconx, flag_hudstatusicony, flag_hudstatusiconw, flag_hudstatusiconh, flag_hudstatusiconalign ) elseif _G[flagname].status == 0 then AddHudTextToAll("flag_athome", "#AD_FlagIsAt", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0) @@ -908,7 +908,7 @@ function update_hud() else AddHudTextToAll("flag_tobase_text", "#AD_FlagReturnBase", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0) end - AddHudTimerToAll("flag_tobase_timer", current_timer + 1, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign) + AddHudTimerToAll("flag_tobase_timer", current_timer, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign) AddHudIconToAll(hudstatusicontobase, ( "cp_flag_h" ), flag_hudstatusiconx, flag_hudstatusicony, flag_hudstatusiconw, flag_hudstatusiconh, flag_hudstatusiconalign ) end diff --git a/maps/includes/base_id_new.lua b/maps/includes/base_id_new.lua index 2b9fa47..d9dfdd0 100644 --- a/maps/includes/base_id_new.lua +++ b/maps/includes/base_id_new.lua @@ -1026,7 +1026,7 @@ function flaginfo( player_entity ) else AddHudTextToAll("flag_return_text", "#AD_FlagReturnBase", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0, 2) end - AddHudTimer(player, "flag_return_timer", current_timer + 1, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign, 0, 3) + AddHudTimer(player, "flag_return_timer", current_timer, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign, 0, 3) AddHudIcon(player, hudstatusicondropped, ( "cp_flag_d" ), flag_hudstatusiconx, flag_hudstatusicony, flag_hudstatusiconw, flag_hudstatusiconh, flag_hudstatusiconalign ) elseif _G[flagname].status == 0 then AddHudText(player, "flag_athome", "#AD_FlagIsAt", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0, 2) @@ -1043,7 +1043,7 @@ function flaginfo( player_entity ) else AddHudText(player, "flag_tobase_text", "#AD_FlagReturnBase", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0, 2) end - AddHudTimer(player, "flag_tobase_timer", current_timer + 1, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign, 0, 3) + AddHudTimer(player, "flag_tobase_timer", current_timer, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign, 0, 3) AddHudIcon(player, hudstatusicontobase, ( "cp_flag_h" ), flag_hudstatusiconx, flag_hudstatusicony, flag_hudstatusiconw, flag_hudstatusiconh, flag_hudstatusiconalign ) end @@ -1140,7 +1140,7 @@ function update_hud() else AddHudTextToAll("flag_return_text", "#AD_FlagReturnBase", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0, 2) end - AddHudTimerToAll("flag_return_timer", current_timer + 1, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign, 0, 3) + AddHudTimerToAll("flag_return_timer", current_timer, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign, 0, 3) AddHudIconToAll( hudstatusicondropped, ( "cp_flag_d" ), flag_hudstatusiconx, flag_hudstatusicony, flag_hudstatusiconw, flag_hudstatusiconh, flag_hudstatusiconalign ) elseif _G[flagname].status == 0 then AddHudTextToAll("flag_athome", "#AD_FlagIsAt", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0, 2) @@ -1157,7 +1157,7 @@ function update_hud() else AddHudTextToAll("flag_tobase_text", "#AD_FlagReturnBase", text_hudstatusx, text_hudstatusy, text_hudstatusalign, 0, 2) end - AddHudTimerToAll("flag_tobase_timer", current_timer + 1, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign, 0, 3) + AddHudTimerToAll("flag_tobase_timer", current_timer, -1, text_hudstatusx, text_hudstatusy+8, text_hudstatusalign, 0, 3) AddHudIconToAll(hudstatusicontobase, ( "cp_flag_h" ), flag_hudstatusiconx, flag_hudstatusicony, flag_hudstatusiconw, flag_hudstatusiconh, flag_hudstatusiconalign ) end diff --git a/maps/includes/base_teamplay.lua b/maps/includes/base_teamplay.lua index bf36bd2..a3b2d2e 100644 --- a/maps/includes/base_teamplay.lua +++ b/maps/includes/base_teamplay.lua @@ -757,7 +757,7 @@ function baseflag:refreshStatusIcons(flagname) AddHudIconToAll( self.hudstatusiconcarried, ( flagname .. "_status" ), self.hudstatusiconx, self.hudstatusicony, self.hudstatusiconw, self.hudstatusiconh, self.hudstatusiconalign ) elseif self.status == 2 then AddHudTextToAll( flagname .. "location", self.droppedlocation, self.hudstatusiconx + 24, (self.hudstatusicony + self.hudstatusiconh), self.hudstatusiconalign ) - AddHudTimerToAll( flagname .. "timer", FLAG_RETURN_TIME+1, -1, self.hudstatusiconx, (self.hudstatusicony + self.hudstatusiconh), self.hudstatusiconalign ) + AddHudTimerToAll( flagname .. "timer", FLAG_RETURN_TIME, -1, self.hudstatusiconx, (self.hudstatusicony + self.hudstatusiconh), self.hudstatusiconalign ) AddHudIconToAll( self.hudstatusicondropped, ( flagname .. "_status" ), self.hudstatusiconx, self.hudstatusicony, self.hudstatusiconw, self.hudstatusiconh, self.hudstatusiconalign ) else AddHudIconToAll( self.hudstatusiconhome, ( flagname .. "_status" ), self.hudstatusiconx, self.hudstatusicony, self.hudstatusiconw, self.hudstatusiconh, self.hudstatusiconalign ) From 30d9db6d6db8abca442c98dba149c9386707ae94 Mon Sep 17 00:00:00 2001 From: squeek Date: Sat, 28 Mar 2015 17:51:04 -0700 Subject: [PATCH 29/38] Fix backwards compatibility issue with base_shutdown - 'hurt' got removed, which some maps use --- maps/includes/base_shutdown.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/maps/includes/base_shutdown.lua b/maps/includes/base_shutdown.lua index c92e76e..ea12551 100644 --- a/maps/includes/base_shutdown.lua +++ b/maps/includes/base_shutdown.lua @@ -245,6 +245,8 @@ blue_security_trigger = base_security_trigger:new( { team = Team.kBlue, button = -- Hurts ----------------------------------------------------------------------------- +-- backwards compatibility +hurt = team_only_trigger:new({}) -- red lasers hurt blue and vice-versa red_security_hurt = not_red_trigger:new({}) blue_security_hurt = not_blue_trigger:new({}) From 8fa867b685b8a8b51e54236668162f0bc186ff73 Mon Sep 17 00:00:00 2001 From: squeek Date: Sun, 29 Mar 2015 17:33:45 -0700 Subject: [PATCH 30/38] Remove `name "WhenFFwillOut"` to make way for Steam Friends name as the default * See fortressforever/fortressforever#172 --- cfg/config_default.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/cfg/config_default.cfg b/cfg/config_default.cfg index 0ff7acd..a7bc681 100644 --- a/cfg/config_default.cfg +++ b/cfg/config_default.cfg @@ -66,5 +66,4 @@ cl_updaterate "66" con_enable 1 //cl_interp "0.03" -name "WhenFFwillOut" From 90b3a9f15d2c4d3ac067804992678143bc49b29b Mon Sep 17 00:00:00 2001 From: squeek Date: Sun, 29 Mar 2015 19:19:12 -0700 Subject: [PATCH 31/38] Remove unused DamageRadius keys from PL/RPG weapon scripts * Those values are defined in C++ --- scripts/ff_weapon_pipelauncher.txt | 1 - scripts/ff_weapon_rpg.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/scripts/ff_weapon_pipelauncher.txt b/scripts/ff_weapon_pipelauncher.txt index 97ecbb3..e82264d 100644 --- a/scripts/ff_weapon_pipelauncher.txt +++ b/scripts/ff_weapon_pipelauncher.txt @@ -5,7 +5,6 @@ WeaponData "CycleDecrement" "1" // Number of bullets fired per cycle "Damage" "108" // Damage per burst - "DamageRadius" "150" // Radius of damage "RecoilAmount" "1" // Amount of recoil diff --git a/scripts/ff_weapon_rpg.txt b/scripts/ff_weapon_rpg.txt index df7f57b..482d5b0 100644 --- a/scripts/ff_weapon_rpg.txt +++ b/scripts/ff_weapon_rpg.txt @@ -5,7 +5,6 @@ WeaponData "CycleDecrement" "1" // Number of bullets fired per cycle "Damage" "102" // Damage per burst - "DamageRadius" "125" // Radius of damage "RecoilAmount" "1" // Amount of recoil From fe1797af7d19f874ce51c99323bd3d65ca6091ce Mon Sep 17 00:00:00 2001 From: squeek Date: Mon, 30 Mar 2015 16:30:59 -0700 Subject: [PATCH 32/38] Merge in schtop_k lua changes * See SVN r15059 --- maps/ff_schtop.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/maps/ff_schtop.lua b/maps/ff_schtop.lua index 7a948af..b3973f7 100644 --- a/maps/ff_schtop.lua +++ b/maps/ff_schtop.lua @@ -124,6 +124,14 @@ blue_dspawn = { validspawn = blue_d_only } -- AND THEN, SOME MORE STUFF... ----------------------------------------------------------------------------- +red_window_clip = trigger_ff_clip:new({ clipflags = { +ClipFlags.kClipAllPlayers, ClipFlags.kClipAllProjectiles, +ClipFlags.kClipAllBullets,ClipFlags.kClipAllGrenades } }) + +blue_window_clip = trigger_ff_clip:new({ clipflags = { +ClipFlags.kClipAllPlayers, ClipFlags.kClipAllProjectiles, +ClipFlags.kClipAllBullets,ClipFlags.kClipAllGrenades } }) + red_sec = red_security_trigger:new() blue_sec = blue_security_trigger:new() From f48571d932477e48f4b477a78ff940c67d807082 Mon Sep 17 00:00:00 2001 From: squeek Date: Sun, 5 Apr 2015 12:35:44 -0700 Subject: [PATCH 33/38] Fix typo in base_chatcommands.lua --- maps/includes/base_chatcommands.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maps/includes/base_chatcommands.lua b/maps/includes/base_chatcommands.lua index b4cae0b..0d49306 100644 --- a/maps/includes/base_chatcommands.lua +++ b/maps/includes/base_chatcommands.lua @@ -375,7 +375,7 @@ function player_onchat( player, chatstring ) func(unpack(params)) else ChatToPlayer(player, "^"..CHAT_COMMAND_COLOR_ERROR.."Unexpected error while executing command") - chat_error("Command function find error for "..command.."("..paramstring.."):".. finderror) + chatbase_error("Command function find error for "..command.."("..paramstring.."):".. finderror) return true end From 5a30b6255d12ccdc589c6285774160467249e68e Mon Sep 17 00:00:00 2001 From: squeek Date: Sun, 5 Apr 2015 12:46:11 -0700 Subject: [PATCH 34/38] Practicing what I preach: Removed all file-local variables from util/collection.lua File local variables frustrated me to no end in the Don't Starve codebase; they have no real reason for existing and they only serve to limit mod-ability (their implementation would have to be copy+pasted for any other file to use it and the implementation can't be modified by other files), so they should be generally avoided. --- maps/includes/util/collection.lua | 110 ++++++++++++++---------------- maps/includes/util/utils.lua | 6 ++ 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/maps/includes/util/collection.lua b/maps/includes/util/collection.lua index ea39e02..9b52e27 100644 --- a/maps/includes/util/collection.lua +++ b/maps/includes/util/collection.lua @@ -3,52 +3,9 @@ local Class = require "util.class" require "util.utils" -local function setup_items_key(self) - -- keep a usable reference to the base metatable - local real_obj = setmetatable({}, getmetatable(self)) - -- add special handling of the items key - setmetatable(self, { - -- the items key returns an iterator - __index = function(t, k) - if k == "items" then - local i = 0 - local n = self:Count() - return function() - i = i + 1 - if i <= n then return self.entities[i] end - end - end - return real_obj[k] - end, - -- protect the items key from being assigned - __newindex = function(t, k, v) - if k == "items" then - return - end - real_obj[k] = v - end - }) -end - -local function get_param_as_table(param) - if param == nil then return {} end - if type(param) == "table" then return param end - return {param} -end - --- lua tables start at index 1 -local function to_lua_index(collection_index) - return collection_index+1 -end - --- Collection started at index 0 -local function to_collection_index(lua_index) - return lua_index-1 -end - local Collection = Class(function(self, entity_or_entities) - setup_items_key(self) - self.entities = get_param_as_table(entity_or_entities) + self.entities = totable(entity_or_entities) + self:SetupItemsKey() end) Collection.filters = { @@ -98,7 +55,7 @@ end function Collection.PassesFilters(entity, filters) if not filters then return true end - filters = get_param_as_table(filters) + filters = totable(filters) for _,filter in ipairs(filters) do if not Collection.PassesFilter(entity, filter) then return false @@ -107,8 +64,45 @@ function Collection.PassesFilters(entity, filters) return true end +function Collection:SetupItemsKey() + -- keep a usable reference to the base metatable + local real_obj = setmetatable({}, getmetatable(self)) + -- add special handling of the items key + setmetatable(self, { + -- the items key returns an iterator + __index = function(t, k) + if k == "items" then + local i = 0 + local n = self:Count() + return function() + i = i + 1 + if i <= n then return self.entities[i] end + end + end + return real_obj[k] + end, + -- protect the items key from being assigned + __newindex = function(t, k, v) + if k == "items" then + return + end + real_obj[k] = v + end + }) +end + +-- lua tables start at index 1 +function Collection.ToLuaIndex(collection_index) + return collection_index+1 +end + +-- Collection started at index 0 +function Collection.ToCollectionIndex(lua_index) + return lua_index-1 +end + function Collection:AddItem(entity_or_entities) - local entities_to_add = get_param_as_table(entity_or_entities) + local entities_to_add = totable(entity_or_entities) for i,entity_to_add in ipairs(entities_to_add) do table.insert(self.entities, entity_to_add) @@ -116,7 +110,7 @@ function Collection:AddItem(entity_or_entities) end function Collection:AddFiltered(entity_or_entities, filters) - local entities_to_add = get_param_as_table(entity_or_entities) + local entities_to_add = totable(entity_or_entities) for i,entity_to_add in ipairs(entities_to_add) do if Collection.PassesFilters(entity_to_add, filters) then @@ -126,12 +120,12 @@ function Collection:AddFiltered(entity_or_entities, filters) end function Collection:RemoveItem(entity_or_entities) - local entities_to_find = get_param_as_table(entity_or_entities) + local entities_to_find = totable(entity_or_entities) for i,entity_to_find in ipairs(entities_to_find) do local i = self:FindItemIndex(entity_to_find) if i then - table.remove(self.entities, to_lua_index(i)) + table.remove(self.entities, Collection.ToLuaIndex(i)) end end end @@ -153,7 +147,7 @@ function Collection:IsEmpty() end function Collection:HasItem(entity_or_entities) - local entities_to_find = get_param_as_table(entity_or_entities) + local entities_to_find = totable(entity_or_entities) for i,entity_to_find in ipairs(entities_to_find) do if self:FindItemIndex(entity_to_find) then @@ -165,7 +159,7 @@ end -- this is a strange function function Collection:GetItem(entity_or_entities) - local entities_to_find = get_param_as_table(entity_or_entities) + local entities_to_find = totable(entity_or_entities) for i,entity_to_find in ipairs(entities_to_find) do local i = self:FindItemIndex(entity_to_find) @@ -178,18 +172,18 @@ end function Collection:FindItemIndex(entity_to_find) for i,entity in ipairs(self.entities) do if entity:GetId() == entity_to_find:GetId() then - return to_collection_index(i) + return Collection.ToCollectionIndex(i) end end return nil end function Collection:Element(i) - return self.entities[to_lua_index(i)] + return self.entities[Collection.ToLuaIndex(i)] end function Collection:GetByFilter(filters) - filters = get_param_as_table(filters) + filters = totable(filters) -- optimization for players local players_only = false @@ -210,8 +204,8 @@ function Collection:GetByFilter(filters) end function Collection:GetByName(name_or_names, filters) - local names_to_find = get_param_as_table(name_or_names) - filters = get_param_as_table(filters) + local names_to_find = totable(name_or_names) + filters = totable(filters) for i,name_to_find in ipairs(names_to_find) do self:AddFiltered(GetEntitiesByName(name_to_find), filters) @@ -219,7 +213,7 @@ function Collection:GetByName(name_or_names, filters) end function Collection:GetInSphere(entity_or_origin, radius, filters) - filters = get_param_as_table(filters) + filters = totable(filters) local origin = IsEntity(entity_or_origin) and entity_or_origin:GetOrigin() or entity_or_origin local ignore_walls = not table.contains(filters, CF.kTraceBlockWalls) self:AddFiltered(GetEntitiesInSphere(origin, radius, ignore_walls), filters) diff --git a/maps/includes/util/utils.lua b/maps/includes/util/utils.lua index d279d6c..86c4571 100644 --- a/maps/includes/util/utils.lua +++ b/maps/includes/util/utils.lua @@ -25,4 +25,10 @@ function table.contains_any(tbl, elements) end end return false +end + +function totable(obj) + if obj == nil then return {} end + if type(obj) == "table" then return obj end + return {obj} end \ No newline at end of file From c586b718b44c91a4575470d5d893aaea08b5235e Mon Sep 17 00:00:00 2001 From: squeek Date: Sun, 12 Apr 2015 14:06:22 -0700 Subject: [PATCH 35/38] Increase flag touch bounds a bit * Height from 65% of model height to 80% * Width from 100% of model width to 150% + Stops a single SG from being able to completely block the flag, though you can still make it difficult to grab * See fortressforever/fortressforever#166 Flag model bounds: 26.254800796509 x 69.179306283593 Flag bounds before this change: 26.254800796509 x 45.048884835839 Flag bounds after this change: 39.382202148438 x 55.155250549316 --- maps/includes/base_teamplay.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/maps/includes/base_teamplay.lua b/maps/includes/base_teamplay.lua index a3b2d2e..4ed3cd3 100644 --- a/maps/includes/base_teamplay.lua +++ b/maps/includes/base_teamplay.lua @@ -724,12 +724,12 @@ end function baseflag:hasanimation() return true end function baseflag:gettouchsize( mins, maxs ) - mins.x = mins.x - mins.y = mins.y - maxs.x = maxs.x - maxs.y = maxs.y + mins.x = mins.x * 1.50 + mins.y = mins.y * 1.50 + maxs.x = maxs.x * 1.50 + maxs.y = maxs.y * 1.50 mins.z = 0 - maxs.z = maxs.z * 0.65 + maxs.z = maxs.z * 0.80 end function baseflag:getphysicssize( mins, maxs ) From 6007a9692bc11c7fd24bcd33e4a64871113a5c09 Mon Sep 17 00:00:00 2001 From: pizzahut2 Date: Wed, 22 Apr 2015 19:31:00 +0200 Subject: [PATCH 36/38] Update classcfg_default.cfg Fixed wiki link. --- cfg/classcfg_default.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/classcfg_default.cfg b/cfg/classcfg_default.cfg index 7da4b80..cafcc24 100644 --- a/cfg/classcfg_default.cfg +++ b/cfg/classcfg_default.cfg @@ -1,4 +1,4 @@ exec userconfig.cfg // This config will be executed every time you spawn as this class -// For more information, see our tutorials on the Fortress-Forever Wiki. http://www.fortress-forever.com/wiki/Main_Page \ No newline at end of file +// For more information, see our tutorials on the Fortress-Forever Wiki. http://www.fortress-forever.com/wiki/ From 5a7a98a93a1aa1e747e8acb430a07450889f42ab Mon Sep 17 00:00:00 2001 From: pizzahut2 Date: Wed, 22 Apr 2015 19:31:57 +0200 Subject: [PATCH 37/38] Update userconfig_default.cfg Fixed wiki link. --- cfg/userconfig_default.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/userconfig_default.cfg b/cfg/userconfig_default.cfg index 74ea5b3..6acfcd0 100644 --- a/cfg/userconfig_default.cfg +++ b/cfg/userconfig_default.cfg @@ -4,4 +4,4 @@ // IMPORTANT: This file DOES NOT auto-execute. // It must be executed in the developer console with "exec userconfig.cfg" OR in the .cfg files. // The first line of each .cfg should be "exec userconfig.cfg". -// For more information, see our tutorials on the Fortress-Forever Wiki. http://www.fortress-forever.com/wiki/Main_Page \ No newline at end of file +// For more information, see our tutorials on the Fortress-Forever Wiki. http://www.fortress-forever.com/wiki/ From 5d079c9a94a128e54f1b56d41c38b9844c2c2afb Mon Sep 17 00:00:00 2001 From: R00Ki3 Date: Sun, 26 Apr 2015 19:53:31 -0500 Subject: [PATCH 38/38] Update FortressForever_english.txt --- resource/FortressForever_english.txt | Bin 92000 -> 46005 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/resource/FortressForever_english.txt b/resource/FortressForever_english.txt index 019119d04e21b072779292a08980ee8ad2bf912c..9f68a365f1a3365964c1bb7dab84d18830db3c89 100644 GIT binary patch literal 46005 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�|v<=Up=p27ksW8s;#V!Q>WsA#u9 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 literal 92000 zcmd^|YmXgAa;E#M7w`|*Z#@L8@xVKp(QR(~!Du!w;)pkQH$~G}fRIRvBa5PFHf4#L z^^`S5A~J3n5gD2FfB(;wy%&35?7iH3zISEsZ}aocj~KZ_h_VRer_{_^Pu*AG~`y!R?K_7V`Q!x-D#^}Vm+k2L!)qyBV;an4sP?u)%I1Ix3$tMTvmfgLS=y7&3Sap|ylF8lP;`_rg=et+-Z zn-M*3R&3Yy-cGpT$dk!BK0oK!m9UDJ@hOyi5wdv}*78+6_be!U8b5y*zX{*7y&vMI zA3}=whyBp8?x--56?X-_Kxe=<=Q530nAKW)X1nVSJ8f z5ZA``u*tV*y|lkv`jWn19eI!Au)FVqYT&#G%DxK8zKGxOO|A9#$^FSv^I3k+r+fT8 z2$-xMXxoeUA1l2XpD7v;zu}Ib`}L$heiCc-vpwke89W3r%A38zz<|d%jh|R+@gmk{ zaI{bFhu-^ney$^WxQ+ti^PnDUco7zeG~dK1%ib#+E3){yKUr6fkv?iv`oFQf>#B1) zVRKBA_No1teT^o1yt;NqfmWvb!H>5=kyh&a!IkfV zQu|Eci(WkqXYk0(mH1*mo~`5gJt6e4qrpTwc(WT3r5%Sa`7uVJRrXtny*|Bv_B>v# zH=>8_;UpPw$)mCs<54ZE)Qfx)&A?YJpIw8&K3fiEOhS#z3 zD?S$8S3(-qUZEKrjA5v>$eswuo)T&3TYOf250oCHlc0)K16b()>+?9>5XsQ=j3Dw9aUs54@qQ2P zVT{4&!g*&{{EUzNDj=BR>J7ba@!WpQP*1)N>XPfwAjnvV*L89Se&?IMJWc`zS?2Y4 z;%UfUoOv1=og>LgzYCgW`^;Nouy#iMI==lX{>8f}qe3V8<9j@@-zS!WR@MqKHgT!P zk+%~jxIt8<*d4Bd*D(6?HLimxV!}FE>o#Gol1RK?G~>79RZK{ngKvH|$@_U=XP$TB z@5||P%{3!P;(9%gt)qpKzef`J=h#iWtx?o*jIjsparcM#J|iwH4-2pPMy~p3BRNMM zgP!zgxe-u-bR18A9sdKx_^~P?jc=zJk>{b?(22i1EhF$k-%X$8EYO)g4Lv&Ug^&2x zfUVVr$oW?Mj6WO22lMCm&qs_RgfWhsF_Fg@a-WB+x4D*5X-i;?g|T0MVq9hUpSXDD|RwxphlZu`tS$j1Tm?X+Gj zVM29&zYbo1mdI#QNW_MhJILgiGu5=y>aBztmUkgIj;SbalNtE1EXTBDp_i1EfvJ6LHzj|tUk+m{4%&u@jeM2umgjaBd=rLq?*Y6>%D)APoGV6w{q4DRU63pn`%i``yBVDxucbjr&aJxmsBC8{q z>o+49eg@C(+COugfBya+f2#E^>B%v!=i><~=ax_GPackEh{UbMOV~u!SO(dzDs_@Y z{e1uYo6&4l(;NQGnEYf!A3X%G$_W47gU^2P)A*CCEwgDq z?Tw@A`6m8gb4gqK>4?66J|6)te(Pa))I7y+BY1V!J!xq_?O|XQpu&m&u!T$W_#976 zWKAVv{$vjtb&jV6lC^jat3KC*a}qGx8lQw(yKO0f-W6V5x z2~GN>_q-|x zJvdqK@jk4fI!ct?RPy|+9xuKsW3+zA;V&?2+e%kiT0!!?NjEqd{mDjV(BL_BX%7&LtZ|) z9lAJEXN_mc$i|#|UbxB*#4?g~tscHJe#9m6TYMI~OJq!5tMLS^Hp~^h!m_EdlW+eJ z|NeXYPbUOxwRQxsE-K?>Xw=KS6Z4z+%s5W>eiPr3M-iJ+{l?pXNBbJ!BX4DV*4BYf zt_Ebrx&HqB^i;ba@qT>!zXAe(b8gC*wX@^V%9KAo!)2NBB-+Jnoy*O8w?3QZ{USI7 z#8(aH-X-7auG?>dYplia7s|o=pUca?#H`^?N*2!ZNz$o35afgmEz@t#_@%LE8~lBC z&flJ$&8ukAKih0uMf7()I9`R^HK0gHt5)XHZB~XQD1KsZ+R=tQVEt~teA~lapUvHg z9-REP2dAZh8RREC-y3r^W}wVn`273$*}C#;1w)sC(tfiEf^v2G^lbf-nBnxk@4-uc z*yrabz31s_#wzS7;ZgmpH|8Mxo~W#`Ui&HIdSh?I$l7;o{c(gMZR_sc)yAY|XW#vj5#Et-;`kT>Qk$$^>q9{?H^{^5R zdL5DW`IFw$TH%O&$R4s2jGYhbVfzfLg!{jEYFT%)JXB?=-O~4hGS(wJP{N=0N!^Yo zlvRs6^o+OTdNW~`KZZ|9ioBd9$2_j|vc z#@Bww)AJrPQLozYlX98`x*UN#o>pzDDOUoL{NmpQl^;yd`RT*>>3_#xe*S0%d+y1B zhK00znXgOeJ1dpCv+3Pog`(o=It4LIZzUkcXg_~E<%Dq6+J#o$4p^*E#Cv}U*mN2y z6Hr9`WRelpD>QRI?1w7Mt7(4+-rGXjZ@!GD*wcDD!PL`ezxu6!^d^3$|AYN4a^vr( zJuh;D76bgIV->lh_dHLAfnQ<$hc}M%B}GmKoy5GZhaBlYJ&HbI{=F4@N%Wk1_Uzc^ zx9lD0`=j9TK|s*?BHLModJ^M^0vHdT!}7HB!cUMfE}vP_3C8>96qrKfqi=ShuFmT7 zfO`})7-Bo;-<(5d%*iy1yWwYeeng`pp2LZsc?wJL>2bf4B zKaMQyUQl32hrwC=_GcmIllW$Tdg}HxpPTV>k3!&aR_uCEac_E(Q&EmU``PgUiGI2~aBY(W7 zwERy~PF&a0(>;AgCnDJ{YnE7(SAOLfEE&eV;y%3g!$)V2*mJEkdXqmmYYQllE<7wn}0rraTw!2kH6Sq za+!!^{`nZj(KPbfB&nQr{gi4hddbO7+q5jJ)mP?%H-nmL)pr9nUiLx2`80l72Mzna z8@hiKoJE$_A^FGoH{T-vgt(!ou(C&^iE}e~e5<0;ca%t*!P(;m!_!tc0 z23bAXEjcc*l|S+n=iRj%^;LXFzAqTc>ey{;&sI<&Z1qCY5U=Lz6ui1UVPn6G92i{4 zCaaFf2|kEg?N~wIvp9ov8sDh5kZKE=HYbdskZOe~XE%ikBh?Gn%T(>cQmJkjj;Kdl zM$&HAL)#GYCS&&b74i?VbIU?_;AKzxNRey=3N^p>TqV{CchWboZ^phe)h1voS64;O z=R;M6(M~+QF6M@;o%(<^jy-IigL80MBU1v_8_8UIV`!B0BDqT?fqOTA!H(^>@fT^1 zHDVqYn4fvNL1#d9`regfxTL*F{-uXibw=3{dQOLu>0{>T_pjqKG>i&`HJpl}^nIzv z_7ATnT*!b*h$O^r8~UbazMrIEeCF!XHpu!~P0=~3Z#HnKMm^#VHghn|P&+)voARP3 zS^e8oUf`8?h-B|*4fc_hB6g9oURf>NxR(+K;ZGJ=m!H44#}%`2_l9N9q0WLfjOi9pBcE!_hC}8|+U#YH%FiEr}yLX)N-^ z9<8Ndr&>s#i>3POX(dP>pS#Q0v3C3ICsYxX4N*zlN?<+ag`;#En?AcrKrVF3ow)XYHy0SMS7Us%BG(PMz*)>ez2NqOY@) zp0Gx%LW@qpSu{mHS@lysLDTpj*=U6~rFbJeF+8dDQ=lO~uvp)6uivA+`lWSJ@z%I6 zC&o}tAo~@ zF`t*2k2p>yBYq=)tU*3Tw`dqLpKYcRtLB_}Ml;VMp2?G3MIT>IYmcREs%8C0K@~PGd7F25N#Z}BW|il_deql#?sHBApRWCmmt>Yi(JV&1Z|xJs;Fa=tGKGu zQdGzGVo&0a9Q&KdSRO>Ket*hdT;Cqi(vJk^5I>Eo)z!#_R0-?D8bv`Dfz^)}S{^Ou z*{7?&=C)Lg_}yCp*6?EKSzFpi_{N@M9lc|nciu{6mCPAlRen7TeYqQ}HTSwbKFePZ z;y0=u^C}^c8`V>PkKd(U>pJ2lxYYm2s&9qHVh^$_AnKd_=DRT@_Hph-4g6}1%<2jr zwf%eyp;s@JE%v?{!&z6^Wj9?_-!UX)d=hdvh*^Ag#uoFo^9O&T>6yy?OMMA zr&VR4=gWf%aOO4f4*t9tm}-PYbmnOs?WFki|^OKoO68+ zbN>ApCc9kB^q<04Xg3cZX>XC=uJMWNMG<+ZLVa+i*;G;IpKqdvecL;Woi|n@eZGd0 z%j}r7R&-NSa|(@43Qq) z<8wc1Ncwb_*|2AI|BMps&%ci`D^@uO8^N2;W!rwc3nl7GIf%9RIB2>z?echD`5pV< z`R$m>?7y;qmt?ZPo@ z)LaJsybo&=tu@B35jOF8-5;d8nn)cD&`#VYsPhPX4h_9q4^J9a`w@EZ>fYp-wq+!J zaae84+=J6TvB~$2;^sM2vJb6O>=};dX$|Se)GgF2dml$1DbmIpeHt3u_RIBrefn2o z^%kCD4nMJ(PRFqG2zL(gA~dq%Wu!ZYhz|OR%`__BU5*!ojC?mkA+GJg0E)T#yn4=2G8CdJIQlOJ*GWjAU*PTmCiZ59@QS#gLx8kJdZ!rp8Z_XdnNkm*__=~&WgA%g?X_L^5pz9hyAL~(L4{hzHz9vUhR<5N8!CPIKi%?Iw8DY zW=!@mhRg%y)nEO#=HgEgXue+ zsL*rX^j1lJ9*4H__cxP=r`PR9V;PSk(xJPVHQsp8wJT9UL8|H};B=#Q=GmdNc7X-0XE)KB z=H4@Fnmh027z`h+!Zzg9=v}xtF6wxyRrj%KeZpoc6yq( z_{|nY21Z894(0D6E2ds>82JX38_)5|^bPSx-nzmXNS7fUH;NMQV(OMqR|&mLr;FKE zd>=>d)5pg*?;hVr!};;eyT|vzaDIIAbKo1v?}MLZetqe&ru`hV)5$vCAy>P<(=sxy zNqb05td>{xUneuA`+e>)AMuYn@L2Cz$ z=R`^H?4mprzLtZR#kYxu)l92V_P|nkRows@m6_iUU8C2&Qmw2q&s`ceRBzAD zksy^a^TTwT2bKKBjNGTw_QUE|3W@SxN*UE{LPs8IS{I_y%jj>1C{Z|dwsu7=`BUm}iC z45f|E>_J96RrFEEIv&|Jl6z}dG3ZE_5PN8?^6-Gq^HG=z21O$aUL>pc;3spz{Z zmxMx1wCX_CoY)2HeFvNhYc5%CrK0bp-b+RFnxFBmKKvLPHcwj&P!{IIESaw znq`Q~=QhK2B#%Z=eM`7n%Qy|CXO4qjPUGl?Gq{*zz|o$XPme~{rf&BdMY8+GNo021 zmU>RNJ*yfv2luL;&*8DoeIMk6EFbtPV>?2k7*D7|$gv>RWVJu+OK80<)o8gm(v%aqY*Sn?dm$ zw)jY&;v6d0BYysJinSA3?rm=8N7WPOV`LuOk9u?R=Zem9F7@{G{qSW}LXc?d2j{R3 z&bcAFiKW#cz#aqNZldJs#?gGs=n4UTJ&HMy$E18XIWxa!By$_*!{jB%#}ebTC?~~< z2bQ}$#>9Cp_J)@jn6YDi;dr?xnYEBx9vH5AM#%xy8=L;B!p*!)x0k;RuF@Z+Q})_1 z-$cFjEa?Y7RUq3$&OvdJ_OYpsQH$3ZbF7g%g5Q2&ZO?fwCDrSR#TM}dtdsP_9Z%j! zX8`E))~>lvK3i_&|MmyD`zJ1_vO!Ji^}@z_6tH5ev-w`g&Rj4L$gq}hIT5Tb8hT#f z3h^s<@bYx*la~t(ItxD!NwWZc7eF|LnbL73GRA;f= zUrhHg5;fzW)FJaczLAc)<|S|3%1hlwb5G2=G^e~TF~^*?`4&3-svSYTPc`Xo{Xh?| z@9Ao9h*Ul+tjKN-8Ee#imr%g2?wf@znETtMCVz((Lj}7awa-4~M*gCki;z_MsV_Pd zn&;c~Xs*YtpJ#6+qZ-R$u0bs=NU3T%wzif(JrB}SWWH|G>N!n#@ans$EBjrG=9Xg` z<7j0EFXo=+UC`F^MZ410!?CP_5N0KMzOhQV1)#FrGVHH8r6fk4i~$YM^hX?ZAzy? zE{2c!iaU987u-NgQfuH4QOetu8dEidh>w`J?WI$em223TBY2*k?ubS-$nmn?FtmQc(C%}M8i?~Y3Diz133L*0d&irqPX9$6W3&c{ z%Nf1TeQd?S+amP-73s?l3p`|8_$wlZ5y#;?Pt^*KW34f-$*4WRvjOn$*MKJRYAb>s9?vaapaGZ_*IO zF7*zvH8NBUq{T{I&!_2^I^%h^`1 z&$`7s=YjE$IM8|kb7VPpZXTdY$o&tyK%D~xdv*@e^XEU zQ2Ti<_f^el6;yow+=GlL7Hncu{JEpFaaFple9UQ3enV8x4#65K$ow)|gQr^KmDRAm z5-y3DKRlxD>_B@2(TdWVkeBIC`t=JH;LYb5zKxaR!d1>?`b@lCq1)K2t**}IlX zZGdXeY$!OYmfK#F5eFo`*&MU%)TbO!0d>!x5;~o z(zDI!aSZ8vcb-YQJ|{k^Ly25qzK58#68U;!bv!GpGphhO3ei$hawY8e`}q4&M3BUn zzm4CB8U7Ie|04FxiNLfHJ&*5xAK&~X`lWu1pI^tAWqhXl9+G1l8ryoQ_8cc<7ud*IaZbwlm4vZy*urK-hNcV^m} zFtgMRDyoT4+xM(JU!p(a68>-ZX7HoZKvzD9LwPe_oomJJ{tWh_YDVc9pPbhNvol(- z*@dD@w}rj5dhI>k4lP#Bheu+TZJgQjN@(bds0mOB)IGt>kC?i}iHDt6+S$F?hO>q?Qk26S&UT4}q)BdD^Nyk-~k&D7I&61t}w4|-}%{4()f?gg*<&P-bwV+>~ttUWW4}YY|N#UGFBWhEAb6V$I`Ol=5YSx&` zyU?t=EdKL2Pu*QLE3Ddme@pKBO}zcOu;UZQs_4S=DIZtoHL)$9eIFWfd0n9=fQtOJ zvI}<+ZKgI4U5cC)PkPN%6^yrwJe}Td;eE~BHF-qoE?V((P|8hodbh4)9ZP*4uY2!f zL@~WM+{E-Y_^CL(@7wEb1e_}pj~(~bUD7vOJ;s>&xqrJX)$8=N#vwY5;Z?ylMSqm< z+C*EgOcufIHt6904E|9ocpK46Mr*g?)9jBRN@rh%&NohF{3&jD`gH1RJ(zwzm~m}H zhd%ed-jxY2)!?;s;OmL#u$9YE(smljYwW@g-CpHNYLx*IAoW?FWgt7?Tn3(c9tpH7 ziBC@wi@0}z7*Tw0?Z1Zw>){>G&M!y$SAC{3AXZlHnIj(coV>r)!$fy4`waDL!+LCb z^U%MCB*D1srtD#)cR6qAAK~JyUFy{1T_%-}zWr;>?5M1h)#VQK2;Y*E_5EGORkfqW zt-hI&{1{xWiBmIzg4)~JN`D!7>h01kl;u+`6rwWplq`KY9zRi^Xvf-q`s4iVe9YYM zd+p@@{yYz#-uy{u2YY=~oAmw}ui~m2=t*^JP>FREzjj@q8-%RzRp6oDmW=NoCcR|e z1Wo$j+#aeF{oan2Kdv-kQ|}~usT8kF?>?N$_EYA3hG?u5vls!v;W=Pz+oIZ z)jXbOl|kY}AlD{n+c`~lU;Bpi+Y!Bf6)?8Zfz;+B={ej!lG`LL6R$UGMp1D`tI|re zj-gfCsAWH@eai-?(!Y(EYwbu*Et6A`*=P?5>tOGZ{DJ&`cZk4pk1qEq>GavIaL@zK@?*DXJ9W7i<#p>gs(8?}Zan&q{<*&tTF4P!hX&5~`trmm0U~tJJH)*N_-Myxbv<9w1svjwqu38Y zfAqUxJ_s1paM>NkCjoU{1z$pBKVB!Z1&^Nv?_p3#RfyeaG?SHJ``W0J&spgwBA|w3 zN;c0=E4uQ1W=Z@wKfCNTURj#xL$*2%&3Rz5fG@V{7<}Z!syW)nMLh2}zFr&`u>v_9 zzLY!U@{IiB_y*08mZKYolV{V;4;gB%o1CUcPqyjaCTzOBY#p|fu(ZyUT4ywjg;TqO&nhI|>m`gX*`%I?MH`Q8W*Kn?UVc4j8CR-XuXV2 zLaVm(xy@7`N2abfC)+!qzxcm;vh~xj74^Zkes;58KMXJS!Q}Vw@Z8Q(=K`Ml(`u7_ zBpR_@TKD4yE&S;&a6b%u+v)viXSg4&g8T8#a6euJ_miFBezFSg?{I}TTsuLT(wCU|2{m4aoErMQY@4;@V-o|@kz05yc zcV*vUO$I_Wg}p>YS63qrwpT`8MCQc5>U}L^&vNBXv~jPINh{lZ332pPo(Kmbc=0cSvxr6Zs|?g?HJgb<&$kXP)2oRNrKy z6P7^NTY~)78%|77fl)s6Dqx_CR3E$xcN&;Et6mrL#JG4f z6WsD{^EQp6)_iluncD$@x8NmTj;EigvH5Hha%)t3Jnop+3^B^XsqVBt&oR1*G zYANc?@GV=6MiUg9GAndhC%xBd<#DWF>Az1V`NA(-$z1c;^VS^oK9#Sh_e(Kbs$a}i zoo;X)ZPTZs^V{gl(L43f4MCCJ`!?|O0P-N-@z!}a)m9}FbTTo5KW)}JgN}Me_C)dw z){hE-x32l~ku9`RKZp^vU#mhx+NQ&2CODaaZq+;d*7*+h&2{%2^|kAh#8g*>$E>uP zmwOMSC)+uM46Kv=Im1KUQuwYV2EVZoY*aP}|BZq^5B0?fISHwvo3g5 zVT5SIZ`x}ars(AU6uRI{7oGJlCkY^AvHmCB+O=Rt#Mpd~2ECs2 zBkAxOq>~}Q!GFDuKZ^L!5wA9BJ9+PT-*$BWKfQrH+sV;L+3TsIv$~E-1GSb*bG35Y zH?W7#DK#XUx0I%>ScCm$GI-8jsZYRAWoD*~)wyPIDs@yV0&v8a7s1PKCn+!zUxt); zQ(amO+JY2R_rvaZ`vARW%&qlGe5W;%XiWOacvD_`6I8RcAM3?jxQv!5`eDZgiir8}4zf8sgHFx-wD;4*otA3mr2b8N1Li@T3GMRFDNX5d-s|TT z2|Y%Bct`FHP`-hTP9_~iW3~4Kr;)rOR=w+#(OPNeb9xq4W^x1h6U{SM5BlzOTMIKz zPNOyQsIMj-WkpaYK7nTnux(;FNzM{vUO^KEa!`U<>k4AnuNjT48B7q0N3+5u9sWk?U6FHKBWb7kp zSYNFtSX9rWe{tr0$S}sSQR?yX9!cd@o@r{8?$1npBsavn6SW}|=*ccXeIo65u7q^( zvbyUTE})6>4*7Nn+c|nA4!w-$JpZ>bp0%7$umya+-qV`$c6Oju+8JogL7^yPV`2*^ z<9TaFdg43rIU4$;sVrxfn*HxRPn@Hz9cc%>yx%Jjb5I@~zXg4) zPmZ3HeM;}~x0bZ{qIpWD%0Q@H)!cx1^=Zgkd-+=R(2BI=zXmpZ{+n1s|06z^lv6Wm z|8{D4)i*pVJ{WCA67n-dzwrG?qY7B?)5NG z>8nuETh=vOIj=MaKBF!8bKCaPj_kwWxK|GRF4a5c$x478Qt9PQ=ssbhJNlHHu&xk` z>8)PW8i+#t#IItUxX7xlz6j@8_*tm@@ys@VnsD02(Qe6EF>uyfRQss?yeVCIpp5x# zm#*N*56aefiM{oJDx&fd#ZJJ6AFP_nc!7)GSMCAdi1$)Es%}{8 zx6jY_fYSYp-$_4;z8ytPrK~`BGwT5SRHdBLMXomTc8H8kYR(V-=aYsx z<0lqI-q?ZWxL%8Df3`S$6fl6}niR7qsv7GQ(YRtudq5(auNGa_lmSwOEhvVDJdpQinrARNja)m%1wN{IBtyc0tihMx?z$v1Q!G9InGDHh1)! z`megddQFD+^_&muIvNfBxh+Y{@iy$+pkL@&Qk|I_Be}yCUoAPv$F}-4uj3U!HB=IiyQ@iB_i7aiOHgJb8Gs|Zp}l%y7mC7UIp}z5lWsOpgra(d zWUrGhSl9i@vnao`$Fq-2IIX4BtU&Q1HmLnE?F13~&#kSM(0ZxU=gB={_G3D^htG$% zj@lHk4SByBZ_ z6;2g%)dl76q+!)Fn&XZVWuMkV@8&W`Bq{xoB7mE=nQ@#VdHZ%#Pu)_TFxEtPM^;Hh?<&34VaW)dua`Oz7-xU@HzP2ui&_ip zF~_>OywgFo8pZ<&Ym%lI78#(SD{h3xM8mAZcvs(NA-ltZUr%dUW-%G_JKoF)%Wui- z$5z}fOh;5Nsv>`Nbc~m zU#u!rt(a6N~stR6_ajXMyXU$xFvxxfaP9_^s z{DGfCnykC>j`B9zIn^r6GwRRLYRmkPge94oWv%P!Zc65CJ5`w!fWcetp;b;kXFq(2clD5uJUstbFCdR$Uf7bshD6EU>=~th>}FyA z!~|$nu5ehRGa_*dYjcz%`iLjFRYI%7(<%1G!yAWfGkq`XEcG9BhM!NvQg}XbF@sjl zw%*hc=wUwuSX!ksnt{LCzjCB<8uNYn&ZtHB6y*(#=YNe@TKPRXR!ywS!`7Sgo^y~QWd{_pKfFh^EVcC%XxSXz-|y=BF~Gp8G# zsJ5?TM?p8Mg=fzHUK^m_oWL6B2;qNsVi0j^&%5el?)<|S*LycCtf6R5)x>~IYPl8Un5|O(& zP^}t*q>!U_>srtoLv%Lz?%qG0)rwdd9)ujxTJr}DgLCZo!KtsK14Z$nJLp6SJM!Ei zojM`wfKT3GH;)Coc7me|+`7$*S>>Z%qc+}vHnI-+qwU&(rnCQ|j7_$E5To(*+GSQm zZD~3t@_J!T{59@{5{=)KdbO$1jyN;Gmu1E>*Sn1Nz>YL^?=~@{E&tJEIr5F_{b7aD z-W?uLbrEz8T|ipW?bJK!p?#mo4E`EwNM(d<-Dc>e4O09Jb3_kO8?G1NLV{XlP`+LS{*C&l0MQQ8>>P}pqb5z^odAYCUJ3ST-I9ZR+vPHg3pT zaq(_M;rJ_7ta~w5)g;-{FVDOpek?2N)VJ6#5I)HQFOe1T{k`1n|75Z?*&z7ZIE9*@ zXsflpoRPfASd)_bT03-OH+xCC&xbn(zzSDbt>CeEU*q=l!qNw-fW$xe$zQ|>+p{^Y znj`DD;!evA$aSpe=BOa)ke0%8A}q<1wG>$(MdCrSB}XXAM;-g&`|Q=!@kfP(J!pTL z^*8q>uHj+c4`psDQuX|$E2=I_9 za}nOa6UKrGKV4(Z+WE36GEbe!`QnM}C)drkXKBduDCom?Avwhq?uwDrwDO_z#HMfv zS+kd;JxD%L1g80t!z0<$QF%mg_1-4iLIdY~r1@!GK@vX(&02GyIs0XnG24=Re&?I+ z;&CUxD-}qTTyBnaX=$o*5Wk5x=o$7(zAjobUs_s-^#*OL`vkI_jPR2iKLlUVC02a6 zc{P4hM}Rs@(CKMlFnenUG(o42Dx%6Lv0Au=7fc>z z9{G_#2oJTvTp5nEAZUG-FT9KD_mNY}`L0$1{_(>0;-fB>9;XMeL z#I*P;Jn!YY2-9mb-{XLpdXO4gEl*K0lE^t`^w94WbYw5v#yh~rezq;ix4u-~#JP#r znKeB0x_B)#l3r>~m+6iq>m}0dc?M+4H>`9zEBbV*0JM~?^;V-Ujr19Kip^B^bUvda zbU|7Me_gx#Mao)l6aoQZDt(%a|Ftq91bdP;QMl_=K= zbvHWtn)WLh&7)8JTJ;ICVl)nar)XUD@40{Jt>ZOfS=wDsCR#Dj3~VI1R;|don_0`v z$sX8o!bAQ2^glmkCP9Art3mCV{uAEc&b%R?bdS%>wXW1~ zPrUAN0e^Bc^bJUgCQ|2GeDfYk{3l*E_qw66?%An^F0atb)>0!j#g#43$U*Lh1)`0* zDTnGz-B))7MC&FMc}AdVic1s^O270o^RDuzTF$!LT3J0Em2owi!1-`ikh~)RZfgAj zHW^KNVd(I8aQ`Iqj}>S{=R7L{7Z#$t);;m)vHRxRl}+6;e8w}3qPNA~6l?STn>rxf zUE<6^(PCzyK%$;yx&HOcFB?+!o7j4m(QYeKB9i+Nji^UfXTh$7R#tgw)_kIjSo{5O zw_m?^-)p7wAI^24UH{}ysAE}2YMmb$9R*%iT<>Ja@4^9O`NMgfEAIuBig3{)Y1Swb z%#0E_tMYBlwLSU$ztqB1M{w=MTDz&|dK0g?=?VMUjn|uW0nR*+KX41Zf7a9l&FT8o zo8aGfUHcyNxwn24&})xs zN^kC^!Mff5q}|G{t!4RnwP)?W+3(7u-~+Kfq8NErJf*wVv}Gh)S3W^7> z_Wt`mGhCkQUB6OuZjAdP=Jg-PcW5J&KqESbozpA5M&fm>N9OGDAkGTYR_d5}ytXUO zjP@#4MbZ6kG2QvCeleeVG-n>h+;uZL9RT)e+x1F1tms<*S~tkQRds;Fcm^P&oyw7z zKh_WL)ceJKRX%eyU*G>BBqextRL)%b1s3?C_ssA-Q9>L05G~=Cas)N-*Wqs*h48=D zR5U>qd{$U~^GYh+#@^Hs#m=H=pU*S3Rd;h;KjVhy1JwW8cXK&5qi2_!cjxzB^A-Ut znYRHGaXT;9e&JEb0J)P{)LXHUoVuTN8$D08IVSH!co5Kb!N}d_?tI@J{&YEAA-R(JaJQ%~D>2f3u{=*fRznNqZCaD)Ga;f0=H4eH3f&gU~nM6N|m-k1J|g8R<)+b}Bno zKCdVU`DdM)U6FYt)5E2V;zjJ>`uLsT`gj#C?w!5- zygu22i}$Xprnl4*^O7o_|!E#MaJxRJaRb&KKWJghl500Q|IT z^6%b4Mzpjxa&k7?cR|b8T1K?A_VO-i8C%YXmezLOB`sqs8qw0)(YvH&Y*Bq$MmDu8 zP4B|GG9Gb7z$=`6jXJd0xlk9o`+4~E{0@I!AGe;j^p`IaR4I9CGbuO%OJMM4!W`fj*UV#II5$B*OBd6x^^ z&zOe$hMljs7?32DW8zL~YTI!5ZDV=+_vRVoIpCgl`M#H2BWh%wZvtXQ?BhL-h*MEE zyyPuLN0H-sp4KaMx+}_N%^0@fEUn2n zdiFzw3txLtY*k+KIrU@8%i%Ns?!{R#s!mIs&XwnQ*b$=6#sA4q>ghMa=iCafvm1B& z6s+U%yP>7>engG6w?@+IIrC|7hQDh#W6AK|M!lUb*DiBK>#ceU=iUhEs5?lzHk|BN z4|%RyuIctHEA@U81+Ax|-v0AYQ)Sbqrze@8j~?$>sxLAnll3`v&WOg=ahuKttPh{* zw?rSuC%l7=oA0Czcpkrde7Vc09TM+;tkE%ByW)c-U$0CjNY&q`u1?|sMU{$8*uC-H zSM)I06A(FYPr-b5P45EWsmto8qsRU#Gm0DQ8Z(ZrYBVPaa6gT1y5#M`$c3I*_pB>J z!J6nIr>jBH+x6g%a{sn&*oTRg=V=_BFZ5c2+#duqby?E?=aW}!AlsJNIp$~e^WKUX z@n)Qx5$oWub>orVz)A-topQ{E_hzso$j;%Lpkq6C^gdMHFqb!jg0059hiBDf?T&Na zCU3!6gJV92%BiEt_Ua6Flf=!SoHug&#!vT;S)ZHE&7bx4gk@4GyhP zyj49jre`Fqp1Q zIP3YKH8Y!IbpNF}x5RTC^HS}B9wd4uU#_wmTcLZLSqbW#&<-Sn6;js#`o-pCOw6TL zEqfSvhW^#tfmvr$*x~urPBQ{Vtw^rL^Wg>X)N12eJRhyZ!&-ywaC4P?>PT86OTMVg z+LIW@ZjYW?iJjH+OzESrHCC+cR@R$m4^!V)t;eG`-K!>nkD|-1uBm!MTkg>1ihU!z zFKg49*|b=49ruc{#BvzcrCTl36LUX)S6|Cz@X;Z09DneVu5$Ho(}TS0iYp(F$GBD^ z70=Lipi`~Xl`c2KKDPe+w6fq4h4-SfgJ*O_J&Ne-F#gQvR=whUc86yknI5J!60~*M zPgY!?g(m1s`Fw3&1DS}3_r%`{3Ez(Y$?g1>cUBZS)YX5jH`Ig&iwTBVyah9WvlHA!Vn7+}PQ$6!oX)VNj zSB+sFPcDxTy!nLJ*fa9`CL{PS4YQSWyB@GW%4dp|G|{jI^udO)^8<=wIImH3H{ zOV%?wyVuDRKk|9}WiNrdVxWe#i~AAqhq{YZG;N;~*)w*_YIQq2x}YhRt+|2f-t$vh z@5d>M_gBwfdk*H_2nXwvGW805`%K)OX!zNe=KYEa&-J#x%@B3zETg;^{z`j5$}!hN zs@-j-tnFIcox1E;GsN0;*n_v^URE~*L-RZg{n0HVJ)Opzv4?gLRf;<5c+xv%TE6Rv zx=0@e(JL|g2o|11H!{wtSlCu=DJ*W`%tk*JQT41%)KEL zr$3xm4yCOg%h^smvSqU&Ra~?zULFfRtAW=zh#*P1& z=i8b=-ZnAL*{)8Jk?wNQ`a7-{%%S#atPt1HDeBNzw2GbaKD|@}sG?{U)ZNdH8n#ir z#IdBl4}a|(s5ABHMslp+ROj;smv!7G9-so-(}pF?5v@xt6I|EDvNPw(-X~}J#jc)m z7}v>qR@}njjr3_J{N@h$-C=#$z~Z-y!}_Fw#c!KoReseNm+0a2Y=&54M!){1jzm7r zK>fW|fZjKZ)M)ltsJJT+I-ESU?n`(YwLsMlSy`PY>4XcX*NAbbU+cuF$LI`?rPo4l za|BVBkn;we*OUJGc4qKwhj%q7MZ%dLP5_oZtUws`SHiTpKR zDiQ9_Ne!J#P}Ny=@dz`gW3Ek>;I}%n*X`3|-h<>8CVKy=x}xb>x4} zJDkz)?l$L)r>igf@ogPh^(JRgKlLsZ=XcP8T1(2Fb+10?aMd;VQKi<(O}yoVE$52h zaZ1Y&E43emogD{HoECiOj*hH^K)QFe_~499!X?7aIXIc$M7j)>l;va@qQ=iI31r&hu{d>WN4y0E-| zzvR_%XrRySeiG4={1JM^>ZN-Z$o?gds#T8L@&5^9GlmZv3?Kds7(Qq)d@#e%+Qmg? zkh&{v?P=uYv7`nI%SrH`ldCPSZ58XZwo2OCc66>8*cy8@bY=WH{+c&vQkAc?iT=r+ zWh6XdK#%HY_<`0JT%Wvp)x0&jN8I`_-fWRzV&K{zvHefv<<(- zo+M|8xvQ43J~O_o-t14>0|gHQn(h?Q|B4Fng+Mo58C76CV8y?oH;Emb#CqIMqjTc! zQsE|PX#U6Oy7J8N&$cw*jh}xTe|R!i$y|F_iQqa>m;B8VmSP3tBD!(4 zx}`$=7oYvKrI2f3OUc0`vs*!PdW{OF#wo17$lzJ5#OPnHoJ%Y%%^6pit~R>Z#xHKV zW_Kq$wz$&-eMM?>8o6zTOp^+#z3m)d(&y@)>UciE`*`nnA+_YmQD7nlP#i`E;oEl5 zisgw}-C~Vy0mtJUBbwqHk^iXUHqT~1-uw6+VFu1_nDKe3p-=ayC9 zBSYk(j#MnmeKFkDnDwCd11E1H0ycGww)%kVh;YEGbyzVs)e38{I4TcB7aX^$62q}t z(vd;`n0w{bhsr!vyQLS7J700Ga|(PjXR^)?br_kGo9J&=5w=)=S1Js%aDfdW zpPvTzc;_+yI_LAf_Uq?NpVRfgM^_d4nOM<+?enYq-(#Jiw@SNa__zo0^Szj!@S@R+G@ue+~-9l;8~y0v=XI6}d_@<-C?gZXU(X@F1+^ z&%#UO2@I+XWa{+