mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-05 21:53:21 +00:00
Compare commits
6 commits
d278f582cc
...
28a4346e8d
Author | SHA1 | Date | |
---|---|---|---|
28a4346e8d | |||
902ea46566 | |||
eae0356c03 | |||
e343fc0346 | |||
6a15c9c196 | |||
c51aa6533c |
24 changed files with 6618 additions and 1018 deletions
28
data/prop_spawner/models/Fencing & Walls/barriers.txt
Normal file
28
data/prop_spawner/models/Fencing & Walls/barriers.txt
Normal file
|
@ -0,0 +1,28 @@
|
|||
Barriers
|
||||
models/props_fortifications/barricade001_128_reference.mdl Metal Mesh Barricade (128u)
|
||||
models/props_fortifications/barricade001_64_reference.mdl Metal Mesh Barricade (64u)
|
||||
models/props_fortifications/barricade_gate001_64_reference.mdl Metal Mesh Barricade Gate (64u)
|
||||
models/props_fortifications/barricade_razorwire001_128_reference.mdl Barricade Razorwire (128u) (no collision)
|
||||
models/props_fortifications/concrete_barrier01.mdl Concrete wall
|
||||
models/props_fortifications/concrete_barrier001_96_reference.mdl Concrete crash barrier (96u)
|
||||
models/props_fortifications/concrete_barrier001_128_reference.mdl Concrete crash barrier (128u)
|
||||
models/props_fortifications/concrete_post001_48.mdl Concrete Post (48u)
|
||||
models/props_fortifications/concrete_wall001_96_reference.mdl Concrete wall (96u)
|
||||
models/props_fortifications/concrete_block001_128_reference.mdl Concrete block (128u)
|
||||
models/props_fortifications/police_barrier001_128_reference.mdl Police Barrier Notice
|
||||
models/props_fortifications/fortification_indoor_01.mdl Luggage Push Fort
|
||||
models/props_fortifications/sandbags_line2.mdl Building sandbags 6 layers
|
||||
models/props_fortifications/sandbags_corner3.mdl Building sandbags 4 layers curved
|
||||
models/props_fortifications/sandbags_corner2.mdl Building sandbags 6 layers curved
|
||||
models/props_fortifications/traffic_barrier001.mdl Traffic Barrier
|
||||
models/props_urban/railroad_gate001.mdl Railroad Crossing Light
|
||||
models/props_urban/railroad_gate_arm001.mdl Railroad Crossing Arm
|
||||
models/props_downtown/bollards_ornate.mdl Ornate metal bollard
|
||||
models/props_street/bollards_512.mdl Bollard (512u)
|
||||
models/props_unique/wooden_barricade.mdl Wooden barricade (no damage)
|
||||
models/props_unique/wooden_barricade_break1.mdl wooden barricade (low damage)
|
||||
models/props_unique/wooden_barricade_break2.mdl Wooden barricade (medium damage)
|
||||
models/props_unique/wooden_barricade_break3.mdl wooden barricade (high damage)
|
||||
models/props_c17/concrete_barrier001a.mdl Concrete crash barrier-higher
|
||||
models/props_exteriors/guardrail128a.mdl road guardrail (128u)
|
||||
models/props_buildables/wall_barricade_helper.mdl Wall Barricade Helper
|
79
data/prop_spawner/models/Fencing & Walls/fences.txt
Normal file
79
data/prop_spawner/models/Fencing & Walls/fences.txt
Normal file
|
@ -0,0 +1,79 @@
|
|||
Fences & Gates
|
||||
models/lighthouse/props/wooden_gate.mdl Valerie's fancy wooden gate
|
||||
models/props_exteriors/fence002.mdl wooden fence (very long)
|
||||
models/props_exteriors/fence002_end.mdl wooden fence end
|
||||
models/props_urban/fence_gate001_256.mdl urban fence gate (easy to use)
|
||||
models/props_urban/fence_cover001_64.mdl shelter Fence (64u)
|
||||
models/props_urban/fence_cover001_128.mdl shelter fence (128u)
|
||||
models/props_urban/fence_cover001_256.mdl shelter fence (256u)
|
||||
models/props_fortifications/barricade_gate001_64_reference.mdl roadblock-single layer without handle (easy to use)
|
||||
models/props_fortifications/barricade001_64_reference.mdl roadblock-single layer
|
||||
models/props_fortifications/barricade001_128_reference.mdl roadblock-double layer
|
||||
models/props_unique/airport/temp_barricade.mdl roadblock-airport
|
||||
models/props_wasteland/exterior_fence002b.mdl Barbed wire fence - 1 wide skinny
|
||||
models/props_wasteland/exterior_fence002c.mdl Barbed wire fence - 1 wide
|
||||
models/props_wasteland/exterior_fence002d.mdl Barbed wire fence - 2 wide
|
||||
models/props_wasteland/exterior_fence002e.mdl Barbed wire fence - 4 wide
|
||||
models/props_street/police_barricade.mdl Police Barricade - 1 wide
|
||||
models/props_street/police_barricade2.mdl Police barricade - 3 wide
|
||||
models/props_street/police_barricade3.mdl Police Barricade - 6 wide
|
||||
models/props_street/police_barricade_368in.mdl Police Barricade - 8 wide
|
||||
models/props_street/police_barricade_496in.mdl Police Barricade - 10 wide
|
||||
models/props_street/police_barricade4.mdl Iron Frame Barricade - 12 wide
|
||||
models/lostcoast/props_wasteland/gate01a.mdl Iron fence gate a
|
||||
models/lostcoast/props_wasteland/gate01b.mdl iron fence gate b
|
||||
models/props_mill/elevator01_cage.mdl Mill Elevator-c4m2
|
||||
models/props_mill/elevator01_cagedoor02.mdl Mill Elevator telescopic door-c4m2 (No Collision)
|
||||
models/props_mill/elevator01_cagedoor.mdl Mill Elevator Cage door
|
||||
models/props_mill/elevator01_framework.mdl Elevator shaft framework
|
||||
models/props_mill/freightelevatorbutton01.mdl Mill Freight Elevator Button 1
|
||||
models/props_mill/freightelevatorbutton02.mdl Mill Freight Elevator Button 2
|
||||
models/props_street/barricade_door_01.mdl Military Agency Door-c9m1
|
||||
models/props_urban/fence_768_collapsed.mdl Fence with covered shelter-c4m5
|
||||
models/props_urban/gate_wall003_32.mdl Screening fence wall (32u)
|
||||
models/props_urban/gate_wall003_64.mdl Screening fence wall (64u)
|
||||
models/props_urban/gate_wall003_128.mdl Shelter fence wall (128u)
|
||||
models/props_urban/gate_wall_gate003_64.mdl Wall Gate 3 (64u)
|
||||
models/props_urban/wood_fence001_64.mdl Urban wooden fence a (64u)
|
||||
models/props_urban/wood_fence001_128.mdl Urban wooden fence a (128u)
|
||||
models/props_urban/wood_fence001_256.mdl Urban wooden fence a (256u)
|
||||
models/props_urban/wood_fence002_64.mdl Urban wooden fence b (64u)
|
||||
models/props_urban/wood_fence002_128.mdl Urban wooden fence b (128u)
|
||||
models/props_urban/wood_fence002_256.mdl Urban wooden fence b (256u)
|
||||
models/props_urban/wood_post001.mdl Urban Wood Post 1
|
||||
models/props_urban/wood_post002.mdl Urban Wood Post 2
|
||||
models/props_cemetery/cemetery_gate.mdl Cemetary Gate Barbed Wire with Spikes
|
||||
models/props_cemetery/cemetery_gate_32.mdl Cemetary Gate Barbed Wire with Spikes (32u)
|
||||
models/props_cemetery/cemetery_gate_64.mdl Cemetary Gate Barbed Wire with Spikes (64u)
|
||||
models/props_cemetery/cemetery_gate_128.mdl Cemetary Gate Barbed Wire with Spikes (128u)
|
||||
models/props_exteriors/roadsidefence_64.mdl Road fence-single layer (64u)
|
||||
models/props_exteriors/roadsidefence_512.mdl road fence-eight layers (512u)
|
||||
models/props_exteriors/fence_plastic001.mdl Plastic Fence
|
||||
models/props_downtown/garden_gate.mdl Downtown Garden Gate
|
||||
models/props/de_inferno/wood_fence.mdl De Inferno Wood Fence
|
||||
models/props/de_inferno/wood_fence_end.mdl De Inferno Wood Fence End
|
||||
models/props_urban/fence001_128.mdl Urban Chain Link Fence1 (128u)
|
||||
models/props_urban/fence001_256.mdl Urban Chain Link Fence1 (256u)
|
||||
models/props_urban/fence001_64.mdl Urban Chain Link Fence1 (64u)
|
||||
models/props_urban/fence002_128.mdl Urban Chain Link Fence2 (128u)
|
||||
models/props_urban/fence002_256.mdl Urban Chain Link Fence2 (256u)
|
||||
models/props_urban/fence002_64.mdl Urban Chain Link Fence2 (64u)
|
||||
models/props_urban/fence003_128.mdl Urban Chain Link Fence3 (128u)
|
||||
models/props_urban/fence003_64.mdl Urban Chain Link Fence3 (64u)
|
||||
models/props_urban/fence004_128.mdl Urban Chain Link Fence Frame (128u)
|
||||
models/props_urban/fence004_256.mdl Urban Chain Link Fence Frame (256u)
|
||||
models/props_urban/fence004_64.mdl Urban Fence Chain Link Frame (64u)
|
||||
models/props_urban/fence_barbwire001_128.mdl Urban Barbwire Fence (128u)
|
||||
models/props_urban/fence_barbwire001_256.mdl Urban Barbwire Fence (256u)
|
||||
models/props_urban/fence_barbwire001_64.mdl Urban Barbwire Fence (64u)
|
||||
models/props_urban/fence_post_barbwire001.mdl Urban Barbwire Fence Post
|
||||
models/props_urban/fence_gate001_128.mdl Urban Fence Gate1 (128u)
|
||||
models/props_urban/fence_gate001_256.mdl Urban Fence Gate1 (256u)
|
||||
models/props_urban/fence_gate002_256.mdl Urban Fence Gate2 (256u)
|
||||
models/props_urban/fence_gate003.mdl Urban Fence Gate3 (Small)
|
||||
models/props_urban/fence_gate_post001.mdl Urban Chain Link Fence Gate Post 1
|
||||
models/props_urban/fence_gate_post003.mdl Urban Chain Link Fence Gate Post 2
|
||||
models/props_urban/fence_post001.mdl Urban Chain Link Fence Post 1
|
||||
models/props_urban/fence_post002.mdl Urban Chain Link Fence Post 2
|
||||
models/props_urban/fence_post003.mdl Urban Chain Link Fence Post 3
|
||||
models/props_urban/gate_column001_32.mdl Urban Gate Column
|
28
data/prop_spawner/models/Fencing & Walls/walls.txt
Normal file
28
data/prop_spawner/models/Fencing & Walls/walls.txt
Normal file
|
@ -0,0 +1,28 @@
|
|||
Walls
|
||||
models/props_update/brick_128.mdl brick wall/floor (128u)
|
||||
models/props_update/brick_256.mdl brick wall/floor (256u)
|
||||
models/props_update/concrete_128.mdl cement wall/floor (128u)
|
||||
models/props_update/concrete_256.mdl cement wall/floor (256u)
|
||||
models/props_update/plywood_128.mdl wooden wall/floor (128u)
|
||||
models/props_update/plywood_256.mdl wooden wall/floor (256u)
|
||||
models/props_update/whitebrick_128.mdl white brick wall (128u)
|
||||
models/props_update/whitebrick_256.mdl white brick wall (256u)
|
||||
models/props_update/wood_128.mdl wooden walls (128u)
|
||||
models/props_update/wood_256.mdl wooden walls (256u)
|
||||
models/props_urban/gate_wall001_64.mdl Urban Wall (64u)
|
||||
models/props_urban/gate_wall001_128.mdl Urban Wall (128u)
|
||||
models/props_urban/gate_wall001_256.mdl Urban Wall (256u)
|
||||
models/props_urban/gate_wall002_128.mdl urban fence wall (128u)
|
||||
models/props_unique/zombiebreakwallexteriorairport01_main.mdl Wallpaper - Airport
|
||||
models/props_unique/zombiebreakwallexteriorairportoffices01_main.mdl Wallpaper - Airport Office
|
||||
models/props_unique/zombiebreakwallhospitalexterior01_main.mdl Wallpaper - Hospital
|
||||
models/lighthouse/props/wall_144_324.mdl Wall-144X(324u) (No Side)
|
||||
models/props_interiors/constructionwalls02checkpoint.mdl steel building framing (with doorway)
|
||||
models/props_interiors/constructionwalls03.mdl steel building framing
|
||||
models/props_interiors/constructionwalls04_damage01.mdl Extra-long building steel column
|
||||
models/props_cemetery/crypts_wall.mdl Thickened stone wall-Cemetery Exposed Brick
|
||||
models/props_mill/locker_roof_collapsed01.mdl Mill Locker Roof Collapsed (no side)
|
||||
models/props_mill/millwall_01.mdl Mill wall 1 (no side)
|
||||
models/props_mill/millwall_02.mdl Mill wall 2 (no side)
|
||||
models/props_mill/millwall_03.mdl Mill wall 3 (no side)
|
||||
models/props_mill/column_01.mdl Mill Rebar Column
|
|
@ -595,5 +595,67 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"truck-bridge-gap": {
|
||||
"chance": 0.40000000596046448,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/semi_trailer_wrecked.mdl",
|
||||
"origin": [
|
||||
-12307.5810546875,
|
||||
-11925.724609375,
|
||||
-349.92706298828125
|
||||
],
|
||||
"angles": [
|
||||
4.0999965667724609,
|
||||
72.799995422363281,
|
||||
-2.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"catwalk-pipes": {
|
||||
"chance": 0.5,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_mill/pipeset08d_256_001a.mdl",
|
||||
"origin": [
|
||||
-12992.806640625,
|
||||
-5664.62939453125,
|
||||
-266.845703125
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
270.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_mill/pipeset08d_256_001a.mdl",
|
||||
"origin": [
|
||||
-13243.6201171875,
|
||||
-5662.48095703125,
|
||||
-267.79513549804688
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
270.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -524,6 +524,578 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fortifications/barricade001_128_reference.mdl",
|
||||
"origin": [
|
||||
-7604.6962890625,
|
||||
-5517.0537109375,
|
||||
-63.71875
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fortifications/barricade001_128_reference.mdl",
|
||||
"origin": [
|
||||
-7600.89892578125,
|
||||
-5628.1220703125,
|
||||
-63.71875
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fortifications/barricade001_128_reference.mdl",
|
||||
"origin": [
|
||||
-7598.435546875,
|
||||
-5730.88330078125,
|
||||
-63.718753814697266
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fortifications/barricade001_128_reference.mdl",
|
||||
"origin": [
|
||||
-7599.41845703125,
|
||||
-5829.40625,
|
||||
-63.718753814697266
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fortifications/barricade001_128_reference.mdl",
|
||||
"origin": [
|
||||
-7599.73095703125,
|
||||
-5930.41748046875,
|
||||
-63.718746185302734
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_exteriors/roadsidefence_64.mdl",
|
||||
"origin": [
|
||||
-7670.9248046875,
|
||||
-5441.72509765625,
|
||||
-96.096488952636719
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
-30.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_exteriors/roadsidefence_64.mdl",
|
||||
"origin": [
|
||||
-7715.326171875,
|
||||
-5440.0615234375,
|
||||
-125.46791076660156
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
-30.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_interiors/sheetrock_leaning.mdl",
|
||||
"origin": [
|
||||
-7834.50634765625,
|
||||
-5506.349609375,
|
||||
-247.73503112792969
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
-270.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_exteriors/roadsidefence_64.mdl",
|
||||
"origin": [
|
||||
-7768.7626953125,
|
||||
-5440.03125,
|
||||
-158.68734741210938
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
-30.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_exteriors/roadsidefence_64.mdl",
|
||||
"origin": [
|
||||
-7824.25048828125,
|
||||
-5441.51611328125,
|
||||
-195.01101684570312
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
-30.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_equipment/metalladder002.mdl",
|
||||
"origin": [
|
||||
-8446.7109375,
|
||||
-6000.96875,
|
||||
-179.07974243164062
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props/cs_assault/forklift.mdl",
|
||||
"origin": [
|
||||
-8446.1474609375,
|
||||
-5954.8544921875,
|
||||
-321.01327514648438
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
-90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_industrial/warehouse_shelf001.mdl",
|
||||
"origin": [
|
||||
-8764.8349609375,
|
||||
-6118.96630859375,
|
||||
-61.846946716308594
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_industrial/warehouse_shelf003.mdl",
|
||||
"origin": [
|
||||
-8538.37109375,
|
||||
-6279.68115234375,
|
||||
-63.222255706787109
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
-90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_interiors/sheetrock_leaning.mdl",
|
||||
"origin": [
|
||||
-7712.74853515625,
|
||||
-6103.77587890625,
|
||||
-63.735023498535156
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
-165.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props/cs_militia/shelves_wood.mdl",
|
||||
"origin": [
|
||||
-7655.509765625,
|
||||
-6076.41162109375,
|
||||
-61.889106750488281
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
45.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_industrial/warehouse_shelf002.mdl",
|
||||
"origin": [
|
||||
-7701.6396484375,
|
||||
-6118.47412109375,
|
||||
-62.106662750244141
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/train_box_open.mdl",
|
||||
"origin": [
|
||||
-7822.83056640625,
|
||||
-6486.45556640625,
|
||||
-61.381694793701172
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/train_enginecar.mdl",
|
||||
"origin": [
|
||||
-7410.93994140625,
|
||||
-6787.6025390625,
|
||||
-61.410385131835938
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/train_flatcar.mdl",
|
||||
"origin": [
|
||||
-8124.68115234375,
|
||||
-6636.7177734375,
|
||||
-62.520648956298828
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/train_box.mdl",
|
||||
"origin": [
|
||||
-8475.91015625,
|
||||
-6484.85595703125,
|
||||
-62.520648956298828
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_urban/metal_plate001.mdl",
|
||||
"origin": [
|
||||
-7953.88037109375,
|
||||
-6027.1240234375,
|
||||
-50.131851196289062
|
||||
],
|
||||
"angles": [
|
||||
-15.0,
|
||||
90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_urban/metal_plate001.mdl",
|
||||
"origin": [
|
||||
-7959.54736328125,
|
||||
-5806.42041015625,
|
||||
-99.561187744140625
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_industrial/plywood_leaning.mdl",
|
||||
"origin": [
|
||||
-7823.16748046875,
|
||||
-5862.0478515625,
|
||||
-246.55105590820312
|
||||
],
|
||||
"angles": [
|
||||
15.0,
|
||||
90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_industrial/pallet_barrels_water01_docks.mdl",
|
||||
"origin": [
|
||||
-8305.1142578125,
|
||||
-5699.38525390625,
|
||||
-319.90985107421875
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "env_physics_blocker",
|
||||
"origin": [
|
||||
-7645.275390625,
|
||||
-5453.0224609375,
|
||||
-21.96875
|
||||
],
|
||||
"scale": [
|
||||
10.0,
|
||||
15.0,
|
||||
100.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "light_dynamic",
|
||||
"origin": [
|
||||
-8442.83984375,
|
||||
-5990.68310546875,
|
||||
-80.129623413085938
|
||||
],
|
||||
"color": [
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
1
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"scale": [
|
||||
400.0,
|
||||
-1.0,
|
||||
-1.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "infodecal",
|
||||
"origin": [
|
||||
-8508.3330078125,
|
||||
-5999.96875,
|
||||
-139.70254516601562
|
||||
],
|
||||
"model": "decals/checkpointarrow01_black.vmt"
|
||||
},
|
||||
{
|
||||
"type": "infodecal",
|
||||
"origin": [
|
||||
-7578.3076171875,
|
||||
-5344.03125,
|
||||
-1.9795554876327515
|
||||
],
|
||||
"model": "decals/checkpointarrow01_black.vmt"
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_equipment/light_floodlight.mdl",
|
||||
"origin": [
|
||||
-8609.4853515625,
|
||||
-5886.58740234375,
|
||||
-318.59130859375
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
-30.0,
|
||||
0.0
|
||||
],
|
||||
"properties": {
|
||||
"int": {
|
||||
"m_nSkin": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_equipment/light_floodlight.mdl",
|
||||
"origin": [
|
||||
-7772.57275390625,
|
||||
-6078.6318359375,
|
||||
-61.102703094482422
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
-165.0,
|
||||
0.0
|
||||
],
|
||||
"properties": {
|
||||
"int": {
|
||||
"m_nSkin": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "light_dynamic",
|
||||
"origin": [
|
||||
-7789.453125,
|
||||
-6090.96240234375,
|
||||
-25.968757629394531
|
||||
],
|
||||
"color": [
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
1
|
||||
],
|
||||
"angles": [
|
||||
-162.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"scale": [
|
||||
400.0,
|
||||
-1.0,
|
||||
-1.0
|
||||
]
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"hammerid": 286780,
|
||||
"input": "_allow_ladder"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"start-help": {
|
||||
"chance": 0.40000000596046448,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_urban/metal_plate001.mdl",
|
||||
"origin": [
|
||||
-11552.841796875,
|
||||
-8238.443359375,
|
||||
-461.36874389648438
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_urban/metal_plate001.mdl",
|
||||
"origin": [
|
||||
-11452.822265625,
|
||||
-8187.95556640625,
|
||||
-462.92050170898438
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_urban/metal_plate001.mdl",
|
||||
"origin": [
|
||||
-11321.1884765625,
|
||||
-8188.3017578125,
|
||||
-462.57418823242188
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_urban/metal_plate001.mdl",
|
||||
"origin": [
|
||||
-11188.369140625,
|
||||
-8189.39599609375,
|
||||
-462.95126342773438
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_c17/truss02h.mdl",
|
||||
"origin": [
|
||||
-11365.6318359375,
|
||||
-8171.609375,
|
||||
-480.19430541992188
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_c17/truss02h.mdl",
|
||||
"origin": [
|
||||
-11244.2041015625,
|
||||
-8188.748046875,
|
||||
-478.780517578125
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
341
data/randomizer/c1m4_atrium.json
Normal file
341
data/randomizer/c1m4_atrium.json
Normal file
|
@ -0,0 +1,341 @@
|
|||
{
|
||||
"pills": {
|
||||
"chance": 0.10000000149011612,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "weapon_pain_pills",
|
||||
"model": "models/w_models/weapons/w_eq_painpills.mdl",
|
||||
"origin": [
|
||||
-2223.25439453125,
|
||||
-5297.4228515625,
|
||||
657.84283447265625
|
||||
],
|
||||
"angles": [
|
||||
36.637165069580078,
|
||||
166.42544555664062,
|
||||
-85.725311279296875
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "weapon_pain_pills",
|
||||
"model": "models/w_models/weapons/w_eq_painpills.mdl",
|
||||
"origin": [
|
||||
-2223.25439453125,
|
||||
-5297.4228515625,
|
||||
657.84283447265625
|
||||
],
|
||||
"angles": [
|
||||
36.637165069580078,
|
||||
166.42544555664062,
|
||||
-85.725311279296875
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "weapon_pain_pills",
|
||||
"model": "models/w_models/weapons/w_eq_painpills.mdl",
|
||||
"origin": [
|
||||
-2223.25439453125,
|
||||
-5297.4228515625,
|
||||
657.84283447265625
|
||||
],
|
||||
"angles": [
|
||||
36.637165069580078,
|
||||
166.42544555664062,
|
||||
-85.725311279296875
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "weapon_pain_pills",
|
||||
"model": "models/w_models/weapons/w_eq_painpills.mdl",
|
||||
"origin": [
|
||||
-2223.25439453125,
|
||||
-5297.4228515625,
|
||||
657.84283447265625
|
||||
],
|
||||
"angles": [
|
||||
36.637165069580078,
|
||||
166.42544555664062,
|
||||
-85.725311279296875
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "weapon_pain_pills",
|
||||
"model": "models/w_models/weapons/w_eq_painpills.mdl",
|
||||
"origin": [
|
||||
-2223.25439453125,
|
||||
-5297.4228515625,
|
||||
657.84283447265625
|
||||
],
|
||||
"angles": [
|
||||
36.637165069580078,
|
||||
166.42544555664062,
|
||||
-85.725311279296875
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "weapon_pain_pills",
|
||||
"model": "models/w_models/weapons/w_eq_painpills.mdl",
|
||||
"origin": [
|
||||
-2223.25439453125,
|
||||
-5297.4228515625,
|
||||
657.84283447265625
|
||||
],
|
||||
"angles": [
|
||||
36.637165069580078,
|
||||
166.42544555664062,
|
||||
-85.725311279296875
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "weapon_pain_pills",
|
||||
"model": "models/w_models/weapons/w_eq_painpills.mdl",
|
||||
"origin": [
|
||||
-2223.25439453125,
|
||||
-5297.4228515625,
|
||||
657.84283447265625
|
||||
],
|
||||
"angles": [
|
||||
36.637165069580078,
|
||||
166.42544555664062,
|
||||
-85.725311279296875
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "weapon_pain_pills",
|
||||
"model": "models/w_models/weapons/w_eq_painpills.mdl",
|
||||
"origin": [
|
||||
-2223.25439453125,
|
||||
-5297.4228515625,
|
||||
657.84283447265625
|
||||
],
|
||||
"angles": [
|
||||
36.637165069580078,
|
||||
166.42544555664062,
|
||||
-85.725311279296875
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "weapon_pain_pills",
|
||||
"model": "models/w_models/weapons/w_eq_painpills.mdl",
|
||||
"origin": [
|
||||
-2223.25439453125,
|
||||
-5297.4228515625,
|
||||
657.84283447265625
|
||||
],
|
||||
"angles": [
|
||||
36.637165069580078,
|
||||
166.42544555664062,
|
||||
-85.725311279296875
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gascans": {
|
||||
"chance": 0.80000001192092896,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-6051.14208984375,
|
||||
-3448.0810546875,
|
||||
10.876523017883301
|
||||
],
|
||||
"angles": [
|
||||
-0.55249863862991333,
|
||||
129.0628662109375,
|
||||
0.0064697265625
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-5950.7998046875,
|
||||
-3225.01025390625,
|
||||
10.882441520690918
|
||||
],
|
||||
"angles": [
|
||||
-0.5578463077545166,
|
||||
-139.19509887695312,
|
||||
-0.124267578125
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-4745.12109375,
|
||||
-2358.740234375,
|
||||
10.877493858337402
|
||||
],
|
||||
"angles": [
|
||||
-0.58881288766860962,
|
||||
-56.487579345703125,
|
||||
-0.1336669921875
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-4925.220703125,
|
||||
-2751.919921875,
|
||||
290.86605834960938
|
||||
],
|
||||
"angles": [
|
||||
-0.55006474256515503,
|
||||
-44.867576599121094,
|
||||
0.007659912109375
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-3909.123291015625,
|
||||
-2742.46826171875,
|
||||
290.86465454101562
|
||||
],
|
||||
"angles": [
|
||||
-0.55862104892730713,
|
||||
-159.15614318847656,
|
||||
0.0079345703125
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-3879.3017578125,
|
||||
-3364.2548828125,
|
||||
290.87225341796875
|
||||
],
|
||||
"angles": [
|
||||
-0.55406862497329712,
|
||||
-47.913330078125,
|
||||
0.0017852783203125
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-2867.53466796875,
|
||||
-3212.300048828125,
|
||||
290.868408203125
|
||||
],
|
||||
"angles": [
|
||||
-0.53946495056152344,
|
||||
103.97676849365234,
|
||||
0.0077972412109375
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-3061.08349609375,
|
||||
-3134.86376953125,
|
||||
10.877670288085938
|
||||
],
|
||||
"angles": [
|
||||
-0.57504987716674805,
|
||||
-77.274543762207031,
|
||||
-0.1275634765625
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-3607.03955078125,
|
||||
-3158.387939453125,
|
||||
10.877679824829102
|
||||
],
|
||||
"angles": [
|
||||
-0.57509583234786987,
|
||||
-121.18537902832031,
|
||||
-0.12750244140625
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-4482.93115234375,
|
||||
-4446.20458984375,
|
||||
10.853196144104004
|
||||
],
|
||||
"angles": [
|
||||
-0.72719091176986694,
|
||||
54.255725860595703,
|
||||
-0.16156005859375
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-4020.397705078125,
|
||||
-4442.953125,
|
||||
10.86365795135498
|
||||
],
|
||||
"angles": [
|
||||
0.3856024444103241,
|
||||
114.11133575439453,
|
||||
-0.273193359375
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-5399.42822265625,
|
||||
-4438.22119140625,
|
||||
10.882131576538086
|
||||
],
|
||||
"angles": [
|
||||
-0.54621058702468872,
|
||||
33.001979827880859,
|
||||
-0.1214599609375
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "_gascan",
|
||||
"origin": [
|
||||
-5424.62451171875,
|
||||
-4431.45849609375,
|
||||
290.86849975585938
|
||||
],
|
||||
"angles": [
|
||||
-0.868499755859375,
|
||||
72.193069458007812,
|
||||
0.2503509521484375
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"PEANUT": {
|
||||
"chance": 1.0,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fairgrounds/lil'peanut_cutout001.mdl",
|
||||
"origin": [
|
||||
-4683.3173828125,
|
||||
-2287.525634765625,
|
||||
303.778564453125
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
-90.0,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
1482
data/randomizer/c4m1_milltown_a.json
Normal file
1482
data/randomizer/c4m1_milltown_a.json
Normal file
File diff suppressed because it is too large
Load diff
1548
data/randomizer/c4m2_sugarmill_a.json
Normal file
1548
data/randomizer/c4m2_sugarmill_a.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -22,5 +22,251 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"trailer": {
|
||||
"chance": 0.30000001192092896,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_debris/concrete_debris128pile001b.mdl",
|
||||
"origin": [
|
||||
-5020.86962890625,
|
||||
6377.85693359375,
|
||||
641.72576904296875
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/hmmwv.mdl",
|
||||
"origin": [
|
||||
-4926.7568359375,
|
||||
6393.20068359375,
|
||||
626.56927490234375
|
||||
],
|
||||
"angles": [
|
||||
-3.8999967575073242,
|
||||
61.0,
|
||||
9.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_debris/concrete_debris128pile001a.mdl",
|
||||
"origin": [
|
||||
-4907.00537109375,
|
||||
6379.3125,
|
||||
701.50091552734375
|
||||
],
|
||||
"angles": [
|
||||
19.80000114440918,
|
||||
-10.699999809265137,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/semi_trailer_wrecked.mdl",
|
||||
"origin": [
|
||||
-5159.9794921875,
|
||||
6288.13427734375,
|
||||
516.46624755859375
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
118.30000305175781,
|
||||
-5.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_debris/concrete_debris128pile001a.mdl",
|
||||
"origin": [
|
||||
-4939.30126953125,
|
||||
6397.275390625,
|
||||
697.10382080078125
|
||||
],
|
||||
"angles": [
|
||||
4.4000000953674316,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"bus": {
|
||||
"chance": 0.30000001192092896,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/bus01_2.mdl",
|
||||
"origin": [
|
||||
-3170.48095703125,
|
||||
6297.6298828125,
|
||||
640.4088134765625
|
||||
],
|
||||
"angles": [
|
||||
-23.000001907348633,
|
||||
49.799995422363281,
|
||||
-20.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"humvee": {
|
||||
"chance": 0.30000001192092896,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/hmmwv.mdl",
|
||||
"origin": [
|
||||
4218.40283203125,
|
||||
6309.74951171875,
|
||||
455.75555419921875
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
-93.300003051757812,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"car-block": {
|
||||
"chance": 0.30000001192092896,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/cara_95sedan.mdl",
|
||||
"origin": [
|
||||
4680.36962890625,
|
||||
6451.8359375,
|
||||
598.89410400390625
|
||||
],
|
||||
"angles": [
|
||||
-16.500001907348633,
|
||||
113.90000152587891,
|
||||
-3.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"bus-down-alt": {
|
||||
"chance": 0.40000000596046448,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/cara_84sedan.mdl",
|
||||
"origin": [
|
||||
9448.177734375,
|
||||
2465.4091796875,
|
||||
402.39703369140625
|
||||
],
|
||||
"angles": [
|
||||
-19.69999885559082,
|
||||
-7.8000001907348633,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/cara_95sedan_wrecked.mdl",
|
||||
"origin": [
|
||||
9574.169921875,
|
||||
2354.686279296875,
|
||||
230.94760131835938
|
||||
],
|
||||
"angles": [
|
||||
-3.7000000476837158,
|
||||
66.599998474121094,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fortifications/barricade001_128_reference.mdl",
|
||||
"origin": [
|
||||
9241.9619140625,
|
||||
2593.072998046875,
|
||||
395.70574951171875
|
||||
],
|
||||
"angles": [
|
||||
-1.5000001192092896,
|
||||
-16.5,
|
||||
3.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fortifications/barricade001_128_reference.mdl",
|
||||
"origin": [
|
||||
9209.5185546875,
|
||||
2495.00341796875,
|
||||
387.2938232421875
|
||||
],
|
||||
"angles": [
|
||||
-1.5000001192092896,
|
||||
-16.5,
|
||||
3.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fortifications/barricade001_128_reference.mdl",
|
||||
"origin": [
|
||||
9276.5849609375,
|
||||
2693.54833984375,
|
||||
405.56076049804688
|
||||
],
|
||||
"angles": [
|
||||
-1.5000001192092896,
|
||||
-16.5,
|
||||
3.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_fortifications/barricade001_64_reference.mdl",
|
||||
"origin": [
|
||||
9286.923828125,
|
||||
2788.736328125,
|
||||
409.21328735351562
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
-22.400001525878906,
|
||||
5.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1004,6 +1004,61 @@
|
|||
69.000007629394531,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_street/concertinawire128.mdl",
|
||||
"origin": [
|
||||
1089.169921875,
|
||||
1763.4981689453125,
|
||||
291.31658935546875
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_street/concertinawire128.mdl",
|
||||
"origin": [
|
||||
964.45440673828125,
|
||||
1765.302490234375,
|
||||
291.97311401367188
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_street/concertinawire128.mdl",
|
||||
"origin": [
|
||||
837.82415771484375,
|
||||
1765.9117431640625,
|
||||
289.5538330078125
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
90.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "env_physics_blocker",
|
||||
"origin": [
|
||||
752.350830078125,
|
||||
2041.630615234375,
|
||||
548.03125
|
||||
],
|
||||
"scale": [
|
||||
15.0,
|
||||
240.0,
|
||||
100.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1369,7 +1424,7 @@
|
|||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"type": "prop_dynamic_override",
|
||||
"model": "models/props_junk/gnome.mdl",
|
||||
"origin": [
|
||||
-1365.762451171875,
|
||||
|
@ -1385,5 +1440,123 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"bar-block": {
|
||||
"chance": 0.30000001192092896,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_highway/plywood_03.mdl",
|
||||
"origin": [
|
||||
273.46566772460938,
|
||||
-357.96719360351562,
|
||||
0.3364105224609375
|
||||
],
|
||||
"angles": [
|
||||
90.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_highway/plywood_03.mdl",
|
||||
"origin": [
|
||||
273.00442504882812,
|
||||
-405.81011962890625,
|
||||
7.7817878723144531
|
||||
],
|
||||
"angles": [
|
||||
90.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_highway/plywood_01.mdl",
|
||||
"origin": [
|
||||
249.58372497558594,
|
||||
-385.9383544921875,
|
||||
-25.917247772216797
|
||||
],
|
||||
"angles": [
|
||||
90.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_highway/plywood_01.mdl",
|
||||
"origin": [
|
||||
253.77641296386719,
|
||||
-356.08816528320312,
|
||||
-4.7134323120117188
|
||||
],
|
||||
"angles": [
|
||||
90.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_highway/plywood_01.mdl",
|
||||
"origin": [
|
||||
253.83631896972656,
|
||||
-362.62399291992188,
|
||||
55.695259094238281
|
||||
],
|
||||
"angles": [
|
||||
90.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "prop_dynamic",
|
||||
"model": "models/props_highway/plywood_01.mdl",
|
||||
"origin": [
|
||||
252.20606994628906,
|
||||
-385.1119384765625,
|
||||
46.342216491699219
|
||||
],
|
||||
"angles": [
|
||||
90.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"sedan": {
|
||||
"chance": 0.20000000298023224,
|
||||
"variants": [
|
||||
{
|
||||
"weight": 1,
|
||||
"entities": [
|
||||
{
|
||||
"type": "_car_physics",
|
||||
"model": "models/props_vehicles/cara_95sedan.mdl",
|
||||
"origin": [
|
||||
11.371078491210938,
|
||||
-84.446060180664062,
|
||||
-2.687330961227417
|
||||
],
|
||||
"angles": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -297,12 +297,12 @@
|
|||
"type": "prop_dynamic",
|
||||
"model": "models/props_c17/metalladder001.mdl",
|
||||
"origin": [
|
||||
3513.515673828125,
|
||||
3513.5156738281248,
|
||||
3324.55859375,
|
||||
84.583740234375
|
||||
],
|
||||
"angles": [
|
||||
0.3999999761581421,
|
||||
0.39999997615814209,
|
||||
-91.400001525878906,
|
||||
0.0
|
||||
]
|
||||
|
@ -511,7 +511,7 @@
|
|||
"type": "prop_dynamic",
|
||||
"model": "models/props_vehicles/bus01.mdl",
|
||||
"origin": [
|
||||
7087.00927734375,
|
||||
7099.00927734375,
|
||||
5887.7353515625,
|
||||
41.365642547607422
|
||||
],
|
||||
|
@ -576,6 +576,19 @@
|
|||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "env_physics_blocker",
|
||||
"origin": [
|
||||
7155.35693359375,
|
||||
5903.732421875,
|
||||
134.93994140625
|
||||
],
|
||||
"scale": [
|
||||
18.0,
|
||||
240.0,
|
||||
40.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -489,24 +489,9 @@ void DirectorSpawn(specialType special, int player = -1) {
|
|||
}
|
||||
}
|
||||
|
||||
// Finds a player that is suitable (lowest intensity)
|
||||
// TODO: biased random (lower intensity : bias)
|
||||
// dice roll, #sides = #players, sort list of players by intensity
|
||||
// then use biased left dice, therefore lower intensity = higher random weight
|
||||
int g_iLastVictim;
|
||||
int GetSuitableVictim() {
|
||||
// TODO: randomize?
|
||||
return GetRandomSurvivor(1, -1);
|
||||
// ArrayList survivors = new ArrayList(2);
|
||||
// for(int i = 1; i <= MaxClients; i++) {
|
||||
// if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
|
||||
// int index = survivors.Push(i);
|
||||
// survivors.Set(index, 1, L4D_GetPlayerIntensity(i));
|
||||
// }
|
||||
// }
|
||||
// // Soe
|
||||
// survivors.SortCustom()
|
||||
|
||||
int victim = -1;
|
||||
float lowestIntensity = 0.0;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
|
|
|
@ -46,7 +46,7 @@ stock int CreateEnvBlockerScaled(const char[] entClass, const float pos[3], cons
|
|||
int entity = CreateEntityByName(entClass);
|
||||
DispatchKeyValue(entity, "targetname", ENT_BLOCKER_NAME);
|
||||
DispatchKeyValue(entity, "initialstate", "1");
|
||||
DispatchKeyValue(entity, "BlockType", "0");
|
||||
DispatchKeyValueInt(entity, "BlockType", StrEqual(entClass, "env_physics_blocker") ? 4 : 0);
|
||||
static float mins[3];
|
||||
mins = scale;
|
||||
NegateVector(mins);
|
||||
|
@ -85,8 +85,8 @@ enum struct PortalData {
|
|||
float portalOffsets[3];
|
||||
}
|
||||
static AnyMap portals;
|
||||
|
||||
stock int CreatePortal(PortalType type, const char model[64], const float pos[3], const float offset[3] = { 40.0, 40.0, 0.0 }, const float scale[3] = { 5.0, 5.0, 5.0 }) {
|
||||
#pragma unused model
|
||||
int entity = CreateEntityByName("trigger_multiple");
|
||||
if(entity == -1) return -1;
|
||||
DispatchKeyValue(entity, "spawnflags", "513");
|
||||
|
@ -160,11 +160,12 @@ stock void ClearPortalData() {
|
|||
portals.Clear();
|
||||
}
|
||||
|
||||
stock int StartPropCreate(const char[] entClass, const char[] model, const float pos[3], const float ang[3] = NULL_VECTOR, const float vel[3] = NULL_VECTOR) {
|
||||
stock int StartPropCreate(const char[] entClass, const char[] model, const float pos[3], const float ang[3] = NULL_VECTOR, const float vel[3] = NULL_VECTOR, bool hasCollision = true) {
|
||||
int entity = CreateEntityByName(entClass);
|
||||
if(entity == -1) return -1;
|
||||
DispatchKeyValue(entity, "model", model);
|
||||
DispatchKeyValue(entity, "solid", "6");
|
||||
if(hasCollision)
|
||||
DispatchKeyValue(entity, "solid", "6");
|
||||
DispatchKeyValue(entity, "targetname", ENT_PROP_NAME);
|
||||
DispatchKeyValue(entity, "disableshadows", "1");
|
||||
TeleportEntity(entity, pos, ang, vel);
|
||||
|
|
|
@ -884,6 +884,7 @@ stock bool IsAreaClear(const float pos[3], const float ang[3], const float minBo
|
|||
}
|
||||
|
||||
stock Action Timer_KillEntity(Handle h, int entity) {
|
||||
|
||||
RemoveEntity(entity);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
#define WINDSHIELD_LIST_COUNT 1
|
||||
char VEHICLE_MODEL_WINDSHIELD_KEY[WINDSHIELD_LIST_COUNT][] = {
|
||||
"models/props_vehicles/cement_truck01.mdl"
|
||||
};
|
||||
char VEHICLE_MODEL_WINDSHIELD_VAL[WINDSHIELD_LIST_COUNT][] = {
|
||||
"models/props_vehicles/cement_truck01_windows.mdl"
|
||||
};
|
||||
|
||||
bool GetWindshieldModel(const char[] vehicleModel, char[] model, int modelSize) {
|
||||
bool found = false;
|
||||
for(int i = 0; i < WINDSHIELD_LIST_COUNT; i++) {
|
||||
if(StrEqual(VEHICLE_MODEL_WINDSHIELD_KEY[i], vehicleModel)) {
|
||||
strcopy(model, modelSize, VEHICLE_MODEL_WINDSHIELD_VAL[i]);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
strcopy(model, modelSize, vehicleModel);
|
||||
ReplaceString(model, modelSize, ".mdl", "_glass.mdl");
|
||||
}
|
||||
return PrecacheModel(model);
|
||||
}
|
||||
|
||||
int SpawnCar(VariantEntityData entity) {
|
||||
if(entity.model[0] == '\0') {
|
||||
LogError("Missing model for entity with type \"%s\"", entity.type);
|
||||
|
@ -12,14 +36,12 @@ int SpawnCar(VariantEntityData entity) {
|
|||
}
|
||||
|
||||
char glassModel[64];
|
||||
strcopy(glassModel, sizeof(glassModel), entity.model);
|
||||
ReplaceString(glassModel, sizeof(glassModel), ".mdl", "_glass.mdl");
|
||||
if(StrEqual(entity.type, "_car_physics")) {
|
||||
vehicle = CreateProp("prop_physics", entity.model, entity.origin, entity.angles);
|
||||
} else {
|
||||
vehicle = CreateProp("prop_dynamic", entity.model, entity.origin, entity.angles);
|
||||
}
|
||||
if(PrecacheModel(glassModel)) {
|
||||
if(GetWindshieldModel(entity.model, glassModel, sizeof(glassModel))) {
|
||||
int glass = CreateProp("prop_dynamic", glassModel, entity.origin, entity.angles);
|
||||
if(glass != -1) {
|
||||
SetVariantString("!activator");
|
||||
|
|
599
scripting/include/randomizer/defs.sp
Normal file
599
scripting/include/randomizer/defs.sp
Normal file
|
@ -0,0 +1,599 @@
|
|||
#define MAX_SCENE_NAME_LENGTH 32
|
||||
#define MAX_INPUTS_CLASSNAME_LENGTH 64
|
||||
|
||||
int DEFAULT_COLOR[4] = { 255, 255, 255, 255 };
|
||||
|
||||
MapData g_MapData; // The global map data
|
||||
SceneSelection g_selection; // The selected scenes from the global map data
|
||||
BuilderData g_builder; // The global instance of the builder
|
||||
ArrayList g_mapTraverseSelectionStack; // For maps that traverse backwards, holds record of the selected scenes so they can be re-applied
|
||||
|
||||
int g_ropeIndex; // Unique id for ropes on spawn, is reset to 0 for every new spawn attempt
|
||||
ArrayList g_gascanRespawnQueue; // Queue that gascan respawns pop from to respawn to
|
||||
AnyMap g_gascanSpawners; // Mapping of <entity index, GascanSpawnerData>, for when a can is destroyed it can be respawned in position
|
||||
|
||||
int g_iLaserIndex;
|
||||
|
||||
public void InitGlobals() {
|
||||
g_gascanSpawners = new AnyMap();
|
||||
g_mapTraverseSelectionStack = new ArrayList(sizeof(TraverseData));
|
||||
}
|
||||
|
||||
enum struct TraverseData {
|
||||
char map[64];
|
||||
ArrayList selection;
|
||||
}
|
||||
|
||||
methodmap SceneSelection < ArrayList {
|
||||
public SceneSelection() {
|
||||
ArrayList selectedScenes = new ArrayList(sizeof(SelectedSceneData));
|
||||
return view_as<SceneSelection>(selectedScenes);
|
||||
}
|
||||
|
||||
property int Count {
|
||||
public get() {
|
||||
return (view_as<ArrayList>(this)).Length;
|
||||
}
|
||||
}
|
||||
|
||||
public void Cleanup() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
public void Activate(MapData data, int flags = 0) {
|
||||
g_ropeIndex = 0;
|
||||
SelectedSceneData aScene;
|
||||
SceneData scene;
|
||||
SceneVariantData choice;
|
||||
ArrayList list = view_as<ArrayList>(this);
|
||||
for(int i = 0; i < list.Length; i++) {
|
||||
list.GetArray(i, aScene);
|
||||
Log("Activating scene \"%s\" with %d variants", aScene.name, aScene.selectedVariantIndexes.Length);
|
||||
|
||||
// Fetch the scene that aScene marks
|
||||
if(!data.scenesKv.GetArray(aScene.name, scene, sizeof(scene))) {
|
||||
Log("WARN: Selected scene \"%s\" not found, skipping", aScene.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int v = 0; v < aScene.selectedVariantIndexes.Length; v++) {
|
||||
int variantIndex = aScene.selectedVariantIndexes.Get(v);
|
||||
|
||||
|
||||
scene.variants.GetArray(variantIndex, choice);
|
||||
activateVariant(choice, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Get(int sceneIndex, SelectedSceneData scene) {
|
||||
(view_as<ArrayList>(this)).GetArray(sceneIndex, scene);
|
||||
}
|
||||
|
||||
property ArrayList List {
|
||||
public get() {
|
||||
return view_as<ArrayList>(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddScene(SelectedSceneData aScene) {
|
||||
view_as<ArrayList>(this).PushArray(aScene);
|
||||
}
|
||||
}
|
||||
|
||||
void StoreTraverseSelection(const char[] name, SceneSelection selection) {
|
||||
// Pushes selection and map to the stack
|
||||
TraverseData data;
|
||||
strcopy(data.map, sizeof(data.map), name);
|
||||
data.selection = selection.List.Clone();
|
||||
g_mapTraverseSelectionStack.PushArray(data);
|
||||
}
|
||||
|
||||
bool PopTraverseSelection(TraverseData data) {
|
||||
if(g_mapTraverseSelectionStack.Length == 0) {
|
||||
Log("WARN: PopTraverseSelection() called but stack is empty");
|
||||
return false;
|
||||
}
|
||||
int index = g_mapTraverseSelectionStack.Length - 1;
|
||||
g_mapTraverseSelectionStack.GetArray(index, data);
|
||||
g_mapTraverseSelectionStack.Erase(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClearTraverseStack() {
|
||||
TraverseData trav;
|
||||
for(int i = 0; i < g_mapTraverseSelectionStack.Length; i++) {
|
||||
g_mapTraverseSelectionStack.GetArray(i, trav, sizeof(trav));
|
||||
delete trav.selection;
|
||||
}
|
||||
g_mapTraverseSelectionStack.Clear();
|
||||
}
|
||||
|
||||
enum struct SelectedSceneData {
|
||||
char name[MAX_SCENE_NAME_LENGTH];
|
||||
ArrayList selectedVariantIndexes;
|
||||
}
|
||||
|
||||
enum struct GascanSpawnerData {
|
||||
float origin[3];
|
||||
float angles[3];
|
||||
}
|
||||
|
||||
enum struct MapData {
|
||||
StringMap scenesKv;
|
||||
ArrayList scenes;
|
||||
ArrayList lumpEdits;
|
||||
ArrayList activeScenes;
|
||||
ArrayList gascanSpawners;
|
||||
StringMap groups;
|
||||
|
||||
void Cleanup() {
|
||||
SceneData scene;
|
||||
for(int i = 0; i < this.scenes.Length; i++) {
|
||||
this.scenes.GetArray(i, scene);
|
||||
scene.Cleanup();
|
||||
}
|
||||
delete this.scenes;
|
||||
delete this.scenesKv;
|
||||
delete this.lumpEdits;
|
||||
delete this.activeScenes;
|
||||
delete this.gascanSpawners;
|
||||
delete this.groups;
|
||||
}
|
||||
|
||||
SceneSelection GenerateSelection(int flags) {
|
||||
return selectScenes(this, flags);
|
||||
}
|
||||
|
||||
bool ApplySelection(SceneSelection selection, int flags) {
|
||||
Profiler profiler = new Profiler();
|
||||
|
||||
profiler.Start();
|
||||
selection.Activate(this, flags);
|
||||
spawnGascans(this);
|
||||
profiler.Stop();
|
||||
|
||||
// _ropeIndex = 0;
|
||||
|
||||
Log("Done applying selection in %.4f seconds", profiler.Time);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsLoaded() {
|
||||
return this.scenes != null;
|
||||
}
|
||||
}
|
||||
|
||||
enum loadFlags {
|
||||
FLAG_NONE = 0,
|
||||
FLAG_ALL_SCENES = 1, // Pick all scenes, no random chance
|
||||
FLAG_ALL_VARIANTS = 2, // Pick all variants (for debug purposes),
|
||||
FLAG_REFRESH = 4, // Load data bypassing cache
|
||||
FLAG_FORCE_ACTIVE = 8, // Similar to ALL_SCENES, bypasses % chance
|
||||
FLAG_IGNORE_TRAVERSE_STORE = 16 // Do not load stored selection from the g_mapTraverseSelections
|
||||
}
|
||||
|
||||
enum struct BuilderData {
|
||||
JSONObject mapData;
|
||||
|
||||
JSONObject selectedSceneData;
|
||||
char selectedSceneId[64];
|
||||
|
||||
JSONObject selectedVariantData;
|
||||
int selectedVariantIndex;
|
||||
|
||||
bool IsLoaded() {
|
||||
return this.mapData != null;
|
||||
}
|
||||
|
||||
void Cleanup() {
|
||||
this.selectedSceneData = null;
|
||||
this.selectedVariantData = null;
|
||||
this.selectedVariantIndex = -1;
|
||||
this.selectedSceneId[0] = '\0';
|
||||
if(this.mapData != null)
|
||||
delete this.mapData;
|
||||
// JSONcleanup_and_delete(this.mapData);
|
||||
}
|
||||
|
||||
bool SelectScene(const char[] group) {
|
||||
if(!g_builder.mapData.HasKey(group)) return false;
|
||||
this.selectedSceneData = view_as<JSONObject>(g_builder.mapData.Get(group));
|
||||
strcopy(this.selectedSceneId, sizeof(this.selectedSceneId), group);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a variant, enter -1 to not select any (scene's entities)
|
||||
*/
|
||||
bool SelectVariant(int index = -1) {
|
||||
if(this.selectedSceneData == null) LogError("SelectVariant called, but no group selected");
|
||||
JSONArray variants = view_as<JSONArray>(this.selectedSceneData.Get("variants"));
|
||||
if(index >= variants.Length) return false;
|
||||
else if(index < -1) return false;
|
||||
else if(index > -1) {
|
||||
this.selectedVariantData = view_as<JSONObject>(variants.Get(index));
|
||||
} else {
|
||||
this.selectedVariantData = null;
|
||||
}
|
||||
this.selectedVariantIndex = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddEntity(int entity, ExportType exportType = Export_Model) {
|
||||
JSONObject entityData = ExportEntity(entity, exportType);
|
||||
this.AddEntityData(entityData);
|
||||
}
|
||||
|
||||
void AddEntityData(JSONObject entityData) {
|
||||
JSONArray entities;
|
||||
if(g_builder.selectedVariantData == null) {
|
||||
// Create <scene>.entities if doesn't exist:
|
||||
if(!g_builder.selectedSceneData.HasKey("entities")) {
|
||||
g_builder.selectedSceneData.Set("entities", new JSONArray());
|
||||
}
|
||||
entities = view_as<JSONArray>(g_builder.selectedSceneData.Get("entities"));
|
||||
} else {
|
||||
entities = view_as<JSONArray>(g_builder.selectedVariantData.Get("entities"));
|
||||
}
|
||||
entities.Push(entityData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum struct SceneData {
|
||||
char name[MAX_SCENE_NAME_LENGTH];
|
||||
float chance;
|
||||
char group[MAX_SCENE_NAME_LENGTH];
|
||||
ArrayList variants;
|
||||
|
||||
void Cleanup() {
|
||||
SceneVariantData choice;
|
||||
for(int i = 0; i < this.variants.Length; i++) {
|
||||
this.variants.GetArray(i, choice);
|
||||
choice.Cleanup();
|
||||
}
|
||||
delete this.variants;
|
||||
}
|
||||
}
|
||||
|
||||
enum struct SceneVariantData {
|
||||
int weight;
|
||||
ArrayList inputsList;
|
||||
ArrayList entities;
|
||||
ArrayList forcedScenes;
|
||||
|
||||
void Cleanup() {
|
||||
delete this.inputsList;
|
||||
VariantEntityData entity;
|
||||
for(int i = 0; i < this.entities.Length; i++) {
|
||||
this.entities.GetArray(i, entity, sizeof(entity));
|
||||
entity.Cleanup();
|
||||
}
|
||||
delete this.entities;
|
||||
delete this.forcedScenes;
|
||||
}
|
||||
}
|
||||
|
||||
enum propertyType {
|
||||
PROPERTY_NONE = -1,
|
||||
PROPERTY_STRING,
|
||||
PROPERTY_INTEGER,
|
||||
PROPERTY_FLOAT
|
||||
}
|
||||
|
||||
// This is horrible but we need a way to know what the type of the netprop to set is
|
||||
enum struct PropertyStore {
|
||||
JSONObject intKv;
|
||||
JSONObject stringKv;
|
||||
JSONObject floatKv;
|
||||
|
||||
void Cleanup() {
|
||||
if(this.intKv != null) delete this.intKv;
|
||||
if(this.stringKv != null) delete this.stringKv;
|
||||
if(this.floatKv != null) delete this.floatKv;
|
||||
}
|
||||
|
||||
bool GetInt(const char[] name, int &value) {
|
||||
if(this.intKv == null) return false;
|
||||
if(!this.intKv.HasKey(name)) return false;
|
||||
value = this.intKv.GetInt(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetString(const char[] name, char[] buffer, int maxlen) {
|
||||
if(this.stringKv == null) return false;
|
||||
if(!this.stringKv.HasKey(name)) return false;
|
||||
this.stringKv.GetString(name, buffer, maxlen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetFloat(const char[] name, float &value) {
|
||||
if(this.floatKv == null) return false;
|
||||
if(!this.floatKv.HasKey(name)) return false;
|
||||
value = this.floatKv.GetFloat(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
propertyType GetPropertyType(const char[] key) {
|
||||
if(this.intKv != null && this.intKv.HasKey(key)) return PROPERTY_INTEGER;
|
||||
if(this.floatKv != null && this.floatKv.HasKey(key)) return PROPERTY_FLOAT;
|
||||
if(this.stringKv != null && this.stringKv.HasKey(key)) return PROPERTY_STRING;
|
||||
return PROPERTY_NONE;
|
||||
}
|
||||
|
||||
bool HasAny() {
|
||||
return this.intKv != null || this.floatKv != null || this.stringKv != null;
|
||||
}
|
||||
|
||||
ArrayList Keys() {
|
||||
char key[128];
|
||||
ArrayList list = new ArrayList(ByteCountToCells(128));
|
||||
JSONObjectKeys keys;
|
||||
if(this.stringKv != null) {
|
||||
keys = this.stringKv.Keys()
|
||||
while(keys.ReadKey(key, sizeof(key))) {
|
||||
list.PushString(key);
|
||||
}
|
||||
delete keys;
|
||||
}
|
||||
if(this.intKv != null) {
|
||||
keys = this.intKv.Keys()
|
||||
while(keys.ReadKey(key, sizeof(key))) {
|
||||
list.PushString(key);
|
||||
}
|
||||
delete keys;
|
||||
}
|
||||
if(this.floatKv != null) {
|
||||
keys = this.floatKv.Keys()
|
||||
while(keys.ReadKey(key, sizeof(key))) {
|
||||
list.PushString(key);
|
||||
}
|
||||
delete keys;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
StringMap Entries() {
|
||||
char key[128];
|
||||
StringMap kv = new StringMap();
|
||||
JSONObjectKeys keys;
|
||||
if(this.stringKv != null) {
|
||||
keys = this.stringKv.Keys()
|
||||
while(keys.ReadKey(key, sizeof(key))) {
|
||||
kv.SetValue(key, PROPERTY_STRING);
|
||||
}
|
||||
delete keys;
|
||||
}
|
||||
if(this.intKv != null) {
|
||||
keys = this.intKv.Keys()
|
||||
while(keys.ReadKey(key, sizeof(key))) {
|
||||
kv.SetValue(key, PROPERTY_INTEGER);
|
||||
}
|
||||
delete keys;
|
||||
}
|
||||
if(this.floatKv != null) {
|
||||
keys = this.floatKv.Keys()
|
||||
while(keys.ReadKey(key, sizeof(key))) {
|
||||
kv.SetValue(key, PROPERTY_FLOAT);
|
||||
}
|
||||
delete keys;
|
||||
}
|
||||
return kv;
|
||||
}
|
||||
}
|
||||
|
||||
enum struct VariantEntityData {
|
||||
char type[32];
|
||||
char model[128];
|
||||
char targetname[128];
|
||||
float origin[3];
|
||||
float angles[3];
|
||||
float scale[3];
|
||||
int color[4];
|
||||
|
||||
ArrayList keyframes;
|
||||
PropertyStore properties;
|
||||
JSONObject propertiesInt;
|
||||
JSONObject propertiesString;
|
||||
JSONObject propertiesFloat;
|
||||
|
||||
void Cleanup() {
|
||||
if(this.keyframes != null) {
|
||||
delete this.keyframes;
|
||||
}
|
||||
this.properties.Cleanup();
|
||||
}
|
||||
|
||||
void ApplyProperties(int entity) {
|
||||
if(!this.properties.HasAny()) return;
|
||||
char key[64], buffer[128];
|
||||
ArrayList keys = this.properties.Keys();
|
||||
for(int i = 0; i < keys.Length; i++) {
|
||||
keys.GetString(i, key, sizeof(key));
|
||||
// Only want to apply netprops (m_ prefix)
|
||||
if(key[0] == 'm' && key[1] == '_') {
|
||||
propertyType type = this.properties.GetPropertyType(key);
|
||||
Debug("netprop %s type %d", key, type);
|
||||
switch(type) {
|
||||
case PROPERTY_STRING: {
|
||||
this.properties.GetString(key, buffer, sizeof(buffer));
|
||||
Debug("Applying netprop %s (val=%s) on %d", key, buffer, entity);
|
||||
SetEntPropString(entity, Prop_Send, key, buffer);
|
||||
break;
|
||||
}
|
||||
case PROPERTY_INTEGER: {
|
||||
int val;
|
||||
this.properties.GetInt(key, val);
|
||||
Debug("Applying netprop %s (val=%d) on %d", key, val, entity);
|
||||
SetEntProp(entity, Prop_Send, key, val);
|
||||
break;
|
||||
}
|
||||
case PROPERTY_FLOAT: {
|
||||
float val;
|
||||
this.properties.GetFloat(key, val);
|
||||
Debug("Applying netprop %s (val=%f) on %d", key, val, entity);
|
||||
SetEntPropFloat(entity, Prop_Send, key, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete keys;
|
||||
}
|
||||
}
|
||||
|
||||
enum InputType {
|
||||
Input_Classname,
|
||||
Input_Targetname,
|
||||
Input_HammerId
|
||||
}
|
||||
enum struct VariantInputData {
|
||||
char name[MAX_INPUTS_CLASSNAME_LENGTH];
|
||||
InputType type;
|
||||
char input[64];
|
||||
|
||||
void Trigger() {
|
||||
int entity = -1;
|
||||
switch(this.type) {
|
||||
case Input_Classname: {
|
||||
while((entity = FindEntityByClassname(entity, this.name)) != INVALID_ENT_REFERENCE) {
|
||||
this._trigger(entity);
|
||||
}
|
||||
}
|
||||
case Input_Targetname: {
|
||||
char targetname[64];
|
||||
int count = 0;
|
||||
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE) {
|
||||
GetEntPropString(entity, Prop_Data, "m_iName", targetname, sizeof(targetname));
|
||||
if(StrEqual(targetname, this.name)) {
|
||||
this._trigger(entity);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if(count == 0) {
|
||||
PrintToServer("[Randomizer::WARN] Input TargetName=\"%s\" matched 0 entties", this.name);
|
||||
}
|
||||
}
|
||||
case Input_HammerId: {
|
||||
int targetId = StringToInt(this.name);
|
||||
int count = 0;
|
||||
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE) {
|
||||
int hammerId = GetEntProp(entity, Prop_Data, "m_iHammerID");
|
||||
if(hammerId == targetId ) {
|
||||
this._trigger(entity);
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(count == 0) {
|
||||
PrintToServer("[Randomizer::WARN] Input HammerId=%d matched 0 entties", targetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _trigger(int entity) {
|
||||
if(entity > 0 && IsValidEntity(entity)) {
|
||||
if(StrEqual(this.input, "_allow_ladder")) {
|
||||
if(HasEntProp(entity, Prop_Send, "m_iTeamNum")) {
|
||||
SetEntProp(entity, Prop_Send, "m_iTeamNum", 0);
|
||||
} else {
|
||||
Log("Warn: Entity (%d) with id \"%s\" has no teamnum for \"_allow_ladder\"", entity, this.name);
|
||||
}
|
||||
} else if(StrEqual(this.input, "_lock")) {
|
||||
AcceptEntityInput(entity, "Close");
|
||||
AcceptEntityInput(entity, "Lock");
|
||||
} else if(StrEqual(this.input, "_lock_nobreak")) {
|
||||
AcceptEntityInput(entity, "Close");
|
||||
AcceptEntityInput(entity, "Lock");
|
||||
AcceptEntityInput(entity, "SetUnbreakable");
|
||||
} else {
|
||||
char cmd[32];
|
||||
// Split input "a b" to a with variant "b"
|
||||
int len = SplitString(this.input, " ", cmd, sizeof(cmd));
|
||||
if(len > -1) {
|
||||
SetVariantString(this.input[len]);
|
||||
AcceptEntityInput(entity, cmd);
|
||||
Debug("_trigger(%d): %s (v=%s)", entity, cmd, this.input[len]);
|
||||
} else {
|
||||
Debug("_trigger(%d): %s", entity, this.input);
|
||||
AcceptEntityInput(entity, this.input);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum struct LumpEditData {
|
||||
char name[MAX_INPUTS_CLASSNAME_LENGTH];
|
||||
InputType type;
|
||||
char action[32];
|
||||
char value[64];
|
||||
|
||||
int _findLumpIndex(int startIndex = 0, EntityLumpEntry entry) {
|
||||
int length = EntityLump.Length();
|
||||
char val[64];
|
||||
Debug("Scanning for \"%s\" (type=%d)", this.name, this.type);
|
||||
for(int i = startIndex; i < length; i++) {
|
||||
entry = EntityLump.Get(i);
|
||||
int index = entry.FindKey("hammerid");
|
||||
if(index != -1) {
|
||||
entry.Get(index, "", 0, val, sizeof(val));
|
||||
if(StrEqual(val, this.name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
index = entry.FindKey("classname");
|
||||
if(index != -1) {
|
||||
entry.Get(index, "", 0, val, sizeof(val));
|
||||
Debug("%s vs %s", val, this.name);
|
||||
if(StrEqual(val, this.name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
index = entry.FindKey("targetname");
|
||||
if(index != -1) {
|
||||
entry.Get(index, "", 0, val, sizeof(val));
|
||||
if(StrEqual(val, this.name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
delete entry;
|
||||
}
|
||||
Log("Warn: Could not find any matching lump for \"%s\" (type=%d)", this.name, this.type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Trigger() {
|
||||
int index = 0;
|
||||
EntityLumpEntry entry;
|
||||
while((index = this._findLumpIndex(index, entry) != -1)) {
|
||||
// for(int i = 0; i < entry.Length; i++) {
|
||||
// entry.Get(i, a, sizeof(a), v, sizeof(v));
|
||||
// Debug("%s=%s", a, v);
|
||||
// }
|
||||
this._trigger(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void _updateKey(EntityLumpEntry entry, const char[] key, const char[] value) {
|
||||
int index = entry.FindKey(key);
|
||||
if(index != -1) {
|
||||
Debug("update key %s = %s", key, value);
|
||||
entry.Update(index, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void _trigger(EntityLumpEntry entry) {
|
||||
if(StrEqual(this.action, "setclassname")) {
|
||||
this._updateKey(entry, "classname", this.value);
|
||||
}
|
||||
|
||||
delete entry;
|
||||
}
|
||||
}
|
268
scripting/include/randomizer/loader_functions.sp
Normal file
268
scripting/include/randomizer/loader_functions.sp
Normal file
|
@ -0,0 +1,268 @@
|
|||
public bool LoadGlobalMapData(const char[] map, int flags) {
|
||||
Cleanup();
|
||||
g_selection = null;
|
||||
return ParseMapData(g_MapData, map, flags);
|
||||
}
|
||||
|
||||
public JSONObject LoadMapJson(const char[] map) {
|
||||
Debug("Loading config for %s", map);
|
||||
char filePath[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, filePath, sizeof(filePath), "data/randomizer/%s.json", map);
|
||||
if(!FileExists(filePath)) {
|
||||
Log("No map config file (data/randomizer/%s.json), not loading", map);
|
||||
return null;
|
||||
}
|
||||
|
||||
JSONObject data = JSONObject.FromFile(filePath);
|
||||
if(data == null) {
|
||||
LogError("Could not parse map config file (data/randomizer/%s.json)", map);
|
||||
return null;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
public void SaveMapJson(const char[] map, JSONObject json) {
|
||||
Debug("Saving config for %s", map);
|
||||
char filePath[PLATFORM_MAX_PATH], filePathTemp[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, filePathTemp, sizeof(filePath), "data/randomizer/%s.json.tmp", map);
|
||||
BuildPath(Path_SM, filePath, sizeof(filePath), "data/randomizer/%s.json", map);
|
||||
|
||||
json.ToFile(filePathTemp, JSON_INDENT(4));
|
||||
RenameFile(filePath, filePathTemp);
|
||||
SetFilePermissions(filePath, FPERM_U_WRITE | FPERM_U_READ | FPERM_G_WRITE | FPERM_G_READ | FPERM_O_READ);
|
||||
}
|
||||
|
||||
/// Parses map data into first parameter, bool for success
|
||||
public bool ParseMapData(MapData data, const char[] map, int flags) {
|
||||
JSONObject json = LoadMapJson(map);
|
||||
if(json == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug("Starting parsing json data");
|
||||
|
||||
data.scenes = new ArrayList(sizeof(SceneData));
|
||||
data.scenesKv = new StringMap();
|
||||
data.lumpEdits = new ArrayList(sizeof(LumpEditData));
|
||||
|
||||
Profiler profiler = new Profiler();
|
||||
profiler.Start();
|
||||
|
||||
JSONObjectKeys iterator = json.Keys();
|
||||
char key[32];
|
||||
while(iterator.ReadKey(key, sizeof(key))) {
|
||||
if(key[0] == '_') {
|
||||
if(StrEqual(key, "_lumps")) {
|
||||
JSONArray lumpsList = view_as<JSONArray>(json.Get(key));
|
||||
if(lumpsList != null) {
|
||||
for(int l = 0; l < lumpsList.Length; l++) {
|
||||
loadLumpData(data.lumpEdits, view_as<JSONObject>(lumpsList.Get(l)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Debug("Unknown special entry \"%s\", skipping", key);
|
||||
}
|
||||
} else {
|
||||
// if(data.GetType(key) != JSONType_Object) {
|
||||
// Debug("Invalid normal entry \"%s\" (not an object), skipping", key);
|
||||
// continue;
|
||||
// }
|
||||
JSONObject scene = view_as<JSONObject>(json.Get(key));
|
||||
// Parses scene data and inserts to scenes
|
||||
loadScene(data, key, scene);
|
||||
}
|
||||
}
|
||||
delete json;
|
||||
|
||||
data.groups = new StringMap();
|
||||
getSceneGroups(data, data.groups);
|
||||
|
||||
profiler.Stop();
|
||||
Log("Parsed map %s(%d) in %.4f seconds (%d scenes)", map, flags, profiler.Time, data.scenes.Length);
|
||||
delete profiler;
|
||||
return true;
|
||||
}
|
||||
|
||||
void getSceneGroups(MapData data, StringMap groups) {
|
||||
ArrayList groupList;
|
||||
SceneData scene;
|
||||
for(int i = 0; i < data.scenes.Length; i++) {
|
||||
data.scenes.GetArray(i, scene);
|
||||
if(scene.group[0] != '\0') {
|
||||
// Load it into group list
|
||||
if(!groups.GetValue(scene.group, groupList)) {
|
||||
groupList = new ArrayList();
|
||||
}
|
||||
groupList.Push(i);
|
||||
groups.SetValue(scene.group, groupList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loadScene(MapData data, const char key[MAX_SCENE_NAME_LENGTH], JSONObject sceneData) {
|
||||
SceneData scene;
|
||||
scene.name = key;
|
||||
scene.chance = sceneData.GetFloat("chance");
|
||||
if(scene.chance < 0.0 || scene.chance > 1.0) {
|
||||
LogError("Scene \"%s\" has invalid chance (%f)", scene.name, scene.chance);
|
||||
return;
|
||||
} else if(!sceneData.HasKey("variants")) {
|
||||
ThrowError("Failed to load: Scene \"%s\" has missing \"variants\" array", scene.name);
|
||||
return;
|
||||
}
|
||||
// TODO: load "entities", merge with choice.entities
|
||||
sceneData.GetString("group", scene.group, sizeof(scene.group));
|
||||
scene.variants = new ArrayList(sizeof(SceneVariantData));
|
||||
|
||||
JSONArray entities;
|
||||
if(sceneData.HasKey("entities")) {
|
||||
entities = view_as<JSONArray>(sceneData.Get("entities"));
|
||||
}
|
||||
|
||||
// Load all variants
|
||||
JSONArray variants = view_as<JSONArray>(sceneData.Get("variants"));
|
||||
for(int i = 0; i < variants.Length; i++) {
|
||||
// Parses choice and loads to scene.choices
|
||||
loadChoice(scene, view_as<JSONObject>(variants.Get(i)), entities);
|
||||
}
|
||||
|
||||
data.scenes.PushArray(scene);
|
||||
data.scenesKv.SetArray(scene.name, scene, sizeof(scene));
|
||||
}
|
||||
|
||||
void loadChoice(SceneData scene, JSONObject choiceData, JSONArray extraEntities) {
|
||||
SceneVariantData choice;
|
||||
choice.weight = choiceData.HasKey("weight") ? choiceData.GetInt("weight") : 1;
|
||||
choice.entities = new ArrayList(sizeof(VariantEntityData));
|
||||
choice.inputsList = new ArrayList(sizeof(VariantInputData));
|
||||
choice.forcedScenes = new ArrayList(ByteCountToCells(MAX_SCENE_NAME_LENGTH));
|
||||
// Load in any variant-based entities
|
||||
if(choiceData.HasKey("entities")) {
|
||||
JSONArray entities = view_as<JSONArray>(choiceData.Get("entities"));
|
||||
for(int i = 0; i < entities.Length; i++) {
|
||||
// Parses entities and loads to choice.entities
|
||||
loadChoiceEntity(choice.entities, view_as<JSONObject>(entities.Get(i)));
|
||||
}
|
||||
delete entities;
|
||||
}
|
||||
// Load in any entities that the scene has
|
||||
if(extraEntities != null) {
|
||||
for(int i = 0; i < extraEntities.Length; i++) {
|
||||
// Parses entities and loads to choice.entities
|
||||
loadChoiceEntity(choice.entities, view_as<JSONObject>(extraEntities.Get(i)));
|
||||
}
|
||||
// delete extraEntities;
|
||||
}
|
||||
// Load all inputs
|
||||
if(choiceData.HasKey("inputs")) {
|
||||
JSONArray inputsList = view_as<JSONArray>(choiceData.Get("inputs"));
|
||||
for(int i = 0; i < inputsList.Length; i++) {
|
||||
loadChoiceInput(choice.inputsList, view_as<JSONObject>(inputsList.Get(i)));
|
||||
}
|
||||
delete inputsList;
|
||||
}
|
||||
if(choiceData.HasKey("force_scenes")) {
|
||||
JSONArray scenes = view_as<JSONArray>(choiceData.Get("force_scenes"));
|
||||
char sceneId[32];
|
||||
for(int i = 0; i < scenes.Length; i++) {
|
||||
scenes.GetString(i, sceneId, sizeof(sceneId));
|
||||
choice.forcedScenes.PushString(sceneId);
|
||||
Debug("scene %s: require %s", scene.name, sceneId);
|
||||
}
|
||||
delete scenes;
|
||||
}
|
||||
scene.variants.PushArray(choice);
|
||||
}
|
||||
|
||||
void loadChoiceInput(ArrayList list, JSONObject inputData) {
|
||||
VariantInputData input;
|
||||
input.type = Input_Classname;
|
||||
// Check classname -> targetname -> hammerid
|
||||
if(!inputData.GetString("classname", input.name, sizeof(input.name))) {
|
||||
if(inputData.GetString("targetname", input.name, sizeof(input.name))) {
|
||||
input.type = Input_Targetname;
|
||||
} else {
|
||||
if(inputData.GetString("hammerid", input.name, sizeof(input.name))) {
|
||||
input.type = Input_HammerId;
|
||||
} else {
|
||||
int id = inputData.GetInt("hammerid");
|
||||
if(id > 0) {
|
||||
input.type = Input_HammerId;
|
||||
IntToString(id, input.name, sizeof(input.name));
|
||||
} else {
|
||||
LogError("Missing valid input specification (hammerid, classname, targetname)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inputData.GetString("input", input.input, sizeof(input.input));
|
||||
list.PushArray(input);
|
||||
}
|
||||
|
||||
void loadLumpData(ArrayList list, JSONObject inputData) {
|
||||
LumpEditData input;
|
||||
// Check classname -> targetname -> hammerid
|
||||
if(!inputData.GetString("classname", input.name, sizeof(input.name))) {
|
||||
if(inputData.GetString("targetname", input.name, sizeof(input.name))) {
|
||||
input.type = Input_Targetname;
|
||||
} else {
|
||||
if(inputData.GetString("hammerid", input.name, sizeof(input.name))) {
|
||||
input.type = Input_HammerId;
|
||||
} else {
|
||||
int id = inputData.GetInt("hammerid");
|
||||
if(id > 0) {
|
||||
input.type = Input_HammerId;
|
||||
IntToString(id, input.name, sizeof(input.name));
|
||||
} else {
|
||||
LogError("Missing valid input specification (hammerid, classname, targetname)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inputData.GetString("action", input.action, sizeof(input.action));
|
||||
inputData.GetString("value", input.value, sizeof(input.value));
|
||||
list.PushArray(input);
|
||||
}
|
||||
|
||||
void loadChoiceEntity(ArrayList list, JSONObject entityData) {
|
||||
VariantEntityData entity;
|
||||
entityData.GetString("model", entity.model, sizeof(entity.model));
|
||||
if(entityData.GetString("targetname", entity.targetname, sizeof(entity.targetname))) {
|
||||
Format(entity.targetname, sizeof(entity.targetname), "randomizer_%s", entity.targetname);
|
||||
}
|
||||
if(!entityData.GetString("type", entity.type, sizeof(entity.type))) {
|
||||
entity.type = "prop_dynamic";
|
||||
} /*else if(entity.type[0] == '_') {
|
||||
LogError("Invalid custom entity type \"%s\"", entity.type);
|
||||
return;
|
||||
}*/
|
||||
|
||||
if(StrEqual(entity.type, "move_rope")) {
|
||||
if(!entityData.HasKey("keyframes")) {
|
||||
LogError("move_rope entity is missing keyframes: Vec[] property");
|
||||
return;
|
||||
}
|
||||
entity.keyframes = new ArrayList(3);
|
||||
JSONArray keyframesData = view_as<JSONArray>(entityData.Get("keyframes"));
|
||||
float vec[3];
|
||||
for(int i = 0 ; i < keyframesData.Length; i++) {
|
||||
JSONArray vecArray = view_as<JSONArray>(keyframesData.Get(i));
|
||||
vec[0] = vecArray.GetFloat(0);
|
||||
vec[1] = vecArray.GetFloat(1);
|
||||
vec[2] = vecArray.GetFloat(2);
|
||||
entity.keyframes.PushArray(vec);
|
||||
}
|
||||
}
|
||||
GetVector(entityData, "origin", entity.origin);
|
||||
GetVector(entityData, "angles", entity.angles);
|
||||
GetVector(entityData, "scale", entity.scale);
|
||||
GetColor(entityData, "color", entity.color, DEFAULT_COLOR);
|
||||
if(entityData.HasKey("properties")) {
|
||||
JSONObject propRoot = view_as<JSONObject>(entityData.Get("properties"));
|
||||
if(propRoot.HasKey("int")) entity.properties.intKv = view_as<JSONObject>(propRoot.Get("int"));
|
||||
if(propRoot.HasKey("float")) entity.properties.floatKv = view_as<JSONObject>(propRoot.Get("float"));
|
||||
if(propRoot.HasKey("string")) entity.properties.stringKv = view_as<JSONObject>(propRoot.Get("string"));
|
||||
}
|
||||
list.PushArray(entity);
|
||||
}
|
230
scripting/include/randomizer/select_functions.sp
Normal file
230
scripting/include/randomizer/select_functions.sp
Normal file
|
@ -0,0 +1,230 @@
|
|||
bool IsTraverseMapA(const char[] map) {
|
||||
return String_EndsWith(map, "_a");
|
||||
}
|
||||
bool IsTraverseMapB(const char[] map) {
|
||||
// c4m1_milltown_a was added twice so _escape can pop it off and re-use
|
||||
return StrEqual(map, "c4m5_milltown_escape") || String_EndsWith(map, "_b");
|
||||
}
|
||||
|
||||
public bool LoadRunGlobalMap(const char[] map, int flags) {
|
||||
// Unless FLAG_IGNORE_TRAVERSE_STORE, if the map is the _b variant, then load the stored _a value
|
||||
SceneSelection selection;
|
||||
// Only load map data if we don't already have it
|
||||
if(g_MapData.scenes == null || g_selection == null || flags & view_as<int>(FLAG_REFRESH)) {
|
||||
if(~flags & view_as<int>(FLAG_IGNORE_TRAVERSE_STORE) && IsTraverseMapB(map) ) {
|
||||
Log("LoadRunGlobal: Trying to load traverse selection");
|
||||
TraverseData traverse;
|
||||
if(PopTraverseSelection(traverse)) {
|
||||
Debug("traverse map: %s", traverse.map);
|
||||
// Try Load the A variant
|
||||
if(LoadGlobalMapData(traverse.map, flags)) {
|
||||
selection = view_as<SceneSelection>(traverse.selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(selection == null) {
|
||||
// This is called if not traverse map or previous data not found
|
||||
Log("LoadRunGlobal: Loading & generating selection");
|
||||
if(!LoadGlobalMapData(map, flags)) {
|
||||
return false;
|
||||
}
|
||||
selection = selectScenes(g_MapData, flags);
|
||||
}
|
||||
}
|
||||
if(selection == null) {
|
||||
LogError("LoadRunGlobalMap: No selection was loaded");
|
||||
}
|
||||
|
||||
g_selection = selection;
|
||||
|
||||
return g_MapData.ApplySelection(selection, flags);
|
||||
}
|
||||
|
||||
void trySelectScene(SceneSelection selection, SceneData scene, int flags) {
|
||||
// Use the .chance field unless FLAG_ALL_SCENES or FLAG_FORCE_ACTIVE is set
|
||||
if(~flags & view_as<int>(FLAG_ALL_SCENES) && ~flags & view_as<int>(FLAG_FORCE_ACTIVE) && GetURandomFloat() > scene.chance) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(scene.variants.Length == 0) {
|
||||
LogError("Warn: No variants were found for scene \"%s\"", scene.name);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: select variant...
|
||||
SelectedSceneData aScene;
|
||||
aScene.name = scene.name;
|
||||
aScene.selectedVariantIndexes = new ArrayList();
|
||||
|
||||
ArrayList choices = new ArrayList();
|
||||
SceneVariantData choice;
|
||||
int chosenIndex;
|
||||
Debug("Scene %s has %d variants", scene.name, scene.variants.Length);
|
||||
// Weighted random: Push N times dependent on weight
|
||||
for(int i = 0; i < scene.variants.Length; i++) {
|
||||
scene.variants.GetArray(i, choice);
|
||||
if(flags & view_as<int>(FLAG_ALL_VARIANTS)) {
|
||||
aScene.selectedVariantIndexes.Push(i);
|
||||
} else {
|
||||
if(choice.weight <= 0) {
|
||||
PrintToServer("Warn: Variant %d in scene %s has invalid weight", i, scene.name);
|
||||
continue;
|
||||
}
|
||||
for(int c = 0; c < choice.weight; c++) {
|
||||
choices.Push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(flags & view_as<int>(FLAG_ALL_VARIANTS)) {
|
||||
|
||||
} else if(choices.Length > 0) {
|
||||
// Pick a random variant from list
|
||||
chosenIndex = GetURandomInt() % choices.Length;
|
||||
chosenIndex = choices.Get(chosenIndex);
|
||||
Log("Chosen scene \"%s\" with variant #%d", scene.name, chosenIndex);
|
||||
|
||||
aScene.selectedVariantIndexes.Push(chosenIndex);
|
||||
}
|
||||
delete choices;
|
||||
|
||||
selection.AddScene(aScene);
|
||||
}
|
||||
|
||||
void selectGroups(SceneSelection selection, MapData data, int flags) {
|
||||
StringMapSnapshot snapshot = data.groups.Snapshot();
|
||||
char key[MAX_SCENE_NAME_LENGTH];
|
||||
ArrayList groupList;
|
||||
SceneData scene;
|
||||
for(int i = 0; i < snapshot.Length; i++) {
|
||||
snapshot.GetKey(i, key, sizeof(key));
|
||||
data.groups.GetValue(key, groupList);
|
||||
|
||||
// Select a random scene from the group:
|
||||
int index = GetURandomInt() % groupList.Length;
|
||||
index = groupList.Get(index);
|
||||
data.scenes.GetArray(index, scene);
|
||||
|
||||
Debug("Selected scene \"%s\" for group %s (%d members)", scene.name, key, groupList.Length);
|
||||
trySelectScene(selection, scene, flags);
|
||||
delete groupList;
|
||||
}
|
||||
delete snapshot;
|
||||
}
|
||||
|
||||
void selectForcedScenes(SceneSelection selection, MapData data, int flags) {
|
||||
// Traverse active scenes, loading any other scene it requires (via .force_scenes)
|
||||
SelectedSceneData aScene;
|
||||
SceneVariantData choice;
|
||||
SceneData scene;
|
||||
// list of scenes that will need to be forced if not already:
|
||||
ArrayList forcedScenes = new ArrayList(ByteCountToCells(MAX_SCENE_NAME_LENGTH));
|
||||
char key[MAX_SCENE_NAME_LENGTH];
|
||||
for(int i = 0; i < selection.Count; i++) {
|
||||
selection.Get(i, aScene);
|
||||
// Load scene from active scene entry
|
||||
if(!data.scenesKv.GetArray(aScene.name, scene, sizeof(scene))) {
|
||||
// this shouldn't happen
|
||||
Log("WARN: scene \"%s\" not found in scene selection", aScene.name);
|
||||
// can't find scene, ignore
|
||||
continue;
|
||||
}
|
||||
for(int v = 0; v < aScene.selectedVariantIndexes.Length; v++) {
|
||||
aScene.selectedVariantIndexes.GetArray(v, choice);
|
||||
// If the choice has forced scenes
|
||||
if(choice.forcedScenes != null) {
|
||||
// Add each scene to the list to be added
|
||||
for(int j = 0; j < choice.forcedScenes.Length; j++) {
|
||||
choice.forcedScenes.GetString(j, key, sizeof(key));
|
||||
forcedScenes.PushString(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(forcedScenes.Length > 0) {
|
||||
Debug("Loading %d forced scenes", forcedScenes.Length);
|
||||
}
|
||||
// Iterate and activate any forced scenes
|
||||
for(int i = 0; i < forcedScenes.Length; i++) {
|
||||
forcedScenes.GetString(i, key, sizeof(key));
|
||||
// Check if scene was already loaded
|
||||
bool isSceneAlreadyLoaded = false;
|
||||
for(int j = 0; j < data.activeScenes.Length; j++) {
|
||||
data.activeScenes.GetArray(j, aScene);
|
||||
if(StrEqual(aScene.name, key)) {
|
||||
isSceneAlreadyLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(isSceneAlreadyLoaded) continue;
|
||||
data.scenesKv.GetArray(key, scene, sizeof(scene));
|
||||
trySelectScene(selection, scene, flags | view_as<int>(FLAG_FORCE_ACTIVE));
|
||||
}
|
||||
delete forcedScenes;
|
||||
}
|
||||
|
||||
// Selects what scenes and its variants to apply and returns list - does not activate
|
||||
SceneSelection selectScenes(MapData data, int flags = 0) {
|
||||
SceneData scene;
|
||||
SceneSelection selection = new SceneSelection();
|
||||
|
||||
Profiler profiler = new Profiler();
|
||||
profiler.Start();
|
||||
|
||||
for(int i = 0; i < data.scenes.Length; i++) {
|
||||
data.scenes.GetArray(i, scene);
|
||||
if(scene.group[0] == '\0') {
|
||||
trySelectScene(selection, scene, flags);
|
||||
}
|
||||
}
|
||||
selectGroups(selection, data, flags);
|
||||
selectForcedScenes(selection, data, flags);
|
||||
|
||||
profiler.Stop();
|
||||
Log("Done generating selection in %.4f seconds", profiler.Time);
|
||||
return selection;
|
||||
}
|
||||
|
||||
void spawnGascans(MapData data) {
|
||||
if(data.gascanSpawners != null && data.gascanSpawners.Length > 0) {
|
||||
// Iterate through every gascan until we run out - picking a random spawner each time
|
||||
int entity = -1;
|
||||
char targetname[9];
|
||||
GascanSpawnerData spawner;
|
||||
int spawnerCount = data.gascanSpawners.Length;
|
||||
int count;
|
||||
while((entity = FindEntityByClassname(entity, "weapon_gascan")) != INVALID_ENT_REFERENCE) {
|
||||
GetEntPropString(entity, Prop_Data, "m_iName", targetname, sizeof(targetname));
|
||||
int hammerid = GetEntProp(entity, Prop_Data, "m_iHammerID");
|
||||
int glowColor = GetEntProp(entity, Prop_Send, "m_glowColorOverride"); // check if white
|
||||
if(hammerid == 0 && glowColor == 16777215 && targetname[0] == '\0' && !g_gascanSpawners.ContainsKey(entity)) {
|
||||
// Found a valid gascan, apply a random spawner
|
||||
int spawnerIndex = GetRandomInt(0, data.gascanSpawners.Length - 1);
|
||||
data.gascanSpawners.GetArray(spawnerIndex, spawner);
|
||||
data.gascanSpawners.Erase(spawnerIndex); // only want one can to use this spawner
|
||||
|
||||
AssignGascan(entity, spawner);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
Debug("Assigned %d gascans to %d spawners", count, spawnerCount);
|
||||
}
|
||||
}
|
||||
|
||||
void activateVariant(SceneVariantData choice, int flags) {
|
||||
#pragma unused flags
|
||||
VariantEntityData entity;
|
||||
for(int i = 0; i < choice.entities.Length; i++) {
|
||||
choice.entities.GetArray(i, entity);
|
||||
spawnEntity(entity);
|
||||
}
|
||||
|
||||
if(choice.inputsList.Length > 0) {
|
||||
VariantInputData input;
|
||||
for(int i = 0; i < choice.inputsList.Length; i++) {
|
||||
choice.inputsList.GetArray(i, input);
|
||||
input.Trigger();
|
||||
}
|
||||
}
|
||||
}
|
40
scripting/include/randomizer/util.sp
Normal file
40
scripting/include/randomizer/util.sp
Normal file
|
@ -0,0 +1,40 @@
|
|||
public bool GetVector(JSONObject obj, const char[] key, float out[3]) {
|
||||
if(!obj.HasKey(key)) return false;
|
||||
JSONArray vecArray = view_as<JSONArray>(obj.Get(key));
|
||||
if(vecArray != null) {
|
||||
out[0] = vecArray.GetFloat(0);
|
||||
out[1] = vecArray.GetFloat(1);
|
||||
out[2] = vecArray.GetFloat(2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GetColor(JSONObject obj, const char[] key, int out[4], int defaultColor[4]) {
|
||||
if(obj.HasKey(key)) {
|
||||
JSONArray vecArray = view_as<JSONArray>(obj.Get(key));
|
||||
out[0] = vecArray.GetInt(0);
|
||||
out[1] = vecArray.GetInt(1);
|
||||
out[2] = vecArray.GetInt(2);
|
||||
if(vecArray.Length == 4)
|
||||
out[3] = vecArray.GetInt(3);
|
||||
else
|
||||
out[3] = 255;
|
||||
} else {
|
||||
out = defaultColor;
|
||||
}
|
||||
}
|
||||
|
||||
stock JSONArray FromFloatArray(float[] vec, int count) {
|
||||
JSONArray arr = new JSONArray();
|
||||
for(int i = 0 ; i < count; i++) {
|
||||
arr.PushFloat(vec[i]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
stock JSONArray FromIntArray(int[] vec, int count) {
|
||||
JSONArray arr = new JSONArray();
|
||||
for(int i = 0 ; i < count; i++) {
|
||||
arr.PushInt(vec[i]);
|
||||
}
|
||||
return arr;
|
||||
}
|
|
@ -55,11 +55,6 @@
|
|||
#undef REQUIRE_PLUGIN
|
||||
#include <CreateSurvivorBot>
|
||||
|
||||
#define L4D2_WEPUPGFLAG_NONE (0 << 0)
|
||||
#define L4D2_WEPUPGFLAG_INCENDIARY (1 << 0)
|
||||
#define L4D2_WEPUPGFLAG_EXPLOSIVE (1 << 1)
|
||||
#define L4D2_WEPUPGFLAG_LASER (1 << 2)
|
||||
|
||||
#define AMMOPACK_ENTID 0
|
||||
#define AMMOPACK_USERS 1
|
||||
|
||||
|
@ -1779,7 +1774,7 @@ Action Timer_UpdateHud(Handle h) {
|
|||
void PopulateItems() {
|
||||
if(g_areItemsPopulated) return;
|
||||
UpdateSurvivorCount();
|
||||
PrintToServer("[EPI:TEMP] PopulateItems hasRan=%b finale=%b willRun=%b players=%d", g_areItemsPopulated, L4D_IsMissionFinalMap(true), !g_areItemsPopulated&&IsEPIActive, g_realSurvivorCount);
|
||||
PrintToServer("[EPI:TEMP] PopulateItems hasRan=%b finale=%b willRun=%b players=%d", g_areItemsPopulated, L4D_IsMissionFinalMap(true), !g_areItemsPopulated&&IsEPIActive(), g_realSurvivorCount);
|
||||
if(!IsEPIActive()) return;
|
||||
|
||||
g_areItemsPopulated = true;
|
||||
|
@ -1821,6 +1816,20 @@ void PopulateItems() {
|
|||
PopulateCabinets();
|
||||
}
|
||||
|
||||
int CalculateExtraDefibCount() {
|
||||
if(L4D_IsMissionFinalMap()) {
|
||||
int maxCount = g_survivorCount - 4;
|
||||
if(maxCount < 0) maxCount = 0;
|
||||
|
||||
return DiceRoll(0, maxCount, 2, BIAS_LEFT);
|
||||
} else if(g_survivorCount > 4) {
|
||||
float chance = float(g_survivorCount) / 64.0;
|
||||
return GetRandomFloat() > chance ? 1 : 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateItemSpawns(int minWalls = 4) {
|
||||
ArrayList navs = new ArrayList();
|
||||
L4D_GetAllNavAreas(navs);
|
||||
|
@ -1837,6 +1846,9 @@ void PopulateItemSpawns(int minWalls = 4) {
|
|||
float mapFlowMax = L4D2Direct_GetMapMaxFlowDistance();
|
||||
PrintToServer("[EPI] PopulateItemSpawns: flow[0, %f]", mapFlowMax);
|
||||
int maxSpawns = RoundFloat(mapFlowMax / MAX_RANDOM_SPAWNS);
|
||||
int defibCount = CalculateExtraDefibCount();
|
||||
bool isFinale = L4D_IsMissionFinalMap();
|
||||
|
||||
for(int i = 0; i < navs.Length; i++) {
|
||||
Address nav = navs.Get(i);
|
||||
int spawnFlags = L4D_GetNavArea_SpawnAttributes(nav);
|
||||
|
@ -1866,8 +1878,19 @@ void PopulateItemSpawns(int minWalls = 4) {
|
|||
}
|
||||
if(wpn == -1) continue;
|
||||
if(++count >= maxSpawns) break;
|
||||
} else if(defibCount > 0) {
|
||||
if(isFinale) {
|
||||
if(spawnFlags & NAV_SPAWN_FINALE) {
|
||||
CreateWeaponSpawn(pos, "weapon_defibrilator", tier);
|
||||
defibCount--;
|
||||
}
|
||||
} else {
|
||||
CreateWeaponSpawn(pos, "weapon_defibrilator", tier);
|
||||
defibCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
PrintToServer("[EPI] Spawned %d/%d new item spawns (tier=%d)", count, maxSpawns, tier);
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue