mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-07-12 06:55:12 +00:00
Merge branch 'master' into force-dome
This commit is contained in:
commit
a5a1ded98e
28 changed files with 1782 additions and 115 deletions
|
|
@ -0,0 +1,80 @@
|
|||
-- Fix scoring functions and triggers
|
||||
-- Cleanup
|
||||
|
||||
-- fix trigger function (OLD for DELETE actions)
|
||||
-- fix capture counter
|
||||
-- fix functions by using correct variable names instead of out of scope table columns
|
||||
-- improve functions to use index with ON CONFLICT
|
||||
-- cleanup by removing return values,
|
||||
|
||||
CREATE OR REPLACE FUNCTION fn_buildingcapture_updateOnDelete()
|
||||
RETURNS TRIGGER
|
||||
AS
|
||||
$$
|
||||
DECLARE
|
||||
oldAvatarId INT;
|
||||
oldZoneId INT;
|
||||
oldBuildingId INT;
|
||||
oldExp INT;
|
||||
oldType TEXT;
|
||||
BEGIN
|
||||
oldAvatarId := OLD.avatar_id;
|
||||
oldZoneId := OLD.zone_id;
|
||||
oldBuildingId := OLD.building_id;
|
||||
oldExp := OLD.exp;
|
||||
oldType := OLD.exp_type;
|
||||
|
||||
IF (oldType = 'bep') THEN
|
||||
PERFORM proc_expbuildingcapture_addEntryIfNone(oldAvatarId, oldBuildingId, oldZoneId);
|
||||
UPDATE expbuildingcapture
|
||||
SET
|
||||
captures = captures + 1,
|
||||
bep = bep + oldExp
|
||||
WHERE avatar_id = oldAvatarId AND zone_id = oldZoneId AND building_id = oldBuildingId;
|
||||
|
||||
ELSIF (oldType = 'cep') THEN
|
||||
PERFORM proc_expbuildingcapture_addEntryIfNone(oldAvatarId, oldBuildingId, oldZoneId);
|
||||
UPDATE expbuildingcapture
|
||||
SET
|
||||
captures = captures + 1,
|
||||
cep = cep + oldExp
|
||||
WHERE avatar_id = oldAvatarId AND zone_id = oldZoneId AND building_id = oldBuildingId;
|
||||
|
||||
ELSIF (oldType = 'llu') THEN
|
||||
PERFORM proc_llubuildingcapture_addEntryIfNone(oldAvatarId, oldBuildingId, oldZoneId);
|
||||
UPDATE llubuildingcapture
|
||||
SET
|
||||
captures = captures + 1,
|
||||
exp = exp + oldExp
|
||||
WHERE avatar_id = oldAvatarId AND zone_id = oldZoneId AND building_id = oldBuildingId;
|
||||
END IF;
|
||||
|
||||
RETURN OLD;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
DROP FUNCTION proc_expbuildingcapture_addEntryIfNone;
|
||||
CREATE OR REPLACE FUNCTION proc_expbuildingcapture_addEntryIfNone
|
||||
(avatarId INT, buildingId INT, zoneId INT)
|
||||
RETURNS VOID
|
||||
AS
|
||||
$$
|
||||
BEGIN
|
||||
INSERT INTO expbuildingcapture (avatar_id, zone_id, building_id, captures, bep, cep)
|
||||
VALUES (avatarId, zoneId, buildingId, 0, 0, 0)
|
||||
ON CONFLICT (avatar_id, zone_id, building_id) DO NOTHING;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
DROP FUNCTION proc_llubuildingcapture_addEntryIfNone;
|
||||
CREATE OR REPLACE FUNCTION proc_llubuildingcapture_addEntryIfNone
|
||||
(avatarId INT, buildingId INT, zoneId INT)
|
||||
RETURNS VOID
|
||||
AS
|
||||
$$
|
||||
BEGIN
|
||||
INSERT INTO llubuildingcapture (avatar_id, zone_id, building_id, captures, exp)
|
||||
VALUES (avatarId, zoneId, buildingId, 0, 0)
|
||||
ON CONFLICT (avatar_id, zone_id, building_id) DO NOTHING;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
|
@ -64,7 +64,7 @@ add_property mini_chaingun equiptime 750
|
|||
add_property mini_chaingun holstertime 750
|
||||
add_property nano_dispenser equiptime 750
|
||||
add_property nano_dispenser holstertime 750
|
||||
add_property oicw allowed true
|
||||
add_property oicw allowed false
|
||||
add_property pellet_gun equiptime 600
|
||||
add_property pellet_gun holstertime 600
|
||||
add_property peregrine_flight requirement_award0 false
|
||||
|
|
|
|||
135
server/src/main/resources/overrides/game_objectstz.adb.lst
Normal file
135
server/src/main/resources/overrides/game_objectstz.adb.lst
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
add_property ace firemode1_change_ammo_cert standard_assault
|
||||
add_property ace firemode2_change_ammo_cert standard_assault
|
||||
add_property ace firemode3_change_ammo_cert standard_assault
|
||||
add_property ace requirement_certification0 standard_assault
|
||||
add_property ace_deployable requirement_certification0 standard_assault
|
||||
add_property advanced_ace requirement_certification0 standard_assault
|
||||
add_property advanced_ace firemode0_requirement_certification0 standard_assault
|
||||
add_property advanced_ace firemode1_requirement_certification0 standard_assault
|
||||
add_property advanced_ace firemode2_requirement_certification0 standard_assault
|
||||
add_property anniversary_gun requirement_certification0 standard_assault
|
||||
add_property anniversary_guna requirement_certification0 standard_assault
|
||||
add_property anniversary_gunb requirement_certification0 standard_assault
|
||||
add_property applicator requirement_certification0 standard_assault
|
||||
add_property bank requirement_certification0 standard_assault
|
||||
add_property bolt_driver requirement_certification0 standard_assault
|
||||
add_property boomer_trigger requirement_certification0 standard_assault
|
||||
add_property cycler requirement_certification0 standard_assault
|
||||
add_property cycler_v2 requirement_certification0 standard_assault
|
||||
add_property cycler_v3 requirement_certification0 standard_assault
|
||||
add_property cycler_v4 requirement_certification0 standard_assault
|
||||
add_property dynomite allowed true
|
||||
add_property flamethrower requirement_certification0 standard_assault
|
||||
add_property flechette requirement_certification0 standard_assault
|
||||
add_property gauss requirement_certification0 standard_assault
|
||||
add_property heavy_sniper requirement_certification0 standard_assault
|
||||
add_property hunterseeker requirement_certification0 standard_assault
|
||||
add_property lancer requirement_certification0 standard_assault
|
||||
add_property lasher requirement_certification0 standard_assault
|
||||
add_property lite_armor requirement_certification0 standard_armor
|
||||
add_property maelstrom purchase_module none
|
||||
add_property maelstrom requirement_certification0 standard_assault
|
||||
add_property med_armor requirement_certification0 standard_armor
|
||||
add_property mini_chaingun requirement_certification0 standard_assault
|
||||
add_property nano_dispenser requirement_certification0 standard_assault
|
||||
add_property nchev_antiaircraft requirement_certification0 standard_armor
|
||||
add_property nchev_antipersonnel requirement_certification0 standard_armor
|
||||
add_property nchev_antivehicular requirement_certification0 standard_armor
|
||||
add_property oicw requirement_certification0 standard_assault
|
||||
add_property pellet_gun allowed true
|
||||
add_property pellet_gun_ammo allowed true
|
||||
add_property phoenix requirement_certification0 standard_assault
|
||||
add_property pulsar requirement_certification0 standard_assault
|
||||
add_property punisher requirement_certification0 standard_assault
|
||||
add_property r_shotgun requirement_certification0 standard_assault
|
||||
add_property radiator purchase_module none
|
||||
add_property radiator requirement_certification0 standard_assault
|
||||
add_property rocklet requirement_certification0 standard_assault
|
||||
add_property six_shooter allowed true
|
||||
add_property six_shooter_ammo allowed true
|
||||
add_property spiker purchase_module none
|
||||
add_property spiker requirement_certification0 standard_assault
|
||||
add_property stealth_armor requirement_certification0 standard_armor
|
||||
add_property striker requirement_certification0 standard_assault
|
||||
add_property thumper requirement_certification0 standard_assault
|
||||
add_property trek requirement_certification0 standard_assault
|
||||
add_property trhev_antiaircraft requirement_certification0 standard_armor
|
||||
add_property trhev_antipersonnel requirement_certification0 standard_armor
|
||||
add_property trhev_antivehicular requirement_certification0 standard_armor
|
||||
add_property vshev_antiaircraft requirement_certification0 standard_armor
|
||||
add_property vshev_antipersonnel requirement_certification0 standard_armor
|
||||
add_property vshev_antivehicular requirement_certification0 standard_armor
|
||||
add_property winchester allowed true
|
||||
add_property winchester_ammo allowed true
|
||||
add_property order_terminal forsale_dynomite ordertype_weapon
|
||||
add_property order_terminal forsale_pellet_gun ordertype_weapon
|
||||
add_property order_terminal forsale_pellet_gun_ammo
|
||||
add_property order_terminal forsale_six_shooter ordertype_weapon
|
||||
add_property order_terminal forsale_six_shooter_ammo
|
||||
add_property order_terminal forsale_winchester ordertype_weapon
|
||||
add_property order_terminal forsale_winchester_ammo
|
||||
add_property portable_order_terminal forsale_dynomite ordertype_weapon
|
||||
add_property portable_order_terminal forsale_pellet_gun ordertype_weapon
|
||||
add_property portable_order_terminal forsale_pellet_gun_ammo
|
||||
add_property portable_order_terminal forsale_six_shooter ordertype_weapon
|
||||
add_property portable_order_terminal forsale_six_shooter_ammo
|
||||
add_property portable_order_terminal forsale_winchester ordertype_weapon
|
||||
add_property portable_order_terminal forsale_winchester_ammo
|
||||
add_property ams requirement_certification0 vehicles
|
||||
add_property apc requirement_certification0 vehicles
|
||||
add_property aphelion_flight requirement_award0 false
|
||||
add_property aphelion_flight requirement_certification0 vehicles
|
||||
add_property aphelion_gunner requirement_certification0 vehicles
|
||||
add_property aphelion_laser requirement_certification0 vehicles
|
||||
add_property aphelion_starfire requirement_certification0 vehicles
|
||||
add_property aurora requirement_certification0 vehicles
|
||||
add_property bfr_terminal requirement_certification0 vehicles
|
||||
add_property colossus_burster requirement_certification0 vehicles
|
||||
add_property colossus_chaingun requirement_certification0 vehicles
|
||||
add_property colossus_flight requirement_award0 false
|
||||
add_property colossus_flight requirement_certification0 vehicles
|
||||
add_property colossus_gunner requirement_certification0 vehicles
|
||||
add_property delivererv requirement_certification0 vehicles
|
||||
add_property dropship requirement_certification0 vehicles
|
||||
add_property flail purchase_module none
|
||||
add_property flail requirement_certification0 vehicles
|
||||
add_property fury requirement_certification0 vehicles
|
||||
add_property galaxy_gunship requirement_certification0 vehicles
|
||||
add_property liberator purchase_tech_plant false
|
||||
add_property liberator requirement_certification0 vehicles
|
||||
add_property lightgunship purchase_tech_plant false
|
||||
add_property lightgunship requirement_certification0 vehicles
|
||||
add_property lightning requirement_certification0 vehicles
|
||||
add_property lodestar requirement_certification0 vehicles
|
||||
add_property magrider purchase_tech_plant false
|
||||
add_property magrider requirement_certification0 vehicles
|
||||
add_property mediumtransport requirement_certification0 vehicles
|
||||
add_property mosquito requirement_certification0 vehicles
|
||||
add_property peregrine_flight requirement_award0 false
|
||||
add_property peregrine_flight requirement_certification0 vehicles
|
||||
add_property peregrine_gunner requirement_certification0 vehicles
|
||||
add_property peregrine_mechhammer requirement_certification0 vehicles
|
||||
add_property peregrine_sparrow requirement_certification0 vehicles
|
||||
add_property phantasm purchase_tech_plant false
|
||||
add_property phantasm requirement_certification0 vehicles
|
||||
add_property prowler purchase_tech_plant false
|
||||
add_property prowler requirement_certification0 vehicles
|
||||
add_property quadassault requirement_certification0 vehicles
|
||||
add_property quadstealth requirement_certification0 vehicles
|
||||
add_property router requirement_certification0 vehicles
|
||||
add_property skyguard purchase_tech_plant false
|
||||
add_property skyguard requirement_certification0 vehicles
|
||||
add_property switchblade purchase_module none
|
||||
add_property switchblade requirement_certification0 vehicles
|
||||
add_property threemanheavybuggy requirement_certification0 vehicles
|
||||
add_property thunderer requirement_certification0 vehicles
|
||||
add_property two_man_assault_buggy requirement_certification0 vehicles
|
||||
add_property twomanheavybuggy requirement_certification0 vehicles
|
||||
add_property twomanhoverbuggy requirement_certification0 vehicles
|
||||
add_property vanguard purchase_tech_plant false
|
||||
add_property vanguard requirement_certification0 vehicles
|
||||
add_property vulture purchase_tech_plant false
|
||||
add_property vulture requirement_award0 false
|
||||
add_property vulture requirement_certification0 vehicles
|
||||
add_property wasp purchase_tech_plant false
|
||||
add_property wasp requirement_certification0 vehicles
|
||||
184
src/main/resources/zonemaps/map14.json
Normal file
184
src/main/resources/zonemaps/map14.json
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
[
|
||||
{
|
||||
"Id": 0,
|
||||
"ObjectName": "vr_training",
|
||||
"ObjectType": "vr_training",
|
||||
"Owner": null,
|
||||
"AbsX": 500.0,
|
||||
"AbsY": 530.0,
|
||||
"AbsZ": 13.37697,
|
||||
"Yaw": 360.0,
|
||||
"GUID": 1,
|
||||
"MapID": 1,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 9,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 483.33,
|
||||
"AbsY": 527.669,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 90.0,
|
||||
"GUID": 65,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 10,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 483.347,
|
||||
"AbsY": 529.654,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 90.0,
|
||||
"GUID": 66,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 6,
|
||||
"ObjectName": "spawn_pad",
|
||||
"ObjectType": "spawn_pad",
|
||||
"Owner": 0,
|
||||
"AbsX": 500.0,
|
||||
"AbsY": 530.0,
|
||||
"AbsZ": 13.37697,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 833,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 7,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 489.495,
|
||||
"AbsY": 540.36,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 150.0,
|
||||
"GUID": 82,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 11,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 489.512,
|
||||
"AbsY": 516.936,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 30.0,
|
||||
"GUID": 81,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 12,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 491.222,
|
||||
"AbsY": 515.929,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 30.0,
|
||||
"GUID": 97,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 8,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 491.201,
|
||||
"AbsY": 541.382,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 150.0,
|
||||
"GUID": 98,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 509.539,
|
||||
"AbsY": 515.922,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 330.0,
|
||||
"GUID": 113,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 13,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 509.518,
|
||||
"AbsY": 541.376,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 210.0,
|
||||
"GUID": 114,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 511.245,
|
||||
"AbsY": 516.945,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 330.0,
|
||||
"GUID": 129,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 511.229,
|
||||
"AbsY": 540.368,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 210.0,
|
||||
"GUID": 130,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 517.393,
|
||||
"AbsY": 527.651,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 270.0,
|
||||
"GUID": 145,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"ObjectName": "order_terminal",
|
||||
"ObjectType": "order_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 517.411,
|
||||
"AbsY": 529.636,
|
||||
"AbsZ": 14.9649706,
|
||||
"Yaw": 270.0,
|
||||
"GUID": 146,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
}
|
||||
]
|
||||
977
src/main/resources/zonemaps/map15.json
Executable file
977
src/main/resources/zonemaps/map15.json
Executable file
|
|
@ -0,0 +1,977 @@
|
|||
[
|
||||
{
|
||||
"Id": 72,
|
||||
"ObjectName": "repair_silo_11115",
|
||||
"ObjectType": "repair_silo",
|
||||
"Owner": null,
|
||||
"AbsX": 2469.91,
|
||||
"AbsY": 1845.11,
|
||||
"AbsZ": 23.33,
|
||||
"Yaw": 245.0,
|
||||
"GUID": 1,
|
||||
"MapID": 11115,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 27,
|
||||
"ObjectName": "vt_air_vehicle",
|
||||
"ObjectType": "vt_air_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 1296.0,
|
||||
"AbsY": 1778.0,
|
||||
"AbsZ": 14.6012754,
|
||||
"Yaw": 150.0,
|
||||
"GUID": 17,
|
||||
"MapID": 10,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 30,
|
||||
"ObjectName": "vt_air_vehicle",
|
||||
"ObjectType": "vt_air_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 2422.0,
|
||||
"AbsY": 1190.0,
|
||||
"AbsZ": 15.4802084,
|
||||
"Yaw": 138.0,
|
||||
"GUID": 19,
|
||||
"MapID": 11,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 33,
|
||||
"ObjectName": "vt_air_vehicle",
|
||||
"ObjectType": "vt_air_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 2788.0,
|
||||
"AbsY": 2582.0,
|
||||
"AbsZ": 19.1222878,
|
||||
"Yaw": 360.0,
|
||||
"GUID": 21,
|
||||
"MapID": 12,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 24,
|
||||
"ObjectName": "vt_dropship",
|
||||
"ObjectType": "vt_dropship",
|
||||
"Owner": null,
|
||||
"AbsX": 1716.0,
|
||||
"AbsY": 1860.0,
|
||||
"AbsZ": 32.4491119,
|
||||
"Yaw": 360.0,
|
||||
"GUID": 29,
|
||||
"MapID": 9,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 66,
|
||||
"ObjectName": "vt_spawn_11112",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 1309.08,
|
||||
"AbsY": 2221.91,
|
||||
"AbsZ": 15.18,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 33,
|
||||
"MapID": 11112,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 36,
|
||||
"ObjectName": "vt_spawn_11091",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 1441.54,
|
||||
"AbsY": 1487.18,
|
||||
"AbsZ": 17.76,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 35,
|
||||
"MapID": 11091,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 38,
|
||||
"ObjectName": "vt_spawn_11092",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 1447.23,
|
||||
"AbsY": 1900.92,
|
||||
"AbsZ": 12.31,
|
||||
"Yaw": 338.0,
|
||||
"GUID": 37,
|
||||
"MapID": 11092,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 64,
|
||||
"ObjectName": "vt_spawn_11111",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 1481.31,
|
||||
"AbsY": 2427.31,
|
||||
"AbsZ": 16.62,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 39,
|
||||
"MapID": 11111,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 68,
|
||||
"ObjectName": "vt_spawn_11113",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 1526.13,
|
||||
"AbsY": 981.66,
|
||||
"AbsZ": 20.92,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 41,
|
||||
"MapID": 11113,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 58,
|
||||
"ObjectName": "vt_spawn_11106",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 1792.6,
|
||||
"AbsY": 1748.62,
|
||||
"AbsZ": 12.65,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 43,
|
||||
"MapID": 11106,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 62,
|
||||
"ObjectName": "vt_spawn_11109",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 1828.01,
|
||||
"AbsY": 2390.93,
|
||||
"AbsZ": 14.77,
|
||||
"Yaw": 324.0,
|
||||
"GUID": 45,
|
||||
"MapID": 11109,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 70,
|
||||
"ObjectName": "vt_spawn_11114",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 1846.59,
|
||||
"AbsY": 807.64,
|
||||
"AbsZ": 13.76,
|
||||
"Yaw": 346.0,
|
||||
"GUID": 47,
|
||||
"MapID": 11114,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 46,
|
||||
"ObjectName": "vt_spawn_11100",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 1898.58,
|
||||
"AbsY": 3223.86,
|
||||
"AbsZ": 14.37,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 49,
|
||||
"MapID": 11100,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 48,
|
||||
"ObjectName": "vt_spawn_11101",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 2038.42,
|
||||
"AbsY": 3039.22,
|
||||
"AbsZ": 24.41,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 51,
|
||||
"MapID": 11101,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 60,
|
||||
"ObjectName": "vt_spawn_11107",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 2126.87,
|
||||
"AbsY": 2026.58,
|
||||
"AbsZ": 14.55,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 53,
|
||||
"MapID": 11107,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 56,
|
||||
"ObjectName": "vt_spawn_11105",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 2237.12,
|
||||
"AbsY": 1436.94,
|
||||
"AbsZ": 20.63,
|
||||
"Yaw": 313.0,
|
||||
"GUID": 55,
|
||||
"MapID": 11105,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 40,
|
||||
"ObjectName": "vt_spawn_11093",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 2456.26,
|
||||
"AbsY": 1983.63,
|
||||
"AbsZ": 13.75,
|
||||
"Yaw": 43.0,
|
||||
"GUID": 57,
|
||||
"MapID": 11093,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 42,
|
||||
"ObjectName": "vt_spawn_11094",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 2456.92,
|
||||
"AbsY": 2849.11,
|
||||
"AbsZ": 20.43,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 59,
|
||||
"MapID": 11094,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 44,
|
||||
"ObjectName": "vt_spawn_11095",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 2492.26,
|
||||
"AbsY": 2303.02,
|
||||
"AbsZ": 12.81,
|
||||
"Yaw": 22.0,
|
||||
"GUID": 61,
|
||||
"MapID": 11095,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 54,
|
||||
"ObjectName": "vt_spawn_11104",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 2643.76,
|
||||
"AbsY": 1396.84,
|
||||
"AbsZ": 15.43,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 63,
|
||||
"MapID": 11104,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 50,
|
||||
"ObjectName": "vt_spawn_11102",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 2916.48,
|
||||
"AbsY": 2589.26,
|
||||
"AbsZ": 14.75,
|
||||
"Yaw": 0.0,
|
||||
"GUID": 65,
|
||||
"MapID": 11102,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 52,
|
||||
"ObjectName": "vt_spawn_11103",
|
||||
"ObjectType": "vt_spawn",
|
||||
"Owner": null,
|
||||
"AbsX": 2963.03,
|
||||
"AbsY": 1881.18,
|
||||
"AbsZ": 17.4,
|
||||
"Yaw": 353.0,
|
||||
"GUID": 67,
|
||||
"MapID": 11103,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 18,
|
||||
"ObjectName": "vt_vehicle",
|
||||
"ObjectType": "vt_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 1230.0,
|
||||
"AbsY": 2266.0,
|
||||
"AbsZ": 19.3969536,
|
||||
"Yaw": 360.0,
|
||||
"GUID": 105,
|
||||
"MapID": 7,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 21,
|
||||
"ObjectName": "vt_vehicle",
|
||||
"ObjectType": "vt_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 1464.0,
|
||||
"AbsY": 858.0,
|
||||
"AbsZ": 18.7295151,
|
||||
"Yaw": 55.0,
|
||||
"GUID": 107,
|
||||
"MapID": 8,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 0,
|
||||
"ObjectName": "vt_vehicle",
|
||||
"ObjectType": "vt_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 1728.0,
|
||||
"AbsY": 3180.0,
|
||||
"AbsZ": 17.1666622,
|
||||
"Yaw": 360.0,
|
||||
"GUID": 109,
|
||||
"MapID": 1,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"ObjectName": "xx06_width_13_slope_0.06_offset_-2_blend_50",
|
||||
"ObjectType": "vt_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 1888.0,
|
||||
"AbsY": 3008.0,
|
||||
"AbsZ": 19.0838337,
|
||||
"Yaw": 36.0,
|
||||
"GUID": 111,
|
||||
"MapID": 2,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 9,
|
||||
"ObjectName": "vt_vehicle",
|
||||
"ObjectType": "vt_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 2186.0,
|
||||
"AbsY": 3154.0,
|
||||
"AbsZ": 16.35365,
|
||||
"Yaw": 233.0,
|
||||
"GUID": 113,
|
||||
"MapID": 4,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 15,
|
||||
"ObjectName": "vt_vehicle",
|
||||
"ObjectType": "vt_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 2436.0,
|
||||
"AbsY": 1872.0,
|
||||
"AbsZ": 23.4730072,
|
||||
"Yaw": 95.0,
|
||||
"GUID": 115,
|
||||
"MapID": 6,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 6,
|
||||
"ObjectName": "xx08_width_13_slope_0.06_offset_-2_blend_50",
|
||||
"ObjectType": "vt_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 2440.0,
|
||||
"AbsY": 2974.0,
|
||||
"AbsZ": 19.660635,
|
||||
"Yaw": 232.0,
|
||||
"GUID": 117,
|
||||
"MapID": 3,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 12,
|
||||
"ObjectName": "vt_vehicle",
|
||||
"ObjectType": "vt_vehicle",
|
||||
"Owner": null,
|
||||
"AbsX": 2732.0,
|
||||
"AbsY": 1450.0,
|
||||
"AbsZ": 13.8541822,
|
||||
"Yaw": 102.0,
|
||||
"GUID": 119,
|
||||
"MapID": 5,
|
||||
"IsChildObject": false
|
||||
},
|
||||
{
|
||||
"Id": 28,
|
||||
"ObjectName": "air_vehicle_terminal",
|
||||
"ObjectType": "air_vehicle_terminal",
|
||||
"Owner": 27,
|
||||
"AbsX": 1308.55444,
|
||||
"AbsY": 1770.761,
|
||||
"AbsZ": 17.2882748,
|
||||
"Yaw": 120.0,
|
||||
"GUID": 137,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 31,
|
||||
"ObjectName": "air_vehicle_terminal",
|
||||
"ObjectType": "air_vehicle_terminal",
|
||||
"Owner": 30,
|
||||
"AbsX": 2432.775,
|
||||
"AbsY": 1180.309,
|
||||
"AbsZ": 18.1672077,
|
||||
"Yaw": 132.0,
|
||||
"GUID": 139,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 34,
|
||||
"ObjectName": "air_vehicle_terminal",
|
||||
"ObjectType": "air_vehicle_terminal",
|
||||
"Owner": 33,
|
||||
"AbsX": 2773.508,
|
||||
"AbsY": 2581.992,
|
||||
"AbsZ": 21.809288,
|
||||
"Yaw": 270.0,
|
||||
"GUID": 141,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 75,
|
||||
"ObjectName": "bfr_door",
|
||||
"ObjectType": "bfr_door",
|
||||
"Owner": 15,
|
||||
"AbsX": 2402.71436,
|
||||
"AbsY": 1928.01074,
|
||||
"AbsZ": 20.6460171,
|
||||
"Yaw": 50.0,
|
||||
"GUID": 149,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 74,
|
||||
"ObjectName": "bfr_terminal",
|
||||
"ObjectType": "bfr_terminal",
|
||||
"Owner": 15,
|
||||
"AbsX": 2394.414,
|
||||
"AbsY": 1931.7948,
|
||||
"AbsZ": 17.5699425,
|
||||
"Yaw": 5.0,
|
||||
"GUID": 153,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 26,
|
||||
"ObjectName": "dropship_pad_doors",
|
||||
"ObjectType": "dropship_pad_doors",
|
||||
"Owner": 24,
|
||||
"AbsX": 1712.411,
|
||||
"AbsY": 1859.98,
|
||||
"AbsZ": 28.4641113,
|
||||
"Yaw": 90.0,
|
||||
"GUID": 157,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 25,
|
||||
"ObjectName": "dropship_vehicle_terminal",
|
||||
"ObjectType": "dropship_vehicle_terminal",
|
||||
"Owner": 24,
|
||||
"AbsX": 1692.53,
|
||||
"AbsY": 1859.88,
|
||||
"AbsZ": 35.317112,
|
||||
"Yaw": 270.0,
|
||||
"GUID": 161,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 20,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 18,
|
||||
"AbsX": 1230.147,
|
||||
"AbsY": 2266.027,
|
||||
"AbsZ": 17.9259529,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 165,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 29,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 27,
|
||||
"AbsX": 1295.85925,
|
||||
"AbsY": 1778.05017,
|
||||
"AbsZ": 13.1302757,
|
||||
"Yaw": 30.0,
|
||||
"GUID": 167,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 23,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 21,
|
||||
"AbsX": 1464.06226,
|
||||
"AbsY": 858.1359,
|
||||
"AbsZ": 17.2585144,
|
||||
"Yaw": 125.0,
|
||||
"GUID": 169,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 0,
|
||||
"AbsX": 1728.147,
|
||||
"AbsY": 3180.027,
|
||||
"AbsZ": 15.6956625,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 171,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 3,
|
||||
"AbsX": 1888.103,
|
||||
"AbsY": 3008.10815,
|
||||
"AbsZ": 17.612833,
|
||||
"Yaw": 144.0,
|
||||
"GUID": 173,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 11,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 9,
|
||||
"AbsX": 2185.933,
|
||||
"AbsY": 3153.86646,
|
||||
"AbsZ": 14.8826494,
|
||||
"Yaw": 307.0,
|
||||
"GUID": 175,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 32,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 30,
|
||||
"AbsX": 2421.8728,
|
||||
"AbsY": 1190.07825,
|
||||
"AbsZ": 14.0092087,
|
||||
"Yaw": 42.0,
|
||||
"GUID": 177,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 17,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 15,
|
||||
"AbsX": 2435.96021,
|
||||
"AbsY": 1872.144,
|
||||
"AbsZ": 22.0020065,
|
||||
"Yaw": 85.0,
|
||||
"GUID": 179,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 8,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 6,
|
||||
"AbsX": 2439.93066,
|
||||
"AbsY": 2973.86743,
|
||||
"AbsZ": 18.1896343,
|
||||
"Yaw": 308.0,
|
||||
"GUID": 181,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 14,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 12,
|
||||
"AbsX": 2731.943,
|
||||
"AbsY": 1450.13818,
|
||||
"AbsZ": 12.3831825,
|
||||
"Yaw": 78.0,
|
||||
"GUID": 183,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 35,
|
||||
"ObjectName": "mb_pad_creation",
|
||||
"ObjectType": "mb_pad_creation",
|
||||
"Owner": 33,
|
||||
"AbsX": 2788.147,
|
||||
"AbsY": 2582.027,
|
||||
"AbsZ": 17.6512871,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 185,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 67,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 66,
|
||||
"AbsX": 1309.08,
|
||||
"AbsY": 2221.80981,
|
||||
"AbsZ": 16.3210011,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 209,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 37,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 36,
|
||||
"AbsX": 1441.54,
|
||||
"AbsY": 1487.08008,
|
||||
"AbsZ": 18.901001,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 211,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 39,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 38,
|
||||
"AbsX": 1447.1925,
|
||||
"AbsY": 1900.82727,
|
||||
"AbsZ": 13.451,
|
||||
"Yaw": 202.0,
|
||||
"GUID": 213,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 65,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 64,
|
||||
"AbsX": 1481.31,
|
||||
"AbsY": 2427.21,
|
||||
"AbsZ": 17.7610016,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 215,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 69,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 68,
|
||||
"AbsX": 1526.13,
|
||||
"AbsY": 981.56,
|
||||
"AbsZ": 22.061,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 217,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 59,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 58,
|
||||
"AbsX": 1792.6,
|
||||
"AbsY": 1748.52,
|
||||
"AbsZ": 13.7909994,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 219,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 63,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 62,
|
||||
"AbsX": 1827.95117,
|
||||
"AbsY": 2390.849,
|
||||
"AbsZ": 15.911,
|
||||
"Yaw": 216.0,
|
||||
"GUID": 221,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 71,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 70,
|
||||
"AbsX": 1846.5658,
|
||||
"AbsY": 807.542969,
|
||||
"AbsZ": 14.901,
|
||||
"Yaw": 194.0,
|
||||
"GUID": 223,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 47,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 46,
|
||||
"AbsX": 1898.58,
|
||||
"AbsY": 3223.76,
|
||||
"AbsZ": 15.511,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 225,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 49,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 48,
|
||||
"AbsX": 2038.42,
|
||||
"AbsY": 3039.11987,
|
||||
"AbsZ": 25.551,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 227,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 61,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 60,
|
||||
"AbsX": 2126.87,
|
||||
"AbsY": 2026.48,
|
||||
"AbsZ": 15.691,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 229,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 57,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 56,
|
||||
"AbsX": 2237.04688,
|
||||
"AbsY": 1436.8717,
|
||||
"AbsZ": 21.771,
|
||||
"Yaw": 227.0,
|
||||
"GUID": 231,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 41,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 40,
|
||||
"AbsX": 2456.32812,
|
||||
"AbsY": 1983.55688,
|
||||
"AbsZ": 14.891,
|
||||
"Yaw": 137.0,
|
||||
"GUID": 233,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 43,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 42,
|
||||
"AbsX": 2456.92,
|
||||
"AbsY": 2849.01,
|
||||
"AbsZ": 21.5710011,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 235,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 45,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 44,
|
||||
"AbsX": 2492.29736,
|
||||
"AbsY": 2302.92725,
|
||||
"AbsZ": 13.951,
|
||||
"Yaw": 158.0,
|
||||
"GUID": 237,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 55,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 54,
|
||||
"AbsX": 2643.76,
|
||||
"AbsY": 1396.74,
|
||||
"AbsZ": 16.5710011,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 239,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 51,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 50,
|
||||
"AbsX": 2916.48,
|
||||
"AbsY": 2589.16,
|
||||
"AbsZ": 15.891,
|
||||
"Yaw": 180.0,
|
||||
"GUID": 241,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 53,
|
||||
"ObjectName": "spawn_zone",
|
||||
"ObjectType": "spawn_zone",
|
||||
"Owner": 52,
|
||||
"AbsX": 2963.01782,
|
||||
"AbsY": 1881.08081,
|
||||
"AbsZ": 18.541,
|
||||
"Yaw": 187.0,
|
||||
"GUID": 243,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 19,
|
||||
"ObjectName": "vehicle_terminal",
|
||||
"ObjectType": "vehicle_terminal",
|
||||
"Owner": 18,
|
||||
"AbsX": 1215.508,
|
||||
"AbsY": 2265.992,
|
||||
"AbsZ": 22.0839539,
|
||||
"Yaw": 270.0,
|
||||
"GUID": 281,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 22,
|
||||
"ObjectName": "vehicle_terminal",
|
||||
"ObjectType": "vehicle_terminal",
|
||||
"Owner": 21,
|
||||
"AbsX": 1455.69434,
|
||||
"AbsY": 846.124268,
|
||||
"AbsZ": 21.4165154,
|
||||
"Yaw": 215.0,
|
||||
"GUID": 283,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"ObjectName": "vehicle_terminal",
|
||||
"ObjectType": "vehicle_terminal",
|
||||
"Owner": 0,
|
||||
"AbsX": 1713.508,
|
||||
"AbsY": 3179.992,
|
||||
"AbsZ": 19.8536625,
|
||||
"Yaw": 270.0,
|
||||
"GUID": 285,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"ObjectName": "vehicle_terminal",
|
||||
"ObjectType": "vehicle_terminal",
|
||||
"Owner": 3,
|
||||
"AbsX": 1876.2804,
|
||||
"AbsY": 2999.47534,
|
||||
"AbsZ": 21.770834,
|
||||
"Yaw": 234.0,
|
||||
"GUID": 287,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 10,
|
||||
"ObjectName": "vehicle_terminal",
|
||||
"ObjectType": "vehicle_terminal",
|
||||
"Owner": 9,
|
||||
"AbsX": 2194.715,
|
||||
"AbsY": 3165.57861,
|
||||
"AbsZ": 19.04065,
|
||||
"Yaw": 37.0,
|
||||
"GUID": 289,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 16,
|
||||
"ObjectName": "vehicle_terminal",
|
||||
"ObjectType": "vehicle_terminal",
|
||||
"Owner": 15,
|
||||
"AbsX": 2437.271,
|
||||
"AbsY": 1857.56384,
|
||||
"AbsZ": 26.1600075,
|
||||
"Yaw": 175.0,
|
||||
"GUID": 291,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 7,
|
||||
"ObjectName": "vehicle_terminal",
|
||||
"ObjectType": "vehicle_terminal",
|
||||
"Owner": 6,
|
||||
"AbsX": 2448.91577,
|
||||
"AbsY": 2985.4248,
|
||||
"AbsZ": 22.3476353,
|
||||
"Yaw": 38.0,
|
||||
"GUID": 293,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
{
|
||||
"Id": 13,
|
||||
"ObjectName": "vehicle_terminal",
|
||||
"ObjectType": "vehicle_terminal",
|
||||
"Owner": 12,
|
||||
"AbsX": 2735.021,
|
||||
"AbsY": 1435.82629,
|
||||
"AbsZ": 16.5411816,
|
||||
"Yaw": 168.0,
|
||||
"GUID": 295,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
}
|
||||
]
|
||||
|
|
@ -6,7 +6,6 @@ import akka.actor.typed.scaladsl.{ActorContext, Behaviors}
|
|||
import akka.io.Udp
|
||||
import java.net.InetSocketAddress
|
||||
import java.security.{SecureRandom, Security}
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
|
||||
|
|
@ -26,6 +25,7 @@ import net.psforever.packet.game._
|
|||
import net.psforever.packet.crypto._
|
||||
import net.psforever.packet.game.{ChangeFireModeMessage, CharacterInfoMessage, KeepAliveMessage, PingMsg}
|
||||
import net.psforever.packet.PacketCoding.CryptoCoding
|
||||
import net.psforever.packet.reset.ResetSequence
|
||||
import net.psforever.util.{Config, DiffieHellman, Md5Mac}
|
||||
|
||||
/**
|
||||
|
|
@ -219,17 +219,13 @@ class MiddlewareActor(
|
|||
* Increment the outbound sequence number.
|
||||
* The previous sequence number is returned.
|
||||
* The fidelity of the sequence field in packets is 16 bits, so wrap back to 0 after 65535.
|
||||
* @return
|
||||
* @return next sequence number
|
||||
*/
|
||||
private def nextSequence: Int = {
|
||||
if (outSequence >= 0xffff) {
|
||||
// TODO resetting the sequence to 0 causes a client crash
|
||||
// but that does not happen when we always send the same number
|
||||
// the solution is most likely to send the proper ResetSequence payload
|
||||
// send(ResetSequence(), None, crypto)
|
||||
// outSequence = -1
|
||||
// return nextSequence
|
||||
outSequence
|
||||
if (outSequence >= 0x8000) {
|
||||
send(ResetSequence(), Some(outSequence), crypto)
|
||||
performResetSequenceReset()
|
||||
0
|
||||
} else {
|
||||
outSequence += 1
|
||||
outSequence
|
||||
|
|
@ -257,6 +253,16 @@ class MiddlewareActor(
|
|||
r
|
||||
}
|
||||
|
||||
/**
|
||||
* When the sequence is reset,
|
||||
* the server resets both the expectant packet sequence id and the delivered packet sequence id
|
||||
* and gaslight the client to send packets using refreshed (delivered) id's.
|
||||
*/
|
||||
private def performResetSequenceReset(): Unit = {
|
||||
outSequence = 0
|
||||
inSequence = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not bundle these packets together with other packets
|
||||
*/
|
||||
|
|
@ -623,7 +629,7 @@ class MiddlewareActor(
|
|||
Behaviors.same
|
||||
|
||||
case _: PlanetSideResetSequencePacket =>
|
||||
log.error(s"Unexpected crypto packet: received a PlanetSideResetSequencePacket when it should never happen")
|
||||
performResetSequenceReset()
|
||||
Behaviors.same
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1559,6 +1559,8 @@ class AvatarActor(
|
|||
.foreach {
|
||||
case (item, name) =>
|
||||
Avatar.purchaseCooldowns.get(item) match {
|
||||
case Some(cooldown) if session.get.player.IsInVRZone => ()
|
||||
//don't update purchase timers for players in VR training zones
|
||||
case Some(cooldown) =>
|
||||
//only send for items with cooldowns
|
||||
updateTheTimes = true
|
||||
|
|
@ -2248,7 +2250,15 @@ class AvatarActor(
|
|||
sessionActor ! SessionActor.SendResponse(
|
||||
CharacterInfoMessage(
|
||||
unk = 15,
|
||||
PlanetSideZoneID(zoneNum),
|
||||
PlanetSideZoneID(
|
||||
//there is a client bug that causes the NC/VS versions of VR shooting/driving zones to have no background image
|
||||
//remap them to the TR versions as a workaround
|
||||
//the VR combat zones have no background image at all, so they are not accounted for
|
||||
zoneNum match {
|
||||
case 17 | 20 => 14
|
||||
case 18 | 21 => 15
|
||||
case _ => zoneNum
|
||||
}),
|
||||
avatar.id,
|
||||
pguid,
|
||||
finished = false,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import net.psforever.objects.serverobject.mount.Mountable
|
|||
import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.{AIDamage, ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarGrenadeStateMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BeginZoningMessage, BindPlayerMessage, BugReportMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ChildObjectStateMessage, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DeployRequestMessage, DismountVehicleCargoMsg, DismountVehicleMsg, DisplayedAwardMessage, DropItemMessage, DroppodLaunchRequestMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FavoritesRequest, FrameVehicleStateMessage, FriendsRequest, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, HitMessage, InvalidTerrainMessage, ItemTransactionMessage, LashMessage, LongRangeProjectileInfoMessage, LootItemMessage, MountVehicleCargoMsg, MountVehicleMsg, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, ProjectileStateMessage, ProximityTerminalUseMessage, ReleaseAvatarRequestMessage, ReloadMessage, RequestDestroyMessage, SetChatFilterMessage, SpawnRequestMessage, SplashHitMessage, SquadDefinitionActionMessage, SquadMembershipRequest, SquadWaypointRequest, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UplinkRequest, UseItemMessage, VehicleStateMessage, VehicleSubStateMessage, VoiceHostInfo, VoiceHostRequest, WarpgateRequest, WeaponDelayFireMessage, WeaponDryFireMessage, WeaponFireMessage, WeaponLazeTargetPositionMessage, ZipLineMessage}
|
||||
import net.psforever.packet.game.{AIDamage, ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarGrenadeStateMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BeginZoningMessage, BindPlayerMessage, BugReportMessage, ChangeAmmoMessage, ChangeFireModeMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ChildObjectStateMessage, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DeployRequestMessage, DismountVehicleCargoMsg, DismountVehicleMsg, DisplayedAwardMessage, DropItemMessage, DroppodLaunchRequestMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FavoritesRequest, FrameVehicleStateMessage, FriendsRequest, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, HitMessage, InvalidTerrainMessage, ItemTransactionMessage, LashMessage, LongRangeProjectileInfoMessage, LootItemMessage, MountVehicleCargoMsg, MountVehicleMsg, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, ProjectileStateMessage, ProximityTerminalUseMessage, ReleaseAvatarRequestMessage, ReloadMessage, RequestDestroyMessage, SetChatFilterMessage, SpawnRequestMessage, SplashHitMessage, SquadDefinitionActionMessage, SquadMembershipRequest, SquadWaypointRequest, TargetingImplantRequest, TradeMessage, TrainingZoneMessage, UnuseItemMessage, UplinkRequest, UseItemMessage, VehicleStateMessage, VehicleSubStateMessage, VoiceHostInfo, VoiceHostRequest, WarpgateRequest, WeaponDelayFireMessage, WeaponDryFireMessage, WeaponFireMessage, WeaponLazeTargetPositionMessage, ZipLineMessage}
|
||||
import net.psforever.services.{InterstellarClusterService => ICS}
|
||||
import net.psforever.services.CavernRotationService
|
||||
import net.psforever.services.CavernRotationService.SendCavernRotationUpdates
|
||||
|
|
@ -619,6 +619,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
case packet: OutfitMembershipResponse =>
|
||||
logic.general.handleOutfitMembershipResponse(packet)
|
||||
|
||||
case packet: TrainingZoneMessage =>
|
||||
data.zoning.handleTrainingZoneMessage(packet)
|
||||
|
||||
case pkt =>
|
||||
data.log.warn(s"Unhandled GamePacket $pkt")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1059,6 +1059,12 @@ class GeneralOperations(
|
|||
sendResponse(ChatMsg(ChatMessageType.UNK_227, wideContents=false, "", "@charsaved", None))
|
||||
}
|
||||
|
||||
def trainingGriefWarning(): Unit = {
|
||||
//don't know the correct ChatMessageType for this one yet;
|
||||
//it's supposed to use a pop-up that takes 5 seconds before you are allowed to close it, so disabled for now
|
||||
//sendResponse(ChatMsg(ChatMessageType.CMT_QUIT, wideContents=true, "", "@TrainingGriefWarning", None))
|
||||
}
|
||||
|
||||
def noVoicedChat(pkt: PlanetSideGamePacket): Unit = {
|
||||
log.debug(s"$pkt")
|
||||
sendResponse(VoiceHostKill())
|
||||
|
|
|
|||
|
|
@ -422,7 +422,12 @@ class SessionData(
|
|||
if (obj.spectator && obj != player) {
|
||||
administrativeKick(player)
|
||||
} else {
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
if (obj.IsInVRZone && obj.Faction == player.Faction && obj.CharId != player.CharId) {
|
||||
//don't do friendly-fire in VR zones
|
||||
general.trainingGriefWarning()
|
||||
} else {
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
}
|
||||
}
|
||||
|
||||
case obj: Vehicle if obj.CanDamage =>
|
||||
|
|
@ -433,10 +438,20 @@ class SessionData(
|
|||
} else {
|
||||
log.info(s"$name is attacking $ownerName's ${obj.Definition.Name}")
|
||||
}
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
if (obj.IsInVRZone && obj.Faction == player.Faction && !ownerName.equals(name)) {
|
||||
//don't do friendly-fire in VR zones
|
||||
general.trainingGriefWarning()
|
||||
} else {
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
}
|
||||
|
||||
case obj: Amenity if obj.CanDamage =>
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
if (obj.IsInVRZone && obj.Faction == player.Faction) {
|
||||
//don't do friendly-fire in VR zones
|
||||
general.trainingGriefWarning()
|
||||
} else {
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
}
|
||||
|
||||
case obj: Deployable if obj.CanDamage =>
|
||||
val name = player.Name
|
||||
|
|
@ -446,7 +461,12 @@ class SessionData(
|
|||
} else {
|
||||
log.info(s"$name is attacking $ownerName's ${obj.Definition.Name}")
|
||||
}
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
if (obj.IsInVRZone && obj.Faction == player.Faction && !ownerName.equals(name)) {
|
||||
//don't do friendly-fire in VR zones
|
||||
general.trainingGriefWarning()
|
||||
} else {
|
||||
obj.Actor ! Vitality.Damage(func)
|
||||
}
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -409,7 +409,8 @@ class WeaponAndProjectileOperations(
|
|||
} else {
|
||||
equipment foreach {
|
||||
case obj: ConstructionItem =>
|
||||
if (Deployables.performConstructionItemAmmoChange(player.avatar.certifications, obj, obj.AmmoTypeIndex)) {
|
||||
val certifications = if (player.IsInVRZone) GlobalDefinitions.vrZoneTempEngineeringCerts() else player.avatar.certifications
|
||||
if (Deployables.performConstructionItemAmmoChange(certifications, obj, obj.AmmoTypeIndex)) {
|
||||
log.info(
|
||||
s"${player.Name} switched ${player.Sex.possessive} ${obj.Definition.Name} to construct ${obj.AmmoType} (option #${obj.FireModeIndex})"
|
||||
)
|
||||
|
|
@ -437,8 +438,9 @@ class WeaponAndProjectileOperations(
|
|||
val originalModeIndex = obj.FireModeIndex
|
||||
if (obj match {
|
||||
case citem: ConstructionItem =>
|
||||
val certifications = if (player.IsInVRZone) GlobalDefinitions.vrZoneTempEngineeringCerts() else player.avatar.certifications
|
||||
val modeChanged = Deployables.performConstructionItemFireModeChange(
|
||||
player.avatar.certifications,
|
||||
certifications,
|
||||
citem,
|
||||
originalModeIndex
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, VehicleSource}
|
|||
import net.psforever.objects.vital.{InGameHistory, IncarnationActivity, ReconstructionActivity, SpawningActivity}
|
||||
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
||||
import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect
|
||||
import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, WeatherMessage}
|
||||
import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage}
|
||||
import net.psforever.services.chat.DefaultChannel
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -863,6 +863,66 @@ class ZoningOperations(
|
|||
}
|
||||
}
|
||||
|
||||
import scala.util.Random
|
||||
private val rand = Random
|
||||
// temp, will be replaced by proper spawn point logic in the future (hopefully)
|
||||
val vrShootingZoneSpawns: List[Vector3] = List[Vector3](
|
||||
Vector3(491.91f, 531.82f, 13.72f),
|
||||
Vector3(508.36f, 531.56f, 13.72f),
|
||||
Vector3(508.56f, 525.34f, 13.72f),
|
||||
Vector3(500.88f, 521.95f, 13.72f),
|
||||
Vector3(492.85f, 526.03f, 13.72f),
|
||||
Vector3(500.48f, 534.74f, 13.72f)
|
||||
)
|
||||
val vrDrivingAreaSpawns: List[Vector3] = List[Vector3](
|
||||
Vector3(1893.53f, 2988.72f, 19.1f),
|
||||
Vector3(1716.85f, 3198.06f, 17.2f),
|
||||
Vector3(2176.49f, 3174.48f, 16.4f),
|
||||
Vector3(2431.75f, 2995.72f, 19.7f),
|
||||
Vector3(2775.13f, 2562.91f, 19.2f),
|
||||
Vector3(2752.12f, 1442.14f, 13.9f),
|
||||
Vector3(1216.68f, 2283.52f, 19.4f),
|
||||
Vector3(1318.21f, 1786.59f, 14.6f),
|
||||
Vector3(1471.92f, 834.2f, 18.8f),
|
||||
Vector3(2419f, 1167.62f, 15.5f),
|
||||
Vector3(2455.81f, 1860.8f, 23.5f)
|
||||
)
|
||||
|
||||
def handleTrainingZoneMessage(pkt: TrainingZoneMessage): Unit = {
|
||||
pkt.zone.guid match {
|
||||
case 11 | 12 | 13 =>
|
||||
player.avatar.deployables.UpdateMaxCounts(player.avatar.certifications)
|
||||
RequestSanctuaryZoneSpawn(player, player.Zone.Number)
|
||||
// leveraging SetZone for now because the VR zones have no "proper" spawn points configured yet
|
||||
case 17 =>
|
||||
if (player.Zone.id != "tzshtr") {
|
||||
context.self ! SessionActor.SetZone("tzshtr", vrShootingZoneSpawns.toArray.apply(rand.nextInt(vrShootingZoneSpawns.size)))
|
||||
}
|
||||
case 18 =>
|
||||
if (player.Zone.id != "tzshnc") {
|
||||
context.self ! SessionActor.SetZone("tzshnc", vrShootingZoneSpawns.toArray.apply(rand.nextInt(vrShootingZoneSpawns.size)))
|
||||
}
|
||||
case 19 =>
|
||||
if (player.Zone.id != "tzshvs") {
|
||||
context.self ! SessionActor.SetZone("tzshvs", vrShootingZoneSpawns.toArray.apply(rand.nextInt(vrShootingZoneSpawns.size)))
|
||||
}
|
||||
case 20 =>
|
||||
if (player.Zone.id != "tzdrtr") {
|
||||
context.self ! SessionActor.SetZone("tzdrtr", vrDrivingAreaSpawns.toArray.apply(rand.nextInt(vrDrivingAreaSpawns.size)))
|
||||
}
|
||||
case 21 =>
|
||||
if (player.Zone.id != "tzdrnc") {
|
||||
context.self ! SessionActor.SetZone("tzdrnc", vrDrivingAreaSpawns.toArray.apply(rand.nextInt(vrDrivingAreaSpawns.size)))
|
||||
}
|
||||
case 22 =>
|
||||
if (player.Zone.id != "tzdrvs") {
|
||||
context.self ! SessionActor.SetZone("tzdrvs", vrDrivingAreaSpawns.toArray.apply(rand.nextInt(vrDrivingAreaSpawns.size)))
|
||||
}
|
||||
case _ =>
|
||||
log.warn(s"Received TrainingZoneMessage that requests unexpected zone number ${pkt.zone.guid}?")
|
||||
}
|
||||
}
|
||||
|
||||
/* support functions */
|
||||
|
||||
/**
|
||||
|
|
@ -918,13 +978,23 @@ class ZoningOperations(
|
|||
* the time representative of the the tower has priority.
|
||||
* When no spheres of influence are being encroached, one is considered "in the wilderness".
|
||||
* The messaging is different but the location is normally treated the same as if in a neutral sphere of influence.
|
||||
* Being anywhere in one's faction's own sanctuary is a special case.
|
||||
* Being anywhere in one's faction's own sanctuary or VR training area(s) is a special case.
|
||||
*
|
||||
* @return a `Tuple` composed of the initial countdown time and the descriptor for message composition
|
||||
*/
|
||||
def ZoningStartInitialMessageAndTimer(): (Int, String) = {
|
||||
val location = if (Zones.sanctuaryZoneNumber(player.Faction) == continent.Number) {
|
||||
Zoning.Time.Sanctuary
|
||||
} else if (player.IsInVRZone) {
|
||||
continent.id match {
|
||||
case "tzshtr" | "tzdrtr" | "tzcotr" =>
|
||||
if (player.Faction == PlanetSideEmpire.TR) Zoning.Time.Friendly else Zoning.Time.None
|
||||
case "tzshnc" | "tzdrnc" | "tzconc" =>
|
||||
if (player.Faction == PlanetSideEmpire.NC) Zoning.Time.Friendly else Zoning.Time.None
|
||||
case "tzshvs" | "tzdrvs" | "tzcovs" =>
|
||||
if (player.Faction == PlanetSideEmpire.VS) Zoning.Time.Friendly else Zoning.Time.None
|
||||
case _ => Zoning.Time.None
|
||||
}
|
||||
} else {
|
||||
ZoningOperations.findBuildingsBySoiOccupancy(continent, player.Position) match {
|
||||
case Nil =>
|
||||
|
|
@ -1218,6 +1288,13 @@ class ZoningOperations(
|
|||
ICS.FindZone(_.id.equals(zoneId), context.self)
|
||||
))
|
||||
} else if (player.HasGUID) {
|
||||
if (player.IsInVRZone && !zoneId.startsWith("tz")) {
|
||||
// reset the player to default gear to prevent them from smuggling things out of VR
|
||||
log.info(s"${player.Name} is exiting VR Training, resetting ${player.Sex.possessive} loadout")
|
||||
val newPlayer = Player.Respawn(player)
|
||||
DefinitionUtil.applyDefaultLoadout(newPlayer)
|
||||
session = session.copy(player = newPlayer)
|
||||
}
|
||||
TaskWorkflow.execute(taskThenZoneChange(
|
||||
GUIDTask.unregisterAvatar(continent.GUID, original),
|
||||
ICS.FindZone(_.id.equals(zoneId), context.self)
|
||||
|
|
@ -2051,6 +2128,30 @@ class ZoningOperations(
|
|||
SpawnOperations.sendEventMessage(ChatMsg(ChatMessageType.CMT_QUIT, "@reset_sanctuary_locked")), 20)
|
||||
) //You have been returned to the sanctuary because the location you logged out is not available.
|
||||
player.Zone = Zone.Nowhere
|
||||
} else if (inZone.id.startsWith("tz")) {
|
||||
inZone.id match {
|
||||
case "tzshtr" | "tzdrtr" | "tzcotr" =>
|
||||
if (player.Faction != PlanetSideEmpire.TR) {
|
||||
enqueueNewActivity(ActivityQueuedTask(
|
||||
SpawnOperations.sendEventMessage(ChatMsg(ChatMessageType.CMT_QUIT, "@reset_sanctuary_locked")), 20)
|
||||
) //You have been returned to the sanctuary because the location you logged out is not available.
|
||||
player.Zone = Zone.Nowhere
|
||||
}
|
||||
case "tzshnc" | "tzdrnc" | "tzconc" =>
|
||||
if (player.Faction != PlanetSideEmpire.NC) {
|
||||
enqueueNewActivity(ActivityQueuedTask(
|
||||
SpawnOperations.sendEventMessage(ChatMsg(ChatMessageType.CMT_QUIT, "@reset_sanctuary_locked")), 20)
|
||||
) //You have been returned to the sanctuary because the location you logged out is not available.
|
||||
player.Zone = Zone.Nowhere
|
||||
}
|
||||
case "tzshvs" | "tzdrvs" | "tzcovs" =>
|
||||
if (player.Faction != PlanetSideEmpire.VS) {
|
||||
enqueueNewActivity(ActivityQueuedTask(
|
||||
SpawnOperations.sendEventMessage(ChatMsg(ChatMessageType.CMT_QUIT, "@reset_sanctuary_locked")), 20)
|
||||
) //You have been returned to the sanctuary because the location you logged out is not available.
|
||||
player.Zone = Zone.Nowhere
|
||||
}
|
||||
}
|
||||
} else if (ourBuildings.isEmpty && (amsSpawnPoints.isEmpty || noFriendlyPlayersInZone)) {
|
||||
enqueueNewActivity(ActivityQueuedTask(
|
||||
SpawnOperations.sendEventMessage(ChatMsg(ChatMessageType.CMT_QUIT, "@reset_sanctuary_locked")), 20)
|
||||
|
|
@ -2230,6 +2331,12 @@ class ZoningOperations(
|
|||
sessionLogic.persist = UpdatePersistenceAndRefs
|
||||
tplayer.avatar = avatar
|
||||
session = session.copy(player = tplayer)
|
||||
if (id.startsWith("tz")) {
|
||||
// have to set the deployable counts as if the player has all the certs so they can deploy CE in VR zones without having the certs
|
||||
player.avatar.deployables.UpdateMaxCounts(GlobalDefinitions.vrZoneTempEngineeringCerts())
|
||||
} else {
|
||||
player.avatar.deployables.UpdateMaxCounts(player.avatar.certifications)
|
||||
}
|
||||
//LoadMapMessage causes the client to send BeginZoningMessage, eventually leading to SetCurrentAvatar
|
||||
//val weaponsEnabled = !(mapName.equals("map11") || mapName.equals("map12") || mapName.equals("map13"))
|
||||
sendResponse(LoadMapMessage(mapName, id, 40100, 25, zone.LiveFireAllowed(tplayer.Faction), map.checksum))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects
|
||||
|
||||
import net.psforever.objects.avatar.Certification
|
||||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.ce.DeployedItem
|
||||
import net.psforever.objects.definition._
|
||||
|
|
@ -18,7 +19,7 @@ import net.psforever.objects.serverobject.painbox.PainboxDefinition
|
|||
import net.psforever.objects.serverobject.terminals._
|
||||
import net.psforever.objects.serverobject.tube.SpawnTubeDefinition
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSiloDefinition
|
||||
import net.psforever.objects.serverobject.structures.{AmenityDefinition, BuildingDefinition, WarpGateDefinition}
|
||||
import net.psforever.objects.serverobject.structures.{AmenityDefinition, BuildingDefinition, VirtualTrainingTeleporterDefinition, WarpGateDefinition}
|
||||
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminalDefinition
|
||||
import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMechDefinition
|
||||
import net.psforever.objects.serverobject.turret.FacilityTurretDefinition
|
||||
|
|
@ -1281,6 +1282,10 @@ object GlobalDefinitions {
|
|||
|
||||
val obbasemesh: AmenityDefinition = new AmenityDefinition(598) {}
|
||||
|
||||
val spawn_pad = new VirtualTrainingTeleporterDefinition()
|
||||
|
||||
val spawn_zone = new VirtualTrainingTeleporterDefinition()
|
||||
|
||||
val targeting_laser_dispenser = new OrderTerminalDefinition(851)
|
||||
|
||||
val stationaryteleportpad = new GenericTeleportationDefinition(836)
|
||||
|
|
@ -1389,6 +1394,10 @@ object GlobalDefinitions {
|
|||
|
||||
val orbital_building_vs = new BuildingDefinition(607)
|
||||
|
||||
val vr_training = new BuildingDefinition(955)
|
||||
|
||||
val vt_air_vehicle = new BuildingDefinition(976)
|
||||
|
||||
val VT_building_nc = new BuildingDefinition(978)
|
||||
|
||||
val VT_building_tr = new BuildingDefinition(979)
|
||||
|
|
@ -2073,6 +2082,19 @@ object GlobalDefinitions {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Engineering certifications to temporarily apply to the avatar in VR Training zones.
|
||||
* @return the set of certifications to apply.
|
||||
*/
|
||||
def vrZoneTempEngineeringCerts(): Set[Certification] = {
|
||||
Set[Certification](
|
||||
Certification.AdvancedEngineering,
|
||||
Certification.AdvancedHacking,
|
||||
Certification.CombatEngineering,
|
||||
Certification.GroundSupport
|
||||
)
|
||||
}
|
||||
|
||||
GlobalDefinitionsImplant.init()
|
||||
GlobalDefinitionsExoSuit.init()
|
||||
GlobalDefinitionsKit.init()
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ object Players {
|
|||
ExoSuitDefinition.Select(exosuit, player.Faction).Permissions match {
|
||||
case Nil =>
|
||||
true
|
||||
case permissions if player.IsInVRZone =>
|
||||
true
|
||||
case permissions if subtype != 0 =>
|
||||
val certs = player.avatar.certifications
|
||||
certs.intersect(permissions.toSet).nonEmpty &&
|
||||
|
|
|
|||
|
|
@ -758,7 +758,8 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
val deployables = player.avatar.deployables
|
||||
if (deployables.Valid(obj) &&
|
||||
!deployables.Contains(obj) &&
|
||||
Players.deployableWithinBuildLimits(player, obj)) {
|
||||
Players.deployableWithinBuildLimits(player, obj) &&
|
||||
routerFactionSame(obj)) {
|
||||
//deployables, upon construction, may display an animation effect
|
||||
tool.Definition match {
|
||||
case GlobalDefinitions.router_telepad => () /* no special animation */
|
||||
|
|
@ -809,7 +810,30 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
case Damageable.MakeInvulnerable =>
|
||||
player.LastDamage.exists { d => System.currentTimeMillis() - d.interaction.hitTime > 2500L }
|
||||
case _ =>
|
||||
true
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Prevent a player from deploying a telepad that belongs to a Router of a different faction
|
||||
*/
|
||||
private def routerFactionSame(obj: Deployable): Boolean = {
|
||||
obj match {
|
||||
case tp: TelepadDeployable =>
|
||||
val zone = player.Zone
|
||||
tp.Router match {
|
||||
case Some(routerGuid) =>
|
||||
zone.Vehicles.find(_.GUID == routerGuid) match {
|
||||
case Some(router) =>
|
||||
router.Faction == player.Faction
|
||||
case None =>
|
||||
false
|
||||
}
|
||||
case None =>
|
||||
false
|
||||
}
|
||||
case _ =>
|
||||
true //not a telepad
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,11 @@ object GlobalDefinitionsBuilding {
|
|||
orbital_building_tr.Name = "orbital_building_tr"
|
||||
|
||||
orbital_building_vs.Name = "orbital_building_vs"
|
||||
|
||||
|
||||
vr_training.Name = "vr_training"
|
||||
|
||||
vt_air_vehicle.Name = "vt_air_vehicle"
|
||||
|
||||
VT_building_nc.Name = "VT_building_nc"
|
||||
|
||||
VT_building_tr.Name = "VT_building_tr"
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ abstract class PlanetSideServerObject
|
|||
actor = ActorRef.noSender
|
||||
out
|
||||
}
|
||||
|
||||
def IsInVRZone: Boolean = Zone.id.startsWith("tz")
|
||||
}
|
||||
|
||||
object PlanetSideServerObject {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2026 PSForever
|
||||
package net.psforever.objects.serverobject.structures
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.objects.GlobalDefinitions
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
|
||||
class VirtualTrainingTeleporter extends PlanetSideServerObject {
|
||||
def Definition: VirtualTrainingTeleporterDefinition = GlobalDefinitions.spawn_zone
|
||||
|
||||
def Faction: PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
}
|
||||
|
||||
object VirtualTrainingTeleporter {
|
||||
|
||||
/**
|
||||
* Overloaded constructor.
|
||||
* @return the `VirtualTrainingTeleporter` object
|
||||
*/
|
||||
def apply(): VirtualTrainingTeleporter = {
|
||||
new VirtualTrainingTeleporter()
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an configure a `VirtualTrainingTeleporter` object
|
||||
* @param id the unique id that will be assigned to this entity
|
||||
* @param context a context to allow the object to properly set up `ActorSystem` functionality;
|
||||
* not necessary for this object, but required by signature
|
||||
* @return the `VirtualTrainingTeleporter` object
|
||||
*/
|
||||
def Constructor(id: Int, context: ActorContext): VirtualTrainingTeleporter = {
|
||||
val obj = VirtualTrainingTeleporter()
|
||||
obj
|
||||
}
|
||||
|
||||
def Constructor(pos: Vector3)(id: Int, context: ActorContext): VirtualTrainingTeleporter = {
|
||||
val obj = VirtualTrainingTeleporter()
|
||||
obj.Position = pos
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) 2026 PSForever
|
||||
package net.psforever.objects.serverobject.structures
|
||||
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
|
||||
/**
|
||||
* Shared definition for spawn_pad and spawn_zone objects.
|
||||
*/
|
||||
class VirtualTrainingTeleporterDefinition extends ObjectDefinition(815) {
|
||||
Name = "spawn_zone"
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ final case class EquipmentPage(stock: Map[String, () => Equipment]) extends Scru
|
|||
stock.get(msg.item_name) match {
|
||||
case Some(item) =>
|
||||
val createdItem = item()
|
||||
if (!Exclude.exists(_.checkRule(player, msg, createdItem))) {
|
||||
if (!Exclude.exists(_.checkRule(player, msg, createdItem)) || player.IsInVRZone) {
|
||||
Terminal.BuyEquipment(createdItem)
|
||||
} else {
|
||||
Terminal.NoDeal()
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ final case class VehiclePage(stock: Map[String, () => Vehicle], trunk: Map[Strin
|
|||
stock.get(msg.item_name) match {
|
||||
case Some(vehicle) =>
|
||||
val createdVehicle = vehicle()
|
||||
if(!Exclude.exists(_.checkRule(player, msg, createdVehicle))) {
|
||||
if(!Exclude.exists(_.checkRule(player, msg, createdVehicle)) || player.IsInVRZone) {
|
||||
val (weapons, inventory) = trunk.get(msg.item_name) match {
|
||||
case Some(loadout: VehicleLoadout) =>
|
||||
(
|
||||
|
|
|
|||
|
|
@ -309,21 +309,21 @@ case object MapInfo extends StringEnum[MapInfo] {
|
|||
case object Map14
|
||||
extends MapInfo(
|
||||
value = "map14",
|
||||
checksum = 0L,
|
||||
checksum = 4276645952L,
|
||||
scale = MapScale.Dim1024,
|
||||
hotSpotSpan = 0,
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Water, 0)) ++
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Water, 10)) ++
|
||||
MapEnvironment.dim1024MapEdgeKillPlanes
|
||||
)
|
||||
|
||||
case object Map15
|
||||
extends MapInfo(
|
||||
value = "map15",
|
||||
checksum = 0L,
|
||||
scale = MapScale.Dim8192,
|
||||
checksum = 3628825458L,
|
||||
scale = MapScale.Dim4096,
|
||||
hotSpotSpan = 0,
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Water, 0)) ++
|
||||
MapEnvironment.dim8192MapEdgeKillPlanes
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Water, 8)) ++
|
||||
MapEnvironment.dim4096MapEdgeKillPlanes
|
||||
)
|
||||
|
||||
case object Map16
|
||||
|
|
|
|||
|
|
@ -1898,7 +1898,13 @@ object Zone {
|
|||
val allAffectedTargets = pssos.filter { target => testTargetsFromZone(source, target, radius) }
|
||||
//inform remaining targets that they have suffered damage
|
||||
allAffectedTargets
|
||||
.foreach { target => target.Actor ! Vitality.Damage(createInteraction(source, target).calculate()) }
|
||||
.foreach { target =>
|
||||
if (zone.id.startsWith("tz") && source.Faction == target.Faction) {
|
||||
//do not perform friendly-fire in VR zones
|
||||
} else {
|
||||
target.Actor ! Vitality.Damage(createInteraction(source, target).calculate())
|
||||
}
|
||||
}
|
||||
allAffectedTargets
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,91 +23,97 @@ object PacketCoding {
|
|||
final val PLANETSIDE_MIN_PACKET_SIZE = 1
|
||||
|
||||
/**
|
||||
* Transform a kind of packet into the sequence of data that represents it.
|
||||
* Wraps around the encoding process for all valid packet container types.
|
||||
* @param packet the packet to encode
|
||||
* @param sequence the packet's sequence number. Must be set for all non ControlPacket packets (but always for encrypted packets).
|
||||
* @param crypto if set, encrypt final payload
|
||||
* @return a `BitVector` translated from the packet's data
|
||||
*/
|
||||
* Transform a kind of packet into the sequence of data that represents it.
|
||||
* Wraps around the encoding process for all valid packet container types.
|
||||
* @param packet packet to encode
|
||||
* @param sequenceOpt packet's sequence number;
|
||||
* must be set for all packets that are not `ControlPacket`;
|
||||
* always for encrypted packets
|
||||
* @param crypto if set, encrypt final payload
|
||||
* @return a `BitVector` translated from the packet's data
|
||||
*/
|
||||
def marshalPacket(
|
||||
packet: PlanetSidePacket,
|
||||
sequence: Option[Int] = None,
|
||||
sequenceOpt: Option[Int] = None,
|
||||
crypto: Option[CryptoCoding] = None
|
||||
): Attempt[BitVector] = {
|
||||
val seq = packet match {
|
||||
case _: PlanetSideControlPacket if crypto.isEmpty => BitVector.empty
|
||||
case _: PlanetSideResetSequencePacket => BitVector.empty
|
||||
packet match {
|
||||
case _: PlanetSideControlPacket if crypto.isEmpty =>
|
||||
marshalPacket(packet, BitVector.empty, crypto)
|
||||
case _ =>
|
||||
sequence match {
|
||||
case Some(_sequence) =>
|
||||
uint16L.encode(_sequence) match {
|
||||
case Successful(_seq) => _seq
|
||||
case f @ Failure(_) => return f
|
||||
sequenceOpt match {
|
||||
case Some(sequence) =>
|
||||
uint16L.encode(sequence) match {
|
||||
case Successful(encodedSequence) => marshalPacket(packet, encodedSequence, crypto)
|
||||
case f: Failure => f
|
||||
}
|
||||
case None =>
|
||||
return Failure(Err(s"Missing sequence"))
|
||||
Failure(Err(s"can not marshal $packet without a proper sequence id"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val (flags, payload) = packet match {
|
||||
/** Common flags for normal encrypted packets. */
|
||||
private val normalSecuredFlags: BitVector = PlanetSidePacketFlags.codec
|
||||
.encode(PlanetSidePacketFlags(PacketType.Normal, secured = true))
|
||||
.require
|
||||
/** Common flags for normal unencrypted packets. */
|
||||
private val normalNotSecuredFlags: BitVector = PlanetSidePacketFlags.codec
|
||||
.encode(PlanetSidePacketFlags(PacketType.Normal, secured = false))
|
||||
.require
|
||||
/** Common flags for crypto unencrypted packets (that's not illogical). */
|
||||
private val cryptoNotSecuredFlags: BitVector = PlanetSidePacketFlags.codec
|
||||
.encode(PlanetSidePacketFlags(PacketType.Crypto, secured = false))
|
||||
.require
|
||||
|
||||
/**
|
||||
* Transform a kind of packet into the sequence of data that represents it.
|
||||
* @param packet the packet to encode
|
||||
* @param sequence the packet's sequence number. Must be set for all non ControlPacket packets (but always for encrypted packets).
|
||||
* @param crypto if set, encrypt final payload
|
||||
* @return a `BitVector` translated from the packet's data
|
||||
*/
|
||||
private def marshalPacket(
|
||||
packet: PlanetSidePacket,
|
||||
sequence: BitVector,
|
||||
crypto: Option[CryptoCoding]
|
||||
): Attempt[BitVector] = {
|
||||
packet match {
|
||||
case _: PlanetSideGamePacket | _: PlanetSideControlPacket if crypto.isDefined =>
|
||||
encodePacket(packet) match {
|
||||
case Successful(_payload) =>
|
||||
val encryptedPayload = crypto.get.encrypt(_payload.bytes) match {
|
||||
case Successful(p) => p
|
||||
case f: Failure => return f
|
||||
}
|
||||
(
|
||||
PlanetSidePacketFlags.codec.encode(PlanetSidePacketFlags(PacketType.Normal, secured = true)).require,
|
||||
// encrypted packets need to be aligned to 4 bytes before encryption/decryption
|
||||
// first byte are flags, second is the sequence, and third is the pad
|
||||
hex"00".bits ++ encryptedPayload.bits
|
||||
)
|
||||
case f @ Failure(_) => return f
|
||||
}
|
||||
encodePacket(packet)
|
||||
.flatMap { _payload => crypto.get.encrypt(_payload.bytes) }
|
||||
.flatMap { encryptedPayload =>
|
||||
// these encrypted packets need to be aligned to 4 bytes before encryption/decryption
|
||||
// first byte are flags, second is the sequence, and third is the pad
|
||||
val payload = hex"00".bits ++ encryptedPayload.bits
|
||||
Successful(normalSecuredFlags ++ sequence ++ payload)
|
||||
}
|
||||
case packet: PlanetSideGamePacket =>
|
||||
encodePacket(packet) match {
|
||||
case Successful(_payload) =>
|
||||
(
|
||||
PlanetSidePacketFlags.codec.encode(PlanetSidePacketFlags(PacketType.Normal, secured = false)).require,
|
||||
_payload
|
||||
)
|
||||
case f @ Failure(_) => return f
|
||||
}
|
||||
encodePacket(packet)
|
||||
.flatMap { _payload =>
|
||||
Successful(normalNotSecuredFlags ++ sequence ++ _payload)
|
||||
}
|
||||
case packet: PlanetSideControlPacket =>
|
||||
encodePacket(packet) match {
|
||||
case Successful(_payload) =>
|
||||
(
|
||||
// control packets don't have flags
|
||||
BitVector.empty,
|
||||
_payload
|
||||
)
|
||||
case f @ Failure(_) => return f
|
||||
}
|
||||
encodePacket(packet)
|
||||
.flatMap { _payload =>
|
||||
Successful(sequence ++ _payload)
|
||||
}
|
||||
case packet: PlanetSideCryptoPacket =>
|
||||
encodePacket(packet) match {
|
||||
case Successful(_payload) =>
|
||||
(
|
||||
PlanetSidePacketFlags.codec.encode(PlanetSidePacketFlags(PacketType.Crypto, secured = false)).require,
|
||||
_payload
|
||||
)
|
||||
case f @ Failure(_) => return f
|
||||
}
|
||||
case packet: PlanetSideResetSequencePacket =>
|
||||
encodePacket(packet) match {
|
||||
case Successful(_payload) =>
|
||||
(
|
||||
PlanetSidePacketFlags.codec
|
||||
.encode(PlanetSidePacketFlags(PacketType.ResetSequence, secured = false))
|
||||
.require,
|
||||
_payload
|
||||
)
|
||||
case f @ Failure(_) => return f
|
||||
}
|
||||
encodePacket(packet)
|
||||
.flatMap { _payload =>
|
||||
Successful(cryptoNotSecuredFlags ++ sequence ++ _payload)
|
||||
}
|
||||
case packet: PlanetSideResetSequencePacket if crypto.isDefined =>
|
||||
encodePacket(packet)
|
||||
.flatMap { _payload => crypto.get.encrypt(_payload.bytes) }
|
||||
.flatMap { encryptedPayload =>
|
||||
//uncommon, so it's fine to not cache these flags (above)
|
||||
val flags = PlanetSidePacketFlags.codec.encode(PlanetSidePacketFlags(PacketType.ResetSequence, secured = true)).require
|
||||
Successful(flags ++ sequence ++ encryptedPayload.bits)
|
||||
}
|
||||
case _ =>
|
||||
Failure(Err(s"can not marshal $packet, sequence? $sequence, crypto state? ${crypto.isDefined}"))
|
||||
}
|
||||
|
||||
Successful(flags ++ seq ++ payload)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -131,17 +137,16 @@ object PacketCoding {
|
|||
case Successful(opcode) => Successful(opcode ++ payload)
|
||||
case f @ Failure(_) => f
|
||||
}
|
||||
|
||||
case packet: PlanetSideResetSequencePacket =>
|
||||
ResetSequenceOpcode.codec.encode(packet.opcode) match {
|
||||
case Successful(opcode) => Successful(opcode)
|
||||
case f @ Failure(_) => f
|
||||
case f: Failure => f
|
||||
}
|
||||
|
||||
case _ =>
|
||||
Failure(Err("packet not supported"))
|
||||
}
|
||||
case f @ Failure(_) => f
|
||||
case f: Failure => f
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -360,6 +365,5 @@ object PacketCoding {
|
|||
|
||||
Successful(payloadNoMac)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -422,6 +422,8 @@ object ObjectClass {
|
|||
final val order_terminalb = 614
|
||||
final val portable_ammo_terminal = 684
|
||||
final val portable_order_terminal = 690
|
||||
final val spawn_pad = 800
|
||||
final val spawn_zone = 815
|
||||
final val targeting_laser_dispenser = 851
|
||||
final val teleportpad_terminal = 853
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,11 @@ class PropertyOverrideManager extends Actor {
|
|||
}
|
||||
|
||||
private def LoadOverridesFromFile(zoneId: Int): Unit = {
|
||||
val zoneOverrides = LoadFile(s"overrides/game_objects$zoneId.adb.lst")
|
||||
val zoneOverrides = if (zoneId > 13 && zoneId < 23) {
|
||||
LoadFile(s"overrides/game_objectstz.adb.lst")
|
||||
} else {
|
||||
LoadFile(s"overrides/game_objects$zoneId.adb.lst")
|
||||
}
|
||||
if (zoneOverrides == null) {
|
||||
log.debug(s"PropertyOverride: no overrides found for zone $zoneId using filename game_objects$zoneId.adb.lst")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -492,19 +492,19 @@ object PointOfInterest {
|
|||
"gate3" -> Vector3(4079, 2467, 155)
|
||||
)
|
||||
zones("home3").locations += "hart_c" -> Vector3(3675, 2727, 91)
|
||||
zones("tzshtr").locations += "roof" -> Vector3(499, 1568, 25)
|
||||
zones("tzshtr").locations += "roof" -> Vector3(499, 544, 25)
|
||||
zones("tzcotr").locations += "spawn" -> Vector3(960, 1002, 32)
|
||||
zones("tzdrtr").locations ++= Map(
|
||||
"start" -> Vector3(2457, 1864, 23),
|
||||
"air_pad" -> Vector3(1700, 1900, 32)
|
||||
)
|
||||
zones("tzshvs").locations += "roof" -> Vector3(499, 1568, 25)
|
||||
zones("tzshvs").locations += "roof" -> Vector3(499, 544, 25)
|
||||
zones("tzcovs").locations += "spawn" -> Vector3(960, 1002, 32)
|
||||
zones("tzdrvs").locations ++= Map(
|
||||
"start" -> Vector3(2457, 1864, 23),
|
||||
"air_pad" -> Vector3(1700, 1900, 32)
|
||||
)
|
||||
zones("tzshnc").locations += "roof" -> Vector3(499, 1568, 25)
|
||||
zones("tzshnc").locations += "roof" -> Vector3(499, 544, 25)
|
||||
zones("tzconc").locations += "spawn" -> Vector3(960, 1002, 32)
|
||||
zones("tzdrnc").locations ++= Map(
|
||||
"start" -> Vector3(2457, 1864, 23),
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import net.psforever.objects.serverobject.pad.{VehicleSpawnPad, VehicleSpawnPadD
|
|||
import net.psforever.objects.serverobject.painbox.{Painbox, PainboxDefinition}
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
import net.psforever.objects.serverobject.shuttle.OrbitalShuttlePad
|
||||
import net.psforever.objects.serverobject.structures.{Building, BuildingDefinition, FoundationBuilder, StructureType, WarpGate}
|
||||
import net.psforever.objects.serverobject.structures.{Building, BuildingDefinition, FoundationBuilder, StructureType, VirtualTrainingTeleporter, WarpGate}
|
||||
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalDefinition}
|
||||
import net.psforever.objects.serverobject.terminals.implant.{ImplantTerminalInterface, ImplantTerminalMech}
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
|
|
@ -113,6 +113,8 @@ object Zones {
|
|||
"orbital_building_vs",
|
||||
"orbital_building_tr",
|
||||
"orbital_building_nc",
|
||||
"vr_training",
|
||||
"vt_air_vehicle",
|
||||
"VT_building_vs",
|
||||
"VT_building_tr",
|
||||
"VT_building_nc",
|
||||
|
|
@ -724,6 +726,10 @@ object Zones {
|
|||
)
|
||||
zoneMap.linkShuttleToBay(obj.guid)
|
||||
|
||||
case "spawn_pad" | "spawn_zone" =>
|
||||
zoneMap
|
||||
.addLocalObject(obj.guid, VirtualTrainingTeleporter.Constructor(obj.position))
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
|
@ -780,10 +786,12 @@ object Zones {
|
|||
this.HotSpotCoordinateFunction = Zones.HotSpots.standardRemapping(info.map.scale, info.map.hotSpotSpan, info.map.hotSpotSpan)
|
||||
this.HotSpotTimeFunction = Zones.HotSpots.standardTimeRules
|
||||
Zones.initZoneAmenities(zone = this)
|
||||
} else {
|
||||
Zones.initZoneAmenities(zone = this)
|
||||
}
|
||||
|
||||
//special conditions
|
||||
//1. sanctuaries are completely owned by a single faction
|
||||
//1. sanctuaries and VR training zones are completely owned by a single faction
|
||||
//2. set up the third warp gate on sanctuaries to be a broadcast warp gate
|
||||
//3. set up sanctuary-linked warp gates on "home continents" (the names make no sense anymore, don't even ask)
|
||||
//4. assign the caverns internally
|
||||
|
|
@ -833,6 +841,12 @@ object Zones {
|
|||
bldgs.filter(_.Name.startsWith("WG_")).map {
|
||||
case gate: WarpGate => gate.AllowBroadcastFor = PlanetSideEmpire.VS
|
||||
}
|
||||
case "tzshtr" | "tzdrtr" | "tzcotr" =>
|
||||
bldgs.foreach(_.Faction = PlanetSideEmpire.TR)
|
||||
case "tzshnc" | "tzdrnc" | "tzconc" =>
|
||||
bldgs.foreach(_.Faction = PlanetSideEmpire.NC)
|
||||
case "tzshvs" | "tzdrvs" | "tzcovs" =>
|
||||
bldgs.foreach(_.Faction = PlanetSideEmpire.VS)
|
||||
case "i4" =>
|
||||
bldgs.find(_.Name.equals("Map96_Gate_Three")).map {
|
||||
case gate: WarpGate => gate.Active = false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue