diff --git a/scripts/vscripts/anv_functions.nut b/scripts/vscripts/anv_functions.nut index 06ac1b2b..1240f9a7 100644 --- a/scripts/vscripts/anv_functions.nut +++ b/scripts/vscripts/anv_functions.nut @@ -993,6 +993,12 @@ function find_ladder( strDesiredVSSM, flRadius = 1.4 ) while( ( hndLadder = Entities.FindByClassname( hndLadder, "func_simpleladder" ) ) != null ) { + // TODO: Replace with GetCenter(). The vecMaxs/vecMins approach + // replaced the "VSSM", and now the replacement is obsolete since + // this has been added to get "true origins". Low-priority, isn't + // going to noticeably boost efficiency and I fear rare edge cases + // of broken ladders if before/after spawn counts aren't verified. + // Instead of using NetProp "m_vecSpecifiedSurroundingMaxs" which requires a // dynamic delay and reveals the exact center origin of the ladder, derive it // directly from its vecMins/vecMaxs so that it can be spawned instantly! @@ -1430,7 +1436,7 @@ function patch_spawninfront( strOrigin, strMins, strMaxs ) { OnStartTouch = { - cmd1 = "!selfRunScriptCodeg_MapScript.LocalScript.DirectorOptions.PreferredMobDirection = -101" + cmd1 = "!selfRunScriptCodeg_MapScript.LocalScript.DirectorOptions.PreferredMobDirection <- -101" } } } ); diff --git a/scripts/vscripts/anv_mapfixes.nut b/scripts/vscripts/anv_mapfixes.nut index 288c03e0..613587d2 100644 --- a/scripts/vscripts/anv_mapfixes.nut +++ b/scripts/vscripts/anv_mapfixes.nut @@ -92,7 +92,7 @@ __CollectEventCallbacks( this, "OnGameEvent_", "GameEventCallbacks", RegisterScr // is true. Includes new Infected ladders and any supporting props i.e. pipes. // Exclude VS Survival (mutation15) from only overtly obvious new props. - if ( HasPlayerControlledZombies() == true ) + if ( HasPlayerControlledZombies() ) { EntFire( "worldspawn", "RunScriptFile", "anv_versus" ); @@ -277,6 +277,8 @@ make_clip( "_cliprework_skylighta", "Survivors", 1, "-192 -193 -23", "192 191 57 make_clip( "_cliprework_skylightb", "Survivors", 1, "-541 -189 -1", "547 195 32", "4173 -2627 793" ); make_clip( "_cliprework_skylightc", "Survivors", 1, "-194 -544 -1", "190 544 32", "2274 -672 793" ); make_clip( "_cliprework_skylightd", "Survivors", 1, "-1017 -167 0", "1018 149 32", "1465 -3418 794", "0 45 0" ); +make_clip( "_permstuck_colddrinks", "Everyone", 1, "-1 -1 -1", "1 1 1", "736 -548 363" ); +make_trigduck( "_duckqol_shopliftscanners", "-2 -88 0", "2 64 77", "5247 -2685 280" ); con_comment( "FIX:\tMoved an exposed stairwell hurt trigger down inside a vending machine." ); @@ -348,6 +350,13 @@ make_clip( "_booster_hardhatsb", "Survivors", 1, "-42 -14 0", "42 14 512", "-337 make_clip( "_booster_highbalcony", "Survivors", 1, "-260 -162 0", "260 162 520", "-4695 -4336 792" ); make_clip( "_booster_glassbalcony", "Survivors", 1, "-128 -82 0", "128 0 1", "-3688 -4334 791" ); make_clip( "_nav_ladyshoes", "Survivors", 1, "-103 -3 0", "70 3 56", "-4971 -4461 432" ); +make_clip( "_collision_atrium", "All and Physics", 1, "-2400 -3200 -2", "2400 3200 0", "-4452 -3208 0" ); +make_clip( "_kiosk_qol_1", "Everyone", 1, "-44 -44 -1", "44 44 0", "-3208 -3864 94" ); +make_clip( "_kiosk_qol_2a", "Everyone", 1, "-44 -44 -1", "44 44 0", "-4080 -4005 94" ); +make_clip( "_kiosk_qol_2b", "Everyone", 1, "-100 -1 -1", "100 1 0", "-4081 -3949 94" ); +make_clip( "_kiosk_qol_3a", "Everyone", 1, "-44 -44 -1", "44 44 0", "-4848 -3935 94" ); +make_clip( "_kiosk_qol_3b", "Everyone", 1, "-1 -100 -1", "1 100 0", "-4796 -3936 94" ); +make_trigduck( "_duckqol_informationbooth", "-96 -8 0", "96 8 64", "-4448 -3865 44" ); if ( g_BaseMode == "coop" || g_BaseMode == "realism" ) { @@ -824,8 +833,8 @@ make_clip( "_backstairs_right", "Survivors", 1, "-8 -158 0", "8 197 760", "-951 // FIXES -make_prop( "dynamic", "_helistuck_caseunique", "models/props_fairgrounds/bass_case.mdl", "-3466 2899 -106", "-15 1 89.73", "shadow_no" ); -make_prop( "dynamic", "_helistuck_casecaster", "models/props_fairgrounds/anvil_case_casters_64.mdl", "-3488 2870 -128", "0 180 0", "shadow_no" ); +make_prop( "dynamic", "_helistuck_caseunique", "models/props_fairgrounds/bass_case.mdl", "-3466 2899 -106", "-15 1 89.73", "shadow_yes" ); +make_prop( "dynamic", "_helistuck_casecaster", "models/props_fairgrounds/anvil_case_casters_64.mdl", "-3488 2870 -128", "0 180 0", "shadow_yes" ); break; } @@ -835,8 +844,8 @@ make_prop( "dynamic", "_helistuck_casecaster", "models/props_fairgrounds/anvil_c // FIXES -make_prop( "dynamic", "_helistuck_caseunique", "models/props_fairgrounds/bass_case.mdl", "-3466 2899 -106", "-15 1 89.73", "shadow_no" ); -make_prop( "dynamic", "_helistuck_casecaster", "models/props_fairgrounds/anvil_case_casters_64.mdl", "-3488 2870 -128", "0 180 0", "shadow_no" ); +make_prop( "dynamic", "_helistuck_caseunique", "models/props_fairgrounds/bass_case.mdl", "-3466 2899 -106", "-15 1 89.73", "shadow_yes" ); +make_prop( "dynamic", "_helistuck_casecaster", "models/props_fairgrounds/anvil_case_casters_64.mdl", "-3488 2870 -128", "0 180 0", "shadow_yes" ); break; } @@ -895,8 +904,27 @@ make_clip( "_fallenlog_shrub_infected", "SI Players and AI", 1, "-182 -383 -99", make_clip( "_chargerassist_commonhop1", "Survivors", 1, "-155 -16 0", "117 5 864", "-7093 6280 160" ); make_clip( "_chargerassist_commonhop2", "Survivors", 1, "-49 -170 0", "63 134 864", "-7093 6452 160", "0 -3 0" ); make_clip( "_booster_powerpole", "Survivors", 1, "-9 -8 0", "9 10 582", "-7630 6718 444" ); +patch_ladder( "-6084.5 6272 90", "6 0 0" ); -make_prop( "dynamic", "_keepcalmgator", "models/props_fairgrounds/alligator.mdl", "-5274 7386 -19", "0 150 0", "shadow_no", "solid_no" ); +// Tsuey's note: Special thanks to the person who originally complained +// on the Steam Forums that there weren't any gators -- I'm unable to +// re-find your thread. Special thanks to Rise for naming him Fred; we +// can't spell Friend without it. Left4Facts Discord btw. :fred: + +make_prop( "dynamic", "_fred", "models/props_fairgrounds/alligator.mdl", "-5274 7386 -19", "0 150 0", "shadow_no", "solid_no" ); + +// Allow only SI Players to stand on it while maintaining its non-solidity +// because it'd be inhumane for Survivors to put bullet holes on him. Also +// prevents Fred from becoming a godspot. + +make_clip( "_fred_collision", "SI Players", 1, "-3.6 -17 0", "3.6 16 3", "-5274 7386 -17", "0 150 0" ); + +// Incrementally "bites" both Spawned and Ghost SI. Doesn't damage Survivors +// but it's difficult to even reach it without hanging and we dare not move +// him. Does 120 DPS, 60 per hit, or something. It's a trigger_hurt_ghost. + +make_trighurt( "_fred_pain_cuddles", "Ghost", "-4 -4 -4", "4 4 4", "-5280 7375 -12" ); +EntFire( g_UpdateName + "_fred_pain_cuddles", "SetDamage", 120 ); if ( g_BaseMode == "coop" || g_BaseMode == "realism" ) { @@ -1166,7 +1194,7 @@ make_clip( "_commonhop_safehouse", "Survivors", 1, "-280 -456 0", "280 456 110 make_clip( "_booster_burgertankpole", "Survivors", 1, "-12 -12 -170", "12 12 1000", "-5800 7496 603" ); make_clip( "_booster_burgertankspin", "Survivors", 1, "-216 -216 -170", "216 216 640", "-5800 7496 915" ); make_clip( "_booster_ginnytop", "Survivors", 1, "-22 -29 0", "17 29 1150", "-5425 6789 385", "0 45 0" ); -make_clip( "_booster_ginnyjon", "Survivors", 1, "6 -4 -284", "-10 4 0", "-5425 6789 385", "0 45 0" ); +make_clip( "_booster_ginnyjon", "Survivors", 1, "-6 -4 -284", "10 4 0", "-5425 6789 385", "0 45 0" ); make_clip( "_booster_gasextend", "Survivors", 1, "-41 -196 0", "528 164 1250", "-4624 7952 284" ); make_clip( "_booster_blueframe", "Survivors", 1, "-17 -70 0", "17 76 1100", "-4641 7618 479", "0 -7 0" ); make_clip( "_booster_roofwedge", "Survivors", 1, "-17 -24 0", "47 64 1200", "-5711 6528 416" ); @@ -1180,6 +1208,19 @@ make_trigduck( "_duckqol_greenposts1", "-60 -97 0", "60 97 142", "-2021 5568 98" make_trigduck( "_duckqol_greenposts2", "-60 -97 0", "60 97 142", "1069 6976 224" ); make_trigduck( "_duckqol_playground", "-156 -1 0", "156 1 77", "-1442 6968 119" ); +// Prevent Survivor bots from picking up items inside c4m4's saferoom. + +local item = null; + +while ( item = Entities.FindInSphere( item, Vector( -3140, 7815, 175 ), 80 ) ) +{ + if ( item.IsValid() ) + { + if ( item.GetClassname().find("weapon_") != null ) + NetProps.SetPropInt( item, "m_fEffects", 32 ); + } +} + if ( g_BaseMode == "coop" || g_BaseMode == "realism" ) { devchap( "BASE COOP" ); @@ -1495,7 +1536,7 @@ make_clip( "_booster_burgertankpole", "Survivors", 1, "-12 -12 -170", "12 12 10 make_clip( "_booster_burgertankspin", "Survivors", 1, "-216 -216 -170", "216 216 640", "-5800 7496 915" ); make_clip( "_permstuck_highuptree", "Everyone", 1, "-32 -54 0", "24 24 10", "-3312 7326 315" ); make_clip( "_booster_ginnytop", "Survivors", 1, "-22 -29 0", "17 29 1150", "-5425 6789 385", "0 45 0" ); -make_clip( "_booster_ginnyjon", "Survivors", 1, "6 -4 -284", "-10 4 0", "-5425 6789 385", "0 45 0" ); +make_clip( "_booster_ginnyjon", "Survivors", 1, "-6 -4 -284", "10 4 0", "-5425 6789 385", "0 45 0" ); make_clip( "_booster_gasextend", "Survivors", 1, "-41 -196 0", "528 164 1250", "-4624 7952 284" ); make_clip( "_booster_blueframe", "Survivors", 1, "-17 -70 0", "17 76 1100", "-4641 7618 479", "0 -7 0" ); make_clip( "_booster_roofwedge", "Survivors", 1, "-17 -24 0", "47 64 1200", "-5711 6528 416" ); @@ -1575,7 +1616,7 @@ make_clip( "_vuln_balconyb", "Survivors", 1, "-48 -256 -253", "48 256 253", "- make_clip( "_vuln_balconyc", "Survivors", 1, "0 0 0", "65 256 150", "-737 -2048 -208" ); make_clip( "_vuln_balconyd", "Survivors", 1, "-518 -64 0", "0 0 320", "-687 -2304 -176" ); //make_clip( "_phonebooth_hopandnav", "Survivors", 1, "-37 -14 -153", "37 14 555", "-1731 -2370 -224" ); -make_clip( "_skybox_shielda", "SI Players", 1, "-176 -5.5 22", "-175 6.5 94", "-272 -2055 50" ); +make_clip( "_skybox_shielda", "SI Players", 1, "-64 -6 0", "64 6 20", "-384 -2054 124" ); make_clip( "_skybox_shieldd", "SI Players", 1, "-21 -252.5 -147", "21 252.5 147", "-3948 257 130" ); make_clip( "_skybox_shieldb", "SI Players", 1, "-277 -115 -138", "283 115 100", "-1543.5 -1855.5 249.6" ); make_clip( "_skybox_shieldc", "SI Players", 1, "-145 -212 -19", "165 212 77", "-2971 -1264 125" ); @@ -1682,7 +1723,7 @@ make_clip( "_cliprework_missingno", "Survivors", 1, "-164 -272 0", "172 240 1626 // FIXES make_clip( "_nav_eventsign", "Survivors", 1, "-4 -10 -908", "4 10 908", "-8552 -6310 756" ); -patch_ladder( "-9260 -5130 -152", "0 14 0" ); +patch_ladder( "-9260 -5130 -152", "1 14 0" ); break; } @@ -1802,7 +1843,7 @@ make_clip( "_booster_float", "Survivors", 1, "-430 -320 0", "999 280 777", "- make_clip( "_clipextend_afterfloata", "Survivors", 1, "-120 -354 -36", "160 350 845", "-2592 665 312.5" ); make_clip( "_clipextend_garage", "Survivors", 1, "-320 -8 0", "320 8 732", "-1264 2992 420" ); make_clip( "_clipextend_1ststreet", "Survivors", 1, "-8 -296 0", "272 42 600", "-368 2887 576" ); -make_clip( "_commonhop_electricalbox", "Survivors", 1, "8 -64 0", "8 64 752", "-80 1535 400" ); +make_clip( "_commonhop_electricalbox", "Survivors", 1, "-8 -64 0", "8 64 752", "-80 1535 400" ); make_clip( "_clipextend_afterfloatb", "Survivors", 1, "-4 -94 0", "4 94 128", "-2700 222 432" ); make_clip( "_clipextend_2ndstreeta", "Survivors", 1, "-8 -246 0", "95 216 768", "-2848 -840 384" ); make_clip( "_vuln_balconyg", "Survivors", 1, "-525 -48 0", "525 54 737", "-2440 -1040 416" ); @@ -2560,7 +2601,7 @@ make_clip( "_cliprework_subwayupper", "Survivors", 1, "-201 -94 0", "215 90 4322 make_clip( "_cliprework_subwayledge", "Survivors", 1, "-218 -18 132", "233 3 4322", "3014 4017 156" ); make_clip( "_cliprework_subwayfence", "Survivors", 1, "-5 -143 0", "4 149 3926", "3268 4141 552", "0 -8 0" ); make_clip( "_subwins_smoother", "Everyone", 1, "-120 -9 0", "120 9 3", "2968 4103 48" ); -make_trighurt( "_instakill_griefroom", "Survivor", "-512 -1080 0", "384 1080 125", "1152 936 8" ); +make_trighurt( "_instakill_griefroom", "Survivor", "-512 -1080 0", "384 1080 17", "1152 936 202" ); con_comment( "FIX:\tFans will now rotate. Server-side entities used to have Client-side Animation spawnflag." ); @@ -2988,6 +3029,7 @@ make_clip( "_booster_enginecar", "Survivors", 1, "-180 -88 -180", "114 94 463", make_clip( "_booster_telepole1", "Survivors", 1, "-8 -8 -80", "8 8 234", "-1111 -6480 694" ); make_clip( "_booster_telepole2", "Survivors", 1, "-8 -8 -80", "8 8 464", "50 -5432 464" ); make_clip( "_clipgap_survivoronly", "Survivors", 1, "-100 -24 -80", "108 40 1072", "1428 -4936 -144" ); +make_clip( "_permstuck_boxwreck_weird", "Everyone", 1, "-1 -1 0", "1 1 1", "-2836.7 -7030 128" ); con_comment( "LOGIC:\tBile anti-skip made 2 breakwalls indestructible until howitzer fires." ); @@ -3069,6 +3111,7 @@ make_clip( "_booster_ventpipe", "Survivors", 1, "-13 -14 -80", "17 14 657", "753 make_clip( "_nav_jump_semitrailer", "Survivors", 1, "-4 -94 0", "4 188 288", "5756 1062 -32" ); make_clip( "_nav_jump_cargowindow", "Survivors", 1, "-5 -85 0", "4 89 86", "2044 3030 49" ); make_clip( "_booster_armoredtop", "Survivors", 1, "-158 -65 0", "172 59 63", "7838 6366 449" ); +make_clip( "_collisionqol_finalebuses", "All and Physics", 1, "-236 -32 0", "236 32 108", "6675 6470 65" ); make_trigmove( "_duckqol_finalevent", "Duck", "0 -32 0", "8 32 1", "7568 7392 447" ); con_comment( "LOGIC:\tFinale switch will re-Lock when all Survivors aren't inside trigger." ); @@ -3782,6 +3825,7 @@ make_clip( "_booster_pipeb", "Survivors", 1, "-12 -7 -32", "24 29 216", "302 make_clip( "_chairbodypile_smoother", "Everyone", 1, "-50 -25 0", "25 40 8", "500 5301 295", "10 0 -15" ); make_clip( "_hallwayguard_right", "Everyone", 1, "-14 15 0", "9 16 128", "693 5566.3 296", "0 45 0" ); make_clip( "_hallwayguard_left", "Everyone", 1, "-9 16 0", "14 15 128", "667.5 5679.3 296", "0 -45 0" ); +make_clip( "_permstuck_endrubble", "SI Players and AI", 1, "-34 -17 0", "17 17 64", "2742 989 152" ); make_prop( "dynamic", "_cosmetic_wallpaper", "models/props_unique/zombiebreakwallexteriorairport01_main.mdl", "2507.95 3263.99 216", "0 180 0", "shadow_no" ); make_prop( "dynamic", "_cosmetic_wallblock", "models/props_unique/zombiebreakwallhospitalexterior01_main.mdl", "2507.99 3263.99 252", "0 180 0", "shadow_no" ); @@ -4342,6 +4386,7 @@ make_clip( "_permstuck_tree_h", "Everyone", 1, "-17 -17 -32", "17 17 0", "984 66 make_clip( "_permstuck_tree_i", "Everyone", 1, "-17 -17 -32", "17 17 0", "1151 6258 932" ); make_clip( "_permstuck_tree_j", "Everyone", 1, "-17 -17 -32", "17 17 0", "1153 5929 981" ); make_clip( "_stuckwarp_yellowbarrels", "Everyone", 1, "-108 -16 0", "59 13 128", "4861 2732 608", "0 -17 0" ); +make_clip( "_permstuck_taito_ftw", "Everyone", 1, "-8 -8 -8", "28 24 28", "2552 2292 460" ); patch_spawninfront( "78 8574 -405", "-70 -8 0", "70 8 256" ); if ( g_BaseMode == "coop" || g_BaseMode == "realism" ) @@ -4399,7 +4444,7 @@ make_clip( "_permstuck_treea", "Everyone", 1, "-18 -17 -446", "18 17 446", "- make_clip( "_permstuck_treeb", "Everyone", 1, "-30 -75 -476.5", "30 75 476.5", "-3343 -5975 854" ); make_clip( "_permstuck_treed", "Everyone", 1, "-22 -20.5 -91.5", "22 20.5 91.5", "-3310 -3600 405" ); make_clip( "_permstuck_treec", "Everyone", 1, "-30 -16 -110", "30 16 110", "-3305 -4815 442" ); -make_clip( "_permstuck_jaynjer", "Everyone", 1, "-42 -42 -32", "42 42 10", "-4495 -4584 719" ); +make_clip( "_permstuck_jaynjer", "Everyone", 1, "-42 -52 -32", "42 42 90", "-4495 -4584 719" ); make_clip( "_hangcancel_perimeter", "Survivors", 1, "-25 -44 0", "28 94 1484", "13 -3620 896", "0 -8 0" ); make_clip( "_sneaky_hunter", "SI Players", 1, "-19 -1242 0", "37 615 112", "5666 -5383 272" ); make_clip( "_permstuck_shrubtreea", "Everyone", 1, "-17 -17 -17", "17 17 17", "-5080 -5712 970" ); diff --git a/scripts/vscripts/anv_standards.nut b/scripts/vscripts/anv_standards.nut index a54cd87e..f9757649 100644 --- a/scripts/vscripts/anv_standards.nut +++ b/scripts/vscripts/anv_standards.nut @@ -1,5 +1,8 @@ // TUTORIAL_STANDARDS_VS +// NOTE: See "mapspawn.nut" for links to more information, such as the +// development team's Github, Steam Workshop, guides, etc. + // Every map has been modified with care. Tutorial Standards VS offers a brief // opportunity to explain the standards applied to every map to improve Versus. // When this map is loaded, use "ShowUpdate()" to visualize these changes. diff --git a/scripts/vscripts/anv_versus.nut b/scripts/vscripts/anv_versus.nut index cb4dbde3..2d692cb0 100644 --- a/scripts/vscripts/anv_versus.nut +++ b/scripts/vscripts/anv_versus.nut @@ -42,7 +42,7 @@ switch( g_MapName ) con_comment( "LOGIC:\tAnti-doorbreak trighurt will be deleted 4 seconds after elevator starts." ); -make_trighurt( "_elevator_exploit_bean", "Ghost", "-55 -2 0", "55 2 111", "2169 5713 2352" ); +make_trighurt( "_elevator_exploit_bean", "Ghost", "-55 -2 0", "55 2 111", "2169 5713 2344" ); EntFire( "elevator_button", "AddOutput", "OnPressed anv_mapfixes_elevator_exploit_bean:Kill::4:-1" ); con_comment( "QOL:\tThe 2nd fire door is open immediately for Versus-only QoL." ); @@ -284,6 +284,7 @@ make_ladder( "_ladder_columnfallbanner_cloned_columnbusystairs", "-4948 -4181 31 kill_entity( Entities.FindByClassnameNearest( "env_player_blocker", Vector( 1388, 5660, -649 ), 1 ) ); kill_entity( Entities.FindByClassnameNearest( "env_player_blocker", Vector( 2972, 3724, -649 ), 1 ) ); +make_navblock( "_nav_motelfencejump", "Survivors", "Apply", "-24 -108 -24", "24 24 24", "2105 3700 -820" ); make_brush( "_losfix_bush", "-10 -190 -60", "10 200 35", "8224 8378 -536" ); make_brush( "_losfix_end_fence", "-254 -1 -5", "254 0 5", "-522 -2416 -1083" ); make_brush( "_losfix_highway_bus1", "-40 -1 -10", "100 1 14", "7035 7874 -641" ); @@ -552,6 +553,7 @@ make_clip( "_ladder_askewhedgeshared_clip", "SI Players and AI", 1, "-3 -279 -7" make_clip( "_ladder_barnoverhang_clip", "Survivors", 1, "-24 -4 -10", "24 4 188", "-731 56 -86" ); make_clip( "_ladder_barnsarearight_clip", "Everyone", 1, "1 -232 0", "2 16 85", "263 2288 -192" ); make_clip( "_ladder_startroof_clip", "Everyone", 1, "-16 -17 -5", "16 20 175", "3362.5 3216 -187" ); +make_clip( "_ladder_startfoodcart_clip", "Everyone", 1, "-2 -8 0", "2 8 124", "2450 3348 -192", "0 -45 0" ); make_ladder( "_ladder_askewhedgebotr1_cloned_askewhedgebotl", "610 1209.88 -123.984", "0 26 0" ); make_ladder( "_ladder_askewhedgebotr2_cloned_askewhedgebotl", "610 1209.88 -123.984", "0 52 0" ); make_ladder( "_ladder_askewhedgetopl1_cloned_askewhedgetopr", "594 1262 -24", "0 -26 0" ); @@ -574,7 +576,7 @@ make_ladder( "_ladder_lightticketsbackT_cloned_lightapplesback", "-208 856 -120" make_ladder( "_ladder_lightticketsfrontB_cloned_lightapplesback", "-208 856 -120", "-1307 1127 0", "0 90 0", "0 1 0" ); make_ladder( "_ladder_lightticketsfrontT_cloned_lightapplesback", "-208 856 -120", "-1307 1127 128", "0 90 0", "0 1 0" ); make_ladder( "_ladder_redtentmid_cloned_redtentstart", "2848 2074 -140", "-3787.5 -1225.5 1" ); -make_ladder( "_ladder_startfoodcart_cloned_colddrinkfence", "1710 2272 -124", "741 1088 -13" ); +make_ladder( "_ladder_startfoodcart_cloned_bumpsidemid", "1462 2296 -124", "992 1073 -13" ); make_ladder( "_ladder_starthedge_cloned_startfence", "2384 2462 -124", "-295 84 -7" ); make_ladder( "_ladder_startroof_cloned_elecbox", "1907 894 -64", "1455.5 2307 -68" ); make_prop( "dynamic", "_barn_overhang_floor", "models/props_update/c2m4_barn_overhang.mdl", "-608 162 28", "0 90 0", "shadow_no" ); @@ -649,7 +651,7 @@ make_ladder( "_ladder_fireworksR_cloned_scaffoldsinglefork", "-2980 3298 -152", make_ladder( "_ladder_leftchopperwindowl_cloned_leftchopperwindowr", "-763.5005 2285.4995 240", "263 263 0" ); make_ladder( "_ladder_startfenceback_cloned_fencecoverfront", "-3444 3528 -188", "3838 2073 5", "0 43.5 0", "0.7 0.7 0" ); make_ladder( "_ladder_startfencefront_cloned_fencecoverback", "-3468 3592 -188", "3857 2072 5", "0 43.5 0", "-0.7 -0.7 0" ); -make_prop( "dynamic", "_missing_staircase", "models/props_interiors/stair_metal_02.mdl", "-840 1792 136", "0 315 0", "shadow_no" ); +make_prop( "dynamic", "_missing_staircase", "models/props_interiors/stair_metal_02.mdl", "-840 1792 136", "0 315 0", "shadow_yes" ); make_prop( "dynamic", "_yesdraw_infecteddoorway", "models/props_update/c2m5_infectedroom_doorway.mdl", "-3200 3972 0", "0 90 0", "shadow_yes" ); make_prop( "dynamic", "_yesdraw_infectedroom", "models/props_update/c2m5_infectedroom.mdl", "-3200 3727 0", "0 -90 0", "shadow_yes" ); make_prop( "physics", "_hittable_dumpleft", "models/props_junk/dumpster_2.mdl", "-1551 3682 -255", "0 270 0" ); @@ -1205,8 +1207,9 @@ make_prop( "dynamic", "_solidify_flatawningend1", "models/props_street/awning_sh make_prop( "dynamic", "_solidify_flatawningend2", "models/props_street/awning_short.mdl", "-8537 -8320 -108.921", "0 0 0", "shadow_no" ); make_prop( "dynamic", "_solidify_flatawningmid", "models/props_street/awning_short.mdl", "-9216 -3712 -78.4492", "0 270 0", "shadow_no" ); make_prop( "dynamic", "_yesdraw_billboard_nodraw", "models/props_update/c5m2_billboard_nodraw.mdl", "-9152 -6938 92", "0 -90 0", "shadow_no", "solid_no" ); -make_prop( "physics", "_hittable_dumpster", "models/props_junk/dumpster_2.mdl", "-8095 -600 -246", "0 0 0", "shadow_no" ); -patch_ladder( "-9260 -5130 -152", "0 14 0" ); +make_prop( "dynamic", "_solidify_chimney007", "models/props_urban/chimney007.mdl", "-9076 -4300 150.405", "0 180 0", "shadow_no" ); +make_prop( "physics", "_hittable_dumpster", "models/props_junk/dumpster_2.mdl", "-8095 -600 -246", "0 0 0", "shadow_no" ); +patch_ladder( "-9260 -5130 -152", "1 14 0" ); break; } @@ -1623,6 +1626,7 @@ make_clip( "_yesdraw_dairy_clipb", "SI Players", 1, "-17 -142 0", "17 142 3952", make_clip( "_yesdraw_farcorner_clip", "SI Players", 1, "-216 -215 -256", "168 233 3952", "216 5303 528" ); make_clip( "_yesdraw_start_clipa", "SI Players", 1, "-300 -447 0", "0 449 1120", "3052 959 800" ); make_clip( "_yesdraw_start_clipb", "SI Players", 1, "-158 -10 -580", "42 312 549", "2710 508 1370" ); +make_clip( "_ladder_crushedescape_clip", "Survivors", 1, "-20 -3 0", "20 3 1745", "2478 769 173" ); make_ladder( "_ladder_alleywindow_cloned_tankerwindow", "1720 3959.5 120", "820 -1590 0" ); make_ladder( "_ladder_commvignette_cloned_trashorange", "2428 3204.5 255.9905", "-1800 97 -144" ); make_ladder( "_ladder_crushedescape_cloned_tankerwindow", "1720 3959.5 120", "4198 4729 -51", "0 180 0", "0 1 0" ); @@ -2760,7 +2764,7 @@ patch_ladder( "-4322 -8715 32", "71 0 21" ); patch_ladder( "-5991 -8719 32", "247 0 21" ); make_prop( "dynamic", "_easter_dorykcir", "models/weapons/melee/w_crowbar.mdl", "-8690 -7340 201", "0 -45 90", "shadow_no" ); -make_prop( "dynamic_ovr", "_easter_yofffej", "models/props_junk/gnome.mdl", "-8695 -7340 211", "0 45 0", "shadow_no" ); +make_prop( "dynamic_ovr", "_easter_yofffej", "models/props_junk/gnome.mdl", "-8695.10 -7340.17 210.7719", "0 45 0", "shadow_no" ); EntFire( g_UpdateName + "_easter_dorykcir", "skin", "1" ); con_comment( "QOL:\tDeleted blockers to allow ghost infected to pass through the event door for Versus-only QoL." ); @@ -2889,6 +2893,7 @@ make_prop( "dynamic", "_ladder_atlanticroofleft_pipe", "models/props_rooftop/Gut make_prop( "dynamic", "_ladder_finalrooftop_pipe", "models/props_mill/PipeSet08d_256_001a.mdl", "10842 -4603 84", "90 90 0", "shadow_no" ); make_prop( "dynamic", "_solidify_finalchimney1", "models/props/cs_militia/fireplacechimney01.mdl", "11020 -4586 329", "0 135 0", "shadow_no" ); make_prop( "dynamic", "_solidify_finalchimney2", "models/props/cs_militia/fireplacechimney01.mdl", "11020 -4073 329", "0 135 0", "shadow_no" ); +patch_ladder( "11314.7 -4535 -259.108", "0 -22 9" ); break; } @@ -3121,6 +3126,8 @@ patch_ladder( "195 4845.5 -18.624", "-17 0 0" ); { // ENTITIES FOR HUMAN-CONTROLLED SI MODES ONLY +make_clip( "_dispcrouch_cliffside", "SI Players", 1, "-120 -8 -80", "120 8 80", "127 -818 428", "0 8 -10" ); + break; } diff --git a/scripts/vscripts/mapspawn.nut b/scripts/vscripts/mapspawn.nut index e3e1d96b..11f4966b 100644 --- a/scripts/vscripts/mapspawn.nut +++ b/scripts/vscripts/mapspawn.nut @@ -20,6 +20,12 @@ printl( "VSCRIPT: Running mapspawn.nut" ); ** Community Servers/Groups -> Dev Thread: Map fixes for Valve ** https://steamcommunity.com/app/550/discussions/1/1651043320659915818/ ** +** Help us shape the potential future of L4D2 vanilla. +** https://github.com/Tsuey/L4D2-Community-Update +** +** Community Update Testing Initiative (Workshop mirror) +** https://steamcommunity.com/sharedfiles/filedetails/?id=1959405608 +** ** This work is dedicated to two lost brothers and all those tragically lost ** in these horrific times of COVID-19. Somehow we'll survive together. *****************************************************************************/ diff --git a/scripts/vscripts/z_developer_showupdate.nut b/scripts/vscripts/z_developer_showupdate.nut index 7f4f6141..f95b8144 100644 --- a/scripts/vscripts/z_developer_showupdate.nut +++ b/scripts/vscripts/z_developer_showupdate.nut @@ -42,6 +42,50 @@ ** before then will be missed -- but not if it's manual! *****************************************************************************/ +/* New changes/additions: +** - TODO: +** -> Update above comment block with any changes, update tutorial messages +** -> Add more filter options for props +** -> Optional range cut off for rendering debug draw boxes and text +** -> Check if prop is glowing/not glowing in prop redraw loop to prevent unneccessary EntFire calls +** -> Highlight/glow additional entities in some way - Might be possible to fire a glow input on them +** -> func_clip_vphysics +** -> func_playerinfected_clip, func_playerghostinfected_clip +** -> Optimize fire time for DebugRedraw() +** - DONE: +** - Various performance improvements +** -> Reduced repeated function calls +** -> Optimized order of execution and removed some statements from loops that only needed to be called or checked once +** -> g_arrayFixHandles is now dynamically resized and cleared when not in use, which also fixes script from failing if >200 entities are indexed +** -> Used switch cases in place of many if else statements +** - Fixed some issues with glows not being removed from props consistently +** - Added optional arguments for ShowUpdate() to change which entities are highlighted, text arguments must be enclosed in "quotes", invalid or blank argument will call ShowUpdate() +** -> ShowUpdate() - Only highlights entities prefixed with "anv_mapfixes" and commentary blockers, unchanged +** -> ShowUpdate("all") - Highlights all valid entities regardless of targetname - ShowUpdateAll() can be used instead +** -> ShowUpdate("other") - Highlights all entities without the "anv_mapfixes" prefix - ShowUpdateOther can be used instead +** - Added SetFilter function, usage: function SetFilter( entityGroup, value ), text arguments must be enclosed in "quotes", invalid or blank arguments will result in default values +** -> Allows user to filter out different groups of entities, allowing us to massively extend the functionality of ShowUpdate() to see (almost) exactly the entities we want at any time +** -> Full description of filters is found just above the function +** - Created new function for drawing text on highlighted entities +** -> Index of the entity is show at the end of the string, indicating the order it was added and acting as a unique ID +** -> Now labels non-anv_mapfixes clips +** - Fixed text on rotated ladders being displaced from the actual model, leaving them unlabelled +* - Fixed ladder clone source text being duplicated for each ladder that clones from it, now it only draws the text once per ladder source +** - When the appropriate settings to highlight them are on, ladders that have been moved (or added with no targetname) are highlighted in purple +** -> Ladders that are not new and haven't been moved are highlighted in light orange +** - Added trigger_teleport to potential triggers to highlight +** - Allowed commentary blockers, lump blockers, and any blockers added by mods etc to be highlighted with the full functionality that anv_mapfixes blockers are given +** - Invalid or deleted entities are removed from the drawing index before attempting to draw them +** -> This removes the need to toggle ShowUpdate()/HideUpdate() when an entity is deleted +** - Adjusted func_brush color to help distinguish it from infected clips better +** - Text will stop being rendered if it is off-screen for 10 seconds +** - Made ShowUpdate() instantly call DebugRedraw(), instead of waiting 1 second for worldspawn to fire the script +** - ShowUpdate() now skips over all entity types that won't be highlighted +** - Number of entities indexed is printed to console +** - Changed some if statements to switch case for optimization +** - Defines entity highlight colors at initialization instead of calling them within draw loop +*/ + // Call to cease and desist DebugRedraw(). Technically fires "StopGlowing" to all blockers, // too, but only props will process that Input and it's more efficient than another loop. @@ -54,21 +98,81 @@ function HideUpdate() DebugDrawClear(); EntFire( "worldspawn", "RunScriptCode", "DebugDrawClear()", 0.1 ); EntFire( g_UpdateName + "*", "StopGlowing" ); + + // Disable glows on props highlighted by ShowUpdate without with g_UpdateName prefixed. + + if ( g_TutorialShown ) + { + + for ( local index = 0; + g_arrayFixHandles[index] != null && index <= g_arrayFixHandles.len(); + index++ ) + { + if ( ! g_arrayFixHandles[index].IsValid() ) + { + g_arrayFixHandles.remove( index ); // Entity is not valid, remove from array and skip. + printl( "Invalid entity '" + index + "' removed from drawing index." ); + break; + } + + EntFire( g_arrayFixHandles[index].GetName(), "StopGlowing" ); + } + + // Clean up global arrays. + + g_arrayFixHandles.clear(); + g_arrayLadderSources.clear(); + g_arrayFixHandles <- array( 1, null ); + g_arrayLadderSources <- array( 1, null); + } + } // Opacity override for DebugDrawBox's (default 37). g_BoxOpacity <- 37; +// Define "constants" for colors used with DebugDrawBox. +// Constants and enums cannot be vectors, so make do with variables. + +COLOR_CLIP_RED <- Vector( 255, 0, 0 ); +COLOR_CLIP_PINK <- Vector( 185, 0, 185 ); +COLOR_CLIP_GREEN <- Vector( 0, 255, 0 ); +COLOR_CLIP_BLUE <- Vector( 0, 0, 255 ); +COLOR_CLIP_LTBLUE <- Vector( 0, 128, 255 ); +COLOR_CLIP_BLACK <- Vector( 0, 0, 0 ); +COLOR_BRUSH_LTGREEN <- Vector( 108, 200, 64 ); +COLOR_NAV_ORANGE <- Vector( 255, 45, 0 ); +COLOR_TRIGGER_YELLOW <- Vector( 255, 255, 0 ); +COLOR_LADDER_WHITE <- Vector( 255, 255, 255 ); +COLOR_LADDER_PURPLE <- Vector( 134, 60, 218 ); +COLOR_LADDER_ORANGE <- Vector( 255, 128, 64 ); + // Only show CLIP (blocker) color coding tutorial once per load session. g_TutorialShown <- false; +// Wrapper functions for ShowUpdate to allow the arguments to be used with key binds. + +function ShowUpdateAll() +{ + ShowUpdate( "all" ) +} + +function ShowUpdateOther() +{ + ShowUpdate( "other" ) +} + // Call to create a logic_timer as 1/10th of a Think to start DebugRedraw(). This Timer // is named "anv_mapfixes_DebugRedraw_timer" and only exists if it's manually created. -function ShowUpdate() +function ShowUpdate( showGroup = "anv" ) { + + // Ignore case sensitivity for arguments. + showGroup = showGroup.tolower(); + // Print a quick tutorial to console for CLIP (blocker) color coding and binds. if ( ! g_TutorialShown ) @@ -106,24 +210,85 @@ function ShowUpdate() // The "find" returns the earliest character index where 0 means it's a match. // The Timer (and any "helper entities") have no reason to be in this array. - g_arrayFixHandles <- array( 200, null ); // We'll never need all 200 fix entities. + // Initialize global arrays. + + g_arrayFixHandles <- array( 1, null ); + g_arrayLadderSources <- array( 1, null); - local entity = Entities.First(); // Start looping from "worldspawn". + local entity = Entities.First(); // Start looping from "worldspawn". - local index = 0; // Increment not on loop but rather confirmed matches. + local index = 0; // Increment not on loop but rather confirmed matches. while( ( entity = Entities.Next( entity ) ) != null ) { - if ( entity.GetName().find( g_UpdateName ) == 0 - && entity.GetName() != "anv_mapfixes_DebugRedraw_timer" ) + + // Store entity properties. + + local strEntityName = entity.GetName(); + local strClassname = entity.GetClassname(); + + // Skip entities that we don't care about. + + switch ( strClassname ) + { + case "env_physics_blocker": + case "env_player_blocker": + case "func_brush": + case "func_nav_blocker": + case "trigger_multiple": + case "trigger_once": + case "trigger_push": + case "trigger_hurt": + case "trigger_hurt_ghost": + case "trigger_auto_crouch": + case "trigger_playermovement": + case "trigger_teleport": + case "func_simpleladder": + break; + case "prop_dynamic": + case "prop_dynamic_override": + case "prop_physics": + case "prop_physics_override": + EntFire( strEntityName, "StopGlowing" ); // Reset glows on all models. + break; + default: + continue; // Not any of the above entities, skip. + break; + } + + // Determine which entities to index based on argument given in ShowUpdate(). + + local anvUpdateEntity = strEntityName.find( g_UpdateName ); + local validEntity = 0; + + switch( showGroup ) + { + case "all": + break; + case "other": + if ( anvUpdateEntity == 0 ) continue; // Found g_UpdateName at start of name, skip entity. + break; + default: + if ( strClassname == "env_player_blocker" ) break; // Entity is a commentary blocker, index it. + if ( anvUpdateEntity != 0 ) continue; // Did not find g_UpdateName at start of name, skip entity. + break; + } + + if ( strEntityName != "anv_mapfixes_DebugRedraw_timer" ) { // Confirmed to be a fix entity so add it to array. - + g_arrayFixHandles[index] = entity; - + index++; + + // Resize array for next entity. + + g_arrayFixHandles.resize( index + 1 , null ); } } + + printl( "\nIndexed "+ index + " entities!\n" ); // Timer that DebugRedraw()'s every 1 second, better than AddThinkToEnt() because it // runs 1/10th as often and still looks good. Only make if one doesn't already exist. @@ -143,257 +308,678 @@ function ShowUpdate() } } ); } + + DebugRedraw() } // Declare function that houses the redraw loop the above Timer runs every 1 second. -// The IsValid() avoids "Accessed null instance" error if an entity within Handle array -// is deleted -- this will still break redraws, hence "TUTORIAL" to explain Hide/Show toggle. function DebugRedraw() { - // Draw all "anv_mapfixes"-prefixed entities. + local index = 0; + + // Clear ladder model sources array at the start of a redraw. + + g_arrayLadderSources.clear() + + // Clear debug overlay info before starting a new redraw. + // Props don't need to be "redrawn" since the one "StartGlowing" is sufficient. + + DebugDrawClear(); + + // Draw all indexed entities. - for ( local index = 0; - g_arrayFixHandles[index] != null && g_arrayFixHandles[index].IsValid(); + for ( index = 0; + g_arrayFixHandles[index] != null && index <= g_arrayFixHandles.len(); index++ ) { - // Only clear for 1st redrawn entity. If absent, only last-most blocker is drawn. - // Props don't need to be "redrawn" since the one "StartGlowing" is sufficient. - - if ( index == 0 ) + // Remove invalid or deleted entities from array before drawing. + + if ( ! g_arrayFixHandles[index].IsValid() ) { - DebugDrawClear(); + g_arrayFixHandles.remove( index ); // Entity is not valid, remove from array and skip. + printl( "Invalid entity '" + index + "' removed from drawing index." ); + break; } - - // Variables for readability. GetOrigin() and GetName() read well without them. - - local strClassname = g_arrayFixHandles[index].GetClassname(); + + // Store entity handles and values. + local hndFixHandle = g_arrayFixHandles[index]; - - // Restore Keyvalues from make_clip() to draw visible box for invisible blocker. - - if ( strClassname == "env_physics_blocker" ) - { - local intBlockType = NetProps.GetPropInt( hndFixHandle, "m_nBlockType" ); - - local vecBoxColor = null; - - switch( intBlockType ) - { - case 0: vecBoxColor = Vector( 255, 0, 0 ); break; // "Everyone" (RED) - case 1: vecBoxColor = Vector( 185, 0, 185 ); break; // "Survivors" (PINK) - case 2: vecBoxColor = Vector( 0, 255, 0 ); break; // "SI Players" (GREEN) - case 3: vecBoxColor = Vector( 0, 0, 255 ); break; // "SI Players and AI" (BLUE) - case 4: vecBoxColor = Vector( 0, 128, 255 ); break; // "All and Physics" (LT BLUE) - } - - local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); - local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); - - // Note DebugDrawBoxDirection() with GetForwardVector() only supports Y (yaw). - // X/pitch and Z/roll don't show. Kerry added DebugDrawBoxAngles() to fix this. - // DebugDrawBoxAngles() requires a QAngle which GetAngles() returns! - - DebugDrawBoxAngles( hndFixHandle.GetOrigin(), vecMins, vecMaxs, - hndFixHandle.GetAngles(), vecBoxColor, - g_BoxOpacity, 99999999 ); - - // Post-fix " (ANGLED)" to all blockers that have non-"0 0 0" rotation. This is - // warned in ShowUpdate()'s tutorial. Engine forces rotated clips to block Physics! - // NetProp "m_angRotation" used instead of GetAngles() because it returns a Vector. - - local strPseudonym = hndFixHandle.GetName(); - - if ( NetProps.GetPropVector( hndFixHandle, "m_angRotation" ).tostring() != Vector( 0, 0, 0 ).tostring() ) - { - strPseudonym = strPseudonym + " (ANGLED)"; - } - - // Slice "anv_mapfixes" out of name by using lengths and prefix "CLIP: " instead. - - DebugDrawText( hndFixHandle.GetOrigin(), - "CLIP: " + strPseudonym.slice( g_UpdateName.len(), strPseudonym.len() ), - false, 99999999 ); - } - - // Restore Keyvalues from make_brush() to draw visible box for invisible brush. - - if ( strClassname == "func_brush" ) + local strClassname = hndFixHandle.GetClassname(); + local strTargetname = hndFixHandle.GetName(); + local vecOrigin = hndFixHandle.GetOrigin(); + local vecAngles = hndFixHandle.GetAngles(); + + // Evaulate classname and apply debug draw. + + switch ( strClassname ) { - local vecBoxColor = Vector( 32, 255, 64 ); // LT GREEN - - local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); - local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); - - // Brush rotation unsupported so GetAngles() does nothing. - - DebugDrawBoxAngles( hndFixHandle.GetOrigin(), vecMins, vecMaxs, - hndFixHandle.GetAngles(), vecBoxColor, - g_BoxOpacity, 99999999 ); + + // Restore Keyvalues from make_clip() to draw visible box for invisible blocker. + + case "env_physics_blocker": + case "env_player_blocker": + + local intBlockType = NetProps.GetPropInt( hndFixHandle, "m_nBlockType" ); + local blockerIsAngled = false; + + // Post-fix " (ANGLED)" to all blockers that have non-"0 0 0" rotation. This is + // warned in ShowUpdate()'s tutorial. Engine forces rotated clips to block Physics! + // NetProp "m_angRotation" used instead of GetAngles() because it returns a Vector. + if ( NetProps.GetPropVector( hndFixHandle, "m_angRotation" ).tostring() != Vector( 0, 0, 0 ).tostring() ) + { + blockerIsAngled = true; + strTargetname = strTargetname + " (ANGLED)"; + } + + // See SetFilter function for values. + + switch( g_SetFilterClip ) + { + case 0: + continue; + break; + case 1: + break; + case 2: + if ( strClassname == "env_player_blocker" ) continue; + break; + case 3: + if ( strClassname == "env_physics_blocker" ) continue; + break; + case 4: + if ( blockerIsAngled == false ) continue; + break; + } + + if ( g_SetFilterBlockType != -1 ) + { + if ( g_SetFilterBlockType != intBlockType ) continue; + } + + local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); + local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); + local vecBoxColor = null; + + // Color debug box by BlockType. + + switch( intBlockType ) + { + case 0: vecBoxColor = COLOR_CLIP_RED; break; // "Everyone" (RED) + case 1: vecBoxColor = COLOR_CLIP_PINK; break; // "Survivors" (PINK) + case 2: vecBoxColor = COLOR_CLIP_GREEN; break; // "SI Players" (GREEN) + case 3: vecBoxColor = COLOR_CLIP_BLUE; break; // "SI Players and AI" (BLUE) + case 4: vecBoxColor = COLOR_CLIP_LTBLUE; break; // "All and Physics" (LT BLUE) + default: vecBoxColor = COLOR_CLIP_BLACK; break; // Invalid block type (BLACK) + } - // Slice "anv_mapfixes" out of name by using lengths and prefix "BRUSH: " instead. + // Note DebugDrawBoxDirection() with GetForwardVector() only supports Y (yaw). + // X/pitch and Z/roll don't show. Kerry added DebugDrawBoxAngles() to fix this. + // DebugDrawBoxAngles() requires a QAngle which GetAngles() returns! + + DebugDrawBoxAngles( vecOrigin, vecMins, vecMaxs, + vecAngles, vecBoxColor, + g_BoxOpacity, 99999999 ); + + // Label env_player_blocker separately, we assume they are always from _commentary.txt + + local clipType = ""; + switch( strClassname ) + { + case "env_physics_blocker": clipType = "CLIP"; break; + case "env_player_blocker": clipType = "PCLIP"; break; + } + + // Draw text to identify entity. + + DebugRedrawName( vecOrigin, strTargetname, clipType, index); + + break; + + // Restore Keyvalues from make_brush() to draw visible box for invisible brush. + + case "func_brush": + + // See SetFilter function for values. + + switch( g_SetFilterBrush ) + { + case 0: + continue; + break; + case 1: + if ( NetProps.GetPropInt( hndFixHandle, "m_nModelIndex" ) != 0 ) continue; // Brushes from scripts won't have a model. + break; + case 2: + break; + } + + local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); + local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); + local vecBoxColor = COLOR_BRUSH_LTGREEN; // LT GREEN + + // Brush rotation unsupported so GetAngles() does nothing. + + DebugDrawBoxAngles( vecOrigin, vecMins, vecMaxs, + vecAngles, vecBoxColor, + g_BoxOpacity, 99999999 ); + + // Draw text to identify entity. + + DebugRedrawName( vecOrigin, strTargetname, "BRUSH", index); + + break; + + // Restore Keyvalues from make_navblock() to draw visible box for navblocked region. + + case "func_nav_blocker": + + // See SetFilter function for values. + + switch( g_SetFilterNav ) + { + case 0: + continue; + break; + case 1: + if ( NetProps.GetPropInt( hndFixHandle, "m_nModelIndex" ) != 0 ) continue; // Brushes from scripts won't have a model. + break; + case 2: + break; + } - DebugDrawText( hndFixHandle.GetOrigin(), - "BRUSH: " + hndFixHandle.GetName().slice( g_UpdateName.len(), hndFixHandle.GetName().len() ), - false, 99999999 ); + local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); + local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); + local vecBoxColor = COLOR_NAV_ORANGE; // ORANGE + + // Rotation on navblockers is especially unsupported and always 0's. + + DebugDrawBoxAngles( vecOrigin, vecMins, vecMaxs, + vecAngles, vecBoxColor, + g_BoxOpacity, 99999999 ); + + // Draw text to identify entity. + + DebugRedrawName( vecOrigin, strTargetname, "NAVBLOCK", index); + + break; + + // Restore Keyvalues from several "trigger_" entities to draw visible boxes for them. + + case "trigger_multiple": + case "trigger_once": + case "trigger_push": + case "trigger_hurt": + case "trigger_hurt_ghost": + case "trigger_auto_crouch": + case "trigger_playermovement": + case "trigger_teleport": + + // See SetFilter function for values. + + switch( g_SetFilterTrigger ) + { + case 0: + continue; + break; + case 1: + if ( NetProps.GetPropInt( hndFixHandle, "m_nModelIndex" ) != 0 ) continue; // Brushes from scripts won't have a model. + break; + case 2: + break; + } + + local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); + local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); + local vecBoxColor = COLOR_TRIGGER_YELLOW; // YELLOW + + // Triggers are a wildcard but try to draw Angles just in case they're non-0. + // Note that "trigger_push" rotation has unknown mild influence on Push Direction + // that's only noticeable with Death Toll 5's Rockslide RNG. Angles definitely don't + // impact actual collidability and is why "trigger_hurt" fails entirely with them. + + DebugDrawBoxAngles( vecOrigin, vecMins, vecMaxs, + vecAngles, vecBoxColor, + g_BoxOpacity, 99999999 ); + + // Draw text to identify entity. + + DebugRedrawName( vecOrigin, strTargetname, "TRIGGER", index); + + break; + + // Extract vecMins/vecMaxs from make_ladder() to draw visible box around cloned Infected Ladder. + + case "func_simpleladder": + + local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); + local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); + local vecBoxColor = COLOR_LADDER_WHITE; // WHITE + + // Draw moved non-update-named ladders in purple. + + if ( strTargetname.find( g_UpdateName ) == null) + { + vecBoxColor = COLOR_LADDER_PURPLE; // PURPLE + } + + // See SetFilter function for values. + + switch( g_SetFilterLadder ) + { + case 0: + continue; + break; + case 1: + if ( vecOrigin.tostring() == Vector( 0, 0, 0 ).tostring() ) // Ladders from scripts won't be at (0,0,0). Also draws ladders that are not new but have been moved. + { + continue; + } + break; + case 2: + if ( vecOrigin.tostring() == Vector( 0, 0, 0 ).tostring() ) // Draws built in ladders. + { + vecBoxColor = COLOR_LADDER_ORANGE; // LIGHT ORANGE + } + break; + } + + // Draw text at the SOURCE ladder's location for inspection/comparison. + // For fun, sprinkle in its modelindex-turned-model so that it + // can at least be compared with "developer 1" Table dumps! + + local modelName = hndFixHandle.GetModelName(); + + DebugRedrawCloneSource(vecMins, modelName) + + // By the grace of GabeN with a sparkle of luck from Kerry ladders can be rotated. + + // Salt the opacity with + 24 so it stands out a bit more. + + DebugDrawBoxAngles( vecOrigin, vecMins, vecMaxs, + vecAngles, vecBoxColor, + g_BoxOpacity + 24, 99999999 ); + + // Draw text to identify entity. + + DebugRedrawName( vecOrigin + MathLadderOrigin(vecMins, vecMaxs, vecAngles), strTargetname, "LADDER", index); + + break; + + // Keyvalues from make_prop() don't need restoration as attributes can be visually assessed. + + case "prop_dynamic": + case "prop_dynamic_override": + case "prop_physics": + case "prop_physics_override": + + // See SetFilter function for values. + + switch( g_SetFilterProp ) + { + case 0: + EntFire( strTargetname, "StopGlowing" ); + continue; + break; + case 1: + break; + case 2: + if ( strClassname == "prop_physics" || strClassname == "prop_physics_override" ) continue; + break; + case 3: + if ( strClassname == "prop_dynamic" || strClassname == "prop_dynamic_override" ) continue; + break; + } + + EntFire( strTargetname, "StartGlowing" ); + + // Draw text to identify entity. + + DebugRedrawName( vecOrigin, strTargetname, "PROP", index); + + break; + + default: + break; } + } +} - // Restore Keyvalues from make_navblock() to draw visible box for navblocked region. +// Function to handle the drawing of text on highlighted entities. - if ( strClassname == "func_nav_blocker" ) - { - local vecBoxColor = Vector( 255, 45, 0 ); // ORANGE +function DebugRedrawName( origin, name, entityType, index ) +{ + + // See SetFilter function for values. + + local UseViewCheck = false; + + if ( g_SetFilterText == 0 ) + { + return; + } + else if ( g_SetFilterText == 2 ) + { + UseViewCheck = true; + } + + local namePrefix = entityType + ": "; + local additionalPrefix = ""; + + // Rules by entity type. + + switch( entityType ) + { + case "CLIP": + additionalPrefix = "(LUMP)" // Prefix for non-anv_mapfixes entities. + break; + case "PCLIP": + additionalPrefix = "(COMMENTARY)" // Prefix for commentary blocker entities (env_player_blocker). + break; + default: + break; + } + + // Entity does not have a targetname. + + if ( name == "" ) + { + name = "unnamed"; + } + + // Build display text and check for g_UpdateName string within entity name. + + if ( name.find( g_UpdateName ) == null ) + { + namePrefix = additionalPrefix + " " + namePrefix; // g_UpdateName was not found, mark as non-anv_mapfixes entity. + } + else + { + name = name.slice( g_UpdateName.len(), name.len() ); // g_UpdateName string was found, remove it. + } + + DebugDrawText( origin, namePrefix + name + " (" + index + ")", UseViewCheck, 10 ); +} - local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); - local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); +// Function to handle the drawing of text on cloned ladder models. - // Rotation on navblockers is especially unsupported and always 0's. +function DebugRedrawCloneSource( origin, modelName ) +{ - DebugDrawBoxAngles( hndFixHandle.GetOrigin(), vecMins, vecMaxs, - hndFixHandle.GetAngles(), vecBoxColor, - g_BoxOpacity, 99999999 ); + // See SetFilter function for values. + + local UseViewCheck = false; + + if ( g_SetFilterText == 0 ) + { + return; + } + else if ( g_SetFilterText == 2 ) + { + UseViewCheck = true; + } + + // Build list of used ladder sources to avoid duplicating text. + + if ( g_arrayLadderSources.find( modelName ) == null ) + { + DebugDrawText( origin, "LADDER CLONE SOURCE (" + modelName + ")", UseViewCheck, 10 ); + g_arrayLadderSources.resize( g_arrayLadderSources.len() + 1 , null ); + g_arrayLadderSources.append( modelName ); + } +} - // Slice "anv_mapfixes" out of name by using lengths and prefix "NAVBLOCK: " instead. +// Calculate correct position to display text at with MathLadderOrigin, otherwise labels for rotated ladders will be displaced. - DebugDrawText( hndFixHandle.GetOrigin(), - "NAVBLOCK: " + hndFixHandle.GetName().slice( g_UpdateName.len(), hndFixHandle.GetName().len() ), - false, 99999999 ); - } +function MathLadderOrigin( vecMins, vecMaxs, vecAngles ) +{ - // Restore Keyvalues from several "trigger_" entities to draw visible boxes for them. + // Position of ladder mins and maxs to transform. + + local vectorX = ( vecMins.x + vecMaxs.x ) / 2; + local vectorY = ( vecMins.y + vecMaxs.y ) / 2; + local vectorZ = ( vecMins.z + vecMaxs.z ) / 2; - if ( strClassname == "trigger_multiple" - || strClassname == "trigger_once" - || strClassname == "trigger_push" - || strClassname == "trigger_hurt" - || strClassname == "trigger_hurt_ghost" - || strClassname == "trigger_auto_crouch" - || strClassname == "trigger_playermovement" ) - { - local vecBoxColor = Vector( 255, 255, 0 ); // YELLOW + // Angle ladder is rotated by, in radians. - local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); - local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); + local angleX = ( vecAngles.z * PI ) / 180; + local angleY = ( vecAngles.x * PI ) / 180; + local angleZ = ( vecAngles.y * PI ) / 180; - // Triggers are a wildcard but try to draw Angles just in case they're non-0. - // Note that "trigger_push" rotation has unknown mild influence on Push Direction - // that's only noticeable with Death Toll 5's Rockslide RNG. Angles definitely don't - // impact actual collidability and is why "trigger_hurt" fails entirely with them. + // Store trig calculations. - DebugDrawBoxAngles( hndFixHandle.GetOrigin(), vecMins, vecMaxs, - hndFixHandle.GetAngles(), vecBoxColor, - g_BoxOpacity, 99999999 ); + local cosX = cos( angleX ); + local cosY = cos( angleY ); + local cosZ = cos( angleZ ); + local sinX = sin( angleX ); + local sinY = sin( angleY ); + local sinZ = sin( angleZ ); - // Slice "anv_mapfixes" out of name by using lengths and prefix "TRIGGER: " instead. + // Mid-calculation variables. - DebugDrawText( hndFixHandle.GetOrigin(), - "TRIGGER: " + hndFixHandle.GetName().slice( g_UpdateName.len(), hndFixHandle.GetName().len() ), - false, 99999999 ); - } + local transformedX = 0; + local transformedY = 0; + local transformedZ = 0; - // Extract vecMins/vecMaxs from make_ladder() to draw visible box around cloned Infected Ladder. + // 3D rotation matrix. - if ( strClassname == "func_simpleladder" ) - { - local vecBoxColor = Vector( 255, 255, 255 ); // WHITE - - local vecMins = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMins" ); - local vecMaxs = NetProps.GetPropVector( hndFixHandle, "m_Collision.m_vecMaxs" ); - - // By the grace of GabeN with a sparkle of luck from Kerry ladders can be rotated. - - // Salt the opacity with + 24 so it stands out a bit more. - - DebugDrawBoxAngles( hndFixHandle.GetOrigin(), vecMins, vecMaxs, - hndFixHandle.GetAngles(), vecBoxColor, - g_BoxOpacity + 24, 99999999 ); - - // Slice "anv_mapfixes" out of name by using lengths and prefix "LADDER: " instead. - - // LADDERS ONLY: - // - // The math here is a bit confusing but comes down to this, an example - // extracted from Parish 2's new "_ladder_farcorner_cloned_horsehedge": - // - // -5703.076172 -4246.962891 -246.501984 Where the tester sees drawn box - // -6441.002441 -3077.000000 -257.000000 vecMins far away b/c cloned brush - // -6359.000000 -3059.000000 -127.000000 vecMaxs, also misleading - // 695.000000 -1186.000000 -16.000000 GetOrigin(), source ladder shift/offset - // - // There's no crazy math needed here. While just how DebugDrawBox() - // still works so perfectly is a bit of a mystery, simply adding - // vecMins to GetOrigin() will produce the final, visible location - // of the cloned ladder. The fact NetProp "m_vecSpecifiedSurroundingMaxs" - // is not populated for clones requires this to determine location - // (and isn't worth risking the game crashing if the VSSM is force-set). - // Without adding them the text is placed towards the map's origin. - ////////////////////////////////////////////////////////////////////////////// - - // Draw the CLONED ladder's targetname where DebugDrawBox is / players actually use it. - - DebugDrawText( vecMins + hndFixHandle.GetOrigin(), - "LADDER: " + hndFixHandle.GetName().slice( g_UpdateName.len(), hndFixHandle.GetName().len() ), - false, 99999999 ); - - // Draw text at the SOURCE ladder's location for inspection/comparison. Given that several - // of these will often overlap because the same source was used, they'd be unreadable, so - // the text is simple here. For fun, sprinkle in its modelindex-turned-model so that it - // can at least be compared with "developer 1" Table dumps! - - DebugDrawText( vecMins, "LADDER CLONE SOURCE (" + hndFixHandle.GetModelName() + ")", false, 99999999 ); - } + transformedY = ( cosX * vectorY ) - ( sinX * vectorZ ); + transformedZ = ( cosX * vectorZ ) + ( sinX * vectorY ); + vectorY = transformedY; + vectorZ = transformedZ; - // Keyvalues from make_prop() don't need restoration as attributes can be visually assessed. + transformedX = ( cosY * vectorX ) + ( sinY * vectorZ ); + transformedZ = ( cosY * vectorZ ) - ( sinY * vectorX ); + vectorX = transformedX; + vectorZ = transformedZ; - if ( strClassname == "prop_dynamic" - || strClassname == "prop_dynamic_override" - || strClassname == "prop_physics" - || strClassname == "prop_physics_override" ) - { - EntFire( hndFixHandle.GetName(), "StartGlowing" ); + transformedX = ( cosZ * vectorX ) - ( sinZ * vectorY ); + transformedY = ( cosZ * vectorY ) + ( sinZ * vectorX ); + vectorX = transformedX; + vectorY = transformedY; - // Slice "anv_mapfixes" out of name by using lengths and prefix "PROP: " instead. + // Final result is the offset of the ladder from the world's origin (0,0,0), but corrected for rotation. + // GetOrigin gives us the offset of the ladder from its cloned model. + // Adding them together produces the actual position of the ladder in the world. + + return Vector( vectorX, vectorY, vectorZ ); +} - DebugDrawText( hndFixHandle.GetOrigin(), - "PROP: " + hndFixHandle.GetName().slice( g_UpdateName.len(), hndFixHandle.GetName().len() ), - false, 99999999 ); - } +// Function to change settings for groups of entities to be highlighted. +// Entering "all" for the value argument will default to 1, except for blocktype where it defaults to -1 (no filter). + +// Initialize SetFilter settings. + +g_SetFilterClip <- 1; +g_SetFilterBlockType <- -1; +g_SetFilterBrush <- 1; +g_SetFilterNav <- 1; +g_SetFilterTrigger <- 1; +g_SetFilterLadder <- 1; +g_SetFilterProp <- 1; +g_SetFilterText <- 1; + +/* +** Entity Filters: +** all +** - Entities: All below entities +** - Values: 0 = Hides all entity groups, 1 = Shows all entity groups (Default) +** clip +** - Entities: env_physics_blocker, env_player_blocker +** - Values: 0 = Hide all clips, 1 = Show all clips (Default), 2 = Only env_physics_blocker, 3 = Only env_player_blocker, 4 = Only angled blockers +** blocktype +** - Entities: env_physics_blocker, env_player_blocker - Filters by BlockType key value +** - Values: all (-1) = All block types (Default), 0 = Everyone, 1 = Survivors, 2 = Player Infected, +** 3 = All Special Infected (Player and AI), 4 = All players and physics objects (env_physics_blocker only) +** brush +** - Entities: func_brush +** - Values: 0 = Hide all brushes, 1 = Show all brushes with "model" key value set to "0" (Default), 2 = Shows all brushes +** nav +** - Entities: func_nav_blocker +** - Values: 0 = Hide all nav blockers, 1 = Show all nav blockers with "model" key value set to "0" (Default), 2 = Shows all nav blockers +** trigger +** - Entities: trigger_multiple, trigger_once, trigger_push, trigger_hurt, trigger_hurt_ghost, trigger_auto_crouch, +** trigger_playermovement, trigger_teleport +** - Values: 0 = Hide all triggers, 1 = Show all triggers with "model" key value set to "0" (Default), 2 = Shows all triggers +** ladder +** - Entities: func_simpleladders +** - Values: 0 = Hide all ladders, 1 = Show all ladders with non-zero "origin" key value (Default), 2 = Shows all ladders +** prop +** - Entities: prop_dynamic, prop_dynamic_override, prop_physics, prop_physics_override +** - Values: 0 = Hide all props, 1 = Shows all props (Default), 2 = Show dynamic props only, 3 = Show physics props only +** text +** - Entities: Debug text +** - Values: 0 = Hides all text, 1 = Shows all text (Default), 2 = Shows text only if there is a direct line of sight +*/ + +function SetFilter( entityGroup = null, value = null ) +{ + + // Ignore case sensitivity for arguments. + + entityGroup = entityGroup.tolower(); + + // Process value argument to ensure it's valid for the entityGroup switch. + + switch( value ) + { + case null: + if ( entityGroup == "blocktype" ) + { + value = -1; + } + else + { + value = 1; + } + break; + case "all": + if ( entityGroup == "blocktype" ) + { + value = -1; + } + else + { + value = 1; + } + break; + default: + try + { + value = value.tointeger(); + } + catch ( err ) + { + value = 1; + printl("\nValue: '" + value + "' is not valid, using default value.\n"); + } + break; } - - // To be complete, draw in BLACK all player and physics blockers that are NOT - // "anv_mapfixes"-prefixed. This reveals lump and _commentary.txt blockers. - - local hndPlay = null; - - while( ( hndPlay = Entities.FindByClassname( hndPlay, "env_player_blocker" ) ) != null ) + + // Change filter settings to parsed arguments. + // Catch if value provided is outside the possible range, set to default if it is. + + switch( entityGroup ) { - if ( hndPlay.GetName().find( "anv_mapfixes" ) != 0 ) - { - local mins = NetProps.GetPropVector( hndPlay, "m_Collision.m_vecMins" ); - local maxs = NetProps.GetPropVector( hndPlay, "m_Collision.m_vecMaxs" ); - - local vecBoxColor = Vector( 0, 0, 0 ); - - DebugDrawBoxAngles( hndPlay.GetOrigin(), mins, maxs, - hndPlay.GetAngles(), vecBoxColor, - g_BoxOpacity + 61, 99999999 ); - } + case "all": + if (value < 0 || value > 1) + { + value = 1; + } + + // Clip Block Type is a special case and has a different default. + + /* + if ( value == 1 ) + { + g_SetFilterBlockType <- -1; + } + else + { + g_SetFilterBlockType <- value; + } + */ + + g_SetFilterClip <- value; + g_SetFilterBrush <- value; + g_SetFilterNav <- value; + g_SetFilterTrigger <- value; + g_SetFilterLadder <- value; + g_SetFilterProp <- value; + break; + case "clip": + if (value < 0 || value > 4) + { + value = 1; + } + g_SetFilterClip <- value; + break; + case "blocktype": + if (value < -1 || value > 4) + { + value = -1; + } + g_SetFilterBlockType <- value; + break; + case "brush": + if (value < 0 || value > 2) + { + value = 1; + } + g_SetFilterBrush <- value; + break; + case "nav": + if (value < 0 || value > 2) + { + value = 1; + } + g_SetFilterNav <- value; + break; + case "trigger": + if (value < 0 || value > 2) + { + value = 1; + } + g_SetFilterTrigger <- value; + break; + case "ladder": + if (value < 0 || value > 2) + { + value = 1; + } + g_SetFilterLadder <- value; + break; + case "prop": + if (value < 0 || value > 3) + { + value = 1; + } + g_SetFilterProp <- value; + break; + case "text": + if (value < 0 || value > 2) + { + value = 1; + } + g_SetFilterText <- value; + break; + default: + printl("\nEntity group: '" + entityGroup + "' is not valid, or no entity group was specified.\n"); + return; + break; } - - local hndPhys = null; - - while( ( hndPhys = Entities.FindByClassname( hndPhys, "env_physics_blocker" ) ) != null ) + + // Disable glows on props highlighted by ShowUpdate without with g_UpdateName prefixed. + + if ( g_TutorialShown ) { - if ( hndPhys.GetName().find( "anv_mapfixes" ) != 0 ) + for ( local index = 0; + g_arrayFixHandles[index] != null && index <= g_arrayFixHandles.len(); + index++ ) { - local mins = NetProps.GetPropVector( hndPhys, "m_Collision.m_vecMins" ); - local maxs = NetProps.GetPropVector( hndPhys, "m_Collision.m_vecMaxs" ); - - local vecBoxColor = Vector( 0, 0, 0 ); - - DebugDrawBoxAngles( hndPhys.GetOrigin(), mins, maxs, - hndPhys.GetAngles(), vecBoxColor, - g_BoxOpacity + 61, 99999999 ); + EntFire( g_arrayFixHandles[index].GetName(), "StopGlowing" ); } } + + printl("\nShowing Group: '" + entityGroup + "', with filter: '" + value + "'.\n"); } \ No newline at end of file